@ankhorage/orchestrator-module-expo-localization 0.1.5 → 0.3.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/CHANGELOG.md +12 -0
- package/README.md +56 -3
- package/dist/authoring.d.ts +56 -0
- package/dist/authoring.d.ts.map +1 -0
- package/dist/authoring.js +76 -0
- package/dist/authoring.js.map +1 -0
- package/dist/config.d.ts +13 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +73 -21
- package/dist/config.js.map +1 -1
- package/dist/host.d.ts +35 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +39 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +16 -4
- package/dist/module.js.map +1 -1
- package/dist/resources.d.ts +40 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +209 -0
- package/dist/resources.js.map +1 -0
- package/dist/templateFiles.js +6 -6
- package/package.json +6 -2
- package/templates/LocalizationProvider.tsx.tpl +3 -3
- package/templates/index.ts.tpl +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/orchestrator-module-expo-localization
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9bd52ad: Own locale validation, canonical dictionary resources, and metadata-driven translatable-field discovery in the localization module. Translation dictionaries now live only in runtime-consumed locale JSON resources and can be edited without module reconfiguration. Require Orchestrator 0.3.1 so failed lifecycle reconfiguration preserves the exact domain-edited resource pre-state.
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- ef56e0d: Generate localization runtime files under the canonical `src/modules/localization` namespace and rename the generated provider to `LocalizationModuleProvider`. Add an optional package-owned host contribution with generic metadata, layout integration, config normalization, and a serializable admin schema while keeping the root Orchestrator module standalone.
|
|
14
|
+
|
|
3
15
|
## 0.1.5
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,12 +8,65 @@ Adds localization support to Expo apps.
|
|
|
8
8
|
- No boilerplate
|
|
9
9
|
- Fully reversible
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Usage
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
orchestrator
|
|
14
|
+
import { createOrchestrator } from '@ankhorage/orchestrator';
|
|
15
|
+
import { expoLocalizationModule } from '@ankhorage/orchestrator-module-expo-localization';
|
|
16
|
+
|
|
17
|
+
const orchestrator = createOrchestrator({
|
|
18
|
+
modules: [expoLocalizationModule],
|
|
19
|
+
projectRoot: '/path/to/project',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
await orchestrator.installModule('expo-localization', { config: {} });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The Orchestrator ledger is the canonical lifecycle and configuration source. Updating an existing
|
|
26
|
+
installation uses `reconfigureModule()`, which also removes outputs recorded by an earlier module
|
|
27
|
+
version before generating the canonical `src/modules/localization` namespace.
|
|
28
|
+
|
|
29
|
+
The ledger configuration contains only lifecycle settings (`locales` and `defaultLocale`).
|
|
30
|
+
Translation dictionaries are module-owned domain resources at
|
|
31
|
+
`src/modules/localization/locales/{locale}.json`. These files are the single writable dictionary
|
|
32
|
+
source and are imported directly by the generated runtime; they are not mirrored into ledger config.
|
|
33
|
+
Use the package APIs for ordinary dictionary edits without reinstalling or reconfiguring the module:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import {
|
|
37
|
+
readExpoLocalizationDictionaries,
|
|
38
|
+
setExpoLocalizationTranslation,
|
|
39
|
+
} from '@ankhorage/orchestrator-module-expo-localization';
|
|
40
|
+
|
|
41
|
+
const dictionaries = await readExpoLocalizationDictionaries({
|
|
42
|
+
projectRoot: '/path/to/project',
|
|
43
|
+
locales: ['en', 'de'],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await setExpoLocalizationTranslation({
|
|
47
|
+
projectRoot: '/path/to/project',
|
|
48
|
+
locale: 'de',
|
|
49
|
+
key: 'home.title',
|
|
50
|
+
value: 'Startseite',
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Missing locale resource files load as empty dictionaries. Invalid files fail explicitly. Writes are
|
|
55
|
+
atomic and keys are sorted so runtime and source-control output remain deterministic. Existing
|
|
56
|
+
`translations` ledger data is accepted only as a one-time seed when a canonical locale file does not
|
|
57
|
+
yet exist; normalized config never writes dictionaries back to the ledger.
|
|
58
|
+
|
|
59
|
+
Package-neutral helpers for locale rules and translatable-field discovery are also exported from the
|
|
60
|
+
root package. Discovery accepts manifest-shaped nodes and component metadata from the caller, so the
|
|
61
|
+
module has no Studio component-registry dependency.
|
|
62
|
+
|
|
63
|
+
Generic authoring hosts can opt into the package-owned metadata, layout integration, config
|
|
64
|
+
normalizer, and serializable admin schema without making the core module depend on Studio:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { expoLocalizationHostContribution } from '@ankhorage/orchestrator-module-expo-localization/host';
|
|
15
68
|
```
|
|
16
69
|
|
|
17
|
-
##
|
|
70
|
+
## Why this exists
|
|
18
71
|
|
|
19
72
|
Standardizes localization setup across apps.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ExpoLocalizationDictionaries } from './resources';
|
|
2
|
+
export interface ExpoLocalizationManifestNode {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly alias?: string;
|
|
6
|
+
readonly props?: Readonly<Record<string, unknown>>;
|
|
7
|
+
readonly children?: readonly ExpoLocalizationManifestNode[];
|
|
8
|
+
}
|
|
9
|
+
export interface ExpoLocalizationManifestScreen {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
readonly root: ExpoLocalizationManifestNode;
|
|
12
|
+
}
|
|
13
|
+
export interface ExpoLocalizationComponentMetaField {
|
|
14
|
+
readonly keyProp: string;
|
|
15
|
+
readonly defaultTextProp: string;
|
|
16
|
+
}
|
|
17
|
+
export interface ExpoLocalizationComponentMeta {
|
|
18
|
+
readonly i18n?: {
|
|
19
|
+
readonly fields?: readonly ExpoLocalizationComponentMetaField[];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export type ExpoLocalizationComponentMetaRegistry = Readonly<Record<string, ExpoLocalizationComponentMeta | undefined>>;
|
|
23
|
+
export interface ExpoLocalizationTranslatableField {
|
|
24
|
+
readonly screenId: string;
|
|
25
|
+
readonly nodeId: string;
|
|
26
|
+
readonly componentName: string;
|
|
27
|
+
readonly keyProp: string;
|
|
28
|
+
readonly defaultTextProp: string;
|
|
29
|
+
readonly currentKey: string;
|
|
30
|
+
readonly defaultText: string;
|
|
31
|
+
readonly path: string;
|
|
32
|
+
}
|
|
33
|
+
export interface ExpoLocalizationMissingTranslation {
|
|
34
|
+
readonly key: string;
|
|
35
|
+
readonly missingLocales: readonly string[];
|
|
36
|
+
readonly fieldCount: number;
|
|
37
|
+
}
|
|
38
|
+
export type ExpoLocalizationFieldFilter = 'all' | 'unlinked' | 'missing-translations' | 'incomplete';
|
|
39
|
+
export declare function collectExpoLocalizationTranslatableFields(args: {
|
|
40
|
+
readonly screens: readonly ExpoLocalizationManifestScreen[];
|
|
41
|
+
readonly componentMeta: ExpoLocalizationComponentMetaRegistry;
|
|
42
|
+
}): ExpoLocalizationTranslatableField[];
|
|
43
|
+
export declare function findExpoLocalizationMissingTranslations(args: {
|
|
44
|
+
readonly fields: readonly ExpoLocalizationTranslatableField[];
|
|
45
|
+
readonly locales: readonly string[];
|
|
46
|
+
readonly dictionaries: ExpoLocalizationDictionaries;
|
|
47
|
+
}): ExpoLocalizationMissingTranslation[];
|
|
48
|
+
export declare function filterExpoLocalizationTranslatableFields(args: {
|
|
49
|
+
readonly fields: readonly ExpoLocalizationTranslatableField[];
|
|
50
|
+
readonly searchQuery?: string;
|
|
51
|
+
readonly filter?: ExpoLocalizationFieldFilter;
|
|
52
|
+
readonly locales: readonly string[];
|
|
53
|
+
readonly dictionaries: ExpoLocalizationDictionaries;
|
|
54
|
+
}): ExpoLocalizationTranslatableField[];
|
|
55
|
+
export declare function createExpoLocalizationKeyFromText(text: string): string;
|
|
56
|
+
//# sourceMappingURL=authoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring.d.ts","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,4BAA4B,EAAE,CAAC;CAC7D;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;CAC7C;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,CAAC,EAAE;QACd,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,kCAAkC,EAAE,CAAC;KACjE,CAAC;CACH;AAED,MAAM,MAAM,qCAAqC,GAAG,QAAQ,CAC1D,MAAM,CAAC,MAAM,EAAE,6BAA6B,GAAG,SAAS,CAAC,CAC1D,CAAC;AAEF,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,2BAA2B,GACnC,KAAK,GACL,UAAU,GACV,sBAAsB,GACtB,YAAY,CAAC;AAEjB,wBAAgB,yCAAyC,CAAC,IAAI,EAAE;IAC9D,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;IAC5D,QAAQ,CAAC,aAAa,EAAE,qCAAqC,CAAC;CAC/D,GAAG,iCAAiC,EAAE,CAQtC;AAED,wBAAgB,uCAAuC,CAAC,IAAI,EAAE;IAC5D,QAAQ,CAAC,MAAM,EAAE,SAAS,iCAAiC,EAAE,CAAC;IAC9D,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,4BAA4B,CAAC;CACrD,GAAG,kCAAkC,EAAE,CAgBvC;AAED,wBAAgB,wCAAwC,CAAC,IAAI,EAAE;IAC7D,QAAQ,CAAC,MAAM,EAAE,SAAS,iCAAiC,EAAE,CAAC;IAC9D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,4BAA4B,CAAC;CACrD,GAAG,iCAAiC,EAAE,CAqBtC;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export function collectExpoLocalizationTranslatableFields(args) {
|
|
2
|
+
const refs = [];
|
|
3
|
+
for (const screen of args.screens) {
|
|
4
|
+
traverse(screen.root, screen.id, screen.id, args.componentMeta, refs);
|
|
5
|
+
}
|
|
6
|
+
return refs;
|
|
7
|
+
}
|
|
8
|
+
export function findExpoLocalizationMissingTranslations(args) {
|
|
9
|
+
const fieldCounts = new Map();
|
|
10
|
+
for (const field of args.fields) {
|
|
11
|
+
if (field.currentKey) {
|
|
12
|
+
fieldCounts.set(field.currentKey, (fieldCounts.get(field.currentKey) ?? 0) + 1);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return [...fieldCounts.entries()]
|
|
16
|
+
.map(([key, fieldCount]) => ({
|
|
17
|
+
key,
|
|
18
|
+
fieldCount,
|
|
19
|
+
missingLocales: args.locales.filter((locale) => !args.dictionaries[locale]?.[key]),
|
|
20
|
+
}))
|
|
21
|
+
.filter(({ missingLocales }) => missingLocales.length > 0)
|
|
22
|
+
.sort(({ key: left }, { key: right }) => compareText(left, right));
|
|
23
|
+
}
|
|
24
|
+
export function filterExpoLocalizationTranslatableFields(args) {
|
|
25
|
+
const query = args.searchQuery?.trim().toLowerCase() ?? '';
|
|
26
|
+
const filter = args.filter ?? 'all';
|
|
27
|
+
return args.fields.filter((field) => {
|
|
28
|
+
const matchesSearch = !query ||
|
|
29
|
+
[field.nodeId, field.componentName, field.currentKey, field.defaultText, field.path].some((value) => value.toLowerCase().includes(query));
|
|
30
|
+
if (!matchesSearch)
|
|
31
|
+
return false;
|
|
32
|
+
const isUnlinked = !field.currentKey;
|
|
33
|
+
const hasMissingTranslation = !isUnlinked && args.locales.some((locale) => !args.dictionaries[locale]?.[field.currentKey]);
|
|
34
|
+
if (filter === 'unlinked')
|
|
35
|
+
return isUnlinked;
|
|
36
|
+
if (filter === 'missing-translations')
|
|
37
|
+
return hasMissingTranslation;
|
|
38
|
+
if (filter === 'incomplete')
|
|
39
|
+
return isUnlinked || hasMissingTranslation;
|
|
40
|
+
return true;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export function createExpoLocalizationKeyFromText(text) {
|
|
44
|
+
return text
|
|
45
|
+
.normalize('NFKD')
|
|
46
|
+
.replace(/[\u0300-\u036f]/g, '')
|
|
47
|
+
.trim()
|
|
48
|
+
.toLowerCase()
|
|
49
|
+
.replace(/[^a-z0-9.-]+/g, '_')
|
|
50
|
+
.replace(/^_+|_+$/g, '');
|
|
51
|
+
}
|
|
52
|
+
function traverse(node, screenId, parentPath, componentMeta, refs) {
|
|
53
|
+
const path = `${parentPath} > ${node.alias ?? node.type}`;
|
|
54
|
+
for (const field of componentMeta[node.type]?.i18n?.fields ?? []) {
|
|
55
|
+
refs.push({
|
|
56
|
+
screenId,
|
|
57
|
+
nodeId: node.id,
|
|
58
|
+
componentName: node.type,
|
|
59
|
+
keyProp: field.keyProp,
|
|
60
|
+
defaultTextProp: field.defaultTextProp,
|
|
61
|
+
currentKey: readString(node.props?.[field.keyProp]),
|
|
62
|
+
defaultText: readString(node.props?.[field.defaultTextProp]),
|
|
63
|
+
path,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
for (const child of node.children ?? []) {
|
|
67
|
+
traverse(child, screenId, path, componentMeta, refs);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function readString(value) {
|
|
71
|
+
return typeof value === 'string' ? value : '';
|
|
72
|
+
}
|
|
73
|
+
function compareText(left, right) {
|
|
74
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=authoring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authoring.js","sourceRoot":"","sources":["../src/authoring.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
export interface ExpoLocalizationModuleConfig {
|
|
2
2
|
defaultLocale?: string;
|
|
3
|
-
locales?: string[];
|
|
4
|
-
translations?: Record<string, Record<string, string>>;
|
|
3
|
+
locales?: readonly string[];
|
|
5
4
|
}
|
|
6
|
-
export
|
|
5
|
+
export interface NormalizedExpoLocalizationModuleConfig {
|
|
6
|
+
defaultLocale: string;
|
|
7
|
+
locales: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare class ExpoLocalizationConfigError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
export declare function parseExpoLocalizationModuleConfig(input: unknown): NormalizedExpoLocalizationModuleConfig;
|
|
13
|
+
export declare function normalizeExpoLocalizationLocale(input: string): string;
|
|
14
|
+
export declare function addExpoLocalizationLocale(config: ExpoLocalizationModuleConfig, localeInput: string): NormalizedExpoLocalizationModuleConfig;
|
|
15
|
+
export declare function removeExpoLocalizationLocale(config: ExpoLocalizationModuleConfig, localeInput: string): NormalizedExpoLocalizationModuleConfig;
|
|
16
|
+
export declare function setExpoLocalizationDefaultLocale(config: ExpoLocalizationModuleConfig, localeInput: string): NormalizedExpoLocalizationModuleConfig;
|
|
7
17
|
//# sourceMappingURL=config.d.ts.map
|
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,WAAW,4BAA4B;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,4BAA4B;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,sCAAsC;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,OAAO,GACb,sCAAsC,CAaxC;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,4BAA4B,EACpC,WAAW,EAAE,MAAM,GAClB,sCAAsC,CAOxC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,EACpC,WAAW,EAAE,MAAM,GAClB,sCAAsC,CAkBxC;AAED,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,4BAA4B,EACpC,WAAW,EAAE,MAAM,GAClB,sCAAsC,CASxC"}
|
package/dist/config.js
CHANGED
|
@@ -1,28 +1,80 @@
|
|
|
1
|
+
export class ExpoLocalizationConfigError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'ExpoLocalizationConfigError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
1
7
|
export function parseExpoLocalizationModuleConfig(input) {
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
const record = isRecord(input) ? input : {};
|
|
9
|
+
const parsedDefaultLocale = parseLocale(record.defaultLocale);
|
|
10
|
+
const locales = Array.isArray(record.locales)
|
|
11
|
+
? uniqueLocales(record.locales.map(parseLocale).filter(isDefined))
|
|
12
|
+
: [];
|
|
13
|
+
const defaultLocale = parsedDefaultLocale ?? locales[0] ?? 'en';
|
|
14
|
+
if (!locales.includes(defaultLocale)) {
|
|
15
|
+
locales.push(defaultLocale);
|
|
16
|
+
}
|
|
17
|
+
return { defaultLocale, locales };
|
|
18
|
+
}
|
|
19
|
+
export function normalizeExpoLocalizationLocale(input) {
|
|
20
|
+
const locale = parseLocale(input);
|
|
21
|
+
if (!locale) {
|
|
22
|
+
throw new ExpoLocalizationConfigError(`Invalid locale: ${JSON.stringify(input)}.`);
|
|
23
|
+
}
|
|
24
|
+
return locale;
|
|
25
|
+
}
|
|
26
|
+
export function addExpoLocalizationLocale(config, localeInput) {
|
|
27
|
+
const normalized = parseExpoLocalizationModuleConfig(config);
|
|
28
|
+
const locale = normalizeExpoLocalizationLocale(localeInput);
|
|
29
|
+
if (!normalized.locales.includes(locale)) {
|
|
30
|
+
normalized.locales.push(locale);
|
|
31
|
+
}
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
export function removeExpoLocalizationLocale(config, localeInput) {
|
|
35
|
+
const normalized = parseExpoLocalizationModuleConfig(config);
|
|
36
|
+
const locale = normalizeExpoLocalizationLocale(localeInput);
|
|
37
|
+
if (!normalized.locales.includes(locale)) {
|
|
38
|
+
return normalized;
|
|
39
|
+
}
|
|
40
|
+
if (normalized.locales.length === 1) {
|
|
41
|
+
throw new ExpoLocalizationConfigError('The final configured locale cannot be removed.');
|
|
42
|
+
}
|
|
43
|
+
const locales = normalized.locales.filter((candidate) => candidate !== locale);
|
|
20
44
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
45
|
+
locales,
|
|
46
|
+
defaultLocale: normalized.defaultLocale === locale
|
|
47
|
+
? (locales[0] ?? normalized.defaultLocale)
|
|
48
|
+
: normalized.defaultLocale,
|
|
24
49
|
};
|
|
25
50
|
}
|
|
51
|
+
export function setExpoLocalizationDefaultLocale(config, localeInput) {
|
|
52
|
+
const normalized = parseExpoLocalizationModuleConfig(config);
|
|
53
|
+
const defaultLocale = normalizeExpoLocalizationLocale(localeInput);
|
|
54
|
+
if (!normalized.locales.includes(defaultLocale)) {
|
|
55
|
+
throw new ExpoLocalizationConfigError(`Default locale ${JSON.stringify(defaultLocale)} is not configured.`);
|
|
56
|
+
}
|
|
57
|
+
return { ...normalized, defaultLocale };
|
|
58
|
+
}
|
|
59
|
+
function parseLocale(input) {
|
|
60
|
+
if (typeof input !== 'string')
|
|
61
|
+
return undefined;
|
|
62
|
+
const candidate = input.trim().replaceAll('_', '-');
|
|
63
|
+
if (!candidate)
|
|
64
|
+
return undefined;
|
|
65
|
+
try {
|
|
66
|
+
return Intl.getCanonicalLocales(candidate)[0];
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function uniqueLocales(locales) {
|
|
73
|
+
return [...new Set(locales)];
|
|
74
|
+
}
|
|
75
|
+
function isDefined(value) {
|
|
76
|
+
return value !== undefined;
|
|
77
|
+
}
|
|
26
78
|
function isRecord(value) {
|
|
27
79
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
28
80
|
}
|
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":"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"}
|
package/dist/host.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { parseExpoLocalizationModuleConfig } from './config';
|
|
2
|
+
/**
|
|
3
|
+
* Optional package-owned data consumed by generic authoring hosts.
|
|
4
|
+
* The core module remains independently usable from the package root.
|
|
5
|
+
*/
|
|
6
|
+
export declare const expoLocalizationHostContribution: {
|
|
7
|
+
readonly id: "expo-localization";
|
|
8
|
+
readonly name: "Localization (Expo)";
|
|
9
|
+
readonly description: "Multi-language support powered by expo-localization and i18next.";
|
|
10
|
+
readonly definition: import("@ankhorage/orchestrator").ModuleDefinition<import("./config").ExpoLocalizationModuleConfig>;
|
|
11
|
+
readonly normalizeConfig: typeof parseExpoLocalizationModuleConfig;
|
|
12
|
+
readonly layout: {
|
|
13
|
+
readonly imports: readonly ["import { LocalizationModuleProvider } from \"@/modules/localization\";"];
|
|
14
|
+
readonly hooks: readonly [];
|
|
15
|
+
readonly providerStart: readonly ["<LocalizationModuleProvider>"];
|
|
16
|
+
readonly providerEnd: readonly ["</LocalizationModuleProvider>"];
|
|
17
|
+
};
|
|
18
|
+
readonly admin: {
|
|
19
|
+
readonly kind: "config-schema";
|
|
20
|
+
readonly title: "Localization";
|
|
21
|
+
readonly description: "Configure supported locales and the default locale.";
|
|
22
|
+
readonly fields: readonly [{
|
|
23
|
+
readonly key: "defaultLocale";
|
|
24
|
+
readonly label: "Default locale";
|
|
25
|
+
readonly control: "text";
|
|
26
|
+
readonly required: true;
|
|
27
|
+
}, {
|
|
28
|
+
readonly key: "locales";
|
|
29
|
+
readonly label: "Locales";
|
|
30
|
+
readonly control: "string-list";
|
|
31
|
+
readonly required: true;
|
|
32
|
+
}];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAG7D;;;GAGG;AACH,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BnC,CAAC"}
|
package/dist/host.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { parseExpoLocalizationModuleConfig } from './config';
|
|
2
|
+
import { EXPO_LOCALIZATION_MODULE_ID, expoLocalizationModule } from './module';
|
|
3
|
+
/**
|
|
4
|
+
* Optional package-owned data consumed by generic authoring hosts.
|
|
5
|
+
* The core module remains independently usable from the package root.
|
|
6
|
+
*/
|
|
7
|
+
export const expoLocalizationHostContribution = {
|
|
8
|
+
id: EXPO_LOCALIZATION_MODULE_ID,
|
|
9
|
+
name: 'Localization (Expo)',
|
|
10
|
+
description: 'Multi-language support powered by expo-localization and i18next.',
|
|
11
|
+
definition: expoLocalizationModule,
|
|
12
|
+
normalizeConfig: parseExpoLocalizationModuleConfig,
|
|
13
|
+
layout: {
|
|
14
|
+
imports: ['import { LocalizationModuleProvider } from "@/modules/localization";'],
|
|
15
|
+
hooks: [],
|
|
16
|
+
providerStart: ['<LocalizationModuleProvider>'],
|
|
17
|
+
providerEnd: ['</LocalizationModuleProvider>'],
|
|
18
|
+
},
|
|
19
|
+
admin: {
|
|
20
|
+
kind: 'config-schema',
|
|
21
|
+
title: 'Localization',
|
|
22
|
+
description: 'Configure supported locales and the default locale.',
|
|
23
|
+
fields: [
|
|
24
|
+
{
|
|
25
|
+
key: 'defaultLocale',
|
|
26
|
+
label: 'Default locale',
|
|
27
|
+
control: 'text',
|
|
28
|
+
required: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
key: 'locales',
|
|
32
|
+
label: 'Locales',
|
|
33
|
+
control: 'string-list',
|
|
34
|
+
required: true,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=host.js.map
|
package/dist/host.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG;IAC9C,EAAE,EAAE,2BAA2B;IAC/B,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,kEAAkE;IAC/E,UAAU,EAAE,sBAAsB;IAClC,eAAe,EAAE,iCAAiC;IAClD,MAAM,EAAE;QACN,OAAO,EAAE,CAAC,sEAAsE,CAAC;QACjF,KAAK,EAAE,EAAE;QACT,aAAa,EAAE,CAAC,8BAA8B,CAAC;QAC/C,WAAW,EAAE,CAAC,+BAA+B,CAAC;KAC/C;IACD,KAAK,EAAE;QACL,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,qDAAqD;QAClE,MAAM,EAAE;YACN;gBACE,GAAG,EAAE,eAAe;gBACpB,KAAK,EAAE,gBAAgB;gBACvB,OAAO,EAAE,MAAM;gBACf,QAAQ,EAAE,IAAI;aACf;YACD;gBACE,GAAG,EAAE,SAAS;gBACd,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,aAAa;gBACtB,QAAQ,EAAE,IAAI;aACf;SACF;KACF;CACO,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { type
|
|
1
|
+
export { collectExpoLocalizationTranslatableFields, createExpoLocalizationKeyFromText, type ExpoLocalizationComponentMeta, type ExpoLocalizationComponentMetaField, type ExpoLocalizationComponentMetaRegistry, type ExpoLocalizationFieldFilter, type ExpoLocalizationManifestNode, type ExpoLocalizationManifestScreen, type ExpoLocalizationMissingTranslation, type ExpoLocalizationTranslatableField, filterExpoLocalizationTranslatableFields, findExpoLocalizationMissingTranslations, } from './authoring';
|
|
2
|
+
export { addExpoLocalizationLocale, ExpoLocalizationConfigError, type ExpoLocalizationModuleConfig, type NormalizedExpoLocalizationModuleConfig, normalizeExpoLocalizationLocale, parseExpoLocalizationModuleConfig, removeExpoLocalizationLocale, setExpoLocalizationDefaultLocale, } from './config';
|
|
2
3
|
export { EXPO_LOCALIZATION_MODULE_ID, expoLocalizationModule } from './module';
|
|
4
|
+
export { deleteExpoLocalizationTranslation, EXPO_LOCALIZATION_RESOURCE_DIRECTORY, type ExpoLocalizationDictionaries, type ExpoLocalizationDictionary, ExpoLocalizationResourceError, readExpoLocalizationDictionaries, readExpoLocalizationDictionary, resolveExpoLocalizationDictionaryPath, setExpoLocalizationTranslation, writeExpoLocalizationDictionary, } from './resources';
|
|
3
5
|
//# 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":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yCAAyC,EACzC,iCAAiC,EACjC,KAAK,6BAA6B,EAClC,KAAK,kCAAkC,EACvC,KAAK,qCAAqC,EAC1C,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,iCAAiC,EACtC,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,KAAK,4BAA4B,EACjC,KAAK,sCAAsC,EAC3C,+BAA+B,EAC/B,iCAAiC,EACjC,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EACL,iCAAiC,EACjC,oCAAoC,EACpC,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,6BAA6B,EAC7B,gCAAgC,EAChC,8BAA8B,EAC9B,qCAAqC,EACrC,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { collectExpoLocalizationTranslatableFields, createExpoLocalizationKeyFromText, filterExpoLocalizationTranslatableFields, findExpoLocalizationMissingTranslations, } from './authoring';
|
|
2
|
+
export { addExpoLocalizationLocale, ExpoLocalizationConfigError, normalizeExpoLocalizationLocale, parseExpoLocalizationModuleConfig, removeExpoLocalizationLocale, setExpoLocalizationDefaultLocale, } from './config';
|
|
2
3
|
export { EXPO_LOCALIZATION_MODULE_ID, expoLocalizationModule } from './module';
|
|
4
|
+
export { deleteExpoLocalizationTranslation, EXPO_LOCALIZATION_RESOURCE_DIRECTORY, ExpoLocalizationResourceError, readExpoLocalizationDictionaries, readExpoLocalizationDictionary, resolveExpoLocalizationDictionaryPath, setExpoLocalizationTranslation, writeExpoLocalizationDictionary, } from './resources';
|
|
3
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yCAAyC,EACzC,iCAAiC,EASjC,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAG3B,+BAA+B,EAC/B,iCAAiC,EACjC,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EACL,iCAAiC,EACjC,oCAAoC,EAGpC,6BAA6B,EAC7B,gCAAgC,EAChC,8BAA8B,EAC9B,qCAAqC,EACrC,8BAA8B,EAC9B,+BAA+B,GAChC,MAAM,aAAa,CAAC"}
|
package/dist/module.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAE,KAAK,4BAA4B,EAAqC,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAE,KAAK,4BAA4B,EAAqC,MAAM,UAAU,CAAC;AAIhG,eAAO,MAAM,2BAA2B,sBAAsB,CAAC;AAE/D,eAAO,MAAM,sBAAsB,EAAE,gBAAgB,CAAC,4BAA4B,CAqE9E,CAAC"}
|
package/dist/module.js
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { defineModule } from '@ankhorage/orchestrator';
|
|
2
2
|
import { parseExpoLocalizationModuleConfig } from './config';
|
|
3
|
+
import { readExpoLocalizationResourceSeeds } from './resources';
|
|
3
4
|
import { buildLocalizationWriteFiles } from './templateFiles';
|
|
4
5
|
export const EXPO_LOCALIZATION_MODULE_ID = 'expo-localization';
|
|
5
6
|
export const expoLocalizationModule = defineModule({
|
|
6
7
|
id: EXPO_LOCALIZATION_MODULE_ID,
|
|
7
|
-
plan(context) {
|
|
8
|
+
async plan(context) {
|
|
8
9
|
const config = parseExpoLocalizationModuleConfig(context.config);
|
|
10
|
+
const translations = await readExpoLocalizationResourceSeeds({
|
|
11
|
+
projectRoot: context.projectRoot,
|
|
12
|
+
locales: config.locales,
|
|
13
|
+
legacyTranslations: readLegacyTranslations(context.config),
|
|
14
|
+
});
|
|
9
15
|
return [
|
|
10
16
|
{
|
|
11
17
|
type: 'ensure-packages',
|
|
@@ -20,14 +26,14 @@ export const expoLocalizationModule = defineModule({
|
|
|
20
26
|
files: buildLocalizationWriteFiles({
|
|
21
27
|
defaultLocale: config.defaultLocale,
|
|
22
28
|
locales: config.locales,
|
|
23
|
-
translations
|
|
29
|
+
translations,
|
|
24
30
|
}),
|
|
25
31
|
},
|
|
26
32
|
{
|
|
27
33
|
type: 'patch-text-block',
|
|
28
34
|
path: 'src/app/_layout.tsx',
|
|
29
35
|
blockId: `${EXPO_LOCALIZATION_MODULE_ID}:root-layout-import`,
|
|
30
|
-
content: 'import {
|
|
36
|
+
content: 'import { LocalizationModuleProvider } from "@/modules/localization";',
|
|
31
37
|
anchor: {
|
|
32
38
|
find: "import ankhConfig from '@root/ankh.config.json';",
|
|
33
39
|
position: 'before',
|
|
@@ -37,7 +43,7 @@ export const expoLocalizationModule = defineModule({
|
|
|
37
43
|
type: 'patch-text-block',
|
|
38
44
|
path: 'src/app/_layout.tsx',
|
|
39
45
|
blockId: `${EXPO_LOCALIZATION_MODULE_ID}:root-layout-provider`,
|
|
40
|
-
content: ' output = <
|
|
46
|
+
content: ' output = <LocalizationModuleProvider>{output}</LocalizationModuleProvider>;',
|
|
41
47
|
anchor: {
|
|
42
48
|
find: ' return (',
|
|
43
49
|
position: 'before',
|
|
@@ -65,4 +71,10 @@ export const expoLocalizationModule = defineModule({
|
|
|
65
71
|
];
|
|
66
72
|
},
|
|
67
73
|
});
|
|
74
|
+
function readLegacyTranslations(config) {
|
|
75
|
+
return isRecord(config) ? config.translations : undefined;
|
|
76
|
+
}
|
|
77
|
+
function isRecord(value) {
|
|
78
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
79
|
+
}
|
|
68
80
|
//# sourceMappingURL=module.js.map
|
package/dist/module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4C,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAqC,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAChG,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAAC;AAE/D,MAAM,CAAC,MAAM,sBAAsB,GACjC,YAAY,CAA+B;IACzC,EAAE,EAAE,2BAA2B;IAC/B,IAAI,CAAC,OAAO;
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA4C,MAAM,yBAAyB,CAAC;AAEjG,OAAO,EAAqC,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAChG,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAAC;AAE/D,MAAM,CAAC,MAAM,sBAAsB,GACjC,YAAY,CAA+B;IACzC,EAAE,EAAE,2BAA2B;IAC/B,KAAK,CAAC,IAAI,CAAC,OAAO;QAChB,MAAM,MAAM,GAAG,iCAAiC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjE,MAAM,YAAY,GAAG,MAAM,iCAAiC,CAAC;YAC3D,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,kBAAkB,EAAE,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC;SAC3D,CAAC,CAAC;QAEH,OAAO;YACL;gBACE,IAAI,EAAE,iBAAiB;gBACvB,GAAG,EAAE;oBACH,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE;oBACxC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE;oBAC7C,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE;iBAClD;aACF;YACD;gBACE,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,2BAA2B,CAAC;oBACjC,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,YAAY;iBACb,CAAC;aACH;YACD;gBACE,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,GAAG,2BAA2B,qBAAqB;gBAC5D,OAAO,EAAE,sEAAsE;gBAC/E,MAAM,EAAE;oBACN,IAAI,EAAE,kDAAkD;oBACxD,QAAQ,EAAE,QAAQ;iBACnB;aACF;YACD;gBACE,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,qBAAqB;gBAC3B,OAAO,EAAE,GAAG,2BAA2B,uBAAuB;gBAC9D,OAAO,EAAE,+EAA+E;gBACxF,MAAM,EAAE;oBACN,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,QAAQ;iBACnB;aACF;YACD;gBACE,IAAI,EAAE,kBAAkB;gBACxB,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,GAAG,2BAA2B,cAAc;gBACrD,OAAO,EAAE,0BAA0B;gBACnC,MAAM,EAAE;oBACN,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,OAAO;iBAClB;aACF;YACD;gBACE,IAAI,EAAE,UAAU;gBAChB,IAAI,EAAE,kBAAkB;gBACxB,QAAQ,EAAE,uBAAuB;gBACjC,KAAK,EAAE;oBACL,aAAa,EAAE,MAAM,CAAC,aAAa;oBACnC,OAAO,EAAE,MAAM,CAAC,OAAO;iBACxB;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEL,SAAS,sBAAsB,CAAC,MAAe;IAC7C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5D,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type ExpoLocalizationDictionary = Record<string, string>;
|
|
2
|
+
export type ExpoLocalizationDictionaries = Record<string, ExpoLocalizationDictionary>;
|
|
3
|
+
export declare const EXPO_LOCALIZATION_RESOURCE_DIRECTORY = "src/modules/localization/locales";
|
|
4
|
+
export declare class ExpoLocalizationResourceError extends Error {
|
|
5
|
+
constructor(message: string, options?: ErrorOptions);
|
|
6
|
+
}
|
|
7
|
+
export declare function resolveExpoLocalizationDictionaryPath(args: {
|
|
8
|
+
readonly projectRoot: string;
|
|
9
|
+
readonly locale: string;
|
|
10
|
+
}): string;
|
|
11
|
+
export declare function readExpoLocalizationDictionary(args: {
|
|
12
|
+
readonly projectRoot: string;
|
|
13
|
+
readonly locale: string;
|
|
14
|
+
}): Promise<ExpoLocalizationDictionary>;
|
|
15
|
+
export declare function readExpoLocalizationDictionaries(args: {
|
|
16
|
+
readonly projectRoot: string;
|
|
17
|
+
readonly locales: readonly string[];
|
|
18
|
+
}): Promise<ExpoLocalizationDictionaries>;
|
|
19
|
+
export declare function writeExpoLocalizationDictionary(args: {
|
|
20
|
+
readonly projectRoot: string;
|
|
21
|
+
readonly locale: string;
|
|
22
|
+
readonly dictionary: Readonly<Record<string, string>>;
|
|
23
|
+
}): Promise<ExpoLocalizationDictionary>;
|
|
24
|
+
export declare function setExpoLocalizationTranslation(args: {
|
|
25
|
+
readonly projectRoot: string;
|
|
26
|
+
readonly locale: string;
|
|
27
|
+
readonly key: string;
|
|
28
|
+
readonly value: string;
|
|
29
|
+
}): Promise<ExpoLocalizationDictionary>;
|
|
30
|
+
export declare function deleteExpoLocalizationTranslation(args: {
|
|
31
|
+
readonly projectRoot: string;
|
|
32
|
+
readonly locale: string;
|
|
33
|
+
readonly key: string;
|
|
34
|
+
}): Promise<ExpoLocalizationDictionary>;
|
|
35
|
+
export declare function readExpoLocalizationResourceSeeds(args: {
|
|
36
|
+
readonly projectRoot: string;
|
|
37
|
+
readonly locales: readonly string[];
|
|
38
|
+
readonly legacyTranslations?: unknown;
|
|
39
|
+
}): Promise<ExpoLocalizationDictionaries>;
|
|
40
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChE,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;AAEtF,eAAO,MAAM,oCAAoC,qCAAqC,CAAC;AAEvF,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,wBAAgB,qCAAqC,CAAC,IAAI,EAAE;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CAGT;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAEtC;AAED,wBAAsB,gCAAgC,CAAC,IAAI,EAAE;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAUxC;AAED,wBAAsB,+BAA+B,CAAC,IAAI,EAAE;IAC1D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAoBtC;AAED,wBAAsB,8BAA8B,CAAC,IAAI,EAAE;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAOtC;AAED,wBAAsB,iCAAiC,CAAC,IAAI,EAAE;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAKtC;AAED,wBAAsB,iCAAiC,CAAC,IAAI,EAAE;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACvC,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAiBxC"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { normalizeExpoLocalizationLocale } from './config';
|
|
4
|
+
export const EXPO_LOCALIZATION_RESOURCE_DIRECTORY = 'src/modules/localization/locales';
|
|
5
|
+
export class ExpoLocalizationResourceError extends Error {
|
|
6
|
+
constructor(message, options) {
|
|
7
|
+
super(message, options);
|
|
8
|
+
this.name = 'ExpoLocalizationResourceError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function resolveExpoLocalizationDictionaryPath(args) {
|
|
12
|
+
const locale = normalizeExpoLocalizationLocale(args.locale);
|
|
13
|
+
return path.resolve(args.projectRoot, EXPO_LOCALIZATION_RESOURCE_DIRECTORY, `${locale}.json`);
|
|
14
|
+
}
|
|
15
|
+
export async function readExpoLocalizationDictionary(args) {
|
|
16
|
+
return (await readDictionaryIfPresent(args)) ?? {};
|
|
17
|
+
}
|
|
18
|
+
export async function readExpoLocalizationDictionaries(args) {
|
|
19
|
+
const dictionaries = {};
|
|
20
|
+
for (const localeInput of args.locales) {
|
|
21
|
+
const locale = normalizeExpoLocalizationLocale(localeInput);
|
|
22
|
+
dictionaries[locale] = await readExpoLocalizationDictionary({
|
|
23
|
+
projectRoot: args.projectRoot,
|
|
24
|
+
locale,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return dictionaries;
|
|
28
|
+
}
|
|
29
|
+
export async function writeExpoLocalizationDictionary(args) {
|
|
30
|
+
const locale = normalizeExpoLocalizationLocale(args.locale);
|
|
31
|
+
const dictionary = normalizeDictionary(args.dictionary);
|
|
32
|
+
const dictionaryPath = resolveExpoLocalizationDictionaryPath({ ...args, locale });
|
|
33
|
+
const temporaryPath = `${dictionaryPath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
34
|
+
await mkdir(path.dirname(dictionaryPath), { recursive: true });
|
|
35
|
+
try {
|
|
36
|
+
await writeFile(temporaryPath, `${JSON.stringify(dictionary, null, 2)}\n`, 'utf8');
|
|
37
|
+
await rename(temporaryPath, dictionaryPath);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
await rm(temporaryPath, { force: true }).catch(() => undefined);
|
|
41
|
+
throw new ExpoLocalizationResourceError(`Could not persist the ${JSON.stringify(locale)} localization dictionary.`, { cause: error });
|
|
42
|
+
}
|
|
43
|
+
await removeLegacyDictionaryAliases({ projectRoot: args.projectRoot, locale, dictionaryPath });
|
|
44
|
+
return dictionary;
|
|
45
|
+
}
|
|
46
|
+
export async function setExpoLocalizationTranslation(args) {
|
|
47
|
+
const key = normalizeTranslationKey(args.key);
|
|
48
|
+
const dictionary = await readExpoLocalizationDictionary(args);
|
|
49
|
+
return await writeExpoLocalizationDictionary({
|
|
50
|
+
...args,
|
|
51
|
+
dictionary: { ...dictionary, [key]: args.value },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export async function deleteExpoLocalizationTranslation(args) {
|
|
55
|
+
const key = normalizeTranslationKey(args.key);
|
|
56
|
+
const dictionary = await readExpoLocalizationDictionary(args);
|
|
57
|
+
delete dictionary[key];
|
|
58
|
+
return await writeExpoLocalizationDictionary({ ...args, dictionary });
|
|
59
|
+
}
|
|
60
|
+
export async function readExpoLocalizationResourceSeeds(args) {
|
|
61
|
+
const legacyTranslations = parseDictionaries(args.legacyTranslations);
|
|
62
|
+
const dictionaries = {};
|
|
63
|
+
for (const localeInput of args.locales) {
|
|
64
|
+
const locale = normalizeExpoLocalizationLocale(localeInput);
|
|
65
|
+
const existing = await readDictionaryIfPresent({ projectRoot: args.projectRoot, locale });
|
|
66
|
+
if (existing) {
|
|
67
|
+
dictionaries[locale] = existing;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (legacyTranslations[locale]) {
|
|
71
|
+
dictionaries[locale] = legacyTranslations[locale];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return dictionaries;
|
|
75
|
+
}
|
|
76
|
+
function normalizeTranslationKey(input) {
|
|
77
|
+
const key = input.trim();
|
|
78
|
+
if (!key) {
|
|
79
|
+
throw new ExpoLocalizationResourceError('Translation keys cannot be empty.');
|
|
80
|
+
}
|
|
81
|
+
return key;
|
|
82
|
+
}
|
|
83
|
+
function normalizeDictionary(input) {
|
|
84
|
+
if (!isStringRecord(input)) {
|
|
85
|
+
throw new ExpoLocalizationResourceError('Localization dictionaries must contain string values.');
|
|
86
|
+
}
|
|
87
|
+
return Object.fromEntries(Object.entries(input)
|
|
88
|
+
.map(([key, value]) => [normalizeTranslationKey(key), value])
|
|
89
|
+
.sort(([left], [right]) => compareText(left, right)));
|
|
90
|
+
}
|
|
91
|
+
async function readDictionaryIfPresent(args) {
|
|
92
|
+
const locale = normalizeExpoLocalizationLocale(args.locale);
|
|
93
|
+
let dictionaryPath;
|
|
94
|
+
try {
|
|
95
|
+
dictionaryPath = await resolveExistingDictionaryPath({ ...args, locale });
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
throw new ExpoLocalizationResourceError(`Could not read the ${JSON.stringify(locale)} localization dictionary.`, { cause: error });
|
|
99
|
+
}
|
|
100
|
+
if (!dictionaryPath)
|
|
101
|
+
return null;
|
|
102
|
+
let content;
|
|
103
|
+
try {
|
|
104
|
+
content = await readFile(dictionaryPath, 'utf8');
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (isNotFoundError(error))
|
|
108
|
+
return null;
|
|
109
|
+
throw new ExpoLocalizationResourceError(`Could not read the ${JSON.stringify(locale)} localization dictionary.`, { cause: error });
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const parsed = JSON.parse(content);
|
|
113
|
+
if (!isStringRecord(parsed))
|
|
114
|
+
throw new Error('Dictionary values must be strings.');
|
|
115
|
+
return normalizeDictionary(parsed);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw new ExpoLocalizationResourceError(`Invalid localization dictionary for locale ${JSON.stringify(locale)}.`, { cause: error });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function resolveExistingDictionaryPath(args) {
|
|
122
|
+
const canonicalPath = resolveExpoLocalizationDictionaryPath(args);
|
|
123
|
+
try {
|
|
124
|
+
await readFile(canonicalPath, 'utf8');
|
|
125
|
+
return canonicalPath;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (!isNotFoundError(error))
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
const resourceDirectory = path.resolve(args.projectRoot, EXPO_LOCALIZATION_RESOURCE_DIRECTORY);
|
|
132
|
+
const entries = await readResourceDirectory(resourceDirectory);
|
|
133
|
+
if (!entries)
|
|
134
|
+
return null;
|
|
135
|
+
const locale = normalizeExpoLocalizationLocale(args.locale);
|
|
136
|
+
const legacyFiles = findLocaleAliases(entries, locale, path.basename(canonicalPath));
|
|
137
|
+
if (legacyFiles.length > 1) {
|
|
138
|
+
throw new Error(`Multiple localization dictionaries normalize to ${JSON.stringify(locale)}: ${legacyFiles.join(', ')}.`);
|
|
139
|
+
}
|
|
140
|
+
return legacyFiles[0] ? path.resolve(resourceDirectory, legacyFiles[0]) : null;
|
|
141
|
+
}
|
|
142
|
+
async function removeLegacyDictionaryAliases(args) {
|
|
143
|
+
const resourceDirectory = path.resolve(args.projectRoot, EXPO_LOCALIZATION_RESOURCE_DIRECTORY);
|
|
144
|
+
const entries = await readResourceDirectory(resourceDirectory);
|
|
145
|
+
if (!entries)
|
|
146
|
+
return;
|
|
147
|
+
const aliases = findLocaleAliases(entries, args.locale, path.basename(args.dictionaryPath));
|
|
148
|
+
try {
|
|
149
|
+
for (const alias of aliases) {
|
|
150
|
+
await rm(path.resolve(resourceDirectory, alias), { force: true });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
throw new ExpoLocalizationResourceError(`Could not remove legacy aliases for ${JSON.stringify(args.locale)}.`, { cause: error });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function readResourceDirectory(resourceDirectory) {
|
|
158
|
+
try {
|
|
159
|
+
return await readdir(resourceDirectory);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
if (isNotFoundError(error))
|
|
163
|
+
return null;
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function findLocaleAliases(entries, locale, canonicalFileName) {
|
|
168
|
+
return entries
|
|
169
|
+
.filter((entry) => entry !== canonicalFileName && entry.endsWith('.json'))
|
|
170
|
+
.filter((entry) => tryNormalizeLocale(entry.slice(0, -'.json'.length)) === locale)
|
|
171
|
+
.sort(compareText);
|
|
172
|
+
}
|
|
173
|
+
function parseDictionaries(input) {
|
|
174
|
+
if (!isRecord(input))
|
|
175
|
+
return {};
|
|
176
|
+
const dictionaries = {};
|
|
177
|
+
for (const [localeInput, dictionary] of Object.entries(input)) {
|
|
178
|
+
if (!isStringRecord(dictionary))
|
|
179
|
+
continue;
|
|
180
|
+
try {
|
|
181
|
+
dictionaries[normalizeExpoLocalizationLocale(localeInput)] = normalizeDictionary(dictionary);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return dictionaries;
|
|
188
|
+
}
|
|
189
|
+
function isStringRecord(value) {
|
|
190
|
+
return isRecord(value) && Object.values(value).every((entry) => typeof entry === 'string');
|
|
191
|
+
}
|
|
192
|
+
function isRecord(value) {
|
|
193
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
194
|
+
}
|
|
195
|
+
function isNotFoundError(error) {
|
|
196
|
+
return isRecord(error) && error.code === 'ENOENT';
|
|
197
|
+
}
|
|
198
|
+
function tryNormalizeLocale(locale) {
|
|
199
|
+
try {
|
|
200
|
+
return normalizeExpoLocalizationLocale(locale);
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function compareText(left, right) {
|
|
207
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
|
package/dist/templateFiles.js
CHANGED
|
@@ -11,24 +11,24 @@ export function buildLocalizationWriteFiles(args) {
|
|
|
11
11
|
const { defaultLocale, locales, translations } = args;
|
|
12
12
|
return [
|
|
13
13
|
{
|
|
14
|
-
path: 'src/
|
|
14
|
+
path: 'src/modules/localization/i18n.ts',
|
|
15
15
|
content: renderTemplate('i18n.ts.tpl', {
|
|
16
16
|
DEFAULT_LOCALE: JSON.stringify(defaultLocale),
|
|
17
17
|
}),
|
|
18
18
|
overwrite: true,
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
|
-
path: 'src/
|
|
21
|
+
path: 'src/modules/localization/useT.ts',
|
|
22
22
|
content: readTemplate('useT.ts.tpl'),
|
|
23
23
|
overwrite: true,
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
path: 'src/
|
|
26
|
+
path: 'src/modules/localization/runtimeLocalization.ts',
|
|
27
27
|
content: readTemplate('runtimeLocalization.ts.tpl'),
|
|
28
28
|
overwrite: true,
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
|
-
path: 'src/
|
|
31
|
+
path: 'src/modules/localization/LocalizationProvider.tsx',
|
|
32
32
|
content: renderTemplate('LocalizationProvider.tsx.tpl', {
|
|
33
33
|
DEFAULT_LOCALE: JSON.stringify(defaultLocale),
|
|
34
34
|
RESOURCE_LINES: locales
|
|
@@ -38,7 +38,7 @@ export function buildLocalizationWriteFiles(args) {
|
|
|
38
38
|
overwrite: true,
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
|
-
path: 'src/
|
|
41
|
+
path: 'src/modules/localization/index.ts',
|
|
42
42
|
content: readTemplate('index.ts.tpl'),
|
|
43
43
|
overwrite: true,
|
|
44
44
|
},
|
|
@@ -50,7 +50,7 @@ function buildLocaleJsonFiles(locales, configTranslations) {
|
|
|
50
50
|
const contentSource = configTranslations[locale] ??
|
|
51
51
|
(locale.startsWith('de') ? defaultTranslations.de : defaultTranslations.en);
|
|
52
52
|
return {
|
|
53
|
-
path: `src/
|
|
53
|
+
path: `src/modules/localization/locales/${locale}.json`,
|
|
54
54
|
content: `${JSON.stringify(contentSource, null, 2)}\n`,
|
|
55
55
|
};
|
|
56
56
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "MIT",
|
|
3
3
|
"name": "@ankhorage/orchestrator-module-expo-localization",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"description": "Expo localization module for @ankhorage/orchestrator.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
".": {
|
|
35
35
|
"types": "./dist/index.d.ts",
|
|
36
36
|
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./host": {
|
|
39
|
+
"types": "./dist/host.d.ts",
|
|
40
|
+
"default": "./dist/host.js"
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
"version-packages": "changeset version"
|
|
49
53
|
},
|
|
50
54
|
"dependencies": {
|
|
51
|
-
"@ankhorage/orchestrator": "^0.
|
|
55
|
+
"@ankhorage/orchestrator": "^0.3.1"
|
|
52
56
|
},
|
|
53
57
|
"devDependencies": {
|
|
54
58
|
"@ankhorage/devtools": "^1.0.6",
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
createLocalizationNodePropsResolver,
|
|
11
11
|
} from "./runtimeLocalization";
|
|
12
12
|
|
|
13
|
-
export interface
|
|
13
|
+
export interface LocalizationModuleConfig {
|
|
14
14
|
defaultLocale?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export function
|
|
17
|
+
export function LocalizationModuleProvider(props: {
|
|
18
18
|
children: React.ReactNode;
|
|
19
|
-
config?:
|
|
19
|
+
config?: LocalizationModuleConfig;
|
|
20
20
|
}) {
|
|
21
21
|
const { children, config } = props;
|
|
22
22
|
|
package/templates/index.ts.tpl
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/* generated by @ankhorage/orchestrator-module-expo-localization */
|
|
2
|
-
export {
|
|
2
|
+
export { LocalizationModuleProvider } from "./LocalizationProvider";
|
|
3
3
|
export { useT } from "./useT";
|
|
4
4
|
export { i18n } from "./i18n";
|