The design system defines parsing and serialization rules for different iCalendar and vCard formats. Design sets contain the metadata that drives how ICAL.js interprets component structures, property types, parameter validation, and value formatting across different specification versions.
Core functions for working with design sets that define format-specific parsing rules.
/**
* Get design set for a specific component type
* @param {string} componentName - Name of component (e.g., 'vcalendar', 'vcard')
* @returns {Object} Design set object containing parsing and serialization rules
*/
ICAL.design.getDesignSet(componentName: string): Object;Usage Examples:
const ICAL = require('ical.js');
// Get design set for iCalendar components
const icalendarDesign = ICAL.design.getDesignSet('vcalendar');
console.log('iCalendar design loaded');
// Get design set for vCard components
const vcardDesign = ICAL.design.getDesignSet('vcard');
console.log('vCard design loaded');
// Use design set in parsing
const propertyString = 'DTSTART:20230615T100000Z';
const parsedProperty = ICAL.parse.property(propertyString, icalendarDesign);Pre-defined design sets for different format specifications.
// Default design set (typically iCalendar)
ICAL.design.defaultSet: Object;
// iCalendar (RFC 5545) design set
ICAL.design.icalendar: Object;
// vCard 4.0 (RFC 6350) design set
ICAL.design.vcard: Object;
// Component-specific design sets
ICAL.design.components: Object;
// Strict parsing mode flag
ICAL.design.strict: boolean;Usage Examples:
const ICAL = require('ical.js');
// Access different design sets
console.log('Default design set:', ICAL.design.defaultSet);
console.log('iCalendar design set:', ICAL.design.icalendar);
console.log('vCard design set:', ICAL.design.vcard);
// Check strict parsing mode
console.log('Strict mode enabled:', ICAL.design.strict);
// Use specific design set for parsing
const icalString = 'BEGIN:VCALENDAR\nVERSION:2.0\nEND:VCALENDAR';
const jcalData = ICAL.parse(icalString); // Uses default design set
// Parse with explicit design set
const vcardString = 'BEGIN:VCARD\nVERSION:4.0\nFN:John Doe\nEND:VCARD';
const jcardData = ICAL.parse(vcardString); // Automatically detects vCard formatDesign sets contain several key sections that define how components and properties are handled:
interface DesignSet {
// Property definitions and validation rules
property: {
[propertyName: string]: PropertyDesign;
};
// Property grouping rules
propertyGroups: {
[groupName: string]: string[];
};
// Value type definitions and parsing rules
value: {
[valueType: string]: ValueDesign;
};
// Parameter definitions and validation rules
param: {
[parameterName: string]: ParameterDesign;
};
}Each property in a design set has specific rules for validation and processing:
// Example property design structure
const propertyDesign = {
defaultType: 'text', // Default value type
allowedTypes: ['text'], // Permitted value types
multiValue: false, // Whether property allows multiple values
multiValueSeparator: ',', // Separator for multi-value properties
structuredValue: false, // Whether value has structured components
allowedParams: ['type'], // Permitted parameters
detectType: function(value) { // Type detection function
// Custom logic to detect value type
return 'text';
}
};Value types define how different data types are parsed and serialized:
// Example value type design structure
const valueDesign = {
fromICAL: function(value) {
// Parse string value to JavaScript type
return processedValue;
},
toICAL: function(value) {
// Serialize JavaScript type to string
return stringValue;
},
matches: /^regex-pattern$/ // Optional: regex for validation
};Use design sets to parse properties with specific rules:
const ICAL = require('ical.js');
// Parse iCalendar property with iCalendar design set
const icalProperty = 'DTSTART;TZID=America/New_York:20230615T100000';
const icalDesign = ICAL.design.icalendar;
const parsedIcalProp = ICAL.parse.property(icalProperty, icalDesign);
// Parse vCard property with vCard design set
const vcardProperty = 'BDAY:19900615';
const vcardDesign = ICAL.design.vcard;
const parsedVcardProp = ICAL.parse.property(vcardProperty, vcardDesign);
console.log('iCal property:', parsedIcalProp);
console.log('vCard property:', parsedVcardProp);Access design sets for specific component types:
const ICAL = require('ical.js');
// Get component-specific design rules
const components = ICAL.design.components;
// Check if specific component design exists
if (components.vevent) {
console.log('VEVENT component design available');
}
if (components.vcard) {
console.log('VCARD component design available');
}
// Use component design for specialized parsing
const componentDesign = ICAL.design.getDesignSet('vevent');
// componentDesign will contain rules specific to VEVENT componentsControl parsing strictness using the design system:
const ICAL = require('ical.js');
// Check current strict mode setting
console.log('Strict mode:', ICAL.design.strict);
// Enable strict parsing (if modifiable in environment)
// Note: This may be read-only in some implementations
try {
ICAL.design.strict = true;
console.log('Enabled strict parsing mode');
} catch (error) {
console.log('Strict mode is read-only');
}
// Parse with strict validation
const icalString = 'BEGIN:VCALENDAR\nVERSION:2.0\nEND:VCALENDAR';
try {
const jcalData = ICAL.parse(icalString);
console.log('Parsing successful');
} catch (error) {
console.error('Strict parsing error:', error.message);
}Design sets drive property validation during parsing and component manipulation:
const ICAL = require('ical.js');
// Create component and add properties
const vcalendar = new ICAL.Component('vcalendar');
// The design system validates property types and parameters
try {
vcalendar.addPropertyWithValue('version', '2.0'); // Valid
vcalendar.addPropertyWithValue('version', 123); // May be validated by design set
} catch (error) {
console.error('Property validation error:', error.message);
}
// Check property definition in design set
const icalDesign = ICAL.design.icalendar;
if (icalDesign.property.version) {
console.log('VERSION property design:', icalDesign.property.version);
}Design sets determine how values are converted between string and object representations:
const ICAL = require('ical.js');
// Different value types are processed according to design set rules
const designs = ICAL.design.icalendar;
// Date-time values
if (designs.value['date-time']) {
console.log('Date-time value design available');
// Used internally when parsing DTSTART, DTEND, etc.
}
// Recurrence values
if (designs.value.recur) {
console.log('Recurrence value design available');
// Used internally when parsing RRULE values
}
// Duration values
if (designs.value.duration) {
console.log('Duration value design available');
// Used internally when parsing DURATION values
}Design sets enable ICAL.js to support multiple format versions:
const ICAL = require('ical.js');
// Parse different format versions using appropriate design sets
const vcard3String = `BEGIN:VCARD
VERSION:3.0
FN:John Doe
EMAIL:john@example.com
END:VCARD`;
const vcard4String = `BEGIN:VCARD
VERSION:4.0
FN:John Doe
EMAIL:john@example.com
END:VCARD`;
// ICAL.js automatically selects appropriate design set based on version
const vcard3Data = ICAL.parse(vcard3String);
const vcard4Data = ICAL.parse(vcard4String);
console.log('vCard 3.0 parsed');
console.log('vCard 4.0 parsed');
// Explicit design set usage for edge cases
const vcard3Design = ICAL.design.vcard3; // If available
const vcard4Design = ICAL.design.vcard; // Default vCard 4.0 designWhile design sets are typically read-only, understanding their structure helps when working with extensions:
const ICAL = require('ical.js');
// Examine design set structure for custom property handling
const icalDesign = ICAL.design.icalendar;
// Check for custom property support
if (icalDesign.property['x-custom-property']) {
console.log('Custom property design found');
} else {
console.log('Custom properties use default text handling');
}
// Work with experimental properties
const component = new ICAL.Component('vevent');
component.addPropertyWithValue('x-my-extension', 'custom value');
// Design set determines how this is parsed and serialized
const serialized = component.toString();
console.log('Serialized with custom property:', serialized);Use design set information for debugging parsing issues:
const ICAL = require('ical.js');
function debugPropertyParsing(propertyString, designSet) {
try {
const parsed = ICAL.parse.property(propertyString, designSet);
console.log('Successfully parsed:', parsed);
return parsed;
} catch (error) {
console.error('Parse error:', error.message);
// Check design set for property definition
const propertyName = propertyString.split(':')[0].split(';')[0];
const propertyDesign = designSet.property[propertyName.toLowerCase()];
if (propertyDesign) {
console.log('Property design exists:', propertyDesign);
} else {
console.log('No specific design for property:', propertyName);
}
return null;
}
}
// Debug problematic property
const problematicProperty = 'DTSTART;INVALID-PARAM=value:20230615T100000Z';
debugPropertyParsing(problematicProperty, ICAL.design.icalendar);