@ankhorage/contracts 11.1.0 → 12.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/appManifest/navigator.js +1 -7
- package/dist/appManifest/navigator.js.map +1 -1
- package/dist/appManifest/navigatorOptions.js +18 -17
- package/dist/appManifest/navigatorOptions.js.map +1 -1
- package/dist/navigator/catalog.d.ts +42 -0
- package/dist/navigator/catalog.d.ts.map +1 -0
- package/dist/navigator/catalog.js +2 -0
- package/dist/navigator/catalog.js.map +1 -0
- package/dist/navigator/generation.d.ts +14 -4
- package/dist/navigator/generation.d.ts.map +1 -1
- package/dist/navigator/generation.js.map +1 -1
- package/dist/navigator/planning.d.ts +9 -9
- package/dist/navigator/planning.d.ts.map +1 -1
- package/dist/navigator/planning.js.map +1 -1
- package/dist/navigator.d.ts +20 -24
- package/dist/navigator.d.ts.map +1 -1
- package/dist/navigator.js +9 -9
- package/dist/navigator.js.map +1 -1
- package/package.json +2 -2
- package/src/appManifest/navigator.ts +1 -10
- package/src/appManifest/navigatorOptions.ts +19 -18
- package/src/navigator/catalog.ts +79 -0
- package/src/navigator/generation.ts +22 -4
- package/src/navigator/planning.ts +10 -9
- package/src/navigator-runtime-contracts.test.ts +54 -3
- package/src/navigator-validation.test.ts +31 -4
- package/src/navigator.test.ts +37 -16
- package/src/navigator.ts +39 -30
package/src/navigator.test.ts
CHANGED
|
@@ -23,7 +23,6 @@ function createAdaptiveTabs(): AppNavigatorManifest {
|
|
|
23
23
|
expanded: 'sidebar',
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
|
-
flows: { onboarding: true },
|
|
27
26
|
routes: [{ name: 'home', path: '/', screenId: 'home' }],
|
|
28
27
|
};
|
|
29
28
|
}
|
|
@@ -85,11 +84,24 @@ const VALID_NAVIGATOR_NODES = [
|
|
|
85
84
|
describe('app navigator manifest topology', () => {
|
|
86
85
|
it('keeps canonical topology presets finite and authorable', () => {
|
|
87
86
|
expect(NAVIGATOR_TYPES).toEqual(['slot', 'stack', 'tabs', 'drawer', 'split-view', 'custom']);
|
|
88
|
-
expect(NAVIGATOR_PRESETS).
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
expect(NAVIGATOR_PRESETS).toEqual([
|
|
88
|
+
'slot',
|
|
89
|
+
'stack',
|
|
90
|
+
'tabs',
|
|
91
|
+
'tabs-stack',
|
|
92
|
+
'stack-tabs',
|
|
93
|
+
'stack-tabs-stack',
|
|
94
|
+
'drawer',
|
|
95
|
+
'drawer-stack',
|
|
96
|
+
'stack-drawer',
|
|
97
|
+
'stack-drawer-stack',
|
|
98
|
+
'drawer-tabs',
|
|
99
|
+
'drawer-tabs-stack',
|
|
100
|
+
'stack-drawer-tabs',
|
|
101
|
+
'stack-drawer-tabs-stack',
|
|
102
|
+
'split-view',
|
|
103
|
+
'custom',
|
|
104
|
+
]);
|
|
93
105
|
});
|
|
94
106
|
|
|
95
107
|
it('accepts adaptive native/Web tabs with responsive custom presentation', () => {
|
|
@@ -152,12 +164,12 @@ describe('app navigator manifest node variants', () => {
|
|
|
152
164
|
});
|
|
153
165
|
});
|
|
154
166
|
|
|
155
|
-
describe('app navigator manifest
|
|
167
|
+
describe('app navigator manifest headless presentation', () => {
|
|
156
168
|
it('accepts fixed and registered custom Web presentations', () => {
|
|
157
169
|
expect(
|
|
158
170
|
isAppNavigatorManifest({
|
|
159
171
|
type: 'tabs',
|
|
160
|
-
implementation: '
|
|
172
|
+
implementation: 'headless',
|
|
161
173
|
presentation: 'sidebar',
|
|
162
174
|
routes: [],
|
|
163
175
|
}),
|
|
@@ -166,7 +178,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
166
178
|
expect(
|
|
167
179
|
isAppNavigatorManifest({
|
|
168
180
|
type: 'tabs',
|
|
169
|
-
implementation: '
|
|
181
|
+
implementation: 'headless',
|
|
170
182
|
presentation: 'custom',
|
|
171
183
|
customPresentationId: 'workspace-tabs',
|
|
172
184
|
routes: [],
|
|
@@ -178,7 +190,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
178
190
|
expect(
|
|
179
191
|
isAppNavigatorManifest({
|
|
180
192
|
type: 'tabs',
|
|
181
|
-
implementation: '
|
|
193
|
+
implementation: 'headless',
|
|
182
194
|
presentation: 'responsive',
|
|
183
195
|
routes: [],
|
|
184
196
|
}),
|
|
@@ -187,7 +199,7 @@ describe('app navigator manifest custom presentation', () => {
|
|
|
187
199
|
expect(
|
|
188
200
|
isAppNavigatorManifest({
|
|
189
201
|
type: 'tabs',
|
|
190
|
-
implementation: '
|
|
202
|
+
implementation: 'headless',
|
|
191
203
|
presentation: 'custom',
|
|
192
204
|
routes: [],
|
|
193
205
|
}),
|
|
@@ -219,7 +231,7 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
219
231
|
expect(
|
|
220
232
|
isAppNavigatorManifest({
|
|
221
233
|
type: 'tabs',
|
|
222
|
-
implementation: '
|
|
234
|
+
implementation: 'headless',
|
|
223
235
|
presentation: 'sidebar',
|
|
224
236
|
customPresentationId: 'must-not-apply',
|
|
225
237
|
routes: [],
|
|
@@ -229,7 +241,7 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
229
241
|
expect(
|
|
230
242
|
isAppNavigatorManifest({
|
|
231
243
|
type: 'tabs',
|
|
232
|
-
implementation: '
|
|
244
|
+
implementation: 'headless',
|
|
233
245
|
presentation: 'custom',
|
|
234
246
|
customPresentationId: 'workspace-tabs',
|
|
235
247
|
responsive: { compact: 'bottom', expanded: 'sidebar' },
|
|
@@ -240,14 +252,21 @@ describe('app navigator manifest tabs branch validation', () => {
|
|
|
240
252
|
});
|
|
241
253
|
|
|
242
254
|
describe('app navigator manifest composition', () => {
|
|
243
|
-
it('
|
|
255
|
+
it('expresses app-owned sequences as ordinary guarded navigator branches', () => {
|
|
244
256
|
expect(
|
|
245
257
|
isAppNavigatorManifest({
|
|
246
258
|
type: 'stack',
|
|
247
|
-
flows: { authentication: true },
|
|
248
259
|
routes: [
|
|
249
260
|
{
|
|
250
|
-
name: '
|
|
261
|
+
name: 'entry',
|
|
262
|
+
navigator: {
|
|
263
|
+
type: 'stack',
|
|
264
|
+
routes: [{ name: 'step', screenId: 'step' }],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'main',
|
|
269
|
+
guards: ['entry-complete'],
|
|
251
270
|
navigator: {
|
|
252
271
|
type: 'tabs',
|
|
253
272
|
routes: [{ name: 'home', screenId: 'home' }],
|
|
@@ -257,7 +276,9 @@ describe('app navigator manifest composition', () => {
|
|
|
257
276
|
}),
|
|
258
277
|
).toBe(true);
|
|
259
278
|
});
|
|
279
|
+
});
|
|
260
280
|
|
|
281
|
+
describe('app navigator manifest route metadata', () => {
|
|
261
282
|
it('preserves authored route names, labels, paths, guards, and visibility without inference', () => {
|
|
262
283
|
const navigator = {
|
|
263
284
|
type: 'stack',
|
package/src/navigator.ts
CHANGED
|
@@ -8,16 +8,16 @@ export const NAVIGATOR_PRESETS = [
|
|
|
8
8
|
'stack',
|
|
9
9
|
'tabs',
|
|
10
10
|
'tabs-stack',
|
|
11
|
+
'stack-tabs',
|
|
12
|
+
'stack-tabs-stack',
|
|
11
13
|
'drawer',
|
|
12
14
|
'drawer-stack',
|
|
15
|
+
'stack-drawer',
|
|
16
|
+
'stack-drawer-stack',
|
|
13
17
|
'drawer-tabs',
|
|
14
18
|
'drawer-tabs-stack',
|
|
15
|
-
'
|
|
16
|
-
'
|
|
17
|
-
'root-stack-drawer',
|
|
18
|
-
'root-stack-drawer-stack',
|
|
19
|
-
'root-stack-drawer-tabs',
|
|
20
|
-
'root-stack-drawer-tabs-stack',
|
|
19
|
+
'stack-drawer-tabs',
|
|
20
|
+
'stack-drawer-tabs-stack',
|
|
21
21
|
'split-view',
|
|
22
22
|
'custom',
|
|
23
23
|
] as const;
|
|
@@ -94,15 +94,15 @@ export interface DrawerNavigatorOptions {
|
|
|
94
94
|
headerShown?: boolean;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export const
|
|
98
|
-
export type
|
|
97
|
+
export const FIXED_HEADLESS_TABS_PRESENTATIONS = ['bottom', 'top', 'rail', 'sidebar'] as const;
|
|
98
|
+
export type FixedHeadlessTabsPresentation = (typeof FIXED_HEADLESS_TABS_PRESENTATIONS)[number];
|
|
99
99
|
|
|
100
|
-
export const
|
|
101
|
-
...
|
|
100
|
+
export const HEADLESS_TABS_PRESENTATIONS = [
|
|
101
|
+
...FIXED_HEADLESS_TABS_PRESENTATIONS,
|
|
102
102
|
'responsive',
|
|
103
103
|
'custom',
|
|
104
104
|
] as const;
|
|
105
|
-
export type
|
|
105
|
+
export type HeadlessTabsPresentation = (typeof HEADLESS_TABS_PRESENTATIONS)[number];
|
|
106
106
|
|
|
107
107
|
export const JAVASCRIPT_TABS_PRESENTATIONS = ['bottom', 'top'] as const;
|
|
108
108
|
export type JavaScriptTabsPresentation = (typeof JAVASCRIPT_TABS_PRESENTATIONS)[number];
|
|
@@ -116,14 +116,14 @@ export const NATIVE_TABS_MINIMIZE_BEHAVIORS = [
|
|
|
116
116
|
export type NativeTabsMinimizeBehavior = (typeof NATIVE_TABS_MINIMIZE_BEHAVIORS)[number];
|
|
117
117
|
|
|
118
118
|
export interface ResponsiveTabsPresentation {
|
|
119
|
-
compact:
|
|
120
|
-
medium?:
|
|
121
|
-
expanded:
|
|
119
|
+
compact: FixedHeadlessTabsPresentation;
|
|
120
|
+
medium?: FixedHeadlessTabsPresentation;
|
|
121
|
+
expanded: FixedHeadlessTabsPresentation;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
export type
|
|
124
|
+
export type HeadlessTabsPresentationConfig =
|
|
125
125
|
| {
|
|
126
|
-
presentation:
|
|
126
|
+
presentation: FixedHeadlessTabsPresentation;
|
|
127
127
|
responsive?: never;
|
|
128
128
|
customPresentationId?: never;
|
|
129
129
|
}
|
|
@@ -139,11 +139,11 @@ export type CustomTabsPresentationConfig =
|
|
|
139
139
|
customPresentationId: string;
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
-
export type
|
|
143
|
-
implementation: '
|
|
144
|
-
} &
|
|
142
|
+
export type HeadlessTabsConfig = {
|
|
143
|
+
implementation: 'headless';
|
|
144
|
+
} & HeadlessTabsPresentationConfig;
|
|
145
145
|
|
|
146
|
-
export type
|
|
146
|
+
export type HeadlessTabsWebConfig = HeadlessTabsPresentationConfig;
|
|
147
147
|
|
|
148
148
|
export interface NavigatorScreenReference {
|
|
149
149
|
screenId: string;
|
|
@@ -167,12 +167,12 @@ export interface AdaptiveTabsConfig {
|
|
|
167
167
|
implementation?: 'adaptive';
|
|
168
168
|
/** Android/iOS branch. Expo Router may expose this implementation as unstable. */
|
|
169
169
|
native?: NativeTabsConfig;
|
|
170
|
-
/** Web branch rendered through headless
|
|
171
|
-
web?:
|
|
170
|
+
/** Web branch rendered through headless tabs. */
|
|
171
|
+
web?: HeadlessTabsWebConfig;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
export type TabsImplementationConfig =
|
|
175
|
-
AdaptiveTabsConfig |
|
|
175
|
+
AdaptiveTabsConfig | HeadlessTabsConfig | JavaScriptTabsConfig | NativeTabsConfig;
|
|
176
176
|
|
|
177
177
|
interface NavigatorNodeBase {
|
|
178
178
|
initialRouteName?: string;
|
|
@@ -237,11 +237,6 @@ export interface RouteDefinition {
|
|
|
237
237
|
navigator?: NavigatorNode;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
-
export interface NavigatorFlows {
|
|
241
|
-
onboarding?: boolean;
|
|
242
|
-
authentication?: boolean;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
240
|
export interface NavigatorDefaults {
|
|
246
241
|
tabs?: TabsImplementationConfig;
|
|
247
242
|
stack?: StackImplementationConfig;
|
|
@@ -266,20 +261,33 @@ export interface NavigatorPlatforms {
|
|
|
266
261
|
*/
|
|
267
262
|
export type AppNavigatorManifest = NavigatorNode & {
|
|
268
263
|
preset?: NavigatorPreset;
|
|
269
|
-
flows?: NavigatorFlows;
|
|
270
264
|
defaults?: NavigatorDefaults;
|
|
271
265
|
platforms?: NavigatorPlatforms;
|
|
272
266
|
};
|
|
273
267
|
|
|
268
|
+
export type {
|
|
269
|
+
NavigatorCapabilityDescriptor,
|
|
270
|
+
NavigatorCapabilityRequirement,
|
|
271
|
+
NavigatorCapabilityTarget,
|
|
272
|
+
NavigatorCapabilityVerification,
|
|
273
|
+
NavigatorCatalog,
|
|
274
|
+
NavigatorImplementation,
|
|
275
|
+
NavigatorPresentation,
|
|
276
|
+
NavigatorPresetDescriptor,
|
|
277
|
+
NavigatorVerificationKind,
|
|
278
|
+
NavigatorVerificationStatus,
|
|
279
|
+
} from './navigator/catalog';
|
|
274
280
|
export type {
|
|
275
281
|
CustomNavigatorConfigIssue,
|
|
276
282
|
CustomNavigatorRegistration,
|
|
277
283
|
CustomNavigatorRegistry,
|
|
278
284
|
} from './navigator/extensions';
|
|
279
285
|
export type {
|
|
286
|
+
NavigatorDependencyRequirement,
|
|
280
287
|
NavigatorGeneratedFile,
|
|
281
288
|
NavigatorGenerationBindings,
|
|
282
289
|
NavigatorGenerationOptions,
|
|
290
|
+
NavigatorGenerationResult,
|
|
283
291
|
NavigatorScreenModule,
|
|
284
292
|
} from './navigator/generation';
|
|
285
293
|
export type {
|
|
@@ -288,6 +296,7 @@ export type {
|
|
|
288
296
|
NavigatorAdapterId,
|
|
289
297
|
NavigatorAdapterPlan,
|
|
290
298
|
NavigatorApiStability,
|
|
299
|
+
NavigatorCapabilityId,
|
|
291
300
|
NavigatorDiagnostic,
|
|
292
301
|
NavigatorNodePlan,
|
|
293
302
|
NavigatorPlan,
|
|
@@ -296,7 +305,7 @@ export type {
|
|
|
296
305
|
NavigatorRuntimePlatform,
|
|
297
306
|
NavigatorSupportStatus,
|
|
298
307
|
NavigatorValidationContext,
|
|
299
|
-
|
|
308
|
+
ResolvedHeadlessTabsPresentation,
|
|
300
309
|
ResolvedTabsImplementation,
|
|
301
310
|
ResolvedTabsPresentation,
|
|
302
311
|
TabsNavigatorPlan,
|