@ankhorage/contracts 11.0.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +1 -1
  3. package/dist/appManifest/navigator.js +1 -7
  4. package/dist/appManifest/navigator.js.map +1 -1
  5. package/dist/appManifest/navigatorOptions.js +18 -17
  6. package/dist/appManifest/navigatorOptions.js.map +1 -1
  7. package/dist/navigator/catalog.d.ts +42 -0
  8. package/dist/navigator/catalog.d.ts.map +1 -0
  9. package/dist/navigator/catalog.js +2 -0
  10. package/dist/navigator/catalog.js.map +1 -0
  11. package/dist/navigator/extensions.d.ts +23 -0
  12. package/dist/navigator/extensions.d.ts.map +1 -0
  13. package/dist/navigator/extensions.js +2 -0
  14. package/dist/navigator/extensions.js.map +1 -0
  15. package/dist/navigator/generation.d.ts +36 -0
  16. package/dist/navigator/generation.d.ts.map +1 -0
  17. package/dist/navigator/generation.js +2 -0
  18. package/dist/navigator/generation.js.map +1 -0
  19. package/dist/navigator/planning.d.ts +105 -0
  20. package/dist/navigator/planning.d.ts.map +1 -0
  21. package/dist/navigator/planning.js +2 -0
  22. package/dist/navigator/planning.js.map +1 -0
  23. package/dist/navigator.d.ts +21 -23
  24. package/dist/navigator.d.ts.map +1 -1
  25. package/dist/navigator.js +9 -9
  26. package/dist/navigator.js.map +1 -1
  27. package/package.json +4 -4
  28. package/src/appManifest/navigator.ts +1 -10
  29. package/src/appManifest/navigatorOptions.ts +19 -18
  30. package/src/navigator/catalog.ts +79 -0
  31. package/src/navigator/extensions.ts +26 -0
  32. package/src/navigator/generation.ts +46 -0
  33. package/src/navigator/planning.ts +147 -0
  34. package/src/navigator-runtime-contracts.test.ts +104 -0
  35. package/src/navigator-validation.test.ts +31 -4
  36. package/src/navigator.test.ts +37 -16
  37. package/src/navigator.ts +69 -29
