@ankhorage/orchestrator-module-expo-localization 0.2.0 → 0.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +32 -2
  3. package/dist/admin/configOperations.d.ts +8 -0
  4. package/dist/admin/configOperations.d.ts.map +1 -0
  5. package/dist/admin/configOperations.js +19 -0
  6. package/dist/admin/configOperations.js.map +1 -0
  7. package/dist/admin/dictionaryOperations.d.ts +14 -0
  8. package/dist/admin/dictionaryOperations.d.ts.map +1 -0
  9. package/dist/admin/dictionaryOperations.js +10 -0
  10. package/dist/admin/dictionaryOperations.js.map +1 -0
  11. package/dist/admin/linkTranslationKey.d.ts +6 -0
  12. package/dist/admin/linkTranslationKey.d.ts.map +1 -0
  13. package/dist/admin/linkTranslationKey.js +60 -0
  14. package/dist/admin/linkTranslationKey.js.map +1 -0
  15. package/dist/admin/load.d.ts +3 -0
  16. package/dist/admin/load.d.ts.map +1 -0
  17. package/dist/admin/load.js +28 -0
  18. package/dist/admin/load.js.map +1 -0
  19. package/dist/admin/runtime.d.ts +17 -0
  20. package/dist/admin/runtime.d.ts.map +1 -0
  21. package/dist/admin/runtime.js +109 -0
  22. package/dist/admin/runtime.js.map +1 -0
  23. package/dist/admin/types.d.ts +43 -0
  24. package/dist/admin/types.d.ts.map +1 -0
  25. package/dist/admin/types.js +2 -0
  26. package/dist/admin/types.js.map +1 -0
  27. package/dist/authoring.d.ts +56 -0
  28. package/dist/authoring.d.ts.map +1 -0
  29. package/dist/authoring.js +76 -0
  30. package/dist/authoring.js.map +1 -0
  31. package/dist/config.d.ts +13 -3
  32. package/dist/config.d.ts.map +1 -1
  33. package/dist/config.js +73 -21
  34. package/dist/config.js.map +1 -1
  35. package/dist/host.d.ts +7 -10
  36. package/dist/host.d.ts.map +1 -1
  37. package/dist/host.js +7 -23
  38. package/dist/host.js.map +1 -1
  39. package/dist/index.d.ts +3 -1
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3 -1
  42. package/dist/index.js.map +1 -1
  43. package/dist/module.d.ts.map +1 -1
  44. package/dist/module.js +14 -2
  45. package/dist/module.js.map +1 -1
  46. package/dist/resources.d.ts +40 -0
  47. package/dist/resources.d.ts.map +1 -0
  48. package/dist/resources.js +209 -0
  49. package/dist/resources.js.map +1 -0
  50. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ankhorage/orchestrator-module-expo-localization
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 27d81c9: Add the package-owned Localization administration runtime for lifecycle configuration, canonical dictionary editing, metadata-driven authoring state, and translation-key linking through injected generic host context.
8
+
9
+ ## 0.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 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.
14
+
3
15
  ## 0.2.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -26,13 +26,43 @@ The Orchestrator ledger is the canonical lifecycle and configuration source. Upd
26
26
  installation uses `reconfigureModule()`, which also removes outputs recorded by an earlier module
27
27
  version before generating the canonical `src/modules/localization` namespace.
28
28
 
29
- Generic authoring hosts can opt into the package-owned metadata, layout integration, config
30
- normalizer, and serializable admin schema without making the core module depend on Studio:
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
+ Missing locale resource files load as empty dictionaries. Invalid files fail explicitly. Writes are
36
+ atomic and keys are sorted so runtime and source-control output remain deterministic. Existing
37
+ `translations` ledger data is accepted only as a one-time seed when a canonical locale file does not
38
+ yet exist; normalized config never writes dictionaries back to the ledger.
39
+
40
+ Package-neutral helpers for locale rules and translatable-field discovery are exported from the root
41
+ package. Discovery accepts manifest-shaped nodes and component metadata from the caller, so the
42
+ module has no Studio component-registry dependency.
43
+
44
+ ## Authoring host contribution
45
+
46
+ Generic authoring hosts can import the package-owned contribution without adding Studio, ZORA, or
47
+ React to the module root:
31
48
 
