@decohere/forge 0.0.1-dev.12 → 0.0.1-dev.120
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 +141 -0
- package/commonjs/src/actions/build.action.js +8 -6
- package/commonjs/src/actions/clean.action.js +6 -8
- package/commonjs/src/actions/commit.action.js +4 -6
- package/commonjs/src/actions/copy.action.js +43 -12
- package/commonjs/src/actions/dependency-report.action.js +4 -6
- package/commonjs/src/actions/dependency-sync.action.js +3 -5
- package/commonjs/src/actions/docker.action.js +209 -0
- package/commonjs/src/actions/index.js +6 -2
- package/commonjs/src/actions/link.action.js +154 -0
- package/commonjs/src/actions/package.action.js +234 -0
- package/commonjs/src/actions/paths.action.js +109 -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 +74 -0
- package/commonjs/src/actions/version.action.js +10 -14
- 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 +26 -0
- package/commonjs/src/commands/forge.command.js +1 -3
- package/commonjs/src/commands/index.js +5 -2
- package/commonjs/src/commands/link.command.js +90 -0
- 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 +1 -3
- package/commonjs/src/const.js +0 -2
- package/commonjs/src/create-workspace.js +42 -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 +23 -22
- package/commonjs/src/index.js +11 -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 +92 -0
- package/commonjs/src/services/dependency-resolver.service.js +1 -3
- 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-program-host.js +4 -6
- package/commonjs/src/services/type-emission-program.js +24 -9
- package/commonjs/src/services/type-emitter.js +51 -16
- 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 +39 -6
- package/es6/src/actions/build.action.js +7 -7
- package/es6/src/actions/clean.action.js +5 -8
- package/es6/src/actions/commit.action.js +3 -6
- package/es6/src/actions/copy.action.js +42 -12
- package/es6/src/actions/dependency-report.action.js +3 -7
- package/es6/src/actions/dependency-sync.action.js +2 -6
- package/es6/src/actions/docker.action.js +194 -0
- package/es6/src/actions/index.js +6 -2
- package/es6/src/actions/link.action.js +128 -0
- package/es6/src/actions/package.action.js +219 -0
- package/es6/src/actions/paths.action.js +86 -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 +59 -0
- package/es6/src/actions/version.action.js +5 -10
- 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 +16 -0
- package/es6/src/commands/forge.command.js +1 -3
- package/es6/src/commands/index.js +5 -2
- package/es6/src/commands/link.command.js +67 -0
- 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 +1 -3
- package/es6/src/const.js +0 -2
- package/es6/src/create-workspace.js +30 -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 +23 -22
- package/es6/src/index.js +3 -3
- 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 +71 -0
- package/es6/src/services/dependency-resolver.service.js +1 -3
- 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-program-host.js +4 -6
- package/es6/src/services/type-emission-program.js +24 -9
- package/es6/src/services/type-emitter.js +48 -16
- 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 +39 -5
- package/package.json +6 -5
- package/types/src/actions/build.action.d.ts +5 -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 +13 -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 +38 -0
- package/types/src/actions/index.d.ts +6 -0
- package/types/src/actions/link.action.d.ts +25 -0
- 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 +9 -0
- package/types/src/actions/version.action.d.ts +4 -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 +6 -0
- package/types/src/commands/forge.command.d.ts +2 -2
- package/types/src/commands/index.d.ts +5 -0
- package/types/src/commands/link.command.d.ts +29 -0
- 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 +16 -4
- package/types/src/index.d.ts +3 -1
- 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 +18 -0
- package/types/src/services/dependency-resolver.service.d.ts +1 -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-program-host.d.ts +2 -2
- package/types/src/services/type-emission-program.d.ts +8 -3
- package/types/src/services/type-emitter.d.ts +21 -8
- package/types/src/types/configuration.type.d.ts +6 -1
- package/types/src/types/dependency.types.d.ts +1 -1
- 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 +2 -11
- package/types/src/types/workspace-config.type.d.ts +3 -3
- package/types/src/vitest/forge-build.plugin.d.ts +0 -2
- package/types/src/workspace.config.d.ts +6 -0
- 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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "DependencyPinner", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return DependencyPinner;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
|
+
const _decorators = require("@decohere/crucible/decorators");
|
|
13
|
+
const _io = require("@decohere/core/io");
|
|
14
|
+
const _errors = require("../errors.js");
|
|
15
|
+
function _interop_require_default(obj) {
|
|
16
|
+
return obj && obj.__esModule ? obj : {
|
|
17
|
+
default: obj
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
21
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
22
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
23
|
+
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;
|
|
24
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
25
|
+
}
|
|
26
|
+
class DependencyPinner {
|
|
27
|
+
async pin(imported, shipped, projects, workspaceRoot) {
|
|
28
|
+
const scopes = [
|
|
29
|
+
...shipped.map((project)=>({
|
|
30
|
+
name: project.name,
|
|
31
|
+
dir: project.projectRoot,
|
|
32
|
+
pkg: project.pkg
|
|
33
|
+
})),
|
|
34
|
+
{
|
|
35
|
+
name: "the workspace root",
|
|
36
|
+
dir: workspaceRoot.dir,
|
|
37
|
+
pkg: workspaceRoot.pkg
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
const declaredBy = new Map();
|
|
41
|
+
for (const scope of scopes){
|
|
42
|
+
for (const name of Object.keys(scope.pkg.dependencies ?? {})){
|
|
43
|
+
if (projects.has(name)) {
|
|
44
|
+
continue; // a workspace library, copied from its build, never installed
|
|
45
|
+
}
|
|
46
|
+
declaredBy.set(name, [
|
|
47
|
+
...declaredBy.get(name) ?? [],
|
|
48
|
+
scope
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
this.assertImportsAreShipped(imported, declaredBy, scopes);
|
|
53
|
+
const pinned = {};
|
|
54
|
+
for (const name of [
|
|
55
|
+
...declaredBy.keys()
|
|
56
|
+
].sort()){
|
|
57
|
+
pinned[name] = await this.installedVersion(name, declaredBy.get(name) ?? [], workspaceRoot.dir);
|
|
58
|
+
}
|
|
59
|
+
return pinned;
|
|
60
|
+
}
|
|
61
|
+
assertImportsAreShipped(imported, declaredBy, scopes) {
|
|
62
|
+
for (const name of [
|
|
63
|
+
...imported.keys()
|
|
64
|
+
].sort()){
|
|
65
|
+
if (declaredBy.has(name)) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const importers = [
|
|
69
|
+
...imported.get(name) ?? []
|
|
70
|
+
].sort().join(", ");
|
|
71
|
+
const devOnly = scopes.find((scope)=>scope.pkg.devDependencies?.[name] != null);
|
|
72
|
+
if (devOnly != null) {
|
|
73
|
+
throw new _errors.ForgeError(`${name} is imported at run time by ${importers}, but it is only a devDependency ` + `(of ${devOnly.name}). Move it to "dependencies".`);
|
|
74
|
+
}
|
|
75
|
+
throw new _errors.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.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async installedVersion(name, declarers, workspaceRootDir) {
|
|
79
|
+
const versions = new Map();
|
|
80
|
+
for (const scope of declarers){
|
|
81
|
+
const version = await findInstalledVersion(name, scope.dir) ?? await findInstalledVersion(name, workspaceRootDir);
|
|
82
|
+
if (version == null) {
|
|
83
|
+
throw new _errors.ForgeError(`${name} is declared by ${scope.name} but is not installed. ` + "Run the package manager install first.");
|
|
84
|
+
}
|
|
85
|
+
versions.set(scope.name, version);
|
|
86
|
+
}
|
|
87
|
+
const distinct = new Set(versions.values());
|
|
88
|
+
if (distinct.size > 1) {
|
|
89
|
+
const detail = [
|
|
90
|
+
...versions
|
|
91
|
+
].map(([owner, version])=>`${owner}: ${version}`).join(", ");
|
|
92
|
+
throw new _errors.ForgeError(`${name} is installed at different versions for the packages that declare it (${detail}). ` + "One packaged app can only ship one version; align them.");
|
|
93
|
+
}
|
|
94
|
+
const [version] = distinct;
|
|
95
|
+
if (version == null) {
|
|
96
|
+
throw new _errors.ForgeError(`${name} is not installed. Run the package manager install first.`);
|
|
97
|
+
}
|
|
98
|
+
return version;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
DependencyPinner = _ts_decorate([
|
|
102
|
+
(0, _decorators.injectable)()
|
|
103
|
+
], DependencyPinner);
|
|
104
|
+
/** Looks for `node_modules/<name>` in `fromDir` and each folder above it, as Node does. */ async function findInstalledVersion(name, fromDir) {
|
|
105
|
+
let dir = _nodepath.default.resolve(fromDir);
|
|
106
|
+
for(;;){
|
|
107
|
+
const manifest = _nodepath.default.join(dir, "node_modules", name, "package.json");
|
|
108
|
+
if (await _io.io.fileExists(manifest)) {
|
|
109
|
+
const { version } = await _io.io.readJsonFile(manifest);
|
|
110
|
+
return version;
|
|
111
|
+
}
|
|
112
|
+
const parent = _nodepath.default.dirname(dir);
|
|
113
|
+
if (parent === dir) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
dir = parent;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get PACKAGE_DIR () {
|
|
13
|
+
return PACKAGE_DIR;
|
|
14
|
+
},
|
|
15
|
+
get deployable () {
|
|
16
|
+
return deployable;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
20
|
+
const _io = require("@decohere/core/io");
|
|
21
|
+
function _interop_require_default(obj) {
|
|
22
|
+
return obj && obj.__esModule ? obj : {
|
|
23
|
+
default: obj
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const PACKAGE_DIR = ".package";
|
|
27
|
+
/**
|
|
28
|
+
* A deployable is a project with a Dockerfile: `docker.dockerfile` from `.decohere.js`,
|
|
29
|
+
* or `Dockerfile` in the project folder. `forge docker` and `forge package` share this
|
|
30
|
+
* rule so they always agree on which projects are deployables.
|
|
31
|
+
*/ function dockerfileName(project) {
|
|
32
|
+
return project.dockerConfig?.dockerfile ?? "Dockerfile";
|
|
33
|
+
}
|
|
34
|
+
function dockerfilePath(project) {
|
|
35
|
+
return _nodepath.default.join(project.projectRoot, dockerfileName(project));
|
|
36
|
+
}
|
|
37
|
+
async function isDeployable(project) {
|
|
38
|
+
return await _io.io.fileExists(dockerfilePath(project));
|
|
39
|
+
}
|
|
40
|
+
const deployable = {
|
|
41
|
+
dockerfileName,
|
|
42
|
+
dockerfilePath,
|
|
43
|
+
isDeployable
|
|
44
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ImportGraph", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ImportGraph;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
12
|
+
const _decorators = require("@decohere/crucible/decorators");
|
|
13
|
+
const _io = require("@decohere/core/io");
|
|
14
|
+
const _scribe = require("@decohere/scribe");
|
|
15
|
+
const _parseimports = require("parse-imports");
|
|
16
|
+
const _const = require("../const.js");
|
|
17
|
+
const _errors = require("../errors.js");
|
|
18
|
+
const _releaseexports = require("./release-exports.js");
|
|
19
|
+
function _interop_require_default(obj) {
|
|
20
|
+
return obj && obj.__esModule ? obj : {
|
|
21
|
+
default: obj
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
25
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
27
|
+
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;
|
|
28
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
29
|
+
}
|
|
30
|
+
const CODE_FILE = /\.(?:js|mjs|cjs)$/;
|
|
31
|
+
class ImportGraph {
|
|
32
|
+
#logger = _scribe.scribe.logger(ImportGraph.name);
|
|
33
|
+
async walk(entry, projects) {
|
|
34
|
+
const reached = {
|
|
35
|
+
workspace: new Set([
|
|
36
|
+
entry.name
|
|
37
|
+
]),
|
|
38
|
+
thirdParty: new Map()
|
|
39
|
+
};
|
|
40
|
+
const exportsByProject = new Map();
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
const queue = [
|
|
43
|
+
{
|
|
44
|
+
file: _nodepath.default.join(entry.releaseDir, "es6", _releaseexports.releaseExports.toJs(entry.pkg.main ?? "src/index.ts")),
|
|
45
|
+
owner: entry
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
while(queue.length > 0){
|
|
49
|
+
const { file, owner } = queue.pop();
|
|
50
|
+
if (seen.has(file)) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
seen.add(file);
|
|
54
|
+
for (const specifier of (await this.importsOf(file, owner))){
|
|
55
|
+
if (specifier.startsWith(".")) {
|
|
56
|
+
queue.push({
|
|
57
|
+
file: await this.resolveRelative(file, specifier, owner),
|
|
58
|
+
owner
|
|
59
|
+
});
|
|
60
|
+
} else if (!isBuiltin(specifier)) {
|
|
61
|
+
this.follow(specifier, owner, projects, exportsByProject, reached, queue);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return reached;
|
|
66
|
+
}
|
|
67
|
+
follow(specifier, importer, projects, exportsByProject, reached, queue) {
|
|
68
|
+
const name = packageName(specifier);
|
|
69
|
+
const project = projects.get(name);
|
|
70
|
+
if (project == null) {
|
|
71
|
+
const owners = reached.thirdParty.get(name) ?? new Set();
|
|
72
|
+
owners.add(importer.name);
|
|
73
|
+
reached.thirdParty.set(name, owners);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
reached.workspace.add(name);
|
|
77
|
+
let exports1 = exportsByProject.get(name);
|
|
78
|
+
if (exports1 == null) {
|
|
79
|
+
exports1 = _releaseexports.releaseExports.build(project.pkg);
|
|
80
|
+
exportsByProject.set(name, exports1);
|
|
81
|
+
}
|
|
82
|
+
const subpath = specifier.slice(name.length);
|
|
83
|
+
const target = _releaseexports.releaseExports.resolve(exports1, subpath);
|
|
84
|
+
if (target == null) {
|
|
85
|
+
throw new _errors.ForgeError(`${importer.name} imports "${specifier}", but ${name} does not export "${subpath === "" ? "." : `.${subpath}`}".`);
|
|
86
|
+
}
|
|
87
|
+
queue.push({
|
|
88
|
+
file: _nodepath.default.join(project.releaseDir, target),
|
|
89
|
+
owner: project
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async importsOf(file, owner) {
|
|
93
|
+
if (!await _io.io.fileExists(file)) {
|
|
94
|
+
throw new _errors.ForgeError(`${file} is imported by ${owner.name} but was not built. ` + "Run `forge build --configuration release` first.");
|
|
95
|
+
}
|
|
96
|
+
if (!CODE_FILE.test(file)) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
const code = await _io.io.readFile(file);
|
|
100
|
+
const specifiers = [];
|
|
101
|
+
try {
|
|
102
|
+
for (const entry of (await (0, _parseimports.parseImports)(code))){
|
|
103
|
+
if (entry.moduleSpecifier.value != null) {
|
|
104
|
+
specifiers.push(entry.moduleSpecifier.value);
|
|
105
|
+
} else if (entry.isDynamicImport) {
|
|
106
|
+
this.#logger.warn(`${file}: dynamic import of ${entry.moduleSpecifier.code} cannot be followed; ` + "whatever it loads is not packaged");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
} catch (reason) {
|
|
110
|
+
throw new _errors.ForgeError(`Could not read the imports of ${file}: ${reason instanceof Error ? reason.message : String(reason)}`);
|
|
111
|
+
}
|
|
112
|
+
return specifiers;
|
|
113
|
+
}
|
|
114
|
+
/** Compiled output keeps explicit `.js` paths; tolerate extensionless and folder imports. */ async resolveRelative(importer, specifier, owner) {
|
|
115
|
+
const base = _nodepath.default.resolve(_nodepath.default.dirname(importer), specifier);
|
|
116
|
+
for (const candidate of [
|
|
117
|
+
base,
|
|
118
|
+
`${base}.js`,
|
|
119
|
+
_nodepath.default.join(base, "index.js")
|
|
120
|
+
]){
|
|
121
|
+
if (await _io.io.fileExists(candidate)) {
|
|
122
|
+
return candidate;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
throw new _errors.ForgeError(`${importer} (${owner.name}) imports "${specifier}", which was not built. ` + "Run `forge build --configuration release` first.");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
ImportGraph = _ts_decorate([
|
|
129
|
+
(0, _decorators.injectable)()
|
|
130
|
+
], ImportGraph);
|
|
131
|
+
/** `@scope/pkg/deep/path` becomes `@scope/pkg`; `pkg/deep` becomes `pkg`. */ function packageName(specifier) {
|
|
132
|
+
const parts = specifier.split("/");
|
|
133
|
+
return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0] ?? specifier;
|
|
134
|
+
}
|
|
135
|
+
function isBuiltin(specifier) {
|
|
136
|
+
return specifier.startsWith("node:") || _const.BUILT_IN_MODULES.includes(specifier) || _const.BUILT_IN_MODULES.includes(packageName(specifier));
|
|
137
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "releaseExports", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return releaseExports;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _workspace = require("@decohere/workspace");
|
|
12
|
+
const ES6_PREFIX = "./es6/";
|
|
13
|
+
/** Condition names that can point at runnable ESM, most specific first. `types` never does. */ const RUNTIME_CONDITIONS = [
|
|
14
|
+
"import",
|
|
15
|
+
"node",
|
|
16
|
+
"default"
|
|
17
|
+
];
|
|
18
|
+
/** `src/main.ts` becomes `src/main.js` (`.mts` `.mjs`, `.cts` `.cjs`), with any leading `./` dropped. */ function toJs(filePath) {
|
|
19
|
+
const file = filePath.replace(/^\.\//, "");
|
|
20
|
+
return _workspace.sourceExtensions.isSource(file) ? _workspace.sourceExtensions.outputPath(file) : file;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The `exports` a library needs once only its `es6/` output is shipped: the library's own
|
|
24
|
+
* map (or its `main`) with every path pointed at `./es6/...js`.
|
|
25
|
+
*/ function build(pkg) {
|
|
26
|
+
const result = {};
|
|
27
|
+
for (const [subpath, target] of Object.entries(subpathMap(pkg.exports))){
|
|
28
|
+
const file = runtimeFile(target);
|
|
29
|
+
if (file != null) {
|
|
30
|
+
result[subpath] = file.startsWith(ES6_PREFIX) ? file : `${ES6_PREFIX}${toJs(file)}`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Object.keys(result).length === 0) {
|
|
34
|
+
result["."] = `${ES6_PREFIX}${toJs(pkg.main ?? "src/index.ts")}`;
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
/** The file one subpath (`""` for the package root, `/testing`) points at, or undefined. */ function resolve(exports1, subpath) {
|
|
39
|
+
const key = subpath === "" ? "." : `.${subpath}`;
|
|
40
|
+
const exact = exports1[key];
|
|
41
|
+
if (exact != null) {
|
|
42
|
+
return exact;
|
|
43
|
+
}
|
|
44
|
+
for (const [pattern, target] of Object.entries(exports1)){
|
|
45
|
+
const star = pattern.indexOf("*");
|
|
46
|
+
if (star < 0) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const prefix = pattern.slice(0, star);
|
|
50
|
+
const suffix = pattern.slice(star + 1);
|
|
51
|
+
if (key.startsWith(prefix) && key.endsWith(suffix) && key.length >= pattern.length - 1) {
|
|
52
|
+
return target.replaceAll("*", key.slice(prefix.length, key.length - suffix.length));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/** A bare path or a conditions object means "the root"; otherwise keys are subpaths. */ function subpathMap(exports1) {
|
|
58
|
+
if (exports1 == null) {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
if (typeof exports1 === "string") {
|
|
62
|
+
return {
|
|
63
|
+
".": exports1
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const keys = Object.keys(exports1);
|
|
67
|
+
return keys.length > 0 && keys.every((key)=>key.startsWith(".")) ? exports1 : {
|
|
68
|
+
".": exports1
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function runtimeFile(target) {
|
|
72
|
+
if (typeof target === "string") {
|
|
73
|
+
return target;
|
|
74
|
+
}
|
|
75
|
+
if (target == null) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
for (const condition of RUNTIME_CONDITIONS){
|
|
79
|
+
const file = runtimeFile(target[condition]);
|
|
80
|
+
if (file != null) {
|
|
81
|
+
return file;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const releaseExports = {
|
|
87
|
+
build,
|
|
88
|
+
resolve,
|
|
89
|
+
toJs
|
|
90
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get DEFAULT_UI_OUTPUT () {
|
|
13
|
+
return DEFAULT_UI_OUTPUT;
|
|
14
|
+
},
|
|
15
|
+
get DEFAULT_UI_TARGET () {
|
|
16
|
+
return DEFAULT_UI_TARGET;
|
|
17
|
+
},
|
|
18
|
+
get uiAssets () {
|
|
19
|
+
return uiAssets;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
23
|
+
const _io = require("@decohere/core/io");
|
|
24
|
+
const _errors = require("../errors.js");
|
|
25
|
+
function _interop_require_default(obj) {
|
|
26
|
+
return obj && obj.__esModule ? obj : {
|
|
27
|
+
default: obj
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const DEFAULT_UI_OUTPUT = "dist";
|
|
31
|
+
const DEFAULT_UI_TARGET = "ui";
|
|
32
|
+
/** Folders `forge package` writes itself; a UI cannot land on top of them. */ const RESERVED_TARGETS = new Set([
|
|
33
|
+
"es6",
|
|
34
|
+
"node_modules",
|
|
35
|
+
"config",
|
|
36
|
+
"package.json"
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* What the deployable's `ui` declaration (`.decohere.js`) asks for, checked before anything
|
|
40
|
+
* is written: the UI project exists and has been built. Forge does not build it (see ADR 0007).
|
|
41
|
+
* Returns `undefined` when the deployable declares no UI.
|
|
42
|
+
*/ async function resolve(deployable, projects) {
|
|
43
|
+
const ui = deployable.uiConfig;
|
|
44
|
+
if (ui == null) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const to = _nodepath.default.normalize(ui.to ?? DEFAULT_UI_TARGET);
|
|
48
|
+
const output = ui.output ?? DEFAULT_UI_OUTPUT;
|
|
49
|
+
if (_nodepath.default.isAbsolute(to) || to.split(_nodepath.default.sep).includes("..") || to === ".") {
|
|
50
|
+
throw new _errors.ForgeError(`ui.to of ${deployable.name} must be a folder inside .package/, but is "${ui.to}".`);
|
|
51
|
+
}
|
|
52
|
+
if (RESERVED_TARGETS.has(to.split(_nodepath.default.sep)[0])) {
|
|
53
|
+
throw new _errors.ForgeError(`ui.to of ${deployable.name} is "${ui.to}", which forge package uses for something else.`);
|
|
54
|
+
}
|
|
55
|
+
const uiProject = projects.find((candidate)=>candidate.name === ui.project);
|
|
56
|
+
if (uiProject == null) {
|
|
57
|
+
throw new _errors.ForgeError(`${deployable.name} declares the UI project ${ui.project}, which is not a workspace project. ` + `Known projects: ${projects.map((p)=>p.name).join(", ")}`);
|
|
58
|
+
}
|
|
59
|
+
const root = _nodepath.default.resolve(uiProject.projectRoot);
|
|
60
|
+
const from = _nodepath.default.resolve(root, output);
|
|
61
|
+
if (!from.startsWith(root + _nodepath.default.sep)) {
|
|
62
|
+
throw new _errors.ForgeError(`ui.output of ${deployable.name} must stay inside ${ui.project}.`);
|
|
63
|
+
}
|
|
64
|
+
if (!await _io.io.directoryExists(from)) {
|
|
65
|
+
throw new _errors.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.");
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
project: ui.project,
|
|
69
|
+
from,
|
|
70
|
+
to
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const uiAssets = {
|
|
74
|
+
resolve
|
|
75
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./semver.js"), exports);
|
|
6
|
+
function _export_star(from, to) {
|
|
7
|
+
Object.keys(from).forEach(function(k) {
|
|
8
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
9
|
+
Object.defineProperty(to, k, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function() {
|
|
12
|
+
return from[k];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
return from;
|
|
18
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Semver () {
|
|
13
|
+
return Semver;
|
|
14
|
+
},
|
|
15
|
+
get SemverError () {
|
|
16
|
+
return SemverError;
|
|
17
|
+
},
|
|
18
|
+
get VersionTypes () {
|
|
19
|
+
return VersionTypes;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const VersionTypes = {
|
|
23
|
+
major: "major",
|
|
24
|
+
minor: "minor",
|
|
25
|
+
patch: "patch",
|
|
26
|
+
prerelease: "prerelease"
|
|
27
|
+
};
|
|
28
|
+
class SemverError extends Error {
|
|
29
|
+
constructor(message){
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = SemverError.name;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const SEMVER_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
35
|
+
class Semver {
|
|
36
|
+
version;
|
|
37
|
+
constructor(version){
|
|
38
|
+
this.ensureValid(version);
|
|
39
|
+
this.version = version;
|
|
40
|
+
}
|
|
41
|
+
increment(versionType, preid = "pre") {
|
|
42
|
+
const { major, minor, patch, prerelease } = this.parse(this.version);
|
|
43
|
+
if (versionType === "major") {
|
|
44
|
+
this.version = `${major + 1}.0.0`;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
if (versionType === "minor") {
|
|
48
|
+
this.version = `${major}.${minor + 1}.0`;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
if (versionType === "patch") {
|
|
52
|
+
this.version = `${major}.${minor}.${patch + 1}`;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
if (prerelease == null) {
|
|
56
|
+
this.version = `${major}.${minor}.${patch + 1}-${preid}.0`;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
const [identifier, ...rest] = prerelease.split(".");
|
|
60
|
+
const maybeCounter = rest.at(-1);
|
|
61
|
+
const counter = maybeCounter != null ? Number.parseInt(maybeCounter, 10) : Number.NaN;
|
|
62
|
+
if (identifier === preid && Number.isFinite(counter)) {
|
|
63
|
+
const nextCounter = counter + 1;
|
|
64
|
+
const prefix = rest.length > 1 ? `${rest.slice(0, -1).join(".")}.` : "";
|
|
65
|
+
this.version = `${major}.${minor}.${patch}-${preid}.${prefix}${nextCounter}`;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
this.version = `${major}.${minor}.${patch}-${preid}.0`;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
toString() {
|
|
72
|
+
return this.version;
|
|
73
|
+
}
|
|
74
|
+
ensureValid(version) {
|
|
75
|
+
if (SEMVER_REGEX.test(version)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
79
|
+
}
|
|
80
|
+
parse(version) {
|
|
81
|
+
const match = version.match(SEMVER_REGEX);
|
|
82
|
+
if (match == null) {
|
|
83
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
major: Number.parseInt(match[1], 10),
|
|
87
|
+
minor: Number.parseInt(match[2], 10),
|
|
88
|
+
patch: Number.parseInt(match[3], 10),
|
|
89
|
+
prerelease: match[4]
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "DependencyResolver", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _decorators = require("@decohere/crucible/decorators");
|
|
12
|
-
const _io = require("@decohere/
|
|
12
|
+
const _io = require("@decohere/core/io");
|
|
13
13
|
const _parseimports = require("parse-imports");
|
|
14
14
|
const _const = require("../const.js");
|
|
15
15
|
const _errors = require("../errors.js");
|
|
@@ -168,5 +168,3 @@ class DependencyResolver {
|
|
|
168
168
|
DependencyResolver = _ts_decorate([
|
|
169
169
|
(0, _decorators.injectable)()
|
|
170
170
|
], DependencyResolver);
|
|
171
|
-
|
|
172
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2ZvcmdlL3NyYy9zZXJ2aWNlcy9kZXBlbmRlbmN5LXJlc29sdmVyLnNlcnZpY2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBQYWNrYWdlSnNvbiwgUHJvamVjdCwgV29ya3NwYWNlIH0gZnJvbSBcIkBkZWNvaGVyZS9tZXNoXCI7XG5pbXBvcnQgeyB0eXBlIEZpbGVFeCwgaW8gfSBmcm9tIFwiQGRlY29oZXJlL25leHVzL2lvXCI7XG5pbXBvcnQgeyBwYXJzZUltcG9ydHMgfSBmcm9tIFwicGFyc2UtaW1wb3J0c1wiO1xuaW1wb3J0IHsgQlVJTFRfSU5fTU9EVUxFUyB9IGZyb20gXCIuLi9jb25zdC5qc1wiO1xuaW1wb3J0IHsgRm9yZ2VFcnJvciB9IGZyb20gXCIuLi9lcnJvcnMuanNcIjtcbmltcG9ydCB0eXBlIHtcblx0RGVwZW5kZW5jeVdhcm5pbmcsXG5cdERyaWZ0RW50cnksXG5cdFBhY2thZ2UsXG5cdFJlc29sdmVkRGVwZW5kZW5jeSxcbn0gZnJvbSBcIi4uL3R5cGVzL2RlcGVuZGVuY3kudHlwZXMuanNcIjtcblxuZXhwb3J0IHR5cGUgUHJvamVjdERlcGVuZGVuY2llcyA9IHtcblx0cHJvamVjdDogUHJvamVjdDtcblx0dXBkYXRlZFBhY2thZ2U6IFBhY2thZ2VKc29uO1xuXHR3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXTtcbn07XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBEZXBlbmRlbmN5UmVzb2x2ZXIge1xuXHRwdWJsaWMgY29tcHV0ZURyaWZ0KGN1cnJlbnQ6IFBhY2thZ2VKc29uLCBjb21wdXRlZDogUGFja2FnZUpzb24pOiBEcmlmdEVudHJ5IHwgbnVsbCB7XG5cdFx0Y29uc3Qgc29ydEtleXMgPSAob2JqOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PlxuXHRcdFx0T2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKG9iaikuc29ydCgpKTtcblxuXHRcdGNvbnN0IGN1cnJlbnREZXBzID0gc29ydEtleXMoY3VycmVudC5kZXBlbmRlbmNpZXMgPz8ge30pO1xuXHRcdGNvbnN0IGNvbXB1dGVkRGVwcyA9IHNvcnRLZXlzKGNvbXB1dGVkLmRlcGVuZGVuY2llcyA/PyB7fSk7XG5cdFx0Y29uc3QgY3VycmVudERldkRlcHMgPSBzb3J0S2V5cyhjdXJyZW50LmRldkRlcGVuZGVuY2llcyA/PyB7fSk7XG5cdFx0Y29uc3QgY29tcHV0ZWREZXZEZXBzID0gc29ydEtleXMoY29tcHV0ZWQuZGV2RGVwZW5kZW5jaWVzID8/IHt9KTtcblxuXHRcdGNvbnN0IGhhc0RyaWZ0ID1cblx0XHRcdEpTT04uc3RyaW5naWZ5KGN1cnJlbnREZXBzKSAhPT0gSlNPTi5zdHJpbmdpZnkoY29tcHV0ZWREZXBzKSB8fFxuXHRcdFx0SlNPTi5zdHJpbmdpZnkoY3VycmVudERldkRlcHMpICE9PSBKU09OLnN0cmluZ2lmeShjb21wdXRlZERldkRlcHMpO1xuXG5cdFx0aWYgKCFoYXNEcmlmdCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHtcblx0XHRcdG9yaWdpbmFsOiB7IGRlcGVuZGVuY2llczogY3VycmVudERlcHMsIGRldkRlcGVuZGVuY2llczogY3VycmVudERldkRlcHMgfSxcblx0XHRcdHVwZGF0ZWQ6IHsgZGVwZW5kZW5jaWVzOiBjb21wdXRlZERlcHMsIGRldkRlcGVuZGVuY2llczogY29tcHV0ZWREZXZEZXBzIH0sXG5cdFx0fTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBnZXRXb3Jrc3BhY2VQYWNrYWdlcyhcblx0XHR3b3Jrc3BhY2U6IFdvcmtzcGFjZSxcblx0XHRwcm9qZWN0czogcmVhZG9ubHkgUHJvamVjdFtdLFxuXHQpOiBQcm9taXNlPE1hcDxzdHJpbmcsIFBhY2thZ2U+PiB7XG5cdFx0Y29uc3QgcGFja2FnZUpzb24gPSBhd2FpdCB3b3Jrc3BhY2UuZ2V0UGFja2FnZUpzb24oKS5jYXRjaCgoKSA9PiB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXG5cdFx0XHRcdGBSb290IHBhY2thZ2UuanNvbiBub3QgZm91bmQgYXQgXCIke3dvcmtzcGFjZS5wYWNrYWdlSnNvbkRpcmVjdG9yeX0vcGFja2FnZS5qc29uXCIuIGAgK1xuXHRcdFx0XHRcdGBFbnN1cmUgdGhlIHdvcmtzcGFjZSByb290IGhhcyBhIHBhY2thZ2UuanNvbiB3aXRoIGRlcGVuZGVuY2llcyBsaXN0ZWQuYCxcblx0XHRcdCk7XG5cdFx0fSk7XG5cblx0XHRjb25zdCBpbnRlcm5hbHMgPSBuZXcgTWFwKFxuXHRcdFx0YXdhaXQgUHJvbWlzZS5hbGwoXG5cdFx0XHRcdHByb2plY3RzLm1hcChhc3luYyAocHJvaik6IFByb21pc2U8W3N0cmluZywgUGFja2FnZV0+ID0+IHtcblx0XHRcdFx0XHRjb25zdCBwYWNrYWdlSnNvbiA9IGF3YWl0IHByb2ouZ2V0UGFja2FnZUpzb24oKTtcblx0XHRcdFx0XHRyZXR1cm4gW1xuXHRcdFx0XHRcdFx0cGFja2FnZUpzb24ubmFtZSxcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0bmFtZTogcGFja2FnZUpzb24ubmFtZSxcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGFja2FnZUpzb24udmVyc2lvbixcblx0XHRcdFx0XHRcdFx0aXNJbnRlcm5hbDogdHJ1ZSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XTtcblx0XHRcdFx0fSksXG5cdFx0XHQpLFxuXHRcdCk7XG5cblx0XHRjb25zdCBwYWNrYWdlcyA9IE9iamVjdC5lbnRyaWVzKHBhY2thZ2VKc29uLmRlcGVuZGVuY2llcylcblx0XHRcdC5maWx0ZXIoKFtrZXldKSA9PiAhaW50ZXJuYWxzLmhhcyhrZXkpKVxuXHRcdFx0Lm1hcDxbc3RyaW5nLCBQYWNrYWdlXT4oKFtrZXksIHZhbF0pID0+IFtrZXksIHsgbmFtZToga2V5LCB2ZXJzaW9uOiB2YWwgfV0pO1xuXG5cdFx0Y29uc3QgZGV2UGFja2FnZXMgPSBPYmplY3QuZW50cmllcyhwYWNrYWdlSnNvbi5kZXZEZXBlbmRlbmNpZXMpXG5cdFx0XHQuZmlsdGVyKChba2V5XSkgPT4gIWludGVybmFscy5oYXMoa2V5KSlcblx0XHRcdC5tYXA8W3N0cmluZywgUGFja2FnZV0+KChba2V5LCB2YWxdKSA9PiBba2V5LCB7IG5hbWU6IGtleSwgdmVyc2lvbjogdmFsLCBpc0RldjogdHJ1ZSB9XSk7XG5cblx0XHRyZXR1cm4gbmV3IE1hcChbLi4ucGFja2FnZXMsIC4uLmRldlBhY2thZ2VzLCAuLi5pbnRlcm5hbHNdKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBjb21wdXRlUHJvamVjdERlcGVuZGVuY2llcyhcblx0XHRwcm9qZWN0OiBQcm9qZWN0LFxuXHRcdHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPixcblx0KTogUHJvbWlzZTxQcm9qZWN0RGVwZW5kZW5jaWVzPiB7XG5cdFx0Y29uc3QgeyBkZXBlbmRlbmNpZXMsIGRldkRlcGVuZGVuY2llcywgd2FybmluZ3MgfSA9IGF3YWl0IHRoaXMuZ2V0RGVwZW5kZW5jaWVzKFxuXHRcdFx0cHJvamVjdCxcblx0XHRcdHdvcmtzcGFjZVBhY2thZ2VzLFxuXHRcdCk7XG5cblx0XHRjb25zdCBwa2cgPSBhd2FpdCBwcm9qZWN0LmdldFBhY2thZ2VKc29uKCk7XG5cdFx0Y29uc3QgdXBkYXRlZFBhY2thZ2UgPSBwa2dcblx0XHRcdC53aXRoRGVwZW5kZW5jaWVzKGRlcGVuZGVuY2llcylcblx0XHRcdC53aXRoRGV2RGVwZW5kZW5jaWVzKGRldkRlcGVuZGVuY2llcyk7XG5cblx0XHRyZXR1cm4geyBwcm9qZWN0LCB1cGRhdGVkUGFja2FnZSwgd2FybmluZ3MgfTtcblx0fVxuXG5cdHByaXZhdGUgYXN5bmMgZ2V0RGVwZW5kZW5jaWVzKHByb2plY3Q6IFByb2plY3QsIHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPikge1xuXHRcdGNvbnN0IGZpbGVzID0gYXdhaXQgcHJvamVjdC5nZXRBbGxGaWxlcygpO1xuXHRcdGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChmaWxlcy5tYXAoKGZpbGUpID0+IHRoaXMuZ2V0RmlsZUltcG9ydHMoZmlsZSkpKTtcblx0XHRjb25zdCBpbXBvcnRzID0gcmVzdWx0cy5mbGF0TWFwKChyKSA9PiByLmltcG9ydHMpO1xuXHRcdGNvbnN0IHdhcm5pbmdzID0gcmVzdWx0cy5mbGF0TWFwKChyKSA9PiByLndhcm5pbmdzKTtcblxuXHRcdGNvbnN0IGFsbERlcGVuZGVuY2llcyA9IFsuLi5uZXcgU2V0KGltcG9ydHMpXVxuXHRcdFx0Lm1hcCgoZmlsZUltcG9ydCkgPT4gdGhpcy5nZXREZXBlbmRlbmN5RnJvbShmaWxlSW1wb3J0LCB3b3Jrc3BhY2VQYWNrYWdlcykpXG5cdFx0XHQuZmlsdGVyKChkZXApID0+IGRlcCAhPSBudWxsKTtcblxuXHRcdGNvbnN0IG1pc3NpbmcgPSBhbGxEZXBlbmRlbmNpZXMuZmlsdGVyKFxuXHRcdFx0KGRlcCk6IGRlcCBpcyBSZXNvbHZlZERlcGVuZGVuY3kgJiB7IG1pc3Npbmc6IHRydWUgfSA9PiBkZXAubWlzc2luZyxcblx0XHQpO1xuXG5cdFx0aWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc3QgbmFtZXMgPSBtaXNzaW5nLm1hcCgoZGVwKSA9PiBkZXAubmFtZSkuam9pbihcIiwgXCIpO1xuXHRcdFx0dGhyb3cgbmV3IEZvcmdlRXJyb3IoYE1pc3NpbmcgcGFja2FnZXMgaW4gcHJvamVjdCBcIiR7cHJvamVjdC5uYW1lfVwiOiAke25hbWVzfWApO1xuXHRcdH1cblxuXHRcdGNvbnN0IHJlc29sdmVkID0gYWxsRGVwZW5kZW5jaWVzLmZpbHRlcihcblx0XHRcdChkZXApOiBkZXAgaXMgUmVzb2x2ZWREZXBlbmRlbmN5ICYgeyBtaXNzaW5nOiBmYWxzZSB9ID0+ICFkZXAubWlzc2luZyxcblx0XHQpO1xuXG5cdFx0Y29uc3QgZGVwZW5kZW5jaWVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0cmVzb2x2ZWRcblx0XHRcdFx0LmZpbHRlcigoZGVwKSA9PiAhZGVwLmlzRGV2KVxuXHRcdFx0XHQubWFwPFtzdHJpbmcsIHN0cmluZ10+KChkZXApID0+IFtkZXAubmFtZSwgZGVwLnZlcnNpb25dKSxcblx0XHQpO1xuXG5cdFx0Y29uc3QgZGV2RGVwZW5kZW5jaWVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0cmVzb2x2ZWRcblx0XHRcdFx0LmZpbHRlcigoZGVwKSA9PiBkZXAuaXNEZXYpXG5cdFx0XHRcdC5tYXA8W3N0cmluZywgc3RyaW5nXT4oKGRlcCkgPT4gW2RlcC5uYW1lLCBkZXAudmVyc2lvbl0pLFxuXHRcdCk7XG5cblx0XHRyZXR1cm4geyBkZXBlbmRlbmNpZXMsIGRldkRlcGVuZGVuY2llcywgd2FybmluZ3MgfTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0RGVwZW5kZW5jeUZyb20oXG5cdFx0aW1wb3J0TmFtZTogc3RyaW5nLFxuXHRcdHdvcmtzcGFjZVBhY2thZ2VzOiBNYXA8c3RyaW5nLCBQYWNrYWdlPixcblx0KTogUmVzb2x2ZWREZXBlbmRlbmN5IHwgdW5kZWZpbmVkIHtcblx0XHRpZiAoaW1wb3J0TmFtZS5zdGFydHNXaXRoKFwiLlwiKSB8fCBpbXBvcnROYW1lLnN0YXJ0c1dpdGgoXCJub2RlOlwiKSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHBhY2thZ2VOYW1lTWF0Y2ggPSBpbXBvcnROYW1lLm1hdGNoKC9eKD86KEBbXi9dK1xcL1teL10rKXwoW14vXSspKS8pO1xuXHRcdGNvbnN0IHBhY2thZ2VOYW1lID0gcGFja2FnZU5hbWVNYXRjaD8uWzBdO1xuXG5cdFx0aWYgKHBhY2thZ2VOYW1lID09IG51bGwgfHwgQlVJTFRfSU5fTU9EVUxFUy5pbmNsdWRlcyhwYWNrYWdlTmFtZSkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBwYWNrZyA9IHdvcmtzcGFjZVBhY2thZ2VzLmdldChwYWNrYWdlTmFtZSk7XG5cblx0XHRpZiAocGFja2cgPT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0bmFtZTogcGFja2FnZU5hbWUsXG5cdFx0XHRcdHZlcnNpb246IHVuZGVmaW5lZCxcblx0XHRcdFx0aW50ZXJuYWw6IHVuZGVmaW5lZCxcblx0XHRcdFx0bWlzc2luZzogdHJ1ZSxcblx0XHRcdFx0aXNEZXY6IGZhbHNlLFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0bmFtZTogcGFja2FnZU5hbWUsXG5cdFx0XHR2ZXJzaW9uOiBwYWNrZy52ZXJzaW9uID8/IFwiXCIsXG5cdFx0XHRpbnRlcm5hbDogcGFja2cuaXNJbnRlcm5hbCA/PyBmYWxzZSxcblx0XHRcdG1pc3Npbmc6IGZhbHNlLFxuXHRcdFx0aXNEZXY6IHBhY2tnLmlzRGV2ID8/IGZhbHNlLFxuXHRcdH07XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIGdldEZpbGVJbXBvcnRzKFxuXHRcdGZpbGU6IEZpbGVFeCxcblx0KTogUHJvbWlzZTx7IGltcG9ydHM6IHN0cmluZ1tdOyB3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXSB9PiB7XG5cdFx0Y29uc3QgY29udGVudHMgPSBhd2FpdCBpby5yZWFkRmlsZShmaWxlLmZ1bGxQYXRoKTtcblx0XHRjb25zdCBwYXJzZWQgPSBBcnJheS5mcm9tKGF3YWl0IHBhcnNlSW1wb3J0cyhjb250ZW50cykpO1xuXG5cdFx0Y29uc3QgaW1wb3J0czogc3RyaW5nW10gPSBbXTtcblx0XHRjb25zdCB3YXJuaW5nczogRGVwZW5kZW5jeVdhcm5pbmdbXSA9IFtdO1xuXG5cdFx0Zm9yIChjb25zdCBpbXB0IG9mIHBhcnNlZCkge1xuXHRcdFx0aWYgKGltcHQubW9kdWxlU3BlY2lmaWVyLnZhbHVlICE9IG51bGwpIHtcblx0XHRcdFx0aW1wb3J0cy5wdXNoKGltcHQubW9kdWxlU3BlY2lmaWVyLnZhbHVlKTtcblx0XHRcdH0gZWxzZSBpZiAoaW1wdC5pc0R5bmFtaWNJbXBvcnQpIHtcblx0XHRcdFx0Y29uc3QgbGluZSA9IGNvbnRlbnRzLnN1YnN0cmluZygwLCBpbXB0LnN0YXJ0SW5kZXgpLnNwbGl0KFwiXFxuXCIpLmxlbmd0aDtcblx0XHRcdFx0d2FybmluZ3MucHVzaCh7XG5cdFx0XHRcdFx0ZmlsZTogZmlsZS5mdWxsUGF0aCxcblx0XHRcdFx0XHRsaW5lLFxuXHRcdFx0XHRcdG1lc3NhZ2U6IGBEeW5hbWljIGltcG9ydCB3aXRoIG5vbi1saXRlcmFsIHNwZWNpZmllciBcXGAke2ltcHQubW9kdWxlU3BlY2lmaWVyLmNvZGV9XFxgIGNhbm5vdCBiZSBzdGF0aWNhbGx5IHJlc29sdmVkYCxcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHsgaW1wb3J0cywgd2FybmluZ3MgfTtcblx0fVxufVxuIl0sIm5hbWVzIjpbIkRlcGVuZGVuY3lSZXNvbHZlciIsImNvbXB1dGVEcmlmdCIsImN1cnJlbnQiLCJjb21wdXRlZCIsInNvcnRLZXlzIiwib2JqIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJlbnRyaWVzIiwic29ydCIsImN1cnJlbnREZXBzIiwiZGVwZW5kZW5jaWVzIiwiY29tcHV0ZWREZXBzIiwiY3VycmVudERldkRlcHMiLCJkZXZEZXBlbmRlbmNpZXMiLCJjb21wdXRlZERldkRlcHMiLCJoYXNEcmlmdCIsIkpTT04iLCJzdHJpbmdpZnkiLCJvcmlnaW5hbCIsInVwZGF0ZWQiLCJnZXRXb3Jrc3BhY2VQYWNrYWdlcyIsIndvcmtzcGFjZSIsInByb2plY3RzIiwicGFja2FnZUpzb24iLCJnZXRQYWNrYWdlSnNvbiIsImNhdGNoIiwiRXJyb3IiLCJwYWNrYWdlSnNvbkRpcmVjdG9yeSIsImludGVybmFscyIsIk1hcCIsIlByb21pc2UiLCJhbGwiLCJtYXAiLCJwcm9qIiwibmFtZSIsInZlcnNpb24iLCJpc0ludGVybmFsIiwicGFja2FnZXMiLCJmaWx0ZXIiLCJrZXkiLCJoYXMiLCJ2YWwiLCJkZXZQYWNrYWdlcyIsImlzRGV2IiwiY29tcHV0ZVByb2plY3REZXBlbmRlbmNpZXMiLCJwcm9qZWN0Iiwid29ya3NwYWNlUGFja2FnZXMiLCJ3YXJuaW5ncyIsImdldERlcGVuZGVuY2llcyIsInBrZyIsInVwZGF0ZWRQYWNrYWdlIiwid2l0aERlcGVuZGVuY2llcyIsIndpdGhEZXZEZXBlbmRlbmNpZXMiLCJmaWxlcyIsImdldEFsbEZpbGVzIiwicmVzdWx0cyIsImZpbGUiLCJnZXRGaWxlSW1wb3J0cyIsImltcG9ydHMiLCJmbGF0TWFwIiwiciIsImFsbERlcGVuZGVuY2llcyIsIlNldCIsImZpbGVJbXBvcnQiLCJnZXREZXBlbmRlbmN5RnJvbSIsImRlcCIsIm1pc3NpbmciLCJsZW5ndGgiLCJuYW1lcyIsImpvaW4iLCJGb3JnZUVycm9yIiwicmVzb2x2ZWQiLCJpbXBvcnROYW1lIiwic3RhcnRzV2l0aCIsInBhY2thZ2VOYW1lTWF0Y2giLCJtYXRjaCIsInBhY2thZ2VOYW1lIiwiQlVJTFRfSU5fTU9EVUxFUyIsImluY2x1ZGVzIiwicGFja2ciLCJnZXQiLCJ1bmRlZmluZWQiLCJpbnRlcm5hbCIsImNvbnRlbnRzIiwiaW8iLCJyZWFkRmlsZSIsImZ1bGxQYXRoIiwicGFyc2VkIiwiQXJyYXkiLCJmcm9tIiwicGFyc2VJbXBvcnRzIiwiaW1wdCIsIm1vZHVsZVNwZWNpZmllciIsInZhbHVlIiwicHVzaCIsImlzRHluYW1pY0ltcG9ydCIsImxpbmUiLCJzdWJzdHJpbmciLCJzdGFydEluZGV4Iiwic3BsaXQiLCJtZXNzYWdlIiwiY29kZSJdLCJtYXBwaW5ncyI6Ijs7OzsrQkFvQmFBOzs7ZUFBQUE7Ozs0QkFwQmM7b0JBRUs7OEJBQ0g7dUJBQ0k7d0JBQ047Ozs7Ozs7QUFlcEIsTUFBTUE7SUFDTEMsYUFBYUMsT0FBb0IsRUFBRUMsUUFBcUIsRUFBcUI7UUFDbkYsTUFBTUMsV0FBVyxDQUFDQyxNQUNqQkMsT0FBT0MsV0FBVyxDQUFDRCxP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
|