@@ -0,0 +1,147 @@
1
+ import type {
2
+ CustomNavigatorNode,
3
+ DrawerNavigatorOptions,
4
+ NavigatorType,
5
+ RouteDefinition,
6
+ StackImplementation,
7
+ StackScreenOptions,
8
+ } from '../navigator';
9
+ import type { CustomNavigatorRegistry } from './extensions';
10
+ import type { NavigatorDependencyRequirement } from './generation';
11
+
12
+ export interface ResolvedHeadlessTabsPresentation {
13
+ presentation: ResolvedTabsPresentation;
14
+ customPresentationId?: string;
15
+ }
16
+
17
+ export type ResolvedTabsImplementation = 'headless' | 'javascript' | 'native';
18
+
19
+ export type ResolvedTabsPresentation = 'bottom' | 'top' | 'rail' | 'sidebar' | 'custom';
20
+
21
+ /**
22
+ * Disposable adapter plan for a `tabs` topology.
23
+ *
24
+ * The implementation selects the Router runtime. Presentation only selects its visual chrome and
25
+ * never creates another route topology.
26
+ */
27
+ export interface TabsNavigatorPlan {
28
+ implementation: ResolvedTabsImplementation;
29
+ module: ExpoRouterNavigatorModule;
30
+ exportName: string;
31
+ stability: NavigatorApiStability;
32
+ presentation?: ResolvedTabsPresentation;
33
+ presentations?: Readonly<Record<NavigatorResponsiveSize, ResolvedTabsPresentation>>;
34
+ customPresentationId?: string;
35
+ minimizeBehavior?: 'automatic' | 'never' | 'onScrollDown' | 'onScrollUp';
36
+ bottomAccessoryScreenId?: string;
37
+ }
38
+
39
+ export interface CreateNavigatorPlanOptions {
40
+ platform: NavigatorRuntimePlatform;
41
+ expoRouterVersion: string;
42
+ responsiveSize?: NavigatorResponsiveSize;
43
+ customNavigators?: CustomNavigatorRegistry;
44
+ }
45
+
46
+ export type ExpoRouterNavigatorModule =
47
+ | 'expo-router'
48
+ | 'expo-router/drawer'
49
+ | 'expo-router/js-stack'
50
+ | 'expo-router/js-tabs'
51
+ | 'expo-router/js-top-tabs'
52
+ | 'expo-router/ui'
53
+ | 'expo-router/unstable-split-view'
54
+ | 'expo-router/unstable-native-tabs';
55
+
56
+ export type NavigatorAdapterId =
57
+ | 'slot'
58
+ | 'stack.native'
59
+ | 'stack.javascript'
60
+ | 'stack.experimental'
61
+ | 'drawer'
62
+ | 'tabs.native'
63
+ | 'tabs.javascript'
64
+ | 'tabs.headless'
65
+ | 'split-view'
66
+ | 'custom';
67
+
68
+ export interface NavigatorAdapterPlan {
69
+ id: NavigatorAdapterId;
70
+ /** Built-in Expo Router entry point or an explicitly registered custom module. */
71
+ module?: string;
72
+ exportName?: string;
73
+ support: NavigatorSupportStatus;
74
+ stability: NavigatorApiStability;
75
+ limitations: readonly string[];
76
+ }
77
+
78
+ export type NavigatorApiStability = 'stable' | 'alpha';
79
+
80
+ export type NavigatorCapabilityId = string;
81
+
82
+ export interface NavigatorDiagnostic {
83
+ code: string;
84
+ severity: 'error' | 'warning';
85
+ path: string;
86
+ message: string;
87
+ }
88
+
89
+ export interface NavigatorNodePlan {
90
+ type: NavigatorType;
91
+ pointer: string;
92
+ adapter: NavigatorAdapterPlan;
93
+ initialRouteName?: string;
94
+ routes: readonly NavigatorRoutePlan[];
95
+ stack?: {
96
+ implementation: StackImplementation;
97
+ options?: StackScreenOptions;
98
+ };
99
+ drawer?: {
100
+ options?: DrawerNavigatorOptions;
101
+ };
102
+ tabs?: TabsNavigatorPlan;
103
+ splitView?: {
104
+ columns: {
105
+ primary: string;
106
+ supplementary?: string;
107
+ };
108
+ inspector?: string;
109
+ topColumnForCollapsing?: 'primary' | 'secondary' | 'supplementary';
110
+ };
111
+ custom?: {
112
+ navigatorId: string;
113
+ config?: CustomNavigatorNode['config'];
114
+ };
115
+ }
116
+
117
+ export interface NavigatorPlan {
118
+ context: NavigatorValidationContext;
119
+ root: NavigatorNodePlan;
120
+ diagnostics: readonly NavigatorDiagnostic[];
121
+ support: NavigatorSupportStatus;
122
+ capabilityIds: readonly NavigatorCapabilityId[];
123
+ dependencies: readonly NavigatorDependencyRequirement[];
124
+ }
125
+
126
+ export type NavigatorResponsiveSize = 'compact' | 'medium' | 'expanded';
127
+
128
+ export interface NavigatorRoutePlan {
129
+ name: string;
130
+ path?: string;
131
+ label?: string;
132
+ icon?: RouteDefinition['icon'];
133
+ showInPrimaryNavigation?: boolean;
134
+ guards: readonly string[];
135
+ screenId?: string;
136
+ stackOptions?: StackScreenOptions;
137
+ navigator?: NavigatorNodePlan;
138
+ }
139
+
140
+ export type NavigatorRuntimePlatform = 'android' | 'ios' | 'web';
141
+
142
+ export type NavigatorSupportStatus = 'supported' | 'testing-only' | 'unsupported';
143
+
144
+ export interface NavigatorValidationContext {
145
+ platform: NavigatorRuntimePlatform;
146
+ expoRouterVersion: string;
147
+ }
@@ -0,0 +1,104 @@
1
+ import { expect, test } from 'bun:test';
2
+
3
+ import type {
4
+ CustomNavigatorRegistration,
5
+ NavigatorCatalog,
6
+ NavigatorGeneratedFile,
7
+ NavigatorGenerationBindings,
8
+ NavigatorGenerationResult,
9
+ NavigatorPlan,
10
+ } from './navigator';
11
+
12
+ test('keeps generation bindings and plan output portable across package boundaries', () => {
13
+ const bindings: NavigatorGenerationBindings = {
14
+ screens: { home: { module: '@/screens/Home', exportName: 'Home' } },
15
+ guards: {},
16
+ };
17
+ const file: NavigatorGeneratedFile = {
18
+ path: 'src/app/index.tsx',
19
+ contents: 'export default Home;',
20
+ };
21
+ const plan: NavigatorPlan = {
22
+ context: { platform: 'web', expoRouterVersion: '57.0.18' },
23
+ root: {
24
+ type: 'slot',
25
+ pointer: '',
26
+ adapter: {
27
+ id: 'slot',
28
+ module: 'expo-router',
29
+ exportName: 'Slot',
30
+ support: 'supported',
31
+ stability: 'stable',
32
+ limitations: [],
33
+ },
34
+ routes: [],
35
+ },
36
+ diagnostics: [],
37
+ support: 'supported',
38
+ capabilityIds: ['slot'],
39
+ dependencies: [],
40
+ };
41
+ const result: NavigatorGenerationResult = {
42
+ support: plan.support,
43
+ capabilityIds: plan.capabilityIds,
44
+ dependencies: plan.dependencies,
45
+ diagnostics: plan.diagnostics,
46
+ plan,
47
+ files: [file],
48
+ };
49
+ expect(JSON.parse(JSON.stringify({ bindings, result }))).toEqual({ bindings, result });
50
+ });
51
+
52
+ test('separates capability taxonomy, target support, stability, and verification', () => {
53
+ const catalog: NavigatorCatalog = {
54
+ capabilities: [
55
+ {
56
+ id: 'tabs.headless.sidebar',
57
+ topology: 'tabs',
58
+ implementation: 'headless',
59
+ presentation: 'sidebar',
60
+ stability: 'stable',
61
+ targets: [
62
+ {
63
+ platform: 'web',
64
+ support: 'supported',
65
+ verification: [{ kind: 'browser', status: 'verified' }],
66
+ },
67
+ {
68
+ platform: 'ios',
69
+ support: 'testing-only',
70
+ verification: [{ kind: 'device', status: 'unverified' }],
71
+ },
72
+ ],
73
+ dependencies: [],
74
+ requirements: [],
75
+ incompatibilities: [],
76
+ limitations: [],
77
+ },
78
+ ],
79
+ presets: [
80
+ {
81
+ id: 'drawer',
82
+ description: 'Drawer as the root navigator with direct routes.',
83
+ topology: ['drawer'],
84
+ },
85
+ ],
86
+ };
87
+
88
+ expect(catalog.capabilities[0]?.targets[1]?.support).toBe('testing-only');
89
+ expect(catalog.presets[0]?.topology).toEqual(['drawer']);
90
+ });
91
+
92
+ test('describes a custom extension without importing Navigator or a UI runtime', () => {
93
+ const registration: CustomNavigatorRegistration = {
94
+ id: 'example',
95
+ platforms: ['web'],
96
+ stability: 'stable',
97
+ integration: 'expo-router-standard',
98
+ router: 'stack',
99
+ module: '@example/navigation',
100
+ exportName: 'ExampleNavigator',
101
+ validateConfig: () => [],
102
+ };
103
+ expect(registration.validateConfig({ mode: 'compact' })).toEqual([]);
104
+ });
@@ -6,7 +6,7 @@ import { describe, expect, it } from 'bun:test';
6
6
  import { isAppNavigatorManifest } from './appManifest/screens';
