@ankhorage/orchestrator-module-expo-localization 0.4.0 → 0.5.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 (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +17 -0
  3. package/dist/admin-view/DictionaryEditorCard.d.ts +9 -0
  4. package/dist/admin-view/DictionaryEditorCard.d.ts.map +1 -0
  5. package/dist/admin-view/DictionaryEditorCard.js +26 -0
  6. package/dist/admin-view/DictionaryEditorCard.js.map +1 -0
  7. package/dist/admin-view/ExpoLocalizationAdminView.d.ts +3 -0
  8. package/dist/admin-view/ExpoLocalizationAdminView.d.ts.map +1 -0
  9. package/dist/admin-view/ExpoLocalizationAdminView.js +18 -0
  10. package/dist/admin-view/ExpoLocalizationAdminView.js.map +1 -0
  11. package/dist/admin-view/LocaleManagementCard.d.ts +9 -0
  12. package/dist/admin-view/LocaleManagementCard.d.ts.map +1 -0
  13. package/dist/admin-view/LocaleManagementCard.js +14 -0
  14. package/dist/admin-view/LocaleManagementCard.js.map +1 -0
  15. package/dist/admin-view/MissingTranslationsCard.d.ts +5 -0
  16. package/dist/admin-view/MissingTranslationsCard.d.ts.map +1 -0
  17. package/dist/admin-view/MissingTranslationsCard.js +6 -0
  18. package/dist/admin-view/MissingTranslationsCard.js.map +1 -0
  19. package/dist/admin-view/TranslatableFieldRow.d.ts +10 -0
  20. package/dist/admin-view/TranslatableFieldRow.d.ts.map +1 -0
  21. package/dist/admin-view/TranslatableFieldRow.js +18 -0
  22. package/dist/admin-view/TranslatableFieldRow.js.map +1 -0
  23. package/dist/admin-view/TranslatableFieldsCard.d.ts +11 -0
  24. package/dist/admin-view/TranslatableFieldsCard.d.ts.map +1 -0
  25. package/dist/admin-view/TranslatableFieldsCard.js +19 -0
  26. package/dist/admin-view/TranslatableFieldsCard.js.map +1 -0
  27. package/dist/admin-view/index.d.ts +8 -0
  28. package/dist/admin-view/index.d.ts.map +1 -0
  29. package/dist/admin-view/index.js +8 -0
  30. package/dist/admin-view/index.js.map +1 -0
  31. package/dist/admin-view/readSnapshot.d.ts +3 -0
  32. package/dist/admin-view/readSnapshot.d.ts.map +1 -0
  33. package/dist/admin-view/readSnapshot.js +71 -0
  34. package/dist/admin-view/readSnapshot.js.map +1 -0
  35. package/dist/admin-view/types.d.ts +6 -0
  36. package/dist/admin-view/types.d.ts.map +1 -0
  37. package/dist/admin-view/types.js +2 -0
  38. package/dist/admin-view/types.js.map +1 -0
  39. package/dist/admin-view/useLocalizationAdmin.d.ts +12 -0
  40. package/dist/admin-view/useLocalizationAdmin.d.ts.map +1 -0
  41. package/dist/admin-view/useLocalizationAdmin.js +48 -0
  42. package/dist/admin-view/useLocalizationAdmin.js.map +1 -0
  43. package/package.json +21 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/orchestrator-module-expo-localization
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ba14722: Add the optional package-owned React/ZORA Localization administration view for locale management, canonical dictionary editing, metadata-driven field linking, and missing-translation authoring through the opaque module admin runtime contract.
8
+
3
9
  ## 0.4.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -63,6 +63,23 @@ from module-owned domain APIs. The link operation validates eligibility from inj
63
63
  metadata and uses the generic manifest mutation callback; new keys are seeded in the configured
64
64
  default-locale dictionary without overwriting an existing translation.
65
65
 
66
+ ## Optional admin view
67
+
68
+ React/ZORA authoring hosts can render the package-owned administration surface from the optional
69
+ `./admin-view` subpath. The view receives only an opaque executor and an optional project-change
70
+ callback; Localization operation IDs and result semantics remain inside this package.
71
+
72
+ ```ts
73
+ import {
74
+ ExpoLocalizationAdminView,
75
+ expoLocalizationAdminViewContribution,
76
+ } from '@ankhorage/orchestrator-module-expo-localization/admin-view';
77
+ ```
78
+
79
+ The view covers locale/default-locale management, canonical dictionary create/update/delete,
80
+ metadata-driven translatable-field search/filtering and linking, and missing-translation state. React
81
+ and ZORA are optional peer dependencies and are not dependencies of the root or `./host` entrypoints.
82
+
66
83
  ## Why this exists
67
84
 
68
85
  Standardizes localization setup across apps.
@@ -0,0 +1,9 @@
1
+ import type { ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ interface DictionaryEditorCardProps {
3
+ readonly snapshot: ExpoLocalizationAdminSnapshot;
4
+ readonly busy: boolean;
5
+ readonly run: (operation: string, input?: unknown) => Promise<void>;
6
+ }
7
+ export declare function DictionaryEditorCard({ snapshot, busy, run }: DictionaryEditorCardProps): import("react").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=DictionaryEditorCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DictionaryEditorCard.d.ts","sourceRoot":"","sources":["../../src/admin-view/DictionaryEditorCard.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAGpE,UAAU,yBAAyB;IACjC,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,yBAAyB,+BAgEtF"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, Input, Select, Stack } from '@ankhorage/zora';
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ import { EXPO_LOCALIZATION_ADMIN_OPERATIONS } from '../admin/runtime';
5
+ export function DictionaryEditorCard({ snapshot, busy, run }) {
6
+ const [locale, setLocale] = useState(snapshot.config.defaultLocale);
7
+ const [key, setKey] = useState('');
8
+ const [value, setValue] = useState('');
9
+ const localeOptions = useMemo(() => snapshot.config.locales.map((item) => ({ value: item, label: item })), [snapshot.config.locales]);
10
+ useEffect(() => {
11
+ if (!snapshot.config.locales.includes(locale))
12
+ setLocale(snapshot.config.defaultLocale);
13
+ }, [locale, snapshot.config.defaultLocale, snapshot.config.locales]);
14
+ useEffect(() => {
15
+ setValue(snapshot.dictionaries[locale]?.[key] ?? '');
16
+ }, [key, locale, snapshot.dictionaries]);
17
+ return (_jsx(Card, { title: "Dictionary entry", description: "Edit the canonical locale JSON resources directly.", children: _jsxs(Stack, { gap: 8, children: [_jsx(Select, { value: locale, options: localeOptions, onValueChange: setLocale, disabled: busy }), _jsx(Input, { accessibilityLabel: "Translation key", value: key, autoCapitalize: "none", onChangeText: setKey }), _jsx(Input, { accessibilityLabel: "Translation value", value: value, multiline: true, onChangeText: setValue }), _jsxs(Stack, { direction: "row", gap: 8, children: [_jsx(Button, { loading: busy, disabled: !key.trim(), onPress: () => void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.setTranslation, {
18
+ locale,
19
+ key: key.trim(),
20
+ value,
21
+ }), children: "Save translation" }), _jsx(Button, { variant: "outline", color: "danger", disabled: busy || !key.trim(), onPress: () => void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.deleteTranslation, {
22
+ locale,
23
+ key: key.trim(),
24
+ }), children: "Delete" })] })] }) }));
25
+ }
26
+ //# sourceMappingURL=DictionaryEditorCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DictionaryEditorCard.js","sourceRoot":"","sources":["../../src/admin-view/DictionaryEditorCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ExpoLocalizationAdminViewProps } from './types';
2
+ export declare function ExpoLocalizationAdminView(props: ExpoLocalizationAdminViewProps): import("react").JSX.Element;
3
+ //# sourceMappingURL=ExpoLocalizationAdminView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoLocalizationAdminView.d.ts","sourceRoot":"","sources":["../../src/admin-view/ExpoLocalizationAdminView.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAG9D,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,8BAA8B,+BA2B9E"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Stack, Text } from '@ankhorage/zora';
3
+ import { DictionaryEditorCard } from './DictionaryEditorCard';
4
+ import { LocaleManagementCard } from './LocaleManagementCard';
5
+ import { MissingTranslationsCard } from './MissingTranslationsCard';
6
+ import { TranslatableFieldsCard } from './TranslatableFieldsCard';
7
+ import { useLocalizationAdmin } from './useLocalizationAdmin';
8
+ export function ExpoLocalizationAdminView(props) {
9
+ const admin = useLocalizationAdmin(props);
10
+ if (admin.loading && !admin.snapshot) {
11
+ return _jsx(Text, { children: "Loading localization administration\u2026" });
12
+ }
13
+ if (!admin.snapshot) {
14
+ return (_jsx(Text, { color: "danger", children: admin.message ?? 'Localization administration is unavailable.' }));
15
+ }
16
+ return (_jsxs(Stack, { gap: 12, children: [admin.message ? _jsx(Text, { color: "danger", children: admin.message }) : null, _jsx(LocaleManagementCard, { snapshot: admin.snapshot, busy: admin.busy, run: admin.run }), _jsx(DictionaryEditorCard, { snapshot: admin.snapshot, busy: admin.busy, run: admin.run }), _jsx(TranslatableFieldsCard, { snapshot: admin.snapshot, options: admin.options, busy: admin.busy, reload: admin.reload, run: admin.run }), _jsx(MissingTranslationsCard, { snapshot: admin.snapshot })] }));
17
+ }
18
+ //# sourceMappingURL=ExpoLocalizationAdminView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExpoLocalizationAdminView.js","sourceRoot":"","sources":["../../src/admin-view/ExpoLocalizationAdminView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,UAAU,yBAAyB,CAAC,KAAqC;IAC7E,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE1C,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO,KAAC,IAAI,4DAA4C,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACpB,OAAO,CACL,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,KAAK,CAAC,OAAO,IAAI,6CAA6C,GAAQ,CAC7F,CAAC;IACJ,CAAC;IAED,OAAO,CACL,MAAC,KAAK,IAAC,GAAG,EAAE,EAAE,aACX,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,YAAE,KAAK,CAAC,OAAO,GAAQ,CAAC,CAAC,CAAC,IAAI,EACnE,KAAC,oBAAoB,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAI,EACpF,KAAC,oBAAoB,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,GAAI,EACpF,KAAC,sBAAsB,IACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,MAAM,EAAE,KAAK,CAAC,MAAM,EACpB,GAAG,EAAE,KAAK,CAAC,GAAG,GACd,EACF,KAAC,uBAAuB,IAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,GAAI,IAC/C,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ interface LocaleManagementCardProps {
3
+ readonly snapshot: ExpoLocalizationAdminSnapshot;
4
+ readonly busy: boolean;
5
+ readonly run: (operation: string, input?: unknown) => Promise<void>;
6
+ }
7
+ export declare function LocaleManagementCard({ snapshot, busy, run }: LocaleManagementCardProps): import("react").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=LocaleManagementCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocaleManagementCard.d.ts","sourceRoot":"","sources":["../../src/admin-view/LocaleManagementCard.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAGpE,UAAU,yBAAyB;IACjC,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,yBAAyB,+BAyDtF"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, Input, Stack, Text } from '@ankhorage/zora';
3
+ import { useState } from 'react';
4
+ import { EXPO_LOCALIZATION_ADMIN_OPERATIONS } from '../admin/runtime';
5
+ export function LocaleManagementCard({ snapshot, busy, run }) {
6
+ const [newLocale, setNewLocale] = useState('');
7
+ const { config } = snapshot;
8
+ return (_jsx(Card, { title: "Locales", description: "Configure supported locales and the default locale.", children: _jsxs(Stack, { gap: 8, children: [config.locales.map((locale) => (_jsxs(Stack, { direction: "row", gap: 8, align: "center", justify: "space-between", children: [_jsx(Text, { children: locale === config.defaultLocale ? `${locale} (default)` : locale }), _jsxs(Stack, { direction: "row", gap: 8, children: [locale !== config.defaultLocale ? (_jsx(Button, { variant: "outline", disabled: busy, onPress: () => void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.setDefaultLocale, { locale }), children: "Make default" })) : null, _jsx(Button, { variant: "outline", color: "danger", disabled: busy || config.locales.length === 1, onPress: () => void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.removeLocale, { locale }), children: "Remove" })] })] }, locale))), _jsxs(Stack, { direction: "row", gap: 8, align: "center", children: [_jsx(Input, { accessibilityLabel: "New locale", value: newLocale, autoCapitalize: "none", onChangeText: setNewLocale }), _jsx(Button, { loading: busy, disabled: !newLocale.trim(), onPress: () => {
9
+ const locale = newLocale.trim();
10
+ setNewLocale('');
11
+ void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.addLocale, { locale });
12
+ }, children: "Add locale" })] })] }) }));
13
+ }
14
+ //# sourceMappingURL=LocaleManagementCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocaleManagementCard.js","sourceRoot":"","sources":["../../src/admin-view/LocaleManagementCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC,OAAO,EAAE,kCAAkC,EAAE,MAAM,kBAAkB,CAAC;AAQtE,MAAM,UAAU,oBAAoB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAA6B;IACrF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/C,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;IAE5B,OAAO,CACL,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,WAAW,EAAC,qDAAqD,YACrF,MAAC,KAAK,IAAC,GAAG,EAAE,CAAC,aACV,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAC9B,MAAC,KAAK,IAAc,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,eAAe,aAChF,KAAC,IAAI,cAAE,MAAM,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,GAAQ,EAC/E,MAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,aAC1B,MAAM,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CACjC,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,GAAG,EAAE,CACZ,KAAK,GAAG,CAAC,kCAAkC,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,6BAIpE,CACV,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,KAAK,EAAC,QAAQ,EACd,QAAQ,EAAE,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAC7C,OAAO,EAAE,GAAG,EAAE,CACZ,KAAK,GAAG,CAAC,kCAAkC,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,uBAIhE,IACH,KAxBE,MAAM,CAyBV,CACT,CAAC,EACF,MAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAC,QAAQ,aAC3C,KAAC,KAAK,IACJ,kBAAkB,EAAC,YAAY,EAC/B,KAAK,EAAE,SAAS,EAChB,cAAc,EAAC,MAAM,EACrB,YAAY,EAAE,YAAY,GAC1B,EACF,KAAC,MAAM,IACL,OAAO,EAAE,IAAI,EACb,QAAQ,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAC3B,OAAO,EAAE,GAAG,EAAE;gCACZ,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;gCAChC,YAAY,CAAC,EAAE,CAAC,CAAC;gCACjB,KAAK,GAAG,CAAC,kCAAkC,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;4BACrE,CAAC,2BAGM,IACH,IACF,GACH,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ export declare function MissingTranslationsCard({ snapshot, }: {
3
+ readonly snapshot: ExpoLocalizationAdminSnapshot;
4
+ }): import("react").JSX.Element;
5
+ //# sourceMappingURL=MissingTranslationsCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MissingTranslationsCard.d.ts","sourceRoot":"","sources":["../../src/admin-view/MissingTranslationsCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAEpE,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;CAClD,+BAqBA"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card, Stack, Text } from '@ankhorage/zora';
3
+ export function MissingTranslationsCard({ snapshot, }) {
4
+ return (_jsx(Card, { title: "Missing translations", description: "Keys that are incomplete across configured locales.", children: _jsx(Stack, { gap: 6, children: snapshot.missingTranslations.length === 0 ? (_jsx(Text, { color: "neutral", emphasis: "muted", children: "No missing translations." })) : (snapshot.missingTranslations.map((item) => (_jsxs(Text, { children: [item.key, ": ", item.missingLocales.join(', ')] }, item.key)))) }) }));
5
+ }
6
+ //# sourceMappingURL=MissingTranslationsCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MissingTranslationsCard.js","sourceRoot":"","sources":["../../src/admin-view/MissingTranslationsCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAIpD,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,GAGT;IACC,OAAO,CACL,KAAC,IAAI,IACH,KAAK,EAAC,sBAAsB,EAC5B,WAAW,EAAC,qDAAqD,YAEjE,KAAC,KAAK,IAAC,GAAG,EAAE,CAAC,YACV,QAAQ,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,yCAE/B,CACR,CAAC,CAAC,CAAC,CACF,QAAQ,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzC,MAAC,IAAI,eACF,IAAI,CAAC,GAAG,QAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,KADlC,IAAI,CAAC,GAAG,CAEZ,CACR,CAAC,CACH,GACK,GACH,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { ExpoLocalizationTranslatableField } from '../authoring';
2
+ interface TranslatableFieldRowProps {
3
+ readonly field: ExpoLocalizationTranslatableField;
4
+ readonly missingLocales: readonly string[];
5
+ readonly busy: boolean;
6
+ readonly run: (operation: string, input?: unknown) => Promise<void>;
7
+ }
8
+ export declare function TranslatableFieldRow({ field, missingLocales, busy, run, }: TranslatableFieldRowProps): import("react").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=TranslatableFieldRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslatableFieldRow.d.ts","sourceRoot":"","sources":["../../src/admin-view/TranslatableFieldRow.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAC;AAItE,UAAU,yBAAyB;IACjC,QAAQ,CAAC,KAAK,EAAE,iCAAiC,CAAC;IAClD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,wBAAgB,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,EACd,IAAI,EACJ,GAAG,GACJ,EAAE,yBAAyB,+BA4C3B"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Input, Stack, Text } from '@ankhorage/zora';
3
+ import { useEffect, useState } from 'react';
4
+ import { createExpoLocalizationKeyFromText } from '../authoring';
5
+ import { EXPO_LOCALIZATION_ADMIN_OPERATIONS } from '../admin/runtime';
6
+ export function TranslatableFieldRow({ field, missingLocales, busy, run, }) {
7
+ const [key, setKey] = useState(field.currentKey || createExpoLocalizationKeyFromText(field.defaultText));
8
+ useEffect(() => {
9
+ setKey(field.currentKey || createExpoLocalizationKeyFromText(field.defaultText));
10
+ }, [field.currentKey, field.defaultText]);
11
+ return (_jsxs(Stack, { gap: 6, children: [_jsx(Text, { weight: "semiBold", children: field.path }), _jsx(Text, { color: "neutral", emphasis: "muted", variant: "caption", children: field.defaultText || 'No default text' }), missingLocales.length > 0 ? (_jsxs(Text, { color: "danger", variant: "caption", children: ["Missing: ", missingLocales.join(', ')] })) : null, _jsxs(Stack, { direction: "row", gap: 8, align: "center", children: [_jsx(Input, { accessibilityLabel: `Translation key for ${field.path}`, value: key, autoCapitalize: "none", onChangeText: setKey }), _jsx(Button, { variant: field.currentKey ? 'outline' : 'solid', disabled: busy || !key.trim(), onPress: () => void run(EXPO_LOCALIZATION_ADMIN_OPERATIONS.linkTranslationKey, {
12
+ screenId: field.screenId,
13
+ nodeId: field.nodeId,
14
+ keyProp: field.keyProp,
15
+ key: key.trim(),
16
+ }), children: field.currentKey ? 'Relink' : 'Link' })] })] }));
17
+ }
18
+ //# sourceMappingURL=TranslatableFieldRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslatableFieldRow.js","sourceRoot":"","sources":["../../src/admin-view/TranslatableFieldRow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,kCAAkC,EAAE,MAAM,kBAAkB,CAAC;AAStE,MAAM,UAAU,oBAAoB,CAAC,EACnC,KAAK,EACL,cAAc,EACd,IAAI,EACJ,GAAG,GACuB;IAC1B,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAC5B,KAAK,CAAC,UAAU,IAAI,iCAAiC,CAAC,KAAK,CAAC,WAAW,CAAC,CACzE,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,iCAAiC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IACnF,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1C,OAAO,CACL,MAAC,KAAK,IAAC,GAAG,EAAE,CAAC,aACX,KAAC,IAAI,IAAC,MAAM,EAAC,UAAU,YAAE,KAAK,CAAC,IAAI,GAAQ,EAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,EAAC,OAAO,EAAC,SAAS,YACrD,KAAK,CAAC,WAAW,IAAI,iBAAiB,GAClC,EACN,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC3B,MAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,SAAS,0BAC1B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAC9B,CACR,CAAC,CAAC,CAAC,IAAI,EACR,MAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAC,QAAQ,aAC3C,KAAC,KAAK,IACJ,kBAAkB,EAAE,uBAAuB,KAAK,CAAC,IAAI,EAAE,EACvD,KAAK,EAAE,GAAG,EACV,cAAc,EAAC,MAAM,EACrB,YAAY,EAAE,MAAM,GACpB,EACF,KAAC,MAAM,IACL,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAC/C,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAC7B,OAAO,EAAE,GAAG,EAAE,CACZ,KAAK,GAAG,CAAC,kCAAkC,CAAC,kBAAkB,EAAE;4BAC9D,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,MAAM,EAAE,KAAK,CAAC,MAAM;4BACpB,OAAO,EAAE,KAAK,CAAC,OAAO;4BACtB,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE;yBAChB,CAAC,YAGH,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAC9B,IACH,IACF,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ExpoLocalizationAdminLoadOptions, ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ interface TranslatableFieldsCardProps {
3
+ readonly snapshot: ExpoLocalizationAdminSnapshot;
4
+ readonly options: ExpoLocalizationAdminLoadOptions;
5
+ readonly busy: boolean;
6
+ readonly reload: (options: ExpoLocalizationAdminLoadOptions) => Promise<void>;
7
+ readonly run: (operation: string, input?: unknown) => Promise<void>;
8
+ }
9
+ export declare function TranslatableFieldsCard(props: TranslatableFieldsCardProps): import("react").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=TranslatableFieldsCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslatableFieldsCard.d.ts","sourceRoot":"","sources":["../../src/admin-view/TranslatableFieldsCard.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gCAAgC,EAChC,6BAA6B,EAC9B,MAAM,gBAAgB,CAAC;AAYxB,UAAU,2BAA2B;IACnC,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,gCAAgC,CAAC;IACnD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,gCAAgC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,QAAQ,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,+BAiDxE"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, Input, Select, Stack, Text } from '@ankhorage/zora';
3
+ import { useEffect, useState } from 'react';
4
+ import { TranslatableFieldRow } from './TranslatableFieldRow';
5
+ const FILTER_OPTIONS = [
6
+ { value: 'all', label: 'All fields' },
7
+ { value: 'unlinked', label: 'Unlinked' },
8
+ { value: 'missing-translations', label: 'Missing translations' },
9
+ { value: 'incomplete', label: 'Incomplete' },
10
+ ];
11
+ export function TranslatableFieldsCard(props) {
12
+ const [searchQuery, setSearchQuery] = useState(props.options.searchQuery ?? '');
13
+ const [filter, setFilter] = useState(props.options.filter ?? 'all');
14
+ useEffect(() => setSearchQuery(props.options.searchQuery ?? ''), [props.options.searchQuery]);
15
+ useEffect(() => setFilter(props.options.filter ?? 'all'), [props.options.filter]);
16
+ return (_jsx(Card, { title: "Translatable fields", description: "Discover and link fields from component metadata.", children: _jsxs(Stack, { gap: 10, children: [_jsxs(Stack, { direction: "row", gap: 8, align: "center", children: [_jsx(Input, { accessibilityLabel: "Search translatable fields", value: searchQuery, onChangeText: setSearchQuery }), _jsx(Select, { value: filter, options: FILTER_OPTIONS, onValueChange: setFilter }), _jsx(Button, { variant: "outline", disabled: props.busy, onPress: () => void props.reload({ searchQuery, filter }), children: "Apply" })] }), props.snapshot.visibleFields.length === 0 ? (_jsx(Text, { color: "neutral", emphasis: "muted", children: "No matching translatable fields." })) : (props.snapshot.visibleFields.map((field) => (_jsx(TranslatableFieldRow, { field: field, missingLocales: props.snapshot.missingTranslations.find((item) => item.key === field.currentKey)
17
+ ?.missingLocales ?? [], busy: props.busy, run: props.run }, `${field.screenId}:${field.nodeId}:${field.keyProp}`))))] }) }));
18
+ }
19
+ //# sourceMappingURL=TranslatableFieldsCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TranslatableFieldsCard.js","sourceRoot":"","sources":["../../src/admin-view/TranslatableFieldsCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAqB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAM5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAI9D,MAAM,cAAc,GAAoC;IACtD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE;IACrC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;IACxC,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,sBAAsB,EAAE;IAChE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE;CAC7C,CAAC;AAUF,MAAM,UAAU,sBAAsB,CAAC,KAAkC;IACvE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAChF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAS,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;IAE5E,SAAS,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9F,SAAS,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAElF,OAAO,CACL,KAAC,IAAI,IACH,KAAK,EAAC,qBAAqB,EAC3B,WAAW,EAAC,mDAAmD,YAE/D,MAAC,KAAK,IAAC,GAAG,EAAE,EAAE,aACZ,MAAC,KAAK,IAAC,SAAS,EAAC,KAAK,EAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAC,QAAQ,aAC3C,KAAC,KAAK,IACJ,kBAAkB,EAAC,4BAA4B,EAC/C,KAAK,EAAE,WAAW,EAClB,YAAY,EAAE,cAAc,GAC5B,EACF,KAAC,MAAM,IAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,GAAI,EAC5E,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,QAAQ,EAAE,KAAK,CAAC,IAAI,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,sBAGlD,IACH,EACP,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAC3C,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,OAAO,iDAE/B,CACR,CAAC,CAAC,CAAC,CACF,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC1C,KAAC,oBAAoB,IAEnB,KAAK,EAAE,KAAK,EACZ,cAAc,EACZ,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,CAAC,UAAU,CAAC;wBAC9E,EAAE,cAAc,IAAI,EAAE,EAE1B,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,GAAG,EAAE,KAAK,CAAC,GAAG,IAPT,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAQzD,CACH,CAAC,CACH,IACK,GACH,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { ExpoLocalizationAdminView } from './ExpoLocalizationAdminView';
2
+ export { ExpoLocalizationAdminView } from './ExpoLocalizationAdminView';
3
+ export type { ExpoLocalizationAdminExecutor, ExpoLocalizationAdminViewProps } from './types';
4
+ export declare const expoLocalizationAdminViewContribution: {
5
+ readonly id: "expo-localization";
6
+ readonly View: typeof ExpoLocalizationAdminView;
7
+ };
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin-view/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACxE,YAAY,EAAE,6BAA6B,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAE7F,eAAO,MAAM,qCAAqC;;;CAGxC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { EXPO_LOCALIZATION_MODULE_ID } from '../module';
2
+ import { ExpoLocalizationAdminView } from './ExpoLocalizationAdminView';
3
+ export { ExpoLocalizationAdminView } from './ExpoLocalizationAdminView';
4
+ export const expoLocalizationAdminViewContribution = {
5
+ id: EXPO_LOCALIZATION_MODULE_ID,
6
+ View: ExpoLocalizationAdminView,
7
+ };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/admin-view/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAGxE,MAAM,CAAC,MAAM,qCAAqC,GAAG;IACnD,EAAE,EAAE,2BAA2B;IAC/B,IAAI,EAAE,yBAAyB;CACvB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ export declare function readExpoLocalizationAdminSnapshot(value: unknown): ExpoLocalizationAdminSnapshot;
3
+ //# sourceMappingURL=readSnapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readSnapshot.d.ts","sourceRoot":"","sources":["../../src/admin-view/readSnapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAQpE,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,OAAO,GAAG,6BAA6B,CAS/F"}
@@ -0,0 +1,71 @@
1
+ import { parseExpoLocalizationModuleConfig } from '../config';
2
+ export function readExpoLocalizationAdminSnapshot(value) {
3
+ const record = requireRecord(value, 'Localization admin snapshot');
4
+ return {
5
+ config: parseExpoLocalizationModuleConfig(record.config),
6
+ dictionaries: readDictionaries(record.dictionaries),
7
+ fields: readFields(record.fields),
8
+ visibleFields: readFields(record.visibleFields),
9
+ missingTranslations: readMissingTranslations(record.missingTranslations),
10
+ };
11
+ }
12
+ function readDictionaries(value) {
13
+ const record = requireRecord(value, 'Localization dictionaries');
14
+ const result = {};
15
+ for (const [locale, dictionary] of Object.entries(record)) {
16
+ result[locale] = readDictionary(dictionary, locale);
17
+ }
18
+ return result;
19
+ }
20
+ function readDictionary(value, locale) {
21
+ const record = requireRecord(value, `Dictionary '${locale}'`);
22
+ const result = {};
23
+ for (const [key, translation] of Object.entries(record)) {
24
+ if (typeof translation !== 'string')
25
+ throw new Error(`Dictionary '${locale}' is invalid.`);
26
+ result[key] = translation;
27
+ }
28
+ return result;
29
+ }
30
+ function readFields(value) {
31
+ if (!Array.isArray(value) || !value.every(isTranslatableField)) {
32
+ throw new Error('Localization translatable fields are invalid.');
33
+ }
34
+ return value;
35
+ }
36
+ function isTranslatableField(value) {
37
+ if (!isRecord(value))
38
+ return false;
39
+ return [
40
+ 'screenId',
41
+ 'nodeId',
42
+ 'componentName',
43
+ 'keyProp',
44
+ 'defaultTextProp',
45
+ 'currentKey',
46
+ 'defaultText',
47
+ 'path',
48
+ ].every((key) => typeof value[key] === 'string');
49
+ }
50
+ function readMissingTranslations(value) {
51
+ if (!Array.isArray(value) || !value.every(isMissingTranslation)) {
52
+ throw new Error('Localization missing-translation state is invalid.');
53
+ }
54
+ return value;
55
+ }
56
+ function isMissingTranslation(value) {
57
+ return (isRecord(value) &&
58
+ typeof value.key === 'string' &&
59
+ typeof value.fieldCount === 'number' &&
60
+ Array.isArray(value.missingLocales) &&
61
+ value.missingLocales.every((locale) => typeof locale === 'string'));
62
+ }
63
+ function requireRecord(value, label) {
64
+ if (!isRecord(value))
65
+ throw new Error(`${label} is invalid.`);
66
+ return value;
67
+ }
68
+ function isRecord(value) {
69
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
70
+ }
71
+ //# sourceMappingURL=readSnapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readSnapshot.js","sourceRoot":"","sources":["../../src/admin-view/readSnapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type ExpoLocalizationAdminExecutor = (operation: string, input?: unknown) => Promise<unknown>;
2
+ export interface ExpoLocalizationAdminViewProps {
3
+ readonly execute: ExpoLocalizationAdminExecutor;
4
+ readonly onProjectChange?: () => Promise<void> | void;
5
+ }
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/admin-view/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,6BAA6B,GAAG,CAC1C,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,OAAO,KACZ,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,OAAO,EAAE,6BAA6B,CAAC;IAChD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACvD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/admin-view/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import type { ExpoLocalizationAdminLoadOptions, ExpoLocalizationAdminSnapshot } from '../admin/types';
2
+ import type { ExpoLocalizationAdminViewProps } from './types';
3
+ export declare function useLocalizationAdmin({ execute, onProjectChange }: ExpoLocalizationAdminViewProps): {
4
+ snapshot: ExpoLocalizationAdminSnapshot | null;
5
+ options: ExpoLocalizationAdminLoadOptions;
6
+ loading: boolean;
7
+ busy: boolean;
8
+ message: string | null;
9
+ reload: (nextOptions?: ExpoLocalizationAdminLoadOptions) => Promise<void>;
10
+ run: (operation: string, input?: unknown) => Promise<void>;
11
+ };
12
+ //# sourceMappingURL=useLocalizationAdmin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLocalizationAdmin.d.ts","sourceRoot":"","sources":["../../src/admin-view/useLocalizationAdmin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gCAAgC,EAChC,6BAA6B,EAC9B,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAE9D,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,8BAA8B;;;;;;2BAQzE,gCAAgC;qBAiBlC,MAAM,UAAU,OAAO;EAqB5C"}
@@ -0,0 +1,48 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { EXPO_LOCALIZATION_ADMIN_OPERATIONS } from '../admin/runtime';
3
+ import { readExpoLocalizationAdminSnapshot } from './readSnapshot';
4
+ export function useLocalizationAdmin({ execute, onProjectChange }) {
5
+ const [snapshot, setSnapshot] = useState(null);
6
+ const [options, setOptions] = useState({});
7
+ const [loading, setLoading] = useState(true);
8
+ const [busy, setBusy] = useState(false);
9
+ const [message, setMessage] = useState(null);
10
+ const reload = useCallback(async (nextOptions = options) => {
11
+ setLoading(true);
12
+ try {
13
+ const result = await execute(EXPO_LOCALIZATION_ADMIN_OPERATIONS.load, nextOptions);
14
+ setSnapshot(readExpoLocalizationAdminSnapshot(result));
15
+ setOptions(nextOptions);
16
+ setMessage(null);
17
+ }
18
+ catch (error) {
19
+ setMessage(toMessage(error));
20
+ }
21
+ finally {
22
+ setLoading(false);
23
+ }
24
+ }, [execute, options]);
25
+ const run = useCallback(async (operation, input) => {
26
+ setBusy(true);
27
+ setMessage(null);
28
+ try {
29
+ await execute(operation, input);
30
+ await onProjectChange?.();
31
+ await reload();
32
+ }
33
+ catch (error) {
34
+ setMessage(toMessage(error));
35
+ }
36
+ finally {
37
+ setBusy(false);
38
+ }
39
+ }, [execute, onProjectChange, reload]);
40
+ useEffect(() => {
41
+ void reload({});
42
+ }, [execute]);
43
+ return { snapshot, options, loading, busy, message, reload, run };
44
+ }
45
+ function toMessage(error) {
46
+ return error instanceof Error ? error.message : String(error);
47
+ }
48
+ //# sourceMappingURL=useLocalizationAdmin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLocalizationAdmin.js","sourceRoot":"","sources":["../../src/admin-view/useLocalizationAdmin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,kCAAkC,EAAE,MAAM,kBAAkB,CAAC;AAKtE,OAAO,EAAE,iCAAiC,EAAE,MAAM,gBAAgB,CAAC;AAGnE,MAAM,UAAU,oBAAoB,CAAC,EAAE,OAAO,EAAE,eAAe,EAAkC;IAC/F,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAuC,IAAI,CAAC,CAAC;IACrF,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAmC,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,WAAW,CACxB,KAAK,EAAE,cAAgD,OAAO,EAAE,EAAE;QAChE,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,kCAAkC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACnF,WAAW,CAAC,iCAAiC,CAAC,MAAM,CAAC,CAAC,CAAC;YACvD,UAAU,CAAC,WAAW,CAAC,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/B,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EACD,CAAC,OAAO,EAAE,OAAO,CAAC,CACnB,CAAC;IAEF,MAAM,GAAG,GAAG,WAAW,CACrB,KAAK,EAAE,SAAiB,EAAE,KAAe,EAAE,EAAE;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YAChC,MAAM,eAAe,EAAE,EAAE,CAAC;YAC1B,MAAM,MAAM,EAAE,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/B,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;IACH,CAAC,EACD,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,CACnC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACpE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
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.0",
4
+ "version": "0.5.0",
5
5
  "description": "Expo localization module for @ankhorage/orchestrator.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -38,6 +38,10 @@
