iamcal 1.0.2 → 1.0.3
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/README.md +7 -3
- package/lib/index.d.ts +110 -9
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +295 -15
- package/lib/types.d.ts +6 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/package.json +15 -4
- package/src/index.ts +383 -23
- package/src/types.ts +5 -0
package/README.md
CHANGED
|
@@ -10,9 +10,11 @@ A library for reading, modifying and writing [ICalendar](https://en.wikipedia.or
|
|
|
10
10
|
npm install iamcal
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## Getting started
|
|
13
|
+
## Getting started
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
### Parsing and editing a calendar
|
|
16
|
+
|
|
17
|
+
This code:
|
|
16
18
|
|
|
17
19
|
```typescript
|
|
18
20
|
import { Calendar } from 'iamcal'
|
|
@@ -58,4 +60,6 @@ DTSTART:20241211T200000Z
|
|
|
58
60
|
DTEND:20241211T230000Z
|
|
59
61
|
END:VEVENT
|
|
60
62
|
END:VCALENDAR
|
|
61
|
-
```
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Creating a new calendar
|
package/lib/index.d.ts
CHANGED
|
@@ -1,36 +1,137 @@
|
|
|
1
|
-
|
|
2
|
-
name: string;
|
|
3
|
-
params: string[];
|
|
4
|
-
value: string;
|
|
5
|
-
}
|
|
1
|
+
import { Property } from './types';
|
|
6
2
|
export declare class Component {
|
|
7
3
|
name: string;
|
|
8
|
-
properties:
|
|
9
|
-
components:
|
|
10
|
-
constructor(name: string, properties?:
|
|
4
|
+
properties: Property[];
|
|
5
|
+
components: Component[];
|
|
6
|
+
constructor(name: string, properties?: Property[], components?: Component[]);
|
|
11
7
|
serialize(): string;
|
|
12
8
|
getProperty(name: string): Property | null;
|
|
13
9
|
setProperty(name: string, value: string): void;
|
|
10
|
+
removePropertiesWithName(name: string): void;
|
|
14
11
|
getPropertyParams(name: string): string[] | null;
|
|
15
12
|
setPropertyParams(name: string, params: string[]): void;
|
|
13
|
+
addComponent(component: Component): void;
|
|
14
|
+
removeComponent(component: Component): boolean;
|
|
15
|
+
getComponents(name: string): Component[];
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Represents a VCALENDAR component, the root component of an iCalendar file.
|
|
19
|
+
*/
|
|
17
20
|
export declare class Calendar extends Component {
|
|
18
21
|
name: string;
|
|
22
|
+
/**
|
|
23
|
+
* @param prodid A unique identifier of the program creating the calendar.
|
|
24
|
+
*
|
|
25
|
+
* Example: `-//Google Inc//Google Calendar 70.9054//EN`
|
|
26
|
+
*/
|
|
27
|
+
constructor(prodid: string);
|
|
28
|
+
/**
|
|
29
|
+
* @param prodid A unique identifier of the program creating the calendar.
|
|
30
|
+
*
|
|
31
|
+
* Example: `-//Google Inc//Google Calendar 70.9054//EN`
|
|
32
|
+
* @param version The version of the iCalendar specification that this calendar uses.
|
|
33
|
+
*/
|
|
34
|
+
constructor(prodid: string, version: string);
|
|
35
|
+
/**
|
|
36
|
+
* @param component A VCALENDAR component.
|
|
37
|
+
*/
|
|
38
|
+
constructor(component: Component);
|
|
39
|
+
events(): CalendarEvent[];
|
|
40
|
+
removeEvent(event: CalendarEvent): boolean;
|
|
41
|
+
removeEvent(uid: string): boolean;
|
|
42
|
+
prodId(): string;
|
|
43
|
+
setProdId(value: string): void;
|
|
44
|
+
version(): string;
|
|
45
|
+
setVersion(value: string): void;
|
|
46
|
+
calScale(): string | undefined;
|
|
47
|
+
setCalScale(value: string): void;
|
|
48
|
+
removeCalScale(): void;
|
|
49
|
+
method(): string | undefined;
|
|
50
|
+
setMethod(value: string): void;
|
|
51
|
+
removeMethod(): void;
|
|
52
|
+
calendarName(): string | undefined;
|
|
53
|
+
setCalendarName(value: string): void;
|
|
54
|
+
removeCalendarName(): void;
|
|
55
|
+
calendarDescription(): string | undefined;
|
|
56
|
+
setCalendarDescription(value: string): void;
|
|
57
|
+
removeCalendarDescription(): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Represents a VTIMEZONE component, containing time zone definitions.
|
|
61
|
+
*/
|
|
62
|
+
export declare class TimeZone extends Component {
|
|
63
|
+
constructor(id: string);
|
|
19
64
|
constructor(component: Component);
|
|
20
|
-
|
|
65
|
+
id(): string;
|
|
66
|
+
setId(value: string): void;
|
|
67
|
+
lastMod(): Date | undefined;
|
|
68
|
+
setLastMod(value: Date): void;
|
|
69
|
+
removeLastMod(): void;
|
|
70
|
+
url(): string | undefined;
|
|
71
|
+
setUrl(value: string): void;
|
|
72
|
+
removeUrl(): void;
|
|
73
|
+
/** Get all time offsets. */
|
|
74
|
+
offsets(): TimeZoneOffset[];
|
|
75
|
+
/** Get standard/winter time offsets. */
|
|
76
|
+
standardOffsets(): TimeZoneOffset[];
|
|
77
|
+
/** Get daylight savings time offsets. */
|
|
78
|
+
daylightOffsets(): TimeZoneOffset[];
|
|
79
|
+
}
|
|
80
|
+
export type OffsetType = 'DAYLIGHT' | 'STANDARD';
|
|
81
|
+
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
82
|
+
export type Offset = `${'-' | '+'}${Digit}${Digit}${Digit}${Digit}`;
|
|
83
|
+
/** Represents a STANDARD or DAYLIGHT component, defining a time zone offset. */
|
|
84
|
+
declare class TimeZoneOffset extends Component {
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @param type If this is a STANDARD or DAYLIGHT component.
|
|
88
|
+
* @param start From when this offset is active.
|
|
89
|
+
* @param offsetFrom The offset that is in use prior to this time zone observance.
|
|
90
|
+
* @param offsetTo The offset that is in use during this time zone observance.
|
|
91
|
+
*/
|
|
92
|
+
constructor(type: OffsetType, start: Date, offsetFrom: Offset, offsetTo: Offset);
|
|
93
|
+
constructor(component: Component);
|
|
94
|
+
start(): Date;
|
|
95
|
+
setStart(value: Date): void;
|
|
96
|
+
offsetFrom(): Offset;
|
|
97
|
+
setOffsetFrom(value: Offset): void;
|
|
98
|
+
offsetTo(): Offset;
|
|
99
|
+
setOffsetTo(value: Offset): void;
|
|
100
|
+
comment(): string | undefined;
|
|
101
|
+
setComment(value: string): void;
|
|
102
|
+
removeComment(): void;
|
|
103
|
+
timeZoneName(): string | undefined;
|
|
104
|
+
setTimeZoneName(value: string): void;
|
|
105
|
+
removeTimeZoneName(): void;
|
|
21
106
|
}
|
|
22
107
|
export declare class CalendarEvent extends Component {
|
|
23
108
|
name: string;
|
|
109
|
+
constructor(uid: string, dtstamp: Date);
|
|
24
110
|
constructor(component: Component);
|
|
111
|
+
stamp(): Date;
|
|
112
|
+
setStamp(value: Date): void;
|
|
113
|
+
uid(): string;
|
|
114
|
+
setUid(value: string): void;
|
|
25
115
|
summary(): string;
|
|
26
116
|
setSummary(value: string): void;
|
|
117
|
+
removeSummary(): void;
|
|
27
118
|
description(): string;
|
|
28
119
|
setDescription(value: string): void;
|
|
120
|
+
removeDescription(): void;
|
|
29
121
|
location(): string | undefined;
|
|
30
122
|
setLocation(value: string): void;
|
|
123
|
+
removeLocation(): void;
|
|
31
124
|
start(): Date;
|
|
32
125
|
setStart(value: Date): void;
|
|
126
|
+
removeStart(): void;
|
|
33
127
|
end(): Date;
|
|
34
128
|
setEnd(value: Date): void;
|
|
129
|
+
removeEnd(): void;
|
|
130
|
+
created(): Date | undefined;
|
|
131
|
+
setCreated(value: Date): void;
|
|
132
|
+
removeCreated(): void;
|
|
133
|
+
geo(): [number, number] | undefined;
|
|
134
|
+
setGeo(latitude: number, longitude: number): void;
|
|
35
135
|
}
|
|
136
|
+
export {};
|
|
36
137
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CalendarEvent = exports.Calendar = exports.Component = void 0;
|
|
3
|
+
exports.CalendarEvent = exports.TimeZone = 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 {
|
|
@@ -33,7 +33,7 @@ class Component {
|
|
|
33
33
|
// Wrap lines
|
|
34
34
|
while (line.length > MAX_LINE_LENGTH) {
|
|
35
35
|
lines.push(line.substring(0, MAX_LINE_LENGTH));
|
|
36
|
-
line =
|
|
36
|
+
line = ' ' + line.substring(MAX_LINE_LENGTH);
|
|
37
37
|
}
|
|
38
38
|
lines.push(line);
|
|
39
39
|
}
|
|
@@ -66,6 +66,13 @@ class Component {
|
|
|
66
66
|
value: value,
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
+
removePropertiesWithName(name) {
|
|
70
|
+
const index = this.properties.findIndex(p => p.name === name);
|
|
71
|
+
if (index === -1)
|
|
72
|
+
return;
|
|
73
|
+
// Remove property at index
|
|
74
|
+
this.properties.splice(index, 1);
|
|
75
|
+
}
|
|
69
76
|
getPropertyParams(name) {
|
|
70
77
|
for (const property of this.properties) {
|
|
71
78
|
if (property.name === name) {
|
|
@@ -81,59 +88,332 @@ class Component {
|
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
}
|
|
91
|
+
addComponent(component) {
|
|
92
|
+
this.components.push(component);
|
|
93
|
+
}
|
|
94
|
+
removeComponent(component) {
|
|
95
|
+
const index = this.components.indexOf(component);
|
|
96
|
+
if (index === -1)
|
|
97
|
+
return false;
|
|
98
|
+
// Remove element at index from list
|
|
99
|
+
this.components.splice(index, 1);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
getComponents(name) {
|
|
103
|
+
const components = [];
|
|
104
|
+
for (let component of this.components) {
|
|
105
|
+
if (component.name === name) {
|
|
106
|
+
components.push(component);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return components;
|
|
110
|
+
}
|
|
84
111
|
}
|
|
85
112
|
exports.Component = Component;
|
|
113
|
+
/**
|
|
114
|
+
* Represents a VCALENDAR component, the root component of an iCalendar file.
|
|
115
|
+
*/
|
|
86
116
|
class Calendar extends Component {
|
|
87
117
|
name = 'VCALENDAR';
|
|
88
|
-
constructor(
|
|
118
|
+
constructor(a, b) {
|
|
119
|
+
var component;
|
|
120
|
+
if (a instanceof Component) {
|
|
121
|
+
component = a;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
const prodid = a;
|
|
125
|
+
const version = b ?? '2.0';
|
|
126
|
+
component = new Component('VCALENDAR');
|
|
127
|
+
component.setProperty('PRODID', prodid);
|
|
128
|
+
component.setProperty('VERSION', version);
|
|
129
|
+
}
|
|
89
130
|
super(component.name, component.properties, component.components);
|
|
90
131
|
}
|
|
91
132
|
events() {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
133
|
+
return this.getComponents('VEVENT').map(c => new CalendarEvent(c));
|
|
134
|
+
}
|
|
135
|
+
removeEvent(a) {
|
|
136
|
+
if (a instanceof CalendarEvent) {
|
|
137
|
+
const event = a;
|
|
138
|
+
return this.removeComponent(event);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
const uid = a;
|
|
142
|
+
for (const event of this.events()) {
|
|
143
|
+
if (event.uid() !== uid)
|
|
144
|
+
continue;
|
|
145
|
+
return this.removeComponent(event);
|
|
96
146
|
}
|
|
97
147
|
}
|
|
98
|
-
return
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
prodId() {
|
|
151
|
+
return this.getProperty('PRODID').value;
|
|
152
|
+
}
|
|
153
|
+
setProdId(value) {
|
|
154
|
+
this.setProperty('PRODID', value);
|
|
155
|
+
}
|
|
156
|
+
version() {
|
|
157
|
+
return this.getProperty('VERSION').value;
|
|
158
|
+
}
|
|
159
|
+
setVersion(value) {
|
|
160
|
+
this.setProperty('VERSION', value);
|
|
161
|
+
}
|
|
162
|
+
calScale() {
|
|
163
|
+
return this.getProperty('CALSCALE')?.value;
|
|
164
|
+
}
|
|
165
|
+
setCalScale(value) {
|
|
166
|
+
this.setProperty('CALSCALE', value);
|
|
167
|
+
}
|
|
168
|
+
removeCalScale() {
|
|
169
|
+
this.removePropertiesWithName('CALSCALE');
|
|
170
|
+
}
|
|
171
|
+
method() {
|
|
172
|
+
return this.getProperty('METHOD')?.value;
|
|
173
|
+
}
|
|
174
|
+
setMethod(value) {
|
|
175
|
+
this.setProperty('METHOD', value);
|
|
176
|
+
}
|
|
177
|
+
removeMethod() {
|
|
178
|
+
this.removePropertiesWithName('METHOD');
|
|
179
|
+
}
|
|
180
|
+
calendarName() {
|
|
181
|
+
return this.getProperty('X-WR-CALNAME')?.value;
|
|
182
|
+
}
|
|
183
|
+
setCalendarName(value) {
|
|
184
|
+
this.setProperty('X-WR-CALNAME', value);
|
|
185
|
+
}
|
|
186
|
+
removeCalendarName() {
|
|
187
|
+
this.removePropertiesWithName('X-WR-CALNAME');
|
|
188
|
+
}
|
|
189
|
+
calendarDescription() {
|
|
190
|
+
return this.getProperty('X-WR-CALDESC')?.value;
|
|
191
|
+
}
|
|
192
|
+
setCalendarDescription(value) {
|
|
193
|
+
this.setProperty('X-WR-CALDESC', value);
|
|
194
|
+
}
|
|
195
|
+
removeCalendarDescription() {
|
|
196
|
+
this.removePropertiesWithName('X-WR-CALDESC');
|
|
99
197
|
}
|
|
100
198
|
}
|
|
101
199
|
exports.Calendar = Calendar;
|
|
200
|
+
/**
|
|
201
|
+
* Represents a VTIMEZONE component, containing time zone definitions.
|
|
202
|
+
*/
|
|
203
|
+
class TimeZone extends Component {
|
|
204
|
+
constructor(a) {
|
|
205
|
+
var component;
|
|
206
|
+
if (a instanceof Component) {
|
|
207
|
+
component = a;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
const tzid = a;
|
|
211
|
+
component = new Component('VTIMEZONE');
|
|
212
|
+
component.setProperty('TZID', tzid);
|
|
213
|
+
}
|
|
214
|
+
super(component.name, component.properties, component.components);
|
|
215
|
+
}
|
|
216
|
+
id() {
|
|
217
|
+
return this.getProperty('TZID').value;
|
|
218
|
+
}
|
|
219
|
+
setId(value) {
|
|
220
|
+
this.setProperty('TZID', value);
|
|
221
|
+
}
|
|
222
|
+
lastMod() {
|
|
223
|
+
const text = this.getProperty('LAST-MOD');
|
|
224
|
+
if (!text)
|
|
225
|
+
return;
|
|
226
|
+
return new Date(text.value);
|
|
227
|
+
}
|
|
228
|
+
setLastMod(value) {
|
|
229
|
+
this.setProperty('LAST-MOD', value.toISOString());
|
|
230
|
+
}
|
|
231
|
+
removeLastMod() {
|
|
232
|
+
this.removePropertiesWithName('LAST-MOD');
|
|
233
|
+
}
|
|
234
|
+
url() {
|
|
235
|
+
return this.getProperty('TZURL')?.value;
|
|
236
|
+
}
|
|
237
|
+
setUrl(value) {
|
|
238
|
+
this.setProperty('TZURL', value);
|
|
239
|
+
}
|
|
240
|
+
removeUrl() {
|
|
241
|
+
this.removePropertiesWithName('TZURL');
|
|
242
|
+
}
|
|
243
|
+
/** Get all time offsets. */
|
|
244
|
+
offsets() {
|
|
245
|
+
const offsets = [];
|
|
246
|
+
this.components.forEach(component => {
|
|
247
|
+
if (component.name === 'STANDARD' || component.name === 'DAYLIGHT') {
|
|
248
|
+
offsets.push(new TimeZoneOffset(component));
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
return offsets;
|
|
252
|
+
}
|
|
253
|
+
/** Get standard/winter time offsets. */
|
|
254
|
+
standardOffsets() {
|
|
255
|
+
return this.getComponents('STANDARD').map(c => new TimeZoneOffset(c));
|
|
256
|
+
}
|
|
257
|
+
/** Get daylight savings time offsets. */
|
|
258
|
+
daylightOffsets() {
|
|
259
|
+
return this.getComponents('DAYLIGHT').map(c => new TimeZoneOffset(c));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
exports.TimeZone = TimeZone;
|
|
263
|
+
/** Represents a STANDARD or DAYLIGHT component, defining a time zone offset. */
|
|
264
|
+
class TimeZoneOffset extends Component {
|
|
265
|
+
constructor(a, b, c, d) {
|
|
266
|
+
var component;
|
|
267
|
+
if (a instanceof Component) {
|
|
268
|
+
component = a;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
const name = a;
|
|
272
|
+
const start = b;
|
|
273
|
+
const offsetFrom = c;
|
|
274
|
+
const offsetTo = d;
|
|
275
|
+
component = new Component(name);
|
|
276
|
+
component.setProperty('DTSTART', start.toISOString());
|
|
277
|
+
component.setProperty('TZOFFSETFROM', offsetFrom);
|
|
278
|
+
component.setProperty('TZOFFSETTO', offsetTo);
|
|
279
|
+
}
|
|
280
|
+
super(component.name, component.properties, component.components);
|
|
281
|
+
}
|
|
282
|
+
start() {
|
|
283
|
+
return new Date(this.getProperty('DTSTART').value);
|
|
284
|
+
}
|
|
285
|
+
setStart(value) {
|
|
286
|
+
this.setProperty('DTSTART', value.toISOString());
|
|
287
|
+
}
|
|
288
|
+
offsetFrom() {
|
|
289
|
+
return this.getProperty('TZOFFSETFROM').value;
|
|
290
|
+
}
|
|
291
|
+
setOffsetFrom(value) {
|
|
292
|
+
this.setProperty('TZOFFSETFROM', value);
|
|
293
|
+
}
|
|
294
|
+
offsetTo() {
|
|
295
|
+
return this.getProperty('TZOFFSETTO').value;
|
|
296
|
+
}
|
|
297
|
+
setOffsetTo(value) {
|
|
298
|
+
this.setProperty('TZOFFSETTO', value);
|
|
299
|
+
}
|
|
300
|
+
comment() {
|
|
301
|
+
return this.getProperty('COMMENT')?.value;
|
|
302
|
+
}
|
|
303
|
+
setComment(value) {
|
|
304
|
+
this.setProperty('COMMENT', value);
|
|
305
|
+
}
|
|
306
|
+
removeComment() {
|
|
307
|
+
this.removePropertiesWithName('COMMENT');
|
|
308
|
+
}
|
|
309
|
+
timeZoneName() {
|
|
310
|
+
return this.getProperty('TZNAME')?.value;
|
|
311
|
+
}
|
|
312
|
+
setTimeZoneName(value) {
|
|
313
|
+
this.setProperty('TZNAME', value);
|
|
314
|
+
}
|
|
315
|
+
removeTimeZoneName() {
|
|
316
|
+
this.removePropertiesWithName('TZNAME');
|
|
317
|
+
}
|
|
318
|
+
}
|
|
102
319
|
class CalendarEvent extends Component {
|
|
103
320
|
name = 'VEVENT';
|
|
104
|
-
constructor(
|
|
321
|
+
constructor(a, b) {
|
|
322
|
+
var component;
|
|
323
|
+
if (b) {
|
|
324
|
+
const uid = a;
|
|
325
|
+
const dtstamp = b;
|
|
326
|
+
component = new Component('VEVENT');
|
|
327
|
+
component.setProperty('UID', uid);
|
|
328
|
+
component.setProperty('DTSTAMP', dtstamp.toISOString());
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
component = a;
|
|
332
|
+
}
|
|
105
333
|
super(component.name, component.properties, component.components);
|
|
106
334
|
}
|
|
335
|
+
stamp() {
|
|
336
|
+
return new Date(this.getProperty('DTSTAMP').value);
|
|
337
|
+
}
|
|
338
|
+
setStamp(value) {
|
|
339
|
+
this.setProperty('DTSTAMP', value.toISOString());
|
|
340
|
+
}
|
|
341
|
+
uid() {
|
|
342
|
+
return this.getProperty('UID').value;
|
|
343
|
+
}
|
|
344
|
+
setUid(value) {
|
|
345
|
+
this.setProperty('UID', value);
|
|
346
|
+
}
|
|
107
347
|
summary() {
|
|
108
348
|
return this.getProperty('SUMMARY').value;
|
|
109
349
|
}
|
|
110
350
|
setSummary(value) {
|
|
111
|
-
this.setProperty(
|
|
351
|
+
this.setProperty('SUMMARY', value);
|
|
352
|
+
}
|
|
353
|
+
removeSummary() {
|
|
354
|
+
this.removePropertiesWithName('SUMMARY');
|
|
112
355
|
}
|
|
113
356
|
description() {
|
|
114
357
|
return this.getProperty('DESCRIPTION').value;
|
|
115
358
|
}
|
|
116
359
|
setDescription(value) {
|
|
117
|
-
this.setProperty(
|
|
360
|
+
this.setProperty('DESCRIPTION', value);
|
|
361
|
+
}
|
|
362
|
+
removeDescription() {
|
|
363
|
+
this.removePropertiesWithName('DESCRIPTION');
|
|
118
364
|
}
|
|
119
365
|
location() {
|
|
120
366
|
return this.getProperty('LOCATION')?.value;
|
|
121
367
|
}
|
|
122
368
|
setLocation(value) {
|
|
123
|
-
this.setProperty(
|
|
369
|
+
this.setProperty('LOCATION', value);
|
|
370
|
+
}
|
|
371
|
+
removeLocation() {
|
|
372
|
+
this.removePropertiesWithName('LOCATION');
|
|
124
373
|
}
|
|
125
374
|
start() {
|
|
126
375
|
return new Date(this.getProperty('DTSTART').value);
|
|
127
376
|
}
|
|
128
377
|
setStart(value) {
|
|
129
|
-
this.setProperty(
|
|
378
|
+
this.setProperty('DTSTART', value.toISOString());
|
|
379
|
+
}
|
|
380
|
+
removeStart() {
|
|
381
|
+
this.removePropertiesWithName('DTSTART');
|
|
130
382
|
}
|
|
131
383
|
end() {
|
|
132
384
|
return new Date(this.getProperty('DTEND').value);
|
|
133
385
|
}
|
|
134
386
|
setEnd(value) {
|
|
135
|
-
this.setProperty(
|
|
387
|
+
this.setProperty('DTEND', value.toISOString());
|
|
388
|
+
}
|
|
389
|
+
removeEnd() {
|
|
390
|
+
this.removePropertiesWithName('DTEND');
|
|
391
|
+
}
|
|
392
|
+
created() {
|
|
393
|
+
const text = this.getProperty('CREATED')?.value;
|
|
394
|
+
if (!text)
|
|
395
|
+
return;
|
|
396
|
+
return new Date(text);
|
|
397
|
+
}
|
|
398
|
+
setCreated(value) {
|
|
399
|
+
this.setProperty('CREATED', value.toISOString());
|
|
400
|
+
}
|
|
401
|
+
removeCreated() {
|
|
402
|
+
this.removePropertiesWithName('CREATED');
|
|
403
|
+
}
|
|
404
|
+
geo() {
|
|
405
|
+
const text = this.getProperty('GEO')?.value;
|
|
406
|
+
if (!text)
|
|
407
|
+
return;
|
|
408
|
+
const pattern = /^[+-]?\d+(\.\d+)?,[+-]?\d+(\.\d+)?$/;
|
|
409
|
+
if (!pattern.test(text))
|
|
410
|
+
throw new Error(`Failed to parse GEO property: ${text}`);
|
|
411
|
+
const [longitude, latitude] = text.split(',');
|
|
412
|
+
return [parseFloat(longitude), parseFloat(latitude)];
|
|
413
|
+
}
|
|
414
|
+
setGeo(latitude, longitude) {
|
|
415
|
+
const text = `${latitude},${longitude}`;
|
|
136
416
|
}
|
|
137
417
|
}
|
|
138
418
|
exports.CalendarEvent = CalendarEvent;
|
|
139
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBTUEsOENBQThDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQTtBQUUxQixNQUFhLFNBQVM7SUFDbEIsSUFBSSxDQUFRO0lBQ1osVUFBVSxDQUFpQjtJQUMzQixVQUFVLENBQWtCO0lBRTVCLFlBQVksSUFBWSxFQUFFLFVBQTRCLEVBQUUsVUFBNkI7UUFDakYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7UUFDaEIsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQ2hDLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFBO1FBQ2pDLENBQUM7UUFDRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUE7UUFDaEMsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksS0FBSyxFQUFFLENBQUE7UUFDakMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTO1FBQ0wsZUFBZTtRQUNmLE1BQU0sS0FBSyxHQUFHLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUVwQyxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNuQyxJQUFJLElBQUksR0FDSixRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDckIsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsR0FBRztnQkFDSCxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUE7WUFF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
|
|
419
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsOENBQThDO0FBQzlDLE1BQU0sZUFBZSxHQUFHLEVBQUUsQ0FBQTtBQUUxQixNQUFhLFNBQVM7SUFDbEIsSUFBSSxDQUFRO0lBQ1osVUFBVSxDQUFZO0lBQ3RCLFVBQVUsQ0FBYTtJQUV2QixZQUFZLElBQVksRUFBRSxVQUF1QixFQUFFLFVBQXdCO1FBQ3ZFLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksVUFBVSxFQUFFLENBQUM7WUFDYixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQTtRQUNoQyxDQUFDO2FBQU0sQ0FBQztZQUNKLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQTtRQUNqQyxDQUFDO1FBQ0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNiLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQ2hDLENBQUM7YUFBTSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFBO1FBQ2pDLENBQUM7SUFDTCxDQUFDO0lBRUQsU0FBUztRQUNMLGVBQWU7UUFDZixNQUFNLEtBQUssR0FBRyxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7UUFFcEMsS0FBSyxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbkMsSUFBSSxJQUFJLEdBQ0osUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEVBQUU7Z0JBQ3JCLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzFDLEdBQUc7Z0JBQ0gsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBRXJC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
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CAChB"}
|
package/lib/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iamcal",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Read and write ICalendar files",
|
|
5
5
|
"files": [
|
|
6
6
|
"/lib",
|
|
7
7
|
"/src"
|
|
8
8
|
],
|
|
9
9
|
"exports": {
|
|
10
|
-
".":
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
".": {
|
|
11
|
+
"default": "./lib/index.js",
|
|
12
|
+
"types": "./lib/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./parse": {
|
|
15
|
+
"default": "./lib/parse.js",
|
|
16
|
+
"types": "./lib/parse.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./io": {
|
|
19
|
+
"default": "./lib/io.js",
|
|
20
|
+
"types": "./lib/io.d.ts"
|
|
21
|
+
}
|
|
13
22
|
},
|
|
23
|
+
"main": "./lib/index.js",
|
|
24
|
+
"types": "./lib/index.d.ts",
|
|
14
25
|
"scripts": {
|
|
15
26
|
"build": "rimraf lib && tsc",
|
|
16
27
|
"test": "echo \"Error: no test specified\" && exit 1"
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
name: string
|
|
3
|
-
params: string[]
|
|
4
|
-
value: string
|
|
5
|
-
}
|
|
1
|
+
import { Property } from './types'
|
|
6
2
|
|
|
7
3
|
// Max line length as defined by RFC 5545 3.1.
|
|
8
4
|
const MAX_LINE_LENGTH = 75
|
|
9
5
|
|
|
10
6
|
export class Component {
|
|
11
7
|
name: string
|
|
12
|
-
properties:
|
|
13
|
-
components:
|
|
8
|
+
properties: Property[]
|
|
9
|
+
components: Component[]
|
|
14
10
|
|
|
15
|
-
constructor(name: string, properties?:
|
|
11
|
+
constructor(name: string, properties?: Property[], components?: Component[]) {
|
|
16
12
|
this.name = name
|
|
17
13
|
if (properties) {
|
|
18
14
|
this.properties = properties
|
|
@@ -40,7 +36,7 @@ export class Component {
|
|
|
40
36
|
// Wrap lines
|
|
41
37
|
while (line.length > MAX_LINE_LENGTH) {
|
|
42
38
|
lines.push(line.substring(0, MAX_LINE_LENGTH))
|
|
43
|
-
line =
|
|
39
|
+
line = ' ' + line.substring(MAX_LINE_LENGTH)
|
|
44
40
|
}
|
|
45
41
|
lines.push(line)
|
|
46
42
|
}
|
|
@@ -80,6 +76,13 @@ export class Component {
|
|
|
80
76
|
})
|
|
81
77
|
}
|
|
82
78
|
|
|
79
|
+
removePropertiesWithName(name: string) {
|
|
80
|
+
const index = this.properties.findIndex(p => p.name === name)
|
|
81
|
+
if (index === -1) return
|
|
82
|
+
// Remove property at index
|
|
83
|
+
this.properties.splice(index, 1)
|
|
84
|
+
}
|
|
85
|
+
|
|
83
86
|
getPropertyParams(name: string): string[] | null {
|
|
84
87
|
for (const property of this.properties) {
|
|
85
88
|
if (property.name === name) {
|
|
@@ -96,41 +99,355 @@ export class Component {
|
|
|
96
99
|
}
|
|
97
100
|
}
|
|
98
101
|
}
|
|
102
|
+
|
|
103
|
+
addComponent(component: Component) {
|
|
104
|
+
this.components.push(component)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
removeComponent(component: Component): boolean {
|
|
108
|
+
const index = this.components.indexOf(component)
|
|
109
|
+
if (index === -1) return false
|
|
110
|
+
|
|
111
|
+
// Remove element at index from list
|
|
112
|
+
this.components.splice(index, 1)
|
|
113
|
+
|
|
114
|
+
return true
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
getComponents(name: string): Component[] {
|
|
118
|
+
const components: Component[] = []
|
|
119
|
+
|
|
120
|
+
for (let component of this.components) {
|
|
121
|
+
if (component.name === name) {
|
|
122
|
+
components.push(component)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return components
|
|
127
|
+
}
|
|
99
128
|
}
|
|
100
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Represents a VCALENDAR component, the root component of an iCalendar file.
|
|
132
|
+
*/
|
|
101
133
|
export class Calendar extends Component {
|
|
102
134
|
name = 'VCALENDAR'
|
|
103
135
|
|
|
104
|
-
|
|
136
|
+
/**
|
|
137
|
+
* @param prodid A unique identifier of the program creating the calendar.
|
|
138
|
+
*
|
|
139
|
+
* Example: `-//Google Inc//Google Calendar 70.9054//EN`
|
|
140
|
+
*/
|
|
141
|
+
constructor(prodid: string)
|
|
142
|
+
/**
|
|
143
|
+
* @param prodid A unique identifier of the program creating the calendar.
|
|
144
|
+
*
|
|
145
|
+
* Example: `-//Google Inc//Google Calendar 70.9054//EN`
|
|
146
|
+
* @param version The version of the iCalendar specification that this calendar uses.
|
|
147
|
+
*/
|
|
148
|
+
constructor(prodid: string, version: string)
|
|
149
|
+
/**
|
|
150
|
+
* @param component A VCALENDAR component.
|
|
151
|
+
*/
|
|
152
|
+
constructor(component: Component)
|
|
153
|
+
constructor(a?: string | Component, b?: string) {
|
|
154
|
+
var component: Component
|
|
155
|
+
if (a instanceof Component) {
|
|
156
|
+
component = a as Component
|
|
157
|
+
} else {
|
|
158
|
+
const prodid = a as string
|
|
159
|
+
const version = (b as string) ?? '2.0'
|
|
160
|
+
component = new Component('VCALENDAR')
|
|
161
|
+
component.setProperty('PRODID', prodid)
|
|
162
|
+
component.setProperty('VERSION', version)
|
|
163
|
+
}
|
|
105
164
|
super(component.name, component.properties, component.components)
|
|
106
165
|
}
|
|
107
166
|
|
|
108
|
-
events():
|
|
109
|
-
|
|
167
|
+
events(): CalendarEvent[] {
|
|
168
|
+
return this.getComponents('VEVENT').map(c => new CalendarEvent(c))
|
|
169
|
+
}
|
|
110
170
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
171
|
+
removeEvent(event: CalendarEvent): boolean
|
|
172
|
+
removeEvent(uid: string): boolean
|
|
173
|
+
removeEvent(a: CalendarEvent | string): boolean {
|
|
174
|
+
if (a instanceof CalendarEvent) {
|
|
175
|
+
const event = a as CalendarEvent
|
|
176
|
+
return this.removeComponent(event)
|
|
177
|
+
} else {
|
|
178
|
+
const uid = a as string
|
|
179
|
+
for (const event of this.events()) {
|
|
180
|
+
if (event.uid() !== uid) continue
|
|
181
|
+
return this.removeComponent(event)
|
|
114
182
|
}
|
|
115
183
|
}
|
|
184
|
+
return false
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
prodId(): string {
|
|
188
|
+
return this.getProperty('PRODID')!.value
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
setProdId(value: string) {
|
|
192
|
+
this.setProperty('PRODID', value)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
version(): string {
|
|
196
|
+
return this.getProperty('VERSION')!.value
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setVersion(value: string) {
|
|
200
|
+
this.setProperty('VERSION', value)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
calScale(): string | undefined {
|
|
204
|
+
return this.getProperty('CALSCALE')?.value
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
setCalScale(value: string) {
|
|
208
|
+
this.setProperty('CALSCALE', value)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
removeCalScale() {
|
|
212
|
+
this.removePropertiesWithName('CALSCALE')
|
|
213
|
+
}
|
|
116
214
|
|
|
117
|
-
|
|
215
|
+
method(): string | undefined {
|
|
216
|
+
return this.getProperty('METHOD')?.value
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
setMethod(value: string) {
|
|
220
|
+
this.setProperty('METHOD', value)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
removeMethod() {
|
|
224
|
+
this.removePropertiesWithName('METHOD')
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
calendarName(): string | undefined {
|
|
228
|
+
return this.getProperty('X-WR-CALNAME')?.value
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
setCalendarName(value: string) {
|
|
232
|
+
this.setProperty('X-WR-CALNAME', value)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
removeCalendarName() {
|
|
236
|
+
this.removePropertiesWithName('X-WR-CALNAME')
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
calendarDescription(): string | undefined {
|
|
240
|
+
return this.getProperty('X-WR-CALDESC')?.value
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
setCalendarDescription(value: string) {
|
|
244
|
+
this.setProperty('X-WR-CALDESC', value)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
removeCalendarDescription() {
|
|
248
|
+
this.removePropertiesWithName('X-WR-CALDESC')
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Represents a VTIMEZONE component, containing time zone definitions.
|
|
254
|
+
*/
|
|
255
|
+
export class TimeZone extends Component {
|
|
256
|
+
constructor(id: string)
|
|
257
|
+
constructor(component: Component)
|
|
258
|
+
constructor(a: string | Component) {
|
|
259
|
+
var component: Component
|
|
260
|
+
if (a instanceof Component) {
|
|
261
|
+
component = a as Component
|
|
262
|
+
} else {
|
|
263
|
+
const tzid = a as string
|
|
264
|
+
component = new Component('VTIMEZONE')
|
|
265
|
+
component.setProperty('TZID', tzid)
|
|
266
|
+
}
|
|
267
|
+
super(component.name, component.properties, component.components)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
id(): string {
|
|
271
|
+
return this.getProperty('TZID')!.value
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
setId(value: string) {
|
|
275
|
+
this.setProperty('TZID', value)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
lastMod(): Date | undefined {
|
|
279
|
+
const text = this.getProperty('LAST-MOD')
|
|
280
|
+
if (!text) return
|
|
281
|
+
return new Date(text.value)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
setLastMod(value: Date) {
|
|
285
|
+
this.setProperty('LAST-MOD', value.toISOString())
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
removeLastMod() {
|
|
289
|
+
this.removePropertiesWithName('LAST-MOD')
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
url(): string | undefined {
|
|
293
|
+
return this.getProperty('TZURL')?.value
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
setUrl(value: string) {
|
|
297
|
+
this.setProperty('TZURL', value)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
removeUrl() {
|
|
301
|
+
this.removePropertiesWithName('TZURL')
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Get all time offsets. */
|
|
305
|
+
offsets(): TimeZoneOffset[] {
|
|
306
|
+
const offsets: TimeZoneOffset[] = []
|
|
307
|
+
this.components.forEach(component => {
|
|
308
|
+
if (component.name === 'STANDARD' || component.name === 'DAYLIGHT') {
|
|
309
|
+
offsets.push(new TimeZoneOffset(component))
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
return offsets
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/** Get standard/winter time offsets. */
|
|
316
|
+
standardOffsets(): TimeZoneOffset[] {
|
|
317
|
+
return this.getComponents('STANDARD').map(c => new TimeZoneOffset(c))
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Get daylight savings time offsets. */
|
|
321
|
+
daylightOffsets(): TimeZoneOffset[] {
|
|
322
|
+
return this.getComponents('DAYLIGHT').map(c => new TimeZoneOffset(c))
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export type OffsetType = 'DAYLIGHT' | 'STANDARD'
|
|
327
|
+
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
|
|
328
|
+
export type Offset = `${'-' | '+'}${Digit}${Digit}${Digit}${Digit}`
|
|
329
|
+
/** Represents a STANDARD or DAYLIGHT component, defining a time zone offset. */
|
|
330
|
+
class TimeZoneOffset extends Component {
|
|
331
|
+
/**
|
|
332
|
+
*
|
|
333
|
+
* @param type If this is a STANDARD or DAYLIGHT component.
|
|
334
|
+
* @param start From when this offset is active.
|
|
335
|
+
* @param offsetFrom The offset that is in use prior to this time zone observance.
|
|
336
|
+
* @param offsetTo The offset that is in use during this time zone observance.
|
|
337
|
+
*/
|
|
338
|
+
constructor(type: OffsetType, start: Date, offsetFrom: Offset, offsetTo: Offset)
|
|
339
|
+
constructor(component: Component)
|
|
340
|
+
constructor(a: OffsetType | Component, b?: Date, c?: Offset, d?: Offset) {
|
|
341
|
+
var component: Component
|
|
342
|
+
if (a instanceof Component) {
|
|
343
|
+
component = a as Component
|
|
344
|
+
} else {
|
|
345
|
+
const name = a as OffsetType
|
|
346
|
+
const start = b as Date
|
|
347
|
+
const offsetFrom = c as Offset
|
|
348
|
+
const offsetTo = d as Offset
|
|
349
|
+
component = new Component(name)
|
|
350
|
+
component.setProperty('DTSTART', start.toISOString())
|
|
351
|
+
component.setProperty('TZOFFSETFROM', offsetFrom)
|
|
352
|
+
component.setProperty('TZOFFSETTO', offsetTo)
|
|
353
|
+
}
|
|
354
|
+
super(component.name, component.properties, component.components)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
start(): Date {
|
|
358
|
+
return new Date(this.getProperty('DTSTART')!.value)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
setStart(value: Date) {
|
|
362
|
+
this.setProperty('DTSTART', value.toISOString())
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
offsetFrom(): Offset {
|
|
366
|
+
return this.getProperty('TZOFFSETFROM')!.value as Offset
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
setOffsetFrom(value: Offset) {
|
|
370
|
+
this.setProperty('TZOFFSETFROM', value)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
offsetTo(): Offset {
|
|
374
|
+
return this.getProperty('TZOFFSETTO')!.value as Offset
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
setOffsetTo(value: Offset) {
|
|
378
|
+
this.setProperty('TZOFFSETTO', value)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
comment(): string | undefined {
|
|
382
|
+
return this.getProperty('COMMENT')?.value
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
setComment(value: string) {
|
|
386
|
+
this.setProperty('COMMENT', value)
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
removeComment() {
|
|
390
|
+
this.removePropertiesWithName('COMMENT')
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
timeZoneName(): string | undefined {
|
|
394
|
+
return this.getProperty('TZNAME')?.value
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
setTimeZoneName(value: string) {
|
|
398
|
+
this.setProperty('TZNAME', value)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
removeTimeZoneName() {
|
|
402
|
+
this.removePropertiesWithName('TZNAME')
|
|
118
403
|
}
|
|
119
404
|
}
|
|
120
405
|
|
|
121
406
|
export class CalendarEvent extends Component {
|
|
122
407
|
name = 'VEVENT'
|
|
123
408
|
|
|
124
|
-
constructor(
|
|
409
|
+
constructor(uid: string, dtstamp: Date)
|
|
410
|
+
constructor(component: Component)
|
|
411
|
+
constructor(a: string | Component, b?: Date) {
|
|
412
|
+
var component: Component
|
|
413
|
+
if (b) {
|
|
414
|
+
const uid = a as string
|
|
415
|
+
const dtstamp = b as Date
|
|
416
|
+
component = new Component('VEVENT')
|
|
417
|
+
component.setProperty('UID', uid)
|
|
418
|
+
component.setProperty('DTSTAMP', dtstamp.toISOString())
|
|
419
|
+
} else {
|
|
420
|
+
component = a as Component
|
|
421
|
+
}
|
|
125
422
|
super(component.name, component.properties, component.components)
|
|
126
423
|
}
|
|
127
424
|
|
|
425
|
+
stamp(): Date {
|
|
426
|
+
return new Date(this.getProperty('DTSTAMP')!.value)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
setStamp(value: Date) {
|
|
430
|
+
this.setProperty('DTSTAMP', value.toISOString())
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
uid(): string {
|
|
434
|
+
return this.getProperty('UID')!.value
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
setUid(value: string) {
|
|
438
|
+
this.setProperty('UID', value)
|
|
439
|
+
}
|
|
440
|
+
|
|
128
441
|
summary(): string {
|
|
129
442
|
return this.getProperty('SUMMARY')!.value
|
|
130
443
|
}
|
|
131
444
|
|
|
132
445
|
setSummary(value: string) {
|
|
133
|
-
this.setProperty(
|
|
446
|
+
this.setProperty('SUMMARY', value)
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
removeSummary() {
|
|
450
|
+
this.removePropertiesWithName('SUMMARY')
|
|
134
451
|
}
|
|
135
452
|
|
|
136
453
|
description(): string {
|
|
@@ -138,7 +455,11 @@ export class CalendarEvent extends Component {
|
|
|
138
455
|
}
|
|
139
456
|
|
|
140
457
|
setDescription(value: string) {
|
|
141
|
-
this.setProperty(
|
|
458
|
+
this.setProperty('DESCRIPTION', value)
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
removeDescription() {
|
|
462
|
+
this.removePropertiesWithName('DESCRIPTION')
|
|
142
463
|
}
|
|
143
464
|
|
|
144
465
|
location(): string | undefined {
|
|
@@ -146,7 +467,11 @@ export class CalendarEvent extends Component {
|
|
|
146
467
|
}
|
|
147
468
|
|
|
148
469
|
setLocation(value: string) {
|
|
149
|
-
this.setProperty(
|
|
470
|
+
this.setProperty('LOCATION', value)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
removeLocation() {
|
|
474
|
+
this.removePropertiesWithName('LOCATION')
|
|
150
475
|
}
|
|
151
476
|
|
|
152
477
|
start(): Date {
|
|
@@ -154,14 +479,49 @@ export class CalendarEvent extends Component {
|
|
|
154
479
|
}
|
|
155
480
|
|
|
156
481
|
setStart(value: Date) {
|
|
157
|
-
this.setProperty(
|
|
482
|
+
this.setProperty('DTSTART', value.toISOString())
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
removeStart() {
|
|
486
|
+
this.removePropertiesWithName('DTSTART')
|
|
158
487
|
}
|
|
159
488
|
|
|
160
489
|
end(): Date {
|
|
161
490
|
return new Date(this.getProperty('DTEND')!.value)
|
|
162
491
|
}
|
|
163
|
-
|
|
492
|
+
|
|
164
493
|
setEnd(value: Date) {
|
|
165
|
-
this.setProperty(
|
|
494
|
+
this.setProperty('DTEND', value.toISOString())
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
removeEnd() {
|
|
498
|
+
this.removePropertiesWithName('DTEND')
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
created(): Date | undefined {
|
|
502
|
+
const text = this.getProperty('CREATED')?.value
|
|
503
|
+
if (!text) return
|
|
504
|
+
return new Date(text)
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
setCreated(value: Date) {
|
|
508
|
+
this.setProperty('CREATED', value.toISOString())
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
removeCreated() {
|
|
512
|
+
this.removePropertiesWithName('CREATED')
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
geo(): [number, number] | undefined {
|
|
516
|
+
const text = this.getProperty('GEO')?.value
|
|
517
|
+
if (!text) return
|
|
518
|
+
const pattern = /^[+-]?\d+(\.\d+)?,[+-]?\d+(\.\d+)?$/
|
|
519
|
+
if (!pattern.test(text)) throw new Error(`Failed to parse GEO property: ${text}`)
|
|
520
|
+
const [longitude, latitude] = text.split(',')
|
|
521
|
+
return [parseFloat(longitude), parseFloat(latitude)]
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
setGeo(latitude: number, longitude: number) {
|
|
525
|
+
const text = `${latitude},${longitude}`
|
|
166
526
|
}
|
|
167
527
|
}
|