@intech-software/chronera 0.1.6 → 0.1.7

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.
@@ -0,0 +1,428 @@
1
+ import { ChroneraError } from "../errors/errors.js";
2
+ import { projectInstantToZonedFields } from "../runtime/timezone.js";
3
+ import { absoluteDayFromGregorianFields, gregorianFieldsFromAbsoluteDay, } from "../core/absolute-day.js";
4
+ import { addDays, addMonths, addYears, startOfMonth, endOfMonth, startOfYear, endOfYear, } from "./convenience.js";
5
+ function todayLocal(tz) {
6
+ const zone = tz ??
7
+ (typeof Intl !== "undefined"
8
+ ? Intl.DateTimeFormat().resolvedOptions().timeZone
9
+ : "UTC") ??
10
+ "UTC";
11
+ const instant = { kind: "instant", epochMilliseconds: Date.now() };
12
+ const z = projectInstantToZonedFields(instant, zone);
13
+ return { kind: "local-date", year: z.year, month: z.month, day: z.day };
14
+ }
15
+ function absDay(d) {
16
+ return absoluteDayFromGregorianFields(d.year, d.month, d.day);
17
+ }
18
+ function fromAbs(n) {
19
+ const f = gregorianFieldsFromAbsoluteDay(n);
20
+ return { kind: "local-date", year: f.year, month: f.month, day: f.day };
21
+ }
22
+ // absDay % 7 mapping (derived from absoluteDayFromGregorianFields):
23
+ // Thursday=0, Friday=1, Saturday=2, Sunday=3, Monday=4, Tuesday=5, Wednesday=6
24
+ const DOW_INDEX = {
25
+ monday: 4,
26
+ tuesday: 5,
27
+ wednesday: 6,
28
+ thursday: 0,
29
+ friday: 1,
30
+ saturday: 2,
31
+ sunday: 3,
32
+ };
33
+ function dayOfWeekIndex(d) {
34
+ return absDay(d) % 7;
35
+ }
36
+ function nextWeekday(ref, t) {
37
+ const diff = (t - dayOfWeekIndex(ref) + 7) % 7 || 7;
38
+ return fromAbs(absDay(ref) + diff);
39
+ }
40
+ function lastWeekday(ref, t) {
41
+ const diff = (dayOfWeekIndex(ref) - t + 7) % 7 || 7;
42
+ return fromAbs(absDay(ref) - diff);
43
+ }
44
+ const LANG_TOKENS = {
45
+ th: {
46
+ วันนี้: "today",
47
+ เมื่อวาน: "yesterday",
48
+ เมื่อวานนี้: "yesterday",
49
+ พรุ่งนี้: "tomorrow",
50
+ มะรืน: "day after tomorrow",
51
+ อาทิตย์หน้า: "next week",
52
+ สัปดาห์หน้า: "next week",
53
+ อาทิตย์ที่แล้ว: "last week",
54
+ สัปดาห์ที่แล้ว: "last week",
55
+ เดือนหน้า: "next month",
56
+ เดือนที่แล้ว: "last month",
57
+ ปีหน้า: "next year",
58
+ ปีที่แล้ว: "last year",
59
+ วันจันทร์: "monday",
60
+ วันอังคาร: "tuesday",
61
+ วันพุธ: "wednesday",
62
+ วันพฤหัสบดี: "thursday",
63
+ วันพฤหัส: "thursday",
64
+ วันศุกร์: "friday",
65
+ วันเสาร์: "saturday",
66
+ วันอาทิตย์: "sunday",
67
+ ต้นเดือน: "start of month",
68
+ ปลายเดือน: "end of month",
69
+ ต้นปี: "start of year",
70
+ ปลายปี: "end of year",
71
+ },
72
+ ja: {
73
+ 今日: "today",
74
+ 本日: "today",
75
+ 昨日: "yesterday",
76
+ 明日: "tomorrow",
77
+ 明後日: "day after tomorrow",
78
+ 来週: "next week",
79
+ 先週: "last week",
80
+ 今週: "this week",
81
+ 来月: "next month",
82
+ 先月: "last month",
83
+ 今月: "this month",
84
+ 来年: "next year",
85
+ 去年: "last year",
86
+ 今年: "this year",
87
+ 月曜日: "monday",
88
+ 火曜日: "tuesday",
89
+ 水曜日: "wednesday",
90
+ 木曜日: "thursday",
91
+ 金曜日: "friday",
92
+ 土曜日: "saturday",
93
+ 日曜日: "sunday",
94
+ 月曜: "monday",
95
+ 火曜: "tuesday",
96
+ 水曜: "wednesday",
97
+ 木曜: "thursday",
98
+ 金曜: "friday",
99
+ 土曜: "saturday",
100
+ 日曜: "sunday",
101
+ },
102
+ zh: {
103
+ 今天: "today",
104
+ 今日: "today",
105
+ 昨天: "yesterday",
106
+ 昨日: "yesterday",
107
+ 明天: "tomorrow",
108
+ 明日: "tomorrow",
109
+ 后天: "day after tomorrow",
110
+ 後天: "day after tomorrow",
111
+ 下周: "next week",
112
+ 下週: "next week",
113
+ 上周: "last week",
114
+ 上週: "last week",
115
+ 下个月: "next month",
116
+ 下個月: "next month",
117
+ 上个月: "last month",
118
+ 上個月: "last month",
119
+ 明年: "next year",
120
+ 去年: "last year",
121
+ 星期一: "monday",
122
+ 星期二: "tuesday",
123
+ 星期三: "wednesday",
124
+ 星期四: "thursday",
125
+ 星期五: "friday",
126
+ 星期六: "saturday",
127
+ 星期日: "sunday",
128
+ 星期天: "sunday",
129
+ 周一: "monday",
130
+ 周二: "tuesday",
131
+ 周三: "wednesday",
132
+ 周四: "thursday",
133
+ 周五: "friday",
134
+ 周六: "saturday",
135
+ 周日: "sunday",
136
+ },
137
+ ko: {
138
+ 오늘: "today",
139
+ 어제: "yesterday",
140
+ 내일: "tomorrow",
141
+ 모레: "day after tomorrow",
142
+ 다음주: "next week",
143
+ 지난주: "last week",
144
+ 다음달: "next month",
145
+ 지난달: "last month",
146
+ 내년: "next year",
147
+ 작년: "last year",
148
+ 월요일: "monday",
149
+ 화요일: "tuesday",
150
+ 수요일: "wednesday",
151
+ 목요일: "thursday",
152
+ 금요일: "friday",
153
+ 토요일: "saturday",
154
+ 일요일: "sunday",
155
+ },
156
+ de: {
157
+ heute: "today",
158
+ gestern: "yesterday",
159
+ morgen: "tomorrow",
160
+ übermorgen: "day after tomorrow",
161
+ "nächste woche": "next week",
162
+ "letzte woche": "last week",
163
+ "nächsten monat": "next month",
164
+ "letzten monat": "last month",
165
+ "nächstes jahr": "next year",
166
+ "letztes jahr": "last year",
167
+ montag: "monday",
168
+ dienstag: "tuesday",
169
+ mittwoch: "wednesday",
170
+ donnerstag: "thursday",
171
+ freitag: "friday",
172
+ samstag: "saturday",
173
+ sonntag: "sunday",
174
+ "nächsten montag": "next monday",
175
+ "nächsten dienstag": "next tuesday",
176
+ "nächsten mittwoch": "next wednesday",
177
+ "nächsten donnerstag": "next thursday",
178
+ "nächsten freitag": "next friday",
179
+ },
180
+ fr: {
181
+ "aujourd'hui": "today",
182
+ hier: "yesterday",
183
+ demain: "tomorrow",
184
+ "après-demain": "day after tomorrow",
185
+ "la semaine prochaine": "next week",
186
+ "la semaine dernière": "last week",
187
+ "le mois prochain": "next month",
188
+ "le mois dernier": "last month",
189
+ "l'année prochaine": "next year",
190
+ "l'année dernière": "last year",
191
+ lundi: "monday",
192
+ mardi: "tuesday",
193
+ mercredi: "wednesday",
194
+ jeudi: "thursday",
195
+ vendredi: "friday",
196
+ samedi: "saturday",
197
+ dimanche: "sunday",
198
+ "lundi prochain": "next monday",
199
+ "mardi prochain": "next tuesday",
200
+ },
201
+ };
202
+ function normalize(input, locale) {
203
+ const lang = locale.split("-")[0]?.toLowerCase() ?? "en";
204
+ const map = LANG_TOKENS[lang] ?? {};
205
+ let s = input.trim().toLowerCase();
206
+ const keys = Object.keys(map).sort((a, b) => b.length - a.length);
207
+ for (const k of keys) {
208
+ const val = map[k];
209
+ if (val !== undefined)
210
+ s = s.replace(k.toLowerCase(), val);
211
+ }
212
+ return s.replace(/\s+/g, " ").trim();
213
+ }
214
+ function matchPattern(s, ref) {
215
+ if (s === "today")
216
+ return { date: ref, pattern: "today" };
217
+ if (s === "yesterday")
218
+ return { date: fromAbs(absDay(ref) - 1), pattern: "yesterday" };
219
+ if (s === "tomorrow")
220
+ return { date: fromAbs(absDay(ref) + 1), pattern: "tomorrow" };
221
+ if (s === "day after tomorrow")
222
+ return { date: fromAbs(absDay(ref) + 2), pattern: "day after tomorrow" };
223
+ if (s === "day before yesterday")
224
+ return { date: fromAbs(absDay(ref) - 2), pattern: "day before yesterday" };
225
+ if (s === "next week")
226
+ return { date: fromAbs(absDay(ref) + 7), pattern: "next week" };
227
+ if (s === "last week")
228
+ return { date: fromAbs(absDay(ref) - 7), pattern: "last week" };
229
+ if (s === "this week" || s === "start of this week") {
230
+ return {
231
+ date: fromAbs(absDay(ref) - dayOfWeekIndex(ref)),
232
+ pattern: "start of this week",
233
+ };
234
+ }
235
+ if (s === "end of this week") {
236
+ return {
237
+ date: fromAbs(absDay(ref) + (6 - dayOfWeekIndex(ref))),
238
+ pattern: "end of this week",
239
+ };
240
+ }
241
+ if (s === "next month")
242
+ return {
243
+ date: addMonths(ref, 1, "constrain"),
244
+ pattern: "next month",
245
+ };
246
+ if (s === "last month")
247
+ return {
248
+ date: addMonths(ref, -1, "constrain"),
249
+ pattern: "last month",
250
+ };
251
+ if (s === "this month" || s === "start of month")
252
+ return { date: startOfMonth(ref), pattern: "start of month" };
253
+ if (s === "end of month")
254
+ return { date: endOfMonth(ref), pattern: "end of month" };
255
+ if (s === "next year")
256
+ return {
257
+ date: addYears(ref, 1, "constrain"),
258
+ pattern: "next year",
259
+ };
260
+ if (s === "last year")
261
+ return {
262
+ date: addYears(ref, -1, "constrain"),
263
+ pattern: "last year",
264
+ };
265
+ if (s === "this year" || s === "start of year")
266
+ return { date: startOfYear(ref), pattern: "start of year" };
267
+ if (s === "end of year")
268
+ return { date: endOfYear(ref), pattern: "end of year" };
269
+ if (DOW_INDEX[s] !== undefined)
270
+ return {
271
+ date: nextWeekday(ref, DOW_INDEX[s]),
272
+ pattern: `next ${s}`,
273
+ };
274
+ const nextDay = /^next (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);
275
+ if (nextDay?.[1])
276
+ return {
277
+ date: nextWeekday(ref, DOW_INDEX[nextDay[1]]),
278
+ pattern: `next ${nextDay[1]}`,
279
+ };
280
+ const lastDay = /^last (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);
281
+ if (lastDay?.[1])
282
+ return {
283
+ date: lastWeekday(ref, DOW_INDEX[lastDay[1]]),
284
+ pattern: `last ${lastDay[1]}`,
285
+ };
286
+ const thisDay = /^this (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);
287
+ if (thisDay?.[1]) {
288
+ const t = DOW_INDEX[thisDay[1]];
289
+ const diff = (t - dayOfWeekIndex(ref) + 7) % 7;
290
+ return { date: fromAbs(absDay(ref) + diff), pattern: `this ${thisDay[1]}` };
291
+ }
292
+ const inFuture = /^in (\d+) (day|days|week|weeks|month|months|year|years)$/.exec(s);
293
+ if (inFuture?.[1] && inFuture[2]) {
294
+ const n = parseInt(inFuture[1], 10);
295
+ const u = inFuture[2].replace(/s$/, "");
296
+ if (u === "day")
297
+ return { date: addDays(ref, n), pattern: `in ${n} days` };
298
+ if (u === "week")
299
+ return {
300
+ date: addDays(ref, n * 7),
301
+ pattern: `in ${n} weeks`,
302
+ };
303
+ if (u === "month")
304
+ return {
305
+ date: addMonths(ref, n, "constrain"),
306
+ pattern: `in ${n} months`,
307
+ };
308
+ if (u === "year")
309
+ return {
310
+ date: addYears(ref, n, "constrain"),
311
+ pattern: `in ${n} years`,
312
+ };
313
+ }
314
+ const ago = /^(\d+) (day|days|week|weeks|month|months|year|years) ago$/.exec(s);
315
+ if (ago?.[1] && ago[2]) {
316
+ const n = parseInt(ago[1], 10);
317
+ const u = ago[2].replace(/s$/, "");
318
+ if (u === "day")
319
+ return { date: addDays(ref, -n), pattern: `${n} days ago` };
320
+ if (u === "week")
321
+ return {
322
+ date: addDays(ref, -n * 7),
323
+ pattern: `${n} weeks ago`,
324
+ };
325
+ if (u === "month")
326
+ return {
327
+ date: addMonths(ref, -n, "constrain"),
328
+ pattern: `${n} months ago`,
329
+ };
330
+ if (u === "year")
331
+ return {
332
+ date: addYears(ref, -n, "constrain"),
333
+ pattern: `${n} years ago`,
334
+ };
335
+ }
336
+ const fromNow = /^(\d+) (day|days|week|weeks|month|months|year|years) from now$/.exec(s);
337
+ if (fromNow?.[1] && fromNow[2]) {
338
+ const n = parseInt(fromNow[1], 10);
339
+ const u = fromNow[2].replace(/s$/, "");
340
+ if (u === "day")
341
+ return {
342
+ date: addDays(ref, n),
343
+ pattern: `${n} days from now`,
344
+ };
345
+ if (u === "week")
346
+ return {
347
+ date: addDays(ref, n * 7),
348
+ pattern: `${n} weeks from now`,
349
+ };
350
+ if (u === "month")
351
+ return {
352
+ date: addMonths(ref, n, "constrain"),
353
+ pattern: `${n} months from now`,
354
+ };
355
+ if (u === "year")
356
+ return {
357
+ date: addYears(ref, n, "constrain"),
358
+ pattern: `${n} years from now`,
359
+ };
360
+ }
361
+ const boundary = /^(start|end) of (next|last|this) (month|year)$/.exec(s);
362
+ if (boundary) {
363
+ const edge = boundary[1];
364
+ const rel = boundary[2];
365
+ const unit = boundary[3];
366
+ let base = ref;
367
+ if (unit === "month") {
368
+ if (rel === "next")
369
+ base = addMonths(ref, 1, "constrain");
370
+ else if (rel === "last")
371
+ base = addMonths(ref, -1, "constrain");
372
+ return {
373
+ date: (edge === "start"
374
+ ? startOfMonth(base)
375
+ : endOfMonth(base)),
376
+ pattern: `${edge} of ${rel} month`,
377
+ };
378
+ }
379
+ if (unit === "year") {
380
+ if (rel === "next")
381
+ base = addYears(ref, 1, "constrain");
382
+ else if (rel === "last")
383
+ base = addYears(ref, -1, "constrain");
384
+ return {
385
+ date: (edge === "start"
386
+ ? startOfYear(base)
387
+ : endOfYear(base)),
388
+ pattern: `${edge} of ${rel} year`,
389
+ };
390
+ }
391
+ }
392
+ const iso = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
393
+ if (iso?.[1] && iso[2] && iso[3]) {
394
+ return {
395
+ date: { kind: "local-date", year: +iso[1], month: +iso[2], day: +iso[3] },
396
+ pattern: "iso-date",
397
+ };
398
+ }
399
+ return null;
400
+ }
401
+ export function parseNaturalDate(input, options) {
402
+ const ref = options?.referenceDate ?? todayLocal(options?.timeZone);
403
+ const normalized = normalize(input, options?.locale ?? "en");
404
+ const result = matchPattern(normalized, ref);
405
+ if (!result) {
406
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Cannot parse natural language date: "${input}". ` +
407
+ `Supported: today, yesterday, tomorrow, next/last week/month/year, ` +
408
+ `in N days/weeks/months/years, N days ago, next/last <weekday>, YYYY-MM-DD.`);
409
+ }
410
+ return result.date;
411
+ }
412
+ export function safeParseNaturalDate(input, options) {
413
+ try {
414
+ return parseNaturalDate(input, options);
415
+ }
416
+ catch {
417
+ return null;
418
+ }
419
+ }
420
+ export function parseNaturalDateDebug(input, options) {
421
+ const ref = options?.referenceDate ?? todayLocal(options?.timeZone);
422
+ const normalized = normalize(input, options?.locale ?? "en");
423
+ const result = matchPattern(normalized, ref);
424
+ if (!result)
425
+ throw new ChroneraError("CHRONERA_INVALID_DATE", `Cannot parse: "${input}".`);
426
+ return result;
427
+ }
428
+ //# sourceMappingURL=natural-language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"natural-language.js","sourceRoot":"","sources":["../../src/operations/natural-language.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChroneraError } from \"../errors/errors.js\";\nimport { projectInstantToZonedFields } from \"../runtime/timezone.js\";\nimport {\n absoluteDayFromGregorianFields,\n gregorianFieldsFromAbsoluteDay,\n} from \"../core/absolute-day.js\";\nimport {\n addDays,\n addMonths,\n addYears,\n startOfMonth,\n endOfMonth,\n startOfYear,\n endOfYear,\n} from \"./convenience.js\";\n\nimport type { LocalDate, TimeZoneId } from \"../public-types.js\";\n\nexport interface ParseNaturalDateOptions {\n readonly locale?: string;\n readonly referenceDate?: LocalDate;\n readonly timeZone?: TimeZoneId;\n}\n\nexport interface ParseNaturalDateResult {\n readonly date: LocalDate;\n readonly pattern: string;\n}\n\nfunction todayLocal(tz?: TimeZoneId): LocalDate {\n const zone =\n tz ??\n (typeof Intl !== \"undefined\"\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : \"UTC\") ??\n \"UTC\";\n const instant = { kind: \"instant\" as const, epochMilliseconds: Date.now() };\n const z = projectInstantToZonedFields(instant, zone);\n return { kind: \"local-date\", year: z.year, month: z.month, day: z.day };\n}\n\nfunction absDay(d: LocalDate): number {\n return absoluteDayFromGregorianFields(d.year, d.month, d.day);\n}\n\nfunction fromAbs(n: number): LocalDate {\n const f = gregorianFieldsFromAbsoluteDay(n);\n return { kind: \"local-date\", year: f.year, month: f.month, day: f.day };\n}\n\n// absDay % 7 mapping (derived from absoluteDayFromGregorianFields):\n// Thursday=0, Friday=1, Saturday=2, Sunday=3, Monday=4, Tuesday=5, Wednesday=6\nconst DOW_INDEX: Record<string, number> = {\n monday: 4,\n tuesday: 5,\n wednesday: 6,\n thursday: 0,\n friday: 1,\n saturday: 2,\n sunday: 3,\n};\n\nfunction dayOfWeekIndex(d: LocalDate): number {\n return absDay(d) % 7;\n}\n\nfunction nextWeekday(ref: LocalDate, t: number): LocalDate {\n const diff = (t - dayOfWeekIndex(ref) + 7) % 7 || 7;\n return fromAbs(absDay(ref) + diff);\n}\n\nfunction lastWeekday(ref: LocalDate, t: number): LocalDate {\n const diff = (dayOfWeekIndex(ref) - t + 7) % 7 || 7;\n return fromAbs(absDay(ref) - diff);\n}\n\nconst LANG_TOKENS: Record<string, Record<string, string>> = {\n th: {\n วันนี้: \"today\",\n เมื่อวาน: \"yesterday\",\n เมื่อวานนี้: \"yesterday\",\n พรุ่งนี้: \"tomorrow\",\n มะรืน: \"day after tomorrow\",\n อาทิตย์หน้า: \"next week\",\n สัปดาห์หน้า: \"next week\",\n อาทิตย์ที่แล้ว: \"last week\",\n สัปดาห์ที่แล้ว: \"last week\",\n เดือนหน้า: \"next month\",\n เดือนที่แล้ว: \"last month\",\n ปีหน้า: \"next year\",\n ปีที่แล้ว: \"last year\",\n วันจันทร์: \"monday\",\n วันอังคาร: \"tuesday\",\n วันพุธ: \"wednesday\",\n วันพฤหัสบดี: \"thursday\",\n วันพฤหัส: \"thursday\",\n วันศุกร์: \"friday\",\n วันเสาร์: \"saturday\",\n วันอาทิตย์: \"sunday\",\n ต้นเดือน: \"start of month\",\n ปลายเดือน: \"end of month\",\n ต้นปี: \"start of year\",\n ปลายปี: \"end of year\",\n },\n ja: {\n 今日: \"today\",\n 本日: \"today\",\n 昨日: \"yesterday\",\n 明日: \"tomorrow\",\n 明後日: \"day after tomorrow\",\n 来週: \"next week\",\n 先週: \"last week\",\n 今週: \"this week\",\n 来月: \"next month\",\n 先月: \"last month\",\n 今月: \"this month\",\n 来年: \"next year\",\n 去年: \"last year\",\n 今年: \"this year\",\n 月曜日: \"monday\",\n 火曜日: \"tuesday\",\n 水曜日: \"wednesday\",\n 木曜日: \"thursday\",\n 金曜日: \"friday\",\n 土曜日: \"saturday\",\n 日曜日: \"sunday\",\n 月曜: \"monday\",\n 火曜: \"tuesday\",\n 水曜: \"wednesday\",\n 木曜: \"thursday\",\n 金曜: \"friday\",\n 土曜: \"saturday\",\n 日曜: \"sunday\",\n },\n zh: {\n 今天: \"today\",\n 今日: \"today\",\n 昨天: \"yesterday\",\n 昨日: \"yesterday\",\n 明天: \"tomorrow\",\n 明日: \"tomorrow\",\n 后天: \"day after tomorrow\",\n 後天: \"day after tomorrow\",\n 下周: \"next week\",\n 下週: \"next week\",\n 上周: \"last week\",\n 上週: \"last week\",\n 下个月: \"next month\",\n 下個月: \"next month\",\n 上个月: \"last month\",\n 上個月: \"last month\",\n 明年: \"next year\",\n 去年: \"last year\",\n 星期一: \"monday\",\n 星期二: \"tuesday\",\n 星期三: \"wednesday\",\n 星期四: \"thursday\",\n 星期五: \"friday\",\n 星期六: \"saturday\",\n 星期日: \"sunday\",\n 星期天: \"sunday\",\n 周一: \"monday\",\n 周二: \"tuesday\",\n 周三: \"wednesday\",\n 周四: \"thursday\",\n 周五: \"friday\",\n 周六: \"saturday\",\n 周日: \"sunday\",\n },\n ko: {\n 오늘: \"today\",\n 어제: \"yesterday\",\n 내일: \"tomorrow\",\n 모레: \"day after tomorrow\",\n 다음주: \"next week\",\n 지난주: \"last week\",\n 다음달: \"next month\",\n 지난달: \"last month\",\n 내년: \"next year\",\n 작년: \"last year\",\n 월요일: \"monday\",\n 화요일: \"tuesday\",\n 수요일: \"wednesday\",\n 목요일: \"thursday\",\n 금요일: \"friday\",\n 토요일: \"saturday\",\n 일요일: \"sunday\",\n },\n de: {\n heute: \"today\",\n gestern: \"yesterday\",\n morgen: \"tomorrow\",\n übermorgen: \"day after tomorrow\",\n \"nächste woche\": \"next week\",\n \"letzte woche\": \"last week\",\n \"nächsten monat\": \"next month\",\n \"letzten monat\": \"last month\",\n \"nächstes jahr\": \"next year\",\n \"letztes jahr\": \"last year\",\n montag: \"monday\",\n dienstag: \"tuesday\",\n mittwoch: \"wednesday\",\n donnerstag: \"thursday\",\n freitag: \"friday\",\n samstag: \"saturday\",\n sonntag: \"sunday\",\n \"nächsten montag\": \"next monday\",\n \"nächsten dienstag\": \"next tuesday\",\n \"nächsten mittwoch\": \"next wednesday\",\n \"nächsten donnerstag\": \"next thursday\",\n \"nächsten freitag\": \"next friday\",\n },\n fr: {\n \"aujourd'hui\": \"today\",\n hier: \"yesterday\",\n demain: \"tomorrow\",\n \"après-demain\": \"day after tomorrow\",\n \"la semaine prochaine\": \"next week\",\n \"la semaine dernière\": \"last week\",\n \"le mois prochain\": \"next month\",\n \"le mois dernier\": \"last month\",\n \"l'année prochaine\": \"next year\",\n \"l'année dernière\": \"last year\",\n lundi: \"monday\",\n mardi: \"tuesday\",\n mercredi: \"wednesday\",\n jeudi: \"thursday\",\n vendredi: \"friday\",\n samedi: \"saturday\",\n dimanche: \"sunday\",\n \"lundi prochain\": \"next monday\",\n \"mardi prochain\": \"next tuesday\",\n },\n};\n\nfunction normalize(input: string, locale: string): string {\n const lang = locale.split(\"-\")[0]?.toLowerCase() ?? \"en\";\n const map = LANG_TOKENS[lang] ?? {};\n let s = input.trim().toLowerCase();\n const keys = Object.keys(map).sort((a, b) => b.length - a.length);\n for (const k of keys) {\n const val = map[k];\n if (val !== undefined) s = s.replace(k.toLowerCase(), val);\n }\n return s.replace(/\\s+/g, \" \").trim();\n}\n\ntype MatchResult = { date: LocalDate; pattern: string } | null;\n\nfunction matchPattern(s: string, ref: LocalDate): MatchResult {\n if (s === \"today\") return { date: ref, pattern: \"today\" };\n if (s === \"yesterday\")\n return { date: fromAbs(absDay(ref) - 1), pattern: \"yesterday\" };\n if (s === \"tomorrow\")\n return { date: fromAbs(absDay(ref) + 1), pattern: \"tomorrow\" };\n if (s === \"day after tomorrow\")\n return { date: fromAbs(absDay(ref) + 2), pattern: \"day after tomorrow\" };\n if (s === \"day before yesterday\")\n return { date: fromAbs(absDay(ref) - 2), pattern: \"day before yesterday\" };\n\n if (s === \"next week\")\n return { date: fromAbs(absDay(ref) + 7), pattern: \"next week\" };\n if (s === \"last week\")\n return { date: fromAbs(absDay(ref) - 7), pattern: \"last week\" };\n if (s === \"this week\" || s === \"start of this week\") {\n return {\n date: fromAbs(absDay(ref) - dayOfWeekIndex(ref)),\n pattern: \"start of this week\",\n };\n }\n if (s === \"end of this week\") {\n return {\n date: fromAbs(absDay(ref) + (6 - dayOfWeekIndex(ref))),\n pattern: \"end of this week\",\n };\n }\n\n if (s === \"next month\")\n return {\n date: addMonths(ref, 1, \"constrain\") as LocalDate,\n pattern: \"next month\",\n };\n if (s === \"last month\")\n return {\n date: addMonths(ref, -1, \"constrain\") as LocalDate,\n pattern: \"last month\",\n };\n if (s === \"this month\" || s === \"start of month\")\n return { date: startOfMonth(ref) as LocalDate, pattern: \"start of month\" };\n if (s === \"end of month\")\n return { date: endOfMonth(ref) as LocalDate, pattern: \"end of month\" };\n\n if (s === \"next year\")\n return {\n date: addYears(ref, 1, \"constrain\") as LocalDate,\n pattern: \"next year\",\n };\n if (s === \"last year\")\n return {\n date: addYears(ref, -1, \"constrain\") as LocalDate,\n pattern: \"last year\",\n };\n if (s === \"this year\" || s === \"start of year\")\n return { date: startOfYear(ref) as LocalDate, pattern: \"start of year\" };\n if (s === \"end of year\")\n return { date: endOfYear(ref) as LocalDate, pattern: \"end of year\" };\n\n if (DOW_INDEX[s] !== undefined)\n return {\n date: nextWeekday(ref, DOW_INDEX[s] as number),\n pattern: `next ${s}`,\n };\n\n const nextDay =\n /^next (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);\n if (nextDay?.[1])\n return {\n date: nextWeekday(ref, DOW_INDEX[nextDay[1]] as number),\n pattern: `next ${nextDay[1]}`,\n };\n\n const lastDay =\n /^last (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);\n if (lastDay?.[1])\n return {\n date: lastWeekday(ref, DOW_INDEX[lastDay[1]] as number),\n pattern: `last ${lastDay[1]}`,\n };\n\n const thisDay =\n /^this (monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/.exec(s);\n if (thisDay?.[1]) {\n const t = DOW_INDEX[thisDay[1]] as number;\n const diff = (t - dayOfWeekIndex(ref) + 7) % 7;\n return { date: fromAbs(absDay(ref) + diff), pattern: `this ${thisDay[1]}` };\n }\n\n const inFuture =\n /^in (\\d+) (day|days|week|weeks|month|months|year|years)$/.exec(s);\n if (inFuture?.[1] && inFuture[2]) {\n const n = parseInt(inFuture[1], 10);\n const u = inFuture[2].replace(/s$/, \"\");\n if (u === \"day\")\n return { date: addDays(ref, n) as LocalDate, pattern: `in ${n} days` };\n if (u === \"week\")\n return {\n date: addDays(ref, n * 7) as LocalDate,\n pattern: `in ${n} weeks`,\n };\n if (u === \"month\")\n return {\n date: addMonths(ref, n, \"constrain\") as LocalDate,\n pattern: `in ${n} months`,\n };\n if (u === \"year\")\n return {\n date: addYears(ref, n, \"constrain\") as LocalDate,\n pattern: `in ${n} years`,\n };\n }\n\n const ago = /^(\\d+) (day|days|week|weeks|month|months|year|years) ago$/.exec(\n s,\n );\n if (ago?.[1] && ago[2]) {\n const n = parseInt(ago[1], 10);\n const u = ago[2].replace(/s$/, \"\");\n if (u === \"day\")\n return { date: addDays(ref, -n) as LocalDate, pattern: `${n} days ago` };\n if (u === \"week\")\n return {\n date: addDays(ref, -n * 7) as LocalDate,\n pattern: `${n} weeks ago`,\n };\n if (u === \"month\")\n return {\n date: addMonths(ref, -n, \"constrain\") as LocalDate,\n pattern: `${n} months ago`,\n };\n if (u === \"year\")\n return {\n date: addYears(ref, -n, \"constrain\") as LocalDate,\n pattern: `${n} years ago`,\n };\n }\n\n const fromNow =\n /^(\\d+) (day|days|week|weeks|month|months|year|years) from now$/.exec(s);\n if (fromNow?.[1] && fromNow[2]) {\n const n = parseInt(fromNow[1], 10);\n const u = fromNow[2].replace(/s$/, \"\");\n if (u === \"day\")\n return {\n date: addDays(ref, n) as LocalDate,\n pattern: `${n} days from now`,\n };\n if (u === \"week\")\n return {\n date: addDays(ref, n * 7) as LocalDate,\n pattern: `${n} weeks from now`,\n };\n if (u === \"month\")\n return {\n date: addMonths(ref, n, \"constrain\") as LocalDate,\n pattern: `${n} months from now`,\n };\n if (u === \"year\")\n return {\n date: addYears(ref, n, \"constrain\") as LocalDate,\n pattern: `${n} years from now`,\n };\n }\n\n const boundary = /^(start|end) of (next|last|this) (month|year)$/.exec(s);\n if (boundary) {\n const edge = boundary[1] as \"start\" | \"end\";\n const rel = boundary[2] as \"next\" | \"last\" | \"this\";\n const unit = boundary[3] as \"month\" | \"year\";\n let base = ref as LocalDate;\n if (unit === \"month\") {\n if (rel === \"next\") base = addMonths(ref, 1, \"constrain\") as LocalDate;\n else if (rel === \"last\")\n base = addMonths(ref, -1, \"constrain\") as LocalDate;\n return {\n date: (edge === \"start\"\n ? startOfMonth(base)\n : endOfMonth(base)) as LocalDate,\n pattern: `${edge} of ${rel} month`,\n };\n }\n if (unit === \"year\") {\n if (rel === \"next\") base = addYears(ref, 1, \"constrain\") as LocalDate;\n else if (rel === \"last\")\n base = addYears(ref, -1, \"constrain\") as LocalDate;\n return {\n date: (edge === \"start\"\n ? startOfYear(base)\n : endOfYear(base)) as LocalDate,\n pattern: `${edge} of ${rel} year`,\n };\n }\n }\n\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(s);\n if (iso?.[1] && iso[2] && iso[3]) {\n return {\n date: { kind: \"local-date\", year: +iso[1], month: +iso[2], day: +iso[3] },\n pattern: \"iso-date\",\n };\n }\n\n return null;\n}\n\nexport function parseNaturalDate(\n input: string,\n options?: ParseNaturalDateOptions,\n): LocalDate {\n const ref = options?.referenceDate ?? todayLocal(options?.timeZone);\n const normalized = normalize(input, options?.locale ?? \"en\");\n const result = matchPattern(normalized, ref);\n if (!result) {\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Cannot parse natural language date: \"${input}\". ` +\n `Supported: today, yesterday, tomorrow, next/last week/month/year, ` +\n `in N days/weeks/months/years, N days ago, next/last <weekday>, YYYY-MM-DD.`,\n );\n }\n return result.date;\n}\n\nexport function safeParseNaturalDate(\n input: string,\n options?: ParseNaturalDateOptions,\n): LocalDate | null {\n try {\n return parseNaturalDate(input, options);\n } catch {\n return null;\n }\n}\n\nexport function parseNaturalDateDebug(\n input: string,\n options?: ParseNaturalDateOptions,\n): ParseNaturalDateResult {\n const ref = options?.referenceDate ?? todayLocal(options?.timeZone);\n const normalized = normalize(input, options?.locale ?? \"en\");\n const result = matchPattern(normalized, ref);\n if (!result)\n throw new ChroneraError(\n \"CHRONERA_INVALID_DATE\",\n `Cannot parse: \"${input}\".`,\n );\n return result;\n}\n"]}
@@ -0,0 +1,48 @@
1
+ import type { DateOrCalendarDate } from "../public-types.js";
2
+ export type RecurrenceFrequency = "daily" | "weekly" | "monthly" | "yearly";
3
+ export type DayOfWeek = "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday" | "sunday";
4
+ export interface RecurrenceRule {
5
+ readonly frequency: RecurrenceFrequency;
6
+ readonly interval: number;
7
+ readonly daysOfWeek?: DayOfWeek[];
8
+ readonly until?: DateOrCalendarDate;
9
+ readonly count?: number;
10
+ }
11
+ export interface RecurrenceBuilder {
12
+ every(n: number): FrequencySelector;
13
+ }
14
+ export interface FrequencySelector {
15
+ days(): RecurrenceRuleBuilder;
16
+ weeks(): RecurrenceRuleBuilder;
17
+ months(): RecurrenceRuleBuilder;
18
+ years(): RecurrenceRuleBuilder;
19
+ }
20
+ export interface RecurrenceRuleBuilder {
21
+ on(days: DayOfWeek[]): RecurrenceRuleBuilder;
22
+ until(date: DateOrCalendarDate): RecurrenceRuleBuilder;
23
+ count(n: number): RecurrenceRuleBuilder;
24
+ next(n: number): DateOrCalendarDate[];
25
+ occurrences(): DateOrCalendarDate[];
26
+ build(): RecurrenceRule;
27
+ }
28
+ /**
29
+ * Computes all occurrences of a recurring schedule.
30
+ */
31
+ export declare function getOccurrences<T extends DateOrCalendarDate>(startDate: T, rule: RecurrenceRule, limit?: number): T[];
32
+ /**
33
+ * Returns true if the given date is an occurrence of the recurrence rule starting from startDate.
34
+ */
35
+ export declare function isOccurrence<T extends DateOrCalendarDate>(date: T, startDate: T, rule: RecurrenceRule): boolean;
36
+ /**
37
+ * Creates a fluent recurrence builder anchored to the given start date.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const dates = recur(localDate(2026, 1, 1))
42
+ * .every(1).weeks()
43
+ * .on(['monday', 'wednesday', 'friday'])
44
+ * .until(localDate(2026, 3, 31))
45
+ * .occurrences();
46
+ * ```
47
+ */
48
+ export declare function recur<T extends DateOrCalendarDate>(startDate: T): RecurrenceBuilder;