iamcal 1.0.0 → 1.0.1
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/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -136
- package/lib/index.js.map +1 -1
- package/lib/io.d.ts +1 -1
- package/lib/io.d.ts.map +1 -1
- package/lib/io.js +4 -36
- package/lib/io.js.map +1 -1
- package/lib/parse.d.ts.map +1 -1
- package/lib/parse.js +45 -193
- package/lib/parse.js.map +1 -1
- package/package.json +41 -38
- package/src/index.ts +167 -0
- package/src/io.ts +37 -0
- package/src/parse.ts +165 -0
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/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
|
@@ -1,137 +1,8 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CalendarEvent = exports.Calendar = exports.Component = void 0;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CalendarEvent=exports.Calendar=exports.Component=void 0;
|
|
4
2
|
// Max line length as defined by RFC 5545 3.1.
|
|
5
|
-
const MAX_LINE_LENGTH =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
3
|
+
const MAX_LINE_LENGTH=75;class Component{name;properties;components;constructor(e,t,r){this.name=e,this.properties=t||new Array,this.components=r||new Array}serialize(){
|
|
4
|
+
// Create lines
|
|
5
|
+
const e=[`BEGIN:${this.name}`];for(let t of this.properties){let r=t.name+t.params.map((e=>";"+e)).join("")+":"+t.value;
|
|
6
|
+
// Wrap lines
|
|
7
|
+
for(;r.length>75;)e.push(r.substring(0,75)),r=" "+r.substring(75);e.push(r)}for(let t of this.components)e.push(t.serialize());e.push(`END:${this.name}`);return e.join("\n")}getProperty(e){for(const t of this.properties)if(t.name===e)return t;return null}setProperty(e,t){for(const r of this.properties)if(r.name===e)return void(r.value=t);this.properties.push({name:e,params:[],value:t})}getPropertyParams(e){for(const t of this.properties)if(t.name===e)return t.params;return null}setPropertyParams(e,t){for(const r of this.properties)r.name===e&&(r.params=t)}}exports.Component=Component;class Calendar extends Component{name="VCALENDAR";constructor(e){super(e.name,e.properties,e.components)}events(){const e=new Array;for(let t of this.components)"VEVENT"===t.name&&e.push(new CalendarEvent(t));return e}}exports.Calendar=Calendar;class CalendarEvent extends Component{name="VEVENT";constructor(e){super(e.name,e.properties,e.components)}summary(){return this.getProperty("SUMMARY").value}setSummary(e){this.setProperty("SUMMARY",e)}description(){return this.getProperty("DESCRIPTION").value}setDescription(e){this.setProperty("DESCRIPTION",e)}location(){return this.getProperty("LOCATION")?.value}setLocation(e){this.setProperty("LOCATION",e)}start(){return new Date(this.getProperty("DTSTART").value)}setStart(e){this.setProperty("DTSTART",e.toISOString())}end(){return new Date(this.getProperty("DTEND").value)}setEnd(e){this.setProperty("DTEND",e.toISOString())}}exports.CalendarEvent=CalendarEvent;
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEsOENBQThDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQTtBQUUxQixNQUFhLFNBQVM7SUFDbEIsSUFBSSxDQUFRO0lBQ1osVUFBVSxDQUFpQjtJQUMzQixVQUFVLENBQWtCO0lBRTVCLFlBQVksSUFBWSxFQUFFLFVBQTRCLEVBQUUsVUFBNkI7UUFDakYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7UUFDaEIsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQ2hDLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFBO1FBQ2pDLENBQUM7UUFDRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUE7UUFDaEMsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUE7UUFDakMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTO1FBQ0wsZUFBZTtRQUNmLE1BQU0sS0FBSyxHQUFHLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUVwQyxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxJQUFJLElBQUksR0FDSixRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDckIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsR0FBRztnQkFDSCxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7WUFF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
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"names":["MAX_LINE_LENGTH","Component","name","properties","components","constructor","this","Array","serialize","lines","property","line","params","map","p","join","length","push","substring","component","getProperty","setProperty","value","getPropertyParams","setPropertyParams","exports","Calendar","super","events","CalendarEvent","summary","setSummary","description","setDescription","location","setLocation","start","Date","setStart","toISOString","end","setEnd"],"sources":["../src/index.ts"],"mappings":";;AAOA,MAAMA,gBAAkB,GAExB,MAAaC,UACTC,KACAC,WACAC,WAEAC,YAAYH,EAAcC,EAA8BC,GACpDE,KAAKJ,KAAOA,EAERI,KAAKH,WADLA,GAGkB,IAAII,MAGtBD,KAAKF,WADLA,GAGkB,IAAIG,KAE9B,CAEAC;;AAEI,MAAMC,EAAQ,CAAC,SAASH,KAAKJ,QAE7B,IAAK,IAAIQ,KAAYJ,KAAKH,WAAY,CAClC,IAAIQ,EACAD,EAAe,KACfA,EAASE,OAAOC,KAAIC,GAAK,IAAMA,IAAGC,KAAK,IACvC,IACAL,EAAgB;aAGpB;KAAOC,EAAKK,OAjCA,IAkCRP,EAAMQ,KAAKN,EAAKO,UAAU,EAlClB,KAmCRP,EAAO,IAAMA,EAAKO,UAnCV,IAqCZT,EAAMQ,KAAKN,EACf,CAEA,IAAK,IAAIQ,KAAab,KAAKF,WACvBK,EAAMQ,KAAKE,EAAUX,aAGzBC,EAAMQ,KAAK,OAAOX,KAAKJ,QAKvB,OAFmBO,EAAMM,KAAK,KAGlC,CAEAK,YAAYlB,GACR,IAAK,MAAMQ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAClB,OAAOQ,EAGf,OAAO,IACX,CAEAW,YAAYnB,EAAcoB,GACtB,IAAK,MAAMZ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAElB,YADAQ,EAASY,MAAQA,GAIzBhB,KAAKH,WAAWc,KAAK,CACjBf,KAAMA,EACNU,OAAQ,GACRU,MAAOA,GAEf,CAEAC,kBAAkBrB,GACd,IAAK,MAAMQ,KAAYJ,KAAKH,WACxB,GAAIO,EAASR,OAASA,EAClB,OAAOQ,EAASE,OAGxB,OAAO,IACX,CAEAY,kBAAkBtB,EAAcU,GAC5B,IAAK,MAAMF,KAAYJ,KAAKH,WACpBO,EAASR,OAASA,IAClBQ,EAASE,OAASA,EAG9B,EAxFJa,QAAAxB,oBA2FA,MAAayB,iBAAiBzB,UAC1BC,KAAO,YAEPG,YAAYc,GACRQ,MAAMR,EAAUjB,KAAMiB,EAAUhB,WAAYgB,EAAUf,WAC1D,CAEAwB,SACI,MAAMA,EAAS,IAAIrB,MAEnB,IAAK,IAAIY,KAAab,KAAKF,WACA,WAAnBe,EAAUjB,MACV0B,EAAOX,KAAK,IAAIY,cAAcV,IAItC,OAAOS,CACX,EAjBJH,QAAAC,kBAoBA,MAAaG,sBAAsB5B,UAC/BC,KAAO,SAEPG,YAAYc,GACRQ,MAAMR,EAAUjB,KAAMiB,EAAUhB,WAAYgB,EAAUf,WAC1D,CAEA0B,UACI,OAAOxB,KAAKc,YAAY,WAAYE,KACxC,CAEAS,WAAWT,GACPhB,KAAKe,YAAY,UAAWC,EAChC,CAEAU,cACI,OAAO1B,KAAKc,YAAY,eAAgBE,KAC5C,CAEAW,eAAeX,GACXhB,KAAKe,YAAY,cAAeC,EACpC,CAEAY,WACI,OAAO5B,KAAKc,YAAY,aAAaE,KACzC,CAEAa,YAAYb,GACRhB,KAAKe,YAAY,WAAYC,EACjC,CAEAc,QACI,OAAO,IAAIC,KAAK/B,KAAKc,YAAY,WAAYE,MACjD,CAEAgB,SAAShB,GACLhB,KAAKe,YAAY,UAAWC,EAAMiB,cACtC,CAEAC,MACI,OAAO,IAAIH,KAAK/B,KAAKc,YAAY,SAAUE,MAC/C,CAEAmB,OAAOnB,GACHhB,KAAKe,YAAY,QAASC,EAAMiB,cACpC,EA7CJd,QAAAI","ignoreList":[]}
|
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,46 +1,14 @@
|
|
|
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");
|
|
1
|
+
"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.load=load,exports.dump=dump;const fs_1=__importDefault(require("fs")),readline_1=__importDefault(require("readline")),_1=require("."),parse_1=require("./parse");
|
|
21
2
|
/**
|
|
22
3
|
* Read a calendar from a .ical file
|
|
23
4
|
* @param path Path to the file to read
|
|
24
5
|
* @throws DeserializationError Component must be of valid format
|
|
25
6
|
* @throws TypeError Component must be a `VCALENDAR`
|
|
26
7
|
*/
|
|
27
|
-
function load(
|
|
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
|
-
}
|
|
8
|
+
async function load(e){const r=fs_1.default.createReadStream(e),t=readline_1.default.createInterface({input:r,crlfDelay:1/0}),a=await(0,parse_1.deserialize)(t);if("VCALENDAR"!=a.name)throw TypeError("Component is not a calendar");return new _1.Calendar(a)}
|
|
38
9
|
/**
|
|
39
10
|
* Write a calendar to a .ical file
|
|
40
11
|
* @param calendar The calendar
|
|
41
12
|
* @param path Path to the file to write
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
fs_1.default.writeFileSync(path, calendar.serialize());
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=io.js.map
|
|
13
|
+
*/function dump(e,r){return new Promise((t=>{fs_1.default.writeFile(r,e.serialize(),(()=>{t()}))}))}
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFZQSxvQkFXQztBQU9ELG9CQU1DO0FBcENELDRDQUFtQjtBQUNuQix3REFBK0I7QUFDL0Isd0JBQTRCO0FBQzVCLG1DQUFxQztBQUdyQzs7Ozs7R0FLRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBaUI7SUFDeEMsTUFBTSxNQUFNLEdBQUcsWUFBRSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3hDLE1BQU0sS0FBSyxHQUFHLGtCQUFRLENBQUMsZUFBZSxDQUFDLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUU5RSxNQUFNLFNBQVMsR0FBRyxNQUFNLElBQUEsbUJBQVcsRUFBQyxLQUFLLENBQUMsQ0FBQTtJQUUxQyxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEMsTUFBTSxTQUFTLENBQUMsNkJBQTZCLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQsT0FBTyxJQUFJLFdBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNsQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLElBQUksQ0FBQyxRQUFrQixFQUFFLElBQVk7SUFDakQsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUN6QixZQUFFLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQzFDLE9BQU8sRUFBRSxDQUFBO1FBQ2IsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMifQ==
|
package/lib/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"names":["exports","load","dump","fs_1","__importDefault","require","readline_1","_1","parse_1","async","path","stream","default","createReadStream","lines","createInterface","input","crlfDelay","Infinity","component","deserialize","name","TypeError","Calendar","calendar","Promise","resolve","writeFile","serialize"],"sources":["../src/io.ts"],"mappings":"sKAYAA,QAAAC,UAkBAD,QAAAE,UA9BA,MAAAC,KAAAC,gBAAAC,QAAA,OACAC,WAAAF,gBAAAC,QAAA,aACAE,GAAAF,QAAA,KACAG,QAAAH,QAAA;;;;;;;AASOI,eAAeR,KAAKS,GACvB,MAAMC,EAASR,KAAAS,QAAGC,iBAAiBH,GAC7BI,EAAQR,WAAAM,QAASG,gBAAgB,CAAEC,MAAOL,EAAQM,UAAWC,MAE7DC,QAAkB,EAAAX,QAAAY,aAAYN,GAEpC,GAAsB,aAAlBK,EAAUE,KACV,MAAMC,UAAU,+BAGpB,OAAO,IAAIf,GAAAgB,SAASJ,EACxB;;;;;GAOA,SAAgBjB,KAAKsB,EAAoBd,GACrC,OAAO,IAAIe,SAAQC,IACfvB,KAAAS,QAAGe,UAAUjB,EAAMc,EAASI,aAAa,KACrCF,GAAS,GACX,GAEV","ignoreList":[]}
|
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,208 +1,60 @@
|
|
|
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;
|
|
1
|
+
"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.DeserializationError=void 0,exports.deserialize=deserialize,exports.deserializeString=deserializeString,exports.parseCalendar=parseCalendar,exports.parseEvent=parseEvent;const readline_1=__importDefault(require("readline")),stream_1=require("stream"),_1=require(".");class DeserializationError extends Error{name="DeserializationError"}
|
|
37
2
|
/**
|
|
38
3
|
* Deserialize a calendar component
|
|
39
4
|
* @param lines the serialized component as a readline interface
|
|
40
5
|
*/
|
|
41
|
-
function deserialize(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
}
|
|
6
|
+
async function deserialize(e){const r=new _1.Component("");let t=!1;
|
|
7
|
+
// We use a stack to keep track of nested components
|
|
8
|
+
const i=new Array,n=new Array;async function a(e){if(""!==e.trim()){if(t)throw new DeserializationError("Trailing data after component end");if(e.startsWith("BEGIN:")){
|
|
9
|
+
// Begin component
|
|
10
|
+
const t=e.slice(e.indexOf(":")+1);i.push(t),1==i.length?r.name=t:n.push(e)}else if(e.startsWith("END:")){
|
|
11
|
+
// End component
|
|
12
|
+
if(0==i.length)throw new DeserializationError("Component end before begin");if(i.pop()!==e.slice(e.indexOf(":")+1))throw new DeserializationError("Malformed subcomponent");
|
|
13
|
+
// Check the length of the stack after being popped
|
|
14
|
+
if(1==i.length){n.push(e);const t=await deserializeString(n.join("\r\n"));n.length=0,r.components.push(t)}else i.length>1?n.push(e):0==i.length&&(t=!0)}else{if(0==i.length)throw new DeserializationError("Property outside of components");if(i.length>1)
|
|
15
|
+
// Line of subcomponent
|
|
16
|
+
n.push(e);else{
|
|
17
|
+
// Property
|
|
18
|
+
const t=e.indexOf(":");if(-1===t)throw new DeserializationError(`Invalid content line: ${e}`);const i=e.slice(0,t),n=e.slice(t+1),a=i.split(";"),s={name:a[0],params:a.slice(1),value:n};r.properties.push(s)}}}}
|
|
19
|
+
/*
|
|
20
|
+
The following code unfolds lines and passes them to be processed above.
|
|
21
|
+
|
|
22
|
+
According to RFC 5545 content lines may be split using a line "folding"
|
|
23
|
+
technique. That is, a long line can be split between any two characters by
|
|
24
|
+
inserting a newline immediately followed by a white-space character.
|
|
25
|
+
|
|
26
|
+
For example, the line:
|
|
27
|
+
|
|
28
|
+
DESCRIPTION:This is a long description that exists on a long line.
|
|
29
|
+
|
|
30
|
+
Can be represented as:
|
|
31
|
+
|
|
32
|
+
DESCRIPTION:This is a lo
|
|
33
|
+
ng description
|
|
34
|
+
that exists on a long line.
|
|
35
|
+
*/let s="";for await(const r of e)r.startsWith(" ")||r.startsWith("\t")?
|
|
36
|
+
// Unfold continuation line (remove leading whitespace and append)
|
|
37
|
+
s+=r.replace(/[\r\n]/,"").slice(1):(s&&
|
|
38
|
+
// Process the previous unfolded line
|
|
39
|
+
await a(s),
|
|
40
|
+
// Start a new unfolded line
|
|
41
|
+
s=r);
|
|
42
|
+
// Process the last unfolded line
|
|
43
|
+
// Check that component has been closed
|
|
44
|
+
if(await a(s),!t)throw new DeserializationError("No component end");return r}
|
|
171
45
|
/**
|
|
172
46
|
* Deserialize a calendar component
|
|
173
47
|
* @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
|
-
}
|
|
48
|
+
*/async function deserializeString(e){const r=stream_1.Readable.from(e);return deserialize(readline_1.default.createInterface({input:r,crlfDelay:1/0}))}
|
|
182
49
|
/**
|
|
183
50
|
* Parse a calendar in ICalendar format
|
|
184
51
|
* @param text the serialized calendar
|
|
185
52
|
* @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
|
-
}
|
|
53
|
+
*/async function parseCalendar(e){const r=await deserializeString(e);if("VCALENDAR"!==r.name)throw new DeserializationError("Not a calendar");return new _1.Calendar(r)}
|
|
195
54
|
/**
|
|
196
55
|
* Parse an event in ICalendar format
|
|
197
56
|
* @param text the serialized event
|
|
198
57
|
* @returns the parsed event
|
|
199
|
-
*/
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
58
|
+
*/async function parseEvent(e){const r=await deserializeString(e);if("VEVENT"!==r.name)throw new DeserializationError("Not an event");return new _1.CalendarEvent(r)}
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcGFyc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBWUEsa0NBc0hDO0FBTUQsOENBSUM7QUFPRCxzQ0FLQztBQU9ELGdDQUtDO0FBcEtELHdEQUErQjtBQUMvQixtQ0FBaUM7QUFDakMsd0JBQXNEO0FBRXRELE1BQWEsb0JBQXFCLFNBQVEsS0FBSztJQUMzQyxJQUFJLEdBQUcsc0JBQXNCLENBQUE7Q0FDaEM7QUFGRCxvREFFQztBQUVEOzs7R0FHRztBQUNJLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBeUI7SUFDdkQsTUFBTSxTQUFTLEdBQUcsSUFBSSxZQUFTLENBQUMsRUFBRSxDQUFDLENBQUE7SUFDbkMsSUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFBO0lBRWhCLG9EQUFvRDtJQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFBO0lBRWpDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQTtJQUU3QyxLQUFLLFVBQVUsV0FBVyxDQUFDLElBQVk7UUFDbkMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtZQUFFLE9BQU07UUFFOUIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNQLE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFBO1FBQ3ZFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUM1QixrQkFBa0I7WUFDbEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQzlDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7WUFFaEIsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNwQixTQUFT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
|
|
60
|
+
exports.DeserializationError=DeserializationError;
|
package/lib/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"names":["exports","deserialize","deserializeString","parseCalendar","parseEvent","readline_1","__importDefault","require","stream_1","_1","DeserializationError","Error","name","async","lines","component","Component","done","stack","Array","subcomponentLines","processLine","line","trim","startsWith","slice","indexOf","push","length","pop","subcomponent","join","components","colon","value","params","split","property","properties","unfoldedLine","replace","text","stream","Readable","from","default","createInterface","input","crlfDelay","Infinity","Calendar","CalendarEvent"],"sources":["../src/parse.ts"],"mappings":"0MAYAA,QAAAC,wBA4HAD,QAAAE,oCAWAF,QAAAG,4BAYAH,QAAAI,sBA/JA,MAAAC,WAAAC,gBAAAC,QAAA,aACAC,SAAAD,QAAA,UACAE,GAAAF,QAAA,KAEA,MAAaG,6BAA6BC,MACtCC,KAAO;;;;;AAOJC,eAAeZ,YAAYa,GAC9B,MAAMC,EAAY,IAAIN,GAAAO,UAAU,IAChC,IAAIC,GAAO;oDAGX;MAAMC,EAAQ,IAAIC,MAEZC,EAAoB,IAAID,MAE9BN,eAAeQ,EAAYC,GACvB,GAAoB,KAAhBA,EAAKC,OAAT,CAEA,GAAIN,EACA,MAAM,IAAIP,qBAAqB,qCAGnC,GAAIY,EAAKE,WAAW,UAAW;;AAE3B,MAAMZ,EAAOU,EAAKG,MAAMH,EAAKI,QAAQ,KAAO,GAC5CR,EAAMS,KAAKf,GAES,GAAhBM,EAAMU,OACNb,EAAUH,KAAOA,EAEjBQ,EAAkBO,KAAKL,EAE/B,MAAO,GAAIA,EAAKE,WAAW,QAAS;;AAEhC,GAAoB,GAAhBN,EAAMU,OACN,MAAM,IAAIlB,qBAAqB,8BAKnC,GAFkBQ,EAAMW,QACXP,EAAKG,MAAMH,EAAKI,QAAQ,KAAO,GAExC,MAAM,IAAIhB,qBAAqB;mDAInC;GAAoB,GAAhBQ,EAAMU,OAAa,CACnBR,EAAkBO,KAAKL,GACvB,MAAMQ,QAAqB5B,kBAAkBkB,EAAkBW,KAAK,SACpEX,EAAkBQ,OAAS,EAE3Bb,EAAUiB,WAAWL,KAAKG,EAC9B,MAAWZ,EAAMU,OAAS,EACtBR,EAAkBO,KAAKL,GACA,GAAhBJ,EAAMU,SACbX,GAAO,EAEf,KAAO,CACH,GAAoB,GAAhBC,EAAMU,OAAa,MAAM,IAAIlB,qBAAqB,kCAEtD,GAAIQ,EAAMU,OAAS;;AAEfR,EAAkBO,KAAKL,OACpB;;AAEH,MAAMW,EAAQX,EAAKI,QAAQ,KAC3B,IAAe,IAAXO,EACA,MAAM,IAAIvB,qBAAqB,yBAAyBY,KAE5D,MAAMV,EAAOU,EAAKG,MAAM,EAAGQ,GACrBC,EAAQZ,EAAKG,MAAMQ,EAAQ,GAE3BE,EAASvB,EAAKwB,MAAM,KACpBC,EAAW,CACbzB,KAAMuB,EAAO,GACbA,OAAQA,EAAOV,MAAM,GACrBS,MAAOA,GAGXnB,EAAUuB,WAAWX,KAAKU,EAC9B,CACJ,CAhEwB,CAiE5B;;;;;;;;;;;;;;;;;MAmBA,IAAIE,EAAe,GACnB,UAAW,MAAMjB,KAAQR,EACjBQ,EAAKE,WAAW,MAAQF,EAAKE,WAAW;;AAExCe,GAAgBjB,EAAKkB,QAAQ,SAAU,IAAIf,MAAM,IAE7Cc;;MAEMlB,EAAYkB;;AAGtBA,EAAejB;;;AAQvB,SAHMD,EAAYkB,IAGbtB,EACD,MAAM,IAAIP,qBAAqB,oBAGnC,OAAOK,CACX;;;;GAMOF,eAAeX,kBAAkBuC,GACpC,MAAMC,EAASlC,SAAAmC,SAASC,KAAKH,GAE7B,OAAOxC,YADOI,WAAAwC,QAASC,gBAAgB,CAAEC,MAAOL,EAAQM,UAAWC,MAEvE;;;;;GAOOpC,eAAeV,cAAcsC,GAChC,MAAM1B,QAAkBb,kBAAkBuC,GAC1C,GAAuB,cAAnB1B,EAAUH,KACV,MAAM,IAAIF,qBAAqB,kBACnC,OAAO,IAAID,GAAAyC,SAASnC,EACxB;;;;;GAOOF,eAAeT,WAAWqC,GAC7B,MAAM1B,QAAkBb,kBAAkBuC,GAC1C,GAAuB,WAAnB1B,EAAUH,KACV,MAAM,IAAIF,qBAAqB,gBACnC,OAAO,IAAID,GAAA0C,cAAcpC,EAC7B;0yKAhKAf;QAAAU","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,38 +1,41 @@
|
|
|
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.1",
|
|
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 && npm run minify",
|
|
16
|
+
"minify": "uglifyjs-folder lib -eo lib -x .js --config-file './uglify.json'",
|
|
17
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/olillin/iamcal.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"ical",
|
|
25
|
+
"calendar"
|
|
26
|
+
],
|
|
27
|
+
"author": "Oli <oli@olillin.com>",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/olillin/iamcal/issues"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/olillin/iamcal#readme",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"typescript": "^5.7.2"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^22.10.1",
|
|
38
|
+
"rimraf": "^6.0.1",
|
|
39
|
+
"uglifyjs-folder": "^3.3.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
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
|
+
}
|