ts-file-router 1.0.5 → 2.0.1

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/README.md CHANGED
@@ -7,12 +7,12 @@ Automatically scans folders and outputs a clean, structured `routes.ts` tree rea
7
7
 
8
8
  ## âœĻ Features
9
9
 
10
- - 🔍 Recursive folder scanning
11
- - 📄 Auto-generated `routes.ts` (TypeScript code, no `resolveJsonModule` required)
12
- - ⚛ïļ Works perfectly with `React.lazy()` and dynamic imports
13
- - 📘 Full TypeScript `.d.ts` definitions included
14
- - ðŸ§Đ Custom route file name (default: `page.ts`)
15
- - ðŸŠķ Zero runtime dependencies
10
+ - 🔍 Recursive folder scanning
11
+ - 📄 Auto-generated `routes.ts` (TypeScript code, no `resolveJsonModule` required)
12
+ - ⚛ïļ Works perfectly with `React.lazy()` and dynamic imports
13
+ - 📘 Full TypeScript `.d.ts` definitions included
14
+ - ðŸ§Đ Custom route file name (default: `page.ts`)
15
+ - ðŸŠķ Zero runtime dependencies
16
16
  - ðŸŽŊ Clean, formatted output with readable keys
17
17
 
18
18
  ---
@@ -23,3 +23,34 @@ Automatically scans folders and outputs a clean, structured `routes.ts` tree rea
23
23
  npm install ts-file-router
24
24
  # or
25
25
  yarn add ts-file-router
