@stamcat/localize 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Localize, createLocalize } from "./src/localize";
2
+ export { createLocalize };
3
+ export default Localize;
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import { Localize, createLocalize } from "./src/localize";
2
+ export { createLocalize };
3
+ export default Localize;
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@stamcat/localize",
3
+ "version": "1.0.4",
4
+ "description": "A collection of localization tools built on FormatJS & i18n",
5
+ "main": "index.ts",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Stamcat/Localize.git"
9
+ },
10
+ "keywords": [
11
+ "formatjs",
12
+ "i18n",
13
+ "internationalization",
14
+ "localization"
15
+ ],
16
+ "author": "Devin Marra",
17
+ "license": "MIT",
18
+ "bugs": {
19
+ "url": "https://github.com/Stamcat/Localize/issues"
20
+ },
21
+ "homepage": "https://github.com/Stamcat/Localize#readme",
22
+ "scripts": {},
23
+ "dependencies": {
24
+ "flat": "6.0.1",
25
+ "react-intl": "10.1.13"
26
+ },
27
+ "devDependencies": {},
28
+ "lint-staged": {
29
+ "package-lock.json": "node qualityChecks/check-package-lock.cjs",
30
+ "*.json": "npm run pretty:commit --",
31
+ "src/*.{ts,tsx,js}|*.{ts,tsx}": [
32
+ "npm run lint:commit --fix --silent --"
33
+ ]
34
+ }
35
+ }
package/src/cache.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function runWithCache<T>(fn: () => T): T;
2
+ export declare function cache<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
package/src/cache.js ADDED
@@ -0,0 +1,51 @@
1
+ let als = null;
2
+ try {
3
+ const { AsyncLocalStorage } = require("async_hooks");
4
+ als = new AsyncLocalStorage();
5
+ }
6
+ catch {
7
+ }
8
+ const globalStore = new Map();
9
+ function getCurrentStore() {
10
+ return als?.getStore() ?? globalStore;
11
+ }
12
+ export function runWithCache(fn) {
13
+ if (als) {
14
+ return als.run(new Map(), fn);
15
+ }
16
+ return fn();
17
+ }
18
+ export function cache(fn) {
19
+ return (...args) => {
20
+ const store = getCurrentStore();
21
+ let node = store.get(fn);
22
+ if (!node) {
23
+ node = { children: new Map() };
24
+ store.set(fn, node);
25
+ }
26
+ let current = node;
27
+ for (const arg of args) {
28
+ let child = current.children.get(arg);
29
+ if (!child) {
30
+ child = { children: new Map() };
31
+ current.children.set(arg, child);
32
+ }
33
+ current = child;
34
+ }
35
+ if (current.entry) {
36
+ if (current.entry.status === "fulfilled") {
37
+ return current.entry.value;
38
+ }
39
+ throw current.entry.reason;
40
+ }
41
+ try {
42
+ const value = fn(...args);
43
+ current.entry = { status: "fulfilled", value };
44
+ return value;
45
+ }
46
+ catch (reason) {
47
+ current.entry = { status: "rejected", reason };
48
+ throw reason;
49
+ }
50
+ };
51
+ }
@@ -0,0 +1,6 @@
1
+ export declare const localeMap: {
2
+ [key: string]: string;
3
+ };
4
+ export declare const intlOverrideMap: {
5
+ [name: string]: string;
6
+ };
@@ -0,0 +1,161 @@
1
+ export const localeMap = {
2
+ ar: "ar-IL",
3
+ "ar-IL": "ar-IL",
4
+ az: "az",
5
+ "az-AZ": "az",
6
+ bg: "bg",
7
+ "bg-BG": "bg",
8
+ cs: "cs",
9
+ "cs-CZ": "cs",
10
+ da: "da-DK",
11
+ "da-DK": "da",
12
+ de: "de",
13
+ "de-AT": "de-AT",
14
+ "de-CH": "de-CH",
15
+ "de-DE": "de",
16
+ el: "el",
17
+ "el-CY": "el-CY",
18
+ "el-GR": "el",
19
+ en: "en-US",
20
+ "en-AU": "en-AU",
21
+ "en-BW": "en-BW",
22
+ "en-CA": "en-CA",
23
+ "en-GB": "en-GB",
24
+ "en-GH": "en-GH",
25
+ "en-HK": "en-HK",
26
+ "en-ID": "en-US",
27
+ "en-IE": "en-IE",
28
+ "en-IN": "en-IN",
29
+ "en-JM": "en-JM",
30
+ "en-KH": "en-KH",
31
+ "en-LB": "en-US",
32
+ "en-LS": "en-LS",
33
+ "en-MT": "en-MT",
34
+ "en-MY": "en-MY",
35
+ "en-NA": "en-NA",
36
+ "en-NZ": "en-NZ",
37
+ "en-PH": "en-PH",
38
+ "en-SG": "en-SG",
39
+ "en-SZ": "en-SZ",
40
+ "en-TT": "en-TT",
41
+ "en-US": "en-US",
42
+ "en-US-POSIX": "en-US",
43
+ "en-ZA": "en-ZA",
44
+ "en-ZM": "en-ZM",
45
+ es: "es",
46
+ "es-AR": "es-AR",
47
+ "es-AW": "es-AW",
48
+ "es-BO": "es-BO",
49
+ "es-CL": "es-CL",
50
+ "es-CO": "es-CO",
51
+ "es-CR": "es-CR",
52
+ "es-DO": "es-DO",
53
+ "es-EC": "es-EC",
54
+ "es-ES": "es",
55
+ "es-GT": "es-GT",
56
+ "es-HN": "es-HN",
57
+ "es-MX": "es-MX",
58
+ "es-NI": "es-NI",
59
+ "es-PA": "es-PA",
60
+ "es-PE": "es-PE",
61
+ "es-PR": "es-PR",
62
+ "es-PY": "es-PY",
63
+ "es-SV": "es-SV",
64
+ "es-US": "es-US",
65
+ "es-UY": "es-UY",
66
+ "es-VE": "es-VE",
67
+ et: "et",
68
+ "et-EE": "et",
69
+ fi: "fi",
70
+ "fi-FI": "fi",
71
+ fr: "fr",
72
+ "fr-BE": "fr-BE",
73
+ "fr-CA": "fr-CA",
74
+ "fr-CH": "fr-CH",
75
+ "fr-FR": "fr",
76
+ "fr-PF": "fr-PF",
77
+ he: "he",
78
+ "he-IL": "he",
79
+ hi: "hi",
80
+ "hi-IN": "hi",
81
+ hr: "hr",
82
+ "hr-BA": "hr-BA",
83
+ "hr-HR": "hr",
84
+ hu: "hu",
85
+ "hu-HU": "hu",
86
+ hy: "hy",
87
+ "hy-AM": "hy",
88
+ id: "id",
89
+ "id-ID": "id",
90
+ is: "is",
91
+ "is-IS": "is",
92
+ it: "it",
93
+ "it-CH": "it-CH",
94
+ "it-IT": "it",
95
+ ja: "ja",
96
+ "ja-JP": "ja",
97
+ ka: "ka",
98
+ "ka-GE": "ka",
99
+ km: "km",
100
+ "km-KH": "km",
101
+ ko: "ko",
102
+ "ko-KR": "ko",
103
+ lt: "lt",
104
+ "lt-LT": "lt",
105
+ lv: "lv",
106
+ "lv-LV": "lv",
107
+ mk: "mk",
108
+ "mk-MK": "mk",
109
+ mn: "mn",
110
+ "mn-NM": "mn",
111
+ ms: "ms-MY",
112
+ "ms-MY": "ms",
113
+ nl: "nl",
114
+ "nl-BE": "nl-BE",
115
+ "nl-NL": "nl",
116
+ nn: "nn",
117
+ "nn-NO": "nn-NO",
118
+ pl: "pl",
119
+ "pl-PL": "pl",
120
+ pt: "pt",
121
+ "pt-BR": "pt",
122
+ "pt-PT": "pt-PT",
123
+ ro: "ro",
124
+ "ro-MD": "ro-MD",
125
+ "ro-RO": "ro",
126
+ ru: "ru",
127
+ "ru-BY": "ru-BY",
128
+ "ru-IL": "ru-IL",
129
+ "ru-KG": "ru-KG",
130
+ "ru-KZ": "ru-KZ",
131
+ "ru-RU": "ru",
132
+ "ru-UZ": "ru-UZ",
133
+ sk: "sk",
134
+ "sk-SK": "sk",
135
+ sl: "sl",
136
+ "sl-SI": "sl",
137
+ sr: "sr",
138
+ "sr-RS": "sr",
139
+ sv: "sv",
140
+ "sv-FI": "sv",
141
+ "sv-SE": "sv",
142
+ th: "th",
143
+ "th-TH": "th",
144
+ tr: "tr",
145
+ "tr-TR": "tr",
146
+ uk: "uk",
147
+ "uk-UA": "uk",
148
+ uz: "uz",
149
+ "uz-UZ": "uz",
150
+ vi: "vi",
151
+ "vi-VN": "vi",
152
+ "zh-HK": "zh-HK",
153
+ "zh-MO": "zh-MO",
154
+ "zh-MY": "zh-MY",
155
+ zh: "zh-TW",
156
+ "zh-TW": "zh-TW",
157
+ };
158
+ export const intlOverrideMap = {
159
+ "es-US": "es-PR",
160
+ "sr-RS": "sr-latn",
161
+ };
package/src/intl.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { IntlShape } from "react-intl";
2
+ import { LocalizeInstance } from "./storage";
3
+ export type IntlFunctions = {
4
+ appIntl: () => IntlShape;
5
+ overrideAppIntl: () => IntlShape;
6
+ appIntlFormatOverride: () => IntlShape;
7
+ };
8
+ export declare function createIntlFunctions(localeInstance: LocalizeInstance): IntlFunctions;
9
+ export declare const appIntl: () => IntlShape;
10
+ export declare const overrideAppIntl: () => IntlShape;
11
+ export declare const appIntlFormatOverride: () => IntlShape;
package/src/intl.js ADDED
@@ -0,0 +1,56 @@
1
+ import { createIntl, createIntlCache } from "react-intl";
2
+ import { intlOverrideMap, localeMap } from "./constants";
3
+ import { Locale } from "./storage";
4
+ import { flatten } from "flat";
5
+ let flattenedMessages = {};
6
+ const getMessages = (locale, delimiter = "/", getAllTranslations) => {
7
+ if (getAllTranslations) {
8
+ const f = flatten(getAllTranslations(), { delimiter });
9
+ return f;
10
+ }
11
+ const currentLocale = localeMap[locale];
12
+ if (!flattenedMessages[currentLocale]) {
13
+ const allMessages = Locale.getAllTranslations();
14
+ const fetchedMessages = allMessages;
15
+ const f = flatten(fetchedMessages, {
16
+ delimiter,
17
+ });
18
+ flattenedMessages = {
19
+ [locale]: f,
20
+ };
21
+ }
22
+ return flattenedMessages[locale];
23
+ };
24
+ export function createIntlFunctions(localeInstance) {
25
+ let intl;
26
+ let intlOverride;
27
+ const appIntl = () => {
28
+ const l = localeInstance.getLocale();
29
+ if (!intl || intl.locale !== l) {
30
+ const m = getMessages(l, "/", localeInstance.getAllTranslations);
31
+ intl = createIntl({
32
+ locale: l,
33
+ messages: m,
34
+ }, createIntlCache());
35
+ }
36
+ return intl;
37
+ };
38
+ const overrideAppIntl = () => {
39
+ if (!intlOverride) {
40
+ const l = localeInstance.getLocale();
41
+ intlOverride = createIntl({
42
+ locale: intlOverrideMap[l] || `${l}-u-nu-latn`,
43
+ }, createIntlCache());
44
+ }
45
+ return intlOverride;
46
+ };
47
+ const appIntlFormatOverride = () => {
48
+ const l = localeInstance.getLocale();
49
+ return intlOverrideMap[l] ? overrideAppIntl() : appIntl();
50
+ };
51
+ return { appIntl, overrideAppIntl, appIntlFormatOverride };
52
+ }
53
+ const _singletonIntl = createIntlFunctions(Locale);
54
+ export const appIntl = _singletonIntl.appIntl;
55
+ export const overrideAppIntl = _singletonIntl.overrideAppIntl;
56
+ export const appIntlFormatOverride = _singletonIntl.appIntlFormatOverride;
@@ -0,0 +1,53 @@
1
+ import { FormatNumberOptions, FormatDateOptions, MessageDescriptor, PrimitiveType } from "react-intl";
2
+ import { Formats, FormatXMLElementFn } from "intl-messageformat";
3
+ import { IntlMessageFormatOptions } from "./types";
4
+ export declare function createLocalize(defaultLocale?: string): {
5
+ getLocale: () => string;
6
+ setLocale: (newLocale: string) => void;
7
+ getCountryCode: () => string;
8
+ getLanguageCode: () => string;
9
+ pending: {
10
+ get: (key: string) => Promise<void> | undefined;
11
+ set: (key: string, value: Promise<void>) => void;
12
+ delete: (key: string) => void;
13
+ has: (key: string) => boolean;
14
+ clear: () => void;
15
+ };
16
+ getAllMessages: () => Record<string, unknown>;
17
+ prepareMessages: (locale: string, fetchedMessages: object, delimiter?: string) => Record<string, string>;
18
+ appendMessages: (newMessages: Record<string, unknown>) => void;
19
+ setTranslations: (newMessages: Record<string, unknown>) => void;
20
+ changeLocale: (newLocale: string, messages?: object, delimiter?: string) => void;
21
+ getMeasureFormat: (locale?: string) => "metric" | "imperial";
22
+ getCountryName: (locale: string, localizedTo?: string) => string;
23
+ formatDate: (value: Parameters<Intl.DateTimeFormat["format"]>[0] | string, opts?: FormatDateOptions) => string;
24
+ formatDateRange: (from: Parameters<Intl.DateTimeFormat["format"]>[0] | string, to: Parameters<Intl.DateTimeFormat["format"]>[0] | string, opts?: any) => string;
25
+ formatMessage: (id: string, values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>, descriptor?: MessageDescriptor, opts?: IntlMessageFormatOptions) => string;
26
+ message: (message: string, values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>, overrideFormats?: Partial<Formats>, opts?: IntlMessageFormatOptions) => string | string[];
27
+ formatNumber: (value: Parameters<Intl.NumberFormat["format"]>[0], opts?: FormatNumberOptions) => string;
28
+ };
29
+ export declare const Localize: {
30
+ getLocale: () => string;
31
+ setLocale: (newLocale: string) => void;
32
+ getCountryCode: () => string;
33
+ getLanguageCode: () => string;
34
+ pending: {
35
+ get: (key: string) => Promise<void> | undefined;
36
+ set: (key: string, value: Promise<void>) => void;
37
+ delete: (key: string) => void;
38
+ has: (key: string) => boolean;
39
+ clear: () => void;
40
+ };
41
+ getAllMessages: () => Record<string, unknown>;
42
+ prepareMessages: (locale: string, fetchedMessages: object, delimiter?: string) => Record<string, string>;
43
+ appendMessages: (newMessages: Record<string, unknown>) => void;
44
+ setTranslations: (newMessages: Record<string, unknown>) => void;
45
+ changeLocale: (newLocale: string, messages?: object, delimiter?: string) => void;
46
+ getMeasureFormat: (locale?: string) => "metric" | "imperial";
47
+ getCountryName: (locale: string, localizedTo?: string) => string;
48
+ formatDate: (value: Parameters<Intl.DateTimeFormat["format"]>[0] | string, opts?: FormatDateOptions) => string;
49
+ formatDateRange: (from: Parameters<Intl.DateTimeFormat["format"]>[0] | string, to: Parameters<Intl.DateTimeFormat["format"]>[0] | string, opts?: any) => string;
50
+ formatMessage: (id: string, values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>, descriptor?: MessageDescriptor, opts?: IntlMessageFormatOptions) => string;
51
+ message: (message: string, values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>, overrideFormats?: Partial<Formats>, opts?: IntlMessageFormatOptions) => string | string[];
52
+ formatNumber: (value: Parameters<Intl.NumberFormat["format"]>[0], opts?: FormatNumberOptions) => string;
53
+ };
@@ -0,0 +1,108 @@
1
+ import { IntlMessageFormat } from "intl-messageformat";
2
+ import { createIntlFunctions } from "./intl";
3
+ import { flatten } from "flat";
4
+ import { createLocalizeInstance } from "./storage";
5
+ import { localeMap } from "./constants";
6
+ export function createLocalize(defaultLocale = "en-US") {
7
+ const localeInstance = createLocalizeInstance(defaultLocale);
8
+ const { appIntl, appIntlFormatOverride } = createIntlFunctions(localeInstance);
9
+ const instance = {
10
+ getLocale: () => localeInstance.getLocale(),
11
+ setLocale: (newLocale) => {
12
+ localeInstance.setLocale(newLocale);
13
+ },
14
+ getCountryCode: () => localeInstance.getCountryCode(),
15
+ getLanguageCode: () => localeInstance.getLanguageCode(),
16
+ pending: {
17
+ get: (key) => localeInstance.getPending(key),
18
+ set: (key, value) => localeInstance.setPending(key, value),
19
+ delete: (key) => localeInstance.deletePending(key),
20
+ has: (key) => localeInstance.hasPending(key),
21
+ clear: () => localeInstance.clearPending(),
22
+ },
23
+ getAllMessages: () => localeInstance.getAllTranslations(),
24
+ prepareMessages: (locale, fetchedMessages, delimiter) => {
25
+ let flattenedMessages = {};
26
+ const currentLocale = localeMap[locale];
27
+ if (!flattenedMessages[currentLocale]) {
28
+ const f = flatten(fetchedMessages, {
29
+ delimiter,
30
+ });
31
+ flattenedMessages = {
32
+ [locale]: f,
33
+ };
34
+ }
35
+ return flattenedMessages[locale];
36
+ },
37
+ appendMessages: (newMessages) => {
38
+ const messages = localeInstance.getAllTranslations();
39
+ localeInstance.setTranslations({ ...messages, ...newMessages });
40
+ },
41
+ setTranslations: (newMessages) => {
42
+ localeInstance.setTranslations(newMessages);
43
+ },
44
+ changeLocale: (newLocale, messages, delimiter) => {
45
+ localeInstance.setLocale(newLocale);
46
+ if (messages) {
47
+ const newMessages = instance.prepareMessages(newLocale, messages, delimiter);
48
+ localeInstance.setTranslations(newMessages);
49
+ }
50
+ },
51
+ getMeasureFormat: (locale) => {
52
+ const l = locale || instance.getLocale();
53
+ const region = new Intl.Locale(l).region;
54
+ const imperialRegions = ["US", "LR", "MM"];
55
+ return imperialRegions.includes(region || "US") ? "imperial" : "metric";
56
+ },
57
+ getCountryName: (locale, localizedTo) => {
58
+ const parts = locale.split("-");
59
+ const region = parts.length > 1 ? parts[1].toUpperCase() : "";
60
+ try {
61
+ const displayLocale = Intl.DisplayNames.supportedLocalesOf([localizedTo || locale])[0] || instance.getLocale();
62
+ const displayNames = new Intl.DisplayNames([displayLocale], {
63
+ type: "region",
64
+ });
65
+ return displayNames.of(region) || region;
66
+ }
67
+ catch {
68
+ return region;
69
+ }
70
+ },
71
+ formatDate: (value, opts) => {
72
+ const intl = appIntlFormatOverride();
73
+ if (!value) {
74
+ return "";
75
+ }
76
+ return intl.formatDate(value, opts);
77
+ },
78
+ formatDateRange: (from, to, opts) => {
79
+ const intl = appIntlFormatOverride();
80
+ if (!from || !to) {
81
+ return "";
82
+ }
83
+ return intl.formatDateTimeRange(from, to, opts);
84
+ },
85
+ formatMessage: (id, values, descriptor, opts) => {
86
+ const nodeEnv = globalThis.process?.env?.NODE_ENV;
87
+ if (nodeEnv === "test") {
88
+ return id;
89
+ }
90
+ const intl = appIntl();
91
+ if (!id) {
92
+ return "";
93
+ }
94
+ return intl.formatMessage({ id, ...descriptor }, values, opts);
95
+ },
96
+ message: (message, values, overrideFormats, opts) => {
97
+ const locale = localeInstance.getLocale();
98
+ const msg = new IntlMessageFormat(message, locale, overrideFormats, opts);
99
+ return msg.format(values);
100
+ },
101
+ formatNumber: (value, opts) => {
102
+ const intl = appIntlFormatOverride();
103
+ return intl.formatNumber(value, opts);
104
+ },
105
+ };
106
+ return instance;
107
+ }
108
+ export const Localize = createLocalize();
@@ -0,0 +1,20 @@
1
+ export type LocalizeStore = {
2
+ locale: string;
3
+ messages: Record<string, unknown>;
4
+ pending: Map<string, Promise<void>>;
5
+ };
6
+ export type LocalizeInstance = {
7
+ getLocale: () => string;
8
+ setLocale: (newLocale: string) => void;
9
+ getAllTranslations: () => Record<string, unknown>;
10
+ setTranslations: (newMessages: Record<string, unknown>) => void;
11
+ getCountryCode: () => string;
12
+ getLanguageCode: () => string;
13
+ getPending: (key: string) => Promise<void> | undefined;
14
+ setPending: (key: string, value: Promise<void>) => void;
15
+ deletePending: (key: string) => void;
16
+ hasPending: (key: string) => boolean;
17
+ clearPending: () => void;
18
+ };
19
+ export declare function createLocalizeInstance(defaultLocale?: string): LocalizeInstance;
20
+ export declare const Locale: LocalizeInstance;
package/src/storage.js ADDED
@@ -0,0 +1,39 @@
1
+ import { cache } from "./cache";
2
+ export function createLocalizeInstance(defaultLocale = "en-US") {
3
+ const storeCache = cache(() => ({
4
+ locale: defaultLocale,
5
+ messages: {},
6
+ pending: new Map(),
7
+ }));
8
+ const store = storeCache();
9
+ return {
10
+ getLocale: () => store.locale,
11
+ setLocale: (newLocale) => {
12
+ store.locale = newLocale;
13
+ },
14
+ getAllTranslations: () => store.messages,
15
+ setTranslations: (newMessages) => {
16
+ store.messages = newMessages;
17
+ },
18
+ getPending: (key) => store.pending.get(key),
19
+ setPending: (key, value) => {
20
+ store.pending.set(key, value);
21
+ },
22
+ deletePending: (key) => {
23
+ store.pending.delete(key);
24
+ },
25
+ hasPending: (key) => store.pending.has(key),
26
+ clearPending: () => {
27
+ store.pending.clear();
28
+ },
29
+ getCountryCode: () => {
30
+ const parts = store.locale.split("-");
31
+ return parts.length > 1 ? parts[1].toUpperCase() : "US";
32
+ },
33
+ getLanguageCode: () => {
34
+ const parts = store.locale.split("-");
35
+ return parts[0].toLowerCase();
36
+ },
37
+ };
38
+ }
39
+ export const Locale = createLocalizeInstance();
package/src/types.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Options } from "intl-messageformat";
2
+ import { MessageFormatElement } from "react-intl";
3
+ export type IntlMessageFormatOptions = Options;
4
+ export type IntlMessage = Record<string, string> | Record<string, MessageFormatElement[]> | undefined;
5
+ export type LegacyRaw = "dd'.'MM'.'yyyy" | "dd'/'MM'/'yy" | "dd'/'MM'/'yyyy" | "M'/'d'/'yy" | "M'/'d'/'yyyy" | "MMM d 'd.'" | "MMMM Y" | "dd MMMM, yyyy" | "d MMMM" | "d'/'M'/'yyyy" | "yyyy'-'MM'-'dd";
6
+ export type LegacySkeleton = "MMMMd" | "MMMd" | "yMMdd" | "yMd";
7
+ export type LegacyDate = "full" | "long" | "medium" | "short";
8
+ export type LegacyDateFormat = {
9
+ date?: LegacyDate;
10
+ raw?: LegacyRaw;
11
+ skeleton?: LegacySkeleton;
12
+ };
13
+ export type LegacyDateFormats = LegacyRaw & LegacyDate & LegacySkeleton;
package/src/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};