calendaryjs 0.2.2 → 0.2.4
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 +6 -0
- package/dist/builder/index.cjs +338 -0
- package/dist/builder/index.d.cts +153 -0
- package/dist/builder/index.d.ts +153 -0
- package/dist/builder/index.js +326 -0
- package/dist/events-Bm7R9XFB.d.cts +590 -0
- package/dist/events-Bm7R9XFB.d.ts +590 -0
- package/dist/index.d.cts +3 -589
- package/dist/index.d.ts +3 -589
- package/package.json +13 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,591 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Template literal type provides compile-time format validation.
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* ```typescript
|
|
7
|
-
* const date: DateString = "2025-12-25"; // ✓ Valid
|
|
8
|
-
* const bad: DateString = "25-12-2025"; // ✗ Error: wrong format
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
type DateString = `${number}-${number}-${number}`;
|
|
12
|
-
/**
|
|
13
|
-
* Map of dates to override (force reschedule).
|
|
14
|
-
* Unlike onConflict which handles conflicts, this unconditionally moves events.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* const overrideDates: OverrideDatesMap = {
|
|
19
|
-
* "2026-02-18": "2026-02-20", // Move from Feb 18 to Feb 20
|
|
20
|
-
* "2027-02-10": "2027-02-12", // Move from Feb 10 to Feb 12
|
|
21
|
-
* };
|
|
22
|
-
* ```
|
|
23
|
-
*/
|
|
24
|
-
type OverrideDatesMap = Record<DateString, DateString>;
|
|
25
|
-
/**
|
|
26
|
-
* Base properties shared by all event types (ICS-compatible)
|
|
27
|
-
*
|
|
28
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
29
|
-
* @template TCategory - Category type (default: string, can be enum for type safety)
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* // Default usage
|
|
34
|
-
* type Event = BaseEventProperties;
|
|
35
|
-
*
|
|
36
|
-
* // With typed categories
|
|
37
|
-
* type LiturgicalCategory = "solemnity" | "feast" | "memorial";
|
|
38
|
-
* type LiturgicalEvent = BaseEventProperties<LiturgicalMetadata, LiturgicalCategory>;
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
41
|
-
interface BaseEventProperties<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> {
|
|
42
|
-
id: string;
|
|
43
|
-
title: string;
|
|
44
|
-
keywords?: string[];
|
|
45
|
-
allDay?: boolean;
|
|
46
|
-
startTime?: string;
|
|
47
|
-
endTime?: string;
|
|
48
|
-
duration?: number;
|
|
49
|
-
description?: string;
|
|
50
|
-
location?: string;
|
|
51
|
-
url?: string;
|
|
52
|
-
/**
|
|
53
|
-
* Origin of the event — the plugin, feed, or ICS subscription that produced it.
|
|
54
|
-
* Lets a consumer customize/filter in bulk by source (like toggling a calendar
|
|
55
|
-
* in Google/Apple Calendar) and namespaces the ICS export `UID`.
|
|
56
|
-
* Distinct from `groupId` (a user-defined group) and `sourceEventId` (the
|
|
57
|
-
* originating config id).
|
|
58
|
-
*/
|
|
59
|
-
source?: string;
|
|
60
|
-
categories?: TCategory[];
|
|
61
|
-
/**
|
|
62
|
-
* Display precedence when several events land on the same day, like CSS
|
|
63
|
-
* `z-index`: **higher = on top**, default `0`. The core only sorts by this
|
|
64
|
-
* number (highest first); it assigns no meaning to the values — the consumer
|
|
65
|
-
* does. Ties keep generation order (stable).
|
|
66
|
-
*/
|
|
67
|
-
priority?: number;
|
|
68
|
-
status?: "confirmed" | "tentative" | "cancelled";
|
|
69
|
-
color?: string;
|
|
70
|
-
icon?: string;
|
|
71
|
-
metadata?: TMetadata;
|
|
72
|
-
reminders?: Reminder[];
|
|
73
|
-
/**
|
|
74
|
-
* Conflict resolver for handling events on the same day.
|
|
75
|
-
* Called during event generation to determine action when this event
|
|
76
|
-
* would occur on a specific date.
|
|
77
|
-
*
|
|
78
|
-
* Default behavior (when not specified): keep all events
|
|
79
|
-
*/
|
|
80
|
-
onConflict?: ConflictResolver;
|
|
81
|
-
/**
|
|
82
|
-
* Force reschedule dates unconditionally.
|
|
83
|
-
* Unlike onConflict which handles conflicts, this always moves events.
|
|
84
|
-
* Key is the original computed date (YYYY-MM-DD), value is the new date.
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* overrideDates: {
|
|
89
|
-
* "2026-02-18": "2026-02-20", // Move from Feb 18 to Feb 20
|
|
90
|
-
* }
|
|
91
|
-
* ```
|
|
92
|
-
*/
|
|
93
|
-
overrideDates?: OverrideDatesMap;
|
|
94
|
-
/**
|
|
95
|
-
* Per-occurrence exceptions keyed by the event's ORIGINAL computed date
|
|
96
|
-
* (YYYY-MM-DD) — maps ICS `EXDATE` / `RECURRENCE-ID`. `{ skip: true }` drops
|
|
97
|
-
* that occurrence; `{ override }` replaces properties for that one instance.
|
|
98
|
-
*/
|
|
99
|
-
exceptions?: EventExceptions;
|
|
100
|
-
/**
|
|
101
|
-
* Recurrence validity window (`YYYY-MM-DD`, **both bounds inclusive**).
|
|
102
|
-
* Occurrences before `startDate` or after `endDate` are dropped — applied
|
|
103
|
-
* centrally during generation, so it works for ANY event type (const, monthly,
|
|
104
|
-
* weekly, nth-weekday, plugin types…), not just the few that ship their own
|
|
105
|
-
* range fields.
|
|
106
|
-
*
|
|
107
|
-
* Maps iCalendar semantics: `startDate` ↔ `DTSTART` lower bound, `endDate` ↔
|
|
108
|
-
* `RRULE;UNTIL` (which RFC 5545 defines as **inclusive**). Both are DATE values
|
|
109
|
-
* (all-day); recurrences are date-based, so no time component is involved.
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* // Weekly stand-up, but only for July 2026
|
|
113
|
-
* { type: "weekly", id: "standup", dayOfWeek: 1,
|
|
114
|
-
* startDate: "2026-07-01", endDate: "2026-07-31" }
|
|
115
|
-
*/
|
|
116
|
-
startDate?: string;
|
|
117
|
-
endDate?: string;
|
|
118
|
-
/**
|
|
119
|
-
* Per-occurrence **dynamic** fields, derived from each occurrence's date. A map
|
|
120
|
-
* of `fieldName → template`, where the template may contain date tokens
|
|
121
|
-
* (`{YYYY}` `{MM}` `{DD}` zero-padded · `{M}` `{D}` no padding). Each occurrence
|
|
122
|
-
* gets the field set to the interpolated value.
|
|
123
|
-
*
|
|
124
|
-
* Applied during generation, **after** the base value and **before** a
|
|
125
|
-
* per-date `exceptions[date].override` (which always wins). Typically used for a
|
|
126
|
-
* date-specific `url`, but any string field works (`title`, `description`,
|
|
127
|
-
* `location`, …).
|
|
128
|
-
*
|
|
129
|
-
* @example
|
|
130
|
-
* // Every Sunday's link points at a date page
|
|
131
|
-
* { type: "weekly", id: "mass", dayOfWeek: 0, title: "Mass",
|
|
132
|
-
* templates: { url: "https://x.com/mass/{D}-{M}" } }
|
|
133
|
-
* // 2026-07-07 → .../mass/7-7 · 2026-07-14 → .../mass/14-7
|
|
134
|
-
*/
|
|
135
|
-
templates?: Record<string, string>;
|
|
136
|
-
}
|
|
137
|
-
interface Reminder {
|
|
138
|
-
type: "notification" | "email";
|
|
139
|
-
trigger: number;
|
|
140
|
-
message?: string;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* A single per-occurrence exception (see `BaseEventProperties.exceptions`).
|
|
144
|
-
* - `{ skip: true }` — drop this occurrence (ICS `EXDATE`).
|
|
145
|
-
* - `{ override }` — replace properties for this one instance (ICS
|
|
146
|
-
* `RECURRENCE-ID`). Changes display properties only; to move an occurrence to
|
|
147
|
-
* another date use `overrideDates`.
|
|
148
|
-
*/
|
|
149
|
-
type EventException = {
|
|
150
|
-
skip: true;
|
|
151
|
-
} | {
|
|
152
|
-
override: Partial<Omit<BaseEventProperties, "id" | "exceptions">>;
|
|
153
|
-
};
|
|
154
|
-
/**
|
|
155
|
-
* Map of an event's ORIGINAL computed dates (YYYY-MM-DD) to per-occurrence
|
|
156
|
-
* exceptions.
|
|
157
|
-
*/
|
|
158
|
-
type EventExceptions = Record<DateString, EventException>;
|
|
159
|
-
/**
|
|
160
|
-
* Conflict action when multiple events occur on the same day.
|
|
161
|
-
*
|
|
162
|
-
* - `keep` - Keep this event (default behavior, allows multiple events on same day)
|
|
163
|
-
* - `drop` - Remove this event when conflict exists
|
|
164
|
-
* - `reschedule` - Move this event to a different date
|
|
165
|
-
*/
|
|
166
|
-
type ConflictAction = {
|
|
167
|
-
action: "keep";
|
|
168
|
-
} | {
|
|
169
|
-
action: "drop";
|
|
170
|
-
} | {
|
|
171
|
-
action: "reschedule";
|
|
172
|
-
to: DateString;
|
|
173
|
-
};
|
|
174
|
-
/**
|
|
175
|
-
* Map of dates to conflict actions.
|
|
176
|
-
* Dates not in the map default to "keep".
|
|
177
|
-
*/
|
|
178
|
-
type ConflictMap = Partial<Record<DateString, ConflictAction>>;
|
|
179
|
-
/**
|
|
180
|
-
* Function to determine conflict action for a specific date.
|
|
181
|
-
*/
|
|
182
|
-
type ConflictResolverFn = (date: DateString) => ConflictAction;
|
|
183
|
-
/**
|
|
184
|
-
* Resolver to determine conflict action for events.
|
|
185
|
-
* Can be either a function for dynamic logic or a map for static date lists.
|
|
186
|
-
*
|
|
187
|
-
* @example
|
|
188
|
-
* ```typescript
|
|
189
|
-
* // Option 1: Function for complex logic
|
|
190
|
-
* const onConflict: ConflictResolver = (date) => {
|
|
191
|
-
* if (date === "2026-02-18") {
|
|
192
|
-
* return { action: "reschedule", to: "2026-02-17" };
|
|
193
|
-
* }
|
|
194
|
-
* return { action: "keep" };
|
|
195
|
-
* };
|
|
196
|
-
*
|
|
197
|
-
* // Option 2: Map for static date lists (cleaner for many dates)
|
|
198
|
-
* const onConflict: ConflictResolver = {
|
|
199
|
-
* "2026-02-18": { action: "reschedule", to: "2026-02-17" },
|
|
200
|
-
* "2027-11-24": { action: "drop" },
|
|
201
|
-
* "2028-02-18": { action: "reschedule", to: "2028-02-19" },
|
|
202
|
-
* // Dates not in map default to "keep"
|
|
203
|
-
* };
|
|
204
|
-
* ```
|
|
205
|
-
*/
|
|
206
|
-
type ConflictResolver = ConflictResolverFn | ConflictMap;
|
|
207
|
-
/**
|
|
208
|
-
* CONST - Fixed annual events (e.g., Christmas on Dec 25)
|
|
209
|
-
* Supports year exclusions and date range constraints.
|
|
210
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
211
|
-
* @example
|
|
212
|
-
* // Basic annual event
|
|
213
|
-
* { type: "const", id: "christmas", month: 12, day: 25 }
|
|
214
|
-
*
|
|
215
|
-
* // Annual event with exclusions
|
|
216
|
-
* { type: "const", id: "liberation-day",
|
|
217
|
-
* month: 4, day: 30, excludeYears: [2025, 2040, 2043] }
|
|
218
|
-
*
|
|
219
|
-
* // Annual event with date range
|
|
220
|
-
* { type: "const", id: "company-anniversary",
|
|
221
|
-
* month: 3, day: 15, startYear: 2020, endYear: 2030 }
|
|
222
|
-
*/
|
|
223
|
-
interface ConstEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
224
|
-
type: "const";
|
|
225
|
-
/**
|
|
226
|
-
* Month of the event (1-12)
|
|
227
|
-
* @example 12 // December
|
|
228
|
-
*/
|
|
229
|
-
month: number;
|
|
230
|
-
/**
|
|
231
|
-
* Day of the month (1-31)
|
|
232
|
-
* @example 25 // 25th day
|
|
233
|
-
*/
|
|
234
|
-
day: number;
|
|
235
|
-
/**
|
|
236
|
-
* Years to exclude from recurrence
|
|
237
|
-
* @example [2025, 2040, 2043] // Skip these years
|
|
238
|
-
*/
|
|
239
|
-
excludeYears?: number[];
|
|
240
|
-
/**
|
|
241
|
-
* First year the event occurs (inclusive)
|
|
242
|
-
* @example 2020 // Start from 2020
|
|
243
|
-
*/
|
|
244
|
-
startYear?: number;
|
|
245
|
-
/**
|
|
246
|
-
* Last year the event occurs (inclusive)
|
|
247
|
-
* @example 2030 // End at 2030
|
|
248
|
-
*/
|
|
249
|
-
endYear?: number;
|
|
250
|
-
}
|
|
251
|
-
/**
|
|
252
|
-
* FIXED - One-time events on a specific date
|
|
253
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
254
|
-
* @example
|
|
255
|
-
* { type: "fixed", id: "wedding",
|
|
256
|
-
* year: 2025, month: 6, day: 15 }
|
|
257
|
-
*/
|
|
258
|
-
interface FixedEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
259
|
-
type: "fixed";
|
|
260
|
-
/**
|
|
261
|
-
* Year of the event
|
|
262
|
-
* @example 2025
|
|
263
|
-
*/
|
|
264
|
-
year: number;
|
|
265
|
-
/**
|
|
266
|
-
* Month of the event (1-12)
|
|
267
|
-
* @example 6 // June
|
|
268
|
-
*/
|
|
269
|
-
month: number;
|
|
270
|
-
/**
|
|
271
|
-
* Day of the month (1-31)
|
|
272
|
-
* @example 15
|
|
273
|
-
*/
|
|
274
|
-
day: number;
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* MONTHLY - Recurring events on the same day every month
|
|
278
|
-
* Supports intervals, month exclusions, and date exclusions.
|
|
279
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
280
|
-
* @example
|
|
281
|
-
* // Every 15th of the month
|
|
282
|
-
* { type: "monthly", id: "payday", day: 15 }
|
|
283
|
-
*
|
|
284
|
-
* // Quarterly (every 3 months starting January)
|
|
285
|
-
* { type: "monthly", id: "quarterly-review",
|
|
286
|
-
* day: 1, interval: 3, startMonth: 1 }
|
|
287
|
-
*
|
|
288
|
-
* // Monthly except December
|
|
289
|
-
* { type: "monthly", id: "team-lunch",
|
|
290
|
-
* day: 10, excludeMonths: [12] }
|
|
291
|
-
*/
|
|
292
|
-
interface MonthlyEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
293
|
-
type: "monthly";
|
|
294
|
-
/**
|
|
295
|
-
* Day of the month (1-31)
|
|
296
|
-
* Note: If day exceeds month's days (e.g., 31 in February), event is skipped for that month
|
|
297
|
-
* @example 15 // 15th of each month
|
|
298
|
-
*/
|
|
299
|
-
day: number;
|
|
300
|
-
/**
|
|
301
|
-
* Recurrence interval in months (default: 1)
|
|
302
|
-
* @example 3 // Every 3 months (quarterly)
|
|
303
|
-
*/
|
|
304
|
-
interval?: number;
|
|
305
|
-
/**
|
|
306
|
-
* Starting month for interval calculation (1-12, default: 1)
|
|
307
|
-
* Used with interval to determine which months the event occurs
|
|
308
|
-
* @example 1 // Start counting from January
|
|
309
|
-
*/
|
|
310
|
-
startMonth?: number;
|
|
311
|
-
/**
|
|
312
|
-
* Months to exclude (1-12)
|
|
313
|
-
* @example [7, 8] // Skip July and August
|
|
314
|
-
*/
|
|
315
|
-
excludeMonths?: number[];
|
|
316
|
-
/**
|
|
317
|
-
* Specific dates to exclude (ISO format: YYYY-MM-DD)
|
|
318
|
-
* @example ["2025-12-15"] // Skip this specific date
|
|
319
|
-
*/
|
|
320
|
-
excludeDates?: string[];
|
|
321
|
-
}
|
|
322
|
-
/** A weekday index: 0 = Sunday, 1 = Monday, … 6 = Saturday. */
|
|
323
|
-
type WeekdayIndex = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
324
|
-
/**
|
|
325
|
-
* WEEKLY - Recurring events on one or more days every week
|
|
326
|
-
* Supports multiple weekdays, intervals, date range, and date exclusions.
|
|
327
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
328
|
-
* @example
|
|
329
|
-
* // Every Monday
|
|
330
|
-
* { type: "weekly", id: "standup", dayOfWeek: 1 }
|
|
331
|
-
*
|
|
332
|
-
* // Every Monday, Wednesday & Friday (like an alarm's "Repeat")
|
|
333
|
-
* { type: "weekly", id: "logwork", dayOfWeek: [1, 3, 5] }
|
|
334
|
-
*
|
|
335
|
-
* // Every other Wednesday
|
|
336
|
-
* { type: "weekly", id: "biweekly-sync",
|
|
337
|
-
* dayOfWeek: 3, interval: 2 }
|
|
338
|
-
*
|
|
339
|
-
* // Every Friday with date range
|
|
340
|
-
* { type: "weekly", id: "sprint-review",
|
|
341
|
-
* dayOfWeek: 5, startDate: "2025-01-01", endDate: "2025-12-31" }
|
|
342
|
-
*/
|
|
343
|
-
interface WeeklyEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
344
|
-
type: "weekly";
|
|
345
|
-
/**
|
|
346
|
-
* Day of the week, or several. `0=Sunday, 1=Monday, ..., 6=Saturday`.
|
|
347
|
-
* A list fires on each selected day every week (ICS `BYDAY` semantics); with
|
|
348
|
-
* `interval`, all selected days share one reference week.
|
|
349
|
-
* @example 1 // Monday
|
|
350
|
-
* @example [1, 3, 5] // Monday, Wednesday, Friday
|
|
351
|
-
*/
|
|
352
|
-
dayOfWeek: WeekdayIndex | WeekdayIndex[];
|
|
353
|
-
/**
|
|
354
|
-
* Recurrence interval in weeks (default: 1)
|
|
355
|
-
* @example 2 // Every 2 weeks (bi-weekly)
|
|
356
|
-
*/
|
|
357
|
-
interval?: number;
|
|
358
|
-
/**
|
|
359
|
-
* Start date for the recurrence (ISO format: YYYY-MM-DD)
|
|
360
|
-
* Used as reference point for interval calculation
|
|
361
|
-
* @example "2025-01-06" // First Monday of 2025
|
|
362
|
-
*/
|
|
363
|
-
startDate?: string;
|
|
364
|
-
/**
|
|
365
|
-
* End date for the recurrence (ISO format: YYYY-MM-DD)
|
|
366
|
-
* @example "2025-12-31"
|
|
367
|
-
*/
|
|
368
|
-
endDate?: string;
|
|
369
|
-
/**
|
|
370
|
-
* Specific dates to exclude (ISO format: YYYY-MM-DD)
|
|
371
|
-
* @example ["2025-12-25"] // Skip Christmas
|
|
372
|
-
*/
|
|
373
|
-
excludeDates?: string[];
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* FORMULA - Custom formula-based events
|
|
377
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
378
|
-
*/
|
|
379
|
-
interface FormulaEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
380
|
-
type: "formula";
|
|
381
|
-
formula: string;
|
|
382
|
-
params?: Record<string, unknown>;
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Anchor point for nth-weekday events relative to a fixed date.
|
|
386
|
-
*/
|
|
387
|
-
interface DateAnchor {
|
|
388
|
-
/** Month (1-12) */
|
|
389
|
-
month: number;
|
|
390
|
-
/** Day of month (1-31) */
|
|
391
|
-
day: number;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* NTH-WEEKDAY - Recurring events on the Nth weekday of a month, or the first
|
|
395
|
-
* matching weekday relative to a fixed-date anchor.
|
|
396
|
-
*
|
|
397
|
-
* Supports two modes:
|
|
398
|
-
*
|
|
399
|
-
* **Simple mode** — nth occurrence of a weekday within a calendar month:
|
|
400
|
-
* ```typescript
|
|
401
|
-
* // Mother's Day: 2nd Sunday of May
|
|
402
|
-
* { type: "nth-weekday", nth: 2, dayOfWeek: 0, month: 5 }
|
|
403
|
-
*
|
|
404
|
-
* // Thanksgiving (US): 4th Thursday of November
|
|
405
|
-
* { type: "nth-weekday", nth: 4, dayOfWeek: 4, month: 11 }
|
|
406
|
-
*
|
|
407
|
-
* // Last Monday of August
|
|
408
|
-
* { type: "nth-weekday", nth: -1, dayOfWeek: 1, month: 8 }
|
|
409
|
-
* ```
|
|
410
|
-
*
|
|
411
|
-
* **Anchored mode** — first matching weekday on or after a fixed date,
|
|
412
|
-
* optionally bounded and with a fallback:
|
|
413
|
-
* ```typescript
|
|
414
|
-
* // Holy Family: first Sunday after Dec 25, fallback Dec 30
|
|
415
|
-
* { type: "nth-weekday", dayOfWeek: 0,
|
|
416
|
-
* after: { month: 12, day: 26 }, before: { month: 12, day: 31 },
|
|
417
|
-
* fallback: { month: 12, day: 30 } }
|
|
418
|
-
*
|
|
419
|
-
* // Baptism of the Lord: first Sunday on/after Jan 7
|
|
420
|
-
* { type: "nth-weekday", dayOfWeek: 0, after: { month: 1, day: 7 } }
|
|
421
|
-
* ```
|
|
422
|
-
*
|
|
423
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
424
|
-
*/
|
|
425
|
-
interface NthWeekdayEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
426
|
-
type: "nth-weekday";
|
|
427
|
-
/**
|
|
428
|
-
* Day of the week (0=Sunday, 1=Monday, ..., 6=Saturday)
|
|
429
|
-
* @example 0 // Sunday
|
|
430
|
-
*/
|
|
431
|
-
dayOfWeek: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
432
|
-
/**
|
|
433
|
-
* Which occurrence within the month:
|
|
434
|
-
* - `1`–`4`: 1st through 4th occurrence
|
|
435
|
-
* - `-1`: last occurrence
|
|
436
|
-
*
|
|
437
|
-
* Required in simple mode (paired with `month`). Omit for anchored mode.
|
|
438
|
-
*/
|
|
439
|
-
nth?: 1 | 2 | 3 | 4 | -1;
|
|
440
|
-
/**
|
|
441
|
-
* Month (1-12). Required in simple mode. Omit for anchored mode.
|
|
442
|
-
*/
|
|
443
|
-
month?: number;
|
|
444
|
-
/**
|
|
445
|
-
* Find the first matching `dayOfWeek` on or after this date.
|
|
446
|
-
* When provided, `nth` and `month` are ignored.
|
|
447
|
-
*/
|
|
448
|
-
after?: DateAnchor;
|
|
449
|
-
/**
|
|
450
|
-
* Upper-bound anchor. If the first match found via `after` falls on or
|
|
451
|
-
* after this date, the `fallback` date is used instead (if supplied).
|
|
452
|
-
*/
|
|
453
|
-
before?: DateAnchor;
|
|
454
|
-
/**
|
|
455
|
-
* Fallback date used when no `dayOfWeek` is found between `after` and
|
|
456
|
-
* `before` (inclusive). Only meaningful when `before` is also set.
|
|
457
|
-
*/
|
|
458
|
-
fallback?: DateAnchor;
|
|
459
|
-
/** Years to skip entirely. */
|
|
460
|
-
excludeYears?: number[];
|
|
461
|
-
/** First year the event applies (inclusive). */
|
|
462
|
-
startYear?: number;
|
|
463
|
-
/** Last year the event applies (inclusive). */
|
|
464
|
-
endYear?: number;
|
|
465
|
-
}
|
|
466
|
-
/**
|
|
467
|
-
* Core event types (without plugins)
|
|
468
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
469
|
-
*/
|
|
470
|
-
/**
|
|
471
|
-
* RELATIVE - A date computed as an offset from a named anchor.
|
|
472
|
-
* The anchor is a resolver (year → Date) registered by the consumer or a plugin;
|
|
473
|
-
* the offset shifts from it. The core knows no specific anchors — it only
|
|
474
|
-
* resolves whatever name was registered. Compile target of the builder's
|
|
475
|
-
* `from(anchor).plus(...)`.
|
|
476
|
-
*
|
|
477
|
-
* @example
|
|
478
|
-
* // 49 days after whatever the "anchor" resolver returns for that year
|
|
479
|
-
* { type: "relative", id: "x", anchor: "anchor", offset: { days: 49 } }
|
|
480
|
-
*/
|
|
481
|
-
interface RelativeEvent<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> extends BaseEventProperties<TMetadata, TCategory> {
|
|
482
|
-
type: "relative";
|
|
483
|
-
/** Name of a registered anchor resolver (year → Date). */
|
|
484
|
-
anchor: string;
|
|
485
|
-
/** Offset from the anchor date. */
|
|
486
|
-
offset: {
|
|
487
|
-
days?: number;
|
|
488
|
-
weeks?: number;
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
type CoreEventConfig<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> = ConstEvent<TMetadata, TCategory> | FixedEvent<TMetadata, TCategory> | MonthlyEvent<TMetadata, TCategory> | WeeklyEvent<TMetadata, TCategory> | NthWeekdayEvent<TMetadata, TCategory> | FormulaEvent<TMetadata, TCategory> | RelativeEvent<TMetadata, TCategory>;
|
|
492
|
-
/**
|
|
493
|
-
* Generic event config - extended by plugins.
|
|
494
|
-
* Use the generic parameter to enforce metadata types.
|
|
495
|
-
*
|
|
496
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
497
|
-
*
|
|
498
|
-
* @example
|
|
499
|
-
* ```typescript
|
|
500
|
-
* // Basic usage (any metadata)
|
|
501
|
-
* const event: EventConfig = { type: "const", id: "x", ... };
|
|
502
|
-
*
|
|
503
|
-
* // With typed metadata
|
|
504
|
-
* interface MyMetadata { rank: string; color: string; }
|
|
505
|
-
* const event: EventConfig<MyMetadata> = { ... metadata: { rank: "high", color: "red" } };
|
|
506
|
-
* ```
|
|
507
|
-
*/
|
|
508
|
-
type EventConfig<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string> = CoreEventConfig<TMetadata, TCategory> | {
|
|
509
|
-
type: string;
|
|
510
|
-
metadata?: TMetadata;
|
|
511
|
-
[key: string]: unknown;
|
|
512
|
-
};
|
|
513
|
-
/**
|
|
514
|
-
* Event type identifiers
|
|
515
|
-
*/
|
|
516
|
-
type CoreEventType = "const" | "fixed" | "monthly" | "weekly" | "nth-weekday" | "formula" | "relative";
|
|
517
|
-
/**
|
|
518
|
-
* Custom event configuration for overriding event properties.
|
|
519
|
-
* Used by generator packages to allow customization of generated events.
|
|
520
|
-
*
|
|
521
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
522
|
-
* @template TExclude - Fields to exclude from customization (default: never)
|
|
523
|
-
*
|
|
524
|
-
* @example
|
|
525
|
-
* ```typescript
|
|
526
|
-
* // Allow all fields except id
|
|
527
|
-
* const customConfig: CustomEventConfig<{ localName: string }> = {
|
|
528
|
-
* title: "Easter Sunday",
|
|
529
|
-
* keywords: ["easter", "resurrection"],
|
|
530
|
-
* metadata: { localName: "Pâques" },
|
|
531
|
-
* url: "https://example.com/easter",
|
|
532
|
-
* };
|
|
533
|
-
*
|
|
534
|
-
* // Force reschedule to different dates
|
|
535
|
-
* const customConfig: CustomEventConfig = {
|
|
536
|
-
* overrideDates: {
|
|
537
|
-
* "2026-02-18": "2026-02-20", // Move Ash Wednesday
|
|
538
|
-
* },
|
|
539
|
-
* };
|
|
540
|
-
*
|
|
541
|
-
* // Restrict certain fields from customization
|
|
542
|
-
* type RestrictedConfig = CustomEventConfig<MyMetadata, "status" | "reminders">;
|
|
543
|
-
* // Now status and reminders cannot be customized
|
|
544
|
-
* ```
|
|
545
|
-
*/
|
|
546
|
-
type CustomEventConfig<TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string, TExclude extends keyof BaseEventProperties<TMetadata, TCategory> = never> = Partial<Omit<BaseEventProperties<TMetadata, TCategory>, "id" | "metadata" | TExclude>> & {
|
|
547
|
-
/**
|
|
548
|
-
* Partial metadata to merge with the base event's metadata.
|
|
549
|
-
* Only specify the fields you want to add or override.
|
|
550
|
-
* The base metadata fields will be preserved.
|
|
551
|
-
*
|
|
552
|
-
* @example
|
|
553
|
-
* ```typescript
|
|
554
|
-
* // Only add extra fields - base metadata (rank, season, etc.) is preserved
|
|
555
|
-
* metadata: { wikiFileUrl: "christmas.md" }
|
|
556
|
-
* ```
|
|
557
|
-
*/
|
|
558
|
-
metadata?: Partial<TMetadata>;
|
|
559
|
-
/**
|
|
560
|
-
* Force reschedule dates unconditionally.
|
|
561
|
-
* Unlike onConflict which handles conflicts, this always moves events.
|
|
562
|
-
* Key is the original computed date, value is the new date.
|
|
563
|
-
*/
|
|
564
|
-
overrideDates?: OverrideDatesMap;
|
|
565
|
-
};
|
|
566
|
-
/**
|
|
567
|
-
* Resolver function that provides custom configuration for each event key.
|
|
568
|
-
* Returns partial event properties that will be merged with the generated event.
|
|
569
|
-
*
|
|
570
|
-
* @template TKey - Event key type (e.g., MassKey, LunarKey)
|
|
571
|
-
* @template TMetadata - Custom metadata type extending Record<string, unknown>
|
|
572
|
-
* @template TExclude - Fields to exclude from customization (default: never)
|
|
573
|
-
*
|
|
574
|
-
* @example
|
|
575
|
-
* ```typescript
|
|
576
|
-
* // Liturgical events - allow all customization
|
|
577
|
-
* const resolver: CustomEventResolver<MassKey, LiturgicalMetadata> = (key) => ({
|
|
578
|
-
* title: localTexts[key]?.title,
|
|
579
|
-
* metadata: { localName: localTexts[key]?.name },
|
|
580
|
-
* });
|
|
581
|
-
*
|
|
582
|
-
* // Lunar events - restrict status and reminders
|
|
583
|
-
* const resolver: CustomEventResolver<LunarKey, LunarMetadata, "status" | "reminders"> = (key) => ({
|
|
584
|
-
* title: lunarTexts[key]?.title,
|
|
585
|
-
* });
|
|
586
|
-
* ```
|
|
587
|
-
*/
|
|
588
|
-
type CustomEventResolver<TKey extends string, TMetadata extends Record<string, unknown> = Record<string, unknown>, TCategory extends string = string, TExclude extends keyof BaseEventProperties = never> = (key: TKey) => CustomEventConfig<TMetadata, TCategory, TExclude> | undefined;
|
|
1
|
+
import { E as EventConfig, B as BaseEventProperties, D as DateString, C as ConflictResolver, a as ConflictAction } from './events-Bm7R9XFB.js';
|
|
2
|
+
export { b as ConflictMap, c as ConflictResolverFn, d as ConstEvent, e as CoreEventConfig, f as CoreEventType, g as CustomEventConfig, h as CustomEventResolver, i as DateAnchor, F as FixedEvent, j as FormulaEvent, M as MonthlyEvent, N as NthWeekdayEvent, O as OverrideDatesMap, R as RelativeEvent, k as Reminder, W as WeekdayIndex, l as WeeklyEvent } from './events-Bm7R9XFB.js';
|
|
589
3
|
|
|
590
4
|
/**
|
|
591
5
|
* Group configuration
|
|
@@ -1286,4 +700,4 @@ interface MergeEventConfigOptions {
|
|
|
1286
700
|
*/
|
|
1287
701
|
declare function mergeEventConfig<T extends Record<string, unknown>>(base: T, custom: Partial<T> | undefined, options?: MergeEventConfigOptions): T;
|
|
1288
702
|
|
|
1289
|
-
export {
|
|
703
|
+
export { BaseEventProperties, type Buildable, type CalendarDay, type CalendarEvent, CalendaryInstance as Calendary, type CalendaryForPlugin, CalendaryInstance, type CalendaryPlugin, type Collection, ConflictAction, ConflictResolver, type DateComponents, DateString, type DayEnricher, EventConfig, type EventText, type EventTypeHandler, type FormulaFn, type GetDaysOptions, type Group, type GroupConfig, type GroupInput, type MergeEventConfigOptions, type MetadataQuery, type PluginContext, type PluginFactory, SearchBuilder, type SearchOptions, type SortField, type SortOrder, addDays, calendary, daysBetween, formatDate, getYear, interpolateDateTokens, isCalendary, isValidDateString, mergeEventConfig, parseDate, resolveConflict };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "calendaryjs",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Composable calendar & recurrence engine with pluggable calendar systems.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -14,6 +14,16 @@
|
|
|
14
14
|
"types": "./dist/index.d.cts",
|
|
15
15
|
"default": "./dist/index.cjs"
|
|
16
16
|
}
|
|
17
|
+
},
|
|
18
|
+
"./builder": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/builder/index.d.ts",
|
|
21
|
+
"default": "./dist/builder/index.js"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./dist/builder/index.d.cts",
|
|
25
|
+
"default": "./dist/builder/index.cjs"
|
|
26
|
+
}
|
|
17
27
|
}
|
|
18
28
|
},
|
|
19
29
|
"keywords": [
|
|
@@ -48,7 +58,8 @@
|
|
|
48
58
|
],
|
|
49
59
|
"tsup": {
|
|
50
60
|
"entry": [
|
|
51
|
-
"src/index.ts"
|
|
61
|
+
"src/index.ts",
|
|
62
|
+
"src/builder/index.ts"
|
|
52
63
|
],
|
|
53
64
|
"format": [
|
|
54
65
|
"esm",
|