@decohere/scaffold 0.0.1-dev.18 → 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/commonjs/src/add-api.action.js +37 -0
- package/commonjs/src/add-api.command.js +39 -0
- package/commonjs/src/add.command.js +22 -0
- package/commonjs/src/add.module.js +24 -0
- package/commonjs/src/auth0-configure.action.js +28 -0
- package/commonjs/src/auth0-configure.command.js +24 -0
- package/commonjs/src/auth0-login.action.js +28 -0
- package/commonjs/src/auth0-login.command.js +23 -0
- package/commonjs/src/auth0.command.js +22 -0
- package/commonjs/src/auth0.module.js +28 -0
- package/commonjs/src/cli.js +8 -0
- package/commonjs/src/create.command.js +22 -0
- package/commonjs/src/create.module.js +24 -0
- package/commonjs/src/domain/prompt.js +62 -0
- package/commonjs/src/index.js +48 -0
- package/commonjs/src/models/compose.model.js +258 -0
- package/commonjs/src/models/config-yaml.model.js +86 -0
- package/commonjs/src/models/const.js +30 -0
- package/commonjs/src/models/dev-container.model.js +172 -0
- package/commonjs/src/models/docker-image.model.js +277 -0
- package/commonjs/src/models/env-file.model.js +48 -0
- package/commonjs/src/models/gitignore.model.js +48 -0
- package/commonjs/src/models/launch-json.model.js +70 -0
- package/commonjs/src/models/package-json.model.js +156 -0
- package/commonjs/src/models/project.model.js +132 -0
- package/commonjs/src/models/source-file.js +4 -0
- package/commonjs/src/models/tsconfig.model.js +32 -0
- package/commonjs/src/models/vitest-config.model.js +33 -0
- package/commonjs/src/models/vscode-settings.model.js +29 -0
- package/commonjs/src/program.js +64 -0
- package/commonjs/src/resolve-target-dir.js +17 -0
- package/commonjs/src/services/scaffold.service.js +60 -0
- package/commonjs/src/version.js +55 -0
- package/commonjs/src/webapi/api-name.js +93 -0
- package/commonjs/src/webapi/auth0-commands.js +250 -0
- package/commonjs/src/webapi/authorize-scopes.js +79 -0
- package/commonjs/src/webapi/cli-options.js +99 -0
- package/commonjs/src/webapi/const.js +54 -0
- package/commonjs/src/webapi/create-api.js +265 -0
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +164 -0
- package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/commonjs/src/webapi/devcontainer/host-scripts.js +50 -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 +408 -0
- package/commonjs/src/webapi/features/auth0-cli.js +472 -0
- package/commonjs/src/webapi/features/biome-format.js +47 -0
- package/commonjs/src/webapi/features/database.feature.js +433 -0
- package/commonjs/src/webapi/features/finalize.feature.js +93 -0
- package/commonjs/src/webapi/features/postman.feature.js +322 -0
- package/commonjs/src/webapi/models/api-package-json.model.js +58 -0
- package/commonjs/src/webapi/models/auth-config.model.js +24 -0
- package/commonjs/src/webapi/models/controller-source-file.model.js +190 -0
- package/commonjs/src/webapi/models/github-ci.model.js +193 -0
- package/commonjs/src/webapi/models/main-source-file.model.js +165 -0
- package/commonjs/src/webapi/models/production-dockerfile.model.js +75 -0
- package/commonjs/src/webapi/models/sample-files.model.js +58 -0
- package/commonjs/src/webapi/models/webapi-image.model.js +25 -0
- package/commonjs/src/webapi/postman/hello-openapi.js +173 -0
- package/commonjs/src/webapi/postman/local-view.js +182 -0
- package/commonjs/src/webapi/postman/openapi-to-postman.js +238 -0
- package/commonjs/src/webapi/workspace-readme.js +109 -0
- package/commonjs/src/webapi.action.js +28 -0
- package/commonjs/src/webapi.command.js +43 -0
- package/es6/src/add-api.action.js +27 -0
- package/es6/src/add-api.command.js +29 -0
- package/es6/src/add.command.js +12 -0
- package/es6/src/add.module.js +14 -0
- package/es6/src/auth0-configure.action.js +18 -0
- package/es6/src/auth0-configure.command.js +14 -0
- package/es6/src/auth0-login.action.js +18 -0
- package/es6/src/auth0-login.command.js +13 -0
- package/es6/src/auth0.command.js +12 -0
- package/es6/src/auth0.module.js +18 -0
- package/es6/src/cli.js +4 -0
- package/es6/src/create.command.js +12 -0
- package/es6/src/create.module.js +14 -0
- package/es6/src/domain/prompt.js +41 -0
- package/es6/src/index.js +9 -0
- package/es6/src/models/compose.model.js +254 -0
- package/es6/src/models/config-yaml.model.js +74 -0
- package/es6/src/models/const.js +20 -0
- package/es6/src/models/dev-container.model.js +162 -0
- package/es6/src/models/docker-image.model.js +235 -0
- package/es6/src/models/env-file.model.js +44 -0
- package/es6/src/models/gitignore.model.js +38 -0
- package/es6/src/models/launch-json.model.js +60 -0
- package/es6/src/models/package-json.model.js +141 -0
- package/es6/src/models/project.model.js +117 -0
- package/es6/src/models/source-file.js +1 -0
- package/es6/src/models/tsconfig.model.js +22 -0
- package/es6/src/models/vitest-config.model.js +23 -0
- package/es6/src/models/vscode-settings.model.js +19 -0
- package/es6/src/program.js +50 -0
- package/es6/src/resolve-target-dir.js +7 -0
- package/es6/src/services/scaffold.service.js +50 -0
- package/es6/src/version.js +34 -0
- package/es6/src/webapi/api-name.js +57 -0
- package/es6/src/webapi/auth0-commands.js +185 -0
- package/es6/src/webapi/authorize-scopes.js +55 -0
- package/es6/src/webapi/cli-options.js +34 -0
- package/es6/src/webapi/const.js +21 -0
- package/es6/src/webapi/create-api.js +245 -0
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +154 -0
- package/es6/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/es6/src/webapi/devcontainer/host-scripts.js +29 -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 +357 -0
- package/es6/src/webapi/features/auth0-cli.js +406 -0
- package/es6/src/webapi/features/biome-format.js +40 -0
- package/es6/src/webapi/features/database.feature.js +423 -0
- package/es6/src/webapi/features/finalize.feature.js +83 -0
- package/es6/src/webapi/features/postman.feature.js +256 -0
- package/es6/src/webapi/models/api-package-json.model.js +53 -0
- package/es6/src/webapi/models/auth-config.model.js +20 -0
- package/es6/src/webapi/models/controller-source-file.model.js +181 -0
- package/{src/webapi/models/github-ci.model.ts → es6/src/webapi/models/github-ci.model.js} +27 -29
- package/es6/src/webapi/models/main-source-file.model.js +161 -0
- package/es6/src/webapi/models/production-dockerfile.model.js +66 -0
- package/es6/src/webapi/models/sample-files.model.js +40 -0
- package/es6/src/webapi/models/webapi-image.model.js +18 -0
- package/es6/src/webapi/postman/hello-openapi.js +166 -0
- package/es6/src/webapi/postman/local-view.js +167 -0
- package/es6/src/webapi/postman/openapi-to-postman.js +179 -0
- package/es6/src/webapi/workspace-readme.js +88 -0
- package/es6/src/webapi.action.js +18 -0
- package/es6/src/webapi.command.js +33 -0
- package/package.json +19 -9
- 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/auth0-configure.action.d.ts +7 -0
- package/types/src/auth0-configure.command.d.ts +6 -0
- package/types/src/auth0-login.action.d.ts +4 -0
- package/types/src/auth0-login.command.d.ts +6 -0
- package/types/src/auth0.command.d.ts +6 -0
- package/types/src/auth0.module.d.ts +18 -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/{src/index.ts → types/src/index.d.ts} +4 -0
- package/types/src/models/compose.model.d.ts +73 -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 +49 -0
- package/types/src/models/docker-image.model.d.ts +90 -0
- package/types/src/models/env-file.model.d.ts +16 -0
- package/types/src/models/gitignore.model.d.ts +9 -0
- package/types/src/models/launch-json.model.d.ts +7 -0
- package/types/src/models/package-json.model.d.ts +36 -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 +8 -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/auth0-commands.d.ts +11 -0
- package/types/src/webapi/authorize-scopes.d.ts +7 -0
- package/types/src/webapi/cli-options.d.ts +6 -0
- package/{src/webapi/const.ts → types/src/webapi/const.d.ts} +9 -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 +84 -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 +18 -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/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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
async function convertAsync(data, options) {
|
|
2
|
+
// Loaded here, not at the top: the converter pulls in about 700 modules (lodash, faker, ajv,
|
|
3
|
+
// …), which every scaffolder run paid for even with `--postman none`.
|
|
4
|
+
const { default: converter } = await import("openapi-to-postmanv2");
|
|
5
|
+
return new Promise((resolve, reject)=>{
|
|
6
|
+
converter.convert({
|
|
7
|
+
type: "json",
|
|
8
|
+
data
|
|
9
|
+
}, options, (err, result)=>{
|
|
10
|
+
if (err) {
|
|
11
|
+
reject(err);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
resolve(result);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/** Convert an OpenAPI document to a Postman Collection v2.1 via openapi-to-postmanv2. */ export async function openApiToPostmanCollection(document) {
|
|
19
|
+
const result = await convertAsync(document, {
|
|
20
|
+
folderStrategy: "Tags",
|
|
21
|
+
requestNameSource: "Fallback",
|
|
22
|
+
includeAuthInfoInExample: false
|
|
23
|
+
});
|
|
24
|
+
if (!result.result || result.output?.[0]?.data == null) {
|
|
25
|
+
throw new Error(result.reason ?? "openapi-to-postmanv2 conversion failed");
|
|
26
|
+
}
|
|
27
|
+
return result.output[0].data;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Overlay Auth0 OAuth2 (PKCE) collection auth and fix Local View-friendly URLs.
|
|
31
|
+
* Route items come from OpenAPI; auth/env remain hand-authored.
|
|
32
|
+
*/ export function applyPostmanAuthOverlay(collection, projectName, auth, options) {
|
|
33
|
+
const next = {
|
|
34
|
+
...collection,
|
|
35
|
+
info: {
|
|
36
|
+
...collection.info,
|
|
37
|
+
name: `${projectName} WebAPI`,
|
|
38
|
+
description: options.description,
|
|
39
|
+
schema: collection.info.schema ?? "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
if (auth?.auth0Domain) {
|
|
43
|
+
next.auth = {
|
|
44
|
+
type: "oauth2",
|
|
45
|
+
oauth2: [
|
|
46
|
+
{
|
|
47
|
+
key: "grant_type",
|
|
48
|
+
value: "authorization_code_with_pkce",
|
|
49
|
+
type: "string"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "authUrl",
|
|
53
|
+
value: "https://{{auth0Domain}}/authorize?audience={{auth0Audience}}",
|
|
54
|
+
type: "string"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
key: "accessTokenUrl",
|
|
58
|
+
value: "https://{{auth0Domain}}/oauth/token",
|
|
59
|
+
type: "string"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
key: "clientId",
|
|
63
|
+
value: "{{auth0ClientId}}",
|
|
64
|
+
type: "string"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
key: "scope",
|
|
68
|
+
value: options.scopes,
|
|
69
|
+
type: "string"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: "redirect_uri",
|
|
73
|
+
value: options.callbacks[0],
|
|
74
|
+
type: "string"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
key: "useBrowser",
|
|
78
|
+
value: "true",
|
|
79
|
+
type: "boolean"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: "addTokenTo",
|
|
83
|
+
value: "header",
|
|
84
|
+
type: "string"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: "challengeAlgorithm",
|
|
88
|
+
value: "S256",
|
|
89
|
+
type: "string"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
key: "client_authentication",
|
|
93
|
+
value: "body",
|
|
94
|
+
type: "string"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
key: "clientSecret",
|
|
98
|
+
value: "",
|
|
99
|
+
type: "string"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
key: "tokenName",
|
|
103
|
+
value: `${projectName} Access Token`,
|
|
104
|
+
type: "string"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
next.item = rewriteCollectionItems(collection.item ?? [], {
|
|
110
|
+
markListAnonymous: true
|
|
111
|
+
});
|
|
112
|
+
return next;
|
|
113
|
+
}
|
|
114
|
+
function rewriteCollectionItems(items, opts) {
|
|
115
|
+
return items.map((item)=>{
|
|
116
|
+
if (item.item != null) {
|
|
117
|
+
return {
|
|
118
|
+
...item,
|
|
119
|
+
item: rewriteCollectionItems(item.item, opts)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const request = item.request;
|
|
123
|
+
if (request == null) {
|
|
124
|
+
return item;
|
|
125
|
+
}
|
|
126
|
+
const method = (request.method ?? "GET").toUpperCase();
|
|
127
|
+
const rawUrl = requestUrlRaw(request);
|
|
128
|
+
const nextRequest = {
|
|
129
|
+
...request,
|
|
130
|
+
url: toPostmanUrl(rawUrl)
|
|
131
|
+
};
|
|
132
|
+
// List Hello stays anonymous (matches scaffold AllowAnonymous on GET /hello).
|
|
133
|
+
if (opts.markListAnonymous && method === "GET" && normalizePath(rawUrl) === "/hello" && !rawUrl.includes("/:")) {
|
|
134
|
+
nextRequest.auth = {
|
|
135
|
+
type: "noauth"
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
...item,
|
|
140
|
+
request: nextRequest
|
|
141
|
+
};
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function requestUrlRaw(request) {
|
|
145
|
+
const url = request.url;
|
|
146
|
+
if (typeof url === "string") {
|
|
147
|
+
return url;
|
|
148
|
+
}
|
|
149
|
+
if (url?.raw) {
|
|
150
|
+
return url.raw;
|
|
151
|
+
}
|
|
152
|
+
const host = url?.host?.[0] ?? "{{baseUrl}}";
|
|
153
|
+
const path = (url?.path ?? []).join("/");
|
|
154
|
+
return path ? `${host}/${path}` : host;
|
|
155
|
+
}
|
|
156
|
+
/** OpenAPI `{id}` → Postman `:id`, without touching `{{variables}}`. */ export function openApiPathParamsToColon(url) {
|
|
157
|
+
return url.replace(/(?<!\{)\{([A-Za-z_][\w]*)\}(?!\})/g, ":$1");
|
|
158
|
+
}
|
|
159
|
+
function normalizePath(rawUrl) {
|
|
160
|
+
const withoutBase = rawUrl.replace(/\{\{baseUrl\}\}/g, "").split("?")[0] ?? "";
|
|
161
|
+
const withSlash = withoutBase.startsWith("/") ? withoutBase : `/${withoutBase}`;
|
|
162
|
+
return openApiPathParamsToColon(withSlash);
|
|
163
|
+
}
|
|
164
|
+
/** Prefer Postman template URL shape used by existing Local View / API uploads. */ function toPostmanUrl(rawUrl) {
|
|
165
|
+
let pathPart = rawUrl.replace(/\{\{baseUrl\}\}/g, "");
|
|
166
|
+
if (!pathPart.startsWith("/")) {
|
|
167
|
+
pathPart = `/${pathPart}`;
|
|
168
|
+
}
|
|
169
|
+
// openapi-to-postman uses {id}; Local View / prior collections use :id
|
|
170
|
+
pathPart = openApiPathParamsToColon(pathPart);
|
|
171
|
+
const segments = pathPart.split("/").filter(Boolean);
|
|
172
|
+
return {
|
|
173
|
+
raw: `{{baseUrl}}${pathPart}`,
|
|
174
|
+
host: [
|
|
175
|
+
"{{baseUrl}}"
|
|
176
|
+
],
|
|
177
|
+
path: segments
|
|
178
|
+
};
|
|
179
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { WELL_KNOWN_FILES } from "../models/const.js";
|
|
4
|
+
import { apiNameFromProjectDir, listExistingApiNames } from "./api-name.js";
|
|
5
|
+
/** Pure renderer — keep feature sections short and copy-paste ready. */ export function renderWorkspaceReadme(input) {
|
|
6
|
+
const { projectName, apiNames, hasPostgres, hasAuth0, hasPostman } = input;
|
|
7
|
+
const apis = apiNames.length > 0 ? apiNames : [
|
|
8
|
+
"api"
|
|
9
|
+
];
|
|
10
|
+
const lines = [
|
|
11
|
+
`# ${projectName}`,
|
|
12
|
+
"",
|
|
13
|
+
"Decohere web API workspace. Scaffolded with [`@decohere/create`](https://www.npmjs.com/package/@decohere/create).",
|
|
14
|
+
"",
|
|
15
|
+
"## Get started",
|
|
16
|
+
"",
|
|
17
|
+
"1. Open this folder in VS Code / Cursor.",
|
|
18
|
+
"2. **Reopen in Container** (or rebuild the Dev Container).",
|
|
19
|
+
" Host `initialize.sh` and container `post-start.sh` ask y/N (TTY only) before npm auth or codebase RAG MCP.",
|
|
20
|
+
" Skip or decline; missing TTY skips. RAG credentials land in `.cursor/` (gitignored).",
|
|
21
|
+
"3. Install dependencies if needed:",
|
|
22
|
+
"",
|
|
23
|
+
"```bash",
|
|
24
|
+
"pnpm install",
|
|
25
|
+
"```",
|
|
26
|
+
"",
|
|
27
|
+
"## Develop",
|
|
28
|
+
"",
|
|
29
|
+
"```bash",
|
|
30
|
+
"pnpm dev # Flux HMR (first API)",
|
|
31
|
+
"pnpm start # run the compiled first API",
|
|
32
|
+
"pnpm run build # forge release build",
|
|
33
|
+
"pnpm run package # release build + .package/ for each API (what Docker copies)"
|
|
34
|
+
];
|
|
35
|
+
for (const name of apis){
|
|
36
|
+
lines.push(`pnpm run dev:${name} # HMR for ${name}`);
|
|
37
|
+
lines.push(`pnpm run start:${name} # production entry for ${name}`);
|
|
38
|
+
}
|
|
39
|
+
lines.push("```", "");
|
|
40
|
+
lines.push("## Logging", "", "In development, Scribe uses pino-pretty and rolling files under `logs/` (gitignored).", "When `NODE_ENV=production`, the process writes structured JSON to stdout and does not rotate files.", "Ship and retain those streams outside the app (platform logs, a sidecar, or a log agent) so shipping can change without rebuilding.", "", "Override roll path and rotation without changing app code:", "`SCRIBE_LOG_FILE`, `SCRIBE_LOG_SIZE`, `SCRIBE_LOG_FREQUENCY`, `SCRIBE_LOG_KEEP`.", "", 'Opt into in-process pretty or roll in production only with `{ when: "always" }` on `scribe.withPinoPretty` / `scribe.withPinoRoll`.', "");
|
|
41
|
+
if (hasPostgres) {
|
|
42
|
+
lines.push("## Database", "", "Postgres runs via Dev Container Compose:", "", "```bash", "pnpm db:up", "pnpm db:down", "pnpm db:reset", "```", "");
|
|
43
|
+
}
|
|
44
|
+
lines.push("## Deploy", "", "Each API has its own `projects/<name>/Dockerfile`. It copies `.package/`, which `forge package`", "writes before Docker runs: the API's compiled code, the workspace libraries it imports, and", "a plain `node_modules` of the third-party packages it uses (no symlinks). The image build", "installs nothing and needs no npm token.", "", "```bash", "pnpm run package # release build, then .package/ in every API", `docker build -t ${projectName} projects/api`, "```", "", "One API: `pnpm run package:<name>`, then `docker build projects/<name>`.", "A host that builds from a git clone does not have `.package/`; build and push the image", "from CI instead (`forge docker` after `pnpm run package`).", "");
|
|
45
|
+
lines.push("## Add another API", "", "```bash", "decohere add api <name>", "```", "", "Example: `decohere add api billing`", "");
|
|
46
|
+
if (hasAuth0) {
|
|
47
|
+
lines.push("## Auth0", "", "JWT auth is wired from `.env` (`AUTH0_ISSUER_BASE_URL`, `AUTH0_AUDIENCE`).", 'After you add a controller, `@Authorize("read", "Invoice")` becomes the Auth0 permission `read:Invoice`.', "Sync the Auth0 API, admin grants, and Postman token scopes without re-scaffolding:", "", "```bash", "npx @decohere/create auth0 login # once / when the CLI token expires", "npx @decohere/create auth0 configure # after new @Authorize decorators", "```", "");
|
|
48
|
+
}
|
|
49
|
+
if (hasPostman) {
|
|
50
|
+
lines.push("## Postman", "", "Open this **project root** in Postman Local View (Files → Open folder), not the `postman/` subfolder.", "Select the Local environment, then Authorization → Get New Access Token when Auth0 is enabled.", "");
|
|
51
|
+
}
|
|
52
|
+
lines.push("## More", "", "- Package docs: https://www.npmjs.com/package/@decohere/create", "- After `decohere add api`, this README is refreshed so scripts and APIs stay accurate.", "");
|
|
53
|
+
return `${lines.join("\n")}`;
|
|
54
|
+
}
|
|
55
|
+
export function resolveWorkspaceReadmeInput(workspace, options) {
|
|
56
|
+
const newNames = workspace.getProjects().map((project)=>apiNameFromProjectDir(project.dir));
|
|
57
|
+
const apiNames = options.add ? mergeApiNames(listExistingApiNames(workspace.targetDir), newNames) : newNames;
|
|
58
|
+
const pkg = workspace.getModel(WELL_KNOWN_FILES.PACKAGE_JSON);
|
|
59
|
+
const env = workspace.getModel(WELL_KNOWN_FILES.ENV_FILE);
|
|
60
|
+
const hasPostgres = options.databaseProvider === "postgres/typeorm" || Boolean(pkg?.hasScript("db:up"));
|
|
61
|
+
const hasAuth0 = options.authProvider === "auth0" || Boolean(env?.hasEntry("AUTH0_ISSUER_BASE_URL"));
|
|
62
|
+
const hasPostman = options.postmanProvider === "local" || options.postmanProvider === "api" || existsSync(join(workspace.targetDir, "postman")) || existsSync(join(workspace.targetDir, ".postman"));
|
|
63
|
+
return {
|
|
64
|
+
projectName: workspace.name,
|
|
65
|
+
apiNames,
|
|
66
|
+
hasPostgres,
|
|
67
|
+
hasAuth0,
|
|
68
|
+
hasPostman
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export function writeWorkspaceReadme(workspace, options) {
|
|
72
|
+
const content = renderWorkspaceReadme(resolveWorkspaceReadmeInput(workspace, options));
|
|
73
|
+
workspace.addFile({
|
|
74
|
+
files: ()=>[
|
|
75
|
+
{
|
|
76
|
+
filePath: "README.md",
|
|
77
|
+
content
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function mergeApiNames(existing, added) {
|
|
83
|
+
const seen = new Set(existing);
|
|
84
|
+
return [
|
|
85
|
+
...existing,
|
|
86
|
+
...added.filter((name)=>!seen.has(name))
|
|
87
|
+
];
|
|
88
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
}
|
|
7
|
+
import { injectable } from "@decohere/crucible/decorators";
|
|
8
|
+
import { ActionResponse } from "@decohere/devkit/cli";
|
|
9
|
+
import { runScaffoldApi, toApiOptions } from "./webapi/cli-options.js";
|
|
10
|
+
export class WebapiAction {
|
|
11
|
+
async run(options) {
|
|
12
|
+
await runScaffoldApi(toApiOptions(options.directory, options));
|
|
13
|
+
return ActionResponse.Success("webapi");
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
WebapiAction = _ts_decorate([
|
|
17
|
+
injectable()
|
|
18
|
+
], WebapiAction);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DecohereCommand } from "@decohere/devkit/cli";
|
|
2
|
+
import { addWebapiFeatureOptions, collectName } from "./webapi/cli-options.js";
|
|
3
|
+
import { WebapiAction } from "./webapi.action.js";
|
|
4
|
+
export class WebapiCommand extends DecohereCommand {
|
|
5
|
+
get actions() {
|
|
6
|
+
return [
|
|
7
|
+
WebapiAction
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
constructor(name){
|
|
11
|
+
super(name);
|
|
12
|
+
this.description("Scaffold a web API workspace");
|
|
13
|
+
this.argument("[directory]", "Target directory (default: -d or current directory)");
|
|
14
|
+
this.option("-d <directory>", "Target directory (default: current directory)", ".");
|
|
15
|
+
this.option("--name <slug>", "API name under projects/ (repeatable; default: api)", collectName, []);
|
|
16
|
+
addWebapiFeatureOptions(this);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Commander passes positional args before options when `[directory]` is declared.
|
|
20
|
+
* ModuleFactory expects `(opts, cmd)` — stash the directory on the command.
|
|
21
|
+
*/ action(fn) {
|
|
22
|
+
return super.action((...args)=>{
|
|
23
|
+
const cmd = args.at(-1);
|
|
24
|
+
const first = args[0];
|
|
25
|
+
const hasPositional = typeof first === "string" || first === undefined;
|
|
26
|
+
const opts = hasPositional ? args[1] : args[0];
|
|
27
|
+
if (typeof first === "string" && first !== "") {
|
|
28
|
+
cmd.setOptionValue("directory", first);
|
|
29
|
+
}
|
|
30
|
+
return fn(opts, cmd);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decohere/scaffold",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
4
|
-
"decohere": {
|
|
5
|
-
"dockerImageRepository": "ghcr.io/typesmiths/decohere/create",
|
|
6
|
-
"devcontainerImageRepository": "ghcr.io/typesmiths/decohere/devcontainer"
|
|
7
|
-
},
|
|
3
|
+
"version": "0.0.1-dev.20261105.46",
|
|
8
4
|
"description": "Decohere project scaffolder (runs inside ghcr.io/typesmiths/decohere/create)",
|
|
9
5
|
"keywords": [
|
|
10
6
|
"decohere",
|
|
11
7
|
"scaffold"
|
|
12
8
|
],
|
|
9
|
+
"homepage": "https://github.com/typesmiths/decohere/tree/main/projects/scaffold#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/typesmiths/decohere/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/typesmiths/decohere.git",
|
|
16
|
+
"directory": "projects/scaffold"
|
|
17
|
+
},
|
|
13
18
|
"license": "ISC",
|
|
14
19
|
"author": "Typesmiths",
|
|
15
20
|
"type": "module",
|
|
@@ -26,10 +31,15 @@
|
|
|
26
31
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
27
32
|
},
|
|
28
33
|
"dependencies": {
|
|
29
|
-
"@decohere/crucible": "0.0.1-dev.
|
|
30
|
-
"@decohere/
|
|
34
|
+
"@decohere/crucible": "0.0.1-dev.20261105.46",
|
|
35
|
+
"@decohere/devkit": "0.0.1-dev.20261105.46",
|
|
31
36
|
"commander": "^13.1.0",
|
|
32
|
-
"openapi-to-postmanv2": "^5.0.0"
|
|
37
|
+
"openapi-to-postmanv2": "^5.0.0",
|
|
38
|
+
"yaml": "^2.9.1"
|
|
33
39
|
},
|
|
34
|
-
"devDependencies": {}
|
|
40
|
+
"devDependencies": {},
|
|
41
|
+
"decohere": {
|
|
42
|
+
"dockerImageRepository": "ghcr.io/typesmiths/decohere/create",
|
|
43
|
+
"devcontainerImageRepository": "ghcr.io/typesmiths/decohere/devcontainer"
|
|
44
|
+
}
|
|
35
45
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Action, ActionResponse } from "@decohere/devkit/cli";
|
|
2
|
+
export type AddApiOptions = {
|
|
3
|
+
apiName?: string;
|
|
4
|
+
d?: string;
|
|
5
|
+
database?: string;
|
|
6
|
+
auth?: string;
|
|
7
|
+
postman?: string;
|
|
8
|
+
yes?: boolean;
|
|
9
|
+
install?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare class AddApiAction implements Action<AddApiOptions> {
|
|
12
|
+
run(options: AddApiOptions): Promise<ActionResponse>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DecohereCommand } from "@decohere/devkit/cli";
|
|
2
|
+
import { AddApiAction } from "./add-api.action.js";
|
|
3
|
+
export declare class AddApiCommand extends DecohereCommand {
|
|
4
|
+
get actions(): (typeof AddApiAction)[];
|
|
5
|
+
constructor(name: string);
|
|
6
|
+
action(fn: (...args: unknown[]) => void | Promise<void>): this;
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Actions } from "@decohere/devkit/cli";
|
|
2
|
+
import { type CommandHandler, type CommandResponse, type CommandType, DecohereCommand } from "@decohere/devkit/cli";
|
|
3
|
+
export declare class AddCommand extends DecohereCommand {
|
|
4
|
+
constructor(commands: Record<string, CommandType>, handler: CommandHandler);
|
|
5
|
+
run(_actions: Actions, _options: never): Promise<CommandResponse>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ModuleManifest } from "@decohere/devkit/cli";
|
|
2
|
+
import { AddCommand } from "./add.command.js";
|
|
3
|
+
import { AddApiAction } from "./add-api.action.js";
|
|
4
|
+
import { AddApiCommand } from "./add-api.command.js";
|
|
5
|
+
export declare class AddModule extends ModuleManifest {
|
|
6
|
+
readonly id = "add";
|
|
7
|
+
readonly command: typeof AddCommand;
|
|
8
|
+
readonly commands: {
|
|
9
|
+
api: typeof AddApiCommand;
|
|
10
|
+
};
|
|
11
|
+
readonly actions: {
|
|
12
|
+
api: typeof AddApiAction;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Action, ActionResponse } from "@decohere/devkit/cli";
|
|
2
|
+
export type Auth0ConfigureOptions = {
|
|
3
|
+
d?: string;
|
|
4
|
+
};
|
|
5
|
+
export declare class Auth0ConfigureAction implements Action<Auth0ConfigureOptions> {
|
|
6
|
+
run(options: Auth0ConfigureOptions): Promise<ActionResponse>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DecohereCommand } from "@decohere/devkit/cli";
|
|
2
|
+
import { Auth0ConfigureAction } from "./auth0-configure.action.js";
|
|
3
|
+
export declare class Auth0ConfigureCommand extends DecohereCommand {
|
|
4
|
+
get actions(): (typeof Auth0ConfigureAction)[];
|
|
5
|
+
constructor(name: string);
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Actions } from "@decohere/devkit/cli";
|
|
2
|
+
import { type CommandHandler, type CommandResponse, type CommandType, DecohereCommand } from "@decohere/devkit/cli";
|
|
3
|
+
export declare class Auth0Command extends DecohereCommand {
|
|
4
|
+
constructor(commands: Record<string, CommandType>, handler: CommandHandler);
|
|
5
|
+
run(_actions: Actions, _options: never): Promise<CommandResponse>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ModuleManifest } from "@decohere/devkit/cli";
|
|
2
|
+
import { Auth0Command } from "./auth0.command.js";
|
|
3
|
+
import { Auth0ConfigureAction } from "./auth0-configure.action.js";
|
|
4
|
+
import { Auth0ConfigureCommand } from "./auth0-configure.command.js";
|
|
5
|
+
import { Auth0LoginAction } from "./auth0-login.action.js";
|
|
6
|
+
import { Auth0LoginCommand } from "./auth0-login.command.js";
|
|
7
|
+
export declare class Auth0Module extends ModuleManifest {
|
|
8
|
+
readonly id = "auth0";
|
|
9
|
+
readonly command: typeof Auth0Command;
|
|
10
|
+
readonly commands: {
|
|
11
|
+
login: typeof Auth0LoginCommand;
|
|
12
|
+
configure: typeof Auth0ConfigureCommand;
|
|
13
|
+
};
|
|
14
|
+
readonly actions: {
|
|
15
|
+
login: typeof Auth0LoginAction;
|
|
16
|
+
configure: typeof Auth0ConfigureAction;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Actions } from "@decohere/devkit/cli";
|
|
2
|
+
import { type CommandHandler, type CommandResponse, type CommandType, DecohereCommand } from "@decohere/devkit/cli";
|
|
3
|
+
export declare class CreateCommand extends DecohereCommand {
|
|
4
|
+
constructor(commands: Record<string, CommandType>, handler: CommandHandler);
|
|
5
|
+
run(_actions: Actions, _options: never): Promise<CommandResponse>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ModuleManifest } from "@decohere/devkit/cli";
|
|
2
|
+
import { CreateCommand } from "./create.command.js";
|
|
3
|
+
import { WebapiAction } from "./webapi.action.js";
|
|
4
|
+
import { WebapiCommand } from "./webapi.command.js";
|
|
5
|
+
export declare class CreateModule extends ModuleManifest {
|
|
6
|
+
readonly id = "create";
|
|
7
|
+
readonly command: typeof CreateCommand;
|
|
8
|
+
readonly commands: {
|
|
9
|
+
webapi: typeof WebapiCommand;
|
|
10
|
+
};
|
|
11
|
+
readonly actions: {
|
|
12
|
+
webapi: typeof WebapiAction;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Release stdin so the process can exit after interactive prompts. */
|
|
2
|
+
export declare function closePrompt(): void;
|
|
3
|
+
export declare function ask(question: string, fallback?: string): Promise<string>;
|
|
4
|
+
export declare function pick<T>(label: string, items: T[], display: (item: T) => string): Promise<T | null>;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { AddModule } from "./add.module.js";
|
|
2
2
|
export type { AddApiOptions } from "./add-api.action.js";
|
|
3
3
|
export { AddApiAction } from "./add-api.action.js";
|
|
4
|
+
export { Auth0Module } from "./auth0.module.js";
|
|
5
|
+
export type { Auth0ConfigureOptions } from "./auth0-configure.action.js";
|
|
6
|
+
export { Auth0ConfigureAction } from "./auth0-configure.action.js";
|
|
7
|
+
export { Auth0LoginAction } from "./auth0-login.action.js";
|
|
4
8
|
export { CreateModule } from "./create.module.js";
|
|
5
9
|
export { runCli } from "./program.js";
|
|
6
10
|
export type { ApiOptions } from "./webapi/create-api.js";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { KeyedModel } from "./source-file.js";
|
|
2
|
+
export type ComposeNetworkRef = string | {
|
|
3
|
+
/** Network key under `networks:` on this service */
|
|
4
|
+
[networkKey: string]: {
|
|
5
|
+
aliases?: string[];
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
export interface ComposeHealthcheck {
|
|
9
|
+
test: string[];
|
|
10
|
+
interval?: string;
|
|
11
|
+
timeout?: string;
|
|
12
|
+
retries?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ComposeService {
|
|
15
|
+
build?: string;
|
|
16
|
+
image?: string;
|
|
17
|
+
container_name?: string;
|
|
18
|
+
/** Quoted in YAML (`0:0` must not parse as a number). */
|
|
19
|
+
user?: string;
|
|
20
|
+
env_file?: string[];
|
|
21
|
+
environment?: Record<string, string>;
|
|
22
|
+
ports?: string[];
|
|
23
|
+
volumes?: string[];
|
|
24
|
+
command?: string;
|
|
25
|
+
restart?: string;
|
|
26
|
+
depends_on?: string[];
|
|
27
|
+
/** Compose profiles (service only starts when profile is enabled). */
|
|
28
|
+
profiles?: string[];
|
|
29
|
+
/** Attach to compose networks (string name or map with aliases). */
|
|
30
|
+
networks?: ComposeNetworkRef[];
|
|
31
|
+
healthcheck?: ComposeHealthcheck;
|
|
32
|
+
}
|
|
33
|
+
export type ComposeNetwork = {
|
|
34
|
+
/** Fixed Docker network name (shareable across compose projects). */
|
|
35
|
+
name: string;
|
|
36
|
+
external?: boolean;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Live builder for `docker-compose.yml`.
|
|
40
|
+
*
|
|
41
|
+
* Features call `addService` / `addVolume` / `addNetwork` in their scaffold phases.
|
|
42
|
+
* Loaded with `fromFile` (`decohere add api`), additions merge into the existing file:
|
|
43
|
+
* services, networks and volumes already there are left untouched, comments kept.
|
|
44
|
+
*/
|
|
45
|
+
export declare class DockerCompose implements KeyedModel {
|
|
46
|
+
readonly key: string;
|
|
47
|
+
private _projectName;
|
|
48
|
+
private readonly _headerComments;
|
|
49
|
+
private readonly _services;
|
|
50
|
+
private readonly _volumes;
|
|
51
|
+
private readonly _networks;
|
|
52
|
+
private readonly _envFiles;
|
|
53
|
+
private _existing;
|
|
54
|
+
/** Load an existing compose file so `decohere add api` can merge into it. */
|
|
55
|
+
static fromFile(absolutePath: string): DockerCompose;
|
|
56
|
+
/** True when the service is defined (in the loaded file or added since). */
|
|
57
|
+
hasService(name: string): boolean;
|
|
58
|
+
/** Compose project name (`name:` top-level) — isolates containers/volumes. */
|
|
59
|
+
setProjectName(name: string): this;
|
|
60
|
+
/** File-level `#` comments rendered above `name:` / `services:`. */
|
|
61
|
+
addHeaderComment(...lines: string[]): this;
|
|
62
|
+
addService(name: string, config: ComposeService): this;
|
|
63
|
+
files(): {
|
|
64
|
+
filePath: string;
|
|
65
|
+
content: string;
|
|
66
|
+
}[];
|
|
67
|
+
addVolume(name: string): this;
|
|
68
|
+
addNetwork(key: string, network: ComposeNetwork): this;
|
|
69
|
+
/** Append an env_file path to an existing service. */
|
|
70
|
+
addEnvFile(serviceName: string, filePath: string): this;
|
|
71
|
+
getContent(): string;
|
|
72
|
+
private mergeIntoExisting;
|
|
73
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KeyedModel, SourceFile } from "./source-file.js";
|
|
2
|
+
/**
|
|
3
|
+
* Builder for a YAML config file (e.g. config/config.yaml or config/config.dev.yaml).
|
|
4
|
+
*
|
|
5
|
+
* Starts with a base section passed to the constructor. Features call
|
|
6
|
+
* `addSection(yaml)` during their scaffold phase to append their own block.
|
|
7
|
+
* `files()` joins all sections with a blank line separator.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ConfigYaml implements KeyedModel {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
private readonly filePath;
|
|
12
|
+
private readonly _sections;
|
|
13
|
+
constructor(key: string, filePath: string, baseContent: string);
|
|
14
|
+
addSection(yaml: string): this;
|
|
15
|
+
/** True when a datasource with this `name:` already appears in the file. */
|
|
16
|
+
hasDataSource(name: string): boolean;
|
|
17
|
+
hasDataSources(): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Insert a `dataSources` list item. Used by `webapi add` so we do not write a
|
|
20
|
+
* second top-level `database:` key (YAML last-key-wins).
|
|
21
|
+
*/
|
|
22
|
+
appendDataSource(item: string): this;
|
|
23
|
+
static fromFile(key: string, relativePath: string, absolutePath: string): ConfigYaml;
|
|
24
|
+
files(): SourceFile[];
|
|
25
|
+
}
|
|
26
|
+
/** Insert a YAML list item under `dataSources:`; append a new `database:` block if missing. */
|
|
27
|
+
export declare function injectYamlDataSource(yaml: string, item: string): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const WELL_KNOWN_FILES: {
|
|
2
|
+
VSCODE_SETTINGS: string;
|
|
3
|
+
LAUNCH_JSON: string;
|
|
4
|
+
DOCKER_COMPOSE: string;
|
|
5
|
+
DEVCONTAINER_JSON: string;
|
|
6
|
+
DOCKERFILE: string;
|
|
7
|
+
PRODUCTION_DOCKERFILE: string;
|
|
8
|
+
GITHUB_CI: string;
|
|
9
|
+
PACKAGE_JSON: string;
|
|
10
|
+
API_PACKAGE_JSON: string;
|
|
11
|
+
TSCONFIG: string;
|
|
12
|
+
VITEST_CONFIG: string;
|
|
13
|
+
MAIN_TS: string;
|
|
14
|
+
CONTROLLER_TS: string;
|
|
15
|
+
CONFIG_YAML: string;
|
|
16
|
+
CONFIG_DEV_YAML: string;
|
|
17
|
+
GITIGNORE: string;
|
|
18
|
+
AUTH_CONFIG: string;
|
|
19
|
+
ENV_FILE: string;
|
|
20
|
+
};
|