@ingram-tech/nk-i18n 0.1.2 → 0.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/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core.d.ts +17 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +28 -6
- package/dist/core.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/negotiate.d.ts +5 -3
- package/dist/negotiate.d.ts.map +1 -1
- package/dist/negotiate.js +22 -9
- package/dist/negotiate.js.map +1 -1
- package/package.json +7 -7
package/dist/config.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reserved: declared for forward compatibility but not yet consumed by
|
|
3
|
+
* `createT`/`useT` — a missing key currently always falls back to the English
|
|
4
|
+
* source silently, regardless of this setting.
|
|
5
|
+
*/
|
|
1
6
|
export type MissingKeysPolicy = "error" | "warn" | "ignore";
|
|
2
7
|
/**
|
|
3
8
|
* Metadata for one locale. `label` (the display name, usually native) is
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,UAAU,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,CACzD,MAAM,EACN,gBAAgB,CAChB,EACD,WAAW,SAAS,MAAM,GAAG,MAAM,IAChC;IACH,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,KAAK,aAAa,GAAG;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EACnE,MAAM,EAAE,OAAO,GACb,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EACxE,MAAM,EAAE,OAAO,GACb;IACF,iBAAiB,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC;IAC5D,cAAc,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAGtC,YAAY,EAAE;SACZ,CAAC,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;KACxE,CAAC;CACF,CAYA;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EAAE,MAAM,EACpE,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,CACL,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,EAC1D,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,KACrC,MAAM,GACT,MAAM,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAQnD"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,UAAU,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,CACzD,MAAM,EACN,gBAAgB,CAChB,EACD,WAAW,SAAS,MAAM,GAAG,MAAM,IAChC;IACH,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,KAAK,aAAa,GAAG;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1C,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EACnE,MAAM,EAAE,OAAO,GACb,OAAO,CAET;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EACxE,MAAM,EAAE,OAAO,GACb;IACF,iBAAiB,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC;IAC5D,cAAc,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAGtC,YAAY,EAAE;SACZ,CAAC,IAAI,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;KACxE,CAAC;CACF,CAYA;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,OAAO,SAAS,aAAa,EAAE,MAAM,EACpE,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,CACL,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,EAC1D,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,KACrC,MAAM,GACT,MAAM,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,CAQnD"}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiCA;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC/B,MAAe;IAEf,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACpC,MAAe;IAWf,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAsC,CAAC;IACpF,OAAO;QACN,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC;QACpD,cAAc,EAAE,MAAM,CAAC,UAAU;QACjC,YAAY,EAAE,MAAM,CAAC,WAAW,CAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAGnD;KACD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACxB,MAAe,EACf,IAGW;IAGX,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAE5C,CAAC;IACF,OAAO,MAAM,CAAC,WAAW,CACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CACjC,CAAC;AAC7B,CAAC"}
|
package/dist/core.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
type MessageCatalog = Record<string, string>;
|
|
2
2
|
declare const I18N_KEY_BRAND: unique symbol;
|
|
3
|
+
declare const LOCALIZED_STRING_BRAND: unique symbol;
|
|
4
|
+
/**
|
|
5
|
+
* A string that has passed through a {@link Translator} — display-ready text in
|
|
6
|
+
* the active locale. It is a plain `string` at runtime (the brand is erased), so
|
|
7
|
+
* it flows anywhere a `string` is wanted; the brand only matters where a prop is
|
|
8
|
+
* tightened to require `LocalizedString`, which turns hardcoded English at that
|
|
9
|
+
* boundary into a compile error. Sites that need to pass deliberately
|
|
10
|
+
* untranslated text (a name, an id, a number) opt out with `x as LocalizedString`.
|
|
11
|
+
*/
|
|
12
|
+
export type LocalizedString = string & {
|
|
13
|
+
readonly [LOCALIZED_STRING_BRAND]: "LocalizedString";
|
|
14
|
+
};
|
|
3
15
|
/**
|
|
4
16
|
* A set of per-locale message catalogs, keyed by locale code. The English
|
|
5
17
|
* source text is used as the key, so there is no `en` catalog: a missing lookup
|
|
@@ -32,8 +44,12 @@ type DeepMessageKeys<TValue> = TValue extends string ? I18nKey<TValue> : TValue
|
|
|
32
44
|
* source the key is checked against the catalogs at compile time; without one,
|
|
33
45
|
* any literal string is allowed. The optional `values` are interpolated with
|
|
34
46
|
* ICU MessageFormat (`{name}`, `{count, number}`, plurals, …).
|
|
47
|
+
*
|
|
48
|
+
* The return is branded {@link LocalizedString} so a prop can require translated
|
|
49
|
+
* text; interpolation done here stays branded, but composing with `+` or a
|
|
50
|
+
* template literal collapses back to a plain `string`.
|
|
35
51
|
*/
|
|
36
|
-
export type Translator<TSource extends MessageSource | undefined = undefined> = <const TValue extends string>(english: AllowedMessageKey<TSource, TValue>, values?: Record<string, unknown>) =>
|
|
52
|
+
export type Translator<TSource extends MessageSource | undefined = undefined> = <const TValue extends string>(english: AllowedMessageKey<TSource, TValue>, values?: Record<string, unknown>) => LocalizedString;
|
|
37
53
|
/**
|
|
38
54
|
* Brand a tree of English source strings as translation keys so the compiler
|
|
39
55
|
* can check them. Returns the value unchanged at runtime.
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAEA,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC7C,OAAO,CAAC,MAAM,cAAc,EAAE,OAAO,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/core.js
CHANGED
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
import IntlMessageFormat from "intl-messageformat";
|
|
2
2
|
const cache = new Map();
|
|
3
|
+
// Bound the formatter cache: keys embed the locale, and an unvalidated
|
|
4
|
+
// user-controlled locale (cookie/path segment) would otherwise grow server
|
|
5
|
+
// memory without limit.
|
|
6
|
+
const CACHE_MAX = 5000;
|
|
7
|
+
const warnedFormatErrors = new Set();
|
|
3
8
|
function format(message, locale, values) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
try {
|
|
10
|
+
const key = `${locale}:${message}`;
|
|
11
|
+
let fmt = cache.get(key);
|
|
12
|
+
if (!fmt) {
|
|
13
|
+
if (cache.size >= CACHE_MAX)
|
|
14
|
+
cache.clear();
|
|
15
|
+
fmt = new IntlMessageFormat(message, locale);
|
|
16
|
+
cache.set(key, fmt);
|
|
17
|
+
}
|
|
18
|
+
const result = fmt.format(values);
|
|
19
|
+
return typeof result === "string" ? result : String(result);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
// A malformed catalog entry, a missing placeholder value, or a bad
|
|
23
|
+
// locale tag must degrade to the raw message — not 500 every page that
|
|
24
|
+
// renders this key in this locale (which base-locale testing never hits,
|
|
25
|
+
// since values-less lookups return early).
|
|
26
|
+
if (!warnedFormatErrors.has(message)) {
|
|
27
|
+
warnedFormatErrors.add(message);
|
|
28
|
+
console.warn(`@ingram-tech/nk-i18n: failed to format "${message}" (${locale}): ${error instanceof Error ? error.message : String(error)}`);
|
|
29
|
+
}
|
|
30
|
+
return message;
|
|
9
31
|
}
|
|
10
|
-
return fmt.format(values);
|
|
11
32
|
}
|
|
12
33
|
function isI18nScope(source) {
|
|
13
34
|
return (typeof source === "object" &&
|
|
@@ -40,6 +61,7 @@ export function defineI18nScope(scope) {
|
|
|
40
61
|
*/
|
|
41
62
|
export function createT(locale, messagesOrScope, runtimeMessages) {
|
|
42
63
|
const resolvedMessages = resolveMessages(runtimeMessages) ?? resolveMessages(messagesOrScope);
|
|
64
|
+
// The brand is erased at runtime; this function is the sole mint site.
|
|
43
65
|
const translate = (english, values) => {
|
|
44
66
|
const translated = resolvedMessages?.[locale]?.[english] ?? english;
|
|
45
67
|
if (!values)
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createT, defineI18nScope, defineMessages, type I18nScope, type Messages, type MessageSource, type TranslationKey, type Translator, } from "./core.js";
|
|
1
|
+
export { createT, defineI18nScope, defineMessages, type I18nScope, type LocalizedString, type Messages, type MessageSource, type TranslationKey, type Translator, } from "./core.js";
|
|
2
2
|
export { defineI18nConfig, deriveLocaleConstants, type I18nConfig, localeMap, type LocaleDefinition, type MissingKeysPolicy, } from "./config.js";
|
|
3
3
|
export { negotiateAcceptLanguage } from "./negotiate.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,OAAO,EACP,eAAe,EACf,cAAc,EACd,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,UAAU,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,UAAU,EACf,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,OAAO,EACP,eAAe,EACf,cAAc,EACd,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,UAAU,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,UAAU,EACf,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EACN,OAAO,EACP,eAAe,EACf,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EACN,OAAO,EACP,eAAe,EACf,cAAc,GAOd,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,qBAAqB,EAErB,SAAS,GAGT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/negotiate.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pick the best supported locale from an `Accept-Language` header value.
|
|
3
|
-
* Compares on the primary subtag only (`fr-BE` → `fr`), case-insensitively,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Compares on the primary subtag only (`fr-BE` → `fr`), case-insensitively,
|
|
4
|
+
* honoring q-values per RFC 9110: highest quality wins (header order breaks
|
|
5
|
+
* ties), and `q=0` — an explicit rejection — never matches. Returns
|
|
6
|
+
* `undefined` when nothing matches. Pure — compose it inside a
|
|
7
|
+
* framework-specific locale resolver.
|
|
6
8
|
*/
|
|
7
9
|
export declare function negotiateAcceptLanguage(header: string | null | undefined, supported: readonly string[]): string | undefined;
|
|
8
10
|
//# sourceMappingURL=negotiate.d.ts.map
|
package/dist/negotiate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../src/negotiate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"negotiate.d.ts","sourceRoot":"","sources":["../src/negotiate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC1B,MAAM,GAAG,SAAS,CAgBpB"}
|
package/dist/negotiate.js
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pick the best supported locale from an `Accept-Language` header value.
|
|
3
|
-
* Compares on the primary subtag only (`fr-BE` → `fr`), case-insensitively,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Compares on the primary subtag only (`fr-BE` → `fr`), case-insensitively,
|
|
4
|
+
* honoring q-values per RFC 9110: highest quality wins (header order breaks
|
|
5
|
+
* ties), and `q=0` — an explicit rejection — never matches. Returns
|
|
6
|
+
* `undefined` when nothing matches. Pure — compose it inside a
|
|
7
|
+
* framework-specific locale resolver.
|
|
6
8
|
*/
|
|
7
9
|
export function negotiateAcceptLanguage(header, supported) {
|
|
8
10
|
if (!header)
|
|
9
11
|
return undefined;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const candidates = [];
|
|
13
|
+
header.split(",").forEach((part, index) => {
|
|
14
|
+
const [tag, ...params] = part.split(";");
|
|
15
|
+
const lang = tag?.trim().split("-")[0]?.toLowerCase();
|
|
16
|
+
if (!lang)
|
|
17
|
+
return;
|
|
18
|
+
let q = 1;
|
|
19
|
+
for (const param of params) {
|
|
20
|
+
const match = /^\s*q\s*=\s*(\d(?:\.\d{0,3})?)\s*$/i.exec(param);
|
|
21
|
+
if (match)
|
|
22
|
+
q = Math.min(Number(match[1]), 1);
|
|
23
|
+
}
|
|
24
|
+
if (q > 0)
|
|
25
|
+
candidates.push({ lang, q, index });
|
|
26
|
+
});
|
|
27
|
+
candidates.sort((a, b) => b.q - a.q || a.index - b.index);
|
|
28
|
+
return candidates.find((c) => supported.includes(c.lang))?.lang;
|
|
16
29
|
}
|
|
17
30
|
//# sourceMappingURL=negotiate.js.map
|
package/dist/negotiate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiate.js","sourceRoot":"","sources":["../src/negotiate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"negotiate.js","sourceRoot":"","sources":["../src/negotiate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,uBAAuB,CACtC,MAAiC,EACjC,SAA4B;IAE5B,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,UAAU,GAAiD,EAAE,CAAC;IACpE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QACzC,MAAM,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACtD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,qCAAqC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChE,IAAI,KAAK;gBAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,GAAG,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IACH,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1D,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AACjE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingram-tech/nk-i18n",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Type-safe, English-as-key i18n for Ingram Next.js sites — ICU translator, scopes, locale config, and Accept-Language negotiation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
"test": "vitest run"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"intl-messageformat": "^11.2.
|
|
34
|
+
"intl-messageformat": "^11.2.10"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@ingram-tech/nk-dev": "0.
|
|
38
|
-
"@types/react": "^19.
|
|
39
|
-
"react": "^19.
|
|
40
|
-
"typescript": "^
|
|
41
|
-
"vitest": "^4.1.
|
|
37
|
+
"@ingram-tech/nk-dev": "0.5.0",
|
|
38
|
+
"@types/react": "^19.2.17",
|
|
39
|
+
"react": "^19.2.7",
|
|
40
|
+
"typescript": "^7.0.2",
|
|
41
|
+
"vitest": "^4.1.10"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"react": "^18.0.0 || ^19.0.0"
|