@sprucelabs/calendar-utils 42.0.489 → 42.0.491
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/build/esm/errors/SpruceError.js +1 -1
- package/build/esm/locales/DateUtilDecorator.js +24 -12
- package/build/esm/locales/Locale.js +9 -20
- package/build/esm/parsing/DateParser.js +5 -1
- package/build/esm/parsing/strategies/DowParser.js +1 -2
- package/build/esm/parsing/strategies/TimeParser.js +3 -4
- package/build/esm/parsing/strategies/WeekParser.js +1 -2
- package/build/esm/schemas/v2021_05_19/calendarEvent.builder.js +5 -2
- package/build/esm/utilities/DurationUtilBuilder.js +9 -20
- package/build/esm/utilities/PeopleSorter.js +3 -5
- package/build/esm/utilities/RepeatingRuleTextGenerator.js +2 -2
- package/build/esm/utilities/calendar.utility.js +10 -6
- package/build/esm/utilities/date.utility.js +1 -2
- package/build/esm/utilities/duration.utility.js +1 -1
- package/build/esm/utilities/sortTimezoneChoices.js +5 -3
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@ export default class SpruceError extends BaseSpruceError {
|
|
|
4
4
|
friendlyMessage() {
|
|
5
5
|
const { options } = this;
|
|
6
6
|
let message;
|
|
7
|
-
switch (options
|
|
7
|
+
switch (options?.code) {
|
|
8
8
|
case 'INVALID_TIMEZONE_NAME':
|
|
9
9
|
message = `Invalid timezone: ${options.name}!`;
|
|
10
10
|
break;
|
|
@@ -7,9 +7,12 @@ export default class DateUtilDecorator {
|
|
|
7
7
|
}
|
|
8
8
|
makeLocaleAware(dateUtil) {
|
|
9
9
|
assertOptions({ dateUtil }, ['dateUtil']);
|
|
10
|
-
return
|
|
10
|
+
return {
|
|
11
|
+
...dateUtil,
|
|
11
12
|
//@ts-ignore
|
|
12
|
-
__beenDecorated: true,
|
|
13
|
+
__beenDecorated: true,
|
|
14
|
+
__locale: this.locale,
|
|
15
|
+
date: (date) => {
|
|
13
16
|
let value;
|
|
14
17
|
if (!date) {
|
|
15
18
|
const d = new Date();
|
|
@@ -22,26 +25,35 @@ export default class DateUtilDecorator {
|
|
|
22
25
|
return value - offset;
|
|
23
26
|
}
|
|
24
27
|
return this.addOffset(value);
|
|
25
|
-
},
|
|
28
|
+
},
|
|
29
|
+
setTimeOfDay: (...args) => {
|
|
26
30
|
return this.addOffset(dateUtil.setTimeOfDay(...args));
|
|
27
|
-
},
|
|
31
|
+
},
|
|
32
|
+
format: (date, format) => {
|
|
28
33
|
return dateUtil.format(this.addOffset(date, false), format);
|
|
29
|
-
},
|
|
34
|
+
},
|
|
35
|
+
getStartOfDay: (date) => {
|
|
30
36
|
return this.addOffset(dateUtil.getStartOfDay(this.offsetDate(date)));
|
|
31
|
-
},
|
|
37
|
+
},
|
|
38
|
+
getEndOfDay: (date) => {
|
|
32
39
|
return this.addOffset(dateUtil.getEndOfDay(this.offsetDate(date)));
|
|
33
|
-
},
|
|
40
|
+
},
|
|
41
|
+
getStartOfMonth: (date) => {
|
|
34
42
|
return this.addOffset(dateUtil.getStartOfMonth(this.offsetDate(date)));
|
|
35
|
-
},
|
|
43
|
+
},
|
|
44
|
+
getEndOfMonth: (date) => {
|
|
36
45
|
return this.addOffset(dateUtil.getEndOfMonth(this.offsetDate(date)));
|
|
37
|
-
},
|
|
46
|
+
},
|
|
47
|
+
splitDate: (timestamp) => {
|
|
38
48
|
return dateUtil.splitDate(this.addOffset(timestamp, false));
|
|
39
|
-
},
|
|
49
|
+
},
|
|
50
|
+
addMonths: (date, months) => {
|
|
40
51
|
return this.addOffset(dateUtil.addMonths(this.addOffset(date, false), months));
|
|
41
|
-
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
42
54
|
}
|
|
43
55
|
offsetDate(date) {
|
|
44
|
-
return this.addOffset(date
|
|
56
|
+
return this.addOffset(date ?? new Date().getTime(), false);
|
|
45
57
|
}
|
|
46
58
|
addOffset(value, shouldInverse = true) {
|
|
47
59
|
let offset = this.calculateOffset(value);
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { AbstractEventEmitter } from '@sprucelabs/mercury-event-emitter';
|
|
11
2
|
import { buildEventContract } from '@sprucelabs/mercury-types';
|
|
12
3
|
import { assertOptions, buildSchema } from '@sprucelabs/schema';
|
|
@@ -30,7 +21,7 @@ export default class LocaleImpl extends AbstractEventEmitter {
|
|
|
30
21
|
if (onDate || timezone) {
|
|
31
22
|
const date = onDate ? onDate : Date.now();
|
|
32
23
|
const dateRoundedToNearestHour = date - (date % 3600000);
|
|
33
|
-
const zone = timezone
|
|
24
|
+
const zone = timezone ?? this.getZoneName();
|
|
34
25
|
const key = `${zone}-${dateRoundedToNearestHour}`;
|
|
35
26
|
if (!(key in this.offsetsForDate)) {
|
|
36
27
|
this.offsetsForDate[key] = this.zoneNameToOffsetMinutes(zone, onDate);
|
|
@@ -39,16 +30,14 @@ export default class LocaleImpl extends AbstractEventEmitter {
|
|
|
39
30
|
}
|
|
40
31
|
return this.offset;
|
|
41
32
|
}
|
|
42
|
-
setZoneName(zone) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
zoneName: zone,
|
|
51
|
-
});
|
|
33
|
+
async setZoneName(zone) {
|
|
34
|
+
if (this.currentZone === zone) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.currentZone = zone;
|
|
38
|
+
this.offset = this.zoneNameToOffsetMinutes(zone);
|
|
39
|
+
await this.emit('did-change-timezones', {
|
|
40
|
+
zoneName: zone,
|
|
52
41
|
});
|
|
53
42
|
}
|
|
54
43
|
getZoneName() {
|
|
@@ -32,7 +32,11 @@ export default class DateParser {
|
|
|
32
32
|
if (parsed === original) {
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
-
let normalized = dateUtil.date(
|
|
35
|
+
let normalized = dateUtil.date({
|
|
36
|
+
...date,
|
|
37
|
+
milliseconds: 0,
|
|
38
|
+
second: 0,
|
|
39
|
+
});
|
|
36
40
|
return normalized;
|
|
37
41
|
}
|
|
38
42
|
}
|
|
@@ -2,7 +2,6 @@ import dateUtil from '../../utilities/date.utility.js';
|
|
|
2
2
|
import { AbstractParser } from '../AbstractParser.js';
|
|
3
3
|
export default class DowParser extends AbstractParser {
|
|
4
4
|
parse(str, date) {
|
|
5
|
-
var _a;
|
|
6
5
|
if (str.includes('tomorrow')) {
|
|
7
6
|
date.day += 1;
|
|
8
7
|
str = str.replace('tomorrow', '');
|
|
@@ -41,7 +40,7 @@ export default class DowParser extends AbstractParser {
|
|
|
41
40
|
const re = new RegExp(`(^|\\W)${dow.abbr}(\\W|$)`, 'gi');
|
|
42
41
|
str = str.replace(re, `$1${dow.full}$2`);
|
|
43
42
|
}
|
|
44
|
-
const match =
|
|
43
|
+
const match = str.match(/(monday|tuesday|wednesday|thursday|friday|saturday|sunday)/)?.[0];
|
|
45
44
|
if (match) {
|
|
46
45
|
while (dateUtil
|
|
47
46
|
.format(dateUtil.date(date), 'EEEE')
|
|
@@ -2,8 +2,7 @@ import dateUtil from '../../utilities/date.utility.js';
|
|
|
2
2
|
import { AbstractParser } from '../AbstractParser.js';
|
|
3
3
|
export default class TimeParser extends AbstractParser {
|
|
4
4
|
parse(str, date, context) {
|
|
5
|
-
|
|
6
|
-
const matches = (_a = str.match(/(\d{1,2})(:?(\d{1,2}))?\s*([ap]m?)?/)) !== null && _a !== void 0 ? _a : [];
|
|
5
|
+
const matches = str.match(/(\d{1,2})(:?(\d{1,2}))?\s*([ap]m?)?/) ?? [];
|
|
7
6
|
let [match, hour, , minutes, ampm] = matches;
|
|
8
7
|
if (!match) {
|
|
9
8
|
return str;
|
|
@@ -11,7 +10,7 @@ export default class TimeParser extends AbstractParser {
|
|
|
11
10
|
if (hour) {
|
|
12
11
|
let parsedHour = parseInt(hour, 10);
|
|
13
12
|
if (parsedHour > 12) {
|
|
14
|
-
minutes = hour[1] + (minutes
|
|
13
|
+
minutes = hour[1] + (minutes ?? '');
|
|
15
14
|
hour = hour[0];
|
|
16
15
|
parsedHour = parseInt(hour, 10);
|
|
17
16
|
}
|
|
@@ -24,7 +23,7 @@ export default class TimeParser extends AbstractParser {
|
|
|
24
23
|
}
|
|
25
24
|
date.minute = parseInt(minutes, 10);
|
|
26
25
|
}
|
|
27
|
-
if (ampm
|
|
26
|
+
if (ampm?.includes('p')) {
|
|
28
27
|
date.hour += 12;
|
|
29
28
|
}
|
|
30
29
|
else if (date.hour === 12 && match.includes('am')) {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { AbstractParser } from '../AbstractParser.js';
|
|
2
2
|
export default class WeekParser extends AbstractParser {
|
|
3
3
|
parse(str, date) {
|
|
4
|
-
var _a;
|
|
5
4
|
if (str.includes('next week')) {
|
|
6
5
|
date.day += 7;
|
|
7
6
|
str = str.replace('next week', '');
|
|
8
7
|
}
|
|
9
|
-
const match =
|
|
8
|
+
const match = str.match(/(\d{1,2}) ?(weeks?)/)?.[0];
|
|
10
9
|
if (match) {
|
|
11
10
|
date.day += parseInt(match, 10) * 7;
|
|
12
11
|
str = str.replace(match, '');
|
|
@@ -76,10 +76,13 @@ export default buildSchema({
|
|
|
76
76
|
options: {
|
|
77
77
|
schema: {
|
|
78
78
|
id: 'calendarEventTarget',
|
|
79
|
-
fields:
|
|
79
|
+
fields: {
|
|
80
|
+
...eventTargetSchema.fields,
|
|
81
|
+
personId: {
|
|
80
82
|
type: 'id',
|
|
81
83
|
isRequired: true,
|
|
82
|
-
}
|
|
84
|
+
},
|
|
85
|
+
},
|
|
83
86
|
},
|
|
84
87
|
},
|
|
85
88
|
},
|
|
@@ -1,30 +1,19 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import DateUtilDecorator from '../locales/DateUtilDecorator.js';
|
|
11
2
|
import LocaleImpl from '../locales/Locale.js';
|
|
12
3
|
import dateUtil from './date.utility.js';
|
|
13
4
|
import durationUtil from './duration.utility.js';
|
|
14
5
|
class DurationUtilBuilder {
|
|
15
|
-
static getForTimezone(timezone) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return durationUtilCopy;
|
|
23
|
-
});
|
|
6
|
+
static async getForTimezone(timezone) {
|
|
7
|
+
const locale = new LocaleImpl();
|
|
8
|
+
await locale.setZoneName(timezone);
|
|
9
|
+
const durationUtilCopy = { ...this.durationUtil };
|
|
10
|
+
durationUtilCopy.dates = new DateUtilDecorator(locale).makeLocaleAware(dateUtil);
|
|
11
|
+
this.lastBuiltDurationUtil = durationUtilCopy;
|
|
12
|
+
return durationUtilCopy;
|
|
24
13
|
}
|
|
25
14
|
static reset() {
|
|
26
|
-
this.durationUtil =
|
|
15
|
+
this.durationUtil = { ...durationUtil };
|
|
27
16
|
}
|
|
28
17
|
}
|
|
29
|
-
DurationUtilBuilder.durationUtil =
|
|
18
|
+
DurationUtilBuilder.durationUtil = { ...durationUtil };
|
|
30
19
|
export default DurationUtilBuilder;
|
|
@@ -29,7 +29,7 @@ export default class PeopleSorter {
|
|
|
29
29
|
}
|
|
30
30
|
peopleExcluding(selectedPeopleWithValidEvents) {
|
|
31
31
|
return this.people.filter((p) => {
|
|
32
|
-
const match = selectedPeopleWithValidEvents.find((sp) =>
|
|
32
|
+
const match = selectedPeopleWithValidEvents.find((sp) => sp?.id === p.id);
|
|
33
33
|
if (match) {
|
|
34
34
|
return false;
|
|
35
35
|
}
|
|
@@ -94,12 +94,10 @@ export default class PeopleSorter {
|
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
get people() {
|
|
97
|
-
|
|
98
|
-
return (_a = this._people) !== null && _a !== void 0 ? _a : [];
|
|
97
|
+
return this._people ?? [];
|
|
99
98
|
}
|
|
100
99
|
get events() {
|
|
101
|
-
|
|
102
|
-
return (_a = this._events) !== null && _a !== void 0 ? _a : [];
|
|
100
|
+
return this._events ?? [];
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
function sortByCasualName(people) {
|
|
@@ -30,13 +30,13 @@ export default class RepeatingRuleTextGenerator {
|
|
|
30
30
|
.map((d) => this.downMap[d])
|
|
31
31
|
.join(', ')}`;
|
|
32
32
|
}
|
|
33
|
-
else if ((interval
|
|
33
|
+
else if ((interval ?? 0) > 1) {
|
|
34
34
|
message = `Repeats every ${interval} ${this.unitMap[repeats]}`;
|
|
35
35
|
}
|
|
36
36
|
else {
|
|
37
37
|
message = `Repeats ${repeats}`;
|
|
38
38
|
}
|
|
39
|
-
const until = activeUntilDate
|
|
39
|
+
const until = activeUntilDate ?? repeatsUntil;
|
|
40
40
|
if (until) {
|
|
41
41
|
message += ` until ${this.dates.formatDate(until)}.`;
|
|
42
42
|
}
|
|
@@ -24,7 +24,6 @@ const calendarUtil = {
|
|
|
24
24
|
return excludedEvents;
|
|
25
25
|
},
|
|
26
26
|
applyRuleAndGetEventsWithoutExclusion(e, dateUntil, timezone) {
|
|
27
|
-
var _a, _b, _c, _d;
|
|
28
27
|
let repeatsUntil;
|
|
29
28
|
if (e.repeats) {
|
|
30
29
|
if (e.repeatsUntil) {
|
|
@@ -40,13 +39,13 @@ const calendarUtil = {
|
|
|
40
39
|
const dtstart = datetime(startSplit.year, startSplit.month + 1, startSplit.day, startSplit.hour, startSplit.minute);
|
|
41
40
|
const rule = new RRule({
|
|
42
41
|
freq: this.freqMapToRRule[e.repeats],
|
|
43
|
-
interval:
|
|
44
|
-
byweekday:
|
|
42
|
+
interval: e.interval ?? 1,
|
|
43
|
+
byweekday: e.daysOfWeek?.map((d) => this.weekDaysMapToRRuleDays[d]),
|
|
45
44
|
dtstart,
|
|
46
|
-
bymonthday:
|
|
45
|
+
bymonthday: e.daysOfMonth?.map((d) => parseInt(d)),
|
|
47
46
|
until: new Date(repeatsUntil),
|
|
48
47
|
count: e.occurrences,
|
|
49
|
-
bysetpos:
|
|
48
|
+
bysetpos: e.nthOccurrences?.map((o) => {
|
|
50
49
|
if (o >= 0) {
|
|
51
50
|
++o;
|
|
52
51
|
}
|
|
@@ -64,7 +63,12 @@ const calendarUtil = {
|
|
|
64
63
|
const iosDate = dateUtil.splitDate(r.getTime());
|
|
65
64
|
const startDateTimeMs = dateUtil.date(iosDate);
|
|
66
65
|
const offset = calculateOffsetAtDate(iosDate, this.locale, timezone);
|
|
67
|
-
return
|
|
66
|
+
return {
|
|
67
|
+
...e,
|
|
68
|
+
nthInRepeating: idx,
|
|
69
|
+
totalInRepeating: allEvents.length,
|
|
70
|
+
startDateTimeMs: startDateTimeMs - offset,
|
|
71
|
+
};
|
|
68
72
|
});
|
|
69
73
|
return events;
|
|
70
74
|
},
|
|
@@ -161,11 +161,10 @@ const dateUtil = {
|
|
|
161
161
|
return this.addMonths(this.getStartOfMonth(timestamp), count);
|
|
162
162
|
},
|
|
163
163
|
date(date) {
|
|
164
|
-
var _a, _b, _c, _d;
|
|
165
164
|
if (!date) {
|
|
166
165
|
return new Date().getTime();
|
|
167
166
|
}
|
|
168
|
-
return Date.UTC(date.year, date.month, date.day,
|
|
167
|
+
return Date.UTC(date.year, date.month, date.day, date.hour ?? 0, date.minute ?? 0, date.second ?? 0, date.milliseconds ?? 0);
|
|
169
168
|
},
|
|
170
169
|
/**
|
|
171
170
|
* Unit_______________Pattern___Results
|
|
@@ -27,7 +27,7 @@ const durationUtil = {
|
|
|
27
27
|
return durationStr.trim();
|
|
28
28
|
},
|
|
29
29
|
renderDateTimeUntil(end, prefixes) {
|
|
30
|
-
const { today = null, tomorrow = null, yesterday = null, future = null, past = null, shouldCapitalize, now = Date.now(), } = prefixes
|
|
30
|
+
const { today = null, tomorrow = null, yesterday = null, future = null, past = null, shouldCapitalize, now = Date.now(), } = prefixes ?? {};
|
|
31
31
|
let prefix = today;
|
|
32
32
|
let startDateAndTime = 'today';
|
|
33
33
|
const daysFromNow = Math.round((this.dates.getStartOfDay(end) - this.dates.getStartOfDay(now)) /
|
|
@@ -2,13 +2,15 @@ import { cloneDeep } from '@sprucelabs/schema';
|
|
|
2
2
|
import { timezoneChoices } from '@sprucelabs/spruce-core-schemas';
|
|
3
3
|
import TimezoneChoiceSorter from '../locales/TimezoneChoiceSorter.js';
|
|
4
4
|
export default function sortTimezoneChoices(locale, schema, fieldName) {
|
|
5
|
-
var _a;
|
|
6
5
|
const sorter = new TimezoneChoiceSorter(locale);
|
|
7
6
|
const choices = sorter.sort(timezoneChoices);
|
|
8
7
|
const copy = cloneDeep(schema);
|
|
9
|
-
const field =
|
|
8
|
+
const field = copy.fields?.[fieldName];
|
|
10
9
|
if (field) {
|
|
11
|
-
field.options =
|
|
10
|
+
field.options = {
|
|
11
|
+
...field.options,
|
|
12
|
+
choices,
|
|
13
|
+
};
|
|
12
14
|
}
|
|
13
15
|
return copy;
|
|
14
16
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "42.0.
|
|
6
|
+
"version": "42.0.491",
|
|
7
7
|
"files": [
|
|
8
8
|
"build/**/*",
|
|
9
9
|
"!build/__tests__",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@sprucelabs/error": "^6.0.538",
|
|
65
|
-
"@sprucelabs/mercury-event-emitter": "^42.0.
|
|
65
|
+
"@sprucelabs/mercury-event-emitter": "^42.0.597",
|
|
66
66
|
"@sprucelabs/mercury-types": "^47.0.596",
|
|
67
67
|
"@sprucelabs/schema": "^30.0.555",
|
|
68
68
|
"@sprucelabs/spruce-core-schemas": "^40.1.542",
|