@nextop-os/ui-i18n-runtime 0.0.3

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 ADDED
@@ -0,0 +1,8 @@
1
+ # @nextop-os/ui-i18n-runtime
2
+
3
+ Host-agnostic i18n runtime helpers for shared Nextop frontend packages.
4
+
5
+ This package is published to npm as `@nextop-os/ui-i18n-runtime`.
6
+
7
+ Use it to compose reusable locale resources into one application-level runtime,
8
+ then scope that runtime for shared package surfaces when needed.
@@ -0,0 +1,39 @@
1
+ type I18nPrimitive = string | number | boolean | null | undefined;
2
+ type I18nParams = Record<string, I18nPrimitive>;
3
+ type I18nDictionary = {
4
+ readonly [key: string]: string | I18nDictionary;
5
+ };
6
+ interface LocaleObjectI18nModuleManifest {
7
+ exportMode: "locale-object";
8
+ fileByLocale: Record<string, string>;
9
+ name: string;
10
+ }
11
+ interface ScopedLocaleObjectsI18nModuleManifest {
12
+ exportMode: "scoped-locale-objects";
13
+ localeObjectByLocale: Record<string, string>;
14
+ name: string;
15
+ namespace: string;
16
+ sourceRoot: string;
17
+ }
18
+ type I18nModuleManifest = LocaleObjectI18nModuleManifest | ScopedLocaleObjectsI18nModuleManifest;
19
+ declare function createLocaleObjectI18nModuleManifest(input: {
20
+ fileByLocale: Record<string, string>;
21
+ name: string;
22
+ }): LocaleObjectI18nModuleManifest;
23
+ declare function createScopedLocaleObjectsI18nModuleManifest(input: {
24
+ localeObjectByLocale: Record<string, string>;
25
+ name: string;
26
+ namespace: string;
27
+ sourceRoot: string;
28
+ }): ScopedLocaleObjectsI18nModuleManifest;
29
+ interface I18nRuntime<TKey extends string = string> {
30
+ has(key: TKey): boolean;
31
+ t(key: TKey, params?: I18nParams): string;
32
+ tFirst(keys: readonly TKey[], params?: I18nParams): string;
33
+ }
34
+ declare function createI18nRuntime<TKey extends string = string>(input: {
35
+ dictionaries: readonly I18nDictionary[];
36
+ }): I18nRuntime<TKey>;
37
+ declare function createScopedI18nRuntime<TKey extends string = string>(runtime: I18nRuntime<string>, namespace: string): I18nRuntime<TKey>;
38
+
39
+ export { type I18nDictionary, type I18nModuleManifest, type I18nParams, type I18nPrimitive, type I18nRuntime, type LocaleObjectI18nModuleManifest, type ScopedLocaleObjectsI18nModuleManifest, createI18nRuntime, createLocaleObjectI18nModuleManifest, createScopedI18nRuntime, createScopedLocaleObjectsI18nModuleManifest };
package/dist/index.js ADDED
@@ -0,0 +1,98 @@
1
+ // src/index.ts
2
+ function createLocaleObjectI18nModuleManifest(input) {
3
+ return {
4
+ exportMode: "locale-object",
5
+ fileByLocale: input.fileByLocale,
6
+ name: input.name
7
+ };
8
+ }
9
+ function createScopedLocaleObjectsI18nModuleManifest(input) {
10
+ return {
11
+ exportMode: "scoped-locale-objects",
12
+ localeObjectByLocale: input.localeObjectByLocale,
13
+ name: input.name,
14
+ namespace: input.namespace,
15
+ sourceRoot: input.sourceRoot
16
+ };
17
+ }
18
+ function createI18nRuntime(input) {
19
+ return {
20
+ has(key) {
21
+ return resolveI18nValue(input.dictionaries, key) !== null;
22
+ },
23
+ t(key, params) {
24
+ const resolved = resolveI18nValue(input.dictionaries, key);
25
+ if (resolved === null) {
26
+ return key;
27
+ }
28
+ return interpolateI18nTemplate(resolved, params);
29
+ },
30
+ tFirst(keys, params) {
31
+ for (const key of keys) {
32
+ const resolved = resolveI18nValue(input.dictionaries, key);
33
+ if (resolved !== null) {
34
+ return interpolateI18nTemplate(resolved, params);
35
+ }
36
+ }
37
+ return keys[0] ?? "";
38
+ }
39
+ };
40
+ }
41
+ function createScopedI18nRuntime(runtime, namespace) {
42
+ return {
43
+ has(key) {
44
+ return runtime.has(joinI18nKey(namespace, key));
45
+ },
46
+ t(key, params) {
47
+ return runtime.t(joinI18nKey(namespace, key), params);
48
+ },
49
+ tFirst(keys, params) {
50
+ return runtime.tFirst(
51
+ keys.map((key) => joinI18nKey(namespace, key)),
52
+ params
53
+ );
54
+ }
55
+ };
56
+ }
57
+ function joinI18nKey(namespace, key) {
58
+ return `${namespace}.${key}`;
59
+ }
60
+ function resolveI18nValue(dictionaries, key) {
61
+ for (const dictionary of dictionaries) {
62
+ const resolved = resolveDictionaryValue(dictionary, key);
63
+ if (resolved !== null) {
64
+ return resolved;
65
+ }
66
+ }
67
+ return null;
68
+ }
69
+ function resolveDictionaryValue(dictionary, key) {
70
+ const segments = key.split(".");
71
+ let current = dictionary;
72
+ for (const segment of segments) {
73
+ if (typeof current === "string" || !current) {
74
+ return null;
75
+ }
76
+ current = current[segment];
77
+ }
78
+ return typeof current === "string" ? current : null;
79
+ }
80
+ function interpolateI18nTemplate(template, params) {
81
+ if (!params) {
82
+ return template;
83
+ }
84
+ return template.replace(
85
+ /\{\{\s*([\w.]+)\s*\}\}/g,
86
+ (_match, key) => {
87
+ const value = params[key];
88
+ return value === null || value === void 0 ? "" : String(value);
89
+ }
90
+ );
91
+ }
92
+ export {
93
+ createI18nRuntime,
94
+ createLocaleObjectI18nModuleManifest,
95
+ createScopedI18nRuntime,
96
+ createScopedLocaleObjectsI18nModuleManifest
97
+ };
98
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type I18nPrimitive = string | number | boolean | null | undefined;\n\nexport type I18nParams = Record<string, I18nPrimitive>;\n\nexport type I18nDictionary = {\n readonly [key: string]: string | I18nDictionary;\n};\n\nexport interface LocaleObjectI18nModuleManifest {\n exportMode: \"locale-object\";\n fileByLocale: Record<string, string>;\n name: string;\n}\n\nexport interface ScopedLocaleObjectsI18nModuleManifest {\n exportMode: \"scoped-locale-objects\";\n localeObjectByLocale: Record<string, string>;\n name: string;\n namespace: string;\n sourceRoot: string;\n}\n\nexport type I18nModuleManifest =\n | LocaleObjectI18nModuleManifest\n | ScopedLocaleObjectsI18nModuleManifest;\n\nexport function createLocaleObjectI18nModuleManifest(input: {\n fileByLocale: Record<string, string>;\n name: string;\n}): LocaleObjectI18nModuleManifest {\n return {\n exportMode: \"locale-object\",\n fileByLocale: input.fileByLocale,\n name: input.name\n };\n}\n\nexport function createScopedLocaleObjectsI18nModuleManifest(input: {\n localeObjectByLocale: Record<string, string>;\n name: string;\n namespace: string;\n sourceRoot: string;\n}): ScopedLocaleObjectsI18nModuleManifest {\n return {\n exportMode: \"scoped-locale-objects\",\n localeObjectByLocale: input.localeObjectByLocale,\n name: input.name,\n namespace: input.namespace,\n sourceRoot: input.sourceRoot\n };\n}\n\nexport interface I18nRuntime<TKey extends string = string> {\n has(key: TKey): boolean;\n t(key: TKey, params?: I18nParams): string;\n tFirst(keys: readonly TKey[], params?: I18nParams): string;\n}\n\nexport function createI18nRuntime<TKey extends string = string>(input: {\n dictionaries: readonly I18nDictionary[];\n}): I18nRuntime<TKey> {\n return {\n has(key) {\n return resolveI18nValue(input.dictionaries, key) !== null;\n },\n t(key, params) {\n const resolved = resolveI18nValue(input.dictionaries, key);\n if (resolved === null) {\n return key;\n }\n\n return interpolateI18nTemplate(resolved, params);\n },\n tFirst(keys, params) {\n for (const key of keys) {\n const resolved = resolveI18nValue(input.dictionaries, key);\n if (resolved !== null) {\n return interpolateI18nTemplate(resolved, params);\n }\n }\n\n return keys[0] ?? \"\";\n }\n };\n}\n\nexport function createScopedI18nRuntime<TKey extends string = string>(\n runtime: I18nRuntime<string>,\n namespace: string\n): I18nRuntime<TKey> {\n return {\n has(key) {\n return runtime.has(joinI18nKey(namespace, key));\n },\n t(key, params) {\n return runtime.t(joinI18nKey(namespace, key), params);\n },\n tFirst(keys, params) {\n return runtime.tFirst(\n keys.map((key) => joinI18nKey(namespace, key)),\n params\n );\n }\n };\n}\n\nfunction joinI18nKey(namespace: string, key: string): string {\n return `${namespace}.${key}`;\n}\n\nfunction resolveI18nValue(\n dictionaries: readonly I18nDictionary[],\n key: string\n): string | null {\n for (const dictionary of dictionaries) {\n const resolved = resolveDictionaryValue(dictionary, key);\n if (resolved !== null) {\n return resolved;\n }\n }\n\n return null;\n}\n\nfunction resolveDictionaryValue(\n dictionary: I18nDictionary,\n key: string\n): string | null {\n const segments = key.split(\".\");\n let current: string | I18nDictionary | undefined = dictionary;\n\n for (const segment of segments) {\n if (typeof current === \"string\" || !current) {\n return null;\n }\n current = current[segment];\n }\n\n return typeof current === \"string\" ? current : null;\n}\n\nfunction interpolateI18nTemplate(\n template: string,\n params: I18nParams | undefined\n): string {\n if (!params) {\n return template;\n }\n\n return template.replace(\n /\\{\\{\\s*([\\w.]+)\\s*\\}\\}/g,\n (_match: string, key: string) => {\n const value = params[key];\n return value === null || value === undefined ? \"\" : String(value);\n }\n );\n}\n"],"mappings":";AA0BO,SAAS,qCAAqC,OAGlB;AACjC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,cAAc,MAAM;AAAA,IACpB,MAAM,MAAM;AAAA,EACd;AACF;AAEO,SAAS,4CAA4C,OAKlB;AACxC,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,sBAAsB,MAAM;AAAA,IAC5B,MAAM,MAAM;AAAA,IACZ,WAAW,MAAM;AAAA,IACjB,YAAY,MAAM;AAAA,EACpB;AACF;AAQO,SAAS,kBAAgD,OAE1C;AACpB,SAAO;AAAA,IACL,IAAI,KAAK;AACP,aAAO,iBAAiB,MAAM,cAAc,GAAG,MAAM;AAAA,IACvD;AAAA,IACA,EAAE,KAAK,QAAQ;AACb,YAAM,WAAW,iBAAiB,MAAM,cAAc,GAAG;AACzD,UAAI,aAAa,MAAM;AACrB,eAAO;AAAA,MACT;AAEA,aAAO,wBAAwB,UAAU,MAAM;AAAA,IACjD;AAAA,IACA,OAAO,MAAM,QAAQ;AACnB,iBAAW,OAAO,MAAM;AACtB,cAAM,WAAW,iBAAiB,MAAM,cAAc,GAAG;AACzD,YAAI,aAAa,MAAM;AACrB,iBAAO,wBAAwB,UAAU,MAAM;AAAA,QACjD;AAAA,MACF;AAEA,aAAO,KAAK,CAAC,KAAK;AAAA,IACpB;AAAA,EACF;AACF;AAEO,SAAS,wBACd,SACA,WACmB;AACnB,SAAO;AAAA,IACL,IAAI,KAAK;AACP,aAAO,QAAQ,IAAI,YAAY,WAAW,GAAG,CAAC;AAAA,IAChD;AAAA,IACA,EAAE,KAAK,QAAQ;AACb,aAAO,QAAQ,EAAE,YAAY,WAAW,GAAG,GAAG,MAAM;AAAA,IACtD;AAAA,IACA,OAAO,MAAM,QAAQ;AACnB,aAAO,QAAQ;AAAA,QACb,KAAK,IAAI,CAAC,QAAQ,YAAY,WAAW,GAAG,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,WAAmB,KAAqB;AAC3D,SAAO,GAAG,SAAS,IAAI,GAAG;AAC5B;AAEA,SAAS,iBACP,cACA,KACe;AACf,aAAW,cAAc,cAAc;AACrC,UAAM,WAAW,uBAAuB,YAAY,GAAG;AACvD,QAAI,aAAa,MAAM;AACrB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,uBACP,YACA,KACe;AACf,QAAM,WAAW,IAAI,MAAM,GAAG;AAC9B,MAAI,UAA+C;AAEnD,aAAW,WAAW,UAAU;AAC9B,QAAI,OAAO,YAAY,YAAY,CAAC,SAAS;AAC3C,aAAO;AAAA,IACT;AACA,cAAU,QAAQ,OAAO;AAAA,EAC3B;AAEA,SAAO,OAAO,YAAY,WAAW,UAAU;AACjD;AAEA,SAAS,wBACP,UACA,QACQ;AACR,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,SAAO,SAAS;AAAA,IACd;AAAA,IACA,CAAC,QAAgB,QAAgB;AAC/B,YAAM,QAAQ,OAAO,GAAG;AACxB,aAAO,UAAU,QAAQ,UAAU,SAAY,KAAK,OAAO,KAAK;AAAA,IAClE;AAAA,EACF;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@nextop-os/ui-i18n-runtime",
3
+ "version": "0.0.3",
4
+ "private": false,
5
+ "type": "module",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/nextop-os/nextop.git",
19
+ "directory": "packages/ui/i18n-runtime"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.8.3",
23
+ "@nextop-os/config-tsconfig": "0.0.0"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "scripts": {
29
+ "build": "tsup --config tsup.config.ts",
30
+ "typecheck": "tsc --noEmit -p tsconfig.json"
31
+ }
32
+ }