@craftguild/jscalendar 0.2.0 → 0.3.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.
Files changed (99) hide show
  1. package/README.md +63 -0
  2. package/dist/__tests__/builders.test.d.ts +1 -0
  3. package/dist/__tests__/builders.test.js +82 -0
  4. package/dist/__tests__/calendar-extra.test.js +36 -0
  5. package/dist/__tests__/recurrence.test.js +123 -0
  6. package/dist/__tests__/search.test.js +27 -0
  7. package/dist/__tests__/utils.test.js +3 -0
  8. package/dist/__tests__/validation.test.js +113 -0
  9. package/dist/ical.d.ts +6 -0
  10. package/dist/ical.js +71 -3
  11. package/dist/jscal/base.d.ts +90 -0
  12. package/dist/jscal/base.js +181 -0
  13. package/dist/jscal/builders.d.ts +135 -0
  14. package/dist/jscal/builders.js +220 -0
  15. package/dist/jscal/constants.d.ts +11 -0
  16. package/dist/jscal/constants.js +11 -0
  17. package/dist/jscal/datetime.d.ts +14 -0
  18. package/dist/jscal/datetime.js +42 -0
  19. package/dist/jscal/defaults.d.ts +31 -0
  20. package/dist/jscal/defaults.js +102 -0
  21. package/dist/jscal/duration.d.ts +43 -0
  22. package/dist/jscal/duration.js +72 -0
  23. package/dist/jscal/event.d.ts +17 -0
  24. package/dist/jscal/event.js +71 -0
  25. package/dist/jscal/group.d.ts +25 -0
  26. package/dist/jscal/group.js +62 -0
  27. package/dist/jscal/guards.d.ts +19 -0
  28. package/dist/jscal/guards.js +25 -0
  29. package/dist/jscal/ids.d.ts +11 -0
  30. package/dist/jscal/ids.js +77 -0
  31. package/dist/jscal/normalize.d.ts +32 -0
  32. package/dist/jscal/normalize.js +45 -0
  33. package/dist/jscal/task.d.ts +17 -0
  34. package/dist/jscal/task.js +60 -0
  35. package/dist/jscal/types.d.ts +38 -0
  36. package/dist/jscal/types.js +1 -0
  37. package/dist/jscal.d.ts +77 -70
  38. package/dist/jscal.js +77 -465
  39. package/dist/patch.d.ts +13 -0
  40. package/dist/patch.js +166 -41
  41. package/dist/recurrence/constants.d.ts +13 -0
  42. package/dist/recurrence/constants.js +13 -0
  43. package/dist/recurrence/date-utils.d.ts +125 -0
  44. package/dist/recurrence/date-utils.js +259 -0
  45. package/dist/recurrence/expand.d.ts +23 -0
  46. package/dist/recurrence/expand.js +294 -0
  47. package/dist/recurrence/rule-candidates.d.ts +21 -0
  48. package/dist/recurrence/rule-candidates.js +120 -0
  49. package/dist/recurrence/rule-generate.d.ts +11 -0
  50. package/dist/recurrence/rule-generate.js +36 -0
  51. package/dist/recurrence/rule-matchers.d.ts +34 -0
  52. package/dist/recurrence/rule-matchers.js +120 -0
  53. package/dist/recurrence/rule-normalize.d.ts +9 -0
  54. package/dist/recurrence/rule-normalize.js +57 -0
  55. package/dist/recurrence/rule-selectors.d.ts +7 -0
  56. package/dist/recurrence/rule-selectors.js +21 -0
  57. package/dist/recurrence/rules.d.ts +14 -0
  58. package/dist/recurrence/rules.js +57 -0
  59. package/dist/recurrence/types.d.ts +27 -0
  60. package/dist/recurrence/types.js +1 -0
  61. package/dist/recurrence.d.ts +2 -15
  62. package/dist/recurrence.js +1 -674
  63. package/dist/search.d.ts +30 -0
  64. package/dist/search.js +92 -8
  65. package/dist/timezones/chunk_1.d.ts +2 -0
  66. package/dist/timezones/chunk_1.js +72 -0
  67. package/dist/timezones/chunk_2.d.ts +2 -0
  68. package/dist/timezones/chunk_2.js +72 -0
  69. package/dist/timezones/chunk_3.d.ts +2 -0
  70. package/dist/timezones/chunk_3.js +72 -0
  71. package/dist/timezones/chunk_4.d.ts +2 -0
  72. package/dist/timezones/chunk_4.js +72 -0
  73. package/dist/timezones/chunk_5.d.ts +2 -0
  74. package/dist/timezones/chunk_5.js +72 -0
  75. package/dist/timezones/chunk_6.d.ts +2 -0
  76. package/dist/timezones/chunk_6.js +72 -0
  77. package/dist/timezones/chunk_7.d.ts +2 -0
  78. package/dist/timezones/chunk_7.js +6 -0
  79. package/dist/timezones.d.ts +5 -0
  80. package/dist/timezones.js +14 -3
  81. package/dist/utils.d.ts +72 -0
  82. package/dist/utils.js +85 -1
  83. package/dist/validate/asserts.d.ts +155 -0
  84. package/dist/validate/asserts.js +381 -0
  85. package/dist/validate/constants.d.ts +25 -0
  86. package/dist/validate/constants.js +33 -0
  87. package/dist/validate/error.d.ts +19 -0
  88. package/dist/validate/error.js +25 -0
  89. package/dist/validate/validators-common.d.ts +64 -0
  90. package/dist/validate/validators-common.js +385 -0
  91. package/dist/validate/validators-objects.d.ts +8 -0
  92. package/dist/validate/validators-objects.js +70 -0
  93. package/dist/validate/validators-recurrence.d.ts +15 -0
  94. package/dist/validate/validators-recurrence.js +115 -0
  95. package/dist/validate/validators.d.ts +1 -0
  96. package/dist/validate/validators.js +1 -0
  97. package/dist/validate.d.ts +2 -6
  98. package/dist/validate.js +2 -745
  99. package/package.json +1 -1
