rpc4next 0.3.4 → 0.3.5

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 (59) hide show
  1. package/dist/rpc/cli/cli-handler.js +1 -48
  2. package/dist/rpc/cli/cli.js +1 -32
  3. package/dist/rpc/cli/constants.js +1 -9
  4. package/dist/rpc/cli/core/alias.js +1 -16
  5. package/dist/rpc/cli/core/cache.js +1 -30
  6. package/dist/rpc/cli/core/constants.js +2 -19
  7. package/dist/rpc/cli/core/generate-path-structure.js +1 -30
  8. package/dist/rpc/cli/core/path-utils.js +1 -24
  9. package/dist/rpc/cli/core/route-scanner.js +1 -189
  10. package/dist/rpc/cli/core/scan-utils.js +1 -44
  11. package/dist/rpc/cli/core/type-utils.js +1 -26
  12. package/dist/rpc/cli/debounce.js +1 -43
  13. package/dist/rpc/cli/generator.js +1 -28
  14. package/dist/rpc/cli/index.js +1 -4
  15. package/dist/rpc/cli/logger.js +1 -31
  16. package/dist/rpc/cli/types.js +0 -2
  17. package/dist/rpc/cli/watcher.js +1 -67
  18. package/dist/rpc/client/http-method.js +1 -88
  19. package/dist/rpc/client/index.js +1 -6
  20. package/dist/rpc/client/match.js +1 -30
  21. package/dist/rpc/client/rpc.js +1 -99
  22. package/dist/rpc/client/types.js +0 -2
  23. package/dist/rpc/client/url.js +1 -57
  24. package/dist/rpc/client/utils.js +1 -31
  25. package/dist/rpc/lib/constants.js +1 -9
  26. package/dist/rpc/lib/content-type-types.js +0 -2
  27. package/dist/rpc/lib/http-request-headers-types.js +0 -2
  28. package/dist/rpc/lib/http-response-headers-types.js +0 -2
  29. package/dist/rpc/lib/http-status-code-types.js +0 -2
  30. package/dist/rpc/lib/types.js +0 -2
  31. package/dist/rpc/server/create-handler.js +1 -10
  32. package/dist/rpc/server/create-route-context.js +1 -25
  33. package/dist/rpc/server/index.js +1 -5
  34. package/dist/rpc/server/route-handler-factory.js +1 -68
  35. package/dist/rpc/server/route-types.js +0 -2
  36. package/dist/rpc/server/search-params-to-object.js +1 -18
  37. package/dist/rpc/server/types.js +0 -2
  38. package/dist/rpc/server/validators/validator-utils.js +1 -31
  39. package/dist/rpc/server/validators/zod/index.js +1 -5
  40. package/dist/rpc/server/validators/zod/zod-validator.js +1 -53
  41. package/package.json +5 -2
  42. package/dist/index.js +0 -18
  43. package/dist/rpc/cli/cli-handler.d.ts +0 -2
  44. package/dist/rpc/cli/cli.d.ts +0 -2
  45. package/dist/rpc/cli/constants.d.ts +0 -7
  46. package/dist/rpc/cli/core/alias.d.ts +0 -1
  47. package/dist/rpc/cli/core/cache.d.ts +0 -14
  48. package/dist/rpc/cli/core/constants.d.ts +0 -11
  49. package/dist/rpc/cli/core/generate-path-structure.d.ts +0 -7
  50. package/dist/rpc/cli/core/path-utils.d.ts +0 -3
  51. package/dist/rpc/cli/core/route-scanner.d.ts +0 -28
  52. package/dist/rpc/cli/core/scan-utils.d.ts +0 -19
  53. package/dist/rpc/cli/core/type-utils.d.ts +0 -6
  54. package/dist/rpc/cli/debounce.d.ts +0 -1
  55. package/dist/rpc/cli/generator.d.ts +0 -7
  56. package/dist/rpc/cli/index.d.ts +0 -2
  57. package/dist/rpc/cli/logger.d.ts +0 -3
  58. package/dist/rpc/cli/types.d.ts +0 -21
  59. package/dist/rpc/cli/watcher.d.ts +0 -2
