iamcal 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Oli<oli@olillin.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # iamcal
2
+
3
+ A library for reading, modifying and writing [ICalendar](https://en.wikipedia.org/wiki/ICalendar) files.
4
+
5
+ ## Installation
6
+
7
+ **iamcal** can be installed from the npm registry:
8
+
9
+ ```console
10
+ npm install iamcal
11
+ ```
12
+
13
+ ## Getting started/Example
14
+
15
+ This code;
16
+
17
+ ```typescript
18
+ import { Calendar } from 'iamcal'
19
+ import { dump } from 'iamcal/io'
20
+ import { parseCalendar } from 'iamcal/parse'
21
+
22
+ const calendar: Calendar = await parseCalendar(`
23
+ BEGIN:VCALENDAR
24
+ VERSION:2.0
25
+ PRODID:example
26
+ BEGIN:VEVENT
27
+ SUMMARY:🎉iamcal release party
28
+ LOCATION:Las Vegas!!
29
+ UID:20241209T100000Z-EF79AE@example.com
30
+ DTSTAMP:20241209T100000Z
31
+ DTSTART:20241211T200000Z
32
+ DTEND:20241211T230000Z
33
+ END:VEVENT
34
+ END:VCALENDAR
35
+ `)
36
+
37
+ calendar.events().forEach(event => {
38
+ if (event.summary() === "🎉iamcal release party") {
39
+ event.setLocation("My house (budget cuts sorry)")
40
+ }
41
+ })
42
+
43
+ await dump(calendar, "./new_calendar.ics")
44
+ ```
45
+
46
+ produces the file `new_calendar.ics`:
47
+
48
+ ```icalendar
49
+ BEGIN:VCALENDAR
50
+ VERSION:2.0
51
+ PRODID:example
52
+ BEGIN:VEVENT
53
+ SUMMARY:🎉iamcal release party
54
+ LOCATION:My house (budget cuts sorry)
55
+ UID:20241209T100000Z-EF79AE@example.com
56
+ DTSTAMP:20241209T100000Z
57
+ DTSTART:20241211T200000Z
58
+ DTEND:20241211T230000Z
59
+ END:VEVENT
60
+ END:VCALENDAR
61
+ ```
package/lib/index.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ export interface Property {
2
+ name: string;
3
+ params: string[];
4
+ value: string;
5
+ }
6
+ export declare class Component {
7
+ name: string;
8
+ properties: Array<Property>;
9
+ components: Array<Component>;
10
+ constructor(name: string, properties?: Array<Property>, components?: Array<Component>);
11
+ serialize(): string;
12
+ getProperty(name: string): Property | null;
13
+ setProperty(name: string, value: string): void;
14
+ getPropertyParams(name: string): string[] | null;
15
+ setPropertyParams(name: string, params: string[]): void;
16
+ }
17
+ export declare class Calendar extends Component {
18
+ name: string;
19
+ constructor(component: Component);
20
+ events(): Array<CalendarEvent>;
21
+ }
22
+ export declare class CalendarEvent extends Component {
23
+ name: string;
24
+ constructor(component: Component);
25
+ summary(): string;
26
+ setSummary(value: string): void;
27
+ description(): string;
28
+ setDescription(value: string): void;
29
+ location(): string | undefined;
30
+ setLocation(value: string): void;
31
+ start(): Date;
32
+ setStart(value: Date): void;
33
+ end(): Date;
34
+ setEnd(value: Date): void;
35
+ }
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CAChB;AAKD,qBAAa,SAAS;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;gBAEhB,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAcrF,SAAS,IAAI,MAAM;IA+BnB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAS1C,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAcvC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAShD,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;CAOnD;AAED,qBAAa,QAAS,SAAQ,SAAS;IACnC,IAAI,SAAc;gBAEN,SAAS,EAAE,SAAS;IAIhC,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC;CAWjC;AAED,qBAAa,aAAc,SAAQ,SAAS;IACxC,IAAI,SAAW;gBAEH,SAAS,EAAE,SAAS;IAIhC,OAAO,IAAI,MAAM;IAIjB,UAAU,CAAC,KAAK,EAAE,MAAM;IAIxB,WAAW,IAAI,MAAM;IAIrB,cAAc,CAAC,KAAK,EAAE,MAAM;IAI5B,QAAQ,IAAI,MAAM,GAAG,SAAS;IAI9B,WAAW,CAAC,KAAK,EAAE,MAAM;IAIzB,KAAK,IAAI,IAAI;IAIb,QAAQ,CAAC,KAAK,EAAE,IAAI;IAIpB,GAAG,IAAI,IAAI;IAIX,MAAM,CAAC,KAAK,EAAE,IAAI;CAGrB"}
package/lib/index.js ADDED
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CalendarEvent = exports.Calendar = exports.Component = void 0;
4
+ // Max line length as defined by RFC 5545 3.1.
5
+ const MAX_LINE_LENGTH = 75;
6
+ class Component {
7
+ constructor(name, properties, components) {
8
+ this.name = name;
9
+ if (properties) {
10
+ this.properties = properties;
11
+ }
12
+ else {
13
+ this.properties = new Array();
14
+ }
15
+ if (components) {
16
+ this.components = components;
17
+ }
18
+ else {
19
+ this.components = new Array();
20
+ }
21
+ }
22
+ serialize() {
23
+ // Create lines
24
+ const lines = [`BEGIN:${this.name}`];
25
+ for (let property of this.properties) {
26
+ let line = property['name'] + //
27
+ property.params.map(p => ';' + p).join('') +
28
+ ':' +
29
+ property['value'];
30
+ // Wrap lines
31
+ while (line.length > MAX_LINE_LENGTH) {
32
+ lines.push(line.substring(0, MAX_LINE_LENGTH));
33
+ line = " " + line.substring(MAX_LINE_LENGTH);
34
+ }
35
+ lines.push(line);
36
+ }
37
+ for (let component of this.components) {
38
+ lines.push(component.serialize());
39
+ }
40
+ lines.push(`END:${this.name}`);
41
+ // Join lines
42
+ const serialized = lines.join('\n');
43
+ return serialized;
44
+ }
45
+ getProperty(name) {
46
+ for (const property of this.properties) {
47
+ if (property.name === name) {
48
+ return property;
49
+ }
50
+ }
51
+ return null;
52
+ }
53
+ setProperty(name, value) {
54
+ for (const property of this.properties) {
55
+ if (property.name === name) {
56
+ property.value = value;
57
+ return;
58
+ }
59
+ }
60
+ this.properties.push({
61
+ name: name,
62
+ params: [],
63
+ value: value,
64
+ });
65
+ }
66
+ getPropertyParams(name) {
67
+ for (const property of this.properties) {
68
+ if (property.name === name) {
69
+ return property.params;
70
+ }
71
+ }
72
+ return null;
73
+ }
74
+ setPropertyParams(name, params) {
75
+ for (const property of this.properties) {
76
+ if (property.name === name) {
77
+ property.params = params;
78
+ }
79
+ }
80
+ }
81
+ }
82
+ exports.Component = Component;
83
+ class Calendar extends Component {
84
+ constructor(component) {
85
+ super(component.name, component.properties, component.components);
86
+ this.name = 'VCALENDAR';
87
+ }
88
+ events() {
89
+ const events = new Array();
90
+ for (let component of this.components) {
91
+ if (component.name === 'VEVENT') {
92
+ events.push(new CalendarEvent(component));
93
+ }
94
+ }
95
+ return events;
96
+ }
97
+ }
98
+ exports.Calendar = Calendar;
99
+ class CalendarEvent extends Component {
100
+ constructor(component) {
101
+ super(component.name, component.properties, component.components);
102
+ this.name = 'VEVENT';
103
+ }
104
+ summary() {
105
+ return this.getProperty('SUMMARY').value;
106
+ }
107
+ setSummary(value) {
108
+ this.setProperty("SUMMARY", value);
109
+ }
110
+ description() {
111
+ return this.getProperty('DESCRIPTION').value;
112
+ }
113
+ setDescription(value) {
114
+ this.setProperty("DESCRIPTION", value);
115
+ }
116
+ location() {
117
+ var _a;
118
+ return (_a = this.getProperty('LOCATION')) === null || _a === void 0 ? void 0 : _a.value;
119
+ }
120
+ setLocation(value) {
121
+ this.setProperty("LOCATION", value);
122
+ }
123
+ start() {
124
+ return new Date(this.getProperty('DTSTART').value);
125
+ }
126
+ setStart(value) {
127
+ this.setProperty("DTSTART", value.toISOString());
128
+ }
129
+ end() {
130
+ return new Date(this.getProperty('DTEND').value);
131
+ }
132
+ setEnd(value) {
133
+ this.setProperty("DTEND", value.toISOString());
134
+ }
135
+ }
136
+ exports.CalendarEvent = CalendarEvent;
137
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/lib/io.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import fs from 'fs';
2
+ import { Calendar } from '.';
3
+ /**
4
+ * Read a calendar from a .ical file
5
+ * @param path Path to the file to read
6
+ * @throws DeserializationError Component must be of valid format
7
+ * @throws TypeError Component must be a `VCALENDAR`
8
+ */
9
+ export declare function load(path: fs.PathLike): Promise<Calendar>;
10
+ /**
11
+ * Write a calendar to a .ical file
12
+ * @param calendar The calendar
13
+ * @param path Path to the file to write
14
+ */
15
+ export declare function dump(calendar: Calendar, path: string): void;
16
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;AAG5B;;;;;GAKG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAW/D;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,QAEpD"}
package/lib/io.js ADDED
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.load = load;
16
+ exports.dump = dump;
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const readline_1 = __importDefault(require("readline"));
19
+ const _1 = require(".");
20
+ const parse_1 = require("./parse");
21
+ /**
22
+ * Read a calendar from a .ical file
23
+ * @param path Path to the file to read
24
+ * @throws DeserializationError Component must be of valid format
25
+ * @throws TypeError Component must be a `VCALENDAR`
26
+ */
27
+ function load(path) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const stream = fs_1.default.createReadStream(path);
30
+ const lines = readline_1.default.createInterface({ input: stream, crlfDelay: Infinity });
31
+ const component = yield (0, parse_1.deserialize)(lines);
32
+ if (component.name != 'VCALENDAR') {
33
+ throw TypeError('Component is not a calendar');
34
+ }
35
+ return new _1.Calendar(component);
36
+ });
37
+ }
38
+ /**
39
+ * Write a calendar to a .ical file
40
+ * @param calendar The calendar
41
+ * @param path Path to the file to write
42
+ */
43
+ function dump(calendar, path) {
44
+ fs_1.default.writeFileSync(path, calendar.serialize());
45
+ }
46
+ //# sourceMappingURL=io.js.map
package/lib/io.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.js","sourceRoot":"","sources":["../io.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAWA,oBAWC;AAOD,oBAEC;AA/BD,4CAAmB;AACnB,wDAA+B;AAC/B,wBAA4B;AAC5B,mCAAqC;AAErC;;;;;GAKG;AACH,SAAsB,IAAI,CAAC,IAAiB;;QACxC,MAAM,MAAM,GAAG,YAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,kBAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAA;QAE9E,MAAM,SAAS,GAAG,MAAM,IAAA,mBAAW,EAAC,KAAK,CAAC,CAAA;QAE1C,IAAI,SAAS,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;YAChC,MAAM,SAAS,CAAC,6BAA6B,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,IAAI,WAAQ,CAAC,SAAS,CAAC,CAAA;IAClC,CAAC;CAAA;AAED;;;;GAIG;AACH,SAAgB,IAAI,CAAC,QAAkB,EAAE,IAAY;IACjD,YAAE,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;AAChD,CAAC"}
package/lib/parse.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import readline from 'readline';
2
+ import { Calendar, CalendarEvent, Component } from '.';
3
+ export declare class DeserializationError extends Error {
4
+ name: string;
5
+ }
6
+ /**
7
+ * Deserialize a calendar component
8
+ * @param lines the serialized component as a readline interface
9
+ */
10
+ export declare function deserialize(lines: readline.Interface): Promise<Component>;
11
+ /**
12
+ * Deserialize a calendar component
13
+ * @param text the serialized component
14
+ */
15
+ export declare function deserializeString(text: string): Promise<Component>;
16
+ /**
17
+ * Parse a calendar in ICalendar format
18
+ * @param text the serialized calendar
19
+ * @returns the parsed calendar
20
+ */
21
+ export declare function parseCalendar(text: string): Promise<Calendar>;
22
+ /**
23
+ * Parse an event in ICalendar format
24
+ * @param text the serialized event
25
+ * @returns the parsed event
26
+ */
27
+ export declare function parseEvent(text: string): Promise<CalendarEvent>;
28
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../parse.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAE/B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,CAAA;AAEtD,qBAAa,oBAAqB,SAAQ,KAAK;IAC3C,IAAI,SAAyB;CAChC;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAsH/E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAIxE;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAKnE;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAKrE"}
package/lib/parse.js ADDED
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
12
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
13
+ var m = o[Symbol.asyncIterator], i;
14
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
15
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
16
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
17
+ };
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.DeserializationError = void 0;
23
+ exports.deserialize = deserialize;
24
+ exports.deserializeString = deserializeString;
25
+ exports.parseCalendar = parseCalendar;
26
+ exports.parseEvent = parseEvent;
27
+ const readline_1 = __importDefault(require("readline"));
28
+ const stream_1 = require("stream");
29
+ const _1 = require(".");
30
+ class DeserializationError extends Error {
31
+ constructor() {
32
+ super(...arguments);
33
+ this.name = 'DeserializationError';
34
+ }
35
+ }
36
+ exports.DeserializationError = DeserializationError;
37
+ /**
38
+ * Deserialize a calendar component
39
+ * @param lines the serialized component as a readline interface
40
+ */
41
+ function deserialize(lines) {
42
+ return __awaiter(this, void 0, void 0, function* () {
43
+ var _a, lines_1, lines_1_1;
44
+ var _b, e_1, _c, _d;
45
+ const component = new _1.Component('');
46
+ let done = false;
47
+ // We use a stack to keep track of nested components
48
+ const stack = new Array();
49
+ const subcomponentLines = new Array();
50
+ function processLine(line) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ if (line.trim() === '')
53
+ return;
54
+ if (done) {
55
+ throw new DeserializationError('Trailing data after component end');
56
+ }
57
+ if (line.startsWith('BEGIN:')) {
58
+ // Begin component
59
+ const name = line.slice(line.indexOf(':') + 1);
60
+ stack.push(name);
61
+ if (stack.length == 1) {
62
+ component.name = name;
63
+ }
64
+ else {
65
+ subcomponentLines.push(line);
66
+ }
67
+ }
68
+ else if (line.startsWith('END:')) {
69
+ // End component
70
+ if (stack.length == 0) {
71
+ throw new DeserializationError('Component end before begin');
72
+ }
73
+ const stackName = stack.pop();
74
+ const name = line.slice(line.indexOf(':') + 1);
75
+ if (stackName !== name) {
76
+ throw new DeserializationError('Malformed subcomponent');
77
+ }
78
+ // Check the length of the stack after being popped
79
+ if (stack.length == 1) {
80
+ subcomponentLines.push(line);
81
+ const subcomponent = yield deserializeString(subcomponentLines.join('\r\n'));
82
+ subcomponentLines.length = 0;
83
+ component.components.push(subcomponent);
84
+ }
85
+ else if (stack.length > 1) {
86
+ subcomponentLines.push(line);
87
+ }
88
+ else if (stack.length == 0) {
89
+ done = true;
90
+ }
91
+ }
92
+ else {
93
+ if (stack.length == 0)
94
+ throw new DeserializationError('Property outside of components');
95
+ if (stack.length > 1) {
96
+ // Line of subcomponent
97
+ subcomponentLines.push(line);
98
+ }
99
+ else {
100
+ // Property
101
+ const colon = line.indexOf(':');
102
+ if (colon === -1) {
103
+ throw new DeserializationError(`Invalid content line: ${line}`);
104
+ }
105
+ const name = line.slice(0, colon);
106
+ const value = line.slice(colon + 1);
107
+ const params = name.split(';');
108
+ const property = {
109
+ name: params[0],
110
+ params: params.slice(1),
111
+ value: value,
112
+ };
113
+ component.properties.push(property);
114
+ }
115
+ }
116
+ });
117
+ }
118
+ /*
119
+ The following code unfolds lines and passes them to be processed above.
120
+
121
+ According to RFC 5545 content lines may be split using a line "folding"
122
+ technique. That is, a long line can be split between any two characters by
123
+ inserting a newline immediately followed by a white-space character.
124
+
125
+ For example, the line:
126
+
127
+ DESCRIPTION:This is a long description that exists on a long line.
128
+
129
+ Can be represented as:
130
+
131
+ DESCRIPTION:This is a lo
132
+ ng description
133
+ that exists on a long line.
134
+ */
135
+ let unfoldedLine = '';
136
+ try {
137
+ for (_a = true, lines_1 = __asyncValues(lines); lines_1_1 = yield lines_1.next(), _b = lines_1_1.done, !_b; _a = true) {
138
+ _d = lines_1_1.value;
139
+ _a = false;
140
+ const line = _d;
141
+ if (line.startsWith(' ') || line.startsWith('\t')) {
142
+ // Unfold continuation line (remove leading whitespace and append)
143
+ unfoldedLine += line.replace(/[\r\n]/, '').slice(1);
144
+ }
145
+ else {
146
+ if (unfoldedLine) {
147
+ // Process the previous unfolded line
148
+ yield processLine(unfoldedLine);
149
+ }
150
+ // Start a new unfolded line
151
+ unfoldedLine = line;
152
+ }
153
+ }
154
+ }
155
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
156
+ finally {
157
+ try {
158
+ if (!_a && !_b && (_c = lines_1.return)) yield _c.call(lines_1);
159
+ }
160
+ finally { if (e_1) throw e_1.error; }
161
+ }
162
+ // Process the last unfolded line
163
+ yield processLine(unfoldedLine);
164
+ // Check that component has been closed
165
+ if (!done) {
166
+ throw new DeserializationError('No component end');
167
+ }
168
+ return component;
169
+ });
170
+ }
171
+ /**
172
+ * Deserialize a calendar component
173
+ * @param text the serialized component
174
+ */
175
+ function deserializeString(text) {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ const stream = stream_1.Readable.from(text);
178
+ const lines = readline_1.default.createInterface({ input: stream, crlfDelay: Infinity });
179
+ return deserialize(lines);
180
+ });
181
+ }
182
+ /**
183
+ * Parse a calendar in ICalendar format
184
+ * @param text the serialized calendar
185
+ * @returns the parsed calendar
186
+ */
187
+ function parseCalendar(text) {
188
+ return __awaiter(this, void 0, void 0, function* () {
189
+ const component = yield deserializeString(text);
190
+ if (component.name !== "VCALENDAR")
191
+ throw new DeserializationError("Not a calendar");
192
+ return new _1.Calendar(component);
193
+ });
194
+ }
195
+ /**
196
+ * Parse an event in ICalendar format
197
+ * @param text the serialized event
198
+ * @returns the parsed event
199
+ */
200
+ function parseEvent(text) {
201
+ return __awaiter(this, void 0, void 0, function* () {
202
+ const component = yield deserializeString(text);
203
+ if (component.name !== "VEVENT")
204
+ throw new DeserializationError("Not an event");
205
+ return new _1.CalendarEvent(component);
206
+ });
207
+ }
208
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../parse.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "iamcal",
3
+ "version": "1.0.0",
4
+ "description": "Read and write ICalendar files",
5
+ "files": [
6
+ "/lib"
7
+ ],
8
+ "exports": {
9
+ ".": "./lib/index.js",
10
+ "./parse": "./lib/parse.js",
11
+ "./io": "./lib/io.js"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "echo \"Error: no test specified\" && exit 1"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/olillin/iamcal.git"
20
+ },
21
+ "keywords": [
22
+ "ical",
23
+ "calendar"
24
+ ],
25
+ "author": "Oli <oli@olillin.com>",
26
+ "license": "MIT",
27
+ "bugs": {
28
+ "url": "https://github.com/olillin/iamcal/issues"
29
+ },
30
+ "homepage": "https://github.com/olillin/iamcal#readme",
31
+ "dependencies": {
32
+ "typescript": "^5.7.2"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.10.1",
36
+ "tsc": "^2.0.4"
37
+ }
38
+ }