7
7
  import type {
8
8
  CustomNavigatorNode,
9
- CustomTabsConfig,
9
+ HeadlessTabsConfig,
10
10
  NavigatorNode,
11
11
  StackImplementationConfig,
12
12
  } from './navigator';
@@ -20,9 +20,9 @@ describe('app navigator manifest type discrimination', () => {
20
20
  implementation: 'experimental',
21
21
  options: { presentation: 'modal' },
22
22
  };
23
- // @ts-expect-error Fixed custom tabs do not accept a registered custom presentation id.
24
- const tabs: CustomTabsConfig = {
25
- implementation: 'custom',
23
+ // @ts-expect-error Fixed headless tabs do not accept a registered custom presentation id.
24
+ const tabs: HeadlessTabsConfig = {
25
+ implementation: 'headless',
26
26
  presentation: 'sidebar',
27
27
  customPresentationId: 'workspace-tabs',
28
28
  };
@@ -70,6 +70,33 @@ describe('app navigator manifest stack validation', () => {
70
70
  });
71
71
  });
72
72
 
73
+ describe('app navigator manifest removed fields', () => {
74
+ it('rejects flow metadata and the superseded custom Tabs implementation', () => {
75
+ expect(
76
+ isAppNavigatorManifest({
77
+ type: 'stack',
78
+ flows: { onboarding: true },
79
+ routes: [],
80
+ }),
81
+ ).toBe(false);
82
+ expect(
83
+ isAppNavigatorManifest({
84
+ type: 'tabs',
85
+ implementation: 'custom',
86
+ presentation: 'bottom',
87
+ routes: [],
88
+ }),
89
+ ).toBe(false);
90
+ expect(
91
+ isAppNavigatorManifest({
92
+ type: 'stack',
93
+ preset: 'root-stack-tabs',
94
+ routes: [],
95
+ }),
96
+ ).toBe(false);
97
+ });
98
+ });
99
+
73
100
  describe('app navigator manifest sheet validation', () => {
74
101
  it('validates native form-sheet detents and their presentation discriminant', () => {
75
102
  for (const sheetAllowedDetents of [[], [0.8, 0.4], [0.4, 0.4], [0], [1.1], [Number.NaN]]) {
@@ -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,7 +261,52 @@ 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
  };
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';
280
+ export type {
281
+ CustomNavigatorConfigIssue,
282
+ CustomNavigatorRegistration,
283
+ CustomNavigatorRegistry,
284
+ } from './navigator/extensions';
285
+ export type {
286
+ NavigatorDependencyRequirement,
287
+ NavigatorGeneratedFile,
288
+ NavigatorGenerationBindings,
289
+ NavigatorGenerationOptions,
290
+ NavigatorGenerationResult,
291
+ NavigatorScreenModule,
292
+ } from './navigator/generation';
293
+ export type {
294
+ CreateNavigatorPlanOptions,
295
+ ExpoRouterNavigatorModule,
296
+ NavigatorAdapterId,
297
+ NavigatorAdapterPlan,
298
+ NavigatorApiStability,
299
+ NavigatorCapabilityId,
300
+ NavigatorDiagnostic,
301
+ NavigatorNodePlan,
302
+ NavigatorPlan,
303
+ NavigatorResponsiveSize,
304
+ NavigatorRoutePlan,
305
+ NavigatorRuntimePlatform,
306
+ NavigatorSupportStatus,
307
+ NavigatorValidationContext,
308
+ ResolvedHeadlessTabsPresentation,
309
+ ResolvedTabsImplementation,
310
+ ResolvedTabsPresentation,
311
+ TabsNavigatorPlan,
312
+ } from './navigator/planning';