ical-generator 1.12.2 → 1.15.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/CHANGELOG.md CHANGED
@@ -4,6 +4,27 @@ _The following document documents changes to this library. Changes to the depend
4
4
 
5
5
  <br />
6
6
 
7
+ ## [1.15.1](https://github.com/sebbo2002/ical-generator/releases/tag/1.15.1) - 2020-10-03
8
+ ### Bugfix
9
+ - Typings: OPT_PARTICIPANT should be OPT-PARTICIPANT (#192)
10
+
11
+ ## [1.15.0](https://github.com/sebbo2002/ical-generator/releases/tag/1.15.0) - 2020-08-24
12
+ ### Feature
13
+ - Events: Add WKST support
14
+
15
+
16
+ ## [1.14.0](https://github.com/sebbo2002/ical-generator/releases/tag/1.14.0) - 2020-08-18
17
+ ### Bugfix
18
+ - Make x key optional in types (#211)
19
+
20
+ ### Feature
21
+ - Events: Use provided timezone when constructing `repeating.exclude`
22
+
23
+
24
+ ## [1.13.0](https://github.com/sebbo2002/ical-generator/releases/tag/1.13.0) - 2020-08-12
25
+ ### Feature
26
+ - Made Event.domain optional
27
+
7
28
  ## [1.12.2](https://github.com/sebbo2002/ical-generator/releases/tag/1.12.2) - 2020-08-11
8
29
  ### Bugfix
9
30
  - Don't modify input to createEvent()
package/README.md CHANGED
@@ -125,8 +125,8 @@ cal.domain('sebbo.net');
125
125
 
126
126
  #### domain([_String_ domain])
127
127
 
128
- Use this method to set your server's hostname. It will be used to generate the feed's UID. Default hostname is your
129
- server's one (`require('os').hostname()`).
128
+ Use this method to set your server's hostname. If provided, it will be used to generate the feed's UID.
129
+ `require('os').hostname()` can be used to get your server's hostname.
130
130
 
131
131
 
132
132
  #### prodId([_String_|_Object_ prodId])
@@ -289,7 +289,10 @@ Empty the Calender.
289
289
 
290
290
  #### uid([_String_|_Number_ uid]) or id([_String_|_Number_ id])
291
291
 
292
- Use this method to set the event's ID. If not set, an UID will be generated randomly. When output, the ID will be suffixed with '@' + your calendar's domain.
292
+ Use this method to set the event's ID. If not set, an UID will be generated randomly.
293
+ If your calendar's domain is provided, the ID will be suffixed with '@' + your calendar's domain.
294
+ If you do not provide a calendar domain, generating an ID using the
295
+ [uuid](https://www.npmjs.com/package/uuid) module is recommended.
293
296
 
294
297
 
295
298
  #### sequence([_Number_ sequence])
@@ -355,7 +358,8 @@ event.repeating({
355
358
  byMonthDay: [1, 15], // repeat only on the 1st and 15th
356
359
  bySetPos: 3, // repeat every 3rd sunday (will take the first element of the byDay array)
357
360
  exclude: [new Date('Dec 25 2013 00:00:00 UTC')], // exclude these dates
358
- excludeTimezone: 'Europe/Berlin' // timezone of exclude
361
+ excludeTimezone: 'Europe/Berlin', // timezone of exclude
362
+ wkst: 'SU' // Start the week on Sunday, default is Monday
359
363
  });
360
364
  ```
361
365
 
package/dist/event.js CHANGED
@@ -510,7 +510,13 @@ var ICalEvent = /*#__PURE__*/function () {
510
510
  c._data.repeating.exclude = [];
511
511
  exclude.forEach(function (excludedDate, i) {
512
512
  if (typeof excludedDate === 'string') {
513
- excludedDate = moment(excludedDate);
513
+ var timezone = _repeating.excludeTimezone || c._calendar._data.timezone;
514
+
515
+ if (timezone) {
516
+ excludedDate = moment.tz(excludedDate, timezone);
517
+ } else {
518
+ excludedDate = moment(excludedDate);
519
+ }
514
520
  } else if (excludedDate instanceof Date) {
515
521
  excludedDate = moment(excludedDate);
516
522
  } else if (!moment.isMoment(excludedDate)) {
@@ -533,6 +539,16 @@ var ICalEvent = /*#__PURE__*/function () {
533
539
  c._data.repeating.excludeTimezone = _repeating.excludeTimezone;
534
540
  }
535
541
 
542
+ if (_repeating.wkst) {
543
+ var wkst = _repeating.wkst;
544
+
545
+ if (['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'].indexOf(wkst) === -1) {
546
+ throw new Error('`repeating.wkst` contains invalid value `' + wkst + '`!');
547
+ }
548
+
549
+ c._data.repeating.wkst = wkst;
550
+ }
551
+
536
552
  return c;
537
553
  }
538
554
  /**
@@ -1101,7 +1117,15 @@ var ICalEvent = /*#__PURE__*/function () {
1101
1117
 
1102
1118
 
1103
1119
  g += 'BEGIN:VEVENT\r\n';
1104
- g += 'UID:' + this._data.id + '@' + this._calendar.domain() + '\r\n'; // SEQUENCE
1120
+
1121
+ var domain = this._calendar.domain();
1122
+
1123
+ if (domain) {
1124
+ g += 'UID:' + this._data.id + '@' + domain + '\r\n';
1125
+ } else {
1126
+ g += 'UID:' + this._data.id + '\r\n';
1127
+ } // SEQUENCE
1128
+
1105
1129
 
1106
1130
  g += 'SEQUENCE:' + this._data.sequence + '\r\n';
1107
1131
  g += 'DTSTAMP:' + ICalTools.formatDate(this._calendar.timezone(), this._data.stamp) + '\r\n';
@@ -1155,6 +1179,10 @@ var ICalEvent = /*#__PURE__*/function () {
1155
1179
  g += ';BYSETPOS=' + this._data.repeating.bySetPos;
1156
1180
  }
1157
1181
 
1182
+ if (this._data.repeating.wkst) {
1183
+ g += ';WKST=' + this._data.repeating.wkst;
1184
+ }
1185
+
1158
1186
  g += '\r\n'; // REPEATING EXCLUSION
1159
1187
 
1160
1188
  if (this._data.repeating.exclude) {
package/index.d.ts CHANGED
@@ -17,10 +17,10 @@ declare module 'ical-generator' {
17
17
  type status = 'CONFIRMED' | 'TENTATIVE' | 'CANCELLED';
18
18
  type busystatus = 'FREE' | 'TENTATIVE' | 'BUSY' | 'OOF';
19
19
  type day = 'SU' | 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA';
20
- type attendeeRole = 'CHAIR' | 'REQ-PARTICIPANT' | 'OPT_PARTICIPANT' | 'NON-PARTICIPANT';
21
- type attendeeStatus = 'ACCEPTED' | 'TENTATIVE'| 'DECLINED'| 'DELEGATED' | 'NEEDS-ACTION';
22
- type attendeeRsvp = 'true' | 'false'| true| false;
23
- type attendeeType = 'INDIVIDUAL'| 'GROUP'| 'RESOURCE'| 'ROOM'| 'UNKNOWN';
20
+ type attendeeRole = 'CHAIR' | 'REQ-PARTICIPANT' | 'OPT-PARTICIPANT' | 'NON-PARTICIPANT';
21
+ type attendeeStatus = 'ACCEPTED' | 'TENTATIVE' | 'DECLINED' | 'DELEGATED' | 'NEEDS-ACTION';
22
+ type attendeeRsvp = 'true' | 'false' | true | false;
23
+ type attendeeType = 'INDIVIDUAL' | 'GROUP' | 'RESOURCE' | 'ROOM' | 'UNKNOWN';
24
24
  type alarmType = 'display' | 'audio';
25
25
 
26
26
 
@@ -81,7 +81,7 @@ declare module 'ical-generator' {
81
81
  timezone?: string;
82
82
  recurrenceId?: moment.Moment | Date | string;
83
83
  transparency?: string;
84
- x: { key:string, value:string }[];
84
+ x?: { key: string, value: string }[];
85
85
  }
86
86
 
87
87
  interface RepeatingData {
@@ -94,6 +94,7 @@ declare module 'ical-generator' {
94
94
  byMonthDay?: number[];
95
95
  bySetPos?: number;
96
96
  exclude?: moment.Moment[] | Date[] | string[];
97
+ wkst?: day;
97
98
  }
98
99
 
99
100
  /**
@@ -192,7 +193,7 @@ declare module 'ical-generator' {
192
193
  sequence(): number;
193
194
  sequence(sequence: number): ICalEvent;
194
195
  start(): moment.Moment;
195
- start(start: string | moment.Moment | Date): ICalEvent;
196
+ start(start: string | moment.Moment | Date): ICalEvent;
196
197
  end(): moment.Moment;
197
198
  end(end: string | moment.Moment | Date): ICalEvent;
198
199
  recurrenceId(): moment.Moment;
package/package.json CHANGED
@@ -14,21 +14,21 @@
14
14
  "moment-timezone": "^0.5.31"
15
15
  },
16
16
  "devDependencies": {
17
- "@babel/cli": "^7.10.5",
18
- "@babel/core": "^7.11.1",
19
- "@babel/preset-env": "^7.11.0",
17
+ "@babel/cli": "^7.11.6",
18
+ "@babel/core": "^7.11.6",
19
+ "@babel/preset-env": "^7.11.5",
20
20
  "babel-loader": "^8.1.0",
21
- "babel-plugin-add-module-exports": "^1.0.2",
22
- "eslint": "^7.6.0",
21
+ "babel-plugin-add-module-exports": "^1.0.4",
22
+ "eslint": "^7.10.0",
23
23
  "jquery": "^3.5.1",
24
24
  "jshint": "^2.12.0",
25
- "mocha": "^8.1.1",
25
+ "mocha": "^8.1.3",
26
26
  "mochawesome": "^6.1.1",
27
- "moment": "^2.27.0",
27
+ "moment": "^2.29.0",
28
28
  "npm-check": "^5.9.2",
29
29
  "nyc": "^15.1.0",
30
30
  "portfinder": "^1.0.28",
31
- "webpack": "^4.44.1",
31
+ "webpack": "^4.44.2",
32
32
  "webpack-cli": "^3.3.12"
33
33
  },
34
34
  "peerDependencies": {
@@ -55,5 +55,5 @@
55
55
  },
56
56
  "typings": "index.d.ts",
57
57
  "runkitExampleFilename": "examples/example-runkit.js",
58
- "version": "1.12.2"
58
+ "version": "1.15.1"
59
59
  }
package/src/event.js CHANGED
@@ -504,7 +504,13 @@ class ICalEvent {
504
504
  c._data.repeating.exclude = [];
505
505
  exclude.forEach(function (excludedDate, i) {
506
506
  if (typeof excludedDate === 'string') {
507
- excludedDate = moment(excludedDate);
507
+ let timezone = repeating.excludeTimezone || c._calendar._data.timezone;
508
+ if (timezone) {
509
+ excludedDate = moment.tz(excludedDate, timezone);
510
+ }
511
+ else {
512
+ excludedDate = moment(excludedDate);
513
+ }
508
514
  }
509
515
  else if (excludedDate instanceof Date) {
510
516
  excludedDate = moment(excludedDate);
@@ -529,6 +535,14 @@ class ICalEvent {
529
535
  c._data.repeating.excludeTimezone = repeating.excludeTimezone;
530
536
  }
531
537
 
538
+ if (repeating.wkst) {
539
+ let {wkst} = repeating;
540
+ if (['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'].indexOf(wkst) === -1) {
541
+ throw new Error('`repeating.wkst` contains invalid value `' + wkst + '`!');
542
+ }
543
+ c._data.repeating.wkst = wkst;
544
+ }
545
+
532
546
  return c;
533
547
  }
534
548
 
@@ -1059,7 +1073,13 @@ class ICalEvent {
1059
1073
 
1060
1074
  // DATE & TIME
1061
1075
  g += 'BEGIN:VEVENT\r\n';
1062
- g += 'UID:' + this._data.id + '@' + this._calendar.domain() + '\r\n';
1076
+ let domain = this._calendar.domain();
1077
+ if (domain) {
1078
+ g += 'UID:' + this._data.id + '@' + domain + '\r\n';
1079
+ }
1080
+ else {
1081
+ g += 'UID:' + this._data.id + '\r\n';
1082
+ }
1063
1083
 
1064
1084
  // SEQUENCE
1065
1085
  g += 'SEQUENCE:' + this._data.sequence + '\r\n';
@@ -1113,6 +1133,10 @@ class ICalEvent {
1113
1133
  g += ';BYSETPOS=' + this._data.repeating.bySetPos;
1114
1134
  }
1115
1135
 
1136
+ if (this._data.repeating.wkst) {
1137
+ g += ';WKST=' + this._data.repeating.wkst;
1138
+ }
1139
+
1116
1140
  g += '\r\n';
1117
1141
 
1118
1142
  // REPEATING EXCLUSION
@@ -901,6 +901,27 @@ describe('ical-generator Event', function () {
901
901
 
902
902
  assert.ok(e._data.repeating.excludeTimezone, 'Europe/Berlin');
903
903
  });
904
+
905
+ it('should throw error when repeating.wkst is not valid', function () {
906
+ assert.throws(function () {
907
+ new ICalEvent({
908
+ start: moment(),
909
+ summary: 'test',
910
+ repeating: {
911
+ freq: 'DAILY',
912
+ interval: 2,
913
+ wkst: 'FOO'
914
+ }
915
+ }, new ICalCalendar());
916
+ }, /`repeating\.wkst` contains invalid value `FOO`/);
917
+ });
918
+
919
+ it('setter should update repeating.wkst', function () {
920
+ const e = new ICalEvent(null, new ICalCalendar());
921
+
922
+ e.repeating({freq: 'monthly', wkst: 'SU'});
923
+ assert.deepStrictEqual(e._data.repeating.wkst, 'SU');
924
+ });
904
925
  });
905
926
 
906
927
  describe('summary()', function () {
@@ -1071,7 +1092,7 @@ describe('ical-generator Event', function () {
1071
1092
  radius: 40,
1072
1093
  geo: {
1073
1094
  lat: '52.063921',
1074
- lon: '5.128511',
1095
+ lon: '5.128511'
1075
1096
  }
1076
1097
  };
1077
1098
  assert.deepEqual(e.appleLocation(), {
@@ -1080,7 +1101,7 @@ describe('ical-generator Event', function () {
1080
1101
  radius: 40,
1081
1102
  geo: {
1082
1103
  lat: '52.063921',
1083
- lon: '5.128511',
1104
+ lon: '5.128511'
1084
1105
  }
1085
1106
  });
1086
1107
 
@@ -1097,7 +1118,7 @@ describe('ical-generator Event', function () {
1097
1118
  radius: 40,
1098
1119
  geo: {
1099
1120
  lat: '52.063921',
1100
- lon: '5.128511',
1121
+ lon: '5.128511'
1101
1122
  }
1102
1123
  }));
1103
1124
  });
@@ -1114,7 +1135,7 @@ describe('ical-generator Event', function () {
1114
1135
  radius: 40,
1115
1136
  geo: {
1116
1137
  lat: '52.063921',
1117
- lon: '5.128511',
1138
+ lon: '5.128511'
1118
1139
  }
1119
1140
  });
1120
1141
  assert.deepEqual(event._data.appleLocation, {
@@ -1123,7 +1144,7 @@ describe('ical-generator Event', function () {
1123
1144
  radius: 40,
1124
1145
  geo: {
1125
1146
  lat: '52.063921',
1126
- lon: '5.128511',
1147
+ lon: '5.128511'
1127
1148
  }
1128
1149
  });
1129
1150
  });
@@ -1141,7 +1162,7 @@ describe('ical-generator Event', function () {
1141
1162
  radius: 40,
1142
1163
  geo: {
1143
1164
  lat: '52.063921',
1144
- lon: '5.128511',
1165
+ lon: '5.128511'
1145
1166
  }
1146
1167
  });
1147
1168
  assert.ok(event._data.location !== 'Batman Cave', null);
@@ -1731,12 +1752,34 @@ describe('ical-generator Event', function () {
1731
1752
  summary: ':)'
1732
1753
  }, cal);
1733
1754
 
1734
- assert.ok(event._generate().indexOf('UID:42@') > -1, 'without domain');
1755
+ assert.ok(event._generate().indexOf('UID:42\r') > -1, 'without domain');
1735
1756
 
1736
1757
  cal.domain('dojo-enterprises.wtf');
1737
1758
  assert.ok(event._generate().indexOf('UID:42@dojo-enterprises.wtf') > -1, 'with domain');
1738
1759
  });
1739
1760
 
1761
+ it('should include wkst only if provided', function () {
1762
+ const cal = new ICalCalendar();
1763
+ let event = new ICalEvent({
1764
+ start: moment(),
1765
+ end: moment(),
1766
+ repeating: {
1767
+ freq: 'weekly'
1768
+ }
1769
+ }, cal);
1770
+ assert.ok(event._generate().indexOf('WKST') === -1, 'without WKST');
1771
+
1772
+ event = new ICalEvent({
1773
+ start: moment(),
1774
+ end: moment(),
1775
+ repeating: {
1776
+ freq: 'weekly',
1777
+ wkst: 'SU'
1778
+ }
1779
+ }, cal);
1780
+ assert.ok(event._generate().indexOf('WKST') > -1, 'without WKST');
1781
+ });
1782
+
1740
1783
  /*it('case #1', function () {
1741
1784
  const cal = ical({domain: 'sebbo.net', prodId: '//sebbo.net//ical-generator.tests//EN'});
1742
1785
  cal.createEvent({
@@ -106,4 +106,47 @@ describe('Issues', function () {
106
106
  });
107
107
  });
108
108
  });
109
+
110
+ describe('Issue #210', function () {
111
+ it('should repeat/exclude with Europe/Berlin', function () {
112
+ const calendar = ical({
113
+ domain: 'sebbo.net',
114
+ prodId: '//superman-industries.com//ical-generator//EN',
115
+ timezone: 'Europe/Berlin',
116
+ events: [{
117
+ start: '2020-08-13T00:00:00',
118
+ summary: 'Example Event',
119
+ repeating: {
120
+ freq: 'MONTHLY',
121
+ count: 12,
122
+ exclude: '2020-12-13T00:00:00',
123
+ excludeTimezone: 'Europe/Berlin'
124
+ }
125
+ }]
126
+ });
127
+
128
+ const str = calendar.toString();
129
+ assert.ok(str.indexOf('EXDATE;TZID=Europe/Berlin:20201213T000000') > -1);
130
+ });
131
+ it('should repeat/exclude with America/New_York', function () {
132
+ const calendar = ical({
133
+ domain: 'sebbo.net',
134
+ prodId: '//superman-industries.com//ical-generator//EN',
135
+ timezone: 'America/New_York',
136
+ events: [{
137
+ start: '2020-08-13T00:00:00',
138
+ summary: 'Example Event',
139
+ repeating: {
140
+ freq: 'MONTHLY',
141
+ count: 12,
142
+ exclude: '2020-12-13T00:00:00',
143
+ excludeTimezone: 'America/New_York',
144
+ }
145
+ }]
146
+ });
147
+
148
+ const str = calendar.toString();
149
+ assert.ok(str.indexOf('EXDATE;TZID=America/New_York:20201213T000000') > -1);
150
+ });
151
+ });
109
152
  });