38
38
  "./host": {
39
39
  "types": "./dist/host.d.ts",
40
40
  "default": "./dist/host.js"
41
+ },
42
+ "./admin-view": {
43
+ "types": "./dist/admin-view/index.d.ts",
44
+ "default": "./dist/admin-view/index.js"
41
45
  }
42
46
  },
43
47
  "scripts": {
@@ -54,11 +58,27 @@
54
58
  "dependencies": {
55
59
  "@ankhorage/orchestrator": "^0.3.1"
56
60
  },
61
+ "peerDependencies": {
62
+ "@ankhorage/zora": "^2.9.3",
63
+ "react": ">=18.2.0"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "@ankhorage/zora": {
67
+ "optional": true
68
+ },
69
+ "react": {
70
+ "optional": true
71
+ }
72
+ },
57
73
  "devDependencies": {
58
74
  "@ankhorage/devtools": "^1.0.6",
75
+ "@ankhorage/zora": "^2.9.3",
59
76
  "@changesets/cli": "^2.31.0",
60
77
  "@types/bun": "^1.3.13",
61
78
  "@types/node": "^25.6.0",
79
+ "@types/react": "^19.2.14",
80
+ "react": "19.1.0",
81
+ "react-native": "0.81.5",
62
82
  "typescript": "^5.9.3"
63
83
  },
64
84
  "packageManager": "bun@1.3.13",