@ankhorage/contracts 10.1.0 → 11.1.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 (42) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +1 -1
  3. package/dist/appManifest/navigator.d.ts +3 -0
  4. package/dist/appManifest/navigator.d.ts.map +1 -0
  5. package/dist/appManifest/navigator.js +142 -0
  6. package/dist/appManifest/navigator.js.map +1 -0
  7. package/dist/appManifest/navigatorOptions.d.ts +13 -0
  8. package/dist/appManifest/navigatorOptions.d.ts.map +1 -0
  9. package/dist/appManifest/navigatorOptions.js +226 -0
  10. package/dist/appManifest/navigatorOptions.js.map +1 -0
  11. package/dist/appManifest/screens.d.ts +1 -2
  12. package/dist/appManifest/screens.d.ts.map +1 -1
  13. package/dist/appManifest/screens.js +2 -116
  14. package/dist/appManifest/screens.js.map +1 -1
  15. package/dist/navigator/extensions.d.ts +23 -0
  16. package/dist/navigator/extensions.d.ts.map +1 -0
  17. package/dist/navigator/extensions.js +2 -0
  18. package/dist/navigator/extensions.js.map +1 -0
  19. package/dist/navigator/generation.d.ts +26 -0
  20. package/dist/navigator/generation.d.ts.map +1 -0
  21. package/dist/navigator/generation.js +2 -0
  22. package/dist/navigator/generation.js.map +1 -0
  23. package/dist/navigator/planning.d.ts +105 -0
  24. package/dist/navigator/planning.d.ts.map +1 -0
  25. package/dist/navigator/planning.js +2 -0
  26. package/dist/navigator/planning.js.map +1 -0
  27. package/dist/navigator.d.ts +104 -15
  28. package/dist/navigator.d.ts.map +1 -1
  29. package/dist/navigator.js +23 -1
  30. package/dist/navigator.js.map +1 -1
  31. package/package.json +4 -4
  32. package/src/appManifest/navigator.ts +179 -0
  33. package/src/appManifest/navigatorOptions.ts +292 -0
  34. package/src/appManifest/screens.ts +3 -170
  35. package/src/contracts.test.ts +1 -1
  36. package/src/navigator/extensions.ts +26 -0
  37. package/src/navigator/generation.ts +28 -0
  38. package/src/navigator/planning.ts +146 -0
  39. package/src/navigator-runtime-contracts.test.ts +53 -0
  40. package/src/navigator-validation.test.ts +153 -0
  41. package/src/navigator.test.ts +153 -10
  42. package/src/navigator.ts +180 -13
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @ankhorage/contracts
2
2
 
3
+ ## 11.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8a62b08: Expose the portable Navigator planning, generation, and custom-registration contracts through the navigator subpath. Group related declarations by topic so Navigator and Studio can consume canonical shared types without depending on another capability's type exports.
8
+
9
+ ## 11.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - 1696309: Add serializable Slot, typed Stack, Drawer, Tabs, Split View, and Custom navigator variants with matching structural validation.
14
+
15
+ This is a breaking contract change: the arbitrary navigator `options` bag is removed, Stack and Drawer options are now finite typed branches, custom tabs use strict presentation discriminants, and invalid or non-JSON custom configuration is rejected. No authored `options` values were found in the current canonical consumers; the major release prevents their existing `^10` ranges from receiving the narrowed contract automatically.
16
+
3
17
  ## 10.1.0
4
18
 
5
19
  ### Minor Changes
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # CONTRACTS
5
5
 
