@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.
@@ -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).toContain('slot');
89
- expect(NAVIGATOR_PRESETS).toContain('split-view');
90
- expect(NAVIGATOR_PRESETS).toContain('custom');
91
- expect(NAVIGATOR_PRESETS).toContain('root-stack-tabs-stack');
92
- expect(NAVIGATOR_PRESETS).toContain('root-stack-drawer-tabs-stack');
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 custom presentation', () => {
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: 'custom',
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: 'custom',
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: 'custom',
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: 'custom',
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: 'custom',
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: 'custom',
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('keeps nested topology separate from app-level flow metadata', () => {
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: 'app',
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
- 'root-stack-tabs',
16
- 'root-stack-tabs-stack',
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 FIXED_CUSTOM_TABS_PRESENTATIONS = ['bottom', 'top', 'rail', 'sidebar'] as const;
98
- export type FixedCustomTabsPresentation = (typeof FIXED_CUSTOM_TABS_PRESENTATIONS)[number];
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 CUSTOM_TABS_PRESENTATIONS = [
101
- ...FIXED_CUSTOM_TABS_PRESENTATIONS,
100
+ export const HEADLESS_TABS_PRESENTATIONS = [
101
+ ...FIXED_HEADLESS_TABS_PRESENTATIONS,
102
102
  'responsive',
103
103
  'custom',
104
104
  ] as const;
105
- export type CustomTabsPresentation = (typeof CUSTOM_TABS_PRESENTATIONS)[number];
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: FixedCustomTabsPresentation;
120
- medium?: FixedCustomTabsPresentation;
121
- expanded: FixedCustomTabsPresentation;
119
+ compact: FixedHeadlessTabsPresentation;
120
+ medium?: FixedHeadlessTabsPresentation;
121
+ expanded: FixedHeadlessTabsPresentation;
122
122
  }
123
123
 
124
- export type CustomTabsPresentationConfig =
124
+ export type HeadlessTabsPresentationConfig =
125
125
  | {
126
- presentation: FixedCustomTabsPresentation;
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 CustomTabsConfig = {
143
- implementation: 'custom';
144
- } & CustomTabsPresentationConfig;
142
+ export type HeadlessTabsConfig = {
143
+ implementation: 'headless';
144
+ } & HeadlessTabsPresentationConfig;
145
145
 
146
- export type CustomTabsWebConfig = CustomTabsPresentationConfig;
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 custom tabs. */
171
- web?: CustomTabsWebConfig;
170
+ /** Web branch rendered through headless tabs. */
171
+ web?: HeadlessTabsWebConfig;
172
172
  }
173
173
 
174
174
  export type TabsImplementationConfig =
175
- AdaptiveTabsConfig | CustomTabsConfig | JavaScriptTabsConfig | NativeTabsConfig;
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
- ResolvedCustomTabsPresentation,
308
+ ResolvedHeadlessTabsPresentation,
300
309
  ResolvedTabsImplementation,
301
310
  ResolvedTabsPresentation,
302
311
  TabsNavigatorPlan,