@@ -0,0 +1,90 @@
1
+ import type { Alert, Id, JSCalendarObject, Location, Participant, PatchObject, VirtualLocation } from "../types.js";
2
+ import type { UpdateOptions } from "./types.js";
3
+ export declare class Base<T extends JSCalendarObject> {
4
+ data: T;
5
+ /**
6
+ * Create a new base instance that wraps a JSCalendar object.
7
+ * @param data Underlying JSCalendar data.
8
+ * @return Result.
9
+ */
10
+ constructor(data: T);
11
+ /**
12
+ * Return a deep-cloned plain object for safe serialization.
13
+ * @return Cloned JSCalendar data.
14
+ */
15
+ eject(): T;
16
+ /**
17
+ * Clone the current instance with a deep-cloned payload.
18
+ * @return New instance with cloned data.
19
+ */
20
+ clone(): Base<T>;
21
+ /**
22
+ * Read a field value from the underlying data.
23
+ * @param key Field key.
24
+ * @return Field value.
25
+ */
26
+ get<K extends keyof T>(key: K): T[K];
27
+ /**
28
+ * Set a field value and update metadata as needed.
29
+ * @param key Field key.
30
+ * @param value Field value.
31
+ * @return Updated instance.
32
+ */
33
+ set<K extends keyof T>(key: K, value: T[K]): this;
34
+ /**
35
+ * Apply shallow updates and touch updated/sequence metadata.
36
+ * @param values Partial values to merge.
37
+ * @param options Update options.
38
+ * @return Updated instance.
39
+ */
40
+ update(values: Partial<T>, options?: UpdateOptions): this;
41
+ /**
42
+ * Apply a PatchObject and touch updated/sequence metadata.
43
+ * @param patch Patch to apply.
44
+ * @param options Update options.
45
+ * @return Updated instance.
46
+ */
47
+ patch(patch: PatchObject, options?: UpdateOptions): this;
48
+ /**
49
+ * Add a physical location and return its generated ID.
50
+ * @param location Location data (without @type).
51
+ * @param id Optional location ID.
52
+ * @return Location ID.
53
+ */
54
+ addLocation(location: Omit<Location, "@type"> & Partial<Pick<Location, "@type">>, id?: Id): Id;
55
+ /**
56
+ * Add a virtual location and return its generated ID.
57
+ * @param location Virtual location data (without @type).
58
+ * @param id Optional virtual location ID.
59
+ * @return Virtual location ID.
60
+ */
61
+ addVirtualLocation(location: Omit<VirtualLocation, "@type"> & Partial<Pick<VirtualLocation, "@type">>, id?: Id): Id;
62
+ /**
63
+ * Add a participant and return its generated ID.
64
+ * @param participant Participant data (without @type).
65
+ * @param id Optional participant ID.
66
+ * @return Participant ID.
67
+ */
68
+ addParticipant(participant: Omit<Participant, "@type"> & Partial<Pick<Participant, "@type">>, id?: Id): Id;
69
+ /**
70
+ * Add an alert and return its generated ID.
71
+ * @param alert Alert data (without @type).
72
+ * @param id Optional alert ID.
73
+ * @return Alert ID.
74
+ */
75
+ addAlert(alert: Omit<Alert, "@type"> & Partial<Pick<Alert, "@type">>, id?: Id): Id;
76
+ /**
77
+ * Update updated/sequence metadata for modified keys.
78
+ * @param keys Modified keys.
79
+ * @param options Update options.
80
+ * @return Updated instance.
81
+ */
82
+ protected touchKeys(keys: string[], options?: UpdateOptions): this;
83
+ /**
84
+ * Update updated/sequence metadata for PatchObject changes.
85
+ * @param patch Patch applied to the object.
86
+ * @param options Update options.
87
+ * @return Updated instance.
88
+ */
89
+ protected touchFromPatch(patch: PatchObject, options?: UpdateOptions): this;
90
+ }
@@ -0,0 +1,181 @@
1
+ import { applyPatch } from "../patch.js";
2
+ import { deepClone, isNumberValue, nowUtc } from "../utils.js";
3
+ import { validateJsCalendarObject } from "../validate.js";
4
+ import { KEY_PARTICIPANTS } from "./constants.js";
5
+ import { applyAlertDefaults, applyParticipantDefaults } from "./defaults.js";
6
+ import { createId } from "./ids.js";
7
+ export class Base {
8
+ data;
9
+ /**
10
+ * Create a new base instance that wraps a JSCalendar object.
11
+ * @param data Underlying JSCalendar data.
12
+ * @return Result.
13
+ */
14
+ constructor(data) {
15
+ this.data = data;
16
+ }
17
+ /**
18
+ * Return a deep-cloned plain object for safe serialization.
19
+ * @return Cloned JSCalendar data.
20
+ */
21
+ eject() {
22
+ return deepClone(this.data);
23
+ }
24
+ /**
25
+ * Clone the current instance with a deep-cloned payload.
26
+ * @return New instance with cloned data.
27
+ */
28
+ clone() {
29
+ return new Base(deepClone(this.data));
30
+ }
31
+ /**
32
+ * Read a field value from the underlying data.
33
+ * @param key Field key.
34
+ * @return Field value.
35
+ */
36
+ get(key) {
37
+ return this.data[key];
38
+ }
39
+ /**
40
+ * Set a field value and update metadata as needed.
41
+ * @param key Field key.
42
+ * @param value Field value.
43
+ * @return Updated instance.
44
+ */
45
+ set(key, value) {
46
+ this.data[key] = value;
47
+ return this.touchKeys([String(key)]);
48
+ }
49
+ /**
50
+ * Apply shallow updates and touch updated/sequence metadata.
51
+ * @param values Partial values to merge.
52
+ * @param options Update options.
53
+ * @return Updated instance.
54
+ */
55
+ update(values, options = {}) {
56
+ const next = { ...this.data, ...values };
57
+ if (options.validate !== false) {
58
+ validateJsCalendarObject(next);
59
+ }
60
+ this.data = next;
61
+ return this.touchKeys(Object.keys(values), options);
62
+ }
63
+ /**
64
+ * Apply a PatchObject and touch updated/sequence metadata.
65
+ * @param patch Patch to apply.
66
+ * @param options Update options.
67
+ * @return Updated instance.
68
+ */
69
+ patch(patch, options = {}) {
70
+ const next = applyPatch(this.data, patch);
71
+ if (options.validate !== false) {
72
+ validateJsCalendarObject(next);
73
+ }
74
+ this.data = next;
75
+ return this.touchFromPatch(patch, options);
76
+ }
77
+ /**
78
+ * Add a physical location and return its generated ID.
79
+ * @param location Location data (without @type).
80
+ * @param id Optional location ID.
81
+ * @return Location ID.
82
+ */
83
+ addLocation(location, id) {
84
+ const actualId = id ?? createId();
85
+ if (!this.data.locations)
86
+ this.data.locations = {};
87
+ this.data.locations[actualId] = { ...location, "@type": "Location" };
88
+ this.touchKeys(["locations"]);
89
+ return actualId;
90
+ }
91
+ /**
92
+ * Add a virtual location and return its generated ID.
93
+ * @param location Virtual location data (without @type).
94
+ * @param id Optional virtual location ID.
95
+ * @return Virtual location ID.
96
+ */
97
+ addVirtualLocation(location, id) {
98
+ const actualId = id ?? createId();
99
+ if (!this.data.virtualLocations)
100
+ this.data.virtualLocations = {};
101
+ const name = location.name ?? "";
102
+ this.data.virtualLocations[actualId] = { ...location, name, "@type": "VirtualLocation" };
103
+ this.touchKeys(["virtualLocations"]);
104
+ return actualId;
105
+ }
106
+ /**
107
+ * Add a participant and return its generated ID.
108
+ * @param participant Participant data (without @type).
109
+ * @param id Optional participant ID.
110
+ * @return Participant ID.
111
+ */
112
+ addParticipant(participant, id) {
113
+ const actualId = id ?? createId();
114
+ if (!this.data.participants)
115
+ this.data.participants = {};
116
+ const filled = applyParticipantDefaults({ ...participant, "@type": "Participant" });
117
+ this.data.participants[actualId] = filled;
118
+ this.touchKeys(["participants"], { sequence: false });
119
+ return actualId;
120
+ }
121
+ /**
122
+ * Add an alert and return its generated ID.
123
+ * @param alert Alert data (without @type).
124
+ * @param id Optional alert ID.
125
+ * @return Alert ID.
126
+ */
127
+ addAlert(alert, id) {
128
+ const actualId = id ?? createId();
129
+ if (!this.data.alerts)
130
+ this.data.alerts = {};
131
+ const filled = applyAlertDefaults({ ...alert, "@type": "Alert" });
132
+ this.data.alerts[actualId] = filled;
133
+ this.touchKeys(["alerts"]);
134
+ return actualId;
135
+ }
136
+ /**
137
+ * Update updated/sequence metadata for modified keys.
138
+ * @param keys Modified keys.
139
+ * @param options Update options.
140
+ * @return Updated instance.
141
+ */
142
+ touchKeys(keys, options = {}) {
143
+ if (options.touch === false)
144
+ return this;
145
+ const now = options.now ?? nowUtc;
146
+ this.data.updated = now();
147
+ if (options.sequence === false)
148
+ return this;
149
+ const onlyParticipants = keys.length > 0 && keys.every((key) => key === KEY_PARTICIPANTS);
150
+ if (!onlyParticipants) {
151
+ const current = isNumberValue(this.data.sequence) ? this.data.sequence : 0;
152
+ this.data.sequence = current + 1;
153
+ }
154
+ return this;
155
+ }
156
+ /**
157
+ * Update updated/sequence metadata for PatchObject changes.
158
+ * @param patch Patch applied to the object.
159
+ * @param options Update options.
160
+ * @return Updated instance.
161
+ */
162
+ touchFromPatch(patch, options = {}) {
163
+ if (options.touch === false)
164
+ return this;
165
+ const now = options.now ?? nowUtc;
166
+ this.data.updated = now();
167
+ if (options.sequence === false)
168
+ return this;
169
+ const pointers = Object.keys(patch);
170
+ const onlyParticipants = pointers.length > 0 &&
171
+ pointers.every((pointer) => {
172
+ const normalized = pointer.startsWith("/") ? pointer.slice(1) : pointer;
173
+ return normalized.startsWith("participants");
174
+ });
175
+ if (!onlyParticipants) {
176
+ const current = isNumberValue(this.data.sequence) ? this.data.sequence : 0;
177
+ this.data.sequence = current + 1;
178
+ }
179
+ return this;
180
+ }
181
+ }
@@ -0,0 +1,135 @@
1
+ import type { Alert, Link, Location, NDay, Participant, RecurrenceRule, Relation, TimeZone, TimeZoneRule, VirtualLocation, Id } from "../types.js";
2
+ declare const TYPE_PARTICIPANT = "Participant";
3
+ declare const TYPE_LOCATION = "Location";
4
+ declare const TYPE_VIRTUAL_LOCATION = "VirtualLocation";
5
+ declare const TYPE_ALERT = "Alert";
6
+ declare const TYPE_RELATION = "Relation";
7
+ declare const TYPE_LINK = "Link";
8
+ declare const TYPE_TIME_ZONE = "TimeZone";
9
+ declare const TYPE_TIME_ZONE_RULE = "TimeZoneRule";
10
+ declare const TYPE_RECURRENCE_RULE = "RecurrenceRule";
11
+ declare const TYPE_NDAY = "NDay";
12
+ type WithOptionalType<T, TypeName extends string> = Omit<T, "@type"> & {
13
+ "@type"?: TypeName;
14
+ };
15
+ export type ParticipantInput = WithOptionalType<Participant, typeof TYPE_PARTICIPANT>;
16
+ export type LocationInput = WithOptionalType<Location, typeof TYPE_LOCATION>;
17
+ export type VirtualLocationInput = WithOptionalType<VirtualLocation, typeof TYPE_VIRTUAL_LOCATION>;
18
+ export type AlertInput = WithOptionalType<Alert, typeof TYPE_ALERT>;
19
+ export type RelationInput = WithOptionalType<Relation, typeof TYPE_RELATION>;
20
+ export type LinkInput = WithOptionalType<Link, typeof TYPE_LINK>;
21
+ export type TimeZoneInput = WithOptionalType<TimeZone, typeof TYPE_TIME_ZONE>;
22
+ export type TimeZoneRuleInput = WithOptionalType<TimeZoneRule, typeof TYPE_TIME_ZONE_RULE>;
23
+ export type RecurrenceRuleInput = WithOptionalType<RecurrenceRule, typeof TYPE_RECURRENCE_RULE>;
24
+ export type NDayInput = WithOptionalType<NDay, typeof TYPE_NDAY>;
25
+ /**
26
+ * Build a Participant object with @type set and validated.
27
+ * @param input Participant fields without @type.
28
+ * @return Validated Participant object.
29
+ */
30
+ export declare function buildParticipant(input: ParticipantInput): Participant;
31
+ /**
32
+ * Build a Location object with @type set and validated.
33
+ * @param input Location fields without @type.
34
+ * @return Validated Location object.
35
+ */
36
+ export declare function buildLocation(input: LocationInput): Location;
37
+ /**
38
+ * Build a VirtualLocation object with @type set and validated.
39
+ * @param input VirtualLocation fields without @type.
40
+ * @return Validated VirtualLocation object.
41
+ */
42
+ export declare function buildVirtualLocation(input: VirtualLocationInput): VirtualLocation;
43
+ /**
44
+ * Build an Alert object with @type set and validated.
45
+ * @param input Alert fields without @type.
46
+ * @return Validated Alert object.
47
+ */
48
+ export declare function buildAlert(input: AlertInput): Alert;
49
+ /**
50
+ * Build a Relation object with @type set and validated.
51
+ * @param input Relation fields without @type.
52
+ * @return Validated Relation object.
53
+ */
54
+ export declare function buildRelation(input: RelationInput): Relation;
55
+ /**
56
+ * Build a Link object with @type set and validated.
57
+ * @param input Link fields without @type.
58
+ * @return Validated Link object.
59
+ */
60
+ export declare function buildLink(input: LinkInput): Link;
61
+ /**
62
+ * Build a TimeZone object with @type set and validated.
63
+ * @param input TimeZone fields without @type.
64
+ * @return Validated TimeZone object.
65
+ */
66
+ export declare function buildTimeZone(input: TimeZoneInput): TimeZone;
67
+ /**
68
+ * Build a TimeZoneRule object with @type set and validated.
69
+ * @param input TimeZoneRule fields without @type.
70
+ * @return Validated TimeZoneRule object.
71
+ */
72
+ export declare function buildTimeZoneRule(input: TimeZoneRuleInput): TimeZoneRule;
73
+ /**
74
+ * Build a RecurrenceRule object with @type set and validated.
75
+ * @param input RecurrenceRule fields without @type.
76
+ * @return Validated RecurrenceRule object.
77
+ */
78
+ export declare function buildRecurrenceRule(input: RecurrenceRuleInput): RecurrenceRule;
79
+ /**
80
+ * Build an NDay object with @type set and validated.
81
+ * @param input NDay fields without @type.
82
+ * @return Validated NDay object.
83
+ */
84
+ export declare function buildNDay(input: NDayInput): NDay;
85
+ /**
86
+ * Build a record keyed by generated Ids.
87
+ * @param items Items to store.
88
+ * @param builder Builder function to validate each item.
89
+ * @param idFn Optional ID generator.
90
+ * @return Record keyed by generated Ids.
91
+ */
92
+ export declare function buildIdMap<TInput, TOutput>(items: TInput[], builder: (input: TInput) => TOutput, idFn?: (input: TInput, index: number) => Id): Record<Id, TOutput>;
93
+ /**
94
+ * Build a record of Participant objects keyed by generated Ids.
95
+ * @param items Participant inputs.
96
+ * @return Participant record keyed by Id.
97
+ */
98
+ export declare function buildParticipants(items: ParticipantInput[]): Record<Id, Participant>;
99
+ /**
100
+ * Build a record of Location objects keyed by generated Ids.
101
+ * @param items Location inputs.
102
+ * @return Location record keyed by Id.
103
+ */
104
+ export declare function buildLocations(items: LocationInput[]): Record<Id, Location>;
105
+ /**
106
+ * Build a record of VirtualLocation objects keyed by generated Ids.
107
+ * @param items VirtualLocation inputs.
108
+ * @return VirtualLocation record keyed by Id.
109
+ */
110
+ export declare function buildVirtualLocations(items: VirtualLocationInput[]): Record<Id, VirtualLocation>;
111
+ /**
112
+ * Build a record of Alert objects keyed by generated Ids.
113
+ * @param items Alert inputs.
114
+ * @return Alert record keyed by Id.
115
+ */
116
+ export declare function buildAlerts(items: AlertInput[]): Record<Id, Alert>;
117
+ /**
118
+ * Build a record of Link objects keyed by generated Ids.
119
+ * @param items Link inputs.
120
+ * @return Link record keyed by Id.
121
+ */
122
+ export declare function buildLinks(items: LinkInput[]): Record<Id, Link>;
123
+ /**
124
+ * Build a record of Relation objects keyed by generated Ids.
125
+ * @param items Relation inputs.
126
+ * @return Relation record keyed by Id.
127
+ */
128
+ export declare function buildRelatedTo(items: RelationInput[]): Record<Id, Relation>;
129
+ /**
130
+ * Build a record of TimeZone objects keyed by tzId.
131
+ * @param items TimeZone inputs.
132
+ * @return TimeZone record keyed by tzId.
133
+ */
134
+ export declare function buildTimeZoneMap(items: TimeZoneInput[]): Record<string, TimeZone>;
135
+ export {};
@@ -0,0 +1,220 @@
1
+ import { createId } from "./ids.js";
2
+ import { validateAlert, validateLink, validateLocation, validateParticipant, validateRelation, validateTimeZoneObject, validateTimeZoneRule, validateVirtualLocation } from "../validate/validators-common.js";
3
+ import { validateNDay, validateRecurrenceRule } from "../validate/validators-recurrence.js";
4
+ import { fail } from "../validate/error.js";
5
+ const TYPE_PARTICIPANT = "Participant";
6
+ const TYPE_LOCATION = "Location";
7
+ const TYPE_VIRTUAL_LOCATION = "VirtualLocation";
8
+ const TYPE_ALERT = "Alert";
9
+ const TYPE_RELATION = "Relation";
10
+ const TYPE_LINK = "Link";
11
+ const TYPE_TIME_ZONE = "TimeZone";
12
+ const TYPE_TIME_ZONE_RULE = "TimeZoneRule";
13
+ const TYPE_RECURRENCE_RULE = "RecurrenceRule";
14
+ const TYPE_NDAY = "NDay";
15
+ /**
16
+ * Build a Participant object with @type set and validated.
17
+ * @param input Participant fields without @type.
18
+ * @return Validated Participant object.
19
+ */
20
+ export function buildParticipant(input) {
21
+ if (input["@type"] && input["@type"] !== TYPE_PARTICIPANT) {
22
+ fail("participant", `must have @type ${TYPE_PARTICIPANT}`);
23
+ }
24
+ const participant = { ...input, "@type": TYPE_PARTICIPANT };
25
+ validateParticipant(participant, "participant");
26
+ return participant;
27
+ }
28
+ /**
29
+ * Build a Location object with @type set and validated.
30
+ * @param input Location fields without @type.
31
+ * @return Validated Location object.
32
+ */
33
+ export function buildLocation(input) {
34
+ if (input["@type"] && input["@type"] !== TYPE_LOCATION) {
35
+ fail("location", `must have @type ${TYPE_LOCATION}`);
36
+ }
37
+ const location = { ...input, "@type": TYPE_LOCATION };
38
+ validateLocation(location, "location");
39
+ return location;
40
+ }
41
+ /**
42
+ * Build a VirtualLocation object with @type set and validated.
43
+ * @param input VirtualLocation fields without @type.
44
+ * @return Validated VirtualLocation object.
45
+ */
46
+ export function buildVirtualLocation(input) {
47
+ if (input["@type"] && input["@type"] !== TYPE_VIRTUAL_LOCATION) {
48
+ fail("virtualLocation", `must have @type ${TYPE_VIRTUAL_LOCATION}`);
49
+ }
50
+ const virtualLocation = { ...input, "@type": TYPE_VIRTUAL_LOCATION };
51
+ validateVirtualLocation(virtualLocation, "virtualLocation");
52
+ return virtualLocation;
53
+ }
54
+ /**
55
+ * Build an Alert object with @type set and validated.
56
+ * @param input Alert fields without @type.
57
+ * @return Validated Alert object.
58
+ */
59
+ export function buildAlert(input) {
60
+ if (input["@type"] && input["@type"] !== TYPE_ALERT) {
61
+ fail("alert", `must have @type ${TYPE_ALERT}`);
62
+ }
63
+ const alert = { ...input, "@type": TYPE_ALERT };
64
+ validateAlert(alert, "alert");
65
+ return alert;
66
+ }
67
+ /**
68
+ * Build a Relation object with @type set and validated.
69
+ * @param input Relation fields without @type.
70
+ * @return Validated Relation object.
71
+ */
72
+ export function buildRelation(input) {
73
+ if (input["@type"] && input["@type"] !== TYPE_RELATION) {
74
+ fail("relation", `must have @type ${TYPE_RELATION}`);
75
+ }
76
+ const relation = { ...input, "@type": TYPE_RELATION };
77
+ validateRelation(relation, "relation");
78
+ return relation;
79
+ }
80
+ /**
81
+ * Build a Link object with @type set and validated.
82
+ * @param input Link fields without @type.
83
+ * @return Validated Link object.
84
+ */
85
+ export function buildLink(input) {
86
+ if (input["@type"] && input["@type"] !== TYPE_LINK) {
87
+ fail("link", `must have @type ${TYPE_LINK}`);
88
+ }
89
+ const link = { ...input, "@type": TYPE_LINK };
90
+ validateLink(link, "link");
91
+ return link;
92
+ }
93
+ /**
94
+ * Build a TimeZone object with @type set and validated.
95
+ * @param input TimeZone fields without @type.
96
+ * @return Validated TimeZone object.
97
+ */
98
+ export function buildTimeZone(input) {
99
+ if (input["@type"] && input["@type"] !== TYPE_TIME_ZONE) {
100
+ fail("timeZone", `must have @type ${TYPE_TIME_ZONE}`);
101
+ }
102
+ const timeZone = { ...input, "@type": TYPE_TIME_ZONE };
103
+ validateTimeZoneObject(timeZone, "timeZone");
104
+ return timeZone;
105
+ }
106
+ /**
107
+ * Build a TimeZoneRule object with @type set and validated.
108
+ * @param input TimeZoneRule fields without @type.
109
+ * @return Validated TimeZoneRule object.
110
+ */
111
+ export function buildTimeZoneRule(input) {
112
+ if (input["@type"] && input["@type"] !== TYPE_TIME_ZONE_RULE) {
113
+ fail("timeZoneRule", `must have @type ${TYPE_TIME_ZONE_RULE}`);
114
+ }
115
+ const rule = { ...input, "@type": TYPE_TIME_ZONE_RULE };
116
+ validateTimeZoneRule(rule, "timeZoneRule");
117
+ return rule;
118
+ }
119
+ /**
120
+ * Build a RecurrenceRule object with @type set and validated.
121
+ * @param input RecurrenceRule fields without @type.
122
+ * @return Validated RecurrenceRule object.
123
+ */
124
+ export function buildRecurrenceRule(input) {
125
+ if (input["@type"] && input["@type"] !== TYPE_RECURRENCE_RULE) {
126
+ fail("recurrenceRule", `must have @type ${TYPE_RECURRENCE_RULE}`);
127
+ }
128
+ const rule = { ...input, "@type": TYPE_RECURRENCE_RULE };
129
+ validateRecurrenceRule(rule, "recurrenceRule");
130
+ return rule;
131
+ }
132
+ /**
133
+ * Build an NDay object with @type set and validated.
134
+ * @param input NDay fields without @type.
135
+ * @return Validated NDay object.
136
+ */
137
+ export function buildNDay(input) {
138
+ if (input["@type"] && input["@type"] !== TYPE_NDAY) {
139
+ fail("nday", `must have @type ${TYPE_NDAY}`);
140
+ }
141
+ const nday = { ...input, "@type": TYPE_NDAY };
142
+ validateNDay(nday, "nday");
143
+ return nday;
144
+ }
145
+ /**
146
+ * Build a record keyed by generated Ids.
147
+ * @param items Items to store.
148
+ * @param builder Builder function to validate each item.
149
+ * @param idFn Optional ID generator.
150
+ * @return Record keyed by generated Ids.
151
+ */
152
+ export function buildIdMap(items, builder, idFn = () => createId()) {
153
+ const result = {};
154
+ items.forEach((item, index) => {
155
+ const id = idFn(item, index);
156
+ result[id] = builder(item);
157
+ });
158
+ return result;
159
+ }
160
+ /**
161
+ * Build a record of Participant objects keyed by generated Ids.
162
+ * @param items Participant inputs.
163
+ * @return Participant record keyed by Id.
164
+ */
165
+ export function buildParticipants(items) {
166
+ return buildIdMap(items, buildParticipant);
167
+ }
168
+ /**
169
+ * Build a record of Location objects keyed by generated Ids.
170
+ * @param items Location inputs.
171
+ * @return Location record keyed by Id.
172
+ */
173
+ export function buildLocations(items) {
174
+ return buildIdMap(items, buildLocation);
175
+ }
176
+ /**
177
+ * Build a record of VirtualLocation objects keyed by generated Ids.
178
+ * @param items VirtualLocation inputs.
179
+ * @return VirtualLocation record keyed by Id.
180
+ */
181
+ export function buildVirtualLocations(items) {
182
+ return buildIdMap(items, buildVirtualLocation);
183
+ }
184
+ /**
185
+ * Build a record of Alert objects keyed by generated Ids.
186
+ * @param items Alert inputs.
187
+ * @return Alert record keyed by Id.
188
+ */
189
+ export function buildAlerts(items) {
190
+ return buildIdMap(items, buildAlert);
191
+ }
192
+ /**
193
+ * Build a record of Link objects keyed by generated Ids.
194
+ * @param items Link inputs.
195
+ * @return Link record keyed by Id.
196
+ */
197
+ export function buildLinks(items) {
198
+ return buildIdMap(items, buildLink);
199
+ }
200
+ /**
201
+ * Build a record of Relation objects keyed by generated Ids.
202
+ * @param items Relation inputs.
203
+ * @return Relation record keyed by Id.
204
+ */
205
+ export function buildRelatedTo(items) {
206
+ return buildIdMap(items, buildRelation);
207
+ }
208
+ /**
209
+ * Build a record of TimeZone objects keyed by tzId.
210
+ * @param items TimeZone inputs.
211
+ * @return TimeZone record keyed by tzId.
212
+ */
213
+ export function buildTimeZoneMap(items) {
214
+ const result = {};
215
+ items.forEach((item) => {
216
+ const timeZone = buildTimeZone(item);
217
+ result[timeZone.tzId] = timeZone;
218
+ });
219
+ return result;
220
+ }
@@ -0,0 +1,11 @@
1
+ export declare const TYPEOF_FUNCTION = "function";
2
+ export declare const EMPTY_STRING = "";
3
+ export declare const TYPE_EVENT = "Event";
4
+ export declare const TYPE_TASK = "Task";
5
+ export declare const TYPE_GROUP = "Group";
6
+ export declare const STATUS_COMPLETED = "completed";
7
+ export declare const STATUS_FAILED = "failed";
8
+ export declare const STATUS_IN_PROCESS = "in-process";
9
+ export declare const STATUS_NEEDS_ACTION = "needs-action";
10
+ export declare const TRIGGER_OFFSET = "OffsetTrigger";
11
+ export declare const KEY_PARTICIPANTS = "participants";
@@ -0,0 +1,11 @@
1
+ export const TYPEOF_FUNCTION = "function";
2
+ export const EMPTY_STRING = "";
3
+ export const TYPE_EVENT = "Event";
4
+ export const TYPE_TASK = "Task";
5
+ export const TYPE_GROUP = "Group";
6
+ export const STATUS_COMPLETED = "completed";
7
+ export const STATUS_FAILED = "failed";
8
+ export const STATUS_IN_PROCESS = "in-process";
9
+ export const STATUS_NEEDS_ACTION = "needs-action";
10
+ export const TRIGGER_OFFSET = "OffsetTrigger";
11
+ export const KEY_PARTICIPANTS = "participants";
@@ -0,0 +1,14 @@
1
+ import type { UTCDateTime } from "../types.js";
2
+ import type { DateInput } from "./types.js";
3
+ /**
4
+ * Convert a Date input to a LocalDateTime string.
5
+ * @param value Date or LocalDateTime string.
6
+ * @return LocalDateTime string.
7
+ */
8
+ export declare function toLocalDateTime(value: DateInput): string;
9
+ /**
10
+ * Convert a Date input to a UTCDateTime string.
11
+ * @param value Date or UTCDateTime string.
12
+ * @return UTCDateTime string.
13
+ */
14
+ export declare function toUtcDateTime(value: DateInput): UTCDateTime;