iamcal 1.0.0 → 1.0.2
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 +21 -21
- package/README.md +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -5
- package/lib/io.d.ts +1 -1
- package/lib/io.d.ts.map +1 -1
- package/lib/io.js +14 -21
- package/lib/parse.d.ts.map +1 -1
- package/lib/parse.js +121 -164
- package/package.json +37 -38
- package/src/index.ts +167 -0
- package/src/io.ts +37 -0
- package/src/parse.ts +165 -0
- package/lib/index.js.map +0 -1
- package/lib/io.js.map +0 -1
- package/lib/parse.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,21 +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.
|
|
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
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# iamcal
|
|
1
|
+
# iamcal [](https://github.com/olillin/iamcal/actions/workflows/npm-test.yml) [](https://www.npmjs.com/package/iamcal)
|
|
2
2
|
|
|
3
3
|
A library for reading, modifying and writing [ICalendar](https://en.wikipedia.org/wiki/ICalendar) files.
|
|
4
4
|
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/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
CHANGED
|
@@ -4,6 +4,9 @@ exports.CalendarEvent = exports.Calendar = exports.Component = void 0;
|
|
|
4
4
|
// Max line length as defined by RFC 5545 3.1.
|
|
5
5
|
const MAX_LINE_LENGTH = 75;
|
|
6
6
|
class Component {
|
|
7
|
+
name;
|
|
8
|
+
properties;
|
|
9
|
+
components;
|
|
7
10
|
constructor(name, properties, components) {
|
|
8
11
|
this.name = name;
|
|
9
12
|
if (properties) {
|
|
@@ -81,9 +84,9 @@ class Component {
|
|
|
81
84
|
}
|
|
82
85
|
exports.Component = Component;
|
|
83
86
|
class Calendar extends Component {
|
|
87
|
+
name = 'VCALENDAR';
|
|
84
88
|
constructor(component) {
|
|
85
89
|
super(component.name, component.properties, component.components);
|
|
86
|
-
this.name = 'VCALENDAR';
|
|
87
90
|
}
|
|
88
91
|
events() {
|
|
89
92
|
const events = new Array();
|
|
@@ -97,9 +100,9 @@ class Calendar extends Component {
|
|
|
97
100
|
}
|
|
98
101
|
exports.Calendar = Calendar;
|
|
99
102
|
class CalendarEvent extends Component {
|
|
103
|
+
name = 'VEVENT';
|
|
100
104
|
constructor(component) {
|
|
101
105
|
super(component.name, component.properties, component.components);
|
|
102
|
-
this.name = 'VEVENT';
|
|
103
106
|
}
|
|
104
107
|
summary() {
|
|
105
108
|
return this.getProperty('SUMMARY').value;
|
|
@@ -114,8 +117,7 @@ class CalendarEvent extends Component {
|
|
|
114
117
|
this.setProperty("DESCRIPTION", value);
|
|
115
118
|
}
|
|
116
119
|
location() {
|
|
117
|
-
|
|
118
|
-
return (_a = this.getProperty('LOCATION')) === null || _a === void 0 ? void 0 : _a.value;
|
|
120
|
+
return this.getProperty('LOCATION')?.value;
|
|
119
121
|
}
|
|
120
122
|
setLocation(value) {
|
|
121
123
|
this.setProperty("LOCATION", value);
|
|
@@ -134,4 +136,4 @@ class CalendarEvent extends Component {
|
|
|
134
136
|
}
|
|
135
137
|
}
|
|
136
138
|
exports.CalendarEvent = CalendarEvent;
|
|
137
|
-
//# sourceMappingURL=
|
|
139
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEsOENBQThDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQTtBQUUxQixNQUFhLFNBQVM7SUFDbEIsSUFBSSxDQUFRO0lBQ1osVUFBVSxDQUFpQjtJQUMzQixVQUFVLENBQWtCO0lBRTVCLFlBQVksSUFBWSxFQUFFLFVBQTRCLEVBQUUsVUFBNkI7UUFDakYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7UUFDaEIsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQ2hDLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFBO1FBQ2pDLENBQUM7UUFDRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUE7UUFDaEMsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUE7UUFDakMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTO1FBQ0wsZUFBZTtRQUNmLE1BQU0sS0FBSyxHQUFHLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUVwQyxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxJQUFJLElBQUksR0FDSixRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDckIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsR0FBRztnQkFDSCxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7WUFF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
|
package/lib/io.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export declare function load(path: fs.PathLike): Promise<Calendar>;
|
|
|
12
12
|
* @param calendar The calendar
|
|
13
13
|
* @param path Path to the file to write
|
|
14
14
|
*/
|
|
15
|
-
export declare function dump(calendar: Calendar, path: string): void
|
|
15
|
+
export declare function dump(calendar: Calendar, path: string): Promise<void>;
|
|
16
16
|
//# sourceMappingURL=io.d.ts.map
|
package/lib/io.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;AAI5B;;;;;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,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpE"}
|
package/lib/io.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -24,16 +15,14 @@ const parse_1 = require("./parse");
|
|
|
24
15
|
* @throws DeserializationError Component must be of valid format
|
|
25
16
|
* @throws TypeError Component must be a `VCALENDAR`
|
|
26
17
|
*/
|
|
27
|
-
function load(path) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return new _1.Calendar(component);
|
|
36
|
-
});
|
|
18
|
+
async function load(path) {
|
|
19
|
+
const stream = fs_1.default.createReadStream(path);
|
|
20
|
+
const lines = readline_1.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
21
|
+
const component = await (0, parse_1.deserialize)(lines);
|
|
22
|
+
if (component.name != 'VCALENDAR') {
|
|
23
|
+
throw TypeError('Component is not a calendar');
|
|
24
|
+
}
|
|
25
|
+
return new _1.Calendar(component);
|
|
37
26
|
}
|
|
38
27
|
/**
|
|
39
28
|
* Write a calendar to a .ical file
|
|
@@ -41,6 +30,10 @@ function load(path) {
|
|
|
41
30
|
* @param path Path to the file to write
|
|
42
31
|
*/
|
|
43
32
|
function dump(calendar, path) {
|
|
44
|
-
|
|
33
|
+
return new Promise(resolve => {
|
|
34
|
+
fs_1.default.writeFile(path, calendar.serialize(), () => {
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
45
38
|
}
|
|
46
|
-
//# sourceMappingURL=
|
|
39
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFZQSxvQkFXQztBQU9ELG9CQU1DO0FBcENELDRDQUFtQjtBQUNuQix3REFBK0I7QUFDL0Isd0JBQTRCO0FBQzVCLG1DQUFxQztBQUdyQzs7Ozs7R0FLRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBaUI7SUFDeEMsTUFBTSxNQUFNLEdBQUcsWUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3hDLE1BQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUU5RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUEsbUJBQVcsRUFBQyxLQUFLLENBQUMsQ0FBQTtJQUUxQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEMsTUFBTSxTQUFTLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQsT0FBTyxJQUFJLFdBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNsQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLElBQUksQ0FBQyxRQUFrQixFQUFFLElBQVk7SUFDakQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN6QixZQUFFLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQzFDLE9BQU8sRUFBRSxDQUFBO1FBQ2IsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMifQ==
|
package/lib/parse.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/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
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
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
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
19
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
4
|
};
|
|
@@ -28,181 +12,154 @@ const readline_1 = __importDefault(require("readline"));
|
|
|
28
12
|
const stream_1 = require("stream");
|
|
29
13
|
const _1 = require(".");
|
|
30
14
|
class DeserializationError extends Error {
|
|
31
|
-
|
|
32
|
-
super(...arguments);
|
|
33
|
-
this.name = 'DeserializationError';
|
|
34
|
-
}
|
|
15
|
+
name = 'DeserializationError';
|
|
35
16
|
}
|
|
36
17
|
exports.DeserializationError = DeserializationError;
|
|
37
18
|
/**
|
|
38
19
|
* Deserialize a calendar component
|
|
39
20
|
* @param lines the serialized component as a readline interface
|
|
40
21
|
*/
|
|
41
|
-
function deserialize(lines) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
});
|
|
22
|
+
async function deserialize(lines) {
|
|
23
|
+
const component = new _1.Component('');
|
|
24
|
+
let done = false;
|
|
25
|
+
// We use a stack to keep track of nested components
|
|
26
|
+
const stack = new Array();
|
|
27
|
+
const subcomponentLines = new Array();
|
|
28
|
+
async function processLine(line) {
|
|
29
|
+
if (line.trim() === '')
|
|
30
|
+
return;
|
|
31
|
+
if (done) {
|
|
32
|
+
throw new DeserializationError('Trailing data after component end');
|
|
117
33
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
}
|
|
34
|
+
if (line.startsWith('BEGIN:')) {
|
|
35
|
+
// Begin component
|
|
36
|
+
const name = line.slice(line.indexOf(':') + 1);
|
|
37
|
+
stack.push(name);
|
|
38
|
+
if (stack.length == 1) {
|
|
39
|
+
component.name = name;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
subcomponentLines.push(line);
|
|
153
43
|
}
|
|
154
44
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
45
|
+
else if (line.startsWith('END:')) {
|
|
46
|
+
// End component
|
|
47
|
+
if (stack.length == 0) {
|
|
48
|
+
throw new DeserializationError('Component end before begin');
|
|
49
|
+
}
|
|
50
|
+
const stackName = stack.pop();
|
|
51
|
+
const name = line.slice(line.indexOf(':') + 1);
|
|
52
|
+
if (stackName !== name) {
|
|
53
|
+
throw new DeserializationError('Malformed subcomponent');
|
|
54
|
+
}
|
|
55
|
+
// Check the length of the stack after being popped
|
|
56
|
+
if (stack.length == 1) {
|
|
57
|
+
subcomponentLines.push(line);
|
|
58
|
+
const subcomponent = await deserializeString(subcomponentLines.join('\r\n'));
|
|
59
|
+
subcomponentLines.length = 0;
|
|
60
|
+
component.components.push(subcomponent);
|
|
61
|
+
}
|
|
62
|
+
else if (stack.length > 1) {
|
|
63
|
+
subcomponentLines.push(line);
|
|
64
|
+
}
|
|
65
|
+
else if (stack.length == 0) {
|
|
66
|
+
done = true;
|
|
159
67
|
}
|
|
160
|
-
finally { if (e_1) throw e_1.error; }
|
|
161
68
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
69
|
+
else {
|
|
70
|
+
if (stack.length == 0)
|
|
71
|
+
throw new DeserializationError('Property outside of components');
|
|
72
|
+
if (stack.length > 1) {
|
|
73
|
+
// Line of subcomponent
|
|
74
|
+
subcomponentLines.push(line);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Property
|
|
78
|
+
const colon = line.indexOf(':');
|
|
79
|
+
if (colon === -1) {
|
|
80
|
+
throw new DeserializationError(`Invalid content line: ${line}`);
|
|
81
|
+
}
|
|
82
|
+
const name = line.slice(0, colon);
|
|
83
|
+
const value = line.slice(colon + 1);
|
|
84
|
+
const params = name.split(';');
|
|
85
|
+
const property = {
|
|
86
|
+
name: params[0],
|
|
87
|
+
params: params.slice(1),
|
|
88
|
+
value: value,
|
|
89
|
+
};
|
|
90
|
+
component.properties.push(property);
|
|
91
|
+
}
|
|
167
92
|
}
|
|
168
|
-
|
|
169
|
-
|
|
93
|
+
}
|
|
94
|
+
/*
|
|
95
|
+
The following code unfolds lines and passes them to be processed above.
|
|
96
|
+
|
|
97
|
+
According to RFC 5545 content lines may be split using a line "folding"
|
|
98
|
+
technique. That is, a long line can be split between any two characters by
|
|
99
|
+
inserting a newline immediately followed by a white-space character.
|
|
100
|
+
|
|
101
|
+
For example, the line:
|
|
102
|
+
|
|
103
|
+
DESCRIPTION:This is a long description that exists on a long line.
|
|
104
|
+
|
|
105
|
+
Can be represented as:
|
|
106
|
+
|
|
107
|
+
DESCRIPTION:This is a lo
|
|
108
|
+
ng description
|
|
109
|
+
that exists on a long line.
|
|
110
|
+
*/
|
|
111
|
+
let unfoldedLine = '';
|
|
112
|
+
for await (const line of lines) {
|
|
113
|
+
if (line.startsWith(' ') || line.startsWith('\t')) {
|
|
114
|
+
// Unfold continuation line (remove leading whitespace and append)
|
|
115
|
+
unfoldedLine += line.replace(/[\r\n]/, '').slice(1);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
if (unfoldedLine) {
|
|
119
|
+
// Process the previous unfolded line
|
|
120
|
+
await processLine(unfoldedLine);
|
|
121
|
+
}
|
|
122
|
+
// Start a new unfolded line
|
|
123
|
+
unfoldedLine = line;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Process the last unfolded line
|
|
127
|
+
await processLine(unfoldedLine);
|
|
128
|
+
// Check that component has been closed
|
|
129
|
+
if (!done) {
|
|
130
|
+
throw new DeserializationError('No component end');
|
|
131
|
+
}
|
|
132
|
+
return component;
|
|
170
133
|
}
|
|
171
134
|
/**
|
|
172
135
|
* Deserialize a calendar component
|
|
173
136
|
* @param text the serialized component
|
|
174
137
|
*/
|
|
175
|
-
function deserializeString(text) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return deserialize(lines);
|
|
180
|
-
});
|
|
138
|
+
async function deserializeString(text) {
|
|
139
|
+
const stream = stream_1.Readable.from(text);
|
|
140
|
+
const lines = readline_1.default.createInterface({ input: stream, crlfDelay: Infinity });
|
|
141
|
+
return deserialize(lines);
|
|
181
142
|
}
|
|
182
143
|
/**
|
|
183
144
|
* Parse a calendar in ICalendar format
|
|
184
145
|
* @param text the serialized calendar
|
|
185
146
|
* @returns the parsed calendar
|
|
186
147
|
*/
|
|
187
|
-
function parseCalendar(text) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return new _1.Calendar(component);
|
|
193
|
-
});
|
|
148
|
+
async function parseCalendar(text) {
|
|
149
|
+
const component = await deserializeString(text);
|
|
150
|
+
if (component.name !== "VCALENDAR")
|
|
151
|
+
throw new DeserializationError("Not a calendar");
|
|
152
|
+
return new _1.Calendar(component);
|
|
194
153
|
}
|
|
195
154
|
/**
|
|
196
155
|
* Parse an event in ICalendar format
|
|
197
156
|
* @param text the serialized event
|
|
198
157
|
* @returns the parsed event
|
|
199
158
|
*/
|
|
200
|
-
function parseEvent(text) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return new _1.CalendarEvent(component);
|
|
206
|
-
});
|
|
159
|
+
async function parseEvent(text) {
|
|
160
|
+
const component = await deserializeString(text);
|
|
161
|
+
if (component.name !== "VEVENT")
|
|
162
|
+
throw new DeserializationError("Not an event");
|
|
163
|
+
return new _1.CalendarEvent(component);
|
|
207
164
|
}
|
|
208
|
-
//# sourceMappingURL=
|
|
165
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGFyc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBWUEsa0NBc0hDO0FBTUQsOENBSUM7QUFPRCxzQ0FLQztBQU9ELGdDQUtDO0FBcEtELHdEQUErQjtBQUMvQixtQ0FBaUM7QUFDakMsd0JBQXNEO0FBRXRELE1BQWEsb0JBQXFCLFNBQVEsS0FBSztJQUMzQyxJQUFJLEdBQUcsc0JBQXNCLENBQUE7Q0FDaEM7QUFGRCxvREFFQztBQUVEOzs7R0FHRztBQUNJLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBeUI7SUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxZQUFTLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDbkMsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFBO0lBRWhCLG9EQUFvRDtJQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFBO0lBRWpDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQTtJQUU3QyxLQUFLLFVBQVUsV0FBVyxDQUFDLElBQVk7UUFDbkMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtZQUFFLE9BQU07UUFFOUIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNQLE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFBO1FBQ3ZFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM1QixrQkFBa0I7WUFDbEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQzlDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFaEIsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNwQixTQUFTLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQTtZQUN6QixDQUFDO2lCQUFNLENBQUM7Z0JBQ0osaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2hDLENBQUM7UUFDTCxDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDakMsZ0JBQWdCO1lBQ2hCLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxJQUFJLG9CQUFvQixDQUFDLDRCQUE0QixDQUFDLENBQUE7WUFDaEUsQ0FBQztZQUVELE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQTtZQUM3QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7WUFDOUMsSUFBSSxTQUFTLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQ3JCLE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFBO1lBQzVELENBQUM7WUFFRCxtREFBbUQ7WUFDbkQsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNwQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQzVCLE1BQU0sWUFBWSxHQUFHLE1BQU0saUJBQWlCLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7Z0JBQzVFLGlCQUFpQixDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUE7Z0JBRTVCLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO1lBQzNDLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMxQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDaEMsQ0FBQztpQkFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzNCLElBQUksR0FBRyxJQUFJLENBQUE7WUFDZixDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQztnQkFBRSxNQUFNLElBQUksb0JBQW9CLENBQUMsZ0NBQWdDLENBQUMsQ0FBQTtZQUV2RixJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ25CLHVCQUF1QjtnQkFDdkIsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2hDLENBQUM7aUJBQU0sQ0FBQztnQkFDSixXQUFXO2dCQUNYLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQy9CLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ2YsTUFBTSxJQUFJLG9CQUFvQixDQUFDLHlCQUF5QixJQUFJLEVBQUUsQ0FBQyxDQUFBO2dCQUNuRSxDQUFDO2dCQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFBO2dCQUNqQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQTtnQkFFbkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtnQkFDOUIsTUFBTSxRQUFRLEdBQUc7b0JBQ2IsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7b0JBQ2YsTUFBTSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUN2QixLQUFLLEVBQUUsS0FBSztpQkFDZixDQUFBO2dCQUVELFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ3ZDLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O01BZ0JFO0lBQ0YsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFBO0lBQ3JCLElBQUksS0FBSyxFQUFFLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQzdCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDaEQsa0VBQWtFO1lBQ2xFLFlBQVksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdkQsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUNmLHFDQUFxQztnQkFDckMsTUFBTSxXQUFXLENBQUMsWUFBWSxDQUFDLENBQUE7WUFDbkMsQ0FBQztZQUNELDRCQUE0QjtZQUM1QixZQUFZLEdBQUcsSUFBSSxDQUFBO1FBQ3ZCLENBQUM7SUFDTCxDQUFDO0lBRUQsaUNBQWlDO0lBQ2pDLE1BQU0sV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFBO0lBRS9CLHVDQUF1QztJQUN2QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixNQUFNLElBQUksb0JBQW9CLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtJQUN0RCxDQUFDO0lBRUQsT0FBTyxTQUFTLENBQUE7QUFDcEIsQ0FBQztBQUVEOzs7R0FHRztBQUNJLEtBQUssVUFBVSxpQkFBaUIsQ0FBQyxJQUFZO0lBQ2hELE1BQU0sTUFBTSxHQUFHLGlCQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUM5RSxPQUFPLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUM3QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxhQUFhLENBQUMsSUFBWTtJQUM1QyxNQUFNLFNBQVMsR0FBRyxNQUFNLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFBO0lBQy9DLElBQUksU0FBUyxDQUFDLElBQUksS0FBSyxXQUFXO1FBQzlCLE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFBO0lBQ3BELE9BQU8sSUFBSSxXQUFRLENBQUMsU0FBUyxDQUFDLENBQUE7QUFDbEMsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSSxLQUFLLFVBQVUsVUFBVSxDQUFDLElBQVk7SUFDekMsTUFBTSxTQUFTLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMvQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssUUFBUTtRQUMzQixNQUFNLElBQUksb0JBQW9CLENBQUMsY0FBYyxDQUFDLENBQUE7SUFDbEQsT0FBTyxJQUFJLGdCQUFhLENBQUMsU0FBUyxDQUFDLENBQUE7QUFDdkMsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "iamcal",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Read and write ICalendar files",
|
|
5
|
-
"files": [
|
|
6
|
-
"/lib"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
"./
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "iamcal",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Read and write ICalendar files",
|
|
5
|
+
"files": [
|
|
6
|
+
"/lib",
|
|
7
|
+
"/src"
|
|
8
|
+
],
|
|
9
|
+
"exports": {
|
|
10
|
+
".": "./lib/index.js",
|
|
11
|
+
"./parse": "./lib/parse.js",
|
|
12
|
+
"./io": "./lib/io.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "rimraf lib && tsc",
|
|
16
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/olillin/iamcal.git"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ical",
|
|
24
|
+
"calendar"
|
|
25
|
+
],
|
|
26
|
+
"author": "Oli <oli@olillin.com>",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/olillin/iamcal/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/olillin/iamcal#readme",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^22.10.1",
|
|
34
|
+
"rimraf": "^6.0.1",
|
|
35
|
+
"typescript": "^5.7.2"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
export interface Property {
|
|
2
|
+
name: string
|
|
3
|
+
params: string[]
|
|
4
|
+
value: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Max line length as defined by RFC 5545 3.1.
|
|
8
|
+
const MAX_LINE_LENGTH = 75
|
|
9
|
+
|
|
10
|
+
export class Component {
|
|
11
|
+
name: string
|
|
12
|
+
properties: Array<Property>
|
|
13
|
+
components: Array<Component>
|
|
14
|
+
|
|
15
|
+
constructor(name: string, properties?: Array<Property>, components?: Array<Component>) {
|
|
16
|
+
this.name = name
|
|
17
|
+
if (properties) {
|
|
18
|
+
this.properties = properties
|
|
19
|
+
} else {
|
|
20
|
+
this.properties = new Array()
|
|
21
|
+
}
|
|
22
|
+
if (components) {
|
|
23
|
+
this.components = components
|
|
24
|
+
} else {
|
|
25
|
+
this.components = new Array()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
serialize(): string {
|
|
30
|
+
// Create lines
|
|
31
|
+
const lines = [`BEGIN:${this.name}`]
|
|
32
|
+
|
|
33
|
+
for (let property of this.properties) {
|
|
34
|
+
let line =
|
|
35
|
+
property['name'] + //
|
|
36
|
+
property.params.map(p => ';' + p).join('') +
|
|
37
|
+
':' +
|
|
38
|
+
property['value']
|
|
39
|
+
|
|
40
|
+
// Wrap lines
|
|
41
|
+
while (line.length > MAX_LINE_LENGTH) {
|
|
42
|
+
lines.push(line.substring(0, MAX_LINE_LENGTH))
|
|
43
|
+
line = " " + line.substring(MAX_LINE_LENGTH)
|
|
44
|
+
}
|
|
45
|
+
lines.push(line)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (let component of this.components) {
|
|
49
|
+
lines.push(component.serialize())
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
lines.push(`END:${this.name}`)
|
|
53
|
+
|
|
54
|
+
// Join lines
|
|
55
|
+
const serialized = lines.join('\n')
|
|
56
|
+
|
|
57
|
+
return serialized
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getProperty(name: string): Property | null {
|
|
61
|
+
for (const property of this.properties) {
|
|
62
|
+
if (property.name === name) {
|
|
63
|
+
return property
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setProperty(name: string, value: string) {
|
|
70
|
+
for (const property of this.properties) {
|
|
71
|
+
if (property.name === name) {
|
|
72
|
+
property.value = value
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
this.properties.push({
|
|
77
|
+
name: name,
|
|
78
|
+
params: [],
|
|
79
|
+
value: value,
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getPropertyParams(name: string): string[] | null {
|
|
84
|
+
for (const property of this.properties) {
|
|
85
|
+
if (property.name === name) {
|
|
86
|
+
return property.params
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return null
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setPropertyParams(name: string, params: string[]) {
|
|
93
|
+
for (const property of this.properties) {
|
|
94
|
+
if (property.name === name) {
|
|
95
|
+
property.params = params
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export class Calendar extends Component {
|
|
102
|
+
name = 'VCALENDAR'
|
|
103
|
+
|
|
104
|
+
constructor(component: Component) {
|
|
105
|
+
super(component.name, component.properties, component.components)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
events(): Array<CalendarEvent> {
|
|
109
|
+
const events = new Array<CalendarEvent>()
|
|
110
|
+
|
|
111
|
+
for (let component of this.components) {
|
|
112
|
+
if (component.name === 'VEVENT') {
|
|
113
|
+
events.push(new CalendarEvent(component))
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return events
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class CalendarEvent extends Component {
|
|
122
|
+
name = 'VEVENT'
|
|
123
|
+
|
|
124
|
+
constructor(component: Component) {
|
|
125
|
+
super(component.name, component.properties, component.components)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
summary(): string {
|
|
129
|
+
return this.getProperty('SUMMARY')!.value
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
setSummary(value: string) {
|
|
133
|
+
this.setProperty("SUMMARY", value)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
description(): string {
|
|
137
|
+
return this.getProperty('DESCRIPTION')!.value
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
setDescription(value: string) {
|
|
141
|
+
this.setProperty("DESCRIPTION", value)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
location(): string | undefined {
|
|
145
|
+
return this.getProperty('LOCATION')?.value
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
setLocation(value: string) {
|
|
149
|
+
this.setProperty("LOCATION", value)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
start(): Date {
|
|
153
|
+
return new Date(this.getProperty('DTSTART')!.value)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
setStart(value: Date) {
|
|
157
|
+
this.setProperty("DTSTART", value.toISOString())
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
end(): Date {
|
|
161
|
+
return new Date(this.getProperty('DTEND')!.value)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
setEnd(value: Date) {
|
|
165
|
+
this.setProperty("DTEND", value.toISOString())
|
|
166
|
+
}
|
|
167
|
+
}
|
package/src/io.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import readline from 'readline'
|
|
3
|
+
import { Calendar } from '.'
|
|
4
|
+
import { deserialize } from './parse'
|
|
5
|
+
import { resolve } from 'path'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Read a calendar from a .ical file
|
|
9
|
+
* @param path Path to the file to read
|
|
10
|
+
* @throws DeserializationError Component must be of valid format
|
|
11
|
+
* @throws TypeError Component must be a `VCALENDAR`
|
|
12
|
+
*/
|
|
13
|
+
export async function load(path: fs.PathLike): Promise<Calendar> {
|
|
14
|
+
const stream = fs.createReadStream(path)
|
|
15
|
+
const lines = readline.createInterface({ input: stream, crlfDelay: Infinity })
|
|
16
|
+
|
|
17
|
+
const component = await deserialize(lines)
|
|
18
|
+
|
|
19
|
+
if (component.name != 'VCALENDAR') {
|
|
20
|
+
throw TypeError('Component is not a calendar')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return new Calendar(component)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Write a calendar to a .ical file
|
|
28
|
+
* @param calendar The calendar
|
|
29
|
+
* @param path Path to the file to write
|
|
30
|
+
*/
|
|
31
|
+
export function dump(calendar: Calendar, path: string): Promise<void> {
|
|
32
|
+
return new Promise(resolve => {
|
|
33
|
+
fs.writeFile(path, calendar.serialize(), () => {
|
|
34
|
+
resolve()
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
}
|
package/src/parse.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import readline from 'readline'
|
|
2
|
+
import { Readable } from 'stream'
|
|
3
|
+
import { Calendar, CalendarEvent, Component } from '.'
|
|
4
|
+
|
|
5
|
+
export class DeserializationError extends Error {
|
|
6
|
+
name = 'DeserializationError'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Deserialize a calendar component
|
|
11
|
+
* @param lines the serialized component as a readline interface
|
|
12
|
+
*/
|
|
13
|
+
export async function deserialize(lines: readline.Interface): Promise<Component> {
|
|
14
|
+
const component = new Component('')
|
|
15
|
+
let done = false
|
|
16
|
+
|
|
17
|
+
// We use a stack to keep track of nested components
|
|
18
|
+
const stack = new Array<string>()
|
|
19
|
+
|
|
20
|
+
const subcomponentLines = new Array<string>()
|
|
21
|
+
|
|
22
|
+
async function processLine(line: string) {
|
|
23
|
+
if (line.trim() === '') return
|
|
24
|
+
|
|
25
|
+
if (done) {
|
|
26
|
+
throw new DeserializationError('Trailing data after component end')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (line.startsWith('BEGIN:')) {
|
|
30
|
+
// Begin component
|
|
31
|
+
const name = line.slice(line.indexOf(':') + 1)
|
|
32
|
+
stack.push(name)
|
|
33
|
+
|
|
34
|
+
if (stack.length == 1) {
|
|
35
|
+
component.name = name
|
|
36
|
+
} else {
|
|
37
|
+
subcomponentLines.push(line)
|
|
38
|
+
}
|
|
39
|
+
} else if (line.startsWith('END:')) {
|
|
40
|
+
// End component
|
|
41
|
+
if (stack.length == 0) {
|
|
42
|
+
throw new DeserializationError('Component end before begin')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const stackName = stack.pop()
|
|
46
|
+
const name = line.slice(line.indexOf(':') + 1)
|
|
47
|
+
if (stackName !== name) {
|
|
48
|
+
throw new DeserializationError('Malformed subcomponent')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Check the length of the stack after being popped
|
|
52
|
+
if (stack.length == 1) {
|
|
53
|
+
subcomponentLines.push(line)
|
|
54
|
+
const subcomponent = await deserializeString(subcomponentLines.join('\r\n'))
|
|
55
|
+
subcomponentLines.length = 0
|
|
56
|
+
|
|
57
|
+
component.components.push(subcomponent)
|
|
58
|
+
} else if (stack.length > 1) {
|
|
59
|
+
subcomponentLines.push(line)
|
|
60
|
+
} else if (stack.length == 0) {
|
|
61
|
+
done = true
|
|
62
|
+
}
|
|
63
|
+
} else {
|
|
64
|
+
if (stack.length == 0) throw new DeserializationError('Property outside of components')
|
|
65
|
+
|
|
66
|
+
if (stack.length > 1) {
|
|
67
|
+
// Line of subcomponent
|
|
68
|
+
subcomponentLines.push(line)
|
|
69
|
+
} else {
|
|
70
|
+
// Property
|
|
71
|
+
const colon = line.indexOf(':')
|
|
72
|
+
if (colon === -1) {
|
|
73
|
+
throw new DeserializationError(`Invalid content line: ${line}`)
|
|
74
|
+
}
|
|
75
|
+
const name = line.slice(0, colon)
|
|
76
|
+
const value = line.slice(colon + 1)
|
|
77
|
+
|
|
78
|
+
const params = name.split(';')
|
|
79
|
+
const property = {
|
|
80
|
+
name: params[0],
|
|
81
|
+
params: params.slice(1),
|
|
82
|
+
value: value,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
component.properties.push(property)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/*
|
|
91
|
+
The following code unfolds lines and passes them to be processed above.
|
|
92
|
+
|
|
93
|
+
According to RFC 5545 content lines may be split using a line "folding"
|
|
94
|
+
technique. That is, a long line can be split between any two characters by
|
|
95
|
+
inserting a newline immediately followed by a white-space character.
|
|
96
|
+
|
|
97
|
+
For example, the line:
|
|
98
|
+
|
|
99
|
+
DESCRIPTION:This is a long description that exists on a long line.
|
|
100
|
+
|
|
101
|
+
Can be represented as:
|
|
102
|
+
|
|
103
|
+
DESCRIPTION:This is a lo
|
|
104
|
+
ng description
|
|
105
|
+
that exists on a long line.
|
|
106
|
+
*/
|
|
107
|
+
let unfoldedLine = ''
|
|
108
|
+
for await (const line of lines) {
|
|
109
|
+
if (line.startsWith(' ') || line.startsWith('\t')) {
|
|
110
|
+
// Unfold continuation line (remove leading whitespace and append)
|
|
111
|
+
unfoldedLine += line.replace(/[\r\n]/, '').slice(1)
|
|
112
|
+
} else {
|
|
113
|
+
if (unfoldedLine) {
|
|
114
|
+
// Process the previous unfolded line
|
|
115
|
+
await processLine(unfoldedLine)
|
|
116
|
+
}
|
|
117
|
+
// Start a new unfolded line
|
|
118
|
+
unfoldedLine = line
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Process the last unfolded line
|
|
123
|
+
await processLine(unfoldedLine)
|
|
124
|
+
|
|
125
|
+
// Check that component has been closed
|
|
126
|
+
if (!done) {
|
|
127
|
+
throw new DeserializationError('No component end')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return component
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Deserialize a calendar component
|
|
135
|
+
* @param text the serialized component
|
|
136
|
+
*/
|
|
137
|
+
export async function deserializeString(text: string): Promise<Component> {
|
|
138
|
+
const stream = Readable.from(text)
|
|
139
|
+
const lines = readline.createInterface({ input: stream, crlfDelay: Infinity })
|
|
140
|
+
return deserialize(lines)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Parse a calendar in ICalendar format
|
|
145
|
+
* @param text the serialized calendar
|
|
146
|
+
* @returns the parsed calendar
|
|
147
|
+
*/
|
|
148
|
+
export async function parseCalendar(text: string): Promise<Calendar> {
|
|
149
|
+
const component = await deserializeString(text)
|
|
150
|
+
if (component.name !== "VCALENDAR")
|
|
151
|
+
throw new DeserializationError("Not a calendar")
|
|
152
|
+
return new Calendar(component)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Parse an event in ICalendar format
|
|
157
|
+
* @param text the serialized event
|
|
158
|
+
* @returns the parsed event
|
|
159
|
+
*/
|
|
160
|
+
export async function parseEvent(text: string): Promise<CalendarEvent> {
|
|
161
|
+
const component = await deserializeString(text)
|
|
162
|
+
if (component.name !== "VEVENT")
|
|
163
|
+
throw new DeserializationError("Not an event")
|
|
164
|
+
return new CalendarEvent(component)
|
|
165
|
+
}
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/lib/io.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../parse.ts"],"names":[],"mappings":"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"}
|