@decohere/scaffold 0.0.1-dev.18 → 0.0.1-dev.81
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/commonjs/src/add-api.action.js +39 -0
- package/commonjs/src/add-api.command.js +41 -0
- package/commonjs/src/add.command.js +24 -0
- package/commonjs/src/add.module.js +26 -0
- package/commonjs/src/cli.js +9 -0
- package/commonjs/src/create.command.js +24 -0
- package/commonjs/src/create.module.js +26 -0
- package/commonjs/src/domain/prompt.js +64 -0
- package/commonjs/src/index.js +38 -0
- package/commonjs/src/models/compose.model.js +150 -0
- package/commonjs/src/models/config-yaml.model.js +88 -0
- package/commonjs/src/models/const.js +32 -0
- package/commonjs/src/models/dev-container.model.js +116 -0
- package/commonjs/src/models/docker-image.model.js +259 -0
- package/commonjs/src/models/env-file.model.js +50 -0
- package/commonjs/src/models/gitignore.model.js +43 -0
- package/commonjs/src/models/launch-json.model.js +74 -0
- package/commonjs/src/models/package-json.model.js +149 -0
- package/commonjs/src/models/project.model.js +134 -0
- package/commonjs/src/models/source-file.js +6 -0
- package/commonjs/src/models/tsconfig.model.js +34 -0
- package/commonjs/src/models/vitest-config.model.js +35 -0
- package/commonjs/src/models/vscode-settings.model.js +31 -0
- package/commonjs/src/program.js +57 -0
- package/commonjs/src/resolve-target-dir.js +19 -0
- package/commonjs/src/services/scaffold.service.js +62 -0
- package/commonjs/src/version.js +57 -0
- package/commonjs/src/webapi/api-name.js +95 -0
- package/commonjs/src/webapi/cli-options.js +101 -0
- package/commonjs/src/webapi/const.js +50 -0
- package/commonjs/src/webapi/create-api.js +237 -0
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +166 -0
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/commonjs/src/webapi/devcontainer/host-scripts.js +52 -0
- package/commonjs/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
- package/commonjs/src/webapi/devcontainer/templates/initialize.sh +169 -0
- package/commonjs/src/webapi/devcontainer/templates/post-create.sh +35 -0
- package/commonjs/src/webapi/devcontainer/templates/post-start.sh +65 -0
- package/commonjs/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
- package/commonjs/src/webapi/features/auth.feature.js +441 -0
- package/commonjs/src/webapi/features/auth0-cli.js +435 -0
- package/commonjs/src/webapi/features/biome-format.js +49 -0
- package/commonjs/src/webapi/features/database.feature.js +433 -0
- package/commonjs/src/webapi/features/finalize.feature.js +95 -0
- package/commonjs/src/webapi/features/postman.feature.js +324 -0
- package/commonjs/src/webapi/models/api-package-json.model.js +60 -0
- package/commonjs/src/webapi/models/auth-config.model.js +26 -0
- package/commonjs/src/webapi/models/controller-source-file.model.js +193 -0
- package/commonjs/src/webapi/models/github-ci.model.js +193 -0
- package/commonjs/src/webapi/models/main-source-file.model.js +167 -0
- package/commonjs/src/webapi/models/production-dockerfile.model.js +157 -0
- package/commonjs/src/webapi/models/sample-files.model.js +60 -0
- package/commonjs/src/webapi/models/webapi-image.model.js +27 -0
- package/commonjs/src/webapi/postman/hello-openapi.js +175 -0
- package/commonjs/src/webapi/postman/local-view.js +184 -0
- package/commonjs/src/webapi/postman/openapi-to-postman.js +202 -0
- package/commonjs/src/webapi/workspace-readme.js +110 -0
- package/commonjs/src/webapi.action.js +30 -0
- package/commonjs/src/webapi.command.js +45 -0
- package/es6/src/add-api.action.js +29 -0
- package/es6/src/add-api.command.js +31 -0
- package/es6/src/add.command.js +14 -0
- package/es6/src/add.module.js +16 -0
- package/es6/src/cli.js +5 -0
- package/es6/src/create.command.js +14 -0
- package/es6/src/create.module.js +16 -0
- package/es6/src/domain/prompt.js +43 -0
- package/es6/src/index.js +8 -0
- package/es6/src/models/compose.model.js +144 -0
- package/es6/src/models/config-yaml.model.js +76 -0
- package/es6/src/models/const.js +22 -0
- package/es6/src/models/dev-container.model.js +106 -0
- package/es6/src/models/docker-image.model.js +217 -0
- package/es6/src/models/env-file.model.js +46 -0
- package/es6/src/models/gitignore.model.js +33 -0
- package/es6/src/models/launch-json.model.js +64 -0
- package/es6/src/models/package-json.model.js +137 -0
- package/es6/src/models/project.model.js +119 -0
- package/es6/src/models/source-file.js +3 -0
- package/es6/src/models/tsconfig.model.js +24 -0
- package/es6/src/models/vitest-config.model.js +25 -0
- package/es6/src/models/vscode-settings.model.js +21 -0
- package/es6/src/program.js +39 -0
- package/es6/src/resolve-target-dir.js +9 -0
- package/es6/src/services/scaffold.service.js +52 -0
- package/es6/src/version.js +36 -0
- package/es6/src/webapi/api-name.js +59 -0
- package/es6/src/webapi/cli-options.js +36 -0
- package/es6/src/webapi/const.js +20 -0
- package/es6/src/webapi/create-api.js +217 -0
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +156 -0
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/es6/src/webapi/devcontainer/host-scripts.js +31 -0
- package/es6/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
- package/es6/src/webapi/devcontainer/templates/initialize.sh +169 -0
- package/es6/src/webapi/devcontainer/templates/post-create.sh +35 -0
- package/es6/src/webapi/devcontainer/templates/post-start.sh +65 -0
- package/es6/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
- package/es6/src/webapi/features/auth.feature.js +390 -0
- package/es6/src/webapi/features/auth0-cli.js +375 -0
- package/es6/src/webapi/features/biome-format.js +42 -0
- package/es6/src/webapi/features/database.feature.js +423 -0
- package/es6/src/webapi/features/finalize.feature.js +85 -0
- package/es6/src/webapi/features/postman.feature.js +258 -0
- package/es6/src/webapi/models/api-package-json.model.js +55 -0
- package/es6/src/webapi/models/auth-config.model.js +22 -0
- package/es6/src/webapi/models/controller-source-file.model.js +184 -0
- package/es6/src/webapi/models/github-ci.model.js +186 -0
- package/es6/src/webapi/models/main-source-file.model.js +163 -0
- package/es6/src/webapi/models/production-dockerfile.model.js +148 -0
- package/es6/src/webapi/models/sample-files.model.js +42 -0
- package/es6/src/webapi/models/webapi-image.model.js +20 -0
- package/es6/src/webapi/postman/hello-openapi.js +168 -0
- package/es6/src/webapi/postman/local-view.js +169 -0
- package/es6/src/webapi/postman/openapi-to-postman.js +179 -0
- package/es6/src/webapi/workspace-readme.js +89 -0
- package/es6/src/webapi.action.js +20 -0
- package/es6/src/webapi.command.js +35 -0
- package/package.json +8 -8
- package/types/src/add-api.action.d.ts +13 -0
- package/types/src/add-api.command.d.ts +7 -0
- package/types/src/add.command.d.ts +6 -0
- package/types/src/add.module.d.ts +14 -0
- package/types/src/cli.d.ts +2 -0
- package/types/src/create.command.d.ts +6 -0
- package/types/src/create.module.d.ts +14 -0
- package/types/src/domain/prompt.d.ts +4 -0
- package/types/src/models/compose.model.d.ts +64 -0
- package/types/src/models/config-yaml.model.d.ts +27 -0
- package/types/src/models/const.d.ts +20 -0
- package/types/src/models/dev-container.model.d.ts +37 -0
- package/types/src/models/docker-image.model.d.ts +84 -0
- package/types/src/models/env-file.model.d.ts +16 -0
- package/types/src/models/gitignore.model.d.ts +7 -0
- package/types/src/models/launch-json.model.d.ts +7 -0
- package/types/src/models/package-json.model.d.ts +35 -0
- package/types/src/models/project.model.d.ts +60 -0
- package/{src/models/source-file.ts → types/src/models/source-file.d.ts} +4 -6
- package/types/src/models/tsconfig.model.d.ts +5 -0
- package/types/src/models/vitest-config.model.d.ts +5 -0
- package/types/src/models/vscode-settings.model.d.ts +7 -0
- package/types/src/program.d.ts +3 -0
- package/{src/resolve-target-dir.ts → types/src/resolve-target-dir.d.ts} +1 -4
- package/types/src/services/scaffold.service.d.ts +22 -0
- package/types/src/version.d.ts +6 -0
- package/types/src/webapi/api-name.d.ts +14 -0
- package/types/src/webapi/cli-options.d.ts +6 -0
- package/{src/webapi/const.ts → types/src/webapi/const.d.ts} +7 -21
- package/types/src/webapi/create-api.d.ts +15 -0
- package/types/src/webapi/devcontainer/codebase-rag-mcp.d.ts +32 -0
- package/types/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/types/src/webapi/devcontainer/host-scripts.d.ts +7 -0
- package/types/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
- package/types/src/webapi/devcontainer/templates/initialize.sh +169 -0
- package/types/src/webapi/devcontainer/templates/post-create.sh +35 -0
- package/types/src/webapi/devcontainer/templates/post-start.sh +65 -0
- package/types/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
- package/types/src/webapi/features/auth.feature.d.ts +10 -0
- package/types/src/webapi/features/auth0-cli.d.ts +80 -0
- package/types/src/webapi/features/biome-format.d.ts +5 -0
- package/types/src/webapi/features/database.feature.d.ts +7 -0
- package/types/src/webapi/features/finalize.feature.d.ts +2 -0
- package/types/src/webapi/features/postman.feature.d.ts +16 -0
- package/types/src/webapi/models/api-package-json.model.d.ts +18 -0
- package/types/src/webapi/models/auth-config.model.d.ts +26 -0
- package/types/src/webapi/models/controller-source-file.model.d.ts +46 -0
- package/types/src/webapi/models/github-ci.model.d.ts +9 -0
- package/types/src/webapi/models/main-source-file.model.d.ts +54 -0
- package/types/src/webapi/models/production-dockerfile.model.d.ts +23 -0
- package/types/src/webapi/models/sample-files.model.d.ts +7 -0
- package/types/src/webapi/models/webapi-image.model.d.ts +12 -0
- package/types/src/webapi/postman/hello-openapi.d.ts +19 -0
- package/types/src/webapi/postman/local-view.d.ts +17 -0
- package/types/src/webapi/postman/openapi-to-postman.d.ts +62 -0
- package/types/src/webapi/workspace-readme.d.ts +18 -0
- package/types/src/webapi.action.d.ts +14 -0
- package/types/src/webapi.command.d.ts +11 -0
- package/src/add-api.action.ts +0 -25
- package/src/add-api.command.ts +0 -31
- package/src/add.command.ts +0 -20
- package/src/add.module.ts +0 -11
- package/src/cli.ts +0 -4
- package/src/create.command.ts +0 -20
- package/src/create.module.ts +0 -11
- package/src/domain/prompt.ts +0 -50
- package/src/models/compose.model.ts +0 -205
- package/src/models/config-yaml.model.ts +0 -83
- package/src/models/const.ts +0 -20
- package/src/models/dev-container.model.ts +0 -136
- package/src/models/docker-image.model.ts +0 -343
- package/src/models/env-file.model.ts +0 -45
- package/src/models/gitignore.model.ts +0 -35
- package/src/models/launch-json.model.ts +0 -60
- package/src/models/package-json.model.ts +0 -169
- package/src/models/project.model.ts +0 -141
- package/src/models/tsconfig.model.ts +0 -29
- package/src/models/vitest-config.model.ts +0 -26
- package/src/models/vscode-settings.model.ts +0 -24
- package/src/program.ts +0 -63
- package/src/services/scaffold.service.ts +0 -89
- package/src/version.ts +0 -56
- package/src/webapi/api-name.ts +0 -73
- package/src/webapi/cli-options.ts +0 -56
- package/src/webapi/create-api.ts +0 -275
- package/src/webapi/devcontainer/host-scripts.ts +0 -35
- package/src/webapi/features/auth.feature.ts +0 -454
- package/src/webapi/features/auth0-cli.ts +0 -421
- package/src/webapi/features/biome-format.ts +0 -34
- package/src/webapi/features/database.feature.ts +0 -522
- package/src/webapi/features/finalize.feature.ts +0 -112
- package/src/webapi/features/postman.feature.ts +0 -287
- package/src/webapi/models/api-package-json.model.ts +0 -60
- package/src/webapi/models/auth-config.model.ts +0 -36
- package/src/webapi/models/controller-source-file.model.ts +0 -232
- package/src/webapi/models/github-ci.model.ts +0 -188
- package/src/webapi/models/main-source-file.model.ts +0 -208
- package/src/webapi/models/production-dockerfile.model.ts +0 -162
- package/src/webapi/models/sample-files.model.ts +0 -45
- package/src/webapi/models/webapi-image.model.ts +0 -21
- package/src/webapi/postman/hello-openapi.ts +0 -92
- package/src/webapi/postman/local-view.ts +0 -195
- package/src/webapi/postman/openapi-to-postman.ts +0 -208
- package/src/webapi/workspace-readme.ts +0 -192
- package/src/webapi.action.ts +0 -22
- package/src/webapi.command.ts +0 -41
- package/tests/auth-postman.wiring.spec.ts +0 -263
- package/tests/auth0-cli.spec.ts +0 -232
- package/tests/biome-format.spec.ts +0 -49
- package/tests/cli.integration.spec.ts +0 -658
- package/tests/compose.model.spec.ts +0 -51
- package/tests/container-image.model.spec.ts +0 -162
- package/tests/dev-container.model.spec.ts +0 -29
- package/tests/devcontainer-base-image.spec.ts +0 -32
- package/tests/hello-di-inject.scaffold.spec.ts +0 -18
- package/tests/hello-route.contract.spec.ts +0 -94
- package/tests/package-json.order.spec.ts +0 -59
- package/tests/postman-from-openapi.spec.ts +0 -197
- package/tests/seed-devcontainer-templates.ts +0 -40
- package/tests/webapi/devcontainer/codebase-rag-mcp.spec.ts +0 -96
- /package/{src/index.ts → types/src/index.d.ts} +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { WELL_KNOWN_FILES } from "./const.js";
|
|
2
|
+
export class DevContainer {
|
|
3
|
+
key = WELL_KNOWN_FILES.DEVCONTAINER_JSON;
|
|
4
|
+
_extensions = [];
|
|
5
|
+
_ports = [];
|
|
6
|
+
_portAttributes = new Map();
|
|
7
|
+
_mounts;
|
|
8
|
+
_postCreateCommand;
|
|
9
|
+
_updateContentCommand;
|
|
10
|
+
_postStartCommand;
|
|
11
|
+
_initializeCommand;
|
|
12
|
+
_remoteUser = "node";
|
|
13
|
+
_useCompose = false;
|
|
14
|
+
constructor(){
|
|
15
|
+
this._mounts = [
|
|
16
|
+
"source=..,target=/workspace,type=bind,consistency=cached"
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
addExtension(...ids) {
|
|
20
|
+
this._extensions.push(...ids);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
forwardPort(...ports) {
|
|
24
|
+
this._ports.push(...ports);
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
setPortAttributes(port, attrs) {
|
|
28
|
+
this._portAttributes.set(port, attrs);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
setPostCreateCommand(cmd) {
|
|
32
|
+
this._postCreateCommand = cmd;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
setUpdateContentCommand(cmd) {
|
|
36
|
+
this._updateContentCommand = cmd;
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
setPostStartCommand(cmd) {
|
|
40
|
+
this._postStartCommand = cmd;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
setInitializeCommand(cmd) {
|
|
44
|
+
this._initializeCommand = cmd;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
setRemoteUser(user) {
|
|
48
|
+
this._remoteUser = user;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
useCompose() {
|
|
52
|
+
this._useCompose = true;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
files() {
|
|
56
|
+
const config = {};
|
|
57
|
+
if (this._useCompose) {
|
|
58
|
+
config.dockerComposeFile = "docker-compose.yml";
|
|
59
|
+
config.service = "devcontainer";
|
|
60
|
+
config.workspaceFolder = "/workspace";
|
|
61
|
+
}
|
|
62
|
+
if (this._initializeCommand) {
|
|
63
|
+
config.initializeCommand = this._initializeCommand;
|
|
64
|
+
}
|
|
65
|
+
if (this._mounts) {
|
|
66
|
+
config.mounts = this._mounts;
|
|
67
|
+
}
|
|
68
|
+
if (this._extensions.length > 0) {
|
|
69
|
+
config.customizations = {
|
|
70
|
+
vscode: {
|
|
71
|
+
extensions: this._extensions
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (this._ports.length > 0) {
|
|
76
|
+
config.forwardPorts = this._ports;
|
|
77
|
+
}
|
|
78
|
+
if (this._portAttributes.size > 0) {
|
|
79
|
+
const portsAttributes = {};
|
|
80
|
+
for (const [port, attrs] of this._portAttributes){
|
|
81
|
+
portsAttributes[String(port)] = attrs;
|
|
82
|
+
}
|
|
83
|
+
config.portsAttributes = portsAttributes;
|
|
84
|
+
}
|
|
85
|
+
if (this._postCreateCommand) {
|
|
86
|
+
config.postCreateCommand = this._postCreateCommand;
|
|
87
|
+
}
|
|
88
|
+
if (this._updateContentCommand) {
|
|
89
|
+
config.updateContentCommand = this._updateContentCommand;
|
|
90
|
+
}
|
|
91
|
+
if (this._postStartCommand) {
|
|
92
|
+
config.postStartCommand = this._postStartCommand;
|
|
93
|
+
}
|
|
94
|
+
if (this._remoteUser) {
|
|
95
|
+
config.remoteUser = this._remoteUser;
|
|
96
|
+
}
|
|
97
|
+
return [
|
|
98
|
+
{
|
|
99
|
+
filePath: ".devcontainer/devcontainer.json",
|
|
100
|
+
content: JSON.stringify(config, null, 2)
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9tb2RlbHMvZGV2LWNvbnRhaW5lci5tb2RlbC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBXRUxMX0tOT1dOX0ZJTEVTIH0gZnJvbSBcIi4vY29uc3QuanNcIjtcbmltcG9ydCB0eXBlIHsgS2V5ZWRNb2RlbCwgU291cmNlRmlsZSB9IGZyb20gXCIuL3NvdXJjZS1maWxlLmpzXCI7XG5cbi8qKlxuICogTW9kZWwgZm9yIGAuZGV2Y29udGFpbmVyL2RldmNvbnRhaW5lci5qc29uYC5cbiAqXG4gKiBGZWF0dXJlcyBjYWxsIGJ1aWxkZXIgbWV0aG9kcyAoYGFkZEV4dGVuc2lvbmAsIGBmb3J3YXJkUG9ydGAsIGV0Yy4pIGR1cmluZ1xuICogdGhlaXIgY29uZmlndXJlIHBoYXNlLiBgTW9ub1JlcG9TY2FmZm9sZGAgY2FsbHMgYGZpbGVzKClgIGF0IHJlbmRlciB0aW1lLlxuICovXG5cbmV4cG9ydCB0eXBlIFBvcnRBdHRyaWJ1dGVzID0ge1xuXHRsYWJlbD86IHN0cmluZztcblx0LyoqIFdoZW4gdHJ1ZSwgaG9zdCBwb3J0IG11c3QgbWF0Y2ggdGhlIGNvbnRhaW5lciBwb3J0IChubyByYW5kb20gcmVtYXApLiAqL1xuXHRyZXF1aXJlTG9jYWxQb3J0PzogYm9vbGVhbjtcblx0b25BdXRvRm9yd2FyZD86IFwibm90aWZ5XCIgfCBcIm9wZW5Ccm93c2VyXCIgfCBcIm9wZW5QcmV2aWV3XCIgfCBcInNpbGVudFwiIHwgXCJpZ25vcmVcIjtcbn07XG5cbmV4cG9ydCBjbGFzcyBEZXZDb250YWluZXIgaW1wbGVtZW50cyBLZXllZE1vZGVsIHtcblx0cHVibGljIHJlYWRvbmx5IGtleSA9IFdFTExfS05PV05fRklMRVMuREVWQ09OVEFJTkVSX0pTT047XG5cdHByaXZhdGUgcmVhZG9ubHkgX2V4dGVuc2lvbnM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX3BvcnRzOiBudW1iZXJbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wb3J0QXR0cmlidXRlcyA9IG5ldyBNYXA8bnVtYmVyLCBQb3J0QXR0cmlidXRlcz4oKTtcblx0cHJpdmF0ZSByZWFkb25seSBfbW91bnRzOiBzdHJpbmdbXTtcblx0cHJpdmF0ZSBfcG9zdENyZWF0ZUNvbW1hbmQ/OiBzdHJpbmc7XG5cdHByaXZhdGUgX3VwZGF0ZUNvbnRlbnRDb21tYW5kPzogc3RyaW5nO1xuXHRwcml2YXRlIF9wb3N0U3RhcnRDb21tYW5kPzogc3RyaW5nO1xuXHRwcml2YXRlIF9pbml0aWFsaXplQ29tbWFuZD86IHN0cmluZztcblx0cHJpdmF0ZSBfcmVtb3RlVXNlciA9IFwibm9kZVwiO1xuXHRwcml2YXRlIF91c2VDb21wb3NlID0gZmFsc2U7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKCkge1xuXHRcdHRoaXMuX21vdW50cyA9IFtcInNvdXJjZT0uLix0YXJnZXQ9L3dvcmtzcGFjZSx0eXBlPWJpbmQsY29uc2lzdGVuY3k9Y2FjaGVkXCJdO1xuXHR9XG5cblx0cHVibGljIGFkZEV4dGVuc2lvbiguLi5pZHM6IHN0cmluZ1tdKTogdGhpcyB7XG5cdFx0dGhpcy5fZXh0ZW5zaW9ucy5wdXNoKC4uLmlkcyk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgZm9yd2FyZFBvcnQoLi4ucG9ydHM6IG51bWJlcltdKTogdGhpcyB7XG5cdFx0dGhpcy5fcG9ydHMucHVzaCguLi5wb3J0cyk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgc2V0UG9ydEF0dHJpYnV0ZXMocG9ydDogbnVtYmVyLCBhdHRyczogUG9ydEF0dHJpYnV0ZXMpOiB0aGlzIHtcblx0XHR0aGlzLl9wb3J0QXR0cmlidXRlcy5zZXQocG9ydCwgYXR0cnMpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIHNldFBvc3RDcmVhdGVDb21tYW5kKGNtZDogc3RyaW5nKTogdGhpcyB7XG5cdFx0dGhpcy5fcG9zdENyZWF0ZUNvbW1hbmQgPSBjbWQ7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgc2V0VXBkYXRlQ29udGVudENvbW1hbmQoY21kOiBzdHJpbmcpOiB0aGlzIHtcblx0XHR0aGlzLl91cGRhdGVDb250ZW50Q29tbWFuZCA9IGNtZDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBzZXRQb3N0U3RhcnRDb21tYW5kKGNtZDogc3RyaW5nKTogdGhpcyB7XG5cdFx0dGhpcy5fcG9zdFN0YXJ0Q29tbWFuZCA9IGNtZDtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBzZXRJbml0aWFsaXplQ29tbWFuZChjbWQ6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX2luaXRpYWxpemVDb21tYW5kID0gY21kO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIHNldFJlbW90ZVVzZXIodXNlcjogc3RyaW5nKTogdGhpcyB7XG5cdFx0dGhpcy5fcmVtb3RlVXNlciA9IHVzZXI7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgdXNlQ29tcG9zZSgpOiB0aGlzIHtcblx0XHR0aGlzLl91c2VDb21wb3NlID0gdHJ1ZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBmaWxlcygpOiBTb3VyY2VGaWxlW10ge1xuXHRcdGNvbnN0IGNvbmZpZzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcblxuXHRcdGlmICh0aGlzLl91c2VDb21wb3NlKSB7XG5cdFx0XHRjb25maWcuZG9ja2VyQ29tcG9zZUZpbGUgPSBcImRvY2tlci1jb21wb3NlLnltbFwiO1xuXHRcdFx0Y29uZmlnLnNlcnZpY2UgPSBcImRldmNvbnRhaW5lclwiO1xuXHRcdFx0Y29uZmlnLndvcmtzcGFjZUZvbGRlciA9IFwiL3dvcmtzcGFjZVwiO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9pbml0aWFsaXplQ29tbWFuZCkge1xuXHRcdFx0Y29uZmlnLmluaXRpYWxpemVDb21tYW5kID0gdGhpcy5faW5pdGlhbGl6ZUNvbW1hbmQ7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX21vdW50cykge1xuXHRcdFx0Y29uZmlnLm1vdW50cyA9IHRoaXMuX21vdW50cztcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fZXh0ZW5zaW9ucy5sZW5ndGggPiAwKSB7XG5cdFx0XHRjb25maWcuY3VzdG9taXphdGlvbnMgPSB7IHZzY29kZTogeyBleHRlbnNpb25zOiB0aGlzLl9leHRlbnNpb25zIH0gfTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcG9ydHMubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uZmlnLmZvcndhcmRQb3J0cyA9IHRoaXMuX3BvcnRzO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9wb3J0QXR0cmlidXRlcy5zaXplID4gMCkge1xuXHRcdFx0Y29uc3QgcG9ydHNBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBQb3J0QXR0cmlidXRlcz4gPSB7fTtcblx0XHRcdGZvciAoY29uc3QgW3BvcnQsIGF0dHJzXSBvZiB0aGlzLl9wb3J0QXR0cmlidXRlcykge1xuXHRcdFx0XHRwb3J0c0F0dHJpYnV0ZXNbU3RyaW5nKHBvcnQpXSA9IGF0dHJzO1xuXHRcdFx0fVxuXHRcdFx0Y29uZmlnLnBvcnRzQXR0cmlidXRlcyA9IHBvcnRzQXR0cmlidXRlcztcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcG9zdENyZWF0ZUNvbW1hbmQpIHtcblx0XHRcdGNvbmZpZy5wb3N0Q3JlYXRlQ29tbWFuZCA9IHRoaXMuX3Bvc3RDcmVhdGVDb21tYW5kO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl91cGRhdGVDb250ZW50Q29tbWFuZCkge1xuXHRcdFx0Y29uZmlnLnVwZGF0ZUNvbnRlbnRDb21tYW5kID0gdGhpcy5fdXBkYXRlQ29udGVudENvbW1hbmQ7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3Bvc3RTdGFydENvbW1hbmQpIHtcblx0XHRcdGNvbmZpZy5wb3N0U3RhcnRDb21tYW5kID0gdGhpcy5fcG9zdFN0YXJ0Q29tbWFuZDtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcmVtb3RlVXNlcikge1xuXHRcdFx0Y29uZmlnLnJlbW90ZVVzZXIgPSB0aGlzLl9yZW1vdGVVc2VyO1xuXHRcdH1cblxuXHRcdHJldHVybiBbXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi5kZXZjb250YWluZXIvZGV2Y29udGFpbmVyLmpzb25cIixcblx0XHRcdFx0Y29udGVudDogSlNPTi5zdHJpbmdpZnkoY29uZmlnLCBudWxsLCAyKSxcblx0XHRcdH0sXG5cdFx0XTtcblx0fVxufVxuIl0sIm5hbWVzIjpbIldFTExfS05PV05fRklMRVMiLCJEZXZDb250YWluZXIiLCJrZXkiLCJERVZDT05UQUlORVJfSlNPTiIsIl9leHRlbnNpb25zIiwiX3BvcnRzIiwiX3BvcnRBdHRyaWJ1dGVzIiwiTWFwIiwiX21vdW50cyIsIl9wb3N0Q3JlYXRlQ29tbWFuZCIsIl91cGRhdGVDb250ZW50Q29tbWFuZCIsIl9wb3N0U3RhcnRDb21tYW5kIiwiX2luaXRpYWxpemVDb21tYW5kIiwiX3JlbW90ZVVzZXIiLCJfdXNlQ29tcG9zZSIsImFkZEV4dGVuc2lvbiIsImlkcyIsInB1c2giLCJmb3J3YXJkUG9ydCIsInBvcnRzIiwic2V0UG9ydEF0dHJpYnV0ZXMiLCJwb3J0IiwiYXR0cnMiLCJzZXQiLCJzZXRQb3N0Q3JlYXRlQ29tbWFuZCIsImNtZCIsInNldFVwZGF0ZUNvbnRlbnRDb21tYW5kIiwic2V0UG9zdFN0YXJ0Q29tbWFuZCIsInNldEluaXRpYWxpemVDb21tYW5kIiwic2V0UmVtb3RlVXNlciIsInVzZXIiLCJ1c2VDb21wb3NlIiwiZmlsZXMiLCJjb25maWciLCJkb2NrZXJDb21wb3NlRmlsZSIsInNlcnZpY2UiLCJ3b3Jrc3BhY2VGb2xkZXIiLCJpbml0aWFsaXplQ29tbWFuZCIsIm1vdW50cyIsImxlbmd0aCIsImN1c3RvbWl6YXRpb25zIiwidnNjb2RlIiwiZXh0ZW5zaW9ucyIsImZvcndhcmRQb3J0cyIsInNpemUiLCJwb3J0c0F0dHJpYnV0ZXMiLCJTdHJpbmciLCJwb3N0Q3JlYXRlQ29tbWFuZCIsInVwZGF0ZUNvbnRlbnRDb21tYW5kIiwicG9zdFN0YXJ0Q29tbWFuZCIsInJlbW90ZVVzZXIiLCJmaWxlUGF0aCIsImNvbnRlbnQiLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxnQkFBZ0IsUUFBUSxhQUFhO0FBaUI5QyxPQUFPLE1BQU1DO0lBQ0lDLE1BQU1GLGlCQUFpQkcsaUJBQWlCLENBQUM7SUFDeENDLGNBQXdCLEVBQUUsQ0FBQztJQUMzQkMsU0FBbUIsRUFBRSxDQUFDO0lBQ3RCQyxrQkFBa0IsSUFBSUMsTUFBOEI7SUFDcERDLFFBQWtCO0lBQzNCQyxtQkFBNEI7SUFDNUJDLHNCQUErQjtJQUMvQkMsa0JBQTJCO0lBQzNCQyxtQkFBNEI7SUFDNUJDLGNBQWMsT0FBTztJQUNyQkMsY0FBYyxNQUFNO0lBRTVCLGFBQXFCO1FBQ3BCLElBQUksQ0FBQ04sT0FBTyxHQUFHO1lBQUM7U0FBMkQ7SUFDNUU7SUFFT08sYUFBYSxHQUFHQyxHQUFhLEVBQVE7UUFDM0MsSUFBSSxDQUFDWixXQUFXLENBQUNhLElBQUksSUFBSUQ7UUFDekIsT0FBTyxJQUFJO0lBQ1o7SUFFT0UsWUFBWSxHQUFHQyxLQUFlLEVBQVE7UUFDNUMsSUFBSSxDQUFDZCxNQUFNLENBQUNZLElBQUksSUFBSUU7UUFDcEIsT0FBTyxJQUFJO0lBQ1o7SUFFT0Msa0JBQWtCQyxJQUFZLEVBQUVDLEtBQXFCLEVBQVE7UUFDbkUsSUFBSSxDQUFDaEIsZUFBZSxDQUFDaUIsR0FBRyxDQUFDRixNQUFNQztRQUMvQixPQUFPLElBQUk7SUFDWjtJQUVPRSxxQkFBcUJDLEdBQVcsRUFBUTtRQUM5QyxJQUFJLENBQUNoQixrQkFBa0IsR0FBR2dCO1FBQzFCLE9BQU8sSUFBSTtJQUNaO0lBRU9DLHdCQUF3QkQsR0FBVyxFQUFRO1FBQ2pELElBQUksQ0FBQ2YscUJBQXFCLEdBQUdlO1FBQzdCLE9BQU8sSUFBSTtJQUNaO0lBRU9FLG9CQUFvQkYsR0FBVyxFQUFRO1FBQzdDLElBQUksQ0FBQ2QsaUJBQWlCLEdBQUdjO1FBQ3pCLE9BQU8sSUFBSTtJQUNaO0lBRU9HLHFCQUFxQkgsR0FBVyxFQUFRO1FBQzlDLElBQUksQ0FBQ2Isa0JBQWtCLEdBQUdhO1FBQzFCLE9BQU8sSUFBSTtJQUNaO0lBRU9JLGNBQWNDLElBQVksRUFBUTtRQUN4QyxJQUFJLENBQUNqQixXQUFXLEdBQUdpQjtRQUNuQixPQUFPLElBQUk7SUFDWjtJQUVPQyxhQUFtQjtRQUN6QixJQUFJLENBQUNqQixXQUFXLEdBQUc7UUFDbkIsT0FBTyxJQUFJO0lBQ1o7SUFFT2tCLFFBQXNCO1FBQzVCLE1BQU1DLFNBQWtDLENBQUM7UUFFekMsSUFBSSxJQUFJLENBQUNuQixXQUFXLEVBQUU7WUFDckJtQixPQUFPQyxpQkFBaUIsR0FBRztZQUMzQkQsT0FBT0UsT0FBTyxHQUFHO1lBQ2pCRixPQUFPRyxlQUFlLEdBQUc7UUFDMUI7UUFFQSxJQUFJLElBQUksQ0FBQ3hCLGtCQUFrQixFQUFFO1lBQzVCcUIsT0FBT0ksaUJBQWlCLEdBQUcsSUFBSSxDQUFDekIsa0JBQWtCO1FBQ25EO1FBRUEsSUFBSSxJQUFJLENBQUNKLE9BQU8sRUFBRTtZQUNqQnlCLE9BQU9LLE1BQU0sR0FBRyxJQUFJLENBQUM5QixPQUFPO1FBQzdCO1FBRUEsSUFBSSxJQUFJLENBQUNKLFdBQVcsQ0FBQ21DLE1BQU0sR0FBRyxHQUFHO1lBQ2hDTixPQUFPTyxjQUFjLEdBQUc7Z0JBQUVDLFFBQVE7b0JBQUVDLFlBQVksSUFBSSxDQUFDdEMsV0FBVztnQkFBQztZQUFFO1FBQ3BFO1FBRUEsSUFBSSxJQUFJLENBQUNDLE1BQU0sQ0FBQ2tDLE1BQU0sR0FBRyxHQUFHO1lBQzNCTixPQUFPVSxZQUFZLEdBQUcsSUFBSSxDQUFDdEMsTUFBTTtRQUNsQztRQUVBLElBQUksSUFBSSxDQUFDQyxlQUFlLENBQUNzQyxJQUFJLEdBQUcsR0FBRztZQUNsQyxNQUFNQyxrQkFBa0QsQ0FBQztZQUN6RCxLQUFLLE1BQU0sQ0FBQ3hCLE1BQU1DLE1BQU0sSUFBSSxJQUFJLENBQUNoQixlQUFlLENBQUU7Z0JBQ2pEdUMsZUFBZSxDQUFDQyxPQUFPekIsTUFBTSxHQUFHQztZQUNqQztZQUNBVyxPQUFPWSxlQUFlLEdBQUdBO1FBQzFCO1FBRUEsSUFBSSxJQUFJLENBQUNwQyxrQkFBa0IsRUFBRTtZQUM1QndCLE9BQU9jLGlCQUFpQixHQUFHLElBQUksQ0FBQ3RDLGtCQUFrQjtRQUNuRDtRQUVBLElBQUksSUFBSSxDQUFDQyxxQkFBcUIsRUFBRTtZQUMvQnVCLE9BQU9lLG9CQUFvQixHQUFHLElBQUksQ0FBQ3RDLHFCQUFxQjtRQUN6RDtRQUVBLElBQUksSUFBSSxDQUFDQyxpQkFBaUIsRUFBRTtZQUMzQnNCLE9BQU9nQixnQkFBZ0IsR0FBRyxJQUFJLENBQUN0QyxpQkFBaUI7UUFDakQ7UUFFQSxJQUFJLElBQUksQ0FBQ0UsV0FBVyxFQUFFO1lBQ3JCb0IsT0FBT2lCLFVBQVUsR0FBRyxJQUFJLENBQUNyQyxXQUFXO1FBQ3JDO1FBRUEsT0FBTztZQUNOO2dCQUNDc0MsVUFBVTtnQkFDVkMsU0FBU0MsS0FBS0MsU0FBUyxDQUFDckIsUUFBUSxNQUFNO1lBQ3ZDO1NBQ0E7SUFDRjtBQUNEIn0=
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { WELL_KNOWN_FILES } from "./const.js";
|
|
2
|
+
export class DockerStep {
|
|
3
|
+
key;
|
|
4
|
+
content;
|
|
5
|
+
order;
|
|
6
|
+
constructor(key, content, order = 0){
|
|
7
|
+
this.key = key;
|
|
8
|
+
this.content = content;
|
|
9
|
+
this.order = order;
|
|
10
|
+
}
|
|
11
|
+
static run(key, command, order = 0) {
|
|
12
|
+
return new DockerStep(key, `RUN ${command}`, order);
|
|
13
|
+
}
|
|
14
|
+
static raw(key, content, order = 0) {
|
|
15
|
+
return new DockerStep(key, content, order);
|
|
16
|
+
}
|
|
17
|
+
static entrypoint(key, value, order = 0) {
|
|
18
|
+
const content = typeof value === "string" ? `ENTRYPOINT ${value}` : `ENTRYPOINT ${JSON.stringify(value)}`;
|
|
19
|
+
return new DockerStep(key, content, order);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const StepOrder = {
|
|
23
|
+
base: 1_000,
|
|
24
|
+
features: 5_000,
|
|
25
|
+
user: 9_000,
|
|
26
|
+
entrypoint: 10_000
|
|
27
|
+
};
|
|
28
|
+
const VSCODE_BOOTLOADER_FIX_BASH_SNIPPET = `if [[ -n "\${NODE_OPTIONS:-}" && "\${NODE_OPTIONS}" == *"bootloader.js"* ]]; then
|
|
29
|
+
_bootloader_path="$(printf '%s\\n' "$NODE_OPTIONS" | sed -n 's/.*--require[= ]\\([^[:space:]]*bootloader\\.js\\).*/\\1/p')"
|
|
30
|
+
if [[ -n "\${_bootloader_path}" && ! -f "\${_bootloader_path}" ]]; then
|
|
31
|
+
_stable_bootloader="$(find /vscode/vscode-server /home/node/.vscode-server/extensions -name "bootloader.js" -path "*/ms-vscode.js-debug/*" 2>/dev/null | head -1)"
|
|
32
|
+
if [[ -n "\${_stable_bootloader}" ]]; then
|
|
33
|
+
NODE_OPTIONS="\${NODE_OPTIONS//\${_bootloader_path}/\${_stable_bootloader}}"
|
|
34
|
+
else
|
|
35
|
+
NODE_OPTIONS="$(printf '%s\\n' "$NODE_OPTIONS" | sed -E 's#(^| )--require(=| )[[:graph:]]*bootloader\\.js( |$)# #g; s# +# #g; s#^ ##; s# $##')"
|
|
36
|
+
unset VSCODE_INSPECTOR_OPTIONS
|
|
37
|
+
fi
|
|
38
|
+
export NODE_OPTIONS
|
|
39
|
+
if [[ -z "$NODE_OPTIONS" ]]; then
|
|
40
|
+
unset NODE_OPTIONS
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
unset _bootloader_path _stable_bootloader
|
|
44
|
+
fi`;
|
|
45
|
+
/** Named volume + paths for interactive bash history in app Dev Containers. */ export const commandHistory = {
|
|
46
|
+
volumeName: "bashhistory",
|
|
47
|
+
dir: "/commandhistory",
|
|
48
|
+
fileName: ".bash_history",
|
|
49
|
+
histFile: "/commandhistory/.bash_history"
|
|
50
|
+
};
|
|
51
|
+
export function withCommandHistory(options) {
|
|
52
|
+
const historyDir = options?.historyDir ?? commandHistory.dir;
|
|
53
|
+
const historyFileName = options?.historyFileName ?? commandHistory.fileName;
|
|
54
|
+
const username = options?.username ?? "node";
|
|
55
|
+
const order = options?.order ?? StepOrder.base;
|
|
56
|
+
const historyFile = `${historyDir}/${historyFileName}`;
|
|
57
|
+
return (dockerfile)=>{
|
|
58
|
+
dockerfile.addStep(DockerStep.run("history-dir", `mkdir -p ${historyDir} && touch ${historyFile} && chown -R ${username} ${historyDir}`, order)).addStep(DockerStep.raw("history-env", `ENV HISTFILE=${historyFile}`, order + 1)).addStep(DockerStep.raw("history-bashrc", `RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=${historyFile}" \\\n\t&& echo "$SNIPPET" >> "/home/${username}/.bashrc"`, order + 2));
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function withNodeUser(options) {
|
|
62
|
+
const username = options?.username ?? "node";
|
|
63
|
+
const includeUserInstruction = options?.includeUserInstruction ?? true;
|
|
64
|
+
const order = options?.order ?? StepOrder.features;
|
|
65
|
+
return (dockerfile)=>{
|
|
66
|
+
dockerfile.addStep(DockerStep.raw("arg-username", `ARG USERNAME=${username}`, order));
|
|
67
|
+
if (includeUserInstruction) {
|
|
68
|
+
dockerfile.addStep(DockerStep.raw("user", "USER ${USERNAME}", StepOrder.user));
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export function withPnpm(options) {
|
|
73
|
+
const version = options?.version ?? "10";
|
|
74
|
+
const usernameExpr = options?.usernameExpr ?? "${USERNAME}";
|
|
75
|
+
const order = options?.order ?? StepOrder.features + 100;
|
|
76
|
+
return (dockerfile)=>{
|
|
77
|
+
dockerfile.addStep(DockerStep.run("pnpm-install", `npm install --global npm@latest && npm add --global pnpm@${version}`, order)).addStep(DockerStep.run("pnpm-config", `mkdir -p /home/${usernameExpr}/.config/pnpm /home/${usernameExpr}/.pnpm-store && chown -R ${usernameExpr}:${usernameExpr} /home/${usernameExpr}/.config /home/${usernameExpr}/.pnpm-store && printf "store-dir=/home/${usernameExpr}/.pnpm-store\\n" > /home/${usernameExpr}/.config/pnpm/rc`, order + 1));
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Client-only (`psql`, etc.). Escalates to root so this also works when layered on
|
|
82
|
+
* a published base image that already switched to `USER node`.
|
|
83
|
+
*/ export function withPostgresqlClient(options) {
|
|
84
|
+
const order = options?.order ?? StepOrder.features + 150;
|
|
85
|
+
const username = options?.username ?? "node";
|
|
86
|
+
return (dockerfile)=>{
|
|
87
|
+
dockerfile.addStep(DockerStep.raw("postgresql-client-root", "USER root", order)).addStep(DockerStep.run("postgresql-client", "apt-get update && apt-get install -y --no-install-recommends postgresql-client && rm -rf /var/lib/apt/lists/*", order + 1)).addStep(DockerStep.raw("postgresql-client-user", `USER ${username}`, order + 2));
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/** GitHub CLI — install before USER switches away from root. */ export function withGithubCli(options) {
|
|
91
|
+
const order = options?.order ?? StepOrder.features + 140;
|
|
92
|
+
return (dockerfile)=>{
|
|
93
|
+
dockerfile.addStep(DockerStep.run("github-cli", "apt-get update && apt-get install -y --no-install-recommends gh && rm -rf /var/lib/apt/lists/*", order));
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function withWorkspaceNodeModulesOwnership(options) {
|
|
97
|
+
const workspaceDir = options?.workspaceDir ?? "/workspace";
|
|
98
|
+
const usernameExpr = options?.usernameExpr ?? "${USERNAME}";
|
|
99
|
+
const order = options?.order ?? StepOrder.features + 200;
|
|
100
|
+
return (dockerfile)=>{
|
|
101
|
+
dockerfile.addStep(DockerStep.raw("workspace-node-modules", `RUN mkdir -p ${workspaceDir}/node_modules && chown ${usernameExpr}:${usernameExpr} ${workspaceDir}/node_modules`, order));
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export function withVsCodeJsDebugBootloaderFix(options) {
|
|
105
|
+
const bashrcPath = options?.bashrcPath ?? "/home/${USERNAME}/.bashrc";
|
|
106
|
+
const order = options?.order ?? StepOrder.features + 300;
|
|
107
|
+
return (dockerfile)=>{
|
|
108
|
+
dockerfile.addStep(DockerStep.raw("vscode-bootloader-fix", [
|
|
109
|
+
"# VS Code / Cursor js-debug Auto Attach injects --require …/bootloader.js into",
|
|
110
|
+
"# NODE_OPTIONS. On a fresh Dev Container that path often does not exist yet",
|
|
111
|
+
"# (workspaceStorage file is only created after toggling Auto Attach), which crashes",
|
|
112
|
+
"# every Node command. If the injected path is missing, prefer the stable",
|
|
113
|
+
"# bootloader from the server extension install; otherwise strip the bad require.",
|
|
114
|
+
`RUN cat <<'EOF' >> "${bashrcPath}"`,
|
|
115
|
+
VSCODE_BOOTLOADER_FIX_BASH_SNIPPET,
|
|
116
|
+
"EOF"
|
|
117
|
+
].join("\n"), order));
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export class DockerfileModel {
|
|
121
|
+
key = WELL_KNOWN_FILES.DOCKERFILE;
|
|
122
|
+
_steps = new Map();
|
|
123
|
+
_layerWriters = [];
|
|
124
|
+
_fromImage;
|
|
125
|
+
_layerCounter = 0;
|
|
126
|
+
constructor(baseImage){
|
|
127
|
+
this._fromImage = baseImage;
|
|
128
|
+
this.registerBaseLayers();
|
|
129
|
+
}
|
|
130
|
+
from(baseImage) {
|
|
131
|
+
this._fromImage = baseImage;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
134
|
+
addLayer(layer, order = StepOrder.features) {
|
|
135
|
+
if (typeof layer === "string") {
|
|
136
|
+
const idx = ++this._layerCounter;
|
|
137
|
+
const key = `layer-run-${idx}`;
|
|
138
|
+
this._layerWriters.push((dockerfile)=>{
|
|
139
|
+
dockerfile.addStep(DockerStep.run(key, layer, order + idx));
|
|
140
|
+
});
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
this._layerWriters.push(layer);
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
addStep(step) {
|
|
147
|
+
this._steps.set(step.key, step);
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
removeStep(key) {
|
|
151
|
+
this._steps.delete(key);
|
|
152
|
+
return this;
|
|
153
|
+
}
|
|
154
|
+
entrypoint(value, order = StepOrder.entrypoint) {
|
|
155
|
+
this.addStep(DockerStep.entrypoint("entrypoint", value, order));
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
addRunStep(cmd) {
|
|
159
|
+
return this.addLayer(cmd);
|
|
160
|
+
}
|
|
161
|
+
build() {
|
|
162
|
+
for (const layerWriter of this._layerWriters){
|
|
163
|
+
layerWriter(this);
|
|
164
|
+
}
|
|
165
|
+
const lines = [
|
|
166
|
+
`FROM ${this._fromImage}`
|
|
167
|
+
];
|
|
168
|
+
const sortedSteps = [
|
|
169
|
+
...this._steps.values()
|
|
170
|
+
].sort((left, right)=>{
|
|
171
|
+
if (left.order !== right.order) {
|
|
172
|
+
return left.order - right.order;
|
|
173
|
+
}
|
|
174
|
+
return left.key.localeCompare(right.key, "en");
|
|
175
|
+
});
|
|
176
|
+
for (const step of sortedSteps){
|
|
177
|
+
lines.push("", step.content);
|
|
178
|
+
}
|
|
179
|
+
return `${lines.join("\n")}\n`;
|
|
180
|
+
}
|
|
181
|
+
registerBaseLayers() {
|
|
182
|
+
// Generic base model intentionally has no default layers.
|
|
183
|
+
}
|
|
184
|
+
files() {
|
|
185
|
+
return [
|
|
186
|
+
{
|
|
187
|
+
filePath: "./Dockerfile",
|
|
188
|
+
content: this.build()
|
|
189
|
+
}
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Shared layers for the published `ghcr.io/typesmiths/decohere/devcontainer` image.
|
|
195
|
+
* Checked in at `projects/devcontainer/Dockerfile` — keep in sync via the unit test.
|
|
196
|
+
*/ export class AppDevContainerBaseImage extends DockerfileModel {
|
|
197
|
+
registerBaseLayers() {
|
|
198
|
+
super.registerBaseLayers();
|
|
199
|
+
this.addLayer(withCommandHistory()).addLayer(withNodeUser()).addLayer(withPnpm()).addLayer(withGithubCli()).addLayer(withWorkspaceNodeModulesOwnership()).addLayer(withVsCodeJsDebugBootloaderFix());
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** Generic Dev Container image helpers (history + bootloader) without webapi defaults. */ export class DevContainerImageModel extends DockerfileModel {
|
|
203
|
+
registerBaseLayers() {
|
|
204
|
+
super.registerBaseLayers();
|
|
205
|
+
this.addLayer(withCommandHistory()).addLayer(withVsCodeJsDebugBootloaderFix());
|
|
206
|
+
}
|
|
207
|
+
files() {
|
|
208
|
+
return [
|
|
209
|
+
{
|
|
210
|
+
filePath: ".devcontainer/Dockerfile",
|
|
211
|
+
content: this.build()
|
|
212
|
+
}
|
|
213
|
+
];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9tb2RlbHMvZG9ja2VyLWltYWdlLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdFTExfS05PV05fRklMRVMgfSBmcm9tIFwiLi9jb25zdC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBLZXllZE1vZGVsLCBTb3VyY2VGaWxlIH0gZnJvbSBcIi4vc291cmNlLWZpbGUuanNcIjtcblxuZXhwb3J0IHR5cGUgTGF5ZXJXcml0ZXIgPSAoZG9ja2VyZmlsZTogRG9ja2VyZmlsZU1vZGVsKSA9PiB2b2lkO1xuXG5leHBvcnQgY2xhc3MgRG9ja2VyU3RlcCB7XG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwdWJsaWMgcmVhZG9ubHkga2V5OiBzdHJpbmcsXG5cdFx0cHVibGljIHJlYWRvbmx5IGNvbnRlbnQ6IHN0cmluZyxcblx0XHRwdWJsaWMgcmVhZG9ubHkgb3JkZXIgPSAwLFxuXHQpIHt9XG5cblx0cHVibGljIHN0YXRpYyBydW4oa2V5OiBzdHJpbmcsIGNvbW1hbmQ6IHN0cmluZywgb3JkZXIgPSAwKSB7XG5cdFx0cmV0dXJuIG5ldyBEb2NrZXJTdGVwKGtleSwgYFJVTiAke2NvbW1hbmR9YCwgb3JkZXIpO1xuXHR9XG5cblx0cHVibGljIHN0YXRpYyByYXcoa2V5OiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZywgb3JkZXIgPSAwKSB7XG5cdFx0cmV0dXJuIG5ldyBEb2NrZXJTdGVwKGtleSwgY29udGVudCwgb3JkZXIpO1xuXHR9XG5cblx0cHVibGljIHN0YXRpYyBlbnRyeXBvaW50KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10sIG9yZGVyID0gMCkge1xuXHRcdGNvbnN0IGNvbnRlbnQgPVxuXHRcdFx0dHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiXG5cdFx0XHRcdD8gYEVOVFJZUE9JTlQgJHt2YWx1ZX1gXG5cdFx0XHRcdDogYEVOVFJZUE9JTlQgJHtKU09OLnN0cmluZ2lmeSh2YWx1ZSl9YDtcblx0XHRyZXR1cm4gbmV3IERvY2tlclN0ZXAoa2V5LCBjb250ZW50LCBvcmRlcik7XG5cdH1cbn1cblxuY29uc3QgU3RlcE9yZGVyID0ge1xuXHRiYXNlOiAxXzAwMCxcblx0ZmVhdHVyZXM6IDVfMDAwLFxuXHR1c2VyOiA5XzAwMCxcblx0ZW50cnlwb2ludDogMTBfMDAwLFxufSBhcyBjb25zdDtcblxuY29uc3QgVlNDT0RFX0JPT1RMT0FERVJfRklYX0JBU0hfU05JUFBFVCA9IGBpZiBbWyAtbiBcIlxcJHtOT0RFX09QVElPTlM6LX1cIiAmJiBcIlxcJHtOT0RFX09QVElPTlN9XCIgPT0gKlwiYm9vdGxvYWRlci5qc1wiKiBdXTsgdGhlblxuICAgIF9ib290bG9hZGVyX3BhdGg9XCIkKHByaW50ZiAnJXNcXFxcbicgXCIkTk9ERV9PUFRJT05TXCIgfCBzZWQgLW4gJ3MvLiotLXJlcXVpcmVbPSBdXFxcXChbXls6c3BhY2U6XV0qYm9vdGxvYWRlclxcXFwuanNcXFxcKS4qL1xcXFwxL3AnKVwiXG4gICAgaWYgW1sgLW4gXCJcXCR7X2Jvb3Rsb2FkZXJfcGF0aH1cIiAmJiAhIC1mIFwiXFwke19ib290bG9hZGVyX3BhdGh9XCIgXV07IHRoZW5cbiAgICAgICAgX3N0YWJsZV9ib290bG9hZGVyPVwiJChmaW5kIC92c2NvZGUvdnNjb2RlLXNlcnZlciAvaG9tZS9ub2RlLy52c2NvZGUtc2VydmVyL2V4dGVuc2lvbnMgLW5hbWUgXCJib290bG9hZGVyLmpzXCIgLXBhdGggXCIqL21zLXZzY29kZS5qcy1kZWJ1Zy8qXCIgMj4vZGV2L251bGwgfCBoZWFkIC0xKVwiXG4gICAgICAgIGlmIFtbIC1uIFwiXFwke19zdGFibGVfYm9vdGxvYWRlcn1cIiBdXTsgdGhlblxuICAgICAgICAgICAgTk9ERV9PUFRJT05TPVwiXFwke05PREVfT1BUSU9OUy8vXFwke19ib290bG9hZGVyX3BhdGh9L1xcJHtfc3RhYmxlX2Jvb3Rsb2FkZXJ9fVwiXG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIE5PREVfT1BUSU9OUz1cIiQocHJpbnRmICclc1xcXFxuJyBcIiROT0RFX09QVElPTlNcIiB8IHNlZCAtRSAncyMoXnwgKS0tcmVxdWlyZSg9fCApW1s6Z3JhcGg6XV0qYm9vdGxvYWRlclxcXFwuanMoIHwkKSMgI2c7IHMjICArIyAjZzsgcyNeICMjOyBzIyAkIyMnKVwiXG4gICAgICAgICAgICB1bnNldCBWU0NPREVfSU5TUEVDVE9SX09QVElPTlNcbiAgICAgICAgZmlcbiAgICAgICAgZXhwb3J0IE5PREVfT1BUSU9OU1xuICAgICAgICBpZiBbWyAteiBcIiROT0RFX09QVElPTlNcIiBdXTsgdGhlblxuICAgICAgICAgICAgdW5zZXQgTk9ERV9PUFRJT05TXG4gICAgICAgIGZpXG4gICAgZmlcbiAgICB1bnNldCBfYm9vdGxvYWRlcl9wYXRoIF9zdGFibGVfYm9vdGxvYWRlclxuZmlgO1xuXG4vKiogTmFtZWQgdm9sdW1lICsgcGF0aHMgZm9yIGludGVyYWN0aXZlIGJhc2ggaGlzdG9yeSBpbiBhcHAgRGV2IENvbnRhaW5lcnMuICovXG5leHBvcnQgY29uc3QgY29tbWFuZEhpc3RvcnkgPSB7XG5cdHZvbHVtZU5hbWU6IFwiYmFzaGhpc3RvcnlcIixcblx0ZGlyOiBcIi9jb21tYW5kaGlzdG9yeVwiLFxuXHRmaWxlTmFtZTogXCIuYmFzaF9oaXN0b3J5XCIsXG5cdGhpc3RGaWxlOiBcIi9jb21tYW5kaGlzdG9yeS8uYmFzaF9oaXN0b3J5XCIsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgZnVuY3Rpb24gd2l0aENvbW1hbmRIaXN0b3J5KG9wdGlvbnM/OiB7XG5cdGhpc3RvcnlEaXI/OiBzdHJpbmc7XG5cdGhpc3RvcnlGaWxlTmFtZT86IHN0cmluZztcblx0dXNlcm5hbWU/OiBzdHJpbmc7XG5cdG9yZGVyPzogbnVtYmVyO1xufSk6IExheWVyV3JpdGVyIHtcblx0Y29uc3QgaGlzdG9yeURpciA9IG9wdGlvbnM/Lmhpc3RvcnlEaXIgPz8gY29tbWFuZEhpc3RvcnkuZGlyO1xuXHRjb25zdCBoaXN0b3J5RmlsZU5hbWUgPSBvcHRpb25zPy5oaXN0b3J5RmlsZU5hbWUgPz8gY29tbWFuZEhpc3RvcnkuZmlsZU5hbWU7XG5cdGNvbnN0IHVzZXJuYW1lID0gb3B0aW9ucz8udXNlcm5hbWUgPz8gXCJub2RlXCI7XG5cdGNvbnN0IG9yZGVyID0gb3B0aW9ucz8ub3JkZXIgPz8gU3RlcE9yZGVyLmJhc2U7XG5cdGNvbnN0IGhpc3RvcnlGaWxlID0gYCR7aGlzdG9yeURpcn0vJHtoaXN0b3J5RmlsZU5hbWV9YDtcblxuXHRyZXR1cm4gKGRvY2tlcmZpbGUpID0+IHtcblx0XHRkb2NrZXJmaWxlXG5cdFx0XHQuYWRkU3RlcChcblx0XHRcdFx0RG9ja2VyU3RlcC5ydW4oXG5cdFx0XHRcdFx0XCJoaXN0b3J5LWRpclwiLFxuXHRcdFx0XHRcdGBta2RpciAtcCAke2hpc3RvcnlEaXJ9ICYmIHRvdWNoICR7aGlzdG9yeUZpbGV9ICYmIGNob3duIC1SICR7dXNlcm5hbWV9ICR7aGlzdG9yeURpcn1gLFxuXHRcdFx0XHRcdG9yZGVyLFxuXHRcdFx0XHQpLFxuXHRcdFx0KVxuXHRcdFx0LmFkZFN0ZXAoRG9ja2VyU3RlcC5yYXcoXCJoaXN0b3J5LWVudlwiLCBgRU5WIEhJU1RGSUxFPSR7aGlzdG9yeUZpbGV9YCwgb3JkZXIgKyAxKSlcblx0XHRcdC5hZGRTdGVwKFxuXHRcdFx0XHREb2NrZXJTdGVwLnJhdyhcblx0XHRcdFx0XHRcImhpc3RvcnktYmFzaHJjXCIsXG5cdFx0XHRcdFx0YFJVTiBTTklQUEVUPVwiZXhwb3J0IFBST01QVF9DT01NQU5EPSdoaXN0b3J5IC1hJyAmJiBleHBvcnQgSElTVEZJTEU9JHtoaXN0b3J5RmlsZX1cIiBcXFxcXFxuXFx0JiYgZWNobyBcIiRTTklQUEVUXCIgPj4gXCIvaG9tZS8ke3VzZXJuYW1lfS8uYmFzaHJjXCJgLFxuXHRcdFx0XHRcdG9yZGVyICsgMixcblx0XHRcdFx0KSxcblx0XHRcdCk7XG5cdH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3aXRoTm9kZVVzZXIob3B0aW9ucz86IHtcblx0dXNlcm5hbWU/OiBzdHJpbmc7XG5cdGluY2x1ZGVVc2VySW5zdHJ1Y3Rpb24/OiBib29sZWFuO1xuXHRvcmRlcj86IG51bWJlcjtcbn0pOiBMYXllcldyaXRlciB7XG5cdGNvbnN0IHVzZXJuYW1lID0gb3B0aW9ucz8udXNlcm5hbWUgPz8gXCJub2RlXCI7XG5cdGNvbnN0IGluY2x1ZGVVc2VySW5zdHJ1Y3Rpb24gPSBvcHRpb25zPy5pbmNsdWRlVXNlckluc3RydWN0aW9uID8/IHRydWU7XG5cdGNvbnN0IG9yZGVyID0gb3B0aW9ucz8ub3JkZXIgPz8gU3RlcE9yZGVyLmZlYXR1cmVzO1xuXG5cdHJldHVybiAoZG9ja2VyZmlsZSkgPT4ge1xuXHRcdGRvY2tlcmZpbGUuYWRkU3RlcChEb2NrZXJTdGVwLnJhdyhcImFyZy11c2VybmFtZVwiLCBgQVJHIFVTRVJOQU1FPSR7dXNlcm5hbWV9YCwgb3JkZXIpKTtcblxuXHRcdGlmIChpbmNsdWRlVXNlckluc3RydWN0aW9uKSB7XG5cdFx0XHRkb2NrZXJmaWxlLmFkZFN0ZXAoRG9ja2VyU3RlcC5yYXcoXCJ1c2VyXCIsIFwiVVNFUiAke1VTRVJOQU1FfVwiLCBTdGVwT3JkZXIudXNlcikpO1xuXHRcdH1cblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhQbnBtKG9wdGlvbnM/OiB7XG5cdHZlcnNpb24/OiBzdHJpbmc7XG5cdHVzZXJuYW1lRXhwcj86IHN0cmluZztcblx0b3JkZXI/OiBudW1iZXI7XG59KTogTGF5ZXJXcml0ZXIge1xuXHRjb25zdCB2ZXJzaW9uID0gb3B0aW9ucz8udmVyc2lvbiA/PyBcIjEwXCI7XG5cdGNvbnN0IHVzZXJuYW1lRXhwciA9IG9wdGlvbnM/LnVzZXJuYW1lRXhwciA/PyBcIiR7VVNFUk5BTUV9XCI7XG5cdGNvbnN0IG9yZGVyID0gb3B0aW9ucz8ub3JkZXIgPz8gU3RlcE9yZGVyLmZlYXR1cmVzICsgMTAwO1xuXG5cdHJldHVybiAoZG9ja2VyZmlsZSkgPT4ge1xuXHRcdGRvY2tlcmZpbGVcblx0XHRcdC5hZGRTdGVwKFxuXHRcdFx0XHREb2NrZXJTdGVwLnJ1bihcblx0XHRcdFx0XHRcInBucG0taW5zdGFsbFwiLFxuXHRcdFx0XHRcdGBucG0gaW5zdGFsbCAtLWdsb2JhbCBucG1AbGF0ZXN0ICYmIG5wbSBhZGQgLS1nbG9iYWwgcG5wbUAke3ZlcnNpb259YCxcblx0XHRcdFx0XHRvcmRlcixcblx0XHRcdFx0KSxcblx0XHRcdClcblx0XHRcdC5hZGRTdGVwKFxuXHRcdFx0XHREb2NrZXJTdGVwLnJ1bihcblx0XHRcdFx0XHRcInBucG0tY29uZmlnXCIsXG5cdFx0XHRcdFx0YG1rZGlyIC1wIC9ob21lLyR7dXNlcm5hbWVFeHByfS8uY29uZmlnL3BucG0gL2hvbWUvJHt1c2VybmFtZUV4cHJ9Ly5wbnBtLXN0b3JlICYmIGNob3duIC1SICR7dXNlcm5hbWVFeHByfToke3VzZXJuYW1lRXhwcn0gL2hvbWUvJHt1c2VybmFtZUV4cHJ9Ly5jb25maWcgL2hvbWUvJHt1c2VybmFtZUV4cHJ9Ly5wbnBtLXN0b3JlICYmIHByaW50ZiBcInN0b3JlLWRpcj0vaG9tZS8ke3VzZXJuYW1lRXhwcn0vLnBucG0tc3RvcmVcXFxcblwiID4gL2hvbWUvJHt1c2VybmFtZUV4cHJ9Ly5jb25maWcvcG5wbS9yY2AsXG5cdFx0XHRcdFx0b3JkZXIgKyAxLFxuXHRcdFx0XHQpLFxuXHRcdFx0KTtcblx0fTtcbn1cblxuLyoqXG4gKiBDbGllbnQtb25seSAoYHBzcWxgLCBldGMuKS4gRXNjYWxhdGVzIHRvIHJvb3Qgc28gdGhpcyBhbHNvIHdvcmtzIHdoZW4gbGF5ZXJlZCBvblxuICogYSBwdWJsaXNoZWQgYmFzZSBpbWFnZSB0aGF0IGFscmVhZHkgc3dpdGNoZWQgdG8gYFVTRVIgbm9kZWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUG9zdGdyZXNxbENsaWVudChvcHRpb25zPzoge1xuXHRvcmRlcj86IG51bWJlcjtcblx0dXNlcm5hbWU/OiBzdHJpbmc7XG59KTogTGF5ZXJXcml0ZXIge1xuXHRjb25zdCBvcmRlciA9IG9wdGlvbnM/Lm9yZGVyID8/IFN0ZXBPcmRlci5mZWF0dXJlcyArIDE1MDtcblx0Y29uc3QgdXNlcm5hbWUgPSBvcHRpb25zPy51c2VybmFtZSA/PyBcIm5vZGVcIjtcblxuXHRyZXR1cm4gKGRvY2tlcmZpbGUpID0+IHtcblx0XHRkb2NrZXJmaWxlXG5cdFx0XHQuYWRkU3RlcChEb2NrZXJTdGVwLnJhdyhcInBvc3RncmVzcWwtY2xpZW50LXJvb3RcIiwgXCJVU0VSIHJvb3RcIiwgb3JkZXIpKVxuXHRcdFx0LmFkZFN0ZXAoXG5cdFx0XHRcdERvY2tlclN0ZXAucnVuKFxuXHRcdFx0XHRcdFwicG9zdGdyZXNxbC1jbGllbnRcIixcblx0XHRcdFx0XHRcImFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSAtLW5vLWluc3RhbGwtcmVjb21tZW5kcyBwb3N0Z3Jlc3FsLWNsaWVudCAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLypcIixcblx0XHRcdFx0XHRvcmRlciArIDEsXG5cdFx0XHRcdCksXG5cdFx0XHQpXG5cdFx0XHQuYWRkU3RlcChEb2NrZXJTdGVwLnJhdyhcInBvc3RncmVzcWwtY2xpZW50LXVzZXJcIiwgYFVTRVIgJHt1c2VybmFtZX1gLCBvcmRlciArIDIpKTtcblx0fTtcbn1cblxuLyoqIEdpdEh1YiBDTEkg4oCUIGluc3RhbGwgYmVmb3JlIFVTRVIgc3dpdGNoZXMgYXdheSBmcm9tIHJvb3QuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aEdpdGh1YkNsaShvcHRpb25zPzogeyBvcmRlcj86IG51bWJlciB9KTogTGF5ZXJXcml0ZXIge1xuXHRjb25zdCBvcmRlciA9IG9wdGlvbnM/Lm9yZGVyID8/IFN0ZXBPcmRlci5mZWF0dXJlcyArIDE0MDtcblxuXHRyZXR1cm4gKGRvY2tlcmZpbGUpID0+IHtcblx0XHRkb2NrZXJmaWxlLmFkZFN0ZXAoXG5cdFx0XHREb2NrZXJTdGVwLnJ1bihcblx0XHRcdFx0XCJnaXRodWItY2xpXCIsXG5cdFx0XHRcdFwiYXB0LWdldCB1cGRhdGUgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIGdoICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKlwiLFxuXHRcdFx0XHRvcmRlcixcblx0XHRcdCksXG5cdFx0KTtcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhXb3Jrc3BhY2VOb2RlTW9kdWxlc093bmVyc2hpcChvcHRpb25zPzoge1xuXHR3b3Jrc3BhY2VEaXI/OiBzdHJpbmc7XG5cdHVzZXJuYW1lRXhwcj86IHN0cmluZztcblx0b3JkZXI/OiBudW1iZXI7XG59KTogTGF5ZXJXcml0ZXIge1xuXHRjb25zdCB3b3Jrc3BhY2VEaXIgPSBvcHRpb25zPy53b3Jrc3BhY2VEaXIgPz8gXCIvd29ya3NwYWNlXCI7XG5cdGNvbnN0IHVzZXJuYW1lRXhwciA9IG9wdGlvbnM/LnVzZXJuYW1lRXhwciA/PyBcIiR7VVNFUk5BTUV9XCI7XG5cdGNvbnN0IG9yZGVyID0gb3B0aW9ucz8ub3JkZXIgPz8gU3RlcE9yZGVyLmZlYXR1cmVzICsgMjAwO1xuXG5cdHJldHVybiAoZG9ja2VyZmlsZSkgPT4ge1xuXHRcdGRvY2tlcmZpbGUuYWRkU3RlcChcblx0XHRcdERvY2tlclN0ZXAucmF3KFxuXHRcdFx0XHRcIndvcmtzcGFjZS1ub2RlLW1vZHVsZXNcIixcblx0XHRcdFx0YFJVTiBta2RpciAtcCAke3dvcmtzcGFjZURpcn0vbm9kZV9tb2R1bGVzICYmIGNob3duICR7dXNlcm5hbWVFeHByfToke3VzZXJuYW1lRXhwcn0gJHt3b3Jrc3BhY2VEaXJ9L25vZGVfbW9kdWxlc2AsXG5cdFx0XHRcdG9yZGVyLFxuXHRcdFx0KSxcblx0XHQpO1xuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFZzQ29kZUpzRGVidWdCb290bG9hZGVyRml4KG9wdGlvbnM/OiB7XG5cdGJhc2hyY1BhdGg/OiBzdHJpbmc7XG5cdG9yZGVyPzogbnVtYmVyO1xufSk6IExheWVyV3JpdGVyIHtcblx0Y29uc3QgYmFzaHJjUGF0aCA9IG9wdGlvbnM/LmJhc2hyY1BhdGggPz8gXCIvaG9tZS8ke1VTRVJOQU1FfS8uYmFzaHJjXCI7XG5cdGNvbnN0IG9yZGVyID0gb3B0aW9ucz8ub3JkZXIgPz8gU3RlcE9yZGVyLmZlYXR1cmVzICsgMzAwO1xuXG5cdHJldHVybiAoZG9ja2VyZmlsZSkgPT4ge1xuXHRcdGRvY2tlcmZpbGUuYWRkU3RlcChcblx0XHRcdERvY2tlclN0ZXAucmF3KFxuXHRcdFx0XHRcInZzY29kZS1ib290bG9hZGVyLWZpeFwiLFxuXHRcdFx0XHRbXG5cdFx0XHRcdFx0XCIjIFZTIENvZGUgLyBDdXJzb3IganMtZGVidWcgQXV0byBBdHRhY2ggaW5qZWN0cyAtLXJlcXVpcmUg4oCmL2Jvb3Rsb2FkZXIuanMgaW50b1wiLFxuXHRcdFx0XHRcdFwiIyBOT0RFX09QVElPTlMuIE9uIGEgZnJlc2ggRGV2IENvbnRhaW5lciB0aGF0IHBhdGggb2Z0ZW4gZG9lcyBub3QgZXhpc3QgeWV0XCIsXG5cdFx0XHRcdFx0XCIjICh3b3Jrc3BhY2VTdG9yYWdlIGZpbGUgaXMgb25seSBjcmVhdGVkIGFmdGVyIHRvZ2dsaW5nIEF1dG8gQXR0YWNoKSwgd2hpY2ggY3Jhc2hlc1wiLFxuXHRcdFx0XHRcdFwiIyBldmVyeSBOb2RlIGNvbW1hbmQuIElmIHRoZSBpbmplY3RlZCBwYXRoIGlzIG1pc3NpbmcsIHByZWZlciB0aGUgc3RhYmxlXCIsXG5cdFx0XHRcdFx0XCIjIGJvb3Rsb2FkZXIgZnJvbSB0aGUgc2VydmVyIGV4dGVuc2lvbiBpbnN0YWxsOyBvdGhlcndpc2Ugc3RyaXAgdGhlIGJhZCByZXF1aXJlLlwiLFxuXHRcdFx0XHRcdGBSVU4gY2F0IDw8J0VPRicgPj4gXCIke2Jhc2hyY1BhdGh9XCJgLFxuXHRcdFx0XHRcdFZTQ09ERV9CT09UTE9BREVSX0ZJWF9CQVNIX1NOSVBQRVQsXG5cdFx0XHRcdFx0XCJFT0ZcIixcblx0XHRcdFx0XS5qb2luKFwiXFxuXCIpLFxuXHRcdFx0XHRvcmRlcixcblx0XHRcdCksXG5cdFx0KTtcblx0fTtcbn1cblxuZXhwb3J0IGNsYXNzIERvY2tlcmZpbGVNb2RlbCBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5ET0NLRVJGSUxFO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9zdGVwcyA9IG5ldyBNYXA8c3RyaW5nLCBEb2NrZXJTdGVwPigpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9sYXllcldyaXRlcnM6IExheWVyV3JpdGVyW10gPSBbXTtcblx0cHJpdmF0ZSBfZnJvbUltYWdlOiBzdHJpbmc7XG5cdHByaXZhdGUgX2xheWVyQ291bnRlciA9IDA7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKGJhc2VJbWFnZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5fZnJvbUltYWdlID0gYmFzZUltYWdlO1xuXHRcdHRoaXMucmVnaXN0ZXJCYXNlTGF5ZXJzKCk7XG5cdH1cblxuXHRwdWJsaWMgZnJvbShiYXNlSW1hZ2U6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX2Zyb21JbWFnZSA9IGJhc2VJbWFnZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBhZGRMYXllcihsYXllcjogTGF5ZXJXcml0ZXIgfCBzdHJpbmcsIG9yZGVyID0gU3RlcE9yZGVyLmZlYXR1cmVzKTogdGhpcyB7XG5cdFx0aWYgKHR5cGVvZiBsYXllciA9PT0gXCJzdHJpbmdcIikge1xuXHRcdFx0Y29uc3QgaWR4ID0gKyt0aGlzLl9sYXllckNvdW50ZXI7XG5cdFx0XHRjb25zdCBrZXkgPSBgbGF5ZXItcnVuLSR7aWR4fWA7XG5cdFx0XHR0aGlzLl9sYXllcldyaXRlcnMucHVzaCgoZG9ja2VyZmlsZSkgPT4ge1xuXHRcdFx0XHRkb2NrZXJmaWxlLmFkZFN0ZXAoRG9ja2VyU3RlcC5ydW4oa2V5LCBsYXllciwgb3JkZXIgKyBpZHgpKTtcblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0dGhpcy5fbGF5ZXJXcml0ZXJzLnB1c2gobGF5ZXIpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIGFkZFN0ZXAoc3RlcDogRG9ja2VyU3RlcCk6IHRoaXMge1xuXHRcdHRoaXMuX3N0ZXBzLnNldChzdGVwLmtleSwgc3RlcCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgcmVtb3ZlU3RlcChrZXk6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX3N0ZXBzLmRlbGV0ZShrZXkpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIGVudHJ5cG9pbnQodmFsdWU6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdLCBvcmRlciA9IFN0ZXBPcmRlci5lbnRyeXBvaW50KTogdGhpcyB7XG5cdFx0dGhpcy5hZGRTdGVwKERvY2tlclN0ZXAuZW50cnlwb2ludChcImVudHJ5cG9pbnRcIiwgdmFsdWUsIG9yZGVyKSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgYWRkUnVuU3RlcChjbWQ6IHN0cmluZyk6IHRoaXMge1xuXHRcdHJldHVybiB0aGlzLmFkZExheWVyKGNtZCk7XG5cdH1cblxuXHRwdWJsaWMgYnVpbGQoKTogc3RyaW5nIHtcblx0XHRmb3IgKGNvbnN0IGxheWVyV3JpdGVyIG9mIHRoaXMuX2xheWVyV3JpdGVycykge1xuXHRcdFx0bGF5ZXJXcml0ZXIodGhpcyk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgbGluZXMgPSBbYEZST00gJHt0aGlzLl9mcm9tSW1hZ2V9YF07XG5cdFx0Y29uc3Qgc29ydGVkU3RlcHMgPSBbLi4udGhpcy5fc3RlcHMudmFsdWVzKCldLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiB7XG5cdFx0XHRpZiAobGVmdC5vcmRlciAhPT0gcmlnaHQub3JkZXIpIHtcblx0XHRcdFx0cmV0dXJuIGxlZnQub3JkZXIgLSByaWdodC5vcmRlcjtcblx0XHRcdH1cblx0XHRcdHJldHVybiBsZWZ0LmtleS5sb2NhbGVDb21wYXJlKHJpZ2h0LmtleSwgXCJlblwiKTtcblx0XHR9KTtcblxuXHRcdGZvciAoY29uc3Qgc3RlcCBvZiBzb3J0ZWRTdGVwcykge1xuXHRcdFx0bGluZXMucHVzaChcIlwiLCBzdGVwLmNvbnRlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBgJHtsaW5lcy5qb2luKFwiXFxuXCIpfVxcbmA7XG5cdH1cblxuXHRwcm90ZWN0ZWQgcmVnaXN0ZXJCYXNlTGF5ZXJzKCk6IHZvaWQge1xuXHRcdC8vIEdlbmVyaWMgYmFzZSBtb2RlbCBpbnRlbnRpb25hbGx5IGhhcyBubyBkZWZhdWx0IGxheWVycy5cblx0fVxuXG5cdHB1YmxpYyBmaWxlcygpOiBTb3VyY2VGaWxlW10ge1xuXHRcdHJldHVybiBbXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi4vRG9ja2VyZmlsZVwiLFxuXHRcdFx0XHRjb250ZW50OiB0aGlzLmJ1aWxkKCksXG5cdFx0XHR9LFxuXHRcdF07XG5cdH1cbn1cblxuLyoqXG4gKiBTaGFyZWQgbGF5ZXJzIGZvciB0aGUgcHVibGlzaGVkIGBnaGNyLmlvL3R5cGVzbWl0aHMvZGVjb2hlcmUvZGV2Y29udGFpbmVyYCBpbWFnZS5cbiAqIENoZWNrZWQgaW4gYXQgYHByb2plY3RzL2RldmNvbnRhaW5lci9Eb2NrZXJmaWxlYCDigJQga2VlcCBpbiBzeW5jIHZpYSB0aGUgdW5pdCB0ZXN0LlxuICovXG5leHBvcnQgY2xhc3MgQXBwRGV2Q29udGFpbmVyQmFzZUltYWdlIGV4dGVuZHMgRG9ja2VyZmlsZU1vZGVsIHtcblx0cHJvdGVjdGVkIG92ZXJyaWRlIHJlZ2lzdGVyQmFzZUxheWVycygpOiB2b2lkIHtcblx0XHRzdXBlci5yZWdpc3RlckJhc2VMYXllcnMoKTtcblx0XHR0aGlzLmFkZExheWVyKHdpdGhDb21tYW5kSGlzdG9yeSgpKVxuXHRcdFx0LmFkZExheWVyKHdpdGhOb2RlVXNlcigpKVxuXHRcdFx0LmFkZExheWVyKHdpdGhQbnBtKCkpXG5cdFx0XHQuYWRkTGF5ZXIod2l0aEdpdGh1YkNsaSgpKVxuXHRcdFx0LmFkZExheWVyKHdpdGhXb3Jrc3BhY2VOb2RlTW9kdWxlc093bmVyc2hpcCgpKVxuXHRcdFx0LmFkZExheWVyKHdpdGhWc0NvZGVKc0RlYnVnQm9vdGxvYWRlckZpeCgpKTtcblx0fVxufVxuXG4vKiogR2VuZXJpYyBEZXYgQ29udGFpbmVyIGltYWdlIGhlbHBlcnMgKGhpc3RvcnkgKyBib290bG9hZGVyKSB3aXRob3V0IHdlYmFwaSBkZWZhdWx0cy4gKi9cbmV4cG9ydCBjbGFzcyBEZXZDb250YWluZXJJbWFnZU1vZGVsIGV4dGVuZHMgRG9ja2VyZmlsZU1vZGVsIHtcblx0cHJvdGVjdGVkIG92ZXJyaWRlIHJlZ2lzdGVyQmFzZUxheWVycygpOiB2b2lkIHtcblx0XHRzdXBlci5yZWdpc3RlckJhc2VMYXllcnMoKTtcblx0XHR0aGlzLmFkZExheWVyKHdpdGhDb21tYW5kSGlzdG9yeSgpKS5hZGRMYXllcih3aXRoVnNDb2RlSnNEZWJ1Z0Jvb3Rsb2FkZXJGaXgoKSk7XG5cdH1cblxuXHRwdWJsaWMgZmlsZXMoKTogU291cmNlRmlsZVtdIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0e1xuXHRcdFx0XHRmaWxlUGF0aDogXCIuZGV2Y29udGFpbmVyL0RvY2tlcmZpbGVcIixcblx0XHRcdFx0Y29udGVudDogdGhpcy5idWlsZCgpLFxuXHRcdFx0fSxcblx0XHRdO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiV0VMTF9LTk9XTl9GSUxFUyIsIkRvY2tlclN0ZXAiLCJrZXkiLCJjb250ZW50Iiwib3JkZXIiLCJydW4iLCJjb21tYW5kIiwicmF3IiwiZW50cnlwb2ludCIsInZhbHVlIiwiSlNPTiIsInN0cmluZ2lmeSIsIlN0ZXBPcmRlciIsImJhc2UiLCJmZWF0dXJlcyIsInVzZXIiLCJWU0NPREVfQk9PVExPQURFUl9GSVhfQkFTSF9TTklQUEVUIiwiY29tbWFuZEhpc3RvcnkiLCJ2b2x1bWVOYW1lIiwiZGlyIiwiZmlsZU5hbWUiLCJoaXN0RmlsZSIsIndpdGhDb21tYW5kSGlzdG9yeSIsIm9wdGlvbnMiLCJoaXN0b3J5RGlyIiwiaGlzdG9yeUZpbGVOYW1lIiwidXNlcm5hbWUiLCJoaXN0b3J5RmlsZSIsImRvY2tlcmZpbGUiLCJhZGRTdGVwIiwid2l0aE5vZGVVc2VyIiwiaW5jbHVkZVVzZXJJbnN0cnVjdGlvbiIsIndpdGhQbnBtIiwidmVyc2lvbiIsInVzZXJuYW1lRXhwciIsIndpdGhQb3N0Z3Jlc3FsQ2xpZW50Iiwid2l0aEdpdGh1YkNsaSIsIndpdGhXb3Jrc3BhY2VOb2RlTW9kdWxlc093bmVyc2hpcCIsIndvcmtzcGFjZURpciIsIndpdGhWc0NvZGVKc0RlYnVnQm9vdGxvYWRlckZpeCIsImJhc2hyY1BhdGgiLCJqb2luIiwiRG9ja2VyZmlsZU1vZGVsIiwiRE9DS0VSRklMRSIsIl9zdGVwcyIsIk1hcCIsIl9sYXllcldyaXRlcnMiLCJfZnJvbUltYWdlIiwiX2xheWVyQ291bnRlciIsImJhc2VJbWFnZSIsInJlZ2lzdGVyQmFzZUxheWVycyIsImZyb20iLCJhZGRMYXllciIsImxheWVyIiwiaWR4IiwicHVzaCIsInN0ZXAiLCJzZXQiLCJyZW1vdmVTdGVwIiwiZGVsZXRlIiwiYWRkUnVuU3RlcCIsImNtZCIsImJ1aWxkIiwibGF5ZXJXcml0ZXIiLCJsaW5lcyIsInNvcnRlZFN0ZXBzIiwidmFsdWVzIiwic29ydCIsImxlZnQiLCJyaWdodCIsImxvY2FsZUNvbXBhcmUiLCJmaWxlcyIsImZpbGVQYXRoIiwiQXBwRGV2Q29udGFpbmVyQmFzZUltYWdlIiwiRGV2Q29udGFpbmVySW1hZ2VNb2RlbCJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsZ0JBQWdCLFFBQVEsYUFBYTtBQUs5QyxPQUFPLE1BQU1DOzs7O0lBQ1osWUFDQyxBQUFnQkMsR0FBVyxFQUMzQixBQUFnQkMsT0FBZSxFQUMvQixBQUFnQkMsUUFBUSxDQUFDLENBQ3hCO2FBSGVGLE1BQUFBO2FBQ0FDLFVBQUFBO2FBQ0FDLFFBQUFBO0lBQ2Q7SUFFSCxPQUFjQyxJ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
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { WELL_KNOWN_FILES } from "./const.js";
|
|
3
|
+
/**
|
|
4
|
+
* Accumulates key=value pairs and renders them as a `.env` file.
|
|
5
|
+
*
|
|
6
|
+
* Register once in the workspace; features call `addEntry` during their
|
|
7
|
+
* scaffold phase to contribute environment variables. The final file is
|
|
8
|
+
* written at render time when `workspace.scaffold()` is called.
|
|
9
|
+
*/ export class EnvFile {
|
|
10
|
+
key = WELL_KNOWN_FILES.ENV_FILE;
|
|
11
|
+
_entries = new Map();
|
|
12
|
+
addEntry(key, value) {
|
|
13
|
+
this._entries.set(key, value);
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
hasEntry(key) {
|
|
17
|
+
return this._entries.has(key);
|
|
18
|
+
}
|
|
19
|
+
static fromFile(absolutePath) {
|
|
20
|
+
const env = new EnvFile();
|
|
21
|
+
const raw = readFileSync(absolutePath, "utf8");
|
|
22
|
+
for (const line of raw.split("\n")){
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
25
|
+
const eq = line.indexOf("=");
|
|
26
|
+
if (eq <= 0) continue;
|
|
27
|
+
env.addEntry(line.slice(0, eq).trim(), line.slice(eq + 1));
|
|
28
|
+
}
|
|
29
|
+
return env;
|
|
30
|
+
}
|
|
31
|
+
files() {
|
|
32
|
+
if (this._entries.size === 0) return [];
|
|
33
|
+
const body = [
|
|
34
|
+
...this._entries.entries()
|
|
35
|
+
].map(([k, v])=>`${k}=${v}`).join("\n");
|
|
36
|
+
const content = `${body}\n`;
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
filePath: ".env",
|
|
40
|
+
content
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9tb2RlbHMvZW52LWZpbGUubW9kZWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IFdFTExfS05PV05fRklMRVMgfSBmcm9tIFwiLi9jb25zdC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBLZXllZE1vZGVsLCBTb3VyY2VGaWxlIH0gZnJvbSBcIi4vc291cmNlLWZpbGUuanNcIjtcblxuLyoqXG4gKiBBY2N1bXVsYXRlcyBrZXk9dmFsdWUgcGFpcnMgYW5kIHJlbmRlcnMgdGhlbSBhcyBhIGAuZW52YCBmaWxlLlxuICpcbiAqIFJlZ2lzdGVyIG9uY2UgaW4gdGhlIHdvcmtzcGFjZTsgZmVhdHVyZXMgY2FsbCBgYWRkRW50cnlgIGR1cmluZyB0aGVpclxuICogc2NhZmZvbGQgcGhhc2UgdG8gY29udHJpYnV0ZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMuIFRoZSBmaW5hbCBmaWxlIGlzXG4gKiB3cml0dGVuIGF0IHJlbmRlciB0aW1lIHdoZW4gYHdvcmtzcGFjZS5zY2FmZm9sZCgpYCBpcyBjYWxsZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbnZGaWxlIGltcGxlbWVudHMgS2V5ZWRNb2RlbCB7XG5cdHB1YmxpYyByZWFkb25seSBrZXkgPSBXRUxMX0tOT1dOX0ZJTEVTLkVOVl9GSUxFO1xuXG5cdHByaXZhdGUgcmVhZG9ubHkgX2VudHJpZXMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG5cdHB1YmxpYyBhZGRFbnRyeShrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHRoaXMge1xuXHRcdHRoaXMuX2VudHJpZXMuc2V0KGtleSwgdmFsdWUpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIGhhc0VudHJ5KGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuX2VudHJpZXMuaGFzKGtleSk7XG5cdH1cblxuXHRwdWJsaWMgc3RhdGljIGZyb21GaWxlKGFic29sdXRlUGF0aDogc3RyaW5nKTogRW52RmlsZSB7XG5cdFx0Y29uc3QgZW52ID0gbmV3IEVudkZpbGUoKTtcblx0XHRjb25zdCByYXcgPSByZWFkRmlsZVN5bmMoYWJzb2x1dGVQYXRoLCBcInV0ZjhcIik7XG5cdFx0Zm9yIChjb25zdCBsaW5lIG9mIHJhdy5zcGxpdChcIlxcblwiKSkge1xuXHRcdFx0Y29uc3QgdHJpbW1lZCA9IGxpbmUudHJpbSgpO1xuXHRcdFx0aWYgKHRyaW1tZWQgPT09IFwiXCIgfHwgdHJpbW1lZC5zdGFydHNXaXRoKFwiI1wiKSkgY29udGludWU7XG5cdFx0XHRjb25zdCBlcSA9IGxpbmUuaW5kZXhPZihcIj1cIik7XG5cdFx0XHRpZiAoZXEgPD0gMCkgY29udGludWU7XG5cdFx0XHRlbnYuYWRkRW50cnkobGluZS5zbGljZSgwLCBlcSkudHJpbSgpLCBsaW5lLnNsaWNlKGVxICsgMSkpO1xuXHRcdH1cblx0XHRyZXR1cm4gZW52O1xuXHR9XG5cblx0cHVibGljIGZpbGVzKCk6IFNvdXJjZUZpbGVbXSB7XG5cdFx0aWYgKHRoaXMuX2VudHJpZXMuc2l6ZSA9PT0gMCkgcmV0dXJuIFtdO1xuXHRcdGNvbnN0IGJvZHkgPSBbLi4udGhpcy5fZW50cmllcy5lbnRyaWVzKCldLm1hcCgoW2ssIHZdKSA9PiBgJHtrfT0ke3Z9YCkuam9pbihcIlxcblwiKTtcblx0XHRjb25zdCBjb250ZW50ID0gYCR7Ym9keX1cXG5gO1xuXHRcdHJldHVybiBbeyBmaWxlUGF0aDogXCIuZW52XCIsIGNvbnRlbnQgfV07XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJyZWFkRmlsZVN5bmMiLCJXRUxMX0tOT1dOX0ZJTEVTIiwiRW52RmlsZSIsImtleSIsIkVOVl9GSUxFIiwiX2VudHJpZXMiLCJNYXAiLCJhZGRFbnRyeSIsInZhbHVlIiwic2V0IiwiaGFzRW50cnkiLCJoYXMiLCJmcm9tRmlsZSIsImFic29sdXRlUGF0aCIsImVudiIsInJhdyIsImxpbmUiLCJzcGxpdCIsInRyaW1tZWQiLCJ0cmltIiwic3RhcnRzV2l0aCIsImVxIiwiaW5kZXhPZiIsInNsaWNlIiwiZmlsZXMiLCJzaXplIiwiYm9keSIsImVudHJpZXMiLCJtYXAiLCJrIiwidiIsImpvaW4iLCJjb250ZW50IiwiZmlsZVBhdGgiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFlBQVksUUFBUSxVQUFVO0FBQ3ZDLFNBQVNDLGdCQUFnQixRQUFRLGFBQWE7QUFHOUM7Ozs7OztDQU1DLEdBQ0QsT0FBTyxNQUFNQztJQUNJQyxNQUFNRixpQkFBaUJHLFFBQVEsQ0FBQztJQUUvQkMsV0FBVyxJQUFJQyxNQUFzQjtJQUUvQ0MsU0FBU0osR0FBVyxFQUFFSyxLQUFhLEVBQVE7UUFDakQsSUFBSSxDQUFDSCxRQUFRLENBQUNJLEdBQUcsQ0FBQ04sS0FBS0s7UUFDdkIsT0FBTyxJQUFJO0lBQ1o7SUFFT0UsU0FBU1AsR0FBVyxFQUFXO1FBQ3JDLE9BQU8sSUFBSSxDQUFDRSxRQUFRLENBQUNNLEdBQUcsQ0FBQ1I7SUFDMUI7SUFFQSxPQUFjUyxTQUFTQyxZQUFvQixFQUFXO1FBQ3JELE1BQU1DLE1BQU0sSUFBSVo7UUFDaEIsTUFBTWEsTUFBTWYsYUFBYWEsY0FBYztRQUN2QyxLQUFLLE1BQU1HLFFBQVFELElBQUlFLEtBQUssQ0FBQyxNQUFPO1lBQ25DLE1BQU1DLFVBQVVGLEtBQUtHLElBQUk7WUFDekIsSUFBSUQsWUFBWSxNQUFNQSxRQUFRRSxVQUFVLENBQUMsTUFBTTtZQUMvQyxNQUFNQyxLQUFLTCxLQUFLTSxPQUFPLENBQUM7WUFDeEIsSUFBSUQsTUFBTSxHQUFHO1lBQ2JQLElBQUlQLFFBQVEsQ0FBQ1MsS0FBS08sS0FBSyxDQUFDLEdBQUdGLElBQUlGLElBQUksSUFBSUgsS0FBS08sS0FBSyxDQUFDRixLQUFLO1FBQ3hEO1FBQ0EsT0FBT1A7SUFDUjtJQUVPVSxRQUFzQjtRQUM1QixJQUFJLElBQUksQ0FBQ25CLFFBQVEsQ0FBQ29CLElBQUksS0FBSyxHQUFHLE9BQU8sRUFBRTtRQUN2QyxNQUFNQyxPQUFPO2VBQUksSUFBSSxDQUFDckIsUUFBUSxDQUFDc0IsT0FBTztTQUFHLENBQUNDLEdBQUcsQ0FBQyxDQUFDLENBQUNDLEdBQUdDLEVBQUUsR0FBSyxHQUFHRCxFQUFFLENBQUMsRUFBRUMsR0FBRyxFQUFFQyxJQUFJLENBQUM7UUFDNUUsTUFBTUMsVUFBVSxHQUFHTixLQUFLLEVBQUUsQ0FBQztRQUMzQixPQUFPO1lBQUM7Z0JBQUVPLFVBQVU7Z0JBQVFEO1lBQVE7U0FBRTtJQUN2QztBQUNEIn0=
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { WELL_KNOWN_FILES } from "./const.js";
|
|
2
|
+
export class Gitignore {
|
|
3
|
+
key = WELL_KNOWN_FILES.GITIGNORE;
|
|
4
|
+
ignoreList = [
|
|
5
|
+
"node_modules",
|
|
6
|
+
"dist",
|
|
7
|
+
".pnpm-store",
|
|
8
|
+
".env",
|
|
9
|
+
".devcontainer/gh.env",
|
|
10
|
+
".cursor/codebase-rag.env",
|
|
11
|
+
".cursor/mcp.json",
|
|
12
|
+
".DS_Store",
|
|
13
|
+
"logs"
|
|
14
|
+
];
|
|
15
|
+
add(...patterns) {
|
|
16
|
+
for (const pattern of patterns){
|
|
17
|
+
if (!this.ignoreList.includes(pattern)) {
|
|
18
|
+
this.ignoreList.push(pattern);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
files() {
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
filePath: ".gitignore",
|
|
27
|
+
content: `${this.ignoreList.join("\n")}\n`
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9tb2RlbHMvZ2l0aWdub3JlLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdFTExfS05PV05fRklMRVMgfSBmcm9tIFwiLi9jb25zdC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBLZXllZE1vZGVsLCBTb3VyY2VGaWxlIH0gZnJvbSBcIi4vc291cmNlLWZpbGUuanNcIjtcblxuZXhwb3J0IGNsYXNzIEdpdGlnbm9yZSBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5HSVRJR05PUkU7XG5cdHByaXZhdGUgaWdub3JlTGlzdCA9IFtcblx0XHRcIm5vZGVfbW9kdWxlc1wiLFxuXHRcdFwiZGlzdFwiLFxuXHRcdFwiLnBucG0tc3RvcmVcIixcblx0XHRcIi5lbnZcIixcblx0XHRcIi5kZXZjb250YWluZXIvZ2guZW52XCIsXG5cdFx0XCIuY3Vyc29yL2NvZGViYXNlLXJhZy5lbnZcIixcblx0XHRcIi5jdXJzb3IvbWNwLmpzb25cIixcblx0XHRcIi5EU19TdG9yZVwiLFxuXHRcdFwibG9nc1wiLFxuXHRdO1xuXG5cdHB1YmxpYyBhZGQoLi4ucGF0dGVybnM6IHN0cmluZ1tdKTogdGhpcyB7XG5cdFx0Zm9yIChjb25zdCBwYXR0ZXJuIG9mIHBhdHRlcm5zKSB7XG5cdFx0XHRpZiAoIXRoaXMuaWdub3JlTGlzdC5pbmNsdWRlcyhwYXR0ZXJuKSkge1xuXHRcdFx0XHR0aGlzLmlnbm9yZUxpc3QucHVzaChwYXR0ZXJuKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgZmlsZXMoKTogU291cmNlRmlsZVtdIHtcblx0XHRyZXR1cm4gW1xuXHRcdFx0e1xuXHRcdFx0XHRmaWxlUGF0aDogXCIuZ2l0aWdub3JlXCIsXG5cdFx0XHRcdGNvbnRlbnQ6IGAke3RoaXMuaWdub3JlTGlzdC5qb2luKFwiXFxuXCIpfVxcbmAsXG5cdFx0XHR9LFxuXHRcdF07XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJXRUxMX0tOT1dOX0ZJTEVTIiwiR2l0aWdub3JlIiwia2V5IiwiR0lUSUdOT1JFIiwiaWdub3JlTGlzdCIsImFkZCIsInBhdHRlcm5zIiwicGF0dGVybiIsImluY2x1ZGVzIiwicHVzaCIsImZpbGVzIiwiZmlsZVBhdGgiLCJjb250ZW50Iiwiam9pbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsZ0JBQWdCLFFBQVEsYUFBYTtBQUc5QyxPQUFPLE1BQU1DO0lBQ0lDLE1BQU1GLGlCQUFpQkcsU0FBUyxDQUFDO0lBQ3pDQyxhQUFhO1FBQ3BCO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7UUFDQTtLQUNBLENBQUM7SUFFS0MsSUFBSSxHQUFHQyxRQUFrQixFQUFRO1FBQ3ZDLEtBQUssTUFBTUMsV0FBV0QsU0FBVTtZQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDRixVQUFVLENBQUNJLFFBQVEsQ0FBQ0QsVUFBVTtnQkFDdkMsSUFBSSxDQUFDSCxVQUFVLENBQUNLLElBQUksQ0FBQ0Y7WUFDdEI7UUFDRDtRQUNBLE9BQU8sSUFBSTtJQUNaO0lBRU9HLFFBQXNCO1FBQzVCLE9BQU87WUFDTjtnQkFDQ0MsVUFBVTtnQkFDVkMsU0FBUyxHQUFHLElBQUksQ0FBQ1IsVUFBVSxDQUFDUyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0M7U0FDQTtJQUNGO0FBQ0QifQ==
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { WELL_KNOWN_FILES } from "./const.js";
|
|
2
|
+
export class LaunchJson {
|
|
3
|
+
apiNames;
|
|
4
|
+
key = WELL_KNOWN_FILES.LAUNCH_JSON;
|
|
5
|
+
constructor(apiNames = [
|
|
6
|
+
"api"
|
|
7
|
+
]){
|
|
8
|
+
this.apiNames = apiNames;
|
|
9
|
+
}
|
|
10
|
+
files() {
|
|
11
|
+
const configurations = [
|
|
12
|
+
{
|
|
13
|
+
name: "Build",
|
|
14
|
+
type: "node",
|
|
15
|
+
request: "launch",
|
|
16
|
+
runtimeExecutable: "pnpm",
|
|
17
|
+
runtimeArgs: [
|
|
18
|
+
"build"
|
|
19
|
+
],
|
|
20
|
+
console: "integratedTerminal",
|
|
21
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: VS Code variable
|
|
22
|
+
cwd: "${workspaceFolder}"
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
const first = this.apiNames[0] ?? "api";
|
|
26
|
+
const defaultDevArgs = first === "api" && this.apiNames.length === 1 ? [
|
|
27
|
+
"dev"
|
|
28
|
+
] : [
|
|
29
|
+
"run",
|
|
30
|
+
`dev:${first}`
|
|
31
|
+
];
|
|
32
|
+
configurations.push(serveConfig("Serve / Dev", defaultDevArgs));
|
|
33
|
+
for (const apiName of this.apiNames){
|
|
34
|
+
if (apiName === first && this.apiNames.length === 1 && apiName === "api") continue;
|
|
35
|
+
configurations.push(serveConfig(`Serve / Dev (${apiName})`, [
|
|
36
|
+
"run",
|
|
37
|
+
`dev:${apiName}`
|
|
38
|
+
]));
|
|
39
|
+
}
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
filePath: ".vscode/launch.json",
|
|
43
|
+
content: JSON.stringify({
|
|
44
|
+
version: "0.2.0",
|
|
45
|
+
configurations
|
|
46
|
+
}, null, 2)
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function serveConfig(name, runtimeArgs) {
|
|
52
|
+
return {
|
|
53
|
+
name,
|
|
54
|
+
type: "node",
|
|
55
|
+
request: "launch",
|
|
56
|
+
runtimeExecutable: "pnpm",
|
|
57
|
+
runtimeArgs,
|
|
58
|
+
console: "integratedTerminal",
|
|
59
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: VS Code variable
|
|
60
|
+
cwd: "${workspaceFolder}"
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL3NjYWZmb2xkL3NyYy9tb2RlbHMvbGF1bmNoLWpzb24ubW9kZWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV0VMTF9LTk9XTl9GSUxFUyB9IGZyb20gXCIuL2NvbnN0LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEtleWVkTW9kZWwsIFNvdXJjZUZpbGUgfSBmcm9tIFwiLi9zb3VyY2UtZmlsZS5qc1wiO1xuXG5leHBvcnQgY2xhc3MgTGF1bmNoSnNvbiBpbXBsZW1lbnRzIEtleWVkTW9kZWwge1xuXHRwdWJsaWMgcmVhZG9ubHkga2V5ID0gV0VMTF9LTk9XTl9GSUxFUy5MQVVOQ0hfSlNPTjtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBhcGlOYW1lczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXCJhcGlcIl0pIHt9XG5cblx0cHVibGljIGZpbGVzKCk6IFNvdXJjZUZpbGVbXSB7XG5cdFx0Y29uc3QgY29uZmlndXJhdGlvbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gPSBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQnVpbGRcIixcblx0XHRcdFx0dHlwZTogXCJub2RlXCIsXG5cdFx0XHRcdHJlcXVlc3Q6IFwibGF1bmNoXCIsXG5cdFx0XHRcdHJ1bnRpbWVFeGVjdXRhYmxlOiBcInBucG1cIixcblx0XHRcdFx0cnVudGltZUFyZ3M6IFtcImJ1aWxkXCJdLFxuXHRcdFx0XHRjb25zb2xlOiBcImludGVncmF0ZWRUZXJtaW5hbFwiLFxuXHRcdFx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vVGVtcGxhdGVDdXJseUluU3RyaW5nOiBWUyBDb2RlIHZhcmlhYmxlXG5cdFx0XHRcdGN3ZDogXCIke3dvcmtzcGFjZUZvbGRlcn1cIixcblx0XHRcdH0sXG5cdFx0XTtcblxuXHRcdGNvbnN0IGZpcnN0ID0gdGhpcy5hcGlOYW1lc1swXSA/PyBcImFwaVwiO1xuXHRcdGNvbnN0IGRlZmF1bHREZXZBcmdzID1cblx0XHRcdGZpcnN0ID09PSBcImFwaVwiICYmIHRoaXMuYXBpTmFtZXMubGVuZ3RoID09PSAxID8gW1wiZGV2XCJdIDogW1wicnVuXCIsIGBkZXY6JHtmaXJzdH1gXTtcblx0XHRjb25maWd1cmF0aW9ucy5wdXNoKHNlcnZlQ29uZmlnKFwiU2VydmUgLyBEZXZcIiwgZGVmYXVsdERldkFyZ3MpKTtcblxuXHRcdGZvciAoY29uc3QgYXBpTmFtZSBvZiB0aGlzLmFwaU5hbWVzKSB7XG5cdFx0XHRpZiAoYXBpTmFtZSA9PT0gZmlyc3QgJiYgdGhpcy5hcGlOYW1lcy5sZW5ndGggPT09IDEgJiYgYXBpTmFtZSA9PT0gXCJhcGlcIikgY29udGludWU7XG5cdFx0XHRjb25maWd1cmF0aW9ucy5wdXNoKHNlcnZlQ29uZmlnKGBTZXJ2ZSAvIERldiAoJHthcGlOYW1lfSlgLCBbXCJydW5cIiwgYGRldjoke2FwaU5hbWV9YF0pKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gW1xuXHRcdFx0e1xuXHRcdFx0XHRmaWxlUGF0aDogXCIudnNjb2RlL2xhdW5jaC5qc29uXCIsXG5cdFx0XHRcdGNvbnRlbnQ6IEpTT04uc3RyaW5naWZ5KFxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdHZlcnNpb246IFwiMC4yLjBcIixcblx0XHRcdFx0XHRcdGNvbmZpZ3VyYXRpb25zLFxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0bnVsbCxcblx0XHRcdFx0XHQyLFxuXHRcdFx0XHQpLFxuXHRcdFx0fSxcblx0XHRdO1xuXHR9XG59XG5cbmZ1bmN0aW9uIHNlcnZlQ29uZmlnKG5hbWU6IHN0cmluZywgcnVudGltZUFyZ3M6IHN0cmluZ1tdKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuXHRyZXR1cm4ge1xuXHRcdG5hbWUsXG5cdFx0dHlwZTogXCJub2RlXCIsXG5cdFx0cmVxdWVzdDogXCJsYXVuY2hcIixcblx0XHRydW50aW1lRXhlY3V0YWJsZTogXCJwbnBtXCIsXG5cdFx0cnVudGltZUFyZ3MsXG5cdFx0Y29uc29sZTogXCJpbnRlZ3JhdGVkVGVybWluYWxcIixcblx0XHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vVGVtcGxhdGVDdXJseUluU3RyaW5nOiBWUyBDb2RlIHZhcmlhYmxlXG5cdFx0Y3dkOiBcIiR7d29ya3NwYWNlRm9sZGVyfVwiLFxuXHR9O1xufVxuIl0sIm5hbWVzIjpbIldFTExfS05PV05fRklMRVMiLCJMYXVuY2hKc29uIiwia2V5IiwiTEFVTkNIX0pTT04iLCJhcGlOYW1lcyIsImZpbGVzIiwiY29uZmlndXJhdGlvbnMiLCJuYW1lIiwidHlwZSIsInJlcXVlc3QiLCJydW50aW1lRXhlY3V0YWJsZSIsInJ1bnRpbWVBcmdzIiwiY29uc29sZSIsImN3ZCIsImZpcnN0IiwiZGVmYXVsdERldkFyZ3MiLCJsZW5ndGgiLCJwdXNoIiwic2VydmVDb25maWciLCJhcGlOYW1lIiwiZmlsZVBhdGgiLCJjb250ZW50IiwiSlNPTiIsInN0cmluZ2lmeSIsInZlcnNpb24iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGdCQUFnQixRQUFRLGFBQWE7QUFHOUMsT0FBTyxNQUFNQzs7SUFDSUMsTUFBTUYsaUJBQWlCRyxXQUFXLENBQUM7SUFFbkQsWUFBbUIsQUFBaUJDLFdBQThCO1FBQUM7S0FBTSxDQUFFO2FBQXZDQSxXQUFBQTtJQUF3QztJQUVyRUMsUUFBc0I7UUFDNUIsTUFBTUMsaUJBQTRDO1lBQ2pEO2dCQUNDQyxNQUFNO2dCQUNOQyxNQUFNO2dCQUNOQyxTQUFTO2dCQUNUQyxtQkFBbUI7Z0JBQ25CQyxhQUFhO29CQUFDO2lCQUFRO2dCQUN0QkMsU0FBUztnQkFDVCx5RUFBeUU7Z0JBQ3pFQyxLQUFLO1lBQ047U0FDQTtRQUVELE1BQU1DLFFBQVEsSUFBSSxDQUFDVixRQUFRLENBQUMsRUFBRSxJQUFJO1FBQ2xDLE1BQU1XLGlCQUNMRCxVQUFVLFNBQVMsSUFBSSxDQUFDVixRQUFRLENBQUNZLE1BQU0sS0FBSyxJQUFJO1lBQUM7U0FBTSxHQUFHO1lBQUM7WUFBTyxDQUFDLElBQUksRUFBRUYsT0FBTztTQUFDO1FBQ2xGUixlQUFlVyxJQUFJLENBQUNDLFlBQVksZUFBZUg7UUFFL0MsS0FBSyxNQUFNSSxXQUFXLElBQUksQ0FBQ2YsUUFBUSxDQUFFO1lBQ3BDLElBQUllLFlBQVlMLFNBQVMsSUFBSSxDQUFDVixRQUFRLENBQUNZLE1BQU0sS0FBSyxLQUFLRyxZQUFZLE9BQU87WUFDMUViLGVBQWVXLElBQUksQ0FBQ0MsWUFBWSxDQUFDLGFBQWEsRUFBRUMsUUFBUSxDQUFDLENBQUMsRUFBRTtnQkFBQztnQkFBTyxDQUFDLElBQUksRUFBRUEsU0FBUzthQUFDO1FBQ3RGO1FBRUEsT0FBTztZQUNOO2dCQUNDQyxVQUFVO2dCQUNWQyxTQUFTQyxLQUFLQyxTQUFTLENBQ3RCO29CQUNDQyxTQUFTO29CQUNUbEI7Z0JBQ0QsR0FDQSxNQUNBO1lBRUY7U0FDQTtJQUNGO0FBQ0Q7QUFFQSxTQUFTWSxZQUFZWCxJQUFZLEVBQUVJLFdBQXFCO0lBQ3ZELE9BQU87UUFDTko7UUFDQUMsTUFBTTtRQUNOQyxTQUFTO1FBQ1RDLG1CQUFtQjtRQUNuQkM7UUFDQUMsU0FBUztRQUNULHlFQUF5RTtRQUN6RUMsS0FBSztJQUNOO0FBQ0QifQ==
|