@gtkx/config 2.0.0-beta.1 → 2.0.0-beta.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/README.md +11 -166
- package/dist/config-dependencies.d.ts +11 -0
- package/dist/config-dependencies.d.ts.map +1 -0
- package/dist/config-dependencies.js +84 -0
- package/dist/config-dependencies.js.map +1 -0
- package/dist/config-error.d.ts +2 -2
- package/dist/config-error.d.ts.map +1 -1
- package/dist/config-error.js +6 -3
- package/dist/config-error.js.map +1 -1
- package/dist/config-reloader.d.ts +8 -0
- package/dist/config-reloader.d.ts.map +1 -0
- package/dist/config-reloader.js +38 -0
- package/dist/config-reloader.js.map +1 -0
- package/dist/config-source.d.ts +7 -0
- package/dist/config-source.d.ts.map +1 -0
- package/dist/config-source.js +17 -0
- package/dist/config-source.js.map +1 -0
- package/dist/config.d.ts +42 -38
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -15
- package/dist/config.js.map +1 -1
- package/dist/deploy.d.ts +28 -22
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +29 -5
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +6 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +6 -1
- package/dist/internal.js.map +1 -1
- package/dist/loader.d.ts +2 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +66 -15
- package/dist/loader.js.map +1 -1
- package/dist/node-version.d.ts +5 -0
- package/dist/node-version.d.ts.map +1 -0
- package/dist/node-version.js +13 -0
- package/dist/node-version.js.map +1 -0
- package/dist/static-dependencies.d.ts +3 -0
- package/dist/static-dependencies.d.ts.map +1 -0
- package/dist/static-dependencies.js +350 -0
- package/dist/static-dependencies.js.map +1 -0
- package/dist/virtual.d.ts.map +1 -1
- package/dist/virtual.js +0 -2
- package/dist/virtual.js.map +1 -1
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +14 -5
- package/dist/vite-plugin.js.map +1 -1
- package/dist/vite-root.d.ts +9 -0
- package/dist/vite-root.d.ts.map +1 -0
- package/dist/vite-root.js +3 -0
- package/dist/vite-root.js.map +1 -0
- package/package.json +23 -6
- package/src/config-dependencies.ts +116 -0
- package/src/config-error.ts +9 -4
- package/src/config-reloader.ts +54 -0
- package/src/config-source.ts +25 -0
- package/src/config.ts +27 -19
- package/src/deploy.ts +61 -8
- package/src/index.ts +1 -0
- package/src/internal.ts +6 -0
- package/src/loader.ts +92 -28
- package/src/node-version.ts +17 -0
- package/src/static-dependencies.ts +464 -0
- package/src/virtual.ts +0 -2
- package/src/vite-plugin.ts +16 -8
- package/src/vite-root.ts +8 -0
package/dist/internal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EACH,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,WAAW,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EACH,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,IAAI,iBAAiB,EAAE,MAAM,KAAK,CAAC"}
|
package/dist/internal.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { configDependenciesFor } from "./config-dependencies.js";
|
|
2
|
+
export { createConfigReloader } from "./config-reloader.js";
|
|
3
|
+
export { APPLICATION_ID_MAX_LENGTH, isAgentReferenceEnabled, isAgentRulesEnabled, isValidApplicationId, resolveAcceptedChildTypes, resolveElementComponents, resolveElementProps, resolveLazyElements, resolveMcpSettings, resolveOmittedProps, } from "./config.js";
|
|
2
4
|
export { createConfigLoader } from "./loader.js";
|
|
5
|
+
export { assertSupportedNodeVersion, DEFAULT_NODE_VERSION, MINIMUM_NODE_VERSION } from "./node-version.js";
|
|
3
6
|
export { resourceBasePath } from "./resource-base-path.js";
|
|
7
|
+
export { viteProjectRoot } from "./vite-root.js";
|
|
8
|
+
export { SUPPORTED_EXTENSIONS as CONFIG_EXTENSIONS } from "c12";
|
|
4
9
|
//# sourceMappingURL=internal.js.map
|
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EACH,yBAAyB,EACzB,uBAAuB,EACvB,mBAAmB,EACnB,oBAAoB,EACpB,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,IAAI,iBAAiB,EAAE,MAAM,KAAK,CAAC","sourcesContent":["export { configDependenciesFor } from \"./config-dependencies.ts\";\nexport { createConfigReloader } from \"./config-reloader.ts\";\nexport type { McpSettings, ResolvedReactCompilerOptions } from \"./config.ts\";\nexport {\n APPLICATION_ID_MAX_LENGTH,\n isAgentReferenceEnabled,\n isAgentRulesEnabled,\n isValidApplicationId,\n resolveAcceptedChildTypes,\n resolveElementComponents,\n resolveElementProps,\n resolveLazyElements,\n resolveMcpSettings,\n resolveOmittedProps,\n} from \"./config.ts\";\nexport { createConfigLoader } from \"./loader.ts\";\nexport { assertSupportedNodeVersion, DEFAULT_NODE_VERSION, MINIMUM_NODE_VERSION } from \"./node-version.ts\";\nexport { resourceBasePath } from \"./resource-base-path.ts\";\nexport { viteProjectRoot } from \"./vite-root.ts\";\nexport { SUPPORTED_EXTENSIONS as CONFIG_EXTENSIONS } from \"c12\";\n"]}
|
package/dist/loader.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ type LoadConfigOptions = {
|
|
|
15
15
|
* top-level values, and the name is passed to a config authored as a function.
|
|
16
16
|
*/
|
|
17
17
|
mode?: string | undefined;
|
|
18
|
-
}
|
|
18
|
+
} & Partial<Record<"configFile", string | undefined>>;
|
|
19
19
|
/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */
|
|
20
20
|
type ConfigLoader = {
|
|
21
21
|
/** Loads the configuration file the given directory resolves to, as {@link loadConfig} does. */
|
|
@@ -31,5 +31,5 @@ type ConfigLoader = {
|
|
|
31
31
|
*/
|
|
32
32
|
declare const loadConfig: (cwd: string, options?: LoadConfigOptions) => Promise<LoadedConfig>;
|
|
33
33
|
declare const createConfigLoader: (options?: LoadConfigOptions) => ConfigLoader;
|
|
34
|
-
export { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader };
|
|
34
|
+
export { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader, type LoadConfigOptions };
|
|
35
35
|
//# sourceMappingURL=loader.d.ts.map
|
package/dist/loader.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAWA,OAAO,EACH,KAAK,MAAM,EAGX,KAAK,cAAc,EAEtB,MAAM,aAAa,CAAC;AAGrB,2DAA2D;AAC3D,KAAK,YAAY,GAAG;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,+FAA+F;AAC/F,KAAK,iBAAiB,GAAG;IACrB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAEtD,sGAAsG;AACtG,KAAK,YAAY,GAAG;IAChB,gGAAgG;IAChG,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C,yGAAyG;IACzG,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CACrD,CAAC;AAwDF;;;;;GAKG;AACH,QAAA,MAAM,UAAU,GAAU,KAAK,MAAM,EAAE,UAAS,iBAAsB,KAAG,OAAO,CAAC,YAAY,CAmD5F,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,UAAS,iBAAsB,KAAG,YAkB7D,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,CAAC"}
|
package/dist/loader.js
CHANGED
|
@@ -1,11 +1,41 @@
|
|
|
1
|
-
import { warn } from "@gtkx/utils";
|
|
1
|
+
import { isPathInside, warn } from "@gtkx/utils";
|
|
2
2
|
import { loadConfig as loadConfigFile } from "c12";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
|
-
import { resolve } from "node:path";
|
|
4
|
+
import { relative, resolve } from "node:path";
|
|
5
|
+
import { captureConfigDependencies, setConfigDependencies, transformConfigModule, } from "./config-dependencies.js";
|
|
5
6
|
import { missingConfigFileError } from "./config-error.js";
|
|
7
|
+
import { localConfigSourcePath } from "./config-source.js";
|
|
6
8
|
import { graduatedFutureKeys, resolveConfig, validateConfig, } from "./config.js";
|
|
9
|
+
import { assertSupportedNodeVersion } from "./node-version.js";
|
|
7
10
|
const GRADUATED_FUTURE_ENV = "GTKX_GRADUATED_FUTURE_SHOWN";
|
|
8
11
|
const graduatedFutureWarnings = new Map();
|
|
12
|
+
const rejectMissingLocalConfig = (source, options) => {
|
|
13
|
+
const path = localConfigSourcePath(source, options);
|
|
14
|
+
if (path !== undefined && !existsSync(path)) {
|
|
15
|
+
throw new Error(`Extended configuration does not exist at ${path}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const withConfigDependencies = (dependencies, operation) => {
|
|
19
|
+
try {
|
|
20
|
+
return operation();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (typeof error === "object" && error !== null) {
|
|
24
|
+
setConfigDependencies(error, dependencies);
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const selectedConfigFile = (root, configured) => {
|
|
30
|
+
if (configured === undefined) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const path = resolve(root, configured);
|
|
34
|
+
if (!isPathInside(root, path)) {
|
|
35
|
+
throw new Error(`Configuration file ${configured} must be inside the project root ${root}`);
|
|
36
|
+
}
|
|
37
|
+
return relative(root, path);
|
|
38
|
+
};
|
|
9
39
|
const warnGraduatedFuture = (config, root) => {
|
|
10
40
|
const keys = graduatedFutureKeys(config);
|
|
11
41
|
const signature = keys.join(",");
|
|
@@ -25,31 +55,52 @@ const warnGraduatedFuture = (config, root) => {
|
|
|
25
55
|
* @throws When that directory holds no configuration file, or when the configuration fails validation.
|
|
26
56
|
*/
|
|
27
57
|
const loadConfig = async (cwd, options = {}) => {
|
|
58
|
+
assertSupportedNodeVersion();
|
|
28
59
|
const searched = resolve(cwd);
|
|
29
|
-
const
|
|
60
|
+
const requestedConfigFile = selectedConfigFile(searched, options.configFile);
|
|
61
|
+
const captured = await captureConfigDependencies(() => loadConfigFile({
|
|
30
62
|
name: "gtkx",
|
|
31
63
|
cwd: searched,
|
|
32
64
|
rcFile: false,
|
|
33
65
|
globalRc: false,
|
|
34
66
|
packageJson: false,
|
|
67
|
+
omit$Keys: true,
|
|
35
68
|
context: { mode: options.mode },
|
|
69
|
+
jitiOptions: { fsCache: false, transform: transformConfigModule },
|
|
70
|
+
resolve: rejectMissingLocalConfig,
|
|
71
|
+
...(requestedConfigFile !== undefined && { configFile: requestedConfigFile }),
|
|
36
72
|
...((options.mode !== undefined) && { envName: options.mode }),
|
|
37
|
-
});
|
|
73
|
+
}));
|
|
74
|
+
const result = captured.value;
|
|
38
75
|
const configFile = result.configFile;
|
|
39
|
-
if (configFile === undefined || !existsSync(resolve(searched, configFile))) {
|
|
40
|
-
throw missingConfigFileError(searched);
|
|
41
|
-
}
|
|
42
|
-
const config = result.config;
|
|
43
76
|
const root = result.cwd ?? searched;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
const layerFiles = (result.layers ?? [])
|
|
78
|
+
.flatMap((layer) => layer.configFile === undefined
|
|
79
|
+
? []
|
|
80
|
+
: [resolve(layer.cwd ?? root, layer.configFile)]);
|
|
81
|
+
const dependencies = [
|
|
82
|
+
...(configFile === undefined ? [] : [configFile]),
|
|
83
|
+
...layerFiles,
|
|
84
|
+
...captured.dependencies,
|
|
85
|
+
];
|
|
86
|
+
return withConfigDependencies(dependencies, () => {
|
|
87
|
+
if (configFile === undefined || !existsSync(resolve(searched, configFile))) {
|
|
88
|
+
throw missingConfigFileError(searched, requestedConfigFile);
|
|
89
|
+
}
|
|
90
|
+
const config = result.config;
|
|
91
|
+
validateConfig(config, configFile);
|
|
92
|
+
warnGraduatedFuture(config, root);
|
|
93
|
+
const loaded = {
|
|
94
|
+
config,
|
|
95
|
+
configFile,
|
|
96
|
+
root,
|
|
97
|
+
};
|
|
98
|
+
setConfigDependencies(loaded, dependencies);
|
|
99
|
+
return loaded;
|
|
100
|
+
});
|
|
51
101
|
};
|
|
52
102
|
const createConfigLoader = (options = {}) => {
|
|
103
|
+
assertSupportedNodeVersion();
|
|
53
104
|
const loaded = new Map();
|
|
54
105
|
const resolved = new Map();
|
|
55
106
|
const load = (cwd) => loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));
|
package/dist/loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,UAAU,IAAI,cAAc,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAEH,mBAAmB,EACnB,aAAa,EAEb,cAAc,GACjB,MAAM,aAAa,CAAC;AA6BrB,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,MAAM,uBAAuB,GAAwB,IAAI,GAAG,EAAE,CAAC;AAE/D,MAAM,mBAAmB,GAAG,CAAC,MAAe,EAAE,IAAY,EAAQ,EAAE;IAChE,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEjC,IACI,IAAI,CAAC,MAAM,KAAK,CAAC;QACjB,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS;QAC/C,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,SAAS,EACjD,CAAC;QACC,OAAO;IACX,CAAC;IAED,uBAAuB,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAC;IAC9C,IAAI,CAAC,0CAA0C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;AACxG,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,GAAG,KAAK,EAAE,GAAW,EAAE,UAA6B,EAAE,EAAyB,EAAE;IAC7F,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAS;QACxC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,KAAK;QAClB,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE;QAC/B,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;KACjE,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAErC,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC;IACpC,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAElC,OAAO;QACH,MAAM;QACN,UAAU;QACV,IAAI;KACP,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,UAA6B,EAAE,EAAgB,EAAE;IACzE,MAAM,MAAM,GAAuC,IAAI,GAAG,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAyC,IAAI,GAAG,EAAE,CAAC;IAEjE,MAAM,IAAI,GAAG,CAAC,GAAW,EAAyB,EAAE,CAChD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAElF,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAA2B,EAAE;QAC9D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAEtD,OAAO,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,OAAO;QACH,IAAI;QACJ,OAAO,EAAE,CAAC,GAAW,EAA2B,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC;KAC3G,CAAC;AACN,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAwC,CAAC","sourcesContent":["import { warn } from \"@gtkx/utils\";\nimport { loadConfig as loadConfigFile } from \"c12\";\nimport { existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { missingConfigFileError } from \"./config-error.ts\";\nimport {\n type Config,\n graduatedFutureKeys,\n resolveConfig,\n type ResolvedConfig,\n validateConfig,\n} from \"./config.ts\";\n\n/** Result of loading a project's `gtkx.config.ts` file. */\ntype LoadedConfig = {\n /** The parsed and validated configuration. */\n config: Config;\n /** Absolute path of the configuration file that was loaded. */\n configFile: string;\n /** Absolute path of the project root the configuration was resolved against. */\n root: string;\n};\n\n/** How a configuration file is read, shared by {@link loadConfig} and `createConfigLoader`. */\ntype LoadConfigOptions = {\n /**\n * Environment name such as `development`: the config's matching `$<mode>` block is layered over the\n * top-level values, and the name is passed to a config authored as a function.\n */\n mode?: string | undefined;\n};\n\n/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */\ntype ConfigLoader = {\n /** Loads the configuration file the given directory resolves to, as {@link loadConfig} does. */\n load: (cwd: string) => Promise<LoadedConfig>;\n /** Loads the configuration for the given directory and reduces it to what the build and the app need. */\n resolve: (cwd: string) => Promise<ResolvedConfig>;\n};\n\nconst GRADUATED_FUTURE_ENV = \"GTKX_GRADUATED_FUTURE_SHOWN\";\nconst graduatedFutureWarnings: Map<string, string> = new Map();\n\nconst warnGraduatedFuture = (config: unknown, root: string): void => {\n const keys = graduatedFutureKeys(config);\n const signature = keys.join(\",\");\n\n if (\n keys.length === 0 ||\n graduatedFutureWarnings.get(root) === signature ||\n process.env[GRADUATED_FUTURE_ENV] === signature\n ) {\n return;\n }\n\n graduatedFutureWarnings.set(root, signature);\n process.env[GRADUATED_FUTURE_ENV] = signature;\n warn(`GTKX 2 ignores graduated future flags: ${keys.join(\", \")}. Remove them from gtkx.config.ts.`);\n};\n\n/**\n * Loads and validates the `gtkx.config.ts` file for a project.\n * @param cwd Directory the configuration file is looked up in; parent directories are not searched.\n * @param options Loading options, such as the environment mode whose overrides are applied.\n * @throws When that directory holds no configuration file, or when the configuration fails validation.\n */\nconst loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise<LoadedConfig> => {\n const searched = resolve(cwd);\n\n const result = await loadConfigFile<Config>({\n name: \"gtkx\",\n cwd: searched,\n rcFile: false,\n globalRc: false,\n packageJson: false,\n context: { mode: options.mode },\n ...((options.mode !== undefined) && { envName: options.mode }),\n });\n\n const configFile = result.configFile;\n\n if (configFile === undefined || !existsSync(resolve(searched, configFile))) {\n throw missingConfigFileError(searched);\n }\n\n const config = result.config;\n const root = result.cwd ?? searched;\n validateConfig(config);\n warnGraduatedFuture(config, root);\n\n return {\n config,\n configFile,\n root,\n };\n};\n\nconst createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {\n const loaded: Map<string, Promise<LoadedConfig>> = new Map();\n const resolved: Map<string, Promise<ResolvedConfig>> = new Map();\n\n const load = (cwd: string): Promise<LoadedConfig> =>\n loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));\n\n const resolveAt = async (root: string): Promise<ResolvedConfig> => {\n const { config, root: configRoot } = await load(root);\n\n return resolveConfig(config, configRoot);\n };\n\n return {\n load,\n resolve: (cwd: string): Promise<ResolvedConfig> => resolved.getOrInsertComputed(resolve(cwd), resolveAt),\n };\n};\n\nexport { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader };\n"]}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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","sourcesContent":["import { isPathInside, warn } from \"@gtkx/utils\";\nimport { loadConfig as loadConfigFile } from \"c12\";\nimport { existsSync } from \"node:fs\";\nimport { relative, resolve } from \"node:path\";\nimport {\n captureConfigDependencies,\n setConfigDependencies,\n transformConfigModule,\n} from \"./config-dependencies.ts\";\nimport { missingConfigFileError } from \"./config-error.ts\";\nimport { type ConfigResolutionOptions, localConfigSourcePath } from \"./config-source.ts\";\nimport {\n type Config,\n graduatedFutureKeys,\n resolveConfig,\n type ResolvedConfig,\n validateConfig,\n} from \"./config.ts\";\nimport { assertSupportedNodeVersion } from \"./node-version.ts\";\n\n/** Result of loading a project's `gtkx.config.ts` file. */\ntype LoadedConfig = {\n /** The parsed and validated configuration. */\n config: Config;\n /** Absolute path of the configuration file that was loaded. */\n configFile: string;\n /** Absolute path of the project root the configuration was resolved against. */\n root: string;\n};\n\n/** How a configuration file is read, shared by {@link loadConfig} and `createConfigLoader`. */\ntype LoadConfigOptions = {\n /**\n * Environment name such as `development`: the config's matching `$<mode>` block is layered over the\n * top-level values, and the name is passed to a config authored as a function.\n */\n mode?: string | undefined;\n} & Partial<Record<\"configFile\", string | undefined>>;\n\n/** Reads a project's configuration once per directory, caching what it loads and what it resolves. */\ntype ConfigLoader = {\n /** Loads the configuration file the given directory resolves to, as {@link loadConfig} does. */\n load: (cwd: string) => Promise<LoadedConfig>;\n /** Loads the configuration for the given directory and reduces it to what the build and the app need. */\n resolve: (cwd: string) => Promise<ResolvedConfig>;\n};\n\nconst GRADUATED_FUTURE_ENV = \"GTKX_GRADUATED_FUTURE_SHOWN\";\nconst graduatedFutureWarnings: Map<string, string> = new Map();\n\nconst rejectMissingLocalConfig = (source: string, options: ConfigResolutionOptions): undefined => {\n const path = localConfigSourcePath(source, options);\n\n if (path !== undefined && !existsSync(path)) {\n throw new Error(`Extended configuration does not exist at ${path}`);\n }\n};\n\nconst withConfigDependencies = <T>(dependencies: string[], operation: () => T): T => {\n try {\n return operation();\n } catch (error) {\n if (typeof error === \"object\" && error !== null) {\n setConfigDependencies(error, dependencies);\n }\n\n throw error;\n }\n};\n\nconst selectedConfigFile = (root: string, configured: string | undefined): string | undefined => {\n if (configured === undefined) {\n return undefined;\n }\n\n const path = resolve(root, configured);\n\n if (!isPathInside(root, path)) {\n throw new Error(`Configuration file ${configured} must be inside the project root ${root}`);\n }\n\n return relative(root, path);\n};\n\nconst warnGraduatedFuture = (config: unknown, root: string): void => {\n const keys = graduatedFutureKeys(config);\n const signature = keys.join(\",\");\n\n if (\n keys.length === 0 ||\n graduatedFutureWarnings.get(root) === signature ||\n process.env[GRADUATED_FUTURE_ENV] === signature\n ) {\n return;\n }\n\n graduatedFutureWarnings.set(root, signature);\n process.env[GRADUATED_FUTURE_ENV] = signature;\n warn(`GTKX 2 ignores graduated future flags: ${keys.join(\", \")}. Remove them from gtkx.config.ts.`);\n};\n\n/**\n * Loads and validates the `gtkx.config.ts` file for a project.\n * @param cwd Directory the configuration file is looked up in; parent directories are not searched.\n * @param options Loading options, such as the environment mode whose overrides are applied.\n * @throws When that directory holds no configuration file, or when the configuration fails validation.\n */\nconst loadConfig = async (cwd: string, options: LoadConfigOptions = {}): Promise<LoadedConfig> => {\n assertSupportedNodeVersion();\n const searched = resolve(cwd);\n const requestedConfigFile = selectedConfigFile(searched, options.configFile);\n\n const captured = await captureConfigDependencies(() =>\n loadConfigFile<Config>({\n name: \"gtkx\",\n cwd: searched,\n rcFile: false,\n globalRc: false,\n packageJson: false,\n omit$Keys: true,\n context: { mode: options.mode },\n jitiOptions: { fsCache: false, transform: transformConfigModule },\n resolve: rejectMissingLocalConfig,\n ...(requestedConfigFile !== undefined && { configFile: requestedConfigFile }),\n ...((options.mode !== undefined) && { envName: options.mode }),\n }));\n const result = captured.value;\n\n const configFile = result.configFile;\n const root = result.cwd ?? searched;\n const layerFiles = (result.layers ?? [])\n .flatMap((layer) => layer.configFile === undefined\n ? []\n : [resolve(layer.cwd ?? root, layer.configFile)]);\n const dependencies = [\n ...(configFile === undefined ? [] : [configFile]),\n ...layerFiles,\n ...captured.dependencies,\n ];\n\n return withConfigDependencies(dependencies, () => {\n if (configFile === undefined || !existsSync(resolve(searched, configFile))) {\n throw missingConfigFileError(searched, requestedConfigFile);\n }\n\n const config = result.config;\n validateConfig(config, configFile);\n warnGraduatedFuture(config, root);\n\n const loaded = {\n config,\n configFile,\n root,\n };\n setConfigDependencies(loaded, dependencies);\n\n return loaded;\n });\n};\n\nconst createConfigLoader = (options: LoadConfigOptions = {}): ConfigLoader => {\n assertSupportedNodeVersion();\n const loaded: Map<string, Promise<LoadedConfig>> = new Map();\n const resolved: Map<string, Promise<ResolvedConfig>> = new Map();\n\n const load = (cwd: string): Promise<LoadedConfig> =>\n loaded.getOrInsertComputed(resolve(cwd), (root) => loadConfig(root, options));\n\n const resolveAt = async (root: string): Promise<ResolvedConfig> => {\n const { config, root: configRoot } = await load(root);\n\n return resolveConfig(config, configRoot);\n };\n\n return {\n load,\n resolve: (cwd: string): Promise<ResolvedConfig> => resolved.getOrInsertComputed(resolve(cwd), resolveAt),\n };\n};\n\nexport { loadConfig, createConfigLoader, type LoadedConfig, type ConfigLoader, type LoadConfigOptions };\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
declare const MINIMUM_NODE_VERSION = "26.7.0";
|
|
2
|
+
declare const DEFAULT_NODE_VERSION = "26.8.2";
|
|
3
|
+
declare const assertSupportedNodeVersion: () => void;
|
|
4
|
+
export { assertSupportedNodeVersion, DEFAULT_NODE_VERSION, MINIMUM_NODE_VERSION };
|
|
5
|
+
//# sourceMappingURL=node-version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version.d.ts","sourceRoot":"","sources":["../src/node-version.ts"],"names":[],"mappings":"AAEA,QAAA,MAAM,oBAAoB,WAAW,CAAC;AACtC,QAAA,MAAM,oBAAoB,WAAW,CAAC;AAEtC,QAAA,MAAM,0BAA0B,QAAO,IAStC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const MINIMUM_NODE_MAJOR = 26;
|
|
2
|
+
const MINIMUM_NODE_MINOR = 7;
|
|
3
|
+
const MINIMUM_NODE_VERSION = "26.7.0";
|
|
4
|
+
const DEFAULT_NODE_VERSION = "26.8.2";
|
|
5
|
+
const assertSupportedNodeVersion = () => {
|
|
6
|
+
const [major = 0, minor = 0] = process.versions.node.split(".").map(Number);
|
|
7
|
+
const isSupported = major > MINIMUM_NODE_MAJOR || (major === MINIMUM_NODE_MAJOR && minor >= MINIMUM_NODE_MINOR);
|
|
8
|
+
if (!isSupported) {
|
|
9
|
+
throw new Error(`GTKX requires Node.js ${MINIMUM_NODE_VERSION} or newer. Current version: ${process.versions.node}.`);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export { assertSupportedNodeVersion, DEFAULT_NODE_VERSION, MINIMUM_NODE_VERSION };
|
|
13
|
+
//# sourceMappingURL=node-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-version.js","sourceRoot":"","sources":["../src/node-version.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAC7B,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AACtC,MAAM,oBAAoB,GAAG,QAAQ,CAAC;AAEtC,MAAM,0BAA0B,GAAG,GAAS,EAAE;IAC1C,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5E,MAAM,WAAW,GAAG,KAAK,GAAG,kBAAkB,IAAI,CAAC,KAAK,KAAK,kBAAkB,IAAI,KAAK,IAAI,kBAAkB,CAAC,CAAC;IAEhH,IAAI,CAAC,WAAW,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACX,yBAAyB,oBAAoB,+BAA+B,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,CACvG,CAAC;IACN,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,CAAC","sourcesContent":["const MINIMUM_NODE_MAJOR = 26;\nconst MINIMUM_NODE_MINOR = 7;\nconst MINIMUM_NODE_VERSION = \"26.7.0\";\nconst DEFAULT_NODE_VERSION = \"26.8.2\";\n\nconst assertSupportedNodeVersion = (): void => {\n const [major = 0, minor = 0] = process.versions.node.split(\".\").map(Number);\n const isSupported = major > MINIMUM_NODE_MAJOR || (major === MINIMUM_NODE_MAJOR && minor >= MINIMUM_NODE_MINOR);\n\n if (!isSupported) {\n throw new Error(\n `GTKX requires Node.js ${MINIMUM_NODE_VERSION} or newer. Current version: ${process.versions.node}.`,\n );\n }\n};\n\nexport { assertSupportedNodeVersion, DEFAULT_NODE_VERSION, MINIMUM_NODE_VERSION };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-dependencies.d.ts","sourceRoot":"","sources":["../src/static-dependencies.ts"],"names":[],"mappings":"AAqbA,QAAA,MAAM,yBAAyB,GAC3B,YAAY,MAAM,EAClB,mBAAiC,EACjC,mBAAgC,KACjC,MAAM,EAoBR,CAAC;AAEF,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { parseSync, traverse, types } from "@babel/core";
|
|
2
|
+
import { parseJSON, parseJSON5, parseJSONC, parseTOML, parseYAML } from "confbox";
|
|
3
|
+
import { createJiti } from "jiti";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { basename, dirname, extname, isAbsolute, join, resolve, sep } from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { localConfigSourcePath } from "./config-source.js";
|
|
8
|
+
const MODULE_EXTENSIONS = new Set([
|
|
9
|
+
".cjs",
|
|
10
|
+
".cts",
|
|
11
|
+
".js",
|
|
12
|
+
".mjs",
|
|
13
|
+
".mts",
|
|
14
|
+
".ts",
|
|
15
|
+
]);
|
|
16
|
+
const RESOLVABLE_EXTENSIONS = [
|
|
17
|
+
".js",
|
|
18
|
+
".ts",
|
|
19
|
+
".mjs",
|
|
20
|
+
".cjs",
|
|
21
|
+
".mts",
|
|
22
|
+
".cts",
|
|
23
|
+
".json",
|
|
24
|
+
".jsonc",
|
|
25
|
+
".json5",
|
|
26
|
+
".yaml",
|
|
27
|
+
".yml",
|
|
28
|
+
".toml",
|
|
29
|
+
];
|
|
30
|
+
const JAVASCRIPT_FALLBACKS = {
|
|
31
|
+
".cjs": [".cts"],
|
|
32
|
+
".js": [".ts"],
|
|
33
|
+
".jsx": [".tsx"],
|
|
34
|
+
".mjs": [".mts"],
|
|
35
|
+
};
|
|
36
|
+
const DATA_PARSERS = {
|
|
37
|
+
".json": parseJSON,
|
|
38
|
+
".json5": parseJSON5,
|
|
39
|
+
".jsonc": parseJSONC,
|
|
40
|
+
".toml": parseTOML,
|
|
41
|
+
".yaml": parseYAML,
|
|
42
|
+
".yml": parseYAML,
|
|
43
|
+
};
|
|
44
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45
|
+
const parserPlugins = (path) => {
|
|
46
|
+
const extension = extname(path).toLowerCase();
|
|
47
|
+
return [
|
|
48
|
+
"decorators",
|
|
49
|
+
...([".cts", ".mts", ".ts"].includes(extension) ? ["typescript"] : []),
|
|
50
|
+
];
|
|
51
|
+
};
|
|
52
|
+
function expressionSources(value) {
|
|
53
|
+
if (types.isStringLiteral(value)) {
|
|
54
|
+
return [value.value];
|
|
55
|
+
}
|
|
56
|
+
if (types.isArrayExpression(value)) {
|
|
57
|
+
return value.elements.flatMap((element) => types.isExpression(element) ? expressionSources(element) : []);
|
|
58
|
+
}
|
|
59
|
+
return types.isObjectExpression(value)
|
|
60
|
+
? value.properties.flatMap((property) => sourcePropertySources(property))
|
|
61
|
+
: [];
|
|
62
|
+
}
|
|
63
|
+
const isNamedProperty = (property, name) => (types.isIdentifier(property.key) && property.key.name === name) ||
|
|
64
|
+
(types.isStringLiteral(property.key) && property.key.value === name);
|
|
65
|
+
function sourcePropertySources(property) {
|
|
66
|
+
return types.isObjectProperty(property) &&
|
|
67
|
+
isNamedProperty(property, "source") &&
|
|
68
|
+
types.isExpression(property.value)
|
|
69
|
+
? expressionSources(property.value)
|
|
70
|
+
: [];
|
|
71
|
+
}
|
|
72
|
+
const extendsSources = (value) => expressionSources(value);
|
|
73
|
+
const isExtendsProperty = (property) => isNamedProperty(property, "extends");
|
|
74
|
+
const parseModule = (path) => {
|
|
75
|
+
try {
|
|
76
|
+
return parseSync(readFileSync(path, "utf8"), {
|
|
77
|
+
ast: true,
|
|
78
|
+
babelrc: false,
|
|
79
|
+
configFile: false,
|
|
80
|
+
filename: path,
|
|
81
|
+
parserOpts: { allowReturnOutsideFunction: true, plugins: parserPlugins(path) },
|
|
82
|
+
sourceType: "unambiguous",
|
|
83
|
+
}) ?? undefined;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const addSource = (sources, source) => {
|
|
90
|
+
if (source !== null && source !== undefined) {
|
|
91
|
+
sources.add(source.value);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const requireSource = (call) => types.isIdentifier(call.callee, { name: "require" }) && types.isStringLiteral(call.arguments[0])
|
|
95
|
+
? call.arguments[0]
|
|
96
|
+
: undefined;
|
|
97
|
+
const importEqualsSource = (declaration) => {
|
|
98
|
+
const { moduleReference } = declaration;
|
|
99
|
+
return types.isTSExternalModuleReference(moduleReference) ? moduleReference.expression : undefined;
|
|
100
|
+
};
|
|
101
|
+
const propertySources = (property) => isExtendsProperty(property) && types.isExpression(property.value)
|
|
102
|
+
? extendsSources(property.value)
|
|
103
|
+
: [];
|
|
104
|
+
const collectModuleSources = (ast) => {
|
|
105
|
+
const sources = new Set();
|
|
106
|
+
const extended = new Set();
|
|
107
|
+
traverse(ast, {
|
|
108
|
+
CallExpression: (nodePath) => {
|
|
109
|
+
addSource(sources, requireSource(nodePath.node));
|
|
110
|
+
},
|
|
111
|
+
ExportAllDeclaration: (nodePath) => {
|
|
112
|
+
addSource(sources, nodePath.node.source);
|
|
113
|
+
},
|
|
114
|
+
ExportNamedDeclaration: (nodePath) => {
|
|
115
|
+
addSource(sources, nodePath.node.source);
|
|
116
|
+
},
|
|
117
|
+
ImportDeclaration: (nodePath) => {
|
|
118
|
+
addSource(sources, nodePath.node.source);
|
|
119
|
+
},
|
|
120
|
+
ImportExpression: (nodePath) => {
|
|
121
|
+
const { source } = nodePath.node;
|
|
122
|
+
addSource(sources, types.isStringLiteral(source) ? source : undefined);
|
|
123
|
+
},
|
|
124
|
+
ObjectProperty: (nodePath) => {
|
|
125
|
+
for (const source of propertySources(nodePath.node)) {
|
|
126
|
+
sources.add(source);
|
|
127
|
+
extended.add(source);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
TSImportEqualsDeclaration: (nodePath) => {
|
|
131
|
+
addSource(sources, importEqualsSource(nodePath.node));
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
return { all: [...sources], extended: [...extended] };
|
|
135
|
+
};
|
|
136
|
+
const moduleSources = (path) => {
|
|
137
|
+
const ast = parseModule(path);
|
|
138
|
+
return ast === undefined ? { all: [], extended: [] } : collectModuleSources(ast);
|
|
139
|
+
};
|
|
140
|
+
function parsedExtendsSources(value) {
|
|
141
|
+
if (typeof value === "string") {
|
|
142
|
+
return [value];
|
|
143
|
+
}
|
|
144
|
+
if (Array.isArray(value)) {
|
|
145
|
+
return value.flatMap((item) => parsedExtendsSources(item));
|
|
146
|
+
}
|
|
147
|
+
return objectExtendsSources(value);
|
|
148
|
+
}
|
|
149
|
+
const objectExtendsSources = (value) => {
|
|
150
|
+
if (typeof value !== "object" || value === null) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
return "source" in value ? parsedExtendsSources(value.source) : [];
|
|
154
|
+
};
|
|
155
|
+
const configExtendsSources = (value) => {
|
|
156
|
+
if (typeof value !== "object" || value === null) {
|
|
157
|
+
return [];
|
|
158
|
+
}
|
|
159
|
+
return "extends" in value ? parsedExtendsSources(value.extends) : [];
|
|
160
|
+
};
|
|
161
|
+
const dataSources = (path) => {
|
|
162
|
+
const parser = DATA_PARSERS[extname(path).toLowerCase()];
|
|
163
|
+
if (parser === undefined) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
return configExtendsSources(parser(readFileSync(path, "utf8")));
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const extensionCandidates = (path) => {
|
|
174
|
+
const extension = extname(path).toLowerCase();
|
|
175
|
+
if (extension.length === 0) {
|
|
176
|
+
return RESOLVABLE_EXTENSIONS.map((candidate) => `${path}${candidate}`);
|
|
177
|
+
}
|
|
178
|
+
const stem = path.slice(0, -extension.length);
|
|
179
|
+
return (JAVASCRIPT_FALLBACKS[extension] ?? []).map((candidate) => `${stem}${candidate}`);
|
|
180
|
+
};
|
|
181
|
+
const targetCandidates = (target, configName) => {
|
|
182
|
+
const extension = extname(target);
|
|
183
|
+
if (extension.length > 0) {
|
|
184
|
+
return [target, ...extensionCandidates(target)];
|
|
185
|
+
}
|
|
186
|
+
return [
|
|
187
|
+
target,
|
|
188
|
+
...extensionCandidates(target),
|
|
189
|
+
join(target, configName),
|
|
190
|
+
...RESOLVABLE_EXTENSIONS.map((candidate) => join(target, `index${candidate}`)),
|
|
191
|
+
];
|
|
192
|
+
};
|
|
193
|
+
const localSourceTarget = (source, importer) => {
|
|
194
|
+
const clean = source.split(/[?#]/u, 1)[0] ?? "";
|
|
195
|
+
if (clean.startsWith("file:")) {
|
|
196
|
+
return fileURLToPath(clean);
|
|
197
|
+
}
|
|
198
|
+
if (!isAbsolute(clean) && !clean.startsWith(".")) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
return resolve(dirname(importer), clean);
|
|
202
|
+
};
|
|
203
|
+
const unresolvedCandidates = (source, importer, configName) => {
|
|
204
|
+
const target = localSourceTarget(source, importer);
|
|
205
|
+
if (target === undefined) {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
return targetCandidates(target, configName);
|
|
209
|
+
};
|
|
210
|
+
const nearestPackageFile = (importer) => {
|
|
211
|
+
let directory = dirname(importer);
|
|
212
|
+
let previous = "";
|
|
213
|
+
while (directory !== previous) {
|
|
214
|
+
const candidate = join(directory, "package.json");
|
|
215
|
+
if (existsSync(candidate)) {
|
|
216
|
+
return candidate;
|
|
217
|
+
}
|
|
218
|
+
previous = directory;
|
|
219
|
+
directory = dirname(directory);
|
|
220
|
+
}
|
|
221
|
+
return undefined;
|
|
222
|
+
};
|
|
223
|
+
const readPackageImports = (importer) => {
|
|
224
|
+
const file = nearestPackageFile(importer);
|
|
225
|
+
if (file === undefined) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const manifest = parseJSON(readFileSync(file, "utf8"));
|
|
230
|
+
return isRecord(manifest) && isRecord(manifest.imports)
|
|
231
|
+
? { file, imports: manifest.imports, root: dirname(file) }
|
|
232
|
+
: undefined;
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
function stringTargets(value) {
|
|
239
|
+
if (typeof value === "string") {
|
|
240
|
+
return [value];
|
|
241
|
+
}
|
|
242
|
+
if (Array.isArray(value)) {
|
|
243
|
+
return value.flatMap((item) => stringTargets(item));
|
|
244
|
+
}
|
|
245
|
+
return isRecord(value)
|
|
246
|
+
? Object.values(value).flatMap((item) => stringTargets(item))
|
|
247
|
+
: [];
|
|
248
|
+
}
|
|
249
|
+
const importPatternMatch = (pattern, source) => {
|
|
250
|
+
if (pattern === source) {
|
|
251
|
+
return "";
|
|
252
|
+
}
|
|
253
|
+
const wildcard = pattern.indexOf("*");
|
|
254
|
+
if (wildcard === -1) {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
const prefix = pattern.slice(0, wildcard);
|
|
258
|
+
const suffix = pattern.slice(wildcard + 1);
|
|
259
|
+
return source.startsWith(prefix) && source.endsWith(suffix)
|
|
260
|
+
? source.slice(prefix.length, source.length - suffix.length)
|
|
261
|
+
: undefined;
|
|
262
|
+
};
|
|
263
|
+
const packageImportTargets = (source, imports) => Object.entries(imports).flatMap(([pattern, value]) => {
|
|
264
|
+
const match = importPatternMatch(pattern, source);
|
|
265
|
+
return match === undefined
|
|
266
|
+
? []
|
|
267
|
+
: stringTargets(value).map((target) => target.split("*").join(match));
|
|
268
|
+
});
|
|
269
|
+
const packageImportDependencies = (source, importer, configName) => {
|
|
270
|
+
if (!source.startsWith("#")) {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
const packageImports = readPackageImports(importer);
|
|
274
|
+
if (packageImports === undefined) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
const targets = packageImportTargets(source, packageImports.imports)
|
|
278
|
+
.filter((target) => target.startsWith("."))
|
|
279
|
+
.flatMap((target) => targetCandidates(resolve(packageImports.root, target), configName));
|
|
280
|
+
return [packageImports.file, ...targets];
|
|
281
|
+
};
|
|
282
|
+
const normalizedResolvedPath = (path) => path.startsWith("file:") ? fileURLToPath(path) : path;
|
|
283
|
+
const resolvedSourcePath = (source, importer, jiti) => {
|
|
284
|
+
try {
|
|
285
|
+
const path = jiti.esmResolve(source, {
|
|
286
|
+
parentURL: pathToFileURL(importer).href,
|
|
287
|
+
try: true,
|
|
288
|
+
});
|
|
289
|
+
return path === undefined ? undefined : normalizedResolvedPath(path);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return undefined;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
const sourceDependencies = (source, importer, configName, jiti) => {
|
|
296
|
+
const dependency = resolvedSourcePath(source, importer, jiti);
|
|
297
|
+
const packageDependencies = packageImportDependencies(source, importer, configName);
|
|
298
|
+
return dependency === undefined
|
|
299
|
+
? [...unresolvedCandidates(source, importer, configName), ...packageDependencies]
|
|
300
|
+
: [dependency, ...packageDependencies];
|
|
301
|
+
};
|
|
302
|
+
const configLayerDirectory = (path, configName, configRoot) => {
|
|
303
|
+
const segments = configName.split(/[\\/]/u).filter((segment) => segment.length > 0);
|
|
304
|
+
let directory = resolve(path);
|
|
305
|
+
let remaining = segments.length;
|
|
306
|
+
while (remaining > 0) {
|
|
307
|
+
directory = dirname(directory);
|
|
308
|
+
remaining -= 1;
|
|
309
|
+
}
|
|
310
|
+
return resolve(directory, ...segments) === resolve(path) ? directory : resolve(configRoot);
|
|
311
|
+
};
|
|
312
|
+
const c12SourceDependencies = (source, importer, configName, configRoot) => {
|
|
313
|
+
const clean = source.split(/[?#]/u, 1)[0] ?? "";
|
|
314
|
+
const cwd = configLayerDirectory(importer, configName, configRoot);
|
|
315
|
+
const target = localConfigSourcePath(clean, { cwd, configFile: configName });
|
|
316
|
+
return target === undefined ? [] : targetCandidates(target, configName);
|
|
317
|
+
};
|
|
318
|
+
const directDependencies = (path, configName, configRoot) => {
|
|
319
|
+
const module = MODULE_EXTENSIONS.has(extname(path).toLowerCase()) ? moduleSources(path) : undefined;
|
|
320
|
+
const sources = module?.all ?? dataSources(path);
|
|
321
|
+
const extended = module?.extended ?? sources;
|
|
322
|
+
const jiti = createJiti(path, {
|
|
323
|
+
extensions: RESOLVABLE_EXTENSIONS,
|
|
324
|
+
fsCache: false,
|
|
325
|
+
moduleCache: false,
|
|
326
|
+
});
|
|
327
|
+
return [
|
|
328
|
+
...sources.flatMap((source) => sourceDependencies(source, path, configName, jiti)),
|
|
329
|
+
...extended.flatMap((source) => c12SourceDependencies(source, path, configName, configRoot)),
|
|
330
|
+
]
|
|
331
|
+
.filter((dependency) => !dependency.includes(`${sep}node_modules${sep}`));
|
|
332
|
+
};
|
|
333
|
+
const resolveConfigDependencies = (configFile, configName = basename(configFile), configRoot = dirname(configFile)) => {
|
|
334
|
+
const dependencies = new Set();
|
|
335
|
+
const pending = [resolve(configFile)];
|
|
336
|
+
while (pending.length > 0) {
|
|
337
|
+
const path = pending.pop();
|
|
338
|
+
if (path === undefined) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
if (dependencies.has(path)) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
dependencies.add(path);
|
|
345
|
+
pending.push(...directDependencies(path, configName, configRoot));
|
|
346
|
+
}
|
|
347
|
+
return [...dependencies];
|
|
348
|
+
};
|
|
349
|
+
export { resolveConfigDependencies };
|
|
350
|
+
//# sourceMappingURL=static-dependencies.js.map
|