@decohere/scaffold 0.0.1-dev.100
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 +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 +7 -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 +432 -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 +200 -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 +3 -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 +46 -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 +422 -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/es6/src/webapi/models/github-ci.model.js +186 -0
- 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 +177 -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 +36 -0
- package/src/webapi/devcontainer/codebase-rag-mcp.ts +182 -0
- package/src/webapi/devcontainer/templates/codebase-rag.env.example +3 -0
- package/src/webapi/devcontainer/templates/initialize.sh +169 -0
- package/src/webapi/devcontainer/templates/post-create.sh +35 -0
- package/src/webapi/devcontainer/templates/post-start.sh +65 -0
- package/src/webapi/devcontainer/templates/tty-prompt.sh +38 -0
- 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/types/src/index.d.ts +13 -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/types/src/models/source-file.d.ts +11 -0
- 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/types/src/resolve-target-dir.d.ts +5 -0
- 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/types/src/webapi/const.d.ts +19 -0
- 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
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Auth0AuthError () {
|
|
13
|
+
return Auth0AuthError;
|
|
14
|
+
},
|
|
15
|
+
get DB_CONNECTION_NAME () {
|
|
16
|
+
return DB_CONNECTION_NAME;
|
|
17
|
+
},
|
|
18
|
+
get HELLO_API_SCOPES () {
|
|
19
|
+
return HELLO_API_SCOPES;
|
|
20
|
+
},
|
|
21
|
+
get REQUIRED_SCOPES () {
|
|
22
|
+
return REQUIRED_SCOPES;
|
|
23
|
+
},
|
|
24
|
+
get assignUserPermissions () {
|
|
25
|
+
return assignUserPermissions;
|
|
26
|
+
},
|
|
27
|
+
get createAdminDatabaseUser () {
|
|
28
|
+
return createAdminDatabaseUser;
|
|
29
|
+
},
|
|
30
|
+
get createApi () {
|
|
31
|
+
return createApi;
|
|
32
|
+
},
|
|
33
|
+
get createSpaApp () {
|
|
34
|
+
return createSpaApp;
|
|
35
|
+
},
|
|
36
|
+
get enableConnectionForClient () {
|
|
37
|
+
return enableConnectionForClient;
|
|
38
|
+
},
|
|
39
|
+
get ensureSpaApp () {
|
|
40
|
+
return ensureSpaApp;
|
|
41
|
+
},
|
|
42
|
+
get findUserByEmail () {
|
|
43
|
+
return findUserByEmail;
|
|
44
|
+
},
|
|
45
|
+
get formatSpaEntityLimitError () {
|
|
46
|
+
return formatSpaEntityLimitError;
|
|
47
|
+
},
|
|
48
|
+
get generateAdminPassword () {
|
|
49
|
+
return generateAdminPassword;
|
|
50
|
+
},
|
|
51
|
+
get isAuth0EntityLimitError () {
|
|
52
|
+
return isAuth0EntityLimitError;
|
|
53
|
+
},
|
|
54
|
+
get isInstalled () {
|
|
55
|
+
return isInstalled;
|
|
56
|
+
},
|
|
57
|
+
get listApiScopes () {
|
|
58
|
+
return listApiScopes;
|
|
59
|
+
},
|
|
60
|
+
get listApis () {
|
|
61
|
+
return listApis;
|
|
62
|
+
},
|
|
63
|
+
get listApps () {
|
|
64
|
+
return listApps;
|
|
65
|
+
},
|
|
66
|
+
get listTenants () {
|
|
67
|
+
return listTenants;
|
|
68
|
+
},
|
|
69
|
+
get login () {
|
|
70
|
+
return login;
|
|
71
|
+
},
|
|
72
|
+
get updateApiScopes () {
|
|
73
|
+
return updateApiScopes;
|
|
74
|
+
},
|
|
75
|
+
get updateSpaCallbacks () {
|
|
76
|
+
return updateSpaCallbacks;
|
|
77
|
+
},
|
|
78
|
+
get updateUserPassword () {
|
|
79
|
+
return updateUserPassword;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const _nodechild_process = require("node:child_process");
|
|
83
|
+
const _nodecrypto = require("node:crypto");
|
|
84
|
+
/** Management API scopes needed for API, SPA, connections, and admin users. */ const REQUIRED_SCOPES = [
|
|
85
|
+
"create:clients",
|
|
86
|
+
"read:clients",
|
|
87
|
+
"update:clients",
|
|
88
|
+
"create:resource_servers",
|
|
89
|
+
"read:resource_servers",
|
|
90
|
+
"update:resource_servers",
|
|
91
|
+
"read:connections",
|
|
92
|
+
"update:connections",
|
|
93
|
+
"create:users",
|
|
94
|
+
"read:users",
|
|
95
|
+
"update:users"
|
|
96
|
+
].join(",");
|
|
97
|
+
/** Hard timeout for any Management API call. Prevents indefinite hangs on token re-auth. */ const API_TIMEOUT_MS = 8_000;
|
|
98
|
+
const HELLO_API_SCOPES = [
|
|
99
|
+
"read:Hello",
|
|
100
|
+
"create:Hello",
|
|
101
|
+
"update:Hello",
|
|
102
|
+
"delete:Hello"
|
|
103
|
+
];
|
|
104
|
+
const DB_CONNECTION_NAME = "Username-Password-Authentication";
|
|
105
|
+
class Auth0AuthError extends Error {
|
|
106
|
+
constructor(message){
|
|
107
|
+
super(message);
|
|
108
|
+
this.name = "Auth0AuthError";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Returns true if an error or stderr output looks like an expired/missing token. */ function isAuthError(text) {
|
|
112
|
+
return text.includes("renew access token") || text.includes("log in") || text.includes("Unauthorized");
|
|
113
|
+
}
|
|
114
|
+
/** Strip Auth0 CLI banner lines before JSON. */ function parseJsonOutput(stdout) {
|
|
115
|
+
const start = stdout.indexOf("{");
|
|
116
|
+
const arrayStart = stdout.indexOf("[");
|
|
117
|
+
let idx = -1;
|
|
118
|
+
if (start === -1) idx = arrayStart;
|
|
119
|
+
else if (arrayStart === -1) idx = start;
|
|
120
|
+
else idx = Math.min(start, arrayStart);
|
|
121
|
+
if (idx < 0) throw new Error(`Expected JSON from auth0 CLI, got: ${stdout.slice(0, 200)}`);
|
|
122
|
+
return JSON.parse(stdout.slice(idx));
|
|
123
|
+
}
|
|
124
|
+
/** Run an auth0 CLI command with a hard timeout. Returns stdout on success, throws on failure. */ function runAuth0(args) {
|
|
125
|
+
const result = (0, _nodechild_process.spawnSync)("auth0", args, {
|
|
126
|
+
encoding: "utf8",
|
|
127
|
+
timeout: API_TIMEOUT_MS,
|
|
128
|
+
input: "",
|
|
129
|
+
stdio: "pipe"
|
|
130
|
+
});
|
|
131
|
+
if (result.error) {
|
|
132
|
+
const msg = result.error.message;
|
|
133
|
+
if (isAuthError(msg) || result.error.code === "ETIMEDOUT") {
|
|
134
|
+
throw new Auth0AuthError(msg);
|
|
135
|
+
}
|
|
136
|
+
throw result.error;
|
|
137
|
+
}
|
|
138
|
+
if (result.status !== 0) {
|
|
139
|
+
const stderr = result.stderr ?? "";
|
|
140
|
+
if (isAuthError(stderr)) throw new Auth0AuthError(stderr);
|
|
141
|
+
throw new Error(stderr || `auth0 exited with code ${result.status}`);
|
|
142
|
+
}
|
|
143
|
+
return result.stdout;
|
|
144
|
+
}
|
|
145
|
+
function isInstalled() {
|
|
146
|
+
try {
|
|
147
|
+
(0, _nodechild_process.execFileSync)("auth0", [
|
|
148
|
+
"--version"
|
|
149
|
+
], {
|
|
150
|
+
stdio: "pipe"
|
|
151
|
+
});
|
|
152
|
+
return true;
|
|
153
|
+
} catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function listTenants() {
|
|
158
|
+
try {
|
|
159
|
+
const out = (0, _nodechild_process.execFileSync)("auth0", [
|
|
160
|
+
"tenants",
|
|
161
|
+
"list",
|
|
162
|
+
"--json"
|
|
163
|
+
], {
|
|
164
|
+
encoding: "utf8",
|
|
165
|
+
stdio: "pipe"
|
|
166
|
+
});
|
|
167
|
+
return JSON.parse(out);
|
|
168
|
+
} catch {
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function login() {
|
|
173
|
+
const result = (0, _nodechild_process.spawnSync)("auth0", [
|
|
174
|
+
"login",
|
|
175
|
+
"--scopes",
|
|
176
|
+
REQUIRED_SCOPES,
|
|
177
|
+
"--no-input"
|
|
178
|
+
], {
|
|
179
|
+
stdio: "inherit"
|
|
180
|
+
});
|
|
181
|
+
return result.status === 0;
|
|
182
|
+
}
|
|
183
|
+
function listApis() {
|
|
184
|
+
try {
|
|
185
|
+
const out = runAuth0([
|
|
186
|
+
"apis",
|
|
187
|
+
"list",
|
|
188
|
+
"--json",
|
|
189
|
+
"--no-input"
|
|
190
|
+
]);
|
|
191
|
+
return parseJsonOutput(out);
|
|
192
|
+
} catch (err) {
|
|
193
|
+
if (err instanceof Auth0AuthError) throw err;
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function createApi(name, identifier, scopes = HELLO_API_SCOPES) {
|
|
198
|
+
const out = runAuth0([
|
|
199
|
+
"apis",
|
|
200
|
+
"create",
|
|
201
|
+
"--name",
|
|
202
|
+
name,
|
|
203
|
+
"--identifier",
|
|
204
|
+
identifier,
|
|
205
|
+
"--scopes",
|
|
206
|
+
scopes.join(","),
|
|
207
|
+
// RBAC: only permissions assigned to the user/role appear on the token.
|
|
208
|
+
"--enforce-policies",
|
|
209
|
+
// Include Auth0 `permissions[]` claim (consumed by sample principalMapper).
|
|
210
|
+
"--token-dialect",
|
|
211
|
+
"access_token_authz",
|
|
212
|
+
"--json",
|
|
213
|
+
"--no-input"
|
|
214
|
+
]);
|
|
215
|
+
return parseJsonOutput(out);
|
|
216
|
+
}
|
|
217
|
+
function listApiScopes(identifier) {
|
|
218
|
+
try {
|
|
219
|
+
const out = runAuth0([
|
|
220
|
+
"apis",
|
|
221
|
+
"show",
|
|
222
|
+
identifier,
|
|
223
|
+
"--json",
|
|
224
|
+
"--no-input"
|
|
225
|
+
]);
|
|
226
|
+
const api = parseJsonOutput(out);
|
|
227
|
+
return (api.scopes ?? []).map((scope)=>typeof scope === "string" ? scope : scope.value ?? scope.name ?? "").filter((scope)=>scope.length > 0);
|
|
228
|
+
} catch (err) {
|
|
229
|
+
if (err instanceof Auth0AuthError) throw err;
|
|
230
|
+
return [];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function assignUserPermissions(userId, audience, permissions) {
|
|
234
|
+
if (permissions.length === 0) return;
|
|
235
|
+
runAuth0([
|
|
236
|
+
"api",
|
|
237
|
+
"post",
|
|
238
|
+
`users/${encodeURIComponent(userId)}/permissions`,
|
|
239
|
+
"--data",
|
|
240
|
+
JSON.stringify({
|
|
241
|
+
permissions: permissions.map((permission_name)=>({
|
|
242
|
+
resource_server_identifier: audience,
|
|
243
|
+
permission_name
|
|
244
|
+
}))
|
|
245
|
+
}),
|
|
246
|
+
"--no-input"
|
|
247
|
+
]);
|
|
248
|
+
}
|
|
249
|
+
function updateApiScopes(identifier, scopes = HELLO_API_SCOPES) {
|
|
250
|
+
runAuth0([
|
|
251
|
+
"apis",
|
|
252
|
+
"update",
|
|
253
|
+
identifier,
|
|
254
|
+
"--scopes",
|
|
255
|
+
scopes.join(","),
|
|
256
|
+
"--enforce-policies",
|
|
257
|
+
"--token-dialect",
|
|
258
|
+
"access_token_authz",
|
|
259
|
+
"--no-input"
|
|
260
|
+
]);
|
|
261
|
+
}
|
|
262
|
+
function isAuth0EntityLimitError(err) {
|
|
263
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
264
|
+
return /limit of entities|reached the limit|tenant application limit reached/i.test(text);
|
|
265
|
+
}
|
|
266
|
+
function formatSpaEntityLimitError(appName, apps) {
|
|
267
|
+
const listed = apps.length === 0 ? "Could not list existing applications." : `This tenant already has ${apps.length} application(s):\n${apps.map((a)=>` - ${a.name} (${a.client_id})`).join("\n")}`;
|
|
268
|
+
return [
|
|
269
|
+
`Auth0 refused to create SPA "${appName}": tenant application limit reached.`,
|
|
270
|
+
listed,
|
|
271
|
+
"",
|
|
272
|
+
"Fix: Auth0 Dashboard → Applications → Applications → delete unused apps,",
|
|
273
|
+
`then re-run the scaffold (or choose Postman "none" to skip SPA creation).`,
|
|
274
|
+
"Re-scaffold of the same project name reuses an exact-name match when it still exists."
|
|
275
|
+
].join("\n");
|
|
276
|
+
}
|
|
277
|
+
function createSpaApp(name, callbackUrls) {
|
|
278
|
+
const callbacks = typeof callbackUrls === "string" ? callbackUrls : callbackUrls.join(",");
|
|
279
|
+
const out = runAuth0([
|
|
280
|
+
"apps",
|
|
281
|
+
"create",
|
|
282
|
+
"--name",
|
|
283
|
+
name,
|
|
284
|
+
"--type",
|
|
285
|
+
"spa",
|
|
286
|
+
"--callbacks",
|
|
287
|
+
callbacks,
|
|
288
|
+
"--json",
|
|
289
|
+
"--no-input"
|
|
290
|
+
]);
|
|
291
|
+
const app = parseJsonOutput(out);
|
|
292
|
+
const clientId = app.client_id ?? app.clientId;
|
|
293
|
+
if (!clientId) {
|
|
294
|
+
throw new Error(`Auth0 create SPA response missing client_id. stdout: ${out.slice(0, 300)}`);
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
client_id: clientId
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function listApps() {
|
|
301
|
+
try {
|
|
302
|
+
const out = runAuth0([
|
|
303
|
+
"apps",
|
|
304
|
+
"list",
|
|
305
|
+
"--json",
|
|
306
|
+
"--no-input"
|
|
307
|
+
]);
|
|
308
|
+
const apps = parseJsonOutput(out);
|
|
309
|
+
return apps.map((a)=>({
|
|
310
|
+
client_id: a.client_id ?? a.clientId ?? "",
|
|
311
|
+
name: a.name ?? ""
|
|
312
|
+
})).filter((a)=>a.client_id && a.name);
|
|
313
|
+
} catch (err) {
|
|
314
|
+
if (err instanceof Auth0AuthError) throw err;
|
|
315
|
+
return [];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function updateSpaCallbacks(clientId, callbackUrls) {
|
|
319
|
+
const callbacks = typeof callbackUrls === "string" ? callbackUrls : callbackUrls.join(",");
|
|
320
|
+
runAuth0([
|
|
321
|
+
"apps",
|
|
322
|
+
"update",
|
|
323
|
+
clientId,
|
|
324
|
+
"--callbacks",
|
|
325
|
+
callbacks,
|
|
326
|
+
"--no-input"
|
|
327
|
+
]);
|
|
328
|
+
}
|
|
329
|
+
function ensureSpaApp(name, callbackUrls) {
|
|
330
|
+
const apps = listApps();
|
|
331
|
+
const existing = apps.find((a)=>a.name === name);
|
|
332
|
+
if (existing) {
|
|
333
|
+
try {
|
|
334
|
+
updateSpaCallbacks(existing.client_id, callbackUrls);
|
|
335
|
+
} catch {
|
|
336
|
+
// Callbacks may already match; still usable for Postman.
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
client_id: existing.client_id,
|
|
340
|
+
reused: true
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
try {
|
|
344
|
+
return {
|
|
345
|
+
...createSpaApp(name, callbackUrls),
|
|
346
|
+
reused: false
|
|
347
|
+
};
|
|
348
|
+
} catch (err) {
|
|
349
|
+
if (isAuth0EntityLimitError(err)) {
|
|
350
|
+
throw new Error(formatSpaEntityLimitError(name, apps));
|
|
351
|
+
}
|
|
352
|
+
throw err;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function enableConnectionForClient(connectionName, clientId) {
|
|
356
|
+
const listOut = runAuth0([
|
|
357
|
+
"api",
|
|
358
|
+
"get",
|
|
359
|
+
"connections",
|
|
360
|
+
"--no-input"
|
|
361
|
+
]);
|
|
362
|
+
const connections = parseJsonOutput(listOut);
|
|
363
|
+
const connection = connections.find((c)=>c.name === connectionName);
|
|
364
|
+
if (!connection) {
|
|
365
|
+
throw new Error(`Auth0 connection not found: ${connectionName}`);
|
|
366
|
+
}
|
|
367
|
+
const clientsOut = runAuth0([
|
|
368
|
+
"api",
|
|
369
|
+
"get",
|
|
370
|
+
`connections/${connection.id}/clients`,
|
|
371
|
+
"--no-input"
|
|
372
|
+
]);
|
|
373
|
+
const { clients } = parseJsonOutput(clientsOut);
|
|
374
|
+
if (clients.some((c)=>c.client_id === clientId)) return;
|
|
375
|
+
// Dedicated enabled-clients endpoint (enabled_clients on connection PATCH is deprecated).
|
|
376
|
+
runAuth0([
|
|
377
|
+
"api",
|
|
378
|
+
"patch",
|
|
379
|
+
`connections/${connection.id}/clients`,
|
|
380
|
+
"--data",
|
|
381
|
+
JSON.stringify([
|
|
382
|
+
{
|
|
383
|
+
client_id: clientId,
|
|
384
|
+
status: true
|
|
385
|
+
}
|
|
386
|
+
]),
|
|
387
|
+
"--no-input"
|
|
388
|
+
]);
|
|
389
|
+
}
|
|
390
|
+
function generateAdminPassword() {
|
|
391
|
+
return `${(0, _nodecrypto.randomBytes)(12).toString("base64url")}aA1!`;
|
|
392
|
+
}
|
|
393
|
+
function isUserAlreadyExistsError(err) {
|
|
394
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
395
|
+
return /already exists|user exists|Conflict|409/i.test(text);
|
|
396
|
+
}
|
|
397
|
+
function findUserByEmail(email) {
|
|
398
|
+
const out = runAuth0([
|
|
399
|
+
"api",
|
|
400
|
+
"get",
|
|
401
|
+
`users-by-email?email=${encodeURIComponent(email)}`,
|
|
402
|
+
"--no-input"
|
|
403
|
+
]);
|
|
404
|
+
const users = parseJsonOutput(out);
|
|
405
|
+
const user = users.find((u)=>u.user_id && u.email);
|
|
406
|
+
if (!user?.user_id || !user.email) return null;
|
|
407
|
+
return {
|
|
408
|
+
user_id: user.user_id,
|
|
409
|
+
email: user.email
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function updateUserPassword(userId, password) {
|
|
413
|
+
runAuth0([
|
|
414
|
+
"api",
|
|
415
|
+
"patch",
|
|
416
|
+
`users/${encodeURIComponent(userId)}`,
|
|
417
|
+
"--data",
|
|
418
|
+
JSON.stringify({
|
|
419
|
+
password,
|
|
420
|
+
connection: DB_CONNECTION_NAME
|
|
421
|
+
}),
|
|
422
|
+
"--no-input"
|
|
423
|
+
]);
|
|
424
|
+
}
|
|
425
|
+
function createAdminDatabaseUser(input) {
|
|
426
|
+
const body = {
|
|
427
|
+
email: input.email,
|
|
428
|
+
connection: DB_CONNECTION_NAME,
|
|
429
|
+
password: input.password,
|
|
430
|
+
name: input.username,
|
|
431
|
+
email_verified: true,
|
|
432
|
+
verify_email: false,
|
|
433
|
+
app_metadata: {
|
|
434
|
+
roles: [
|
|
435
|
+
"admin"
|
|
436
|
+
]
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
try {
|
|
440
|
+
const out = runAuth0([
|
|
441
|
+
"api",
|
|
442
|
+
"post",
|
|
443
|
+
"users",
|
|
444
|
+
"--data",
|
|
445
|
+
JSON.stringify(body),
|
|
446
|
+
"--no-input"
|
|
447
|
+
]);
|
|
448
|
+
const user = parseJsonOutput(out);
|
|
449
|
+
if (!user.user_id || !user.email) {
|
|
450
|
+
throw new Error(`Auth0 create user response missing user_id/email. stdout: ${out.slice(0, 300)}`);
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
user_id: user.user_id,
|
|
454
|
+
email: user.email,
|
|
455
|
+
password: input.password,
|
|
456
|
+
username: input.username
|
|
457
|
+
};
|
|
458
|
+
} catch (err) {
|
|
459
|
+
if (!isUserAlreadyExistsError(err)) throw err;
|
|
460
|
+
const existing = findUserByEmail(input.email);
|
|
461
|
+
if (!existing) {
|
|
462
|
+
throw new Error(`Auth0 user already exists for ${input.email}, but lookup by email returned no user.`);
|
|
463
|
+
}
|
|
464
|
+
updateUserPassword(existing.user_id, input.password);
|
|
465
|
+
return {
|
|
466
|
+
user_id: existing.user_id,
|
|
467
|
+
email: existing.email,
|
|
468
|
+
password: input.password,
|
|
469
|
+
username: input.username
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "formatScaffoldedFiles", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return formatScaffoldedFiles;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _nodechild_process = require("node:child_process");
|
|
12
|
+
function formatScaffoldedFiles(targetDir, paths = [
|
|
13
|
+
"."
|
|
14
|
+
]) {
|
|
15
|
+
process.stdout.write("\n Formatting scaffolded files with Biome...");
|
|
16
|
+
let result = (0, _nodechild_process.spawnSync)("biome", [
|
|
17
|
+
"check",
|
|
18
|
+
"--write",
|
|
19
|
+
...paths
|
|
20
|
+
], {
|
|
21
|
+
cwd: targetDir,
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
stdio: "pipe"
|
|
24
|
+
});
|
|
25
|
+
if (result.error && result.error.code === "ENOENT") {
|
|
26
|
+
result = (0, _nodechild_process.spawnSync)("npx", [
|
|
27
|
+
"--yes",
|
|
28
|
+
"@biomejs/biome",
|
|
29
|
+
"check",
|
|
30
|
+
"--write",
|
|
31
|
+
...paths
|
|
32
|
+
], {
|
|
33
|
+
cwd: targetDir,
|
|
34
|
+
encoding: "utf8",
|
|
35
|
+
stdio: "pipe"
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (result.status === 0) {
|
|
39
|
+
process.stdout.write(" done.\n");
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const detail = (result.stderr || result.stdout || result.error?.message || "").trim();
|
|
43
|
+
process.stdout.write(" failed.\n");
|
|
44
|
+
if (detail) {
|
|
45
|
+
console.error(` ✗ Biome: ${detail.slice(0, 400)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|