ical-generator 8.1.2-develop.9 → 9.0.0-develop.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/README.md +13 -19
- package/dist/index.cjs +7 -7
- 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 +126 -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 +1293 -1118
- package/src/index.ts +19 -25
- package/src/tools.ts +348 -258
- package/src/types.ts +86 -75
package/src/event.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
import uuid from 'uuid-random';
|
|
4
|
+
|
|
5
|
+
import ICalAlarm, { type ICalAlarmData } from './alarm.ts';
|
|
6
|
+
import ICalAttendee, { type ICalAttendeeData } from './attendee.ts';
|
|
7
|
+
import ICalCalendar from './calendar.ts';
|
|
8
|
+
import ICalCategory, { type ICalCategoryData } from './category.ts';
|
|
4
9
|
import {
|
|
5
10
|
addOrGetCustomAttributes,
|
|
6
11
|
checkDate,
|
|
@@ -12,150 +17,147 @@ import {
|
|
|
12
17
|
generateCustomAttributes,
|
|
13
18
|
isRRule,
|
|
14
19
|
toDate,
|
|
15
|
-
toJSON
|
|
20
|
+
toJSON,
|
|
16
21
|
} from './tools.ts';
|
|
17
|
-
import ICalAttendee, { type ICalAttendeeData } from './attendee.ts';
|
|
18
|
-
import ICalAlarm, { type ICalAlarmData } from './alarm.ts';
|
|
19
|
-
import ICalCategory, { type ICalCategoryData } from './category.ts';
|
|
20
|
-
import ICalCalendar from './calendar.ts';
|
|
21
22
|
import {
|
|
22
|
-
ICalEventRepeatingFreq,
|
|
23
|
-
ICalWeekday,
|
|
24
23
|
type ICalDateTimeValue,
|
|
25
24
|
type ICalDescription,
|
|
25
|
+
ICalEventRepeatingFreq,
|
|
26
26
|
type ICalLocation,
|
|
27
27
|
type ICalOrganizer,
|
|
28
|
+
type ICalRepeatingOptions,
|
|
28
29
|
type ICalRRuleStub,
|
|
29
|
-
|
|
30
|
+
ICalWeekday,
|
|
30
31
|
} from './types.ts';
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
export enum ICalEventBusyStatus {
|
|
34
|
+
BUSY = 'BUSY',
|
|
35
|
+
FREE = 'FREE',
|
|
36
|
+
OOF = 'OOF',
|
|
35
37
|
TENTATIVE = 'TENTATIVE',
|
|
36
|
-
CANCELLED = 'CANCELLED'
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
export enum
|
|
40
|
-
|
|
40
|
+
export enum ICalEventClass {
|
|
41
|
+
CONFIDENTIAL = 'CONFIDENTIAL',
|
|
42
|
+
PRIVATE = 'PRIVATE',
|
|
43
|
+
PUBLIC = 'PUBLIC',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export enum ICalEventStatus {
|
|
47
|
+
CANCELLED = 'CANCELLED',
|
|
48
|
+
CONFIRMED = 'CONFIRMED',
|
|
41
49
|
TENTATIVE = 'TENTATIVE',
|
|
42
|
-
BUSY = 'BUSY',
|
|
43
|
-
OOF = 'OOF'
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
export enum ICalEventTransparency {
|
|
53
|
+
OPAQUE = 'OPAQUE',
|
|
47
54
|
TRANSPARENT = 'TRANSPARENT',
|
|
48
|
-
OPAQUE = 'OPAQUE'
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export enum ICalEventClass {
|
|
52
|
-
PUBLIC = 'PUBLIC',
|
|
53
|
-
PRIVATE = 'PRIVATE',
|
|
54
|
-
CONFIDENTIAL = 'CONFIDENTIAL'
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export interface ICalEventData {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
stamp?: ICalDateTimeValue,
|
|
65
|
-
allDay?: boolean,
|
|
66
|
-
floating?: boolean,
|
|
67
|
-
repeating?: ICalRepeatingOptions | ICalRRuleStub | string | null,
|
|
68
|
-
summary?: string,
|
|
69
|
-
location?: ICalLocation | string | null,
|
|
70
|
-
description?: ICalDescription | string | null,
|
|
71
|
-
organizer?: ICalOrganizer | string | null,
|
|
72
|
-
attendees?: ICalAttendee[] | ICalAttendeeData[],
|
|
73
|
-
alarms?: ICalAlarm[] | ICalAlarmData[],
|
|
74
|
-
categories?: ICalCategory[] | ICalCategoryData[],
|
|
75
|
-
status?: ICalEventStatus | null,
|
|
76
|
-
busystatus?: ICalEventBusyStatus | null,
|
|
77
|
-
priority?: number | null,
|
|
78
|
-
url?: string | null,
|
|
79
|
-
attachments?: string[],
|
|
80
|
-
transparency?: ICalEventTransparency | null,
|
|
81
|
-
created?: ICalDateTimeValue | null,
|
|
82
|
-
lastModified?: ICalDateTimeValue | null,
|
|
58
|
+
alarms?: ICalAlarm[] | ICalAlarmData[];
|
|
59
|
+
allDay?: boolean;
|
|
60
|
+
attachments?: string[];
|
|
61
|
+
attendees?: ICalAttendee[] | ICalAttendeeData[];
|
|
62
|
+
busystatus?: ICalEventBusyStatus | null;
|
|
63
|
+
categories?: ICalCategory[] | ICalCategoryData[];
|
|
83
64
|
class?: ICalEventClass | null;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
id
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
priority: number | null,
|
|
108
|
-
url: string | null,
|
|
109
|
-
attachments: string[],
|
|
110
|
-
transparency: ICalEventTransparency | null,
|
|
111
|
-
created: ICalDateTimeValue | null,
|
|
112
|
-
lastModified: ICalDateTimeValue | null,
|
|
113
|
-
class: ICalEventClass | null,
|
|
114
|
-
x: [string, string][];
|
|
65
|
+
created?: ICalDateTimeValue | null;
|
|
66
|
+
description?: ICalDescription | null | string;
|
|
67
|
+
end?: ICalDateTimeValue | null;
|
|
68
|
+
floating?: boolean;
|
|
69
|
+
id?: null | number | string;
|
|
70
|
+
lastModified?: ICalDateTimeValue | null;
|
|
71
|
+
location?: ICalLocation | null | string;
|
|
72
|
+
organizer?: ICalOrganizer | null | string;
|
|
73
|
+
priority?: null | number;
|
|
74
|
+
recurrenceId?: ICalDateTimeValue | null;
|
|
75
|
+
repeating?: ICalRepeatingOptions | ICalRRuleStub | null | string;
|
|
76
|
+
sequence?: number;
|
|
77
|
+
stamp?: ICalDateTimeValue;
|
|
78
|
+
start: ICalDateTimeValue;
|
|
79
|
+
status?: ICalEventStatus | null;
|
|
80
|
+
summary?: string;
|
|
81
|
+
timezone?: null | string;
|
|
82
|
+
transparency?: ICalEventTransparency | null;
|
|
83
|
+
url?: null | string;
|
|
84
|
+
x?:
|
|
85
|
+
| [string, string][]
|
|
86
|
+
| Record<string, string>
|
|
87
|
+
| { key: string; value: string }[];
|
|
115
88
|
}
|
|
116
89
|
|
|
117
90
|
export interface ICalEventJSONData {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
organizer: ICalOrganizer | null
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
x: {key: string
|
|
91
|
+
alarms: ICalAlarm[];
|
|
92
|
+
allDay: boolean;
|
|
93
|
+
attachments: string[];
|
|
94
|
+
attendees: ICalAttendee[];
|
|
95
|
+
busystatus: ICalEventBusyStatus | null;
|
|
96
|
+
categories: ICalCategory[];
|
|
97
|
+
created: null | string;
|
|
98
|
+
description: ICalDescription | null;
|
|
99
|
+
end: null | string;
|
|
100
|
+
floating: boolean;
|
|
101
|
+
id: string;
|
|
102
|
+
lastModified: null | string;
|
|
103
|
+
location: ICalLocation | null;
|
|
104
|
+
organizer: ICalOrganizer | null;
|
|
105
|
+
priority?: null | number;
|
|
106
|
+
recurrenceId: null | string;
|
|
107
|
+
repeating: ICalEventJSONRepeatingData | null | string;
|
|
108
|
+
sequence: number;
|
|
109
|
+
stamp: string;
|
|
110
|
+
start: string;
|
|
111
|
+
status: ICalEventStatus | null;
|
|
112
|
+
summary: string;
|
|
113
|
+
timezone: null | string;
|
|
114
|
+
transparency: ICalEventTransparency | null;
|
|
115
|
+
url: null | string;
|
|
116
|
+
x: { key: string; value: string }[];
|
|
144
117
|
}
|
|
145
118
|
|
|
146
119
|
export interface ICalEventJSONRepeatingData {
|
|
147
|
-
freq: ICalEventRepeatingFreq;
|
|
148
|
-
count?: number;
|
|
149
|
-
interval?: number;
|
|
150
|
-
until?: ICalDateTimeValue;
|
|
151
120
|
byDay?: ICalWeekday[];
|
|
152
121
|
byMonth?: number[];
|
|
153
122
|
byMonthDay?: number[];
|
|
154
123
|
bySetPos?: number[];
|
|
124
|
+
count?: number;
|
|
155
125
|
exclude?: ICalDateTimeValue[];
|
|
126
|
+
freq: ICalEventRepeatingFreq;
|
|
127
|
+
interval?: number;
|
|
156
128
|
startOfWeek?: ICalWeekday;
|
|
129
|
+
until?: ICalDateTimeValue;
|
|
157
130
|
}
|
|
158
131
|
|
|
132
|
+
interface ICalEventInternalData {
|
|
133
|
+
alarms: ICalAlarm[];
|
|
134
|
+
allDay: boolean;
|
|
135
|
+
attachments: string[];
|
|
136
|
+
attendees: ICalAttendee[];
|
|
137
|
+
busystatus: ICalEventBusyStatus | null;
|
|
138
|
+
categories: ICalCategory[];
|
|
139
|
+
class: ICalEventClass | null;
|
|
140
|
+
created: ICalDateTimeValue | null;
|
|
141
|
+
description: ICalDescription | null;
|
|
142
|
+
end: ICalDateTimeValue | null;
|
|
143
|
+
floating: boolean;
|
|
144
|
+
id: string;
|
|
145
|
+
lastModified: ICalDateTimeValue | null;
|
|
146
|
+
location: ICalLocation | null;
|
|
147
|
+
organizer: ICalOrganizer | null;
|
|
148
|
+
priority: null | number;
|
|
149
|
+
recurrenceId: ICalDateTimeValue | null;
|
|
150
|
+
repeating: ICalEventJSONRepeatingData | ICalRRuleStub | null | string;
|
|
151
|
+
sequence: number;
|
|
152
|
+
stamp: ICalDateTimeValue;
|
|
153
|
+
start: ICalDateTimeValue;
|
|
154
|
+
status: ICalEventStatus | null;
|
|
155
|
+
summary: string;
|
|
156
|
+
timezone: null | string;
|
|
157
|
+
transparency: ICalEventTransparency | null;
|
|
158
|
+
url: null | string;
|
|
159
|
+
x: [string, string][];
|
|
160
|
+
}
|
|
159
161
|
|
|
160
162
|
/**
|
|
161
163
|
* Usually you get an {@link ICalEvent} object like this:
|
|
@@ -166,8 +168,8 @@ export interface ICalEventJSONRepeatingData {
|
|
|
166
168
|
* ```
|
|
167
169
|
*/
|
|
168
170
|
export default class ICalEvent {
|
|
169
|
-
private readonly data: ICalEventInternalData;
|
|
170
171
|
private readonly calendar: ICalCalendar;
|
|
172
|
+
private readonly data: ICalEventInternalData;
|
|
171
173
|
|
|
172
174
|
/**
|
|
173
175
|
* Constructor of [[`ICalEvent`]. The calendar reference is
|
|
@@ -178,33 +180,33 @@ export default class ICalEvent {
|
|
|
178
180
|
*/
|
|
179
181
|
constructor(data: ICalEventData, calendar: ICalCalendar) {
|
|
180
182
|
this.data = {
|
|
181
|
-
|
|
182
|
-
sequence: 0,
|
|
183
|
-
start: new Date(),
|
|
184
|
-
end: null,
|
|
185
|
-
recurrenceId: null,
|
|
186
|
-
timezone: null,
|
|
187
|
-
stamp: new Date(),
|
|
183
|
+
alarms: [],
|
|
188
184
|
allDay: false,
|
|
185
|
+
attachments: [],
|
|
186
|
+
attendees: [],
|
|
187
|
+
busystatus: null,
|
|
188
|
+
categories: [],
|
|
189
|
+
class: null,
|
|
190
|
+
created: null,
|
|
191
|
+
description: null,
|
|
192
|
+
end: null,
|
|
189
193
|
floating: false,
|
|
190
|
-
|
|
191
|
-
|
|
194
|
+
id: uuid(),
|
|
195
|
+
lastModified: null,
|
|
192
196
|
location: null,
|
|
193
|
-
description: null,
|
|
194
197
|
organizer: null,
|
|
195
|
-
attendees: [],
|
|
196
|
-
alarms: [],
|
|
197
|
-
categories: [],
|
|
198
|
-
status: null,
|
|
199
|
-
busystatus: null,
|
|
200
198
|
priority: null,
|
|
201
|
-
|
|
202
|
-
|
|
199
|
+
recurrenceId: null,
|
|
200
|
+
repeating: null,
|
|
201
|
+
sequence: 0,
|
|
202
|
+
stamp: new Date(),
|
|
203
|
+
start: new Date(),
|
|
204
|
+
status: null,
|
|
205
|
+
summary: '',
|
|
206
|
+
timezone: null,
|
|
203
207
|
transparency: null,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
class: null,
|
|
207
|
-
x: []
|
|
208
|
+
url: null,
|
|
209
|
+
x: [],
|
|
208
210
|
};
|
|
209
211
|
|
|
210
212
|
this.calendar = calendar;
|
|
@@ -216,7 +218,8 @@ export default class ICalEvent {
|
|
|
216
218
|
if (data.sequence !== undefined) this.sequence(data.sequence);
|
|
217
219
|
if (data.start) this.start(data.start);
|
|
218
220
|
if (data.end !== undefined) this.end(data.end);
|
|
219
|
-
if (data.recurrenceId !== undefined)
|
|
221
|
+
if (data.recurrenceId !== undefined)
|
|
222
|
+
this.recurrenceId(data.recurrenceId);
|
|
220
223
|
if (data.timezone !== undefined) this.timezone(data.timezone);
|
|
221
224
|
if (data.stamp !== undefined) this.stamp(data.stamp);
|
|
222
225
|
if (data.allDay !== undefined) this.allDay(data.allDay);
|
|
@@ -234,109 +237,71 @@ export default class ICalEvent {
|
|
|
234
237
|
if (data.priority !== undefined) this.priority(data.priority);
|
|
235
238
|
if (data.url !== undefined) this.url(data.url);
|
|
236
239
|
if (data.attachments !== undefined) this.attachments(data.attachments);
|
|
237
|
-
if (data.transparency !== undefined)
|
|
240
|
+
if (data.transparency !== undefined)
|
|
241
|
+
this.transparency(data.transparency);
|
|
238
242
|
if (data.created !== undefined) this.created(data.created);
|
|
239
|
-
if (data.lastModified !== undefined)
|
|
243
|
+
if (data.lastModified !== undefined)
|
|
244
|
+
this.lastModified(data.lastModified);
|
|
240
245
|
if (data.class !== undefined) this.class(data.class);
|
|
241
246
|
if (data.x !== undefined) this.x(data.x);
|
|
242
247
|
}
|
|
243
248
|
|
|
244
249
|
/**
|
|
245
|
-
* Get
|
|
250
|
+
* Get all alarms
|
|
246
251
|
* @since 0.2.0
|
|
247
252
|
*/
|
|
248
|
-
|
|
249
|
-
|
|
253
|
+
alarms(): ICalAlarm[];
|
|
250
254
|
/**
|
|
251
|
-
*
|
|
252
|
-
* If not set, a UUID will be generated randomly.
|
|
255
|
+
* Add one or multiple alarms
|
|
253
256
|
*
|
|
254
|
-
*
|
|
255
|
-
|
|
256
|
-
id(id: string | number): this;
|
|
257
|
-
id(id?: string | number): this | string {
|
|
258
|
-
if (id === undefined) {
|
|
259
|
-
return this.data.id;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
this.data.id = String(id);
|
|
263
|
-
return this;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Get the event's ID
|
|
268
|
-
* @since 0.2.0
|
|
269
|
-
* @see {@link id}
|
|
270
|
-
*/
|
|
271
|
-
uid(): string;
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Use this method to set the event's ID.
|
|
275
|
-
* If not set, a UUID will be generated randomly.
|
|
257
|
+
* ```javascript
|
|
258
|
+
* const event = ical().createEvent();
|
|
276
259
|
*
|
|
277
|
-
*
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return id === undefined ? this.id() : this.id(id);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Get the event's SEQUENCE number. Use this method to get the event's
|
|
286
|
-
* revision sequence number of the calendar component within a sequence of revisions.
|
|
260
|
+
* cal.alarms([
|
|
261
|
+
* {type: ICalAlarmType.display, trigger: 600},
|
|
262
|
+
* {type: ICalAlarmType.audio, trigger: 300}
|
|
263
|
+
* ]);
|
|
287
264
|
*
|
|
288
|
-
*
|
|
289
|
-
|
|
290
|
-
sequence(): number;
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Set the event's SEQUENCE number. For a new event, this should be zero.
|
|
294
|
-
* Each time the organizer makes a significant revision, the sequence
|
|
295
|
-
* number should be incremented.
|
|
265
|
+
* cal.alarms(); // --> [ICalAlarm, ICalAlarm]
|
|
266
|
+
```
|
|
296
267
|
*
|
|
297
|
-
* @
|
|
268
|
+
* @since 0.2.0
|
|
298
269
|
*/
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (
|
|
302
|
-
return this.data.
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const s = parseInt(String(sequence), 10);
|
|
306
|
-
if (isNaN(s)) {
|
|
307
|
-
throw new Error('`sequence` must be a number!');
|
|
270
|
+
alarms(alarms: ICalAlarm[] | ICalAlarmData[]): this;
|
|
271
|
+
alarms(alarms?: ICalAlarm[] | ICalAlarmData[]): ICalAlarm[] | this {
|
|
272
|
+
if (!alarms) {
|
|
273
|
+
return this.data.alarms;
|
|
308
274
|
}
|
|
309
275
|
|
|
310
|
-
|
|
276
|
+
alarms.forEach((alarm: ICalAlarm | ICalAlarmData) =>
|
|
277
|
+
this.createAlarm(alarm),
|
|
278
|
+
);
|
|
311
279
|
return this;
|
|
312
280
|
}
|
|
313
281
|
|
|
314
282
|
/**
|
|
315
|
-
* Get the event
|
|
316
|
-
* set. Can be any supported date object.
|
|
317
|
-
*
|
|
283
|
+
* Get the event's allDay flag
|
|
318
284
|
* @since 0.2.0
|
|
319
285
|
*/
|
|
320
|
-
|
|
321
|
-
|
|
286
|
+
allDay(): boolean;
|
|
322
287
|
/**
|
|
323
|
-
* Set the
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
288
|
+
* Set the event's allDay flag.
|
|
289
|
+
*
|
|
290
|
+
* ```javascript
|
|
291
|
+
* event.allDay(true); // → appointment is for the whole day
|
|
292
|
+
* ```
|
|
327
293
|
*
|
|
328
294
|
* ```typescript
|
|
329
295
|
* import ical from 'ical-generator';
|
|
330
296
|
*
|
|
331
297
|
* const cal = ical();
|
|
332
298
|
*
|
|
333
|
-
*
|
|
334
|
-
* start: new Date('2020-01-01')
|
|
299
|
+
* cal.createEvent({
|
|
300
|
+
* start: new Date('2020-01-01'),
|
|
301
|
+
* summary: 'Very Important Day',
|
|
302
|
+
* allDay: true
|
|
335
303
|
* });
|
|
336
304
|
*
|
|
337
|
-
* // overwrites old start date
|
|
338
|
-
* event.start(new Date('2024-02-01'));
|
|
339
|
-
*
|
|
340
305
|
* cal.toString();
|
|
341
306
|
* ```
|
|
342
307
|
*
|
|
@@ -345,272 +310,254 @@ export default class ICalEvent {
|
|
|
345
310
|
* VERSION:2.0
|
|
346
311
|
* PRODID:-//sebbo.net//ical-generator//EN
|
|
347
312
|
* BEGIN:VEVENT
|
|
348
|
-
* UID:
|
|
313
|
+
* UID:1964fe8d-32c5-4f2a-bd62-7d9d7de5992b
|
|
349
314
|
* SEQUENCE:0
|
|
350
|
-
* DTSTAMP:
|
|
351
|
-
* DTSTART:
|
|
352
|
-
*
|
|
315
|
+
* DTSTAMP:20240212T191956Z
|
|
316
|
+
* DTSTART;VALUE=DATE:20200101
|
|
317
|
+
* X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
|
|
318
|
+
* X-MICROSOFT-MSNCALENDAR-ALLDAYEVENT:TRUE
|
|
319
|
+
* SUMMARY:Very Important Day
|
|
353
320
|
* END:VEVENT
|
|
354
321
|
* END:VCALENDAR
|
|
355
322
|
* ```
|
|
356
323
|
*
|
|
357
324
|
* @since 0.2.0
|
|
358
325
|
*/
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (
|
|
362
|
-
this.
|
|
363
|
-
return this.data.start;
|
|
326
|
+
allDay(allDay: boolean): this;
|
|
327
|
+
allDay(allDay?: boolean): boolean | this {
|
|
328
|
+
if (allDay === undefined) {
|
|
329
|
+
return this.data.allDay;
|
|
364
330
|
}
|
|
365
331
|
|
|
366
|
-
this.data.
|
|
332
|
+
this.data.allDay = Boolean(allDay);
|
|
367
333
|
return this;
|
|
368
334
|
}
|
|
369
335
|
|
|
370
336
|
/**
|
|
371
|
-
* Get
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
* @since 0.2.0
|
|
337
|
+
* Get all attachment urls
|
|
338
|
+
* @since 3.2.0-develop.1
|
|
375
339
|
*/
|
|
376
|
-
|
|
377
|
-
|
|
340
|
+
attachments(): string[];
|
|
378
341
|
/**
|
|
379
|
-
*
|
|
380
|
-
* [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
381
|
-
* for details about supported values and timezone handling.
|
|
342
|
+
* Add one or multiple alarms
|
|
382
343
|
*
|
|
383
|
-
*
|
|
344
|
+
* ```javascript
|
|
345
|
+
* const event = ical().createEvent();
|
|
346
|
+
*
|
|
347
|
+
* cal.attachments([
|
|
348
|
+
* 'https://files.sebbo.net/calendar/attachments/foo',
|
|
349
|
+
* 'https://files.sebbo.net/calendar/attachments/bar'
|
|
350
|
+
* ]);
|
|
351
|
+
*
|
|
352
|
+
* cal.attachments(); // --> [string, string]
|
|
353
|
+
```
|
|
354
|
+
*
|
|
355
|
+
* 3.2.0-develop.1
|
|
384
356
|
*/
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
if (
|
|
388
|
-
this.
|
|
389
|
-
return this.data.end;
|
|
390
|
-
}
|
|
391
|
-
if (end === null) {
|
|
392
|
-
this.data.end = null;
|
|
393
|
-
return this;
|
|
357
|
+
attachments(attachments: string[]): this;
|
|
358
|
+
attachments(attachments?: string[]): string[] | this {
|
|
359
|
+
if (!attachments) {
|
|
360
|
+
return this.data.attachments;
|
|
394
361
|
}
|
|
395
362
|
|
|
396
|
-
|
|
363
|
+
attachments.forEach((attachment: string) =>
|
|
364
|
+
this.createAttachment(attachment),
|
|
365
|
+
);
|
|
397
366
|
return this;
|
|
398
367
|
}
|
|
399
368
|
|
|
400
369
|
/**
|
|
401
|
-
*
|
|
402
|
-
* @private
|
|
403
|
-
*/
|
|
404
|
-
private swapStartAndEndIfRequired(): void {
|
|
405
|
-
if (this.data.start && this.data.end && toDate(this.data.start).getTime() > toDate(this.data.end).getTime()) {
|
|
406
|
-
const t = this.data.start;
|
|
407
|
-
this.data.start = this.data.end;
|
|
408
|
-
this.data.end = t;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Get the event's recurrence id
|
|
370
|
+
* Get all attendees
|
|
414
371
|
* @since 0.2.0
|
|
415
372
|
*/
|
|
416
|
-
|
|
417
|
-
|
|
373
|
+
attendees(): ICalAttendee[];
|
|
418
374
|
/**
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
375
|
+
* Add multiple attendees to your event
|
|
376
|
+
*
|
|
377
|
+
* ```javascript
|
|
378
|
+
* const event = ical().createEvent();
|
|
379
|
+
*
|
|
380
|
+
* cal.attendees([
|
|
381
|
+
* {email: 'a@example.com', name: 'Person A'},
|
|
382
|
+
* {email: 'b@example.com', name: 'Person B'}
|
|
383
|
+
* ]);
|
|
384
|
+
*
|
|
385
|
+
* cal.attendees(); // --> [ICalAttendee, ICalAttendee]
|
|
386
|
+
* ```
|
|
422
387
|
*
|
|
423
388
|
* @since 0.2.0
|
|
424
389
|
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
this.data.recurrenceId = null;
|
|
432
|
-
return this;
|
|
390
|
+
attendees(attendees: (ICalAttendee | ICalAttendeeData | string)[]): this;
|
|
391
|
+
attendees(
|
|
392
|
+
attendees?: (ICalAttendee | ICalAttendeeData | string)[],
|
|
393
|
+
): ICalAttendee[] | this {
|
|
394
|
+
if (!attendees) {
|
|
395
|
+
return this.data.attendees;
|
|
433
396
|
}
|
|
434
397
|
|
|
435
|
-
|
|
398
|
+
attendees.forEach((attendee) => this.createAttendee(attendee));
|
|
436
399
|
return this;
|
|
437
400
|
}
|
|
438
401
|
|
|
439
402
|
/**
|
|
440
|
-
* Get the event's
|
|
441
|
-
* @since 0.2
|
|
403
|
+
* Get the event's busy status
|
|
404
|
+
* @since 1.0.2
|
|
442
405
|
*/
|
|
443
|
-
|
|
444
|
-
|
|
406
|
+
busystatus(): ICalEventBusyStatus | null;
|
|
445
407
|
/**
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
* Please note that if the time zone is set, ical-generator assumes
|
|
451
|
-
* that all times are already in the correct time zone. Alternatively,
|
|
452
|
-
* a `moment-timezone` or a Luxon object can be passed with `setZone`,
|
|
453
|
-
* ical-generator will then set the time zone itself.
|
|
454
|
-
*
|
|
455
|
-
* This and the 'floating' flag (see below) are mutually exclusive, and setting a timezone will unset the
|
|
456
|
-
* 'floating' flag. If neither 'timezone' nor 'floating' are set, the date will be output with in UTC format
|
|
457
|
-
* (see [date-time form #2 in section 3.3.5 of RFC 554](https://tools.ietf.org/html/rfc5545#section-3.3.5)).
|
|
458
|
-
*
|
|
459
|
-
* See [Readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones) for details about
|
|
460
|
-
* supported values and timezone handling.
|
|
408
|
+
* Set the event's busy status. Will add the
|
|
409
|
+
* [`X-MICROSOFT-CDO-BUSYSTATUS`](https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/cd68eae7-ed65-4dd3-8ea7-ad585c76c736)
|
|
410
|
+
* attribute to your event.
|
|
461
411
|
*
|
|
462
412
|
* ```javascript
|
|
463
|
-
*
|
|
413
|
+
* import ical, {ICalEventBusyStatus} from 'ical-generator';
|
|
414
|
+
* event.busystatus(ICalEventBusyStatus.BUSY);
|
|
464
415
|
* ```
|
|
465
416
|
*
|
|
466
|
-
* @
|
|
467
|
-
* @since 0.2.6
|
|
417
|
+
* @since 1.0.2
|
|
468
418
|
*/
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
return this.calendar.timezone();
|
|
419
|
+
busystatus(busystatus: ICalEventBusyStatus | null): this;
|
|
420
|
+
busystatus(
|
|
421
|
+
busystatus?: ICalEventBusyStatus | null,
|
|
422
|
+
): ICalEventBusyStatus | null | this {
|
|
423
|
+
if (busystatus === undefined) {
|
|
424
|
+
return this.data.busystatus;
|
|
476
425
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
this.data.floating = false;
|
|
426
|
+
if (busystatus === null) {
|
|
427
|
+
this.data.busystatus = null;
|
|
428
|
+
return this;
|
|
481
429
|
}
|
|
482
430
|
|
|
431
|
+
this.data.busystatus = checkEnum(
|
|
432
|
+
ICalEventBusyStatus,
|
|
433
|
+
busystatus,
|
|
434
|
+
) as ICalEventBusyStatus;
|
|
483
435
|
return this;
|
|
484
436
|
}
|
|
485
437
|
|
|
486
438
|
/**
|
|
487
|
-
* Get
|
|
488
|
-
* @since 0.
|
|
489
|
-
* @see {@link timestamp}
|
|
439
|
+
* Get all categories
|
|
440
|
+
* @since 0.3.0
|
|
490
441
|
*/
|
|
491
|
-
|
|
492
|
-
|
|
442
|
+
categories(): ICalCategory[];
|
|
493
443
|
/**
|
|
494
|
-
*
|
|
495
|
-
* any supported date object, see [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
496
|
-
* for details about supported values and timezone handling.
|
|
444
|
+
* Add categories to the event or return all selected categories.
|
|
497
445
|
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
446
|
+
* ```javascript
|
|
447
|
+
* const event = ical().createEvent();
|
|
448
|
+
*
|
|
449
|
+
* cal.categories([
|
|
450
|
+
* {name: 'APPOINTMENT'},
|
|
451
|
+
* {name: 'MEETING'}
|
|
452
|
+
* ]);
|
|
453
|
+
*
|
|
454
|
+
* cal.categories(); // --> [ICalCategory, ICalCategory]
|
|
455
|
+
* ```
|
|
456
|
+
*
|
|
457
|
+
* @since 0.3.0
|
|
500
458
|
*/
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
459
|
+
categories(categories: (ICalCategory | ICalCategoryData)[]): this;
|
|
460
|
+
categories(
|
|
461
|
+
categories?: (ICalCategory | ICalCategoryData)[],
|
|
462
|
+
): ICalCategory[] | this {
|
|
463
|
+
if (!categories) {
|
|
464
|
+
return this.data.categories;
|
|
505
465
|
}
|
|
506
466
|
|
|
507
|
-
|
|
467
|
+
categories.forEach((category) => this.createCategory(category));
|
|
508
468
|
return this;
|
|
509
469
|
}
|
|
510
|
-
|
|
511
470
|
/**
|
|
512
|
-
* Get the event's
|
|
513
|
-
* @since
|
|
514
|
-
* @see {@link stamp}
|
|
471
|
+
* Get the event's class
|
|
472
|
+
* @since 2.0.0
|
|
515
473
|
*/
|
|
516
|
-
|
|
517
|
-
|
|
474
|
+
class(): ICalEventClass | null;
|
|
518
475
|
/**
|
|
519
|
-
* Set the
|
|
520
|
-
* any supported date object, see [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
521
|
-
* for details about supported values and timezone handling.
|
|
476
|
+
* Set the event's class
|
|
522
477
|
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
478
|
+
* ```javascript
|
|
479
|
+
* import ical, { ICalEventClass } from 'ical-generator';
|
|
480
|
+
* event.class(ICalEventClass.PRIVATE);
|
|
481
|
+
* ```
|
|
482
|
+
*
|
|
483
|
+
* @since 2.0.0
|
|
525
484
|
*/
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (
|
|
529
|
-
return this.
|
|
485
|
+
class(class_: ICalEventClass | null): this;
|
|
486
|
+
class(class_?: ICalEventClass | null): ICalEventClass | null | this {
|
|
487
|
+
if (class_ === undefined) {
|
|
488
|
+
return this.data.class;
|
|
489
|
+
}
|
|
490
|
+
if (class_ === null) {
|
|
491
|
+
this.data.class = null;
|
|
492
|
+
return this;
|
|
530
493
|
}
|
|
531
494
|
|
|
532
|
-
|
|
495
|
+
this.data.class = checkEnum(ICalEventClass, class_) as ICalEventClass;
|
|
496
|
+
return this;
|
|
533
497
|
}
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* Get the event's allDay flag
|
|
537
|
-
* @since 0.2.0
|
|
538
|
-
*/
|
|
539
|
-
allDay(): boolean;
|
|
540
|
-
|
|
541
498
|
/**
|
|
542
|
-
*
|
|
499
|
+
* Creates a new {@link ICalAlarm} and returns it. Use options to prefill
|
|
500
|
+
* the alarm's attributes. Calling this method without options will create
|
|
501
|
+
* an empty alarm.
|
|
543
502
|
*
|
|
544
503
|
* ```javascript
|
|
545
|
-
* event.allDay(true); // → appointment is for the whole day
|
|
546
|
-
* ```
|
|
547
|
-
*
|
|
548
|
-
* ```typescript
|
|
549
|
-
* import ical from 'ical-generator';
|
|
550
|
-
*
|
|
551
504
|
* const cal = ical();
|
|
505
|
+
* const event = cal.createEvent();
|
|
506
|
+
* const alarm = event.createAlarm({type: ICalAlarmType.display, trigger: 300});
|
|
552
507
|
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
508
|
+
* // add another alarm
|
|
509
|
+
* event.createAlarm({
|
|
510
|
+
* type: ICalAlarmType.audio,
|
|
511
|
+
* trigger: 300, // 5min before event
|
|
557
512
|
* });
|
|
558
|
-
*
|
|
559
|
-
* cal.toString();
|
|
560
|
-
* ```
|
|
561
|
-
*
|
|
562
|
-
* ```text
|
|
563
|
-
* BEGIN:VCALENDAR
|
|
564
|
-
* VERSION:2.0
|
|
565
|
-
* PRODID:-//sebbo.net//ical-generator//EN
|
|
566
|
-
* BEGIN:VEVENT
|
|
567
|
-
* UID:1964fe8d-32c5-4f2a-bd62-7d9d7de5992b
|
|
568
|
-
* SEQUENCE:0
|
|
569
|
-
* DTSTAMP:20240212T191956Z
|
|
570
|
-
* DTSTART;VALUE=DATE:20200101
|
|
571
|
-
* X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
|
|
572
|
-
* X-MICROSOFT-MSNCALENDAR-ALLDAYEVENT:TRUE
|
|
573
|
-
* SUMMARY:Very Important Day
|
|
574
|
-
* END:VEVENT
|
|
575
|
-
* END:VCALENDAR
|
|
576
513
|
* ```
|
|
577
514
|
*
|
|
578
|
-
* @since 0.2.
|
|
515
|
+
* @since 0.2.1
|
|
579
516
|
*/
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
this.data.allDay = Boolean(allDay);
|
|
587
|
-
return this;
|
|
517
|
+
createAlarm(data: ICalAlarm | ICalAlarmData): ICalAlarm {
|
|
518
|
+
const alarm =
|
|
519
|
+
data instanceof ICalAlarm ? data : new ICalAlarm(data, this);
|
|
520
|
+
this.data.alarms.push(alarm);
|
|
521
|
+
return alarm;
|
|
588
522
|
}
|
|
589
523
|
|
|
590
524
|
/**
|
|
591
|
-
*
|
|
592
|
-
*
|
|
525
|
+
* Adds an attachment to the event by adding the file URL to the calendar.
|
|
526
|
+
*
|
|
527
|
+
* `ical-generator` only supports external attachments. File attachments that
|
|
528
|
+
* are directly included in the file are not supported, because otherwise the
|
|
529
|
+
* calendar file could easily become unfavourably large.
|
|
530
|
+
*
|
|
531
|
+
* ```javascript
|
|
532
|
+
* const cal = ical();
|
|
533
|
+
* const event = cal.createEvent();
|
|
534
|
+
* event.createAttachment('https://files.sebbo.net/calendar/attachments/foo');
|
|
535
|
+
* ```
|
|
536
|
+
*
|
|
537
|
+
* @since 3.2.0-develop.1
|
|
593
538
|
*/
|
|
594
|
-
|
|
595
|
-
|
|
539
|
+
createAttachment(url: string): this {
|
|
540
|
+
this.data.attachments.push(url);
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
596
543
|
|
|
597
544
|
/**
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
545
|
+
* Creates a new {@link ICalAttendee} and returns it. Use options to prefill
|
|
546
|
+
* the attendee's attributes. Calling this method without options will create
|
|
547
|
+
* an empty attendee.
|
|
601
548
|
*
|
|
602
|
-
* ```
|
|
549
|
+
* ```javascript
|
|
603
550
|
* import ical from 'ical-generator';
|
|
604
551
|
*
|
|
605
552
|
* const cal = ical();
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
* start: new Date('2020-01-01T20:00:00Z'),
|
|
609
|
-
* summary: 'Always at 20:00 in every <Timezone',
|
|
610
|
-
* floating: true
|
|
553
|
+
* const event = cal.createEvent({
|
|
554
|
+
* start: new Date()
|
|
611
555
|
* });
|
|
612
556
|
*
|
|
613
|
-
*
|
|
557
|
+
* event.createAttendee({email: 'hui@example.com', name: 'Hui'});
|
|
558
|
+
*
|
|
559
|
+
* // add another attendee
|
|
560
|
+
* event.createAttendee('Buh <buh@example.net>');
|
|
614
561
|
* ```
|
|
615
562
|
*
|
|
616
563
|
* ```text
|
|
@@ -618,117 +565,188 @@ export default class ICalEvent {
|
|
|
618
565
|
* VERSION:2.0
|
|
619
566
|
* PRODID:-//sebbo.net//ical-generator//EN
|
|
620
567
|
* BEGIN:VEVENT
|
|
621
|
-
* UID:
|
|
568
|
+
* UID:b4944f07-98e4-4581-ac80-2589bb20273d
|
|
622
569
|
* SEQUENCE:0
|
|
623
|
-
* DTSTAMP:
|
|
624
|
-
* DTSTART:
|
|
625
|
-
* SUMMARY:
|
|
570
|
+
* DTSTAMP:20240212T194232Z
|
|
571
|
+
* DTSTART:20240212T194232Z
|
|
572
|
+
* SUMMARY:
|
|
573
|
+
* ATTENDEE;ROLE=REQ-PARTICIPANT;CN="Hui":MAILTO:hui@example.com
|
|
574
|
+
* ATTENDEE;ROLE=REQ-PARTICIPANT;CN="Buh":MAILTO:buh@example.net
|
|
626
575
|
* END:VEVENT
|
|
627
576
|
* END:VCALENDAR
|
|
628
577
|
* ```
|
|
629
578
|
*
|
|
579
|
+
* As with the organizer, you can also add an explicit `mailto` address.
|
|
580
|
+
*
|
|
581
|
+
* ```javascript
|
|
582
|
+
* event.createAttendee({email: 'hui@example.com', name: 'Hui', mailto: 'another@mailto.com'});
|
|
583
|
+
*
|
|
584
|
+
* // overwrite an attendee's mailto address
|
|
585
|
+
* attendee.mailto('another@mailto.net');
|
|
586
|
+
* ```
|
|
587
|
+
*
|
|
630
588
|
* @since 0.2.0
|
|
631
589
|
*/
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
590
|
+
createAttendee(
|
|
591
|
+
data: ICalAttendee | ICalAttendeeData | string,
|
|
592
|
+
): ICalAttendee {
|
|
593
|
+
if (data instanceof ICalAttendee) {
|
|
594
|
+
this.data.attendees.push(data);
|
|
595
|
+
return data;
|
|
596
|
+
}
|
|
597
|
+
if (typeof data === 'string') {
|
|
598
|
+
data = { email: data, ...checkNameAndMail('data', data) };
|
|
599
|
+
}
|
|
636
600
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
601
|
+
const attendee = new ICalAttendee(data, this);
|
|
602
|
+
this.data.attendees.push(attendee);
|
|
603
|
+
return attendee;
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Creates a new {@link ICalCategory} and returns it. Use options to prefill the category's attributes.
|
|
607
|
+
* Calling this method without options will create an empty category.
|
|
608
|
+
*
|
|
609
|
+
* ```javascript
|
|
610
|
+
* const cal = ical();
|
|
611
|
+
* const event = cal.createEvent();
|
|
612
|
+
* const category = event.createCategory({name: 'APPOINTMENT'});
|
|
613
|
+
*
|
|
614
|
+
* // add another category
|
|
615
|
+
* event.createCategory({
|
|
616
|
+
* name: 'MEETING'
|
|
617
|
+
* });
|
|
618
|
+
* ```
|
|
619
|
+
*
|
|
620
|
+
* @since 0.3.0
|
|
621
|
+
*/
|
|
622
|
+
createCategory(data: ICalCategory | ICalCategoryData): ICalCategory {
|
|
623
|
+
const category =
|
|
624
|
+
data instanceof ICalCategory ? data : new ICalCategory(data);
|
|
625
|
+
this.data.categories.push(category);
|
|
626
|
+
return category;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Get the event's creation date
|
|
631
|
+
* @since 0.3.0
|
|
632
|
+
*/
|
|
633
|
+
created(): ICalDateTimeValue | null;
|
|
634
|
+
/**
|
|
635
|
+
* Set the event's creation date
|
|
636
|
+
* @since 0.3.0
|
|
637
|
+
*/
|
|
638
|
+
created(created: ICalDateTimeValue | null): this;
|
|
639
|
+
created(
|
|
640
|
+
created?: ICalDateTimeValue | null,
|
|
641
|
+
): ICalDateTimeValue | null | this {
|
|
642
|
+
if (created === undefined) {
|
|
643
|
+
return this.data.created;
|
|
644
|
+
}
|
|
645
|
+
if (created === null) {
|
|
646
|
+
this.data.created = null;
|
|
647
|
+
return this;
|
|
640
648
|
}
|
|
641
649
|
|
|
650
|
+
this.data.created = checkDate(created, 'created');
|
|
642
651
|
return this;
|
|
643
652
|
}
|
|
644
653
|
|
|
645
654
|
/**
|
|
646
|
-
* Get the event's
|
|
655
|
+
* Get the event's description as an {@link ICalDescription} object.
|
|
647
656
|
* @since 0.2.0
|
|
648
657
|
*/
|
|
649
|
-
|
|
650
|
-
|
|
658
|
+
description(): ICalDescription | null;
|
|
651
659
|
/**
|
|
652
|
-
* Set the
|
|
660
|
+
* Set the events description by passing a plaintext string or
|
|
661
|
+
* an object containing both a plaintext and a html description.
|
|
662
|
+
* Only a few calendar apps support html descriptions and like in
|
|
663
|
+
* emails, supported HTML tags and styling is limited.
|
|
653
664
|
*
|
|
654
665
|
* ```javascript
|
|
655
|
-
* event.
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
* interval: 2,
|
|
659
|
-
* until: new Date('Jan 01 2014 00:00:00 UTC'),
|
|
660
|
-
* byDay: ['su', 'mo'], // repeat only sunday and monday
|
|
661
|
-
* byMonth: [1, 2], // repeat only in january and february,
|
|
662
|
-
* byMonthDay: [1, 15], // repeat only on the 1st and 15th
|
|
663
|
-
* bySetPos: 3, // repeat every 3rd sunday (will take the first element of the byDay array)
|
|
664
|
-
* exclude: [new Date('Dec 25 2013 00:00:00 UTC')], // exclude these dates
|
|
665
|
-
* excludeTimezone: 'Europe/Berlin', // timezone of exclude
|
|
666
|
-
* wkst: 'SU' // Start the week on Sunday, default is Monday
|
|
667
|
-
* });
|
|
668
|
-
* ```
|
|
669
|
-
*
|
|
670
|
-
* **Example:**
|
|
671
|
-
*
|
|
672
|
-
*```typescript
|
|
673
|
-
* import ical, { ICalEventRepeatingFreq } from 'ical-generator';
|
|
674
|
-
*
|
|
675
|
-
* const cal = ical();
|
|
676
|
-
*
|
|
677
|
-
* const event = cal.createEvent({
|
|
678
|
-
* start: new Date('2020-01-01T20:00:00Z'),
|
|
679
|
-
* summary: 'Repeating Event'
|
|
680
|
-
* });
|
|
681
|
-
* event.repeating({
|
|
682
|
-
* freq: ICalEventRepeatingFreq.WEEKLY,
|
|
683
|
-
* count: 4
|
|
666
|
+
* event.description({
|
|
667
|
+
* plain: 'Hello World!',
|
|
668
|
+
* html: '<p>Hello World!</p>'
|
|
684
669
|
* });
|
|
685
|
-
*
|
|
686
|
-
* cal.toString();
|
|
687
670
|
* ```
|
|
688
671
|
*
|
|
689
672
|
* ```text
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
* PRODID:-//sebbo.net//ical-generator//EN
|
|
693
|
-
* BEGIN:VEVENT
|
|
694
|
-
* UID:b80e6a68-c2cd-48f5-b94d-cecc7ce83871
|
|
695
|
-
* SEQUENCE:0
|
|
696
|
-
* DTSTAMP:20240212T193646Z
|
|
697
|
-
* DTSTART:20200101T200000Z
|
|
698
|
-
* RRULE:FREQ=WEEKLY;COUNT=4
|
|
699
|
-
* SUMMARY:Repeating Event
|
|
700
|
-
* END:VEVENT
|
|
701
|
-
* END:VCALENDAR
|
|
673
|
+
* DESCRIPTION:Hello World!
|
|
674
|
+
* X-ALT-DESC;FMTTYPE=text/html:<p>Hello World!</p>
|
|
702
675
|
* ```
|
|
703
676
|
*
|
|
704
677
|
* @since 0.2.0
|
|
705
678
|
*/
|
|
706
|
-
|
|
679
|
+
description(description: ICalDescription | null | string): this;
|
|
680
|
+
description(
|
|
681
|
+
description?: ICalDescription | null | string,
|
|
682
|
+
): ICalDescription | null | this {
|
|
683
|
+
if (description === undefined) {
|
|
684
|
+
return this.data.description;
|
|
685
|
+
}
|
|
686
|
+
if (description === null) {
|
|
687
|
+
this.data.description = null;
|
|
688
|
+
return this;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
if (typeof description === 'string') {
|
|
692
|
+
this.data.description = { plain: description };
|
|
693
|
+
} else {
|
|
694
|
+
this.data.description = description;
|
|
695
|
+
}
|
|
696
|
+
return this;
|
|
697
|
+
}
|
|
707
698
|
|
|
708
699
|
/**
|
|
709
|
-
*
|
|
710
|
-
*
|
|
700
|
+
* Get the event end time which is currently
|
|
701
|
+
* set. Can be any supported date object.
|
|
702
|
+
*
|
|
703
|
+
* @since 0.2.0
|
|
704
|
+
*/
|
|
705
|
+
end(): ICalDateTimeValue | null;
|
|
706
|
+
/**
|
|
707
|
+
* Set the appointment date of end. You can use any supported date object, see
|
|
708
|
+
* [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
709
|
+
* for details about supported values and timezone handling.
|
|
710
|
+
*
|
|
711
|
+
* @since 0.2.0
|
|
712
|
+
*/
|
|
713
|
+
end(end: ICalDateTimeValue | null): this;
|
|
714
|
+
end(end?: ICalDateTimeValue | null): ICalDateTimeValue | null | this {
|
|
715
|
+
if (end === undefined) {
|
|
716
|
+
this.swapStartAndEndIfRequired();
|
|
717
|
+
return this.data.end;
|
|
718
|
+
}
|
|
719
|
+
if (end === null) {
|
|
720
|
+
this.data.end = null;
|
|
721
|
+
return this;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
this.data.end = checkDate(end, 'end');
|
|
725
|
+
return this;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Get the event's floating flag.
|
|
730
|
+
* @since 0.2.0
|
|
731
|
+
*/
|
|
732
|
+
floating(): boolean;
|
|
733
|
+
floating(floating: boolean): this;
|
|
734
|
+
/**
|
|
735
|
+
* Set the event's floating flag. This unsets the event's timezone.
|
|
736
|
+
* Events whose floating flag is set to true always take place at the
|
|
737
|
+
* same time, regardless of the time zone.
|
|
711
738
|
*
|
|
712
739
|
* ```typescript
|
|
713
740
|
* import ical from 'ical-generator';
|
|
714
|
-
* import { datetime, RRule } from 'rrule';
|
|
715
741
|
*
|
|
716
742
|
* const cal = ical();
|
|
717
743
|
*
|
|
718
|
-
*
|
|
744
|
+
* cal.createEvent({
|
|
719
745
|
* start: new Date('2020-01-01T20:00:00Z'),
|
|
720
|
-
* summary: '
|
|
746
|
+
* summary: 'Always at 20:00 in every <Timezone',
|
|
747
|
+
* floating: true
|
|
721
748
|
* });
|
|
722
749
|
*
|
|
723
|
-
* const rule = new RRule({
|
|
724
|
-
* freq: RRule.WEEKLY,
|
|
725
|
-
* interval: 5,
|
|
726
|
-
* byweekday: [RRule.MO, RRule.FR],
|
|
727
|
-
* dtstart: datetime(2012, 2, 1, 10, 30),
|
|
728
|
-
* until: datetime(2012, 12, 31)
|
|
729
|
-
* })
|
|
730
|
-
* event.repeating(rule);
|
|
731
|
-
*
|
|
732
750
|
* cal.toString();
|
|
733
751
|
* ```
|
|
734
752
|
*
|
|
@@ -737,150 +755,81 @@ export default class ICalEvent {
|
|
|
737
755
|
* VERSION:2.0
|
|
738
756
|
* PRODID:-//sebbo.net//ical-generator//EN
|
|
739
757
|
* BEGIN:VEVENT
|
|
740
|
-
* UID:
|
|
758
|
+
* UID:5d7278f9-ada3-40ef-83d1-23c29ce0a763
|
|
741
759
|
* SEQUENCE:0
|
|
742
|
-
* DTSTAMP:
|
|
743
|
-
* DTSTART:
|
|
744
|
-
*
|
|
745
|
-
* SUMMARY:Repeating Event
|
|
760
|
+
* DTSTAMP:20240212T192214Z
|
|
761
|
+
* DTSTART:20200101T200000
|
|
762
|
+
* SUMMARY:Always at 20:00 in every <Timezone
|
|
746
763
|
* END:VEVENT
|
|
747
764
|
* END:VCALENDAR
|
|
748
765
|
* ```
|
|
766
|
+
*
|
|
767
|
+
* @since 0.2.0
|
|
749
768
|
*/
|
|
750
|
-
|
|
769
|
+
floating(floating?: boolean): boolean | this {
|
|
770
|
+
if (floating === undefined) {
|
|
771
|
+
return this.data.floating;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
this.data.floating = Boolean(floating);
|
|
775
|
+
if (this.data.floating) {
|
|
776
|
+
this.data.timezone = null;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return this;
|
|
780
|
+
}
|
|
751
781
|
|
|
752
782
|
/**
|
|
753
|
-
*
|
|
754
|
-
* @since 2.0
|
|
783
|
+
* Get the event's ID
|
|
784
|
+
* @since 0.2.0
|
|
755
785
|
*/
|
|
756
|
-
|
|
757
|
-
|
|
786
|
+
id(): string;
|
|
758
787
|
/**
|
|
759
|
-
*
|
|
788
|
+
* Use this method to set the event's ID.
|
|
789
|
+
* If not set, a UUID will be generated randomly.
|
|
790
|
+
*
|
|
791
|
+
* @param id Event ID you want to set
|
|
760
792
|
*/
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (
|
|
764
|
-
return this.data.
|
|
765
|
-
}
|
|
766
|
-
if (!repeating) {
|
|
767
|
-
this.data.repeating = null;
|
|
768
|
-
return this;
|
|
769
|
-
}
|
|
770
|
-
if(isRRule(repeating) || typeof repeating === 'string') {
|
|
771
|
-
this.data.repeating = repeating;
|
|
772
|
-
return this;
|
|
793
|
+
id(id: number | string): this;
|
|
794
|
+
id(id?: number | string): string | this {
|
|
795
|
+
if (id === undefined) {
|
|
796
|
+
return this.data.id;
|
|
773
797
|
}
|
|
774
798
|
|
|
775
|
-
this.data.
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
if (repeating.count) {
|
|
780
|
-
if (!isFinite(repeating.count)) {
|
|
781
|
-
throw new Error('`repeating.count` must be a finite number!');
|
|
782
|
-
}
|
|
799
|
+
this.data.id = String(id);
|
|
800
|
+
return this;
|
|
801
|
+
}
|
|
783
802
|
|
|
784
|
-
|
|
803
|
+
/**
|
|
804
|
+
* Get the event's last modification date
|
|
805
|
+
* @since 0.3.0
|
|
806
|
+
*/
|
|
807
|
+
lastModified(): ICalDateTimeValue | null;
|
|
808
|
+
/**
|
|
809
|
+
* Set the event's last modification date
|
|
810
|
+
* @since 0.3.0
|
|
811
|
+
*/
|
|
812
|
+
lastModified(lastModified: ICalDateTimeValue | null): this;
|
|
813
|
+
lastModified(
|
|
814
|
+
lastModified?: ICalDateTimeValue | null,
|
|
815
|
+
): ICalDateTimeValue | null | this {
|
|
816
|
+
if (lastModified === undefined) {
|
|
817
|
+
return this.data.lastModified;
|
|
785
818
|
}
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
throw new Error('`repeating.interval` must be a finite number!');
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
this.data.repeating.interval = repeating.interval;
|
|
819
|
+
if (lastModified === null) {
|
|
820
|
+
this.data.lastModified = null;
|
|
821
|
+
return this;
|
|
793
822
|
}
|
|
794
823
|
|
|
795
|
-
|
|
796
|
-
this.data.repeating.until = checkDate(repeating.until, 'repeating.until');
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
if (repeating.byDay) {
|
|
800
|
-
const byDayArray = Array.isArray(repeating.byDay) ? repeating.byDay : [repeating.byDay];
|
|
801
|
-
this.data.repeating.byDay = byDayArray.map(day => checkEnum(ICalWeekday, day) as ICalWeekday);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
if (repeating.byMonth) {
|
|
805
|
-
const byMonthArray = Array.isArray(repeating.byMonth) ? repeating.byMonth : [repeating.byMonth];
|
|
806
|
-
this.data.repeating.byMonth = byMonthArray.map(month => {
|
|
807
|
-
if (typeof month !== 'number' || month < 1 || month > 12) {
|
|
808
|
-
throw new Error('`repeating.byMonth` contains invalid value `' + month + '`!');
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
return month;
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (repeating.byMonthDay) {
|
|
816
|
-
const byMonthDayArray = Array.isArray(repeating.byMonthDay) ? repeating.byMonthDay : [repeating.byMonthDay];
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
this.data.repeating.byMonthDay = byMonthDayArray.map(monthDay => {
|
|
820
|
-
if (typeof monthDay !== 'number' || monthDay < -31 || monthDay > 31 || monthDay === 0) {
|
|
821
|
-
throw new Error('`repeating.byMonthDay` contains invalid value `' + monthDay + '`!');
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
return monthDay;
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
if (repeating.bySetPos) {
|
|
829
|
-
if (!this.data.repeating.byDay) {
|
|
830
|
-
throw '`repeating.bySetPos` must be used along with `repeating.byDay`!';
|
|
831
|
-
}
|
|
832
|
-
const bySetPosArray = Array.isArray(repeating.bySetPos) ? repeating.bySetPos : [repeating.bySetPos];
|
|
833
|
-
this.data.repeating.bySetPos = bySetPosArray.map(bySetPos => {
|
|
834
|
-
if (typeof bySetPos !== 'number' || bySetPos < -366 || bySetPos > 366 || bySetPos === 0) {
|
|
835
|
-
throw '`repeating.bySetPos` contains invalid value `' + bySetPos + '`!';
|
|
836
|
-
}
|
|
837
|
-
return bySetPos;
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
if (repeating.exclude) {
|
|
842
|
-
const excludeArray = Array.isArray(repeating.exclude) ? repeating.exclude : [repeating.exclude];
|
|
843
|
-
this.data.repeating.exclude = excludeArray.map((exclude, i) => {
|
|
844
|
-
return checkDate(exclude, `repeating.exclude[${i}]`);
|
|
845
|
-
});
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
if (repeating.startOfWeek) {
|
|
849
|
-
this.data.repeating.startOfWeek = checkEnum(ICalWeekday, repeating.startOfWeek) as ICalWeekday;
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
return this;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
/**
|
|
856
|
-
* Get the event's summary
|
|
857
|
-
* @since 0.2.0
|
|
858
|
-
*/
|
|
859
|
-
summary(): string;
|
|
860
|
-
|
|
861
|
-
/**
|
|
862
|
-
* Set the event's summary.
|
|
863
|
-
* Defaults to an empty string if nothing is set.
|
|
864
|
-
*
|
|
865
|
-
* @since 0.2.0
|
|
866
|
-
*/
|
|
867
|
-
summary(summary: string): this;
|
|
868
|
-
summary(summary?: string): this | string {
|
|
869
|
-
if (summary === undefined) {
|
|
870
|
-
return this.data.summary;
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
this.data.summary = summary ? String(summary) : '';
|
|
824
|
+
this.data.lastModified = checkDate(lastModified, 'lastModified');
|
|
874
825
|
return this;
|
|
875
826
|
}
|
|
876
827
|
|
|
877
|
-
|
|
878
828
|
/**
|
|
879
829
|
* Get the event's location
|
|
880
830
|
* @since 0.2.0
|
|
881
831
|
*/
|
|
882
832
|
location(): ICalLocation | null;
|
|
883
|
-
|
|
884
833
|
/**
|
|
885
834
|
* Set the event's location by passing a string (minimum) or
|
|
886
835
|
* an {@link ICalLocationWithTitle} object which will also fill the iCal
|
|
@@ -925,25 +874,32 @@ export default class ICalEvent {
|
|
|
925
874
|
*
|
|
926
875
|
* @since 0.2.0
|
|
927
876
|
*/
|
|
928
|
-
location(location: ICalLocation |
|
|
929
|
-
location(
|
|
877
|
+
location(location: ICalLocation | null | string): this;
|
|
878
|
+
location(
|
|
879
|
+
location?: ICalLocation | null | string,
|
|
880
|
+
): ICalLocation | null | this {
|
|
930
881
|
if (location === undefined) {
|
|
931
882
|
return this.data.location;
|
|
932
883
|
}
|
|
933
884
|
if (typeof location === 'string') {
|
|
934
885
|
this.data.location = {
|
|
935
|
-
title: location
|
|
886
|
+
title: location,
|
|
936
887
|
};
|
|
937
888
|
return this;
|
|
938
889
|
}
|
|
939
|
-
if (
|
|
940
|
-
|
|
941
|
-
(
|
|
942
|
-
|
|
943
|
-
|
|
890
|
+
if (
|
|
891
|
+
location &&
|
|
892
|
+
(('title' in location && !location.title) ||
|
|
893
|
+
(location?.geo &&
|
|
894
|
+
(typeof location.geo.lat !== 'number' ||
|
|
895
|
+
!isFinite(location.geo.lat) ||
|
|
896
|
+
typeof location.geo.lon !== 'number' ||
|
|
897
|
+
!isFinite(location.geo.lon))) ||
|
|
898
|
+
(!('title' in location) && !location?.geo))
|
|
899
|
+
) {
|
|
944
900
|
throw new Error(
|
|
945
|
-
|
|
946
|
-
|
|
901
|
+
"`location` isn't formatted correctly. See https://sebbo2002.github.io/ical-generator/" +
|
|
902
|
+
'develop/reference/classes/ICalEvent.html#location',
|
|
947
903
|
);
|
|
948
904
|
}
|
|
949
905
|
|
|
@@ -951,59 +907,11 @@ export default class ICalEvent {
|
|
|
951
907
|
return this;
|
|
952
908
|
}
|
|
953
909
|
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* Get the event's description as an {@link ICalDescription} object.
|
|
957
|
-
* @since 0.2.0
|
|
958
|
-
*/
|
|
959
|
-
description(): ICalDescription | null;
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
* Set the events description by passing a plaintext string or
|
|
963
|
-
* an object containing both a plaintext and a html description.
|
|
964
|
-
* Only a few calendar apps support html descriptions and like in
|
|
965
|
-
* emails, supported HTML tags and styling is limited.
|
|
966
|
-
*
|
|
967
|
-
* ```javascript
|
|
968
|
-
* event.description({
|
|
969
|
-
* plain: 'Hello World!',
|
|
970
|
-
* html: '<p>Hello World!</p>'
|
|
971
|
-
* });
|
|
972
|
-
* ```
|
|
973
|
-
*
|
|
974
|
-
* ```text
|
|
975
|
-
* DESCRIPTION:Hello World!
|
|
976
|
-
* X-ALT-DESC;FMTTYPE=text/html:<p>Hello World!</p>
|
|
977
|
-
* ```
|
|
978
|
-
*
|
|
979
|
-
* @since 0.2.0
|
|
980
|
-
*/
|
|
981
|
-
description(description: ICalDescription | string | null): this;
|
|
982
|
-
description(description?: ICalDescription | string | null): this | ICalDescription | null {
|
|
983
|
-
if (description === undefined) {
|
|
984
|
-
return this.data.description;
|
|
985
|
-
}
|
|
986
|
-
if (description === null) {
|
|
987
|
-
this.data.description = null;
|
|
988
|
-
return this;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
if (typeof description === 'string') {
|
|
992
|
-
this.data.description = {plain: description};
|
|
993
|
-
}
|
|
994
|
-
else {
|
|
995
|
-
this.data.description = description;
|
|
996
|
-
}
|
|
997
|
-
return this;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
910
|
/**
|
|
1002
911
|
* Get the event's organizer
|
|
1003
912
|
* @since 0.2.0
|
|
1004
913
|
*/
|
|
1005
914
|
organizer(): ICalOrganizer | null;
|
|
1006
|
-
|
|
1007
915
|
/**
|
|
1008
916
|
* Set the event's organizer
|
|
1009
917
|
*
|
|
@@ -1031,8 +939,10 @@ export default class ICalEvent {
|
|
|
1031
939
|
*
|
|
1032
940
|
* @since 0.2.0
|
|
1033
941
|
*/
|
|
1034
|
-
organizer(organizer: ICalOrganizer |
|
|
1035
|
-
organizer(
|
|
942
|
+
organizer(organizer: ICalOrganizer | null | string): this;
|
|
943
|
+
organizer(
|
|
944
|
+
organizer?: ICalOrganizer | null | string,
|
|
945
|
+
): ICalOrganizer | null | this {
|
|
1036
946
|
if (organizer === undefined) {
|
|
1037
947
|
return this.data.organizer;
|
|
1038
948
|
}
|
|
@@ -1045,566 +955,551 @@ export default class ICalEvent {
|
|
|
1045
955
|
return this;
|
|
1046
956
|
}
|
|
1047
957
|
|
|
1048
|
-
|
|
1049
958
|
/**
|
|
1050
|
-
*
|
|
1051
|
-
* the
|
|
1052
|
-
*
|
|
1053
|
-
*
|
|
1054
|
-
* ```javascript
|
|
1055
|
-
* import ical from 'ical-generator';
|
|
1056
|
-
*
|
|
1057
|
-
* const cal = ical();
|
|
1058
|
-
* const event = cal.createEvent({
|
|
1059
|
-
* start: new Date()
|
|
1060
|
-
* });
|
|
1061
|
-
*
|
|
1062
|
-
* event.createAttendee({email: 'hui@example.com', name: 'Hui'});
|
|
1063
|
-
*
|
|
1064
|
-
* // add another attendee
|
|
1065
|
-
* event.createAttendee('Buh <buh@example.net>');
|
|
1066
|
-
* ```
|
|
1067
|
-
*
|
|
1068
|
-
* ```text
|
|
1069
|
-
* BEGIN:VCALENDAR
|
|
1070
|
-
* VERSION:2.0
|
|
1071
|
-
* PRODID:-//sebbo.net//ical-generator//EN
|
|
1072
|
-
* BEGIN:VEVENT
|
|
1073
|
-
* UID:b4944f07-98e4-4581-ac80-2589bb20273d
|
|
1074
|
-
* SEQUENCE:0
|
|
1075
|
-
* DTSTAMP:20240212T194232Z
|
|
1076
|
-
* DTSTART:20240212T194232Z
|
|
1077
|
-
* SUMMARY:
|
|
1078
|
-
* ATTENDEE;ROLE=REQ-PARTICIPANT;CN="Hui":MAILTO:hui@example.com
|
|
1079
|
-
* ATTENDEE;ROLE=REQ-PARTICIPANT;CN="Buh":MAILTO:buh@example.net
|
|
1080
|
-
* END:VEVENT
|
|
1081
|
-
* END:VCALENDAR
|
|
1082
|
-
* ```
|
|
1083
|
-
*
|
|
1084
|
-
* As with the organizer, you can also add an explicit `mailto` address.
|
|
1085
|
-
*
|
|
1086
|
-
* ```javascript
|
|
1087
|
-
* event.createAttendee({email: 'hui@example.com', name: 'Hui', mailto: 'another@mailto.com'});
|
|
959
|
+
* Get the event's priority. A value of 1 represents
|
|
960
|
+
* the highest priority, 9 the lowest. 0 specifies an undefined
|
|
961
|
+
* priority.
|
|
1088
962
|
*
|
|
1089
|
-
*
|
|
1090
|
-
|
|
1091
|
-
|
|
963
|
+
* @since v2.0.0-develop.7
|
|
964
|
+
*/
|
|
965
|
+
priority(): null | number;
|
|
966
|
+
/**
|
|
967
|
+
* Set the event's priority. A value of 1 represents
|
|
968
|
+
* the highest priority, 9 the lowest. 0 specifies an undefined
|
|
969
|
+
* priority.
|
|
1092
970
|
*
|
|
1093
|
-
* @since 0.
|
|
971
|
+
* @since v2.0.0-develop.7
|
|
1094
972
|
*/
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
return data;
|
|
973
|
+
priority(priority: null | number): this;
|
|
974
|
+
priority(priority?: null | number): null | number | this {
|
|
975
|
+
if (priority === undefined) {
|
|
976
|
+
return this.data.priority;
|
|
1099
977
|
}
|
|
1100
|
-
if (
|
|
1101
|
-
data =
|
|
978
|
+
if (priority === null) {
|
|
979
|
+
this.data.priority = null;
|
|
980
|
+
return this;
|
|
1102
981
|
}
|
|
1103
982
|
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
983
|
+
if (priority < 0 || priority > 9) {
|
|
984
|
+
throw new Error(
|
|
985
|
+
'`priority` is invalid, musst be 0 ≤ priority ≤ 9.',
|
|
986
|
+
);
|
|
987
|
+
}
|
|
1108
988
|
|
|
989
|
+
this.data.priority = Math.round(priority);
|
|
990
|
+
return this;
|
|
991
|
+
}
|
|
1109
992
|
|
|
1110
993
|
/**
|
|
1111
|
-
* Get
|
|
994
|
+
* Get the event's recurrence id
|
|
1112
995
|
* @since 0.2.0
|
|
1113
996
|
*/
|
|
1114
|
-
|
|
1115
|
-
|
|
997
|
+
recurrenceId(): ICalDateTimeValue | null;
|
|
1116
998
|
/**
|
|
1117
|
-
*
|
|
1118
|
-
*
|
|
1119
|
-
*
|
|
1120
|
-
* const event = ical().createEvent();
|
|
1121
|
-
*
|
|
1122
|
-
* cal.attendees([
|
|
1123
|
-
* {email: 'a@example.com', name: 'Person A'},
|
|
1124
|
-
* {email: 'b@example.com', name: 'Person B'}
|
|
1125
|
-
* ]);
|
|
1126
|
-
*
|
|
1127
|
-
* cal.attendees(); // --> [ICalAttendee, ICalAttendee]
|
|
1128
|
-
* ```
|
|
999
|
+
* Set the event's recurrence id. You can use any supported date object, see
|
|
1000
|
+
* [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
1001
|
+
* for details about supported values and timezone handling.
|
|
1129
1002
|
*
|
|
1130
1003
|
* @since 0.2.0
|
|
1131
1004
|
*/
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1005
|
+
recurrenceId(recurrenceId: ICalDateTimeValue | null): this;
|
|
1006
|
+
recurrenceId(
|
|
1007
|
+
recurrenceId?: ICalDateTimeValue | null,
|
|
1008
|
+
): ICalDateTimeValue | null | this {
|
|
1009
|
+
if (recurrenceId === undefined) {
|
|
1010
|
+
return this.data.recurrenceId;
|
|
1011
|
+
}
|
|
1012
|
+
if (recurrenceId === null) {
|
|
1013
|
+
this.data.recurrenceId = null;
|
|
1014
|
+
return this;
|
|
1136
1015
|
}
|
|
1137
1016
|
|
|
1138
|
-
|
|
1017
|
+
this.data.recurrenceId = checkDate(recurrenceId, 'recurrenceId');
|
|
1139
1018
|
return this;
|
|
1140
1019
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
1020
|
/**
|
|
1144
|
-
*
|
|
1145
|
-
*
|
|
1146
|
-
|
|
1021
|
+
* Get the event's repeating options
|
|
1022
|
+
* @since 0.2.0
|
|
1023
|
+
*/
|
|
1024
|
+
repeating(): ICalEventJSONRepeatingData | ICalRRuleStub | null | string;
|
|
1025
|
+
/**
|
|
1026
|
+
* Set the event's repeating options by passing an {@link ICalRepeatingOptions} object.
|
|
1147
1027
|
*
|
|
1148
1028
|
* ```javascript
|
|
1149
|
-
*
|
|
1150
|
-
*
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1153
|
-
*
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1029
|
+
* event.repeating({
|
|
1030
|
+
* freq: 'MONTHLY', // required
|
|
1031
|
+
* count: 5,
|
|
1032
|
+
* interval: 2,
|
|
1033
|
+
* until: new Date('Jan 01 2014 00:00:00 UTC'),
|
|
1034
|
+
* byDay: ['su', 'mo'], // repeat only sunday and monday
|
|
1035
|
+
* byMonth: [1, 2], // repeat only in january and february,
|
|
1036
|
+
* byMonthDay: [1, 15], // repeat only on the 1st and 15th
|
|
1037
|
+
* bySetPos: 3, // repeat every 3rd sunday (will take the first element of the byDay array)
|
|
1038
|
+
* exclude: [new Date('Dec 25 2013 00:00:00 UTC')], // exclude these dates
|
|
1039
|
+
* excludeTimezone: 'Europe/Berlin', // timezone of exclude
|
|
1040
|
+
* wkst: 'SU' // Start the week on Sunday, default is Monday
|
|
1157
1041
|
* });
|
|
1158
1042
|
* ```
|
|
1159
1043
|
*
|
|
1160
|
-
*
|
|
1161
|
-
*/
|
|
1162
|
-
createAlarm(data: ICalAlarm | ICalAlarmData): ICalAlarm {
|
|
1163
|
-
const alarm = data instanceof ICalAlarm ? data : new ICalAlarm(data, this);
|
|
1164
|
-
this.data.alarms.push(alarm);
|
|
1165
|
-
return alarm;
|
|
1166
|
-
}
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
/**
|
|
1170
|
-
* Get all alarms
|
|
1171
|
-
* @since 0.2.0
|
|
1172
|
-
*/
|
|
1173
|
-
alarms(): ICalAlarm[];
|
|
1174
|
-
|
|
1175
|
-
/**
|
|
1176
|
-
* Add one or multiple alarms
|
|
1044
|
+
* **Example:**
|
|
1177
1045
|
*
|
|
1178
|
-
|
|
1179
|
-
*
|
|
1046
|
+
*```typescript
|
|
1047
|
+
* import ical, { ICalEventRepeatingFreq } from 'ical-generator';
|
|
1180
1048
|
*
|
|
1181
|
-
* cal
|
|
1182
|
-
* {type: ICalAlarmType.display, trigger: 600},
|
|
1183
|
-
* {type: ICalAlarmType.audio, trigger: 300}
|
|
1184
|
-
* ]);
|
|
1049
|
+
* const cal = ical();
|
|
1185
1050
|
*
|
|
1186
|
-
* cal.
|
|
1187
|
-
|
|
1051
|
+
* const event = cal.createEvent({
|
|
1052
|
+
* start: new Date('2020-01-01T20:00:00Z'),
|
|
1053
|
+
* summary: 'Repeating Event'
|
|
1054
|
+
* });
|
|
1055
|
+
* event.repeating({
|
|
1056
|
+
* freq: ICalEventRepeatingFreq.WEEKLY,
|
|
1057
|
+
* count: 4
|
|
1058
|
+
* });
|
|
1059
|
+
*
|
|
1060
|
+
* cal.toString();
|
|
1061
|
+
* ```
|
|
1062
|
+
*
|
|
1063
|
+
* ```text
|
|
1064
|
+
* BEGIN:VCALENDAR
|
|
1065
|
+
* VERSION:2.0
|
|
1066
|
+
* PRODID:-//sebbo.net//ical-generator//EN
|
|
1067
|
+
* BEGIN:VEVENT
|
|
1068
|
+
* UID:b80e6a68-c2cd-48f5-b94d-cecc7ce83871
|
|
1069
|
+
* SEQUENCE:0
|
|
1070
|
+
* DTSTAMP:20240212T193646Z
|
|
1071
|
+
* DTSTART:20200101T200000Z
|
|
1072
|
+
* RRULE:FREQ=WEEKLY;COUNT=4
|
|
1073
|
+
* SUMMARY:Repeating Event
|
|
1074
|
+
* END:VEVENT
|
|
1075
|
+
* END:VCALENDAR
|
|
1076
|
+
* ```
|
|
1188
1077
|
*
|
|
1189
1078
|
* @since 0.2.0
|
|
1190
1079
|
*/
|
|
1191
|
-
|
|
1192
|
-
alarms(alarms?: ICalAlarm[] | ICalAlarmData[]): this | ICalAlarm[] {
|
|
1193
|
-
if (!alarms) {
|
|
1194
|
-
return this.data.alarms;
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
alarms.forEach((alarm: ICalAlarm | ICalAlarmData) => this.createAlarm(alarm));
|
|
1198
|
-
return this;
|
|
1199
|
-
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1080
|
+
repeating(repeating: ICalRepeatingOptions | null): this;
|
|
1202
1081
|
/**
|
|
1203
|
-
*
|
|
1204
|
-
*
|
|
1082
|
+
* Set the event's repeating options by passing an [RRule object](https://github.com/jakubroztocil/rrule).
|
|
1083
|
+
* @since 2.0.0-develop.5
|
|
1084
|
+
*
|
|
1085
|
+
* ```typescript
|
|
1086
|
+
* import ical from 'ical-generator';
|
|
1087
|
+
* import { datetime, RRule } from 'rrule';
|
|
1205
1088
|
*
|
|
1206
|
-
* ```javascript
|
|
1207
1089
|
* const cal = ical();
|
|
1208
|
-
* const event = cal.createEvent();
|
|
1209
|
-
* const category = event.createCategory({name: 'APPOINTMENT'});
|
|
1210
1090
|
*
|
|
1211
|
-
*
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1091
|
+
* const event = cal.createEvent({
|
|
1092
|
+
* start: new Date('2020-01-01T20:00:00Z'),
|
|
1093
|
+
* summary: 'Repeating Event'
|
|
1214
1094
|
* });
|
|
1095
|
+
*
|
|
1096
|
+
* const rule = new RRule({
|
|
1097
|
+
* freq: RRule.WEEKLY,
|
|
1098
|
+
* interval: 5,
|
|
1099
|
+
* byweekday: [RRule.MO, RRule.FR],
|
|
1100
|
+
* dtstart: datetime(2012, 2, 1, 10, 30),
|
|
1101
|
+
* until: datetime(2012, 12, 31)
|
|
1102
|
+
* })
|
|
1103
|
+
* event.repeating(rule);
|
|
1104
|
+
*
|
|
1105
|
+
* cal.toString();
|
|
1215
1106
|
* ```
|
|
1216
1107
|
*
|
|
1217
|
-
*
|
|
1108
|
+
* ```text
|
|
1109
|
+
* BEGIN:VCALENDAR
|
|
1110
|
+
* VERSION:2.0
|
|
1111
|
+
* PRODID:-//sebbo.net//ical-generator//EN
|
|
1112
|
+
* BEGIN:VEVENT
|
|
1113
|
+
* UID:36585e40-8fa8-460d-af0c-88b6f434030b
|
|
1114
|
+
* SEQUENCE:0
|
|
1115
|
+
* DTSTAMP:20240212T193827Z
|
|
1116
|
+
* DTSTART:20200101T200000Z
|
|
1117
|
+
* RRULE:FREQ=WEEKLY;INTERVAL=5;BYDAY=MO,FR;UNTIL=20121231T000000Z
|
|
1118
|
+
* SUMMARY:Repeating Event
|
|
1119
|
+
* END:VEVENT
|
|
1120
|
+
* END:VCALENDAR
|
|
1121
|
+
* ```
|
|
1218
1122
|
*/
|
|
1219
|
-
|
|
1220
|
-
const category = data instanceof ICalCategory ? data : new ICalCategory(data);
|
|
1221
|
-
this.data.categories.push(category);
|
|
1222
|
-
return category;
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1123
|
+
repeating(repeating: ICalRRuleStub | null): this;
|
|
1226
1124
|
/**
|
|
1227
|
-
*
|
|
1228
|
-
* @since 0.
|
|
1125
|
+
* Set the events repeating options by passing a string which is inserted in the ical file.
|
|
1126
|
+
* @since 2.0.0-develop.5
|
|
1229
1127
|
*/
|
|
1230
|
-
|
|
1231
|
-
|
|
1128
|
+
repeating(repeating: null | string): this;
|
|
1232
1129
|
/**
|
|
1233
|
-
*
|
|
1234
|
-
*
|
|
1235
|
-
* ```javascript
|
|
1236
|
-
* const event = ical().createEvent();
|
|
1237
|
-
*
|
|
1238
|
-
* cal.categories([
|
|
1239
|
-
* {name: 'APPOINTMENT'},
|
|
1240
|
-
* {name: 'MEETING'}
|
|
1241
|
-
* ]);
|
|
1242
|
-
*
|
|
1243
|
-
* cal.categories(); // --> [ICalCategory, ICalCategory]
|
|
1244
|
-
* ```
|
|
1245
|
-
*
|
|
1246
|
-
* @since 0.3.0
|
|
1130
|
+
* @internal
|
|
1247
1131
|
*/
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1132
|
+
repeating(
|
|
1133
|
+
repeating: ICalRepeatingOptions | ICalRRuleStub | null | string,
|
|
1134
|
+
): this;
|
|
1135
|
+
repeating(
|
|
1136
|
+
repeating?: ICalRepeatingOptions | ICalRRuleStub | null | string,
|
|
1137
|
+
): ICalEventJSONRepeatingData | ICalRRuleStub | null | string | this {
|
|
1138
|
+
if (repeating === undefined) {
|
|
1139
|
+
return this.data.repeating;
|
|
1140
|
+
}
|
|
1141
|
+
if (!repeating) {
|
|
1142
|
+
this.data.repeating = null;
|
|
1143
|
+
return this;
|
|
1144
|
+
}
|
|
1145
|
+
if (isRRule(repeating) || typeof repeating === 'string') {
|
|
1146
|
+
this.data.repeating = repeating;
|
|
1147
|
+
return this;
|
|
1252
1148
|
}
|
|
1253
1149
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1150
|
+
this.data.repeating = {
|
|
1151
|
+
freq: checkEnum(
|
|
1152
|
+
ICalEventRepeatingFreq,
|
|
1153
|
+
repeating.freq,
|
|
1154
|
+
) as ICalEventRepeatingFreq,
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
if (repeating.count) {
|
|
1158
|
+
if (!isFinite(repeating.count)) {
|
|
1159
|
+
throw new Error('`repeating.count` must be a finite number!');
|
|
1160
|
+
}
|
|
1257
1161
|
|
|
1162
|
+
this.data.repeating.count = repeating.count;
|
|
1163
|
+
}
|
|
1258
1164
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1165
|
+
if (repeating.interval) {
|
|
1166
|
+
if (!isFinite(repeating.interval)) {
|
|
1167
|
+
throw new Error(
|
|
1168
|
+
'`repeating.interval` must be a finite number!',
|
|
1169
|
+
);
|
|
1170
|
+
}
|
|
1264
1171
|
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
* @since 0.2.0
|
|
1274
|
-
*/
|
|
1275
|
-
status(status: ICalEventStatus | null): this;
|
|
1276
|
-
status(status?: ICalEventStatus | null): this | ICalEventStatus | null {
|
|
1277
|
-
if (status === undefined) {
|
|
1278
|
-
return this.data.status;
|
|
1172
|
+
this.data.repeating.interval = repeating.interval;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (repeating.until !== undefined) {
|
|
1176
|
+
this.data.repeating.until = checkDate(
|
|
1177
|
+
repeating.until,
|
|
1178
|
+
'repeating.until',
|
|
1179
|
+
);
|
|
1279
1180
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1181
|
+
|
|
1182
|
+
if (repeating.byDay) {
|
|
1183
|
+
const byDayArray = Array.isArray(repeating.byDay)
|
|
1184
|
+
? repeating.byDay
|
|
1185
|
+
: [repeating.byDay];
|
|
1186
|
+
this.data.repeating.byDay = byDayArray.map(
|
|
1187
|
+
(day) => checkEnum(ICalWeekday, day) as ICalWeekday,
|
|
1188
|
+
);
|
|
1283
1189
|
}
|
|
1284
1190
|
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1191
|
+
if (repeating.byMonth) {
|
|
1192
|
+
const byMonthArray = Array.isArray(repeating.byMonth)
|
|
1193
|
+
? repeating.byMonth
|
|
1194
|
+
: [repeating.byMonth];
|
|
1195
|
+
this.data.repeating.byMonth = byMonthArray.map((month) => {
|
|
1196
|
+
if (typeof month !== 'number' || month < 1 || month > 12) {
|
|
1197
|
+
throw new Error(
|
|
1198
|
+
'`repeating.byMonth` contains invalid value `' +
|
|
1199
|
+
month +
|
|
1200
|
+
'`!',
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1288
1203
|
|
|
1204
|
+
return month;
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1289
1207
|
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1208
|
+
if (repeating.byMonthDay) {
|
|
1209
|
+
const byMonthDayArray = Array.isArray(repeating.byMonthDay)
|
|
1210
|
+
? repeating.byMonthDay
|
|
1211
|
+
: [repeating.byMonthDay];
|
|
1212
|
+
|
|
1213
|
+
this.data.repeating.byMonthDay = byMonthDayArray.map((monthDay) => {
|
|
1214
|
+
if (
|
|
1215
|
+
typeof monthDay !== 'number' ||
|
|
1216
|
+
monthDay < -31 ||
|
|
1217
|
+
monthDay > 31 ||
|
|
1218
|
+
monthDay === 0
|
|
1219
|
+
) {
|
|
1220
|
+
throw new Error(
|
|
1221
|
+
'`repeating.byMonthDay` contains invalid value `' +
|
|
1222
|
+
monthDay +
|
|
1223
|
+
'`!',
|
|
1224
|
+
);
|
|
1225
|
+
}
|
|
1295
1226
|
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
* [`X-MICROSOFT-CDO-BUSYSTATUS`](https://docs.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-oxcical/cd68eae7-ed65-4dd3-8ea7-ad585c76c736)
|
|
1299
|
-
* attribute to your event.
|
|
1300
|
-
*
|
|
1301
|
-
* ```javascript
|
|
1302
|
-
* import ical, {ICalEventBusyStatus} from 'ical-generator';
|
|
1303
|
-
* event.busystatus(ICalEventBusyStatus.BUSY);
|
|
1304
|
-
* ```
|
|
1305
|
-
*
|
|
1306
|
-
* @since 1.0.2
|
|
1307
|
-
*/
|
|
1308
|
-
busystatus(busystatus: ICalEventBusyStatus | null): this;
|
|
1309
|
-
busystatus(busystatus?: ICalEventBusyStatus | null): this | ICalEventBusyStatus | null {
|
|
1310
|
-
if (busystatus === undefined) {
|
|
1311
|
-
return this.data.busystatus;
|
|
1227
|
+
return monthDay;
|
|
1228
|
+
});
|
|
1312
1229
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1230
|
+
|
|
1231
|
+
if (repeating.bySetPos) {
|
|
1232
|
+
if (!this.data.repeating.byDay) {
|
|
1233
|
+
throw '`repeating.bySetPos` must be used along with `repeating.byDay`!';
|
|
1234
|
+
}
|
|
1235
|
+
const bySetPosArray = Array.isArray(repeating.bySetPos)
|
|
1236
|
+
? repeating.bySetPos
|
|
1237
|
+
: [repeating.bySetPos];
|
|
1238
|
+
this.data.repeating.bySetPos = bySetPosArray.map((bySetPos) => {
|
|
1239
|
+
if (
|
|
1240
|
+
typeof bySetPos !== 'number' ||
|
|
1241
|
+
bySetPos < -366 ||
|
|
1242
|
+
bySetPos > 366 ||
|
|
1243
|
+
bySetPos === 0
|
|
1244
|
+
) {
|
|
1245
|
+
throw (
|
|
1246
|
+
'`repeating.bySetPos` contains invalid value `' +
|
|
1247
|
+
bySetPos +
|
|
1248
|
+
'`!'
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
return bySetPos;
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
if (repeating.exclude) {
|
|
1256
|
+
const excludeArray = Array.isArray(repeating.exclude)
|
|
1257
|
+
? repeating.exclude
|
|
1258
|
+
: [repeating.exclude];
|
|
1259
|
+
this.data.repeating.exclude = excludeArray.map((exclude, i) => {
|
|
1260
|
+
return checkDate(exclude, `repeating.exclude[${i}]`);
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
if (repeating.startOfWeek) {
|
|
1265
|
+
this.data.repeating.startOfWeek = checkEnum(
|
|
1266
|
+
ICalWeekday,
|
|
1267
|
+
repeating.startOfWeek,
|
|
1268
|
+
) as ICalWeekday;
|
|
1316
1269
|
}
|
|
1317
1270
|
|
|
1318
|
-
this.data.busystatus = checkEnum(ICalEventBusyStatus, busystatus) as ICalEventBusyStatus;
|
|
1319
1271
|
return this;
|
|
1320
1272
|
}
|
|
1321
1273
|
|
|
1322
|
-
|
|
1323
1274
|
/**
|
|
1324
|
-
* Get the event's
|
|
1325
|
-
*
|
|
1326
|
-
* priority.
|
|
1275
|
+
* Get the event's SEQUENCE number. Use this method to get the event's
|
|
1276
|
+
* revision sequence number of the calendar component within a sequence of revisions.
|
|
1327
1277
|
*
|
|
1328
|
-
* @since
|
|
1278
|
+
* @since 0.2.6
|
|
1329
1279
|
*/
|
|
1330
|
-
|
|
1331
|
-
|
|
1280
|
+
sequence(): number;
|
|
1332
1281
|
/**
|
|
1333
|
-
* Set the event's
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1282
|
+
* Set the event's SEQUENCE number. For a new event, this should be zero.
|
|
1283
|
+
* Each time the organizer makes a significant revision, the sequence
|
|
1284
|
+
* number should be incremented.
|
|
1336
1285
|
*
|
|
1337
|
-
* @
|
|
1286
|
+
* @param sequence Sequence number or null to unset it
|
|
1338
1287
|
*/
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
if (
|
|
1342
|
-
return this.data.
|
|
1343
|
-
}
|
|
1344
|
-
if (priority === null) {
|
|
1345
|
-
this.data.priority = null;
|
|
1346
|
-
return this;
|
|
1288
|
+
sequence(sequence: number): this;
|
|
1289
|
+
sequence(sequence?: number): number | this {
|
|
1290
|
+
if (sequence === undefined) {
|
|
1291
|
+
return this.data.sequence;
|
|
1347
1292
|
}
|
|
1348
1293
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1294
|
+
const s = parseInt(String(sequence), 10);
|
|
1295
|
+
if (isNaN(s)) {
|
|
1296
|
+
throw new Error('`sequence` must be a number!');
|
|
1351
1297
|
}
|
|
1352
1298
|
|
|
1353
|
-
this.data.
|
|
1299
|
+
this.data.sequence = sequence;
|
|
1354
1300
|
return this;
|
|
1355
1301
|
}
|
|
1356
1302
|
|
|
1357
|
-
|
|
1358
1303
|
/**
|
|
1359
|
-
* Get the event's
|
|
1304
|
+
* Get the event's timestamp
|
|
1360
1305
|
* @since 0.2.0
|
|
1306
|
+
* @see {@link timestamp}
|
|
1361
1307
|
*/
|
|
1362
|
-
|
|
1363
|
-
|
|
1308
|
+
stamp(): ICalDateTimeValue;
|
|
1364
1309
|
/**
|
|
1365
|
-
* Set the
|
|
1310
|
+
* Set the appointment date of creation. Defaults to the current time and date (`new Date()`). You can use
|
|
1311
|
+
* any supported date object, see [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
1312
|
+
* for details about supported values and timezone handling.
|
|
1313
|
+
*
|
|
1366
1314
|
* @since 0.2.0
|
|
1315
|
+
* @see {@link timestamp}
|
|
1367
1316
|
*/
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
if (
|
|
1371
|
-
return this.data.
|
|
1317
|
+
stamp(stamp: ICalDateTimeValue): this;
|
|
1318
|
+
stamp(stamp?: ICalDateTimeValue): ICalDateTimeValue | this {
|
|
1319
|
+
if (stamp === undefined) {
|
|
1320
|
+
return this.data.stamp;
|
|
1372
1321
|
}
|
|
1373
1322
|
|
|
1374
|
-
this.data.
|
|
1323
|
+
this.data.stamp = checkDate(stamp, 'stamp');
|
|
1375
1324
|
return this;
|
|
1376
1325
|
}
|
|
1377
1326
|
|
|
1378
1327
|
/**
|
|
1379
|
-
*
|
|
1328
|
+
* Get the event start time which is currently
|
|
1329
|
+
* set. Can be any supported date object.
|
|
1380
1330
|
*
|
|
1381
|
-
*
|
|
1382
|
-
|
|
1383
|
-
|
|
1331
|
+
* @since 0.2.0
|
|
1332
|
+
*/
|
|
1333
|
+
start(): ICalDateTimeValue;
|
|
1334
|
+
/**
|
|
1335
|
+
* Set the appointment date of beginning, which is required for all events.
|
|
1336
|
+
* You can use any supported date object, see
|
|
1337
|
+
* [Readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
1338
|
+
* for details about supported values and timezone handling.
|
|
1339
|
+
*
|
|
1340
|
+
* ```typescript
|
|
1341
|
+
* import ical from 'ical-generator';
|
|
1384
1342
|
*
|
|
1385
|
-
* ```javascript
|
|
1386
1343
|
* const cal = ical();
|
|
1387
|
-
* const event = cal.createEvent();
|
|
1388
|
-
* event.createAttachment('https://files.sebbo.net/calendar/attachments/foo');
|
|
1389
|
-
* ```
|
|
1390
1344
|
*
|
|
1391
|
-
*
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
this.data.attachments.push(url);
|
|
1395
|
-
return this;
|
|
1396
|
-
}
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
/**
|
|
1400
|
-
* Get all attachment urls
|
|
1401
|
-
* @since 3.2.0-develop.1
|
|
1402
|
-
*/
|
|
1403
|
-
attachments(): string[];
|
|
1404
|
-
|
|
1405
|
-
/**
|
|
1406
|
-
* Add one or multiple alarms
|
|
1345
|
+
* const event = cal.createEvent({
|
|
1346
|
+
* start: new Date('2020-01-01')
|
|
1347
|
+
* });
|
|
1407
1348
|
*
|
|
1408
|
-
*
|
|
1409
|
-
*
|
|
1349
|
+
* // overwrites old start date
|
|
1350
|
+
* event.start(new Date('2024-02-01'));
|
|
1410
1351
|
*
|
|
1411
|
-
* cal.
|
|
1412
|
-
*
|
|
1413
|
-
* 'https://files.sebbo.net/calendar/attachments/bar'
|
|
1414
|
-
* ]);
|
|
1352
|
+
* cal.toString();
|
|
1353
|
+
* ```
|
|
1415
1354
|
*
|
|
1416
|
-
*
|
|
1417
|
-
|
|
1355
|
+
* ```text
|
|
1356
|
+
* BEGIN:VCALENDAR
|
|
1357
|
+
* VERSION:2.0
|
|
1358
|
+
* PRODID:-//sebbo.net//ical-generator//EN
|
|
1359
|
+
* BEGIN:VEVENT
|
|
1360
|
+
* UID:7e2aee64-b07a-4256-9b3e-e9eaa452bac8
|
|
1361
|
+
* SEQUENCE:0
|
|
1362
|
+
* DTSTAMP:20240212T190915Z
|
|
1363
|
+
* DTSTART:20240201T000000Z
|
|
1364
|
+
* SUMMARY:
|
|
1365
|
+
* END:VEVENT
|
|
1366
|
+
* END:VCALENDAR
|
|
1367
|
+
* ```
|
|
1418
1368
|
*
|
|
1419
|
-
*
|
|
1369
|
+
* @since 0.2.0
|
|
1420
1370
|
*/
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
if (
|
|
1424
|
-
|
|
1371
|
+
start(start: ICalDateTimeValue): this;
|
|
1372
|
+
start(start?: ICalDateTimeValue): ICalDateTimeValue | this {
|
|
1373
|
+
if (start === undefined) {
|
|
1374
|
+
this.swapStartAndEndIfRequired();
|
|
1375
|
+
return this.data.start;
|
|
1425
1376
|
}
|
|
1426
1377
|
|
|
1427
|
-
|
|
1378
|
+
this.data.start = checkDate(start, 'start');
|
|
1428
1379
|
return this;
|
|
1429
1380
|
}
|
|
1430
1381
|
|
|
1431
1382
|
/**
|
|
1432
|
-
* Get the event's
|
|
1433
|
-
* @since
|
|
1383
|
+
* Get the event's status
|
|
1384
|
+
* @since 0.2.0
|
|
1434
1385
|
*/
|
|
1435
|
-
|
|
1436
|
-
|
|
1386
|
+
status(): ICalEventStatus | null;
|
|
1437
1387
|
/**
|
|
1438
|
-
* Set the event's
|
|
1439
|
-
*
|
|
1440
|
-
* Set the field to `OPAQUE` if the person or resource is no longer
|
|
1441
|
-
* available due to this event. If the calendar entry has no influence
|
|
1442
|
-
* on availability, you can set the field to `TRANSPARENT`. This value
|
|
1443
|
-
* is mostly used to find out if a person has time on a certain date or
|
|
1444
|
-
* not (see `TRANSP` in iCal specification).
|
|
1388
|
+
* Set the event's status
|
|
1445
1389
|
*
|
|
1446
1390
|
* ```javascript
|
|
1447
|
-
* import ical, {
|
|
1448
|
-
* event.
|
|
1391
|
+
* import ical, {ICalEventStatus} from 'ical-generator';
|
|
1392
|
+
* event.status(ICalEventStatus.CONFIRMED);
|
|
1449
1393
|
* ```
|
|
1450
1394
|
*
|
|
1451
|
-
* @since
|
|
1452
|
-
*/
|
|
1453
|
-
transparency(transparency: ICalEventTransparency | null): this;
|
|
1454
|
-
transparency(transparency?: ICalEventTransparency | null): this | ICalEventTransparency | null {
|
|
1455
|
-
if (transparency === undefined) {
|
|
1456
|
-
return this.data.transparency;
|
|
1457
|
-
}
|
|
1458
|
-
if (!transparency) {
|
|
1459
|
-
this.data.transparency = null;
|
|
1460
|
-
return this;
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
|
-
this.data.transparency = checkEnum(ICalEventTransparency, transparency) as ICalEventTransparency;
|
|
1464
|
-
return this;
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
/**
|
|
1469
|
-
* Get the event's creation date
|
|
1470
|
-
* @since 0.3.0
|
|
1471
|
-
*/
|
|
1472
|
-
created(): ICalDateTimeValue | null;
|
|
1473
|
-
|
|
1474
|
-
/**
|
|
1475
|
-
* Set the event's creation date
|
|
1476
|
-
* @since 0.3.0
|
|
1395
|
+
* @since 0.2.0
|
|
1477
1396
|
*/
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
if (
|
|
1481
|
-
return this.data.
|
|
1397
|
+
status(status: ICalEventStatus | null): this;
|
|
1398
|
+
status(status?: ICalEventStatus | null): ICalEventStatus | null | this {
|
|
1399
|
+
if (status === undefined) {
|
|
1400
|
+
return this.data.status;
|
|
1482
1401
|
}
|
|
1483
|
-
if (
|
|
1484
|
-
this.data.
|
|
1402
|
+
if (status === null) {
|
|
1403
|
+
this.data.status = null;
|
|
1485
1404
|
return this;
|
|
1486
1405
|
}
|
|
1487
1406
|
|
|
1488
|
-
this.data.
|
|
1407
|
+
this.data.status = checkEnum(
|
|
1408
|
+
ICalEventStatus,
|
|
1409
|
+
status,
|
|
1410
|
+
) as ICalEventStatus;
|
|
1489
1411
|
return this;
|
|
1490
1412
|
}
|
|
1491
1413
|
|
|
1492
|
-
|
|
1493
1414
|
/**
|
|
1494
|
-
* Get the event's
|
|
1495
|
-
* @since 0.
|
|
1415
|
+
* Get the event's summary
|
|
1416
|
+
* @since 0.2.0
|
|
1496
1417
|
*/
|
|
1497
|
-
|
|
1498
|
-
|
|
1418
|
+
summary(): string;
|
|
1499
1419
|
/**
|
|
1500
|
-
* Set the event's
|
|
1501
|
-
*
|
|
1420
|
+
* Set the event's summary.
|
|
1421
|
+
* Defaults to an empty string if nothing is set.
|
|
1422
|
+
*
|
|
1423
|
+
* @since 0.2.0
|
|
1502
1424
|
*/
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
if (
|
|
1506
|
-
return this.data.
|
|
1507
|
-
}
|
|
1508
|
-
if (lastModified === null) {
|
|
1509
|
-
this.data.lastModified = null;
|
|
1510
|
-
return this;
|
|
1425
|
+
summary(summary: string): this;
|
|
1426
|
+
summary(summary?: string): string | this {
|
|
1427
|
+
if (summary === undefined) {
|
|
1428
|
+
return this.data.summary;
|
|
1511
1429
|
}
|
|
1512
1430
|
|
|
1513
|
-
this.data.
|
|
1431
|
+
this.data.summary = summary ? String(summary) : '';
|
|
1514
1432
|
return this;
|
|
1515
1433
|
}
|
|
1516
1434
|
|
|
1517
1435
|
/**
|
|
1518
|
-
* Get the event's
|
|
1519
|
-
* @since 2.0
|
|
1436
|
+
* Get the event's timestamp
|
|
1437
|
+
* @since 0.2.0
|
|
1438
|
+
* @see {@link stamp}
|
|
1520
1439
|
*/
|
|
1521
|
-
|
|
1522
|
-
|
|
1440
|
+
timestamp(): ICalDateTimeValue;
|
|
1523
1441
|
/**
|
|
1524
|
-
* Set the
|
|
1525
|
-
*
|
|
1526
|
-
*
|
|
1527
|
-
* import ical, { ICalEventClass } from 'ical-generator';
|
|
1528
|
-
* event.class(ICalEventClass.PRIVATE);
|
|
1529
|
-
* ```
|
|
1442
|
+
* Set the appointment date of creation. Defaults to the current time and date (`new Date()`). You can use
|
|
1443
|
+
* any supported date object, see [readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones)
|
|
1444
|
+
* for details about supported values and timezone handling.
|
|
1530
1445
|
*
|
|
1531
|
-
* @since 2.0
|
|
1446
|
+
* @since 0.2.0
|
|
1447
|
+
* @see {@link stamp}
|
|
1532
1448
|
*/
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
if (
|
|
1536
|
-
return this.
|
|
1537
|
-
}
|
|
1538
|
-
if (class_ === null) {
|
|
1539
|
-
this.data.class = null;
|
|
1540
|
-
return this;
|
|
1449
|
+
timestamp(stamp: ICalDateTimeValue): this;
|
|
1450
|
+
timestamp(stamp?: ICalDateTimeValue): ICalDateTimeValue | this {
|
|
1451
|
+
if (stamp === undefined) {
|
|
1452
|
+
return this.stamp();
|
|
1541
1453
|
}
|
|
1542
1454
|
|
|
1543
|
-
this.
|
|
1544
|
-
return this;
|
|
1455
|
+
return this.stamp(stamp);
|
|
1545
1456
|
}
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
1457
|
/**
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
* event.
|
|
1555
|
-
*
|
|
1556
|
-
*
|
|
1557
|
-
* value: "1337!"
|
|
1558
|
-
* }
|
|
1559
|
-
* ]);
|
|
1458
|
+
* Get the event's timezone.
|
|
1459
|
+
* @since 0.2.6
|
|
1460
|
+
*/
|
|
1461
|
+
timezone(): null | string;
|
|
1462
|
+
/**
|
|
1463
|
+
* Sets the time zone to be used for this event. If a time zone has been
|
|
1464
|
+
* defined in both the event and the calendar, the time zone of the event
|
|
1465
|
+
* is used.
|
|
1560
1466
|
*
|
|
1561
|
-
*
|
|
1562
|
-
*
|
|
1563
|
-
*
|
|
1467
|
+
* Please note that if the time zone is set, ical-generator assumes
|
|
1468
|
+
* that all times are already in the correct time zone. Alternatively,
|
|
1469
|
+
* a `moment-timezone` or a Luxon object can be passed with `setZone`,
|
|
1470
|
+
* ical-generator will then set the time zone itself.
|
|
1564
1471
|
*
|
|
1565
|
-
*
|
|
1566
|
-
*
|
|
1567
|
-
*
|
|
1568
|
-
* ```
|
|
1472
|
+
* This and the 'floating' flag (see below) are mutually exclusive, and setting a timezone will unset the
|
|
1473
|
+
* 'floating' flag. If neither 'timezone' nor 'floating' are set, the date will be output with in UTC format
|
|
1474
|
+
* (see [date-time form #2 in section 3.3.5 of RFC 554](https://tools.ietf.org/html/rfc5545#section-3.3.5)).
|
|
1569
1475
|
*
|
|
1570
|
-
*
|
|
1571
|
-
|
|
1572
|
-
x (keyOrArray: {key: string, value: string}[] | [string, string][] | Record<string, string>): this;
|
|
1573
|
-
|
|
1574
|
-
/**
|
|
1575
|
-
* Set a X-* attribute. Woun't filter double attributes,
|
|
1576
|
-
* which are also added by another method (e.g. summary),
|
|
1577
|
-
* so these attributes may be inserted twice.
|
|
1476
|
+
* See [Readme](https://github.com/sebbo2002/ical-generator#-date-time--timezones) for details about
|
|
1477
|
+
* supported values and timezone handling.
|
|
1578
1478
|
*
|
|
1579
1479
|
* ```javascript
|
|
1580
|
-
* event.
|
|
1480
|
+
* event.timezone('America/New_York');
|
|
1581
1481
|
* ```
|
|
1582
1482
|
*
|
|
1583
|
-
* @
|
|
1584
|
-
|
|
1585
|
-
x (keyOrArray: string, value: string): this;
|
|
1586
|
-
|
|
1587
|
-
/**
|
|
1588
|
-
* Get all custom X-* attributes.
|
|
1589
|
-
* @since 1.9.0
|
|
1483
|
+
* @see https://github.com/sebbo2002/ical-generator#-date-time--timezones
|
|
1484
|
+
* @since 0.2.6
|
|
1590
1485
|
*/
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
if (
|
|
1594
|
-
return
|
|
1486
|
+
timezone(timezone: null | string): this;
|
|
1487
|
+
timezone(timezone?: null | string): null | string | this {
|
|
1488
|
+
if (timezone === undefined && this.data.timezone !== null) {
|
|
1489
|
+
return this.data.timezone;
|
|
1595
1490
|
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
addOrGetCustomAttributes(this.data, keyOrArray, value);
|
|
1491
|
+
if (timezone === undefined) {
|
|
1492
|
+
return this.calendar.timezone();
|
|
1599
1493
|
}
|
|
1600
|
-
|
|
1601
|
-
|
|
1494
|
+
|
|
1495
|
+
this.data.timezone =
|
|
1496
|
+
timezone && timezone !== 'UTC' ? timezone.toString() : null;
|
|
1497
|
+
if (this.data.timezone) {
|
|
1498
|
+
this.data.floating = false;
|
|
1602
1499
|
}
|
|
1603
1500
|
|
|
1604
1501
|
return this;
|
|
1605
1502
|
}
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
1503
|
/**
|
|
1609
1504
|
* Return a shallow copy of the events's options for JSON stringification.
|
|
1610
1505
|
* Third party objects like moment.js values or RRule objects are stringified
|
|
@@ -1621,31 +1516,32 @@ export default class ICalEvent {
|
|
|
1621
1516
|
* @since 0.2.4
|
|
1622
1517
|
*/
|
|
1623
1518
|
toJSON(): ICalEventJSONData {
|
|
1624
|
-
let repeating: ICalEventJSONRepeatingData |
|
|
1625
|
-
if(
|
|
1519
|
+
let repeating: ICalEventJSONRepeatingData | null | string = null;
|
|
1520
|
+
if (
|
|
1521
|
+
isRRule(this.data.repeating) ||
|
|
1522
|
+
typeof this.data.repeating === 'string'
|
|
1523
|
+
) {
|
|
1626
1524
|
repeating = this.data.repeating.toString();
|
|
1627
|
-
}
|
|
1628
|
-
else if(this.data.repeating) {
|
|
1525
|
+
} else if (this.data.repeating) {
|
|
1629
1526
|
repeating = Object.assign({}, this.data.repeating, {
|
|
1527
|
+
exclude: this.data.repeating.exclude?.map((d) => toJSON(d)),
|
|
1630
1528
|
until: toJSON(this.data.repeating.until) || undefined,
|
|
1631
|
-
exclude: this.data.repeating.exclude?.map(d => toJSON(d)),
|
|
1632
1529
|
});
|
|
1633
1530
|
}
|
|
1634
1531
|
|
|
1635
1532
|
this.swapStartAndEndIfRequired();
|
|
1636
1533
|
return Object.assign({}, this.data, {
|
|
1637
|
-
start: toJSON(this.data.start) || null,
|
|
1638
|
-
end: toJSON(this.data.end) || null,
|
|
1639
|
-
recurrenceId: toJSON(this.data.recurrenceId) || null,
|
|
1640
|
-
stamp: toJSON(this.data.stamp) || null,
|
|
1641
1534
|
created: toJSON(this.data.created) || null,
|
|
1535
|
+
end: toJSON(this.data.end) || null,
|
|
1642
1536
|
lastModified: toJSON(this.data.lastModified) || null,
|
|
1537
|
+
recurrenceId: toJSON(this.data.recurrenceId) || null,
|
|
1643
1538
|
repeating,
|
|
1644
|
-
|
|
1539
|
+
stamp: toJSON(this.data.stamp) || null,
|
|
1540
|
+
start: toJSON(this.data.start) || null,
|
|
1541
|
+
x: this.x(),
|
|
1645
1542
|
});
|
|
1646
1543
|
}
|
|
1647
1544
|
|
|
1648
|
-
|
|
1649
1545
|
/**
|
|
1650
1546
|
* Return generated event as a string.
|
|
1651
1547
|
*
|
|
@@ -1665,39 +1561,64 @@ export default class ICalEvent {
|
|
|
1665
1561
|
g += 'SEQUENCE:' + this.data.sequence + '\r\n';
|
|
1666
1562
|
|
|
1667
1563
|
this.swapStartAndEndIfRequired();
|
|
1668
|
-
g +=
|
|
1564
|
+
g +=
|
|
1565
|
+
'DTSTAMP:' +
|
|
1566
|
+
formatDate(this.calendar.timezone(), this.data.stamp) +
|
|
1567
|
+
'\r\n';
|
|
1669
1568
|
if (this.data.allDay) {
|
|
1670
|
-
g +=
|
|
1569
|
+
g +=
|
|
1570
|
+
'DTSTART;VALUE=DATE:' +
|
|
1571
|
+
formatDate(this.timezone(), this.data.start, true) +
|
|
1572
|
+
'\r\n';
|
|
1671
1573
|
if (this.data.end) {
|
|
1672
|
-
g +=
|
|
1574
|
+
g +=
|
|
1575
|
+
'DTEND;VALUE=DATE:' +
|
|
1576
|
+
formatDate(this.timezone(), this.data.end, true) +
|
|
1577
|
+
'\r\n';
|
|
1673
1578
|
}
|
|
1674
1579
|
|
|
1675
1580
|
g += 'X-MICROSOFT-CDO-ALLDAYEVENT:TRUE\r\n';
|
|
1676
1581
|
g += 'X-MICROSOFT-MSNCALENDAR-ALLDAYEVENT:TRUE\r\n';
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
|
|
1582
|
+
} else {
|
|
1583
|
+
g +=
|
|
1584
|
+
formatDateTZ(
|
|
1585
|
+
this.timezone(),
|
|
1586
|
+
'DTSTART',
|
|
1587
|
+
this.data.start,
|
|
1588
|
+
this.data,
|
|
1589
|
+
) + '\r\n';
|
|
1680
1590
|
if (this.data.end) {
|
|
1681
|
-
g +=
|
|
1591
|
+
g +=
|
|
1592
|
+
formatDateTZ(
|
|
1593
|
+
this.timezone(),
|
|
1594
|
+
'DTEND',
|
|
1595
|
+
this.data.end,
|
|
1596
|
+
this.data,
|
|
1597
|
+
) + '\r\n';
|
|
1682
1598
|
}
|
|
1683
1599
|
}
|
|
1684
1600
|
|
|
1685
1601
|
// REPEATING
|
|
1686
|
-
if(
|
|
1602
|
+
if (
|
|
1603
|
+
isRRule(this.data.repeating) ||
|
|
1604
|
+
typeof this.data.repeating === 'string'
|
|
1605
|
+
) {
|
|
1687
1606
|
let repeating = this.data.repeating
|
|
1688
1607
|
.toString()
|
|
1689
1608
|
.replace(/\r\n/g, '\n')
|
|
1690
1609
|
.split('\n')
|
|
1691
|
-
.filter(l => l && !l.startsWith('DTSTART:'))
|
|
1610
|
+
.filter((l) => l && !l.startsWith('DTSTART:'))
|
|
1692
1611
|
.join('\r\n');
|
|
1693
1612
|
|
|
1694
|
-
if
|
|
1613
|
+
if (
|
|
1614
|
+
!repeating.includes('\r\n') &&
|
|
1615
|
+
!repeating.startsWith('RRULE:')
|
|
1616
|
+
) {
|
|
1695
1617
|
repeating = 'RRULE:' + repeating;
|
|
1696
1618
|
}
|
|
1697
1619
|
|
|
1698
1620
|
g += repeating.trim() + '\r\n';
|
|
1699
|
-
}
|
|
1700
|
-
else if (this.data.repeating) {
|
|
1621
|
+
} else if (this.data.repeating) {
|
|
1701
1622
|
g += 'RRULE:FREQ=' + this.data.repeating.freq;
|
|
1702
1623
|
|
|
1703
1624
|
if (this.data.repeating.count) {
|
|
@@ -1709,7 +1630,14 @@ export default class ICalEvent {
|
|
|
1709
1630
|
}
|
|
1710
1631
|
|
|
1711
1632
|
if (this.data.repeating.until) {
|
|
1712
|
-
g +=
|
|
1633
|
+
g +=
|
|
1634
|
+
';UNTIL=' +
|
|
1635
|
+
formatDate(
|
|
1636
|
+
this.calendar.timezone(),
|
|
1637
|
+
this.data.repeating.until,
|
|
1638
|
+
false,
|
|
1639
|
+
this.floating(),
|
|
1640
|
+
);
|
|
1713
1641
|
}
|
|
1714
1642
|
|
|
1715
1643
|
if (this.data.repeating.byDay) {
|
|
@@ -1737,23 +1665,52 @@ export default class ICalEvent {
|
|
|
1737
1665
|
// REPEATING EXCLUSION
|
|
1738
1666
|
if (this.data.repeating.exclude) {
|
|
1739
1667
|
if (this.data.allDay) {
|
|
1740
|
-
g +=
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1668
|
+
g +=
|
|
1669
|
+
'EXDATE;VALUE=DATE:' +
|
|
1670
|
+
this.data.repeating.exclude
|
|
1671
|
+
.map((excludedDate) => {
|
|
1672
|
+
return formatDate(
|
|
1673
|
+
this.calendar.timezone(),
|
|
1674
|
+
excludedDate,
|
|
1675
|
+
true,
|
|
1676
|
+
);
|
|
1677
|
+
})
|
|
1678
|
+
.join(',') +
|
|
1679
|
+
'\r\n';
|
|
1680
|
+
} else {
|
|
1745
1681
|
g += 'EXDATE';
|
|
1746
1682
|
if (this.timezone()) {
|
|
1747
|
-
g +=
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1683
|
+
g +=
|
|
1684
|
+
';TZID=' +
|
|
1685
|
+
this.timezone() +
|
|
1686
|
+
':' +
|
|
1687
|
+
this.data.repeating.exclude
|
|
1688
|
+
.map((excludedDate) => {
|
|
1689
|
+
// This isn't a 'floating' event because it has a timezone;
|
|
1690
|
+
// but we use it to omit the 'Z' UTC specifier in formatDate()
|
|
1691
|
+
return formatDate(
|
|
1692
|
+
this.timezone(),
|
|
1693
|
+
excludedDate,
|
|
1694
|
+
false,
|
|
1695
|
+
true,
|
|
1696
|
+
);
|
|
1697
|
+
})
|
|
1698
|
+
.join(',') +
|
|
1699
|
+
'\r\n';
|
|
1700
|
+
} else {
|
|
1701
|
+
g +=
|
|
1702
|
+
':' +
|
|
1703
|
+
this.data.repeating.exclude
|
|
1704
|
+
.map((excludedDate) => {
|
|
1705
|
+
return formatDate(
|
|
1706
|
+
this.timezone(),
|
|
1707
|
+
excludedDate,
|
|
1708
|
+
false,
|
|
1709
|
+
this.floating(),
|
|
1710
|
+
);
|
|
1711
|
+
})
|
|
1712
|
+
.join(',') +
|
|
1713
|
+
'\r\n';
|
|
1757
1714
|
}
|
|
1758
1715
|
}
|
|
1759
1716
|
}
|
|
@@ -1761,7 +1718,13 @@ export default class ICalEvent {
|
|
|
1761
1718
|
|
|
1762
1719
|
// RECURRENCE
|
|
1763
1720
|
if (this.data.recurrenceId) {
|
|
1764
|
-
g +=
|
|
1721
|
+
g +=
|
|
1722
|
+
formatDateTZ(
|
|
1723
|
+
this.timezone(),
|
|
1724
|
+
'RECURRENCE-ID',
|
|
1725
|
+
this.data.recurrenceId,
|
|
1726
|
+
this.data,
|
|
1727
|
+
) + '\r\n';
|
|
1765
1728
|
}
|
|
1766
1729
|
|
|
1767
1730
|
// SUMMARY
|
|
@@ -1773,53 +1736,92 @@ export default class ICalEvent {
|
|
|
1773
1736
|
}
|
|
1774
1737
|
|
|
1775
1738
|
// LOCATION
|
|
1776
|
-
if (
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1739
|
+
if (
|
|
1740
|
+
this.data.location &&
|
|
1741
|
+
'title' in this.data.location &&
|
|
1742
|
+
this.data.location.title
|
|
1743
|
+
) {
|
|
1744
|
+
g +=
|
|
1745
|
+
'LOCATION:' +
|
|
1746
|
+
escape(
|
|
1747
|
+
this.data.location.title +
|
|
1748
|
+
(this.data.location.address
|
|
1749
|
+
? '\n' + this.data.location.address
|
|
1750
|
+
: ''),
|
|
1751
|
+
false,
|
|
1752
|
+
) +
|
|
1753
|
+
'\r\n';
|
|
1782
1754
|
|
|
1783
1755
|
if (this.data.location.radius && this.data.location.geo) {
|
|
1784
|
-
g +=
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1756
|
+
g +=
|
|
1757
|
+
'X-APPLE-STRUCTURED-LOCATION;VALUE=URI;' +
|
|
1758
|
+
(this.data.location.address
|
|
1759
|
+
? 'X-ADDRESS=' +
|
|
1760
|
+
escape(this.data.location.address, false) +
|
|
1761
|
+
';'
|
|
1762
|
+
: '') +
|
|
1763
|
+
'X-APPLE-RADIUS=' +
|
|
1764
|
+
escape(this.data.location.radius, false) +
|
|
1765
|
+
';' +
|
|
1766
|
+
'X-TITLE=' +
|
|
1767
|
+
escape(this.data.location.title, false) +
|
|
1768
|
+
':geo:' +
|
|
1769
|
+
escape(this.data.location.geo?.lat, false) +
|
|
1770
|
+
',' +
|
|
1771
|
+
escape(this.data.location.geo?.lon, false) +
|
|
1772
|
+
'\r\n';
|
|
1790
1773
|
}
|
|
1791
1774
|
}
|
|
1792
1775
|
|
|
1793
1776
|
// GEO
|
|
1794
1777
|
if (this.data.location?.geo?.lat && this.data.location.geo.lon) {
|
|
1795
|
-
g +=
|
|
1796
|
-
|
|
1778
|
+
g +=
|
|
1779
|
+
'GEO:' +
|
|
1780
|
+
escape(this.data.location.geo.lat, false) +
|
|
1781
|
+
';' +
|
|
1782
|
+
escape(this.data.location.geo.lon, false) +
|
|
1783
|
+
'\r\n';
|
|
1797
1784
|
}
|
|
1798
1785
|
|
|
1799
1786
|
// DESCRIPTION
|
|
1800
1787
|
if (this.data.description) {
|
|
1801
|
-
g +=
|
|
1788
|
+
g +=
|
|
1789
|
+
'DESCRIPTION:' +
|
|
1790
|
+
escape(this.data.description.plain, false) +
|
|
1791
|
+
'\r\n';
|
|
1802
1792
|
|
|
1803
1793
|
// HTML DESCRIPTION
|
|
1804
1794
|
if (this.data.description.html) {
|
|
1805
|
-
g +=
|
|
1795
|
+
g +=
|
|
1796
|
+
'X-ALT-DESC;FMTTYPE=text/html:' +
|
|
1797
|
+
escape(this.data.description.html, false) +
|
|
1798
|
+
'\r\n';
|
|
1806
1799
|
}
|
|
1807
1800
|
}
|
|
1808
1801
|
|
|
1809
1802
|
// ORGANIZER
|
|
1810
1803
|
if (this.data.organizer) {
|
|
1811
|
-
g +=
|
|
1804
|
+
g +=
|
|
1805
|
+
'ORGANIZER;CN="' + escape(this.data.organizer.name, true) + '"';
|
|
1812
1806
|
|
|
1813
1807
|
if (this.data.organizer.sentBy) {
|
|
1814
|
-
g +=
|
|
1808
|
+
g +=
|
|
1809
|
+
';SENT-BY="mailto:' +
|
|
1810
|
+
escape(this.data.organizer.sentBy, true) +
|
|
1811
|
+
'"';
|
|
1815
1812
|
}
|
|
1816
1813
|
if (this.data.organizer.email && this.data.organizer.mailto) {
|
|
1817
1814
|
g += ';EMAIL=' + escape(this.data.organizer.email, false);
|
|
1818
1815
|
}
|
|
1819
1816
|
|
|
1820
1817
|
g += ':';
|
|
1821
|
-
if(this.data.organizer.email) {
|
|
1822
|
-
g +=
|
|
1818
|
+
if (this.data.organizer.email) {
|
|
1819
|
+
g +=
|
|
1820
|
+
'mailto:' +
|
|
1821
|
+
escape(
|
|
1822
|
+
this.data.organizer.mailto || this.data.organizer.email,
|
|
1823
|
+
false,
|
|
1824
|
+
);
|
|
1823
1825
|
}
|
|
1824
1826
|
|
|
1825
1827
|
g += '\r\n';
|
|
@@ -1837,9 +1839,12 @@ export default class ICalEvent {
|
|
|
1837
1839
|
|
|
1838
1840
|
// CATEGORIES
|
|
1839
1841
|
if (this.data.categories.length > 0) {
|
|
1840
|
-
g +=
|
|
1841
|
-
|
|
1842
|
-
.
|
|
1842
|
+
g +=
|
|
1843
|
+
'CATEGORIES:' +
|
|
1844
|
+
this.data.categories
|
|
1845
|
+
.map((category) => category.toString())
|
|
1846
|
+
.join() +
|
|
1847
|
+
'\r\n';
|
|
1843
1848
|
}
|
|
1844
1849
|
|
|
1845
1850
|
// URL
|
|
@@ -1849,7 +1854,7 @@ export default class ICalEvent {
|
|
|
1849
1854
|
|
|
1850
1855
|
// ATTACHMENT
|
|
1851
1856
|
if (this.data.attachments.length > 0) {
|
|
1852
|
-
this.data.attachments.forEach(url => {
|
|
1857
|
+
this.data.attachments.forEach((url) => {
|
|
1853
1858
|
g += 'ATTACH:' + escape(url, false) + '\r\n';
|
|
1854
1859
|
});
|
|
1855
1860
|
}
|
|
@@ -1861,7 +1866,10 @@ export default class ICalEvent {
|
|
|
1861
1866
|
|
|
1862
1867
|
// BUSYSTATUS
|
|
1863
1868
|
if (this.data.busystatus) {
|
|
1864
|
-
g +=
|
|
1869
|
+
g +=
|
|
1870
|
+
'X-MICROSOFT-CDO-BUSYSTATUS:' +
|
|
1871
|
+
this.data.busystatus.toUpperCase() +
|
|
1872
|
+
'\r\n';
|
|
1865
1873
|
}
|
|
1866
1874
|
|
|
1867
1875
|
// PRIORITY
|
|
@@ -1874,19 +1882,186 @@ export default class ICalEvent {
|
|
|
1874
1882
|
|
|
1875
1883
|
// CREATED
|
|
1876
1884
|
if (this.data.created) {
|
|
1877
|
-
g +=
|
|
1885
|
+
g +=
|
|
1886
|
+
'CREATED:' +
|
|
1887
|
+
formatDate(this.calendar.timezone(), this.data.created) +
|
|
1888
|
+
'\r\n';
|
|
1878
1889
|
}
|
|
1879
1890
|
|
|
1880
1891
|
// LAST-MODIFIED
|
|
1881
1892
|
if (this.data.lastModified) {
|
|
1882
|
-
g +=
|
|
1893
|
+
g +=
|
|
1894
|
+
'LAST-MODIFIED:' +
|
|
1895
|
+
formatDate(this.calendar.timezone(), this.data.lastModified) +
|
|
1896
|
+
'\r\n';
|
|
1883
1897
|
}
|
|
1884
1898
|
|
|
1885
1899
|
if (this.data.class) {
|
|
1886
|
-
g+= 'CLASS:' + this.data.class.toUpperCase() + '\r\n';
|
|
1900
|
+
g += 'CLASS:' + this.data.class.toUpperCase() + '\r\n';
|
|
1887
1901
|
}
|
|
1888
1902
|
|
|
1889
1903
|
g += 'END:VEVENT\r\n';
|
|
1890
1904
|
return g;
|
|
1891
1905
|
}
|
|
1906
|
+
|
|
1907
|
+
/**
|
|
1908
|
+
* Get the event's transparency
|
|
1909
|
+
* @since 1.7.3
|
|
1910
|
+
*/
|
|
1911
|
+
transparency(): ICalEventTransparency | null;
|
|
1912
|
+
/**
|
|
1913
|
+
* Set the event's transparency
|
|
1914
|
+
*
|
|
1915
|
+
* Set the field to `OPAQUE` if the person or resource is no longer
|
|
1916
|
+
* available due to this event. If the calendar entry has no influence
|
|
1917
|
+
* on availability, you can set the field to `TRANSPARENT`. This value
|
|
1918
|
+
* is mostly used to find out if a person has time on a certain date or
|
|
1919
|
+
* not (see `TRANSP` in iCal specification).
|
|
1920
|
+
*
|
|
1921
|
+
* ```javascript
|
|
1922
|
+
* import ical, {ICalEventTransparency} from 'ical-generator';
|
|
1923
|
+
* event.transparency(ICalEventTransparency.OPAQUE);
|
|
1924
|
+
* ```
|
|
1925
|
+
*
|
|
1926
|
+
* @since 1.7.3
|
|
1927
|
+
*/
|
|
1928
|
+
transparency(transparency: ICalEventTransparency | null): this;
|
|
1929
|
+
transparency(
|
|
1930
|
+
transparency?: ICalEventTransparency | null,
|
|
1931
|
+
): ICalEventTransparency | null | this {
|
|
1932
|
+
if (transparency === undefined) {
|
|
1933
|
+
return this.data.transparency;
|
|
1934
|
+
}
|
|
1935
|
+
if (!transparency) {
|
|
1936
|
+
this.data.transparency = null;
|
|
1937
|
+
return this;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
this.data.transparency = checkEnum(
|
|
1941
|
+
ICalEventTransparency,
|
|
1942
|
+
transparency,
|
|
1943
|
+
) as ICalEventTransparency;
|
|
1944
|
+
return this;
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
/**
|
|
1948
|
+
* Get the event's ID
|
|
1949
|
+
* @since 0.2.0
|
|
1950
|
+
* @see {@link id}
|
|
1951
|
+
*/
|
|
1952
|
+
uid(): string;
|
|
1953
|
+
/**
|
|
1954
|
+
* Use this method to set the event's ID.
|
|
1955
|
+
* If not set, a UUID will be generated randomly.
|
|
1956
|
+
*
|
|
1957
|
+
* @param id Event ID you want to set
|
|
1958
|
+
*/
|
|
1959
|
+
uid(id: number | string): this;
|
|
1960
|
+
uid(id?: number | string): string | this {
|
|
1961
|
+
return id === undefined ? this.id() : this.id(id);
|
|
1962
|
+
}
|
|
1963
|
+
|
|
1964
|
+
/**
|
|
1965
|
+
* Get the event's URL
|
|
1966
|
+
* @since 0.2.0
|
|
1967
|
+
*/
|
|
1968
|
+
url(): null | string;
|
|
1969
|
+
/**
|
|
1970
|
+
* Set the event's URL
|
|
1971
|
+
* @since 0.2.0
|
|
1972
|
+
*/
|
|
1973
|
+
url(url: null | string): this;
|
|
1974
|
+
url(url?: null | string): null | string | this {
|
|
1975
|
+
if (url === undefined) {
|
|
1976
|
+
return this.data.url;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
this.data.url = url ? String(url) : null;
|
|
1980
|
+
return this;
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
/**
|
|
1984
|
+
* Set X-* attributes. Woun't filter double attributes,
|
|
1985
|
+
* which are also added by another method (e.g. summary),
|
|
1986
|
+
* so these attributes may be inserted twice.
|
|
1987
|
+
*
|
|
1988
|
+
* ```javascript
|
|
1989
|
+
* event.x([
|
|
1990
|
+
* {
|
|
1991
|
+
* key: "X-MY-CUSTOM-ATTR",
|
|
1992
|
+
* value: "1337!"
|
|
1993
|
+
* }
|
|
1994
|
+
* ]);
|
|
1995
|
+
*
|
|
1996
|
+
* event.x([
|
|
1997
|
+
* ["X-MY-CUSTOM-ATTR", "1337!"]
|
|
1998
|
+
* ]);
|
|
1999
|
+
*
|
|
2000
|
+
* event.x({
|
|
2001
|
+
* "X-MY-CUSTOM-ATTR": "1337!"
|
|
2002
|
+
* });
|
|
2003
|
+
* ```
|
|
2004
|
+
*
|
|
2005
|
+
* @since 1.9.0
|
|
2006
|
+
*/
|
|
2007
|
+
x(
|
|
2008
|
+
keyOrArray:
|
|
2009
|
+
| [string, string][]
|
|
2010
|
+
| Record<string, string>
|
|
2011
|
+
| { key: string; value: string }[],
|
|
2012
|
+
): this;
|
|
2013
|
+
/**
|
|
2014
|
+
* Set a X-* attribute. Woun't filter double attributes,
|
|
2015
|
+
* which are also added by another method (e.g. summary),
|
|
2016
|
+
* so these attributes may be inserted twice.
|
|
2017
|
+
*
|
|
2018
|
+
* ```javascript
|
|
2019
|
+
* event.x("X-MY-CUSTOM-ATTR", "1337!");
|
|
2020
|
+
* ```
|
|
2021
|
+
*
|
|
2022
|
+
* @since 1.9.0
|
|
2023
|
+
*/
|
|
2024
|
+
x(keyOrArray: string, value: string): this;
|
|
2025
|
+
/**
|
|
2026
|
+
* Get all custom X-* attributes.
|
|
2027
|
+
* @since 1.9.0
|
|
2028
|
+
*/
|
|
2029
|
+
x(): { key: string; value: string }[];
|
|
2030
|
+
x(
|
|
2031
|
+
keyOrArray?:
|
|
2032
|
+
| [string, string][]
|
|
2033
|
+
| Record<string, string>
|
|
2034
|
+
| string
|
|
2035
|
+
| { key: string; value: string }[],
|
|
2036
|
+
value?: string,
|
|
2037
|
+
): this | void | { key: string; value: string }[] {
|
|
2038
|
+
if (keyOrArray === undefined) {
|
|
2039
|
+
return addOrGetCustomAttributes(this.data);
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
if (typeof keyOrArray === 'string' && typeof value === 'string') {
|
|
2043
|
+
addOrGetCustomAttributes(this.data, keyOrArray, value);
|
|
2044
|
+
}
|
|
2045
|
+
if (typeof keyOrArray === 'object') {
|
|
2046
|
+
addOrGetCustomAttributes(this.data, keyOrArray);
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
return this;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
/**
|
|
2053
|
+
* Checks if the start date is after the end date and swaps them if necessary.
|
|
2054
|
+
* @private
|
|
2055
|
+
*/
|
|
2056
|
+
private swapStartAndEndIfRequired(): void {
|
|
2057
|
+
if (
|
|
2058
|
+
this.data.start &&
|
|
2059
|
+
this.data.end &&
|
|
2060
|
+
toDate(this.data.start).getTime() > toDate(this.data.end).getTime()
|
|
2061
|
+
) {
|
|
2062
|
+
const t = this.data.start;
|
|
2063
|
+
this.data.start = this.data.end;
|
|
2064
|
+
this.data.end = t;
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
1892
2067
|
}
|