6
- ![license: MIT](././paradox/badges/license.svg) ![npm: v8.0.1](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
6
+ ![license: MIT](././paradox/badges/license.svg) ![npm: v11.1.0](././paradox/badges/npm.svg) ![runtime: bun](././paradox/badges/runtime.svg) ![typescript: strict](././paradox/badges/typescript.svg) ![eslint: checked](././paradox/badges/eslint.svg) ![prettier: checked](././paradox/badges/prettier.svg) ![build: checked](././paradox/badges/build.svg) ![tests: checked](././paradox/badges/tests.svg) ![docs: paradox](././paradox/badges/docs.svg)
7
7
 
8
8
  Serializable app, action, theme, auth, and secret-store contracts for Ankhorage.
9
9
 
@@ -0,0 +1,3 @@
1
+ /*** Validate the complete serialized `AppManifest.navigator` slice. */
2
+ export declare function isAppNavigatorManifest(value: unknown): boolean;
3
+ //# sourceMappingURL=navigator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigator.d.ts","sourceRoot":"","sources":["../../src/appManifest/navigator.ts"],"names":[],"mappings":"AAeA,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAU9D"}
@@ -0,0 +1,142 @@
1
+ import { NAVIGATOR_PRESETS, NAVIGATOR_TYPES } from '../navigator';
2
+ import { isIconSpec } from './icon';
3
+ import { hasOnlyKeys, isDrawerNavigatorOptions, isNavigatorScreenReference, isStackImplementationConfig, isStackScreenOptions, isTabsImplementationConfig, } from './navigatorOptions';
4
+ import { isOptionalBoolean, isOptionalString, isRecord, isStringArray } from './shared';
5
+ const NAVIGATOR_PRESET_SET = new Set(NAVIGATOR_PRESETS);
6
+ const NAVIGATOR_TYPE_SET = new Set(NAVIGATOR_TYPES);
7
+ /*** Validate the complete serialized `AppManifest.navigator` slice. */
8
+ export function isAppNavigatorManifest(value) {
9
+ return (isRecord(value) &&
10
+ isNavigatorNode(value) &&
11
+ (value.preset === undefined ||
12
+ (typeof value.preset === 'string' && NAVIGATOR_PRESET_SET.has(value.preset))) &&
13
+ (value.flows === undefined || isNavigatorFlows(value.flows)) &&
14
+ (value.defaults === undefined || isNavigatorDefaults(value.defaults)) &&
15
+ (value.platforms === undefined || isNavigatorPlatforms(value.platforms)));
16
+ }
17
+ /*** Validate one nested navigator node independently from app-level authoring metadata. */
18
+ function isNavigatorNode(value) {
19
+ if (!isRecord(value) ||
20
+ typeof value.type !== 'string' ||
21
+ !NAVIGATOR_TYPE_SET.has(value.type) ||
22
+ !isOptionalString(value.initialRouteName) ||
23
+ !Array.isArray(value.routes) ||
24
+ !value.routes.every(isRouteDefinition)) {
25
+ return false;
26
+ }
27
+ switch (value.type) {
28
+ case 'slot':
29
+ return value.options === undefined && value.implementation === undefined;
30
+ case 'stack':
31
+ return isStackImplementationConfig(value);
32
+ case 'tabs':
33
+ return isTabsImplementationConfig(value);
34
+ case 'drawer':
35
+ return (value.implementation === undefined &&
36
+ (value.options === undefined || isDrawerNavigatorOptions(value.options)));
37
+ case 'split-view':
38
+ return isSplitViewNavigatorNode(value);
39
+ case 'custom':
40
+ return isCustomNavigatorNode(value);
41
+ default:
42
+ return false;
43
+ }
44
+ }
45
+ /*** Validate one route and preserve its portable metadata and nested navigator. */
46
+ function isRouteDefinition(value) {
47
+ return (isRecord(value) &&
48
+ typeof value.name === 'string' &&
49
+ isOptionalString(value.path) &&
50
+ isOptionalString(value.label) &&
51
+ (value.icon === undefined || isIconSpec(value.icon)) &&
52
+ isOptionalBoolean(value.showInPrimaryNavigation) &&
53
+ (value.guards === undefined || isStringArray(value.guards)) &&
54
+ isOptionalString(value.screenId) &&
55
+ (value.stackOptions === undefined || isStackScreenOptions(value.stackOptions)) &&
56
+ (value.navigator === undefined || isNavigatorNode(value.navigator)));
57
+ }
58
+ /*** Validate Split View screen references without duplicating the routed secondary tree. */
59
+ function isSplitViewNavigatorNode(value) {
60
+ return (value.implementation === undefined &&
61
+ value.options === undefined &&
62
+ isRecord(value.columns) &&
63
+ hasOnlyKeys(value.columns, ['primary', 'supplementary']) &&
64
+ isNavigatorScreenReference(value.columns.primary) &&
65
+ (value.columns.supplementary === undefined ||
66
+ isNavigatorScreenReference(value.columns.supplementary)) &&
67
+ (value.inspector === undefined || isNavigatorScreenReference(value.inspector)) &&
68
+ (value.topColumnForCollapsing === undefined ||
69
+ value.topColumnForCollapsing === 'primary' ||
70
+ value.topColumnForCollapsing === 'supplementary' ||
71
+ value.topColumnForCollapsing === 'secondary'));
72
+ }
73
+ /*** Validate a registered custom navigator with JSON-safe configuration only. */
74
+ function isCustomNavigatorNode(value) {
75
+ return (value.implementation === undefined &&
76
+ value.options === undefined &&
77
+ typeof value.navigatorId === 'string' &&
78
+ (value.config === undefined || isNavigatorJsonRecord(value.config)));
79
+ }
80
+ /*** Validate an acyclic, finite JSON object used by a custom navigator adapter. */
81
+ function isNavigatorJsonRecord(value) {
82
+ return isRecord(value) && isNavigatorJsonValue(value, new Set());
83
+ }
84
+ /*** Recursively validate the portable manifest value domain and reject cycles. */
85
+ function isNavigatorJsonValue(value, ancestors) {
86
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
87
+ return true;
88
+ if (typeof value === 'number')
89
+ return Number.isFinite(value);
90
+ if (typeof value !== 'object' || ancestors.has(value))
91
+ return false;
92
+ if (Array.isArray(value)) {
93
+ if (Object.keys(value).length !== value.length ||
94
+ Object.getOwnPropertySymbols(value).length > 0) {
95
+ return false;
96
+ }
97
+ }
98
+ else {
99
+ const prototype = Object.getPrototypeOf(value);
100
+ if (prototype !== Object.prototype && prototype !== null)
101
+ return false;
102
+ if (Reflect.ownKeys(value).some((key) => typeof key !== 'string'))
103
+ return false;
104
+ }
105
+ ancestors.add(value);
106
+ const isValid = Object.values(value).every((entry) => isNavigatorJsonValue(entry, ancestors));
107
+ ancestors.delete(value);
108
+ return isValid;
109
+ }
110
+ /*** Validate optional app-level navigator flow intent. */
111
+ function isNavigatorFlows(value) {
112
+ return (isRecord(value) &&
113
+ isOptionalBoolean(value.onboarding) &&
114
+ isOptionalBoolean(value.authentication));
115
+ }
116
+ /*** Validate package-owned navigator defaults without requiring a navigator node type. */
117
+ function isNavigatorDefaults(value) {
118
+ return (isRecord(value) &&
119
+ hasOnlyKeys(value, ['tabs', 'stack']) &&
120
+ (value.tabs === undefined ||
121
+ (isRecord(value.tabs) && isTabsImplementationConfig(value.tabs))) &&
122
+ (value.stack === undefined ||
123
+ (isRecord(value.stack) && isStackImplementationConfig(value.stack))));
124
+ }
125
+ /*** Validate per-platform navigator implementation overrides. */
126
+ function isNavigatorPlatforms(value) {
127
+ return (isRecord(value) &&
128
+ hasOnlyKeys(value, ['android', 'ios', 'web']) &&
129
+ (value.android === undefined || isNavigatorPlatformConfig(value.android)) &&
130
+ (value.ios === undefined || isNavigatorPlatformConfig(value.ios)) &&
131
+ (value.web === undefined || isNavigatorPlatformConfig(value.web)));
132
+ }
133
+ /*** Validate one platform-specific navigator override slice. */
134
+ function isNavigatorPlatformConfig(value) {
135
+ return (isRecord(value) &&
136
+ hasOnlyKeys(value, ['tabs', 'stack']) &&
137
+ (value.tabs === undefined ||
138
+ (isRecord(value.tabs) && isTabsImplementationConfig(value.tabs))) &&
139
+ (value.stack === undefined ||
140
+ (isRecord(value.stack) && isStackImplementationConfig(value.stack))));
141
+ }
142
+ //# sourceMappingURL=navigator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigator.js","sourceRoot":"","sources":["../../src/appManifest/navigator.ts"],"names":[],"mappings":"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","sourcesContent":["import { NAVIGATOR_PRESETS, NAVIGATOR_TYPES } from '../navigator';\nimport { isIconSpec } from './icon';\nimport {\n hasOnlyKeys,\n isDrawerNavigatorOptions,\n isNavigatorScreenReference,\n isStackImplementationConfig,\n isStackScreenOptions,\n isTabsImplementationConfig,\n} from './navigatorOptions';\nimport { isOptionalBoolean, isOptionalString, isRecord, isStringArray } from './shared';\n\nconst NAVIGATOR_PRESET_SET = new Set<string>(NAVIGATOR_PRESETS);\nconst NAVIGATOR_TYPE_SET = new Set<string>(NAVIGATOR_TYPES);\n\n/*** Validate the complete serialized `AppManifest.navigator` slice. */\nexport function isAppNavigatorManifest(value: unknown): boolean {\n return (\n isRecord(value) &&\n isNavigatorNode(value) &&\n (value.preset === undefined ||\n (typeof value.preset === 'string' && NAVIGATOR_PRESET_SET.has(value.preset))) &&\n (value.flows === undefined || isNavigatorFlows(value.flows)) &&\n (value.defaults === undefined || isNavigatorDefaults(value.defaults)) &&\n (value.platforms === undefined || isNavigatorPlatforms(value.platforms))\n );\n}\n\n/*** Validate one nested navigator node independently from app-level authoring metadata. */\nfunction isNavigatorNode(value: unknown): boolean {\n if (\n !isRecord(value) ||\n typeof value.type !== 'string' ||\n !NAVIGATOR_TYPE_SET.has(value.type) ||\n !isOptionalString(value.initialRouteName) ||\n !Array.isArray(value.routes) ||\n !value.routes.every(isRouteDefinition)\n ) {\n return false;\n }\n\n switch (value.type) {\n case 'slot':\n return value.options === undefined && value.implementation === undefined;\n case 'stack':\n return isStackImplementationConfig(value);\n case 'tabs':\n return isTabsImplementationConfig(value);\n case 'drawer':\n return (\n value.implementation === undefined &&\n (value.options === undefined || isDrawerNavigatorOptions(value.options))\n );\n case 'split-view':\n return isSplitViewNavigatorNode(value);\n case 'custom':\n return isCustomNavigatorNode(value);\n default:\n return false;\n }\n}\n\n/*** Validate one route and preserve its portable metadata and nested navigator. */\nfunction isRouteDefinition(value: unknown): boolean {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n isOptionalString(value.path) &&\n isOptionalString(value.label) &&\n (value.icon === undefined || isIconSpec(value.icon)) &&\n isOptionalBoolean(value.showInPrimaryNavigation) &&\n (value.guards === undefined || isStringArray(value.guards)) &&\n isOptionalString(value.screenId) &&\n (value.stackOptions === undefined || isStackScreenOptions(value.stackOptions)) &&\n (value.navigator === undefined || isNavigatorNode(value.navigator))\n );\n}\n\n/*** Validate Split View screen references without duplicating the routed secondary tree. */\nfunction isSplitViewNavigatorNode(value: Record<string, unknown>): boolean {\n return (\n value.implementation === undefined &&\n value.options === undefined &&\n isRecord(value.columns) &&\n hasOnlyKeys(value.columns, ['primary', 'supplementary']) &&\n isNavigatorScreenReference(value.columns.primary) &&\n (value.columns.supplementary === undefined ||\n isNavigatorScreenReference(value.columns.supplementary)) &&\n (value.inspector === undefined || isNavigatorScreenReference(value.inspector)) &&\n (value.topColumnForCollapsing === undefined ||\n value.topColumnForCollapsing === 'primary' ||\n value.topColumnForCollapsing === 'supplementary' ||\n value.topColumnForCollapsing === 'secondary')\n );\n}\n\n/*** Validate a registered custom navigator with JSON-safe configuration only. */\nfunction isCustomNavigatorNode(value: Record<string, unknown>): boolean {\n return (\n value.implementation === undefined &&\n value.options === undefined &&\n typeof value.navigatorId === 'string' &&\n (value.config === undefined || isNavigatorJsonRecord(value.config))\n );\n}\n\n/*** Validate an acyclic, finite JSON object used by a custom navigator adapter. */\nfunction isNavigatorJsonRecord(value: unknown): boolean {\n return isRecord(value) && isNavigatorJsonValue(value, new Set<object>());\n}\n\n/*** Recursively validate the portable manifest value domain and reject cycles. */\nfunction isNavigatorJsonValue(value: unknown, ancestors: Set<object>): boolean {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;\n if (typeof value === 'number') return Number.isFinite(value);\n if (typeof value !== 'object' || ancestors.has(value)) return false;\n\n if (Array.isArray(value)) {\n if (\n Object.keys(value).length !== value.length ||\n Object.getOwnPropertySymbols(value).length > 0\n ) {\n return false;\n }\n } else {\n const prototype = Object.getPrototypeOf(value) as object | null;\n if (prototype !== Object.prototype && prototype !== null) return false;\n if (Reflect.ownKeys(value).some((key) => typeof key !== 'string')) return false;\n }\n\n ancestors.add(value);\n const isValid = Object.values(value).every((entry) => isNavigatorJsonValue(entry, ancestors));\n ancestors.delete(value);\n return isValid;\n}\n\n/*** Validate optional app-level navigator flow intent. */\nfunction isNavigatorFlows(value: unknown): boolean {\n return (\n isRecord(value) &&\n isOptionalBoolean(value.onboarding) &&\n isOptionalBoolean(value.authentication)\n );\n}\n\n/*** Validate package-owned navigator defaults without requiring a navigator node type. */\nfunction isNavigatorDefaults(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['tabs', 'stack']) &&\n (value.tabs === undefined ||\n (isRecord(value.tabs) && isTabsImplementationConfig(value.tabs))) &&\n (value.stack === undefined ||\n (isRecord(value.stack) && isStackImplementationConfig(value.stack)))\n );\n}\n\n/*** Validate per-platform navigator implementation overrides. */\nfunction isNavigatorPlatforms(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['android', 'ios', 'web']) &&\n (value.android === undefined || isNavigatorPlatformConfig(value.android)) &&\n (value.ios === undefined || isNavigatorPlatformConfig(value.ios)) &&\n (value.web === undefined || isNavigatorPlatformConfig(value.web))\n );\n}\n\n/*** Validate one platform-specific navigator override slice. */\nfunction isNavigatorPlatformConfig(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['tabs', 'stack']) &&\n (value.tabs === undefined ||\n (isRecord(value.tabs) && isTabsImplementationConfig(value.tabs))) &&\n (value.stack === undefined ||\n (isRecord(value.stack) && isStackImplementationConfig(value.stack)))\n );\n}\n"]}
@@ -0,0 +1,13 @@
1
+ /*** Validate stable native, JavaScript, or alpha Experimental Stack desired state. */
2
+ export declare function isStackImplementationConfig(value: Record<string, unknown>): boolean;
3
+ /*** Validate the serializable native-stack screen option subset. */
4
+ export declare function isStackScreenOptions(value: unknown): boolean;
5
+ /*** Validate the finite serializable Drawer option subset. */
6
+ export declare function isDrawerNavigatorOptions(value: unknown): boolean;
7
+ /*** Validate tabs implementation desired state, with omitted implementation meaning adaptive. */
8
+ export declare function isTabsImplementationConfig(value: Record<string, unknown>): boolean;
9
+ /*** Validate a reference into the app-owned screen registry. */
10
+ export declare function isNavigatorScreenReference(value: unknown): boolean;
11
+ /*** Check that a finite configuration object contains no unsupported keys. */
12
+ export declare function hasOnlyKeys(value: Record<string, unknown>, allowedKeys: readonly string[]): boolean;
13
+ //# sourceMappingURL=navigatorOptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigatorOptions.d.ts","sourceRoot":"","sources":["../../src/appManifest/navigatorOptions.ts"],"names":[],"mappings":"AAqBA,sFAAsF;AACtF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAwBnF;AAED,oEAAoE;AACpE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0B5D;AAED,8DAA8D;AAC9D,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYhE;AAED,iGAAiG;AACjG,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAWlF;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElE;AAED,8EAA8E;AAC9E,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAGT"}
@@ -0,0 +1,226 @@
1
+ import { CUSTOM_TABS_PRESENTATIONS, DRAWER_POSITIONS, DRAWER_TYPES, FIXED_CUSTOM_TABS_PRESENTATIONS, JAVASCRIPT_STACK_PRESENTATIONS, JAVASCRIPT_TABS_PRESENTATIONS, NATIVE_TABS_MINIMIZE_BEHAVIORS, STACK_PRESENTATIONS, } from '../navigator';
2
+ import { isOptionalBoolean, isOptionalString, isRecord } from './shared';
3
+ const CUSTOM_TABS_PRESENTATION_SET = new Set(CUSTOM_TABS_PRESENTATIONS);
4
+ const DRAWER_POSITION_SET = new Set(DRAWER_POSITIONS);
5
+ const DRAWER_TYPE_SET = new Set(DRAWER_TYPES);
6
+ const FIXED_CUSTOM_TABS_PRESENTATION_SET = new Set(FIXED_CUSTOM_TABS_PRESENTATIONS);
7
+ const JAVASCRIPT_STACK_PRESENTATION_SET = new Set(JAVASCRIPT_STACK_PRESENTATIONS);
8
+ const JAVASCRIPT_TABS_PRESENTATION_SET = new Set(JAVASCRIPT_TABS_PRESENTATIONS);
9
+ const NATIVE_TABS_MINIMIZE_BEHAVIOR_SET = new Set(NATIVE_TABS_MINIMIZE_BEHAVIORS);
10
+ const STACK_PRESENTATION_SET = new Set(STACK_PRESENTATIONS);
11
+ /*** Validate stable native, JavaScript, or alpha Experimental Stack desired state. */
12
+ export function isStackImplementationConfig(value) {
13
+ if (!hasNoDefinedKeys(value, [
14
+ 'native',
15
+ 'web',
16
+ 'presentation',
17
+ 'responsive',
18
+ 'customPresentationId',
19
+ 'minimizeBehavior',
20
+ 'bottomAccessory',
21
+ ])) {
22
+ return false;
23
+ }
24
+ if (value.implementation === undefined || value.implementation === 'native') {
25
+ return value.options === undefined || isStackScreenOptions(value.options);
26
+ }
27
+ if (value.implementation === 'javascript') {
28
+ return value.options === undefined || isJavaScriptStackScreenOptions(value.options);
29
+ }
30
+ return (value.implementation === 'experimental' &&
31
+ (value.options === undefined || isStackHeaderOptions(value.options)));
32
+ }
33
+ /*** Validate the serializable native-stack screen option subset. */
34
+ export function isStackScreenOptions(value) {
35
+ if (!isRecord(value) ||
36
+ !hasOnlyKeys(value, [
37
+ 'title',
38
+ 'headerShown',
39
+ 'headerTransparent',
40
+ 'headerBackVisible',
41
+ 'presentation',
42
+ 'sheetAllowedDetents',
43
+ 'sheetGrabberVisible',
44
+ ]) ||
45
+ !isStackHeaderOptionsShape(value) ||
46
+ (value.presentation !== undefined &&
47
+ (typeof value.presentation !== 'string' || !STACK_PRESENTATION_SET.has(value.presentation)))) {
48
+ return false;
49
+ }
50
+ if (value.presentation !== 'formSheet') {
51
+ return value.sheetAllowedDetents === undefined && value.sheetGrabberVisible === undefined;
52
+ }
53
+ return ((value.sheetAllowedDetents === undefined || isSheetAllowedDetents(value.sheetAllowedDetents)) &&
54
+ isOptionalBoolean(value.sheetGrabberVisible));
55
+ }
56
+ /*** Validate the finite serializable Drawer option subset. */
57
+ export function isDrawerNavigatorOptions(value) {
58
+ return (isRecord(value) &&
59
+ hasOnlyKeys(value, ['drawerPosition', 'drawerType', 'swipeEnabled', 'headerShown']) &&
60
+ (value.drawerPosition === undefined ||
61
+ (typeof value.drawerPosition === 'string' &&
62
+ DRAWER_POSITION_SET.has(value.drawerPosition))) &&
63
+ (value.drawerType === undefined ||
64
+ (typeof value.drawerType === 'string' && DRAWER_TYPE_SET.has(value.drawerType))) &&
65
+ isOptionalBoolean(value.swipeEnabled) &&
66
+ isOptionalBoolean(value.headerShown));
67
+ }
68
+ /*** Validate tabs implementation desired state, with omitted implementation meaning adaptive. */
69
+ export function isTabsImplementationConfig(value) {
70
+ if (value.implementation === undefined || value.implementation === 'adaptive') {
71
+ return isAdaptiveTabsConfig(value);
72
+ }
73
+ if (value.implementation === 'native')
74
+ return isFullNativeTabsConfig(value);
75
+ if (value.implementation === 'javascript')
76
+ return isJavaScriptTabsConfig(value);
77
+ return (value.implementation === 'custom' &&
78
+ hasNoDefinedKeys(value, ['options', 'native', 'web', 'minimizeBehavior', 'bottomAccessory']) &&
79
+ isCustomTabsPresentationConfig(value));
80
+ }
81
+ /*** Validate a reference into the app-owned screen registry. */
82
+ export function isNavigatorScreenReference(value) {
83
+ return isRecord(value) && hasOnlyKeys(value, ['screenId']) && typeof value.screenId === 'string';
84
+ }
85
+ /*** Check that a finite configuration object contains no unsupported keys. */
86
+ export function hasOnlyKeys(value, allowedKeys) {
87
+ const allowed = new Set(allowedKeys);
88
+ return Object.keys(value).every((key) => allowed.has(key));
89
+ }
90
+ /*** Validate JavaScript Stack options without accepting native-only presentations. */
91
+ function isJavaScriptStackScreenOptions(value) {
92
+ return (isRecord(value) &&
93
+ hasOnlyKeys(value, [
94
+ 'title',
95
+ 'headerShown',
96
+ 'headerTransparent',
97
+ 'headerBackVisible',
98
+ 'presentation',
99
+ ]) &&
100
+ isStackHeaderOptionsShape(value) &&
101
+ (value.presentation === undefined ||
102
+ (typeof value.presentation === 'string' &&
103
+ JAVASCRIPT_STACK_PRESENTATION_SET.has(value.presentation))));
104
+ }
105
+ /*** Validate the portable header subset supported by Experimental Stack. */
106
+ function isStackHeaderOptions(value) {
107
+ return (isRecord(value) &&
108
+ hasOnlyKeys(value, ['title', 'headerShown', 'headerTransparent', 'headerBackVisible']) &&
109
+ isStackHeaderOptionsShape(value));
110
+ }
111
+ /*** Validate shared stack header field values after branch-specific key filtering. */
112
+ function isStackHeaderOptionsShape(value) {
113
+ return (isOptionalString(value.title) &&
114
+ isOptionalBoolean(value.headerShown) &&
115
+ isOptionalBoolean(value.headerTransparent) &&
116
+ isOptionalBoolean(value.headerBackVisible));
117
+ }
118
+ /*** Validate sorted, finite native sheet detents or the fit-to-content sentinel. */
119
+ function isSheetAllowedDetents(value) {
120
+ if (value === 'fitToContents')
121
+ return true;
122
+ if (!Array.isArray(value) || value.length === 0)
123
+ return false;
124
+ return value.every((detent, index) => typeof detent === 'number' &&
125
+ Number.isFinite(detent) &&
126
+ detent > 0 &&
127
+ detent <= 1 &&
128
+ (index === 0 || detent > value[index - 1]));
129
+ }
130
+ /*** Validate an adaptive tabs branch and reject implementation-specific conflicts. */
131
+ function isAdaptiveTabsConfig(value) {
132
+ return (hasNoDefinedKeys(value, [
133
+ 'options',
134
+ 'presentation',
135
+ 'responsive',
136
+ 'customPresentationId',
137
+ 'minimizeBehavior',
138
+ 'bottomAccessory',
139
+ ]) &&
140
+ (value.native === undefined || isNativeTabsConfig(value.native)) &&
141
+ (value.web === undefined || isCustomTabsWebConfig(value.web)));
142
+ }
143
+ /*** Validate the top-level native tabs implementation. */
144
+ function isFullNativeTabsConfig(value) {
145
+ return (hasNoDefinedKeys(value, [
146
+ 'options',
147
+ 'native',
148
+ 'web',
149
+ 'presentation',
150
+ 'responsive',
151
+ 'customPresentationId',
152
+ ]) && isNativeTabsFields(value));
153
+ }
154
+ /*** Validate the top-level JavaScript tabs implementation. */
155
+ function isJavaScriptTabsConfig(value) {
156
+ return (hasNoDefinedKeys(value, [
157
+ 'options',
158
+ 'native',
159
+ 'web',
160
+ 'responsive',
161
+ 'customPresentationId',
162
+ 'minimizeBehavior',
163
+ 'bottomAccessory',
164
+ ]) &&
165
+ (value.presentation === undefined ||
166
+ (typeof value.presentation === 'string' &&
167
+ JAVASCRIPT_TABS_PRESENTATION_SET.has(value.presentation))));
168
+ }
169
+ /*** Validate the native branch used by adaptive tabs. */
170
+ function isNativeTabsConfig(value) {
171
+ return (isRecord(value) &&
172
+ hasOnlyKeys(value, ['implementation', 'minimizeBehavior', 'bottomAccessory']) &&
173
+ value.implementation === 'native' &&
174
+ isNativeTabsFields(value));
175
+ }
176
+ /*** Validate fields supported by the native tabs branch. */
177
+ function isNativeTabsFields(value) {
178
+ return ((value.minimizeBehavior === undefined ||
179
+ (typeof value.minimizeBehavior === 'string' &&
180
+ NATIVE_TABS_MINIMIZE_BEHAVIOR_SET.has(value.minimizeBehavior))) &&
181
+ (value.bottomAccessory === undefined || isNavigatorScreenReference(value.bottomAccessory)));
182
+ }
183
+ /*** Validate the implementation-free custom-tabs Web branch inside adaptive tabs. */
184
+ function isCustomTabsWebConfig(value) {
185
+ return (isRecord(value) &&
186
+ hasOnlyKeys(value, ['presentation', 'responsive', 'customPresentationId']) &&
187
+ isCustomTabsPresentationConfig(value));
188
+ }
189
+ /*** Validate custom-tab presentation and its conditional serializable configuration. */
190
+ function isCustomTabsPresentationConfig(value) {
191
+ if (typeof value.presentation !== 'string' ||
192
+ !CUSTOM_TABS_PRESENTATION_SET.has(value.presentation)) {
193
+ return false;
194
+ }
195
+ if (value.responsive !== undefined && !isResponsiveTabsPresentation(value.responsive)) {
196
+ return false;
197
+ }
198
+ if (!isOptionalString(value.customPresentationId))
199
+ return false;
200
+ if (FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.presentation)) {
201
+ return value.responsive === undefined && value.customPresentationId === undefined;
202
+ }
203
+ if (value.presentation === 'responsive') {
204
+ return value.responsive !== undefined && value.customPresentationId === undefined;
205
+ }
206
+ return (value.responsive === undefined &&
207
+ typeof value.customPresentationId === 'string' &&
208
+ value.customPresentationId.length > 0);
209
+ }
210
+ /*** Validate semantic compact/medium/expanded custom-tab presentation mapping. */
211
+ function isResponsiveTabsPresentation(value) {
212
+ return (isRecord(value) &&
213
+ hasOnlyKeys(value, ['compact', 'medium', 'expanded']) &&
214
+ typeof value.compact === 'string' &&
215
+ FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.compact) &&
216
+ (value.medium === undefined ||
217
+ (typeof value.medium === 'string' && FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.medium))) &&
218
+ typeof value.expanded === 'string' &&
219
+ FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.expanded));
220
+ }
221
+ /*** Check that mutually exclusive branch fields are absent. */
222
+ function hasNoDefinedKeys(value, keys) {
223
+ const prohibited = new Set(keys);
224
+ return !Object.entries(value).some(([key, entry]) => prohibited.has(key) && entry !== undefined);
225
+ }
226
+ //# sourceMappingURL=navigatorOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigatorOptions.js","sourceRoot":"","sources":["../../src/appManifest/navigatorOptions.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n CUSTOM_TABS_PRESENTATIONS,\n DRAWER_POSITIONS,\n DRAWER_TYPES,\n FIXED_CUSTOM_TABS_PRESENTATIONS,\n JAVASCRIPT_STACK_PRESENTATIONS,\n JAVASCRIPT_TABS_PRESENTATIONS,\n NATIVE_TABS_MINIMIZE_BEHAVIORS,\n STACK_PRESENTATIONS,\n} from '../navigator';\nimport { isOptionalBoolean, isOptionalString, isRecord } from './shared';\n\nconst CUSTOM_TABS_PRESENTATION_SET = new Set<string>(CUSTOM_TABS_PRESENTATIONS);\nconst DRAWER_POSITION_SET = new Set<string>(DRAWER_POSITIONS);\nconst DRAWER_TYPE_SET = new Set<string>(DRAWER_TYPES);\nconst FIXED_CUSTOM_TABS_PRESENTATION_SET = new Set<string>(FIXED_CUSTOM_TABS_PRESENTATIONS);\nconst JAVASCRIPT_STACK_PRESENTATION_SET = new Set<string>(JAVASCRIPT_STACK_PRESENTATIONS);\nconst JAVASCRIPT_TABS_PRESENTATION_SET = new Set<string>(JAVASCRIPT_TABS_PRESENTATIONS);\nconst NATIVE_TABS_MINIMIZE_BEHAVIOR_SET = new Set<string>(NATIVE_TABS_MINIMIZE_BEHAVIORS);\nconst STACK_PRESENTATION_SET = new Set<string>(STACK_PRESENTATIONS);\n\n/*** Validate stable native, JavaScript, or alpha Experimental Stack desired state. */\nexport function isStackImplementationConfig(value: Record<string, unknown>): boolean {\n if (\n !hasNoDefinedKeys(value, [\n 'native',\n 'web',\n 'presentation',\n 'responsive',\n 'customPresentationId',\n 'minimizeBehavior',\n 'bottomAccessory',\n ])\n ) {\n return false;\n }\n if (value.implementation === undefined || value.implementation === 'native') {\n return value.options === undefined || isStackScreenOptions(value.options);\n }\n if (value.implementation === 'javascript') {\n return value.options === undefined || isJavaScriptStackScreenOptions(value.options);\n }\n return (\n value.implementation === 'experimental' &&\n (value.options === undefined || isStackHeaderOptions(value.options))\n );\n}\n\n/*** Validate the serializable native-stack screen option subset. */\nexport function isStackScreenOptions(value: unknown): boolean {\n if (\n !isRecord(value) ||\n !hasOnlyKeys(value, [\n 'title',\n 'headerShown',\n 'headerTransparent',\n 'headerBackVisible',\n 'presentation',\n 'sheetAllowedDetents',\n 'sheetGrabberVisible',\n ]) ||\n !isStackHeaderOptionsShape(value) ||\n (value.presentation !== undefined &&\n (typeof value.presentation !== 'string' || !STACK_PRESENTATION_SET.has(value.presentation)))\n ) {\n return false;\n }\n\n if (value.presentation !== 'formSheet') {\n return value.sheetAllowedDetents === undefined && value.sheetGrabberVisible === undefined;\n }\n return (\n (value.sheetAllowedDetents === undefined || isSheetAllowedDetents(value.sheetAllowedDetents)) &&\n isOptionalBoolean(value.sheetGrabberVisible)\n );\n}\n\n/*** Validate the finite serializable Drawer option subset. */\nexport function isDrawerNavigatorOptions(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['drawerPosition', 'drawerType', 'swipeEnabled', 'headerShown']) &&\n (value.drawerPosition === undefined ||\n (typeof value.drawerPosition === 'string' &&\n DRAWER_POSITION_SET.has(value.drawerPosition))) &&\n (value.drawerType === undefined ||\n (typeof value.drawerType === 'string' && DRAWER_TYPE_SET.has(value.drawerType))) &&\n isOptionalBoolean(value.swipeEnabled) &&\n isOptionalBoolean(value.headerShown)\n );\n}\n\n/*** Validate tabs implementation desired state, with omitted implementation meaning adaptive. */\nexport function isTabsImplementationConfig(value: Record<string, unknown>): boolean {\n if (value.implementation === undefined || value.implementation === 'adaptive') {\n return isAdaptiveTabsConfig(value);\n }\n if (value.implementation === 'native') return isFullNativeTabsConfig(value);\n if (value.implementation === 'javascript') return isJavaScriptTabsConfig(value);\n return (\n value.implementation === 'custom' &&\n hasNoDefinedKeys(value, ['options', 'native', 'web', 'minimizeBehavior', 'bottomAccessory']) &&\n isCustomTabsPresentationConfig(value)\n );\n}\n\n/*** Validate a reference into the app-owned screen registry. */\nexport function isNavigatorScreenReference(value: unknown): boolean {\n return isRecord(value) && hasOnlyKeys(value, ['screenId']) && typeof value.screenId === 'string';\n}\n\n/*** Check that a finite configuration object contains no unsupported keys. */\nexport function hasOnlyKeys(\n value: Record<string, unknown>,\n allowedKeys: readonly string[],\n): boolean {\n const allowed = new Set(allowedKeys);\n return Object.keys(value).every((key) => allowed.has(key));\n}\n\n/*** Validate JavaScript Stack options without accepting native-only presentations. */\nfunction isJavaScriptStackScreenOptions(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, [\n 'title',\n 'headerShown',\n 'headerTransparent',\n 'headerBackVisible',\n 'presentation',\n ]) &&\n isStackHeaderOptionsShape(value) &&\n (value.presentation === undefined ||\n (typeof value.presentation === 'string' &&\n JAVASCRIPT_STACK_PRESENTATION_SET.has(value.presentation)))\n );\n}\n\n/*** Validate the portable header subset supported by Experimental Stack. */\nfunction isStackHeaderOptions(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['title', 'headerShown', 'headerTransparent', 'headerBackVisible']) &&\n isStackHeaderOptionsShape(value)\n );\n}\n\n/*** Validate shared stack header field values after branch-specific key filtering. */\nfunction isStackHeaderOptionsShape(value: Record<string, unknown>): boolean {\n return (\n isOptionalString(value.title) &&\n isOptionalBoolean(value.headerShown) &&\n isOptionalBoolean(value.headerTransparent) &&\n isOptionalBoolean(value.headerBackVisible)\n );\n}\n\n/*** Validate sorted, finite native sheet detents or the fit-to-content sentinel. */\nfunction isSheetAllowedDetents(value: unknown): boolean {\n if (value === 'fitToContents') return true;\n if (!Array.isArray(value) || value.length === 0) return false;\n return value.every(\n (detent, index) =>\n typeof detent === 'number' &&\n Number.isFinite(detent) &&\n detent > 0 &&\n detent <= 1 &&\n (index === 0 || detent > value[index - 1]),\n );\n}\n\n/*** Validate an adaptive tabs branch and reject implementation-specific conflicts. */\nfunction isAdaptiveTabsConfig(value: Record<string, unknown>): boolean {\n return (\n hasNoDefinedKeys(value, [\n 'options',\n 'presentation',\n 'responsive',\n 'customPresentationId',\n 'minimizeBehavior',\n 'bottomAccessory',\n ]) &&\n (value.native === undefined || isNativeTabsConfig(value.native)) &&\n (value.web === undefined || isCustomTabsWebConfig(value.web))\n );\n}\n\n/*** Validate the top-level native tabs implementation. */\nfunction isFullNativeTabsConfig(value: Record<string, unknown>): boolean {\n return (\n hasNoDefinedKeys(value, [\n 'options',\n 'native',\n 'web',\n 'presentation',\n 'responsive',\n 'customPresentationId',\n ]) && isNativeTabsFields(value)\n );\n}\n\n/*** Validate the top-level JavaScript tabs implementation. */\nfunction isJavaScriptTabsConfig(value: Record<string, unknown>): boolean {\n return (\n hasNoDefinedKeys(value, [\n 'options',\n 'native',\n 'web',\n 'responsive',\n 'customPresentationId',\n 'minimizeBehavior',\n 'bottomAccessory',\n ]) &&\n (value.presentation === undefined ||\n (typeof value.presentation === 'string' &&\n JAVASCRIPT_TABS_PRESENTATION_SET.has(value.presentation)))\n );\n}\n\n/*** Validate the native branch used by adaptive tabs. */\nfunction isNativeTabsConfig(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['implementation', 'minimizeBehavior', 'bottomAccessory']) &&\n value.implementation === 'native' &&\n isNativeTabsFields(value)\n );\n}\n\n/*** Validate fields supported by the native tabs branch. */\nfunction isNativeTabsFields(value: Record<string, unknown>): boolean {\n return (\n (value.minimizeBehavior === undefined ||\n (typeof value.minimizeBehavior === 'string' &&\n NATIVE_TABS_MINIMIZE_BEHAVIOR_SET.has(value.minimizeBehavior))) &&\n (value.bottomAccessory === undefined || isNavigatorScreenReference(value.bottomAccessory))\n );\n}\n\n/*** Validate the implementation-free custom-tabs Web branch inside adaptive tabs. */\nfunction isCustomTabsWebConfig(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['presentation', 'responsive', 'customPresentationId']) &&\n isCustomTabsPresentationConfig(value)\n );\n}\n\n/*** Validate custom-tab presentation and its conditional serializable configuration. */\nfunction isCustomTabsPresentationConfig(value: Record<string, unknown>): boolean {\n if (\n typeof value.presentation !== 'string' ||\n !CUSTOM_TABS_PRESENTATION_SET.has(value.presentation)\n ) {\n return false;\n }\n if (value.responsive !== undefined && !isResponsiveTabsPresentation(value.responsive)) {\n return false;\n }\n if (!isOptionalString(value.customPresentationId)) return false;\n if (FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.presentation)) {\n return value.responsive === undefined && value.customPresentationId === undefined;\n }\n if (value.presentation === 'responsive') {\n return value.responsive !== undefined && value.customPresentationId === undefined;\n }\n return (\n value.responsive === undefined &&\n typeof value.customPresentationId === 'string' &&\n value.customPresentationId.length > 0\n );\n}\n\n/*** Validate semantic compact/medium/expanded custom-tab presentation mapping. */\nfunction isResponsiveTabsPresentation(value: unknown): boolean {\n return (\n isRecord(value) &&\n hasOnlyKeys(value, ['compact', 'medium', 'expanded']) &&\n typeof value.compact === 'string' &&\n FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.compact) &&\n (value.medium === undefined ||\n (typeof value.medium === 'string' && FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.medium))) &&\n typeof value.expanded === 'string' &&\n FIXED_CUSTOM_TABS_PRESENTATION_SET.has(value.expanded)\n );\n}\n\n/*** Check that mutually exclusive branch fields are absent. */\nfunction hasNoDefinedKeys(value: Record<string, unknown>, keys: readonly string[]): boolean {\n const prohibited = new Set(keys);\n return !Object.entries(value).some(([key, entry]) => prohibited.has(key) && entry !== undefined);\n}\n"]}
@@ -1,7 +1,6 @@
1
+ export { isAppNavigatorManifest } from './navigator';
1
2
  export declare function isManifestMetadata(value: unknown): boolean;
2
3
  export declare function isThemeConfig(value: unknown): boolean;
3
- /*** Validate the complete serialized `AppManifest.navigator` slice. */
4
- export declare function isAppNavigatorManifest(value: unknown): boolean;
5
4
  export declare function isScreenRegistry(value: unknown): boolean;
6
5
  export declare function isSplashScreenSpec(value: unknown): boolean;
7
6
  //# sourceMappingURL=screens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screens.d.ts","sourceRoot":"","sources":["../../src/appManifest/screens.ts"],"names":[],"mappings":"AA6BA,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAY1D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAU9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAM1D"}
1
+ {"version":3,"file":"screens.d.ts","sourceRoot":"","sources":["../../src/appManifest/screens.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAMrD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAY1D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAM1D"}