@samline/date 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -7
- package/dist/browser/date.global.js +203 -19
- package/dist/browser/date.global.js.map +1 -1
- package/dist/browser/global.d.ts +2 -1
- package/dist/browser/global.js +203 -19
- package/dist/browser/global.js.map +1 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +203 -19
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +199 -19
- package/dist/react/index.js.map +1 -1
- package/dist/svelte/index.d.ts +2 -1
- package/dist/svelte/index.js +199 -19
- package/dist/svelte/index.js.map +1 -1
- package/dist/vanilla/index.d.ts +1 -1
- package/dist/vanilla/index.js +203 -19
- package/dist/vanilla/index.js.map +1 -1
- package/dist/vue/index.d.ts +2 -1
- package/dist/vue/index.js +199 -19
- package/dist/vue/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,6 +50,9 @@ var resolveLocale = (locale) => {
|
|
|
50
50
|
}
|
|
51
51
|
return asSupportedLocale(baseLocale);
|
|
52
52
|
};
|
|
53
|
+
var isLocaleLoaded = (locale) => {
|
|
54
|
+
return loadedLocales.has(locale);
|
|
55
|
+
};
|
|
53
56
|
var ensureLocaleLoaded = async (locale) => {
|
|
54
57
|
if (loadedLocales.has(locale)) {
|
|
55
58
|
return;
|
|
@@ -76,7 +79,13 @@ var createResolvedConfig = (locale, config) => ({
|
|
|
76
79
|
invalid: config?.invalid ?? DEFAULT_INVALID_DATE
|
|
77
80
|
});
|
|
78
81
|
var getInvalidDateText = (config, props) => {
|
|
79
|
-
|
|
82
|
+
if (typeof props === "object" && props !== null && "invalid" in props) {
|
|
83
|
+
const invalid = props.invalid;
|
|
84
|
+
if (invalid !== void 0) {
|
|
85
|
+
return invalid;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return config?.invalid ?? DEFAULT_INVALID_DATE;
|
|
80
89
|
};
|
|
81
90
|
var getTargetLocale = (currentLocale, props) => {
|
|
82
91
|
if (!props?.locale) {
|
|
@@ -102,29 +111,193 @@ var parseDateValue = (value, input, locale, strict) => {
|
|
|
102
111
|
}
|
|
103
112
|
return dayjs(value, [...input], locale, strict).locale(locale);
|
|
104
113
|
};
|
|
114
|
+
var getCurrentDayjs = (locale) => {
|
|
115
|
+
return dayjs().locale(locale);
|
|
116
|
+
};
|
|
117
|
+
var createParseSuccess = (parsed, locale) => {
|
|
118
|
+
return {
|
|
119
|
+
isValid: true,
|
|
120
|
+
locale,
|
|
121
|
+
date: parsed.toDate(),
|
|
122
|
+
iso: parsed.toISOString(),
|
|
123
|
+
timestamp: parsed.valueOf(),
|
|
124
|
+
format: (output = DEFAULT_FORMAT) => parsed.format(output)
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
var createParseFailure = (locale, error) => {
|
|
128
|
+
return {
|
|
129
|
+
isValid: false,
|
|
130
|
+
locale,
|
|
131
|
+
date: null,
|
|
132
|
+
iso: null,
|
|
133
|
+
timestamp: null,
|
|
134
|
+
error
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
var createDateChainSuccessState = (parsed, locale) => {
|
|
138
|
+
return {
|
|
139
|
+
isValid: true,
|
|
140
|
+
locale,
|
|
141
|
+
date: parsed.toDate(),
|
|
142
|
+
iso: parsed.toISOString(),
|
|
143
|
+
timestamp: parsed.valueOf()
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
var createDateChainFailureState = (locale, error) => {
|
|
147
|
+
return {
|
|
148
|
+
isValid: false,
|
|
149
|
+
locale,
|
|
150
|
+
date: null,
|
|
151
|
+
iso: null,
|
|
152
|
+
timestamp: null,
|
|
153
|
+
error
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
var mapChainSetUnit = (unit) => {
|
|
157
|
+
if (unit === "day") {
|
|
158
|
+
return "date";
|
|
159
|
+
}
|
|
160
|
+
return unit;
|
|
161
|
+
};
|
|
162
|
+
var createReadyError = () => {
|
|
163
|
+
return new Error("Date chain is not ready. Await chain.ready before using it with locales that may need to load.");
|
|
164
|
+
};
|
|
165
|
+
var assertDateChainReady = (state) => {
|
|
166
|
+
if (!state.ready) {
|
|
167
|
+
throw createReadyError();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
var getComparableDayjs = (value) => {
|
|
171
|
+
if (typeof value === "object" && value !== null && "toState" in value) {
|
|
172
|
+
const state = value.toState();
|
|
173
|
+
if (!state.isValid) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
return dayjs(state.date);
|
|
177
|
+
}
|
|
178
|
+
const comparable = dayjs(value);
|
|
179
|
+
if (!comparable.isValid()) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
return comparable;
|
|
183
|
+
};
|
|
184
|
+
var createDateChainApi = (state, ready) => {
|
|
185
|
+
const applyMutation = (transform) => {
|
|
186
|
+
assertDateChainReady(state);
|
|
187
|
+
if (state.current) {
|
|
188
|
+
state.current = transform(state.current);
|
|
189
|
+
}
|
|
190
|
+
return chain;
|
|
191
|
+
};
|
|
192
|
+
const compare = (other, comparator) => {
|
|
193
|
+
assertDateChainReady(state);
|
|
194
|
+
if (!state.current) {
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
const comparable = getComparableDayjs(other);
|
|
198
|
+
if (!comparable) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
return comparator(state.current, comparable);
|
|
202
|
+
};
|
|
203
|
+
const chain = {
|
|
204
|
+
ready,
|
|
205
|
+
add: (value, unit) => applyMutation((current) => current.add(value, unit)),
|
|
206
|
+
subtract: (value, unit) => applyMutation((current) => current.subtract(value, unit)),
|
|
207
|
+
set: (unit, value) => applyMutation((current) => current.set(mapChainSetUnit(unit), value)),
|
|
208
|
+
startOf: (unit) => applyMutation((current) => current.startOf(unit)),
|
|
209
|
+
endOf: (unit) => applyMutation((current) => current.endOf(unit)),
|
|
210
|
+
format: (output = DEFAULT_FORMAT) => {
|
|
211
|
+
assertDateChainReady(state);
|
|
212
|
+
if (!state.current) {
|
|
213
|
+
return state.invalid;
|
|
214
|
+
}
|
|
215
|
+
return state.current.format(output);
|
|
216
|
+
},
|
|
217
|
+
toDate: () => {
|
|
218
|
+
assertDateChainReady(state);
|
|
219
|
+
return state.current ? state.current.toDate() : null;
|
|
220
|
+
},
|
|
221
|
+
toISOString: () => {
|
|
222
|
+
assertDateChainReady(state);
|
|
223
|
+
return state.current ? state.current.toISOString() : null;
|
|
224
|
+
},
|
|
225
|
+
toTimestamp: () => {
|
|
226
|
+
assertDateChainReady(state);
|
|
227
|
+
return state.current ? state.current.valueOf() : null;
|
|
228
|
+
},
|
|
229
|
+
isValid: () => {
|
|
230
|
+
assertDateChainReady(state);
|
|
231
|
+
return state.current !== null;
|
|
232
|
+
},
|
|
233
|
+
isBefore: (other, unit) => compare(other, (current, comparable) => current.isBefore(comparable, unit)),
|
|
234
|
+
isAfter: (other, unit) => compare(other, (current, comparable) => current.isAfter(comparable, unit)),
|
|
235
|
+
isSame: (other, unit) => compare(other, (current, comparable) => current.isSame(comparable, unit)),
|
|
236
|
+
toState: () => {
|
|
237
|
+
assertDateChainReady(state);
|
|
238
|
+
if (!state.current) {
|
|
239
|
+
return createDateChainFailureState(state.locale, state.error ?? state.invalid);
|
|
240
|
+
}
|
|
241
|
+
return createDateChainSuccessState(state.current, state.locale);
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
return chain;
|
|
245
|
+
};
|
|
246
|
+
var createDateChainState = (locale, invalid, getInitialDate) => {
|
|
247
|
+
const state = {
|
|
248
|
+
locale,
|
|
249
|
+
invalid,
|
|
250
|
+
current: null,
|
|
251
|
+
ready: false,
|
|
252
|
+
error: invalid
|
|
253
|
+
};
|
|
254
|
+
const initialize = () => {
|
|
255
|
+
const parsed = getInitialDate();
|
|
256
|
+
state.ready = true;
|
|
257
|
+
if (!parsed.isValid()) {
|
|
258
|
+
state.current = null;
|
|
259
|
+
state.error = invalid;
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
state.current = parsed;
|
|
263
|
+
state.error = null;
|
|
264
|
+
};
|
|
265
|
+
if (isLocaleLoaded(locale)) {
|
|
266
|
+
initialize();
|
|
267
|
+
return {
|
|
268
|
+
state,
|
|
269
|
+
ready: Promise.resolve()
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
state,
|
|
274
|
+
ready: ensureLocaleLoaded(locale).then(() => {
|
|
275
|
+
initialize();
|
|
276
|
+
})
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
var createDateChainFromResolvedConfig = (props, config) => {
|
|
280
|
+
const locale = getTargetLocale(config.locale, props);
|
|
281
|
+
const invalid = getInvalidDateText(config, props);
|
|
282
|
+
const strict = props?.strict ?? config.strict;
|
|
283
|
+
const getInitialDate = () => {
|
|
284
|
+
if (props?.date === void 0) {
|
|
285
|
+
return getCurrentDayjs(locale);
|
|
286
|
+
}
|
|
287
|
+
return parseDateValue(props.date, props.input, locale, strict);
|
|
288
|
+
};
|
|
289
|
+
const { state, ready } = createDateChainState(locale, invalid, getInitialDate);
|
|
290
|
+
return createDateChainApi(state, ready);
|
|
291
|
+
};
|
|
105
292
|
var createFormatterParseDate = (getConfig) => {
|
|
106
293
|
return (props) => {
|
|
107
294
|
const config = getConfig();
|
|
108
295
|
const locale = getTargetLocale(config.locale, props);
|
|
109
296
|
const parsed = parseDateValue(props.date, props.input, locale, props.strict ?? config.strict);
|
|
110
297
|
if (!parsed.isValid()) {
|
|
111
|
-
return
|
|
112
|
-
isValid: false,
|
|
113
|
-
locale,
|
|
114
|
-
date: null,
|
|
115
|
-
iso: null,
|
|
116
|
-
timestamp: null,
|
|
117
|
-
error: getInvalidDateText(config, props)
|
|
118
|
-
};
|
|
298
|
+
return createParseFailure(locale, getInvalidDateText(config, props));
|
|
119
299
|
}
|
|
120
|
-
return
|
|
121
|
-
isValid: true,
|
|
122
|
-
locale,
|
|
123
|
-
date: parsed.toDate(),
|
|
124
|
-
iso: parsed.toISOString(),
|
|
125
|
-
timestamp: parsed.valueOf(),
|
|
126
|
-
format: (output = DEFAULT_FORMAT) => parsed.format(output)
|
|
127
|
-
};
|
|
300
|
+
return createParseSuccess(parsed, locale);
|
|
128
301
|
};
|
|
129
302
|
};
|
|
130
303
|
var createFormatterIsValidDate = (parseDate2) => {
|
|
@@ -137,10 +310,10 @@ var createFormatterGetDate = (getConfig) => {
|
|
|
137
310
|
const locale = getTargetLocale(config.locale, props);
|
|
138
311
|
const output = props?.output ?? DEFAULT_FORMAT;
|
|
139
312
|
if (!props) {
|
|
140
|
-
return
|
|
313
|
+
return getCurrentDayjs(locale).format(DEFAULT_FORMAT);
|
|
141
314
|
}
|
|
142
315
|
if (props.date === void 0) {
|
|
143
|
-
return
|
|
316
|
+
return getCurrentDayjs(locale).format(output);
|
|
144
317
|
}
|
|
145
318
|
const parsed = parseDate2({
|
|
146
319
|
date: props.date,
|
|
@@ -154,6 +327,11 @@ var createFormatterGetDate = (getConfig) => {
|
|
|
154
327
|
return parsed.format(output);
|
|
155
328
|
};
|
|
156
329
|
};
|
|
330
|
+
var createFormatterCreateDateChain = (getConfig) => {
|
|
331
|
+
return (props) => {
|
|
332
|
+
return createDateChainFromResolvedConfig(props, getConfig());
|
|
333
|
+
};
|
|
334
|
+
};
|
|
157
335
|
function resolveLocaleOrThrow(locale) {
|
|
158
336
|
const resolvedLocale = resolveLocale(locale);
|
|
159
337
|
if (!resolvedLocale) {
|
|
@@ -164,6 +342,10 @@ function resolveLocaleOrThrow(locale) {
|
|
|
164
342
|
return resolvedLocale;
|
|
165
343
|
}
|
|
166
344
|
var getSupportedLocales = () => SUPPORTED_LOCALES;
|
|
345
|
+
var createDateChain = (props, config) => {
|
|
346
|
+
const locale = getHelperLocale(config, props);
|
|
347
|
+
return createDateChainFromResolvedConfig(props, createResolvedConfig(locale, config));
|
|
348
|
+
};
|
|
167
349
|
var getDate = async (props, config) => {
|
|
168
350
|
const locale = getHelperLocale(config, props);
|
|
169
351
|
const formatter = createDateFormatter({ ...config, locale });
|
|
@@ -191,6 +373,7 @@ var createDateFormatter = (config) => {
|
|
|
191
373
|
getDate: createFormatterGetDate(getConfig),
|
|
192
374
|
parseDate: parseDate2,
|
|
193
375
|
isValidDate: createFormatterIsValidDate(parseDate2),
|
|
376
|
+
createDateChain: createFormatterCreateDateChain(getConfig),
|
|
194
377
|
getSupportedLocales,
|
|
195
378
|
getCurrentLocale: () => currentLocale,
|
|
196
379
|
setLocale: async (locale) => {
|
|
@@ -203,6 +386,7 @@ var createDateFormatter = (config) => {
|
|
|
203
386
|
};
|
|
204
387
|
export {
|
|
205
388
|
SUPPORTED_LOCALES,
|
|
389
|
+
createDateChain,
|
|
206
390
|
createDateFormatter,
|
|
207
391
|
getDate,
|
|
208
392
|
getSupportedLocales,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/date.ts","../src/core/locales.ts"],"sourcesContent":["import customParseFormat from 'dayjs/plugin/customParseFormat.js'\nimport dayjs from 'dayjs'\nimport type { Dayjs } from 'dayjs'\n\nimport { ensureLocaleLoaded, resolveLocale, SUPPORTED_LOCALES, type LocaleInput, type SupportedLocale } from './locales.js'\n\ndayjs.extend(customParseFormat)\ndayjs.locale('en')\n\nexport type DateValue = string | number | Date\n\ntype DateInputOptions = {\n input?: string | readonly string[]\n locale?: LocaleInput\n strict?: boolean\n}\n\nexport type DateParsingOptions = DateInputOptions & {\n date: DateValue\n}\n\nexport type GetDateOptions = DateInputOptions & {\n date?: DateValue\n output?: string\n invalid?: string\n}\n\nexport type DateFormatterConfig = {\n locale?: LocaleInput\n strict?: boolean\n invalid?: string\n}\n\ntype ResolvedDateFormatterConfig = {\n locale: SupportedLocale\n strict: boolean\n invalid: string\n}\n\nexport type DateFormatter = {\n getDate: (props?: GetDateOptions) => string\n parseDate: (props: DateParsingOptions) => ParseDateResult\n isValidDate: (props: DateParsingOptions) => boolean\n getSupportedLocales: () => readonly SupportedLocale[]\n getCurrentLocale: () => SupportedLocale\n setLocale: (locale: LocaleInput) => Promise<void>\n ready: Promise<void>\n}\n\nexport type ParseDateSuccess = {\n isValid: true\n locale: SupportedLocale\n date: Date\n iso: string\n timestamp: number\n format: (output?: string) => string\n}\n\nexport type ParseDateFailure = {\n isValid: false\n locale: SupportedLocale\n date: null\n iso: null\n timestamp: null\n error: string\n}\n\nexport type ParseDateResult = ParseDateSuccess | ParseDateFailure\n\nconst DEFAULT_FORMAT = 'YYYY-MM-DD'\nconst DEFAULT_LOCALE: SupportedLocale = 'en'\nconst DEFAULT_INVALID_DATE = 'Invalid Date'\nconst DEFAULT_STRICT = true\n\nconst createResolvedConfig = (\n locale: SupportedLocale,\n config?: DateFormatterConfig\n): ResolvedDateFormatterConfig => ({\n locale,\n strict: config?.strict ?? DEFAULT_STRICT,\n invalid: config?.invalid ?? DEFAULT_INVALID_DATE\n})\n\nconst getInvalidDateText = (config?: DateFormatterConfig, props?: GetDateOptions): string => {\n return props?.invalid ?? config?.invalid ?? DEFAULT_INVALID_DATE\n}\n\nconst getTargetLocale = (currentLocale: SupportedLocale, props?: GetDateOptions): SupportedLocale => {\n if (!props?.locale) {\n return currentLocale\n }\n\n return resolveLocaleOrThrow(props.locale)\n}\n\nconst getHelperLocale = <T extends { locale?: LocaleInput }>(\n config?: DateFormatterConfig,\n props?: T\n): SupportedLocale => {\n if (props?.locale) {\n return resolveLocaleOrThrow(props.locale)\n }\n\n if (config?.locale) {\n return resolveLocaleOrThrow(config.locale)\n }\n\n return DEFAULT_LOCALE\n}\n\nconst parseDateValue = (\n value: DateValue,\n input: DateParsingOptions['input'],\n locale: SupportedLocale,\n strict: boolean\n): Dayjs => {\n if (!input) {\n return dayjs(value).locale(locale)\n }\n\n if (typeof input === 'string') {\n return dayjs(value, input, locale, strict).locale(locale)\n }\n\n return dayjs(value, [...input], locale, strict).locale(locale)\n}\n\nconst createFormatterParseDate = (getConfig: () => ResolvedDateFormatterConfig) => {\n return (props: DateParsingOptions): ParseDateResult => {\n const config = getConfig()\n const locale = getTargetLocale(config.locale, props)\n const parsed = parseDateValue(props.date, props.input, locale, props.strict ?? config.strict)\n\n if (!parsed.isValid()) {\n return {\n isValid: false,\n locale,\n date: null,\n iso: null,\n timestamp: null,\n error: getInvalidDateText(config, props)\n }\n }\n\n return {\n isValid: true,\n locale,\n date: parsed.toDate(),\n iso: parsed.toISOString(),\n timestamp: parsed.valueOf(),\n format: (output = DEFAULT_FORMAT) => parsed.format(output)\n }\n }\n}\n\nconst createFormatterIsValidDate = (parseDate: (props: DateParsingOptions) => ParseDateResult) => {\n return (props: DateParsingOptions): boolean => parseDate(props).isValid\n}\n\nconst createFormatterGetDate = (getConfig: () => ResolvedDateFormatterConfig) => {\n const parseDate = createFormatterParseDate(getConfig)\n\n return (props?: GetDateOptions): string => {\n const config = getConfig()\n const locale = getTargetLocale(config.locale, props)\n const output = props?.output ?? DEFAULT_FORMAT\n\n if (!props) {\n return dayjs().locale(locale).format(DEFAULT_FORMAT)\n }\n\n if (props.date === undefined) {\n return dayjs().locale(locale).format(output)\n }\n\n const parsed = parseDate({\n date: props.date,\n input: props.input,\n locale: props.locale,\n strict: props.strict\n })\n\n if (!parsed.isValid) {\n return props.invalid ?? parsed.error\n }\n\n return parsed.format(output)\n }\n}\n\nfunction resolveLocaleOrThrow(locale: LocaleInput): SupportedLocale {\n const resolvedLocale = resolveLocale(locale)\n\n if (!resolvedLocale) {\n throw new Error(\n `Unsupported locale: ${locale}. The package tries an exact locale match first and then falls back to the base locale.`\n )\n }\n\n return resolvedLocale\n}\n\nexport const getSupportedLocales = (): readonly SupportedLocale[] => SUPPORTED_LOCALES\n\nexport const getDate = async (props?: GetDateOptions, config?: DateFormatterConfig): Promise<string> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.getDate(props)\n}\n\nexport const parseDate = async (\n props: DateParsingOptions,\n config?: DateFormatterConfig\n): Promise<ParseDateResult> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.parseDate(props)\n}\n\nexport const isValidDate = async (\n props: DateParsingOptions,\n config?: DateFormatterConfig\n): Promise<boolean> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.isValidDate(props)\n}\n\nexport const createDateFormatter = (config?: DateFormatterConfig): DateFormatter => {\n let currentLocale = config?.locale ? resolveLocaleOrThrow(config.locale) : DEFAULT_LOCALE\n\n const getConfig = (): ResolvedDateFormatterConfig => createResolvedConfig(currentLocale, config)\n\n const ready = ensureLocaleLoaded(currentLocale)\n const parseDate = createFormatterParseDate(getConfig)\n\n return {\n getDate: createFormatterGetDate(getConfig),\n parseDate,\n isValidDate: createFormatterIsValidDate(parseDate),\n getSupportedLocales,\n getCurrentLocale: () => currentLocale,\n setLocale: async (locale: LocaleInput) => {\n const resolvedLocale = resolveLocaleOrThrow(locale)\n\n await ensureLocaleLoaded(resolvedLocale)\n currentLocale = resolvedLocale\n },\n ready\n }\n}\n","export const SUPPORTED_LOCALES = [\n 'en',\n 'es',\n 'es-mx',\n 'fr',\n 'pt',\n 'pt-br',\n 'de',\n 'it',\n 'ja'\n] as const\n\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number]\nexport type LocaleInput = string\n\nconst loadedLocales = new Set<SupportedLocale>(['en'])\n\nconst localeLoaders: Record<SupportedLocale, (() => Promise<unknown>) | null> = {\n en: null,\n es: () => import('dayjs/locale/es.js'),\n 'es-mx': () => import('dayjs/locale/es-mx.js'),\n fr: () => import('dayjs/locale/fr.js'),\n pt: () => import('dayjs/locale/pt.js'),\n 'pt-br': () => import('dayjs/locale/pt-br.js'),\n de: () => import('dayjs/locale/de.js'),\n it: () => import('dayjs/locale/it.js'),\n ja: () => import('dayjs/locale/ja.js')\n}\n\nconst normalizeLocale = (locale: string): string => {\n return locale.trim().toLowerCase().replace(/_/g, '-')\n}\n\nconst asSupportedLocale = (locale: string): SupportedLocale | null => {\n if (!SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return null\n }\n\n return locale as SupportedLocale\n}\n\nexport const isSupportedLocale = (locale: string): boolean => {\n return resolveLocale(locale) !== null\n}\n\nexport const resolveLocale = (locale: LocaleInput): SupportedLocale | null => {\n const normalizedLocale = normalizeLocale(locale)\n const exactLocale = asSupportedLocale(normalizedLocale)\n\n if (exactLocale) {\n return exactLocale\n }\n\n const [baseLocale] = normalizedLocale.split('-')\n\n if (!baseLocale) {\n return null\n }\n\n return asSupportedLocale(baseLocale)\n}\n\nexport const markLocaleAsLoaded = (locale: SupportedLocale): void => {\n loadedLocales.add(locale)\n}\n\nexport const ensureLocaleLoaded = async (locale: SupportedLocale): Promise<void> => {\n if (loadedLocales.has(locale)) {\n return\n }\n\n const load = localeLoaders[locale]\n\n if (!load) {\n loadedLocales.add(locale)\n return\n }\n\n await load()\n loadedLocales.add(locale)\n}\n"],"mappings":"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","names":["parseDate"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/date.ts","../src/core/locales.ts"],"sourcesContent":["import customParseFormat from 'dayjs/plugin/customParseFormat.js'\nimport dayjs from 'dayjs'\nimport type { Dayjs } from 'dayjs'\n\nimport {\n ensureLocaleLoaded,\n isLocaleLoaded,\n resolveLocale,\n SUPPORTED_LOCALES,\n type LocaleInput,\n type SupportedLocale\n} from './locales.js'\n\ndayjs.extend(customParseFormat)\ndayjs.locale('en')\n\nexport type DateValue = string | number | Date\n\ntype DateInputOptions = {\n input?: string | readonly string[]\n locale?: LocaleInput\n strict?: boolean\n}\n\nexport type DateParsingOptions = DateInputOptions & {\n date: DateValue\n}\n\nexport type GetDateOptions = DateInputOptions & {\n date?: DateValue\n output?: string\n invalid?: string\n}\n\nexport type CreateDateChainOptions = DateInputOptions & {\n date?: DateValue\n invalid?: string\n}\n\nexport type DateFormatterConfig = {\n locale?: LocaleInput\n strict?: boolean\n invalid?: string\n}\n\nexport type DateChainManipulateUnit =\n | 'millisecond'\n | 'second'\n | 'minute'\n | 'hour'\n | 'day'\n | 'week'\n | 'month'\n | 'year'\n\nexport type DateChainBoundaryUnit =\n | 'year'\n | 'month'\n | 'week'\n | 'day'\n | 'hour'\n | 'minute'\n | 'second'\n\nexport type DateChainCompareUnit = DateChainBoundaryUnit | 'millisecond'\n\nexport type DateChainSetUnit =\n | 'year'\n | 'month'\n | 'day'\n | 'hour'\n | 'minute'\n | 'second'\n | 'millisecond'\n\ntype ResolvedDateFormatterConfig = {\n locale: SupportedLocale\n strict: boolean\n invalid: string\n}\n\nexport type DateChainSuccessState = {\n isValid: true\n locale: SupportedLocale\n date: Date\n iso: string\n timestamp: number\n}\n\nexport type DateChainFailureState = {\n isValid: false\n locale: SupportedLocale\n date: null\n iso: null\n timestamp: null\n error: string\n}\n\nexport type DateChainState = DateChainSuccessState | DateChainFailureState\n\nexport type DateChain = {\n ready: Promise<void>\n add: (value: number, unit: DateChainManipulateUnit) => DateChain\n subtract: (value: number, unit: DateChainManipulateUnit) => DateChain\n set: (unit: DateChainSetUnit, value: number) => DateChain\n startOf: (unit: DateChainBoundaryUnit) => DateChain\n endOf: (unit: DateChainBoundaryUnit) => DateChain\n format: (output?: string) => string\n toDate: () => Date | null\n toISOString: () => string | null\n toTimestamp: () => number | null\n isValid: () => boolean\n isBefore: (other: DateChainComparable, unit?: DateChainCompareUnit) => boolean\n isAfter: (other: DateChainComparable, unit?: DateChainCompareUnit) => boolean\n isSame: (other: DateChainComparable, unit?: DateChainCompareUnit) => boolean\n toState: () => DateChainState\n}\n\nexport type DateChainComparable = DateValue | DateChain\n\nexport type DateFormatter = {\n getDate: (props?: GetDateOptions) => string\n parseDate: (props: DateParsingOptions) => ParseDateResult\n isValidDate: (props: DateParsingOptions) => boolean\n createDateChain: (props?: CreateDateChainOptions) => DateChain\n getSupportedLocales: () => readonly SupportedLocale[]\n getCurrentLocale: () => SupportedLocale\n setLocale: (locale: LocaleInput) => Promise<void>\n ready: Promise<void>\n}\n\nexport type ParseDateSuccess = {\n isValid: true\n locale: SupportedLocale\n date: Date\n iso: string\n timestamp: number\n format: (output?: string) => string\n}\n\nexport type ParseDateFailure = {\n isValid: false\n locale: SupportedLocale\n date: null\n iso: null\n timestamp: null\n error: string\n}\n\nexport type ParseDateResult = ParseDateSuccess | ParseDateFailure\n\ntype InternalDateChainState = {\n locale: SupportedLocale\n invalid: string\n current: Dayjs | null\n ready: boolean\n error: string | null\n}\n\nconst DEFAULT_FORMAT = 'YYYY-MM-DD'\nconst DEFAULT_LOCALE: SupportedLocale = 'en'\nconst DEFAULT_INVALID_DATE = 'Invalid Date'\nconst DEFAULT_STRICT = true\n\nconst createResolvedConfig = (\n locale: SupportedLocale,\n config?: DateFormatterConfig\n): ResolvedDateFormatterConfig => ({\n locale,\n strict: config?.strict ?? DEFAULT_STRICT,\n invalid: config?.invalid ?? DEFAULT_INVALID_DATE\n})\n\nconst getInvalidDateText = <T>(config?: DateFormatterConfig, props?: T): string => {\n if (typeof props === 'object' && props !== null && 'invalid' in props) {\n const invalid = (props as { invalid?: string }).invalid\n\n if (invalid !== undefined) {\n return invalid\n }\n }\n\n return config?.invalid ?? DEFAULT_INVALID_DATE\n}\n\nconst getTargetLocale = <T extends { locale?: LocaleInput }>(\n currentLocale: SupportedLocale,\n props?: T\n): SupportedLocale => {\n if (!props?.locale) {\n return currentLocale\n }\n\n return resolveLocaleOrThrow(props.locale)\n}\n\nconst getHelperLocale = <T extends { locale?: LocaleInput }>(\n config?: DateFormatterConfig,\n props?: T\n): SupportedLocale => {\n if (props?.locale) {\n return resolveLocaleOrThrow(props.locale)\n }\n\n if (config?.locale) {\n return resolveLocaleOrThrow(config.locale)\n }\n\n return DEFAULT_LOCALE\n}\n\nconst parseDateValue = (\n value: DateValue,\n input: DateParsingOptions['input'],\n locale: SupportedLocale,\n strict: boolean\n): Dayjs => {\n if (!input) {\n return dayjs(value).locale(locale)\n }\n\n if (typeof input === 'string') {\n return dayjs(value, input, locale, strict).locale(locale)\n }\n\n return dayjs(value, [...input], locale, strict).locale(locale)\n}\n\nconst getCurrentDayjs = (locale: SupportedLocale): Dayjs => {\n return dayjs().locale(locale)\n}\n\nconst createParseSuccess = (parsed: Dayjs, locale: SupportedLocale): ParseDateSuccess => {\n return {\n isValid: true,\n locale,\n date: parsed.toDate(),\n iso: parsed.toISOString(),\n timestamp: parsed.valueOf(),\n format: (output = DEFAULT_FORMAT) => parsed.format(output)\n }\n}\n\nconst createParseFailure = (locale: SupportedLocale, error: string): ParseDateFailure => {\n return {\n isValid: false,\n locale,\n date: null,\n iso: null,\n timestamp: null,\n error\n }\n}\n\nconst createDateChainSuccessState = (parsed: Dayjs, locale: SupportedLocale): DateChainSuccessState => {\n return {\n isValid: true,\n locale,\n date: parsed.toDate(),\n iso: parsed.toISOString(),\n timestamp: parsed.valueOf()\n }\n}\n\nconst createDateChainFailureState = (locale: SupportedLocale, error: string): DateChainFailureState => {\n return {\n isValid: false,\n locale,\n date: null,\n iso: null,\n timestamp: null,\n error\n }\n}\n\nconst mapChainSetUnit = (unit: DateChainSetUnit): 'year' | 'month' | 'date' | 'hour' | 'minute' | 'second' | 'millisecond' => {\n if (unit === 'day') {\n return 'date'\n }\n\n return unit\n}\n\nconst createReadyError = (): Error => {\n return new Error('Date chain is not ready. Await chain.ready before using it with locales that may need to load.')\n}\n\nconst assertDateChainReady = (state: InternalDateChainState): void => {\n if (!state.ready) {\n throw createReadyError()\n }\n}\n\nconst getComparableDayjs = (value: DateChainComparable): Dayjs | null => {\n if (typeof value === 'object' && value !== null && 'toState' in value) {\n const state = value.toState()\n\n if (!state.isValid) {\n return null\n }\n\n return dayjs(state.date)\n }\n\n const comparable = dayjs(value)\n\n if (!comparable.isValid()) {\n return null\n }\n\n return comparable\n}\n\nconst createDateChainApi = (state: InternalDateChainState, ready: Promise<void>): DateChain => {\n const applyMutation = (transform: (current: Dayjs) => Dayjs): DateChain => {\n assertDateChainReady(state)\n\n if (state.current) {\n state.current = transform(state.current)\n }\n\n return chain\n }\n\n const compare = (\n other: DateChainComparable,\n comparator: (current: Dayjs, comparable: Dayjs) => boolean\n ): boolean => {\n assertDateChainReady(state)\n\n if (!state.current) {\n return false\n }\n\n const comparable = getComparableDayjs(other)\n\n if (!comparable) {\n return false\n }\n\n return comparator(state.current, comparable)\n }\n\n const chain: DateChain = {\n ready,\n add: (value, unit) => applyMutation((current) => current.add(value, unit)),\n subtract: (value, unit) => applyMutation((current) => current.subtract(value, unit)),\n set: (unit, value) => applyMutation((current) => current.set(mapChainSetUnit(unit), value)),\n startOf: (unit) => applyMutation((current) => current.startOf(unit)),\n endOf: (unit) => applyMutation((current) => current.endOf(unit)),\n format: (output = DEFAULT_FORMAT) => {\n assertDateChainReady(state)\n\n if (!state.current) {\n return state.invalid\n }\n\n return state.current.format(output)\n },\n toDate: () => {\n assertDateChainReady(state)\n\n return state.current ? state.current.toDate() : null\n },\n toISOString: () => {\n assertDateChainReady(state)\n\n return state.current ? state.current.toISOString() : null\n },\n toTimestamp: () => {\n assertDateChainReady(state)\n\n return state.current ? state.current.valueOf() : null\n },\n isValid: () => {\n assertDateChainReady(state)\n\n return state.current !== null\n },\n isBefore: (other, unit) => compare(other, (current, comparable) => current.isBefore(comparable, unit)),\n isAfter: (other, unit) => compare(other, (current, comparable) => current.isAfter(comparable, unit)),\n isSame: (other, unit) => compare(other, (current, comparable) => current.isSame(comparable, unit)),\n toState: () => {\n assertDateChainReady(state)\n\n if (!state.current) {\n return createDateChainFailureState(state.locale, state.error ?? state.invalid)\n }\n\n return createDateChainSuccessState(state.current, state.locale)\n }\n }\n\n return chain\n}\n\nconst createDateChainState = (\n locale: SupportedLocale,\n invalid: string,\n getInitialDate: () => Dayjs\n): { state: InternalDateChainState; ready: Promise<void> } => {\n const state: InternalDateChainState = {\n locale,\n invalid,\n current: null,\n ready: false,\n error: invalid\n }\n\n const initialize = () => {\n const parsed = getInitialDate()\n\n state.ready = true\n\n if (!parsed.isValid()) {\n state.current = null\n state.error = invalid\n return\n }\n\n state.current = parsed\n state.error = null\n }\n\n if (isLocaleLoaded(locale)) {\n initialize()\n\n return {\n state,\n ready: Promise.resolve()\n }\n }\n\n return {\n state,\n ready: ensureLocaleLoaded(locale).then(() => {\n initialize()\n })\n }\n}\n\nconst createDateChainFromResolvedConfig = (\n props: CreateDateChainOptions | undefined,\n config: ResolvedDateFormatterConfig\n): DateChain => {\n const locale = getTargetLocale(config.locale, props)\n const invalid = getInvalidDateText(config, props)\n const strict = props?.strict ?? config.strict\n const getInitialDate = () => {\n if (props?.date === undefined) {\n return getCurrentDayjs(locale)\n }\n\n return parseDateValue(props.date, props.input, locale, strict)\n }\n\n const { state, ready } = createDateChainState(locale, invalid, getInitialDate)\n\n return createDateChainApi(state, ready)\n}\n\nconst createFormatterParseDate = (getConfig: () => ResolvedDateFormatterConfig) => {\n return (props: DateParsingOptions): ParseDateResult => {\n const config = getConfig()\n const locale = getTargetLocale(config.locale, props)\n const parsed = parseDateValue(props.date, props.input, locale, props.strict ?? config.strict)\n\n if (!parsed.isValid()) {\n return createParseFailure(locale, getInvalidDateText(config, props))\n }\n\n return createParseSuccess(parsed, locale)\n }\n}\n\nconst createFormatterIsValidDate = (parseDate: (props: DateParsingOptions) => ParseDateResult) => {\n return (props: DateParsingOptions): boolean => parseDate(props).isValid\n}\n\nconst createFormatterGetDate = (getConfig: () => ResolvedDateFormatterConfig) => {\n const parseDate = createFormatterParseDate(getConfig)\n\n return (props?: GetDateOptions): string => {\n const config = getConfig()\n const locale = getTargetLocale(config.locale, props)\n const output = props?.output ?? DEFAULT_FORMAT\n\n if (!props) {\n return getCurrentDayjs(locale).format(DEFAULT_FORMAT)\n }\n\n if (props.date === undefined) {\n return getCurrentDayjs(locale).format(output)\n }\n\n const parsed = parseDate({\n date: props.date,\n input: props.input,\n locale: props.locale,\n strict: props.strict\n })\n\n if (!parsed.isValid) {\n return props.invalid ?? parsed.error\n }\n\n return parsed.format(output)\n }\n}\n\nconst createFormatterCreateDateChain = (getConfig: () => ResolvedDateFormatterConfig) => {\n return (props?: CreateDateChainOptions): DateChain => {\n return createDateChainFromResolvedConfig(props, getConfig())\n }\n}\n\nfunction resolveLocaleOrThrow(locale: LocaleInput): SupportedLocale {\n const resolvedLocale = resolveLocale(locale)\n\n if (!resolvedLocale) {\n throw new Error(\n `Unsupported locale: ${locale}. The package tries an exact locale match first and then falls back to the base locale.`\n )\n }\n\n return resolvedLocale\n}\n\nexport const getSupportedLocales = (): readonly SupportedLocale[] => SUPPORTED_LOCALES\n\nexport const createDateChain = (props?: CreateDateChainOptions, config?: DateFormatterConfig): DateChain => {\n const locale = getHelperLocale(config, props)\n\n return createDateChainFromResolvedConfig(props, createResolvedConfig(locale, config))\n}\n\nexport const getDate = async (props?: GetDateOptions, config?: DateFormatterConfig): Promise<string> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.getDate(props)\n}\n\nexport const parseDate = async (\n props: DateParsingOptions,\n config?: DateFormatterConfig\n): Promise<ParseDateResult> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.parseDate(props)\n}\n\nexport const isValidDate = async (\n props: DateParsingOptions,\n config?: DateFormatterConfig\n): Promise<boolean> => {\n const locale = getHelperLocale(config, props)\n const formatter = createDateFormatter({ ...config, locale })\n\n await formatter.ready\n\n return formatter.isValidDate(props)\n}\n\nexport const createDateFormatter = (config?: DateFormatterConfig): DateFormatter => {\n let currentLocale = config?.locale ? resolveLocaleOrThrow(config.locale) : DEFAULT_LOCALE\n\n const getConfig = (): ResolvedDateFormatterConfig => createResolvedConfig(currentLocale, config)\n\n const ready = ensureLocaleLoaded(currentLocale)\n const parseDate = createFormatterParseDate(getConfig)\n\n return {\n getDate: createFormatterGetDate(getConfig),\n parseDate,\n isValidDate: createFormatterIsValidDate(parseDate),\n createDateChain: createFormatterCreateDateChain(getConfig),\n getSupportedLocales,\n getCurrentLocale: () => currentLocale,\n setLocale: async (locale: LocaleInput) => {\n const resolvedLocale = resolveLocaleOrThrow(locale)\n\n await ensureLocaleLoaded(resolvedLocale)\n currentLocale = resolvedLocale\n },\n ready\n }\n}\n","export const SUPPORTED_LOCALES = [\n 'en',\n 'es',\n 'es-mx',\n 'fr',\n 'pt',\n 'pt-br',\n 'de',\n 'it',\n 'ja'\n] as const\n\nexport type SupportedLocale = (typeof SUPPORTED_LOCALES)[number]\nexport type LocaleInput = string\n\nconst loadedLocales = new Set<SupportedLocale>(['en'])\n\nconst localeLoaders: Record<SupportedLocale, (() => Promise<unknown>) | null> = {\n en: null,\n es: () => import('dayjs/locale/es.js'),\n 'es-mx': () => import('dayjs/locale/es-mx.js'),\n fr: () => import('dayjs/locale/fr.js'),\n pt: () => import('dayjs/locale/pt.js'),\n 'pt-br': () => import('dayjs/locale/pt-br.js'),\n de: () => import('dayjs/locale/de.js'),\n it: () => import('dayjs/locale/it.js'),\n ja: () => import('dayjs/locale/ja.js')\n}\n\nconst normalizeLocale = (locale: string): string => {\n return locale.trim().toLowerCase().replace(/_/g, '-')\n}\n\nconst asSupportedLocale = (locale: string): SupportedLocale | null => {\n if (!SUPPORTED_LOCALES.includes(locale as SupportedLocale)) {\n return null\n }\n\n return locale as SupportedLocale\n}\n\nexport const isSupportedLocale = (locale: string): boolean => {\n return resolveLocale(locale) !== null\n}\n\nexport const resolveLocale = (locale: LocaleInput): SupportedLocale | null => {\n const normalizedLocale = normalizeLocale(locale)\n const exactLocale = asSupportedLocale(normalizedLocale)\n\n if (exactLocale) {\n return exactLocale\n }\n\n const [baseLocale] = normalizedLocale.split('-')\n\n if (!baseLocale) {\n return null\n }\n\n return asSupportedLocale(baseLocale)\n}\n\nexport const markLocaleAsLoaded = (locale: SupportedLocale): void => {\n loadedLocales.add(locale)\n}\n\nexport const isLocaleLoaded = (locale: SupportedLocale): boolean => {\n return loadedLocales.has(locale)\n}\n\nexport const ensureLocaleLoaded = async (locale: SupportedLocale): Promise<void> => {\n if (loadedLocales.has(locale)) {\n return\n }\n\n const load = localeLoaders[locale]\n\n if (!load) {\n loadedLocales.add(locale)\n return\n }\n\n await load()\n loadedLocales.add(locale)\n}\n"],"mappings":"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","names":["parseDate"]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { DateFormatterConfig, GetDateOptions, DateParsingOptions, ParseDateResult, SupportedLocale, LocaleInput } from '../index.js';
|
|
1
|
+
import { DateFormatterConfig, CreateDateChainOptions, DateChain, GetDateOptions, DateParsingOptions, ParseDateResult, SupportedLocale, LocaleInput } from '../index.js';
|
|
2
2
|
|
|
3
3
|
type UseDateFormatterOptions = DateFormatterConfig;
|
|
4
4
|
declare const useDateFormatter: (options?: UseDateFormatterOptions) => {
|
|
5
5
|
locale: "en" | "es" | "es-mx" | "fr" | "pt" | "pt-br" | "de" | "it" | "ja";
|
|
6
6
|
currentLocale: "en" | "es" | "es-mx" | "fr" | "pt" | "pt-br" | "de" | "it" | "ja";
|
|
7
|
+
createDateChain: (props?: CreateDateChainOptions) => DateChain;
|
|
7
8
|
getDate: (props?: GetDateOptions) => string;
|
|
8
9
|
parseDate: (props: DateParsingOptions) => ParseDateResult;
|
|
9
10
|
isValidDate: (props: DateParsingOptions) => boolean;
|
package/dist/react/index.js
CHANGED
|
@@ -50,6 +50,9 @@ var resolveLocale = (locale) => {
|
|
|
50
50
|
}
|
|
51
51
|
return asSupportedLocale(baseLocale);
|
|
52
52
|
};
|
|
53
|
+
var isLocaleLoaded = (locale) => {
|
|
54
|
+
return loadedLocales.has(locale);
|
|
55
|
+
};
|
|
53
56
|
var ensureLocaleLoaded = async (locale) => {
|
|
54
57
|
if (loadedLocales.has(locale)) {
|
|
55
58
|
return;
|
|
@@ -76,7 +79,13 @@ var createResolvedConfig = (locale, config) => ({
|
|
|
76
79
|
invalid: config?.invalid ?? DEFAULT_INVALID_DATE
|
|
77
80
|
});
|
|
78
81
|
var getInvalidDateText = (config, props) => {
|
|
79
|
-
|
|
82
|
+
if (typeof props === "object" && props !== null && "invalid" in props) {
|
|
83
|
+
const invalid = props.invalid;
|
|
84
|
+
if (invalid !== void 0) {
|
|
85
|
+
return invalid;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return config?.invalid ?? DEFAULT_INVALID_DATE;
|
|
80
89
|
};
|
|
81
90
|
var getTargetLocale = (currentLocale, props) => {
|
|
82
91
|
if (!props?.locale) {
|
|
@@ -93,29 +102,193 @@ var parseDateValue = (value, input, locale, strict) => {
|
|
|
93
102
|
}
|
|
94
103
|
return dayjs(value, [...input], locale, strict).locale(locale);
|
|
95
104
|
};
|
|
105
|
+
var getCurrentDayjs = (locale) => {
|
|
106
|
+
return dayjs().locale(locale);
|
|
107
|
+
};
|
|
108
|
+
var createParseSuccess = (parsed, locale) => {
|
|
109
|
+
return {
|
|
110
|
+
isValid: true,
|
|
111
|
+
locale,
|
|
112
|
+
date: parsed.toDate(),
|
|
113
|
+
iso: parsed.toISOString(),
|
|
114
|
+
timestamp: parsed.valueOf(),
|
|
115
|
+
format: (output = DEFAULT_FORMAT) => parsed.format(output)
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
var createParseFailure = (locale, error) => {
|
|
119
|
+
return {
|
|
120
|
+
isValid: false,
|
|
121
|
+
locale,
|
|
122
|
+
date: null,
|
|
123
|
+
iso: null,
|
|
124
|
+
timestamp: null,
|
|
125
|
+
error
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
var createDateChainSuccessState = (parsed, locale) => {
|
|
129
|
+
return {
|
|
130
|
+
isValid: true,
|
|
131
|
+
locale,
|
|
132
|
+
date: parsed.toDate(),
|
|
133
|
+
iso: parsed.toISOString(),
|
|
134
|
+
timestamp: parsed.valueOf()
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
var createDateChainFailureState = (locale, error) => {
|
|
138
|
+
return {
|
|
139
|
+
isValid: false,
|
|
140
|
+
locale,
|
|
141
|
+
date: null,
|
|
142
|
+
iso: null,
|
|
143
|
+
timestamp: null,
|
|
144
|
+
error
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
var mapChainSetUnit = (unit) => {
|
|
148
|
+
if (unit === "day") {
|
|
149
|
+
return "date";
|
|
150
|
+
}
|
|
151
|
+
return unit;
|
|
152
|
+
};
|
|
153
|
+
var createReadyError = () => {
|
|
154
|
+
return new Error("Date chain is not ready. Await chain.ready before using it with locales that may need to load.");
|
|
155
|
+
};
|
|
156
|
+
var assertDateChainReady = (state) => {
|
|
157
|
+
if (!state.ready) {
|
|
158
|
+
throw createReadyError();
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
var getComparableDayjs = (value) => {
|
|
162
|
+
if (typeof value === "object" && value !== null && "toState" in value) {
|
|
163
|
+
const state = value.toState();
|
|
164
|
+
if (!state.isValid) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
return dayjs(state.date);
|
|
168
|
+
}
|
|
169
|
+
const comparable = dayjs(value);
|
|
170
|
+
if (!comparable.isValid()) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return comparable;
|
|
174
|
+
};
|
|
175
|
+
var createDateChainApi = (state, ready) => {
|
|
176
|
+
const applyMutation = (transform) => {
|
|
177
|
+
assertDateChainReady(state);
|
|
178
|
+
if (state.current) {
|
|
179
|
+
state.current = transform(state.current);
|
|
180
|
+
}
|
|
181
|
+
return chain;
|
|
182
|
+
};
|
|
183
|
+
const compare = (other, comparator) => {
|
|
184
|
+
assertDateChainReady(state);
|
|
185
|
+
if (!state.current) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const comparable = getComparableDayjs(other);
|
|
189
|
+
if (!comparable) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
return comparator(state.current, comparable);
|
|
193
|
+
};
|
|
194
|
+
const chain = {
|
|
195
|
+
ready,
|
|
196
|
+
add: (value, unit) => applyMutation((current) => current.add(value, unit)),
|
|
197
|
+
subtract: (value, unit) => applyMutation((current) => current.subtract(value, unit)),
|
|
198
|
+
set: (unit, value) => applyMutation((current) => current.set(mapChainSetUnit(unit), value)),
|
|
199
|
+
startOf: (unit) => applyMutation((current) => current.startOf(unit)),
|
|
200
|
+
endOf: (unit) => applyMutation((current) => current.endOf(unit)),
|
|
201
|
+
format: (output = DEFAULT_FORMAT) => {
|
|
202
|
+
assertDateChainReady(state);
|
|
203
|
+
if (!state.current) {
|
|
204
|
+
return state.invalid;
|
|
205
|
+
}
|
|
206
|
+
return state.current.format(output);
|
|
207
|
+
},
|
|
208
|
+
toDate: () => {
|
|
209
|
+
assertDateChainReady(state);
|
|
210
|
+
return state.current ? state.current.toDate() : null;
|
|
211
|
+
},
|
|
212
|
+
toISOString: () => {
|
|
213
|
+
assertDateChainReady(state);
|
|
214
|
+
return state.current ? state.current.toISOString() : null;
|
|
215
|
+
},
|
|
216
|
+
toTimestamp: () => {
|
|
217
|
+
assertDateChainReady(state);
|
|
218
|
+
return state.current ? state.current.valueOf() : null;
|
|
219
|
+
},
|
|
220
|
+
isValid: () => {
|
|
221
|
+
assertDateChainReady(state);
|
|
222
|
+
return state.current !== null;
|
|
223
|
+
},
|
|
224
|
+
isBefore: (other, unit) => compare(other, (current, comparable) => current.isBefore(comparable, unit)),
|
|
225
|
+
isAfter: (other, unit) => compare(other, (current, comparable) => current.isAfter(comparable, unit)),
|
|
226
|
+
isSame: (other, unit) => compare(other, (current, comparable) => current.isSame(comparable, unit)),
|
|
227
|
+
toState: () => {
|
|
228
|
+
assertDateChainReady(state);
|
|
229
|
+
if (!state.current) {
|
|
230
|
+
return createDateChainFailureState(state.locale, state.error ?? state.invalid);
|
|
231
|
+
}
|
|
232
|
+
return createDateChainSuccessState(state.current, state.locale);
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
return chain;
|
|
236
|
+
};
|
|
237
|
+
var createDateChainState = (locale, invalid, getInitialDate) => {
|
|
238
|
+
const state = {
|
|
239
|
+
locale,
|
|
240
|
+
invalid,
|
|
241
|
+
current: null,
|
|
242
|
+
ready: false,
|
|
243
|
+
error: invalid
|
|
244
|
+
};
|
|
245
|
+
const initialize = () => {
|
|
246
|
+
const parsed = getInitialDate();
|
|
247
|
+
state.ready = true;
|
|
248
|
+
if (!parsed.isValid()) {
|
|
249
|
+
state.current = null;
|
|
250
|
+
state.error = invalid;
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
state.current = parsed;
|
|
254
|
+
state.error = null;
|
|
255
|
+
};
|
|
256
|
+
if (isLocaleLoaded(locale)) {
|
|
257
|
+
initialize();
|
|
258
|
+
return {
|
|
259
|
+
state,
|
|
260
|
+
ready: Promise.resolve()
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
state,
|
|
265
|
+
ready: ensureLocaleLoaded(locale).then(() => {
|
|
266
|
+
initialize();
|
|
267
|
+
})
|
|
268
|
+
};
|
|
269
|
+
};
|
|
270
|
+
var createDateChainFromResolvedConfig = (props, config) => {
|
|
271
|
+
const locale = getTargetLocale(config.locale, props);
|
|
272
|
+
const invalid = getInvalidDateText(config, props);
|
|
273
|
+
const strict = props?.strict ?? config.strict;
|
|
274
|
+
const getInitialDate = () => {
|
|
275
|
+
if (props?.date === void 0) {
|
|
276
|
+
return getCurrentDayjs(locale);
|
|
277
|
+
}
|
|
278
|
+
return parseDateValue(props.date, props.input, locale, strict);
|
|
279
|
+
};
|
|
280
|
+
const { state, ready } = createDateChainState(locale, invalid, getInitialDate);
|
|
281
|
+
return createDateChainApi(state, ready);
|
|
282
|
+
};
|
|
96
283
|
var createFormatterParseDate = (getConfig) => {
|
|
97
284
|
return (props) => {
|
|
98
285
|
const config = getConfig();
|
|
99
286
|
const locale = getTargetLocale(config.locale, props);
|
|
100
287
|
const parsed = parseDateValue(props.date, props.input, locale, props.strict ?? config.strict);
|
|
101
288
|
if (!parsed.isValid()) {
|
|
102
|
-
return
|
|
103
|
-
isValid: false,
|
|
104
|
-
locale,
|
|
105
|
-
date: null,
|
|
106
|
-
iso: null,
|
|
107
|
-
timestamp: null,
|
|
108
|
-
error: getInvalidDateText(config, props)
|
|
109
|
-
};
|
|
289
|
+
return createParseFailure(locale, getInvalidDateText(config, props));
|
|
110
290
|
}
|
|
111
|
-
return
|
|
112
|
-
isValid: true,
|
|
113
|
-
locale,
|
|
114
|
-
date: parsed.toDate(),
|
|
115
|
-
iso: parsed.toISOString(),
|
|
116
|
-
timestamp: parsed.valueOf(),
|
|
117
|
-
format: (output = DEFAULT_FORMAT) => parsed.format(output)
|
|
118
|
-
};
|
|
291
|
+
return createParseSuccess(parsed, locale);
|
|
119
292
|
};
|
|
120
293
|
};
|
|
121
294
|
var createFormatterIsValidDate = (parseDate2) => {
|
|
@@ -128,10 +301,10 @@ var createFormatterGetDate = (getConfig) => {
|
|
|
128
301
|
const locale = getTargetLocale(config.locale, props);
|
|
129
302
|
const output = props?.output ?? DEFAULT_FORMAT;
|
|
130
303
|
if (!props) {
|
|
131
|
-
return
|
|
304
|
+
return getCurrentDayjs(locale).format(DEFAULT_FORMAT);
|
|
132
305
|
}
|
|
133
306
|
if (props.date === void 0) {
|
|
134
|
-
return
|
|
307
|
+
return getCurrentDayjs(locale).format(output);
|
|
135
308
|
}
|
|
136
309
|
const parsed = parseDate2({
|
|
137
310
|
date: props.date,
|
|
@@ -145,6 +318,11 @@ var createFormatterGetDate = (getConfig) => {
|
|
|
145
318
|
return parsed.format(output);
|
|
146
319
|
};
|
|
147
320
|
};
|
|
321
|
+
var createFormatterCreateDateChain = (getConfig) => {
|
|
322
|
+
return (props) => {
|
|
323
|
+
return createDateChainFromResolvedConfig(props, getConfig());
|
|
324
|
+
};
|
|
325
|
+
};
|
|
148
326
|
function resolveLocaleOrThrow(locale) {
|
|
149
327
|
const resolvedLocale = resolveLocale(locale);
|
|
150
328
|
if (!resolvedLocale) {
|
|
@@ -164,6 +342,7 @@ var createDateFormatter = (config) => {
|
|
|
164
342
|
getDate: createFormatterGetDate(getConfig),
|
|
165
343
|
parseDate: parseDate2,
|
|
166
344
|
isValidDate: createFormatterIsValidDate(parseDate2),
|
|
345
|
+
createDateChain: createFormatterCreateDateChain(getConfig),
|
|
167
346
|
getSupportedLocales,
|
|
168
347
|
getCurrentLocale: () => currentLocale,
|
|
169
348
|
setLocale: async (locale) => {
|
|
@@ -182,6 +361,7 @@ var useDateFormatter = (options) => {
|
|
|
182
361
|
return {
|
|
183
362
|
locale,
|
|
184
363
|
currentLocale: locale,
|
|
364
|
+
createDateChain: (props) => formatterRef.current.createDateChain(props),
|
|
185
365
|
getDate: (props) => formatterRef.current.getDate(props),
|
|
186
366
|
parseDate: (props) => formatterRef.current.parseDate(props),
|
|
187
367
|
isValidDate: (props) => formatterRef.current.isValidDate(props),
|