26
+
27
+ ```
28
+
29
+ ---
30
+
31
+ ## ðŸŽŊ Usage
32
+
33
+ Create a script to generate your routes. Example:
34
+
35
+ ```js
36
+ // scripts/generate-routes.mjs
37
+ import { generateRoutes } from 'ts-file-router';
38
+
39
+ generateRoutes({
40
+ baseFolder: 'src/screens',
41
+ outputFile: 'src/screens/routes.ts',
42
+ routeFileName: 'page.tsx',
43
+ });
44
+ ```
45
+
46
+ ## What this does
47
+
48
+ - baseFolder: Root directory where your screens/pages live
49
+
50
+ - routeFileName: File that represents a route (e.g. page.tsx)
51
+
52
+ - outputFile: Generated routes file (fully typed)
53
+
54
+ Run the script with:
55
+
56
+ node scripts/generate-routes.mjs
@@ -1,3 +1,3 @@
1
- import { TStartConfigs } from './types';
2
- export declare const start: ({ baseFolder, outputFile, routeFileName, }: TStartConfigs) => void;
1
+ import { TGenerateRoutesConfig } from './types';
2
+ export declare const generateRoutes: ({ baseFolder, outputFile, routeFileName, }: TGenerateRoutesConfig) => void;
3
3
  //# sourceMappingURL=file-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../src/file-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAe,MAAM,SAAS,CAAC;AA+BrD,eAAO,MAAM,KAAK,GAAI,4CAInB,aAAa,SAsEf,CAAC"}
1
+ {"version":3,"file":"file-router.d.ts","sourceRoot":"","sources":["../src/file-router.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAG7D,eAAO,MAAM,cAAc,GAAI,4CAI5B,qBAAqB,SAiFvB,CAAC"}
@@ -3,37 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.start = void 0;
7
- const path_1 = __importDefault(require("path"));
6
+ exports.generateRoutes = void 0;
8
7
  const promises_1 = __importDefault(require("fs/promises"));
9
- // Serialize routes objects to TS file output
10
- const serializeRoutes = (obj, ident = 2) => {
11
- const pad = ' '.repeat(ident);
12
- let str = '{\n';
13
- for (const key in obj) {
14
- const value = obj[key];
15
- // Manipulate JS keys
16
- const keyStr = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`;
17
- if (typeof value === 'object' &&
18
- value !== null &&
19
- !('path' in value && 'import' in value)) {
20
- // Create sub folders
21
- str += `${pad}${keyStr}: ${serializeRoutes(value, ident + 2)},\n`;
22
- }
23
- else {
24
- // Routes
25
- str += `${pad}${keyStr}: { path: "${value.path}", import: "${value.import}" },\n`;
26
- }
27
- }
28
- str += ' '.repeat(ident - 2) + '}';
29
- return str;
30
- };
31
- const start = ({ baseFolder, outputFile, routeFileName = 'page.tsx', }) => {
8
+ const path_1 = __importDefault(require("path"));
9
+ const utils_1 = require("./utils");
10
+ const generateRoutes = ({ baseFolder, outputFile, routeFileName = 'page.tsx', }) => {
32
11
  // Get the pages dir to resolve routes
33
12
  const basePath = path_1.default.resolve(process.cwd(), baseFolder);
34
13
  // Output file for routes
35
- const output = path_1.default.resolve(process.cwd(), outputFile);
36
- const generateRouter = async () => {
14
+ const output = path_1.default.resolve(basePath, outputFile);
15
+ const createRoutes = async () => {
37
16
  const mapRoutes = async (dir) => {
38
17
  const routes = {};
39
18
  const directory = await promises_1.default.readdir(dir);
@@ -41,12 +20,18 @@ const start = ({ baseFolder, outputFile, routeFileName = 'page.tsx', }) => {
41
20
  throw new Error(`Invalid pages structure: The folder "${dir}" must contain a ${routeFileName} file.`);
42
21
  }
43
22
  for (const file of directory) {
23
+ // ignore index files, underscore marked, or route file generated
24
+ if (file.includes('index') ||
25
+ file.startsWith('_') ||
26
+ file.includes(outputFile)) {
27
+ continue;
28
+ }
44
29
  const fullPath = path_1.default.join(dir, file);
45
30
  // Get directory info to control file or folder
46
31
  const dirInfo = await promises_1.default.stat(fullPath);
47
32
  // Normalize import path to esm pattern
48
33
  const importPath = './' + path_1.default.relative(basePath, fullPath).replaceAll(/\\/g, '/');
49
- const relativePath = './' + path_1.default.relative(basePath, dir).replaceAll(/\\/g, '/');
34
+ const relativePath = '/' + path_1.default.relative(basePath, dir).replaceAll(/\\/g, '/');
50
35
  // Remove extension from file to naming the route
51
36
  const key = path_1.default.basename(file, path_1.default.extname(file));
52
37
  if (dirInfo.isDirectory()) {
@@ -57,6 +42,8 @@ const start = ({ baseFolder, outputFile, routeFileName = 'page.tsx', }) => {
57
42
  // Skip this directory iteration
58
43
  continue;
59
44
  }
45
+ // Mount the route object with path like "/folder" and import
46
+ // import will be like "(./baseFolder/file or ./baseFolder/folders).extension"
60
47
  routes[key] = {
61
48
  path: relativePath,
62
49
  import: importPath,
@@ -67,18 +54,23 @@ const start = ({ baseFolder, outputFile, routeFileName = 'page.tsx', }) => {
67
54
  try {
68
55
  // Create routes
69
56
  const routes = await mapRoutes(basePath);
57
+ // Serialize object to typescript format
58
+ const ts = (0, utils_1.serializeTs)(routes);
70
59
  // Cria arquivo TS exportando JSON
71
- const tsContent = `// AUTO-GENERATED ROUTES\n\nconst routes = ${serializeRoutes(routes)};\n\nexport default routes;\n`;
60
+ const tsContent = `// GENERATED-ROUTES-FROM-TS-FILE-ROUTER\n\nexport const routes = ${ts};\n`;
72
61
  // Write .ts file
73
62
  await promises_1.default.writeFile(output, tsContent, 'utf-8');
63
+ // Promise writeFile was successfully resolved
74
64
  console.log('🚀 Routes generated successfully!\n', output);
65
+ // Code 0 to finish the process as success
75
66
  process.exit(0);
76
67
  }
77
68
  catch (err) {
78
69
  console.error('❌ Error generating routes:', err);
70
+ // Code 1 to finish the process as error
79
71
  process.exit(1);
80
72
  }
81
73
  };
82
- generateRouter();
74
+ createRoutes();
83
75
  };
84
- exports.start = start;
76
+ exports.generateRoutes = generateRoutes;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { start } from './file-router';
2
- export * from './types';
1
+ export { generateRoutes } from './file-router';
2
+ export { TGenerateRoutesConfig } from './types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,20 +1,5 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.start = void 0;
3
+ exports.generateRoutes = void 0;
18
4
  var file_router_1 = require("./file-router");
19
- Object.defineProperty(exports, "start", { enumerable: true, get: function () { return file_router_1.start; } });
20
- __exportStar(require("./types"), exports);
5
+ Object.defineProperty(exports, "generateRoutes", { enumerable: true, get: function () { return file_router_1.generateRoutes; } });
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type TStartConfigs = {
1
+ export type TGenerateRoutesConfig = {
2
2
  baseFolder: string;
3
3
  outputFile: string;
4
4
  routeFileName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;CACrC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;CACrC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './serializeTs';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./serializeTs"), exports);
@@ -0,0 +1,2 @@
1
+ export declare const serializeTs: (obj: any, ident?: number) => string;
2
+ //# sourceMappingURL=serializeTs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializeTs.d.ts","sourceRoot":"","sources":["../../src/utils/serializeTs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,GAAI,KAAK,GAAG,EAAE,cAAS,KAAG,MA0BjD,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serializeTs = void 0;
4
+ const serializeTs = (obj, ident = 2) => {
5
+ const pad = ' '.repeat(ident);
6
+ let str = '{\n';
7
+ for (const key in obj) {
8
+ const value = obj[key];
9
+ // Manipulate JS keys
10
+ const keyStr = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `"${key}"`;
11
+ if (typeof value === 'object' &&
12
+ value !== null &&
13
+ !('path' in value && 'import' in value)) {
14
+ // Create sub folders
15
+ str += `${pad}${keyStr}: ${(0, exports.serializeTs)(value, ident + 2)},\n`;
16
+ }
17
+ else {
18
+ // Routes
19
+ str += `${pad}${keyStr}: { path: "${value.path}", import: "${value.import}" },\n`;
20
+ }
21
+ }
22
+ str += ' '.repeat(ident - 2) + '}';
23
+ return str;
24
+ };
25
+ exports.serializeTs = serializeTs;
package/package.json CHANGED
@@ -1,20 +1,21 @@
1
- {
2
- "name": "ts-file-router",
3
- "version": "1.0.5",
4
- "description": "router based on project files using typescript",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist"
9
- ],
10
- "scripts": {
11
- "build": "tsc"
12
- },
13
- "author": "MatheusF10",
14
- "license": "ISC",
15
- "devDependencies": {
16
- "@types/node": "^24.10.1",
17
- "ts-node": "^10.9.2",
18
- "typescript": "^5.9.3"
19
- }
20
- }
1
+ {
2
+ "name": "ts-file-router",
3
+ "version": "2.0.1",
4
+ "description": "router based on project files using typescript",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "start": "ts-node ./src/file-router",
12
+ "build": "tsc"
13
+ },
14
+ "author": "MatheusF10",
15
+ "license": "ISC",
16
+ "devDependencies": {
17
+ "@types/node": "^24.10.1",
18
+ "ts-node": "^10.9.2",
19
+ "typescript": "^5.9.3"
20
+ }
21
+ }