@@ -1,48 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.handleCli = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const constants_1 = require("./constants");
9
- const path_utils_1 = require("./core/path-utils");
10
- const generator_1 = require("./generator");
11
- const watcher_1 = require("./watcher");
12
- const handleGenerateSafely = (baseDir, outputPath, paramsFileName, logger) => {
13
- try {
14
- (0, generator_1.generate)({
15
- baseDir,
16
- outputPath,
17
- paramsFileName,
18
- logger,
19
- });
20
- return constants_1.EXIT_SUCCESS;
21
- }
22
- catch (error) {
23
- if (error instanceof Error) {
24
- logger.error(`Failed to generate: ${error.message}`);
25
- }
26
- else {
27
- logger.error(`Unknown error occurred during generate: ${String(error)}`);
28
- }
29
- return constants_1.EXIT_FAILURE;
30
- }
31
- };
32
- const handleCli = (baseDir, outputPath, options, logger) => {
33
- const resolvedBaseDir = (0, path_utils_1.toPosixPath)(path_1.default.resolve(baseDir));
34
- const resolvedOutputPath = (0, path_utils_1.toPosixPath)(path_1.default.resolve(outputPath));
35
- const paramsFileName = typeof options.paramsFile === "string" ? options.paramsFile : null;
36
- if (options.paramsFile !== undefined && !paramsFileName) {
37
- logger.error("Error: --params-file requires a filename.");
38
- return constants_1.EXIT_FAILURE;
39
- }
40
- if (options.watch) {
41
- (0, watcher_1.setupWatcher)(resolvedBaseDir, () => {
42
- handleGenerateSafely(resolvedBaseDir, resolvedOutputPath, paramsFileName, logger);
43
- }, logger);
44
- return constants_1.EXIT_SUCCESS;
45
- }
46
- return handleGenerateSafely(resolvedBaseDir, resolvedOutputPath, paramsFileName, logger);
47
- };
48
- exports.handleCli = handleCli;
1
+ import s from"path";import{EXIT_FAILURE as m,EXIT_SUCCESS as l}from"./constants";import{toPosixPath as p}from"./core/path-utils";import{generate as u}from"./generator";import{setupWatcher as c}from"./watcher";const f=(i,n,t,r)=>{try{return u({baseDir:i,outputPath:n,paramsFileName:t,logger:r}),l}catch(e){return e instanceof Error?r.error(`Failed to generate: ${e.message}`):r.error(`Unknown error occurred during generate: ${String(e)}`),m}},F=(i,n,t,r)=>{const e=p(s.resolve(i)),a=p(s.resolve(n)),o=typeof t.paramsFile=="string"?t.paramsFile:null;return t.paramsFile!==void 0&&!o?(r.error("Error: --params-file requires a filename."),m):t.watch?(c(e,()=>{f(e,a,o,r)},r),l):f(e,a,o,r)};export{F as handleCli};
@@ -1,32 +1 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.runCli = void 0;
13
- const commander_1 = require("commander");
14
- const cli_handler_1 = require("./cli-handler");
15
- const logger_1 = require("./logger");
16
- const runCli = (argv, logger = (0, logger_1.createLogger)()) => {
17
- const program = new commander_1.Command();
18
- program
19
- .description("Generate RPC client type definitions based on the Next.js path structure.")
20
- .argument("<baseDir>", "Base directory containing Next.js paths for type generation")
21
- .argument("<outputPath>", "Output path for the generated type definitions")
22
- .option("-w, --watch", "Watch mode: regenerate on file changes")
23
- .option("-p, --params-file [filename]", "Generate params types file with specified filename")
24
- .action((baseDir, outputPath, options) => __awaiter(void 0, void 0, void 0, function* () {
25
- const exitCode = (0, cli_handler_1.handleCli)(baseDir, outputPath, options, logger);
26
- if (!options.watch) {
27
- process.exit(exitCode);
28
- }
29
- }));
30
- program.parse(argv);
31
- };
32
- exports.runCli = runCli;
1
+ import{Command as s}from"commander";import{handleCli as p}from"./cli-handler";import{EXIT_FAILURE as c}from"./constants";import{createLogger as m}from"./logger";const y=(o,t=m())=>{const r=new s;r.description("Generate RPC client type definitions based on the Next.js path structure.").argument("<baseDir>","Base directory containing Next.js paths for type generation").argument("<outputPath>","Output path for the generated type definitions").option("-w, --watch","Watch mode: regenerate on file changes").option("-p, --params-file [filename]","Generate params types file with specified filename").action(async(n,a,i)=>{try{const e=await p(n,a,i,t);i.watch||process.exit(e)}catch(e){t.error(`Unexpected error occurred:${e instanceof Error?e.message:String(e)}`),process.exit(c)}}),r.parse(o)};export{y as runCli};
@@ -1,9 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SUCCESS_SEPARATOR = exports.SUCCESS_PAD_LENGTH = exports.SUCCESS_INDENT_LEVEL = exports.EXIT_FAILURE = exports.EXIT_SUCCESS = exports.END_POINT_FILE_NAMES = void 0;
4
- exports.END_POINT_FILE_NAMES = ["page.tsx", "route.ts"];
5
- exports.EXIT_SUCCESS = 0;
6
- exports.EXIT_FAILURE = 1;
7
- exports.SUCCESS_INDENT_LEVEL = 1;
8
- exports.SUCCESS_PAD_LENGTH = 20;
9
- exports.SUCCESS_SEPARATOR = "→";
1
+ const S=["page.tsx","route.ts"],r=0,e=1,s=1,C=20,c="\u2192";export{S as END_POINT_FILE_NAMES,e as EXIT_FAILURE,r as EXIT_SUCCESS,s as SUCCESS_INDENT_LEVEL,C as SUCCESS_PAD_LENGTH,c as SUCCESS_SEPARATOR};
@@ -1,16 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createImportAlias = void 0;
7
- const crypto_1 = __importDefault(require("crypto"));
8
- const createImportAlias = (path, name) => {
9
- const hash = crypto_1.default
10
- .createHash("md5")
11
- .update(`${path}::${name}`)
12
- .digest("hex")
13
- .slice(0, 16);
14
- return `${name}_${hash}`;
15
- };
16
- exports.createImportAlias = createImportAlias;
1
+ import s from"crypto";const c=(r,t)=>{const e=s.createHash("md5").update(`${r}::${t}`).digest("hex").slice(0,16);return`${t}_${e}`};export{c as createImportAlias};
@@ -1,30 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.clearScanAppDirCacheAbove = exports.clearVisitedDirsCacheAbove = exports.scanAppDirCache = exports.visitedDirsCache = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- // Caches
9
- exports.visitedDirsCache = new Map();
10
- exports.scanAppDirCache = new Map();
11
- // Generic function to clear cache entries above a target path
12
- const clearCacheAbove = (cache, targetPath) => {
13
- const basePath = path_1.default.resolve(targetPath);
14
- [...cache.keys()].forEach((key) => {
15
- const normalizedKey = path_1.default.resolve(key);
16
- if (normalizedKey === basePath ||
17
- basePath.startsWith(normalizedKey + path_1.default.sep)) {
18
- cache.delete(key);
19
- }
20
- });
21
- };
22
- // Specific clear functions using the generic one
23
- const clearVisitedDirsCacheAbove = (targetPath) => {
24
- clearCacheAbove(exports.visitedDirsCache, targetPath);
25
- };
26
- exports.clearVisitedDirsCacheAbove = clearVisitedDirsCacheAbove;
27
- const clearScanAppDirCacheAbove = (targetPath) => {
28
- clearCacheAbove(exports.scanAppDirCache, targetPath);
29
- };
30
- exports.clearScanAppDirCacheAbove = clearScanAppDirCacheAbove;
1
+ import r from"path";const a=new Map,p=new Map,n=(e,i)=>{const t=r.resolve(i);[...e.keys()].forEach(o=>{const s=r.resolve(o);(s===t||t.startsWith(s+r.sep))&&e.delete(o)})},v=e=>{n(a,e)},h=e=>{n(p,e)};export{h as clearScanAppDirCacheAbove,v as clearVisitedDirsCacheAbove,p as scanAppDirCache,a as visitedDirsCache};
@@ -1,19 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RPC4NEXT_CLIENT_IMPORT_PATH = exports.TYPE_KEYS = exports.TYPE_KEY_PARAMS = exports.TYPE_KEY_OPTIONAL_QUERY = exports.TYPE_KEY_QUERY = exports.TYPE_END_POINT = exports.TYPE_SEPARATOR = exports.STATEMENT_TERMINATOR = exports.NEWLINE = exports.INDENT = exports.QUERY_TYPES = void 0;
4
- exports.QUERY_TYPES = ["Query", "OptionalQuery"];
5
- exports.INDENT = " ";
6
- exports.NEWLINE = "\n";
7
- exports.STATEMENT_TERMINATOR = ";";
8
- exports.TYPE_SEPARATOR = ";";
9
- exports.TYPE_END_POINT = "Endpoint";
10
- exports.TYPE_KEY_QUERY = "QueryKey";
11
- exports.TYPE_KEY_OPTIONAL_QUERY = "OptionalQueryKey";
12
- exports.TYPE_KEY_PARAMS = "ParamsKey";
13
- exports.TYPE_KEYS = [
14
- exports.TYPE_END_POINT,
15
- exports.TYPE_KEY_OPTIONAL_QUERY,
16
- exports.TYPE_KEY_PARAMS,
17
- exports.TYPE_KEY_QUERY,
18
- ];
19
- exports.RPC4NEXT_CLIENT_IMPORT_PATH = "rpc4next/client";
1
+ const T=["Query","OptionalQuery"],n=" ",r=`
2
+ `,_=";",p=";",t="Endpoint",o="QueryKey",E="OptionalQueryKey",e="ParamsKey",P=[t,E,e,o],c="rpc4next/client";export{n as INDENT,r as NEWLINE,T as QUERY_TYPES,c as RPC4NEXT_CLIENT_IMPORT_PATH,_ as STATEMENT_TERMINATOR,t as TYPE_END_POINT,P as TYPE_KEYS,E as TYPE_KEY_OPTIONAL_QUERY,e as TYPE_KEY_PARAMS,o as TYPE_KEY_QUERY,p as TYPE_SEPARATOR};
@@ -1,30 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generatePages = void 0;
4
- const constants_1 = require("./constants");
5
- const route_scanner_1 = require("./route-scanner");
6
- const type_utils_1 = require("./type-utils");
7
- const generatePages = (outputPath, baseDir) => {
8
- const { pathStructure, imports, paramsTypes } = (0, route_scanner_1.scanAppDir)(outputPath, baseDir);
9
- const pathStructureType = `export type PathStructure = ${pathStructure}${constants_1.STATEMENT_TERMINATOR}`;
10
- const importsStr = imports.length
11
- ? `${imports
12
- .sort((a, b) => a.path.localeCompare(b.path, undefined, { numeric: true }))
13
- .map((v) => v.statement)
14
- .join(constants_1.NEWLINE)}`
15
- : "";
16
- const keyTypes = constants_1.TYPE_KEYS.filter((type) => pathStructure.includes(type));
17
- const keyTypesImportStr = (0, type_utils_1.createImport)(keyTypes.join(" ,"), constants_1.RPC4NEXT_CLIENT_IMPORT_PATH);
18
- const dirParamsTypes = paramsTypes.map(({ paramsType, dirPath }) => {
19
- const params = `export type Params = ${paramsType}${constants_1.STATEMENT_TERMINATOR}`;
20
- return {
21
- paramsType: params,
22
- dirPath,
23
- };
24
- });
25
- return {
26
- pathStructure: `${keyTypesImportStr}${constants_1.NEWLINE}${importsStr}${constants_1.NEWLINE}${constants_1.NEWLINE}${pathStructureType}`,
27
- paramsTypes: dirParamsTypes,
28
- };
29
- };
30
- exports.generatePages = generatePages;
1
+ import{STATEMENT_TERMINATOR as s,NEWLINE as r,TYPE_KEYS as $,RPC4NEXT_CLIENT_IMPORT_PATH as E}from"./constants";import{scanAppDir as P}from"./route-scanner";import{createImport as S}from"./type-utils";const g=(o,m)=>{const{pathStructure:p,imports:a,paramsTypes:n}=P(o,m),c=`export type PathStructure = ${p}${s}`,T=a.length?`${a.sort((t,e)=>t.path.localeCompare(e.path,void 0,{numeric:!0})).map(t=>t.statement).join(r)}`:"",i=$.filter(t=>p.includes(t)),u=S(i.join(" ,"),E),y=n.map(({paramsType:t,dirPath:e})=>({paramsType:`export type Params = ${t}${s}`,dirPath:e}));return{pathStructure:`${u}${r}${T}${r}${r}${c}`,paramsTypes:y}};export{g as generatePages};
@@ -1,24 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.relativeFromRoot = exports.toPosixPath = exports.createRelativeImportPath = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const createRelativeImportPath = (outputFile, inputFile) => {
9
- let relativePath = (0, exports.toPosixPath)(path_1.default.relative(path_1.default.dirname(outputFile), inputFile)).replace(/\.tsx?$/, "");
10
- // Add "./" if the file is in the same directory
11
- if (!relativePath.startsWith("../")) {
12
- relativePath = "./" + relativePath;
13
- }
14
- return relativePath;
15
- };
16
- exports.createRelativeImportPath = createRelativeImportPath;
17
- const toPosixPath = (p) => {
18
- return p.replace(/\\/g, "/");
19
- };
20
- exports.toPosixPath = toPosixPath;
21
- const relativeFromRoot = (filePath) => {
22
- return path_1.default.relative(process.cwd(), filePath);
23
- };
24
- exports.relativeFromRoot = relativeFromRoot;
1
+ import e from"path";const a=(t,i)=>{let r=o(e.relative(e.dirname(t),i)).replace(/\.tsx?$/,"");return r.startsWith("../")||(r="./"+r),r},o=t=>t.replace(/\\/g,"/"),n=t=>e.relative(process.cwd(),t);export{a as createRelativeImportPath,n as relativeFromRoot,o as toPosixPath};
@@ -1,192 +1,4 @@
1
- "use strict";
2
1
  /*!
3
2
  * Inspired by pathpida (https://github.com/aspida/pathpida),
4
3
  * especially the design and UX of its CLI.
5
- */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.scanAppDir = exports.hasTargetFiles = void 0;
11
- const fs_1 = __importDefault(require("fs"));
12
- const path_1 = __importDefault(require("path"));
13
- const cache_1 = require("./cache");
14
- const constants_1 = require("./constants");
15
- const scan_utils_1 = require("./scan-utils");
16
- const type_utils_1 = require("./type-utils");
17
- const constants_2 = require("../../lib/constants");
18
- const constants_3 = require("../constants");
19
- const path_utils_1 = require("./path-utils");
20
- const endPointFileNames = new Set(constants_3.END_POINT_FILE_NAMES);
21
- const hasTargetFiles = (dirPath) => {
22
- if (cache_1.visitedDirsCache.has(dirPath))
23
- return cache_1.visitedDirsCache.get(dirPath);
24
- const entries = fs_1.default.readdirSync(dirPath, { withFileTypes: true });
25
- for (const entry of entries) {
26
- const { name } = entry;
27
- const entryPath = path_1.default.join(dirPath, name);
28
- if (name === "node_modules" ||
29
- // private
30
- name.startsWith("_") ||
31
- // intercepts
32
- name.startsWith("(.)") ||
33
- name.startsWith("(..)") ||
34
- name.startsWith("(...)")) {
35
- cache_1.visitedDirsCache.set(dirPath, false);
36
- return false;
37
- }
38
- if (entry.isFile() && endPointFileNames.has(name)) {
39
- cache_1.visitedDirsCache.set(dirPath, true);
40
- return true;
41
- }
42
- if (entry.isDirectory() && (0, exports.hasTargetFiles)(entryPath)) {
43
- cache_1.visitedDirsCache.set(dirPath, true);
44
- return true;
45
- }
46
- }
47
- cache_1.visitedDirsCache.set(dirPath, false);
48
- return false;
49
- };
50
- exports.hasTargetFiles = hasTargetFiles;
51
- const extractParamInfo = (entryName, { isDynamic, isCatchAll, isOptionalCatchAll, }) => {
52
- let param = entryName;
53
- // Remove brackets if it's a dynamic segment
54
- if (isDynamic) {
55
- param = param.replace(/^\[+|\]+$/g, "");
56
- }
57
- // Remove leading "..." if it's a catch-all segment
58
- if (isCatchAll || isOptionalCatchAll) {
59
- param = param.replace(/^\.{3}/, "");
60
- }
61
- const prefix = isOptionalCatchAll
62
- ? constants_2.OPTIONAL_CATCH_ALL_PREFIX
63
- : isCatchAll
64
- ? constants_2.CATCH_ALL_PREFIX
65
- : isDynamic
66
- ? constants_2.DYNAMIC_PREFIX
67
- : "";
68
- return { paramName: param, keyName: `${prefix}${param}` };
69
- };
70
- const scanAppDir = (output, input, indent = "", parentParams = []) => {
71
- if (cache_1.scanAppDirCache.has(input))
72
- return cache_1.scanAppDirCache.get(input);
73
- const previousIndent = indent;
74
- const currentIndent = indent + constants_1.INDENT;
75
- const pathStructures = [];
76
- const imports = [];
77
- const typeFragments = [];
78
- const paramsTypes = [];
79
- const params = [...parentParams];
80
- // Get entries under the directory (only target files or directories) and sort them
81
- const entries = fs_1.default
82
- .readdirSync(input, { withFileTypes: true })
83
- .filter((entry) => {
84
- if (entry.isDirectory()) {
85
- const dirPath = path_1.default.join(input, entry.name);
86
- return (0, exports.hasTargetFiles)(dirPath);
87
- }
88
- return endPointFileNames.has(entry.name);
89
- })
90
- .sort();
91
- for (const entry of entries) {
92
- const fullPath = (0, path_utils_1.toPosixPath)(path_1.default.join(input, entry.name));
93
- if (entry.isDirectory()) {
94
- const entryName = entry.name;
95
- const isGroup = entryName.startsWith("(") && entryName.endsWith(")");
96
- const isParallel = entryName.startsWith("@");
97
- const isOptionalCatchAll = entryName.startsWith("[[...") && entryName.endsWith("]]");
98
- const isCatchAll = entryName.startsWith("[...") && entryName.endsWith("]");
99
- const isDynamic = entryName.startsWith("[") && entryName.endsWith("]");
100
- const { paramName, keyName } = extractParamInfo(entryName, {
101
- isDynamic,
102
- isCatchAll,
103
- isOptionalCatchAll,
104
- });
105
- // If it's a dynamic segment, inherit the parameters
106
- const nextParams = isDynamic || isCatchAll || isOptionalCatchAll
107
- ? [
108
- ...params,
109
- {
110
- paramName,
111
- routeType: {
112
- isDynamic,
113
- isCatchAll,
114
- isOptionalCatchAll,
115
- isGroup,
116
- isParallel,
117
- },
118
- },
119
- ]
120
- : params;
121
- const isSkipDir = isGroup || isParallel;
122
- const { pathStructure: childPathStructure, imports: childImports, paramsTypes: childParamsTypes, } = (0, exports.scanAppDir)(output, fullPath, isSkipDir ? previousIndent : currentIndent, nextParams);
123
- imports.push(...childImports);
124
- paramsTypes.push(...childParamsTypes);
125
- if (isSkipDir) {
126
- // Extract only the inner part inside `{}` from the child output
127
- const match = childPathStructure.match(/^\s*\{([\s\S]*)\}\s*$/);
128
- if (match) {
129
- pathStructures.push(`${currentIndent}${match[1].trim()}`);
130
- }
131
- }
132
- else {
133
- pathStructures.push(`${currentIndent}"${keyName}": ${childPathStructure}`);
134
- }
135
- }
136
- else {
137
- // Process endpoint file
138
- const queryDef = (0, scan_utils_1.scanQuery)(output, fullPath);
139
- if (queryDef) {
140
- const { importStatement, importPath, type } = queryDef;
141
- imports.push({ statement: importStatement, path: importPath });
142
- typeFragments.push(type);
143
- }
144
- // Process routes for each HTTP method (excluding OPTIONS)
145
- constants_2.HTTP_METHODS_EXCLUDE_OPTIONS.forEach((method) => {
146
- const routeDef = (0, scan_utils_1.scanRoute)(output, fullPath, method);
147
- if (routeDef) {
148
- const { importStatement, importPath, type } = routeDef;
149
- imports.push({ statement: importStatement, path: importPath });
150
- typeFragments.push(type);
151
- }
152
- });
153
- // Add endpoint type
154
- typeFragments.push(constants_1.TYPE_END_POINT);
155
- // If parameters exist, generate their type definition
156
- if (params.length > 0) {
157
- const fields = params.map(({ paramName, routeType }) => {
158
- const paramType = routeType.isCatchAll
159
- ? "string[]"
160
- : routeType.isOptionalCatchAll
161
- ? "string[] | undefined"
162
- : "string";
163
- return { name: paramName, type: paramType };
164
- });
165
- const paramsTypeStr = (0, type_utils_1.createObjectType)(fields);
166
- paramsTypes.push({
167
- paramsType: paramsTypeStr,
168
- dirPath: path_1.default.dirname(fullPath),
169
- });
170
- typeFragments.push((0, type_utils_1.createRecodeType)(constants_1.TYPE_KEY_PARAMS, paramsTypeStr));
171
- }
172
- }
173
- }
174
- // Combine all type definitions
175
- const typeString = typeFragments.join(" & ");
176
- // Construct the nested path structure
177
- const pathStructureBody = pathStructures.length > 0
178
- ? `{${constants_1.NEWLINE}${pathStructures.join(`,${constants_1.NEWLINE}`)}${constants_1.NEWLINE}${previousIndent}}`
179
- : "";
180
- const pathStructure = typeString && pathStructureBody
181
- ? `${typeString} & ${pathStructureBody}`
182
- : typeString || pathStructureBody;
183
- const result = {
184
- pathStructure,
185
- imports,
186
- paramsTypes,
187
- };
188
- // Cache the result for reuse
189
- cache_1.scanAppDirCache.set(input, result);
190
- return result;
191
- };
192
- exports.scanAppDir = scanAppDir;
4
+ */import O from"fs";import N from"path";import{scanAppDirCache as I,visitedDirsCache as u}from"./cache";import{INDENT as H,TYPE_END_POINT as M,TYPE_KEY_PARAMS as X,NEWLINE as _}from"./constants";import{scanQuery as Y,scanRoute as w}from"./scan-utils";import{createObjectType as v,createRecodeType as G}from"./type-utils";import{OPTIONAL_CATCH_ALL_PREFIX as q,CATCH_ALL_PREFIX as B,DYNAMIC_PREFIX as K,HTTP_METHODS_EXCLUDE_OPTIONS as Q}from"../../lib/constants";import{END_POINT_FILE_NAMES as U}from"../constants";import{toPosixPath as z}from"./path-utils";const W=new Set(U),b=t=>{if(u.has(t))return u.get(t);const r=O.readdirSync(t,{withFileTypes:!0});for(const o of r){const{name:e}=o,a=N.join(t,e);if(e==="node_modules"||e.startsWith("_")||e.startsWith("(.)")||e.startsWith("(..)")||e.startsWith("(...)"))return u.set(t,!1),!1;if(o.isFile()&&W.has(e))return u.set(t,!0),!0;if(o.isDirectory()&&b(a))return u.set(t,!0),!0}return u.set(t,!1),!1},J=(t,{isDynamic:r,isCatchAll:o,isOptionalCatchAll:e})=>{let a=t;return r&&(a=a.replace(/^\[+|\]+$/g,"")),(o||e)&&(a=a.replace(/^\.{3}/,"")),{paramName:a,keyName:`${e?q:o?B:r?K:""}${a}`}},V=(t,r,o="",e=[])=>{if(I.has(r))return I.get(r);const a=o,y=o+H,T=[],P=[],f=[],d=[],g=[...e],F=O.readdirSync(r,{withFileTypes:!0}).filter(m=>{if(m.isDirectory()){const l=N.join(r,m.name);return b(l)}return W.has(m.name)}).sort();for(const m of F){const l=z(N.join(r,m.name));if(m.isDirectory()){const s=m.name,p=s.startsWith("(")&&s.endsWith(")"),n=s.startsWith("@"),i=s.startsWith("[[...")&&s.endsWith("]]"),c=s.startsWith("[...")&&s.endsWith("]"),h=s.startsWith("[")&&s.endsWith("]"),{paramName:j,keyName:L}=J(s,{isDynamic:h,isCatchAll:c,isOptionalCatchAll:i}),x=h||c||i?[...g,{paramName:j,routeType:{isDynamic:h,isCatchAll:c,isOptionalCatchAll:i,isGroup:p,isParallel:n}}]:g,D=p||n,{pathStructure:$,imports:R,paramsTypes:k}=V(t,l,D?a:y,x);if(P.push(...R),d.push(...k),D){const C=$.match(/^\s*\{([\s\S]*)\}\s*$/);C&&T.push(`${y}${C[1].trim()}`)}else T.push(`${y}"${L}": ${$}`)}else{const s=Y(t,l);if(s){const{importStatement:p,importPath:n,type:i}=s;P.push({statement:p,path:n}),f.push(i)}if(Q.forEach(p=>{const n=w(t,l,p);if(n){const{importStatement:i,importPath:c,type:h}=n;P.push({statement:i,path:c}),f.push(h)}}),f.push(M),g.length>0){const p=g.map(({paramName:i,routeType:c})=>{const h=c.isCatchAll?"string[]":c.isOptionalCatchAll?"string[] | undefined":"string";return{name:i,type:h}}),n=v(p);d.push({paramsType:n,dirPath:N.dirname(l)}),f.push(G(X,n))}}}const E=f.join(" & "),S=T.length>0?`{${_}${T.join(`,${_}`)}${_}${a}}`:"",A={pathStructure:E&&S?`${E} & ${S}`:E||S,imports:P,paramsTypes:d};return I.set(r,A),A};export{b as hasTargetFiles,V as scanAppDir};
@@ -1,44 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.scanRoute = exports.scanQuery = exports.scanFile = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const alias_1 = require("./alias");
9
- const constants_1 = require("./constants");
10
- const path_utils_1 = require("./path-utils");
11
- const type_utils_1 = require("./type-utils");
12
- const scanFile = (outputFile, inputFile, findCallBack, typeCallBack) => {
13
- const fileContents = fs_1.default.readFileSync(inputFile, "utf8");
14
- const type = findCallBack(fileContents);
15
- if (!type)
16
- return;
17
- const relativeImportPath = (0, path_utils_1.createRelativeImportPath)(outputFile, inputFile);
18
- const importAlias = (0, alias_1.createImportAlias)(relativeImportPath, type);
19
- return {
20
- importName: importAlias,
21
- importPath: relativeImportPath,
22
- importStatement: (0, type_utils_1.createImport)(type, relativeImportPath, importAlias),
23
- type: typeCallBack(type, importAlias),
24
- };
25
- };
26
- exports.scanFile = scanFile;
27
- // Create query definitions
28
- const scanQuery = (outputFile, inputFile) => {
29
- return (0, exports.scanFile)(outputFile, inputFile, (fileContents) => {
30
- return constants_1.QUERY_TYPES.find((type) => new RegExp(`export (interface ${type} ?{|type ${type} ?=)`).test(fileContents));
31
- }, (type, importAlias) => type === "Query"
32
- ? (0, type_utils_1.createRecodeType)(constants_1.TYPE_KEY_QUERY, importAlias)
33
- : (0, type_utils_1.createRecodeType)(constants_1.TYPE_KEY_OPTIONAL_QUERY, importAlias));
34
- };
35
- exports.scanQuery = scanQuery;
36
- // Create route definitions
37
- const scanRoute = (outputFile, inputFile, httpMethod) => {
38
- return (0, exports.scanFile)(outputFile, inputFile, (fileContents) => {
39
- return [httpMethod].find((method) => new RegExp(`export (async )?(function ${method} ?\\(|const ${method} ?=|\\{[^}]*\\b${method}\\b[^}]*\\} ?=|const \\{[^}]*\\b${method}\\b[^}]*\\} ?=|\\{[^}]*\\b${method}\\b[^}]*\\} from)`).test(fileContents));
40
- }, (type, importAlias) => (0, type_utils_1.createObjectType)([
41
- { name: `$${type.toLowerCase()}`, type: `typeof ${importAlias}` },
42
- ]));
43
- };
44
- exports.scanRoute = scanRoute;
1
+ import m from"fs";import{createImportAlias as f}from"./alias";import{QUERY_TYPES as g,TYPE_KEY_QUERY as u,TYPE_KEY_OPTIONAL_QUERY as y}from"./constants";import{createRelativeImportPath as l}from"./path-utils";import{createImport as E,createRecodeType as a,createObjectType as $}from"./type-utils";const c=(o,n,r,t)=>{const e=m.readFileSync(n,"utf8"),i=r(e);if(!i)return;const s=l(o,n),p=f(s,i);return{importName:p,importPath:s,importStatement:E(i,s,p),type:t(i,p)}},d=(o,n)=>c(o,n,r=>g.find(t=>new RegExp(`export (interface ${t} ?{|type ${t} ?=)`).test(r)),(r,t)=>r==="Query"?a(u,t):a(y,t)),I=(o,n,r)=>c(o,n,t=>[r].find(e=>new RegExp(`export (async )?(function ${e} ?\\(|const ${e} ?=|\\{[^}]*\\b${e}\\b[^}]*\\} ?=|const \\{[^}]*\\b${e}\\b[^}]*\\} ?=|\\{[^}]*\\b${e}\\b[^}]*\\} from)`).test(t)),(t,e)=>$([{name:`$${t.toLowerCase()}`,type:`typeof ${e}`}]));export{c as scanFile,d as scanQuery,I as scanRoute};
@@ -1,26 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createImport = exports.createObjectType = exports.createRecodeType = void 0;
4
- const constants_1 = require("./constants");
5
- const createRecodeType = (key, value) => {
6
- if (!key || !value)
7
- return "";
8
- return `Record<${key}, ${value}>`;
9
- };
10
- exports.createRecodeType = createRecodeType;
11
- const createObjectType = (fields) => {
12
- if (fields.length === 0 || fields.some(({ name, type }) => !name || !type))
13
- return "";
14
- return `{ ${fields
15
- .map(({ name, type }) => `"${name}": ${type}`)
16
- .join(`${constants_1.TYPE_SEPARATOR} `)}${fields.length > 1 ? constants_1.TYPE_SEPARATOR : ""} }`;
17
- };
18
- exports.createObjectType = createObjectType;
19
- const createImport = (type, path, importAlias) => {
20
- if (!type || !path)
21
- return "";
22
- return importAlias
23
- ? `import type { ${type} as ${importAlias} } from "${path}"${constants_1.STATEMENT_TERMINATOR}`
24
- : `import type { ${type} } from "${path}"${constants_1.STATEMENT_TERMINATOR}`;
25
- };
26
- exports.createImport = createImport;
1
+ import{TYPE_SEPARATOR as n,STATEMENT_TERMINATOR as o}from"./constants";const c=(r,t)=>!r||!t?"":`Record<${r}, ${t}>`,g=r=>r.length===0||r.some(({name:t,type:e})=>!t||!e)?"":`{ ${r.map(({name:t,type:e})=>`"${t}": ${e}`).join(`${n} `)}${r.length>1?n:""} }`,i=(r,t,e)=>!r||!t?"":e?`import type { ${r} as ${e} } from "${t}"${o}`:`import type { ${r} } from "${t}"${o}`;export{i as createImport,g as createObjectType,c as createRecodeType};
@@ -1,43 +1 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.debounceOnceRunningWithTrailing = void 0;
13
- const debounceOnceRunningWithTrailing = (func, delay) => {
14
- let timer = null;
15
- let isRunning = false;
16
- let pendingArgs = null;
17
- const execute = (...args) => __awaiter(void 0, void 0, void 0, function* () {
18
- isRunning = true;
19
- try {
20
- yield func(...args);
21
- }
22
- finally {
23
- isRunning = false;
24
- if (pendingArgs) {
25
- const nextArgs = pendingArgs;
26
- pendingArgs = null;
27
- execute(...nextArgs);
28
- }
29
- }
30
- });
31
- return (...args) => {
32
- if (timer)
33
- clearTimeout(timer);
34
- timer = setTimeout(() => {
35
- if (isRunning) {
36
- pendingArgs = args;
37
- return;
38
- }
39
- execute(...args);
40
- }, delay);
41
- };
42
- };
43
- exports.debounceOnceRunningWithTrailing = debounceOnceRunningWithTrailing;
1
+ const a=(l,u)=>{let t=null,r=!1,e=null;const i=async(...n)=>{r=!0;try{await l(...n)}finally{if(r=!1,e){const s=e;e=null,i(...s)}}};return(...n)=>{t&&clearTimeout(t),t=setTimeout(()=>{if(r){e=n;return}i(...n)},u)}};export{a as debounceOnceRunningWithTrailing};
@@ -1,28 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generate = void 0;
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const constants_1 = require("./constants");
10
- const generate_path_structure_1 = require("./core/generate-path-structure");
11
- const path_utils_1 = require("./core/path-utils");
12
- const logger_1 = require("./logger");
13
- const generate = ({ baseDir, outputPath, paramsFileName, logger, }) => {
14
- logger.info("Generating types...", { event: "generate" });
15
- const { pathStructure, paramsTypes } = (0, generate_path_structure_1.generatePages)(outputPath, baseDir);
16
- fs_1.default.writeFileSync(outputPath, pathStructure);
17
- logger.success((0, logger_1.padMessage)("Path structure type", (0, path_utils_1.relativeFromRoot)(outputPath), constants_1.SUCCESS_SEPARATOR, constants_1.SUCCESS_PAD_LENGTH), { indentLevel: constants_1.SUCCESS_INDENT_LEVEL });
18
- if (paramsFileName) {
19
- paramsTypes.forEach(({ paramsType, dirPath }) => {
20
- const filePath = path_1.default.join(dirPath, paramsFileName);
21
- fs_1.default.writeFileSync(filePath, paramsType);
22
- });
23
- logger.success((0, logger_1.padMessage)("Params types", paramsFileName, constants_1.SUCCESS_SEPARATOR, constants_1.SUCCESS_PAD_LENGTH), {
24
- indentLevel: constants_1.SUCCESS_INDENT_LEVEL,
25
- });
26
- }
27
- };
28
- exports.generate = generate;
1
+ import o from"fs";import E from"path";import{SUCCESS_SEPARATOR as s,SUCCESS_PAD_LENGTH as i,SUCCESS_INDENT_LEVEL as n}from"./constants";import{generatePages as y}from"./core/generate-path-structure";import{relativeFromRoot as L}from"./core/path-utils";import{padMessage as p}from"./logger";const v=({baseDir:m,outputPath:e,paramsFileName:t,logger:r})=>{r.info("Generating types...",{event:"generate"});const{pathStructure:a,paramsTypes:S}=y(e,m);o.writeFileSync(e,a),r.success(p("Path structure type",L(e),s,i),{indentLevel:n}),t&&(S.forEach(({paramsType:c,dirPath:f})=>{const g=E.join(f,t);o.writeFileSync(g,c)}),r.success(p("Params types",t,s,i),{indentLevel:n}))};export{v as generate};
@@ -1,5 +1,2 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- const cli_1 = require("./cli");
5
- (0, cli_1.runCli)(process.argv);
2
+ import{runCli as r}from"./cli";r(process.argv);
@@ -1,31 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createLogger = exports.padMessage = void 0;
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const constants_1 = require("./core/constants");
9
- const padMessage = (label, value, separator = "→", targetLength = 24) => {
10
- return label.padEnd(targetLength) + ` ${separator} ${value}`;
11
- };
12
- exports.padMessage = padMessage;
13
- const createIndent = (level = 0) => constants_1.INDENT.repeat(level);
14
- const createLogger = () => {
15
- return {
16
- info: (msg, options = {}) => {
17
- const { indentLevel = 0, event } = options;
18
- const prefix = event ? `${chalk_1.default.cyan(`[${event}]`)} ` : "";
19
- console.log(`${createIndent(indentLevel)}${prefix}${msg}`);
20
- },
21
- success: (msg, options = {}) => {
22
- const { indentLevel = 0 } = options;
23
- console.log(`${createIndent(indentLevel)}${chalk_1.default.green("✓")} ${msg}`);
24
- },
25
- error: (msg, options = {}) => {
26
- const { indentLevel = 0 } = options;
27
- console.error(`${createIndent(indentLevel)}${chalk_1.default.red("✗")} ${chalk_1.default.red(msg)}`);
28
- },
29
- };
30
- };
31
- exports.createLogger = createLogger;
1
+ import t from"chalk";import{INDENT as $}from"./core/constants";const i=(e,r,o="\u2192",n=24)=>e.padEnd(n)+` ${o} ${r}`,s=(e=0)=>$.repeat(e),d=()=>({info:(e,r={})=>{const{indentLevel:o=0,event:n}=r,c=n?`${t.cyan(`[${n}]`)} `:"";console.log(`${s(o)}${c}${e}`)},success:(e,r={})=>{const{indentLevel:o=0}=r;console.log(`${s(o)}${t.green("\u2713")} ${e}`)},error:(e,r={})=>{const{indentLevel:o=0}=r;console.error(`${s(o)}${t.red("\u2717")} ${t.red(e)}`)}});export{d as createLogger,i as padMessage};
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });