temporal-fmt 0.9.2 → 0.9.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 +480 -9
- package/dist/calendarUtils.cjs +259 -4
- package/dist/calendarUtils.cjs.map +1 -1
- package/dist/calendarUtils.js +33 -1
- package/dist/chunk-4N3WCGEY.js +183 -0
- package/dist/{chunk-4JWGUR4O.js.map → chunk-4N3WCGEY.js.map} +1 -1
- package/dist/chunk-5UTV5VP6.js +984 -0
- package/dist/chunk-5UTV5VP6.js.map +1 -0
- package/dist/chunk-ACKKWH5Z.js +578 -0
- package/dist/{chunk-2JHEV7ZF.js.map → chunk-ACKKWH5Z.js.map} +1 -1
- package/dist/chunk-EGUUO6LE.js +439 -0
- package/dist/chunk-EGUUO6LE.js.map +1 -0
- package/dist/chunk-FBPHNRVW.js +2939 -0
- package/dist/chunk-FBPHNRVW.js.map +1 -0
- package/dist/chunk-GPB4JHGI.js +65 -0
- package/dist/chunk-GPB4JHGI.js.map +1 -0
- package/dist/chunk-H7YQX25T.js +170 -0
- package/dist/{chunk-J2AQNXF2.js.map → chunk-H7YQX25T.js.map} +1 -1
- package/dist/chunk-HXY2GUUM.js +182 -0
- package/dist/{chunk-EHLRZULM.js.map → chunk-HXY2GUUM.js.map} +1 -1
- package/dist/chunk-L24NPTAJ.js +328 -0
- package/dist/chunk-L24NPTAJ.js.map +1 -0
- package/dist/chunk-M3GDTHMT.js +169 -0
- package/dist/chunk-M3GDTHMT.js.map +1 -0
- package/dist/chunk-MKPDLQKD.js +51 -0
- package/dist/chunk-MKPDLQKD.js.map +1 -0
- package/dist/chunk-TSLPIURC.js +242 -0
- package/dist/{chunk-VQXUMFB2.js.map → chunk-TSLPIURC.js.map} +1 -1
- package/dist/chunk-UOPAV3WX.js +75 -0
- package/dist/chunk-UOPAV3WX.js.map +1 -0
- package/dist/chunk-VNIUIQA4.js +398 -0
- package/dist/chunk-VNIUIQA4.js.map +1 -0
- package/dist/chunk-YEUASGDK.js +9 -0
- package/dist/chunk-YEUASGDK.js.map +1 -0
- package/dist/chunk-ZQZF5EXW.js +29 -0
- package/dist/chunk-ZQZF5EXW.js.map +1 -0
- package/dist/config.d.cts +4 -2
- package/dist/config.d.ts +4 -2
- package/dist/duration.cjs +638 -26
- package/dist/duration.cjs.map +1 -1
- package/dist/duration.js +28 -1
- package/dist/format.cjs +833 -35
- package/dist/format.cjs.map +1 -1
- package/dist/format.js +20 -1
- package/dist/index.cjs +7698 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -24
- package/dist/index.d.ts +108 -24
- package/dist/index.js +1536 -58
- package/dist/index.js.map +1 -1
- package/dist/interval.cjs +5480 -35
- package/dist/interval.cjs.map +1 -1
- package/dist/interval.js +46 -1
- package/dist/localeRegistry.cjs +375 -32
- package/dist/localeRegistry.cjs.map +1 -1
- package/dist/localeRegistry.js +11 -1
- package/dist/modApi.d.cts +131 -0
- package/dist/modApi.d.ts +131 -0
- package/dist/parse.cjs +1797 -70
- package/dist/parse.cjs.map +1 -1
- package/dist/parse.js +20 -1
- package/dist/pattern.d.cts +1 -0
- package/dist/pattern.d.ts +1 -0
- package/dist/recurrence.cjs +452 -20
- package/dist/recurrence.cjs.map +1 -1
- package/dist/recurrence.js +19 -1
- package/dist/relativeTime.cjs +268 -21
- package/dist/relativeTime.cjs.map +1 -1
- package/dist/relativeTime.js +14 -1
- package/dist/runtime.d.cts +201 -0
- package/dist/runtime.d.ts +201 -0
- package/dist/timezone.cjs +387 -20
- package/dist/timezone.cjs.map +1 -1
- package/dist/timezone.js +26 -1
- package/package.json +4 -6
- package/scripts/cli.mjs +27 -5
- package/dist/chunk-2JHEV7ZF.js +0 -7
- package/dist/chunk-3MZLTVP3.js +0 -2
- package/dist/chunk-3MZLTVP3.js.map +0 -1
- package/dist/chunk-4JWGUR4O.js +0 -11
- package/dist/chunk-5U5WJ465.js +0 -36
- package/dist/chunk-5U5WJ465.js.map +0 -1
- package/dist/chunk-C5YESWFT.js +0 -2
- package/dist/chunk-C5YESWFT.js.map +0 -1
- package/dist/chunk-C6ZZ62ET.js +0 -2
- package/dist/chunk-C6ZZ62ET.js.map +0 -1
- package/dist/chunk-EHLRZULM.js +0 -5
- package/dist/chunk-F4RGUDA3.js +0 -2
- package/dist/chunk-F4RGUDA3.js.map +0 -1
- package/dist/chunk-J2AQNXF2.js +0 -2
- package/dist/chunk-NBXF7V5B.js +0 -2
- package/dist/chunk-NBXF7V5B.js.map +0 -1
- package/dist/chunk-R52YOKI3.js +0 -7
- package/dist/chunk-R52YOKI3.js.map +0 -1
- package/dist/chunk-UJR6DHXY.js +0 -2
- package/dist/chunk-UJR6DHXY.js.map +0 -1
- package/dist/chunk-VQXUMFB2.js +0 -21
- package/dist/chunk-XH46JNPK.js +0 -2
- package/dist/chunk-XH46JNPK.js.map +0 -1
- package/dist/chunk-YB6YAG7E.js +0 -35
- package/dist/chunk-YB6YAG7E.js.map +0 -1
- package/dist/chunk-ZGMTY52O.js +0 -2
- package/dist/chunk-ZGMTY52O.js.map +0 -1
package/dist/relativeTime.cjs
CHANGED
|
@@ -1,25 +1,272 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/relativeTime.ts
|
|
21
|
+
var relativeTime_exports = {};
|
|
22
|
+
__export(relativeTime_exports, {
|
|
23
|
+
formatRelative: () => formatRelative,
|
|
24
|
+
formatRelativeToNow: () => formatRelativeToNow
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(relativeTime_exports);
|
|
27
|
+
|
|
28
|
+
// src/calendarUtils.ts
|
|
29
|
+
function asDateFieldView(value) {
|
|
30
|
+
if (typeof value !== "object" || value === null) {
|
|
31
|
+
throw new Error(`temporal-fmt: expected a date-carrying Temporal value, got ${String(value)}.`);
|
|
32
|
+
}
|
|
33
|
+
const v = value;
|
|
34
|
+
const out = {};
|
|
35
|
+
if (typeof v.year === "number") out.year = v.year;
|
|
36
|
+
if (typeof v.month === "number") out.month = v.month;
|
|
37
|
+
if (typeof v.day === "number") out.day = v.day;
|
|
38
|
+
if (typeof v.hour === "number") out.hour = v.hour;
|
|
39
|
+
if (typeof v.minute === "number") out.minute = v.minute;
|
|
40
|
+
if (typeof v.second === "number") out.second = v.second;
|
|
41
|
+
if (typeof v.millisecond === "number") out.millisecond = v.millisecond;
|
|
42
|
+
if (typeof v.dayOfWeek === "number") out.dayOfWeek = v.dayOfWeek;
|
|
43
|
+
if (typeof v.calendarId === "string") out.calendarId = v.calendarId;
|
|
44
|
+
if (out.year === void 0 || out.month === void 0 || out.day === void 0) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`temporal-fmt: value is missing year/month/day fields \u2014 pass a Temporal.PlainDate / PlainDateTime / ZonedDateTime.`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/arithmetic.ts
|
|
53
|
+
function asDateTime(value) {
|
|
54
|
+
return asDateFieldView(value);
|
|
55
|
+
}
|
|
56
|
+
function difference(a, b, unit) {
|
|
57
|
+
const av = asDateTime(a);
|
|
58
|
+
const bv = asDateTime(b);
|
|
59
|
+
if (unit === "years") {
|
|
60
|
+
return bv.year - av.year;
|
|
61
|
+
}
|
|
62
|
+
if (unit === "months") {
|
|
63
|
+
return bv.year * 12 + bv.month - 1 - (av.year * 12 + av.month - 1);
|
|
64
|
+
}
|
|
65
|
+
if (unit === "weeks" || unit === "days") {
|
|
66
|
+
const aDays = toDayCount(av);
|
|
67
|
+
const bDays = toDayCount(bv);
|
|
68
|
+
const days = bDays - aDays;
|
|
69
|
+
return unit === "weeks" ? Math.trunc(days / 7) : days;
|
|
70
|
+
}
|
|
71
|
+
const MS_PER_HOUR = 36e5;
|
|
72
|
+
const MS_PER_MINUTE = 6e4;
|
|
73
|
+
const MS_PER_SECOND = 1e3;
|
|
74
|
+
const aMs = toTotalMs(av);
|
|
75
|
+
const bMs = toTotalMs(bv);
|
|
76
|
+
const diffMs = bMs - aMs;
|
|
77
|
+
switch (unit) {
|
|
78
|
+
case "hours":
|
|
79
|
+
return Math.trunc(diffMs / MS_PER_HOUR);
|
|
80
|
+
case "minutes":
|
|
81
|
+
return Math.trunc(diffMs / MS_PER_MINUTE);
|
|
82
|
+
case "seconds":
|
|
83
|
+
return Math.trunc(diffMs / MS_PER_SECOND);
|
|
84
|
+
case "milliseconds":
|
|
85
|
+
return diffMs;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function toDayCount(v) {
|
|
89
|
+
const y = v.year, m = v.month, d = v.day;
|
|
90
|
+
const y2 = m <= 2 ? y - 1 : y;
|
|
91
|
+
const era = Math.floor((y2 >= 0 ? y2 : y2 - 399) / 400);
|
|
92
|
+
const yoe = y2 - era * 400;
|
|
93
|
+
const m2 = m > 2 ? m - 3 : m + 9;
|
|
94
|
+
const doy = Math.floor((153 * m2 + 2) / 5) + d - 1;
|
|
95
|
+
const doe = yoe * 365 + Math.floor(yoe / 4) - Math.floor(yoe / 100) + doy;
|
|
96
|
+
return era * 146097 + doe - 719468;
|
|
97
|
+
}
|
|
98
|
+
function toTotalMs(v) {
|
|
99
|
+
const MS_PER_DAY = 864e5;
|
|
100
|
+
const MS_PER_HOUR = 36e5;
|
|
101
|
+
const MS_PER_MINUTE = 6e4;
|
|
102
|
+
const MS_PER_SECOND = 1e3;
|
|
103
|
+
return toDayCount(v) * MS_PER_DAY + (v.hour ?? 0) * MS_PER_HOUR + (v.minute ?? 0) * MS_PER_MINUTE + (v.second ?? 0) * MS_PER_SECOND + (v.millisecond ?? 0);
|
|
104
|
+
}
|
|
105
|
+
var differenceInDays = (a, b) => difference(a, b, "days");
|
|
106
|
+
|
|
107
|
+
// src/temporalProvider.ts
|
|
108
|
+
var onTemporalChanged = [];
|
|
109
|
+
function subscribeToTemporalChanges(listener) {
|
|
110
|
+
onTemporalChanged.push(listener);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/errors.ts
|
|
114
|
+
var TemporalFmtError = class extends Error {
|
|
115
|
+
code;
|
|
116
|
+
input;
|
|
117
|
+
format;
|
|
118
|
+
token;
|
|
119
|
+
position;
|
|
120
|
+
expected;
|
|
121
|
+
actual;
|
|
122
|
+
reason;
|
|
123
|
+
constructor(message, fields) {
|
|
124
|
+
super(message);
|
|
125
|
+
this.name = "TemporalFmtError";
|
|
126
|
+
this.code = fields.code;
|
|
127
|
+
this.input = fields.input;
|
|
128
|
+
this.format = fields.format;
|
|
129
|
+
this.token = fields.token;
|
|
130
|
+
this.position = fields.position;
|
|
131
|
+
this.expected = fields.expected;
|
|
132
|
+
this.actual = fields.actual;
|
|
133
|
+
this.reason = fields.reason;
|
|
134
|
+
const capture = Error.captureStackTrace;
|
|
135
|
+
if (typeof capture === "function") {
|
|
136
|
+
capture(this, this.constructor);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// lets callers just call err.toJSON() for logging. plain Error doesn't
|
|
140
|
+
// serialize its non-enumerable fields on its own, so this picks them
|
|
141
|
+
// up explicitly
|
|
142
|
+
toJSON() {
|
|
143
|
+
return {
|
|
144
|
+
name: this.name,
|
|
145
|
+
message: this.message,
|
|
146
|
+
code: this.code,
|
|
147
|
+
input: this.input,
|
|
148
|
+
format: this.format,
|
|
149
|
+
token: this.token,
|
|
150
|
+
position: this.position,
|
|
151
|
+
expected: this.expected,
|
|
152
|
+
actual: this.actual,
|
|
153
|
+
reason: this.reason
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
/* c8 ignore start @preserve -- InvalidTimeError is part of the public
|
|
158
|
+
error-class surface (exported from index.ts, code 'INVALID_TIME') but
|
|
159
|
+
nothing in this package actually constructs one. went and checked
|
|
160
|
+
whether it could get wired in the same way InvalidTimeZoneError just
|
|
161
|
+
was (see parse.ts's zzz-validation loop) — does hour/minute/second have
|
|
162
|
+
a post-match semantic range check the way zone ids do? nope.
|
|
7
163
|
pattern.ts's regex fragments for HH/H/hh/h/mm/m/ss/s already enforce
|
|
8
|
-
their valid ranges at the regex level (e.g. HH is
|
|
9
|
-
which can't match "99"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
redundant check purely to give this class a body.
|
|
13
|
-
until the library actually
|
|
164
|
+
their valid ranges right at the regex level (e.g. HH is
|
|
165
|
+
'(?:[01]\d|2[0-3])', which literally can't match "99"), so an
|
|
166
|
+
out-of-range time just gets rejected as a plain shape mismatch before
|
|
167
|
+
any semantic check would even run. no live gap to hook this into
|
|
168
|
+
without inventing a redundant check purely to give this class a body.
|
|
169
|
+
leaving it unconstructed until the library actually hits a real
|
|
170
|
+
invalid-time case worth reporting */
|
|
171
|
+
/* c8 ignore stop @preserve */
|
|
172
|
+
/* c8 ignore start @preserve -- InvalidCalendarError is part of the
|
|
14
173
|
public error-class surface (exported from index.ts, code
|
|
15
|
-
'INVALID_CALENDAR') but
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
174
|
+
'INVALID_CALENDAR') but same story as InvalidTimeError above — nothing
|
|
175
|
+
in this package constructs one. checked for a wiring opportunity the
|
|
176
|
+
same way: there's no user-supplied calendar identifier anywhere in the
|
|
177
|
+
library that we'd validate against a supported list. resolveCalendar()
|
|
19
178
|
in parse.ts derives the calendar entirely from Intl's own resolution
|
|
20
|
-
of the locale string — it's never handed an arbitrary "calendar"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
parameter that could be invalid
|
|
24
|
-
|
|
179
|
+
of the locale string — it's never handed an arbitrary "calendar" value
|
|
180
|
+
a caller could actually get wrong. no live input to reject here.
|
|
181
|
+
leaving it unconstructed until the library accepts an actual calendar
|
|
182
|
+
parameter that could be invalid */
|
|
183
|
+
/* c8 ignore stop @preserve */
|
|
184
|
+
var InvalidLocaleError = class extends TemporalFmtError {
|
|
185
|
+
constructor(fields) {
|
|
186
|
+
const { message, ...rest } = fields;
|
|
187
|
+
super(
|
|
188
|
+
message ?? `locale "${fields.actual ?? ""}" is not a valid BCP-47 tag${fields.reason ? `: ${fields.reason}` : ""}.`,
|
|
189
|
+
{ code: "INVALID_LOCALE", ...rest }
|
|
190
|
+
);
|
|
191
|
+
this.name = "InvalidLocaleError";
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
/* c8 ignore start @preserve -- unreachable from the current test suite,
|
|
195
|
+
see rationale above */
|
|
196
|
+
/* c8 ignore stop @preserve */
|
|
197
|
+
|
|
198
|
+
// src/localeVocab.ts
|
|
199
|
+
function normalizeLocaleTag(locale) {
|
|
200
|
+
return locale.replace(/_/g, "-");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/tokens.ts
|
|
204
|
+
function pad(n, len) {
|
|
205
|
+
const negative = n < 0;
|
|
206
|
+
const digits = String(Math.abs(n)).padStart(len, "0");
|
|
207
|
+
return negative ? "-" + digits : digits;
|
|
208
|
+
}
|
|
209
|
+
pad.fraction = function formatFraction(t, width) {
|
|
210
|
+
const nanoOfSecond = t.millisecond * 1e6 + (t.microsecond ?? 0) * 1e3 + (t.nanosecond ?? 0);
|
|
211
|
+
return pad(nanoOfSecond, 9).slice(0, width);
|
|
212
|
+
};
|
|
213
|
+
var DEFAULT_LOCALE = "en-US";
|
|
214
|
+
var nativeSupport;
|
|
215
|
+
subscribeToTemporalChanges(() => {
|
|
216
|
+
nativeSupport = void 0;
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// src/relativeTime.ts
|
|
220
|
+
var rtfCache = /* @__PURE__ */ new Map();
|
|
221
|
+
var MAX_RTF_CACHE_SIZE = 100;
|
|
222
|
+
function getRtf(locale, numeric) {
|
|
223
|
+
const key = `${locale}|${numeric}`;
|
|
224
|
+
let rtf = rtfCache.get(key);
|
|
225
|
+
if (rtf) return rtf;
|
|
226
|
+
if (rtfCache.size >= MAX_RTF_CACHE_SIZE) {
|
|
227
|
+
const oldestKey = rtfCache.keys().next().value;
|
|
228
|
+
if (oldestKey !== void 0) rtfCache.delete(oldestKey);
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
rtf = new Intl.RelativeTimeFormat(normalizeLocaleTag(locale), { numeric });
|
|
232
|
+
} catch (err) {
|
|
233
|
+
throw new InvalidLocaleError({ actual: locale, reason: err.message });
|
|
234
|
+
}
|
|
235
|
+
rtfCache.set(key, rtf);
|
|
236
|
+
return rtf;
|
|
237
|
+
}
|
|
238
|
+
function formatRelative(date1, date2, options = {}) {
|
|
239
|
+
const locale = options.locale ?? DEFAULT_LOCALE;
|
|
240
|
+
const numeric = options.numeric ?? "auto";
|
|
241
|
+
const rtf = getRtf(locale, numeric);
|
|
242
|
+
const dayDiff = -differenceInDays(date1, date2);
|
|
243
|
+
const absDays = Math.abs(dayDiff);
|
|
244
|
+
if (absDays === 0) {
|
|
245
|
+
return rtf.format(0, "day");
|
|
246
|
+
}
|
|
247
|
+
if (absDays < 7) {
|
|
248
|
+
return rtf.format(dayDiff, "day");
|
|
249
|
+
}
|
|
250
|
+
if (absDays < 30) {
|
|
251
|
+
return rtf.format(-Math.trunc(-dayDiff / 7), "week");
|
|
252
|
+
}
|
|
253
|
+
if (absDays < 365) {
|
|
254
|
+
return rtf.format(-Math.trunc(-dayDiff / 30), "month");
|
|
255
|
+
}
|
|
256
|
+
return rtf.format(-Math.trunc(-dayDiff / 365), "year");
|
|
257
|
+
}
|
|
258
|
+
function formatRelativeToNow(date, options = {}) {
|
|
259
|
+
const now = /* @__PURE__ */ new Date();
|
|
260
|
+
const nowFields = {
|
|
261
|
+
year: now.getFullYear(),
|
|
262
|
+
month: now.getMonth() + 1,
|
|
263
|
+
day: now.getDate()
|
|
264
|
+
};
|
|
265
|
+
return formatRelative(date, nowFields, options);
|
|
266
|
+
}
|
|
267
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
268
|
+
0 && (module.exports = {
|
|
269
|
+
formatRelative,
|
|
270
|
+
formatRelativeToNow
|
|
271
|
+
});
|
|
25
272
|
//# sourceMappingURL=relativeTime.cjs.map
|