@decohere/forge 0.0.1-dev.20 → 0.0.1-dev.20261105.54
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/LICENSE +15 -0
- package/README.md +152 -0
- package/commonjs/src/actions/build.action.js +4 -6
- package/commonjs/src/actions/clean.action.js +4 -6
- package/commonjs/src/actions/commit.action.js +4 -6
- package/commonjs/src/actions/copy.action.js +62 -12
- package/commonjs/src/actions/dependency-report.action.js +8 -6
- package/commonjs/src/actions/dependency-sync.action.js +9 -5
- package/commonjs/src/actions/docker.action.js +83 -36
- package/commonjs/src/actions/index.js +3 -2
- package/commonjs/src/actions/link.action.js +3 -5
- package/commonjs/src/actions/package.action.js +234 -0
- package/commonjs/src/actions/paths.action.js +120 -0
- package/commonjs/src/actions/publish.action.js +4 -6
- package/commonjs/src/actions/sync-lock-file.action.js +2 -4
- package/commonjs/src/actions/tag.action.js +6 -9
- package/commonjs/src/actions/typecheck.action.js +67 -0
- package/commonjs/src/actions/unlink.action.js +1 -3
- package/commonjs/src/actions/version.action.js +74 -21
- package/commonjs/src/actions/watch.action.js +3 -5
- package/commonjs/src/commands/build.command.js +4 -3
- package/commonjs/src/commands/dependency.command.js +1 -3
- package/commonjs/src/commands/docker.command.js +2 -4
- package/commonjs/src/commands/forge.command.js +1 -3
- package/commonjs/src/commands/index.js +3 -2
- package/commonjs/src/commands/link.command.js +4 -3
- package/commonjs/src/commands/package.command.js +36 -0
- package/commonjs/src/commands/paths.command.js +24 -0
- package/commonjs/src/commands/publish.command.js +1 -3
- package/commonjs/src/commands/tag.command.js +1 -3
- package/commonjs/src/commands/typecheck.command.js +24 -0
- package/commonjs/src/commands/version.command.js +3 -3
- package/commonjs/src/const.js +0 -2
- package/commonjs/src/create-workspace.js +38 -0
- package/commonjs/src/errors.js +2 -4
- package/commonjs/src/extensions/project.extensions.js +11 -13
- package/commonjs/src/factories/swc-config.factory.js +29 -9
- package/commonjs/src/forge.module.js +15 -20
- package/commonjs/src/index.js +8 -2
- package/commonjs/src/packaging/dependency-pinner.service.js +118 -0
- package/commonjs/src/packaging/deployable.js +44 -0
- package/commonjs/src/packaging/import-graph.service.js +137 -0
- package/commonjs/src/packaging/release-exports.js +90 -0
- package/commonjs/src/packaging/ui-assets.js +75 -0
- package/commonjs/src/semver/index.js +18 -0
- package/commonjs/src/semver/semver.js +96 -0
- package/commonjs/src/services/dependency-resolver.service.js +70 -26
- package/commonjs/src/services/file-writer.service.js +2 -11
- package/commonjs/src/services/incremental-watch.js +24 -0
- package/commonjs/src/services/output-cache.js +39 -0
- package/commonjs/src/services/swc-transpiler.js +85 -99
- package/commonjs/src/services/transpile-cache.js +44 -0
- package/commonjs/src/services/ts-compiler-options.js +50 -0
- package/commonjs/src/services/ts-program-host.js +4 -6
- package/commonjs/src/services/type-emission-program.js +25 -10
- package/commonjs/src/services/type-emitter.js +60 -20
- package/commonjs/src/transpile/index.js +30 -0
- package/commonjs/src/types/build-target.type.js +0 -2
- package/commonjs/src/types/configuration.type.js +0 -2
- package/commonjs/src/types/dependency.types.js +0 -2
- package/commonjs/src/types/swc-config.type.js +0 -2
- package/commonjs/src/types/transform-response.model.js +3 -18
- package/commonjs/src/types/transformer.type.js +0 -2
- package/commonjs/src/types/workspace-config.type.js +0 -2
- package/commonjs/src/vitest/forge-build.plugin.js +28 -44
- package/commonjs/src/vitest/index.js +0 -2
- package/commonjs/src/workspace.config.js +27 -6
- package/es6/src/actions/build.action.js +3 -7
- package/es6/src/actions/clean.action.js +3 -6
- package/es6/src/actions/commit.action.js +3 -6
- package/es6/src/actions/copy.action.js +61 -12
- package/es6/src/actions/dependency-report.action.js +7 -7
- package/es6/src/actions/dependency-sync.action.js +8 -6
- package/es6/src/actions/docker.action.js +82 -36
- package/es6/src/actions/index.js +3 -2
- package/es6/src/actions/link.action.js +2 -5
- package/es6/src/actions/package.action.js +219 -0
- package/es6/src/actions/paths.action.js +97 -0
- package/es6/src/actions/publish.action.js +3 -6
- package/es6/src/actions/sync-lock-file.action.js +2 -4
- package/es6/src/actions/tag.action.js +5 -9
- package/es6/src/actions/typecheck.action.js +52 -0
- package/es6/src/actions/unlink.action.js +1 -3
- package/es6/src/actions/version.action.js +69 -17
- package/es6/src/actions/watch.action.js +2 -5
- package/es6/src/commands/build.command.js +4 -3
- package/es6/src/commands/dependency.command.js +1 -3
- package/es6/src/commands/docker.command.js +2 -4
- package/es6/src/commands/forge.command.js +1 -3
- package/es6/src/commands/index.js +3 -2
- package/es6/src/commands/link.command.js +4 -3
- package/es6/src/commands/package.command.js +26 -0
- package/es6/src/commands/paths.command.js +14 -0
- package/es6/src/commands/publish.command.js +1 -3
- package/es6/src/commands/tag.command.js +1 -3
- package/es6/src/commands/typecheck.command.js +14 -0
- package/es6/src/commands/version.command.js +3 -3
- package/es6/src/const.js +0 -2
- package/es6/src/create-workspace.js +26 -0
- package/es6/src/errors.js +1 -3
- package/es6/src/extensions/project.extensions.js +5 -7
- package/es6/src/factories/swc-config.factory.js +29 -9
- package/es6/src/forge.module.js +15 -20
- package/es6/src/index.js +2 -2
- package/es6/src/packaging/dependency-pinner.service.js +103 -0
- package/es6/src/packaging/deployable.js +21 -0
- package/es6/src/packaging/import-graph.service.js +122 -0
- package/es6/src/packaging/release-exports.js +80 -0
- package/es6/src/packaging/ui-assets.js +49 -0
- package/es6/src/semver/index.js +1 -0
- package/es6/src/semver/semver.js +75 -0
- package/es6/src/services/dependency-resolver.service.js +70 -26
- package/es6/src/services/file-writer.service.js +2 -11
- package/es6/src/services/incremental-watch.js +18 -0
- package/es6/src/services/output-cache.js +29 -0
- package/es6/src/services/swc-transpiler.js +85 -99
- package/es6/src/services/transpile-cache.js +29 -0
- package/es6/src/services/ts-compiler-options.js +39 -0
- package/es6/src/services/ts-program-host.js +4 -6
- package/es6/src/services/type-emission-program.js +25 -10
- package/es6/src/services/type-emitter.js +57 -20
- package/es6/src/transpile/index.js +6 -0
- package/es6/src/types/build-target.type.js +0 -2
- package/es6/src/types/configuration.type.js +0 -2
- package/es6/src/types/dependency.types.js +0 -2
- package/es6/src/types/swc-config.type.js +0 -2
- package/es6/src/types/transform-response.model.js +0 -7
- package/es6/src/types/transformer.type.js +0 -2
- package/es6/src/types/workspace-config.type.js +0 -2
- package/es6/src/vitest/forge-build.plugin.js +27 -43
- package/es6/src/vitest/index.js +0 -2
- package/es6/src/workspace.config.js +26 -5
- package/package.json +20 -6
- package/types/src/actions/build.action.d.ts +4 -4
- package/types/src/actions/clean.action.d.ts +3 -3
- package/types/src/actions/commit.action.d.ts +3 -3
- package/types/src/actions/copy.action.d.ts +18 -3
- package/types/src/actions/dependency-report.action.d.ts +3 -3
- package/types/src/actions/dependency-sync.action.d.ts +3 -3
- package/types/src/actions/docker.action.d.ts +14 -3
- package/types/src/actions/index.d.ts +3 -0
- package/types/src/actions/link.action.d.ts +3 -3
- package/types/src/actions/package.action.d.ts +38 -0
- package/types/src/actions/paths.action.d.ts +28 -0
- package/types/src/actions/publish.action.d.ts +4 -4
- package/types/src/actions/sync-lock-file.action.d.ts +2 -2
- package/types/src/actions/tag.action.d.ts +3 -3
- package/types/src/actions/typecheck.action.d.ts +14 -0
- package/types/src/actions/unlink.action.d.ts +2 -2
- package/types/src/actions/version.action.d.ts +14 -4
- package/types/src/actions/watch.action.d.ts +3 -3
- package/types/src/commands/build.command.d.ts +3 -2
- package/types/src/commands/dependency.command.d.ts +2 -2
- package/types/src/commands/docker.command.d.ts +1 -1
- package/types/src/commands/forge.command.d.ts +2 -2
- package/types/src/commands/index.d.ts +3 -0
- package/types/src/commands/link.command.d.ts +3 -2
- package/types/src/commands/package.command.d.ts +11 -0
- package/types/src/commands/paths.command.d.ts +6 -0
- package/types/src/commands/publish.command.d.ts +1 -1
- package/types/src/commands/tag.command.d.ts +1 -1
- package/types/src/commands/typecheck.command.d.ts +6 -0
- package/types/src/commands/version.command.d.ts +1 -1
- package/types/src/create-workspace.d.ts +7 -0
- package/types/src/errors.d.ts +1 -1
- package/types/src/extensions/project.extensions.d.ts +2 -2
- package/types/src/factories/swc-config.factory.d.ts +3 -2
- package/types/src/forge.module.d.ts +10 -4
- package/types/src/index.d.ts +2 -0
- package/types/src/packaging/dependency-pinner.service.d.ts +20 -0
- package/types/src/packaging/deployable.d.ts +17 -0
- package/types/src/packaging/import-graph.service.d.ts +33 -0
- package/types/src/packaging/release-exports.d.ts +18 -0
- package/types/src/packaging/ui-assets.d.ts +21 -0
- package/types/src/semver/index.d.ts +1 -0
- package/types/src/semver/semver.d.ts +20 -0
- package/types/src/services/dependency-resolver.service.d.ts +8 -1
- package/types/src/services/file-writer.service.d.ts +1 -2
- package/types/src/services/incremental-watch.d.ts +13 -0
- package/types/src/services/output-cache.d.ts +10 -0
- package/types/src/services/swc-transpiler.d.ts +28 -15
- package/types/src/services/transpile-cache.d.ts +17 -0
- package/types/src/services/ts-compiler-options.d.ts +8 -0
- package/types/src/services/ts-program-host.d.ts +2 -2
- package/types/src/services/type-emission-program.d.ts +10 -3
- package/types/src/services/type-emitter.d.ts +21 -8
- package/types/src/transpile/index.d.ts +6 -0
- package/types/src/types/configuration.type.d.ts +6 -1
- package/types/src/types/dependency.types.d.ts +8 -9
- package/types/src/types/swc-config.type.d.ts +7 -1
- package/types/src/types/transform-response.model.d.ts +2 -7
- package/types/src/types/transformer.type.d.ts +3 -12
- package/types/src/types/workspace-config.type.d.ts +3 -3
- package/types/src/vitest/forge-build.plugin.d.ts +0 -2
- package/commonjs/src/mixins/caches-outputs.mixin.js +0 -44
- package/commonjs/src/mixins/incremental-transform.mixin.js +0 -36
- package/es6/src/mixins/caches-outputs.mixin.js +0 -34
- package/es6/src/mixins/incremental-transform.mixin.js +0 -26
- package/types/src/mixins/caches-outputs.mixin.d.ts +0 -7
- package/types/src/mixins/incremental-transform.mixin.d.ts +0 -13
|
@@ -5,8 +5,9 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
8
|
+
import { packageAliases } from "@decohere/workspace";
|
|
9
|
+
import { Trace } from "@decohere/devkit/diagnostics";
|
|
10
|
+
import { merge } from "@decohere/core/objects";
|
|
10
11
|
import { ForgeError } from "../errors.js";
|
|
11
12
|
const defaultOptions = {
|
|
12
13
|
jsc: {
|
|
@@ -32,10 +33,15 @@ export class SwcConfigFactory {
|
|
|
32
33
|
* Creates a base config for a project+target combination, without a filename.
|
|
33
34
|
* Call once per (project, target) and then use createFileConfig() per file.
|
|
34
35
|
*/ createBaseConfig(buildTarget, configOptions) {
|
|
35
|
-
const { userConfig, tsConfig, aliasPaths } = configOptions;
|
|
36
|
+
const { userConfig, tsConfig, aliasPaths, sourceMaps, workspace, projects } = configOptions;
|
|
36
37
|
const { compilerOptions } = tsConfig ?? {};
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const aliases = aliasPaths ? workspace != null ? workspace.getPackageAliases(projects?.[0]?.configuration.name ?? "debug") : projects != null && projects.length > 0 ? packageAliases.build(projects, {
|
|
39
|
+
baseUrl: SwcConfigFactory.getBaseUrl(tsConfig) ?? path.resolve(projects[0].rootDir),
|
|
40
|
+
tsconfigPaths: compilerOptions?.paths
|
|
41
|
+
}) : undefined : undefined;
|
|
42
|
+
const tsconfigOnlyPaths = aliasPaths && aliases == null ? compilerOptions?.paths : undefined;
|
|
43
|
+
const paths = SwcConfigFactory.nonemptyPaths(aliases?.paths ?? tsconfigOnlyPaths);
|
|
44
|
+
const baseUrl = aliases?.baseUrl ?? SwcConfigFactory.getBaseUrl(tsConfig) ?? (workspace != null ? path.resolve(workspace.rootDir) : undefined) ?? (paths != null ? path.resolve(".") : undefined);
|
|
39
45
|
const options = {
|
|
40
46
|
jsc: {
|
|
41
47
|
baseUrl,
|
|
@@ -43,20 +49,36 @@ export class SwcConfigFactory {
|
|
|
43
49
|
},
|
|
44
50
|
module: {
|
|
45
51
|
type: buildTarget
|
|
46
|
-
}
|
|
52
|
+
},
|
|
53
|
+
...sourceMaps === false ? {
|
|
54
|
+
sourceMaps: false
|
|
55
|
+
} : {}
|
|
47
56
|
};
|
|
48
57
|
return merge.withOptions({
|
|
49
58
|
mergeArrays: false
|
|
50
59
|
}, defaultOptions, options, userConfig ?? {});
|
|
51
60
|
}
|
|
52
|
-
/** Stamps a per-file filename onto a pre-built base config. */ createFileConfig(file, baseConfig) {
|
|
61
|
+
/** Stamps a per-file filename onto a pre-built base config; `.tsx` also turns on JSX. */ createFileConfig(file, baseConfig) {
|
|
62
|
+
const tsx = file.fullPath.endsWith(".tsx");
|
|
63
|
+
const jsc = tsx && baseConfig.jsc?.parser?.syntax === "typescript" ? {
|
|
64
|
+
...baseConfig.jsc,
|
|
65
|
+
parser: {
|
|
66
|
+
...baseConfig.jsc.parser,
|
|
67
|
+
tsx: true
|
|
68
|
+
}
|
|
69
|
+
} : baseConfig.jsc;
|
|
53
70
|
const config = {
|
|
54
71
|
...baseConfig,
|
|
72
|
+
jsc,
|
|
55
73
|
filename: file.fullPath
|
|
56
74
|
};
|
|
57
75
|
this.validate(config);
|
|
58
76
|
return config;
|
|
59
77
|
}
|
|
78
|
+
static nonemptyPaths(paths) {
|
|
79
|
+
if (paths == null || Object.keys(paths).length === 0) return undefined;
|
|
80
|
+
return paths;
|
|
81
|
+
}
|
|
60
82
|
/**
|
|
61
83
|
* Validates SWC options against known causes of Rust/NAPI process crashes.
|
|
62
84
|
* Throws a ForgeError with a descriptive message instead of letting the
|
|
@@ -79,5 +101,3 @@ export class SwcConfigFactory {
|
|
|
79
101
|
SwcConfigFactory = _ts_decorate([
|
|
80
102
|
Trace
|
|
81
103
|
], SwcConfigFactory);
|
|
82
|
-
|
|
83
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9mYWN0b3JpZXMvc3djLWNvbmZpZy5mYWN0b3J5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgVHNjb25maWcgfSBmcm9tIFwiQGRlY29oZXJlL21lc2hcIjtcbmltcG9ydCB7IFRyYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9kaWFnbm9zdGljc1wiO1xuaW1wb3J0IHR5cGUgeyBGaWxlRXggfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2lvXCI7XG5pbXBvcnQgeyBtZXJnZSB9IGZyb20gXCJAZGVjb2hlcmUvbmV4dXMvb2JqZWN0c1wiO1xuaW1wb3J0IHR5cGUgeyBPcHRpb25zIH0gZnJvbSBcIkBzd2MvY29yZVwiO1xuaW1wb3J0IHsgRm9yZ2VFcnJvciB9IGZyb20gXCIuLi9lcnJvcnMuanNcIjtcbmltcG9ydCB0eXBlIHsgVHJhbnNwaWxlVGFyZ2V0IH0gZnJvbSBcIi4uL3R5cGVzL2J1aWxkLXRhcmdldC50eXBlLmpzXCI7XG5pbXBvcnQgdHlwZSB7IFN3Y0NvbmZpZ09wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvc3djLWNvbmZpZy50eXBlLmpzXCI7XG5cbmNvbnN0IGRlZmF1bHRPcHRpb25zID0ge1xuXHRqc2M6IHtcblx0XHRwYXJzZXI6IHtcblx0XHRcdHN5bnRheDogXCJ0eXBlc2NyaXB0XCIsXG5cdFx0XHRkZWNvcmF0b3JzOiB0cnVlLFxuXHRcdH0sXG5cdFx0dGFyZ2V0OiBcImVzbmV4dFwiLFxuXHRcdHRyYW5zZm9ybToge1xuXHRcdFx0ZGVjb3JhdG9yTWV0YWRhdGE6IHRydWUsXG5cdFx0fSxcblx0XHRleHBlcmltZW50YWw6IHsga2VlcEltcG9ydEF0dHJpYnV0ZXM6IHRydWUgfSxcblx0fSxcblx0bW9kdWxlOiB7XG5cdFx0cmVzb2x2ZUZ1bGx5OiB0cnVlLFxuXHR9LFxuXHRzb3VyY2VNYXBzOiBcImlubGluZVwiLFxufTtcblxuQFRyYWNlXG5leHBvcnQgY2xhc3MgU3djQ29uZmlnRmFjdG9yeSB7XG5cdC8qKlxuXHQgKiBDcmVhdGVzIGEgYmFzZSBjb25maWcgZm9yIGEgcHJvamVjdCt0YXJnZXQgY29tYmluYXRpb24sIHdpdGhvdXQgYSBmaWxlbmFtZS5cblx0ICogQ2FsbCBvbmNlIHBlciAocHJvamVjdCwgdGFyZ2V0KSBhbmQgdGhlbiB1c2UgY3JlYXRlRmlsZUNvbmZpZygpIHBlciBmaWxlLlxuXHQgKi9cblx0cHVibGljIGNyZWF0ZUJhc2VDb25maWcoXG5cdFx0YnVpbGRUYXJnZXQ6IFRyYW5zcGlsZVRhcmdldCxcblx0XHRjb25maWdPcHRpb25zOiBTd2NDb25maWdPcHRpb25zLFxuXHQpOiBPcHRpb25zIHtcblx0XHRjb25zdCB7IHVzZXJDb25maWcsIHRzQ29uZmlnLCBhbGlhc1BhdGhzIH0gPSBjb25maWdPcHRpb25zO1xuXHRcdGNvbnN0IHsgY29tcGlsZXJPcHRpb25zIH0gPSB0c0NvbmZpZyA/PyB7fTtcblx0XHRjb25zdCBwYXRocyA9IGFsaWFzUGF0aHMgPyBjb21waWxlck9wdGlvbnM/LnBhdGhzIDogdW5kZWZpbmVkO1xuXHRcdGNvbnN0IGJhc2VVcmwgPVxuXHRcdFx0U3djQ29uZmlnRmFjdG9yeS5nZXRCYXNlVXJsKHRzQ29uZmlnKSA/PyAocGF0aHMgIT0gbnVsbCA/IHBhdGgucmVzb2x2ZShcIi5cIikgOiB1bmRlZmluZWQpO1xuXG5cdFx0Y29uc3Qgb3B0aW9uczogT3B0aW9ucyA9IHtcblx0XHRcdGpzYzoge1xuXHRcdFx0XHRiYXNlVXJsLFxuXHRcdFx0XHRwYXRocyxcblx0XHRcdH0sXG5cdFx0XHRtb2R1bGU6IHtcblx0XHRcdFx0dHlwZTogYnVpbGRUYXJnZXQsXG5cdFx0XHR9LFxuXHRcdH07XG5cblx0XHRyZXR1cm4gbWVyZ2Uud2l0aE9wdGlvbnM8T3B0aW9ucz4oXG5cdFx0XHR7IG1lcmdlQXJyYXlzOiBmYWxzZSB9LFxuXHRcdFx0ZGVmYXVsdE9wdGlvbnMsXG5cdFx0XHRvcHRpb25zLFxuXHRcdFx0dXNlckNvbmZpZyA/PyB7fSxcblx0XHQpO1xuXHR9XG5cblx0LyoqIFN0YW1wcyBhIHBlci1maWxlIGZpbGVuYW1lIG9udG8gYSBwcmUtYnVpbHQgYmFzZSBjb25maWcuICovXG5cdHB1YmxpYyBjcmVhdGVGaWxlQ29uZmlnKGZpbGU6IEZpbGVFeCwgYmFzZUNvbmZpZzogT3B0aW9ucyk6IE9wdGlvbnMge1xuXHRcdGNvbnN0IGNvbmZpZyA9IHsgLi4uYmFzZUNvbmZpZywgZmlsZW5hbWU6IGZpbGUuZnVsbFBhdGggfTtcblx0XHR0aGlzLnZhbGlkYXRlKGNvbmZpZyk7XG5cdFx0cmV0dXJuIGNvbmZpZztcblx0fVxuXG5cdC8qKlxuXHQgKiBWYWxpZGF0ZXMgU1dDIG9wdGlvbnMgYWdhaW5zdCBrbm93biBjYXVzZXMgb2YgUnVzdC9OQVBJIHByb2Nlc3MgY3Jhc2hlcy5cblx0ICogVGhyb3dzIGEgRm9yZ2VFcnJvciB3aXRoIGEgZGVzY3JpcHRpdmUgbWVzc2FnZSBpbnN0ZWFkIG9mIGxldHRpbmcgdGhlXG5cdCAqIE5BUEkgbGF5ZXIgYWJvcnQgdGhlIHByb2Nlc3MuXG5cdCAqXG5cdCAqIEtub3duIGNyYXNoIGNhdXNlczpcblx0ICogLSBganNjLmJhc2VVcmxgIHNldCB0byBhIHJlbGF0aXZlIHBhdGggKFNXQyByZXF1aXJlcyBhbiBhYnNvbHV0ZSBwYXRoKVxuXHQgKi9cblx0cHVibGljIHZhbGlkYXRlKG9wdGlvbnM6IE9wdGlvbnMpOiB2b2lkIHtcblx0XHRjb25zdCBiYXNlVXJsID0gb3B0aW9ucy5qc2M/LmJhc2VVcmw7XG5cdFx0aWYgKGJhc2VVcmwgIT0gbnVsbCAmJiAhcGF0aC5pc0Fic29sdXRlKGJhc2VVcmwpKSB7XG5cdFx0XHR0aHJvdyBuZXcgRm9yZ2VFcnJvcihcblx0XHRcdFx0YFNXQyBjb25maWc6IGpzYy5iYXNlVXJsIG11c3QgYmUgYW4gYWJzb2x1dGUgcGF0aCB0byBhdm9pZCBhIHByb2Nlc3MgY3Jhc2gsIGdvdDogXCIke2Jhc2VVcmx9XCIuIFVzZSBwYXRoLnJlc29sdmUoKSB0byBjb252ZXJ0IGl0LmAsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdC8qKiBSZXNvbHZlcyB0c2NvbmZpZyBiYXNlVXJsIHRvIGFuIGFic29sdXRlIHBhdGguIFJldHVybnMgdW5kZWZpbmVkIGlmIG5vdCBzZXQuICovXG5cdHByaXZhdGUgc3RhdGljIGdldEJhc2VVcmwodHNDb25maWc6IFRzY29uZmlnIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcblx0XHRjb25zdCBiYXNlVXJsID0gdHNDb25maWc/LmNvbXBpbGVyT3B0aW9ucz8uYmFzZVVybDtcblx0XHRpZiAoYmFzZVVybCA9PSBudWxsKSByZXR1cm4gdW5kZWZpbmVkO1xuXHRcdHJldHVybiBwYXRoLnJlc29sdmUoYmFzZVVybCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJwYXRoIiwiVHJhY2UiLCJtZXJnZSIsIkZvcmdlRXJyb3IiLCJkZWZhdWx0T3B0aW9ucyIsImpzYyIsInBhcnNlciIsInN5bnRheCIsImRlY29yYXRvcnMiLCJ0YXJnZXQiLCJ0cmFuc2Zvcm0iLCJkZWNvcmF0b3JNZXRhZGF0YSIsImV4cGVyaW1lbnRhbCIsImtlZXBJbXBvcnRBdHRyaWJ1dGVzIiwibW9kdWxlIiwicmVzb2x2ZUZ1bGx5Iiwic291cmNlTWFwcyIsIlN3Y0NvbmZpZ0ZhY3RvcnkiLCJjcmVhdGVCYXNlQ29uZmlnIiwiYnVpbGRUYXJnZXQiLCJjb25maWdPcHRpb25zIiwidXNlckNvbmZpZyIsInRzQ29uZmlnIiwiYWxpYXNQYXRocyIsImNvbXBpbGVyT3B0aW9ucyIsInBhdGhzIiwidW5kZWZpbmVkIiwiYmFzZVVybCIsImdldEJhc2VVcmwiLCJyZXNvbHZlIiwib3B0aW9ucyIsInR5cGUiLCJ3aXRoT3B0aW9ucyIsIm1lcmdlQXJyYXlzIiwiY3JlYXRlRmlsZUNvbmZpZyIsImZpbGUiLCJiYXNlQ29uZmlnIiwiY29uZmlnIiwiZmlsZW5hbWUiLCJmdWxsUGF0aCIsInZhbGlkYXRlIiwiaXNBYnNvbHV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsT0FBT0EsVUFBVSxZQUFZO0FBRTdCLFNBQVNDLEtBQUssUUFBUSw4QkFBOEI7QUFFcEQsU0FBU0MsS0FBSyxRQUFRLDBCQUEwQjtBQUVoRCxTQUFTQyxVQUFVLFFBQVEsZUFBZTtBQUkxQyxNQUFNQyxpQkFBaUI7SUFDdEJDLEtBQUs7UUFDSkMsUUFBUTtZQUNQQyxRQUFRO1lBQ1JDLFlBQVk7UUFDYjtRQUNBQyxRQUFRO1FBQ1JDLFdBQVc7WUFDVkMsbUJBQW1CO1FBQ3BCO1FBQ0FDLGNBQWM7WUFBRUMsc0JBQXNCO1FBQUs7SUFDNUM7SUFDQUMsUUFBUTtRQUNQQyxjQUFjO0lBQ2Y7SUFDQUMsWUFBWTtBQUNiO0FBR0EsT0FBTyxNQUFNQztJQUNaOzs7RUFHQyxHQUNELEFBQU9DLGlCQUNOQyxXQUE0QixFQUM1QkMsYUFBK0IsRUFDckI7UUFDVixNQUFNLEVBQUVDLFVBQVUsRUFBRUMsUUFBUSxFQUFFQyxVQUFVLEVBQUUsR0FBR0g7UUFDN0MsTUFBTSxFQUFFSSxlQUFlLEVBQUUsR0FBR0YsWUFBWSxDQUFDO1FBQ3pDLE1BQU1HLFFBQVFGLGFBQWFDLGlCQUFpQkMsUUFBUUM7UUFDcEQsTUFBTUMsVUFDTFYsaUJBQWlCVyxVQUFVLENBQUNOLGFBQWNHLENBQUFBLFNBQVMsT0FBT3pCLEtBQUs2QixPQUFPLENBQUMsT0FBT0gsU0FBUTtRQUV2RixNQUFNSSxVQUFtQjtZQUN4QnpCLEtBQUs7Z0JBQ0pzQjtnQkFDQUY7WUFDRDtZQUNBWCxRQUFRO2dCQUNQaUIsTUFBTVo7WUFDUDtRQUNEO1FBRUEsT0FBT2pCLE1BQU04QixXQUFXLENBQ3ZCO1lBQUVDLGFBQWE7UUFBTSxHQUNyQjdCLGdCQUNBMEIsU0FDQVQsY0FBYyxDQUFDO0lBRWpCO0lBRUEsNkRBQTZELEdBQzdELEFBQU9hLGlCQUFpQkMsSUFBWSxFQUFFQyxVQUFtQixFQUFXO1FBQ25FLE1BQU1DLFNBQVM7WUFBRSxHQUFHRCxVQUFVO1lBQUVFLFVBQVVILEtBQUtJLFFBQVE7UUFBQztRQUN4RCxJQUFJLENBQUNDLFFBQVEsQ0FBQ0g7UUFDZCxPQUFPQTtJQUNSO0lBRUE7Ozs7Ozs7RUFPQyxHQUNELEFBQU9HLFNBQVNWLE9BQWdCLEVBQVE7UUFDdkMsTUFBTUgsVUFBVUcsUUFBUXpCLEdBQUcsRUFBRXNCO1FBQzdCLElBQUlBLFdBQVcsUUFBUSxDQUFDM0IsS0FBS3lDLFVBQVUsQ0FBQ2QsVUFBVTtZQUNqRCxNQUFNLElBQUl4QixXQUNULENBQUMsaUZBQWlGLEVBQUV3QixRQUFRLG9DQUFvQyxDQUFDO1FBRW5JO0lBQ0Q7SUFFQSxpRkFBaUYsR0FDakYsT0FBZUMsV0FBV04sUUFBOEIsRUFBc0I7UUFDN0UsTUFBTUssVUFBVUwsVUFBVUUsaUJBQWlCRztRQUMzQyxJQUFJQSxXQUFXLE1BQU0sT0FBT0Q7UUFDNUIsT0FBTzFCLEtBQUs2QixPQUFPLENBQUNGO0lBQ3JCO0FBQ0QifQ==
|
package/es6/src/forge.module.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ModuleManifest } from "@decohere/nexus/cli";
|
|
1
|
+
import { ModuleManifest } from "@decohere/devkit/cli";
|
|
3
2
|
import * as Actions from "./actions/index.js";
|
|
4
3
|
import * as Commands from "./commands/index.js";
|
|
4
|
+
import { createWorkspace } from "./create-workspace.js";
|
|
5
|
+
import { DependencyPinner } from "./packaging/dependency-pinner.service.js";
|
|
6
|
+
import { ImportGraph } from "./packaging/import-graph.service.js";
|
|
5
7
|
import { DependencyResolver } from "./services/dependency-resolver.service.js";
|
|
6
8
|
import { FileWriterService } from "./services/file-writer.service.js";
|
|
7
9
|
import { SwcTranspiler } from "./services/swc-transpiler.js";
|
|
8
10
|
import { TypeEmitter } from "./services/type-emitter.js";
|
|
9
11
|
import { TransformerKey } from "./types/transformer.type.js";
|
|
10
|
-
import { DefaultConfigurations, WorkspaceDefaults } from "./workspace.config.js";
|
|
11
12
|
export class ForgeModule extends ModuleManifest {
|
|
12
13
|
id = "forge";
|
|
13
14
|
command = Commands.ForgeCommand;
|
|
@@ -15,6 +16,7 @@ export class ForgeModule extends ModuleManifest {
|
|
|
15
16
|
clean: Actions.Clean,
|
|
16
17
|
copy: Actions.Copy,
|
|
17
18
|
docker: Actions.Docker,
|
|
19
|
+
package: Actions.PackageDeployable,
|
|
18
20
|
build: Actions.Build,
|
|
19
21
|
watch: Actions.Watch,
|
|
20
22
|
publish: Actions.Publish,
|
|
@@ -23,6 +25,8 @@ export class ForgeModule extends ModuleManifest {
|
|
|
23
25
|
reportDependencies: Actions.ReportDependencies,
|
|
24
26
|
version: Actions.Version,
|
|
25
27
|
tag: Actions.Tag,
|
|
28
|
+
paths: Actions.Paths,
|
|
29
|
+
typecheck: Actions.TypeCheck,
|
|
26
30
|
commitFiles: Actions.CommitFiles,
|
|
27
31
|
link: Actions.Link,
|
|
28
32
|
unlink: Actions.Unlink
|
|
@@ -32,33 +36,24 @@ export class ForgeModule extends ModuleManifest {
|
|
|
32
36
|
publish: Commands.PublishCommand,
|
|
33
37
|
dependencies: Commands.DependencyCommand,
|
|
34
38
|
docker: Commands.DockerCommand,
|
|
39
|
+
package: Commands.PackageCommand,
|
|
35
40
|
version: Commands.VersionCommand,
|
|
36
41
|
tag: Commands.TagCommand,
|
|
42
|
+
paths: Commands.PathsCommand,
|
|
43
|
+
typecheck: Commands.TypeCheckCommand,
|
|
37
44
|
link: Commands.LinkCommand,
|
|
38
45
|
unlink: Commands.UnlinkCommand
|
|
39
46
|
};
|
|
40
47
|
registerServices(builder) {
|
|
48
|
+
builder.registerSingleton(TypeEmitter);
|
|
41
49
|
builder.registerSingleton(TransformerKey, SwcTranspiler);
|
|
42
50
|
builder.registerSingleton(TransformerKey, TypeEmitter);
|
|
43
51
|
builder.registerSingleton(DependencyResolver);
|
|
52
|
+
builder.registerSingleton(ImportGraph);
|
|
53
|
+
builder.registerSingleton(DependencyPinner);
|
|
44
54
|
builder.registerSingleton(FileWriterService);
|
|
45
55
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const userConfig = await UserConfigFactory.getUserConfig(options.configFile);
|
|
49
|
-
// Only apply forge default configurations when user config doesn't provide any.
|
|
50
|
-
// This ensures user-defined configurations take priority while still providing
|
|
51
|
-
// sensible defaults (debug + release) when no config file is present.
|
|
52
|
-
const configurations = userConfig.configurations?.length ? undefined : DefaultConfigurations;
|
|
53
|
-
return WorkspaceFactory.create({
|
|
54
|
-
...forgeDefaults,
|
|
55
|
-
...configurations ? {
|
|
56
|
-
configurations
|
|
57
|
-
} : {},
|
|
58
|
-
configFile: options.configFile,
|
|
59
|
-
rootDir: options.rootDir ?? WorkspaceDefaults.rootDir
|
|
60
|
-
});
|
|
56
|
+
createWorkspace(options) {
|
|
57
|
+
return createWorkspace(options);
|
|
61
58
|
}
|
|
62
59
|
}
|
|
63
|
-
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9mb3JnZS5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVXNlckNvbmZpZ0ZhY3RvcnksIFdvcmtzcGFjZUZhY3RvcnkgfSBmcm9tIFwiQGRlY29oZXJlL21lc2hcIjtcbmltcG9ydCB0eXBlIHsgV29ya3NwYWNlRmFjdG9yeU9wdGlvbnMgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuaW1wb3J0IHsgTW9kdWxlTWFuaWZlc3QgfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2NsaVwiO1xuaW1wb3J0IHR5cGUgeyBDb250YWluZXJCdWlsZGVyIH0gZnJvbSBcIkBkZWNvaGVyZS9uZXh1cy9jb21wb3NpdGlvblwiO1xuaW1wb3J0ICogYXMgQWN0aW9ucyBmcm9tIFwiLi9hY3Rpb25zL2luZGV4LmpzXCI7XG5pbXBvcnQgKiBhcyBDb21tYW5kcyBmcm9tIFwiLi9jb21tYW5kcy9pbmRleC5qc1wiO1xuaW1wb3J0IHsgRGVwZW5kZW5jeVJlc29sdmVyIH0gZnJvbSBcIi4vc2VydmljZXMvZGVwZW5kZW5jeS1yZXNvbHZlci5zZXJ2aWNlLmpzXCI7XG5pbXBvcnQgeyBGaWxlV3JpdGVyU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL2ZpbGUtd3JpdGVyLnNlcnZpY2UuanNcIjtcbmltcG9ydCB7IFN3Y1RyYW5zcGlsZXIgfSBmcm9tIFwiLi9zZXJ2aWNlcy9zd2MtdHJhbnNwaWxlci5qc1wiO1xuaW1wb3J0IHsgVHlwZUVtaXR0ZXIgfSBmcm9tIFwiLi9zZXJ2aWNlcy90eXBlLWVtaXR0ZXIuanNcIjtcbmltcG9ydCB7IFRyYW5zZm9ybWVyS2V5IH0gZnJvbSBcIi4vdHlwZXMvdHJhbnNmb3JtZXIudHlwZS5qc1wiO1xuaW1wb3J0IHsgRGVmYXVsdENvbmZpZ3VyYXRpb25zLCBXb3Jrc3BhY2VEZWZhdWx0cyB9IGZyb20gXCIuL3dvcmtzcGFjZS5jb25maWcuanNcIjtcblxuZXhwb3J0IGNsYXNzIEZvcmdlTW9kdWxlIGV4dGVuZHMgTW9kdWxlTWFuaWZlc3Qge1xuXHRwdWJsaWMgcmVhZG9ubHkgaWQgPSBcImZvcmdlXCI7XG5cdHB1YmxpYyByZWFkb25seSBjb21tYW5kID0gQ29tbWFuZHMuRm9yZ2VDb21tYW5kO1xuXHRwdWJsaWMgcmVhZG9ubHkgYWN0aW9ucyA9IHtcblx0XHRjbGVhbjogQWN0aW9ucy5DbGVhbixcblx0XHRjb3B5OiBBY3Rpb25zLkNvcHksXG5cdFx0ZG9ja2VyOiBBY3Rpb25zLkRvY2tlcixcblx0XHRidWlsZDogQWN0aW9ucy5CdWlsZCxcblx0XHR3YXRjaDogQWN0aW9ucy5XYXRjaCxcblx0XHRwdWJsaXNoOiBBY3Rpb25zLlB1Ymxpc2gsXG5cdFx0c3luY0RlcGVuZGVuY2llczogQWN0aW9ucy5TeW5jRGVwZW5kZW5jaWVzLFxuXHRcdHN5bmNMb2NrRmlsZTogQWN0aW9ucy5TeW5jTG9ja0ZpbGUsXG5cdFx0cmVwb3J0RGVwZW5kZW5jaWVzOiBBY3Rpb25zLlJlcG9ydERlcGVuZGVuY2llcyxcblx0XHR2ZXJzaW9uOiBBY3Rpb25zLlZlcnNpb24sXG5cdFx0dGFnOiBBY3Rpb25zLlRhZyxcblx0XHRjb21taXRGaWxlczogQWN0aW9ucy5Db21taXRGaWxlcyxcblx0XHRsaW5rOiBBY3Rpb25zLkxpbmssXG5cdFx0dW5saW5rOiBBY3Rpb25zLlVubGluayxcblx0fTtcblx0cHVibGljIHJlYWRvbmx5IGNvbW1hbmRzID0ge1xuXHRcdGJ1aWxkOiBDb21tYW5kcy5CdWlsZENvbW1hbmQsXG5cdFx0cHVibGlzaDogQ29tbWFuZHMuUHVibGlzaENvbW1hbmQsXG5cdFx0ZGVwZW5kZW5jaWVzOiBDb21tYW5kcy5EZXBlbmRlbmN5Q29tbWFuZCxcblx0XHRkb2NrZXI6IENvbW1hbmRzLkRvY2tlckNvbW1hbmQsXG5cdFx0dmVyc2lvbjogQ29tbWFuZHMuVmVyc2lvbkNvbW1hbmQsXG5cdFx0dGFnOiBDb21tYW5kcy5UYWdDb21tYW5kLFxuXHRcdGxpbms6IENvbW1hbmRzLkxpbmtDb21tYW5kLFxuXHRcdHVubGluazogQ29tbWFuZHMuVW5saW5rQ29tbWFuZCxcblx0fTtcblxuXHRwdWJsaWMgcmVnaXN0ZXJTZXJ2aWNlcyhidWlsZGVyOiBDb250YWluZXJCdWlsZGVyKSB7XG5cdFx0YnVpbGRlci5yZWdpc3RlclNpbmdsZXRvbihUcmFuc2Zvcm1lcktleSwgU3djVHJhbnNwaWxlcik7XG5cdFx0YnVpbGRlci5yZWdpc3RlclNpbmdsZXRvbihUcmFuc2Zvcm1lcktleSwgVHlwZUVtaXR0ZXIpO1xuXHRcdGJ1aWxkZXIucmVnaXN0ZXJTaW5nbGV0b24oRGVwZW5kZW5jeVJlc29sdmVyKTtcblx0XHRidWlsZGVyLnJlZ2lzdGVyU2luZ2xldG9uKEZpbGVXcml0ZXJTZXJ2aWNlKTtcblx0fVxuXG5cdHB1YmxpYyBvdmVycmlkZSBhc3luYyBjcmVhdGVXb3Jrc3BhY2Uob3B0aW9uczogV29ya3NwYWNlRmFjdG9yeU9wdGlvbnMpIHtcblx0XHRjb25zdCB7IGNvbmZpZ3VyYXRpb25zOiBfLCAuLi5mb3JnZURlZmF1bHRzIH0gPSBXb3Jrc3BhY2VEZWZhdWx0cztcblx0XHRjb25zdCB1c2VyQ29uZmlnID0gYXdhaXQgVXNlckNvbmZpZ0ZhY3RvcnkuZ2V0VXNlckNvbmZpZyhvcHRpb25zLmNvbmZpZ0ZpbGUpO1xuXHRcdC8vIE9ubHkgYXBwbHkgZm9yZ2UgZGVmYXVsdCBjb25maWd1cmF0aW9ucyB3aGVuIHVzZXIgY29uZmlnIGRvZXNuJ3QgcHJvdmlkZSBhbnkuXG5cdFx0Ly8gVGhpcyBlbnN1cmVzIHVzZXItZGVmaW5lZCBjb25maWd1cmF0aW9ucyB0YWtlIHByaW9yaXR5IHdoaWxlIHN0aWxsIHByb3ZpZGluZ1xuXHRcdC8vIHNlbnNpYmxlIGRlZmF1bHRzIChkZWJ1ZyArIHJlbGVhc2UpIHdoZW4gbm8gY29uZmlnIGZpbGUgaXMgcHJlc2VudC5cblx0XHRjb25zdCBjb25maWd1cmF0aW9ucyA9IHVzZXJDb25maWcuY29uZmlndXJhdGlvbnM/Lmxlbmd0aFxuXHRcdFx0PyB1bmRlZmluZWRcblx0XHRcdDogRGVmYXVsdENvbmZpZ3VyYXRpb25zO1xuXHRcdHJldHVybiBXb3Jrc3BhY2VGYWN0b3J5LmNyZWF0ZSh7XG5cdFx0XHQuLi5mb3JnZURlZmF1bHRzLFxuXHRcdFx0Li4uKGNvbmZpZ3VyYXRpb25zID8geyBjb25maWd1cmF0aW9ucyB9IDoge30pLFxuXHRcdFx0Y29uZmlnRmlsZTogb3B0aW9ucy5jb25maWdGaWxlLFxuXHRcdFx0cm9vdERpcjogb3B0aW9ucy5yb290RGlyID8/IFdvcmtzcGFjZURlZmF1bHRzLnJvb3REaXIsXG5cdFx0fSk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJVc2VyQ29uZmlnRmFjdG9yeSIsIldvcmtzcGFjZUZhY3RvcnkiLCJNb2R1bGVNYW5pZmVzdCIsIkFjdGlvbnMiLCJDb21tYW5kcyIsIkRlcGVuZGVuY3lSZXNvbHZlciIsIkZpbGVXcml0ZXJTZXJ2aWNlIiwiU3djVHJhbnNwaWxlciIsIlR5cGVFbWl0dGVyIiwiVHJhbnNmb3JtZXJLZXkiLCJEZWZhdWx0Q29uZmlndXJhdGlvbnMiLCJXb3Jrc3BhY2VEZWZhdWx0cyIsIkZvcmdlTW9kdWxlIiwiaWQiLCJjb21tYW5kIiwiRm9yZ2VDb21tYW5kIiwiYWN0aW9ucyIsImNsZWFuIiwiQ2xlYW4iLCJjb3B5IiwiQ29weSIsImRvY2tlciIsIkRvY2tlciIsImJ1aWxkIiwiQnVpbGQiLCJ3YXRjaCIsIldhdGNoIiwicHVibGlzaCIsIlB1Ymxpc2giLCJzeW5jRGVwZW5kZW5jaWVzIiwiU3luY0RlcGVuZGVuY2llcyIsInN5bmNMb2NrRmlsZSIsIlN5bmNMb2NrRmlsZSIsInJlcG9ydERlcGVuZGVuY2llcyIsIlJlcG9ydERlcGVuZGVuY2llcyIsInZlcnNpb24iLCJWZXJzaW9uIiwidGFnIiwiVGFnIiwiY29tbWl0RmlsZXMiLCJDb21taXRGaWxlcyIsImxpbmsiLCJMaW5rIiwidW5saW5rIiwiVW5saW5rIiwiY29tbWFuZHMiLCJCdWlsZENvbW1hbmQiLCJQdWJsaXNoQ29tbWFuZCIsImRlcGVuZGVuY2llcyIsIkRlcGVuZGVuY3lDb21tYW5kIiwiRG9ja2VyQ29tbWFuZCIsIlZlcnNpb25Db21tYW5kIiwiVGFnQ29tbWFuZCIsIkxpbmtDb21tYW5kIiwiVW5saW5rQ29tbWFuZCIsInJlZ2lzdGVyU2VydmljZXMiLCJidWlsZGVyIiwicmVnaXN0ZXJTaW5nbGV0b24iLCJjcmVhdGVXb3Jrc3BhY2UiLCJvcHRpb25zIiwiY29uZmlndXJhdGlvbnMiLCJfIiwiZm9yZ2VEZWZhdWx0cyIsInVzZXJDb25maWciLCJnZXRVc2VyQ29uZmlnIiwiY29uZmlnRmlsZSIsImxlbmd0aCIsInVuZGVmaW5lZCIsImNyZWF0ZSIsInJvb3REaXIiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGlCQUFpQixFQUFFQyxnQkFBZ0IsUUFBUSxpQkFBaUI7QUFFckUsU0FBU0MsY0FBYyxRQUFRLHNCQUFzQjtBQUVyRCxZQUFZQyxhQUFhLHFCQUFxQjtBQUM5QyxZQUFZQyxjQUFjLHNCQUFzQjtBQUNoRCxTQUFTQyxrQkFBa0IsUUFBUSw0Q0FBNEM7QUFDL0UsU0FBU0MsaUJBQWlCLFFBQVEsb0NBQW9DO0FBQ3RFLFNBQVNDLGFBQWEsUUFBUSwrQkFBK0I7QUFDN0QsU0FBU0MsV0FBVyxRQUFRLDZCQUE2QjtBQUN6RCxTQUFTQyxjQUFjLFFBQVEsOEJBQThCO0FBQzdELFNBQVNDLHFCQUFxQixFQUFFQyxpQkFBaUIsUUFBUSx3QkFBd0I7QUFFakYsT0FBTyxNQUFNQyxvQkFBb0JWO0lBQ2hCVyxLQUFLLFFBQVE7SUFDYkMsVUFBVVYsU0FBU1csWUFBWSxDQUFDO0lBQ2hDQyxVQUFVO1FBQ3pCQyxPQUFPZCxRQUFRZSxLQUFLO1FBQ3BCQyxNQUFNaEIsUUFBUWlCLElBQUk7UUFDbEJDLFFBQVFsQixRQUFRbUIsTUFBTTtRQUN0QkMsT0FBT3BCLFFBQVFxQixLQUFLO1FBQ3BCQyxPQUFPdEIsUUFBUXVCLEtBQUs7UUFDcEJDLFNBQVN4QixRQUFReUIsT0FBTztRQUN4QkMsa0JBQWtCMUIsUUFBUTJCLGdCQUFnQjtRQUMxQ0MsY0FBYzVCLFFBQVE2QixZQUFZO1FBQ2xDQyxvQkFBb0I5QixRQUFRK0Isa0JBQWtCO1FBQzlDQyxTQUFTaEMsUUFBUWlDLE9BQU87UUFDeEJDLEtBQUtsQyxRQUFRbUMsR0FBRztRQUNoQkMsYUFBYXBDLFFBQVFxQyxXQUFXO1FBQ2hDQyxNQUFNdEMsUUFBUXVDLElBQUk7UUFDbEJDLFFBQVF4QyxRQUFReUMsTUFBTTtJQUN2QixFQUFFO0lBQ2NDLFdBQVc7UUFDMUJ0QixPQUFPbkIsU0FBUzBDLFlBQVk7UUFDNUJuQixTQUFTdkIsU0FBUzJDLGNBQWM7UUFDaENDLGNBQWM1QyxTQUFTNkMsaUJBQWlCO1FBQ3hDNUIsUUFBUWpCLFNBQVM4QyxhQUFhO1FBQzlCZixTQUFTL0IsU0FBUytDLGNBQWM7UUFDaENkLEtBQUtqQyxTQUFTZ0QsVUFBVTtRQUN4QlgsTUFBTXJDLFNBQVNpRCxXQUFXO1FBQzFCVixRQUFRdkMsU0FBU2tELGFBQWE7SUFDL0IsRUFBRTtJQUVLQyxpQkFBaUJDLE9BQXlCLEVBQUU7UUFDbERBLFFBQVFDLGlCQUFpQixDQUFDaEQsZ0JBQWdCRjtRQUMxQ2lELFFBQVFDLGlCQUFpQixDQUFDaEQsZ0JBQWdCRDtRQUMxQ2dELFFBQVFDLGlCQUFpQixDQUFDcEQ7UUFDMUJtRCxRQUFRQyxpQkFBaUIsQ0FBQ25EO0lBQzNCO0lBRUEsTUFBc0JvRCxnQkFBZ0JDLE9BQWdDLEVBQUU7UUFDdkUsTUFBTSxFQUFFQyxnQkFBZ0JDLENBQUMsRUFBRSxHQUFHQyxlQUFlLEdBQUduRDtRQUNoRCxNQUFNb0QsYUFBYSxNQUFNL0Qsa0JBQWtCZ0UsYUFBYSxDQUFDTCxRQUFRTSxVQUFVO1FBQzNFLGdGQUFnRjtRQUNoRiwrRUFBK0U7UUFDL0Usc0VBQXNFO1FBQ3RFLE1BQU1MLGlCQUFpQkcsV0FBV0gsY0FBYyxFQUFFTSxTQUMvQ0MsWUFDQXpEO1FBQ0gsT0FBT1QsaUJBQWlCbUUsTUFBTSxDQUFDO1lBQzlCLEdBQUdOLGFBQWE7WUFDaEIsR0FBSUYsaUJBQWlCO2dCQUFFQTtZQUFlLElBQUksQ0FBQyxDQUFDO1lBQzVDSyxZQUFZTixRQUFRTSxVQUFVO1lBQzlCSSxTQUFTVixRQUFRVSxPQUFPLElBQUkxRCxrQkFBa0IwRCxPQUFPO1FBQ3REO0lBQ0Q7QUFDRCJ9
|
package/es6/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
export { createWorkspace } from "./create-workspace.js";
|
|
1
2
|
export { ForgeError } from "./errors.js";
|
|
2
3
|
export { ForgeModule } from "./forge.module.js";
|
|
3
4
|
export { SwcTranspiler } from "./services/swc-transpiler.js";
|
|
5
|
+
export { transpileCache } from "./services/transpile-cache.js";
|
|
4
6
|
export { BuildTargets } from "./types/build-target.type.js";
|
|
5
7
|
export { Debug as DebugConfiguration, DefaultConfigurations, Link as LinkConfiguration, Release as ReleaseConfiguration, WorkspaceDefaults } from "./workspace.config.js";
|
|
6
|
-
|
|
7
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgeyBGb3JnZUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzLmpzXCI7XG5leHBvcnQgeyBGb3JnZU1vZHVsZSB9IGZyb20gXCIuL2ZvcmdlLm1vZHVsZS5qc1wiO1xuZXhwb3J0IHR5cGUgeyBUcmFuc3BpbGVPcHRpb25zIH0gZnJvbSBcIi4vc2VydmljZXMvc3djLXRyYW5zcGlsZXIuanNcIjtcbmV4cG9ydCB7IFN3Y1RyYW5zcGlsZXIgfSBmcm9tIFwiLi9zZXJ2aWNlcy9zd2MtdHJhbnNwaWxlci5qc1wiO1xuZXhwb3J0IHR5cGUgeyBCdWlsZFRhcmdldCwgVHJhbnNwaWxlVGFyZ2V0IH0gZnJvbSBcIi4vdHlwZXMvYnVpbGQtdGFyZ2V0LnR5cGUuanNcIjtcbmV4cG9ydCB7IEJ1aWxkVGFyZ2V0cyB9IGZyb20gXCIuL3R5cGVzL2J1aWxkLXRhcmdldC50eXBlLmpzXCI7XG5leHBvcnQgdHlwZSB7IEZvcmdlQ29uZmlndXJhdGlvbiB9IGZyb20gXCIuL3R5cGVzL2NvbmZpZ3VyYXRpb24udHlwZS5qc1wiO1xuZXhwb3J0IHR5cGUgeyBXb3Jrc3BhY2VPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXMvd29ya3NwYWNlLWNvbmZpZy50eXBlLmpzXCI7XG5leHBvcnQge1xuXHREZWJ1ZyBhcyBEZWJ1Z0NvbmZpZ3VyYXRpb24sXG5cdERlZmF1bHRDb25maWd1cmF0aW9ucyxcblx0TGluayBhcyBMaW5rQ29uZmlndXJhdGlvbixcblx0UmVsZWFzZSBhcyBSZWxlYXNlQ29uZmlndXJhdGlvbixcblx0V29ya3NwYWNlRGVmYXVsdHMsXG59IGZyb20gXCIuL3dvcmtzcGFjZS5jb25maWcuanNcIjtcbiJdLCJuYW1lcyI6WyJGb3JnZUVycm9yIiwiRm9yZ2VNb2R1bGUiLCJTd2NUcmFuc3BpbGVyIiwiQnVpbGRUYXJnZXRzIiwiRGVidWciLCJEZWJ1Z0NvbmZpZ3VyYXRpb24iLCJEZWZhdWx0Q29uZmlndXJhdGlvbnMiLCJMaW5rIiwiTGlua0NvbmZpZ3VyYXRpb24iLCJSZWxlYXNlIiwiUmVsZWFzZUNvbmZpZ3VyYXRpb24iLCJXb3Jrc3BhY2VEZWZhdWx0cyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLGNBQWM7QUFDekMsU0FBU0MsV0FBVyxRQUFRLG9CQUFvQjtBQUVoRCxTQUFTQyxhQUFhLFFBQVEsK0JBQStCO0FBRTdELFNBQVNDLFlBQVksUUFBUSwrQkFBK0I7QUFHNUQsU0FDQ0MsU0FBU0Msa0JBQWtCLEVBQzNCQyxxQkFBcUIsRUFDckJDLFFBQVFDLGlCQUFpQixFQUN6QkMsV0FBV0Msb0JBQW9CLEVBQy9CQyxpQkFBaUIsUUFDWCx3QkFBd0IifQ==
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { injectable } from "@decohere/crucible/decorators";
|
|
9
|
+
import { io } from "@decohere/core/io";
|
|
10
|
+
import { ForgeError } from "../errors.js";
|
|
11
|
+
export class DependencyPinner {
|
|
12
|
+
async pin(imported, shipped, projects, workspaceRoot) {
|
|
13
|
+
const scopes = [
|
|
14
|
+
...shipped.map((project)=>({
|
|
15
|
+
name: project.name,
|
|
16
|
+
dir: project.projectRoot,
|
|
17
|
+
pkg: project.pkg
|
|
18
|
+
})),
|
|
19
|
+
{
|
|
20
|
+
name: "the workspace root",
|
|
21
|
+
dir: workspaceRoot.dir,
|
|
22
|
+
pkg: workspaceRoot.pkg
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
const declaredBy = new Map();
|
|
26
|
+
for (const scope of scopes){
|
|
27
|
+
for (const name of Object.keys(scope.pkg.dependencies ?? {})){
|
|
28
|
+
if (projects.has(name)) {
|
|
29
|
+
continue; // a workspace library, copied from its build, never installed
|
|
30
|
+
}
|
|
31
|
+
declaredBy.set(name, [
|
|
32
|
+
...declaredBy.get(name) ?? [],
|
|
33
|
+
scope
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
this.assertImportsAreShipped(imported, declaredBy, scopes);
|
|
38
|
+
const pinned = {};
|
|
39
|
+
for (const name of [
|
|
40
|
+
...declaredBy.keys()
|
|
41
|
+
].sort()){
|
|
42
|
+
pinned[name] = await this.installedVersion(name, declaredBy.get(name) ?? [], workspaceRoot.dir);
|
|
43
|
+
}
|
|
44
|
+
return pinned;
|
|
45
|
+
}
|
|
46
|
+
assertImportsAreShipped(imported, declaredBy, scopes) {
|
|
47
|
+
for (const name of [
|
|
48
|
+
...imported.keys()
|
|
49
|
+
].sort()){
|
|
50
|
+
if (declaredBy.has(name)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const importers = [
|
|
54
|
+
...imported.get(name) ?? []
|
|
55
|
+
].sort().join(", ");
|
|
56
|
+
const devOnly = scopes.find((scope)=>scope.pkg.devDependencies?.[name] != null);
|
|
57
|
+
if (devOnly != null) {
|
|
58
|
+
throw new ForgeError(`${name} is imported at run time by ${importers}, but it is only a devDependency ` + `(of ${devOnly.name}). Move it to "dependencies".`);
|
|
59
|
+
}
|
|
60
|
+
throw new ForgeError(`${name} is imported at run time by ${importers}, but is not in "dependencies" of the ` + "deployable, any library it uses, or the workspace root package.json. Add it there.");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async installedVersion(name, declarers, workspaceRootDir) {
|
|
64
|
+
const versions = new Map();
|
|
65
|
+
for (const scope of declarers){
|
|
66
|
+
const version = await findInstalledVersion(name, scope.dir) ?? await findInstalledVersion(name, workspaceRootDir);
|
|
67
|
+
if (version == null) {
|
|
68
|
+
throw new ForgeError(`${name} is declared by ${scope.name} but is not installed. ` + "Run the package manager install first.");
|
|
69
|
+
}
|
|
70
|
+
versions.set(scope.name, version);
|
|
71
|
+
}
|
|
72
|
+
const distinct = new Set(versions.values());
|
|
73
|
+
if (distinct.size > 1) {
|
|
74
|
+
const detail = [
|
|
75
|
+
...versions
|
|
76
|
+
].map(([owner, version])=>`${owner}: ${version}`).join(", ");
|
|
77
|
+
throw new ForgeError(`${name} is installed at different versions for the packages that declare it (${detail}). ` + "One packaged app can only ship one version; align them.");
|
|
78
|
+
}
|
|
79
|
+
const [version] = distinct;
|
|
80
|
+
if (version == null) {
|
|
81
|
+
throw new ForgeError(`${name} is not installed. Run the package manager install first.`);
|
|
82
|
+
}
|
|
83
|
+
return version;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
DependencyPinner = _ts_decorate([
|
|
87
|
+
injectable()
|
|
88
|
+
], DependencyPinner);
|
|
89
|
+
/** Looks for `node_modules/<name>` in `fromDir` and each folder above it, as Node does. */ async function findInstalledVersion(name, fromDir) {
|
|
90
|
+
let dir = path.resolve(fromDir);
|
|
91
|
+
for(;;){
|
|
92
|
+
const manifest = path.join(dir, "node_modules", name, "package.json");
|
|
93
|
+
if (await io.fileExists(manifest)) {
|
|
94
|
+
const { version } = await io.readJsonFile(manifest);
|
|
95
|
+
return version;
|
|
96
|
+
}
|
|
97
|
+
const parent = path.dirname(dir);
|
|
98
|
+
if (parent === dir) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
dir = parent;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { io } from "@decohere/core/io";
|
|
3
|
+
/** Where `forge package` writes a deployable's output: inside the project, the Docker build context. */ export const PACKAGE_DIR = ".package";
|
|
4
|
+
/**
|
|
5
|
+
* A deployable is a project with a Dockerfile: `docker.dockerfile` from `.decohere.js`,
|
|
6
|
+
* or `Dockerfile` in the project folder. `forge docker` and `forge package` share this
|
|
7
|
+
* rule so they always agree on which projects are deployables.
|
|
8
|
+
*/ function dockerfileName(project) {
|
|
9
|
+
return project.dockerConfig?.dockerfile ?? "Dockerfile";
|
|
10
|
+
}
|
|
11
|
+
function dockerfilePath(project) {
|
|
12
|
+
return path.join(project.projectRoot, dockerfileName(project));
|
|
13
|
+
}
|
|
14
|
+
async function isDeployable(project) {
|
|
15
|
+
return await io.fileExists(dockerfilePath(project));
|
|
16
|
+
}
|
|
17
|
+
export const deployable = {
|
|
18
|
+
dockerfileName,
|
|
19
|
+
dockerfilePath,
|
|
20
|
+
isDeployable
|
|
21
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { injectable } from "@decohere/crucible/decorators";
|
|
9
|
+
import { io } from "@decohere/core/io";
|
|
10
|
+
import { scribe } from "@decohere/scribe";
|
|
11
|
+
import { parseImports } from "parse-imports";
|
|
12
|
+
import { BUILT_IN_MODULES } from "../const.js";
|
|
13
|
+
import { ForgeError } from "../errors.js";
|
|
14
|
+
import { releaseExports } from "./release-exports.js";
|
|
15
|
+
const CODE_FILE = /\.(?:js|mjs|cjs)$/;
|
|
16
|
+
export class ImportGraph {
|
|
17
|
+
#logger = scribe.logger(ImportGraph.name);
|
|
18
|
+
async walk(entry, projects) {
|
|
19
|
+
const reached = {
|
|
20
|
+
workspace: new Set([
|
|
21
|
+
entry.name
|
|
22
|
+
]),
|
|
23
|
+
thirdParty: new Map()
|
|
24
|
+
};
|
|
25
|
+
const exportsByProject = new Map();
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
const queue = [
|
|
28
|
+
{
|
|
29
|
+
file: path.join(entry.releaseDir, "es6", releaseExports.toJs(entry.pkg.main ?? "src/index.ts")),
|
|
30
|
+
owner: entry
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
while(queue.length > 0){
|
|
34
|
+
const { file, owner } = queue.pop();
|
|
35
|
+
if (seen.has(file)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
seen.add(file);
|
|
39
|
+
for (const specifier of (await this.importsOf(file, owner))){
|
|
40
|
+
if (specifier.startsWith(".")) {
|
|
41
|
+
queue.push({
|
|
42
|
+
file: await this.resolveRelative(file, specifier, owner),
|
|
43
|
+
owner
|
|
44
|
+
});
|
|
45
|
+
} else if (!isBuiltin(specifier)) {
|
|
46
|
+
this.follow(specifier, owner, projects, exportsByProject, reached, queue);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return reached;
|
|
51
|
+
}
|
|
52
|
+
follow(specifier, importer, projects, exportsByProject, reached, queue) {
|
|
53
|
+
const name = packageName(specifier);
|
|
54
|
+
const project = projects.get(name);
|
|
55
|
+
if (project == null) {
|
|
56
|
+
const owners = reached.thirdParty.get(name) ?? new Set();
|
|
57
|
+
owners.add(importer.name);
|
|
58
|
+
reached.thirdParty.set(name, owners);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
reached.workspace.add(name);
|
|
62
|
+
let exports = exportsByProject.get(name);
|
|
63
|
+
if (exports == null) {
|
|
64
|
+
exports = releaseExports.build(project.pkg);
|
|
65
|
+
exportsByProject.set(name, exports);
|
|
66
|
+
}
|
|
67
|
+
const subpath = specifier.slice(name.length);
|
|
68
|
+
const target = releaseExports.resolve(exports, subpath);
|
|
69
|
+
if (target == null) {
|
|
70
|
+
throw new ForgeError(`${importer.name} imports "${specifier}", but ${name} does not export "${subpath === "" ? "." : `.${subpath}`}".`);
|
|
71
|
+
}
|
|
72
|
+
queue.push({
|
|
73
|
+
file: path.join(project.releaseDir, target),
|
|
74
|
+
owner: project
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async importsOf(file, owner) {
|
|
78
|
+
if (!await io.fileExists(file)) {
|
|
79
|
+
throw new ForgeError(`${file} is imported by ${owner.name} but was not built. ` + "Run `forge build --configuration release` first.");
|
|
80
|
+
}
|
|
81
|
+
if (!CODE_FILE.test(file)) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const code = await io.readFile(file);
|
|
85
|
+
const specifiers = [];
|
|
86
|
+
try {
|
|
87
|
+
for (const entry of (await parseImports(code))){
|
|
88
|
+
if (entry.moduleSpecifier.value != null) {
|
|
89
|
+
specifiers.push(entry.moduleSpecifier.value);
|
|
90
|
+
} else if (entry.isDynamicImport) {
|
|
91
|
+
this.#logger.warn(`${file}: dynamic import of ${entry.moduleSpecifier.code} cannot be followed; ` + "whatever it loads is not packaged");
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (reason) {
|
|
95
|
+
throw new ForgeError(`Could not read the imports of ${file}: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
96
|
+
}
|
|
97
|
+
return specifiers;
|
|
98
|
+
}
|
|
99
|
+
/** Compiled output keeps explicit `.js` paths; tolerate extensionless and folder imports. */ async resolveRelative(importer, specifier, owner) {
|
|
100
|
+
const base = path.resolve(path.dirname(importer), specifier);
|
|
101
|
+
for (const candidate of [
|
|
102
|
+
base,
|
|
103
|
+
`${base}.js`,
|
|
104
|
+
path.join(base, "index.js")
|
|
105
|
+
]){
|
|
106
|
+
if (await io.fileExists(candidate)) {
|
|
107
|
+
return candidate;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw new ForgeError(`${importer} (${owner.name}) imports "${specifier}", which was not built. ` + "Run `forge build --configuration release` first.");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
ImportGraph = _ts_decorate([
|
|
114
|
+
injectable()
|
|
115
|
+
], ImportGraph);
|
|
116
|
+
/** `@scope/pkg/deep/path` becomes `@scope/pkg`; `pkg/deep` becomes `pkg`. */ function packageName(specifier) {
|
|
117
|
+
const parts = specifier.split("/");
|
|
118
|
+
return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0] ?? specifier;
|
|
119
|
+
}
|
|
120
|
+
function isBuiltin(specifier) {
|
|
121
|
+
return specifier.startsWith("node:") || BUILT_IN_MODULES.includes(specifier) || BUILT_IN_MODULES.includes(packageName(specifier));
|
|
122
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { sourceExtensions } from "@decohere/workspace";
|
|
2
|
+
const ES6_PREFIX = "./es6/";
|
|
3
|
+
/** Condition names that can point at runnable ESM, most specific first. `types` never does. */ const RUNTIME_CONDITIONS = [
|
|
4
|
+
"import",
|
|
5
|
+
"node",
|
|
6
|
+
"default"
|
|
7
|
+
];
|
|
8
|
+
/** `src/main.ts` becomes `src/main.js` (`.mts` `.mjs`, `.cts` `.cjs`), with any leading `./` dropped. */ function toJs(filePath) {
|
|
9
|
+
const file = filePath.replace(/^\.\//, "");
|
|
10
|
+
return sourceExtensions.isSource(file) ? sourceExtensions.outputPath(file) : file;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The `exports` a library needs once only its `es6/` output is shipped: the library's own
|
|
14
|
+
* map (or its `main`) with every path pointed at `./es6/...js`.
|
|
15
|
+
*/ function build(pkg) {
|
|
16
|
+
const result = {};
|
|
17
|
+
for (const [subpath, target] of Object.entries(subpathMap(pkg.exports))){
|
|
18
|
+
const file = runtimeFile(target);
|
|
19
|
+
if (file != null) {
|
|
20
|
+
result[subpath] = file.startsWith(ES6_PREFIX) ? file : `${ES6_PREFIX}${toJs(file)}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (Object.keys(result).length === 0) {
|
|
24
|
+
result["."] = `${ES6_PREFIX}${toJs(pkg.main ?? "src/index.ts")}`;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
/** The file one subpath (`""` for the package root, `/testing`) points at, or undefined. */ function resolve(exports, subpath) {
|
|
29
|
+
const key = subpath === "" ? "." : `.${subpath}`;
|
|
30
|
+
const exact = exports[key];
|
|
31
|
+
if (exact != null) {
|
|
32
|
+
return exact;
|
|
33
|
+
}
|
|
34
|
+
for (const [pattern, target] of Object.entries(exports)){
|
|
35
|
+
const star = pattern.indexOf("*");
|
|
36
|
+
if (star < 0) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const prefix = pattern.slice(0, star);
|
|
40
|
+
const suffix = pattern.slice(star + 1);
|
|
41
|
+
if (key.startsWith(prefix) && key.endsWith(suffix) && key.length >= pattern.length - 1) {
|
|
42
|
+
return target.replaceAll("*", key.slice(prefix.length, key.length - suffix.length));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
/** A bare path or a conditions object means "the root"; otherwise keys are subpaths. */ function subpathMap(exports) {
|
|
48
|
+
if (exports == null) {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
if (typeof exports === "string") {
|
|
52
|
+
return {
|
|
53
|
+
".": exports
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const keys = Object.keys(exports);
|
|
57
|
+
return keys.length > 0 && keys.every((key)=>key.startsWith(".")) ? exports : {
|
|
58
|
+
".": exports
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function runtimeFile(target) {
|
|
62
|
+
if (typeof target === "string") {
|
|
63
|
+
return target;
|
|
64
|
+
}
|
|
65
|
+
if (target == null) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
for (const condition of RUNTIME_CONDITIONS){
|
|
69
|
+
const file = runtimeFile(target[condition]);
|
|
70
|
+
if (file != null) {
|
|
71
|
+
return file;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
export const releaseExports = {
|
|
77
|
+
build,
|
|
78
|
+
resolve,
|
|
79
|
+
toJs
|
|
80
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { io } from "@decohere/core/io";
|
|
3
|
+
import { ForgeError } from "../errors.js";
|
|
4
|
+
export const DEFAULT_UI_OUTPUT = "dist";
|
|
5
|
+
export const DEFAULT_UI_TARGET = "ui";
|
|
6
|
+
/** Folders `forge package` writes itself; a UI cannot land on top of them. */ const RESERVED_TARGETS = new Set([
|
|
7
|
+
"es6",
|
|
8
|
+
"node_modules",
|
|
9
|
+
"config",
|
|
10
|
+
"package.json"
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* What the deployable's `ui` declaration (`.decohere.js`) asks for, checked before anything
|
|
14
|
+
* is written: the UI project exists and has been built. Forge does not build it (see ADR 0007).
|
|
15
|
+
* Returns `undefined` when the deployable declares no UI.
|
|
16
|
+
*/ async function resolve(deployable, projects) {
|
|
17
|
+
const ui = deployable.uiConfig;
|
|
18
|
+
if (ui == null) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const to = path.normalize(ui.to ?? DEFAULT_UI_TARGET);
|
|
22
|
+
const output = ui.output ?? DEFAULT_UI_OUTPUT;
|
|
23
|
+
if (path.isAbsolute(to) || to.split(path.sep).includes("..") || to === ".") {
|
|
24
|
+
throw new ForgeError(`ui.to of ${deployable.name} must be a folder inside .package/, but is "${ui.to}".`);
|
|
25
|
+
}
|
|
26
|
+
if (RESERVED_TARGETS.has(to.split(path.sep)[0])) {
|
|
27
|
+
throw new ForgeError(`ui.to of ${deployable.name} is "${ui.to}", which forge package uses for something else.`);
|
|
28
|
+
}
|
|
29
|
+
const uiProject = projects.find((candidate)=>candidate.name === ui.project);
|
|
30
|
+
if (uiProject == null) {
|
|
31
|
+
throw new ForgeError(`${deployable.name} declares the UI project ${ui.project}, which is not a workspace project. ` + `Known projects: ${projects.map((p)=>p.name).join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
const root = path.resolve(uiProject.projectRoot);
|
|
34
|
+
const from = path.resolve(root, output);
|
|
35
|
+
if (!from.startsWith(root + path.sep)) {
|
|
36
|
+
throw new ForgeError(`ui.output of ${deployable.name} must stay inside ${ui.project}.`);
|
|
37
|
+
}
|
|
38
|
+
if (!await io.directoryExists(from)) {
|
|
39
|
+
throw new ForgeError(`${deployable.name} declares the UI project ${ui.project}, but it has no build output at ${from}. ` + "Build the UI first (forge does not build it), or set ui.output if it builds somewhere else.");
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
project: ui.project,
|
|
43
|
+
from,
|
|
44
|
+
to
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
export const uiAssets = {
|
|
48
|
+
resolve
|
|
49
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./semver.js";
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export const VersionTypes = {
|
|
2
|
+
major: "major",
|
|
3
|
+
minor: "minor",
|
|
4
|
+
patch: "patch",
|
|
5
|
+
prerelease: "prerelease"
|
|
6
|
+
};
|
|
7
|
+
export class SemverError extends Error {
|
|
8
|
+
constructor(message){
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = SemverError.name;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const SEMVER_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
14
|
+
export class Semver {
|
|
15
|
+
version;
|
|
16
|
+
constructor(version){
|
|
17
|
+
this.ensureValid(version);
|
|
18
|
+
this.version = version;
|
|
19
|
+
}
|
|
20
|
+
increment(versionType, preid = "pre") {
|
|
21
|
+
const { major, minor, patch, prerelease } = this.parse(this.version);
|
|
22
|
+
if (versionType === "major") {
|
|
23
|
+
this.version = `${major + 1}.0.0`;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
if (versionType === "minor") {
|
|
27
|
+
this.version = `${major}.${minor + 1}.0`;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
if (versionType === "patch") {
|
|
31
|
+
this.version = `${major}.${minor}.${patch + 1}`;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
if (prerelease == null) {
|
|
35
|
+
this.version = `${major}.${minor}.${patch + 1}-${preid}.0`;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
const [identifier, ...rest] = prerelease.split(".");
|
|
39
|
+
const maybeCounter = rest.at(-1);
|
|
40
|
+
const counter = maybeCounter != null ? Number.parseInt(maybeCounter, 10) : Number.NaN;
|
|
41
|
+
if (identifier === preid && Number.isFinite(counter)) {
|
|
42
|
+
const nextCounter = counter + 1;
|
|
43
|
+
const prefix = rest.length > 1 ? `${rest.slice(0, -1).join(".")}.` : "";
|
|
44
|
+
this.version = `${major}.${minor}.${patch}-${preid}.${prefix}${nextCounter}`;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
this.version = `${major}.${minor}.${patch}-${preid}.0`;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/** This version's major.minor.patch with `prerelease` in place of any it has now. */ withPrerelease(prerelease) {
|
|
51
|
+
const { major, minor, patch } = this.parse(this.version);
|
|
52
|
+
return new Semver(`${major}.${minor}.${patch}-${prerelease}`);
|
|
53
|
+
}
|
|
54
|
+
toString() {
|
|
55
|
+
return this.version;
|
|
56
|
+
}
|
|
57
|
+
ensureValid(version) {
|
|
58
|
+
if (SEMVER_REGEX.test(version)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
62
|
+
}
|
|
63
|
+
parse(version) {
|
|
64
|
+
const match = version.match(SEMVER_REGEX);
|
|
65
|
+
if (match == null) {
|
|
66
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
major: Number.parseInt(match[1], 10),
|
|
70
|
+
minor: Number.parseInt(match[2], 10),
|
|
71
|
+
patch: Number.parseInt(match[3], 10),
|
|
72
|
+
prerelease: match[4]
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|