@teardown/navigation-metro 2.0.52 → 2.0.56

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 (38) hide show
  1. package/dist/generator/index.d.ts +5 -0
  2. package/dist/generator/index.d.ts.map +1 -0
  3. package/dist/generator/index.js +12 -0
  4. package/dist/generator/route-generator.d.ts +37 -0
  5. package/dist/generator/route-generator.d.ts.map +1 -0
  6. package/dist/generator/route-generator.js +179 -0
  7. package/dist/index.d.ts +83 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +103 -0
  10. package/dist/scanner/file-scanner.d.ts +62 -0
  11. package/dist/scanner/file-scanner.d.ts.map +1 -0
  12. package/dist/scanner/file-scanner.js +250 -0
  13. package/dist/scanner/index.d.ts +5 -0
  14. package/dist/scanner/index.d.ts.map +1 -0
  15. package/dist/scanner/index.js +12 -0
  16. package/{src/validator/index.ts → dist/validator/index.d.ts} +1 -1
  17. package/dist/validator/index.d.ts.map +1 -0
  18. package/dist/validator/index.js +8 -0
  19. package/dist/validator/route-validator.d.ts +15 -0
  20. package/dist/validator/route-validator.d.ts.map +1 -0
  21. package/dist/validator/route-validator.js +153 -0
  22. package/dist/watcher/file-watcher.d.ts +27 -0
  23. package/dist/watcher/file-watcher.d.ts.map +1 -0
  24. package/dist/watcher/file-watcher.js +110 -0
  25. package/{src/watcher/index.ts → dist/watcher/index.d.ts} +1 -1
  26. package/dist/watcher/index.d.ts.map +1 -0
  27. package/dist/watcher/index.js +10 -0
  28. package/package.json +12 -9
  29. package/src/generator/index.ts +0 -13
  30. package/src/generator/route-generator.test.ts +0 -287
  31. package/src/generator/route-generator.ts +0 -231
  32. package/src/index.ts +0 -158
  33. package/src/scanner/file-scanner.test.ts +0 -271
  34. package/src/scanner/file-scanner.ts +0 -329
  35. package/src/scanner/index.ts +0 -15
  36. package/src/validator/route-validator.test.ts +0 -192
  37. package/src/validator/route-validator.ts +0 -178
  38. package/src/watcher/file-watcher.ts +0 -132
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generator module for @teardown/navigation-metro
3
+ */
4
+ export { buildRouteParamsInterface, type GenerateOptions, generateAllRouteFiles, generateLinkingFileContent, generateRegisterFileContent, generateRoutesFileContent, type RouteParamEntry, } from "./route-generator";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACN,yBAAyB,EACzB,KAAK,eAAe,EACpB,qBAAqB,EACrB,0BAA0B,EAC1B,2BAA2B,EAC3B,yBAAyB,EACzB,KAAK,eAAe,GACpB,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /**
3
+ * Generator module for @teardown/navigation-metro
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateRoutesFileContent = exports.generateRegisterFileContent = exports.generateLinkingFileContent = exports.generateAllRouteFiles = exports.buildRouteParamsInterface = void 0;
7
+ var route_generator_1 = require("./route-generator");
8
+ Object.defineProperty(exports, "buildRouteParamsInterface", { enumerable: true, get: function () { return route_generator_1.buildRouteParamsInterface; } });
9
+ Object.defineProperty(exports, "generateAllRouteFiles", { enumerable: true, get: function () { return route_generator_1.generateAllRouteFiles; } });
10
+ Object.defineProperty(exports, "generateLinkingFileContent", { enumerable: true, get: function () { return route_generator_1.generateLinkingFileContent; } });
11
+ Object.defineProperty(exports, "generateRegisterFileContent", { enumerable: true, get: function () { return route_generator_1.generateRegisterFileContent; } });
12
+ Object.defineProperty(exports, "generateRoutesFileContent", { enumerable: true, get: function () { return route_generator_1.generateRoutesFileContent; } });
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Route generator for @teardown/navigation-metro
3
+ * Generates TypeScript type definitions from scanned route tree
4
+ */
5
+ import { type ParamDefinition, type RouteNode } from "../scanner/file-scanner";
6
+ export interface GenerateOptions {
7
+ routesDir: string;
8
+ generatedDir: string;
9
+ prefixes: string[];
10
+ verbose: boolean;
11
+ }
12
+ export interface RouteParamEntry {
13
+ path: string;
14
+ params: ParamDefinition[];
15
+ }
16
+ /**
17
+ * Generates all route files (routes.generated.ts, linking.generated.ts, register.d.ts, manifest.json)
18
+ */
19
+ export declare function generateAllRouteFiles(options: GenerateOptions): void;
20
+ /**
21
+ * Builds the RouteParams interface entries from the route tree
22
+ * Each route has all its params extracted from its full path, so no accumulation needed
23
+ */
24
+ export declare function buildRouteParamsInterface(routes: RouteNode[]): RouteParamEntry[];
25
+ /**
26
+ * Generates the routes.generated.ts file content
27
+ */
28
+ export declare function generateRoutesFileContent(routes: RouteNode[]): string;
29
+ /**
30
+ * Generates the linking.generated.ts file content
31
+ */
32
+ export declare function generateLinkingFileContent(routes: RouteNode[], prefixes: string[]): string;
33
+ /**
34
+ * Generates the register.d.ts file content
35
+ */
36
+ export declare function generateRegisterFileContent(): string;
37
+ //# sourceMappingURL=route-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-generator.d.ts","sourceRoot":"","sources":["../../src/generator/route-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAiB,KAAK,eAAe,EAAE,KAAK,SAAS,EAAuB,MAAM,yBAAyB,CAAC;AAEnH,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CA8BpE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,eAAe,EAAE,CAwBhF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAgDrE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAkC1F;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAepD"}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ /**
3
+ * Route generator for @teardown/navigation-metro
4
+ * Generates TypeScript type definitions from scanned route tree
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.generateAllRouteFiles = generateAllRouteFiles;
8
+ exports.buildRouteParamsInterface = buildRouteParamsInterface;
9
+ exports.generateRoutesFileContent = generateRoutesFileContent;
10
+ exports.generateLinkingFileContent = generateLinkingFileContent;
11
+ exports.generateRegisterFileContent = generateRegisterFileContent;
12
+ const node_fs_1 = require("node:fs");
13
+ const node_path_1 = require("node:path");
14
+ const file_scanner_1 = require("../scanner/file-scanner");
15
+ /**
16
+ * Generates all route files (routes.generated.ts, linking.generated.ts, register.d.ts, manifest.json)
17
+ */
18
+ function generateAllRouteFiles(options) {
19
+ const { routesDir, generatedDir, prefixes, verbose } = options;
20
+ // Ensure generated directory exists
21
+ (0, node_fs_1.mkdirSync)(generatedDir, { recursive: true });
22
+ // Scan routes
23
+ const { routes, errors } = (0, file_scanner_1.scanRoutesDirectory)(routesDir);
24
+ if (errors.length > 0 && verbose) {
25
+ console.warn("[teardown/navigation] Scan warnings:", errors);
26
+ }
27
+ // Generate files
28
+ const routesContent = generateRoutesFileContent(routes);
29
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(generatedDir, "routes.generated.ts"), routesContent);
30
+ const linkingContent = generateLinkingFileContent(routes, prefixes);
31
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(generatedDir, "linking.generated.ts"), linkingContent);
32
+ const registerContent = generateRegisterFileContent();
33
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(generatedDir, "register.d.ts"), registerContent);
34
+ const manifestContent = generateManifestContent(routes);
35
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(generatedDir, "manifest.json"), JSON.stringify(manifestContent, null, 2));
36
+ if (verbose) {
37
+ const count = countRoutes(routes);
38
+ console.log(`[teardown/navigation] Generated ${count} routes`);
39
+ }
40
+ }
41
+ /**
42
+ * Builds the RouteParams interface entries from the route tree
43
+ * Each route has all its params extracted from its full path, so no accumulation needed
44
+ */
45
+ function buildRouteParamsInterface(routes) {
46
+ const result = [];
47
+ function traverse(nodes) {
48
+ for (const node of nodes) {
49
+ if (node.isLayout) {
50
+ // Layouts don't get their own route entry
51
+ traverse(node.children);
52
+ continue;
53
+ }
54
+ result.push({
55
+ path: node.path,
56
+ params: node.params,
57
+ });
58
+ if (node.children.length > 0) {
59
+ traverse(node.children);
60
+ }
61
+ }
62
+ }
63
+ traverse(routes);
64
+ return result;
65
+ }
66
+ /**
67
+ * Generates the routes.generated.ts file content
68
+ */
69
+ function generateRoutesFileContent(routes) {
70
+ const routeParams = buildRouteParamsInterface(routes);
71
+ const lines = [
72
+ "// Auto-generated by @teardown/navigation",
73
+ "// Do not edit this file directly",
74
+ `// Generated at: ${new Date().toISOString()}`,
75
+ "",
76
+ "export interface RouteParams {",
77
+ ];
78
+ // Add route param entries
79
+ for (const { path, params } of routeParams) {
80
+ const paramsType = params.length === 0
81
+ ? "undefined"
82
+ : `{ ${params
83
+ .map((p) => {
84
+ const type = p.isCatchAll ? "string[]" : "string";
85
+ return `${p.name}${p.isOptional ? "?" : ""}: ${type}`;
86
+ })
87
+ .join("; ")} }`;
88
+ lines.push(`\t"${path}": ${paramsType};`);
89
+ }
90
+ lines.push("}");
91
+ lines.push("");
92
+ // Add type aliases
93
+ lines.push("export type RoutePath = keyof RouteParams;");
94
+ lines.push("");
95
+ lines.push("export type ParamsFor<T extends RoutePath> = RouteParams[T];");
96
+ lines.push("");
97
+ // Add RouteWithParams utility type
98
+ lines.push("export type RouteWithParams = {");
99
+ lines.push("\t[K in RoutePath]: RouteParams[K] extends undefined");
100
+ lines.push("\t\t? { path: K }");
101
+ lines.push("\t\t: { path: K; params: RouteParams[K] };");
102
+ lines.push("}[RoutePath];");
103
+ lines.push("");
104
+ // Add NavigatorType
105
+ lines.push('export type NavigatorType = "stack" | "tabs" | "drawer";');
106
+ lines.push("");
107
+ return lines.join("\n");
108
+ }
109
+ /**
110
+ * Generates the linking.generated.ts file content
111
+ */
112
+ function generateLinkingFileContent(routes, prefixes) {
113
+ const routeParams = buildRouteParamsInterface(routes);
114
+ const lines = [
115
+ "// Auto-generated by @teardown/navigation",
116
+ 'import type { LinkingOptions } from "@react-navigation/native";',
117
+ 'import type { RouteParams } from "./routes.generated";',
118
+ "",
119
+ ];
120
+ // Build screens config
121
+ const screens = {};
122
+ for (const { path } of routeParams) {
123
+ // Convert /users/:userId to users/:userId (remove leading slash)
124
+ const linkingPath = path === "/" ? "" : path.slice(1);
125
+ screens[path] = linkingPath;
126
+ }
127
+ lines.push('export const generatedLinkingConfig: LinkingOptions<RouteParams>["config"] = {');
128
+ lines.push("\tscreens: {");
129
+ for (const [routePath, linkingPath] of Object.entries(screens)) {
130
+ lines.push(`\t\t"${routePath}": "${linkingPath}",`);
131
+ }
132
+ lines.push("\t},");
133
+ lines.push("};");
134
+ lines.push("");
135
+ // Add prefixes
136
+ lines.push(`export const defaultPrefixes: string[] = ${JSON.stringify(prefixes)};`);
137
+ lines.push("");
138
+ return lines.join("\n");
139
+ }
140
+ /**
141
+ * Generates the register.d.ts file content
142
+ */
143
+ function generateRegisterFileContent() {
144
+ const lines = [
145
+ "// Auto-generated by @teardown/navigation",
146
+ 'import type { RouteParams, RoutePath } from "./routes.generated";',
147
+ "",
148
+ "declare module '@teardown/navigation' {",
149
+ "\tinterface Register {",
150
+ "\t\trouteParams: RouteParams;",
151
+ "\t\troutePath: RoutePath;",
152
+ "\t}",
153
+ "}",
154
+ "",
155
+ ];
156
+ return lines.join("\n");
157
+ }
158
+ /**
159
+ * Generates the manifest.json content
160
+ */
161
+ function generateManifestContent(routes) {
162
+ const allRoutes = (0, file_scanner_1.flattenRoutes)(routes);
163
+ return {
164
+ generatedAt: new Date().toISOString(),
165
+ routeCount: allRoutes.filter((r) => !r.isLayout).length,
166
+ routes: allRoutes.map((r) => ({
167
+ path: r.path,
168
+ file: r.relativePath,
169
+ params: r.params,
170
+ layoutType: r.layoutType,
171
+ })),
172
+ };
173
+ }
174
+ /**
175
+ * Counts the number of non-layout routes
176
+ */
177
+ function countRoutes(routes) {
178
+ return (0, file_scanner_1.flattenRoutes)(routes).filter((r) => !r.isLayout).length;
179
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @teardown/navigation-metro
3
+ * Metro plugin for type-safe file-based navigation
4
+ */
5
+ /**
6
+ * Options for the Teardown Navigation Metro plugin
7
+ */
8
+ export interface TeardownNavigationOptions {
9
+ /**
10
+ * Path to routes directory relative to project root
11
+ * @default './src/routes'
12
+ */
13
+ routesDir?: string;
14
+ /**
15
+ * Path for generated type files
16
+ * @default './.teardown'
17
+ */
18
+ generatedDir?: string;
19
+ /**
20
+ * Deep link URL prefixes
21
+ * @default []
22
+ */
23
+ prefixes?: string[];
24
+ /**
25
+ * Enable verbose logging
26
+ * @default false
27
+ */
28
+ verbose?: boolean;
29
+ }
30
+ /**
31
+ * Metro configuration type (simplified)
32
+ * Full type from metro-config can be used if available
33
+ */
34
+ export interface MetroConfig {
35
+ projectRoot?: string;
36
+ watchFolders?: string[];
37
+ resolver?: {
38
+ resolveRequest?: (context: unknown, moduleName: string, platform: string | null) => {
39
+ filePath: string;
40
+ type: string;
41
+ } | null;
42
+ [key: string]: unknown;
43
+ };
44
+ transformer?: {
45
+ unstable_allowRequireContext?: boolean;
46
+ [key: string]: unknown;
47
+ };
48
+ [key: string]: unknown;
49
+ }
50
+ /**
51
+ * Wraps a Metro configuration with Teardown Navigation support
52
+ *
53
+ * This function:
54
+ * 1. Generates TypeScript type definitions on startup
55
+ * 2. Watches for route file changes in development
56
+ * 3. Configures Metro to include generated files
57
+ *
58
+ * @example
59
+ * ```js
60
+ * // metro.config.js
61
+ * const { getDefaultConfig } = require('expo/metro-config');
62
+ * const { withTeardownNavigation } = require('@teardown/navigation-metro');
63
+ *
64
+ * const config = getDefaultConfig(__dirname);
65
+ *
66
+ * module.exports = withTeardownNavigation(config, {
67
+ * routesDir: './src/routes',
68
+ * generatedDir: './.teardown',
69
+ * prefixes: ['myapp://', 'https://myapp.com'],
70
+ * verbose: true,
71
+ * });
72
+ * ```
73
+ */
74
+ export declare function withTeardownNavigation(config: MetroConfig, options?: TeardownNavigationOptions): MetroConfig;
75
+ export type { GenerateOptions, RouteParamEntry } from "./generator/route-generator";
76
+ export { generateAllRouteFiles } from "./generator/route-generator";
77
+ export type { ParamDefinition, RouteNode, ScanError, ScanResult } from "./scanner/file-scanner";
78
+ export { buildUrlPath, extractParams, filePathToScreenName, flattenRoutes, scanRoutesDirectory, } from "./scanner/file-scanner";
79
+ export type { ValidationError } from "./validator/route-validator";
80
+ export { validateRoutes } from "./validator/route-validator";
81
+ export type { WatcherOptions } from "./watcher/file-watcher";
82
+ export { isWatcherRunning, startRouteWatcher, stopRouteWatcher } from "./watcher/file-watcher";
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACzC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE;QACV,cAAc,CAAC,EAAE,CAChB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,KACnB;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAC/C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,WAAW,CAAC,EAAE;QACb,4BAA4B,CAAC,EAAE,OAAO,CAAC;QACvC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACvB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,yBAA8B,GAAG,WAAW,CAyDhH;AAED,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEpF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,EACN,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,mBAAmB,GACnB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * @teardown/navigation-metro
4
+ * Metro plugin for type-safe file-based navigation
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.stopRouteWatcher = exports.startRouteWatcher = exports.isWatcherRunning = exports.validateRoutes = exports.scanRoutesDirectory = exports.flattenRoutes = exports.filePathToScreenName = exports.extractParams = exports.buildUrlPath = exports.generateAllRouteFiles = void 0;
8
+ exports.withTeardownNavigation = withTeardownNavigation;
9
+ const node_path_1 = require("node:path");
10
+ const route_generator_1 = require("./generator/route-generator");
11
+ const file_watcher_1 = require("./watcher/file-watcher");
12
+ /**
13
+ * Wraps a Metro configuration with Teardown Navigation support
14
+ *
15
+ * This function:
16
+ * 1. Generates TypeScript type definitions on startup
17
+ * 2. Watches for route file changes in development
18
+ * 3. Configures Metro to include generated files
19
+ *
20
+ * @example
21
+ * ```js
22
+ * // metro.config.js
23
+ * const { getDefaultConfig } = require('expo/metro-config');
24
+ * const { withTeardownNavigation } = require('@teardown/navigation-metro');
25
+ *
26
+ * const config = getDefaultConfig(__dirname);
27
+ *
28
+ * module.exports = withTeardownNavigation(config, {
29
+ * routesDir: './src/routes',
30
+ * generatedDir: './.teardown',
31
+ * prefixes: ['myapp://', 'https://myapp.com'],
32
+ * verbose: true,
33
+ * });
34
+ * ```
35
+ */
36
+ function withTeardownNavigation(config, options = {}) {
37
+ const { routesDir = "./src/routes", generatedDir = "./.teardown", prefixes = [], verbose = false } = options;
38
+ const projectRoot = config.projectRoot ?? process.cwd();
39
+ const absoluteRoutesDir = (0, node_path_1.resolve)(projectRoot, routesDir);
40
+ const absoluteGeneratedDir = (0, node_path_1.resolve)(projectRoot, generatedDir);
41
+ // Generate types on startup
42
+ try {
43
+ (0, route_generator_1.generateAllRouteFiles)({
44
+ routesDir: absoluteRoutesDir,
45
+ generatedDir: absoluteGeneratedDir,
46
+ prefixes,
47
+ verbose,
48
+ });
49
+ if (verbose) {
50
+ console.log("[teardown/navigation] Initial generation complete");
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.error("[teardown/navigation] Initial generation failed:", error);
55
+ }
56
+ // Start file watcher in development
57
+ if (process.env.NODE_ENV !== "production") {
58
+ (0, file_watcher_1.startRouteWatcher)({
59
+ routesDir: absoluteRoutesDir,
60
+ generatedDir: absoluteGeneratedDir,
61
+ prefixes,
62
+ verbose,
63
+ onRegenerate: () => {
64
+ if (verbose) {
65
+ console.log("[teardown/navigation] Routes regenerated");
66
+ }
67
+ },
68
+ onError: (_errors) => {
69
+ if (verbose) {
70
+ console.error("[teardown/navigation] Validation errors during watch");
71
+ }
72
+ },
73
+ });
74
+ }
75
+ // Add watch folders for Metro
76
+ const watchFolders = [...(config.watchFolders ?? []), absoluteRoutesDir, absoluteGeneratedDir];
77
+ return {
78
+ ...config,
79
+ watchFolders,
80
+ transformer: {
81
+ ...config.transformer,
82
+ unstable_allowRequireContext: true,
83
+ },
84
+ resolver: {
85
+ ...config.resolver,
86
+ },
87
+ };
88
+ }
89
+ // Re-export modules
90
+ var route_generator_2 = require("./generator/route-generator");
91
+ Object.defineProperty(exports, "generateAllRouteFiles", { enumerable: true, get: function () { return route_generator_2.generateAllRouteFiles; } });
92
+ var file_scanner_1 = require("./scanner/file-scanner");
93
+ Object.defineProperty(exports, "buildUrlPath", { enumerable: true, get: function () { return file_scanner_1.buildUrlPath; } });
94
+ Object.defineProperty(exports, "extractParams", { enumerable: true, get: function () { return file_scanner_1.extractParams; } });
95
+ Object.defineProperty(exports, "filePathToScreenName", { enumerable: true, get: function () { return file_scanner_1.filePathToScreenName; } });
96
+ Object.defineProperty(exports, "flattenRoutes", { enumerable: true, get: function () { return file_scanner_1.flattenRoutes; } });
97
+ Object.defineProperty(exports, "scanRoutesDirectory", { enumerable: true, get: function () { return file_scanner_1.scanRoutesDirectory; } });
98
+ var route_validator_1 = require("./validator/route-validator");
99
+ Object.defineProperty(exports, "validateRoutes", { enumerable: true, get: function () { return route_validator_1.validateRoutes; } });
100
+ var file_watcher_2 = require("./watcher/file-watcher");
101
+ Object.defineProperty(exports, "isWatcherRunning", { enumerable: true, get: function () { return file_watcher_2.isWatcherRunning; } });
102
+ Object.defineProperty(exports, "startRouteWatcher", { enumerable: true, get: function () { return file_watcher_2.startRouteWatcher; } });
103
+ Object.defineProperty(exports, "stopRouteWatcher", { enumerable: true, get: function () { return file_watcher_2.stopRouteWatcher; } });
@@ -0,0 +1,62 @@
1
+ /**
2
+ * File scanner for @teardown/navigation-metro
3
+ * Scans routes directory and builds a route tree for type generation
4
+ */
5
+ export interface RouteNode {
6
+ /** Screen name derived from file path */
7
+ name: string;
8
+ /** URL path for this route */
9
+ path: string;
10
+ /** Absolute file path */
11
+ filePath: string;
12
+ /** Relative file path from routes dir */
13
+ relativePath: string;
14
+ /** Extracted dynamic params */
15
+ params: ParamDefinition[];
16
+ /** Child routes */
17
+ children: RouteNode[];
18
+ /** Navigator type from _layout.tsx */
19
+ layoutType: "stack" | "tabs" | "drawer" | "none";
20
+ /** Is this an index route */
21
+ isIndex: boolean;
22
+ /** Is this a layout file */
23
+ isLayout: boolean;
24
+ /** Is this a catch-all route */
25
+ isCatchAll: boolean;
26
+ /** Route group name (from parentheses) */
27
+ groupName: string | null;
28
+ }
29
+ export interface ParamDefinition {
30
+ name: string;
31
+ isOptional: boolean;
32
+ isCatchAll: boolean;
33
+ }
34
+ export interface ScanResult {
35
+ routes: RouteNode[];
36
+ errors: ScanError[];
37
+ }
38
+ export interface ScanError {
39
+ file: string;
40
+ message: string;
41
+ }
42
+ /**
43
+ * Scans a routes directory and builds a route tree
44
+ */
45
+ export declare function scanRoutesDirectory(routesDir: string): ScanResult;
46
+ /**
47
+ * Extracts dynamic parameters from a filename
48
+ */
49
+ export declare function extractParams(fileName: string): ParamDefinition[];
50
+ /**
51
+ * Builds a URL path from a relative file path
52
+ */
53
+ export declare function buildUrlPath(relativePath: string, _isIndex: boolean, isLayout: boolean): string;
54
+ /**
55
+ * Converts a file path to a screen name
56
+ */
57
+ export declare function filePathToScreenName(relativePath: string): string;
58
+ /**
59
+ * Flattens a route tree into a flat array
60
+ */
61
+ export declare function flattenRoutes(routes: RouteNode[]): RouteNode[];
62
+ //# sourceMappingURL=file-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-scanner.d.ts","sourceRoot":"","sources":["../../src/scanner/file-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,SAAS;IACzB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,mBAAmB;IACnB,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,sCAAsC;IACtC,UAAU,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;IACjD,6BAA6B;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,gCAAgC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAwCjE;AAkFD;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAkBjE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CAmB/F;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAGjE;AAsFD;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAY9D"}