32
49
  ```ts
33
50
  import { expoLocalizationHostContribution } from '@ankhorage/orchestrator-module-expo-localization/host';
34
51
  ```
35
52
 
53
+ Its serializable `admin` schema continues to describe lifecycle configuration. The sibling
54
+ `adminRuntime` is server-side and conforms to the generic single-entry host contract:
55
+ `execute(context, { operation, input })`. The host treats the operation string, payload, validation,
56
+ and result as opaque module-owned data.
57
+
58
+ The package exports `EXPO_LOCALIZATION_ADMIN_OPERATIONS` as the canonical operation IDs. Locale and
59
+ default-locale operations use the injected lifecycle reconfiguration boundary. Dictionary operations
60
+ write canonical locale JSON directly, so ordinary translation edits never reinstall or reconfigure
61
+ the module. The load operation derives translatable fields, missing translations, search, and filters
62
+ from module-owned domain APIs. The link operation validates eligibility from injected component
63
+ metadata and uses the generic manifest mutation callback; new keys are seeded in the configured
64
+ default-locale dictionary without overwriting an existing translation.
65
+
36
66
  ## Why this exists
37
67
 
38
68
  Standardizes localization setup across apps.
@@ -0,0 +1,8 @@
1
+ import { type NormalizedExpoLocalizationModuleConfig } from '../config';
2
+ import type { ExpoLocalizationAdminHostContext } from './types';
3
+ export declare const expoLocalizationConfigAdminOperations: {
4
+ readonly addLocale: (context: ExpoLocalizationAdminHostContext, locale: string) => Promise<NormalizedExpoLocalizationModuleConfig>;
5
+ readonly removeLocale: (context: ExpoLocalizationAdminHostContext, locale: string) => Promise<NormalizedExpoLocalizationModuleConfig>;
6
+ readonly setDefaultLocale: (context: ExpoLocalizationAdminHostContext, locale: string) => Promise<NormalizedExpoLocalizationModuleConfig>;
7
+ };
8
+ //# sourceMappingURL=configOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configOperations.d.ts","sourceRoot":"","sources":["../../src/admin/configOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,sCAAsC,EAI5C,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;AAEhE,eAAO,MAAM,qCAAqC;kCAErC,gCAAgC,UACjC,MAAM,KACb,OAAO,CAAC,sCAAsC,CAAC;qCAIvC,gCAAgC,UACjC,MAAM,KACb,OAAO,CAAC,sCAAsC,CAAC;yCAIvC,gCAAgC,UACjC,MAAM,KACb,OAAO,CAAC,sCAAsC,CAAC;CAG1C,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { addExpoLocalizationLocale, parseExpoLocalizationModuleConfig, removeExpoLocalizationLocale, setExpoLocalizationDefaultLocale, } from '../config';
2
+ export const expoLocalizationConfigAdminOperations = {
3
+ async addLocale(context, locale) {
4
+ return await reconfigure(context, addExpoLocalizationLocale, locale);
5
+ },
6
+ async removeLocale(context, locale) {
7
+ return await reconfigure(context, removeExpoLocalizationLocale, locale);
8
+ },
9
+ async setDefaultLocale(context, locale) {
10
+ return await reconfigure(context, setExpoLocalizationDefaultLocale, locale);
11
+ },
12
+ };
13
+ async function reconfigure(context, mutate, locale) {
14
+ const current = parseExpoLocalizationModuleConfig(await context.readConfig());
15
+ const next = mutate(current, locale);
16
+ await context.reconfigureConfig(next);
17
+ return next;
18
+ }
19
+ //# sourceMappingURL=configOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configOperations.js","sourceRoot":"","sources":["../../src/admin/configOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EAEzB,iCAAiC,EACjC,4BAA4B,EAC5B,gCAAgC,GACjC,MAAM,WAAW,CAAC;AAGnB,MAAM,CAAC,MAAM,qCAAqC,GAAG;IACnD,KAAK,CAAC,SAAS,CACb,OAAyC,EACzC,MAAc;QAEd,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,yBAAyB,EAAE,MAAM,CAAC,CAAC;IACvE,CAAC;IACD,KAAK,CAAC,YAAY,CAChB,OAAyC,EACzC,MAAc;QAEd,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,4BAA4B,EAAE,MAAM,CAAC,CAAC;IAC1E,CAAC;IACD,KAAK,CAAC,gBAAgB,CACpB,OAAyC,EACzC,MAAc;QAEd,OAAO,MAAM,WAAW,CAAC,OAAO,EAAE,gCAAgC,EAAE,MAAM,CAAC,CAAC;IAC9E,CAAC;CACO,CAAC;AAEX,KAAK,UAAU,WAAW,CACxB,OAAyC,EACzC,MAG2C,EAC3C,MAAc;IAEd,MAAM,OAAO,GAAG,iCAAiC,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,MAAM,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type ExpoLocalizationDictionary } from '../resources';
2
+ import type { ExpoLocalizationAdminHostContext } from './types';
3
+ export declare const expoLocalizationDictionaryAdminOperations: {
4
+ readonly setTranslation: (context: ExpoLocalizationAdminHostContext, input: {
5
+ readonly locale: string;
6
+ readonly key: string;
7
+ readonly value: string;
8
+ }) => Promise<ExpoLocalizationDictionary>;
9
+ readonly deleteTranslation: (context: ExpoLocalizationAdminHostContext, input: {
10
+ readonly locale: string;
11
+ readonly key: string;
12
+ }) => Promise<ExpoLocalizationDictionary>;
13
+ };
14
+ //# sourceMappingURL=dictionaryOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionaryOperations.d.ts","sourceRoot":"","sources":["../../src/admin/dictionaryOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAEhC,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,SAAS,CAAC;AAEhE,eAAO,MAAM,yCAAyC;uCAEzC,gCAAgC,SAClC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAC/E,OAAO,CAAC,0BAA0B,CAAC;0CAI3B,gCAAgC,SAClC;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KACvD,OAAO,CAAC,0BAA0B,CAAC;CAG9B,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { deleteExpoLocalizationTranslation, setExpoLocalizationTranslation, } from '../resources';
2
+ export const expoLocalizationDictionaryAdminOperations = {
3
+ async setTranslation(context, input) {
4
+ return await setExpoLocalizationTranslation({ projectRoot: context.projectRoot, ...input });
5
+ },
6
+ async deleteTranslation(context, input) {
7
+ return await deleteExpoLocalizationTranslation({ projectRoot: context.projectRoot, ...input });
8
+ },
9
+ };
10
+ //# sourceMappingURL=dictionaryOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dictionaryOperations.js","sourceRoot":"","sources":["../../src/admin/dictionaryOperations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EAEjC,8BAA8B,GAC/B,MAAM,cAAc,CAAC;AAGtB,MAAM,CAAC,MAAM,yCAAyC,GAAG;IACvD,KAAK,CAAC,cAAc,CAClB,OAAyC,EACzC,KAAgF;QAEhF,OAAO,MAAM,8BAA8B,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,KAAK,CAAC,iBAAiB,CACrB,OAAyC,EACzC,KAAwD;QAExD,OAAO,MAAM,iCAAiC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;IACjG,CAAC;CACO,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ExpoLocalizationAdminHostContext, ExpoLocalizationLinkTranslationInput } from './types';
2
+ export declare function linkExpoLocalizationTranslationKey(context: ExpoLocalizationAdminHostContext, input: ExpoLocalizationLinkTranslationInput): Promise<{
3
+ readonly key: string;
4
+ readonly defaultLocale: string;
5
+ }>;
6
+ //# sourceMappingURL=linkTranslationKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkTranslationKey.d.ts","sourceRoot":"","sources":["../../src/admin/linkTranslationKey.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gCAAgC,EAChC,oCAAoC,EAErC,MAAM,SAAS,CAAC;AAEjB,wBAAsB,kCAAkC,CACtD,OAAO,EAAE,gCAAgC,EACzC,KAAK,EAAE,oCAAoC,GAC1C,OAAO,CAAC;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAiDnE"}
@@ -0,0 +1,60 @@
1
+ import { collectExpoLocalizationTranslatableFields } from '../authoring';
2
+ import { parseExpoLocalizationModuleConfig } from '../config';
3
+ import { readExpoLocalizationDictionary, setExpoLocalizationTranslation } from '../resources';
4
+ export async function linkExpoLocalizationTranslationKey(context, input) {
5
+ const [rawConfig, authoring] = await Promise.all([
6
+ context.readConfig(),
7
+ context.readAuthoringContext(),
8
+ ]);
9
+ const config = parseExpoLocalizationModuleConfig(rawConfig);
10
+ const fields = collectExpoLocalizationTranslatableFields(authoring);
11
+ const field = fields.find((candidate) => candidate.screenId === input.screenId &&
12
+ candidate.nodeId === input.nodeId &&
13
+ candidate.keyProp === input.keyProp);
14
+ if (!field) {
15
+ throw new Error('The requested manifest field is not translatable according to component metadata.');
16
+ }
17
+ const key = input.key.trim();
18
+ if (!key)
19
+ throw new Error('Translation keys cannot be empty.');
20
+ const dictionary = await readExpoLocalizationDictionary({
21
+ projectRoot: context.projectRoot,
22
+ locale: config.defaultLocale,
23
+ });
24
+ const needsSeed = !Object.prototype.hasOwnProperty.call(dictionary, key);
25
+ const seedValue = input.value ?? field.defaultText;
26
+ if (needsSeed && !seedValue.trim()) {
27
+ throw new Error('A new translation key requires a non-empty default-locale value.');
28
+ }
29
+ const mutation = {
30
+ screenId: field.screenId,
31
+ nodeId: field.nodeId,
32
+ prop: field.keyProp,
33
+ value: key,
34
+ };
35
+ await context.mutateManifestField(mutation);
36
+ if (needsSeed) {
37
+ await persistSeedOrRestoreManifest(context, mutation, field.currentKey, config.defaultLocale, seedValue);
38
+ }
39
+ return { key, defaultLocale: config.defaultLocale };
40
+ }
41
+ async function persistSeedOrRestoreManifest(context, mutation, previousKey, locale, value) {
42
+ try {
43
+ await setExpoLocalizationTranslation({
44
+ projectRoot: context.projectRoot,
45
+ locale,
46
+ key: mutation.value,
47
+ value,
48
+ });
49
+ }
50
+ catch (error) {
51
+ try {
52
+ await context.mutateManifestField({ ...mutation, value: previousKey });
53
+ }
54
+ catch (rollbackError) {
55
+ throw new AggregateError([error, rollbackError], 'Translation linking failed and the manifest field could not be restored.', { cause: rollbackError });
56
+ }
57
+ throw error;
58
+ }
59
+ }
60
+ //# sourceMappingURL=linkTranslationKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkTranslationKey.js","sourceRoot":"","sources":["../../src/admin/linkTranslationKey.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExpoLocalizationAdminHostContext, ExpoLocalizationAdminLoadOptions, ExpoLocalizationAdminSnapshot } from './types';
2
+ export declare function loadExpoLocalizationAdmin(context: ExpoLocalizationAdminHostContext, options?: ExpoLocalizationAdminLoadOptions): Promise<ExpoLocalizationAdminSnapshot>;
3
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/admin/load.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gCAAgC,EAChC,gCAAgC,EAChC,6BAA6B,EAC9B,MAAM,SAAS,CAAC;AAEjB,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,EACzC,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,6BAA6B,CAAC,CAwBxC"}
@@ -0,0 +1,28 @@
1
+ import { collectExpoLocalizationTranslatableFields, filterExpoLocalizationTranslatableFields, findExpoLocalizationMissingTranslations, } from '../authoring';
2
+ import { parseExpoLocalizationModuleConfig } from '../config';
3
+ import { readExpoLocalizationDictionaries } from '../resources';
4
+ export async function loadExpoLocalizationAdmin(context, options = {}) {
5
+ const config = parseExpoLocalizationModuleConfig(await context.readConfig());
6
+ const [dictionaries, authoring] = await Promise.all([
7
+ readExpoLocalizationDictionaries({ projectRoot: context.projectRoot, locales: config.locales }),
8
+ context.readAuthoringContext(),
9
+ ]);
10
+ const fields = collectExpoLocalizationTranslatableFields(authoring);
11
+ return {
12
+ config,
13
+ dictionaries,
14
+ fields,
15
+ missingTranslations: findExpoLocalizationMissingTranslations({
16
+ fields,
17
+ locales: config.locales,
18
+ dictionaries,
19
+ }),
20
+ visibleFields: filterExpoLocalizationTranslatableFields({
21
+ fields,
22
+ locales: config.locales,
23
+ dictionaries,
24
+ ...options,
25
+ }),
26
+ };
27
+ }
28
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/admin/load.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yCAAyC,EACzC,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iCAAiC,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAOhE,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAyC,EACzC,UAA4C,EAAE;IAE9C,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,gCAAgC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;QAC/F,OAAO,CAAC,oBAAoB,EAAE;KAC/B,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,yCAAyC,CAAC,SAAS,CAAC,CAAC;IAEpE,OAAO;QACL,MAAM;QACN,YAAY;QACZ,MAAM;QACN,mBAAmB,EAAE,uCAAuC,CAAC;YAC3D,MAAM;YACN,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY;SACb,CAAC;QACF,aAAa,EAAE,wCAAwC,CAAC;YACtD,MAAM;YACN,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY;YACZ,GAAG,OAAO;SACX,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ExpoLocalizationAdminHostContext, ExpoLocalizationAdminInvocation } from './types';
2
+ export declare const EXPO_LOCALIZATION_ADMIN_OPERATIONS: {
3
+ readonly load: "load";
4
+ readonly addLocale: "config.add-locale";
5
+ readonly removeLocale: "config.remove-locale";
6
+ readonly setDefaultLocale: "config.set-default-locale";
7
+ readonly setTranslation: "dictionary.set-translation";
8
+ readonly deleteTranslation: "dictionary.delete-translation";
9
+ readonly linkTranslationKey: "link-translation-key";
10
+ };
11
+ export declare const expoLocalizationAdminRuntime: {
12
+ readonly kind: "module-admin-runtime";
13
+ readonly execute: typeof executeExpoLocalizationAdminOperation;
14
+ };
15
+ declare function executeExpoLocalizationAdminOperation(context: ExpoLocalizationAdminHostContext, invocation: ExpoLocalizationAdminInvocation): Promise<unknown>;
16
+ export type { ExpoLocalizationAdminAuthoringContext, ExpoLocalizationAdminHostContext, ExpoLocalizationAdminInvocation, ExpoLocalizationAdminLoadOptions, ExpoLocalizationAdminSnapshot, ExpoLocalizationLinkTranslationInput, ExpoLocalizationManifestFieldMutation, } from './types';
17
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/admin/runtime.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gCAAgC,EAChC,+BAA+B,EAGhC,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,kCAAkC;;;;;;;;CAQrC,CAAC;AAEX,eAAO,MAAM,4BAA4B;;;CAG/B,CAAC;AAEX,iBAAe,qCAAqC,CAClD,OAAO,EAAE,gCAAgC,EACzC,UAAU,EAAE,+BAA+B,GAC1C,OAAO,CAAC,OAAO,CAAC,CAkClB;AAyFD,YAAY,EACV,qCAAqC,EACrC,gCAAgC,EAChC,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,EAC7B,oCAAoC,EACpC,qCAAqC,GACtC,MAAM,SAAS,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { expoLocalizationConfigAdminOperations } from './configOperations';
2
+ import { expoLocalizationDictionaryAdminOperations } from './dictionaryOperations';
3
+ import { linkExpoLocalizationTranslationKey } from './linkTranslationKey';
4
+ import { loadExpoLocalizationAdmin } from './load';
5
+ export const EXPO_LOCALIZATION_ADMIN_OPERATIONS = {
6
+ load: 'load',
7
+ addLocale: 'config.add-locale',
8
+ removeLocale: 'config.remove-locale',
9
+ setDefaultLocale: 'config.set-default-locale',
10
+ setTranslation: 'dictionary.set-translation',
11
+ deleteTranslation: 'dictionary.delete-translation',
12
+ linkTranslationKey: 'link-translation-key',
13
+ };
14
+ export const expoLocalizationAdminRuntime = {
15
+ kind: 'module-admin-runtime',
16
+ execute: executeExpoLocalizationAdminOperation,
17
+ };
18
+ async function executeExpoLocalizationAdminOperation(context, invocation) {
19
+ switch (invocation.operation) {
20
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.load:
21
+ return await loadExpoLocalizationAdmin(context, readLoadOptions(invocation.input));
22
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.addLocale:
23
+ return await expoLocalizationConfigAdminOperations.addLocale(context, readRequiredString(invocation.input, 'locale'));
24
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.removeLocale:
25
+ return await expoLocalizationConfigAdminOperations.removeLocale(context, readRequiredString(invocation.input, 'locale'));
26
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.setDefaultLocale:
27
+ return await expoLocalizationConfigAdminOperations.setDefaultLocale(context, readRequiredString(invocation.input, 'locale'));
28
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.setTranslation:
29
+ return await expoLocalizationDictionaryAdminOperations.setTranslation(context, readSetTranslationInput(invocation.input));
30
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.deleteTranslation:
31
+ return await expoLocalizationDictionaryAdminOperations.deleteTranslation(context, readDeleteTranslationInput(invocation.input));
32
+ case EXPO_LOCALIZATION_ADMIN_OPERATIONS.linkTranslationKey:
33
+ return await linkExpoLocalizationTranslationKey(context, readLinkInput(invocation.input));
34
+ default:
35
+ throw new Error(`Unsupported Localization admin operation '${invocation.operation}'.`);
36
+ }
37
+ }
38
+ function readLoadOptions(input) {
39
+ if (input === undefined)
40
+ return {};
41
+ const record = requireRecord(input);
42
+ const searchQuery = readOptionalString(record.searchQuery, 'searchQuery');
43
+ const filter = readFilter(record.filter);
44
+ return {
45
+ ...(searchQuery === undefined ? {} : { searchQuery }),
46
+ ...(filter === undefined ? {} : { filter }),
47
+ };
48
+ }
49
+ function readSetTranslationInput(input) {
50
+ const record = requireRecord(input);
51
+ return {
52
+ locale: readString(record.locale, 'locale'),
53
+ key: readString(record.key, 'key'),
54
+ value: readString(record.value, 'value'),
55
+ };
56
+ }
57
+ function readDeleteTranslationInput(input) {
58
+ const record = requireRecord(input);
59
+ return {
60
+ locale: readString(record.locale, 'locale'),
61
+ key: readString(record.key, 'key'),
62
+ };
63
+ }
64
+ function readLinkInput(input) {
65
+ const record = requireRecord(input);
66
+ const value = readOptionalString(record.value, 'value');
67
+ return {
68
+ screenId: readString(record.screenId, 'screenId'),
69
+ nodeId: readString(record.nodeId, 'nodeId'),
70
+ keyProp: readString(record.keyProp, 'keyProp'),
71
+ key: readString(record.key, 'key'),
72
+ ...(value === undefined ? {} : { value }),
73
+ };
74
+ }
75
+ function readRequiredString(input, key) {
76
+ return readString(requireRecord(input)[key], key);
77
+ }
78
+ function requireRecord(value) {
79
+ if (!isRecord(value)) {
80
+ throw new Error('Localization admin operation input must be an object.');
81
+ }
82
+ return value;
83
+ }
84
+ function isRecord(value) {
85
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
86
+ }
87
+ function readString(value, key) {
88
+ if (typeof value !== 'string') {
89
+ throw new Error(`Localization admin operation field '${key}' must be a string.`);
90
+ }
91
+ return value;
92
+ }
93
+ function readOptionalString(value, key) {
94
+ if (value === undefined)
95
+ return undefined;
96
+ return readString(value, key);
97
+ }
98
+ function readFilter(value) {
99
+ if (value === undefined)
100
+ return undefined;
101
+ if (value === 'all' ||
102
+ value === 'unlinked' ||
103
+ value === 'missing-translations' ||
104
+ value === 'incomplete') {
105
+ return value;
106
+ }
107
+ throw new Error("Localization admin operation field 'filter' is invalid.");
108
+ }
109
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/admin/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { ExpoLocalizationComponentMetaRegistry, ExpoLocalizationManifestScreen, ExpoLocalizationMissingTranslation, ExpoLocalizationTranslatableField } from '../authoring';
2
+ import type { NormalizedExpoLocalizationModuleConfig } from '../config';
3
+ import type { ExpoLocalizationDictionaries } from '../resources';
4
+ export interface ExpoLocalizationAdminInvocation {
5
+ readonly operation: string;
6
+ readonly input?: unknown;
7
+ }
8
+ export interface ExpoLocalizationAdminAuthoringContext {
9
+ readonly screens: readonly ExpoLocalizationManifestScreen[];
10
+ readonly componentMeta: ExpoLocalizationComponentMetaRegistry;
11
+ }
12
+ export interface ExpoLocalizationManifestFieldMutation {
13
+ readonly screenId: string;
14
+ readonly nodeId: string;
15
+ readonly prop: string;
16
+ readonly value: string;
17
+ }
18
+ export interface ExpoLocalizationAdminHostContext {
19
+ readonly projectRoot: string;
20
+ readonly readConfig: () => Promise<unknown>;
21
+ readonly reconfigureConfig: (config: unknown) => Promise<void>;
22
+ readonly readAuthoringContext: () => Promise<ExpoLocalizationAdminAuthoringContext>;
23
+ readonly mutateManifestField: (mutation: ExpoLocalizationManifestFieldMutation) => Promise<void>;
24
+ }
25
+ export interface ExpoLocalizationAdminSnapshot {
26
+ readonly config: NormalizedExpoLocalizationModuleConfig;
27
+ readonly dictionaries: ExpoLocalizationDictionaries;
28
+ readonly fields: readonly ExpoLocalizationTranslatableField[];
29
+ readonly visibleFields: readonly ExpoLocalizationTranslatableField[];
30
+ readonly missingTranslations: readonly ExpoLocalizationMissingTranslation[];
31
+ }
32
+ export interface ExpoLocalizationAdminLoadOptions {
33
+ readonly searchQuery?: string;
34
+ readonly filter?: 'all' | 'unlinked' | 'missing-translations' | 'incomplete';
35
+ }
36
+ export interface ExpoLocalizationLinkTranslationInput {
37
+ readonly screenId: string;
38
+ readonly nodeId: string;
39
+ readonly keyProp: string;
40
+ readonly key: string;
41
+ readonly value?: string;
42
+ }
43
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/admin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qCAAqC,EACrC,8BAA8B,EAC9B,kCAAkC,EAClC,iCAAiC,EAClC,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAEjE,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,OAAO,EAAE,SAAS,8BAA8B,EAAE,CAAC;IAC5D,QAAQ,CAAC,aAAa,EAAE,qCAAqC,CAAC;CAC/D;AAED,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,QAAQ,CAAC,oBAAoB,EAAE,MAAM,OAAO,CAAC,qCAAqC,CAAC,CAAC;IACpF,QAAQ,CAAC,mBAAmB,EAAE,CAAC,QAAQ,EAAE,qCAAqC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClG;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,sCAAsC,CAAC;IACxD,QAAQ,CAAC,YAAY,EAAE,4BAA4B,CAAC;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,iCAAiC,EAAE,CAAC;IAC9D,QAAQ,CAAC,aAAa,EAAE,SAAS,iCAAiC,EAAE,CAAC;IACrE,QAAQ,CAAC,mBAAmB,EAAE,SAAS,kCAAkC,EAAE,CAAC;CAC7E;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,sBAAsB,GAAG,YAAY,CAAC;CAC9E;AAED,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/admin/types.ts"],"names":[],"mappings":""}
@@ -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 declare function parseExpoLocalizationModuleConfig(input: unknown): Required<ExpoLocalizationModuleConfig>;
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