ical-generator 8.1.2-develop.9 → 9.0.0-develop.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -19
- package/dist/index.cjs +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1329 -1329
- package/dist/index.d.ts +1329 -1329
- package/dist/index.js +17 -17
- package/dist/index.js.map +1 -1
- package/package.json +123 -122
- package/src/alarm.ts +499 -454
- package/src/attendee.ts +364 -345
- package/src/calendar.ts +422 -439
- package/src/category.ts +5 -14
- package/src/event.ts +1292 -1119
- package/src/index.ts +19 -25
- package/src/tools.ts +348 -258
- package/src/types.ts +86 -75
package/src/calendar.ts
CHANGED
|
@@ -1,77 +1,81 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
import ICalEvent, {
|
|
4
|
+
type ICalEventData,
|
|
5
|
+
type ICalEventJSONData,
|
|
6
|
+
} from './event.ts';
|
|
3
7
|
import {
|
|
4
8
|
addOrGetCustomAttributes,
|
|
5
9
|
checkEnum,
|
|
6
10
|
foldLines,
|
|
7
11
|
generateCustomAttributes,
|
|
8
12
|
isMomentDuration,
|
|
9
|
-
toDurationString
|
|
13
|
+
toDurationString,
|
|
10
14
|
} from './tools.ts';
|
|
11
|
-
import ICalEvent, { type ICalEventData, type ICalEventJSONData } from './event.ts';
|
|
12
15
|
import { type ICalMomentDurationStub, type ICalTimezone } from './types.ts';
|
|
13
16
|
|
|
17
|
+
export enum ICalCalendarMethod {
|
|
18
|
+
ADD = 'ADD',
|
|
19
|
+
CANCEL = 'CANCEL',
|
|
20
|
+
COUNTER = 'COUNTER',
|
|
21
|
+
DECLINECOUNTER = 'DECLINECOUNTER',
|
|
22
|
+
PUBLISH = 'PUBLISH',
|
|
23
|
+
REFRESH = 'REFRESH',
|
|
24
|
+
REPLY = 'REPLY',
|
|
25
|
+
REQUEST = 'REQUEST',
|
|
26
|
+
}
|
|
14
27
|
|
|
15
28
|
export interface ICalCalendarData {
|
|
16
|
-
|
|
17
|
-
method?: ICalCalendarMethod | null;
|
|
18
|
-
name?: string | null;
|
|
19
|
-
description?: string | null;
|
|
20
|
-
timezone?: ICalTimezone | string | null;
|
|
21
|
-
source?: string | null;
|
|
22
|
-
url?: string | null;
|
|
23
|
-
scale?: string | null;
|
|
24
|
-
ttl?: number | ICalMomentDurationStub | null;
|
|
29
|
+
description?: null | string;
|
|
25
30
|
events?: (ICalEvent | ICalEventData)[];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ttl: number | null;
|
|
39
|
-
events: ICalEvent[];
|
|
40
|
-
x: [string, string][];
|
|
31
|
+
method?: ICalCalendarMethod | null;
|
|
32
|
+
name?: null | string;
|
|
33
|
+
prodId?: ICalCalendarProdIdData | string;
|
|
34
|
+
scale?: null | string;
|
|
35
|
+
source?: null | string;
|
|
36
|
+
timezone?: ICalTimezone | null | string;
|
|
37
|
+
ttl?: ICalMomentDurationStub | null | number;
|
|
38
|
+
url?: null | string;
|
|
39
|
+
x?:
|
|
40
|
+
| [string, string][]
|
|
41
|
+
| Record<string, string>
|
|
42
|
+
| { key: string; value: string }[];
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export interface ICalCalendarJSONData {
|
|
44
|
-
|
|
45
|
-
method: ICalCalendarMethod | null;
|
|
46
|
-
name: string | null;
|
|
47
|
-
description: string | null;
|
|
48
|
-
timezone: string | null;
|
|
49
|
-
source: string | null;
|
|
50
|
-
url: string | null;
|
|
51
|
-
scale: string | null;
|
|
52
|
-
ttl: number | null;
|
|
46
|
+
description: null | string;
|
|
53
47
|
events: ICalEventJSONData[];
|
|
54
|
-
|
|
48
|
+
method: ICalCalendarMethod | null;
|
|
49
|
+
name: null | string;
|
|
50
|
+
prodId: string;
|
|
51
|
+
scale: null | string;
|
|
52
|
+
source: null | string;
|
|
53
|
+
timezone: null | string;
|
|
54
|
+
ttl: null | number;
|
|
55
|
+
url: null | string;
|
|
56
|
+
x: { key: string; value: string }[];
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
export interface ICalCalendarProdIdData {
|
|
58
60
|
company: string;
|
|
59
|
-
product: string;
|
|
60
61
|
language?: string;
|
|
62
|
+
product: string;
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
interface ICalCalendarInternalData {
|
|
66
|
+
description: null | string;
|
|
67
|
+
events: ICalEvent[];
|
|
68
|
+
method: ICalCalendarMethod | null;
|
|
69
|
+
name: null | string;
|
|
70
|
+
prodId: string;
|
|
71
|
+
scale: null | string;
|
|
72
|
+
source: null | string;
|
|
73
|
+
timezone: ICalTimezone | null;
|
|
74
|
+
ttl: null | number;
|
|
75
|
+
url: null | string;
|
|
76
|
+
x: [string, string][];
|
|
72
77
|
}
|
|
73
78
|
|
|
74
|
-
|
|
75
79
|
/**
|
|
76
80
|
* Usually you get an {@link ICalCalendar} object like this:
|
|
77
81
|
* ```javascript
|
|
@@ -124,17 +128,17 @@ export default class ICalCalendar {
|
|
|
124
128
|
*/
|
|
125
129
|
constructor(data: ICalCalendarData = {}) {
|
|
126
130
|
this.data = {
|
|
127
|
-
|
|
131
|
+
description: null,
|
|
132
|
+
events: [],
|
|
128
133
|
method: null,
|
|
129
134
|
name: null,
|
|
130
|
-
|
|
131
|
-
timezone: null,
|
|
132
|
-
source: null,
|
|
133
|
-
url: null,
|
|
135
|
+
prodId: '//sebbo.net//ical-generator//EN',
|
|
134
136
|
scale: null,
|
|
137
|
+
source: null,
|
|
138
|
+
timezone: null,
|
|
135
139
|
ttl: null,
|
|
136
|
-
|
|
137
|
-
x: []
|
|
140
|
+
url: null,
|
|
141
|
+
x: [],
|
|
138
142
|
};
|
|
139
143
|
|
|
140
144
|
if (data.prodId !== undefined) this.prodId(data.prodId);
|
|
@@ -150,61 +154,118 @@ export default class ICalCalendar {
|
|
|
150
154
|
if (data.x !== undefined) this.x(data.x);
|
|
151
155
|
}
|
|
152
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Remove all events from the calendar without
|
|
159
|
+
* touching any other data like name or prodId.
|
|
160
|
+
*
|
|
161
|
+
* @since 2.0.0-develop.1
|
|
162
|
+
*/
|
|
163
|
+
clear(): this {
|
|
164
|
+
this.data.events = [];
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
153
167
|
|
|
154
168
|
/**
|
|
155
|
-
*
|
|
169
|
+
* Creates a new {@link ICalEvent} and returns it. Use options to prefill the event's attributes.
|
|
170
|
+
* Calling this method without options will create an empty event.
|
|
171
|
+
*
|
|
172
|
+
* ```javascript
|
|
173
|
+
* import ical from 'ical-generator';
|
|
174
|
+
*
|
|
175
|
+
* // or use require:
|
|
176
|
+
* // const { default: ical } = require('ical-generator');
|
|
177
|
+
*
|
|
178
|
+
* const cal = ical();
|
|
179
|
+
* const event = cal.createEvent({summary: 'My Event'});
|
|
180
|
+
*
|
|
181
|
+
* // overwrite event summary
|
|
182
|
+
* event.summary('Your Event');
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
156
185
|
* @since 0.2.0
|
|
157
186
|
*/
|
|
158
|
-
|
|
187
|
+
createEvent(data: ICalEvent | ICalEventData): ICalEvent {
|
|
188
|
+
const event =
|
|
189
|
+
data instanceof ICalEvent ? data : new ICalEvent(data, this);
|
|
190
|
+
this.data.events.push(event);
|
|
191
|
+
return event;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Get your feed's description
|
|
195
|
+
* @since 0.2.7
|
|
196
|
+
*/
|
|
197
|
+
description(): null | string;
|
|
198
|
+
/**
|
|
199
|
+
* Set your feed's description
|
|
200
|
+
* @since 0.2.7
|
|
201
|
+
*/
|
|
202
|
+
description(description: null | string): this;
|
|
203
|
+
description(description?: null | string): null | string | this {
|
|
204
|
+
if (description === undefined) {
|
|
205
|
+
return this.data.description;
|
|
206
|
+
}
|
|
159
207
|
|
|
208
|
+
this.data.description = description ? String(description) : null;
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
160
211
|
/**
|
|
161
|
-
*
|
|
162
|
-
* string like `//sebbo.net//ical-generator//EN` or a
|
|
163
|
-
* valid {@link ICalCalendarProdIdData} object. `language`
|
|
164
|
-
* is optional and defaults to `EN`.
|
|
212
|
+
* Returns all events of this calendar.
|
|
165
213
|
*
|
|
166
214
|
* ```javascript
|
|
167
|
-
* cal
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
215
|
+
* const cal = ical();
|
|
216
|
+
*
|
|
217
|
+
* cal.events([
|
|
218
|
+
* {
|
|
219
|
+
* start: new Date(),
|
|
220
|
+
* end: new Date(new Date().getTime() + 3600000),
|
|
221
|
+
* summary: 'Example Event',
|
|
222
|
+
* description: 'It works ;)',
|
|
223
|
+
* url: 'http://sebbo.net/'
|
|
224
|
+
* }
|
|
225
|
+
* ]);
|
|
226
|
+
*
|
|
227
|
+
* cal.events(); // --> [ICalEvent]
|
|
172
228
|
* ```
|
|
173
229
|
*
|
|
174
|
-
*
|
|
175
|
-
|
|
176
|
-
|
|
230
|
+
* @since 0.2.0
|
|
231
|
+
*/
|
|
232
|
+
events(): ICalEvent[];
|
|
233
|
+
/**
|
|
234
|
+
* Add multiple events to your calendar.
|
|
235
|
+
*
|
|
236
|
+
* ```javascript
|
|
237
|
+
* const cal = ical();
|
|
238
|
+
*
|
|
239
|
+
* cal.events([
|
|
240
|
+
* {
|
|
241
|
+
* start: new Date(),
|
|
242
|
+
* end: new Date(new Date().getTime() + 3600000),
|
|
243
|
+
* summary: 'Example Event',
|
|
244
|
+
* description: 'It works ;)',
|
|
245
|
+
* url: 'http://sebbo.net/'
|
|
246
|
+
* }
|
|
247
|
+
* ]);
|
|
248
|
+
*
|
|
249
|
+
* cal.events(); // --> [ICalEvent]
|
|
177
250
|
* ```
|
|
178
251
|
*
|
|
179
252
|
* @since 0.2.0
|
|
180
253
|
*/
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!
|
|
184
|
-
return this.data.
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
if (typeof prodId === 'string') {
|
|
188
|
-
this.data.prodId = prodId;
|
|
189
|
-
return this;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
if (typeof prodId !== 'object') {
|
|
193
|
-
throw new Error('`prodid` needs to be a string or an object!');
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
if (!prodId.company) {
|
|
197
|
-
throw new Error('`prodid.company` is a mandatory item!');
|
|
198
|
-
}
|
|
199
|
-
if (!prodId.product) {
|
|
200
|
-
throw new Error('`prodid.product` is a mandatory item!');
|
|
254
|
+
events(events: (ICalEvent | ICalEventData)[]): this;
|
|
255
|
+
events(events?: (ICalEvent | ICalEventData)[]): ICalEvent[] | this {
|
|
256
|
+
if (!events) {
|
|
257
|
+
return this.data.events;
|
|
201
258
|
}
|
|
202
259
|
|
|
203
|
-
|
|
204
|
-
this.data.prodId = '//' + prodId.company + '//' + prodId.product + '//' + language;
|
|
260
|
+
events.forEach((e: ICalEvent | ICalEventData) => this.createEvent(e));
|
|
205
261
|
return this;
|
|
206
262
|
}
|
|
207
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Get the number of events added to your calendar
|
|
265
|
+
*/
|
|
266
|
+
length(): number {
|
|
267
|
+
return this.data.events.length;
|
|
268
|
+
}
|
|
208
269
|
|
|
209
270
|
/**
|
|
210
271
|
* Get the feed method attribute.
|
|
@@ -213,7 +274,6 @@ export default class ICalCalendar {
|
|
|
213
274
|
* @since 0.2.8
|
|
214
275
|
*/
|
|
215
276
|
method(): ICalCalendarMethod | null;
|
|
216
|
-
|
|
217
277
|
/**
|
|
218
278
|
* Set the feed method attribute.
|
|
219
279
|
* See {@link ICalCalendarMethod} for available options.
|
|
@@ -229,7 +289,9 @@ export default class ICalCalendar {
|
|
|
229
289
|
* @since 0.2.8
|
|
230
290
|
*/
|
|
231
291
|
method(method: ICalCalendarMethod | null): this;
|
|
232
|
-
method(
|
|
292
|
+
method(
|
|
293
|
+
method?: ICalCalendarMethod | null,
|
|
294
|
+
): ICalCalendarMethod | null | this {
|
|
233
295
|
if (method === undefined) {
|
|
234
296
|
return this.data.method;
|
|
235
297
|
}
|
|
@@ -238,17 +300,18 @@ export default class ICalCalendar {
|
|
|
238
300
|
return this;
|
|
239
301
|
}
|
|
240
302
|
|
|
241
|
-
this.data.method = checkEnum(
|
|
303
|
+
this.data.method = checkEnum(
|
|
304
|
+
ICalCalendarMethod,
|
|
305
|
+
method,
|
|
306
|
+
) as ICalCalendarMethod;
|
|
242
307
|
return this;
|
|
243
308
|
}
|
|
244
309
|
|
|
245
|
-
|
|
246
310
|
/**
|
|
247
311
|
* Get your feed's name
|
|
248
312
|
* @since 0.2.0
|
|
249
313
|
*/
|
|
250
|
-
name():
|
|
251
|
-
|
|
314
|
+
name(): null | string;
|
|
252
315
|
/**
|
|
253
316
|
* Set your feed's name. Is used to fill `NAME`
|
|
254
317
|
* and `X-WR-CALNAME` in your iCal file.
|
|
@@ -273,8 +336,8 @@ export default class ICalCalendar {
|
|
|
273
336
|
*
|
|
274
337
|
* @since 0.2.0
|
|
275
338
|
*/
|
|
276
|
-
name(name:
|
|
277
|
-
name(name?:
|
|
339
|
+
name(name: null | string): this;
|
|
340
|
+
name(name?: null | string): null | string | this {
|
|
278
341
|
if (name === undefined) {
|
|
279
342
|
return this.data.name;
|
|
280
343
|
}
|
|
@@ -282,51 +345,141 @@ export default class ICalCalendar {
|
|
|
282
345
|
this.data.name = name ? String(name) : null;
|
|
283
346
|
return this;
|
|
284
347
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
348
|
/**
|
|
288
|
-
* Get your feed's
|
|
289
|
-
* @since 0.2.
|
|
349
|
+
* Get your feed's prodid. Will always return a string.
|
|
350
|
+
* @since 0.2.0
|
|
290
351
|
*/
|
|
291
|
-
|
|
292
|
-
|
|
352
|
+
prodId(): string;
|
|
293
353
|
/**
|
|
294
|
-
* Set your feed's
|
|
295
|
-
*
|
|
354
|
+
* Set your feed's prodid. `prodid` can be either a
|
|
355
|
+
* string like `//sebbo.net//ical-generator//EN` or a
|
|
356
|
+
* valid {@link ICalCalendarProdIdData} object. `language`
|
|
357
|
+
* is optional and defaults to `EN`.
|
|
358
|
+
*
|
|
359
|
+
* ```javascript
|
|
360
|
+
* cal.prodId({
|
|
361
|
+
* company: 'My Company',
|
|
362
|
+
* product: 'My Product',
|
|
363
|
+
* language: 'EN' // optional, defaults to EN
|
|
364
|
+
* });
|
|
365
|
+
* ```
|
|
366
|
+
*
|
|
367
|
+
* `cal.toString()` would then produce the following string:
|
|
368
|
+
* ```text
|
|
369
|
+
* PRODID:-//My Company//My Product//EN
|
|
370
|
+
* ```
|
|
371
|
+
*
|
|
372
|
+
* @since 0.2.0
|
|
296
373
|
*/
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
return this.data.
|
|
374
|
+
prodId(prodId: ICalCalendarProdIdData | string): this;
|
|
375
|
+
prodId(prodId?: ICalCalendarProdIdData | string): string | this {
|
|
376
|
+
if (!prodId) {
|
|
377
|
+
return this.data.prodId;
|
|
301
378
|
}
|
|
302
379
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
380
|
+
if (typeof prodId === 'string') {
|
|
381
|
+
this.data.prodId = prodId;
|
|
382
|
+
return this;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (typeof prodId !== 'object') {
|
|
386
|
+
throw new Error('`prodid` needs to be a string or an object!');
|
|
387
|
+
}
|
|
306
388
|
|
|
389
|
+
if (!prodId.company) {
|
|
390
|
+
throw new Error('`prodid.company` is a mandatory item!');
|
|
391
|
+
}
|
|
392
|
+
if (!prodId.product) {
|
|
393
|
+
throw new Error('`prodid.product` is a mandatory item!');
|
|
394
|
+
}
|
|
307
395
|
|
|
396
|
+
const language = (prodId.language || 'EN').toUpperCase();
|
|
397
|
+
this.data.prodId =
|
|
398
|
+
'//' + prodId.company + '//' + prodId.product + '//' + language;
|
|
399
|
+
return this;
|
|
400
|
+
}
|
|
308
401
|
/**
|
|
309
|
-
* Get the
|
|
310
|
-
*
|
|
402
|
+
* Get current value of the `CALSCALE` attribute. It will
|
|
403
|
+
* return `null` if no value was set. The iCal standard
|
|
404
|
+
* specifies this as `GREGORIAN` if no value is present.
|
|
405
|
+
*
|
|
406
|
+
* @since 1.8.0
|
|
311
407
|
*/
|
|
312
|
-
|
|
313
|
-
|
|
408
|
+
scale(): null | string;
|
|
314
409
|
/**
|
|
315
|
-
* Use this method to set your feed's
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
* time zone is specified, all information is output as UTC.
|
|
410
|
+
* Use this method to set your feed's `CALSCALE` attribute. There is no
|
|
411
|
+
* default value for this property and it will not appear in your iCal
|
|
412
|
+
* file unless set. The iCal standard specifies this as `GREGORIAN` if
|
|
413
|
+
* no value is present.
|
|
320
414
|
*
|
|
321
415
|
* ```javascript
|
|
322
|
-
* cal.
|
|
416
|
+
* cal.scale('gregorian');
|
|
323
417
|
* ```
|
|
324
418
|
*
|
|
325
|
-
* @
|
|
326
|
-
* @since 0.2.0
|
|
419
|
+
* @since 1.8.0
|
|
327
420
|
*/
|
|
328
|
-
|
|
421
|
+
scale(scale: null | string): this;
|
|
422
|
+
scale(scale?: null | string): null | string | this {
|
|
423
|
+
if (scale === undefined) {
|
|
424
|
+
return this.data.scale;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (scale === null) {
|
|
428
|
+
this.data.scale = null;
|
|
429
|
+
} else {
|
|
430
|
+
this.data.scale = scale.toUpperCase();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return this;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get current value of the `SOURCE` attribute.
|
|
437
|
+
* @since 2.2.0-develop.1
|
|
438
|
+
*/
|
|
439
|
+
source(): null | string;
|
|
440
|
+
/**
|
|
441
|
+
* Use this method to set your feed's `SOURCE` attribute.
|
|
442
|
+
* This tells the client where to refresh your feed.
|
|
443
|
+
*
|
|
444
|
+
* ```javascript
|
|
445
|
+
* cal.source('http://example.com/my/original_source.ical');
|
|
446
|
+
* ```
|
|
447
|
+
*
|
|
448
|
+
* ```text
|
|
449
|
+
* SOURCE;VALUE=URI:http://example.com/my/original_source.ical
|
|
450
|
+
* ```
|
|
451
|
+
*
|
|
452
|
+
* @since 2.2.0-develop.1
|
|
453
|
+
*/
|
|
454
|
+
source(source: null | string): this;
|
|
455
|
+
source(source?: null | string): null | string | this {
|
|
456
|
+
if (source === undefined) {
|
|
457
|
+
return this.data.source;
|
|
458
|
+
}
|
|
329
459
|
|
|
460
|
+
this.data.source = source || null;
|
|
461
|
+
return this;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Get the current calendar timezone
|
|
465
|
+
* @since 0.2.0
|
|
466
|
+
*/
|
|
467
|
+
timezone(): null | string;
|
|
468
|
+
/**
|
|
469
|
+
* Use this method to set your feed's timezone. Is used
|
|
470
|
+
* to fill `TIMEZONE-ID` and `X-WR-TIMEZONE` in your iCal export.
|
|
471
|
+
* Please not that all date values are treaded differently, if
|
|
472
|
+
* a timezone was set. See {@link formatDate} for details. If no
|
|
473
|
+
* time zone is specified, all information is output as UTC.
|
|
474
|
+
*
|
|
475
|
+
* ```javascript
|
|
476
|
+
* cal.timezone('America/New_York');
|
|
477
|
+
* ```
|
|
478
|
+
*
|
|
479
|
+
* @see https://github.com/sebbo2002/ical-generator#-date-time--timezones
|
|
480
|
+
* @since 0.2.0
|
|
481
|
+
*/
|
|
482
|
+
timezone(timezone: null | string): this;
|
|
330
483
|
/**
|
|
331
484
|
* Sets the time zone to be used in this calendar file for all times of all
|
|
332
485
|
* events. Please note that if the time zone is set, ical-generator assumes
|
|
@@ -361,130 +514,150 @@ export default class ICalCalendar {
|
|
|
361
514
|
* @see https://github.com/sebbo2002/ical-generator#-date-time--timezones
|
|
362
515
|
* @since 2.0.0
|
|
363
516
|
*/
|
|
364
|
-
timezone(timezone: ICalTimezone |
|
|
365
|
-
timezone(timezone?: ICalTimezone |
|
|
517
|
+
timezone(timezone: ICalTimezone | null | string): this;
|
|
518
|
+
timezone(timezone?: ICalTimezone | null | string): null | string | this {
|
|
366
519
|
if (timezone === undefined) {
|
|
367
520
|
return this.data.timezone?.name || null;
|
|
368
521
|
}
|
|
369
522
|
|
|
370
|
-
if(timezone === 'UTC') {
|
|
523
|
+
if (timezone === 'UTC') {
|
|
371
524
|
this.data.timezone = null;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
else if(timezone === null) {
|
|
525
|
+
} else if (typeof timezone === 'string') {
|
|
526
|
+
this.data.timezone = { name: timezone };
|
|
527
|
+
} else if (timezone === null) {
|
|
377
528
|
this.data.timezone = null;
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
529
|
+
} else {
|
|
380
530
|
this.data.timezone = timezone;
|
|
381
531
|
}
|
|
382
532
|
|
|
383
533
|
return this;
|
|
384
534
|
}
|
|
385
535
|
|
|
386
|
-
|
|
387
536
|
/**
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
|
|
391
|
-
source(): string | null;
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Use this method to set your feed's `SOURCE` attribute.
|
|
395
|
-
* This tells the client where to refresh your feed.
|
|
537
|
+
* Return a shallow copy of the calendar's options for JSON stringification.
|
|
538
|
+
* Third party objects like moment.js values or RRule objects are stringified
|
|
539
|
+
* as well. Can be used for persistence.
|
|
396
540
|
*
|
|
397
541
|
* ```javascript
|
|
398
|
-
* cal
|
|
399
|
-
*
|
|
542
|
+
* const cal = ical();
|
|
543
|
+
* const json = JSON.stringify(cal);
|
|
400
544
|
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
545
|
+
* // later: restore calendar data
|
|
546
|
+
* cal = ical(JSON.parse(json));
|
|
403
547
|
* ```
|
|
404
548
|
*
|
|
405
|
-
* @since
|
|
549
|
+
* @since 0.2.4
|
|
406
550
|
*/
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
this.data.source = source || null;
|
|
414
|
-
return this;
|
|
551
|
+
toJSON(): ICalCalendarJSONData {
|
|
552
|
+
return Object.assign({}, this.data, {
|
|
553
|
+
events: this.data.events.map((event) => event.toJSON()),
|
|
554
|
+
timezone: this.timezone(),
|
|
555
|
+
x: this.x(),
|
|
556
|
+
});
|
|
415
557
|
}
|
|
416
558
|
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Get your feed's URL
|
|
420
|
-
* @since 0.2.5
|
|
421
|
-
*/
|
|
422
|
-
url(): string | null;
|
|
423
|
-
|
|
424
559
|
/**
|
|
425
|
-
*
|
|
560
|
+
* Return generated calendar as a string.
|
|
426
561
|
*
|
|
427
562
|
* ```javascript
|
|
428
|
-
*
|
|
563
|
+
* const cal = ical();
|
|
564
|
+
* console.log(cal.toString()); // → BEGIN:VCALENDAR…
|
|
429
565
|
* ```
|
|
430
|
-
*
|
|
431
|
-
* @since 0.2.5
|
|
432
566
|
*/
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
567
|
+
toString(): string {
|
|
568
|
+
let g = '';
|
|
569
|
+
|
|
570
|
+
// VCALENDAR and VERSION
|
|
571
|
+
g = 'BEGIN:VCALENDAR\r\nVERSION:2.0\r\n';
|
|
572
|
+
|
|
573
|
+
// PRODID
|
|
574
|
+
g += 'PRODID:-' + this.data.prodId + '\r\n';
|
|
575
|
+
|
|
576
|
+
// URL
|
|
577
|
+
if (this.data.url) {
|
|
578
|
+
g += 'URL:' + this.data.url + '\r\n';
|
|
437
579
|
}
|
|
438
580
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
581
|
+
// SOURCE
|
|
582
|
+
if (this.data.source) {
|
|
583
|
+
g += 'SOURCE;VALUE=URI:' + this.data.source + '\r\n';
|
|
584
|
+
}
|
|
442
585
|
|
|
586
|
+
// CALSCALE
|
|
587
|
+
if (this.data.scale) {
|
|
588
|
+
g += 'CALSCALE:' + this.data.scale + '\r\n';
|
|
589
|
+
}
|
|
443
590
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
*
|
|
449
|
-
* @since 1.8.0
|
|
450
|
-
*/
|
|
451
|
-
scale(): string | null;
|
|
591
|
+
// METHOD
|
|
592
|
+
if (this.data.method) {
|
|
593
|
+
g += 'METHOD:' + this.data.method + '\r\n';
|
|
594
|
+
}
|
|
452
595
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
* no value is present.
|
|
458
|
-
*
|
|
459
|
-
* ```javascript
|
|
460
|
-
* cal.scale('gregorian');
|
|
461
|
-
* ```
|
|
462
|
-
*
|
|
463
|
-
* @since 1.8.0
|
|
464
|
-
*/
|
|
465
|
-
scale(scale: string | null): this;
|
|
466
|
-
scale(scale?: string | null): this | string | null {
|
|
467
|
-
if (scale === undefined) {
|
|
468
|
-
return this.data.scale;
|
|
596
|
+
// NAME
|
|
597
|
+
if (this.data.name) {
|
|
598
|
+
g += 'NAME:' + this.data.name + '\r\n';
|
|
599
|
+
g += 'X-WR-CALNAME:' + this.data.name + '\r\n';
|
|
469
600
|
}
|
|
470
601
|
|
|
471
|
-
|
|
472
|
-
|
|
602
|
+
// Description
|
|
603
|
+
if (this.data.description) {
|
|
604
|
+
g += 'X-WR-CALDESC:' + this.data.description + '\r\n';
|
|
473
605
|
}
|
|
474
|
-
|
|
475
|
-
|
|
606
|
+
|
|
607
|
+
// Timezone
|
|
608
|
+
if (this.data.timezone?.generator) {
|
|
609
|
+
const timezones = [
|
|
610
|
+
...new Set([
|
|
611
|
+
this.timezone(),
|
|
612
|
+
...this.data.events.map((event) => event.timezone()),
|
|
613
|
+
]),
|
|
614
|
+
].filter((tz) => tz !== null && !tz.startsWith('/')) as string[];
|
|
615
|
+
|
|
616
|
+
timezones.forEach((tz) => {
|
|
617
|
+
if (!this.data.timezone?.generator) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const s = this.data.timezone.generator(tz);
|
|
622
|
+
if (!s) {
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
g +=
|
|
627
|
+
s.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n').trim() +
|
|
628
|
+
'\r\n';
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
if (this.data.timezone?.name) {
|
|
632
|
+
g += 'TIMEZONE-ID:' + this.data.timezone.name + '\r\n';
|
|
633
|
+
g += 'X-WR-TIMEZONE:' + this.data.timezone.name + '\r\n';
|
|
476
634
|
}
|
|
477
635
|
|
|
478
|
-
|
|
479
|
-
|
|
636
|
+
// TTL
|
|
637
|
+
if (this.data.ttl) {
|
|
638
|
+
g +=
|
|
639
|
+
'REFRESH-INTERVAL;VALUE=DURATION:' +
|
|
640
|
+
toDurationString(this.data.ttl) +
|
|
641
|
+
'\r\n';
|
|
642
|
+
g += 'X-PUBLISHED-TTL:' + toDurationString(this.data.ttl) + '\r\n';
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Events
|
|
646
|
+
this.data.events.forEach((event) => (g += event.toString()));
|
|
647
|
+
|
|
648
|
+
// CUSTOM X ATTRIBUTES
|
|
649
|
+
g += generateCustomAttributes(this.data);
|
|
650
|
+
|
|
651
|
+
g += 'END:VCALENDAR';
|
|
480
652
|
|
|
653
|
+
return foldLines(g);
|
|
654
|
+
}
|
|
481
655
|
|
|
482
656
|
/**
|
|
483
657
|
* Get the current ttl duration in seconds
|
|
484
658
|
* @since 0.2.5
|
|
485
659
|
*/
|
|
486
|
-
ttl():
|
|
487
|
-
|
|
660
|
+
ttl(): null | number;
|
|
488
661
|
/**
|
|
489
662
|
* Use this method to set your feed's time to live
|
|
490
663
|
* (in seconds). Is used to fill `REFRESH-INTERVAL` and
|
|
@@ -499,119 +672,46 @@ export default class ICalCalendar {
|
|
|
499
672
|
*
|
|
500
673
|
* @since 0.2.5
|
|
501
674
|
*/
|
|
502
|
-
ttl(ttl:
|
|
503
|
-
ttl(ttl?:
|
|
675
|
+
ttl(ttl: ICalMomentDurationStub | null | number): this;
|
|
676
|
+
ttl(ttl?: ICalMomentDurationStub | null | number): null | number | this {
|
|
504
677
|
if (ttl === undefined) {
|
|
505
678
|
return this.data.ttl;
|
|
506
679
|
}
|
|
507
680
|
|
|
508
681
|
if (isMomentDuration(ttl)) {
|
|
509
682
|
this.data.ttl = ttl.asSeconds();
|
|
510
|
-
}
|
|
511
|
-
else if (ttl && ttl > 0) {
|
|
683
|
+
} else if (ttl && ttl > 0) {
|
|
512
684
|
this.data.ttl = ttl;
|
|
513
|
-
}
|
|
514
|
-
else {
|
|
685
|
+
} else {
|
|
515
686
|
this.data.ttl = null;
|
|
516
687
|
}
|
|
517
688
|
|
|
518
689
|
return this;
|
|
519
690
|
}
|
|
520
691
|
|
|
521
|
-
|
|
522
692
|
/**
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
* ```javascript
|
|
527
|
-
* import ical from 'ical-generator';
|
|
528
|
-
*
|
|
529
|
-
* // or use require:
|
|
530
|
-
* // const { default: ical } = require('ical-generator');
|
|
531
|
-
*
|
|
532
|
-
* const cal = ical();
|
|
533
|
-
* const event = cal.createEvent({summary: 'My Event'});
|
|
534
|
-
*
|
|
535
|
-
* // overwrite event summary
|
|
536
|
-
* event.summary('Your Event');
|
|
537
|
-
* ```
|
|
538
|
-
*
|
|
539
|
-
* @since 0.2.0
|
|
540
|
-
*/
|
|
541
|
-
createEvent(data: ICalEvent | ICalEventData): ICalEvent {
|
|
542
|
-
const event = data instanceof ICalEvent ? data : new ICalEvent(data, this);
|
|
543
|
-
this.data.events.push(event);
|
|
544
|
-
return event;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Returns all events of this calendar.
|
|
550
|
-
*
|
|
551
|
-
* ```javascript
|
|
552
|
-
* const cal = ical();
|
|
553
|
-
*
|
|
554
|
-
* cal.events([
|
|
555
|
-
* {
|
|
556
|
-
* start: new Date(),
|
|
557
|
-
* end: new Date(new Date().getTime() + 3600000),
|
|
558
|
-
* summary: 'Example Event',
|
|
559
|
-
* description: 'It works ;)',
|
|
560
|
-
* url: 'http://sebbo.net/'
|
|
561
|
-
* }
|
|
562
|
-
* ]);
|
|
563
|
-
*
|
|
564
|
-
* cal.events(); // --> [ICalEvent]
|
|
565
|
-
* ```
|
|
566
|
-
*
|
|
567
|
-
* @since 0.2.0
|
|
693
|
+
* Get your feed's URL
|
|
694
|
+
* @since 0.2.5
|
|
568
695
|
*/
|
|
569
|
-
|
|
570
|
-
|
|
696
|
+
url(): null | string;
|
|
571
697
|
/**
|
|
572
|
-
*
|
|
698
|
+
* Set your feed's URL
|
|
573
699
|
*
|
|
574
700
|
* ```javascript
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
* cal.events([
|
|
578
|
-
* {
|
|
579
|
-
* start: new Date(),
|
|
580
|
-
* end: new Date(new Date().getTime() + 3600000),
|
|
581
|
-
* summary: 'Example Event',
|
|
582
|
-
* description: 'It works ;)',
|
|
583
|
-
* url: 'http://sebbo.net/'
|
|
584
|
-
* }
|
|
585
|
-
* ]);
|
|
586
|
-
*
|
|
587
|
-
* cal.events(); // --> [ICalEvent]
|
|
701
|
+
* calendar.url('http://example.com/my/feed.ical');
|
|
588
702
|
* ```
|
|
589
703
|
*
|
|
590
|
-
* @since 0.2.
|
|
704
|
+
* @since 0.2.5
|
|
591
705
|
*/
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
if (
|
|
595
|
-
return this.data.
|
|
706
|
+
url(url: null | string): this;
|
|
707
|
+
url(url?: null | string): null | string | this {
|
|
708
|
+
if (url === undefined) {
|
|
709
|
+
return this.data.url;
|
|
596
710
|
}
|
|
597
711
|
|
|
598
|
-
|
|
599
|
-
return this;
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
/**
|
|
604
|
-
* Remove all events from the calendar without
|
|
605
|
-
* touching any other data like name or prodId.
|
|
606
|
-
*
|
|
607
|
-
* @since 2.0.0-develop.1
|
|
608
|
-
*/
|
|
609
|
-
clear(): this {
|
|
610
|
-
this.data.events = [];
|
|
712
|
+
this.data.url = url || null;
|
|
611
713
|
return this;
|
|
612
714
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
715
|
/**
|
|
616
716
|
* Set X-* attributes. Woun't filter double attributes,
|
|
617
717
|
* which are also added by another method (e.g. busystatus),
|
|
@@ -644,8 +744,12 @@ export default class ICalCalendar {
|
|
|
644
744
|
*
|
|
645
745
|
* @since 1.9.0
|
|
646
746
|
*/
|
|
647
|
-
x
|
|
648
|
-
|
|
747
|
+
x(
|
|
748
|
+
keyOrArray:
|
|
749
|
+
| [string, string][]
|
|
750
|
+
| Record<string, string>
|
|
751
|
+
| { key: string; value: string }[],
|
|
752
|
+
): this;
|
|
649
753
|
/**
|
|
650
754
|
* Set a X-* attribute. Woun't filter double attributes,
|
|
651
755
|
* which are also added by another method (e.g. busystatus),
|
|
@@ -665,153 +769,32 @@ export default class ICalCalendar {
|
|
|
665
769
|
*
|
|
666
770
|
* @since 1.9.0
|
|
667
771
|
*/
|
|
668
|
-
x
|
|
669
|
-
|
|
772
|
+
x(keyOrArray: string, value: string): this;
|
|
670
773
|
/**
|
|
671
774
|
* Get all custom X-* attributes.
|
|
672
775
|
* @since 1.9.0
|
|
673
776
|
*/
|
|
674
|
-
x
|
|
675
|
-
x
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
addOrGetCustomAttributes
|
|
685
|
-
}
|
|
686
|
-
|
|
777
|
+
x(): { key: string; value: string }[];
|
|
778
|
+
x(
|
|
779
|
+
keyOrArray?:
|
|
780
|
+
| [string, string][]
|
|
781
|
+
| Record<string, string>
|
|
782
|
+
| string
|
|
783
|
+
| { key: string; value: string }[],
|
|
784
|
+
value?: string,
|
|
785
|
+
): this | void | { key: string; value: string }[] {
|
|
786
|
+
if (keyOrArray === undefined) {
|
|
787
|
+
return addOrGetCustomAttributes(this.data);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
if (typeof keyOrArray === 'string' && typeof value === 'string') {
|
|
791
|
+
addOrGetCustomAttributes(this.data, keyOrArray, value);
|
|
792
|
+
} else if (typeof keyOrArray === 'object') {
|
|
793
|
+
addOrGetCustomAttributes(this.data, keyOrArray);
|
|
794
|
+
} else {
|
|
687
795
|
throw new Error('Either key or value is not a string!');
|
|
688
796
|
}
|
|
689
797
|
|
|
690
798
|
return this;
|
|
691
799
|
}
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
/**
|
|
695
|
-
* Return a shallow copy of the calendar's options for JSON stringification.
|
|
696
|
-
* Third party objects like moment.js values or RRule objects are stringified
|
|
697
|
-
* as well. Can be used for persistence.
|
|
698
|
-
*
|
|
699
|
-
* ```javascript
|
|
700
|
-
* const cal = ical();
|
|
701
|
-
* const json = JSON.stringify(cal);
|
|
702
|
-
*
|
|
703
|
-
* // later: restore calendar data
|
|
704
|
-
* cal = ical(JSON.parse(json));
|
|
705
|
-
* ```
|
|
706
|
-
*
|
|
707
|
-
* @since 0.2.4
|
|
708
|
-
*/
|
|
709
|
-
toJSON(): ICalCalendarJSONData {
|
|
710
|
-
return Object.assign({}, this.data, {
|
|
711
|
-
timezone: this.timezone(),
|
|
712
|
-
events: this.data.events.map(event => event.toJSON()),
|
|
713
|
-
x: this.x()
|
|
714
|
-
});
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Get the number of events added to your calendar
|
|
720
|
-
*/
|
|
721
|
-
length(): number {
|
|
722
|
-
return this.data.events.length;
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
/**
|
|
727
|
-
* Return generated calendar as a string.
|
|
728
|
-
*
|
|
729
|
-
* ```javascript
|
|
730
|
-
* const cal = ical();
|
|
731
|
-
* console.log(cal.toString()); // → BEGIN:VCALENDAR…
|
|
732
|
-
* ```
|
|
733
|
-
*/
|
|
734
|
-
toString(): string {
|
|
735
|
-
let g = '';
|
|
736
|
-
|
|
737
|
-
// VCALENDAR and VERSION
|
|
738
|
-
g = 'BEGIN:VCALENDAR\r\nVERSION:2.0\r\n';
|
|
739
|
-
|
|
740
|
-
// PRODID
|
|
741
|
-
g += 'PRODID:-' + this.data.prodId + '\r\n';
|
|
742
|
-
|
|
743
|
-
// URL
|
|
744
|
-
if (this.data.url) {
|
|
745
|
-
g += 'URL:' + this.data.url + '\r\n';
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// SOURCE
|
|
749
|
-
if (this.data.source) {
|
|
750
|
-
g += 'SOURCE;VALUE=URI:' + this.data.source + '\r\n';
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
// CALSCALE
|
|
754
|
-
if (this.data.scale) {
|
|
755
|
-
g += 'CALSCALE:' + this.data.scale + '\r\n';
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// METHOD
|
|
759
|
-
if (this.data.method) {
|
|
760
|
-
g += 'METHOD:' + this.data.method + '\r\n';
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// NAME
|
|
764
|
-
if (this.data.name) {
|
|
765
|
-
g += 'NAME:' + this.data.name + '\r\n';
|
|
766
|
-
g += 'X-WR-CALNAME:' + this.data.name + '\r\n';
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
// Description
|
|
770
|
-
if (this.data.description) {
|
|
771
|
-
g += 'X-WR-CALDESC:' + this.data.description + '\r\n';
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Timezone
|
|
775
|
-
if(this.data.timezone?.generator) {
|
|
776
|
-
const timezones = [...new Set([
|
|
777
|
-
this.timezone(),
|
|
778
|
-
...this.data.events.map(event => event.timezone())
|
|
779
|
-
])].filter(tz => tz !== null && !tz.startsWith('/')) as string[];
|
|
780
|
-
|
|
781
|
-
timezones.forEach(tz => {
|
|
782
|
-
if(!this.data.timezone?.generator) {
|
|
783
|
-
return;
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
const s = this.data.timezone.generator(tz);
|
|
787
|
-
if(!s) {
|
|
788
|
-
return;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
g += s.replace(/\r\n/g, '\n')
|
|
792
|
-
.replace(/\n/g, '\r\n')
|
|
793
|
-
.trim() + '\r\n';
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
if (this.data.timezone?.name) {
|
|
797
|
-
g += 'TIMEZONE-ID:' + this.data.timezone.name + '\r\n';
|
|
798
|
-
g += 'X-WR-TIMEZONE:' + this.data.timezone.name + '\r\n';
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
// TTL
|
|
802
|
-
if (this.data.ttl) {
|
|
803
|
-
g += 'REFRESH-INTERVAL;VALUE=DURATION:' + toDurationString(this.data.ttl) + '\r\n';
|
|
804
|
-
g += 'X-PUBLISHED-TTL:' + toDurationString(this.data.ttl) + '\r\n';
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
// Events
|
|
808
|
-
this.data.events.forEach(event => g += event.toString());
|
|
809
|
-
|
|
810
|
-
// CUSTOM X ATTRIBUTES
|
|
811
|
-
g += generateCustomAttributes(this.data);
|
|
812
|
-
|
|
813
|
-
g += 'END:VCALENDAR';
|
|
814
|
-
|
|
815
|
-
return foldLines(g);
|
|
816
|
-
}
|
|
817
800
|
}
|