@craftguild/jscalendar 0.4.0 → 0.5.0
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 +56 -25
- package/dist/__tests__/builders.test.js +19 -6
- package/dist/__tests__/calendar-extra.test.js +27 -27
- package/dist/__tests__/calendar.test.js +13 -20
- package/dist/__tests__/recurrence.test.js +20 -1
- package/dist/__tests__/validation.test.js +25 -5
- package/dist/jscal/base.d.ts +27 -28
- package/dist/jscal/base.js +55 -63
- package/dist/jscal/builders.d.ts +56 -24
- package/dist/jscal/builders.js +70 -33
- package/dist/jscal/event.d.ts +8 -2
- package/dist/jscal/event.js +10 -3
- package/dist/jscal/group.d.ts +10 -4
- package/dist/jscal/group.js +15 -8
- package/dist/jscal/task.d.ts +8 -2
- package/dist/jscal/task.js +10 -3
- package/dist/jscal.d.ts +9 -2
- package/dist/jscal.js +9 -1
- package/dist/patch.d.ts +2 -2
- package/dist/recurrence/expand.d.ts +1 -1
- package/dist/recurrence/expand.js +28 -7
- package/dist/types.d.ts +31 -4
- package/dist/validate/asserts.d.ts +2 -2
- package/dist/validate/validators-common.js +7 -2
- package/package.json +1 -1
package/dist/jscal.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ import { TaskObject } from "./jscal/task.js";
|
|
|
6
6
|
import { GroupObject } from "./jscal/group.js";
|
|
7
7
|
import { createId, createUid } from "./jscal/ids.js";
|
|
8
8
|
import { isEvent, isGroup, isTask } from "./jscal/guards.js";
|
|
9
|
-
import { buildAlert, buildAbsoluteTrigger, buildLink, buildLocation, buildNDay, buildOffsetTrigger, buildParticipants, buildRecurrenceRule, buildRelation, buildRelatedTo, buildTimeZone, buildTimeZoneMap, buildTimeZoneRule, buildVirtualLocation, buildVirtualLocations, buildLocations, buildLinks, buildParticipant, buildAlerts } from "./jscal/builders.js";
|
|
9
|
+
import { buildAlert, buildAbsoluteTrigger, buildEventPatch, buildLink, buildLocation, buildNDay, buildOffsetTrigger, buildParticipants, buildRecurrenceRule, buildRelation, buildRelatedTo, buildTimeZone, buildTimeZoneMap, buildTimeZoneRule, buildVirtualLocation, buildVirtualLocations, buildLocations, buildLinks, buildParticipant, buildAlerts, buildTaskPatch, buildGroupPatch } from "./jscal/builders.js";
|
|
10
10
|
export type { CreateOptions, UpdateOptions } from "./jscal/types.js";
|
|
11
|
-
export type { AlertInput, AbsoluteTriggerInput, LinkInput, LocationInput, NDayInput, OffsetTriggerInput, ParticipantInput, RecurrenceRuleInput, RelationInput, TimeZoneInput, TimeZoneRuleInput, VirtualLocationInput, } from "./jscal/builders.js";
|
|
11
|
+
export type { AlertInput, AbsoluteTriggerInput, EventPatchInput, GroupPatchInput, IdValueInput, LinkInput, LocationInput, NDayInput, OffsetTriggerInput, ParticipantInput, RecurrenceRuleInput, RelationInput, TaskPatchInput, TimeZoneInput, TimeZoneRuleInput, VirtualLocationInput, } from "./jscal/builders.js";
|
|
12
12
|
export { createId, createUid, isEvent, isGroup, isTask };
|
|
13
13
|
export declare const JsCal: {
|
|
14
14
|
Event: typeof EventObject;
|
|
@@ -16,6 +16,9 @@ export declare const JsCal: {
|
|
|
16
16
|
Group: typeof GroupObject;
|
|
17
17
|
createUid: typeof createUid;
|
|
18
18
|
createId: typeof createId;
|
|
19
|
+
isEvent: typeof isEvent;
|
|
20
|
+
isGroup: typeof isGroup;
|
|
21
|
+
isTask: typeof isTask;
|
|
19
22
|
duration: {
|
|
20
23
|
seconds(value: number): string;
|
|
21
24
|
minutes(value: number): string;
|
|
@@ -43,6 +46,10 @@ export declare const JsCal: {
|
|
|
43
46
|
TimeZoneRule: typeof buildTimeZoneRule;
|
|
44
47
|
RecurrenceRule: typeof buildRecurrenceRule;
|
|
45
48
|
NDay: typeof buildNDay;
|
|
49
|
+
ByDay: typeof buildNDay;
|
|
50
|
+
EventPatch: typeof buildEventPatch;
|
|
51
|
+
TaskPatch: typeof buildTaskPatch;
|
|
52
|
+
GroupPatch: typeof buildGroupPatch;
|
|
46
53
|
participants: typeof buildParticipants;
|
|
47
54
|
locations: typeof buildLocations;
|
|
48
55
|
virtualLocations: typeof buildVirtualLocations;
|
package/dist/jscal.js
CHANGED
|
@@ -10,7 +10,7 @@ import { Duration } from "./jscal/duration.js";
|
|
|
10
10
|
import { createId, createUid } from "./jscal/ids.js";
|
|
11
11
|
import { normalizeItems, normalizeToObjects } from "./jscal/normalize.js";
|
|
12
12
|
import { isEvent, isGroup, isTask } from "./jscal/guards.js";
|
|
13
|
-
import { buildAlert, buildAbsoluteTrigger, buildLink, buildLocation, buildNDay, buildOffsetTrigger, buildParticipants, buildRecurrenceRule, buildRelation, buildRelatedTo, buildTimeZone, buildTimeZoneMap, buildTimeZoneRule, buildVirtualLocation, buildVirtualLocations, buildLocations, buildLinks, buildParticipant, buildAlerts, } from "./jscal/builders.js";
|
|
13
|
+
import { buildAlert, buildAbsoluteTrigger, buildEventPatch, buildLink, buildLocation, buildNDay, buildOffsetTrigger, buildParticipants, buildRecurrenceRule, buildRelation, buildRelatedTo, buildTimeZone, buildTimeZoneMap, buildTimeZoneRule, buildVirtualLocation, buildVirtualLocations, buildLocations, buildLinks, buildParticipant, buildAlerts, buildTaskPatch, buildGroupPatch, } from "./jscal/builders.js";
|
|
14
14
|
export { createId, createUid, isEvent, isGroup, isTask };
|
|
15
15
|
export const JsCal = {
|
|
16
16
|
Event: EventObject,
|
|
@@ -18,6 +18,9 @@ export const JsCal = {
|
|
|
18
18
|
Group: GroupObject,
|
|
19
19
|
createUid,
|
|
20
20
|
createId,
|
|
21
|
+
isEvent,
|
|
22
|
+
isGroup,
|
|
23
|
+
isTask,
|
|
21
24
|
duration: Duration,
|
|
22
25
|
timeZone: resolveTimeZone,
|
|
23
26
|
timeZones: TimeZones,
|
|
@@ -34,6 +37,11 @@ export const JsCal = {
|
|
|
34
37
|
TimeZoneRule: buildTimeZoneRule,
|
|
35
38
|
RecurrenceRule: buildRecurrenceRule,
|
|
36
39
|
NDay: buildNDay,
|
|
40
|
+
// Alias for NDay to better mirror the byDay naming in recurrence rules.
|
|
41
|
+
ByDay: buildNDay,
|
|
42
|
+
EventPatch: buildEventPatch,
|
|
43
|
+
TaskPatch: buildTaskPatch,
|
|
44
|
+
GroupPatch: buildGroupPatch,
|
|
37
45
|
participants: buildParticipants,
|
|
38
46
|
locations: buildLocations,
|
|
39
47
|
virtualLocations: buildVirtualLocations,
|
package/dist/patch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PatchLike } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Error thrown when a patch operation is invalid.
|
|
4
4
|
*/
|
|
@@ -15,4 +15,4 @@ export declare class PatchError extends Error {
|
|
|
15
15
|
* @param patch Patch object to apply.
|
|
16
16
|
* @return Patched clone of the input object.
|
|
17
17
|
*/
|
|
18
|
-
export declare function applyPatch<T extends object>(input: T, patch:
|
|
18
|
+
export declare function applyPatch<T extends object>(input: T, patch: PatchLike): T;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { JSCalendarObject } from "../types.js";
|
|
2
2
|
import type { RecurrenceRange } from "./types.js";
|
|
3
3
|
/**
|
|
4
|
-
* Expand recurrence into occurrences.
|
|
4
|
+
* Expand recurrence into occurrences sorted by recurrenceId/start.
|
|
5
5
|
* @param items JSCalendar objects to expand.
|
|
6
6
|
* @param range Date range bounds.
|
|
7
7
|
* @return Generator of expanded occurrences.
|
|
@@ -3,22 +3,43 @@ import { dateTimeInTimeZone, localDateTimeFromDate, localDateTimeToUtcDate } fro
|
|
|
3
3
|
import { TYPE_EVENT, TYPE_TASK } from "./constants.js";
|
|
4
4
|
import { expandRule } from "./rules.js";
|
|
5
5
|
/**
|
|
6
|
-
* Expand recurrence into occurrences.
|
|
6
|
+
* Expand recurrence into occurrences sorted by recurrenceId/start.
|
|
7
7
|
* @param items JSCalendar objects to expand.
|
|
8
8
|
* @param range Date range bounds.
|
|
9
9
|
* @return Generator of expanded occurrences.
|
|
10
10
|
*/
|
|
11
11
|
export function* expandRecurrence(items, range) {
|
|
12
|
+
const occurrences = [];
|
|
13
|
+
let index = 0;
|
|
12
14
|
for (const item of items) {
|
|
13
15
|
if (item["@type"] === TYPE_EVENT) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
for (const occurrence of expandEvent(item, range)) {
|
|
17
|
+
occurrences.push({ value: occurrence, key: occurrenceKey(occurrence), index });
|
|
18
|
+
index += 1;
|
|
19
|
+
}
|
|
20
|
+
continue;
|
|
18
21
|
}
|
|
19
|
-
|
|
20
|
-
|
|
22
|
+
if (item["@type"] === TYPE_TASK) {
|
|
23
|
+
for (const occurrence of expandTask(item, range)) {
|
|
24
|
+
occurrences.push({ value: occurrence, key: occurrenceKey(occurrence), index });
|
|
25
|
+
index += 1;
|
|
26
|
+
}
|
|
27
|
+
continue;
|
|
21
28
|
}
|
|
29
|
+
occurrences.push({ value: item, key: occurrenceKey(item), index });
|
|
30
|
+
index += 1;
|
|
31
|
+
}
|
|
32
|
+
occurrences.sort((a, b) => {
|
|
33
|
+
if (a.key && b.key)
|
|
34
|
+
return a.key.localeCompare(b.key);
|
|
35
|
+
if (a.key)
|
|
36
|
+
return -1;
|
|
37
|
+
if (b.key)
|
|
38
|
+
return 1;
|
|
39
|
+
return a.index - b.index;
|
|
40
|
+
});
|
|
41
|
+
for (const occurrence of occurrences) {
|
|
42
|
+
yield occurrence.value;
|
|
22
43
|
}
|
|
23
44
|
}
|
|
24
45
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -12,7 +12,30 @@ export type JsonPrimitive = string | number | boolean | null;
|
|
|
12
12
|
export type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
13
13
|
[key: string]: JsonValue;
|
|
14
14
|
};
|
|
15
|
-
export type
|
|
15
|
+
export type PatchValue = JsonValue | null;
|
|
16
|
+
export interface PatchObject {
|
|
17
|
+
[key: string]: PatchValue;
|
|
18
|
+
}
|
|
19
|
+
type PatchFields<T> = {
|
|
20
|
+
[K in keyof Omit<T, "@type">]?: T[K] | null;
|
|
21
|
+
};
|
|
22
|
+
type PatchTag<TTag extends string> = {
|
|
23
|
+
__patchType?: TTag;
|
|
24
|
+
};
|
|
25
|
+
export type EventPatch = PatchFields<Event> & PatchTag<"Event">;
|
|
26
|
+
export type TaskPatch = PatchFields<Task> & PatchTag<"Task">;
|
|
27
|
+
export type GroupPatch = PatchFields<Group> & PatchTag<"Group">;
|
|
28
|
+
export type ParticipantPatch = PatchFields<Participant>;
|
|
29
|
+
export type LocationPatch = PatchFields<Location>;
|
|
30
|
+
export type VirtualLocationPatch = PatchFields<VirtualLocation>;
|
|
31
|
+
export type AlertPatch = PatchFields<Alert>;
|
|
32
|
+
export type RelationPatch = PatchFields<Relation>;
|
|
33
|
+
export type LinkPatch = PatchFields<Link>;
|
|
34
|
+
export type TimeZonePatch = PatchFields<TimeZone>;
|
|
35
|
+
export type TimeZoneRulePatch = PatchFields<TimeZoneRule>;
|
|
36
|
+
export type RecurrenceRulePatch = PatchFields<RecurrenceRule>;
|
|
37
|
+
export type NDayPatch = PatchFields<NDay>;
|
|
38
|
+
export type PatchLike = PatchObject | EventPatch | TaskPatch | GroupPatch | TimeZoneRulePatch;
|
|
16
39
|
export interface Relation {
|
|
17
40
|
"@type": "Relation";
|
|
18
41
|
relation?: BooleanMap;
|
|
@@ -124,7 +147,7 @@ export interface TimeZoneRule {
|
|
|
124
147
|
offsetFrom: string;
|
|
125
148
|
offsetTo: string;
|
|
126
149
|
recurrenceRules?: RecurrenceRule[];
|
|
127
|
-
recurrenceOverrides?: Record<LocalDateTime,
|
|
150
|
+
recurrenceOverrides?: Record<LocalDateTime, TimeZoneRulePatch>;
|
|
128
151
|
names?: BooleanMap;
|
|
129
152
|
comments?: string[];
|
|
130
153
|
}
|
|
@@ -162,7 +185,6 @@ export interface JSCalendarCommon {
|
|
|
162
185
|
recurrenceIdTimeZone?: TimeZoneId | null;
|
|
163
186
|
recurrenceRules?: RecurrenceRule[];
|
|
164
187
|
excludedRecurrenceRules?: RecurrenceRule[];
|
|
165
|
-
recurrenceOverrides?: Record<LocalDateTime, PatchObject>;
|
|
166
188
|
excluded?: boolean;
|
|
167
189
|
priority?: Int;
|
|
168
190
|
freeBusyStatus?: string;
|
|
@@ -173,7 +195,6 @@ export interface JSCalendarCommon {
|
|
|
173
195
|
requestStatus?: string;
|
|
174
196
|
useDefaultAlerts?: boolean;
|
|
175
197
|
alerts?: Record<Id, Alert>;
|
|
176
|
-
localizations?: Record<string, PatchObject>;
|
|
177
198
|
timeZone?: TimeZoneId | null;
|
|
178
199
|
timeZones?: Partial<Record<TimeZoneId, TimeZone>>;
|
|
179
200
|
}
|
|
@@ -182,6 +203,8 @@ export interface Event extends JSCalendarCommon {
|
|
|
182
203
|
start: LocalDateTime;
|
|
183
204
|
duration?: Duration;
|
|
184
205
|
status?: string;
|
|
206
|
+
localizations?: Record<string, EventPatch>;
|
|
207
|
+
recurrenceOverrides?: Record<LocalDateTime, EventPatch>;
|
|
185
208
|
}
|
|
186
209
|
export interface Task extends JSCalendarCommon {
|
|
187
210
|
"@type": "Task";
|
|
@@ -191,11 +214,15 @@ export interface Task extends JSCalendarCommon {
|
|
|
191
214
|
percentComplete?: UnsignedInt;
|
|
192
215
|
progress?: string;
|
|
193
216
|
progressUpdated?: UTCDateTime;
|
|
217
|
+
localizations?: Record<string, TaskPatch>;
|
|
218
|
+
recurrenceOverrides?: Record<LocalDateTime, TaskPatch>;
|
|
194
219
|
}
|
|
195
220
|
export interface Group extends JSCalendarCommon {
|
|
196
221
|
"@type": "Group";
|
|
197
222
|
entries: Array<Event | Task>;
|
|
198
223
|
source?: string;
|
|
224
|
+
localizations?: Record<string, GroupPatch>;
|
|
225
|
+
recurrenceOverrides?: Record<LocalDateTime, GroupPatch>;
|
|
199
226
|
}
|
|
200
227
|
export type JSCalendarObject = Event | Task | Group;
|
|
201
228
|
export type CalendarType = JSCalendarObject["@type"];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { JsonValue,
|
|
1
|
+
import type { JsonValue, PatchLike } from "../types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Get the UTF-8 byte length of a string.
|
|
4
4
|
* @param value Input string.
|
|
@@ -152,4 +152,4 @@ export declare function assertJsonValue(value: JsonValue | object | null | undef
|
|
|
152
152
|
* @param path Validation path.
|
|
153
153
|
* @return Nothing.
|
|
154
154
|
*/
|
|
155
|
-
export declare function assertPatchObject(value:
|
|
155
|
+
export declare function assertPatchObject(value: PatchLike | undefined, path: string): void;
|
|
@@ -191,8 +191,13 @@ export function validateParticipant(value, path) {
|
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
assertString(value.kind, `${path}.kind`);
|
|
194
|
-
if (value.roles)
|
|
195
|
-
|
|
194
|
+
if (!value.roles) {
|
|
195
|
+
fail(`${path}.roles`, "is required");
|
|
196
|
+
}
|
|
197
|
+
assertBooleanMap(value.roles, `${path}.roles`);
|
|
198
|
+
if (Object.keys(value.roles).length === 0) {
|
|
199
|
+
fail(`${path}.roles`, "must include at least one role");
|
|
200
|
+
}
|
|
196
201
|
assertId(value.locationId, `${path}.locationId`);
|
|
197
202
|
assertString(value.language, `${path}.language`);
|
|
198
203
|
assertString(value.participationStatus, `${path}.participationStatus`);
|