@decohere/forge 0.0.1-dev.19 → 0.0.1-dev.20261105.46
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 +209 -0
- package/commonjs/src/actions/index.js +4 -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 +26 -0
- package/commonjs/src/commands/forge.command.js +1 -3
- package/commonjs/src/commands/index.js +4 -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 +17 -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 +194 -0
- package/es6/src/actions/index.js +4 -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 +16 -0
- package/es6/src/commands/forge.command.js +1 -3
- package/es6/src/commands/index.js +4 -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 +17 -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 +38 -0
- package/types/src/actions/index.d.ts +4 -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 +6 -0
- package/types/src/commands/forge.command.d.ts +2 -2
- package/types/src/commands/index.d.ts +4 -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 +12 -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
|
@@ -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,96 @@
|
|
|
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
|
+
/** This version's major.minor.patch with `prerelease` in place of any it has now. */ withPrerelease(prerelease) {
|
|
72
|
+
const { major, minor, patch } = this.parse(this.version);
|
|
73
|
+
return new Semver(`${major}.${minor}.${patch}-${prerelease}`);
|
|
74
|
+
}
|
|
75
|
+
toString() {
|
|
76
|
+
return this.version;
|
|
77
|
+
}
|
|
78
|
+
ensureValid(version) {
|
|
79
|
+
if (SEMVER_REGEX.test(version)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
83
|
+
}
|
|
84
|
+
parse(version) {
|
|
85
|
+
const match = version.match(SEMVER_REGEX);
|
|
86
|
+
if (match == null) {
|
|
87
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
major: Number.parseInt(match[1], 10),
|
|
91
|
+
minor: Number.parseInt(match[2], 10),
|
|
92
|
+
patch: Number.parseInt(match[3], 10),
|
|
93
|
+
prerelease: match[4]
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -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");
|
|
@@ -21,24 +21,22 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
21
21
|
}
|
|
22
22
|
class DependencyResolver {
|
|
23
23
|
computeDrift(current, computed) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
const lists = (pkg)=>{
|
|
25
|
+
const sortKeys = (obj)=>Object.fromEntries(Object.entries(obj ?? {}).sort());
|
|
26
|
+
return {
|
|
27
|
+
dependencies: sortKeys(pkg.dependencies),
|
|
28
|
+
devDependencies: sortKeys(pkg.devDependencies),
|
|
29
|
+
peerDependencies: sortKeys(pkg.peerDependencies)
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const original = lists(current);
|
|
33
|
+
const updated = lists(computed);
|
|
34
|
+
if (JSON.stringify(original) === JSON.stringify(updated)) {
|
|
31
35
|
return null;
|
|
32
36
|
}
|
|
33
37
|
return {
|
|
34
|
-
original
|
|
35
|
-
|
|
36
|
-
devDependencies: currentDevDeps
|
|
37
|
-
},
|
|
38
|
-
updated: {
|
|
39
|
-
dependencies: computedDeps,
|
|
40
|
-
devDependencies: computedDevDeps
|
|
41
|
-
}
|
|
38
|
+
original,
|
|
39
|
+
updated
|
|
42
40
|
};
|
|
43
41
|
}
|
|
44
42
|
async getWorkspacePackages(workspace, projects) {
|
|
@@ -78,29 +76,77 @@ class DependencyResolver {
|
|
|
78
76
|
]);
|
|
79
77
|
}
|
|
80
78
|
async computeProjectDependencies(project, workspacePackages) {
|
|
81
|
-
const { dependencies, devDependencies, warnings } = await this.getDependencies(project, workspacePackages);
|
|
82
79
|
const pkg = await project.getPackageJson();
|
|
83
|
-
const
|
|
80
|
+
const peerNames = Object.keys(pkg.peerDependencies ?? {});
|
|
81
|
+
const peerDependencies = this.getPeerDependencies(project, peerNames, workspacePackages);
|
|
82
|
+
const { dependencies, devDependencies, warnings } = await this.getDependencies(project, workspacePackages, new Set(peerNames));
|
|
83
|
+
let updatedPackage = pkg.withDependencies(dependencies).withDevDependencies(devDependencies);
|
|
84
|
+
if (peerNames.length > 0) {
|
|
85
|
+
updatedPackage = updatedPackage.withPeerDependencies(peerDependencies);
|
|
86
|
+
}
|
|
84
87
|
return {
|
|
85
88
|
project,
|
|
86
89
|
updatedPackage,
|
|
87
90
|
warnings
|
|
88
91
|
};
|
|
89
92
|
}
|
|
90
|
-
|
|
93
|
+
/**
|
|
94
|
+
* A package declares its peers by name in its own `peerDependencies` (and marks optional ones in
|
|
95
|
+
* `peerDependenciesMeta`, which sync leaves as written). The root owns every version, so each
|
|
96
|
+
* peer gets the root's range; a peer the root doesn't list is an error. A declared peer stays
|
|
97
|
+
* even when no code imports it: a pino transport, say, is loaded by name.
|
|
98
|
+
*/ getPeerDependencies(project, peerNames, workspacePackages) {
|
|
99
|
+
const peers = {};
|
|
100
|
+
for (const name of [
|
|
101
|
+
...peerNames
|
|
102
|
+
].sort()){
|
|
103
|
+
const version = workspacePackages.get(name)?.version;
|
|
104
|
+
if (version == null) {
|
|
105
|
+
throw new _errors.ForgeError(`"${name}" is declared a peer of ${project.name}, but the root package.json doesn't list it. ` + "Add it there: the root owns every version.");
|
|
106
|
+
}
|
|
107
|
+
peers[name] = version;
|
|
108
|
+
}
|
|
109
|
+
return peers;
|
|
110
|
+
}
|
|
111
|
+
async getDependencies(project, workspacePackages, peers) {
|
|
91
112
|
const files = await project.getAllFiles();
|
|
92
|
-
const results = await Promise.all(files.map((file)=>
|
|
93
|
-
|
|
113
|
+
const results = await Promise.all(files.map(async (file)=>({
|
|
114
|
+
file,
|
|
115
|
+
...await this.getFileImports(file)
|
|
116
|
+
})));
|
|
94
117
|
const warnings = results.flatMap((r)=>r.warnings);
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
/** Which files import each package, for errors that point at the code. */ const importedBy = new Map();
|
|
119
|
+
const allDependencies = [];
|
|
120
|
+
for (const { file, imports } of results){
|
|
121
|
+
for (const fileImport of imports){
|
|
122
|
+
const dep = this.getDependencyFrom(fileImport, workspacePackages);
|
|
123
|
+
if (dep == null || peers.has(dep.name)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (!importedBy.has(dep.name)) {
|
|
127
|
+
importedBy.set(dep.name, new Set());
|
|
128
|
+
allDependencies.push(dep);
|
|
129
|
+
}
|
|
130
|
+
importedBy.get(dep.name)?.add(file.relativePath);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
98
133
|
const missing = allDependencies.filter((dep)=>dep.missing);
|
|
99
134
|
if (missing.length > 0) {
|
|
100
135
|
const names = missing.map((dep)=>dep.name).join(", ");
|
|
101
136
|
throw new _errors.ForgeError(`Missing packages in project "${project.name}": ${names}`);
|
|
102
137
|
}
|
|
103
138
|
const resolved = allDependencies.filter((dep)=>!dep.missing);
|
|
139
|
+
// A configuration that packs is the published shape: its files ship, so a package they
|
|
140
|
+
// import that the root keeps for development would be missing for the consumer.
|
|
141
|
+
if (project.configuration.pack === true) {
|
|
142
|
+
const devOnly = resolved.filter((dep)=>dep.isDev && !dep.internal);
|
|
143
|
+
if (devOnly.length > 0) {
|
|
144
|
+
const lines = devOnly.map((dep)=>` - ${dep.name}, imported by ${[
|
|
145
|
+
...importedBy.get(dep.name) ?? []
|
|
146
|
+
].sort().join(", ")}`);
|
|
147
|
+
throw new _errors.ForgeError(`${project.name} ships code that imports packages the root lists only as a devDependency:\n` + `${lines.join("\n")}\n` + "Move each to the root's dependencies, or, if the consumer provides it, " + `declare it in ${project.name}'s peerDependencies.`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
104
150
|
const dependencies = Object.fromEntries(resolved.filter((dep)=>!dep.isDev).map((dep)=>[
|
|
105
151
|
dep.name,
|
|
106
152
|
dep.version
|
|
@@ -168,5 +214,3 @@ class DependencyResolver {
|
|
|
168
214
|
DependencyResolver = _ts_decorate([
|
|
169
215
|
(0, _decorators.injectable)()
|
|
170
216
|
], 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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
|