@vielzeug/tempo 1.0.4 → 1.0.6
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/dist/_tz.cjs +1 -1
- package/dist/_tz.cjs.map +1 -1
- package/dist/_tz.js +1 -1
- package/dist/_tz.js.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/format.cjs +1 -1
- package/dist/format.cjs.map +1 -1
- package/dist/format.js +2 -1
- package/dist/format.js.map +1 -1
- package/dist/tempo.cjs +1 -1
- package/dist/tempo.cjs.map +1 -1
- package/dist/tempo.iife.js +1 -1
- package/dist/tempo.iife.js.map +1 -1
- package/dist/tempo.js +1 -1
- package/dist/tempo.js.map +1 -1
- package/package.json +3 -4
package/dist/_tz.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./errors.cjs");let t=require("@js-temporal/polyfill");function n(n){try{t.Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(n)}catch{e.fail(`Unknown or invalid timezone: "${n}". Expected an IANA timezone name (e.g. "America/New_York") or UTC offset (e.g. "+05:30").`,e.TempoInvalidTzError)}return n}function r(r,i){let a=i.tz??(r instanceof t.Temporal.ZonedDateTime?r.timeZoneId:void 0);return a||e.fail(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,e.TempoMissingTzError),n(a)}function i(r,i){if(i.tz)return n(i.tz);let a;for(let n of r){if(!(n instanceof t.Temporal.ZonedDateTime))continue;let r=n.timeZoneId;if(!a){a=r;continue}a!==r&&e.fail(`Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`)}return a||e.fail(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,e.TempoMissingTzError),a}function a(e,n){return t.Temporal.Instant.compare(e,n)<=0?[e,n]:[n,e]}var o=new Set([`day`,`month`,`week`,`year`]),s=
|
|
1
|
+
const e=require("./errors.cjs");let t=require("@js-temporal/polyfill");function n(n){try{t.Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(n)}catch{e.fail(`Unknown or invalid timezone: "${n}". Expected an IANA timezone name (e.g. "America/New_York") or UTC offset (e.g. "+05:30").`,e.TempoInvalidTzError)}return n}function r(r,i){let a=i.tz??(r instanceof t.Temporal.ZonedDateTime?r.timeZoneId:void 0);return a||e.fail(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,e.TempoMissingTzError),n(a)}function i(r,i){if(i.tz)return n(i.tz);let a;for(let n of r){if(!(n instanceof t.Temporal.ZonedDateTime))continue;let r=n.timeZoneId;if(!a){a=r;continue}a!==r&&e.fail(`Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`)}return a||e.fail(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,e.TempoMissingTzError),a}function a(e,n){return t.Temporal.Instant.compare(e,n)<=0?[e,n]:[n,e]}var o=new Set([`day`,`month`,`week`,`year`]),s=26298e5;exports.CALENDAR_UNITS=o,exports.MS_PER_MONTH=s,exports.inferSharedTimeZone=i,exports.inferTimeZone=r,exports.normalizeRange=a,exports.validateTz=n;
|
|
2
2
|
//# sourceMappingURL=_tz.cjs.map
|
package/dist/_tz.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_tz.cjs","names":[],"sources":["../src/_tz.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type { CalendarUnit, TimeInput } from './types';\n\nimport { TempoInvalidTzError, TempoMissingTzError, fail } from './errors';\n\n// ─── Timezone validation ──────────────────────────────────────────────────────\n\nexport function validateTz(tz: string): string {\n try {\n Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(tz);\n } catch {\n fail(\n `Unknown or invalid timezone: \"${tz}\". Expected an IANA timezone name (e.g. \"America/New_York\") or UTC offset (e.g. \"+05:30\").`,\n TempoInvalidTzError,\n );\n }\n\n return tz;\n}\n\n// ─── Timezone inference ───────────────────────────────────────────────────────\n\nexport function inferTimeZone(input: TimeInput, options: { tz?: string }): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n if (!tz)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return validateTz(tz);\n}\n\nexport function inferSharedTimeZone(inputs: TimeInput[], options: { tz?: string }): string {\n if (options.tz) return validateTz(options.tz);\n\n let inferred: string | undefined;\n\n for (const input of inputs) {\n if (!(input instanceof Temporal.ZonedDateTime)) continue;\n\n const tz = input.timeZoneId;\n\n if (!inferred) {\n inferred = tz;\n continue;\n }\n\n if (inferred !== tz) {\n fail('Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.');\n }\n }\n\n if (!inferred)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return inferred;\n}\n\n// ─── Range normalization ──────────────────────────────────────────────────────\n\nexport function normalizeRange(start: Temporal.Instant, end: Temporal.Instant): [Temporal.Instant, Temporal.Instant] {\n return Temporal.Instant.compare(start, end) <= 0 ? [start, end] : [end, start];\n}\n\n// ─── Shared constants ─────────────────────────────────────────────────────────\n\n/** Units that require timezone-aware context for calendar-accurate operations. */\nexport const CALENDAR_UNITS = new Set<CalendarUnit>(['day', 'month', 'week', 'year']);\n\n/** Approximate millisecond constants for threshold arithmetic. */\nexport const MS_PER_MONTH = 30.4375 * 86_400_000; // 365.25 / 12 days × 86400 s × 1000\n"],"mappings":"uEAQA,SAAgB,EAAW,EAAoB,CAC7C,GAAI,CACF,EAAA,SAAS,QAAQ,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAE,CACjE,MAAQ,CACN,EAAA,KACE,iCAAiC,EAAG,4FACpC,EAAA,mBACF,CACF,CAEA,OAAO,CACT,CAIA,SAAgB,EAAc,EAAkB,EAAkC,CAChF,IAAM,EAAK,EAAQ,KAAO,aAAiB,EAAA,SAAS,cAAgB,EAAM,WAAa,IAAA,IAKvF,OAHK,GACH,EAAA,KAAK,oFAAqF,EAAA,mBAAmB,EAExG,EAAW,CAAE,CACtB,CAEA,SAAgB,EAAoB,EAAqB,EAAkC,CACzF,GAAI,EAAQ,GAAI,OAAO,EAAW,EAAQ,EAAE,EAE5C,IAAI,EAEJ,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAI,EAAE,aAAiB,EAAA,SAAS,eAAgB,SAEhD,IAAM,EAAK,EAAM,WAEjB,GAAI,CAAC,EAAU,CACb,EAAW,EACX,QACF,CAEI,IAAa,GACf,EAAA,KAAK,iGAAiG,CAE1G,CAKA,OAHK,GACH,EAAA,KAAK,oFAAqF,EAAA,mBAAmB,EAExG,CACT,CAIA,SAAgB,EAAe,EAAyB,EAA6D,CACnH,OAAO,EAAA,SAAS,QAAQ,QAAQ,EAAO,CAAG,GAAK,EAAI,CAAC,EAAO,CAAG,EAAI,CAAC,EAAK,CAAK,CAC/E,CAKA,IAAa,EAAiB,IAAI,IAAkB,CAAC,MAAO,QAAS,OAAQ,MAAM,CAAC,EAGvE,EAAe
|
|
1
|
+
{"version":3,"file":"_tz.cjs","names":[],"sources":["../src/_tz.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type { CalendarUnit, TimeInput } from './types';\n\nimport { TempoInvalidTzError, TempoMissingTzError, fail } from './errors';\n\n// ─── Timezone validation ──────────────────────────────────────────────────────\n\nexport function validateTz(tz: string): string {\n try {\n Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(tz);\n } catch {\n fail(\n `Unknown or invalid timezone: \"${tz}\". Expected an IANA timezone name (e.g. \"America/New_York\") or UTC offset (e.g. \"+05:30\").`,\n TempoInvalidTzError,\n );\n }\n\n return tz;\n}\n\n// ─── Timezone inference ───────────────────────────────────────────────────────\n\nexport function inferTimeZone(input: TimeInput, options: { tz?: string }): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n if (!tz)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return validateTz(tz);\n}\n\nexport function inferSharedTimeZone(inputs: TimeInput[], options: { tz?: string }): string {\n if (options.tz) return validateTz(options.tz);\n\n let inferred: string | undefined;\n\n for (const input of inputs) {\n if (!(input instanceof Temporal.ZonedDateTime)) continue;\n\n const tz = input.timeZoneId;\n\n if (!inferred) {\n inferred = tz;\n continue;\n }\n\n if (inferred !== tz) {\n fail('Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.');\n }\n }\n\n if (!inferred)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return inferred;\n}\n\n// ─── Range normalization ──────────────────────────────────────────────────────\n\nexport function normalizeRange(start: Temporal.Instant, end: Temporal.Instant): [Temporal.Instant, Temporal.Instant] {\n return Temporal.Instant.compare(start, end) <= 0 ? [start, end] : [end, start];\n}\n\n// ─── Shared constants ─────────────────────────────────────────────────────────\n\n/** Units that require timezone-aware context for calendar-accurate operations. */\nexport const CALENDAR_UNITS = new Set<CalendarUnit>(['day', 'month', 'week', 'year']);\n\n/** Approximate millisecond constants for threshold arithmetic. */\nexport const MS_PER_MONTH = 30.4375 * 86_400_000; // 365.25 / 12 days × 86400 s × 1000\n"],"mappings":"uEAQA,SAAgB,EAAW,EAAoB,CAC7C,GAAI,CACF,EAAA,SAAS,QAAQ,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAE,CACjE,MAAQ,CACN,EAAA,KACE,iCAAiC,EAAG,4FACpC,EAAA,mBACF,CACF,CAEA,OAAO,CACT,CAIA,SAAgB,EAAc,EAAkB,EAAkC,CAChF,IAAM,EAAK,EAAQ,KAAO,aAAiB,EAAA,SAAS,cAAgB,EAAM,WAAa,IAAA,IAKvF,OAHK,GACH,EAAA,KAAK,oFAAqF,EAAA,mBAAmB,EAExG,EAAW,CAAE,CACtB,CAEA,SAAgB,EAAoB,EAAqB,EAAkC,CACzF,GAAI,EAAQ,GAAI,OAAO,EAAW,EAAQ,EAAE,EAE5C,IAAI,EAEJ,IAAK,IAAM,KAAS,EAAQ,CAC1B,GAAI,EAAE,aAAiB,EAAA,SAAS,eAAgB,SAEhD,IAAM,EAAK,EAAM,WAEjB,GAAI,CAAC,EAAU,CACb,EAAW,EACX,QACF,CAEI,IAAa,GACf,EAAA,KAAK,iGAAiG,CAE1G,CAKA,OAHK,GACH,EAAA,KAAK,oFAAqF,EAAA,mBAAmB,EAExG,CACT,CAIA,SAAgB,EAAe,EAAyB,EAA6D,CACnH,OAAO,EAAA,SAAS,QAAQ,QAAQ,EAAO,CAAG,GAAK,EAAI,CAAC,EAAO,CAAG,EAAI,CAAC,EAAK,CAAK,CAC/E,CAKA,IAAa,EAAiB,IAAI,IAAkB,CAAC,MAAO,QAAS,OAAQ,MAAM,CAAC,EAGvE,EAAe"}
|
package/dist/_tz.js
CHANGED
|
@@ -35,7 +35,7 @@ var c = /* @__PURE__ */ new Set([
|
|
|
35
35
|
"month",
|
|
36
36
|
"week",
|
|
37
37
|
"year"
|
|
38
|
-
]), l =
|
|
38
|
+
]), l = 26298e5;
|
|
39
39
|
//#endregion
|
|
40
40
|
export { c as CALENDAR_UNITS, l as MS_PER_MONTH, o as inferSharedTimeZone, a as inferTimeZone, s as normalizeRange, i as validateTz };
|
|
41
41
|
|
package/dist/_tz.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_tz.js","names":[],"sources":["../src/_tz.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type { CalendarUnit, TimeInput } from './types';\n\nimport { TempoInvalidTzError, TempoMissingTzError, fail } from './errors';\n\n// ─── Timezone validation ──────────────────────────────────────────────────────\n\nexport function validateTz(tz: string): string {\n try {\n Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(tz);\n } catch {\n fail(\n `Unknown or invalid timezone: \"${tz}\". Expected an IANA timezone name (e.g. \"America/New_York\") or UTC offset (e.g. \"+05:30\").`,\n TempoInvalidTzError,\n );\n }\n\n return tz;\n}\n\n// ─── Timezone inference ───────────────────────────────────────────────────────\n\nexport function inferTimeZone(input: TimeInput, options: { tz?: string }): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n if (!tz)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return validateTz(tz);\n}\n\nexport function inferSharedTimeZone(inputs: TimeInput[], options: { tz?: string }): string {\n if (options.tz) return validateTz(options.tz);\n\n let inferred: string | undefined;\n\n for (const input of inputs) {\n if (!(input instanceof Temporal.ZonedDateTime)) continue;\n\n const tz = input.timeZoneId;\n\n if (!inferred) {\n inferred = tz;\n continue;\n }\n\n if (inferred !== tz) {\n fail('Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.');\n }\n }\n\n if (!inferred)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return inferred;\n}\n\n// ─── Range normalization ──────────────────────────────────────────────────────\n\nexport function normalizeRange(start: Temporal.Instant, end: Temporal.Instant): [Temporal.Instant, Temporal.Instant] {\n return Temporal.Instant.compare(start, end) <= 0 ? [start, end] : [end, start];\n}\n\n// ─── Shared constants ─────────────────────────────────────────────────────────\n\n/** Units that require timezone-aware context for calendar-accurate operations. */\nexport const CALENDAR_UNITS = new Set<CalendarUnit>(['day', 'month', 'week', 'year']);\n\n/** Approximate millisecond constants for threshold arithmetic. */\nexport const MS_PER_MONTH = 30.4375 * 86_400_000; // 365.25 / 12 days × 86400 s × 1000\n"],"mappings":";;;AAQA,SAAgB,EAAW,GAAoB;CAC7C,IAAI;EACF,EAAS,QAAQ,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAE;CACjE,QAAQ;EACN,EACE,iCAAiC,EAAG,6FACpC,CACF;CACF;CAEA,OAAO;AACT;AAIA,SAAgB,EAAc,GAAkB,GAAkC;CAChF,IAAM,IAAK,EAAQ,OAAO,aAAiB,EAAS,gBAAgB,EAAM,aAAa,KAAA;CAKvF,OAHK,KACH,EAAK,qFAAqF,CAAmB,GAExG,EAAW,CAAE;AACtB;AAEA,SAAgB,EAAoB,GAAqB,GAAkC;CACzF,IAAI,EAAQ,IAAI,OAAO,EAAW,EAAQ,EAAE;CAE5C,IAAI;CAEJ,KAAK,IAAM,KAAS,GAAQ;EAC1B,IAAI,EAAE,aAAiB,EAAS,gBAAgB;EAEhD,IAAM,IAAK,EAAM;EAEjB,IAAI,CAAC,GAAU;GACb,IAAW;GACX;EACF;EAEA,AAAI,MAAa,KACf,EAAK,iGAAiG;CAE1G;CAKA,OAHK,KACH,EAAK,qFAAqF,CAAmB,GAExG;AACT;AAIA,SAAgB,EAAe,GAAyB,GAA6D;CACnH,OAAO,EAAS,QAAQ,QAAQ,GAAO,CAAG,KAAK,IAAI,CAAC,GAAO,CAAG,IAAI,CAAC,GAAK,CAAK;AAC/E;AAKA,IAAa,oBAAiB,IAAI,IAAkB;CAAC;CAAO;CAAS;CAAQ;AAAM,CAAC,GAGvE,IAAe
|
|
1
|
+
{"version":3,"file":"_tz.js","names":[],"sources":["../src/_tz.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type { CalendarUnit, TimeInput } from './types';\n\nimport { TempoInvalidTzError, TempoMissingTzError, fail } from './errors';\n\n// ─── Timezone validation ──────────────────────────────────────────────────────\n\nexport function validateTz(tz: string): string {\n try {\n Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(tz);\n } catch {\n fail(\n `Unknown or invalid timezone: \"${tz}\". Expected an IANA timezone name (e.g. \"America/New_York\") or UTC offset (e.g. \"+05:30\").`,\n TempoInvalidTzError,\n );\n }\n\n return tz;\n}\n\n// ─── Timezone inference ───────────────────────────────────────────────────────\n\nexport function inferTimeZone(input: TimeInput, options: { tz?: string }): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n if (!tz)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return validateTz(tz);\n}\n\nexport function inferSharedTimeZone(inputs: TimeInput[], options: { tz?: string }): string {\n if (options.tz) return validateTz(options.tz);\n\n let inferred: string | undefined;\n\n for (const input of inputs) {\n if (!(input instanceof Temporal.ZonedDateTime)) continue;\n\n const tz = input.timeZoneId;\n\n if (!inferred) {\n inferred = tz;\n continue;\n }\n\n if (inferred !== tz) {\n fail('Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.');\n }\n }\n\n if (!inferred)\n fail('This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.', TempoMissingTzError);\n\n return inferred;\n}\n\n// ─── Range normalization ──────────────────────────────────────────────────────\n\nexport function normalizeRange(start: Temporal.Instant, end: Temporal.Instant): [Temporal.Instant, Temporal.Instant] {\n return Temporal.Instant.compare(start, end) <= 0 ? [start, end] : [end, start];\n}\n\n// ─── Shared constants ─────────────────────────────────────────────────────────\n\n/** Units that require timezone-aware context for calendar-accurate operations. */\nexport const CALENDAR_UNITS = new Set<CalendarUnit>(['day', 'month', 'week', 'year']);\n\n/** Approximate millisecond constants for threshold arithmetic. */\nexport const MS_PER_MONTH = 30.4375 * 86_400_000; // 365.25 / 12 days × 86400 s × 1000\n"],"mappings":";;;AAQA,SAAgB,EAAW,GAAoB;CAC7C,IAAI;EACF,EAAS,QAAQ,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAE;CACjE,QAAQ;EACN,EACE,iCAAiC,EAAG,6FACpC,CACF;CACF;CAEA,OAAO;AACT;AAIA,SAAgB,EAAc,GAAkB,GAAkC;CAChF,IAAM,IAAK,EAAQ,OAAO,aAAiB,EAAS,gBAAgB,EAAM,aAAa,KAAA;CAKvF,OAHK,KACH,EAAK,qFAAqF,CAAmB,GAExG,EAAW,CAAE;AACtB;AAEA,SAAgB,EAAoB,GAAqB,GAAkC;CACzF,IAAI,EAAQ,IAAI,OAAO,EAAW,EAAQ,EAAE;CAE5C,IAAI;CAEJ,KAAK,IAAM,KAAS,GAAQ;EAC1B,IAAI,EAAE,aAAiB,EAAS,gBAAgB;EAEhD,IAAM,IAAK,EAAM;EAEjB,IAAI,CAAC,GAAU;GACb,IAAW;GACX;EACF;EAEA,AAAI,MAAa,KACf,EAAK,iGAAiG;CAE1G;CAKA,OAHK,KACH,EAAK,qFAAqF,CAAmB,GAExG;AACT;AAIA,SAAgB,EAAe,GAAyB,GAA6D;CACnH,OAAO,EAAS,QAAQ,QAAQ,GAAO,CAAG,KAAK,IAAI,CAAC,GAAO,CAAG,IAAI,CAAC,GAAK,CAAK;AAC/E;AAKA,IAAa,oBAAiB,IAAI,IAAkB;CAAC;CAAO;CAAS;CAAQ;AAAM,CAAC,GAGvE,IAAe"}
|
package/dist/errors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all tempo errors. Use `instanceof TempoError` to catch any tempo-originated error. */\nexport class TempoError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is TempoError {\n return err instanceof TempoError;\n }\n}\n\n/** Thrown when a date/time input string or value cannot be parsed. */\nexport class TempoInvalidInputError extends TempoError {}\n\n/** Thrown when the provided timezone identifier is unknown or invalid. */\nexport class TempoInvalidTzError extends TempoError {}\n\n/** Thrown when an operation requires a timezone but none was supplied. */\nexport class TempoMissingTzError extends TempoError {}\n\n/** Thrown when an input type is not supported by the called operation. */\nexport class TempoUnsupportedInputError extends TempoError {}\n\n// ─── Error helpers ────────────────────────────────────────────────────────────\n\ntype TempoErrorCtor = new (message: string) => TempoError;\n\nexport function fail(message: string, Class: TempoErrorCtor = TempoInvalidInputError): never {\n throw new Class(message);\n}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAmB,KAAM,CACpC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all tempo errors. Use `instanceof TempoError` to catch any tempo-originated error. */\nexport class TempoError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is TempoError {\n return err instanceof TempoError;\n }\n}\n\n/** Thrown when a date/time input string or value cannot be parsed. */\nexport class TempoInvalidInputError extends TempoError {}\n\n/** Thrown when the provided timezone identifier is unknown or invalid. */\nexport class TempoInvalidTzError extends TempoError {}\n\n/** Thrown when an operation requires a timezone but none was supplied. */\nexport class TempoMissingTzError extends TempoError {}\n\n/** Thrown when an input type is not supported by the called operation. */\nexport class TempoUnsupportedInputError extends TempoError {}\n\n// ─── Error helpers ────────────────────────────────────────────────────────────\n\ntype TempoErrorCtor = new (message: string) => TempoError;\n\nexport function fail(message: string, Class: TempoErrorCtor = TempoInvalidInputError): never {\n throw new Class(message);\n}\n"],"mappings":"AACA,IAAa,EAAb,MAAa,UAAmB,KAAM,CACpC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CAEA,OAAO,GAAG,EAAiC,CACzC,OAAO,aAAe,CACxB,CACF,EAGa,EAAb,cAA4C,CAAW,CAAC,EAG3C,EAAb,cAAyC,CAAW,CAAC,EAGxC,EAAb,cAAyC,CAAW,CAAC,EAGxC,EAAb,cAAgD,CAAW,CAAC,EAM5D,SAAgB,EAAK,EAAiB,EAAwB,EAA+B,CAC3F,MAAM,IAAI,EAAM,CAAO,CACzB"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all tempo errors. Use `instanceof TempoError` to catch any tempo-originated error. */\nexport class TempoError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is TempoError {\n return err instanceof TempoError;\n }\n}\n\n/** Thrown when a date/time input string or value cannot be parsed. */\nexport class TempoInvalidInputError extends TempoError {}\n\n/** Thrown when the provided timezone identifier is unknown or invalid. */\nexport class TempoInvalidTzError extends TempoError {}\n\n/** Thrown when an operation requires a timezone but none was supplied. */\nexport class TempoMissingTzError extends TempoError {}\n\n/** Thrown when an input type is not supported by the called operation. */\nexport class TempoUnsupportedInputError extends TempoError {}\n\n// ─── Error helpers ────────────────────────────────────────────────────────────\n\ntype TempoErrorCtor = new (message: string) => TempoError;\n\nexport function fail(message: string, Class: TempoErrorCtor = TempoInvalidInputError): never {\n throw new Class(message);\n}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAmB,MAAM;CACpC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all tempo errors. Use `instanceof TempoError` to catch any tempo-originated error. */\nexport class TempoError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n static is(err: unknown): err is TempoError {\n return err instanceof TempoError;\n }\n}\n\n/** Thrown when a date/time input string or value cannot be parsed. */\nexport class TempoInvalidInputError extends TempoError {}\n\n/** Thrown when the provided timezone identifier is unknown or invalid. */\nexport class TempoInvalidTzError extends TempoError {}\n\n/** Thrown when an operation requires a timezone but none was supplied. */\nexport class TempoMissingTzError extends TempoError {}\n\n/** Thrown when an input type is not supported by the called operation. */\nexport class TempoUnsupportedInputError extends TempoError {}\n\n// ─── Error helpers ────────────────────────────────────────────────────────────\n\ntype TempoErrorCtor = new (message: string) => TempoError;\n\nexport function fail(message: string, Class: TempoErrorCtor = TempoInvalidInputError): never {\n throw new Class(message);\n}\n"],"mappings":";AACA,IAAa,IAAb,MAAa,UAAmB,MAAM;CACpC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;CAEA,OAAO,GAAG,GAAiC;EACzC,OAAO,aAAe;CACxB;AACF,GAGa,IAAb,cAA4C,EAAW,CAAC,GAG3C,IAAb,cAAyC,EAAW,CAAC,GAGxC,IAAb,cAAyC,EAAW,CAAC,GAGxC,IAAb,cAAgD,EAAW,CAAC;AAM5D,SAAgB,EAAK,GAAiB,IAAwB,GAA+B;CAC3F,MAAM,IAAI,EAAM,CAAO;AACzB"}
|
package/dist/format.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./errors.cjs"),t=require("./_tz.cjs"),n=require("./_convert.cjs");let r=require("@js-temporal/polyfill");var i=128;function a(e,t,n){let r=e.get(t);if(r!==void 0)return r;if(e.size>=i){let t=e.keys().next().value;t!==void 0&&e.delete(t)}let a=n();return e.set(t,a),a}var o=new Map,s=new Map,c=new Map,l={"date-only":{dateStyle:`short`},long:{dateStyle:`full`,timeStyle:`long`},medium:{dateStyle:`medium`,timeStyle:`short`},short:{dateStyle:`short`,timeStyle:`short`},"time-only":{timeStyle:`short`}};function u(e){return JSON.stringify(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,String(t)]))}function d(e,t){let n=e.tz??t,r=e.locale;if(e.intl!==void 0)return a(o,`${String(r??``)}|intl|${n??``}|${u(e.intl)}`,()=>{let t=n===void 0?e.intl:{...e.intl,timeZone:n};return new Intl.DateTimeFormat(r,t)});let i=e.pattern??`medium`;return a(o,`${String(r??``)}|${i}|${n??``}`,()=>new Intl.DateTimeFormat(r,{...l[i],timeZone:n}))}function f(e){return a(s,`${String(e.locale??``)}|${e.numeric??`auto`}|${e.style??`long`}`,()=>new Intl.RelativeTimeFormat(e.locale,{numeric:e.numeric??`auto`,style:e.style??`long`}))}function p(e){let t=Intl;return t.DurationFormat?a(c,`${String(e.locale??``)}|${e.style??``}`,()=>new t.DurationFormat(e.locale,{style:e.style})):null}var m=60,h=3600,g=86400,_=604800,v=2629800,y=31557600,b=[{scale:1,thresholdToPromote:m,unit:`second`},{scale:m,thresholdToPromote:h/m,unit:`minute`},{scale:h,thresholdToPromote:g/h,unit:`hour`},{scale:g,thresholdToPromote:_/g,unit:`day`},{scale:_,thresholdToPromote:v/_,unit:`week`},{scale:v,thresholdToPromote:12,unit:`month`},{scale:y,thresholdToPromote:1/0,unit:`year`}];function x(t){Number.isFinite(t)||e.fail(`formatRelative received a non-finite time difference.`);let n=Math.round(t);for(let{scale:e,thresholdToPromote:t,unit:r}of b){let i=Math.round(n/e);if(Math.abs(i)<t)return{unit:r,value:i}}return{unit:`year`,value:Math.round(n/y)}}var S=[`years`,`months`,`weeks`,`days`,`hours`,`minutes`,`seconds`,`milliseconds`,`microseconds`,`nanoseconds`];function C(e){let t=[];for(let n of S){let r=Math.abs(e[n]);r!==0&&t.push(`${r} ${r===1?n.slice(0,-1):n}`)}return t.length===0?`0 seconds`:t.join(`, `)}function w(t,n,i,a){if(i.tz)return i.tz;let o=t instanceof r.Temporal.ZonedDateTime?t.timeZoneId:void 0,s=n instanceof r.Temporal.ZonedDateTime?n.timeZoneId:void 0;return o&&s&&o!==s&&e.fail(`${a} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`),o??s}function T(e,t={}){let i=t.tz??(e instanceof r.Temporal.ZonedDateTime?e.timeZoneId:void 0);return d(t,i).format(new Date(n.toInstant(e,{tz:i}).epochMilliseconds))}function E(e,t,r={}){let i=w(e,t,r,`formatRange`);return d(r,i).formatRange(new Date(n.toInstant(e,{tz:i}).epochMilliseconds),new Date(n.toInstant(t,{tz:i}).epochMilliseconds))}function D(e,t,r={}){let i=w(e,t,r,`formatRangeParts`);return d(r,i).formatRangeToParts(new Date(n.toInstant(e,{tz:i}).epochMilliseconds),new Date(n.toInstant(t,{tz:i}).epochMilliseconds))}function O(e,t={}){return n.toInstant(e,t).toString()}function k(e,r={}){return n.toZoned(e,{tz:
|
|
1
|
+
const e=require("./errors.cjs"),t=require("./_tz.cjs"),n=require("./_convert.cjs");let r=require("@js-temporal/polyfill");var i=128;function a(e,t,n){let r=e.get(t);if(r!==void 0)return r;if(e.size>=i){let t=e.keys().next().value;t!==void 0&&e.delete(t)}let a=n();return e.set(t,a),a}var o=new Map,s=new Map,c=new Map,l={"date-only":{dateStyle:`short`},long:{dateStyle:`full`,timeStyle:`long`},medium:{dateStyle:`medium`,timeStyle:`short`},short:{dateStyle:`short`,timeStyle:`short`},"time-only":{timeStyle:`short`}};function u(e){return JSON.stringify(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,String(t)]))}function d(e,t){let n=e.tz??t,r=e.locale;if(e.intl!==void 0)return a(o,`${String(r??``)}|intl|${n??``}|${u(e.intl)}`,()=>{let t=n===void 0?e.intl:{...e.intl,timeZone:n};return new Intl.DateTimeFormat(r,t)});let i=e.pattern??`medium`;return a(o,`${String(r??``)}|${i}|${n??``}`,()=>new Intl.DateTimeFormat(r,{...l[i],timeZone:n}))}function f(e){return a(s,`${String(e.locale??``)}|${e.numeric??`auto`}|${e.style??`long`}`,()=>new Intl.RelativeTimeFormat(e.locale,{numeric:e.numeric??`auto`,style:e.style??`long`}))}function p(e){let t=Intl;return t.DurationFormat?a(c,`${String(e.locale??``)}|${e.style??``}`,()=>new t.DurationFormat(e.locale,{style:e.style})):null}var m=60,h=3600,g=86400,_=604800,v=2629800,y=31557600,b=[{scale:1,thresholdToPromote:m,unit:`second`},{scale:m,thresholdToPromote:h/m,unit:`minute`},{scale:h,thresholdToPromote:g/h,unit:`hour`},{scale:g,thresholdToPromote:_/g,unit:`day`},{scale:_,thresholdToPromote:v/_,unit:`week`},{scale:v,thresholdToPromote:12,unit:`month`},{scale:y,thresholdToPromote:1/0,unit:`year`}];function x(t){Number.isFinite(t)||e.fail(`formatRelative received a non-finite time difference.`);let n=Math.round(t);for(let{scale:e,thresholdToPromote:t,unit:r}of b){let i=Math.round(n/e);if(Math.abs(i)<t)return{unit:r,value:i}}return{unit:`year`,value:Math.round(n/y)}}var S=[`years`,`months`,`weeks`,`days`,`hours`,`minutes`,`seconds`,`milliseconds`,`microseconds`,`nanoseconds`];function C(e){let t=[];for(let n of S){let r=Math.abs(e[n]);r!==0&&t.push(`${r} ${r===1?n.slice(0,-1):n}`)}return t.length===0?`0 seconds`:t.join(`, `)}function w(t,n,i,a){if(i.tz)return i.tz;let o=t instanceof r.Temporal.ZonedDateTime?t.timeZoneId:void 0,s=n instanceof r.Temporal.ZonedDateTime?n.timeZoneId:void 0;return o&&s&&o!==s&&e.fail(`${a} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`),o??s}function T(e,t={}){let i=t.tz??(e instanceof r.Temporal.ZonedDateTime?e.timeZoneId:void 0);return d(t,i).format(new Date(n.toInstant(e,{tz:i}).epochMilliseconds))}function E(e,t,r={}){let i=w(e,t,r,`formatRange`);return d(r,i).formatRange(new Date(n.toInstant(e,{tz:i}).epochMilliseconds),new Date(n.toInstant(t,{tz:i}).epochMilliseconds))}function D(e,t,r={}){let i=w(e,t,r,`formatRangeParts`);return d(r,i).formatRangeToParts(new Date(n.toInstant(e,{tz:i}).epochMilliseconds),new Date(n.toInstant(t,{tz:i}).epochMilliseconds))}function O(e,t={}){return n.toInstant(e,t).toString()}function k(e,r={}){let i=t.inferTimeZone(e,r);return n.toZoned(e,{tz:i}).toString()}function A(e,t={}){let n=e instanceof r.Temporal.Instant?e:e.toInstant(),i=t.base?t.base instanceof r.Temporal.Instant?t.base:t.base.toInstant():r.Temporal.Now.instant(),{unit:a,value:o}=x((n.epochMilliseconds-i.epochMilliseconds)/1e3);return f(t).format(o,a)}function j(t){try{return r.Temporal.Duration.from(t)}catch{e.fail(`Invalid duration input: "${String(t)}". Expected an ISO 8601 duration string or Temporal.DurationLike.`)}}function M(e,t={}){let n=j(e),r=p(t);return r?r.format(n):C(n)}function N(e,t={}){let i=t.tz??(e instanceof r.Temporal.ZonedDateTime?e.timeZoneId:void 0);return d(t,i).formatToParts(new Date(n.toInstant(e,{tz:i}).epochMilliseconds))}function P(e,t={}){let{unit:n,value:r}=e;return`${t.locale?new Intl.NumberFormat(t.locale).format(r):String(r)} ${r===1?n:`${n}s`}`}exports.format=T,exports.formatDuration=M,exports.formatInstant=O,exports.formatParts=N,exports.formatRange=E,exports.formatRangeParts=D,exports.formatRelative=A,exports.formatZoned=k,exports.humanize=P,exports.parseDuration=j;
|
|
2
2
|
//# sourceMappingURL=format.cjs.map
|
package/dist/format.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.cjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type {\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n RelativeFormatOptions,\n RelativeTimeInput,\n TimeDiffResult,\n TimeInput,\n TimeOptions,\n} from './types';\n\nimport { toInstant, toZoned } from './_convert';\nimport { inferTimeZone } from './_tz';\nimport { fail } from './errors';\n\n// ─── Formatter types ──────────────────────────────────────────────────────────\n\ntype DurationFormatter = { format(value: Temporal.Duration): string };\ntype DurationFormatterConstructor = new (\n locales?: Intl.LocalesArgument,\n options?: { style?: 'digital' | 'long' | 'narrow' | 'short' },\n) => DurationFormatter;\n\n// ─── Formatter caches ─────────────────────────────────────────────────────────\n\nconst FORMATTER_CACHE_MAX = 128;\n\nfunction cappedGetOrCreate<V>(cache: Map<string, V>, key: string, factory: () => V): V {\n const cached = cache.get(key);\n\n if (cached !== undefined) return cached;\n\n if (cache.size >= FORMATTER_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n\n if (oldest !== undefined) cache.delete(oldest);\n }\n\n const value = factory();\n\n cache.set(key, value);\n\n return value;\n}\n\nconst DATE_TIME_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nconst RELATIVE_TIME_FORMATTER_CACHE = new Map<string, Intl.RelativeTimeFormat>();\nconst DURATION_FORMATTER_CACHE = new Map<string, DurationFormatter>();\n\n// ─── Format presets ───────────────────────────────────────────────────────────\n\nconst FORMAT_PRESETS: Record<FormatPattern, Intl.DateTimeFormatOptions> = {\n 'date-only': { dateStyle: 'short' },\n long: { dateStyle: 'full', timeStyle: 'long' },\n medium: { dateStyle: 'medium', timeStyle: 'short' },\n short: { dateStyle: 'short', timeStyle: 'short' },\n 'time-only': { timeStyle: 'short' },\n};\n\n// ─── Formatter factory helpers ────────────────────────────────────────────────\n\nfunction serializeIntlOptions(options: Intl.DateTimeFormatOptions): string {\n return JSON.stringify(\n Object.entries(options)\n .filter(([, value]) => value !== undefined)\n .sort(([l], [r]) => l.localeCompare(r))\n .map(([key, value]) => [key, String(value)]),\n );\n}\n\nfunction makeFormatter(options: FormatOptions, fallbackTz?: string): Intl.DateTimeFormat {\n const tz = options.tz ?? fallbackTz;\n const locale = options.locale;\n\n if (options.intl !== undefined) {\n const cacheKey = `${String(locale ?? '')}|intl|${tz ?? ''}|${serializeIntlOptions(options.intl)}`;\n\n return cappedGetOrCreate(DATE_TIME_FORMATTER_CACHE, cacheKey, () => {\n const intlOptions = tz !== undefined ? { ...options.intl, timeZone: tz } : options.intl;\n\n return new Intl.DateTimeFormat(locale, intlOptions);\n });\n }\n\n const pattern = options.pattern ?? 'medium';\n const cacheKey = `${String(locale ?? '')}|${pattern}|${tz ?? ''}`;\n\n return cappedGetOrCreate(\n DATE_TIME_FORMATTER_CACHE,\n cacheKey,\n () => new Intl.DateTimeFormat(locale, { ...FORMAT_PRESETS[pattern], timeZone: tz }),\n );\n}\n\nfunction getRelativeFormatter(options: {\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}): Intl.RelativeTimeFormat {\n const cacheKey = `${String(options.locale ?? '')}|${options.numeric ?? 'auto'}|${options.style ?? 'long'}`;\n\n return cappedGetOrCreate(\n RELATIVE_TIME_FORMATTER_CACHE,\n cacheKey,\n () =>\n new Intl.RelativeTimeFormat(options.locale, {\n numeric: options.numeric ?? 'auto',\n style: options.style ?? 'long',\n }),\n );\n}\n\nfunction getDurationFormatter(options: {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}): DurationFormatter | null {\n const IntlWithDurationFormat = Intl as typeof Intl & { DurationFormat?: DurationFormatterConstructor };\n\n if (!IntlWithDurationFormat.DurationFormat) return null;\n\n const cacheKey = `${String(options.locale ?? '')}|${options.style ?? ''}`;\n\n return cappedGetOrCreate(\n DURATION_FORMATTER_CACHE,\n cacheKey,\n () => new IntlWithDurationFormat.DurationFormat!(options.locale, { style: options.style }),\n );\n}\n\n// ─── Time scale constants ─────────────────────────────────────────────────────\n\nconst SECONDS_PER_MINUTE = 60;\nconst SECONDS_PER_HOUR = 3_600;\nconst SECONDS_PER_DAY = 86_400;\nconst SECONDS_PER_WEEK = 604_800;\nconst SECONDS_PER_MONTH = 2_629_800; // ≈ 30.4375 days × 86400\nconst SECONDS_PER_YEAR = 31_557_600; // 365.25 days × 86400\n\n// ─── Relative time helpers ────────────────────────────────────────────────────\n\nconst RELATIVE_UNITS: ReadonlyArray<{ scale: number; thresholdToPromote: number; unit: Intl.RelativeTimeFormatUnit }> =\n [\n { scale: 1, thresholdToPromote: SECONDS_PER_MINUTE, unit: 'second' },\n { scale: SECONDS_PER_MINUTE, thresholdToPromote: SECONDS_PER_HOUR / SECONDS_PER_MINUTE, unit: 'minute' },\n { scale: SECONDS_PER_HOUR, thresholdToPromote: SECONDS_PER_DAY / SECONDS_PER_HOUR, unit: 'hour' },\n { scale: SECONDS_PER_DAY, thresholdToPromote: SECONDS_PER_WEEK / SECONDS_PER_DAY, unit: 'day' },\n { scale: SECONDS_PER_WEEK, thresholdToPromote: SECONDS_PER_MONTH / SECONDS_PER_WEEK, unit: 'week' },\n { scale: SECONDS_PER_MONTH, thresholdToPromote: 12, unit: 'month' },\n { scale: SECONDS_PER_YEAR, thresholdToPromote: Number.POSITIVE_INFINITY, unit: 'year' },\n ];\n\nfunction toRelativeUnit(seconds: number): { unit: Intl.RelativeTimeFormatUnit; value: number } {\n if (!Number.isFinite(seconds)) fail('formatRelative received a non-finite time difference.');\n\n const roundedSeconds = Math.round(seconds);\n\n for (const { scale, thresholdToPromote, unit } of RELATIVE_UNITS) {\n const value = Math.round(roundedSeconds / scale);\n\n if (Math.abs(value) < thresholdToPromote) return { unit, value };\n }\n\n return { unit: 'year', value: Math.round(roundedSeconds / SECONDS_PER_YEAR) };\n}\n\n// ─── Duration fallback renderer ───────────────────────────────────────────────\n\n// All English duration unit names follow the same pluralization rule: singular = plural.slice(0, -1)\nconst DURATION_UNITS = [\n 'years',\n 'months',\n 'weeks',\n 'days',\n 'hours',\n 'minutes',\n 'seconds',\n 'milliseconds',\n 'microseconds',\n 'nanoseconds',\n] as const satisfies ReadonlyArray<keyof Temporal.Duration>;\n\n// English-only fallback; runs only when Intl.DurationFormat is unavailable in the runtime.\nfunction buildDurationFallback(duration: Temporal.Duration): string {\n const parts: string[] = [];\n\n for (const unit of DURATION_UNITS) {\n const value = Math.abs(duration[unit] as number);\n\n if (value !== 0) parts.push(`${value} ${value === 1 ? unit.slice(0, -1) : unit}`);\n }\n\n return parts.length === 0 ? '0 seconds' : parts.join(', ');\n}\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/**\n * Resolves a shared display timezone for two-input range functions.\n * Throws when both inputs are `ZonedDateTime` with different zones and no `options.tz` override.\n */\nfunction resolveRangeTz(start: TimeInput, end: TimeInput, options: FormatOptions, caller: string): string | undefined {\n if (options.tz) return options.tz;\n\n const startTz = start instanceof Temporal.ZonedDateTime ? start.timeZoneId : undefined;\n const endTz = end instanceof Temporal.ZonedDateTime ? end.timeZoneId : undefined;\n\n if (startTz && endTz && startTz !== endTz) {\n fail(`${caller} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`);\n }\n\n return startTz ?? endTz;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Formats `input` using `Intl.DateTimeFormat`. Defaults to `pattern: 'medium'`.\n *\n * Pass `intl` for full `Intl.DateTimeFormatOptions` control (mutually exclusive with `pattern`).\n * The timezone is inferred from a `ZonedDateTime` input or from `options.tz`.\n *\n * @example\n * ```ts\n * format(parseInstant('2026-03-21T10:15:30Z'), { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:15'\n * ```\n */\nexport function format(input: TimeInput, options: FormatOptions = {}): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).format(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Formats a time span between `start` and `end` using `Intl.DateTimeFormat.formatRange`.\n *\n * @example\n * ```ts\n * formatRange(start, end, { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:00 – 12:00'\n * ```\n */\nexport function formatRange(start: TimeInput, end: TimeInput, options: FormatOptions = {}): string {\n const tz = resolveRangeTz(start, end, options, 'formatRange');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRange(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Returns the raw `Intl.DateTimeRangeFormatPart[]` array for a time span, enabling\n * fine-grained rendering of range start, end, and shared parts separately.\n *\n * @example\n * ```ts\n * formatRangeParts(start, end, { locale: 'en-US', pattern: 'short', tz: 'UTC' })\n * // [{ type: 'month', value: '3', source: 'startRange' }, ...]\n * ```\n */\nexport function formatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options: FormatOptions = {},\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']> {\n const tz = resolveRangeTz(start, end, options, 'formatRangeParts');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRangeToParts(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Serializes `input` to a UTC ISO 8601 instant string (`2026-03-21T10:15:30Z`).\n * Requires `options.tz` when input is a `PlainDate` or `PlainDateTime`.\n *\n * @example\n * ```ts\n * formatInstant(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T10:15:30Z'\n * ```\n */\nexport function formatInstant(input: TimeInput, options: TimeOptions = {}): string {\n return toInstant(input, options).toString();\n}\n\n/**\n * Serializes `input` to a zoned ISO 8601 string (`2026-03-21T11:15:30+01:00[Europe/Berlin]`).\n *\n * @param options.tz - Required when `input` is a `PlainDate` or `PlainDateTime`.\n * Inferred automatically from a `ZonedDateTime` or `Instant` input.\n *\n * @throws {TempoError} When `input` is a `PlainDate` or `PlainDateTime` and `options.tz` is omitted.\n *\n * @example\n * ```ts\n * formatZoned(parseInstant('2026-03-21T10:15:30Z'), { tz: 'Europe/Berlin' })\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]'\n *\n * formatZoned(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]' (tz inferred)\n * ```\n */\nexport function formatZoned(input: TimeInput, options: TimeOptions = {}): string {\n const tz = inferTimeZone(input, options);\n\n return toZoned(input, { tz }).toString();\n}\n\n/**\n * Formats `input` relative to `options.base` (defaults to now) using `Intl.RelativeTimeFormat`.\n *\n * @example\n * ```ts\n * formatRelative(parseInstant('2026-03-21T12:00:00Z'), {\n * base: parseInstant('2026-03-21T10:00:00Z'),\n * locale: 'en-US',\n * numeric: 'always',\n * })\n * // 'in 2 hours'\n * ```\n */\nexport function formatRelative(input: RelativeTimeInput, options: RelativeFormatOptions = {}): string {\n const target = input instanceof Temporal.Instant ? input : input.toInstant();\n const base = options.base\n ? options.base instanceof Temporal.Instant\n ? options.base\n : options.base.toInstant()\n : Temporal.Now.instant();\n const differenceInSeconds = (target.epochMilliseconds - base.epochMilliseconds) / 1000;\n const { unit, value } = toRelativeUnit(differenceInSeconds);\n\n return getRelativeFormatter(options).format(value, unit);\n}\n\n/**\n * Parses an ISO duration string or `Temporal.DurationLike` into a `Temporal.Duration`.\n *\n * @example\n * ```ts\n * parseDuration('PT2H30M').toString() // 'PT2H30M'\n * parseDuration({ hours: 2, minutes: 30 }).toString() // 'PT2H30M'\n * ```\n */\nexport function parseDuration(input: string | Temporal.DurationLike): Temporal.Duration {\n try {\n return Temporal.Duration.from(input);\n } catch {\n fail(`Invalid duration input: \"${String(input)}\". Expected an ISO 8601 duration string or Temporal.DurationLike.`);\n }\n}\n\n/**\n * Formats a duration using `Intl.DurationFormat` when available, falling back to\n * a human-readable plain-English string.\n *\n * @example\n * ```ts\n * formatDuration('PT2H30M', { locale: 'en-US', style: 'long' })\n * // '2 hours, 30 minutes'\n * ```\n */\nexport function formatDuration(input: string | Temporal.DurationLike, options: DurationFormatOptions = {}): string {\n const duration = parseDuration(input);\n const formatter = getDurationFormatter(options);\n\n if (formatter) return formatter.format(duration);\n\n return buildDurationFallback(duration);\n}\n\n/**\n * Returns the raw `Intl.DateTimeFormatPart[]` array for `input`, enabling\n * custom rendering where individual parts (year, month, day, etc.) need\n * to be styled or composed differently.\n *\n * @example\n * ```ts\n * formatParts(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'medium', tz: 'UTC' })\n * // [{ type: 'month', value: 'Mar' }, { type: 'literal', value: ' ' }, ...]\n * ```\n */\nexport function formatParts(input: TimeInput, options: FormatOptions = {}): Intl.DateTimeFormatPart[] {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).formatToParts(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Converts a `TimeDiffResult` to a human-readable string.\n * Uses the singular unit name when value is 1, plural (unit + 's') otherwise.\n *\n * Pass `options.locale` to localize the numeric part via `Intl.NumberFormat`.\n * Unit names remain English — for fully localized output use {@link formatRelative}\n * or {@link formatDuration} instead.\n *\n * @example\n * ```ts\n * humanize({ unit: 'day', value: 1 }) // '1 day'\n * humanize({ unit: 'day', value: 3 }) // '3 days'\n * humanize({ unit: 'day', value: 3 }, { locale: 'ar' }) // '٣ days'\n * humanize({ unit: 'millisecond', value: 0 }) // '0 milliseconds'\n * ```\n */\nexport function humanize(diff: TimeDiffResult, options: { locale?: Intl.LocalesArgument } = {}): string {\n const { unit, value } = diff;\n const formatted = options.locale ? new Intl.NumberFormat(options.locale).format(value) : String(value);\n\n return `${formatted} ${value === 1 ? unit : `${unit}s`}`;\n}\n"],"mappings":"0HA2BA,IAAM,EAAsB,IAE5B,SAAS,EAAqB,EAAuB,EAAa,EAAqB,CACrF,IAAM,EAAS,EAAM,IAAI,CAAG,EAE5B,GAAI,IAAW,IAAA,GAAW,OAAO,EAEjC,GAAI,EAAM,MAAQ,EAAqB,CACrC,IAAM,EAAS,EAAM,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,MAE/B,IAAW,IAAA,IAAW,EAAM,OAAO,CAAM,CAC/C,CAEA,IAAM,EAAQ,EAAQ,EAItB,OAFA,EAAM,IAAI,EAAK,CAAK,EAEb,CACT,CAEA,IAAM,EAA4B,IAAI,IAChC,EAAgC,IAAI,IACpC,EAA2B,IAAI,IAI/B,EAAoE,CACxE,YAAa,CAAE,UAAW,OAAQ,EAClC,KAAM,CAAE,UAAW,OAAQ,UAAW,MAAO,EAC7C,OAAQ,CAAE,UAAW,SAAU,UAAW,OAAQ,EAClD,MAAO,CAAE,UAAW,QAAS,UAAW,OAAQ,EAChD,YAAa,CAAE,UAAW,OAAQ,CACpC,EAIA,SAAS,EAAqB,EAA6C,CACzE,OAAO,KAAK,UACV,OAAO,QAAQ,CAAO,CAAC,CACpB,QAAQ,EAAG,KAAW,IAAU,IAAA,EAAS,CAAC,CAC1C,MAAM,CAAC,GAAI,CAAC,KAAO,EAAE,cAAc,CAAC,CAAC,CAAC,CACtC,KAAK,CAAC,EAAK,KAAW,CAAC,EAAK,OAAO,CAAK,CAAC,CAAC,CAC/C,CACF,CAEA,SAAS,EAAc,EAAwB,EAA0C,CACvF,IAAM,EAAK,EAAQ,IAAM,EACnB,EAAS,EAAQ,OAEvB,GAAI,EAAQ,OAAS,IAAA,GAGnB,OAAO,EAAkB,EAA2B,GAFhC,OAAO,GAAU,EAAE,EAAE,QAAQ,GAAM,GAAG,GAAG,EAAqB,EAAQ,IAAI,QAE1B,CAClE,IAAM,EAAc,IAAO,IAAA,GAAgD,EAAQ,KAA5C,CAAE,GAAG,EAAQ,KAAM,SAAU,CAAG,EAEvE,OAAO,IAAI,KAAK,eAAe,EAAQ,CAAW,CACpD,CAAC,EAGH,IAAM,EAAU,EAAQ,SAAW,SAGnC,OAAO,EACL,EACA,GAJkB,OAAO,GAAU,EAAE,EAAE,GAAG,EAAQ,GAAG,GAAM,SAKrD,IAAI,KAAK,eAAe,EAAQ,CAAE,GAAG,EAAe,GAAU,SAAU,CAAG,CAAC,CACpF,CACF,CAEA,SAAS,EAAqB,EAIF,CAG1B,OAAO,EACL,EACA,GAJkB,OAAO,EAAQ,QAAU,EAAE,EAAE,GAAG,EAAQ,SAAW,OAAO,GAAG,EAAQ,OAAS,aAM9F,IAAI,KAAK,mBAAmB,EAAQ,OAAQ,CAC1C,QAAS,EAAQ,SAAW,OAC5B,MAAO,EAAQ,OAAS,MAC1B,CAAC,CACL,CACF,CAEA,SAAS,EAAqB,EAGD,CAC3B,IAAM,EAAyB,KAM/B,OAJK,EAAuB,eAIrB,EACL,EACA,GAJkB,OAAO,EAAQ,QAAU,EAAE,EAAE,GAAG,EAAQ,OAAS,SAK7D,IAAI,EAAuB,eAAgB,EAAQ,OAAQ,CAAE,MAAO,EAAQ,KAAM,CAAC,CAC3F,EARmD,IASrD,CAIA,IAAM,EAAqB,GACrB,EAAmB,KACnB,EAAkB,MAClB,EAAmB,OACnB,EAAoB,QACpB,EAAmB,SAInB,EACJ,CACE,CAAE,MAAO,EAAG,mBAAoB,EAAoB,KAAM,QAAS,EACnE,CAAE,MAAO,EAAoB,mBAAoB,EAAmB,EAAoB,KAAM,QAAS,EACvG,CAAE,MAAO,EAAkB,mBAAoB,EAAkB,EAAkB,KAAM,MAAO,EAChG,CAAE,MAAO,EAAiB,mBAAoB,EAAmB,EAAiB,KAAM,KAAM,EAC9F,CAAE,MAAO,EAAkB,mBAAoB,EAAoB,EAAkB,KAAM,MAAO,EAClG,CAAE,MAAO,EAAmB,mBAAoB,GAAI,KAAM,OAAQ,EAClE,CAAE,MAAO,EAAkB,mBAAoB,IAA0B,KAAM,MAAO,CACxF,EAEF,SAAS,EAAe,EAAuE,CACxF,OAAO,SAAS,CAAO,GAAG,EAAA,KAAK,uDAAuD,EAE3F,IAAM,EAAiB,KAAK,MAAM,CAAO,EAEzC,IAAK,GAAM,CAAE,QAAO,qBAAoB,UAAU,EAAgB,CAChE,IAAM,EAAQ,KAAK,MAAM,EAAiB,CAAK,EAE/C,GAAI,KAAK,IAAI,CAAK,EAAI,EAAoB,MAAO,CAAE,OAAM,OAAM,CACjE,CAEA,MAAO,CAAE,KAAM,OAAQ,MAAO,KAAK,MAAM,EAAiB,CAAgB,CAAE,CAC9E,CAKA,IAAM,EAAiB,CACrB,QACA,SACA,QACA,OACA,QACA,UACA,UACA,eACA,eACA,aACF,EAGA,SAAS,EAAsB,EAAqC,CAClE,IAAM,EAAkB,CAAC,EAEzB,IAAK,IAAM,KAAQ,EAAgB,CACjC,IAAM,EAAQ,KAAK,IAAI,EAAS,EAAe,EAE3C,IAAU,GAAG,EAAM,KAAK,GAAG,EAAM,GAAG,IAAU,EAAI,EAAK,MAAM,EAAG,EAAE,EAAI,GAAM,CAClF,CAEA,OAAO,EAAM,SAAW,EAAI,YAAc,EAAM,KAAK,IAAI,CAC3D,CAQA,SAAS,EAAe,EAAkB,EAAgB,EAAwB,EAAoC,CACpH,GAAI,EAAQ,GAAI,OAAO,EAAQ,GAE/B,IAAM,EAAU,aAAiB,EAAA,SAAS,cAAgB,EAAM,WAAa,IAAA,GACvE,EAAQ,aAAe,EAAA,SAAS,cAAgB,EAAI,WAAa,IAAA,GAMvE,OAJI,GAAW,GAAS,IAAY,GAClC,EAAA,KAAK,GAAG,EAAO,sFAAsF,EAGhG,GAAW,CACpB,CAgBA,SAAgB,EAAO,EAAkB,EAAyB,CAAC,EAAW,CAC5E,IAAM,EAAK,EAAQ,KAAO,aAAiB,EAAA,SAAS,cAAgB,EAAM,WAAa,IAAA,IAEvF,OAAO,EAAc,EAAS,CAAE,CAAC,CAAC,OAAO,IAAI,KAAK,EAAA,UAAU,EAAO,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAC/F,CAWA,SAAgB,EAAY,EAAkB,EAAgB,EAAyB,CAAC,EAAW,CACjG,IAAM,EAAK,EAAe,EAAO,EAAK,EAAS,aAAa,EAG5D,OAFkB,EAAc,EAAS,CAElC,CAAA,CAAU,YACf,IAAI,KAAK,EAAA,UAAU,EAAO,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,EACnD,IAAI,KAAK,EAAA,UAAU,EAAK,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,CACnD,CACF,CAYA,SAAgB,EACd,EACA,EACA,EAAyB,CAAC,EAC6B,CACvD,IAAM,EAAK,EAAe,EAAO,EAAK,EAAS,kBAAkB,EAGjE,OAFkB,EAAc,EAAS,CAElC,CAAA,CAAU,mBACf,IAAI,KAAK,EAAA,UAAU,EAAO,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,EACnD,IAAI,KAAK,EAAA,UAAU,EAAK,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,CACnD,CACF,CAYA,SAAgB,EAAc,EAAkB,EAAuB,CAAC,EAAW,CACjF,OAAO,EAAA,UAAU,EAAO,CAAO,CAAC,CAAC,SAAS,CAC5C,CAmBA,SAAgB,EAAY,EAAkB,EAAuB,CAAC,EAAW,CAG/E,OAAO,EAAA,QAAQ,EAAO,CAAE,GAFb,EAAA,cAAc,EAAO,CAER,CAAG,CAAC,CAAC,CAAC,SAAS,CACzC,CAeA,SAAgB,EAAe,EAA0B,EAAiC,CAAC,EAAW,CACpG,IAAM,EAAS,aAAiB,EAAA,SAAS,QAAU,EAAQ,EAAM,UAAU,EACrE,EAAO,EAAQ,KACjB,EAAQ,gBAAgB,EAAA,SAAS,QAC/B,EAAQ,KACR,EAAQ,KAAK,UAAU,EACzB,EAAA,SAAS,IAAI,QAAQ,EAEnB,CAAE,OAAM,SAAU,GADK,EAAO,kBAAoB,EAAK,mBAAqB,GACxB,EAE1D,OAAO,EAAqB,CAAO,CAAC,CAAC,OAAO,EAAO,CAAI,CACzD,CAWA,SAAgB,EAAc,EAA0D,CACtF,GAAI,CACF,OAAO,EAAA,SAAS,SAAS,KAAK,CAAK,CACrC,MAAQ,CACN,EAAA,KAAK,4BAA4B,OAAO,CAAK,EAAE,kEAAkE,CACnH,CACF,CAYA,SAAgB,EAAe,EAAuC,EAAiC,CAAC,EAAW,CACjH,IAAM,EAAW,EAAc,CAAK,EAC9B,EAAY,EAAqB,CAAO,EAI9C,OAFI,EAAkB,EAAU,OAAO,CAAQ,EAExC,EAAsB,CAAQ,CACvC,CAaA,SAAgB,EAAY,EAAkB,EAAyB,CAAC,EAA8B,CACpG,IAAM,EAAK,EAAQ,KAAO,aAAiB,EAAA,SAAS,cAAgB,EAAM,WAAa,IAAA,IAEvF,OAAO,EAAc,EAAS,CAAE,CAAC,CAAC,cAAc,IAAI,KAAK,EAAA,UAAU,EAAO,CAAE,IAAG,CAAC,CAAC,CAAC,iBAAiB,CAAC,CACtG,CAkBA,SAAgB,EAAS,EAAsB,EAA6C,CAAC,EAAW,CACtG,GAAM,CAAE,OAAM,SAAU,EAGxB,MAAO,GAFW,EAAQ,OAAS,IAAI,KAAK,aAAa,EAAQ,MAAM,CAAC,CAAC,OAAO,CAAK,EAAI,OAAO,CAAK,EAEjF,GAAG,IAAU,EAAI,EAAO,GAAG,EAAK,IACtD"}
|
|
1
|
+
{"version":3,"file":"format.cjs","names":[],"sources":["../src/format.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type {\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n RelativeFormatOptions,\n RelativeTimeInput,\n TimeDiffResult,\n TimeInput,\n TimeOptions,\n} from './types';\n\nimport { toInstant, toZoned } from './_convert';\nimport { inferTimeZone } from './_tz';\nimport { fail } from './errors';\n\n// ─── Formatter types ──────────────────────────────────────────────────────────\n\ntype DurationFormatter = { format(value: Temporal.Duration): string };\ntype DurationFormatterConstructor = new (\n locales?: Intl.LocalesArgument,\n options?: { style?: 'digital' | 'long' | 'narrow' | 'short' },\n) => DurationFormatter;\n\n// ─── Formatter caches ─────────────────────────────────────────────────────────\n\nconst FORMATTER_CACHE_MAX = 128;\n\nfunction cappedGetOrCreate<V>(cache: Map<string, V>, key: string, factory: () => V): V {\n const cached = cache.get(key);\n\n if (cached !== undefined) return cached;\n\n if (cache.size >= FORMATTER_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n\n if (oldest !== undefined) cache.delete(oldest);\n }\n\n const value = factory();\n\n cache.set(key, value);\n\n return value;\n}\n\nconst DATE_TIME_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nconst RELATIVE_TIME_FORMATTER_CACHE = new Map<string, Intl.RelativeTimeFormat>();\nconst DURATION_FORMATTER_CACHE = new Map<string, DurationFormatter>();\n\n// ─── Format presets ───────────────────────────────────────────────────────────\n\nconst FORMAT_PRESETS: Record<FormatPattern, Intl.DateTimeFormatOptions> = {\n 'date-only': { dateStyle: 'short' },\n long: { dateStyle: 'full', timeStyle: 'long' },\n medium: { dateStyle: 'medium', timeStyle: 'short' },\n short: { dateStyle: 'short', timeStyle: 'short' },\n 'time-only': { timeStyle: 'short' },\n};\n\n// ─── Formatter factory helpers ────────────────────────────────────────────────\n\nfunction serializeIntlOptions(options: Intl.DateTimeFormatOptions): string {\n return JSON.stringify(\n Object.entries(options)\n .filter(([, value]) => value !== undefined)\n .sort(([l], [r]) => l.localeCompare(r))\n .map(([key, value]) => [key, String(value)]),\n );\n}\n\nfunction makeFormatter(options: FormatOptions, fallbackTz?: string): Intl.DateTimeFormat {\n const tz = options.tz ?? fallbackTz;\n const locale = options.locale;\n\n if (options.intl !== undefined) {\n const cacheKey = `${String(locale ?? '')}|intl|${tz ?? ''}|${serializeIntlOptions(options.intl)}`;\n\n return cappedGetOrCreate(DATE_TIME_FORMATTER_CACHE, cacheKey, () => {\n const intlOptions = tz !== undefined ? { ...options.intl, timeZone: tz } : options.intl;\n\n return new Intl.DateTimeFormat(locale, intlOptions);\n });\n }\n\n const pattern = options.pattern ?? 'medium';\n const cacheKey = `${String(locale ?? '')}|${pattern}|${tz ?? ''}`;\n\n return cappedGetOrCreate(\n DATE_TIME_FORMATTER_CACHE,\n cacheKey,\n () => new Intl.DateTimeFormat(locale, { ...FORMAT_PRESETS[pattern], timeZone: tz }),\n );\n}\n\nfunction getRelativeFormatter(options: {\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}): Intl.RelativeTimeFormat {\n const cacheKey = `${String(options.locale ?? '')}|${options.numeric ?? 'auto'}|${options.style ?? 'long'}`;\n\n return cappedGetOrCreate(\n RELATIVE_TIME_FORMATTER_CACHE,\n cacheKey,\n () =>\n new Intl.RelativeTimeFormat(options.locale, {\n numeric: options.numeric ?? 'auto',\n style: options.style ?? 'long',\n }),\n );\n}\n\nfunction getDurationFormatter(options: {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}): DurationFormatter | null {\n const IntlWithDurationFormat = Intl as typeof Intl & { DurationFormat?: DurationFormatterConstructor };\n\n if (!IntlWithDurationFormat.DurationFormat) return null;\n\n const cacheKey = `${String(options.locale ?? '')}|${options.style ?? ''}`;\n\n return cappedGetOrCreate(\n DURATION_FORMATTER_CACHE,\n cacheKey,\n () => new IntlWithDurationFormat.DurationFormat!(options.locale, { style: options.style }),\n );\n}\n\n// ─── Time scale constants ─────────────────────────────────────────────────────\n\nconst SECONDS_PER_MINUTE = 60;\nconst SECONDS_PER_HOUR = 3_600;\nconst SECONDS_PER_DAY = 86_400;\nconst SECONDS_PER_WEEK = 604_800;\nconst SECONDS_PER_MONTH = 2_629_800; // ≈ 30.4375 days × 86400\nconst SECONDS_PER_YEAR = 31_557_600; // 365.25 days × 86400\n\n// ─── Relative time helpers ────────────────────────────────────────────────────\n\nconst RELATIVE_UNITS: ReadonlyArray<{ scale: number; thresholdToPromote: number; unit: Intl.RelativeTimeFormatUnit }> =\n [\n { scale: 1, thresholdToPromote: SECONDS_PER_MINUTE, unit: 'second' },\n { scale: SECONDS_PER_MINUTE, thresholdToPromote: SECONDS_PER_HOUR / SECONDS_PER_MINUTE, unit: 'minute' },\n { scale: SECONDS_PER_HOUR, thresholdToPromote: SECONDS_PER_DAY / SECONDS_PER_HOUR, unit: 'hour' },\n { scale: SECONDS_PER_DAY, thresholdToPromote: SECONDS_PER_WEEK / SECONDS_PER_DAY, unit: 'day' },\n { scale: SECONDS_PER_WEEK, thresholdToPromote: SECONDS_PER_MONTH / SECONDS_PER_WEEK, unit: 'week' },\n { scale: SECONDS_PER_MONTH, thresholdToPromote: 12, unit: 'month' },\n { scale: SECONDS_PER_YEAR, thresholdToPromote: Number.POSITIVE_INFINITY, unit: 'year' },\n ];\n\nfunction toRelativeUnit(seconds: number): { unit: Intl.RelativeTimeFormatUnit; value: number } {\n if (!Number.isFinite(seconds)) fail('formatRelative received a non-finite time difference.');\n\n const roundedSeconds = Math.round(seconds);\n\n for (const { scale, thresholdToPromote, unit } of RELATIVE_UNITS) {\n const value = Math.round(roundedSeconds / scale);\n\n if (Math.abs(value) < thresholdToPromote) return { unit, value };\n }\n\n return { unit: 'year', value: Math.round(roundedSeconds / SECONDS_PER_YEAR) };\n}\n\n// ─── Duration fallback renderer ───────────────────────────────────────────────\n\n// All English duration unit names follow the same pluralization rule: singular = plural.slice(0, -1)\nconst DURATION_UNITS = [\n 'years',\n 'months',\n 'weeks',\n 'days',\n 'hours',\n 'minutes',\n 'seconds',\n 'milliseconds',\n 'microseconds',\n 'nanoseconds',\n] as const satisfies ReadonlyArray<keyof Temporal.Duration>;\n\n// English-only fallback; runs only when Intl.DurationFormat is unavailable in the runtime.\nfunction buildDurationFallback(duration: Temporal.Duration): string {\n const parts: string[] = [];\n\n for (const unit of DURATION_UNITS) {\n const value = Math.abs(duration[unit] as number);\n\n if (value !== 0) parts.push(`${value} ${value === 1 ? unit.slice(0, -1) : unit}`);\n }\n\n return parts.length === 0 ? '0 seconds' : parts.join(', ');\n}\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/**\n * Resolves a shared display timezone for two-input range functions.\n * Throws when both inputs are `ZonedDateTime` with different zones and no `options.tz` override.\n */\nfunction resolveRangeTz(start: TimeInput, end: TimeInput, options: FormatOptions, caller: string): string | undefined {\n if (options.tz) return options.tz;\n\n const startTz = start instanceof Temporal.ZonedDateTime ? start.timeZoneId : undefined;\n const endTz = end instanceof Temporal.ZonedDateTime ? end.timeZoneId : undefined;\n\n if (startTz && endTz && startTz !== endTz) {\n fail(`${caller} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`);\n }\n\n return startTz ?? endTz;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Formats `input` using `Intl.DateTimeFormat`. Defaults to `pattern: 'medium'`.\n *\n * Pass `intl` for full `Intl.DateTimeFormatOptions` control (mutually exclusive with `pattern`).\n * The timezone is inferred from a `ZonedDateTime` input or from `options.tz`.\n *\n * @example\n * ```ts\n * format(parseInstant('2026-03-21T10:15:30Z'), { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:15'\n * ```\n */\nexport function format(input: TimeInput, options: FormatOptions = {}): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).format(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Formats a time span between `start` and `end` using `Intl.DateTimeFormat.formatRange`.\n *\n * @example\n * ```ts\n * formatRange(start, end, { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:00 – 12:00'\n * ```\n */\nexport function formatRange(start: TimeInput, end: TimeInput, options: FormatOptions = {}): string {\n const tz = resolveRangeTz(start, end, options, 'formatRange');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRange(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Returns the raw `Intl.DateTimeRangeFormatPart[]` array for a time span, enabling\n * fine-grained rendering of range start, end, and shared parts separately.\n *\n * @example\n * ```ts\n * formatRangeParts(start, end, { locale: 'en-US', pattern: 'short', tz: 'UTC' })\n * // [{ type: 'month', value: '3', source: 'startRange' }, ...]\n * ```\n */\nexport function formatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options: FormatOptions = {},\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']> {\n const tz = resolveRangeTz(start, end, options, 'formatRangeParts');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRangeToParts(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Serializes `input` to a UTC ISO 8601 instant string (`2026-03-21T10:15:30Z`).\n * Requires `options.tz` when input is a `PlainDate` or `PlainDateTime`.\n *\n * @example\n * ```ts\n * formatInstant(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T10:15:30Z'\n * ```\n */\nexport function formatInstant(input: TimeInput, options: TimeOptions = {}): string {\n return toInstant(input, options).toString();\n}\n\n/**\n * Serializes `input` to a zoned ISO 8601 string (`2026-03-21T11:15:30+01:00[Europe/Berlin]`).\n *\n * @param options.tz - Required when `input` is a `PlainDate` or `PlainDateTime`.\n * Inferred automatically from a `ZonedDateTime` or `Instant` input.\n *\n * @throws {TempoError} When `input` is a `PlainDate` or `PlainDateTime` and `options.tz` is omitted.\n *\n * @example\n * ```ts\n * formatZoned(parseInstant('2026-03-21T10:15:30Z'), { tz: 'Europe/Berlin' })\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]'\n *\n * formatZoned(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]' (tz inferred)\n * ```\n */\nexport function formatZoned(input: TimeInput, options: TimeOptions = {}): string {\n const tz = inferTimeZone(input, options);\n\n return toZoned(input, { tz }).toString();\n}\n\n/**\n * Formats `input` relative to `options.base` (defaults to now) using `Intl.RelativeTimeFormat`.\n *\n * @example\n * ```ts\n * formatRelative(parseInstant('2026-03-21T12:00:00Z'), {\n * base: parseInstant('2026-03-21T10:00:00Z'),\n * locale: 'en-US',\n * numeric: 'always',\n * })\n * // 'in 2 hours'\n * ```\n */\nexport function formatRelative(input: RelativeTimeInput, options: RelativeFormatOptions = {}): string {\n const target = input instanceof Temporal.Instant ? input : input.toInstant();\n const base = options.base\n ? options.base instanceof Temporal.Instant\n ? options.base\n : options.base.toInstant()\n : Temporal.Now.instant();\n const differenceInSeconds = (target.epochMilliseconds - base.epochMilliseconds) / 1000;\n const { unit, value } = toRelativeUnit(differenceInSeconds);\n\n return getRelativeFormatter(options).format(value, unit);\n}\n\n/**\n * Parses an ISO duration string or `Temporal.DurationLike` into a `Temporal.Duration`.\n *\n * @example\n * ```ts\n * parseDuration('PT2H30M').toString() // 'PT2H30M'\n * parseDuration({ hours: 2, minutes: 30 }).toString() // 'PT2H30M'\n * ```\n */\nexport function parseDuration(input: string | Temporal.DurationLike): Temporal.Duration {\n try {\n return Temporal.Duration.from(input);\n } catch {\n fail(`Invalid duration input: \"${String(input)}\". Expected an ISO 8601 duration string or Temporal.DurationLike.`);\n }\n}\n\n/**\n * Formats a duration using `Intl.DurationFormat` when available, falling back to\n * a human-readable plain-English string.\n *\n * @example\n * ```ts\n * formatDuration('PT2H30M', { locale: 'en-US', style: 'long' })\n * // '2 hours, 30 minutes'\n * ```\n */\nexport function formatDuration(input: string | Temporal.DurationLike, options: DurationFormatOptions = {}): string {\n const duration = parseDuration(input);\n const formatter = getDurationFormatter(options);\n\n if (formatter) return formatter.format(duration);\n\n return buildDurationFallback(duration);\n}\n\n/**\n * Returns the raw `Intl.DateTimeFormatPart[]` array for `input`, enabling\n * custom rendering where individual parts (year, month, day, etc.) need\n * to be styled or composed differently.\n *\n * @example\n * ```ts\n * formatParts(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'medium', tz: 'UTC' })\n * // [{ type: 'month', value: 'Mar' }, { type: 'literal', value: ' ' }, ...]\n * ```\n */\nexport function formatParts(input: TimeInput, options: FormatOptions = {}): Intl.DateTimeFormatPart[] {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).formatToParts(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Converts a `TimeDiffResult` to a human-readable string.\n * Uses the singular unit name when value is 1, plural (unit + 's') otherwise.\n *\n * Pass `options.locale` to localize the numeric part via `Intl.NumberFormat`.\n * Unit names remain English — for fully localized output use {@link formatRelative}\n * or {@link formatDuration} instead.\n *\n * @example\n * ```ts\n * humanize({ unit: 'day', value: 1 }) // '1 day'\n * humanize({ unit: 'day', value: 3 }) // '3 days'\n * humanize({ unit: 'day', value: 3 }, { locale: 'ar' }) // '٣ days'\n * humanize({ unit: 'millisecond', value: 0 }) // '0 milliseconds'\n * ```\n */\nexport function humanize(diff: TimeDiffResult, options: { locale?: Intl.LocalesArgument } = {}): string {\n const { unit, value } = diff;\n const formatted = options.locale ? new Intl.NumberFormat(options.locale).format(value) : String(value);\n\n return `${formatted} ${value === 1 ? unit : `${unit}s`}`;\n}\n"],"mappings":"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"}
|
package/dist/format.js
CHANGED
|
@@ -151,7 +151,8 @@ function k(e, t = {}) {
|
|
|
151
151
|
return n(e, t).toString();
|
|
152
152
|
}
|
|
153
153
|
function A(e, n = {}) {
|
|
154
|
-
|
|
154
|
+
let i = t(e, n);
|
|
155
|
+
return r(e, { tz: i }).toString();
|
|
155
156
|
}
|
|
156
157
|
function j(e, t = {}) {
|
|
157
158
|
let n = e instanceof i.Instant ? e : e.toInstant(), r = t.base ? t.base instanceof i.Instant ? t.base : t.base.toInstant() : i.Now.instant(), { unit: a, value: o } = S((n.epochMilliseconds - r.epochMilliseconds) / 1e3);
|
package/dist/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","names":[],"sources":["../src/format.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type {\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n RelativeFormatOptions,\n RelativeTimeInput,\n TimeDiffResult,\n TimeInput,\n TimeOptions,\n} from './types';\n\nimport { toInstant, toZoned } from './_convert';\nimport { inferTimeZone } from './_tz';\nimport { fail } from './errors';\n\n// ─── Formatter types ──────────────────────────────────────────────────────────\n\ntype DurationFormatter = { format(value: Temporal.Duration): string };\ntype DurationFormatterConstructor = new (\n locales?: Intl.LocalesArgument,\n options?: { style?: 'digital' | 'long' | 'narrow' | 'short' },\n) => DurationFormatter;\n\n// ─── Formatter caches ─────────────────────────────────────────────────────────\n\nconst FORMATTER_CACHE_MAX = 128;\n\nfunction cappedGetOrCreate<V>(cache: Map<string, V>, key: string, factory: () => V): V {\n const cached = cache.get(key);\n\n if (cached !== undefined) return cached;\n\n if (cache.size >= FORMATTER_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n\n if (oldest !== undefined) cache.delete(oldest);\n }\n\n const value = factory();\n\n cache.set(key, value);\n\n return value;\n}\n\nconst DATE_TIME_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nconst RELATIVE_TIME_FORMATTER_CACHE = new Map<string, Intl.RelativeTimeFormat>();\nconst DURATION_FORMATTER_CACHE = new Map<string, DurationFormatter>();\n\n// ─── Format presets ───────────────────────────────────────────────────────────\n\nconst FORMAT_PRESETS: Record<FormatPattern, Intl.DateTimeFormatOptions> = {\n 'date-only': { dateStyle: 'short' },\n long: { dateStyle: 'full', timeStyle: 'long' },\n medium: { dateStyle: 'medium', timeStyle: 'short' },\n short: { dateStyle: 'short', timeStyle: 'short' },\n 'time-only': { timeStyle: 'short' },\n};\n\n// ─── Formatter factory helpers ────────────────────────────────────────────────\n\nfunction serializeIntlOptions(options: Intl.DateTimeFormatOptions): string {\n return JSON.stringify(\n Object.entries(options)\n .filter(([, value]) => value !== undefined)\n .sort(([l], [r]) => l.localeCompare(r))\n .map(([key, value]) => [key, String(value)]),\n );\n}\n\nfunction makeFormatter(options: FormatOptions, fallbackTz?: string): Intl.DateTimeFormat {\n const tz = options.tz ?? fallbackTz;\n const locale = options.locale;\n\n if (options.intl !== undefined) {\n const cacheKey = `${String(locale ?? '')}|intl|${tz ?? ''}|${serializeIntlOptions(options.intl)}`;\n\n return cappedGetOrCreate(DATE_TIME_FORMATTER_CACHE, cacheKey, () => {\n const intlOptions = tz !== undefined ? { ...options.intl, timeZone: tz } : options.intl;\n\n return new Intl.DateTimeFormat(locale, intlOptions);\n });\n }\n\n const pattern = options.pattern ?? 'medium';\n const cacheKey = `${String(locale ?? '')}|${pattern}|${tz ?? ''}`;\n\n return cappedGetOrCreate(\n DATE_TIME_FORMATTER_CACHE,\n cacheKey,\n () => new Intl.DateTimeFormat(locale, { ...FORMAT_PRESETS[pattern], timeZone: tz }),\n );\n}\n\nfunction getRelativeFormatter(options: {\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}): Intl.RelativeTimeFormat {\n const cacheKey = `${String(options.locale ?? '')}|${options.numeric ?? 'auto'}|${options.style ?? 'long'}`;\n\n return cappedGetOrCreate(\n RELATIVE_TIME_FORMATTER_CACHE,\n cacheKey,\n () =>\n new Intl.RelativeTimeFormat(options.locale, {\n numeric: options.numeric ?? 'auto',\n style: options.style ?? 'long',\n }),\n );\n}\n\nfunction getDurationFormatter(options: {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}): DurationFormatter | null {\n const IntlWithDurationFormat = Intl as typeof Intl & { DurationFormat?: DurationFormatterConstructor };\n\n if (!IntlWithDurationFormat.DurationFormat) return null;\n\n const cacheKey = `${String(options.locale ?? '')}|${options.style ?? ''}`;\n\n return cappedGetOrCreate(\n DURATION_FORMATTER_CACHE,\n cacheKey,\n () => new IntlWithDurationFormat.DurationFormat!(options.locale, { style: options.style }),\n );\n}\n\n// ─── Time scale constants ─────────────────────────────────────────────────────\n\nconst SECONDS_PER_MINUTE = 60;\nconst SECONDS_PER_HOUR = 3_600;\nconst SECONDS_PER_DAY = 86_400;\nconst SECONDS_PER_WEEK = 604_800;\nconst SECONDS_PER_MONTH = 2_629_800; // ≈ 30.4375 days × 86400\nconst SECONDS_PER_YEAR = 31_557_600; // 365.25 days × 86400\n\n// ─── Relative time helpers ────────────────────────────────────────────────────\n\nconst RELATIVE_UNITS: ReadonlyArray<{ scale: number; thresholdToPromote: number; unit: Intl.RelativeTimeFormatUnit }> =\n [\n { scale: 1, thresholdToPromote: SECONDS_PER_MINUTE, unit: 'second' },\n { scale: SECONDS_PER_MINUTE, thresholdToPromote: SECONDS_PER_HOUR / SECONDS_PER_MINUTE, unit: 'minute' },\n { scale: SECONDS_PER_HOUR, thresholdToPromote: SECONDS_PER_DAY / SECONDS_PER_HOUR, unit: 'hour' },\n { scale: SECONDS_PER_DAY, thresholdToPromote: SECONDS_PER_WEEK / SECONDS_PER_DAY, unit: 'day' },\n { scale: SECONDS_PER_WEEK, thresholdToPromote: SECONDS_PER_MONTH / SECONDS_PER_WEEK, unit: 'week' },\n { scale: SECONDS_PER_MONTH, thresholdToPromote: 12, unit: 'month' },\n { scale: SECONDS_PER_YEAR, thresholdToPromote: Number.POSITIVE_INFINITY, unit: 'year' },\n ];\n\nfunction toRelativeUnit(seconds: number): { unit: Intl.RelativeTimeFormatUnit; value: number } {\n if (!Number.isFinite(seconds)) fail('formatRelative received a non-finite time difference.');\n\n const roundedSeconds = Math.round(seconds);\n\n for (const { scale, thresholdToPromote, unit } of RELATIVE_UNITS) {\n const value = Math.round(roundedSeconds / scale);\n\n if (Math.abs(value) < thresholdToPromote) return { unit, value };\n }\n\n return { unit: 'year', value: Math.round(roundedSeconds / SECONDS_PER_YEAR) };\n}\n\n// ─── Duration fallback renderer ───────────────────────────────────────────────\n\n// All English duration unit names follow the same pluralization rule: singular = plural.slice(0, -1)\nconst DURATION_UNITS = [\n 'years',\n 'months',\n 'weeks',\n 'days',\n 'hours',\n 'minutes',\n 'seconds',\n 'milliseconds',\n 'microseconds',\n 'nanoseconds',\n] as const satisfies ReadonlyArray<keyof Temporal.Duration>;\n\n// English-only fallback; runs only when Intl.DurationFormat is unavailable in the runtime.\nfunction buildDurationFallback(duration: Temporal.Duration): string {\n const parts: string[] = [];\n\n for (const unit of DURATION_UNITS) {\n const value = Math.abs(duration[unit] as number);\n\n if (value !== 0) parts.push(`${value} ${value === 1 ? unit.slice(0, -1) : unit}`);\n }\n\n return parts.length === 0 ? '0 seconds' : parts.join(', ');\n}\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/**\n * Resolves a shared display timezone for two-input range functions.\n * Throws when both inputs are `ZonedDateTime` with different zones and no `options.tz` override.\n */\nfunction resolveRangeTz(start: TimeInput, end: TimeInput, options: FormatOptions, caller: string): string | undefined {\n if (options.tz) return options.tz;\n\n const startTz = start instanceof Temporal.ZonedDateTime ? start.timeZoneId : undefined;\n const endTz = end instanceof Temporal.ZonedDateTime ? end.timeZoneId : undefined;\n\n if (startTz && endTz && startTz !== endTz) {\n fail(`${caller} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`);\n }\n\n return startTz ?? endTz;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Formats `input` using `Intl.DateTimeFormat`. Defaults to `pattern: 'medium'`.\n *\n * Pass `intl` for full `Intl.DateTimeFormatOptions` control (mutually exclusive with `pattern`).\n * The timezone is inferred from a `ZonedDateTime` input or from `options.tz`.\n *\n * @example\n * ```ts\n * format(parseInstant('2026-03-21T10:15:30Z'), { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:15'\n * ```\n */\nexport function format(input: TimeInput, options: FormatOptions = {}): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).format(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Formats a time span between `start` and `end` using `Intl.DateTimeFormat.formatRange`.\n *\n * @example\n * ```ts\n * formatRange(start, end, { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:00 – 12:00'\n * ```\n */\nexport function formatRange(start: TimeInput, end: TimeInput, options: FormatOptions = {}): string {\n const tz = resolveRangeTz(start, end, options, 'formatRange');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRange(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Returns the raw `Intl.DateTimeRangeFormatPart[]` array for a time span, enabling\n * fine-grained rendering of range start, end, and shared parts separately.\n *\n * @example\n * ```ts\n * formatRangeParts(start, end, { locale: 'en-US', pattern: 'short', tz: 'UTC' })\n * // [{ type: 'month', value: '3', source: 'startRange' }, ...]\n * ```\n */\nexport function formatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options: FormatOptions = {},\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']> {\n const tz = resolveRangeTz(start, end, options, 'formatRangeParts');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRangeToParts(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Serializes `input` to a UTC ISO 8601 instant string (`2026-03-21T10:15:30Z`).\n * Requires `options.tz` when input is a `PlainDate` or `PlainDateTime`.\n *\n * @example\n * ```ts\n * formatInstant(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T10:15:30Z'\n * ```\n */\nexport function formatInstant(input: TimeInput, options: TimeOptions = {}): string {\n return toInstant(input, options).toString();\n}\n\n/**\n * Serializes `input` to a zoned ISO 8601 string (`2026-03-21T11:15:30+01:00[Europe/Berlin]`).\n *\n * @param options.tz - Required when `input` is a `PlainDate` or `PlainDateTime`.\n * Inferred automatically from a `ZonedDateTime` or `Instant` input.\n *\n * @throws {TempoError} When `input` is a `PlainDate` or `PlainDateTime` and `options.tz` is omitted.\n *\n * @example\n * ```ts\n * formatZoned(parseInstant('2026-03-21T10:15:30Z'), { tz: 'Europe/Berlin' })\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]'\n *\n * formatZoned(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]' (tz inferred)\n * ```\n */\nexport function formatZoned(input: TimeInput, options: TimeOptions = {}): string {\n const tz = inferTimeZone(input, options);\n\n return toZoned(input, { tz }).toString();\n}\n\n/**\n * Formats `input` relative to `options.base` (defaults to now) using `Intl.RelativeTimeFormat`.\n *\n * @example\n * ```ts\n * formatRelative(parseInstant('2026-03-21T12:00:00Z'), {\n * base: parseInstant('2026-03-21T10:00:00Z'),\n * locale: 'en-US',\n * numeric: 'always',\n * })\n * // 'in 2 hours'\n * ```\n */\nexport function formatRelative(input: RelativeTimeInput, options: RelativeFormatOptions = {}): string {\n const target = input instanceof Temporal.Instant ? input : input.toInstant();\n const base = options.base\n ? options.base instanceof Temporal.Instant\n ? options.base\n : options.base.toInstant()\n : Temporal.Now.instant();\n const differenceInSeconds = (target.epochMilliseconds - base.epochMilliseconds) / 1000;\n const { unit, value } = toRelativeUnit(differenceInSeconds);\n\n return getRelativeFormatter(options).format(value, unit);\n}\n\n/**\n * Parses an ISO duration string or `Temporal.DurationLike` into a `Temporal.Duration`.\n *\n * @example\n * ```ts\n * parseDuration('PT2H30M').toString() // 'PT2H30M'\n * parseDuration({ hours: 2, minutes: 30 }).toString() // 'PT2H30M'\n * ```\n */\nexport function parseDuration(input: string | Temporal.DurationLike): Temporal.Duration {\n try {\n return Temporal.Duration.from(input);\n } catch {\n fail(`Invalid duration input: \"${String(input)}\". Expected an ISO 8601 duration string or Temporal.DurationLike.`);\n }\n}\n\n/**\n * Formats a duration using `Intl.DurationFormat` when available, falling back to\n * a human-readable plain-English string.\n *\n * @example\n * ```ts\n * formatDuration('PT2H30M', { locale: 'en-US', style: 'long' })\n * // '2 hours, 30 minutes'\n * ```\n */\nexport function formatDuration(input: string | Temporal.DurationLike, options: DurationFormatOptions = {}): string {\n const duration = parseDuration(input);\n const formatter = getDurationFormatter(options);\n\n if (formatter) return formatter.format(duration);\n\n return buildDurationFallback(duration);\n}\n\n/**\n * Returns the raw `Intl.DateTimeFormatPart[]` array for `input`, enabling\n * custom rendering where individual parts (year, month, day, etc.) need\n * to be styled or composed differently.\n *\n * @example\n * ```ts\n * formatParts(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'medium', tz: 'UTC' })\n * // [{ type: 'month', value: 'Mar' }, { type: 'literal', value: ' ' }, ...]\n * ```\n */\nexport function formatParts(input: TimeInput, options: FormatOptions = {}): Intl.DateTimeFormatPart[] {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).formatToParts(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Converts a `TimeDiffResult` to a human-readable string.\n * Uses the singular unit name when value is 1, plural (unit + 's') otherwise.\n *\n * Pass `options.locale` to localize the numeric part via `Intl.NumberFormat`.\n * Unit names remain English — for fully localized output use {@link formatRelative}\n * or {@link formatDuration} instead.\n *\n * @example\n * ```ts\n * humanize({ unit: 'day', value: 1 }) // '1 day'\n * humanize({ unit: 'day', value: 3 }) // '3 days'\n * humanize({ unit: 'day', value: 3 }, { locale: 'ar' }) // '٣ days'\n * humanize({ unit: 'millisecond', value: 0 }) // '0 milliseconds'\n * ```\n */\nexport function humanize(diff: TimeDiffResult, options: { locale?: Intl.LocalesArgument } = {}): string {\n const { unit, value } = diff;\n const formatted = options.locale ? new Intl.NumberFormat(options.locale).format(value) : String(value);\n\n return `${formatted} ${value === 1 ? unit : `${unit}s`}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"format.js","names":[],"sources":["../src/format.ts"],"sourcesContent":["import { Temporal } from '@js-temporal/polyfill';\n\nimport type {\n DurationFormatOptions,\n FormatOptions,\n FormatPattern,\n RelativeFormatOptions,\n RelativeTimeInput,\n TimeDiffResult,\n TimeInput,\n TimeOptions,\n} from './types';\n\nimport { toInstant, toZoned } from './_convert';\nimport { inferTimeZone } from './_tz';\nimport { fail } from './errors';\n\n// ─── Formatter types ──────────────────────────────────────────────────────────\n\ntype DurationFormatter = { format(value: Temporal.Duration): string };\ntype DurationFormatterConstructor = new (\n locales?: Intl.LocalesArgument,\n options?: { style?: 'digital' | 'long' | 'narrow' | 'short' },\n) => DurationFormatter;\n\n// ─── Formatter caches ─────────────────────────────────────────────────────────\n\nconst FORMATTER_CACHE_MAX = 128;\n\nfunction cappedGetOrCreate<V>(cache: Map<string, V>, key: string, factory: () => V): V {\n const cached = cache.get(key);\n\n if (cached !== undefined) return cached;\n\n if (cache.size >= FORMATTER_CACHE_MAX) {\n const oldest = cache.keys().next().value;\n\n if (oldest !== undefined) cache.delete(oldest);\n }\n\n const value = factory();\n\n cache.set(key, value);\n\n return value;\n}\n\nconst DATE_TIME_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nconst RELATIVE_TIME_FORMATTER_CACHE = new Map<string, Intl.RelativeTimeFormat>();\nconst DURATION_FORMATTER_CACHE = new Map<string, DurationFormatter>();\n\n// ─── Format presets ───────────────────────────────────────────────────────────\n\nconst FORMAT_PRESETS: Record<FormatPattern, Intl.DateTimeFormatOptions> = {\n 'date-only': { dateStyle: 'short' },\n long: { dateStyle: 'full', timeStyle: 'long' },\n medium: { dateStyle: 'medium', timeStyle: 'short' },\n short: { dateStyle: 'short', timeStyle: 'short' },\n 'time-only': { timeStyle: 'short' },\n};\n\n// ─── Formatter factory helpers ────────────────────────────────────────────────\n\nfunction serializeIntlOptions(options: Intl.DateTimeFormatOptions): string {\n return JSON.stringify(\n Object.entries(options)\n .filter(([, value]) => value !== undefined)\n .sort(([l], [r]) => l.localeCompare(r))\n .map(([key, value]) => [key, String(value)]),\n );\n}\n\nfunction makeFormatter(options: FormatOptions, fallbackTz?: string): Intl.DateTimeFormat {\n const tz = options.tz ?? fallbackTz;\n const locale = options.locale;\n\n if (options.intl !== undefined) {\n const cacheKey = `${String(locale ?? '')}|intl|${tz ?? ''}|${serializeIntlOptions(options.intl)}`;\n\n return cappedGetOrCreate(DATE_TIME_FORMATTER_CACHE, cacheKey, () => {\n const intlOptions = tz !== undefined ? { ...options.intl, timeZone: tz } : options.intl;\n\n return new Intl.DateTimeFormat(locale, intlOptions);\n });\n }\n\n const pattern = options.pattern ?? 'medium';\n const cacheKey = `${String(locale ?? '')}|${pattern}|${tz ?? ''}`;\n\n return cappedGetOrCreate(\n DATE_TIME_FORMATTER_CACHE,\n cacheKey,\n () => new Intl.DateTimeFormat(locale, { ...FORMAT_PRESETS[pattern], timeZone: tz }),\n );\n}\n\nfunction getRelativeFormatter(options: {\n locale?: Intl.LocalesArgument;\n numeric?: Intl.RelativeTimeFormatNumeric;\n style?: Intl.RelativeTimeFormatStyle;\n}): Intl.RelativeTimeFormat {\n const cacheKey = `${String(options.locale ?? '')}|${options.numeric ?? 'auto'}|${options.style ?? 'long'}`;\n\n return cappedGetOrCreate(\n RELATIVE_TIME_FORMATTER_CACHE,\n cacheKey,\n () =>\n new Intl.RelativeTimeFormat(options.locale, {\n numeric: options.numeric ?? 'auto',\n style: options.style ?? 'long',\n }),\n );\n}\n\nfunction getDurationFormatter(options: {\n locale?: Intl.LocalesArgument;\n style?: 'digital' | 'long' | 'narrow' | 'short';\n}): DurationFormatter | null {\n const IntlWithDurationFormat = Intl as typeof Intl & { DurationFormat?: DurationFormatterConstructor };\n\n if (!IntlWithDurationFormat.DurationFormat) return null;\n\n const cacheKey = `${String(options.locale ?? '')}|${options.style ?? ''}`;\n\n return cappedGetOrCreate(\n DURATION_FORMATTER_CACHE,\n cacheKey,\n () => new IntlWithDurationFormat.DurationFormat!(options.locale, { style: options.style }),\n );\n}\n\n// ─── Time scale constants ─────────────────────────────────────────────────────\n\nconst SECONDS_PER_MINUTE = 60;\nconst SECONDS_PER_HOUR = 3_600;\nconst SECONDS_PER_DAY = 86_400;\nconst SECONDS_PER_WEEK = 604_800;\nconst SECONDS_PER_MONTH = 2_629_800; // ≈ 30.4375 days × 86400\nconst SECONDS_PER_YEAR = 31_557_600; // 365.25 days × 86400\n\n// ─── Relative time helpers ────────────────────────────────────────────────────\n\nconst RELATIVE_UNITS: ReadonlyArray<{ scale: number; thresholdToPromote: number; unit: Intl.RelativeTimeFormatUnit }> =\n [\n { scale: 1, thresholdToPromote: SECONDS_PER_MINUTE, unit: 'second' },\n { scale: SECONDS_PER_MINUTE, thresholdToPromote: SECONDS_PER_HOUR / SECONDS_PER_MINUTE, unit: 'minute' },\n { scale: SECONDS_PER_HOUR, thresholdToPromote: SECONDS_PER_DAY / SECONDS_PER_HOUR, unit: 'hour' },\n { scale: SECONDS_PER_DAY, thresholdToPromote: SECONDS_PER_WEEK / SECONDS_PER_DAY, unit: 'day' },\n { scale: SECONDS_PER_WEEK, thresholdToPromote: SECONDS_PER_MONTH / SECONDS_PER_WEEK, unit: 'week' },\n { scale: SECONDS_PER_MONTH, thresholdToPromote: 12, unit: 'month' },\n { scale: SECONDS_PER_YEAR, thresholdToPromote: Number.POSITIVE_INFINITY, unit: 'year' },\n ];\n\nfunction toRelativeUnit(seconds: number): { unit: Intl.RelativeTimeFormatUnit; value: number } {\n if (!Number.isFinite(seconds)) fail('formatRelative received a non-finite time difference.');\n\n const roundedSeconds = Math.round(seconds);\n\n for (const { scale, thresholdToPromote, unit } of RELATIVE_UNITS) {\n const value = Math.round(roundedSeconds / scale);\n\n if (Math.abs(value) < thresholdToPromote) return { unit, value };\n }\n\n return { unit: 'year', value: Math.round(roundedSeconds / SECONDS_PER_YEAR) };\n}\n\n// ─── Duration fallback renderer ───────────────────────────────────────────────\n\n// All English duration unit names follow the same pluralization rule: singular = plural.slice(0, -1)\nconst DURATION_UNITS = [\n 'years',\n 'months',\n 'weeks',\n 'days',\n 'hours',\n 'minutes',\n 'seconds',\n 'milliseconds',\n 'microseconds',\n 'nanoseconds',\n] as const satisfies ReadonlyArray<keyof Temporal.Duration>;\n\n// English-only fallback; runs only when Intl.DurationFormat is unavailable in the runtime.\nfunction buildDurationFallback(duration: Temporal.Duration): string {\n const parts: string[] = [];\n\n for (const unit of DURATION_UNITS) {\n const value = Math.abs(duration[unit] as number);\n\n if (value !== 0) parts.push(`${value} ${value === 1 ? unit.slice(0, -1) : unit}`);\n }\n\n return parts.length === 0 ? '0 seconds' : parts.join(', ');\n}\n\n// ─── Private helpers ──────────────────────────────────────────────────────────\n\n/**\n * Resolves a shared display timezone for two-input range functions.\n * Throws when both inputs are `ZonedDateTime` with different zones and no `options.tz` override.\n */\nfunction resolveRangeTz(start: TimeInput, end: TimeInput, options: FormatOptions, caller: string): string | undefined {\n if (options.tz) return options.tz;\n\n const startTz = start instanceof Temporal.ZonedDateTime ? start.timeZoneId : undefined;\n const endTz = end instanceof Temporal.ZonedDateTime ? end.timeZoneId : undefined;\n\n if (startTz && endTz && startTz !== endTz) {\n fail(`${caller} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`);\n }\n\n return startTz ?? endTz;\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Formats `input` using `Intl.DateTimeFormat`. Defaults to `pattern: 'medium'`.\n *\n * Pass `intl` for full `Intl.DateTimeFormatOptions` control (mutually exclusive with `pattern`).\n * The timezone is inferred from a `ZonedDateTime` input or from `options.tz`.\n *\n * @example\n * ```ts\n * format(parseInstant('2026-03-21T10:15:30Z'), { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:15'\n * ```\n */\nexport function format(input: TimeInput, options: FormatOptions = {}): string {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).format(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Formats a time span between `start` and `end` using `Intl.DateTimeFormat.formatRange`.\n *\n * @example\n * ```ts\n * formatRange(start, end, { locale: 'en-GB', pattern: 'short', tz: 'UTC' })\n * // '21/03/2026, 10:00 – 12:00'\n * ```\n */\nexport function formatRange(start: TimeInput, end: TimeInput, options: FormatOptions = {}): string {\n const tz = resolveRangeTz(start, end, options, 'formatRange');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRange(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Returns the raw `Intl.DateTimeRangeFormatPart[]` array for a time span, enabling\n * fine-grained rendering of range start, end, and shared parts separately.\n *\n * @example\n * ```ts\n * formatRangeParts(start, end, { locale: 'en-US', pattern: 'short', tz: 'UTC' })\n * // [{ type: 'month', value: '3', source: 'startRange' }, ...]\n * ```\n */\nexport function formatRangeParts(\n start: TimeInput,\n end: TimeInput,\n options: FormatOptions = {},\n): ReturnType<Intl.DateTimeFormat['formatRangeToParts']> {\n const tz = resolveRangeTz(start, end, options, 'formatRangeParts');\n const formatter = makeFormatter(options, tz);\n\n return formatter.formatRangeToParts(\n new Date(toInstant(start, { tz }).epochMilliseconds),\n new Date(toInstant(end, { tz }).epochMilliseconds),\n );\n}\n\n/**\n * Serializes `input` to a UTC ISO 8601 instant string (`2026-03-21T10:15:30Z`).\n * Requires `options.tz` when input is a `PlainDate` or `PlainDateTime`.\n *\n * @example\n * ```ts\n * formatInstant(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T10:15:30Z'\n * ```\n */\nexport function formatInstant(input: TimeInput, options: TimeOptions = {}): string {\n return toInstant(input, options).toString();\n}\n\n/**\n * Serializes `input` to a zoned ISO 8601 string (`2026-03-21T11:15:30+01:00[Europe/Berlin]`).\n *\n * @param options.tz - Required when `input` is a `PlainDate` or `PlainDateTime`.\n * Inferred automatically from a `ZonedDateTime` or `Instant` input.\n *\n * @throws {TempoError} When `input` is a `PlainDate` or `PlainDateTime` and `options.tz` is omitted.\n *\n * @example\n * ```ts\n * formatZoned(parseInstant('2026-03-21T10:15:30Z'), { tz: 'Europe/Berlin' })\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]'\n *\n * formatZoned(parseZoned('2026-03-21T11:15:30+01:00[Europe/Berlin]'))\n * // '2026-03-21T11:15:30+01:00[Europe/Berlin]' (tz inferred)\n * ```\n */\nexport function formatZoned(input: TimeInput, options: TimeOptions = {}): string {\n const tz = inferTimeZone(input, options);\n\n return toZoned(input, { tz }).toString();\n}\n\n/**\n * Formats `input` relative to `options.base` (defaults to now) using `Intl.RelativeTimeFormat`.\n *\n * @example\n * ```ts\n * formatRelative(parseInstant('2026-03-21T12:00:00Z'), {\n * base: parseInstant('2026-03-21T10:00:00Z'),\n * locale: 'en-US',\n * numeric: 'always',\n * })\n * // 'in 2 hours'\n * ```\n */\nexport function formatRelative(input: RelativeTimeInput, options: RelativeFormatOptions = {}): string {\n const target = input instanceof Temporal.Instant ? input : input.toInstant();\n const base = options.base\n ? options.base instanceof Temporal.Instant\n ? options.base\n : options.base.toInstant()\n : Temporal.Now.instant();\n const differenceInSeconds = (target.epochMilliseconds - base.epochMilliseconds) / 1000;\n const { unit, value } = toRelativeUnit(differenceInSeconds);\n\n return getRelativeFormatter(options).format(value, unit);\n}\n\n/**\n * Parses an ISO duration string or `Temporal.DurationLike` into a `Temporal.Duration`.\n *\n * @example\n * ```ts\n * parseDuration('PT2H30M').toString() // 'PT2H30M'\n * parseDuration({ hours: 2, minutes: 30 }).toString() // 'PT2H30M'\n * ```\n */\nexport function parseDuration(input: string | Temporal.DurationLike): Temporal.Duration {\n try {\n return Temporal.Duration.from(input);\n } catch {\n fail(`Invalid duration input: \"${String(input)}\". Expected an ISO 8601 duration string or Temporal.DurationLike.`);\n }\n}\n\n/**\n * Formats a duration using `Intl.DurationFormat` when available, falling back to\n * a human-readable plain-English string.\n *\n * @example\n * ```ts\n * formatDuration('PT2H30M', { locale: 'en-US', style: 'long' })\n * // '2 hours, 30 minutes'\n * ```\n */\nexport function formatDuration(input: string | Temporal.DurationLike, options: DurationFormatOptions = {}): string {\n const duration = parseDuration(input);\n const formatter = getDurationFormatter(options);\n\n if (formatter) return formatter.format(duration);\n\n return buildDurationFallback(duration);\n}\n\n/**\n * Returns the raw `Intl.DateTimeFormatPart[]` array for `input`, enabling\n * custom rendering where individual parts (year, month, day, etc.) need\n * to be styled or composed differently.\n *\n * @example\n * ```ts\n * formatParts(parseInstant('2026-03-21T10:15:30Z'), { pattern: 'medium', tz: 'UTC' })\n * // [{ type: 'month', value: 'Mar' }, { type: 'literal', value: ' ' }, ...]\n * ```\n */\nexport function formatParts(input: TimeInput, options: FormatOptions = {}): Intl.DateTimeFormatPart[] {\n const tz = options.tz ?? (input instanceof Temporal.ZonedDateTime ? input.timeZoneId : undefined);\n\n return makeFormatter(options, tz).formatToParts(new Date(toInstant(input, { tz }).epochMilliseconds));\n}\n\n/**\n * Converts a `TimeDiffResult` to a human-readable string.\n * Uses the singular unit name when value is 1, plural (unit + 's') otherwise.\n *\n * Pass `options.locale` to localize the numeric part via `Intl.NumberFormat`.\n * Unit names remain English — for fully localized output use {@link formatRelative}\n * or {@link formatDuration} instead.\n *\n * @example\n * ```ts\n * humanize({ unit: 'day', value: 1 }) // '1 day'\n * humanize({ unit: 'day', value: 3 }) // '3 days'\n * humanize({ unit: 'day', value: 3 }, { locale: 'ar' }) // '٣ days'\n * humanize({ unit: 'millisecond', value: 0 }) // '0 milliseconds'\n * ```\n */\nexport function humanize(diff: TimeDiffResult, options: { locale?: Intl.LocalesArgument } = {}): string {\n const { unit, value } = diff;\n const formatted = options.locale ? new Intl.NumberFormat(options.locale).format(value) : String(value);\n\n return `${formatted} ${value === 1 ? unit : `${unit}s`}`;\n}\n"],"mappings":"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"}
|
package/dist/tempo.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@js-temporal/polyfill");var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{},r=class extends t{},i=class extends t{},a=class extends t{};function o(e,t=n){throw new t(e)}function s(t){try{e.Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(t)}catch{o(`Unknown or invalid timezone: "${t}". Expected an IANA timezone name (e.g. "America/New_York") or UTC offset (e.g. "+05:30").`,r)}return t}function c(t,n){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return r||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),s(r)}function l(t,n){if(n.tz)return s(n.tz);let r;for(let n of t){if(!(n instanceof e.Temporal.ZonedDateTime))continue;let t=n.timeZoneId;if(!r){r=t;continue}r!==t&&o(`Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`)}return r||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),r}function u(t,n){return e.Temporal.Instant.compare(t,n)<=0?[t,n]:[n,t]}var d=new Set([`day`,`month`,`week`,`year`]),f=30.4375*864e5;function p(t,n={}){if(t instanceof e.Temporal.Instant)return t;if(t instanceof e.Temporal.ZonedDateTime)return t.toInstant();if(t instanceof e.Temporal.PlainDateTime)return n.tz||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),t.toZonedDateTime(s(n.tz),{disambiguation:n.prefer}).toInstant();if(t instanceof e.Temporal.PlainDate)return n.tz||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),t.toZonedDateTime({timeZone:s(n.tz)}).toInstant();o(`Unsupported time input type: ${String(t)}`,a)}function m(t,n){let r=n,i=s(r.tz);if(t instanceof e.Temporal.ZonedDateTime)return t.withTimeZone(i);if(t instanceof e.Temporal.PlainDateTime)return t.toZonedDateTime(i,{disambiguation:r.prefer});if(t instanceof e.Temporal.PlainDate)return t.toZonedDateTime({timeZone:i});if(t instanceof e.Temporal.Instant)return t.toZonedDateTimeISO(i);o(`Unsupported time input type: ${String(t)}`,a)}function ee(e,t){return m(e,{tz:t})}function h(t){return e.Temporal.Now.zonedDateTimeISO(t)}function g(){return e.Temporal.Now.instant()}function _(t){try{return e.Temporal.ZonedDateTime.from(t)}catch{o(`Invalid zoned date-time string: "${t}". Expected an ISO 8601 string with offset and timezone (e.g. 2026-03-21T10:00:00+01:00[Europe/Berlin]).`)}}function v(t){try{return e.Temporal.PlainDate.from(t)}catch{o(`Invalid plain date string: "${t}". Expected an ISO 8601 date string (e.g. YYYY-MM-DD).`)}}function y(t){try{return e.Temporal.PlainDateTime.from(t)}catch{o(`Invalid date/time string: "${t}". Expected an ISO 8601 date or date-time string (e.g. YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss).`)}}function b(t){try{return e.Temporal.Instant.from(t)}catch{o(`Invalid instant string: "${t}". Expected an ISO 8601 UTC string (e.g. YYYY-MM-DDTHH:mm:ssZ).`)}}function te(e,t,n={}){let r=c(e,n);return m(e,{prefer:n.prefer,tz:r}).add(t)}function x(t,n,r={}){let{largestUnit:i,prefer:a,roundingIncrement:o,roundingMode:s,smallestUnit:c}=r,u={largestUnit:i,roundingIncrement:o,roundingMode:s,smallestUnit:c};if(!(i!==void 0&&d.has(i)||c!==void 0&&d.has(c))&&t instanceof e.Temporal.Instant&&n instanceof e.Temporal.Instant)return n.since(t,u);let f=l([t,n],r);return m(n,{prefer:a,tz:f}).since(m(t,{prefer:a,tz:f}),u)}function S(t){return t instanceof e.Temporal.Instant||t instanceof e.Temporal.ZonedDateTime||t instanceof e.Temporal.PlainDateTime||t instanceof e.Temporal.PlainDate}function C(t,n){if(n===`zoned`)return _(t);if(n===`instant`)return b(t);if(n===`plain-datetime`)return y(t);if(n===`plain-date`)return v(t);try{return e.Temporal.ZonedDateTime.from(t)}catch{}try{return e.Temporal.Instant.from(t)}catch{}if(t.includes(`T`))try{return e.Temporal.PlainDateTime.from(t)}catch{}else try{return e.Temporal.PlainDate.from(t)}catch{}o(`Unable to parse date/time string: "${t}". Expected ISO 8601 ZonedDateTime, Instant, PlainDateTime, or PlainDate.`)}var w={hour:0,microsecond:0,millisecond:0,minute:0,nanosecond:0,second:0},T={day:w,hour:{microsecond:0,millisecond:0,minute:0,nanosecond:0,second:0},minute:{microsecond:0,millisecond:0,nanosecond:0,second:0},month:{...w,day:1},year:{...w,day:1,month:1}};function E(e,t,n){let r=m(e,{prefer:n.prefer,tz:n.tz});if(t===`week`){let e=(r.dayOfWeek-(n.weekStartsOn??1)+7)%7;return r.subtract({days:e}).with(w).toInstant()}return r.with(T[t]).toInstant()}var D={day:{days:1},hour:{hours:1},minute:{minutes:1},month:{months:1},week:{weeks:1},year:{years:1}};function O(e,t,n={}){let r=c(e,n);return E(e,t,{tz:r,weekStartsOn:n.weekStartsOn}).toZonedDateTimeISO(r)}function ne(e,t,n={}){let r=c(e,n);return E(e,t,{tz:r,weekStartsOn:n.weekStartsOn}).toZonedDateTimeISO(r).add(D[t]).subtract({nanoseconds:1})}function re(e,t,n,r){let i={tz:l([e,t],r),weekStartsOn:r.weekStartsOn};return{left:E(e,n,i),right:E(t,n,i)}}function k(e,t,n,r,i){let a={tz:l([e,t,n],i),weekStartsOn:i.weekStartsOn},o=E(e,r,a),[s,c]=u(E(t,r,a),E(n,r,a));return{lower:s,target:o,upper:c}}function A(t,n,r){if(!r.unit)return e.Temporal.Instant.compare(p(t,r),p(n,r));let{left:i,right:a}=re(t,n,r.unit,r);return e.Temporal.Instant.compare(i,a)}function ie(e,t,n={}){return A(e,t,n)<0}function ae(e,t,n={}){return A(e,t,n)>0}function oe(e,t,n={}){return A(e,t,n)===0}function se(t,n,r,i={}){if(!i.unit){let a=p(t,i),[o,s]=u(p(n,i),p(r,i));return e.Temporal.Instant.compare(o,a)<=0&&e.Temporal.Instant.compare(a,s)<=0}let{lower:a,target:o,upper:s}=k(t,n,r,i.unit,i);return e.Temporal.Instant.compare(a,o)<=0&&e.Temporal.Instant.compare(o,s)<=0}function j(t,n,r,i={}){let a=t instanceof e.Temporal.ZonedDateTime,o=a?t.timeZoneId:void 0;if(!i.unit){let s=p(t,i),[c,l]=u(p(n,i),p(r,i)),d;return d=e.Temporal.Instant.compare(s,c)<0?c:e.Temporal.Instant.compare(s,l)>0?l:s,a&&o?d.toZonedDateTimeISO(o):d}let{lower:s,target:c,upper:d}=k(t,n,r,i.unit,i),f;f=e.Temporal.Instant.compare(c,s)<0?s:e.Temporal.Instant.compare(c,d)>0?d:c;let m=i.tz??o??l([t,n,r],i);return a?f.toZonedDateTimeISO(m):f}var M=128;function N(e,t,n){let r=e.get(t);if(r!==void 0)return r;if(e.size>=M){let t=e.keys().next().value;t!==void 0&&e.delete(t)}let i=n();return e.set(t,i),i}var P=new Map,F=new Map,I=new Map,L={"date-only":{dateStyle:`short`},long:{dateStyle:`full`,timeStyle:`long`},medium:{dateStyle:`medium`,timeStyle:`short`},short:{dateStyle:`short`,timeStyle:`short`},"time-only":{timeStyle:`short`}};function R(e){return JSON.stringify(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,String(t)]))}function z(e,t){let n=e.tz??t,r=e.locale;if(e.intl!==void 0)return N(P,`${String(r??``)}|intl|${n??``}|${R(e.intl)}`,()=>{let t=n===void 0?e.intl:{...e.intl,timeZone:n};return new Intl.DateTimeFormat(r,t)});let i=e.pattern??`medium`;return N(P,`${String(r??``)}|${i}|${n??``}`,()=>new Intl.DateTimeFormat(r,{...L[i],timeZone:n}))}function B(e){return N(F,`${String(e.locale??``)}|${e.numeric??`auto`}|${e.style??`long`}`,()=>new Intl.RelativeTimeFormat(e.locale,{numeric:e.numeric??`auto`,style:e.style??`long`}))}function V(e){let t=Intl;return t.DurationFormat?N(I,`${String(e.locale??``)}|${e.style??``}`,()=>new t.DurationFormat(e.locale,{style:e.style})):null}var H=60,U=3600,W=86400,G=604800,K=2629800,q=31557600,ce=[{scale:1,thresholdToPromote:H,unit:`second`},{scale:H,thresholdToPromote:U/H,unit:`minute`},{scale:U,thresholdToPromote:W/U,unit:`hour`},{scale:W,thresholdToPromote:G/W,unit:`day`},{scale:G,thresholdToPromote:K/G,unit:`week`},{scale:K,thresholdToPromote:12,unit:`month`},{scale:q,thresholdToPromote:1/0,unit:`year`}];function le(e){Number.isFinite(e)||o(`formatRelative received a non-finite time difference.`);let t=Math.round(e);for(let{scale:e,thresholdToPromote:n,unit:r}of ce){let i=Math.round(t/e);if(Math.abs(i)<n)return{unit:r,value:i}}return{unit:`year`,value:Math.round(t/q)}}var ue=[`years`,`months`,`weeks`,`days`,`hours`,`minutes`,`seconds`,`milliseconds`,`microseconds`,`nanoseconds`];function de(e){let t=[];for(let n of ue){let r=Math.abs(e[n]);r!==0&&t.push(`${r} ${r===1?n.slice(0,-1):n}`)}return t.length===0?`0 seconds`:t.join(`, `)}function J(t,n,r,i){if(r.tz)return r.tz;let a=t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0,s=n instanceof e.Temporal.ZonedDateTime?n.timeZoneId:void 0;return a&&s&&a!==s&&o(`${i} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`),a??s}function fe(t,n={}){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return z(n,r).format(new Date(p(t,{tz:r}).epochMilliseconds))}function pe(e,t,n={}){let r=J(e,t,n,`formatRange`);return z(n,r).formatRange(new Date(p(e,{tz:r}).epochMilliseconds),new Date(p(t,{tz:r}).epochMilliseconds))}function me(e,t,n={}){let r=J(e,t,n,`formatRangeParts`);return z(n,r).formatRangeToParts(new Date(p(e,{tz:r}).epochMilliseconds),new Date(p(t,{tz:r}).epochMilliseconds))}function he(e,t={}){return p(e,t).toString()}function ge(e,t={}){return m(e,{tz:c(e,t)}).toString()}function _e(t,n={}){let r=t instanceof e.Temporal.Instant?t:t.toInstant(),i=n.base?n.base instanceof e.Temporal.Instant?n.base:n.base.toInstant():e.Temporal.Now.instant(),{unit:a,value:o}=le((r.epochMilliseconds-i.epochMilliseconds)/1e3);return B(n).format(o,a)}function Y(t){try{return e.Temporal.Duration.from(t)}catch{o(`Invalid duration input: "${String(t)}". Expected an ISO 8601 duration string or Temporal.DurationLike.`)}}function ve(e,t={}){let n=Y(e),r=V(t);return r?r.format(n):de(n)}function ye(t,n={}){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return z(n,r).formatToParts(new Date(p(t,{tz:r}).epochMilliseconds))}function be(e,t={}){let{unit:n,value:r}=e;return`${t.locale?new Intl.NumberFormat(t.locale).format(r):String(r)} ${r===1?n:`${n}s`}`}var X=new WeakMap;function xe(e){let t=X.get(e);if(t)return t;let n=Object.keys(e).map(t=>({key:t,ms:Z(e[t])})).sort((e,t)=>e.ms-t.ms);return X.set(e,n),n}function Se(t,n,r={},i=e.Temporal.Now.instant()){let a=p(t,r).epochMilliseconds-i.epochMilliseconds;for(let{key:e,ms:t}of xe(n))if(a<=t)return e;return null}function Z(t){let n=e.Temporal.Duration.from(t);return(n.years??0)*12*f+(n.months??0)*f+(n.weeks??0)*7*864e5+(n.days??0)*864e5+(n.hours??0)*36e5+(n.minutes??0)*6e4+(n.seconds??0)*1e3+(n.milliseconds??0)+(n.microseconds??0)/1e3+(n.nanoseconds??0)/1e6}var Ce=[{field:`years`,unit:`year`},{field:`months`,unit:`month`},{field:`weeks`,unit:`week`},{field:`days`,unit:`day`},{field:`hours`,unit:`hour`},{field:`minutes`,unit:`minute`},{field:`seconds`,unit:`second`},{field:`milliseconds`,unit:`millisecond`}];function Q(t,n){return e.Temporal.ZonedDateTime.compare(t,n)<=0?n.since(t,{largestUnit:`year`}):t.since(n,{largestUnit:`year`})}function $(e){for(let{field:t,unit:n}of Ce){let r=Math.abs(e[t]);if(r>0)return{unit:n,value:r}}return{unit:`millisecond`,value:0}}function we(t,n,r={}){let i=n??e.Temporal.Now.instant();if(!r.tz&&t instanceof e.Temporal.Instant&&i instanceof e.Temporal.Instant)return $(Q(t.toZonedDateTimeISO(`UTC`),i.toZonedDateTimeISO(`UTC`)));let a=l([t,i],r);return $(Q(m(t,{tz:a}),m(i,{tz:a})))}function Te(t,r,i,a={}){let o=c(t,a),s=m(t,{...a,tz:o}),l=m(r,{...a,tz:o});if(e.Temporal.ZonedDateTime.compare(s.add(i),s)<=0)throw new n(`dateRange: step must advance the date forward`);return Ee(s,l,i)}function*Ee(t,n,r){let i=t;for(;e.Temporal.ZonedDateTime.compare(i,n)<=0;)yield i,i=i.add(r)}function De(e,t,n={}){let{count:r,frequency:i,interval:a=1,until:o}=t,s=c(e,n),l=i===`daily`?{days:a}:i===`weekly`?{weeks:a}:i===`monthly`?{months:a}:{years:a},u=o===void 0?void 0:p(o,{...n,tz:s});return Oe(m(e,{...n,tz:s}),l,r,u)}function*Oe(t,n,r,i){let a=t,o=0;for(;!(r!==void 0&&o>=r||i!==void 0&&e.Temporal.Instant.compare(a.toInstant(),i)>0);)yield a,o++,a=a.add(n)}exports.TempoError=t,exports.TempoInvalidInputError=n,exports.TempoInvalidTzError=r,exports.TempoMissingTzError=i,exports.TempoUnsupportedInputError=a,Object.defineProperty(exports,"Temporal",{enumerable:!0,get:function(){return e.Temporal}}),exports.clamp=j,exports.dateRange=Te,exports.difference=x,exports.endOf=ne,exports.expires=Se,exports.format=fe,exports.formatDuration=ve,exports.formatInstant=he,exports.formatParts=ye,exports.formatRange=pe,exports.formatRangeParts=me,exports.formatRelative=_e,exports.formatZoned=ge,exports.humanize=be,exports.inTz=ee,exports.isAfter=ae,exports.isBefore=ie,exports.isSame=oe,exports.isValid=S,exports.now=h,exports.nowInstant=g,exports.parse=C,exports.parseDuration=Y,exports.parseInstant=b,exports.parsePlainDate=v,exports.parsePlainDateTime=y,exports.parseZoned=_,exports.recurrence=De,exports.shift=te,exports.startOf=O,exports.timeDiff=we,exports.toInstant=p,exports.within=se;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@js-temporal/polyfill");var t=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},n=class extends t{},r=class extends t{},i=class extends t{},a=class extends t{};function o(e,t=n){throw new t(e)}function s(t){try{e.Temporal.Instant.fromEpochMilliseconds(0).toZonedDateTimeISO(t)}catch{o(`Unknown or invalid timezone: "${t}". Expected an IANA timezone name (e.g. "America/New_York") or UTC offset (e.g. "+05:30").`,r)}return t}function c(t,n){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return r||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),s(r)}function l(t,n){if(n.tz)return s(n.tz);let r;for(let n of t){if(!(n instanceof e.Temporal.ZonedDateTime))continue;let t=n.timeZoneId;if(!r){r=t;continue}r!==t&&o(`Comparison received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`)}return r||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),r}function u(t,n){return e.Temporal.Instant.compare(t,n)<=0?[t,n]:[n,t]}var d=new Set([`day`,`month`,`week`,`year`]),f=26298e5;function p(t,n={}){if(t instanceof e.Temporal.Instant)return t;if(t instanceof e.Temporal.ZonedDateTime)return t.toInstant();if(t instanceof e.Temporal.PlainDateTime)return n.tz||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),t.toZonedDateTime(s(n.tz),{disambiguation:n.prefer}).toInstant();if(t instanceof e.Temporal.PlainDate)return n.tz||o(`This operation requires a timezone. Pass options.tz or use a ZonedDateTime input.`,i),t.toZonedDateTime({timeZone:s(n.tz)}).toInstant();o(`Unsupported time input type: ${String(t)}`,a)}function m(t,n){let r=n,i=s(r.tz);if(t instanceof e.Temporal.ZonedDateTime)return t.withTimeZone(i);if(t instanceof e.Temporal.PlainDateTime)return t.toZonedDateTime(i,{disambiguation:r.prefer});if(t instanceof e.Temporal.PlainDate)return t.toZonedDateTime({timeZone:i});if(t instanceof e.Temporal.Instant)return t.toZonedDateTimeISO(i);o(`Unsupported time input type: ${String(t)}`,a)}function ee(e,t){return m(e,{tz:t})}function h(t){return e.Temporal.Now.zonedDateTimeISO(t)}function g(){return e.Temporal.Now.instant()}function _(t){try{return e.Temporal.ZonedDateTime.from(t)}catch{o(`Invalid zoned date-time string: "${t}". Expected an ISO 8601 string with offset and timezone (e.g. 2026-03-21T10:00:00+01:00[Europe/Berlin]).`)}}function v(t){try{return e.Temporal.PlainDate.from(t)}catch{o(`Invalid plain date string: "${t}". Expected an ISO 8601 date string (e.g. YYYY-MM-DD).`)}}function y(t){try{return e.Temporal.PlainDateTime.from(t)}catch{o(`Invalid date/time string: "${t}". Expected an ISO 8601 date or date-time string (e.g. YYYY-MM-DD or YYYY-MM-DDTHH:mm:ss).`)}}function b(t){try{return e.Temporal.Instant.from(t)}catch{o(`Invalid instant string: "${t}". Expected an ISO 8601 UTC string (e.g. YYYY-MM-DDTHH:mm:ssZ).`)}}function te(e,t,n={}){let r=c(e,n);return m(e,{prefer:n.prefer,tz:r}).add(t)}function x(t,n,r={}){let{largestUnit:i,prefer:a,roundingIncrement:o,roundingMode:s,smallestUnit:c}=r,u={largestUnit:i,roundingIncrement:o,roundingMode:s,smallestUnit:c};if(!(i!==void 0&&d.has(i)||c!==void 0&&d.has(c))&&t instanceof e.Temporal.Instant&&n instanceof e.Temporal.Instant)return n.since(t,u);let f=l([t,n],r);return m(n,{prefer:a,tz:f}).since(m(t,{prefer:a,tz:f}),u)}function S(t){return t instanceof e.Temporal.Instant||t instanceof e.Temporal.ZonedDateTime||t instanceof e.Temporal.PlainDateTime||t instanceof e.Temporal.PlainDate}function C(t,n){if(n===`zoned`)return _(t);if(n===`instant`)return b(t);if(n===`plain-datetime`)return y(t);if(n===`plain-date`)return v(t);try{return e.Temporal.ZonedDateTime.from(t)}catch{}try{return e.Temporal.Instant.from(t)}catch{}if(t.includes(`T`))try{return e.Temporal.PlainDateTime.from(t)}catch{}else try{return e.Temporal.PlainDate.from(t)}catch{}o(`Unable to parse date/time string: "${t}". Expected ISO 8601 ZonedDateTime, Instant, PlainDateTime, or PlainDate.`)}var w={hour:0,microsecond:0,millisecond:0,minute:0,nanosecond:0,second:0},T={day:w,hour:{microsecond:0,millisecond:0,minute:0,nanosecond:0,second:0},minute:{microsecond:0,millisecond:0,nanosecond:0,second:0},month:{...w,day:1},year:{...w,day:1,month:1}};function E(e,t,n){let r=m(e,{prefer:n.prefer,tz:n.tz});if(t===`week`){let e=(r.dayOfWeek-(n.weekStartsOn??1)+7)%7;return r.subtract({days:e}).with(w).toInstant()}return r.with(T[t]).toInstant()}var D={day:{days:1},hour:{hours:1},minute:{minutes:1},month:{months:1},week:{weeks:1},year:{years:1}};function O(e,t,n={}){let r=c(e,n);return E(e,t,{tz:r,weekStartsOn:n.weekStartsOn}).toZonedDateTimeISO(r)}function ne(e,t,n={}){let r=c(e,n);return E(e,t,{tz:r,weekStartsOn:n.weekStartsOn}).toZonedDateTimeISO(r).add(D[t]).subtract({nanoseconds:1})}function re(e,t,n,r){let i={tz:l([e,t],r),weekStartsOn:r.weekStartsOn};return{left:E(e,n,i),right:E(t,n,i)}}function k(e,t,n,r,i){let a={tz:l([e,t,n],i),weekStartsOn:i.weekStartsOn},o=E(e,r,a),[s,c]=u(E(t,r,a),E(n,r,a));return{lower:s,target:o,upper:c}}function A(t,n,r){if(!r.unit)return e.Temporal.Instant.compare(p(t,r),p(n,r));let{left:i,right:a}=re(t,n,r.unit,r);return e.Temporal.Instant.compare(i,a)}function ie(e,t,n={}){return A(e,t,n)<0}function ae(e,t,n={}){return A(e,t,n)>0}function oe(e,t,n={}){return A(e,t,n)===0}function se(t,n,r,i={}){if(!i.unit){let a=p(t,i),[o,s]=u(p(n,i),p(r,i));return e.Temporal.Instant.compare(o,a)<=0&&e.Temporal.Instant.compare(a,s)<=0}let{lower:a,target:o,upper:s}=k(t,n,r,i.unit,i);return e.Temporal.Instant.compare(a,o)<=0&&e.Temporal.Instant.compare(o,s)<=0}function j(t,n,r,i={}){let a=t instanceof e.Temporal.ZonedDateTime,o=a?t.timeZoneId:void 0;if(!i.unit){let s=p(t,i),[c,l]=u(p(n,i),p(r,i)),d;return d=e.Temporal.Instant.compare(s,c)<0?c:e.Temporal.Instant.compare(s,l)>0?l:s,a&&o?d.toZonedDateTimeISO(o):d}let{lower:s,target:c,upper:d}=k(t,n,r,i.unit,i),f;f=e.Temporal.Instant.compare(c,s)<0?s:e.Temporal.Instant.compare(c,d)>0?d:c;let m=i.tz??o??l([t,n,r],i);return a?f.toZonedDateTimeISO(m):f}var M=128;function N(e,t,n){let r=e.get(t);if(r!==void 0)return r;if(e.size>=M){let t=e.keys().next().value;t!==void 0&&e.delete(t)}let i=n();return e.set(t,i),i}var P=new Map,F=new Map,I=new Map,L={"date-only":{dateStyle:`short`},long:{dateStyle:`full`,timeStyle:`long`},medium:{dateStyle:`medium`,timeStyle:`short`},short:{dateStyle:`short`,timeStyle:`short`},"time-only":{timeStyle:`short`}};function R(e){return JSON.stringify(Object.entries(e).filter(([,e])=>e!==void 0).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,String(t)]))}function z(e,t){let n=e.tz??t,r=e.locale;if(e.intl!==void 0)return N(P,`${String(r??``)}|intl|${n??``}|${R(e.intl)}`,()=>{let t=n===void 0?e.intl:{...e.intl,timeZone:n};return new Intl.DateTimeFormat(r,t)});let i=e.pattern??`medium`;return N(P,`${String(r??``)}|${i}|${n??``}`,()=>new Intl.DateTimeFormat(r,{...L[i],timeZone:n}))}function B(e){return N(F,`${String(e.locale??``)}|${e.numeric??`auto`}|${e.style??`long`}`,()=>new Intl.RelativeTimeFormat(e.locale,{numeric:e.numeric??`auto`,style:e.style??`long`}))}function V(e){let t=Intl;return t.DurationFormat?N(I,`${String(e.locale??``)}|${e.style??``}`,()=>new t.DurationFormat(e.locale,{style:e.style})):null}var H=60,U=3600,W=86400,G=604800,K=2629800,q=31557600,ce=[{scale:1,thresholdToPromote:H,unit:`second`},{scale:H,thresholdToPromote:U/H,unit:`minute`},{scale:U,thresholdToPromote:W/U,unit:`hour`},{scale:W,thresholdToPromote:G/W,unit:`day`},{scale:G,thresholdToPromote:K/G,unit:`week`},{scale:K,thresholdToPromote:12,unit:`month`},{scale:q,thresholdToPromote:1/0,unit:`year`}];function le(e){Number.isFinite(e)||o(`formatRelative received a non-finite time difference.`);let t=Math.round(e);for(let{scale:e,thresholdToPromote:n,unit:r}of ce){let i=Math.round(t/e);if(Math.abs(i)<n)return{unit:r,value:i}}return{unit:`year`,value:Math.round(t/q)}}var ue=[`years`,`months`,`weeks`,`days`,`hours`,`minutes`,`seconds`,`milliseconds`,`microseconds`,`nanoseconds`];function de(e){let t=[];for(let n of ue){let r=Math.abs(e[n]);r!==0&&t.push(`${r} ${r===1?n.slice(0,-1):n}`)}return t.length===0?`0 seconds`:t.join(`, `)}function J(t,n,r,i){if(r.tz)return r.tz;let a=t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0,s=n instanceof e.Temporal.ZonedDateTime?n.timeZoneId:void 0;return a&&s&&a!==s&&o(`${i} received ZonedDateTime inputs with different time zones. Pass options.tz explicitly.`),a??s}function fe(t,n={}){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return z(n,r).format(new Date(p(t,{tz:r}).epochMilliseconds))}function pe(e,t,n={}){let r=J(e,t,n,`formatRange`);return z(n,r).formatRange(new Date(p(e,{tz:r}).epochMilliseconds),new Date(p(t,{tz:r}).epochMilliseconds))}function me(e,t,n={}){let r=J(e,t,n,`formatRangeParts`);return z(n,r).formatRangeToParts(new Date(p(e,{tz:r}).epochMilliseconds),new Date(p(t,{tz:r}).epochMilliseconds))}function he(e,t={}){return p(e,t).toString()}function ge(e,t={}){return m(e,{tz:c(e,t)}).toString()}function _e(t,n={}){let r=t instanceof e.Temporal.Instant?t:t.toInstant(),i=n.base?n.base instanceof e.Temporal.Instant?n.base:n.base.toInstant():e.Temporal.Now.instant(),{unit:a,value:o}=le((r.epochMilliseconds-i.epochMilliseconds)/1e3);return B(n).format(o,a)}function Y(t){try{return e.Temporal.Duration.from(t)}catch{o(`Invalid duration input: "${String(t)}". Expected an ISO 8601 duration string or Temporal.DurationLike.`)}}function ve(e,t={}){let n=Y(e),r=V(t);return r?r.format(n):de(n)}function ye(t,n={}){let r=n.tz??(t instanceof e.Temporal.ZonedDateTime?t.timeZoneId:void 0);return z(n,r).formatToParts(new Date(p(t,{tz:r}).epochMilliseconds))}function be(e,t={}){let{unit:n,value:r}=e;return`${t.locale?new Intl.NumberFormat(t.locale).format(r):String(r)} ${r===1?n:`${n}s`}`}var X=new WeakMap;function xe(e){let t=X.get(e);if(t)return t;let n=Object.keys(e).map(t=>({key:t,ms:Z(e[t])})).sort((e,t)=>e.ms-t.ms);return X.set(e,n),n}function Se(t,n,r={},i=e.Temporal.Now.instant()){let a=p(t,r).epochMilliseconds-i.epochMilliseconds;for(let{key:e,ms:t}of xe(n))if(a<=t)return e;return null}function Z(t){let n=e.Temporal.Duration.from(t);return(n.years??0)*12*f+(n.months??0)*f+(n.weeks??0)*7*864e5+(n.days??0)*864e5+(n.hours??0)*36e5+(n.minutes??0)*6e4+(n.seconds??0)*1e3+(n.milliseconds??0)+(n.microseconds??0)/1e3+(n.nanoseconds??0)/1e6}var Ce=[{field:`years`,unit:`year`},{field:`months`,unit:`month`},{field:`weeks`,unit:`week`},{field:`days`,unit:`day`},{field:`hours`,unit:`hour`},{field:`minutes`,unit:`minute`},{field:`seconds`,unit:`second`},{field:`milliseconds`,unit:`millisecond`}];function Q(t,n){return e.Temporal.ZonedDateTime.compare(t,n)<=0?n.since(t,{largestUnit:`year`}):t.since(n,{largestUnit:`year`})}function $(e){for(let{field:t,unit:n}of Ce){let r=Math.abs(e[t]);if(r>0)return{unit:n,value:r}}return{unit:`millisecond`,value:0}}function we(t,n,r={}){let i=n??e.Temporal.Now.instant();if(!r.tz&&t instanceof e.Temporal.Instant&&i instanceof e.Temporal.Instant)return $(Q(t.toZonedDateTimeISO(`UTC`),i.toZonedDateTimeISO(`UTC`)));let a=l([t,i],r);return $(Q(m(t,{tz:a}),m(i,{tz:a})))}function Te(t,r,i,a={}){let o=c(t,a),s=m(t,{...a,tz:o}),l=m(r,{...a,tz:o});if(e.Temporal.ZonedDateTime.compare(s.add(i),s)<=0)throw new n(`dateRange: step must advance the date forward`);return Ee(s,l,i)}function*Ee(t,n,r){let i=t;for(;e.Temporal.ZonedDateTime.compare(i,n)<=0;)yield i,i=i.add(r)}function De(e,t,n={}){let{count:r,frequency:i,interval:a=1,until:o}=t,s=c(e,n),l=i===`daily`?{days:a}:i===`weekly`?{weeks:a}:i===`monthly`?{months:a}:{years:a},u=o===void 0?void 0:p(o,{...n,tz:s});return Oe(m(e,{...n,tz:s}),l,r,u)}function*Oe(t,n,r,i){let a=t,o=0;for(;!(r!==void 0&&o>=r||i!==void 0&&e.Temporal.Instant.compare(a.toInstant(),i)>0);)yield a,o++,a=a.add(n)}exports.TempoError=t,exports.TempoInvalidInputError=n,exports.TempoInvalidTzError=r,exports.TempoMissingTzError=i,exports.TempoUnsupportedInputError=a,Object.defineProperty(exports,"Temporal",{enumerable:!0,get:function(){return e.Temporal}}),exports.clamp=j,exports.dateRange=Te,exports.difference=x,exports.endOf=ne,exports.expires=Se,exports.format=fe,exports.formatDuration=ve,exports.formatInstant=he,exports.formatParts=ye,exports.formatRange=pe,exports.formatRangeParts=me,exports.formatRelative=_e,exports.formatZoned=ge,exports.humanize=be,exports.inTz=ee,exports.isAfter=ae,exports.isBefore=ie,exports.isSame=oe,exports.isValid=S,exports.now=h,exports.nowInstant=g,exports.parse=C,exports.parseDuration=Y,exports.parseInstant=b,exports.parsePlainDate=v,exports.parsePlainDateTime=y,exports.parseZoned=_,exports.recurrence=De,exports.shift=te,exports.startOf=O,exports.timeDiff=we,exports.toInstant=p,exports.within=se;
|
|
2
2
|
//# sourceMappingURL=tempo.cjs.map
|