@decohere/create 0.0.1-dev.48 → 0.0.1-dev.5

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.
Files changed (127) hide show
  1. package/commonjs/src/cli.js +9 -3
  2. package/commonjs/src/scaffold.js +48 -0
  3. package/commonjs/src/templates.js +64 -0
  4. package/es6/src/cli.js +9 -3
  5. package/es6/src/scaffold.js +38 -0
  6. package/es6/src/templates.js +40 -0
  7. package/package.json +3 -8
  8. package/types/src/scaffold.d.ts +4 -0
  9. package/types/src/templates.d.ts +4 -0
  10. package/commonjs/src/domain/prompt.js +0 -64
  11. package/commonjs/src/models/compose.model.js +0 -138
  12. package/commonjs/src/models/config-yaml.model.js +0 -88
  13. package/commonjs/src/models/const.js +0 -31
  14. package/commonjs/src/models/dev-container.model.js +0 -100
  15. package/commonjs/src/models/docker-image.model.js +0 -221
  16. package/commonjs/src/models/env-file.model.js +0 -47
  17. package/commonjs/src/models/gitignore.model.js +0 -31
  18. package/commonjs/src/models/launch-json.model.js +0 -74
  19. package/commonjs/src/models/package-json.model.js +0 -133
  20. package/commonjs/src/models/project.model.js +0 -134
  21. package/commonjs/src/models/source-file.js +0 -6
  22. package/commonjs/src/models/tsconfig.model.js +0 -34
  23. package/commonjs/src/models/vscode-settings.model.js +0 -31
  24. package/commonjs/src/program.js +0 -135
  25. package/commonjs/src/resolve-target-dir.js +0 -19
  26. package/commonjs/src/runner.js +0 -144
  27. package/commonjs/src/services/scaffold.service.js +0 -62
  28. package/commonjs/src/version.js +0 -50
  29. package/commonjs/src/webapi/api-name.js +0 -95
  30. package/commonjs/src/webapi/const.js +0 -50
  31. package/commonjs/src/webapi/create-api.js +0 -285
  32. package/commonjs/src/webapi/features/auth.feature.js +0 -463
  33. package/commonjs/src/webapi/features/auth0-cli.js +0 -406
  34. package/commonjs/src/webapi/features/biome-format.js +0 -49
  35. package/commonjs/src/webapi/features/database.feature.js +0 -273
  36. package/commonjs/src/webapi/features/finalize.feature.js +0 -91
  37. package/commonjs/src/webapi/features/postman.feature.js +0 -319
  38. package/commonjs/src/webapi/models/api-package-json.model.js +0 -63
  39. package/commonjs/src/webapi/models/auth-config.model.js +0 -26
  40. package/commonjs/src/webapi/models/controller-source-file.model.js +0 -188
  41. package/commonjs/src/webapi/models/github-ci.model.js +0 -193
  42. package/commonjs/src/webapi/models/main-source-file.model.js +0 -165
  43. package/commonjs/src/webapi/models/production-dockerfile.model.js +0 -138
  44. package/commonjs/src/webapi/models/sample-files.model.js +0 -60
  45. package/commonjs/src/webapi/models/webapi-image.model.js +0 -22
  46. package/commonjs/src/webapi/postman/hello-openapi.js +0 -175
  47. package/commonjs/src/webapi/postman/local-view.js +0 -184
  48. package/commonjs/src/webapi/postman/openapi-to-postman.js +0 -202
  49. package/es6/src/domain/prompt.js +0 -43
  50. package/es6/src/models/compose.model.js +0 -132
  51. package/es6/src/models/config-yaml.model.js +0 -76
  52. package/es6/src/models/const.js +0 -21
  53. package/es6/src/models/dev-container.model.js +0 -90
  54. package/es6/src/models/docker-image.model.js +0 -185
  55. package/es6/src/models/env-file.model.js +0 -43
  56. package/es6/src/models/gitignore.model.js +0 -21
  57. package/es6/src/models/launch-json.model.js +0 -64
  58. package/es6/src/models/package-json.model.js +0 -129
  59. package/es6/src/models/project.model.js +0 -119
  60. package/es6/src/models/source-file.js +0 -3
  61. package/es6/src/models/tsconfig.model.js +0 -24
  62. package/es6/src/models/vscode-settings.model.js +0 -21
  63. package/es6/src/program.js +0 -76
  64. package/es6/src/resolve-target-dir.js +0 -9
  65. package/es6/src/runner.js +0 -146
  66. package/es6/src/services/scaffold.service.js +0 -52
  67. package/es6/src/version.js +0 -32
  68. package/es6/src/webapi/api-name.js +0 -59
  69. package/es6/src/webapi/const.js +0 -20
  70. package/es6/src/webapi/create-api.js +0 -265
  71. package/es6/src/webapi/features/auth.feature.js +0 -412
  72. package/es6/src/webapi/features/auth0-cli.js +0 -348
  73. package/es6/src/webapi/features/biome-format.js +0 -42
  74. package/es6/src/webapi/features/database.feature.js +0 -263
  75. package/es6/src/webapi/features/finalize.feature.js +0 -81
  76. package/es6/src/webapi/features/postman.feature.js +0 -253
  77. package/es6/src/webapi/models/api-package-json.model.js +0 -58
  78. package/es6/src/webapi/models/auth-config.model.js +0 -22
  79. package/es6/src/webapi/models/controller-source-file.model.js +0 -179
  80. package/es6/src/webapi/models/github-ci.model.js +0 -186
  81. package/es6/src/webapi/models/main-source-file.model.js +0 -161
  82. package/es6/src/webapi/models/production-dockerfile.model.js +0 -126
  83. package/es6/src/webapi/models/sample-files.model.js +0 -42
  84. package/es6/src/webapi/models/webapi-image.model.js +0 -12
  85. package/es6/src/webapi/postman/hello-openapi.js +0 -168
  86. package/es6/src/webapi/postman/local-view.js +0 -169
  87. package/es6/src/webapi/postman/openapi-to-postman.js +0 -179
  88. package/pack-builder-tgz.mjs +0 -177
  89. package/types/src/domain/prompt.d.ts +0 -4
  90. package/types/src/models/compose.model.d.ts +0 -59
  91. package/types/src/models/config-yaml.model.d.ts +0 -27
  92. package/types/src/models/const.d.ts +0 -19
  93. package/types/src/models/dev-container.model.d.ts +0 -33
  94. package/types/src/models/docker-image.model.d.ts +0 -56
  95. package/types/src/models/env-file.model.d.ts +0 -15
  96. package/types/src/models/gitignore.model.d.ts +0 -6
  97. package/types/src/models/launch-json.model.d.ts +0 -7
  98. package/types/src/models/package-json.model.d.ts +0 -32
  99. package/types/src/models/project.model.d.ts +0 -60
  100. package/types/src/models/source-file.d.ts +0 -11
  101. package/types/src/models/tsconfig.model.d.ts +0 -5
  102. package/types/src/models/vscode-settings.model.d.ts +0 -7
  103. package/types/src/program.d.ts +0 -3
  104. package/types/src/resolve-target-dir.d.ts +0 -5
  105. package/types/src/runner.d.ts +0 -15
  106. package/types/src/services/scaffold.service.d.ts +0 -22
  107. package/types/src/version.d.ts +0 -4
  108. package/types/src/webapi/api-name.d.ts +0 -14
  109. package/types/src/webapi/const.d.ts +0 -17
  110. package/types/src/webapi/create-api.d.ts +0 -15
  111. package/types/src/webapi/features/auth.feature.d.ts +0 -10
  112. package/types/src/webapi/features/auth0-cli.d.ts +0 -72
  113. package/types/src/webapi/features/biome-format.d.ts +0 -5
  114. package/types/src/webapi/features/database.feature.d.ts +0 -5
  115. package/types/src/webapi/features/finalize.feature.d.ts +0 -2
  116. package/types/src/webapi/features/postman.feature.d.ts +0 -16
  117. package/types/src/webapi/models/api-package-json.model.d.ts +0 -18
  118. package/types/src/webapi/models/auth-config.model.d.ts +0 -26
  119. package/types/src/webapi/models/controller-source-file.model.d.ts +0 -45
  120. package/types/src/webapi/models/github-ci.model.d.ts +0 -9
  121. package/types/src/webapi/models/main-source-file.model.d.ts +0 -54
  122. package/types/src/webapi/models/production-dockerfile.model.d.ts +0 -20
  123. package/types/src/webapi/models/sample-files.model.d.ts +0 -7
  124. package/types/src/webapi/models/webapi-image.model.d.ts +0 -5
  125. package/types/src/webapi/postman/hello-openapi.d.ts +0 -19
  126. package/types/src/webapi/postman/local-view.d.ts +0 -17
  127. package/types/src/webapi/postman/openapi-to-postman.d.ts +0 -62
