@kosmojs/dev 0.0.9 → 0.0.11
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/package.json +18 -21
- package/pkg/base-plugin/routes.js +42 -10
- package/pkg/base-plugin/routes.js.map +2 -2
- package/pkg/base-plugin/worker.js +36 -6
- package/pkg/base-plugin/worker.js.map +3 -3
- package/pkg/cli/cli.js +4 -6
- package/pkg/cli/cli.js.map +2 -2
- package/pkg/cli/index.js +1 -6
- package/pkg/cli/index.js.map +2 -2
- package/pkg/cli/templates/@src/api/router.hbs +2 -2
- package/pkg/cli/templates/core/api/errors.ts +18 -0
- package/pkg/cli/templates/core/api/server.ts +14 -0
- package/pkg/cli/templates/core/api/use.ts +5 -1
- package/pkg/index.js +38 -9
- package/pkg/index.js.map +3 -3
- package/pkg/src/base-plugin/routes/resolve.d.ts +7 -4
- package/pkg/src/cli/templates/core/api/errors.d.ts +1 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@kosmojs/dev",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.11",
|
|
5
5
|
"cacheVersion": "001",
|
|
6
6
|
"author": "Slee Woo",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"./package.json": "./package.json"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"chokidar": "^
|
|
37
|
+
"chokidar": "^5.0.0",
|
|
38
38
|
"concurrently": "^9.2.1",
|
|
39
39
|
"crc": "^4.3.2",
|
|
40
40
|
"dotenv": "^17.2.3",
|
|
41
|
-
"esbuild": "^0.27.
|
|
41
|
+
"esbuild": "^0.27.2",
|
|
42
42
|
"ora": "^9.0.0",
|
|
43
43
|
"picomatch": "^4.0.3",
|
|
44
44
|
"prompts": "^2.4.2",
|
|
@@ -46,35 +46,32 @@
|
|
|
46
46
|
"tinyglobby": "^0.2.15",
|
|
47
47
|
"ts-morph": "^27.0.2",
|
|
48
48
|
"typescript": "^5.9.3",
|
|
49
|
-
"@kosmojs/api": "^0.0.
|
|
50
|
-
"@kosmojs/
|
|
51
|
-
"@kosmojs/
|
|
52
|
-
"@kosmojs/
|
|
49
|
+
"@kosmojs/api": "^0.0.11",
|
|
50
|
+
"@kosmojs/devlib": "^0.0.11",
|
|
51
|
+
"@kosmojs/fetch-generator": "^0.0.11",
|
|
52
|
+
"@kosmojs/api-generator": "^0.0.11"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@solidjs/router": "^0.15.4",
|
|
56
56
|
"@types/koa": "^3.0.1",
|
|
57
57
|
"@types/koa__router": "^12.0.5",
|
|
58
|
-
"@types/node": "^
|
|
58
|
+
"@types/node": "^25.0.3",
|
|
59
59
|
"@types/picomatch": "^4.0.2",
|
|
60
60
|
"@types/prompts": "^2.4.9",
|
|
61
|
-
"@types/
|
|
62
|
-
"@types/react": "^19.2.3",
|
|
61
|
+
"@types/react": "^19.2.7",
|
|
63
62
|
"@types/react-dom": "^19.2.3",
|
|
64
|
-
"@vitejs/plugin-react": "^5.1.
|
|
65
|
-
"@vitejs/plugin-vue": "^6.0.
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"react": "^
|
|
69
|
-
"react-dom": "^19.2.0",
|
|
70
|
-
"react-router": "^7.9.5",
|
|
63
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
64
|
+
"@vitejs/plugin-vue": "^6.0.3",
|
|
65
|
+
"react": "^19.2.3",
|
|
66
|
+
"react-dom": "^19.2.3",
|
|
67
|
+
"react-router": "^7.10.1",
|
|
71
68
|
"solid-js": "^1.9.10",
|
|
72
69
|
"tslib": "^2.8.1",
|
|
73
|
-
"vite": "^7.
|
|
70
|
+
"vite": "^7.3.0",
|
|
74
71
|
"vite-plugin-solid": "^2.11.10",
|
|
75
|
-
"vue": "^3.5.
|
|
76
|
-
"vue-router": "^4.6.
|
|
77
|
-
"@kosmojs/config": "^0.0.
|
|
72
|
+
"vue": "^3.5.25",
|
|
73
|
+
"vue-router": "^4.6.4",
|
|
74
|
+
"@kosmojs/config": "^0.0.11"
|
|
78
75
|
},
|
|
79
76
|
"scripts": {
|
|
80
77
|
"build": "esbuilder src/index.ts src/base-plugin/routes.ts src/base-plugin/worker.ts src/stub-generator/index.ts src/cli/cli.ts src/cli/index.ts",
|
|
@@ -369,6 +369,8 @@ var types_default = '{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport typ
|
|
|
369
369
|
// src/base-plugin/routes/resolve.ts
|
|
370
370
|
var API_INDEX_BASENAME = "index";
|
|
371
371
|
var API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;
|
|
372
|
+
var API_USE_BASENAME = "use";
|
|
373
|
+
var API_USE_PATTERN = `${API_USE_BASENAME}.ts`;
|
|
372
374
|
var PAGE_INDEX_BASENAME = "index";
|
|
373
375
|
var PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;
|
|
374
376
|
var PAGE_LAYOUT_BASENAME = "layout";
|
|
@@ -376,6 +378,8 @@ var PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;
|
|
|
376
378
|
var ROUTE_FILE_PATTERNS = [
|
|
377
379
|
// match index files in api dir
|
|
378
380
|
`${defaults.apiDir}/**/${API_INDEX_PATTERN}`,
|
|
381
|
+
// match use files in api dir
|
|
382
|
+
`${defaults.apiDir}/**/${API_USE_PATTERN}`,
|
|
379
383
|
// match index files in pages dir
|
|
380
384
|
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
381
385
|
// match layout files in pages dir
|
|
@@ -393,6 +397,7 @@ var scanRoutes = async ({
|
|
|
393
397
|
ignore: [
|
|
394
398
|
// ignore top-level matches, routes resides in folders, even index route
|
|
395
399
|
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
400
|
+
`${defaults.apiDir}/${API_USE_PATTERN}`,
|
|
396
401
|
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,
|
|
397
402
|
`${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`
|
|
398
403
|
]
|
|
@@ -408,11 +413,17 @@ var isRouteFile = (file, {
|
|
|
408
413
|
}
|
|
409
414
|
return picomatch.isMatch(join(folder, ...rest), ROUTE_FILE_PATTERNS) ? [folder, rest.join("/")] : void 0;
|
|
410
415
|
};
|
|
411
|
-
var
|
|
412
|
-
return picomatch.matchBase(file, `**/${
|
|
416
|
+
var isApiRoute = (file) => {
|
|
417
|
+
return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);
|
|
413
418
|
};
|
|
414
|
-
var
|
|
415
|
-
return picomatch.matchBase(file, `**/${
|
|
419
|
+
var isApiUse = (file) => {
|
|
420
|
+
return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);
|
|
421
|
+
};
|
|
422
|
+
var isPageRoute = (file) => {
|
|
423
|
+
return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);
|
|
424
|
+
};
|
|
425
|
+
var isPageLayout = (file) => {
|
|
426
|
+
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
416
427
|
};
|
|
417
428
|
var createRouteEntry = (_file, {
|
|
418
429
|
appRoot,
|
|
@@ -482,6 +493,18 @@ var pageRouteResolverFactory = () => {
|
|
|
482
493
|
return { name, handler };
|
|
483
494
|
};
|
|
484
495
|
};
|
|
496
|
+
var apiUseResolverFactory = () => {
|
|
497
|
+
return (entry) => {
|
|
498
|
+
const { name } = entry;
|
|
499
|
+
const handler = async () => {
|
|
500
|
+
return {
|
|
501
|
+
kind: "apiUse",
|
|
502
|
+
entry
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
return { name, handler };
|
|
506
|
+
};
|
|
507
|
+
};
|
|
485
508
|
var apiRouteResolverFactory = (pluginOptions) => {
|
|
486
509
|
const {
|
|
487
510
|
appRoot,
|
|
@@ -738,6 +761,7 @@ var nestedRoutesFactory = (routeEntries) => {
|
|
|
738
761
|
var routes_default = async (pluginOptions) => {
|
|
739
762
|
const { appRoot, sourceFolder } = pluginOptions;
|
|
740
763
|
const apiRouteResolver = apiRouteResolverFactory(pluginOptions);
|
|
764
|
+
const apiUseResolver = apiUseResolverFactory(pluginOptions);
|
|
741
765
|
const pageRouteResolver = pageRouteResolverFactory(pluginOptions);
|
|
742
766
|
const pageLayoutResolver = pageLayoutResolverFactory(pluginOptions);
|
|
743
767
|
const resolversFactory = (routeFiles2) => {
|
|
@@ -748,12 +772,15 @@ var routes_default = async (pluginOptions) => {
|
|
|
748
772
|
});
|
|
749
773
|
for (const entry of entries) {
|
|
750
774
|
if (entry.folder === defaults2.apiDir) {
|
|
751
|
-
|
|
775
|
+
if (isApiRoute(entry.file)) {
|
|
776
|
+
resolvers.set(entry.fileFullpath, apiRouteResolver(entry));
|
|
777
|
+
} else if (isApiUse(entry.file)) {
|
|
778
|
+
resolvers.set(entry.fileFullpath, apiUseResolver(entry));
|
|
779
|
+
}
|
|
752
780
|
} else if (entry.folder === defaults2.pagesDir) {
|
|
753
|
-
|
|
754
|
-
if (pageFile?.kind === "index") {
|
|
781
|
+
if (isPageRoute(entry.file)) {
|
|
755
782
|
resolvers.set(entry.fileFullpath, pageRouteResolver(entry));
|
|
756
|
-
} else if (
|
|
783
|
+
} else if (isPageLayout(entry.file)) {
|
|
757
784
|
resolvers.set(entry.fileFullpath, pageLayoutResolver(entry));
|
|
758
785
|
}
|
|
759
786
|
}
|
|
@@ -769,15 +796,20 @@ var routes_default = async (pluginOptions) => {
|
|
|
769
796
|
export {
|
|
770
797
|
API_INDEX_BASENAME,
|
|
771
798
|
API_INDEX_PATTERN,
|
|
799
|
+
API_USE_BASENAME,
|
|
800
|
+
API_USE_PATTERN,
|
|
772
801
|
PAGE_INDEX_BASENAME,
|
|
773
802
|
PAGE_INDEX_PATTERN,
|
|
774
803
|
PAGE_LAYOUT_BASENAME,
|
|
775
804
|
PAGE_LAYOUT_PATTERN,
|
|
776
805
|
apiRouteResolverFactory,
|
|
806
|
+
apiUseResolverFactory,
|
|
777
807
|
createRouteEntry,
|
|
778
808
|
routes_default as default,
|
|
779
|
-
|
|
780
|
-
|
|
809
|
+
isApiRoute,
|
|
810
|
+
isApiUse,
|
|
811
|
+
isPageLayout,
|
|
812
|
+
isPageRoute,
|
|
781
813
|
isRouteFile,
|
|
782
814
|
nestedRoutesFactory,
|
|
783
815
|
pageLayoutResolverFactory,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/base-plugin/routes.ts", "../../src/base-plugin/routes/resolve.ts", "../../src/base-plugin/ast.ts", "../../src/base-plugin/cache.ts", "../../src/base-plugin/templates/resolved-types.hbs", "../../src/base-plugin/templates/types.hbs", "../../src/base-plugin/routes/nesting.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n defaults,\n type PluginOptionsResolved,\n type RouteEntry,\n} from \"@kosmojs/devlib\";\n\nimport {\n apiRouteResolverFactory,\n createRouteEntry,\n isPageFile,\n pageLayoutResolverFactory,\n pageRouteResolverFactory,\n type ResolverSignature,\n scanRoutes,\n} from \"./routes/resolve\";\n\nexport * from \"./routes/nesting\";\nexport * from \"./routes/resolve\";\n\nexport default async (pluginOptions: PluginOptionsResolved) => {\n const { appRoot, sourceFolder } = pluginOptions;\n\n const apiRouteResolver = apiRouteResolverFactory(pluginOptions);\n const pageRouteResolver = pageRouteResolverFactory(pluginOptions);\n const pageLayoutResolver = pageLayoutResolverFactory(pluginOptions);\n\n const resolversFactory = (routeFiles: Array<string>) => {\n const resolvers = new Map<\n string, // fileFullpath\n ResolverSignature\n >();\n\n const entries: Array<RouteEntry> = routeFiles.flatMap((file) => {\n const entry = createRouteEntry(file, pluginOptions);\n return entry ? [entry] : [];\n });\n\n for (const entry of entries) {\n if (entry.folder === defaults.apiDir) {\n resolvers.set(entry.fileFullpath, apiRouteResolver(entry));\n } else if (entry.folder === defaults.pagesDir) {\n const pageFile = isPageFile(entry.file);\n if (pageFile?.kind === \"index\") {\n resolvers.set(entry.fileFullpath, pageRouteResolver(entry));\n } else if (pageFile?.kind === \"layout\") {\n resolvers.set(entry.fileFullpath, pageLayoutResolver(entry));\n }\n }\n }\n\n return resolvers;\n };\n\n const routeFiles = await scanRoutes({ appRoot, sourceFolder });\n\n return {\n resolvers: resolversFactory(routeFiles),\n resolversFactory,\n };\n};\n", "import { dirname, join, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\nimport picomatch from \"picomatch\";\nimport { glob } from \"tinyglobby\";\n\nimport {\n type ApiRoute,\n defaults,\n type PageRoute,\n type PluginOptionsResolved,\n pathResolver,\n pathTokensFactory,\n type ResolvedEntry,\n type RouteEntry,\n render,\n renderToFile,\n} from \"@kosmojs/devlib\";\n\nimport { resolveRouteSignature, typeResolverFactory } from \"../ast\";\nimport { cacheFactory } from \"../cache\";\nimport resolvedTypesTpl from \"../templates/resolved-types.hbs\";\nimport typesFileTpl from \"../templates/types.hbs\";\n\nexport type ResolverSignature = {\n name: string;\n handler: (updatedFile?: string) => Promise<ResolvedEntry>;\n};\n\nexport const API_INDEX_BASENAME = \"index\";\nexport const API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;\n\nexport const PAGE_INDEX_BASENAME = \"index\";\nexport const PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;\n\nexport const PAGE_LAYOUT_BASENAME = \"layout\";\nexport const PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;\n\nconst ROUTE_FILE_PATTERNS = [\n // match index files in api dir\n `${defaults.apiDir}/**/${API_INDEX_PATTERN}`,\n // match index files in pages dir\n `${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,\n // match layout files in pages dir\n `${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`,\n];\n\nexport const scanRoutes = async ({\n appRoot,\n sourceFolder,\n}: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">) => {\n return glob(ROUTE_FILE_PATTERNS, {\n cwd: resolve(appRoot, sourceFolder),\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n ignore: [\n // ignore top-level matches, routes resides in folders, even index route\n `${defaults.apiDir}/${API_INDEX_PATTERN}`,\n `${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,\n `${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`,\n ],\n });\n};\n\nexport const isRouteFile = (\n file: string,\n {\n appRoot,\n sourceFolder,\n }: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">,\n):\n | [\n // Either `apiDir` or `pagesDir`\n folder: string,\n // Path to a file within the folder, nested at least one level deep\n file: string,\n ]\n | undefined => {\n const [_sourceFolder, folder, ...rest] = resolve(appRoot, file)\n .replace(`${appRoot}/`, \"\")\n .split(\"/\");\n\n /**\n * Ensure the file:\n * - is under the correct source root (`sourceFolder`)\n * - belongs to a known route folder (`apiDir` or `pagesDir`)\n * - is nested at least one level deep (not a direct child of the folder)\n * */\n if (!folder || _sourceFolder !== sourceFolder || rest.length < 2) {\n return;\n }\n\n return picomatch.isMatch(join(folder, ...rest), ROUTE_FILE_PATTERNS)\n ? [folder, rest.join(\"/\")]\n : undefined;\n};\n\nexport const isPageFile = (\n file: string,\n): { kind: \"index\" | \"layout\" } | undefined => {\n return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`)\n ? { kind: \"index\" }\n : picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`)\n ? { kind: \"layout\" }\n : undefined;\n};\n\nexport const isIndexFile = (file: string) => {\n return (\n picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`) ||\n picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`)\n );\n};\n\nexport const createRouteEntry = (\n _file: string,\n {\n appRoot,\n sourceFolder,\n }: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">,\n): RouteEntry | undefined => {\n // scanner already is doing a great job on matching only relevant files\n // but doing a double check here to make sure only needed files added to stack\n const resolvedPaths = isRouteFile(_file, { appRoot, sourceFolder });\n\n if (!resolvedPaths) {\n return;\n }\n\n const [folder, file] = resolvedPaths;\n\n const fileFullpath = join(appRoot, sourceFolder, folder, file);\n\n const pathTokens = pathTokensFactory(dirname(file));\n\n const name = pathTokens.map((e) => e.orig).join(\"/\");\n\n const importFile = file;\n\n const importName = `${importFile.replace(/\\W+/g, \"_\")}_${crc(importFile)}`;\n\n return {\n name,\n folder,\n file,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n };\n};\n\ntype ResolverFactory = (\n pluginOptions: PluginOptionsResolved,\n) => (entry: RouteEntry) => ResolverSignature;\n\nexport const pageLayoutResolverFactory: ResolverFactory = () => {\n return (entry) => {\n const { name } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async () => {\n return {\n kind: \"pageLayout\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n\nexport const pageRouteResolverFactory: ResolverFactory = () => {\n return (entry) => {\n const {\n name,\n folder,\n file,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async () => {\n const entry: PageRoute = {\n name,\n pathTokens,\n params: {\n schema: pathTokens.flatMap((e) => (e.param ? [e.param] : [])),\n },\n folder,\n file,\n fileFullpath,\n importFile,\n importName,\n };\n\n return {\n kind: \"pageRoute\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n\nexport const apiRouteResolverFactory: ResolverFactory = (pluginOptions) => {\n const {\n appRoot,\n sourceFolder,\n generators = [],\n formatters = [],\n refineTypeName,\n } = pluginOptions;\n\n let resolveTypes = false;\n\n for (const { options } of generators) {\n if (options?.resolveTypes) {\n resolveTypes = true;\n }\n }\n\n const {\n //\n literalTypesResolver,\n getSourceFile,\n refreshSourceFile,\n } = typeResolverFactory(pluginOptions);\n\n return (entry) => {\n const {\n name,\n file,\n folder,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async (updatedFile) => {\n const paramsSchema = pathTokens.flatMap((e) => {\n return e.param ? [e.param] : [];\n });\n\n const optionalParams = paramsSchema.length\n ? !paramsSchema.some((e) => e.isRequired)\n : true;\n\n const { getCache, persistCache } = cacheFactory(\n { file, fileFullpath, importName },\n {\n appRoot,\n sourceFolder,\n extraContext: { resolveTypes },\n },\n );\n\n let cache = await getCache({ validate: true });\n\n if (!cache) {\n if (updatedFile === fileFullpath) {\n await refreshSourceFile(fileFullpath);\n }\n\n const {\n typeDeclarations,\n paramsRefinements,\n methods,\n payloadTypes,\n responseTypes,\n referencedFiles = [],\n } = await resolveRouteSignature(\n { importName, fileFullpath, optionalParams },\n {\n withReferencedFiles: true,\n sourceFile: getSourceFile(fileFullpath),\n relpathResolver(path) {\n return join(sourceFolder, defaults.apiDir, dirname(file), path);\n },\n },\n );\n\n const numericParams = paramsRefinements\n ? paramsRefinements.flatMap(({ text, index }) => {\n if (text === \"number\") {\n const param = paramsSchema.at(index);\n return param ? [param.name] : [];\n }\n return [];\n })\n : [];\n\n const typesFile = pathResolver({ appRoot, sourceFolder }).resolve(\n \"apiLibDir\",\n dirname(file),\n \"types.ts\",\n );\n\n const params: ApiRoute[\"params\"] = {\n id: [\"ParamsT\", crc(name)].join(\"\"),\n schema: paramsSchema,\n resolvedType: undefined,\n };\n\n const typesFileContent = render(typesFileTpl, {\n params,\n paramsSchema: paramsSchema.map((param, index) => {\n return {\n ...param,\n refinement: paramsRefinements?.at(index),\n };\n }),\n typeDeclarations,\n payloadTypes,\n responseTypes,\n });\n\n const resolvedTypes = resolveTypes\n ? literalTypesResolver(typesFileContent, {\n overrides: [...payloadTypes, ...responseTypes].reduce(\n (map: Record<string, string>, { id, skipValidation }) => {\n if (skipValidation) {\n map[id] = \"never\";\n }\n return map;\n },\n { [refineTypeName]: refineTypeName },\n ),\n withProperties: [params.id, ...payloadTypes.map((e) => e.id)],\n formatters,\n })\n : undefined;\n\n /**\n * Deploy types.ts file; required by core generators (like fetch).\n * If types resolved, write resolved types;\n * otherwise write original types extracted from API route.\n * */\n await renderToFile(\n typesFile,\n resolvedTypes ? resolvedTypesTpl : typesFileContent,\n { resolvedTypes },\n );\n\n params.resolvedType = resolvedTypes?.find((e) => e.name === params.id);\n\n cache = await persistCache({\n params,\n methods,\n typeDeclarations,\n numericParams,\n // text was needed at writing types.ts file, dropping from cache\n payloadTypes: payloadTypes.map(({ text, ...rest }) => {\n return {\n ...rest,\n resolvedType: resolvedTypes?.find((e) => e.name === rest.id),\n };\n }),\n responseTypes: responseTypes.map(({ text, ...rest }) => {\n return {\n ...rest,\n resolvedType: resolvedTypes?.find((e) => e.name === rest.id),\n };\n }),\n referencedFiles,\n });\n }\n\n const entry: ApiRoute = {\n name,\n pathTokens,\n params: cache.params,\n numericParams: cache.numericParams,\n optionalParams,\n importName,\n importFile,\n folder,\n file,\n fileFullpath,\n methods: cache.methods,\n typeDeclarations: cache.typeDeclarations,\n payloadTypes: cache.payloadTypes,\n responseTypes: cache.responseTypes,\n referencedFiles: Object.keys(cache.referencedFiles).map(\n // expand referenced files path,\n // they are stored as relative in cache\n (e) => resolve(appRoot, e),\n ),\n };\n\n return {\n kind: \"apiRoute\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n", "import { resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\nimport { flattener } from \"tfusion\";\nimport {\n type CallExpression,\n type Identifier,\n type Node,\n Project,\n type ProjectOptions,\n type SourceFile,\n SyntaxKind,\n} from \"ts-morph\";\n\nimport { type HTTPMethod, HTTPMethods } from \"@kosmojs/api\";\nimport type {\n ApiRoute,\n PayloadType,\n PluginOptionsResolved,\n ResponseType,\n TypeDeclaration,\n} from \"@kosmojs/devlib\";\n\ntype PathResolver = (path: string) => string;\n\nexport const createProject = (opts?: ProjectOptions) => new Project(opts);\n\nexport const resolveRouteSignature = async (\n route: Pick<ApiRoute, \"importName\" | \"fileFullpath\" | \"optionalParams\">,\n opts?: {\n relpathResolver?: PathResolver;\n sourceFile?: SourceFile;\n withReferencedFiles?: boolean;\n },\n) => {\n const {\n sourceFile = createProject().addSourceFileAtPath(route.fileFullpath),\n } = { ...opts };\n\n const [typeDeclarations, referencedFiles] = extractTypeDeclarations(\n sourceFile,\n opts,\n );\n\n const defaultExport = extractDefaultExport(sourceFile);\n\n const paramsRefinements = defaultExport\n ? extractParamsRefinements(defaultExport)\n : undefined;\n\n const methods = defaultExport\n ? extractRouteMethods(defaultExport, route)\n : [];\n\n const payloadTypes = methods.flatMap((e) => {\n return e.payloadType ? [e.payloadType] : [];\n });\n\n const responseTypes = methods.flatMap((e) => {\n return e.responseType ? [e.responseType] : [];\n });\n\n return {\n typeDeclarations,\n paramsRefinements,\n methods: methods.map((e) => e.method),\n payloadTypes,\n responseTypes,\n referencedFiles,\n };\n};\n\nexport const extractDefaultExport = (\n sourceFile: SourceFile,\n): CallExpression | undefined => {\n const [defaultExport] = sourceFile\n .getExportAssignments()\n .flatMap((exportAssignment) => {\n if (exportAssignment.isExportEquals()) {\n return [];\n }\n const callExpression = exportAssignment.getExpression();\n return callExpression.isKind(SyntaxKind.CallExpression)\n ? [callExpression]\n : [];\n });\n return defaultExport;\n};\n\nexport const extractParamsRefinements = (\n callExpression: CallExpression,\n):\n | Array<{\n index: number;\n text: string;\n }>\n | undefined => {\n const [firstGeneric] = extractGenerics(callExpression);\n\n if (!firstGeneric?.node.isKind(SyntaxKind.TupleType)) {\n return;\n }\n\n const tupleElements = firstGeneric.node.getElements();\n\n if (!tupleElements?.length) {\n return;\n }\n\n return tupleElements.map((node, index) => {\n return {\n index,\n text: node.getText(),\n };\n });\n};\n\nexport const extractRouteMethods = (\n callExpression: CallExpression,\n route: Pick<ApiRoute, \"importName\" | \"optionalParams\">,\n): Array<{\n method: HTTPMethod;\n payloadType: (PayloadType & { text: string }) | undefined;\n responseType: (ResponseType & { text: string }) | undefined;\n}> => {\n const funcDeclaration =\n callExpression.getFirstChildByKind(SyntaxKind.ArrowFunction) ||\n callExpression.getFirstChildByKind(SyntaxKind.FunctionExpression);\n\n if (!funcDeclaration) {\n return [];\n }\n\n const arrayLiteralExpression = funcDeclaration.getFirstChildByKind(\n SyntaxKind.ArrayLiteralExpression,\n );\n\n if (!arrayLiteralExpression) {\n return [];\n }\n\n const callExpressions: Array<[CallExpression, HTTPMethod]> = [];\n\n for (const e of arrayLiteralExpression.getChildrenOfKind(\n SyntaxKind.CallExpression,\n )) {\n const name = e.getExpression().getText() as HTTPMethod;\n if (HTTPMethods[name]) {\n callExpressions.push([e, name]);\n }\n }\n\n const methods = [];\n\n const skipValidationFilter = (e: string) => /@skip-validation/.test(e);\n\n for (const [callExpression, method] of callExpressions) {\n const [payloadGeneric, responseGeneric] = extractGenerics(callExpression);\n\n const payloadText = payloadGeneric?.node\n ? payloadGeneric.node.getChildren().length === 0\n ? \"{}\"\n : payloadGeneric.node.getFullText()\n : undefined;\n\n const responseText = responseGeneric?.node.getText();\n\n const responseType = responseText\n ? {\n id: [\"ResponseT\", crc(route.importName + method)].join(\"\"),\n method,\n skipValidation: responseGeneric?.comments\n ? responseGeneric.comments.some(skipValidationFilter)\n : false,\n text: [\"never\", \"object\"].includes(responseText)\n ? \"{}\"\n : responseText,\n resolvedType: undefined,\n }\n : undefined;\n\n const payloadType = payloadText\n ? {\n id: [\"PayloadT\", crc(route.importName + method)].join(\"\"),\n responseTypeId: responseType?.id,\n method,\n skipValidation: payloadGeneric?.comments\n ? payloadGeneric.comments.some(skipValidationFilter)\n : false,\n isOptional: payloadText\n ? payloadText === \"{}\" || route.optionalParams\n : true,\n text: payloadText,\n resolvedType: undefined,\n }\n : undefined;\n\n methods.push({\n method,\n payloadType,\n responseType,\n });\n }\n\n return methods;\n};\n\nexport const extractTypeDeclarations = (\n sourceFile: SourceFile,\n opts?: {\n relpathResolver?: PathResolver;\n withReferencedFiles?: boolean;\n },\n): [d: Array<TypeDeclaration>, f?: Array<string>] => {\n const declarations: Array<TypeDeclaration> = [];\n\n const referencedFiles: Array<string> | undefined = opts?.withReferencedFiles\n ? []\n : undefined;\n\n for (const declaration of sourceFile.getImportDeclarations()) {\n const modulePath = declaration.getModuleSpecifierValue();\n\n const path = /^\\.\\.?\\/?/.test(modulePath)\n ? opts?.relpathResolver\n ? opts.relpathResolver(modulePath)\n : modulePath\n : modulePath;\n\n const typeOnlyDeclaration = declaration.isTypeOnly();\n\n const defaultImport = typeOnlyDeclaration\n ? declaration.getDefaultImport()\n : undefined;\n\n if (defaultImport) {\n const name = defaultImport.getText();\n const text = `import type ${name} from \"${path}\";`;\n declarations.push({\n importDeclaration: {\n name,\n path,\n },\n text,\n });\n if (referencedFiles) {\n referencedFiles.push(...getReferencedFiles(defaultImport));\n }\n }\n\n for (const namedImport of declaration.getNamedImports()) {\n if (namedImport.isTypeOnly() || typeOnlyDeclaration) {\n const nameNode = namedImport.getNameNode();\n const name = nameNode.getText();\n const alias = namedImport.getAliasNode()?.getText();\n const nameText = alias ? `${name} as ${alias}` : name;\n\n declarations.push({\n importDeclaration: {\n name,\n alias,\n path,\n },\n text: `import type { ${nameText} } from \"${path}\";`,\n });\n\n if (referencedFiles) {\n if (nameNode.isKind(SyntaxKind.Identifier)) {\n referencedFiles.push(...getReferencedFiles(nameNode));\n }\n }\n }\n }\n }\n\n for (const declaration of sourceFile.getTypeAliases()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n typeAliasDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getInterfaces()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n interfaceDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getEnums()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n enumDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getExportDeclarations()) {\n const typeOnlyDeclaration = declaration.isTypeOnly();\n\n const modulePath = declaration.getModuleSpecifierValue();\n\n const path = modulePath\n ? /^\\.\\.?\\/?/.test(modulePath)\n ? opts?.relpathResolver\n ? opts.relpathResolver(modulePath)\n : modulePath\n : modulePath\n : undefined;\n\n for (const namedExport of declaration.getNamedExports()) {\n if (namedExport.isTypeOnly() || typeOnlyDeclaration) {\n const nameNode = namedExport.getNameNode();\n const name = nameNode.getText();\n const alias = namedExport.getAliasNode()?.getText();\n const nameText = alias ? `${name} as ${alias}` : name;\n\n declarations.push({\n exportDeclaration: {\n name,\n alias: alias ?? name,\n path,\n },\n text: path\n ? `export type { ${nameText} } from \"${path}\";`\n : `export type { ${nameText} };`,\n });\n\n if (referencedFiles) {\n if (nameNode.isKind(SyntaxKind.Identifier)) {\n referencedFiles.push(...getReferencedFiles(nameNode));\n }\n }\n }\n }\n }\n\n return referencedFiles\n ? [declarations, [...new Set<string>(referencedFiles)]]\n : [declarations];\n};\n\nconst getReferencedFiles = (importIdentifier: Identifier): Array<string> => {\n // ambient modules may have declarations in multiple files\n const declarations =\n importIdentifier //\n ?.getSymbol()\n ?.getAliasedSymbol()\n ?.getDeclarations() || [];\n\n return declarations.flatMap((e) => {\n const sourceFile = e.getSourceFile();\n return sourceFile //\n ? [sourceFile.getFilePath()]\n : [];\n });\n};\n\nconst extractGenerics = (\n callExpression: CallExpression,\n): Array<{ node: Node; comments: Array<string> }> => {\n return callExpression.getTypeArguments().map((node) => {\n return {\n node,\n comments: node\n .getLeadingCommentRanges()\n .map((range) => range.getText().trim()),\n };\n });\n};\n\nexport const typeResolverFactory = ({ appRoot }: PluginOptionsResolved) => {\n const project = createProject({\n tsConfigFilePath: resolve(appRoot, \"tsconfig.json\"),\n skipAddingFilesFromTsConfig: true,\n });\n\n const literalTypesResolver = (\n literalTypes: string,\n options: Parameters<typeof flattener>[2],\n ) => {\n const sourceFile = project.createSourceFile(\n `${crc(literalTypes)}-${Date.now()}.ts`,\n literalTypes,\n { overwrite: true },\n );\n\n const resolvedTypes = flattener(project, sourceFile, {\n ...options,\n stripComments: true,\n });\n\n project.removeSourceFile(sourceFile);\n\n return resolvedTypes;\n };\n\n return {\n getSourceFile: (fileFullpath: string) => {\n return (\n project.getSourceFile(fileFullpath) ||\n project.addSourceFileAtPath(fileFullpath)\n );\n },\n refreshSourceFile: async (fileFullpath: string) => {\n const sourceFile = project.getSourceFile(fileFullpath);\n if (sourceFile) {\n await sourceFile.refreshFromFileSystem();\n }\n },\n literalTypesResolver,\n };\n};\n", "import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\n\n/**\n * Import from published package to ensure correct version at runtime.\n * Local import would be bundled with pre-bump version; this external\n * import resolves to the actual published package.json.\n * */\nimport self from \"@kosmojs/dev/package.json\" with { type: \"json\" };\nimport { type ApiRoute, pathExists, pathResolver } from \"@kosmojs/devlib\";\n\nexport type Cache = {\n hash: number;\n referencedFiles: Record<string, number>;\n} & Pick<\n ApiRoute,\n | \"params\"\n | \"methods\"\n | \"typeDeclarations\"\n | \"numericParams\"\n | \"payloadTypes\"\n | \"responseTypes\"\n>;\n\ntype ExtraContext = Record<string | number, unknown>;\n\nexport const cacheFactory = (\n route: Pick<ApiRoute, \"file\" | \"fileFullpath\" | \"importName\">,\n {\n appRoot,\n sourceFolder,\n extraContext,\n }: {\n appRoot: string;\n sourceFolder: string;\n extraContext?: ExtraContext;\n },\n) => {\n const cacheFile = pathResolver({\n appRoot,\n sourceFolder,\n }).resolve(\"apiLibDir\", dirname(route.file), \"cache.json\");\n\n const getCache = async (opt?: {\n validate?: boolean;\n }): Promise<Cache | undefined> => {\n if (await pathExists(cacheFile)) {\n try {\n const cache = JSON.parse(await readFile(cacheFile, \"utf8\"));\n return opt?.validate //\n ? validateCache(cache)\n : cache;\n } catch (_e) {}\n }\n return undefined;\n };\n\n const persistCache = async ({\n referencedFiles: _referencedFiles,\n ...rest\n }: Omit<Cache, \"hash\" | \"referencedFiles\"> & {\n referencedFiles: Array<string>;\n }): Promise<Cache> => {\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n const referencedFiles: Cache[\"referencedFiles\"] = {};\n\n for (const file of _referencedFiles) {\n referencedFiles[\n // Strip project root to ensure cached paths are relative\n // and portable across environments (CI, local, etc.)\n file.replace(`${appRoot}/`, \"\")\n ] = await generateFileHash(file);\n }\n\n const cache = { ...rest, hash, referencedFiles };\n\n await mkdir(dirname(cacheFile), { recursive: true });\n await writeFile(cacheFile, JSON.stringify(cache, null, 2), \"utf8\");\n\n return cache;\n };\n\n const validateCache = async (\n cache: Cache | undefined,\n ): Promise<Cache | undefined> => {\n if (!cache?.hash) {\n return;\n }\n\n if (!cache.typeDeclarations || !cache.referencedFiles) {\n // incomplete cache\n return;\n }\n\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n if (!identicalHashSum(cache.hash, hash)) {\n // route itself updated\n return;\n }\n\n for (const [file, hash] of Object.entries(cache.referencedFiles)) {\n if (\n !identicalHashSum(hash, await generateFileHash(resolve(appRoot, file)))\n ) {\n // some referenced file updated\n return;\n }\n }\n\n return cache;\n };\n\n return {\n getCache,\n validateCache,\n persistCache,\n };\n};\n\nconst generateFileHash = async (\n file: string,\n extraContext?: ExtraContext,\n): Promise<number> => {\n let fileContent: string | undefined;\n try {\n fileContent = await readFile(file, \"utf8\");\n } catch (_e) {\n // file could be deleted since last build\n return 0;\n }\n return fileContent\n ? crc(\n JSON.stringify({\n ...extraContext,\n [self.cacheVersion]: fileContent,\n }),\n )\n : 0;\n};\n\n// return true if sums are identical\nconst identicalHashSum = (a: number, b: number) => {\n return a === b;\n};\n", "{{#each resolvedTypes}}\nexport type {{name}} = {{text}};\n{{/each}}\n", "{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport type {{params.id}} = {\n {{#each paramsSchema}}\n \"{{name}}\"{{#unless isRequired}}?{{/unless}}:{{#if isRest}} Array<{{/if}}\n {{#if refinement}}{{refinement.text}}{{else}}string{{/if}}\n {{#if isRest}}>{{/if}}\n {{/each}}\n};\n\n{{#each payloadTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n\n{{#each responseTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n", "import { basename } from \"node:path\";\n\nimport {\n type NestedRouteEntry,\n type RouteEntry,\n sortRoutes,\n} from \"@kosmojs/devlib\";\n\nimport { PAGE_INDEX_BASENAME, PAGE_LAYOUT_BASENAME } from \"./resolve\";\n\n/**\n * Build a nested route tree from flat route entries.\n * */\nexport const nestedRoutesFactory = (routeEntries: Array<RouteEntry>) => {\n const entryStack = structuredClone(routeEntries).sort(sortRoutes);\n\n /**\n * Group entries by name (at the same level, both layout and index share same name).\n *\n * Handle 3 cases:\n * - both index and layout exists\n * - only index exists\n * - only layout exists\n *\n * */\n const transformEntries = (\n entries: Array<RouteEntry>,\n parent?: RouteEntry,\n ): Array<NestedRouteEntry> => {\n return [...new Set(entries.map((e) => e.name))].flatMap((name) => {\n const nameEntries = entryStack.flatMap(({ fileFullpath, ...entry }) => {\n return entry.name === name ? [entry] : [];\n });\n\n const index = nameEntries.find((e) =>\n basename(e.file).startsWith(PAGE_INDEX_BASENAME),\n ) as RouteEntry;\n\n const layout = nameEntries.find((e) =>\n basename(e.file).startsWith(PAGE_LAYOUT_BASENAME),\n ) as RouteEntry;\n\n if (index || layout) {\n return [\n {\n index: index\n ? {\n ...index,\n pathTokens: index.pathTokens.slice(\n parent?.pathTokens.length || 0,\n ),\n }\n : undefined,\n layout: layout\n ? {\n ...layout,\n pathTokens: layout.pathTokens.slice(\n parent?.pathTokens.length || 0,\n ),\n }\n : undefined,\n parent: parent?.name,\n children: transformEntries(\n findDescendantEntries(index || layout),\n index || layout,\n ),\n },\n ];\n }\n\n return [];\n });\n };\n\n /**\n * Recursively finds direct descendant routes.\n *\n * \"Direct\" means the next existing route in the path hierarchy,\n * skipping intermediate path segments that don't have index/layout files.\n *\n * Example: blog/post/[slug]/index.tsx is a direct child of blog/index.tsx\n * even though \"post\" segment exists (it has no index.tsx).\n * */\n const findDescendantEntries = ({\n name,\n pathTokens,\n }: RouteEntry): Array<RouteEntry> => {\n // Find all potential children - BOTH indexes AND layouts\n const potentialChildren = entryStack.filter((entry) => {\n // Must be deeper than current entry\n if (entry.pathTokens.length <= pathTokens.length) {\n return false;\n }\n // Must be a descendant path\n if (!entry.name.startsWith(`${name}/`)) {\n return false;\n }\n return true;\n });\n\n // Filter to direct children (no intermediate route between parent and child)\n return potentialChildren.filter((child) => {\n // Check if any route exists between parent and child\n const hasIntermediateRoute = potentialChildren.some((intermediate) => {\n if (intermediate === child) {\n return false;\n }\n // Intermediate must be between parent and child in depth\n if (intermediate.pathTokens.length <= pathTokens.length) {\n return false;\n }\n if (intermediate.pathTokens.length >= child.pathTokens.length) {\n return false;\n }\n // Child must be descendant of intermediate\n return child.name.startsWith(`${intermediate.name}/`);\n });\n\n return !hasIntermediateRoute;\n });\n };\n\n // Find root entries - entries that have no parent route\n const rootEntries = entryStack.filter((entry) => {\n // Check if any other entry could be its parent\n const hasParent = entryStack.some((potential) => {\n if (potential === entry) {\n return false;\n }\n if (potential.pathTokens.length >= entry.pathTokens.length) {\n return false;\n }\n return entry.name.startsWith(`${potential.name}/`);\n });\n\n return !hasParent;\n });\n\n return transformEntries(rootEntries);\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import {\n defaults,\n type PluginOptionsResolved,\n type RouteEntry,\n} from \"@kosmojs/devlib\";\n\nimport {\n apiRouteResolverFactory,\n apiUseResolverFactory,\n createRouteEntry,\n isApiRoute,\n isApiUse,\n isPageLayout,\n isPageRoute,\n pageLayoutResolverFactory,\n pageRouteResolverFactory,\n type ResolverSignature,\n scanRoutes,\n} from \"./routes/resolve\";\n\nexport * from \"./routes/nesting\";\nexport * from \"./routes/resolve\";\n\nexport default async (pluginOptions: PluginOptionsResolved) => {\n const { appRoot, sourceFolder } = pluginOptions;\n\n const apiRouteResolver = apiRouteResolverFactory(pluginOptions);\n const apiUseResolver = apiUseResolverFactory(pluginOptions);\n const pageRouteResolver = pageRouteResolverFactory(pluginOptions);\n const pageLayoutResolver = pageLayoutResolverFactory(pluginOptions);\n\n const resolversFactory = (routeFiles: Array<string>) => {\n const resolvers = new Map<\n string, // fileFullpath\n ResolverSignature\n >();\n\n const entries: Array<RouteEntry> = routeFiles.flatMap((file) => {\n const entry = createRouteEntry(file, pluginOptions);\n return entry ? [entry] : [];\n });\n\n for (const entry of entries) {\n if (entry.folder === defaults.apiDir) {\n if (isApiRoute(entry.file)) {\n resolvers.set(entry.fileFullpath, apiRouteResolver(entry));\n } else if (isApiUse(entry.file)) {\n resolvers.set(entry.fileFullpath, apiUseResolver(entry));\n }\n } else if (entry.folder === defaults.pagesDir) {\n if (isPageRoute(entry.file)) {\n resolvers.set(entry.fileFullpath, pageRouteResolver(entry));\n } else if (isPageLayout(entry.file)) {\n resolvers.set(entry.fileFullpath, pageLayoutResolver(entry));\n }\n }\n }\n\n return resolvers;\n };\n\n const routeFiles = await scanRoutes({ appRoot, sourceFolder });\n\n return {\n resolvers: resolversFactory(routeFiles),\n resolversFactory,\n };\n};\n", "import { dirname, join, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\nimport picomatch from \"picomatch\";\nimport { glob } from \"tinyglobby\";\n\nimport {\n type ApiRoute,\n defaults,\n type PageRoute,\n type PluginOptionsResolved,\n pathResolver,\n pathTokensFactory,\n type ResolvedEntry,\n type RouteEntry,\n render,\n renderToFile,\n} from \"@kosmojs/devlib\";\n\nimport { resolveRouteSignature, typeResolverFactory } from \"../ast\";\nimport { cacheFactory } from \"../cache\";\nimport resolvedTypesTpl from \"../templates/resolved-types.hbs\";\nimport typesFileTpl from \"../templates/types.hbs\";\n\nexport type ResolverSignature = {\n name: string;\n handler: (updatedFile?: string) => Promise<ResolvedEntry>;\n};\n\nexport const API_INDEX_BASENAME = \"index\";\nexport const API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;\n\nexport const API_USE_BASENAME = \"use\";\nexport const API_USE_PATTERN = `${API_USE_BASENAME}.ts`;\n\nexport const PAGE_INDEX_BASENAME = \"index\";\nexport const PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;\n\nexport const PAGE_LAYOUT_BASENAME = \"layout\";\nexport const PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;\n\nconst ROUTE_FILE_PATTERNS = [\n // match index files in api dir\n `${defaults.apiDir}/**/${API_INDEX_PATTERN}`,\n // match use files in api dir\n `${defaults.apiDir}/**/${API_USE_PATTERN}`,\n // match index files in pages dir\n `${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,\n // match layout files in pages dir\n `${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`,\n];\n\nexport const scanRoutes = async ({\n appRoot,\n sourceFolder,\n}: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">) => {\n return glob(ROUTE_FILE_PATTERNS, {\n cwd: resolve(appRoot, sourceFolder),\n absolute: true,\n onlyFiles: true,\n followSymbolicLinks: false,\n ignore: [\n // ignore top-level matches, routes resides in folders, even index route\n `${defaults.apiDir}/${API_INDEX_PATTERN}`,\n `${defaults.apiDir}/${API_USE_PATTERN}`,\n `${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,\n `${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`,\n ],\n });\n};\n\nexport const isRouteFile = (\n file: string,\n {\n appRoot,\n sourceFolder,\n }: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">,\n):\n | [\n // Either `apiDir` or `pagesDir`\n folder: string,\n // Path to a file within the folder, nested at least one level deep\n file: string,\n ]\n | undefined => {\n const [_sourceFolder, folder, ...rest] = resolve(appRoot, file)\n .replace(`${appRoot}/`, \"\")\n .split(\"/\");\n\n /**\n * Ensure the file:\n * - is under the correct source root (`sourceFolder`)\n * - belongs to a known route folder (`apiDir` or `pagesDir`)\n * - is nested at least one level deep (not a direct child of the folder)\n * */\n if (!folder || _sourceFolder !== sourceFolder || rest.length < 2) {\n return;\n }\n\n return picomatch.isMatch(join(folder, ...rest), ROUTE_FILE_PATTERNS)\n ? [folder, rest.join(\"/\")]\n : undefined;\n};\n\nexport const isApiRoute = (file: string) => {\n return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);\n};\n\nexport const isApiUse = (file: string) => {\n return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);\n};\n\nexport const isPageRoute = (file: string) => {\n return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);\n};\n\nexport const isPageLayout = (file: string) => {\n return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);\n};\n\nexport const createRouteEntry = (\n _file: string,\n {\n appRoot,\n sourceFolder,\n }: Pick<PluginOptionsResolved, \"appRoot\" | \"sourceFolder\">,\n): RouteEntry | undefined => {\n // scanner already is doing a great job on matching only relevant files\n // but doing a double check here to make sure only needed files added to stack\n const resolvedPaths = isRouteFile(_file, { appRoot, sourceFolder });\n\n if (!resolvedPaths) {\n return;\n }\n\n const [folder, file] = resolvedPaths;\n\n const fileFullpath = join(appRoot, sourceFolder, folder, file);\n\n const pathTokens = pathTokensFactory(dirname(file));\n\n const name = pathTokens.map((e) => e.orig).join(\"/\");\n\n const importFile = file;\n\n const importName = `${importFile.replace(/\\W+/g, \"_\")}_${crc(importFile)}`;\n\n return {\n name,\n folder,\n file,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n };\n};\n\ntype ResolverFactory = (\n pluginOptions: PluginOptionsResolved,\n) => (entry: RouteEntry) => ResolverSignature;\n\nexport const pageLayoutResolverFactory: ResolverFactory = () => {\n return (entry) => {\n const { name } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async () => {\n return {\n kind: \"pageLayout\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n\nexport const pageRouteResolverFactory: ResolverFactory = () => {\n return (entry) => {\n const {\n name,\n folder,\n file,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async () => {\n const entry: PageRoute = {\n name,\n pathTokens,\n params: {\n schema: pathTokens.flatMap((e) => (e.param ? [e.param] : [])),\n },\n folder,\n file,\n fileFullpath,\n importFile,\n importName,\n };\n\n return {\n kind: \"pageRoute\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n\nexport const apiUseResolverFactory: ResolverFactory = () => {\n return (entry) => {\n const { name } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async () => {\n return {\n kind: \"apiUse\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n\nexport const apiRouteResolverFactory: ResolverFactory = (pluginOptions) => {\n const {\n appRoot,\n sourceFolder,\n generators = [],\n formatters = [],\n refineTypeName,\n } = pluginOptions;\n\n let resolveTypes = false;\n\n for (const { options } of generators) {\n if (options?.resolveTypes) {\n resolveTypes = true;\n }\n }\n\n const {\n //\n literalTypesResolver,\n getSourceFile,\n refreshSourceFile,\n } = typeResolverFactory(pluginOptions);\n\n return (entry) => {\n const {\n name,\n file,\n folder,\n fileFullpath,\n pathTokens,\n importFile,\n importName,\n } = entry;\n\n const handler: ResolverSignature[\"handler\"] = async (updatedFile) => {\n const paramsSchema = pathTokens.flatMap((e) => {\n return e.param ? [e.param] : [];\n });\n\n const optionalParams = paramsSchema.length\n ? !paramsSchema.some((e) => e.isRequired)\n : true;\n\n const { getCache, persistCache } = cacheFactory(\n { file, fileFullpath, importName },\n {\n appRoot,\n sourceFolder,\n extraContext: { resolveTypes },\n },\n );\n\n let cache = await getCache({ validate: true });\n\n if (!cache) {\n if (updatedFile === fileFullpath) {\n await refreshSourceFile(fileFullpath);\n }\n\n const {\n typeDeclarations,\n paramsRefinements,\n methods,\n payloadTypes,\n responseTypes,\n referencedFiles = [],\n } = await resolveRouteSignature(\n { importName, fileFullpath, optionalParams },\n {\n withReferencedFiles: true,\n sourceFile: getSourceFile(fileFullpath),\n relpathResolver(path) {\n return join(sourceFolder, defaults.apiDir, dirname(file), path);\n },\n },\n );\n\n const numericParams = paramsRefinements\n ? paramsRefinements.flatMap(({ text, index }) => {\n if (text === \"number\") {\n const param = paramsSchema.at(index);\n return param ? [param.name] : [];\n }\n return [];\n })\n : [];\n\n const typesFile = pathResolver({ appRoot, sourceFolder }).resolve(\n \"apiLibDir\",\n dirname(file),\n \"types.ts\",\n );\n\n const params: ApiRoute[\"params\"] = {\n id: [\"ParamsT\", crc(name)].join(\"\"),\n schema: paramsSchema,\n resolvedType: undefined,\n };\n\n const typesFileContent = render(typesFileTpl, {\n params,\n paramsSchema: paramsSchema.map((param, index) => {\n return {\n ...param,\n refinement: paramsRefinements?.at(index),\n };\n }),\n typeDeclarations,\n payloadTypes,\n responseTypes,\n });\n\n const resolvedTypes = resolveTypes\n ? literalTypesResolver(typesFileContent, {\n overrides: [...payloadTypes, ...responseTypes].reduce(\n (map: Record<string, string>, { id, skipValidation }) => {\n if (skipValidation) {\n map[id] = \"never\";\n }\n return map;\n },\n { [refineTypeName]: refineTypeName },\n ),\n withProperties: [params.id, ...payloadTypes.map((e) => e.id)],\n formatters,\n })\n : undefined;\n\n /**\n * Deploy types.ts file; required by core generators (like fetch).\n * If types resolved, write resolved types;\n * otherwise write original types extracted from API route.\n * */\n await renderToFile(\n typesFile,\n resolvedTypes ? resolvedTypesTpl : typesFileContent,\n { resolvedTypes },\n );\n\n params.resolvedType = resolvedTypes?.find((e) => e.name === params.id);\n\n cache = await persistCache({\n params,\n methods,\n typeDeclarations,\n numericParams,\n // text was needed at writing types.ts file, dropping from cache\n payloadTypes: payloadTypes.map(({ text, ...rest }) => {\n return {\n ...rest,\n resolvedType: resolvedTypes?.find((e) => e.name === rest.id),\n };\n }),\n responseTypes: responseTypes.map(({ text, ...rest }) => {\n return {\n ...rest,\n resolvedType: resolvedTypes?.find((e) => e.name === rest.id),\n };\n }),\n referencedFiles,\n });\n }\n\n const entry: ApiRoute = {\n name,\n pathTokens,\n params: cache.params,\n numericParams: cache.numericParams,\n optionalParams,\n importName,\n importFile,\n folder,\n file,\n fileFullpath,\n methods: cache.methods,\n typeDeclarations: cache.typeDeclarations,\n payloadTypes: cache.payloadTypes,\n responseTypes: cache.responseTypes,\n referencedFiles: Object.keys(cache.referencedFiles).map(\n // expand referenced files path,\n // they are stored as relative in cache\n (e) => resolve(appRoot, e),\n ),\n };\n\n return {\n kind: \"apiRoute\",\n entry,\n };\n };\n\n return { name, handler };\n };\n};\n", "import { resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\nimport { flattener } from \"tfusion\";\nimport {\n type CallExpression,\n type Identifier,\n type Node,\n Project,\n type ProjectOptions,\n type SourceFile,\n SyntaxKind,\n} from \"ts-morph\";\n\nimport { type HTTPMethod, HTTPMethods } from \"@kosmojs/api\";\nimport type {\n ApiRoute,\n PayloadType,\n PluginOptionsResolved,\n ResponseType,\n TypeDeclaration,\n} from \"@kosmojs/devlib\";\n\ntype PathResolver = (path: string) => string;\n\nexport const createProject = (opts?: ProjectOptions) => new Project(opts);\n\nexport const resolveRouteSignature = async (\n route: Pick<ApiRoute, \"importName\" | \"fileFullpath\" | \"optionalParams\">,\n opts?: {\n relpathResolver?: PathResolver;\n sourceFile?: SourceFile;\n withReferencedFiles?: boolean;\n },\n) => {\n const {\n sourceFile = createProject().addSourceFileAtPath(route.fileFullpath),\n } = { ...opts };\n\n const [typeDeclarations, referencedFiles] = extractTypeDeclarations(\n sourceFile,\n opts,\n );\n\n const defaultExport = extractDefaultExport(sourceFile);\n\n const paramsRefinements = defaultExport\n ? extractParamsRefinements(defaultExport)\n : undefined;\n\n const methods = defaultExport\n ? extractRouteMethods(defaultExport, route)\n : [];\n\n const payloadTypes = methods.flatMap((e) => {\n return e.payloadType ? [e.payloadType] : [];\n });\n\n const responseTypes = methods.flatMap((e) => {\n return e.responseType ? [e.responseType] : [];\n });\n\n return {\n typeDeclarations,\n paramsRefinements,\n methods: methods.map((e) => e.method),\n payloadTypes,\n responseTypes,\n referencedFiles,\n };\n};\n\nexport const extractDefaultExport = (\n sourceFile: SourceFile,\n): CallExpression | undefined => {\n const [defaultExport] = sourceFile\n .getExportAssignments()\n .flatMap((exportAssignment) => {\n if (exportAssignment.isExportEquals()) {\n return [];\n }\n const callExpression = exportAssignment.getExpression();\n return callExpression.isKind(SyntaxKind.CallExpression)\n ? [callExpression]\n : [];\n });\n return defaultExport;\n};\n\nexport const extractParamsRefinements = (\n callExpression: CallExpression,\n):\n | Array<{\n index: number;\n text: string;\n }>\n | undefined => {\n const [firstGeneric] = extractGenerics(callExpression);\n\n if (!firstGeneric?.node.isKind(SyntaxKind.TupleType)) {\n return;\n }\n\n const tupleElements = firstGeneric.node.getElements();\n\n if (!tupleElements?.length) {\n return;\n }\n\n return tupleElements.map((node, index) => {\n return {\n index,\n text: node.getText(),\n };\n });\n};\n\nexport const extractRouteMethods = (\n callExpression: CallExpression,\n route: Pick<ApiRoute, \"importName\" | \"optionalParams\">,\n): Array<{\n method: HTTPMethod;\n payloadType: (PayloadType & { text: string }) | undefined;\n responseType: (ResponseType & { text: string }) | undefined;\n}> => {\n const funcDeclaration =\n callExpression.getFirstChildByKind(SyntaxKind.ArrowFunction) ||\n callExpression.getFirstChildByKind(SyntaxKind.FunctionExpression);\n\n if (!funcDeclaration) {\n return [];\n }\n\n const arrayLiteralExpression = funcDeclaration.getFirstChildByKind(\n SyntaxKind.ArrayLiteralExpression,\n );\n\n if (!arrayLiteralExpression) {\n return [];\n }\n\n const callExpressions: Array<[CallExpression, HTTPMethod]> = [];\n\n for (const e of arrayLiteralExpression.getChildrenOfKind(\n SyntaxKind.CallExpression,\n )) {\n const name = e.getExpression().getText() as HTTPMethod;\n if (HTTPMethods[name]) {\n callExpressions.push([e, name]);\n }\n }\n\n const methods = [];\n\n const skipValidationFilter = (e: string) => /@skip-validation/.test(e);\n\n for (const [callExpression, method] of callExpressions) {\n const [payloadGeneric, responseGeneric] = extractGenerics(callExpression);\n\n const payloadText = payloadGeneric?.node\n ? payloadGeneric.node.getChildren().length === 0\n ? \"{}\"\n : payloadGeneric.node.getFullText()\n : undefined;\n\n const responseText = responseGeneric?.node.getText();\n\n const responseType = responseText\n ? {\n id: [\"ResponseT\", crc(route.importName + method)].join(\"\"),\n method,\n skipValidation: responseGeneric?.comments\n ? responseGeneric.comments.some(skipValidationFilter)\n : false,\n text: [\"never\", \"object\"].includes(responseText)\n ? \"{}\"\n : responseText,\n resolvedType: undefined,\n }\n : undefined;\n\n const payloadType = payloadText\n ? {\n id: [\"PayloadT\", crc(route.importName + method)].join(\"\"),\n responseTypeId: responseType?.id,\n method,\n skipValidation: payloadGeneric?.comments\n ? payloadGeneric.comments.some(skipValidationFilter)\n : false,\n isOptional: payloadText\n ? payloadText === \"{}\" || route.optionalParams\n : true,\n text: payloadText,\n resolvedType: undefined,\n }\n : undefined;\n\n methods.push({\n method,\n payloadType,\n responseType,\n });\n }\n\n return methods;\n};\n\nexport const extractTypeDeclarations = (\n sourceFile: SourceFile,\n opts?: {\n relpathResolver?: PathResolver;\n withReferencedFiles?: boolean;\n },\n): [d: Array<TypeDeclaration>, f?: Array<string>] => {\n const declarations: Array<TypeDeclaration> = [];\n\n const referencedFiles: Array<string> | undefined = opts?.withReferencedFiles\n ? []\n : undefined;\n\n for (const declaration of sourceFile.getImportDeclarations()) {\n const modulePath = declaration.getModuleSpecifierValue();\n\n const path = /^\\.\\.?\\/?/.test(modulePath)\n ? opts?.relpathResolver\n ? opts.relpathResolver(modulePath)\n : modulePath\n : modulePath;\n\n const typeOnlyDeclaration = declaration.isTypeOnly();\n\n const defaultImport = typeOnlyDeclaration\n ? declaration.getDefaultImport()\n : undefined;\n\n if (defaultImport) {\n const name = defaultImport.getText();\n const text = `import type ${name} from \"${path}\";`;\n declarations.push({\n importDeclaration: {\n name,\n path,\n },\n text,\n });\n if (referencedFiles) {\n referencedFiles.push(...getReferencedFiles(defaultImport));\n }\n }\n\n for (const namedImport of declaration.getNamedImports()) {\n if (namedImport.isTypeOnly() || typeOnlyDeclaration) {\n const nameNode = namedImport.getNameNode();\n const name = nameNode.getText();\n const alias = namedImport.getAliasNode()?.getText();\n const nameText = alias ? `${name} as ${alias}` : name;\n\n declarations.push({\n importDeclaration: {\n name,\n alias,\n path,\n },\n text: `import type { ${nameText} } from \"${path}\";`,\n });\n\n if (referencedFiles) {\n if (nameNode.isKind(SyntaxKind.Identifier)) {\n referencedFiles.push(...getReferencedFiles(nameNode));\n }\n }\n }\n }\n }\n\n for (const declaration of sourceFile.getTypeAliases()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n typeAliasDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getInterfaces()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n interfaceDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getEnums()) {\n const name = declaration.getName();\n const text = declaration.getFullText().trim();\n declarations.push({\n enumDeclaration: { name },\n text,\n });\n }\n\n for (const declaration of sourceFile.getExportDeclarations()) {\n const typeOnlyDeclaration = declaration.isTypeOnly();\n\n const modulePath = declaration.getModuleSpecifierValue();\n\n const path = modulePath\n ? /^\\.\\.?\\/?/.test(modulePath)\n ? opts?.relpathResolver\n ? opts.relpathResolver(modulePath)\n : modulePath\n : modulePath\n : undefined;\n\n for (const namedExport of declaration.getNamedExports()) {\n if (namedExport.isTypeOnly() || typeOnlyDeclaration) {\n const nameNode = namedExport.getNameNode();\n const name = nameNode.getText();\n const alias = namedExport.getAliasNode()?.getText();\n const nameText = alias ? `${name} as ${alias}` : name;\n\n declarations.push({\n exportDeclaration: {\n name,\n alias: alias ?? name,\n path,\n },\n text: path\n ? `export type { ${nameText} } from \"${path}\";`\n : `export type { ${nameText} };`,\n });\n\n if (referencedFiles) {\n if (nameNode.isKind(SyntaxKind.Identifier)) {\n referencedFiles.push(...getReferencedFiles(nameNode));\n }\n }\n }\n }\n }\n\n return referencedFiles\n ? [declarations, [...new Set<string>(referencedFiles)]]\n : [declarations];\n};\n\nconst getReferencedFiles = (importIdentifier: Identifier): Array<string> => {\n // ambient modules may have declarations in multiple files\n const declarations =\n importIdentifier //\n ?.getSymbol()\n ?.getAliasedSymbol()\n ?.getDeclarations() || [];\n\n return declarations.flatMap((e) => {\n const sourceFile = e.getSourceFile();\n return sourceFile //\n ? [sourceFile.getFilePath()]\n : [];\n });\n};\n\nconst extractGenerics = (\n callExpression: CallExpression,\n): Array<{ node: Node; comments: Array<string> }> => {\n return callExpression.getTypeArguments().map((node) => {\n return {\n node,\n comments: node\n .getLeadingCommentRanges()\n .map((range) => range.getText().trim()),\n };\n });\n};\n\nexport const typeResolverFactory = ({ appRoot }: PluginOptionsResolved) => {\n const project = createProject({\n tsConfigFilePath: resolve(appRoot, \"tsconfig.json\"),\n skipAddingFilesFromTsConfig: true,\n });\n\n const literalTypesResolver = (\n literalTypes: string,\n options: Parameters<typeof flattener>[2],\n ) => {\n const sourceFile = project.createSourceFile(\n `${crc(literalTypes)}-${Date.now()}.ts`,\n literalTypes,\n { overwrite: true },\n );\n\n const resolvedTypes = flattener(project, sourceFile, {\n ...options,\n stripComments: true,\n });\n\n project.removeSourceFile(sourceFile);\n\n return resolvedTypes;\n };\n\n return {\n getSourceFile: (fileFullpath: string) => {\n return (\n project.getSourceFile(fileFullpath) ||\n project.addSourceFileAtPath(fileFullpath)\n );\n },\n refreshSourceFile: async (fileFullpath: string) => {\n const sourceFile = project.getSourceFile(fileFullpath);\n if (sourceFile) {\n await sourceFile.refreshFromFileSystem();\n }\n },\n literalTypesResolver,\n };\n};\n", "import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport crc from \"crc/crc32\";\n\n/**\n * Import from published package to ensure correct version at runtime.\n * Local import would be bundled with pre-bump version; this external\n * import resolves to the actual published package.json.\n * */\nimport self from \"@kosmojs/dev/package.json\" with { type: \"json\" };\nimport { type ApiRoute, pathExists, pathResolver } from \"@kosmojs/devlib\";\n\nexport type Cache = {\n hash: number;\n referencedFiles: Record<string, number>;\n} & Pick<\n ApiRoute,\n | \"params\"\n | \"methods\"\n | \"typeDeclarations\"\n | \"numericParams\"\n | \"payloadTypes\"\n | \"responseTypes\"\n>;\n\ntype ExtraContext = Record<string | number, unknown>;\n\nexport const cacheFactory = (\n route: Pick<ApiRoute, \"file\" | \"fileFullpath\" | \"importName\">,\n {\n appRoot,\n sourceFolder,\n extraContext,\n }: {\n appRoot: string;\n sourceFolder: string;\n extraContext?: ExtraContext;\n },\n) => {\n const cacheFile = pathResolver({\n appRoot,\n sourceFolder,\n }).resolve(\"apiLibDir\", dirname(route.file), \"cache.json\");\n\n const getCache = async (opt?: {\n validate?: boolean;\n }): Promise<Cache | undefined> => {\n if (await pathExists(cacheFile)) {\n try {\n const cache = JSON.parse(await readFile(cacheFile, \"utf8\"));\n return opt?.validate //\n ? validateCache(cache)\n : cache;\n } catch (_e) {}\n }\n return undefined;\n };\n\n const persistCache = async ({\n referencedFiles: _referencedFiles,\n ...rest\n }: Omit<Cache, \"hash\" | \"referencedFiles\"> & {\n referencedFiles: Array<string>;\n }): Promise<Cache> => {\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n const referencedFiles: Cache[\"referencedFiles\"] = {};\n\n for (const file of _referencedFiles) {\n referencedFiles[\n // Strip project root to ensure cached paths are relative\n // and portable across environments (CI, local, etc.)\n file.replace(`${appRoot}/`, \"\")\n ] = await generateFileHash(file);\n }\n\n const cache = { ...rest, hash, referencedFiles };\n\n await mkdir(dirname(cacheFile), { recursive: true });\n await writeFile(cacheFile, JSON.stringify(cache, null, 2), \"utf8\");\n\n return cache;\n };\n\n const validateCache = async (\n cache: Cache | undefined,\n ): Promise<Cache | undefined> => {\n if (!cache?.hash) {\n return;\n }\n\n if (!cache.typeDeclarations || !cache.referencedFiles) {\n // incomplete cache\n return;\n }\n\n const hash = await generateFileHash(route.fileFullpath, {\n ...extraContext,\n });\n\n if (!identicalHashSum(cache.hash, hash)) {\n // route itself updated\n return;\n }\n\n for (const [file, hash] of Object.entries(cache.referencedFiles)) {\n if (\n !identicalHashSum(hash, await generateFileHash(resolve(appRoot, file)))\n ) {\n // some referenced file updated\n return;\n }\n }\n\n return cache;\n };\n\n return {\n getCache,\n validateCache,\n persistCache,\n };\n};\n\nconst generateFileHash = async (\n file: string,\n extraContext?: ExtraContext,\n): Promise<number> => {\n let fileContent: string | undefined;\n try {\n fileContent = await readFile(file, \"utf8\");\n } catch (_e) {\n // file could be deleted since last build\n return 0;\n }\n return fileContent\n ? crc(\n JSON.stringify({\n ...extraContext,\n [self.cacheVersion]: fileContent,\n }),\n )\n : 0;\n};\n\n// return true if sums are identical\nconst identicalHashSum = (a: number, b: number) => {\n return a === b;\n};\n", "{{#each resolvedTypes}}\nexport type {{name}} = {{text}};\n{{/each}}\n", "{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport type {{params.id}} = {\n {{#each paramsSchema}}\n \"{{name}}\"{{#unless isRequired}}?{{/unless}}:{{#if isRest}} Array<{{/if}}\n {{#if refinement}}{{refinement.text}}{{else}}string{{/if}}\n {{#if isRest}}>{{/if}}\n {{/each}}\n};\n\n{{#each payloadTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n\n{{#each responseTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n", "import { basename } from \"node:path\";\n\nimport {\n type NestedRouteEntry,\n type RouteEntry,\n sortRoutes,\n} from \"@kosmojs/devlib\";\n\nimport { PAGE_INDEX_BASENAME, PAGE_LAYOUT_BASENAME } from \"./resolve\";\n\n/**\n * Build a nested route tree from flat route entries.\n * */\nexport const nestedRoutesFactory = (routeEntries: Array<RouteEntry>) => {\n const entryStack = structuredClone(routeEntries).sort(sortRoutes);\n\n /**\n * Group entries by name (at the same level, both layout and index share same name).\n *\n * Handle 3 cases:\n * - both index and layout exists\n * - only index exists\n * - only layout exists\n *\n * */\n const transformEntries = (\n entries: Array<RouteEntry>,\n parent?: RouteEntry,\n ): Array<NestedRouteEntry> => {\n return [...new Set(entries.map((e) => e.name))].flatMap((name) => {\n const nameEntries = entryStack.flatMap(({ fileFullpath, ...entry }) => {\n return entry.name === name ? [entry] : [];\n });\n\n const index = nameEntries.find((e) =>\n basename(e.file).startsWith(PAGE_INDEX_BASENAME),\n ) as RouteEntry;\n\n const layout = nameEntries.find((e) =>\n basename(e.file).startsWith(PAGE_LAYOUT_BASENAME),\n ) as RouteEntry;\n\n if (index || layout) {\n return [\n {\n index: index\n ? {\n ...index,\n pathTokens: index.pathTokens.slice(\n parent?.pathTokens.length || 0,\n ),\n }\n : undefined,\n layout: layout\n ? {\n ...layout,\n pathTokens: layout.pathTokens.slice(\n parent?.pathTokens.length || 0,\n ),\n }\n : undefined,\n parent: parent?.name,\n children: transformEntries(\n findDescendantEntries(index || layout),\n index || layout,\n ),\n },\n ];\n }\n\n return [];\n });\n };\n\n /**\n * Recursively finds direct descendant routes.\n *\n * \"Direct\" means the next existing route in the path hierarchy,\n * skipping intermediate path segments that don't have index/layout files.\n *\n * Example: blog/post/[slug]/index.tsx is a direct child of blog/index.tsx\n * even though \"post\" segment exists (it has no index.tsx).\n * */\n const findDescendantEntries = ({\n name,\n pathTokens,\n }: RouteEntry): Array<RouteEntry> => {\n // Find all potential children - BOTH indexes AND layouts\n const potentialChildren = entryStack.filter((entry) => {\n // Must be deeper than current entry\n if (entry.pathTokens.length <= pathTokens.length) {\n return false;\n }\n // Must be a descendant path\n if (!entry.name.startsWith(`${name}/`)) {\n return false;\n }\n return true;\n });\n\n // Filter to direct children (no intermediate route between parent and child)\n return potentialChildren.filter((child) => {\n // Check if any route exists between parent and child\n const hasIntermediateRoute = potentialChildren.some((intermediate) => {\n if (intermediate === child) {\n return false;\n }\n // Intermediate must be between parent and child in depth\n if (intermediate.pathTokens.length <= pathTokens.length) {\n return false;\n }\n if (intermediate.pathTokens.length >= child.pathTokens.length) {\n return false;\n }\n // Child must be descendant of intermediate\n return child.name.startsWith(`${intermediate.name}/`);\n });\n\n return !hasIntermediateRoute;\n });\n };\n\n // Find root entries - entries that have no parent route\n const rootEntries = entryStack.filter((entry) => {\n // Check if any other entry could be its parent\n const hasParent = entryStack.some((potential) => {\n if (potential === entry) {\n return false;\n }\n if (potential.pathTokens.length >= entry.pathTokens.length) {\n return false;\n }\n return entry.name.startsWith(`${potential.name}/`);\n });\n\n return !hasParent;\n });\n\n return transformEntries(rootEntries);\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["defaults", "dirname", "resolve", "crc", "pathResolver", "callExpression", "resolve", "crc", "hash", "resolve", "dirname", "crc", "entry", "pathResolver", "routeFiles", "defaults"]
|
|
7
7
|
}
|
|
@@ -377,6 +377,8 @@ var types_default = '{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport typ
|
|
|
377
377
|
// src/base-plugin/routes/resolve.ts
|
|
378
378
|
var API_INDEX_BASENAME = "index";
|
|
379
379
|
var API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;
|
|
380
|
+
var API_USE_BASENAME = "use";
|
|
381
|
+
var API_USE_PATTERN = `${API_USE_BASENAME}.ts`;
|
|
380
382
|
var PAGE_INDEX_BASENAME = "index";
|
|
381
383
|
var PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;
|
|
382
384
|
var PAGE_LAYOUT_BASENAME = "layout";
|
|
@@ -384,6 +386,8 @@ var PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;
|
|
|
384
386
|
var ROUTE_FILE_PATTERNS = [
|
|
385
387
|
// match index files in api dir
|
|
386
388
|
`${defaults.apiDir}/**/${API_INDEX_PATTERN}`,
|
|
389
|
+
// match use files in api dir
|
|
390
|
+
`${defaults.apiDir}/**/${API_USE_PATTERN}`,
|
|
387
391
|
// match index files in pages dir
|
|
388
392
|
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
389
393
|
// match layout files in pages dir
|
|
@@ -401,6 +405,7 @@ var scanRoutes = async ({
|
|
|
401
405
|
ignore: [
|
|
402
406
|
// ignore top-level matches, routes resides in folders, even index route
|
|
403
407
|
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
408
|
+
`${defaults.apiDir}/${API_USE_PATTERN}`,
|
|
404
409
|
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,
|
|
405
410
|
`${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`
|
|
406
411
|
]
|
|
@@ -416,8 +421,17 @@ var isRouteFile = (file, {
|
|
|
416
421
|
}
|
|
417
422
|
return picomatch.isMatch(join(folder, ...rest), ROUTE_FILE_PATTERNS) ? [folder, rest.join("/")] : void 0;
|
|
418
423
|
};
|
|
419
|
-
var
|
|
420
|
-
return picomatch.matchBase(file, `**/${
|
|
424
|
+
var isApiRoute = (file) => {
|
|
425
|
+
return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);
|
|
426
|
+
};
|
|
427
|
+
var isApiUse = (file) => {
|
|
428
|
+
return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);
|
|
429
|
+
};
|
|
430
|
+
var isPageRoute = (file) => {
|
|
431
|
+
return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);
|
|
432
|
+
};
|
|
433
|
+
var isPageLayout = (file) => {
|
|
434
|
+
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
421
435
|
};
|
|
422
436
|
var createRouteEntry = (_file, {
|
|
423
437
|
appRoot: appRoot2,
|
|
@@ -487,6 +501,18 @@ var pageRouteResolverFactory = () => {
|
|
|
487
501
|
return { name, handler };
|
|
488
502
|
};
|
|
489
503
|
};
|
|
504
|
+
var apiUseResolverFactory = () => {
|
|
505
|
+
return (entry) => {
|
|
506
|
+
const { name } = entry;
|
|
507
|
+
const handler = async () => {
|
|
508
|
+
return {
|
|
509
|
+
kind: "apiUse",
|
|
510
|
+
entry
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
return { name, handler };
|
|
514
|
+
};
|
|
515
|
+
};
|
|
490
516
|
var apiRouteResolverFactory = (pluginOptions) => {
|
|
491
517
|
const {
|
|
492
518
|
appRoot: appRoot2,
|
|
@@ -660,6 +686,7 @@ import {
|
|
|
660
686
|
var routes_default = async (pluginOptions) => {
|
|
661
687
|
const { appRoot: appRoot2, sourceFolder: sourceFolder2 } = pluginOptions;
|
|
662
688
|
const apiRouteResolver = apiRouteResolverFactory(pluginOptions);
|
|
689
|
+
const apiUseResolver = apiUseResolverFactory(pluginOptions);
|
|
663
690
|
const pageRouteResolver = pageRouteResolverFactory(pluginOptions);
|
|
664
691
|
const pageLayoutResolver = pageLayoutResolverFactory(pluginOptions);
|
|
665
692
|
const resolversFactory2 = (routeFiles2) => {
|
|
@@ -670,12 +697,15 @@ var routes_default = async (pluginOptions) => {
|
|
|
670
697
|
});
|
|
671
698
|
for (const entry of entries) {
|
|
672
699
|
if (entry.folder === defaults2.apiDir) {
|
|
673
|
-
|
|
700
|
+
if (isApiRoute(entry.file)) {
|
|
701
|
+
resolvers2.set(entry.fileFullpath, apiRouteResolver(entry));
|
|
702
|
+
} else if (isApiUse(entry.file)) {
|
|
703
|
+
resolvers2.set(entry.fileFullpath, apiUseResolver(entry));
|
|
704
|
+
}
|
|
674
705
|
} else if (entry.folder === defaults2.pagesDir) {
|
|
675
|
-
|
|
676
|
-
if (pageFile?.kind === "index") {
|
|
706
|
+
if (isPageRoute(entry.file)) {
|
|
677
707
|
resolvers2.set(entry.fileFullpath, pageRouteResolver(entry));
|
|
678
|
-
} else if (
|
|
708
|
+
} else if (isPageLayout(entry.file)) {
|
|
679
709
|
resolvers2.set(entry.fileFullpath, pageLayoutResolver(entry));
|
|
680
710
|
}
|
|
681
711
|
}
|