@kosmojs/lib 0.5.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -6
- package/package.json +11 -8
- package/pkg/ast.d.ts +2 -2
- package/pkg/format.d.ts +2 -0
- package/pkg/generators.d.ts +4 -4
- package/pkg/generic.d.ts +3 -0
- package/pkg/index.d.ts +12 -0
- package/pkg/index.js +189 -46
- package/pkg/index.js.map +1 -1
- package/pkg/paths.d.ts +2 -4
- package/pkg/ports.d.ts +19 -0
- package/pkg/routes/base.d.ts +4 -4
- package/pkg/routes/index.d.ts +2 -2
- package/pkg/routes/resolve.d.ts +2 -2
- package/pkg/tsconfig.d.ts +65 -0
- package/pkg/vite.d.ts +5 -4
package/README.md
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# @kosmojs/lib
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Internal toolkit shared by the CLI and the generators.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Scope
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Published because [`@kosmojs/cli`](https://www.npmjs.com/package/@kosmojs/cli),
|
|
8
|
+
[`@kosmojs/dev`](https://www.npmjs.com/package/@kosmojs/dev) and the generators depend on it - **not** intended for direct use.
|
|
9
|
+
It carries no stability guarantee across releases and can change shape in a patch.
|
|
10
|
+
|
|
11
|
+
It holds the pieces those packages need in common: TypeScript AST helpers for resolving validation types,
|
|
12
|
+
the generator base and file-deployment helpers, path and route utilities, the Handlebars render layer, and Vite helpers.
|
|
13
|
+
|
|
14
|
+
If you are writing a generator, depend on the documented contract in `@kosmojs/core/generators` instead.
|
|
10
15
|
|
|
11
16
|
## Documentation
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
- [Why code generation](https://kosmojs.dev/essentials/why-codegen.html)
|
|
19
|
+
|
|
20
|
+
Full documentation at [kosmojs.dev](https://kosmojs.dev).
|
|
14
21
|
|
|
15
22
|
## License
|
|
16
23
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@kosmojs/lib",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.6.2",
|
|
5
|
+
"description": "Shared internals for the KosmoJS CLI and generators (not a public API)",
|
|
5
6
|
"author": "Slee Woo",
|
|
6
7
|
"license": "MIT",
|
|
7
8
|
"repository": {
|
|
@@ -16,14 +17,16 @@
|
|
|
16
17
|
".": {
|
|
17
18
|
"types": "./pkg/index.d.ts",
|
|
18
19
|
"default": "./pkg/index.js"
|
|
19
|
-
}
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
20
22
|
},
|
|
21
23
|
"dependencies": {
|
|
22
|
-
"@kosmojs/core": "^0.
|
|
24
|
+
"@kosmojs/core": "^0.6.2",
|
|
23
25
|
"@topcli/spinner": "^5.0.0",
|
|
24
26
|
"crc": "^4.3.2",
|
|
25
|
-
"handlebars": "^4.7.
|
|
27
|
+
"handlebars": "^4.7.10",
|
|
26
28
|
"mrmime": "^2.0.1",
|
|
29
|
+
"oxfmt": "^0.72.0",
|
|
27
30
|
"path-to-regexp": "^8.4.2",
|
|
28
31
|
"picomatch": "^4.0.7",
|
|
29
32
|
"tfusion": "^0.2.2",
|
|
@@ -32,11 +35,11 @@
|
|
|
32
35
|
},
|
|
33
36
|
"devDependencies": {
|
|
34
37
|
"@koa/router": "^15.7.0",
|
|
35
|
-
"@kosmojs/lib": "^0.
|
|
38
|
+
"@kosmojs/lib": "^0.6.2",
|
|
36
39
|
"@types/picomatch": "^4.0.3",
|
|
37
|
-
"hono": "^4.13.
|
|
38
|
-
"rou3": "^0.
|
|
39
|
-
"vite": "^8.
|
|
40
|
+
"hono": "^4.13.13",
|
|
41
|
+
"rou3": "^1.0.0",
|
|
42
|
+
"vite": "^8.3.4"
|
|
40
43
|
},
|
|
41
44
|
"scripts": {
|
|
42
45
|
"build": "wsbuild src/index.ts",
|
package/pkg/ast.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import flattener from "tfusion";
|
|
2
2
|
import { type CallExpression, Project, type ProjectOptions, type SourceFile } from "ts-morph";
|
|
3
|
-
import type { ResolvedTypeSignature } from "@kosmojs/core";
|
|
3
|
+
import type { ProjectSettings, ResolvedTypeSignature } from "@kosmojs/core";
|
|
4
4
|
import { type ApiRoute, type SourceFolder, type TypeDeclaration, type ValidationDefinition } from "@kosmojs/core";
|
|
5
5
|
import { type HTTPMethod } from "@kosmojs/core/api";
|
|
6
6
|
type PathResolver = (path: string) => string;
|
|
@@ -33,7 +33,7 @@ export declare const astFactory: () => {
|
|
|
33
33
|
validationDefinitions: ValidationDefinition[];
|
|
34
34
|
referencedFiles: string[] | undefined;
|
|
35
35
|
}>;
|
|
36
|
-
typeResolverFactory: (sourceFolder: SourceFolder) => {
|
|
36
|
+
typeResolverFactory: (projectSettings: ProjectSettings, sourceFolder: SourceFolder) => {
|
|
37
37
|
getSourceFile: (fileFullpath: string) => SourceFile;
|
|
38
38
|
refreshSourceFile: (fileFullpath: string) => Promise<void>;
|
|
39
39
|
literalTypesResolver: (literalTypes: string, options: Parameters<typeof flattener>[2]) => Array<ResolvedTypeSignature>;
|
package/pkg/format.d.ts
ADDED
package/pkg/generators.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { GeneratorFactory, GeneratorSignature, ResolvedEntry, SourceFolder, WatcherEvent } from "@kosmojs/core";
|
|
1
|
+
import type { GeneratorFactory, GeneratorSignature, ProjectSettings, ResolvedEntry, SourceFolder, WatcherEvent } from "@kosmojs/core";
|
|
2
2
|
export declare const defineGenerator: <O extends object, R extends boolean = false>({ meta, factory, dependencies, devDependencies, }: Omit<GeneratorSignature<O>, "factory"> & {
|
|
3
|
-
factory: (f: SourceFolder, o?: O) => GeneratorFactory;
|
|
4
|
-
}) => [R] extends [true] ? (
|
|
5
|
-
export declare const defineGeneratorFactory: <O extends object>(factory: (f: SourceFolder, o?: O) => GeneratorFactory) => (f: SourceFolder, o?: O) => GeneratorFactory;
|
|
3
|
+
factory: (s: ProjectSettings, f: SourceFolder, o?: O) => GeneratorFactory;
|
|
4
|
+
}) => [R] extends [true] ? (o: O) => GeneratorSignature<O> : (o?: O) => GeneratorSignature<O>;
|
|
5
|
+
export declare const defineGeneratorFactory: <O extends object>(factory: (s: ProjectSettings, f: SourceFolder, o?: O) => GeneratorFactory) => (s: ProjectSettings, f: SourceFolder, o?: O) => GeneratorFactory;
|
|
6
6
|
/**
|
|
7
7
|
* Filter watched API routes by event.
|
|
8
8
|
* Handle 3 cases:
|
package/pkg/generic.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type UserConfig } from "vite";
|
|
2
|
+
import { type KosmoSettings } from "@kosmojs/core";
|
|
2
3
|
export declare const mergeConfigs: (...configs: Array<UserConfig | undefined>) => UserConfig;
|
|
3
4
|
export declare const escapeTemplateLiterals: (origin: string) => string;
|
|
4
5
|
export declare const containsPathTraversalPatterns: (str: string) => boolean;
|
|
6
|
+
export declare const configFilePattern: (folder: string) => string;
|
|
7
|
+
export declare const resolveHostAddress: (settings: KosmoSettings | undefined, key: "devHost" | "previewHost") => string;
|
package/pkg/index.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read the installed package.json at runtime to get the actual version.
|
|
3
|
+
* A static import would be inlined by the bundler with the pre-bump version.
|
|
4
|
+
*
|
|
5
|
+
* INFO: For best compatibility, all packages should share the same version.
|
|
6
|
+
* When bumping the version (even a patch) for a single package,
|
|
7
|
+
* bump it for all packages to keep versions fully synchronized across the project.
|
|
8
|
+
* */
|
|
9
|
+
export declare const VERSION: any;
|
|
1
10
|
export * from "./ast";
|
|
11
|
+
export * from "./format";
|
|
2
12
|
export * from "./generators";
|
|
3
13
|
export * from "./generic";
|
|
4
14
|
export * from "./paths";
|
|
15
|
+
export * from "./ports";
|
|
5
16
|
export * from "./render";
|
|
6
17
|
export * from "./routes";
|
|
7
18
|
export * from "./spinner";
|
|
19
|
+
export * from "./tsconfig";
|
|
8
20
|
export * from "./vite";
|
package/pkg/index.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { builtinModules } from "node:module";
|
|
1
|
+
import { builtinModules, createRequire } from "node:module";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
2
3
|
import { styleText } from "node:util";
|
|
3
4
|
import crc from "crc/crc32";
|
|
4
5
|
import flattener from "tfusion";
|
|
5
6
|
import { ModuleResolutionKind, Project, SyntaxKind } from "ts-morph";
|
|
6
|
-
import { RequestValidationTargets, defaults } from "@kosmojs/core";
|
|
7
|
+
import { DEFAULT_DIST, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PREVIEW_HOST, DEFAULT_PREVIEW_PORT, RequestValidationTargets, defaults } from "@kosmojs/core";
|
|
7
8
|
import { HTTPMethods } from "@kosmojs/core/api";
|
|
9
|
+
import { basename, dirname, isAbsolute, join, parse, posix, resolve } from "node:path";
|
|
8
10
|
import { mergeConfig } from "vite";
|
|
9
11
|
import { access, constants, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
10
|
-
import { basename, dirname, isAbsolute, join, parse, posix, resolve } from "node:path";
|
|
11
12
|
import handlebars from "handlebars";
|
|
13
|
+
import { format } from "oxfmt";
|
|
14
|
+
import net from "node:net";
|
|
12
15
|
import picomatch from "picomatch";
|
|
13
16
|
import { glob } from "tinyglobby";
|
|
14
17
|
import { compile, parse as parse$1 } from "path-to-regexp";
|
|
@@ -24,15 +27,27 @@ var escapeTemplateLiterals = (origin) => {
|
|
|
24
27
|
var containsPathTraversalPatterns = (str) => {
|
|
25
28
|
return [/\.\.\//, /\/\.\//].some((e) => e.test(str));
|
|
26
29
|
};
|
|
30
|
+
var configFilePattern = (folder) => {
|
|
31
|
+
return posix.join(defaults.srcDir, folder, "kosmo.config.ts");
|
|
32
|
+
};
|
|
33
|
+
var resolveHostAddress = (settings, key) => {
|
|
34
|
+
let [host, port] = key === "devHost" ? [DEFAULT_HOST, DEFAULT_PORT] : [DEFAULT_PREVIEW_HOST, DEFAULT_PREVIEW_PORT];
|
|
35
|
+
if (settings?.[key]) {
|
|
36
|
+
const url = new URL(`http://${settings[key]}`);
|
|
37
|
+
if (url.hostname) host = url.hostname;
|
|
38
|
+
if (url.port) port = Number(url.port);
|
|
39
|
+
}
|
|
40
|
+
return [host, port].join(":");
|
|
41
|
+
};
|
|
27
42
|
//#endregion
|
|
28
43
|
//#region src/paths.ts
|
|
29
|
-
var pathResolver = (
|
|
44
|
+
var pathResolver = ({ root, distDir = DEFAULT_DIST }, { name }) => {
|
|
30
45
|
const createPath = (...a) => {
|
|
31
|
-
return
|
|
46
|
+
return root ? resolve(root, join(...a)) : join(...a);
|
|
32
47
|
};
|
|
33
48
|
const createImport = {
|
|
34
49
|
src(a, { origin }) {
|
|
35
|
-
return origin === "src" ? join(defaults.srcPrefix, ...a) : join(defaults.appPrefix, defaults.srcDir,
|
|
50
|
+
return origin === "src" ? join(defaults.srcPrefix, ...a) : join(defaults.appPrefix, defaults.srcDir, name, ...a);
|
|
36
51
|
},
|
|
37
52
|
api(a, o) {
|
|
38
53
|
return this.src([defaults.apiDir, ...a], o);
|
|
@@ -44,7 +59,7 @@ var pathResolver = (sourceFolder) => {
|
|
|
44
59
|
return this.src([defaults.pagesDir, ...a], o);
|
|
45
60
|
},
|
|
46
61
|
lib(a, { origin }) {
|
|
47
|
-
return origin === "src" ? join(defaults.libPrefix, ...a) : join(defaults.appPrefix, defaults.libDir,
|
|
62
|
+
return origin === "src" ? join(defaults.libPrefix, ...a) : join(defaults.appPrefix, defaults.libDir, name, ...a);
|
|
48
63
|
},
|
|
49
64
|
libCore(a, o) {
|
|
50
65
|
return this.lib(["core", ...a], o);
|
|
@@ -59,7 +74,7 @@ var pathResolver = (sourceFolder) => {
|
|
|
59
74
|
return {
|
|
60
75
|
createPath: {
|
|
61
76
|
src(...a) {
|
|
62
|
-
return createPath(defaults.srcDir,
|
|
77
|
+
return createPath(defaults.srcDir, name, ...a);
|
|
63
78
|
},
|
|
64
79
|
api(...a) {
|
|
65
80
|
return this.src(defaults.apiDir, ...a);
|
|
@@ -71,7 +86,7 @@ var pathResolver = (sourceFolder) => {
|
|
|
71
86
|
return this.src(defaults.entryDir, ...a);
|
|
72
87
|
},
|
|
73
88
|
lib(...a) {
|
|
74
|
-
return createPath(defaults.libDir,
|
|
89
|
+
return createPath(defaults.libDir, name, ...a);
|
|
75
90
|
},
|
|
76
91
|
libCore(...a) {
|
|
77
92
|
return this.lib("core", ...a);
|
|
@@ -86,7 +101,7 @@ var pathResolver = (sourceFolder) => {
|
|
|
86
101
|
return this.lib(defaults.pagesDir, ...a);
|
|
87
102
|
},
|
|
88
103
|
distDir(...a) {
|
|
89
|
-
return createPath(
|
|
104
|
+
return createPath(distDir, name, ...a);
|
|
90
105
|
}
|
|
91
106
|
},
|
|
92
107
|
createImport,
|
|
@@ -446,15 +461,15 @@ var astFactory = () => {
|
|
|
446
461
|
const extractGenerics = (callExpression) => {
|
|
447
462
|
return callExpression.getTypeArguments();
|
|
448
463
|
};
|
|
449
|
-
const typeResolverFactory = (sourceFolder) => {
|
|
450
|
-
const { createPath } = pathResolver(sourceFolder);
|
|
464
|
+
const typeResolverFactory = (projectSettings, sourceFolder) => {
|
|
465
|
+
const { createPath } = pathResolver(projectSettings, sourceFolder);
|
|
451
466
|
const project = createProject({ compilerOptions: {
|
|
452
467
|
moduleResolution: ModuleResolutionKind.Bundler,
|
|
453
468
|
types: [],
|
|
454
469
|
noLib: true,
|
|
455
470
|
skipLibCheck: true,
|
|
456
471
|
paths: {
|
|
457
|
-
[`${defaults.appPrefix}/*`]: [`${
|
|
472
|
+
[`${defaults.appPrefix}/*`]: [`${projectSettings.root}/*`],
|
|
458
473
|
[`${defaults.srcPrefix}/*`]: [createPath.src("*")],
|
|
459
474
|
[`${defaults.libPrefix}/*`]: [createPath.lib("*")]
|
|
460
475
|
}
|
|
@@ -625,23 +640,27 @@ var renderTypeboxSchema = (typeNode, refineTypeName = defaults.refineTypeName) =
|
|
|
625
640
|
return escapeTemplateLiterals(traverse(typeNode));
|
|
626
641
|
};
|
|
627
642
|
//#endregion
|
|
643
|
+
//#region src/format.ts
|
|
644
|
+
var formatCode = async (code, filename, config) => {
|
|
645
|
+
return format(filename, code, {
|
|
646
|
+
sortImports: true,
|
|
647
|
+
...config
|
|
648
|
+
}).then((e) => e.errors.length ? code : e.code);
|
|
649
|
+
};
|
|
650
|
+
//#endregion
|
|
628
651
|
//#region src/generators.ts
|
|
629
652
|
var defineGenerator = ({ meta, factory, dependencies, devDependencies }) => {
|
|
630
|
-
|
|
653
|
+
return ((options) => {
|
|
631
654
|
return {
|
|
632
655
|
meta,
|
|
633
|
-
factory: (folder) =>
|
|
656
|
+
factory: (settings, folder) => {
|
|
657
|
+
return factory(settings, folder, options);
|
|
658
|
+
},
|
|
634
659
|
dependencies,
|
|
635
660
|
devDependencies,
|
|
636
661
|
options
|
|
637
662
|
};
|
|
638
663
|
});
|
|
639
|
-
Object.assign(wrapper, {
|
|
640
|
-
meta,
|
|
641
|
-
dependencies,
|
|
642
|
-
devDependencies
|
|
643
|
-
});
|
|
644
|
-
return wrapper;
|
|
645
664
|
};
|
|
646
665
|
var defineGeneratorFactory = (factory) => factory;
|
|
647
666
|
/**
|
|
@@ -680,6 +699,51 @@ var createWatchedPageRouteEntriesFilter = (event, eventsOfInterest) => {
|
|
|
680
699
|
};
|
|
681
700
|
};
|
|
682
701
|
//#endregion
|
|
702
|
+
//#region src/ports.ts
|
|
703
|
+
/**
|
|
704
|
+
* Probe whether a single TCP port is free on given host.
|
|
705
|
+
*
|
|
706
|
+
* Resolves `true` only after the probe server has fully closed,
|
|
707
|
+
* so the caller can immediately rebind without racing the OS.
|
|
708
|
+
* `unref()` keeps a dangling probe from holding the event loop open.
|
|
709
|
+
* */
|
|
710
|
+
var isPortFree = (host, port, timeoutMs = 2e3) => {
|
|
711
|
+
return new Promise((resolve) => {
|
|
712
|
+
const server = net.createServer();
|
|
713
|
+
const done = (result) => {
|
|
714
|
+
clearTimeout(timer);
|
|
715
|
+
resolve(result);
|
|
716
|
+
};
|
|
717
|
+
const timer = setTimeout(() => {
|
|
718
|
+
server.close(() => done(false));
|
|
719
|
+
}, timeoutMs);
|
|
720
|
+
server.unref();
|
|
721
|
+
server.once("error", () => done(false));
|
|
722
|
+
server.once("listening", () => server.close(() => done(true)));
|
|
723
|
+
server.listen({
|
|
724
|
+
host,
|
|
725
|
+
port
|
|
726
|
+
});
|
|
727
|
+
});
|
|
728
|
+
};
|
|
729
|
+
/**
|
|
730
|
+
* Find `count` consecutive free ports by probing random offsets within minPort..maxPort.
|
|
731
|
+
* Each attempt picks a uniformly random start, probes the whole window,
|
|
732
|
+
* and returns it only if every port is free.
|
|
733
|
+
* Failed attempts are cheap because only the window is probed - no full-range scan.
|
|
734
|
+
* */
|
|
735
|
+
var findFreePortRange = async (host, count, { minPort = 2e4, maxPort = 29e3, attempts = 32 } = {}) => {
|
|
736
|
+
if (count < 1) throw new Error("count must be >= 1");
|
|
737
|
+
const span = maxPort - minPort - count + 1;
|
|
738
|
+
if (span <= 0) throw new Error(`Port range ${minPort}-${maxPort} is too small for a window of ${count}`);
|
|
739
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
740
|
+
const start = minPort + Math.floor(Math.random() * span);
|
|
741
|
+
const range = Array.from({ length: count }, (_, i) => start + i);
|
|
742
|
+
if ((await Promise.all(range.map((p) => isPortFree(host, p)))).every(Boolean)) return range;
|
|
743
|
+
}
|
|
744
|
+
throw new Error(`No run of ${count} free ports found in range ${minPort}-${maxPort} after ${attempts} random attempts`);
|
|
745
|
+
};
|
|
746
|
+
//#endregion
|
|
683
747
|
//#region src/routes/paths.ts
|
|
684
748
|
/**
|
|
685
749
|
* Parse a filesystem route path into structured PathToken array.
|
|
@@ -813,7 +877,7 @@ var createH3Pattern = (tokens) => {
|
|
|
813
877
|
return tokens.flatMap((t) => {
|
|
814
878
|
if (t.type === "text") return t.value === "/" ? [] : [escapeStatic(t.value)];
|
|
815
879
|
if (t.type === "param") return [`:${t.name}`];
|
|
816
|
-
if (t.type === "wildcard") return [`/**:${t.name}
|
|
880
|
+
if (t.type === "wildcard") return [`/**:${t.name}`];
|
|
817
881
|
if (t.type === "group") return [`{${tokensToPattern(t.tokens)}}?`];
|
|
818
882
|
return [];
|
|
819
883
|
}).join("");
|
|
@@ -851,8 +915,8 @@ var ROUTE_FILE_PATTERNS = [
|
|
|
851
915
|
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
852
916
|
`${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`
|
|
853
917
|
];
|
|
854
|
-
var scanRoutes = async (sourceFolder) => {
|
|
855
|
-
const { createPath } = pathResolver(sourceFolder);
|
|
918
|
+
var scanRoutes = async (projectSettings, sourceFolder) => {
|
|
919
|
+
const { createPath } = pathResolver(projectSettings, sourceFolder);
|
|
856
920
|
return glob(ROUTE_FILE_PATTERNS, {
|
|
857
921
|
cwd: createPath.src(),
|
|
858
922
|
absolute: true,
|
|
@@ -866,8 +930,8 @@ var scanRoutes = async (sourceFolder) => {
|
|
|
866
930
|
]
|
|
867
931
|
});
|
|
868
932
|
};
|
|
869
|
-
var isRouteFile = (
|
|
870
|
-
const [_sourceFolder, _folder, ...rest] = resolve(
|
|
933
|
+
var isRouteFile = (projectSettings, sourceFolder, file) => {
|
|
934
|
+
const [_sourceFolder, _folder, ...rest] = resolve(projectSettings.root, file).replace(`${projectSettings.root}/${defaults.srcDir}/`, "").split("/");
|
|
871
935
|
/**
|
|
872
936
|
* Ensure the file:
|
|
873
937
|
* - is under the correct source root
|
|
@@ -889,8 +953,8 @@ var isPageRoute = (file) => {
|
|
|
889
953
|
var isPageLayout = (file) => {
|
|
890
954
|
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
891
955
|
};
|
|
892
|
-
var createRouteEntry = (
|
|
893
|
-
const resolvedPaths = isRouteFile(
|
|
956
|
+
var createRouteEntry = (projectSettings, sourceFolder, fileFullpath) => {
|
|
957
|
+
const resolvedPaths = isRouteFile(projectSettings, sourceFolder, fileFullpath);
|
|
894
958
|
if (!resolvedPaths) return;
|
|
895
959
|
const [folder, file] = resolvedPaths;
|
|
896
960
|
const id = `${file.replace(/\W+/g, "_")}_${crc(file)}`;
|
|
@@ -999,12 +1063,12 @@ var sortRoutesForResolution = (a, b) => {
|
|
|
999
1063
|
};
|
|
1000
1064
|
//#endregion
|
|
1001
1065
|
//#region src/routes/resolve.ts
|
|
1002
|
-
var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
1003
|
-
const { generators } = sourceFolder
|
|
1066
|
+
var resolverFactory = (projectSettings, sourceFolder, cacheFactory) => {
|
|
1067
|
+
const { generators } = sourceFolder;
|
|
1004
1068
|
const { refineTypeName = defaults.refineTypeName } = typeof sourceFolder.config.validation === "object" ? { ...sourceFolder.config.validation } : {};
|
|
1005
1069
|
const { typeResolverFactory, resolveRouteSignature } = astFactory();
|
|
1006
1070
|
const resolveTypes = generators.some(({ meta }) => meta.resolveTypes);
|
|
1007
|
-
const { literalTypesResolver, getSourceFile, refreshSourceFile } = typeResolverFactory(sourceFolder);
|
|
1071
|
+
const { literalTypesResolver, getSourceFile, refreshSourceFile } = typeResolverFactory(projectSettings, sourceFolder);
|
|
1008
1072
|
return {
|
|
1009
1073
|
pageLayoutResolver(entry) {
|
|
1010
1074
|
const { name } = entry;
|
|
@@ -1067,11 +1131,11 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
1067
1131
|
});
|
|
1068
1132
|
});
|
|
1069
1133
|
const optionalParams = paramsSchema.length ? paramsSchema.filter((e) => e.kind === "required").length === 0 : true;
|
|
1070
|
-
const cacheStore = cacheFactory ? cacheFactory({
|
|
1134
|
+
const cacheStore = cacheFactory ? cacheFactory(projectSettings, sourceFolder, {
|
|
1071
1135
|
id,
|
|
1072
1136
|
file,
|
|
1073
1137
|
fileFullpath
|
|
1074
|
-
},
|
|
1138
|
+
}, { resolveTypes }) : void 0;
|
|
1075
1139
|
let cache = cacheStore ? await cacheStore.get({ validate: true }) : void 0;
|
|
1076
1140
|
if (!cache) {
|
|
1077
1141
|
if (updatedFile === fileFullpath) await refreshSourceFile(fileFullpath);
|
|
@@ -1095,7 +1159,7 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
1095
1159
|
}] : [];
|
|
1096
1160
|
}) : [def.schema];
|
|
1097
1161
|
});
|
|
1098
|
-
const typesFile = pathResolver(sourceFolder).createPath.libApi(dirname(file), "types.ts");
|
|
1162
|
+
const typesFile = pathResolver(projectSettings, sourceFolder).createPath.libApi(dirname(file), "types.ts");
|
|
1099
1163
|
const params = {
|
|
1100
1164
|
id: ["ParamsT", crc(name)].join(""),
|
|
1101
1165
|
schema: paramsSchema,
|
|
@@ -1208,7 +1272,7 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
1208
1272
|
methods: cache.methods,
|
|
1209
1273
|
typeDeclarations: cache.typeDeclarations,
|
|
1210
1274
|
validationDefinitions,
|
|
1211
|
-
referencedFiles: Object.keys(cache.referencedFiles).map((e) => resolve(
|
|
1275
|
+
referencedFiles: Object.keys(cache.referencedFiles).map((e) => resolve(projectSettings.root, e))
|
|
1212
1276
|
}
|
|
1213
1277
|
};
|
|
1214
1278
|
};
|
|
@@ -1288,12 +1352,12 @@ var nestedRoutesFactory = (routeEntries) => {
|
|
|
1288
1352
|
};
|
|
1289
1353
|
//#endregion
|
|
1290
1354
|
//#region src/routes/index.ts
|
|
1291
|
-
var routesFactory = async (sourceFolder, cacheFactory) => {
|
|
1292
|
-
const { apiRouteResolver, apiUseResolver, pageRouteResolver, pageLayoutResolver } = resolverFactory(sourceFolder, cacheFactory);
|
|
1355
|
+
var routesFactory = async (projectSettings, sourceFolder, cacheFactory) => {
|
|
1356
|
+
const { apiRouteResolver, apiUseResolver, pageRouteResolver, pageLayoutResolver } = resolverFactory(projectSettings, sourceFolder, cacheFactory);
|
|
1293
1357
|
const resolversFactory = (routeFiles) => {
|
|
1294
1358
|
const resolvers = /* @__PURE__ */ new Map();
|
|
1295
1359
|
const entries = routeFiles.flatMap((file) => {
|
|
1296
|
-
const entry = createRouteEntry(
|
|
1360
|
+
const entry = createRouteEntry(projectSettings, sourceFolder, file);
|
|
1297
1361
|
return entry ? [entry] : [];
|
|
1298
1362
|
});
|
|
1299
1363
|
for (const entry of entries) if (entry.folder === defaults.apiDir) {
|
|
@@ -1306,7 +1370,7 @@ var routesFactory = async (sourceFolder, cacheFactory) => {
|
|
|
1306
1370
|
return resolvers;
|
|
1307
1371
|
};
|
|
1308
1372
|
return {
|
|
1309
|
-
resolvers: resolversFactory(await scanRoutes(sourceFolder)),
|
|
1373
|
+
resolvers: resolversFactory(await scanRoutes(projectSettings, sourceFolder)),
|
|
1310
1374
|
resolversFactory
|
|
1311
1375
|
};
|
|
1312
1376
|
};
|
|
@@ -1341,6 +1405,70 @@ var spinnerFactory = (startText) => {
|
|
|
1341
1405
|
};
|
|
1342
1406
|
};
|
|
1343
1407
|
//#endregion
|
|
1408
|
+
//#region src/tsconfig.ts
|
|
1409
|
+
var generateTsconfig = ({ dependencies, devDependencies }, sourceFolder) => {
|
|
1410
|
+
const rootDir = "${configDir}";
|
|
1411
|
+
const deps = Object.keys({
|
|
1412
|
+
...dependencies,
|
|
1413
|
+
...devDependencies
|
|
1414
|
+
});
|
|
1415
|
+
const compilerOptions = {
|
|
1416
|
+
types: ["vite/client", ...[
|
|
1417
|
+
"node",
|
|
1418
|
+
"deno",
|
|
1419
|
+
"bun"
|
|
1420
|
+
].flatMap((e) => {
|
|
1421
|
+
return deps.includes(`@types/${e}`) ? [`@types/${e}`] : [];
|
|
1422
|
+
})],
|
|
1423
|
+
moduleResolution: "bundler",
|
|
1424
|
+
module: "ESNext",
|
|
1425
|
+
target: "ESNext",
|
|
1426
|
+
strict: true,
|
|
1427
|
+
exactOptionalPropertyTypes: true,
|
|
1428
|
+
noImplicitAny: true,
|
|
1429
|
+
noImplicitThis: true,
|
|
1430
|
+
noImplicitOverride: true,
|
|
1431
|
+
noImplicitReturns: true,
|
|
1432
|
+
noUnusedLocals: false,
|
|
1433
|
+
noUnusedParameters: false,
|
|
1434
|
+
allowArbitraryExtensions: true,
|
|
1435
|
+
allowImportingTsExtensions: true,
|
|
1436
|
+
allowUnreachableCode: false,
|
|
1437
|
+
allowUnusedLabels: false,
|
|
1438
|
+
useUnknownInCatchVariables: true,
|
|
1439
|
+
noFallthroughCasesInSwitch: true,
|
|
1440
|
+
noUncheckedSideEffectImports: true,
|
|
1441
|
+
resolveJsonModule: true,
|
|
1442
|
+
esModuleInterop: true,
|
|
1443
|
+
verbatimModuleSyntax: true,
|
|
1444
|
+
skipLibCheck: true,
|
|
1445
|
+
noEmit: true
|
|
1446
|
+
};
|
|
1447
|
+
if (sourceFolder) return {
|
|
1448
|
+
include: [
|
|
1449
|
+
`${rootDir}/`,
|
|
1450
|
+
`${rootDir}/../../${defaults.libDir}/${sourceFolder}/`,
|
|
1451
|
+
`${rootDir}/../../${defaults.libDir}/*.d.ts`
|
|
1452
|
+
],
|
|
1453
|
+
compilerOptions: {
|
|
1454
|
+
...compilerOptions,
|
|
1455
|
+
types: [...compilerOptions.types],
|
|
1456
|
+
paths: {
|
|
1457
|
+
[`${defaults.appPrefix}/*`]: [`${rootDir}/../../*`],
|
|
1458
|
+
[`${defaults.srcPrefix}/*`]: [`${rootDir}/*`],
|
|
1459
|
+
[`${defaults.libPrefix}/*`]: [`${rootDir}/../../${defaults.libDir}/${sourceFolder}/*`]
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
return {
|
|
1464
|
+
exclude: [`${rootDir}/${defaults.srcDir}/`],
|
|
1465
|
+
compilerOptions: {
|
|
1466
|
+
...compilerOptions,
|
|
1467
|
+
paths: { [`${defaults.appPrefix}/*`]: [`${rootDir}/*`] }
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
};
|
|
1471
|
+
//#endregion
|
|
1344
1472
|
//#region src/vite.ts
|
|
1345
1473
|
/**
|
|
1346
1474
|
* Resolves Kosmo's generated import prefixes to absolute file paths.
|
|
@@ -1394,7 +1522,7 @@ var spinnerFactory = (startText) => {
|
|
|
1394
1522
|
* tsconfig generator uses, so alias resolution here can never drift from the
|
|
1395
1523
|
* paths that were written into the generated tsconfig.
|
|
1396
1524
|
* */
|
|
1397
|
-
var tsconfigPaths = (sourceFolder) => {
|
|
1525
|
+
var tsconfigPaths = (projectSettings, sourceFolder) => {
|
|
1398
1526
|
/**
|
|
1399
1527
|
* Candidate extensions for an extensionless specifier, in resolution priority order.
|
|
1400
1528
|
* Mirrors the renderable file types the generators emit;
|
|
@@ -1412,11 +1540,11 @@ var tsconfigPaths = (sourceFolder) => {
|
|
|
1412
1540
|
".mdx",
|
|
1413
1541
|
".json"
|
|
1414
1542
|
];
|
|
1415
|
-
const { createPath } = pathResolver(sourceFolder);
|
|
1543
|
+
const { createPath } = pathResolver(projectSettings, sourceFolder);
|
|
1416
1544
|
const table = [
|
|
1417
1545
|
[`${defaults.srcPrefix}/`, createPath.src()],
|
|
1418
1546
|
[`${defaults.libPrefix}/`, createPath.lib()],
|
|
1419
|
-
[`${defaults.appPrefix}/`,
|
|
1547
|
+
[`${defaults.appPrefix}/`, projectSettings.root]
|
|
1420
1548
|
];
|
|
1421
1549
|
const resolveWithin = async (baseDir, rest) => {
|
|
1422
1550
|
const target = join(baseDir, rest);
|
|
@@ -1463,14 +1591,15 @@ var nodePrefix = () => {
|
|
|
1463
1591
|
*
|
|
1464
1592
|
* Generators declare their modules via `factory.virtualModules()`.
|
|
1465
1593
|
* */
|
|
1466
|
-
var virtualModules = (sourceFolder, { kind, command }) => {
|
|
1594
|
+
var virtualModules = (projectSettings, sourceFolder, { kind, command }) => {
|
|
1467
1595
|
/**
|
|
1468
1596
|
* Rollup's / Rolldown's convention for ids owned by a plugin:
|
|
1469
1597
|
* the NUL prefix keeps other plugins and Node resolution from touching them.
|
|
1470
1598
|
* */
|
|
1471
1599
|
const VIRTUAL_PREFIX = "\0";
|
|
1472
|
-
const modules = sourceFolder.
|
|
1473
|
-
|
|
1600
|
+
const modules = sourceFolder.generators.flatMap(({ factory }) => {
|
|
1601
|
+
const { virtualModules } = factory(projectSettings, sourceFolder);
|
|
1602
|
+
return virtualModules ? virtualModules(command) : [];
|
|
1474
1603
|
});
|
|
1475
1604
|
const virtualSources = /* @__PURE__ */ new Map();
|
|
1476
1605
|
for (const { specifier, csr, ssr } of modules) virtualSources.set(specifier, {
|
|
@@ -1503,7 +1632,21 @@ var vitePlugins = {
|
|
|
1503
1632
|
var isFile = async (path) => {
|
|
1504
1633
|
return stat(path).then((e) => e.isFile()).catch(() => false);
|
|
1505
1634
|
};
|
|
1635
|
+
var cacheDir = ({ root }, { name }, target) => {
|
|
1636
|
+
return join(root, defaults.varDir, ".vite", name, target);
|
|
1637
|
+
};
|
|
1638
|
+
//#endregion
|
|
1639
|
+
//#region src/index.ts
|
|
1640
|
+
/**
|
|
1641
|
+
* Read the installed package.json at runtime to get the actual version.
|
|
1642
|
+
* A static import would be inlined by the bundler with the pre-bump version.
|
|
1643
|
+
*
|
|
1644
|
+
* INFO: For best compatibility, all packages should share the same version.
|
|
1645
|
+
* When bumping the version (even a patch) for a single package,
|
|
1646
|
+
* bump it for all packages to keep versions fully synchronized across the project.
|
|
1647
|
+
* */
|
|
1648
|
+
var { version: VERSION } = JSON.parse(readFileSync(createRequire(import.meta.url).resolve("@kosmojs/lib/package.json"), "utf-8"));
|
|
1506
1649
|
//#endregion
|
|
1507
|
-
export { API_INDEX_BASENAME, API_INDEX_PATTERN, API_USE_BASENAME, API_USE_PATTERN, PAGE_INDEX_BASENAME, PAGE_INDEX_PATTERN, PAGE_LAYOUT_BASENAME, PAGE_LAYOUT_PATTERN, astFactory, containsPathTraversalPatterns, createAliasPatterns, createH3Pattern, createHonoPattern, createPathPattern, createRouteEntry, createWatchedApiRouteEntriesFilter, createWatchedPageRouteEntriesFilter, defineGenerator, defineGeneratorFactory, escapeTemplateLiterals, isApiRoute, isApiUse, isPageLayout, isPageRoute, isRouteFile, mergeConfigs, nestedRoutesFactory, pathExists, pathResolver, pathTokensFactory, render, renderFactory, renderToFile, routesFactory, scanRoutes, sortRoutes, sortRoutesForResolution, spinnerFactory, tsconfigPaths, virtualModules, vitePlugins };
|
|
1650
|
+
export { API_INDEX_BASENAME, API_INDEX_PATTERN, API_USE_BASENAME, API_USE_PATTERN, PAGE_INDEX_BASENAME, PAGE_INDEX_PATTERN, PAGE_LAYOUT_BASENAME, PAGE_LAYOUT_PATTERN, VERSION, astFactory, cacheDir, configFilePattern, containsPathTraversalPatterns, createAliasPatterns, createH3Pattern, createHonoPattern, createPathPattern, createRouteEntry, createWatchedApiRouteEntriesFilter, createWatchedPageRouteEntriesFilter, defineGenerator, defineGeneratorFactory, escapeTemplateLiterals, findFreePortRange, formatCode, generateTsconfig, isApiRoute, isApiUse, isPageLayout, isPageRoute, isPortFree, isRouteFile, mergeConfigs, nestedRoutesFactory, pathExists, pathResolver, pathTokensFactory, render, renderFactory, renderToFile, resolveHostAddress, routesFactory, scanRoutes, sortRoutes, sortRoutesForResolution, spinnerFactory, tsconfigPaths, virtualModules, vitePlugins };
|
|
1508
1651
|
|
|
1509
1652
|
//# sourceMappingURL=index.js.map
|