@@ -1,348 +0,0 @@
1
- import { execFileSync, spawnSync } from "node:child_process";
2
- import { randomBytes } from "node:crypto";
3
- /** Management API scopes needed for API, SPA, connections, and admin users. */ const REQUIRED_SCOPES = [
4
- "create:clients",
5
- "read:clients",
6
- "update:clients",
7
- "create:resource_servers",
8
- "read:resource_servers",
9
- "update:resource_servers",
10
- "read:connections",
11
- "update:connections",
12
- "create:users",
13
- "read:users",
14
- "update:users"
15
- ].join(",");
16
- /** Hard timeout for any Management API call. Prevents indefinite hangs on token re-auth. */ const API_TIMEOUT_MS = 8_000;
17
- /** Default API scopes matching Hello CASL Authorize decorators. */ export const HELLO_API_SCOPES = [
18
- "read:Hello",
19
- "create:Hello",
20
- "update:Hello",
21
- "delete:Hello"
22
- ];
23
- export const DB_CONNECTION_NAME = "Username-Password-Authentication";
24
- export class Auth0AuthError extends Error {
25
- constructor(message){
26
- super(message);
27
- this.name = "Auth0AuthError";
28
- }
29
- }
30
- /** Returns true if an error or stderr output looks like an expired/missing token. */ function isAuthError(text) {
31
- return text.includes("renew access token") || text.includes("log in") || text.includes("Unauthorized");
32
- }
33
- /** Strip Auth0 CLI banner lines before JSON. */ function parseJsonOutput(stdout) {
34
- const start = stdout.indexOf("{");
35
- const arrayStart = stdout.indexOf("[");
36
- let idx = -1;
37
- if (start === -1) idx = arrayStart;
38
- else if (arrayStart === -1) idx = start;
39
- else idx = Math.min(start, arrayStart);
40
- if (idx < 0) throw new Error(`Expected JSON from auth0 CLI, got: ${stdout.slice(0, 200)}`);
41
- return JSON.parse(stdout.slice(idx));
42
- }
43
- /** Run an auth0 CLI command with a hard timeout. Returns stdout on success, throws on failure. */ function runAuth0(args) {
44
- const result = spawnSync("auth0", args, {
45
- encoding: "utf8",
46
- timeout: API_TIMEOUT_MS,
47
- input: "",
48
- stdio: "pipe"
49
- });
50
- if (result.error) {
51
- const msg = result.error.message;
52
- if (isAuthError(msg) || result.error.code === "ETIMEDOUT") {
53
- throw new Auth0AuthError(msg);
54
- }
55
- throw result.error;
56
- }
57
- if (result.status !== 0) {
58
- const stderr = result.stderr ?? "";
59
- if (isAuthError(stderr)) throw new Auth0AuthError(stderr);
60
- throw new Error(stderr || `auth0 exited with code ${result.status}`);
61
- }
62
- return result.stdout;
63
- }
64
- export function isInstalled() {
65
- try {
66
- execFileSync("auth0", [
67
- "--version"
68
- ], {
69
- stdio: "pipe"
70
- });
71
- return true;
72
- } catch {
73
- return false;
74
- }
75
- }
76
- export function listTenants() {
77
- try {
78
- const out = execFileSync("auth0", [
79
- "tenants",
80
- "list",
81
- "--json"
82
- ], {
83
- encoding: "utf8",
84
- stdio: "pipe"
85
- });
86
- return JSON.parse(out);
87
- } catch {
88
- return [];
89
- }
90
- }
91
- export function login() {
92
- const result = spawnSync("auth0", [
93
- "login",
94
- "--scopes",
95
- REQUIRED_SCOPES
96
- ], {
97
- stdio: "inherit"
98
- });
99
- return result.status === 0;
100
- }
101
- export function listApis() {
102
- try {
103
- const out = runAuth0([
104
- "apis",
105
- "list",
106
- "--json",
107
- "--no-input"
108
- ]);
109
- return parseJsonOutput(out);
110
- } catch (err) {
111
- if (err instanceof Auth0AuthError) throw err;
112
- return [];
113
- }
114
- }
115
- export function createApi(name, identifier, scopes = HELLO_API_SCOPES) {
116
- const out = runAuth0([
117
- "apis",
118
- "create",
119
- "--name",
120
- name,
121
- "--identifier",
122
- identifier,
123
- "--scopes",
124
- scopes.join(","),
125
- // RBAC: only permissions assigned to the user/role appear on the token.
126
- "--enforce-policies",
127
- // Include Auth0 `permissions[]` claim (consumed by sample principalMapper).
128
- "--token-dialect",
129
- "access_token_authz",
130
- "--json",
131
- "--no-input"
132
- ]);
133
- return parseJsonOutput(out);
134
- }
135
- /**
136
- * Replace an API's scopes and enable RBAC policy enforcement.
137
- * Auth0 CLI `--scopes` replaces the full set.
138
- */ export function updateApiScopes(identifier, scopes = HELLO_API_SCOPES) {
139
- runAuth0([
140
- "apis",
141
- "update",
142
- identifier,
143
- "--scopes",
144
- scopes.join(","),
145
- "--enforce-policies",
146
- "--token-dialect",
147
- "access_token_authz",
148
- "--no-input"
149
- ]);
150
- }
151
- export function createSpaApp(name, callbackUrls) {
152
- const callbacks = typeof callbackUrls === "string" ? callbackUrls : callbackUrls.join(",");
153
- const out = runAuth0([
154
- "apps",
155
- "create",
156
- "--name",
157
- name,
158
- "--type",
159
- "spa",
160
- "--callbacks",
161
- callbacks,
162
- "--json",
163
- "--no-input"
164
- ]);
165
- const app = parseJsonOutput(out);
166
- const clientId = app.client_id ?? app.clientId;
167
- if (!clientId) {
168
- throw new Error(`Auth0 create SPA response missing client_id. stdout: ${out.slice(0, 300)}`);
169
- }
170
- return {
171
- client_id: clientId
172
- };
173
- }
174
- export function listApps() {
175
- try {
176
- const out = runAuth0([
177
- "apps",
178
- "list",
179
- "--json",
180
- "--no-input"
181
- ]);
182
- const apps = parseJsonOutput(out);
183
- return apps.map((a)=>({
184
- client_id: a.client_id ?? a.clientId ?? "",
185
- name: a.name ?? ""
186
- })).filter((a)=>a.client_id && a.name);
187
- } catch (err) {
188
- if (err instanceof Auth0AuthError) throw err;
189
- return [];
190
- }
191
- }
192
- export function updateSpaCallbacks(clientId, callbackUrls) {
193
- const callbacks = typeof callbackUrls === "string" ? callbackUrls : callbackUrls.join(",");
194
- runAuth0([
195
- "apps",
196
- "update",
197
- clientId,
198
- "--callbacks",
199
- callbacks,
200
- "--no-input"
201
- ]);
202
- }
203
- /**
204
- * Create a Postman SPA, or reuse an existing app with the same name (re-scaffold).
205
- * Always returns a client_id suitable for Postman auth0ClientId.
206
- */ export function ensureSpaApp(name, callbackUrls) {
207
- const existing = listApps().find((a)=>a.name === name);
208
- if (existing) {
209
- try {
210
- updateSpaCallbacks(existing.client_id, callbackUrls);
211
- } catch {
212
- // Callbacks may already match; still usable for Postman.
213
- }
214
- return {
215
- client_id: existing.client_id,
216
- reused: true
217
- };
218
- }
219
- return {
220
- ...createSpaApp(name, callbackUrls),
221
- reused: false
222
- };
223
- }
224
- /** Enable a database connection for an application (required for username/password login). */ export function enableConnectionForClient(connectionName, clientId) {
225
- const listOut = runAuth0([
226
- "api",
227
- "get",
228
- "connections",
229
- "--no-input"
230
- ]);
231
- const connections = parseJsonOutput(listOut);
232
- const connection = connections.find((c)=>c.name === connectionName);
233
- if (!connection) {
234
- throw new Error(`Auth0 connection not found: ${connectionName}`);
235
- }
236
- const clientsOut = runAuth0([
237
- "api",
238
- "get",
239
- `connections/${connection.id}/clients`,
240
- "--no-input"
241
- ]);
242
- const { clients } = parseJsonOutput(clientsOut);
243
- if (clients.some((c)=>c.client_id === clientId)) return;
244
- // Dedicated enabled-clients endpoint (enabled_clients on connection PATCH is deprecated).
245
- runAuth0([
246
- "api",
247
- "patch",
248
- `connections/${connection.id}/clients`,
249
- "--data",
250
- JSON.stringify([
251
- {
252
- client_id: clientId,
253
- status: true
254
- }
255
- ]),
256
- "--no-input"
257
- ]);
258
- }
259
- /** Strong default password when the scaffolder caller leaves password blank. */ export function generateAdminPassword() {
260
- return `${randomBytes(12).toString("base64url")}aA1!`;
261
- }
262
- function isUserAlreadyExistsError(err) {
263
- const text = err instanceof Error ? err.message : String(err);
264
- return /already exists|user exists|Conflict|409/i.test(text);
265
- }
266
- /** Look up a user by email (Management API users-by-email). */ export function findUserByEmail(email) {
267
- const out = runAuth0([
268
- "api",
269
- "get",
270
- `users-by-email?email=${encodeURIComponent(email)}`,
271
- "--no-input"
272
- ]);
273
- const users = parseJsonOutput(out);
274
- const user = users.find((u)=>u.user_id && u.email);
275
- if (!user?.user_id || !user.email) return null;
276
- return {
277
- user_id: user.user_id,
278
- email: user.email
279
- };
280
- }
281
- /** Reset password so a re-scaffold can write a known password to .env. */ export function updateUserPassword(userId, password) {
282
- runAuth0([
283
- "api",
284
- "patch",
285
- `users/${encodeURIComponent(userId)}`,
286
- "--data",
287
- JSON.stringify({
288
- password,
289
- connection: DB_CONNECTION_NAME
290
- }),
291
- "--no-input"
292
- ]);
293
- }
294
- /**
295
- * Create a DB connection root-admin user for local / Postman login.
296
- * If the user already exists, look them up, reset password to `input.password`,
297
- * and return that identity so callers can still write .env credentials.
298
- */ export function createAdminDatabaseUser(input) {
299
- const body = {
300
- email: input.email,
301
- connection: DB_CONNECTION_NAME,
302
- password: input.password,
303
- name: input.username,
304
- email_verified: true,
305
- verify_email: false,
306
- app_metadata: {
307
- roles: [
308
- "admin"
309
- ]
310
- }
311
- };
312
- try {
313
- const out = runAuth0([
314
- "api",
315
- "post",
316
- "users",
317
- "--data",
318
- JSON.stringify(body),
319
- "--no-input"
320
- ]);
321
- const user = parseJsonOutput(out);
322
- if (!user.user_id || !user.email) {
323
- throw new Error(`Auth0 create user response missing user_id/email. stdout: ${out.slice(0, 300)}`);
324
- }
325
- return {
326
- user_id: user.user_id,
327
- email: user.email,
328
- password: input.password,
329
- username: input.username
330
- };
331
- } catch (err) {
332
- if (!isUserAlreadyExistsError(err)) throw err;
333
- const existing = findUserByEmail(input.email);
334
- if (!existing) {
335
- throw new Error(`Auth0 user already exists for ${input.email}, but lookup by email returned no user.`);
336
- }
337
- updateUserPassword(existing.user_id, input.password);
338
- return {
339
- user_id: existing.user_id,
340
- email: existing.email,
341
- password: input.password,
342
- username: input.username
343
- };
344
- }
345
- }
346
- export { REQUIRED_SCOPES };
347
-
348
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL2ZlYXR1cmVzL2F1dGgwLWNsaS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGVjRmlsZVN5bmMsIHNwYXduU3luYyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5cbi8qKiBNYW5hZ2VtZW50IEFQSSBzY29wZXMgbmVlZGVkIGZvciBBUEksIFNQQSwgY29ubmVjdGlvbnMsIGFuZCBhZG1pbiB1c2Vycy4gKi9cbmNvbnN0IFJFUVVJUkVEX1NDT1BFUyA9IFtcblx0XCJjcmVhdGU6Y2xpZW50c1wiLFxuXHRcInJlYWQ6Y2xpZW50c1wiLFxuXHRcInVwZGF0ZTpjbGllbnRzXCIsXG5cdFwiY3JlYXRlOnJlc291cmNlX3NlcnZlcnNcIixcblx0XCJyZWFkOnJlc291cmNlX3NlcnZlcnNcIixcblx0XCJ1cGRhdGU6cmVzb3VyY2Vfc2VydmVyc1wiLFxuXHRcInJlYWQ6Y29ubmVjdGlvbnNcIixcblx0XCJ1cGRhdGU6Y29ubmVjdGlvbnNcIixcblx0XCJjcmVhdGU6dXNlcnNcIixcblx0XCJyZWFkOnVzZXJzXCIsXG5cdFwidXBkYXRlOnVzZXJzXCIsXG5dLmpvaW4oXCIsXCIpO1xuXG4vKiogSGFyZCB0aW1lb3V0IGZvciBhbnkgTWFuYWdlbWVudCBBUEkgY2FsbC4gUHJldmVudHMgaW5kZWZpbml0ZSBoYW5ncyBvbiB0b2tlbiByZS1hdXRoLiAqL1xuY29uc3QgQVBJX1RJTUVPVVRfTVMgPSA4XzAwMDtcblxuLyoqIERlZmF1bHQgQVBJIHNjb3BlcyBtYXRjaGluZyBIZWxsbyBDQVNMIEF1dGhvcml6ZSBkZWNvcmF0b3JzLiAqL1xuZXhwb3J0IGNvbnN0IEhFTExPX0FQSV9TQ09QRVMgPSBbXG5cdFwicmVhZDpIZWxsb1wiLFxuXHRcImNyZWF0ZTpIZWxsb1wiLFxuXHRcInVwZGF0ZTpIZWxsb1wiLFxuXHRcImRlbGV0ZTpIZWxsb1wiLFxuXSBhcyBjb25zdDtcblxuZXhwb3J0IGNvbnN0IERCX0NPTk5FQ1RJT05fTkFNRSA9IFwiVXNlcm5hbWUtUGFzc3dvcmQtQXV0aGVudGljYXRpb25cIjtcblxuZXhwb3J0IGNsYXNzIEF1dGgwQXV0aEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5uYW1lID0gXCJBdXRoMEF1dGhFcnJvclwiO1xuXHR9XG59XG5cbi8qKiBSZXR1cm5zIHRydWUgaWYgYW4gZXJyb3Igb3Igc3RkZXJyIG91dHB1dCBsb29rcyBsaWtlIGFuIGV4cGlyZWQvbWlzc2luZyB0b2tlbi4gKi9cbmZ1bmN0aW9uIGlzQXV0aEVycm9yKHRleHQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRyZXR1cm4gKFxuXHRcdHRleHQuaW5jbHVkZXMoXCJyZW5ldyBhY2Nlc3MgdG9rZW5cIikgfHxcblx0XHR0ZXh0LmluY2x1ZGVzKFwibG9nIGluXCIpIHx8XG5cdFx0dGV4dC5pbmNsdWRlcyhcIlVuYXV0aG9yaXplZFwiKVxuXHQpO1xufVxuXG4vKiogU3RyaXAgQXV0aDAgQ0xJIGJhbm5lciBsaW5lcyBiZWZvcmUgSlNPTi4gKi9cbmZ1bmN0aW9uIHBhcnNlSnNvbk91dHB1dDxUPihzdGRvdXQ6IHN0cmluZyk6IFQge1xuXHRjb25zdCBzdGFydCA9IHN0ZG91dC5pbmRleE9mKFwie1wiKTtcblx0Y29uc3QgYXJyYXlTdGFydCA9IHN0ZG91dC5pbmRleE9mKFwiW1wiKTtcblx0bGV0IGlkeCA9IC0xO1xuXHRpZiAoc3RhcnQgPT09IC0xKSBpZHggPSBhcnJheVN0YXJ0O1xuXHRlbHNlIGlmIChhcnJheVN0YXJ0ID09PSAtMSkgaWR4ID0gc3RhcnQ7XG5cdGVsc2UgaWR4ID0gTWF0aC5taW4oc3RhcnQsIGFycmF5U3RhcnQpO1xuXHRpZiAoaWR4IDwgMCkgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBKU09OIGZyb20gYXV0aDAgQ0xJLCBnb3Q6ICR7c3Rkb3V0LnNsaWNlKDAsIDIwMCl9YCk7XG5cdHJldHVybiBKU09OLnBhcnNlKHN0ZG91dC5zbGljZShpZHgpKSBhcyBUO1xufVxuXG4vKiogUnVuIGFuIGF1dGgwIENMSSBjb21tYW5kIHdpdGggYSBoYXJkIHRpbWVvdXQuIFJldHVybnMgc3Rkb3V0IG9uIHN1Y2Nlc3MsIHRocm93cyBvbiBmYWlsdXJlLiAqL1xuZnVuY3Rpb24gcnVuQXV0aDAoYXJnczogc3RyaW5nW10pOiBzdHJpbmcge1xuXHRjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJhdXRoMFwiLCBhcmdzLCB7XG5cdFx0ZW5jb2Rpbmc6IFwidXRmOFwiLFxuXHRcdHRpbWVvdXQ6IEFQSV9USU1FT1VUX01TLFxuXHRcdGlucHV0OiBcIlwiLFxuXHRcdHN0ZGlvOiBcInBpcGVcIixcblx0fSk7XG5cblx0aWYgKHJlc3VsdC5lcnJvcikge1xuXHRcdGNvbnN0IG1zZyA9IHJlc3VsdC5lcnJvci5tZXNzYWdlO1xuXHRcdGlmIChpc0F1dGhFcnJvcihtc2cpIHx8IChyZXN1bHQuZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSBcIkVUSU1FRE9VVFwiKSB7XG5cdFx0XHR0aHJvdyBuZXcgQXV0aDBBdXRoRXJyb3IobXNnKTtcblx0XHR9XG5cdFx0dGhyb3cgcmVzdWx0LmVycm9yO1xuXHR9XG5cblx0aWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcblx0XHRjb25zdCBzdGRlcnIgPSByZXN1bHQuc3RkZXJyID8/IFwiXCI7XG5cdFx0aWYgKGlzQXV0aEVycm9yKHN0ZGVycikpIHRocm93IG5ldyBBdXRoMEF1dGhFcnJvcihzdGRlcnIpO1xuXHRcdHRocm93IG5ldyBFcnJvcihzdGRlcnIgfHwgYGF1dGgwIGV4aXRlZCB3aXRoIGNvZGUgJHtyZXN1bHQuc3RhdHVzfWApO1xuXHR9XG5cblx0cmV0dXJuIHJlc3VsdC5zdGRvdXQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aDBUZW5hbnQge1xuXHRuYW1lOiBzdHJpbmc7XG5cdGFjdGl2ZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0luc3RhbGxlZCgpOiBib29sZWFuIHtcblx0dHJ5IHtcblx0XHRleGVjRmlsZVN5bmMoXCJhdXRoMFwiLCBbXCItLXZlcnNpb25cIl0sIHsgc3RkaW86IFwicGlwZVwiIH0pO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RUZW5hbnRzKCk6IEF1dGgwVGVuYW50W10ge1xuXHR0cnkge1xuXHRcdGNvbnN0IG91dCA9IGV4ZWNGaWxlU3luYyhcImF1dGgwXCIsIFtcInRlbmFudHNcIiwgXCJsaXN0XCIsIFwiLS1qc29uXCJdLCB7XG5cdFx0XHRlbmNvZGluZzogXCJ1dGY4XCIsXG5cdFx0XHRzdGRpbzogXCJwaXBlXCIsXG5cdFx0fSk7XG5cdFx0cmV0dXJuIEpTT04ucGFyc2Uob3V0KSBhcyBBdXRoMFRlbmFudFtdO1xuXHR9IGNhdGNoIHtcblx0XHRyZXR1cm4gW107XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ2luKCk6IGJvb2xlYW4ge1xuXHRjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJhdXRoMFwiLCBbXCJsb2dpblwiLCBcIi0tc2NvcGVzXCIsIFJFUVVJUkVEX1NDT1BFU10sIHtcblx0XHRzdGRpbzogXCJpbmhlcml0XCIsXG5cdH0pO1xuXHRyZXR1cm4gcmVzdWx0LnN0YXR1cyA9PT0gMDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RBcGlzKCk6IEFycmF5PHsgaWRlbnRpZmllcjogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfT4ge1xuXHR0cnkge1xuXHRcdGNvbnN0IG91dCA9IHJ1bkF1dGgwKFtcImFwaXNcIiwgXCJsaXN0XCIsIFwiLS1qc29uXCIsIFwiLS1uby1pbnB1dFwiXSk7XG5cdFx0cmV0dXJuIHBhcnNlSnNvbk91dHB1dChvdXQpO1xuXHR9IGNhdGNoIChlcnIpIHtcblx0XHRpZiAoZXJyIGluc3RhbmNlb2YgQXV0aDBBdXRoRXJyb3IpIHRocm93IGVycjtcblx0XHRyZXR1cm4gW107XG5cdH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFwaShcblx0bmFtZTogc3RyaW5nLFxuXHRpZGVudGlmaWVyOiBzdHJpbmcsXG5cdHNjb3BlczogcmVhZG9ubHkgc3RyaW5nW10gPSBIRUxMT19BUElfU0NPUEVTLFxuKTogeyBpZGVudGlmaWVyOiBzdHJpbmcgfSB7XG5cdGNvbnN0IG91dCA9IHJ1bkF1dGgwKFtcblx0XHRcImFwaXNcIixcblx0XHRcImNyZWF0ZVwiLFxuXHRcdFwiLS1uYW1lXCIsXG5cdFx0bmFtZSxcblx0XHRcIi0taWRlbnRpZmllclwiLFxuXHRcdGlkZW50aWZpZXIsXG5cdFx0XCItLXNjb3Blc1wiLFxuXHRcdHNjb3Blcy5qb2luKFwiLFwiKSxcblx0XHQvLyBSQkFDOiBvbmx5IHBlcm1pc3Npb25zIGFzc2lnbmVkIHRvIHRoZSB1c2VyL3JvbGUgYXBwZWFyIG9uIHRoZSB0b2tlbi5cblx0XHRcIi0tZW5mb3JjZS1wb2xpY2llc1wiLFxuXHRcdC8vIEluY2x1ZGUgQXV0aDAgYHBlcm1pc3Npb25zW11gIGNsYWltIChjb25zdW1lZCBieSBzYW1wbGUgcHJpbmNpcGFsTWFwcGVyKS5cblx0XHRcIi0tdG9rZW4tZGlhbGVjdFwiLFxuXHRcdFwiYWNjZXNzX3Rva2VuX2F1dGh6XCIsXG5cdFx0XCItLWpzb25cIixcblx0XHRcIi0tbm8taW5wdXRcIixcblx0XSk7XG5cdHJldHVybiBwYXJzZUpzb25PdXRwdXQob3V0KTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlIGFuIEFQSSdzIHNjb3BlcyBhbmQgZW5hYmxlIFJCQUMgcG9saWN5IGVuZm9yY2VtZW50LlxuICogQXV0aDAgQ0xJIGAtLXNjb3Blc2AgcmVwbGFjZXMgdGhlIGZ1bGwgc2V0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQXBpU2NvcGVzKFxuXHRpZGVudGlmaWVyOiBzdHJpbmcsXG5cdHNjb3BlczogcmVhZG9ubHkgc3RyaW5nW10gPSBIRUxMT19BUElfU0NPUEVTLFxuKTogdm9pZCB7XG5cdHJ1bkF1dGgwKFtcblx0XHRcImFwaXNcIixcblx0XHRcInVwZGF0ZVwiLFxuXHRcdGlkZW50aWZpZXIsXG5cdFx0XCItLXNjb3Blc1wiLFxuXHRcdHNjb3Blcy5qb2luKFwiLFwiKSxcblx0XHRcIi0tZW5mb3JjZS1wb2xpY2llc1wiLFxuXHRcdFwiLS10b2tlbi1kaWFsZWN0XCIsXG5cdFx0XCJhY2Nlc3NfdG9rZW5fYXV0aHpcIixcblx0XHRcIi0tbm8taW5wdXRcIixcblx0XSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTcGFBcHAoXG5cdG5hbWU6IHN0cmluZyxcblx0Y2FsbGJhY2tVcmxzOiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSxcbik6IHsgY2xpZW50X2lkOiBzdHJpbmcgfSB7XG5cdGNvbnN0IGNhbGxiYWNrcyA9IHR5cGVvZiBjYWxsYmFja1VybHMgPT09IFwic3RyaW5nXCIgPyBjYWxsYmFja1VybHMgOiBjYWxsYmFja1VybHMuam9pbihcIixcIik7XG5cdGNvbnN0IG91dCA9IHJ1bkF1dGgwKFtcblx0XHRcImFwcHNcIixcblx0XHRcImNyZWF0ZVwiLFxuXHRcdFwiLS1uYW1lXCIsXG5cdFx0bmFtZSxcblx0XHRcIi0tdHlwZVwiLFxuXHRcdFwic3BhXCIsXG5cdFx0XCItLWNhbGxiYWNrc1wiLFxuXHRcdGNhbGxiYWNrcyxcblx0XHRcIi0tanNvblwiLFxuXHRcdFwiLS1uby1pbnB1dFwiLFxuXHRdKTtcblx0Y29uc3QgYXBwID0gcGFyc2VKc29uT3V0cHV0PHsgY2xpZW50X2lkPzogc3RyaW5nOyBjbGllbnRJZD86IHN0cmluZyB9PihvdXQpO1xuXHRjb25zdCBjbGllbnRJZCA9IGFwcC5jbGllbnRfaWQgPz8gYXBwLmNsaWVudElkO1xuXHRpZiAoIWNsaWVudElkKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0YEF1dGgwIGNyZWF0ZSBTUEEgcmVzcG9uc2UgbWlzc2luZyBjbGllbnRfaWQuIHN0ZG91dDogJHtvdXQuc2xpY2UoMCwgMzAwKX1gLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHsgY2xpZW50X2lkOiBjbGllbnRJZCB9O1xufVxuXG5leHBvcnQgdHlwZSBBdXRoMEFwcCA9IHsgY2xpZW50X2lkOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9O1xuXG5leHBvcnQgZnVuY3Rpb24gbGlzdEFwcHMoKTogQXV0aDBBcHBbXSB7XG5cdHRyeSB7XG5cdFx0Y29uc3Qgb3V0ID0gcnVuQXV0aDAoW1wiYXBwc1wiLCBcImxpc3RcIiwgXCItLWpzb25cIiwgXCItLW5vLWlucHV0XCJdKTtcblx0XHRjb25zdCBhcHBzID1cblx0XHRcdHBhcnNlSnNvbk91dHB1dDxBcnJheTx7IGNsaWVudF9pZD86IHN0cmluZzsgY2xpZW50SWQ/OiBzdHJpbmc7IG5hbWU/OiBzdHJpbmcgfT4+KG91dCk7XG5cdFx0cmV0dXJuIGFwcHNcblx0XHRcdC5tYXAoKGEpID0+ICh7XG5cdFx0XHRcdGNsaWVudF9pZDogYS5jbGllbnRfaWQgPz8gYS5jbGllbnRJZCA/PyBcIlwiLFxuXHRcdFx0XHRuYW1lOiBhLm5hbWUgPz8gXCJcIixcblx0XHRcdH0pKVxuXHRcdFx0LmZpbHRlcigoYSkgPT4gYS5jbGllbnRfaWQgJiYgYS5uYW1lKTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0aWYgKGVyciBpbnN0YW5jZW9mIEF1dGgwQXV0aEVycm9yKSB0aHJvdyBlcnI7XG5cdFx0cmV0dXJuIFtdO1xuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTcGFDYWxsYmFja3MoXG5cdGNsaWVudElkOiBzdHJpbmcsXG5cdGNhbGxiYWNrVXJsczogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10sXG4pOiB2b2lkIHtcblx0Y29uc3QgY2FsbGJhY2tzID0gdHlwZW9mIGNhbGxiYWNrVXJscyA9PT0gXCJzdHJpbmdcIiA/IGNhbGxiYWNrVXJscyA6IGNhbGxiYWNrVXJscy5qb2luKFwiLFwiKTtcblx0cnVuQXV0aDAoW1wiYXBwc1wiLCBcInVwZGF0ZVwiLCBjbGllbnRJZCwgXCItLWNhbGxiYWNrc1wiLCBjYWxsYmFja3MsIFwiLS1uby1pbnB1dFwiXSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgUG9zdG1hbiBTUEEsIG9yIHJldXNlIGFuIGV4aXN0aW5nIGFwcCB3aXRoIHRoZSBzYW1lIG5hbWUgKHJlLXNjYWZmb2xkKS5cbiAqIEFsd2F5cyByZXR1cm5zIGEgY2xpZW50X2lkIHN1aXRhYmxlIGZvciBQb3N0bWFuIGF1dGgwQ2xpZW50SWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVTcGFBcHAoXG5cdG5hbWU6IHN0cmluZyxcblx0Y2FsbGJhY2tVcmxzOiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXSxcbik6IHsgY2xpZW50X2lkOiBzdHJpbmc7IHJldXNlZDogYm9vbGVhbiB9IHtcblx0Y29uc3QgZXhpc3RpbmcgPSBsaXN0QXBwcygpLmZpbmQoKGEpID0+IGEubmFtZSA9PT0gbmFtZSk7XG5cdGlmIChleGlzdGluZykge1xuXHRcdHRyeSB7XG5cdFx0XHR1cGRhdGVTcGFDYWxsYmFja3MoZXhpc3RpbmcuY2xpZW50X2lkLCBjYWxsYmFja1VybHMpO1xuXHRcdH0gY2F0Y2gge1xuXHRcdFx0Ly8gQ2FsbGJhY2tzIG1heSBhbHJlYWR5IG1hdGNoOyBzdGlsbCB1c2FibGUgZm9yIFBvc3RtYW4uXG5cdFx0fVxuXHRcdHJldHVybiB7IGNsaWVudF9pZDogZXhpc3RpbmcuY2xpZW50X2lkLCByZXVzZWQ6IHRydWUgfTtcblx0fVxuXHRyZXR1cm4geyAuLi5jcmVhdGVTcGFBcHAobmFtZSwgY2FsbGJhY2tVcmxzKSwgcmV1c2VkOiBmYWxzZSB9O1xufVxuXG50eXBlIEF1dGgwQ29ubmVjdGlvbiA9IHsgaWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nOyBzdHJhdGVneTogc3RyaW5nIH07XG5cbi8qKiBFbmFibGUgYSBkYXRhYmFzZSBjb25uZWN0aW9uIGZvciBhbiBhcHBsaWNhdGlvbiAocmVxdWlyZWQgZm9yIHVzZXJuYW1lL3Bhc3N3b3JkIGxvZ2luKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmFibGVDb25uZWN0aW9uRm9yQ2xpZW50KGNvbm5lY3Rpb25OYW1lOiBzdHJpbmcsIGNsaWVudElkOiBzdHJpbmcpOiB2b2lkIHtcblx0Y29uc3QgbGlzdE91dCA9IHJ1bkF1dGgwKFtcImFwaVwiLCBcImdldFwiLCBcImNvbm5lY3Rpb25zXCIsIFwiLS1uby1pbnB1dFwiXSk7XG5cdGNvbnN0IGNvbm5lY3Rpb25zID0gcGFyc2VKc29uT3V0cHV0PEF1dGgwQ29ubmVjdGlvbltdPihsaXN0T3V0KTtcblx0Y29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25zLmZpbmQoKGMpID0+IGMubmFtZSA9PT0gY29ubmVjdGlvbk5hbWUpO1xuXHRpZiAoIWNvbm5lY3Rpb24pIHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoYEF1dGgwIGNvbm5lY3Rpb24gbm90IGZvdW5kOiAke2Nvbm5lY3Rpb25OYW1lfWApO1xuXHR9XG5cblx0Y29uc3QgY2xpZW50c091dCA9IHJ1bkF1dGgwKFtcblx0XHRcImFwaVwiLFxuXHRcdFwiZ2V0XCIsXG5cdFx0YGNvbm5lY3Rpb25zLyR7Y29ubmVjdGlvbi5pZH0vY2xpZW50c2AsXG5cdFx0XCItLW5vLWlucHV0XCIsXG5cdF0pO1xuXHRjb25zdCB7IGNsaWVudHMgfSA9IHBhcnNlSnNvbk91dHB1dDx7IGNsaWVudHM6IEFycmF5PHsgY2xpZW50X2lkOiBzdHJpbmcgfT4gfT4oY2xpZW50c091dCk7XG5cdGlmIChjbGllbnRzLnNvbWUoKGMpID0+IGMuY2xpZW50X2lkID09PSBjbGllbnRJZCkpIHJldHVybjtcblxuXHQvLyBEZWRpY2F0ZWQgZW5hYmxlZC1jbGllbnRzIGVuZHBvaW50IChlbmFibGVkX2NsaWVudHMgb24gY29ubmVjdGlvbiBQQVRDSCBpcyBkZXByZWNhdGVkKS5cblx0cnVuQXV0aDAoW1xuXHRcdFwiYXBpXCIsXG5cdFx0XCJwYXRjaFwiLFxuXHRcdGBjb25uZWN0aW9ucy8ke2Nvbm5lY3Rpb24uaWR9L2NsaWVudHNgLFxuXHRcdFwiLS1kYXRhXCIsXG5cdFx0SlNPTi5zdHJpbmdpZnkoW3sgY2xpZW50X2lkOiBjbGllbnRJZCwgc3RhdHVzOiB0cnVlIH1dKSxcblx0XHRcIi0tbm8taW5wdXRcIixcblx0XSk7XG59XG5cbmV4cG9ydCB0eXBlIEFkbWluRGF0YWJhc2VVc2VyID0ge1xuXHR1c2VyX2lkOiBzdHJpbmc7XG5cdGVtYWlsOiBzdHJpbmc7XG5cdHBhc3N3b3JkOiBzdHJpbmc7XG5cdHVzZXJuYW1lOiBzdHJpbmc7XG59O1xuXG4vKiogU3Ryb25nIGRlZmF1bHQgcGFzc3dvcmQgd2hlbiB0aGUgc2NhZmZvbGRlciBjYWxsZXIgbGVhdmVzIHBhc3N3b3JkIGJsYW5rLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQWRtaW5QYXNzd29yZCgpOiBzdHJpbmcge1xuXHRyZXR1cm4gYCR7cmFuZG9tQnl0ZXMoMTIpLnRvU3RyaW5nKFwiYmFzZTY0dXJsXCIpfWFBMSFgO1xufVxuXG5mdW5jdGlvbiBpc1VzZXJBbHJlYWR5RXhpc3RzRXJyb3IoZXJyOiB1bmtub3duKTogYm9vbGVhbiB7XG5cdGNvbnN0IHRleHQgPSBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycik7XG5cdHJldHVybiAvYWxyZWFkeSBleGlzdHN8dXNlciBleGlzdHN8Q29uZmxpY3R8NDA5L2kudGVzdCh0ZXh0KTtcbn1cblxuLyoqIExvb2sgdXAgYSB1c2VyIGJ5IGVtYWlsIChNYW5hZ2VtZW50IEFQSSB1c2Vycy1ieS1lbWFpbCkuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFVzZXJCeUVtYWlsKGVtYWlsOiBzdHJpbmcpOiB7IHVzZXJfaWQ6IHN0cmluZzsgZW1haWw6IHN0cmluZyB9IHwgbnVsbCB7XG5cdGNvbnN0IG91dCA9IHJ1bkF1dGgwKFtcblx0XHRcImFwaVwiLFxuXHRcdFwiZ2V0XCIsXG5cdFx0YHVzZXJzLWJ5LWVtYWlsP2VtYWlsPSR7ZW5jb2RlVVJJQ29tcG9uZW50KGVtYWlsKX1gLFxuXHRcdFwiLS1uby1pbnB1dFwiLFxuXHRdKTtcblx0Y29uc3QgdXNlcnMgPSBwYXJzZUpzb25PdXRwdXQ8QXJyYXk8eyB1c2VyX2lkPzogc3RyaW5nOyBlbWFpbD86IHN0cmluZyB9Pj4ob3V0KTtcblx0Y29uc3QgdXNlciA9IHVzZXJzLmZpbmQoKHUpID0+IHUudXNlcl9pZCAmJiB1LmVtYWlsKTtcblx0aWYgKCF1c2VyPy51c2VyX2lkIHx8ICF1c2VyLmVtYWlsKSByZXR1cm4gbnVsbDtcblx0cmV0dXJuIHsgdXNlcl9pZDogdXNlci51c2VyX2lkLCBlbWFpbDogdXNlci5lbWFpbCB9O1xufVxuXG4vKiogUmVzZXQgcGFzc3dvcmQgc28gYSByZS1zY2FmZm9sZCBjYW4gd3JpdGUgYSBrbm93biBwYXNzd29yZCB0byAuZW52LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VySWQ6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IHZvaWQge1xuXHRydW5BdXRoMChbXG5cdFx0XCJhcGlcIixcblx0XHRcInBhdGNoXCIsXG5cdFx0YHVzZXJzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KHVzZXJJZCl9YCxcblx0XHRcIi0tZGF0YVwiLFxuXHRcdEpTT04uc3RyaW5naWZ5KHsgcGFzc3dvcmQsIGNvbm5lY3Rpb246IERCX0NPTk5FQ1RJT05fTkFNRSB9KSxcblx0XHRcIi0tbm8taW5wdXRcIixcblx0XSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgREIgY29ubmVjdGlvbiByb290LWFkbWluIHVzZXIgZm9yIGxvY2FsIC8gUG9zdG1hbiBsb2dpbi5cbiAqIElmIHRoZSB1c2VyIGFscmVhZHkgZXhpc3RzLCBsb29rIHRoZW0gdXAsIHJlc2V0IHBhc3N3b3JkIHRvIGBpbnB1dC5wYXNzd29yZGAsXG4gKiBhbmQgcmV0dXJuIHRoYXQgaWRlbnRpdHkgc28gY2FsbGVycyBjYW4gc3RpbGwgd3JpdGUgLmVudiBjcmVkZW50aWFscy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFkbWluRGF0YWJhc2VVc2VyKGlucHV0OiB7XG5cdGVtYWlsOiBzdHJpbmc7XG5cdHBhc3N3b3JkOiBzdHJpbmc7XG5cdHVzZXJuYW1lOiBzdHJpbmc7XG59KTogQWRtaW5EYXRhYmFzZVVzZXIge1xuXHRjb25zdCBib2R5ID0ge1xuXHRcdGVtYWlsOiBpbnB1dC5lbWFpbCxcblx0XHRjb25uZWN0aW9uOiBEQl9DT05ORUNUSU9OX05BTUUsXG5cdFx0cGFzc3dvcmQ6IGlucHV0LnBhc3N3b3JkLFxuXHRcdG5hbWU6IGlucHV0LnVzZXJuYW1lLFxuXHRcdGVtYWlsX3ZlcmlmaWVkOiB0cnVlLFxuXHRcdHZlcmlmeV9lbWFpbDogZmFsc2UsXG5cdFx0YXBwX21ldGFkYXRhOiB7IHJvbGVzOiBbXCJhZG1pblwiXSB9LFxuXHR9O1xuXG5cdHRyeSB7XG5cdFx0Y29uc3Qgb3V0ID0gcnVuQXV0aDAoW1xuXHRcdFx0XCJhcGlcIixcblx0XHRcdFwicG9zdFwiLFxuXHRcdFx0XCJ1c2Vyc1wiLFxuXHRcdFx0XCItLWRhdGFcIixcblx0XHRcdEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuXHRcdFx0XCItLW5vLWlucHV0XCIsXG5cdFx0XSk7XG5cdFx0Y29uc3QgdXNlciA9IHBhcnNlSnNvbk91dHB1dDx7IHVzZXJfaWQ/OiBzdHJpbmc7IGVtYWlsPzogc3RyaW5nIH0+KG91dCk7XG5cdFx0aWYgKCF1c2VyLnVzZXJfaWQgfHwgIXVzZXIuZW1haWwpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YEF1dGgwIGNyZWF0ZSB1c2VyIHJlc3BvbnNlIG1pc3NpbmcgdXNlcl9pZC9lbWFpbC4gc3Rkb3V0OiAke291dC5zbGljZSgwLCAzMDApfWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRyZXR1cm4ge1xuXHRcdFx0dXNlcl9pZDogdXNlci51c2VyX2lkLFxuXHRcdFx0ZW1haWw6IHVzZXIuZW1haWwsXG5cdFx0XHRwYXNzd29yZDogaW5wdXQucGFzc3dvcmQsXG5cdFx0XHR1c2VybmFtZTogaW5wdXQudXNlcm5hbWUsXG5cdFx0fTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0aWYgKCFpc1VzZXJBbHJlYWR5RXhpc3RzRXJyb3IoZXJyKSkgdGhyb3cgZXJyO1xuXG5cdFx0Y29uc3QgZXhpc3RpbmcgPSBmaW5kVXNlckJ5RW1haWwoaW5wdXQuZW1haWwpO1xuXHRcdGlmICghZXhpc3RpbmcpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0YEF1dGgwIHVzZXIgYWxyZWFkeSBleGlzdHMgZm9yICR7aW5wdXQuZW1haWx9LCBidXQgbG9va3VwIGJ5IGVtYWlsIHJldHVybmVkIG5vIHVzZXIuYCxcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0dXBkYXRlVXNlclBhc3N3b3JkKGV4aXN0aW5nLnVzZXJfaWQsIGlucHV0LnBhc3N3b3JkKTtcblx0XHRyZXR1cm4ge1xuXHRcdFx0dXNlcl9pZDogZXhpc3RpbmcudXNlcl9pZCxcblx0XHRcdGVtYWlsOiBleGlzdGluZy5lbWFpbCxcblx0XHRcdHBhc3N3b3JkOiBpbnB1dC5wYXNzd29yZCxcblx0XHRcdHVzZXJuYW1lOiBpbnB1dC51c2VybmFtZSxcblx0XHR9O1xuXHR9XG59XG5cbmV4cG9ydCB7IFJFUVVJUkVEX1NDT1BFUyB9O1xuIl0sIm5hbWVzIjpbImV4ZWNGaWxlU3luYyIsInNwYXduU3luYyIsInJhbmRvbUJ5dGVzIiwiUkVRVUlSRURfU0NPUEVTIiwiam9pbiIsIkFQSV9USU1FT1VUX01TIiwiSEVMTE9fQVBJX1NDT1BFUyIsIkRCX0NPTk5FQ1RJT05fTkFNRSIsIkF1dGgwQXV0aEVycm9yIiwiRXJyb3IiLCJtZXNzYWdlIiwibmFtZSIsImlzQXV0aEVycm9yIiwidGV4dCIsImluY2x1ZGVzIiwicGFyc2VKc29uT3V0cHV0Iiwic3Rkb3V0Iiwic3RhcnQiLCJpbmRleE9mIiwiYXJyYXlTdGFydCIsImlkeCIsIk1hdGgiLCJtaW4iLCJzbGljZSIsIkpTT04iLCJwYXJzZSIsInJ1bkF1dGgwIiwiYXJncyIsInJlc3VsdCIsImVuY29kaW5nIiwidGltZW91dCIsImlucHV0Iiwic3RkaW8iLCJlcnJvciIsIm1zZyIsImNvZGUiLCJzdGF0dXMiLCJzdGRlcnIiLCJpc0luc3RhbGxlZCIsImxpc3RUZW5hbnRzIiwib3V0IiwibG9naW4iLCJsaXN0QXBpcyIsImVyciIsImNyZWF0ZUFwaSIsImlkZW50aWZpZXIiLCJzY29wZXMiLCJ1cGRhdGVBcGlTY29wZXMiLCJjcmVhdGVTcGFBcHAiLCJjYWxsYmFja1VybHMiLCJjYWxsYmFja3MiLCJhcHAiLCJjbGllbnRJZCIsImNsaWVudF9pZCIsImxpc3RBcHBzIiwiYXBwcyIsIm1hcCIsImEiLCJmaWx0ZXIiLCJ1cGRhdGVTcGFDYWxsYmFja3MiLCJlbnN1cmVTcGFBcHAiLCJleGlzdGluZyIsImZpbmQiLCJyZXVzZWQiLCJlbmFibGVDb25uZWN0aW9uRm9yQ2xpZW50IiwiY29ubmVjdGlvbk5hbWUiLCJsaXN0T3V0IiwiY29ubmVjdGlvbnMiLCJjb25uZWN0aW9uIiwiYyIsImNsaWVudHNPdXQiLCJpZCIsImNsaWVudHMiLCJzb21lIiwic3RyaW5naWZ5IiwiZ2VuZXJhdGVBZG1pblBhc3N3b3JkIiwidG9TdHJpbmciLCJpc1VzZXJBbHJlYWR5RXhpc3RzRXJyb3IiLCJTdHJpbmciLCJ0ZXN0IiwiZmluZFVzZXJCeUVtYWlsIiwiZW1haWwiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ1c2VycyIsInVzZXIiLCJ1IiwidXNlcl9pZCIsInVwZGF0ZVVzZXJQYXNzd29yZCIsInVzZXJJZCIsInBhc3N3b3JkIiwiY3JlYXRlQWRtaW5EYXRhYmFzZVVzZXIiLCJib2R5IiwidXNlcm5hbWUiLCJlbWFpbF92ZXJpZmllZCIsInZlcmlmeV9lbWFpbCIsImFwcF9tZXRhZGF0YSIsInJvbGVzIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFT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
@@ -1,42 +0,0 @@
1
- import { spawnSync } from "node:child_process";
2
- /**
3
- * Format/lint-fix all files in the scaffolded workspace with Biome.
4
- * Prefer a global `biome` binary (builder image); fall back to `npx`.
5
- */ export function formatScaffoldedFiles(targetDir, paths = [
6
- "."
7
- ]) {
8
- process.stdout.write("\n Formatting scaffolded files with Biome...");
9
- let result = spawnSync("biome", [
10
- "check",
11
- "--write",
12
- ...paths
13
- ], {
14
- cwd: targetDir,
15
- encoding: "utf8",
16
- stdio: "pipe"
17
- });
18
- if (result.error && result.error.code === "ENOENT") {
19
- result = spawnSync("npx", [
20
- "--yes",
21
- "@biomejs/biome",
22
- "check",
23
- "--write",
24
- ...paths
25
- ], {
26
- cwd: targetDir,
27
- encoding: "utf8",
28
- stdio: "pipe"
29
- });
30
- }
31
- if (result.status === 0) {
32
- process.stdout.write(" done.\n");
33
- return;
34
- }
35
- const detail = (result.stderr || result.stdout || result.error?.message || "").trim();
36
- process.stdout.write(" failed.\n");
37
- if (detail) {
38
- console.error(` ✗ Biome: ${detail.slice(0, 400)}`);
39
- }
40
- }
41
-
42
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL2ZlYXR1cmVzL2Jpb21lLWZvcm1hdC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5cbi8qKlxuICogRm9ybWF0L2xpbnQtZml4IGFsbCBmaWxlcyBpbiB0aGUgc2NhZmZvbGRlZCB3b3Jrc3BhY2Ugd2l0aCBCaW9tZS5cbiAqIFByZWZlciBhIGdsb2JhbCBgYmlvbWVgIGJpbmFyeSAoYnVpbGRlciBpbWFnZSk7IGZhbGwgYmFjayB0byBgbnB4YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdFNjYWZmb2xkZWRGaWxlcyh0YXJnZXREaXI6IHN0cmluZywgcGF0aHM6IHN0cmluZ1tdID0gW1wiLlwiXSk6IHZvaWQge1xuXHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIlxcbiAgRm9ybWF0dGluZyBzY2FmZm9sZGVkIGZpbGVzIHdpdGggQmlvbWUuLi5cIik7XG5cblx0bGV0IHJlc3VsdCA9IHNwYXduU3luYyhcImJpb21lXCIsIFtcImNoZWNrXCIsIFwiLS13cml0ZVwiLCAuLi5wYXRoc10sIHtcblx0XHRjd2Q6IHRhcmdldERpcixcblx0XHRlbmNvZGluZzogXCJ1dGY4XCIsXG5cdFx0c3RkaW86IFwicGlwZVwiLFxuXHR9KTtcblxuXHRpZiAocmVzdWx0LmVycm9yICYmIChyZXN1bHQuZXJyb3IgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSBcIkVOT0VOVFwiKSB7XG5cdFx0cmVzdWx0ID0gc3Bhd25TeW5jKFwibnB4XCIsIFtcIi0teWVzXCIsIFwiQGJpb21lanMvYmlvbWVcIiwgXCJjaGVja1wiLCBcIi0td3JpdGVcIiwgLi4ucGF0aHNdLCB7XG5cdFx0XHRjd2Q6IHRhcmdldERpcixcblx0XHRcdGVuY29kaW5nOiBcInV0ZjhcIixcblx0XHRcdHN0ZGlvOiBcInBpcGVcIixcblx0XHR9KTtcblx0fVxuXG5cdGlmIChyZXN1bHQuc3RhdHVzID09PSAwKSB7XG5cdFx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoXCIgZG9uZS5cXG5cIik7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Y29uc3QgZGV0YWlsID0gKHJlc3VsdC5zdGRlcnIgfHwgcmVzdWx0LnN0ZG91dCB8fCByZXN1bHQuZXJyb3I/Lm1lc3NhZ2UgfHwgXCJcIikudHJpbSgpO1xuXHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIiBmYWlsZWQuXFxuXCIpO1xuXHRpZiAoZGV0YWlsKSB7XG5cdFx0Y29uc29sZS5lcnJvcihgICDinJcgQmlvbWU6ICR7ZGV0YWlsLnNsaWNlKDAsIDQwMCl9YCk7XG5cdH1cbn1cbiJdLCJuYW1lcyI6WyJzcGF3blN5bmMiLCJmb3JtYXRTY2FmZm9sZGVkRmlsZXMiLCJ0YXJnZXREaXIiLCJwYXRocyIsInByb2Nlc3MiLCJzdGRvdXQiLCJ3cml0ZSIsInJlc3VsdCIsImN3ZCIsImVuY29kaW5nIiwic3RkaW8iLCJlcnJvciIsImNvZGUiLCJzdGF0dXMiLCJkZXRhaWwiLCJzdGRlcnIiLCJtZXNzYWdlIiwidHJpbSIsImNvbnNvbGUiLCJzbGljZSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsU0FBUyxRQUFRLHFCQUFxQjtBQUUvQzs7O0NBR0MsR0FDRCxPQUFPLFNBQVNDLHNCQUFzQkMsU0FBaUIsRUFBRUMsUUFBa0I7SUFBQztDQUFJO0lBQy9FQyxRQUFRQyxNQUFNLENBQUNDLEtBQUssQ0FBQztJQUVyQixJQUFJQyxTQUFTUCxVQUFVLFNBQVM7UUFBQztRQUFTO1dBQWNHO0tBQU0sRUFBRTtRQUMvREssS0FBS047UUFDTE8sVUFBVTtRQUNWQyxPQUFPO0lBQ1I7SUFFQSxJQUFJSCxPQUFPSSxLQUFLLElBQUksQUFBQ0osT0FBT0ksS0FBSyxDQUEyQkMsSUFBSSxLQUFLLFVBQVU7UUFDOUVMLFNBQVNQLFVBQVUsT0FBTztZQUFDO1lBQVM7WUFBa0I7WUFBUztlQUFjRztTQUFNLEVBQUU7WUFDcEZLLEtBQUtOO1lBQ0xPLFVBQVU7WUFDVkMsT0FBTztRQUNSO0lBQ0Q7SUFFQSxJQUFJSCxPQUFPTSxNQUFNLEtBQUssR0FBRztRQUN4QlQsUUFBUUMsTUFBTSxDQUFDQyxLQUFLLENBQUM7UUFDckI7SUFDRDtJQUVBLE1BQU1RLFNBQVMsQUFBQ1AsQ0FBQUEsT0FBT1EsTUFBTSxJQUFJUixPQUFPRixNQUFNLElBQUlFLE9BQU9JLEtBQUssRUFBRUssV0FBVyxFQUFDLEVBQUdDLElBQUk7SUFDbkZiLFFBQVFDLE1BQU0sQ0FBQ0MsS0FBSyxDQUFDO0lBQ3JCLElBQUlRLFFBQVE7UUFDWEksUUFBUVAsS0FBSyxDQUFDLENBQUMsV0FBVyxFQUFFRyxPQUFPSyxLQUFLLENBQUMsR0FBRyxNQUFNO0lBQ25EO0FBQ0QifQ==