@geekmidas/cli 10.0.0-alpha.44 → 10.0.0-alpha.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/README.md +144 -183
- package/dist/{OpenApiTsGenerator-B4Kj_qNU.cjs → OpenApiTsGenerator-BN0PIZxd.cjs} +17 -71
- package/dist/OpenApiTsGenerator-BN0PIZxd.cjs.map +1 -0
- package/dist/{OpenApiTsGenerator-CEh3EKN3.mjs → OpenApiTsGenerator-BzIGy8KE.mjs} +17 -71
- package/dist/OpenApiTsGenerator-BzIGy8KE.mjs.map +1 -0
- package/dist/{config-CJ-PAb7M.cjs → config-CsYSyUya.cjs} +3 -3
- package/dist/{config-CJ-PAb7M.cjs.map → config-CsYSyUya.cjs.map} +1 -1
- package/dist/{config-5watB1D0.mjs → config-D8J5rrTb.mjs} +3 -3
- package/dist/{config-5watB1D0.mjs.map → config-D8J5rrTb.mjs.map} +1 -1
- package/dist/config.cjs +2 -2
- package/dist/config.d.cts +2 -2
- package/dist/config.d.mts +2 -2
- package/dist/config.mjs +2 -2
- package/dist/{discover-BLhf7V_J.mjs → discover-Cf2jAcgF.mjs} +4 -56
- package/dist/discover-Cf2jAcgF.mjs.map +1 -0
- package/dist/{discover-B0f_kuNN.cjs → discover-DXNviAh-.cjs} +3 -79
- package/dist/discover-DXNviAh-.cjs.map +1 -0
- package/dist/{emit-Bzq7JsMP.mjs → emit-C1e8qD08.mjs} +12 -43
- package/dist/emit-C1e8qD08.mjs.map +1 -0
- package/dist/{emit-BdoPFjZf.cjs → emit-Dmc1nvdS.cjs} +11 -54
- package/dist/emit-Dmc1nvdS.cjs.map +1 -0
- package/dist/{github-D5MthUlR.mjs → github-BfpadQWQ.mjs} +3 -3
- package/dist/{github-D5MthUlR.mjs.map → github-BfpadQWQ.mjs.map} +1 -1
- package/dist/{github-BAr8WGkR.cjs → github-BrI1tv6u.cjs} +3 -3
- package/dist/{github-BAr8WGkR.cjs.map → github-BrI1tv6u.cjs.map} +1 -1
- package/dist/{index-B3PeGOQp.d.cts → index-BQhJXpaQ.d.mts} +2 -2
- package/dist/{index-B3PeGOQp.d.cts.map → index-BQhJXpaQ.d.mts.map} +1 -1
- package/dist/{index-BOyaGcCm.d.mts → index-DHJePE0y.d.cts} +2 -2
- package/dist/{index-BOyaGcCm.d.mts.map → index-DHJePE0y.d.cts.map} +1 -1
- package/dist/index.cjs +395 -660
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +397 -662
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-BRklCm7b.mjs → migrate-B3opyC3o.mjs} +5 -5
- package/dist/{migrate-BRklCm7b.mjs.map → migrate-B3opyC3o.mjs.map} +1 -1
- package/dist/{migrate-PJi4b1ga.cjs → migrate-Dp5HFzuQ.cjs} +5 -5
- package/dist/{migrate-PJi4b1ga.cjs.map → migrate-Dp5HFzuQ.cjs.map} +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/{ready-3RfHxdA0.cjs → ready-L7I68yXf.cjs} +67 -8
- package/dist/ready-L7I68yXf.cjs.map +1 -0
- package/dist/{ready-ZqOuNvKD.mjs → ready-V6Ou6-B6.mjs} +49 -8
- package/dist/ready-V6Ou6-B6.mjs.map +1 -0
- package/dist/reconcile/public.cjs +2 -4
- package/dist/reconcile/public.d.cts +6 -10
- package/dist/reconcile/public.d.cts.map +1 -1
- package/dist/reconcile/public.d.mts +6 -10
- package/dist/reconcile/public.d.mts.map +1 -1
- package/dist/reconcile/public.mjs +3 -3
- package/dist/{types-0R124hrY.d.mts → types-BbrNu83u.d.mts} +14 -109
- package/dist/{types-0R124hrY.d.mts.map → types-BbrNu83u.d.mts.map} +1 -1
- package/dist/{types-DfdYe31u.d.cts → types-DNqEsctD.d.cts} +14 -109
- package/dist/{types-DfdYe31u.d.cts.map → types-DNqEsctD.d.cts.map} +1 -1
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/workspace/index.cjs +1 -1
- package/dist/workspace/index.d.cts +2 -2
- package/dist/workspace/index.d.mts +2 -2
- package/dist/workspace/index.mjs +1 -1
- package/dist/{workspace-BKytVCzb.mjs → workspace-CHEC80sp.mjs} +6 -7
- package/dist/workspace-CHEC80sp.mjs.map +1 -0
- package/dist/{workspace-dV6f-3vv.cjs → workspace-D9z2ymBW.cjs} +11 -12
- package/dist/workspace-D9z2ymBW.cjs.map +1 -0
- package/dist/{workspace-RYSYtHP7.cjs → workspace-DEibcoBe.cjs} +11 -25
- package/dist/{workspace-RYSYtHP7.cjs.map → workspace-DEibcoBe.cjs.map} +1 -1
- package/dist/{workspace-DOmIhiau.mjs → workspace-DNzWgM1J.mjs} +11 -25
- package/dist/{workspace-DOmIhiau.mjs.map → workspace-DNzWgM1J.mjs.map} +1 -1
- package/package.json +14 -14
- package/dist/OpenApiTsGenerator-B4Kj_qNU.cjs.map +0 -1
- package/dist/OpenApiTsGenerator-CEh3EKN3.mjs.map +0 -1
- package/dist/discover-B0f_kuNN.cjs.map +0 -1
- package/dist/discover-BLhf7V_J.mjs.map +0 -1
- package/dist/emit-BdoPFjZf.cjs.map +0 -1
- package/dist/emit-Bzq7JsMP.mjs.map +0 -1
- package/dist/ready-3RfHxdA0.cjs.map +0 -1
- package/dist/ready-ZqOuNvKD.mjs.map +0 -1
- package/dist/workspace-BKytVCzb.mjs.map +0 -1
- package/dist/workspace-dV6f-3vv.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env -S npx tsx
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
4
|
-
const require_discover = require("./discover-
|
|
5
|
-
const require_config = require("./config-
|
|
6
|
-
const require_workspace = require("./workspace-
|
|
4
|
+
const require_discover = require("./discover-DXNviAh-.cjs");
|
|
5
|
+
const require_config = require("./config-CsYSyUya.cjs");
|
|
6
|
+
const require_workspace = require("./workspace-DEibcoBe.cjs");
|
|
7
7
|
const require_storage = require("./storage-CSGoC3bK.cjs");
|
|
8
8
|
const require_store = require("./store-DQgxT_WR.cjs");
|
|
9
|
-
const require_workspace$1 = require("./workspace-
|
|
10
|
-
const require_OpenApiTsGenerator = require("./OpenApiTsGenerator-
|
|
9
|
+
const require_workspace$1 = require("./workspace-D9z2ymBW.cjs");
|
|
10
|
+
const require_OpenApiTsGenerator = require("./OpenApiTsGenerator-BN0PIZxd.cjs");
|
|
11
11
|
const require_openapi = require("./openapi.cjs");
|
|
12
|
-
const require_ready = require("./ready-
|
|
13
|
-
const require_emit = require("./emit-
|
|
12
|
+
const require_ready = require("./ready-L7I68yXf.cjs");
|
|
13
|
+
const require_emit = require("./emit-Dmc1nvdS.cjs");
|
|
14
14
|
let commander = require("commander");
|
|
15
15
|
let node_process = require("node:process");
|
|
16
16
|
let node_readline_promises = require("node:readline/promises");
|
|
@@ -46,7 +46,7 @@ let _geekmidas_constructs_queue = require("@geekmidas/constructs/queue");
|
|
|
46
46
|
let _geekmidas_constructs_topic = require("@geekmidas/constructs/topic");
|
|
47
47
|
let node_dns_promises = require("node:dns/promises");
|
|
48
48
|
//#region package.json
|
|
49
|
-
var version = "10.0.0-alpha.
|
|
49
|
+
var version = "10.0.0-alpha.46";
|
|
50
50
|
//#endregion
|
|
51
51
|
//#region src/auth/credentials.ts
|
|
52
52
|
/**
|
|
@@ -180,7 +180,7 @@ async function getHostingerToken(options) {
|
|
|
180
180
|
}
|
|
181
181
|
//#endregion
|
|
182
182
|
//#region src/auth/index.ts
|
|
183
|
-
const logger$
|
|
183
|
+
const logger$12 = console;
|
|
184
184
|
/**
|
|
185
185
|
* Validate Dokploy token by making a test API call
|
|
186
186
|
*/
|
|
@@ -247,52 +247,52 @@ async function prompt$1(message, hidden = false) {
|
|
|
247
247
|
async function loginCommand(options) {
|
|
248
248
|
const { provider, token: providedToken, endpoint: providedEndpoint } = options;
|
|
249
249
|
if (provider === "dokploy") {
|
|
250
|
-
logger$
|
|
250
|
+
logger$12.log("\n🔐 Logging in to Dokploy...\n");
|
|
251
251
|
let endpoint = providedEndpoint;
|
|
252
252
|
if (!endpoint) endpoint = await prompt$1("Dokploy URL (e.g., https://dokploy.example.com): ");
|
|
253
253
|
endpoint = endpoint.replace(/\/$/, "");
|
|
254
254
|
try {
|
|
255
255
|
new URL(endpoint);
|
|
256
256
|
} catch {
|
|
257
|
-
logger$
|
|
257
|
+
logger$12.error("Invalid URL format");
|
|
258
258
|
process.exit(1);
|
|
259
259
|
}
|
|
260
260
|
let token = providedToken;
|
|
261
261
|
if (!token) {
|
|
262
|
-
logger$
|
|
262
|
+
logger$12.log(`\nGenerate a token at: ${endpoint}/settings/profile\n`);
|
|
263
263
|
token = await prompt$1("API Token: ", true);
|
|
264
264
|
}
|
|
265
265
|
if (!token) {
|
|
266
|
-
logger$
|
|
266
|
+
logger$12.error("Token is required");
|
|
267
267
|
process.exit(1);
|
|
268
268
|
}
|
|
269
|
-
logger$
|
|
269
|
+
logger$12.log("\nValidating credentials...");
|
|
270
270
|
if (!await validateDokployToken(endpoint, token)) {
|
|
271
|
-
logger$
|
|
271
|
+
logger$12.error("\n✗ Invalid credentials. Please check your token and try again.");
|
|
272
272
|
process.exit(1);
|
|
273
273
|
}
|
|
274
274
|
await storeDokployCredentials(token, endpoint);
|
|
275
|
-
logger$
|
|
276
|
-
logger$
|
|
277
|
-
logger$
|
|
278
|
-
logger$
|
|
275
|
+
logger$12.log("\n✓ Successfully logged in to Dokploy!");
|
|
276
|
+
logger$12.log(` Endpoint: ${endpoint}`);
|
|
277
|
+
logger$12.log(` Credentials stored in: ${getCredentialsPath()}`);
|
|
278
|
+
logger$12.log("\nYou can now use deploy commands without setting DOKPLOY_API_TOKEN.");
|
|
279
279
|
}
|
|
280
280
|
if (provider === "hostinger") {
|
|
281
|
-
logger$
|
|
281
|
+
logger$12.log("\n🔐 Logging in to Hostinger...\n");
|
|
282
282
|
let token = providedToken;
|
|
283
283
|
if (!token) {
|
|
284
|
-
logger$
|
|
284
|
+
logger$12.log("\nGenerate a token at: https://hpanel.hostinger.com/profile/api\n");
|
|
285
285
|
token = await prompt$1("API Token: ", true);
|
|
286
286
|
}
|
|
287
287
|
if (!token) {
|
|
288
|
-
logger$
|
|
288
|
+
logger$12.error("Token is required");
|
|
289
289
|
process.exit(1);
|
|
290
290
|
}
|
|
291
291
|
await storeHostingerToken(token);
|
|
292
|
-
logger$
|
|
293
|
-
logger$
|
|
294
|
-
logger$
|
|
295
|
-
logger$
|
|
292
|
+
logger$12.log("\n✓ Hostinger token stored.");
|
|
293
|
+
logger$12.log(` Credentials stored in: ${getCredentialsPath()}`);
|
|
294
|
+
logger$12.log(" Not validated here: every DNS endpoint is scoped to a domain, so the\n first deploy that touches DNS is where a bad token reports itself.");
|
|
295
|
+
logger$12.log("\nYou can now use it as a DNS provider without setting HOSTINGER_API_TOKEN.");
|
|
296
296
|
}
|
|
297
297
|
}
|
|
298
298
|
/**
|
|
@@ -301,27 +301,27 @@ async function loginCommand(options) {
|
|
|
301
301
|
async function logoutCommand(options) {
|
|
302
302
|
const { provider = "dokploy" } = options;
|
|
303
303
|
if (provider === "all") {
|
|
304
|
-
if (await removeDokployCredentials()) logger$
|
|
305
|
-
else logger$
|
|
304
|
+
if (await removeDokployCredentials()) logger$12.log("\n✓ Logged out from all services");
|
|
305
|
+
else logger$12.log("\nNo stored credentials found");
|
|
306
306
|
return;
|
|
307
307
|
}
|
|
308
308
|
if (provider === "dokploy") {
|
|
309
|
-
if (await removeDokployCredentials()) logger$
|
|
310
|
-
else logger$
|
|
309
|
+
if (await removeDokployCredentials()) logger$12.log("\n✓ Logged out from Dokploy");
|
|
310
|
+
else logger$12.log("\nNo Dokploy credentials found");
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
313
|
/**
|
|
314
314
|
* Show current login status
|
|
315
315
|
*/
|
|
316
316
|
async function whoamiCommand() {
|
|
317
|
-
logger$
|
|
317
|
+
logger$12.log("\n📋 Current credentials:\n");
|
|
318
318
|
const dokploy = await getDokployCredentials();
|
|
319
319
|
if (dokploy) {
|
|
320
|
-
logger$
|
|
321
|
-
logger$
|
|
322
|
-
logger$
|
|
323
|
-
} else logger$
|
|
324
|
-
logger$
|
|
320
|
+
logger$12.log(" Dokploy:");
|
|
321
|
+
logger$12.log(` Endpoint: ${dokploy.endpoint}`);
|
|
322
|
+
logger$12.log(` Token: ${maskToken(dokploy.token)}`);
|
|
323
|
+
} else logger$12.log(" Dokploy: Not logged in");
|
|
324
|
+
logger$12.log(`\n Credentials file: ${getCredentialsPath()}`);
|
|
325
325
|
}
|
|
326
326
|
/**
|
|
327
327
|
* Mask a token for display
|
|
@@ -331,85 +331,14 @@ function maskToken(token) {
|
|
|
331
331
|
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
|
332
332
|
}
|
|
333
333
|
//#endregion
|
|
334
|
-
//#region src/build/providerResolver.ts
|
|
335
|
-
/**
|
|
336
|
-
* Resolves provider configuration from the new simplified system
|
|
337
|
-
* to the internal legacy format for backward compatibility
|
|
338
|
-
*/
|
|
339
|
-
function resolveProviders(config, options) {
|
|
340
|
-
const providers = [];
|
|
341
|
-
let enableOpenApi = options.enableOpenApi || false;
|
|
342
|
-
if (options.providers) return {
|
|
343
|
-
providers: options.providers,
|
|
344
|
-
enableOpenApi
|
|
345
|
-
};
|
|
346
|
-
if (options.provider) {
|
|
347
|
-
const resolvedProviders = resolveMainProvider(options.provider, config.providers);
|
|
348
|
-
providers.push(...resolvedProviders.providers);
|
|
349
|
-
enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
|
|
350
|
-
} else if (config.providers) {
|
|
351
|
-
const resolvedProviders = resolveAllConfiguredProviders(config.providers);
|
|
352
|
-
providers.push(...resolvedProviders.providers);
|
|
353
|
-
enableOpenApi = resolvedProviders.enableOpenApi || enableOpenApi;
|
|
354
|
-
} else providers.push("aws-apigatewayv2", "aws-lambda");
|
|
355
|
-
return {
|
|
356
|
-
providers: [...new Set(providers)],
|
|
357
|
-
enableOpenApi
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
function resolveMainProvider(mainProvider, providersConfig) {
|
|
361
|
-
const providers = [];
|
|
362
|
-
let enableOpenApi = false;
|
|
363
|
-
if (mainProvider === "aws") {
|
|
364
|
-
const awsConfig = providersConfig?.aws;
|
|
365
|
-
if (awsConfig?.apiGateway) {
|
|
366
|
-
if (isEnabled(awsConfig.apiGateway.v1)) providers.push("aws-apigatewayv1");
|
|
367
|
-
if (isEnabled(awsConfig.apiGateway.v2)) providers.push("aws-apigatewayv2");
|
|
368
|
-
} else providers.push("aws-apigatewayv2");
|
|
369
|
-
if (awsConfig?.lambda) {
|
|
370
|
-
if (isEnabled(awsConfig.lambda.functions) || isEnabled(awsConfig.lambda.crons)) providers.push("aws-lambda");
|
|
371
|
-
} else providers.push("aws-lambda");
|
|
372
|
-
} else if (mainProvider === "server") {
|
|
373
|
-
providers.push("server");
|
|
374
|
-
const serverConfig = providersConfig?.server;
|
|
375
|
-
if (typeof serverConfig === "object" && serverConfig?.enableOpenApi) enableOpenApi = true;
|
|
376
|
-
}
|
|
377
|
-
return {
|
|
378
|
-
providers,
|
|
379
|
-
enableOpenApi
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
function resolveAllConfiguredProviders(providersConfig) {
|
|
383
|
-
const providers = [];
|
|
384
|
-
let enableOpenApi = false;
|
|
385
|
-
if (providersConfig.aws) {
|
|
386
|
-
const awsProviders = resolveMainProvider("aws", providersConfig);
|
|
387
|
-
providers.push(...awsProviders.providers);
|
|
388
|
-
}
|
|
389
|
-
if (providersConfig.server && isEnabled(providersConfig.server)) {
|
|
390
|
-
providers.push("server");
|
|
391
|
-
if (typeof providersConfig.server === "object" && providersConfig.server.enableOpenApi) enableOpenApi = true;
|
|
392
|
-
}
|
|
393
|
-
return {
|
|
394
|
-
providers,
|
|
395
|
-
enableOpenApi
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
function isEnabled(config) {
|
|
399
|
-
if (config === void 0) return false;
|
|
400
|
-
if (typeof config === "boolean") return config;
|
|
401
|
-
return config.enabled !== false;
|
|
402
|
-
}
|
|
403
|
-
//#endregion
|
|
404
334
|
//#region src/workspace/client-generator.ts
|
|
405
335
|
/**
|
|
406
336
|
* Normalize routes to an array of patterns.
|
|
407
|
-
* Handles
|
|
337
|
+
* Handles a glob or a list of them.
|
|
408
338
|
* @internal Exported for use in dev command
|
|
409
339
|
*/
|
|
410
340
|
function normalizeRoutes(routes) {
|
|
411
341
|
if (!routes) return [];
|
|
412
|
-
if (require_discover.isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
413
342
|
return Array.isArray(routes) ? routes : [routes];
|
|
414
343
|
}
|
|
415
344
|
//#endregion
|
|
@@ -428,7 +357,7 @@ function normalizeRoutes(routes) {
|
|
|
428
357
|
* trade than one that tells you what to type. Caddy's own `caddy trust` draws
|
|
429
358
|
* the line in the same place.
|
|
430
359
|
*/
|
|
431
|
-
const logger$
|
|
360
|
+
const logger$11 = console;
|
|
432
361
|
const run = (0, node_util.promisify)(node_child_process.execFile);
|
|
433
362
|
/**
|
|
434
363
|
* How each platform is told about a new authority.
|
|
@@ -480,15 +409,15 @@ async function trustCommand(options = {}) {
|
|
|
480
409
|
const certificate = (0, node_path.join)(workspace.root, require_workspace$1.LOCAL_CA_PATH);
|
|
481
410
|
if (!(0, node_fs.existsSync)(certificate)) throw new NoLocalAuthority(certificate);
|
|
482
411
|
const { describe, steps } = installation(process.platform, certificate);
|
|
483
|
-
logger$
|
|
484
|
-
logger$
|
|
412
|
+
logger$11.log(`\n🔐 Trusting the local authority in ${describe}`);
|
|
413
|
+
logger$11.log(` ${certificate}\n`);
|
|
485
414
|
if (options.dryRun) {
|
|
486
|
-
for (const [command, args] of steps) logger$
|
|
415
|
+
for (const [command, args] of steps) logger$11.log(` ${command} ${args.join(" ")}`);
|
|
487
416
|
return;
|
|
488
417
|
}
|
|
489
|
-
logger$
|
|
418
|
+
logger$11.log(" This needs an admin password.\n");
|
|
490
419
|
for (const [command, args] of steps) await run(command, args, { stdio: "inherit" });
|
|
491
|
-
logger$
|
|
420
|
+
logger$11.log("\n✅ Local https addresses are trusted. Restart your browser.\n");
|
|
492
421
|
}
|
|
493
422
|
/**
|
|
494
423
|
* Trust the authority if this machine lacks it and its owner agrees.
|
|
@@ -505,7 +434,7 @@ async function ensureTrusted(root, url, options = {}) {
|
|
|
505
434
|
if (await isTrusted(url)) return;
|
|
506
435
|
if (!options.assumeYes) {
|
|
507
436
|
if (!process.stdin.isTTY) {
|
|
508
|
-
logger$
|
|
437
|
+
logger$11.log(" Local https addresses are not trusted here. Run \"gkm trust\", or \"gkm setup --yes\".");
|
|
509
438
|
return;
|
|
510
439
|
}
|
|
511
440
|
if (await declined(root)) return;
|
|
@@ -517,7 +446,7 @@ async function ensureTrusted(root, url, options = {}) {
|
|
|
517
446
|
});
|
|
518
447
|
if (!install) {
|
|
519
448
|
await recordDeclined(root);
|
|
520
|
-
logger$
|
|
449
|
+
logger$11.log(" Skipped. Run \"gkm trust\" later.");
|
|
521
450
|
return;
|
|
522
451
|
}
|
|
523
452
|
}
|
|
@@ -1067,7 +996,7 @@ function closeFakes(served) {
|
|
|
1067
996
|
}
|
|
1068
997
|
//#endregion
|
|
1069
998
|
//#region src/exec/index.ts
|
|
1070
|
-
const logger$
|
|
999
|
+
const logger$10 = console;
|
|
1071
1000
|
/** `gkm exec` was given nothing to run. */
|
|
1072
1001
|
var NoCommandSpecified = class extends Error {
|
|
1073
1002
|
constructor() {
|
|
@@ -1090,17 +1019,17 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1090
1019
|
const cwd = options.cwd ?? process.cwd();
|
|
1091
1020
|
if (!commandArgs[0]) throw new NoCommandSpecified();
|
|
1092
1021
|
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
1093
|
-
if (defaultEnv.loaded.length > 0) logger$
|
|
1022
|
+
if (defaultEnv.loaded.length > 0) logger$10.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1094
1023
|
const { credentials, secretsJsonPath, appName } = await require_workspace$1.prepareEntryCredentials({ cwd });
|
|
1095
|
-
if (appName) logger$
|
|
1024
|
+
if (appName) logger$10.log(`📦 App: ${appName}`);
|
|
1096
1025
|
const secretCount = Object.keys(credentials).filter((k) => k !== "PORT").length;
|
|
1097
|
-
if (secretCount > 0) logger$
|
|
1026
|
+
if (secretCount > 0) logger$10.log(`🔐 Loaded ${secretCount} secret(s)`);
|
|
1098
1027
|
const preloadDir = (0, node_path.join)(cwd, ".gkm");
|
|
1099
1028
|
await (0, node_fs_promises.mkdir)(preloadDir, { recursive: true });
|
|
1100
1029
|
const preloadPath = (0, node_path.join)(preloadDir, "credentials-preload.mjs");
|
|
1101
1030
|
await require_workspace$1.createCredentialsPreload(preloadPath, secretsJsonPath);
|
|
1102
1031
|
const [cmd, ...args] = commandArgs;
|
|
1103
|
-
logger$
|
|
1032
|
+
logger$10.log(`🚀 Running: ${[cmd, ...args].join(" ")}`);
|
|
1104
1033
|
const nodeOptions = [(process.env.NODE_OPTIONS ?? "").replace(/--import[= ]\S+/g, "").trim(), `--import=${preloadPath}`].filter(Boolean).join(" ");
|
|
1105
1034
|
const child = (0, node_child_process.spawn)(cmd, args, {
|
|
1106
1035
|
cwd,
|
|
@@ -1114,7 +1043,7 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1114
1043
|
const exitCode = await new Promise((resolve) => {
|
|
1115
1044
|
child.on("close", (code) => resolve(code ?? 0));
|
|
1116
1045
|
child.on("error", (error) => {
|
|
1117
|
-
logger$
|
|
1046
|
+
logger$10.error(`Failed to run command: ${error.message}`);
|
|
1118
1047
|
resolve(1);
|
|
1119
1048
|
});
|
|
1120
1049
|
});
|
|
@@ -1122,7 +1051,7 @@ async function execCommand(commandArgs, options = {}) {
|
|
|
1122
1051
|
}
|
|
1123
1052
|
//#endregion
|
|
1124
1053
|
//#region src/dev/index.ts
|
|
1125
|
-
const logger$
|
|
1054
|
+
const logger$9 = console;
|
|
1126
1055
|
/**
|
|
1127
1056
|
* Normalize telescope configuration
|
|
1128
1057
|
* @internal Exported for testing
|
|
@@ -1187,39 +1116,36 @@ function normalizeHooksConfig(config, cwd = process.cwd()) {
|
|
|
1187
1116
|
return { serverHooksPath: (0, node_path.resolve)(cwd, serverPath) };
|
|
1188
1117
|
}
|
|
1189
1118
|
/**
|
|
1190
|
-
*
|
|
1119
|
+
* What a `--production` build is.
|
|
1120
|
+
*
|
|
1121
|
+
* A server runs its worker's background work itself — queues polled, crons
|
|
1122
|
+
* scheduled, subscribers drained — so the production entry wires all three.
|
|
1123
|
+
* The build writes their files on every server build, empty when there is
|
|
1124
|
+
* nothing, so including them costs an app without any nothing.
|
|
1125
|
+
*
|
|
1191
1126
|
* @internal Exported for testing
|
|
1192
1127
|
*/
|
|
1193
|
-
function normalizeProductionConfig(cliProduction
|
|
1128
|
+
function normalizeProductionConfig(cliProduction) {
|
|
1194
1129
|
if (!cliProduction) return;
|
|
1195
|
-
const config = configProduction ?? {};
|
|
1196
1130
|
return {
|
|
1197
1131
|
enabled: true,
|
|
1198
|
-
bundle:
|
|
1199
|
-
minify:
|
|
1200
|
-
healthCheck:
|
|
1201
|
-
gracefulShutdown:
|
|
1202
|
-
external:
|
|
1203
|
-
subscribers:
|
|
1204
|
-
openapi:
|
|
1205
|
-
optimizedHandlers:
|
|
1132
|
+
bundle: true,
|
|
1133
|
+
minify: true,
|
|
1134
|
+
healthCheck: "/health",
|
|
1135
|
+
gracefulShutdown: true,
|
|
1136
|
+
external: [],
|
|
1137
|
+
subscribers: "include",
|
|
1138
|
+
openapi: false,
|
|
1139
|
+
optimizedHandlers: true
|
|
1206
1140
|
};
|
|
1207
1141
|
}
|
|
1208
|
-
/**
|
|
1209
|
-
* Get production config from GkmConfig
|
|
1210
|
-
* @internal
|
|
1211
|
-
*/
|
|
1212
|
-
function getProductionConfigFromGkm(config) {
|
|
1213
|
-
const serverConfig = config.providers?.server;
|
|
1214
|
-
if (typeof serverConfig === "object") return serverConfig.production;
|
|
1215
|
-
}
|
|
1216
1142
|
/** Read by the generated server: no subscriber is subscribed or polled. */
|
|
1217
1143
|
const SUBSCRIBERS_ENV = "GKM_SUBSCRIBERS";
|
|
1218
1144
|
async function devCommand(options) {
|
|
1219
1145
|
if (options.subscribers === false) process.env[SUBSCRIBERS_ENV] = "off";
|
|
1220
1146
|
if (options.entry) return entryDevCommand(options);
|
|
1221
1147
|
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
1222
|
-
if (defaultEnv.loaded.length > 0) logger$
|
|
1148
|
+
if (defaultEnv.loaded.length > 0) logger$9.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1223
1149
|
const appConfig = await require_config.loadAppConfig().catch((error) => {
|
|
1224
1150
|
if (error instanceof require_config.NotInAnApp || error instanceof require_config.NotABackendApp) return;
|
|
1225
1151
|
throw error;
|
|
@@ -1235,7 +1161,7 @@ async function devCommand(options) {
|
|
|
1235
1161
|
const workspaceAppPort = appConfig.app.port;
|
|
1236
1162
|
const workspace = appConfig.workspace;
|
|
1237
1163
|
if (appConfig.app.entry) {
|
|
1238
|
-
logger$
|
|
1164
|
+
logger$9.log(`📄 Using entry point: ${appConfig.app.entry}`);
|
|
1239
1165
|
return entryDevCommand({
|
|
1240
1166
|
...options,
|
|
1241
1167
|
entry: appConfig.app.entry,
|
|
@@ -1245,19 +1171,18 @@ async function devCommand(options) {
|
|
|
1245
1171
|
}
|
|
1246
1172
|
if (config.env) {
|
|
1247
1173
|
const { loaded, missing } = require_workspace$1.loadEnvFiles(config.env, appRoot);
|
|
1248
|
-
if (loaded.length > 0) logger$
|
|
1249
|
-
if (missing.length > 0) logger$
|
|
1174
|
+
if (loaded.length > 0) logger$9.log(`📦 Loaded env: ${loaded.join(", ")}`);
|
|
1175
|
+
if (missing.length > 0) logger$9.warn(`⚠️ Missing env files: ${missing.join(", ")}`);
|
|
1250
1176
|
}
|
|
1251
|
-
const resolved = resolveProviders(config, { provider: "server" });
|
|
1252
1177
|
const telescope = normalizeTelescopeConfig(config.telescope);
|
|
1253
1178
|
const studio = normalizeStudioConfig(config.studio);
|
|
1254
1179
|
const hooks = normalizeHooksConfig(config.hooks, appRoot);
|
|
1255
|
-
const enableOpenApi = require_openapi.resolveOpenApiConfig(config).enabled
|
|
1180
|
+
const enableOpenApi = require_openapi.resolveOpenApiConfig(config).enabled;
|
|
1256
1181
|
const build = (bustCache = false) => quietly(() => buildApp({
|
|
1257
1182
|
config,
|
|
1258
1183
|
workspaceRoot: workspace?.root ?? secretsRoot,
|
|
1259
1184
|
appRoot,
|
|
1260
|
-
|
|
1185
|
+
target: "server",
|
|
1261
1186
|
enableOpenApi,
|
|
1262
1187
|
cacheBackend: require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(workspace ?? config)),
|
|
1263
1188
|
telescope,
|
|
@@ -1278,8 +1203,8 @@ async function devCommand(options) {
|
|
|
1278
1203
|
...options.fake ? { fake: true } : {}
|
|
1279
1204
|
});
|
|
1280
1205
|
if (reconciled.changed && reconciled.plan.containers.length > 0) {
|
|
1281
|
-
logger$
|
|
1282
|
-
for (const [container, address] of Object.entries(reconciled.addresses)) logger$
|
|
1206
|
+
logger$9.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
|
|
1207
|
+
for (const [container, address] of Object.entries(reconciled.addresses)) logger$9.log(` ${container}: ${address}`);
|
|
1283
1208
|
}
|
|
1284
1209
|
Object.assign(appSecrets, reconciled.env);
|
|
1285
1210
|
const own = reconciled.plan.resources.find((r) => (r.kind === "rest-api" || r.kind === "site") && require_config.appKey(r.id) === workspaceAppName);
|
|
@@ -1292,7 +1217,7 @@ async function devCommand(options) {
|
|
|
1292
1217
|
secretsJsonPath = (0, node_path.join)(secretsDir, secretsFileName);
|
|
1293
1218
|
await (0, node_fs_promises.writeFile)(secretsJsonPath, JSON.stringify(appSecrets, null, 2));
|
|
1294
1219
|
}
|
|
1295
|
-
const devServer = new DevServer(
|
|
1220
|
+
const devServer = new DevServer(options.port ?? workspaceAppPort ?? 3e3, options.portExplicit ?? workspaceAppPort !== void 0, enableOpenApi, telescope, studio, runtime, appRoot, secretsJsonPath, initial.selfServing !== void 0);
|
|
1296
1221
|
devServer.label = workspaceAppName ?? "server";
|
|
1297
1222
|
devServer.publicUrl = publicUrl;
|
|
1298
1223
|
await devServer.start();
|
|
@@ -1313,11 +1238,11 @@ async function devCommand(options) {
|
|
|
1313
1238
|
cwd: appRoot
|
|
1314
1239
|
});
|
|
1315
1240
|
watcher.on("error", (error) => {
|
|
1316
|
-
logger$
|
|
1241
|
+
logger$9.error("❌ Watcher error:", error);
|
|
1317
1242
|
});
|
|
1318
1243
|
let rebuildTimeout = null;
|
|
1319
1244
|
watcher.on("change", async (path) => {
|
|
1320
|
-
logger$
|
|
1245
|
+
logger$9.log(`🔄 ${path} changed — rebuilding`);
|
|
1321
1246
|
if (rebuildTimeout) clearTimeout(rebuildTimeout);
|
|
1322
1247
|
rebuildTimeout = setTimeout(async () => {
|
|
1323
1248
|
try {
|
|
@@ -1326,8 +1251,8 @@ async function devCommand(options) {
|
|
|
1326
1251
|
await devServer.restart();
|
|
1327
1252
|
} catch (error) {
|
|
1328
1253
|
const err = error;
|
|
1329
|
-
logger$
|
|
1330
|
-
if (err.stack) logger$
|
|
1254
|
+
logger$9.error(`❌ Rebuild failed: ${err.message}`);
|
|
1255
|
+
if (err.stack) logger$9.error(err.stack);
|
|
1331
1256
|
}
|
|
1332
1257
|
}, 300);
|
|
1333
1258
|
});
|
|
@@ -1335,9 +1260,9 @@ async function devCommand(options) {
|
|
|
1335
1260
|
const shutdown = () => {
|
|
1336
1261
|
if (isShuttingDown) return;
|
|
1337
1262
|
isShuttingDown = true;
|
|
1338
|
-
logger$
|
|
1263
|
+
logger$9.log("\n🛑 Shutting down...");
|
|
1339
1264
|
Promise.all([watcher.close(), devServer.stop()]).catch((err) => {
|
|
1340
|
-
logger$
|
|
1265
|
+
logger$9.error("Error during shutdown:", err);
|
|
1341
1266
|
}).finally(() => {
|
|
1342
1267
|
process.exit(0);
|
|
1343
1268
|
});
|
|
@@ -1539,7 +1464,7 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1539
1464
|
const frontendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "web");
|
|
1540
1465
|
const conflicts = checkPortConflicts(workspace);
|
|
1541
1466
|
if (conflicts.length > 0) {
|
|
1542
|
-
for (const conflict of conflicts) logger$
|
|
1467
|
+
for (const conflict of conflicts) logger$9.error(`❌ Port conflict: Apps "${conflict.app1}" and "${conflict.app2}" both use port ${conflict.port}`);
|
|
1543
1468
|
throw new Error("Port conflicts detected. Please assign unique ports to each app.");
|
|
1544
1469
|
}
|
|
1545
1470
|
if (frontendApps.length > 0) {
|
|
@@ -1548,10 +1473,10 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1548
1473
|
for (const result of validationResults) {
|
|
1549
1474
|
if (!result.valid) {
|
|
1550
1475
|
hasErrors = true;
|
|
1551
|
-
logger$
|
|
1552
|
-
for (const error of result.errors) logger$
|
|
1476
|
+
logger$9.error(`\n❌ Frontend app "${result.appName}" validation failed:`);
|
|
1477
|
+
for (const error of result.errors) logger$9.error(` • ${error}`);
|
|
1553
1478
|
}
|
|
1554
|
-
for (const warning of result.warnings) logger$
|
|
1479
|
+
for (const warning of result.warnings) logger$9.warn(` ⚠️ ${result.appName}: ${warning}`);
|
|
1555
1480
|
}
|
|
1556
1481
|
if (hasErrors) throw new Error("Frontend app validation failed. Fix the issues above and try again.");
|
|
1557
1482
|
}
|
|
@@ -1561,20 +1486,20 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1561
1486
|
...options.fake ? { fake: true } : {}
|
|
1562
1487
|
});
|
|
1563
1488
|
if (reconciled.changed && reconciled.plan.containers.length > 0) {
|
|
1564
|
-
logger$
|
|
1565
|
-
for (const [container, address] of Object.entries(reconciled.addresses)) logger$
|
|
1489
|
+
logger$9.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
|
|
1490
|
+
for (const [container, address] of Object.entries(reconciled.addresses)) logger$9.log(` ${container}: ${address}`);
|
|
1566
1491
|
}
|
|
1567
1492
|
const secretsEnv = {
|
|
1568
1493
|
...rawSecrets,
|
|
1569
1494
|
...reconciled.env
|
|
1570
1495
|
};
|
|
1571
1496
|
const fakes = options.fake ? await serveFakes(reconciled.fakes, reconciled.ports) : [];
|
|
1572
|
-
for (const { id, port } of fakes) logger$
|
|
1497
|
+
for (const { id, port } of fakes) logger$9.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
1573
1498
|
if (options.migrate || options.seed) {
|
|
1574
|
-
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-
|
|
1499
|
+
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs"));
|
|
1575
1500
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
1576
|
-
} else await Promise.resolve().then(() => require("./migrate-
|
|
1577
|
-
logger$
|
|
1501
|
+
} else await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
1502
|
+
logger$9.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
1578
1503
|
});
|
|
1579
1504
|
const appUrls = {};
|
|
1580
1505
|
for (const resource of reconciled.plan.resources) {
|
|
@@ -1595,11 +1520,11 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1595
1520
|
else {
|
|
1596
1521
|
const { filters, unpackaged } = turboFilters(workspace);
|
|
1597
1522
|
turboFilter = filters.flatMap((name) => ["--filter", name]);
|
|
1598
|
-
if (unpackaged.length > 0) logger$
|
|
1523
|
+
if (unpackaged.length > 0) logger$9.warn(`⚠️ No package.json with a name for: ${unpackaged.join(", ")} — turbo cannot run ${unpackaged.length === 1 ? "it" : "them"}.`);
|
|
1599
1524
|
}
|
|
1600
1525
|
const buildOrder = require_workspace.getAppBuildOrder(workspace);
|
|
1601
1526
|
const width = Math.max(...buildOrder.map((name) => name.length));
|
|
1602
|
-
logger$
|
|
1527
|
+
logger$9.log(`\n${workspace.name}: ${appCount} app(s)`);
|
|
1603
1528
|
for (const appName of buildOrder) {
|
|
1604
1529
|
const app = workspace.apps[appName];
|
|
1605
1530
|
if (!app) continue;
|
|
@@ -1607,14 +1532,14 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1607
1532
|
const own = reconciled.plan.resources.find((r) => r.kind === "mobile-app" && require_config.appKey(r.id) === appName);
|
|
1608
1533
|
const scheme = own ? reconciled.env[own.envKey] : void 0;
|
|
1609
1534
|
const device = Object.entries(reconciled.env).find(([key]) => key.endsWith("_DEVICE_URL"))?.[1];
|
|
1610
|
-
logger$
|
|
1535
|
+
logger$9.log(` ${appName.padEnd(width)} ${scheme ? `${scheme}://` : "mobile"}${device ? ` — devices reach ${new URL(device).hostname}` : ""}`);
|
|
1611
1536
|
continue;
|
|
1612
1537
|
}
|
|
1613
1538
|
const local = `http://localhost:${app.port}`;
|
|
1614
1539
|
const url = Object.entries(appUrls).find(([id]) => require_config.appKey(id) === appName)?.[1];
|
|
1615
|
-
logger$
|
|
1540
|
+
logger$9.log(` ${appName.padEnd(width)} ${url ? `${url} -> ${local}` : local}`);
|
|
1616
1541
|
}
|
|
1617
|
-
logger$
|
|
1542
|
+
logger$9.log("");
|
|
1618
1543
|
const configFiles = [
|
|
1619
1544
|
"gkm.config.ts",
|
|
1620
1545
|
"gkm.config.js",
|
|
@@ -1661,7 +1586,7 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1661
1586
|
const shutdown = () => {
|
|
1662
1587
|
if (isShuttingDown) return;
|
|
1663
1588
|
isShuttingDown = true;
|
|
1664
|
-
logger$
|
|
1589
|
+
logger$9.log("\n🛑 Shutting down workspace...");
|
|
1665
1590
|
closeFakes(fakes);
|
|
1666
1591
|
const pid = turboProcess.pid;
|
|
1667
1592
|
if (pid) try {
|
|
@@ -1686,7 +1611,7 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1686
1611
|
process.on("SIGTERM", shutdown);
|
|
1687
1612
|
return new Promise((resolve, reject) => {
|
|
1688
1613
|
turboProcess.on("error", (error) => {
|
|
1689
|
-
logger$
|
|
1614
|
+
logger$9.error("❌ Turbo error:", error);
|
|
1690
1615
|
reject(error);
|
|
1691
1616
|
});
|
|
1692
1617
|
turboProcess.on("exit", (code) => {
|
|
@@ -1705,11 +1630,11 @@ async function entryDevCommand(options) {
|
|
|
1705
1630
|
const entryPath = (0, node_path.resolve)(process.cwd(), entry);
|
|
1706
1631
|
if (!(0, node_fs.existsSync)(entryPath)) throw new Error(`Entry file not found: ${entryPath}`);
|
|
1707
1632
|
const defaultEnv = require_workspace$1.loadEnvFiles(".env");
|
|
1708
|
-
if (defaultEnv.loaded.length > 0) logger$
|
|
1633
|
+
if (defaultEnv.loaded.length > 0) logger$9.log(`📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
1709
1634
|
const { credentials, resolvedPort, secretsJsonPath, appName } = await require_workspace$1.prepareEntryCredentials({ explicitPort: options.portExplicit ? options.port : void 0 });
|
|
1710
|
-
if (appName) logger$
|
|
1711
|
-
logger$
|
|
1712
|
-
if (Object.keys(credentials).length > 1) logger$
|
|
1635
|
+
if (appName) logger$9.log(`📦 App: ${appName} (port ${resolvedPort})`);
|
|
1636
|
+
logger$9.log(`🚀 Starting entry file: ${entry} on port ${resolvedPort}`);
|
|
1637
|
+
if (Object.keys(credentials).length > 1) logger$9.log(`🔐 Loaded ${Object.keys(credentials).length - 1} secret(s) + PORT`);
|
|
1713
1638
|
const wrapperDir = (0, node_path.join)(process.cwd(), ".gkm");
|
|
1714
1639
|
await (0, node_fs_promises.mkdir)(wrapperDir, { recursive: true });
|
|
1715
1640
|
const wrapperPath = (0, node_path.join)(wrapperDir, "entry-wrapper.ts");
|
|
@@ -1720,7 +1645,7 @@ async function entryDevCommand(options) {
|
|
|
1720
1645
|
const shutdown = () => {
|
|
1721
1646
|
if (isShuttingDown) return;
|
|
1722
1647
|
isShuttingDown = true;
|
|
1723
|
-
logger$
|
|
1648
|
+
logger$9.log("\n🛑 Shutting down...");
|
|
1724
1649
|
runner.stop();
|
|
1725
1650
|
process.exit(0);
|
|
1726
1651
|
};
|
|
@@ -1756,14 +1681,14 @@ var EntryRunner = class {
|
|
|
1756
1681
|
});
|
|
1757
1682
|
let restartTimeout = null;
|
|
1758
1683
|
this.watcher.on("change", (path) => {
|
|
1759
|
-
logger$
|
|
1684
|
+
logger$9.log(`📝 File changed: ${path}`);
|
|
1760
1685
|
if (restartTimeout) clearTimeout(restartTimeout);
|
|
1761
1686
|
restartTimeout = setTimeout(async () => {
|
|
1762
|
-
logger$
|
|
1687
|
+
logger$9.log("🔄 Restarting...");
|
|
1763
1688
|
await this.restart();
|
|
1764
1689
|
}, 300);
|
|
1765
1690
|
});
|
|
1766
|
-
logger$
|
|
1691
|
+
logger$9.log(`👀 Watching for changes in: ${watchDir}`);
|
|
1767
1692
|
}
|
|
1768
1693
|
}
|
|
1769
1694
|
async runProcess() {
|
|
@@ -1778,17 +1703,17 @@ var EntryRunner = class {
|
|
|
1778
1703
|
});
|
|
1779
1704
|
this.isRunning = true;
|
|
1780
1705
|
this.childProcess.on("error", (error) => {
|
|
1781
|
-
logger$
|
|
1706
|
+
logger$9.error("❌ Process error:", error);
|
|
1782
1707
|
});
|
|
1783
1708
|
this.childProcess.on("exit", (code) => {
|
|
1784
|
-
if (code !== null && code !== 0 && code !== 143) logger$
|
|
1709
|
+
if (code !== null && code !== 0 && code !== 143) logger$9.error(`❌ Process exited with code ${code}`);
|
|
1785
1710
|
this.isRunning = false;
|
|
1786
1711
|
});
|
|
1787
1712
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1788
1713
|
if (this.isRunning) {
|
|
1789
|
-
logger$
|
|
1790
|
-
logger$
|
|
1791
|
-
logger$
|
|
1714
|
+
logger$9.log("");
|
|
1715
|
+
logger$9.log(` \x1b[32m✓ Ready\x1b[0m at \x1b[36mhttp://localhost:${this.port}\x1b[0m`);
|
|
1716
|
+
logger$9.log("");
|
|
1792
1717
|
}
|
|
1793
1718
|
}
|
|
1794
1719
|
async restart() {
|
|
@@ -1966,7 +1891,6 @@ function listenerOn(port) {
|
|
|
1966
1891
|
}
|
|
1967
1892
|
}
|
|
1968
1893
|
var DevServer = class {
|
|
1969
|
-
provider;
|
|
1970
1894
|
requestedPort;
|
|
1971
1895
|
portExplicit;
|
|
1972
1896
|
enableOpenApi;
|
|
@@ -1980,8 +1904,7 @@ var DevServer = class {
|
|
|
1980
1904
|
isRunning = false;
|
|
1981
1905
|
actualPort;
|
|
1982
1906
|
startTime = Date.now();
|
|
1983
|
-
constructor(
|
|
1984
|
-
this.provider = provider;
|
|
1907
|
+
constructor(requestedPort, portExplicit, enableOpenApi, telescope, studio, runtime = "node", appRoot = process.cwd(), secretsJsonPath, selfServing = false) {
|
|
1985
1908
|
this.requestedPort = requestedPort;
|
|
1986
1909
|
this.portExplicit = portExplicit;
|
|
1987
1910
|
this.enableOpenApi = enableOpenApi;
|
|
@@ -2008,9 +1931,9 @@ var DevServer = class {
|
|
|
2008
1931
|
this.actualPort = this.requestedPort;
|
|
2009
1932
|
} else {
|
|
2010
1933
|
this.actualPort = await require_workspace$1.findAvailablePort(this.requestedPort);
|
|
2011
|
-
if (this.actualPort !== this.requestedPort) logger$
|
|
1934
|
+
if (this.actualPort !== this.requestedPort) logger$9.log(`ℹ️ Port ${this.requestedPort} was in use, using port ${this.actualPort} instead`);
|
|
2012
1935
|
}
|
|
2013
|
-
const serverEntryPath = (0, node_path.join)(this.appRoot, ".gkm",
|
|
1936
|
+
const serverEntryPath = (0, node_path.join)(this.appRoot, ".gkm", "server", "server.ts");
|
|
2014
1937
|
await this.createServerEntry();
|
|
2015
1938
|
this.serverProcess = (0, node_child_process.spawn)(...tsxCommand(this.appRoot, [
|
|
2016
1939
|
serverEntryPath,
|
|
@@ -2027,10 +1950,10 @@ var DevServer = class {
|
|
|
2027
1950
|
});
|
|
2028
1951
|
this.isRunning = true;
|
|
2029
1952
|
this.serverProcess.on("error", (error) => {
|
|
2030
|
-
logger$
|
|
1953
|
+
logger$9.error("❌ Server error:", error);
|
|
2031
1954
|
});
|
|
2032
1955
|
this.serverProcess.on("exit", (code, signal) => {
|
|
2033
|
-
if (code !== null && code !== 0 && signal !== "SIGTERM") logger$
|
|
1956
|
+
if (code !== null && code !== 0 && signal !== "SIGTERM") logger$9.error(`❌ Server exited with code ${code}`);
|
|
2034
1957
|
this.isRunning = false;
|
|
2035
1958
|
});
|
|
2036
1959
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
@@ -2038,13 +1961,13 @@ var DevServer = class {
|
|
|
2038
1961
|
const local = `http://localhost:${this.actualPort}`;
|
|
2039
1962
|
const address = this.publicUrl ? `${this.publicUrl} -> ${local}` : local;
|
|
2040
1963
|
const seconds = ((Date.now() - this.startTime) / 1e3).toFixed(1);
|
|
2041
|
-
logger$
|
|
1964
|
+
logger$9.log(`\x1b[32m✓\x1b[0m ${this.label} ready in ${seconds}s ${address}`);
|
|
2042
1965
|
const tools = this.selfServing ? [] : [
|
|
2043
1966
|
...this.enableOpenApi ? ["docs /__docs"] : [],
|
|
2044
1967
|
...this.telescope ? [`telescope ${this.telescope.path}`] : [],
|
|
2045
1968
|
...this.studio ? [`studio ${this.studio.path}`] : []
|
|
2046
1969
|
];
|
|
2047
|
-
if (tools.length > 0) logger$
|
|
1970
|
+
if (tools.length > 0) logger$9.log(` ${tools.join(" · ")}`);
|
|
2048
1971
|
}
|
|
2049
1972
|
}
|
|
2050
1973
|
async stop() {
|
|
@@ -2082,7 +2005,7 @@ var DevServer = class {
|
|
|
2082
2005
|
}
|
|
2083
2006
|
async createServerEntry() {
|
|
2084
2007
|
const { writeFile: fsWriteFile } = await import("node:fs/promises");
|
|
2085
|
-
await fsWriteFile((0, node_path.join)(this.appRoot, ".gkm",
|
|
2008
|
+
await fsWriteFile((0, node_path.join)(this.appRoot, ".gkm", "server", "server.ts"), generateServerEntryContent({
|
|
2086
2009
|
secretsJsonPath: this.secretsJsonPath,
|
|
2087
2010
|
runtime: this.runtime,
|
|
2088
2011
|
enableOpenApi: this.enableOpenApi,
|
|
@@ -2094,22 +2017,22 @@ var DevServer = class {
|
|
|
2094
2017
|
//#region src/generators/CronGenerator.ts
|
|
2095
2018
|
var CronGenerator = class extends require_discover.ConstructGenerator {
|
|
2096
2019
|
async build(context, constructs, outputDir, options) {
|
|
2097
|
-
const
|
|
2020
|
+
const target = options?.target ?? "aws";
|
|
2098
2021
|
const logger = console;
|
|
2099
2022
|
const cronInfos = [];
|
|
2100
|
-
if (
|
|
2023
|
+
if (target === "server") {
|
|
2101
2024
|
await this.generateServerCronsFile(outputDir, constructs);
|
|
2102
2025
|
logger.log(`Generated server crons file with ${constructs.length} crons`);
|
|
2103
2026
|
return cronInfos;
|
|
2104
2027
|
}
|
|
2105
|
-
if (constructs.length === 0
|
|
2028
|
+
if (constructs.length === 0) return cronInfos;
|
|
2106
2029
|
const cronsDir = (0, node_path.join)(outputDir, "crons");
|
|
2107
2030
|
await (0, node_fs_promises.mkdir)(cronsDir, { recursive: true });
|
|
2108
2031
|
for (const { key, construct, path } of constructs) {
|
|
2109
2032
|
const handlerFile = await this.generateCronHandler(cronsDir, path.relative, key, context, construct.owner);
|
|
2110
2033
|
cronInfos.push({
|
|
2111
2034
|
name: key,
|
|
2112
|
-
handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2035
|
+
handler: (0, node_path.relative)(options?.root ?? process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2113
2036
|
schedule: construct.schedule || "rate(1 hour)",
|
|
2114
2037
|
timeout: construct.timeout,
|
|
2115
2038
|
memorySize: construct.memorySize,
|
|
@@ -2299,17 +2222,17 @@ var FunctionGenerator = class extends require_discover.ConstructGenerator {
|
|
|
2299
2222
|
return _geekmidas_constructs_functions.Function.isFunction(value);
|
|
2300
2223
|
}
|
|
2301
2224
|
async build(context, constructs, outputDir, options) {
|
|
2302
|
-
const
|
|
2225
|
+
const target = options?.target ?? "aws";
|
|
2303
2226
|
const logger = console;
|
|
2304
2227
|
const functionInfos = [];
|
|
2305
|
-
if (constructs.length === 0 ||
|
|
2228
|
+
if (constructs.length === 0 || target === "server") return functionInfos;
|
|
2306
2229
|
const functionsDir = (0, node_path.join)(outputDir, "functions");
|
|
2307
2230
|
await (0, node_fs_promises.mkdir)(functionsDir, { recursive: true });
|
|
2308
2231
|
for (const { key, construct, path } of constructs) {
|
|
2309
2232
|
const handlerFile = await this.generateFunctionHandler(functionsDir, path.relative, key, context, construct.owner);
|
|
2310
2233
|
functionInfos.push({
|
|
2311
2234
|
name: key,
|
|
2312
|
-
handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2235
|
+
handler: (0, node_path.relative)(options?.root ?? process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2313
2236
|
timeout: construct.timeout,
|
|
2314
2237
|
memorySize: construct.memorySize,
|
|
2315
2238
|
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
@@ -2353,22 +2276,22 @@ var QueueGenerator = class extends require_discover.ConstructGenerator {
|
|
|
2353
2276
|
return _geekmidas_constructs_queue.Queue.isQueue(value);
|
|
2354
2277
|
}
|
|
2355
2278
|
async build(context, constructs, outputDir, options) {
|
|
2356
|
-
const
|
|
2279
|
+
const target = options?.target ?? "aws";
|
|
2357
2280
|
const logger = console;
|
|
2358
2281
|
const queueInfos = [];
|
|
2359
|
-
if (
|
|
2282
|
+
if (target === "server") {
|
|
2360
2283
|
await this.generateServerQueuesFile(outputDir, constructs);
|
|
2361
2284
|
logger.log(`Generated server queues file with ${constructs.length} queues (polling mode)`);
|
|
2362
2285
|
return queueInfos;
|
|
2363
2286
|
}
|
|
2364
|
-
if (constructs.length === 0
|
|
2287
|
+
if (constructs.length === 0) return queueInfos;
|
|
2365
2288
|
const queuesDir = (0, node_path.join)(outputDir, "queues");
|
|
2366
2289
|
await (0, node_fs_promises.mkdir)(queuesDir, { recursive: true });
|
|
2367
2290
|
for (const { key, construct, path } of constructs) {
|
|
2368
2291
|
const handlerFile = await this.generateQueueHandler(queuesDir, path.relative, key, context, construct.owner);
|
|
2369
2292
|
queueInfos.push({
|
|
2370
2293
|
name: construct.name,
|
|
2371
|
-
handler: (0, node_path.relative)(process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2294
|
+
handler: (0, node_path.relative)(options?.root ?? process.cwd(), handlerFile).replace(/\.ts$/, ".handler"),
|
|
2372
2295
|
batchSize: construct.batchSize,
|
|
2373
2296
|
fifo: construct.fifo,
|
|
2374
2297
|
timeout: construct.timeout,
|
|
@@ -2534,217 +2457,6 @@ var TopicGenerator = class extends require_discover.ConstructGenerator {
|
|
|
2534
2457
|
}
|
|
2535
2458
|
};
|
|
2536
2459
|
//#endregion
|
|
2537
|
-
//#region src/build/manifests.ts
|
|
2538
|
-
const logger$9 = console;
|
|
2539
|
-
function isPartitioned(field) {
|
|
2540
|
-
return !Array.isArray(field);
|
|
2541
|
-
}
|
|
2542
|
-
/**
|
|
2543
|
-
* Serialize a manifest field to a TypeScript string.
|
|
2544
|
-
* Flat arrays serialize as JSON arrays, partitioned fields as objects of arrays.
|
|
2545
|
-
*/
|
|
2546
|
-
function serializeField(field, indent = 2) {
|
|
2547
|
-
if (Array.isArray(field)) return JSON.stringify(field, null, indent);
|
|
2548
|
-
return `{\n${Object.entries(field).map(([key, value]) => ` ${JSON.stringify(key)}: ${JSON.stringify(value, null, indent)}`).join(",\n")},\n }`;
|
|
2549
|
-
}
|
|
2550
|
-
/**
|
|
2551
|
-
* Count total items across a manifest field (flat or partitioned).
|
|
2552
|
-
*/
|
|
2553
|
-
function countItems(field) {
|
|
2554
|
-
if (Array.isArray(field)) return field.length;
|
|
2555
|
-
return Object.values(field).reduce((sum, arr) => sum + arr.length, 0);
|
|
2556
|
-
}
|
|
2557
|
-
/**
|
|
2558
|
-
* Generate derived types for a construct field.
|
|
2559
|
-
* @param fieldName - The field name in the manifest (e.g., 'routes')
|
|
2560
|
-
* @param typeName - The exported type name (e.g., 'Route')
|
|
2561
|
-
* @param partitioned - Whether this field is partitioned
|
|
2562
|
-
*/
|
|
2563
|
-
function generateDerivedType(fieldName, typeName, partitioned) {
|
|
2564
|
-
if (partitioned) {
|
|
2565
|
-
const partitionTypeName = `${typeName}Partition`;
|
|
2566
|
-
return [`export type ${partitionTypeName} = keyof typeof manifest.${fieldName};`, `export type ${typeName}<P extends ${partitionTypeName} = ${partitionTypeName}> = (typeof manifest.${fieldName})[P][number];`].join("\n");
|
|
2567
|
-
}
|
|
2568
|
-
return `export type ${typeName} = (typeof manifest.${fieldName})[number];`;
|
|
2569
|
-
}
|
|
2570
|
-
/** A manifest field as a flat list, whether or not it is partitioned. */
|
|
2571
|
-
function flatten(field) {
|
|
2572
|
-
return Array.isArray(field) ? field : Object.values(field).flat();
|
|
2573
|
-
}
|
|
2574
|
-
async function generateAwsManifest(outputDir, routes, functions, crons, subscribers, queues = [], topics = [], constructs = {}, backends = {}) {
|
|
2575
|
-
const manifestDir = (0, node_path.join)(outputDir, "manifest");
|
|
2576
|
-
await (0, node_fs_promises.mkdir)(manifestDir, { recursive: true });
|
|
2577
|
-
const awsRoutes = filterAllRoutes(routes);
|
|
2578
|
-
const routesPartitioned = isPartitioned(awsRoutes);
|
|
2579
|
-
const functionsPartitioned = isPartitioned(functions);
|
|
2580
|
-
const cronsPartitioned = isPartitioned(crons);
|
|
2581
|
-
const subscribersPartitioned = isPartitioned(subscribers);
|
|
2582
|
-
const queuesPartitioned = isPartitioned(queues);
|
|
2583
|
-
const topicsPartitioned = isPartitioned(topics);
|
|
2584
|
-
const awsConstructs = require_emit.withCompute(require_emit.withRoutes(constructs, flatten(awsRoutes), { perRoute: true }), {
|
|
2585
|
-
functions: flatten(functions),
|
|
2586
|
-
crons: flatten(crons),
|
|
2587
|
-
queues: flatten(queues),
|
|
2588
|
-
subscribers: flatten(subscribers)
|
|
2589
|
-
});
|
|
2590
|
-
const content = `export const manifest = {
|
|
2591
|
-
routes: ${serializeField(awsRoutes)},
|
|
2592
|
-
functions: ${serializeField(functions)},
|
|
2593
|
-
crons: ${serializeField(crons)},
|
|
2594
|
-
subscribers: ${serializeField(subscribers)},
|
|
2595
|
-
queues: ${serializeField(queues)},
|
|
2596
|
-
topics: ${serializeField(topics)},
|
|
2597
|
-
} as const;
|
|
2598
|
-
|
|
2599
|
-
/**
|
|
2600
|
-
* What the application declares, as opposed to what this build generated.
|
|
2601
|
-
*
|
|
2602
|
-
* Discovery imports application code, so it runs once here rather than in every
|
|
2603
|
-
* consumer — a deploy config calling it would evaluate the whole runtime graph
|
|
2604
|
-
* inside its own toolchain.
|
|
2605
|
-
*/
|
|
2606
|
-
export const constructs = ${JSON.stringify(awsConstructs, null, 2)} as const;
|
|
2607
|
-
|
|
2608
|
-
/**
|
|
2609
|
-
* Where the backends that are config rather than declaration resolved to.
|
|
2610
|
-
*
|
|
2611
|
-
* Recorded because they were answered twice: once by the build, which registers
|
|
2612
|
-
* exactly one cache driver, and once by a deploy, which told the provisioner
|
|
2613
|
-
* something else — leaving the running code with a URL it had no driver for.
|
|
2614
|
-
*/
|
|
2615
|
-
export const backends = ${JSON.stringify(backends, null, 2)} as const;
|
|
2616
|
-
|
|
2617
|
-
// Derived types
|
|
2618
|
-
${generateDerivedType("routes", "Route", routesPartitioned)}
|
|
2619
|
-
${generateDerivedType("functions", "Function", functionsPartitioned)}
|
|
2620
|
-
${generateDerivedType("crons", "Cron", cronsPartitioned)}
|
|
2621
|
-
${generateDerivedType("subscribers", "Subscriber", subscribersPartitioned)}
|
|
2622
|
-
${generateDerivedType("queues", "Queue", queuesPartitioned)}
|
|
2623
|
-
${generateDerivedType("topics", "Topic", topicsPartitioned)}
|
|
2624
|
-
|
|
2625
|
-
export type ConstructId = keyof typeof constructs;
|
|
2626
|
-
export type Construct<Id extends ConstructId> = (typeof constructs)[Id];
|
|
2627
|
-
|
|
2628
|
-
// Useful union types
|
|
2629
|
-
export type Authorizer = Route['authorizer'];
|
|
2630
|
-
export type HttpMethod = Route['method'];
|
|
2631
|
-
export type RoutePath = Route['path'];
|
|
2632
|
-
`;
|
|
2633
|
-
const manifestPath = (0, node_path.join)(manifestDir, "aws.ts");
|
|
2634
|
-
await (0, node_fs_promises.writeFile)(manifestPath, content);
|
|
2635
|
-
logger$9.log(`Generated AWS manifest with ${countItems(awsRoutes)} routes, ${countItems(functions)} functions, ${countItems(crons)} crons, ${countItems(subscribers)} subscribers, ${countItems(queues)} queues, ${countItems(topics)} topics`);
|
|
2636
|
-
logger$9.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
|
|
2637
|
-
}
|
|
2638
|
-
async function generateServerManifest(outputDir, appInfo, routes, subscribers, queues = [], topics = [], constructs = {}, backends = {}) {
|
|
2639
|
-
const manifestDir = (0, node_path.join)(outputDir, "manifest");
|
|
2640
|
-
await (0, node_fs_promises.mkdir)(manifestDir, { recursive: true });
|
|
2641
|
-
const serverRoutes = mapRouteMetadata(filterAllRoutes(routes));
|
|
2642
|
-
const serverSubscribers = mapSubscriberMetadata(subscribers);
|
|
2643
|
-
const serverQueues = mapQueueMetadata(queues);
|
|
2644
|
-
const serverTopics = mapTopicMetadata(topics);
|
|
2645
|
-
const routesPartitioned = isPartitioned(serverRoutes);
|
|
2646
|
-
const subscribersPartitioned = isPartitioned(serverSubscribers);
|
|
2647
|
-
const queuesPartitioned = isPartitioned(serverQueues);
|
|
2648
|
-
const topicsPartitioned = isPartitioned(serverTopics);
|
|
2649
|
-
const content = `export const manifest = {
|
|
2650
|
-
app: ${JSON.stringify(appInfo, null, 2)},
|
|
2651
|
-
routes: ${serializeField(serverRoutes)},
|
|
2652
|
-
subscribers: ${serializeField(serverSubscribers)},
|
|
2653
|
-
queues: ${serializeField(serverQueues)},
|
|
2654
|
-
topics: ${serializeField(serverTopics)},
|
|
2655
|
-
} as const;
|
|
2656
|
-
|
|
2657
|
-
/**
|
|
2658
|
-
* What the application declares, as opposed to what this build generated.
|
|
2659
|
-
*
|
|
2660
|
-
* Discovery imports application code, so it runs once in the build rather than
|
|
2661
|
-
* in every consumer — a deploy config calling it would evaluate the whole
|
|
2662
|
-
* runtime graph inside its own toolchain.
|
|
2663
|
-
*/
|
|
2664
|
-
export const constructs = ${JSON.stringify(constructs, null, 2)} as const;
|
|
2665
|
-
|
|
2666
|
-
/**
|
|
2667
|
-
* Where the backends that are config rather than declaration resolved to.
|
|
2668
|
-
*
|
|
2669
|
-
* Recorded because they were answered twice: once by the build, which registers
|
|
2670
|
-
* exactly one cache driver, and once by a deploy, which told the provisioner
|
|
2671
|
-
* something else — leaving the running code with a URL it had no driver for.
|
|
2672
|
-
*/
|
|
2673
|
-
export const backends = ${JSON.stringify(backends, null, 2)} as const;
|
|
2674
|
-
|
|
2675
|
-
// Derived types
|
|
2676
|
-
${generateDerivedType("routes", "Route", routesPartitioned)}
|
|
2677
|
-
${generateDerivedType("subscribers", "Subscriber", subscribersPartitioned)}
|
|
2678
|
-
${generateDerivedType("queues", "Queue", queuesPartitioned)}
|
|
2679
|
-
${generateDerivedType("topics", "Topic", topicsPartitioned)}
|
|
2680
|
-
|
|
2681
|
-
export type ConstructId = keyof typeof constructs;
|
|
2682
|
-
export type Construct<Id extends ConstructId> = (typeof constructs)[Id];
|
|
2683
|
-
|
|
2684
|
-
// Useful union types
|
|
2685
|
-
export type Authorizer = Route['authorizer'];
|
|
2686
|
-
export type HttpMethod = Route['method'];
|
|
2687
|
-
export type RoutePath = Route['path'];
|
|
2688
|
-
`;
|
|
2689
|
-
const manifestPath = (0, node_path.join)(manifestDir, "server.ts");
|
|
2690
|
-
await (0, node_fs_promises.writeFile)(manifestPath, content);
|
|
2691
|
-
logger$9.log(`Generated server manifest with ${countItems(serverRoutes)} routes, ${countItems(serverSubscribers)} subscribers, ${countItems(serverQueues)} queues, ${countItems(serverTopics)} topics`);
|
|
2692
|
-
logger$9.log(`Manifest: ${(0, node_path.relative)(process.cwd(), manifestPath)}`);
|
|
2693
|
-
}
|
|
2694
|
-
/**
|
|
2695
|
-
* Filter out 'ALL' method routes from a manifest field (flat or partitioned).
|
|
2696
|
-
*/
|
|
2697
|
-
function filterAllRoutes(routes) {
|
|
2698
|
-
if (Array.isArray(routes)) return routes.filter((r) => r.method !== "ALL");
|
|
2699
|
-
const result = {};
|
|
2700
|
-
for (const [partition, partitionRoutes] of Object.entries(routes)) result[partition] = partitionRoutes.filter((r) => r.method !== "ALL");
|
|
2701
|
-
return result;
|
|
2702
|
-
}
|
|
2703
|
-
/**
|
|
2704
|
-
* Map routes to server metadata (path, method, authorizer only).
|
|
2705
|
-
*/
|
|
2706
|
-
function mapRouteMetadata(routes) {
|
|
2707
|
-
const mapFn = (r) => ({
|
|
2708
|
-
path: r.path,
|
|
2709
|
-
method: r.method,
|
|
2710
|
-
authorizer: r.authorizer
|
|
2711
|
-
});
|
|
2712
|
-
if (Array.isArray(routes)) return routes.map(mapFn);
|
|
2713
|
-
const result = {};
|
|
2714
|
-
for (const [partition, partitionRoutes] of Object.entries(routes)) result[partition] = partitionRoutes.map(mapFn);
|
|
2715
|
-
return result;
|
|
2716
|
-
}
|
|
2717
|
-
/**
|
|
2718
|
-
* Map subscribers to server metadata (name, subscribedEvents only).
|
|
2719
|
-
*/
|
|
2720
|
-
function mapSubscriberMetadata(subscribers) {
|
|
2721
|
-
const mapFn = (s) => ({
|
|
2722
|
-
name: s.name,
|
|
2723
|
-
subscribedEvents: s.subscribedEvents
|
|
2724
|
-
});
|
|
2725
|
-
if (Array.isArray(subscribers)) return subscribers.map(mapFn);
|
|
2726
|
-
const result = {};
|
|
2727
|
-
for (const [partition, partitionSubs] of Object.entries(subscribers)) result[partition] = partitionSubs.map(mapFn);
|
|
2728
|
-
return result;
|
|
2729
|
-
}
|
|
2730
|
-
function mapQueueMetadata(queues) {
|
|
2731
|
-
const mapFn = (q) => ({ name: q.name });
|
|
2732
|
-
if (Array.isArray(queues)) return queues.map(mapFn);
|
|
2733
|
-
const result = {};
|
|
2734
|
-
for (const [partition, partitionQueues] of Object.entries(queues)) result[partition] = partitionQueues.map(mapFn);
|
|
2735
|
-
return result;
|
|
2736
|
-
}
|
|
2737
|
-
function mapTopicMetadata(topics) {
|
|
2738
|
-
const mapFn = (t) => ({
|
|
2739
|
-
name: t.name,
|
|
2740
|
-
events: t.events
|
|
2741
|
-
});
|
|
2742
|
-
if (Array.isArray(topics)) return topics.map(mapFn);
|
|
2743
|
-
const result = {};
|
|
2744
|
-
for (const [partition, partitionTopics] of Object.entries(topics)) result[partition] = partitionTopics.map(mapFn);
|
|
2745
|
-
return result;
|
|
2746
|
-
}
|
|
2747
|
-
//#endregion
|
|
2748
2460
|
//#region src/build/owners.ts
|
|
2749
2461
|
/**
|
|
2750
2462
|
* What a generated entry imports its runtime from, read off the discovered
|
|
@@ -2814,27 +2526,6 @@ function restApis(declared) {
|
|
|
2814
2526
|
function servedSurface(declared, workspaceRoot, appRoot) {
|
|
2815
2527
|
return restApis(declared).find((d) => (0, node_path.resolve)(workspaceRoot, d.path) === (0, node_path.resolve)(appRoot));
|
|
2816
2528
|
}
|
|
2817
|
-
/**
|
|
2818
|
-
* Check if any construct across the given arrays has a non-undefined partition.
|
|
2819
|
-
* When true, the manifest should use the partitioned shape for that construct type.
|
|
2820
|
-
*/
|
|
2821
|
-
function hasPartitions(constructs) {
|
|
2822
|
-
return constructs.some((c) => c.partition !== void 0);
|
|
2823
|
-
}
|
|
2824
|
-
/**
|
|
2825
|
-
* Group an info array by partition, using the partition values from
|
|
2826
|
-
* the corresponding construct array. Both arrays must be the same length
|
|
2827
|
-
* and in the same order.
|
|
2828
|
-
*/
|
|
2829
|
-
function groupInfosByPartition(infos, constructs) {
|
|
2830
|
-
const groups = {};
|
|
2831
|
-
for (let i = 0; i < infos.length; i++) {
|
|
2832
|
-
const partition = constructs[i]?.partition ?? "default";
|
|
2833
|
-
if (!groups[partition]) groups[partition] = [];
|
|
2834
|
-
groups[partition].push(infos[i]);
|
|
2835
|
-
}
|
|
2836
|
-
return groups;
|
|
2837
|
-
}
|
|
2838
2529
|
//#endregion
|
|
2839
2530
|
//#region src/build/surfaceEntry.ts
|
|
2840
2531
|
/** Whether a construct serves itself, asked of the construct. */
|
|
@@ -2911,6 +2602,24 @@ function rootGkmConfig(workspace) {
|
|
|
2911
2602
|
constructs: require_workspace.allConstructGlobs(workspace)
|
|
2912
2603
|
};
|
|
2913
2604
|
}
|
|
2605
|
+
/** Directories under `.gkm/` that the removed per-provider builds wrote. */
|
|
2606
|
+
const SUPERSEDED_OUTPUT = [
|
|
2607
|
+
"aws-apigatewayv1",
|
|
2608
|
+
"aws-apigatewayv2",
|
|
2609
|
+
"aws-lambda"
|
|
2610
|
+
];
|
|
2611
|
+
/** Whether `--provider` named something a build can target. */
|
|
2612
|
+
function isMainProvider(value) {
|
|
2613
|
+
return value === "aws" || value === "server";
|
|
2614
|
+
}
|
|
2615
|
+
var UnknownBuildProvider = class extends Error {
|
|
2616
|
+
provider;
|
|
2617
|
+
constructor(provider) {
|
|
2618
|
+
super(`'${provider}' is not a build target. Pass --provider aws or --provider server, or leave it out to build for where gkm.config.ts deploys.`);
|
|
2619
|
+
this.provider = provider;
|
|
2620
|
+
this.name = "UnknownBuildProvider";
|
|
2621
|
+
}
|
|
2622
|
+
};
|
|
2914
2623
|
async function buildCommand(options) {
|
|
2915
2624
|
const loadedConfig = await require_config.loadWorkspaceConfig();
|
|
2916
2625
|
if (loadedConfig.type === "workspace") {
|
|
@@ -2924,25 +2633,62 @@ async function buildCommand(options) {
|
|
|
2924
2633
|
}
|
|
2925
2634
|
}
|
|
2926
2635
|
const config = loadedConfig.type !== "workspace" ? await require_config.loadConfig() : (0, node_path.resolve)(process.cwd()) === (0, node_path.resolve)(loadedConfig.workspace.root) ? rootGkmConfig(loadedConfig.workspace) : (await require_config.loadAppConfig()).gkmConfig;
|
|
2927
|
-
const
|
|
2928
|
-
const
|
|
2929
|
-
const
|
|
2930
|
-
const
|
|
2636
|
+
const target = options.provider ?? require_workspace$1.providerOf(loadedConfig.workspace);
|
|
2637
|
+
const workspaceRoot = loadedConfig.workspace.root;
|
|
2638
|
+
const appRoot = process.cwd();
|
|
2639
|
+
const output = await buildOneApp({
|
|
2640
|
+
config,
|
|
2641
|
+
options,
|
|
2642
|
+
workspace: loadedConfig.workspace,
|
|
2643
|
+
appRoot,
|
|
2644
|
+
target
|
|
2645
|
+
});
|
|
2646
|
+
if ((0, node_path.resolve)(appRoot) === (0, node_path.resolve)(workspaceRoot)) await writeManifest({
|
|
2647
|
+
workspaceRoot,
|
|
2648
|
+
target,
|
|
2649
|
+
builds: output.built ? [output.built] : [],
|
|
2650
|
+
constructs: await declaredIn(config, workspaceRoot),
|
|
2651
|
+
backends: backendsOf(loadedConfig.workspace)
|
|
2652
|
+
});
|
|
2653
|
+
return output;
|
|
2654
|
+
}
|
|
2655
|
+
/** What the workspace declares, read through a config's globs. */
|
|
2656
|
+
async function declaredIn(config, cwd) {
|
|
2657
|
+
return require_discover.discover({
|
|
2658
|
+
patterns: config.constructs,
|
|
2659
|
+
cwd
|
|
2660
|
+
});
|
|
2661
|
+
}
|
|
2662
|
+
/**
|
|
2663
|
+
* The backend choices the manifest records — answered by the deploy target,
|
|
2664
|
+
* the same place reconcile and the build's drivers read them.
|
|
2665
|
+
*/
|
|
2666
|
+
function backendsOf(workspace) {
|
|
2667
|
+
return {
|
|
2668
|
+
cache: require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(workspace)),
|
|
2669
|
+
email: "ses"
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2672
|
+
/** One app's build, from its config and the command's options. */
|
|
2673
|
+
async function buildOneApp(input) {
|
|
2674
|
+
const { config, options, workspace, appRoot, target } = input;
|
|
2675
|
+
const cacheBackend = require_workspace$1.cacheBackendFor(require_workspace$1.providerOf(workspace));
|
|
2676
|
+
const production = normalizeProductionConfig(options.production ?? false);
|
|
2931
2677
|
if (production) logger$8.log(`🏭 Building for PRODUCTION`);
|
|
2932
|
-
logger$8.log(`Building
|
|
2678
|
+
logger$8.log(`Building for ${target}`);
|
|
2933
2679
|
logger$8.log(`Loading constructs from: ${formatRoutes(config.constructs)}`);
|
|
2934
2680
|
const telescope = production ? void 0 : normalizeTelescopeConfig(config.telescope);
|
|
2935
2681
|
if (telescope) logger$8.log(`🔭 Telescope enabled at ${telescope.path}`);
|
|
2936
2682
|
const studio = production ? void 0 : normalizeStudioConfig(config.studio);
|
|
2937
2683
|
if (studio) logger$8.log(`🗄️ Studio enabled at ${studio.path}`);
|
|
2938
|
-
const hooks = normalizeHooksConfig(config.hooks);
|
|
2684
|
+
const hooks = normalizeHooksConfig(config.hooks, appRoot);
|
|
2939
2685
|
if (hooks) logger$8.log(`🪝 Server hooks enabled`);
|
|
2940
2686
|
return buildApp({
|
|
2941
2687
|
config,
|
|
2942
|
-
workspaceRoot:
|
|
2943
|
-
appRoot
|
|
2944
|
-
|
|
2945
|
-
enableOpenApi:
|
|
2688
|
+
workspaceRoot: workspace.root,
|
|
2689
|
+
appRoot,
|
|
2690
|
+
target,
|
|
2691
|
+
enableOpenApi: options.enableOpenApi ?? false,
|
|
2946
2692
|
cacheBackend,
|
|
2947
2693
|
production,
|
|
2948
2694
|
telescope,
|
|
@@ -2954,6 +2700,33 @@ async function buildCommand(options) {
|
|
|
2954
2700
|
});
|
|
2955
2701
|
}
|
|
2956
2702
|
/**
|
|
2703
|
+
* Write the application's manifest: every declared construct, with what each
|
|
2704
|
+
* app generated folded into it.
|
|
2705
|
+
*
|
|
2706
|
+
* The manifest belongs to the whole application, so only the root writes it —
|
|
2707
|
+
* once, after every app has built, from the constructs the workspace declares.
|
|
2708
|
+
* An app's own build generates its handlers and nothing else.
|
|
2709
|
+
*/
|
|
2710
|
+
async function writeManifest(input) {
|
|
2711
|
+
const { workspaceRoot, target, builds, constructs, backends } = input;
|
|
2712
|
+
const manifestDir = (0, node_path.join)(workspaceRoot, ".gkm", "manifest");
|
|
2713
|
+
await (0, node_fs_promises.mkdir)(manifestDir, { recursive: true });
|
|
2714
|
+
await (0, node_fs_promises.rm)((0, node_path.join)(manifestDir, `${target === "aws" ? "server" : "aws"}.ts`), { force: true });
|
|
2715
|
+
const withServed = builds.reduce((manifest, build) => require_emit.withRoutes(manifest, build.routes.filter((route) => route.method !== "ALL"), {
|
|
2716
|
+
perRoute: true,
|
|
2717
|
+
...build.surface ? { surface: build.surface } : {}
|
|
2718
|
+
}), constructs);
|
|
2719
|
+
const folded = require_emit.withCompute(withServed, {
|
|
2720
|
+
functions: builds.flatMap((build) => build.functions),
|
|
2721
|
+
crons: builds.flatMap((build) => build.crons),
|
|
2722
|
+
queues: builds.flatMap((build) => build.queues),
|
|
2723
|
+
subscribers: builds.flatMap((build) => build.subscribers)
|
|
2724
|
+
});
|
|
2725
|
+
const path = (0, node_path.join)(manifestDir, `${target}.ts`);
|
|
2726
|
+
await (0, node_fs_promises.writeFile)(path, require_emit.manifestModule(folded, backends));
|
|
2727
|
+
logger$8.log(`Manifest: ${(0, node_path.relative)(process.cwd(), path)}`);
|
|
2728
|
+
}
|
|
2729
|
+
/**
|
|
2957
2730
|
* Turn one app's constructs into its generated entry.
|
|
2958
2731
|
*
|
|
2959
2732
|
* `gkm build` and `gkm dev` both run this. They used to be two copies of it,
|
|
@@ -2962,8 +2735,8 @@ async function buildCommand(options) {
|
|
|
2962
2735
|
* dev did not, and failed on exactly the apps the build had learned to handle.
|
|
2963
2736
|
*/
|
|
2964
2737
|
async function buildApp(input) {
|
|
2965
|
-
const { config, workspaceRoot, appRoot,
|
|
2966
|
-
const constructGlobs =
|
|
2738
|
+
const { config, workspaceRoot, appRoot, target, enableOpenApi, cacheBackend, production, telescope, studio, hooks, bustCache = false } = input;
|
|
2739
|
+
const constructGlobs = config.constructs;
|
|
2967
2740
|
const constructSources = {};
|
|
2968
2741
|
const declared = constructGlobs ? await require_discover.discover({
|
|
2969
2742
|
patterns: constructGlobs,
|
|
@@ -3029,50 +2802,58 @@ async function buildApp(input) {
|
|
|
3029
2802
|
logger$8.log("No endpoints, functions, crons, subscribers, queues, or topics found to process");
|
|
3030
2803
|
return {};
|
|
3031
2804
|
}
|
|
3032
|
-
const
|
|
3033
|
-
await (0, node_fs_promises.mkdir)(rootOutputDir, { recursive: true });
|
|
3034
|
-
let result = {};
|
|
3035
|
-
for (const provider of providers) {
|
|
3036
|
-
const providerResult = await buildForProvider(provider, buildContext, appRoot, declared, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, queueGenerator, topicGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, allQueues, allTopics, enableOpenApi, input.skipBundle ?? false, input.stage);
|
|
3037
|
-
if (providerResult.masterKey) result = providerResult;
|
|
3038
|
-
}
|
|
2805
|
+
const result = await buildForTarget(target, buildContext, appRoot, workspaceRoot, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, queueGenerator, topicGenerator, allEndpoints, allFunctions, allCrons, allSubscribers, allQueues, allTopics, enableOpenApi, input.skipBundle ?? false, input.stage);
|
|
3039
2806
|
await require_openapi.generateOpenApi(allEndpoints.map(({ construct }) => construct), { openapi: config.openapi });
|
|
3040
2807
|
return result;
|
|
3041
2808
|
}
|
|
3042
|
-
async function
|
|
3043
|
-
const
|
|
3044
|
-
|
|
2809
|
+
async function buildForTarget(target, context, appRoot, workspaceRoot, endpointGenerator, functionGenerator, cronGenerator, subscriberGenerator, queueGenerator, topicGenerator, endpoints, functions, crons, subscribers, queues, topics, enableOpenApi, skipBundle, stage) {
|
|
2810
|
+
const outputDir = (0, node_path.join)(appRoot, ".gkm", target);
|
|
2811
|
+
await Promise.all([...SUPERSEDED_OUTPUT.map((dir) => (0, node_path.join)(appRoot, ".gkm", dir)), ...appRoot === workspaceRoot ? [] : [(0, node_path.join)(appRoot, ".gkm", "manifest")]].map((dir) => (0, node_fs_promises.rm)(dir, {
|
|
2812
|
+
recursive: true,
|
|
2813
|
+
force: true
|
|
2814
|
+
})));
|
|
2815
|
+
if (target === "aws") await (0, node_fs_promises.rm)(outputDir, {
|
|
2816
|
+
recursive: true,
|
|
2817
|
+
force: true
|
|
2818
|
+
});
|
|
3045
2819
|
await (0, node_fs_promises.mkdir)(outputDir, { recursive: true });
|
|
3046
|
-
logger$8.log(`\nGenerating handlers for
|
|
2820
|
+
logger$8.log(`\nGenerating handlers for ${target}`);
|
|
2821
|
+
const options = {
|
|
2822
|
+
target,
|
|
2823
|
+
root: workspaceRoot
|
|
2824
|
+
};
|
|
3047
2825
|
const [routes, functionInfos, cronInfos, subscriberInfos, queueInfos, topicInfos] = await Promise.all([
|
|
3048
2826
|
endpointGenerator.build(context, endpoints, outputDir, {
|
|
3049
|
-
|
|
2827
|
+
...options,
|
|
3050
2828
|
enableOpenApi
|
|
3051
2829
|
}),
|
|
3052
|
-
functionGenerator.build(context, functions, outputDir,
|
|
3053
|
-
cronGenerator.build(context, crons, outputDir,
|
|
3054
|
-
subscriberGenerator.build(context, subscribers, outputDir,
|
|
3055
|
-
queueGenerator.build(context, queues, outputDir,
|
|
3056
|
-
topicGenerator.build(context, topics, outputDir,
|
|
2830
|
+
functionGenerator.build(context, functions, outputDir, options),
|
|
2831
|
+
cronGenerator.build(context, crons, outputDir, options),
|
|
2832
|
+
subscriberGenerator.build(context, subscribers, outputDir, options),
|
|
2833
|
+
queueGenerator.build(context, queues, outputDir, options),
|
|
2834
|
+
topicGenerator.build(context, topics, outputDir, options)
|
|
3057
2835
|
]);
|
|
3058
|
-
logger$8.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers, ${queueInfos.length} queues, ${topicInfos.length} topics for ${
|
|
3059
|
-
const
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
2836
|
+
logger$8.log(`Generated ${routes.length} routes, ${functionInfos.length} functions, ${cronInfos.length} crons, ${subscriberInfos.length} subscribers, ${queueInfos.length} queues, ${topicInfos.length} topics for ${target}`);
|
|
2837
|
+
const fields = {
|
|
2838
|
+
...context.surface ? { surface: context.surface.id } : {},
|
|
2839
|
+
functions: functionInfos,
|
|
2840
|
+
crons: cronInfos,
|
|
2841
|
+
queues: queueInfos,
|
|
2842
|
+
subscribers: subscriberInfos
|
|
2843
|
+
};
|
|
2844
|
+
if (target === "server") {
|
|
2845
|
+
const handler = (0, node_path.relative)(workspaceRoot, (0, node_path.join)(outputDir, "app.ts"));
|
|
2846
|
+
const built = {
|
|
2847
|
+
...fields,
|
|
2848
|
+
routes: await Promise.all(endpoints.map(async ({ construct }) => ({
|
|
2849
|
+
path: construct._path,
|
|
2850
|
+
method: construct.method,
|
|
2851
|
+
handler,
|
|
2852
|
+
environment: await construct.getEnvironment({ markOptional: context.markOptional }),
|
|
2853
|
+
dependencies: construct.constructs,
|
|
2854
|
+
authorizer: construct.authorizer?.name ?? "none"
|
|
2855
|
+
})))
|
|
2856
|
+
};
|
|
3076
2857
|
let masterKey;
|
|
3077
2858
|
if (context.production?.bundle && !skipBundle) {
|
|
3078
2859
|
logger$8.log(`\n📦 Bundling production server...`);
|
|
@@ -3099,12 +2880,15 @@ async function buildForProvider(provider, context, appRoot, discovered, endpoint
|
|
|
3099
2880
|
logger$8.log(` Deploy with: GKM_MASTER_KEY=${masterKey}`);
|
|
3100
2881
|
}
|
|
3101
2882
|
}
|
|
3102
|
-
return {
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
}
|
|
3107
|
-
return {
|
|
2883
|
+
return {
|
|
2884
|
+
masterKey,
|
|
2885
|
+
built
|
|
2886
|
+
};
|
|
2887
|
+
}
|
|
2888
|
+
return { built: {
|
|
2889
|
+
...fields,
|
|
2890
|
+
routes
|
|
2891
|
+
} };
|
|
3108
2892
|
}
|
|
3109
2893
|
/**
|
|
3110
2894
|
* Detect available package manager.
|
|
@@ -3126,8 +2910,8 @@ function detectPackageManager$2() {
|
|
|
3126
2910
|
*
|
|
3127
2911
|
* @internal Exported for testing
|
|
3128
2912
|
*/
|
|
3129
|
-
function getTurboCommand(pm, filters = []) {
|
|
3130
|
-
const filterArgs = (typeof filters === "string" ? [filters] : filters).map((f) => ` --filter=${f}`).join("");
|
|
2913
|
+
function getTurboCommand(pm, filters = [], { only = false } = {}) {
|
|
2914
|
+
const filterArgs = (typeof filters === "string" ? [filters] : filters).map((f) => ` --filter=${f}`).join("") + (only ? " --only" : "");
|
|
3131
2915
|
switch (pm) {
|
|
3132
2916
|
case "pnpm": return `pnpm exec turbo run build${filterArgs}`;
|
|
3133
2917
|
case "yarn": return `yarn turbo run build${filterArgs}`;
|
|
@@ -3147,10 +2931,11 @@ function getTurboCommand(pm, filters = []) {
|
|
|
3147
2931
|
*
|
|
3148
2932
|
* @internal Exported for testing
|
|
3149
2933
|
*/
|
|
3150
|
-
function turboFilters(workspace) {
|
|
2934
|
+
function turboFilters(workspace, { exclude } = {}) {
|
|
3151
2935
|
const filters = [];
|
|
3152
2936
|
const unpackaged = [];
|
|
3153
|
-
for (const appName of Object.
|
|
2937
|
+
for (const [appName, app] of Object.entries(workspace.apps)) {
|
|
2938
|
+
if (app.type === exclude) continue;
|
|
3154
2939
|
const name = appPackageName(workspace, appName);
|
|
3155
2940
|
if (name) filters.push(name);
|
|
3156
2941
|
else unpackaged.push(appName);
|
|
@@ -3189,31 +2974,59 @@ async function workspaceBuildCommand(workspace, options) {
|
|
|
3189
2974
|
if (options.production) logger$8.log(` 🏭 Production mode enabled`);
|
|
3190
2975
|
const buildOrder = require_workspace.getAppBuildOrder(workspace);
|
|
3191
2976
|
logger$8.log(` Build order: ${buildOrder.join(" → ")}`);
|
|
3192
|
-
const pm = detectPackageManager$2();
|
|
3193
|
-
logger$8.log(`\n📦 Using ${pm} with Turbo for parallel builds...\n`);
|
|
3194
2977
|
try {
|
|
3195
|
-
const
|
|
3196
|
-
|
|
3197
|
-
const
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
});
|
|
3209
|
-
child.on("close", (code) => {
|
|
3210
|
-
if (code === 0) resolve();
|
|
3211
|
-
else reject(/* @__PURE__ */ new Error(`Turbo build failed with exit code ${code}`));
|
|
3212
|
-
});
|
|
3213
|
-
child.on("error", (err) => {
|
|
3214
|
-
reject(err);
|
|
2978
|
+
const target = options.provider ?? require_workspace$1.providerOf(workspace);
|
|
2979
|
+
const builds = [];
|
|
2980
|
+
for (const appName of buildOrder) {
|
|
2981
|
+
const app = workspace.apps[appName];
|
|
2982
|
+
const config = require_workspace.getAppGkmConfig(workspace, appName);
|
|
2983
|
+
if (!app || app.type !== "backend" || !config) continue;
|
|
2984
|
+
logger$8.log(`\n⚙️ ${appName}`);
|
|
2985
|
+
const output = await buildOneApp({
|
|
2986
|
+
config,
|
|
2987
|
+
options,
|
|
2988
|
+
workspace,
|
|
2989
|
+
appRoot: (0, node_path.join)(workspace.root, app.path),
|
|
2990
|
+
target
|
|
3215
2991
|
});
|
|
2992
|
+
if (output.built) builds.push(output.built);
|
|
2993
|
+
}
|
|
2994
|
+
await writeManifest({
|
|
2995
|
+
workspaceRoot: workspace.root,
|
|
2996
|
+
target,
|
|
2997
|
+
builds,
|
|
2998
|
+
constructs: await require_discover.discover({
|
|
2999
|
+
patterns: require_workspace.allConstructGlobs(workspace),
|
|
3000
|
+
cwd: workspace.root
|
|
3001
|
+
}),
|
|
3002
|
+
backends: backendsOf(workspace)
|
|
3216
3003
|
});
|
|
3004
|
+
const { filters, unpackaged } = turboFilters(workspace, { exclude: "backend" });
|
|
3005
|
+
if (unpackaged.length > 0) throw new Error(`No package.json for workspace app(s): ${unpackaged.join(", ")}. Each app needs one — turbo builds packages, and gkm reads the name back to know which app it is building.`);
|
|
3006
|
+
const pm = detectPackageManager$2();
|
|
3007
|
+
const turboCommand = getTurboCommand(pm, filters, { only: true });
|
|
3008
|
+
if (filters.length > 0) {
|
|
3009
|
+
logger$8.log(`\n📦 Using ${pm} with Turbo for the other apps...\n`);
|
|
3010
|
+
logger$8.log(`Running: ${turboCommand}`);
|
|
3011
|
+
await new Promise((resolve, reject) => {
|
|
3012
|
+
const child = (0, node_child_process.spawn)(turboCommand, {
|
|
3013
|
+
shell: true,
|
|
3014
|
+
cwd: workspace.root,
|
|
3015
|
+
stdio: "inherit",
|
|
3016
|
+
env: {
|
|
3017
|
+
...process.env,
|
|
3018
|
+
NODE_ENV: options.production ? "production" : "development"
|
|
3019
|
+
}
|
|
3020
|
+
});
|
|
3021
|
+
child.on("close", (code) => {
|
|
3022
|
+
if (code === 0) resolve();
|
|
3023
|
+
else reject(/* @__PURE__ */ new Error(`Turbo build failed with exit code ${code}`));
|
|
3024
|
+
});
|
|
3025
|
+
child.on("error", (err) => {
|
|
3026
|
+
reject(err);
|
|
3027
|
+
});
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3217
3030
|
for (const [appName, app] of apps) {
|
|
3218
3031
|
const outputPath = getAppOutputPath(workspace, appName, app);
|
|
3219
3032
|
results.push({
|
|
@@ -3256,23 +3069,11 @@ function getAppOutputPath(workspace, _appName, app) {
|
|
|
3256
3069
|
}
|
|
3257
3070
|
return (0, node_path.join)(appPath, ".gkm");
|
|
3258
3071
|
}
|
|
3259
|
-
/**
|
|
3260
|
-
* Format routes for logging, handling PartitionedRoutes.
|
|
3261
|
-
*/
|
|
3072
|
+
/** Format routes for logging. */
|
|
3262
3073
|
function formatRoutes(routes) {
|
|
3263
|
-
if (require_discover.isPartitionedRoutes(routes)) return `${Array.isArray(routes.paths) ? routes.paths.join(", ") : routes.paths} (partitioned)`;
|
|
3264
3074
|
return Array.isArray(routes) ? routes.join(", ") : routes;
|
|
3265
3075
|
}
|
|
3266
3076
|
/**
|
|
3267
|
-
* Assemble a ManifestField from build infos and constructs.
|
|
3268
|
-
* If any construct has a partition, returns a Record<string, T[]>.
|
|
3269
|
-
* Otherwise, returns a flat T[].
|
|
3270
|
-
*/
|
|
3271
|
-
function assembleManifestField(infos, constructs) {
|
|
3272
|
-
if (!hasPartitions(constructs)) return infos;
|
|
3273
|
-
return groupInfosByPartition(infos, constructs);
|
|
3274
|
-
}
|
|
3275
|
-
/**
|
|
3276
3077
|
* Format a fatal error for display.
|
|
3277
3078
|
* Always includes the full stack trace since these are process-ending errors.
|
|
3278
3079
|
*/
|
|
@@ -5424,9 +5225,8 @@ async function dockerCommand(options) {
|
|
|
5424
5225
|
logger$6.log("📦 Detected workspace configuration");
|
|
5425
5226
|
return workspaceDockerCommand(loadedConfig.workspace);
|
|
5426
5227
|
}
|
|
5427
|
-
const
|
|
5428
|
-
const
|
|
5429
|
-
const healthCheckPath = (typeof config.providers?.server === "object" ? config.providers.server : void 0)?.production?.healthCheck ?? "/health";
|
|
5228
|
+
const dockerConfig = resolveDockerConfig(await require_config.loadConfig());
|
|
5229
|
+
const healthCheckPath = "/health";
|
|
5430
5230
|
const useSlim = options.slim === true;
|
|
5431
5231
|
if (useSlim) {
|
|
5432
5232
|
const distDir = (0, node_path.join)(process.cwd(), ".gkm", "server", "dist");
|
|
@@ -7432,6 +7232,10 @@ async function workspaceDeployCommand(configured, options) {
|
|
|
7432
7232
|
} else logger$4.log(` Deploying all apps: ${appsToDeployNames.join(", ")}`);
|
|
7433
7233
|
const dokployApps = appsToDeployNames.filter((name) => {
|
|
7434
7234
|
const target = workspace.apps[name].resolvedDeployTarget;
|
|
7235
|
+
if (target === "sst") {
|
|
7236
|
+
logger$4.log(` ⚠️ Skipping ${name}: it deploys with SST — run \`gkm build && sst deploy --stage ${stage}\``);
|
|
7237
|
+
return false;
|
|
7238
|
+
}
|
|
7435
7239
|
if (!require_workspace.isDeployTargetSupported(target)) {
|
|
7436
7240
|
logger$4.log(` ⚠️ Skipping ${name}: ${require_workspace.getDeployTargetError(target, name)}`);
|
|
7437
7241
|
return false;
|
|
@@ -7952,66 +7756,6 @@ async function createApi(endpoint) {
|
|
|
7952
7756
|
});
|
|
7953
7757
|
}
|
|
7954
7758
|
/**
|
|
7955
|
-
* Update gkm.config.ts with Dokploy configuration
|
|
7956
|
-
*/
|
|
7957
|
-
/**
|
|
7958
|
-
* Whether the file's `dokploy` block is more than a flat literal.
|
|
7959
|
-
*
|
|
7960
|
-
* A spread, a `process.env`, a ternary or a nested object all defeat the
|
|
7961
|
-
* single-level regex below — the first two by being expressions it would
|
|
7962
|
-
* stringify away, the last by ending the match at the wrong brace.
|
|
7963
|
-
*/
|
|
7964
|
-
function unsafeToRewrite(content) {
|
|
7965
|
-
const start = content.indexOf("dokploy:");
|
|
7966
|
-
if (start === -1) return false;
|
|
7967
|
-
const block = content.slice(start, content.indexOf("\n },", start) + 1);
|
|
7968
|
-
return /\.\.\.|process\.env|\?\s|`|\{[^}]*\{/s.test(block);
|
|
7969
|
-
}
|
|
7970
|
-
async function updateConfig(config, cwd = process.cwd()) {
|
|
7971
|
-
const configPath = (0, node_path.join)(cwd, "gkm.config.ts");
|
|
7972
|
-
if (!(0, node_fs.existsSync)(configPath)) {
|
|
7973
|
-
logger$3.warn("\n gkm.config.ts not found. Add this configuration manually:\n");
|
|
7974
|
-
logger$3.log(` providers: {`);
|
|
7975
|
-
logger$3.log(` dokploy: {`);
|
|
7976
|
-
logger$3.log(` endpoint: '${config.endpoint}',`);
|
|
7977
|
-
logger$3.log(` projectId: '${config.projectId}',`);
|
|
7978
|
-
logger$3.log(` applicationId: '${config.applicationId}',`);
|
|
7979
|
-
logger$3.log(` },`);
|
|
7980
|
-
logger$3.log(` },`);
|
|
7981
|
-
return;
|
|
7982
|
-
}
|
|
7983
|
-
const content = await (0, node_fs_promises.readFile)(configPath, "utf-8");
|
|
7984
|
-
if (unsafeToRewrite(content)) {
|
|
7985
|
-
logger$3.warn("\n gkm.config.ts holds a dokploy block this cannot safely rewrite —\n it contains an expression or a nested object. Leaving it alone.");
|
|
7986
|
-
logger$3.log(`\n Discovered, if you want them written down:`);
|
|
7987
|
-
logger$3.log(` projectId: '${config.projectId}'`);
|
|
7988
|
-
logger$3.log(` applicationId: '${config.applicationId}'`);
|
|
7989
|
-
if (config.registryId) logger$3.log(` registryId: '${config.registryId}'`);
|
|
7990
|
-
return;
|
|
7991
|
-
}
|
|
7992
|
-
if (content.includes("dokploy:") && content.includes("applicationId:")) {
|
|
7993
|
-
logger$3.log("\n Dokploy config already exists in gkm.config.ts");
|
|
7994
|
-
logger$3.log(" Updating with new values...");
|
|
7995
|
-
}
|
|
7996
|
-
const registryLine = config.registryId ? `\n\t\t\tregistryId: '${config.registryId}',` : "";
|
|
7997
|
-
const dokployConfigStr = `dokploy: {
|
|
7998
|
-
endpoint: '${config.endpoint}',
|
|
7999
|
-
projectId: '${config.projectId}',
|
|
8000
|
-
applicationId: '${config.applicationId}',${registryLine}
|
|
8001
|
-
}`;
|
|
8002
|
-
let newContent;
|
|
8003
|
-
if (content.includes("providers:")) {
|
|
8004
|
-
if (content.includes("dokploy:")) newContent = content.replace(/dokploy:\s*\{[^}]*\}/s, dokployConfigStr);
|
|
8005
|
-
else newContent = content.replace(/providers:\s*\{/, `providers: {\n\t\t${dokployConfigStr},`);
|
|
8006
|
-
} else newContent = content.replace(/}\s*\)\s*;?\s*$/, `
|
|
8007
|
-
providers: {
|
|
8008
|
-
${dokployConfigStr},
|
|
8009
|
-
},
|
|
8010
|
-
});`);
|
|
8011
|
-
await (0, node_fs_promises.writeFile)(configPath, newContent);
|
|
8012
|
-
logger$3.log("\n ✓ Updated gkm.config.ts with Dokploy configuration");
|
|
8013
|
-
}
|
|
8014
|
-
/**
|
|
8015
7759
|
* Initialize Dokploy deployment configuration
|
|
8016
7760
|
*/
|
|
8017
7761
|
async function deployInitCommand(options) {
|
|
@@ -8064,7 +7808,6 @@ async function deployInitCommand(options) {
|
|
|
8064
7808
|
projectId,
|
|
8065
7809
|
applicationId: application.applicationId
|
|
8066
7810
|
};
|
|
8067
|
-
await updateConfig(config);
|
|
8068
7811
|
logger$3.log(`\n✅ Dokploy deployment initialized!`);
|
|
8069
7812
|
logger$3.log(`\n📋 Configuration:`);
|
|
8070
7813
|
logger$3.log(` Project ID: ${projectId}`);
|
|
@@ -9334,26 +9077,26 @@ function loadPackageJson() {
|
|
|
9334
9077
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
9335
9078
|
*/
|
|
9336
9079
|
const GEEKMIDAS_VERSIONS = {
|
|
9337
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
9338
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
9339
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
9340
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
9341
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
9342
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
9343
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
9344
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
9345
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
9346
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
9347
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
9348
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
9349
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
9350
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
9351
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
9352
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
9353
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
9354
|
-
"@geekmidas/studio": "~10.0.0-alpha.
|
|
9355
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
9356
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
9080
|
+
"@geekmidas/audit": "~10.0.0-alpha.46",
|
|
9081
|
+
"@geekmidas/auth": "~10.0.0-alpha.46",
|
|
9082
|
+
"@geekmidas/cache": "~10.0.0-alpha.46",
|
|
9083
|
+
"@geekmidas/client": "~10.0.0-alpha.46",
|
|
9084
|
+
"@geekmidas/cloud": "~10.0.0-alpha.46",
|
|
9085
|
+
"@geekmidas/constructs": "~10.0.0-alpha.46",
|
|
9086
|
+
"@geekmidas/db": "~10.0.0-alpha.46",
|
|
9087
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.46",
|
|
9088
|
+
"@geekmidas/envkit": "~10.0.0-alpha.46",
|
|
9089
|
+
"@geekmidas/errors": "~10.0.0-alpha.46",
|
|
9090
|
+
"@geekmidas/events": "~10.0.0-alpha.46",
|
|
9091
|
+
"@geekmidas/logger": "~10.0.0-alpha.46",
|
|
9092
|
+
"@geekmidas/manifest": "~10.0.0-alpha.46",
|
|
9093
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.46",
|
|
9094
|
+
"@geekmidas/schema": "~10.0.0-alpha.46",
|
|
9095
|
+
"@geekmidas/services": "~10.0.0-alpha.46",
|
|
9096
|
+
"@geekmidas/storage": "~10.0.0-alpha.46",
|
|
9097
|
+
"@geekmidas/studio": "~10.0.0-alpha.46",
|
|
9098
|
+
"@geekmidas/telescope": "~10.0.0-alpha.46",
|
|
9099
|
+
"@geekmidas/testkit": "~10.0.0-alpha.46",
|
|
9357
9100
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
9358
9101
|
};
|
|
9359
9102
|
//#endregion
|
|
@@ -10880,7 +10623,7 @@ function deployPackage(options) {
|
|
|
10880
10623
|
case "sst": {
|
|
10881
10624
|
const v = GEEKMIDAS_VERSIONS;
|
|
10882
10625
|
return {
|
|
10883
|
-
scripts: perStage(options, (stage) => `gkm build
|
|
10626
|
+
scripts: perStage(options, (stage) => `gkm build && sst deploy --stage ${stage}`),
|
|
10884
10627
|
dependencies: {
|
|
10885
10628
|
"@geekmidas/cloud": v["@geekmidas/cloud"],
|
|
10886
10629
|
"@geekmidas/db": v["@geekmidas/db"],
|
|
@@ -10945,7 +10688,7 @@ export default $config({
|
|
|
10945
10688
|
|
|
10946
10689
|
async run() {
|
|
10947
10690
|
const { App, fromManifest, Stack } = await import('@geekmidas/cloud/sst');
|
|
10948
|
-
// Written by \`gkm build
|
|
10691
|
+
// Written by \`gkm build\`. Imported rather than discovered,
|
|
10949
10692
|
// so SST's toolchain never evaluates the application's own modules.
|
|
10950
10693
|
const { backends, constructs } = await import('./.gkm/manifest/aws.js');
|
|
10951
10694
|
|
|
@@ -11183,8 +10926,11 @@ coverage/
|
|
|
11183
10926
|
${isSst ? "\n# SST\n.sst/\n" : ""}`;
|
|
11184
10927
|
const tsConfig = {
|
|
11185
10928
|
compilerOptions: {
|
|
10929
|
+
paths: {
|
|
10930
|
+
...isFullstack ? { [`@${options.name}/constructs/*`]: ["./constructs/*"] } : {},
|
|
10931
|
+
[`@${options.name}/manifest`]: [`./.gkm/manifest/${isSst ? "aws" : "server"}.ts`]
|
|
10932
|
+
},
|
|
11186
10933
|
...isFullstack ? {
|
|
11187
|
-
paths: { [`@${options.name}/constructs/*`]: ["./constructs/*"] },
|
|
11188
10934
|
allowImportingTsExtensions: true,
|
|
11189
10935
|
noEmit: true
|
|
11190
10936
|
} : {},
|
|
@@ -11325,7 +11071,7 @@ export default defineWorkspace({
|
|
|
11325
11071
|
// \`production-${options.name}-database\` on Dokploy and on AWS alike.
|
|
11326
11072
|
name: '${options.name}',
|
|
11327
11073
|
${stagesBlock(options.stages)}
|
|
11328
|
-
|
|
11074
|
+
${deployBlock(options)}
|
|
11329
11075
|
// Every kind, in every app. A declared database is why a Postgres exists, a
|
|
11330
11076
|
// declared bucket is why MinIO does, a declared topic is why a broker does —
|
|
11331
11077
|
// none of it listed here. It is also where the apps come from: a
|
|
@@ -11343,6 +11089,18 @@ ${workspaceConstructsGlobs(options.routesStructure, (0, node_path.dirname)(optio
|
|
|
11343
11089
|
`;
|
|
11344
11090
|
}
|
|
11345
11091
|
/**
|
|
11092
|
+
* Where it deploys, when that is not the default Dokploy: what a bare
|
|
11093
|
+
* `gkm build` builds for, and which backends a cache or a broker resolves to.
|
|
11094
|
+
*/
|
|
11095
|
+
function deployBlock(options) {
|
|
11096
|
+
if (options.deployTarget !== "sst") return "";
|
|
11097
|
+
return `
|
|
11098
|
+
// Deployed with \`sst deploy\`, from the manifest \`gkm build\` writes to
|
|
11099
|
+
// \`.gkm/manifest/aws.ts\`. Each construct becomes a managed AWS resource.
|
|
11100
|
+
deploy: { default: 'sst' },
|
|
11101
|
+
`;
|
|
11102
|
+
}
|
|
11103
|
+
/**
|
|
11346
11104
|
* Where a deployed stage's secrets live. On AWS that is SSM in the stage's own
|
|
11347
11105
|
* account, which the deploy job reaches with the role it already assumed; a
|
|
11348
11106
|
* server target keeps the encrypted local file, the default.
|
|
@@ -11368,7 +11126,7 @@ function secretsStore(options) {
|
|
|
11368
11126
|
*/
|
|
11369
11127
|
function generateRootConstructs(options) {
|
|
11370
11128
|
if (!options.monorepo || options.template !== "fullstack") return [];
|
|
11371
|
-
const {
|
|
11129
|
+
const { frontendFramework } = options;
|
|
11372
11130
|
const { cache, uploads, mail } = options.constructs;
|
|
11373
11131
|
const db = databaseFor();
|
|
11374
11132
|
const files = [];
|
|
@@ -12128,7 +11886,7 @@ const serverlessTemplate = {
|
|
|
12128
11886
|
},
|
|
12129
11887
|
scripts: {
|
|
12130
11888
|
dev: "gkm dev",
|
|
12131
|
-
build: "gkm build --provider aws
|
|
11889
|
+
build: "gkm build --provider aws",
|
|
12132
11890
|
test: "vitest",
|
|
12133
11891
|
"test:once": "vitest run",
|
|
12134
11892
|
typecheck: "tsc --noEmit",
|
|
@@ -12137,7 +11895,7 @@ const serverlessTemplate = {
|
|
|
12137
11895
|
"fmt:check": "biome format ."
|
|
12138
11896
|
},
|
|
12139
11897
|
files: (options) => {
|
|
12140
|
-
const { loggerType, routesStructure
|
|
11898
|
+
const { loggerType, routesStructure } = options;
|
|
12141
11899
|
const loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';
|
|
12142
11900
|
|
|
12143
11901
|
export const logger = createLogger();
|
|
@@ -12422,10 +12180,6 @@ export const telescope = new Telescope({
|
|
|
12422
12180
|
*/
|
|
12423
12181
|
const OPENAPI_OUTPUT_PATH = "./.gkm/openapi/api.ts";
|
|
12424
12182
|
/**
|
|
12425
|
-
* Endpoints output path (generated by gkm dev/build)
|
|
12426
|
-
*/
|
|
12427
|
-
const ENDPOINTS_OUTPUT_PATH = "./.gkm/server/endpoints.ts";
|
|
12428
|
-
/**
|
|
12429
12183
|
* All available templates
|
|
12430
12184
|
*/
|
|
12431
12185
|
const templates = {
|
|
@@ -12638,10 +12392,7 @@ function generatePackageJson(options, template) {
|
|
|
12638
12392
|
private: true,
|
|
12639
12393
|
type: "module",
|
|
12640
12394
|
...!monorepo && options.packageManager === "pnpm" ? { packageManager: PNPM_VERSION } : {},
|
|
12641
|
-
exports: {
|
|
12642
|
-
"./client": OPENAPI_OUTPUT_PATH,
|
|
12643
|
-
"./endpoints": ENDPOINTS_OUTPUT_PATH
|
|
12644
|
-
},
|
|
12395
|
+
exports: { "./client": OPENAPI_OUTPUT_PATH },
|
|
12645
12396
|
scripts,
|
|
12646
12397
|
dependencies: sortObject(dependencies),
|
|
12647
12398
|
devDependencies: sortObject(devDependencies)
|
|
@@ -15367,7 +15118,7 @@ function printNextSteps(projectName, options, pkgManager) {
|
|
|
15367
15118
|
}
|
|
15368
15119
|
if (options.deployTarget === "sst") {
|
|
15369
15120
|
console.log("🚀 Deployment (AWS, through SST):");
|
|
15370
|
-
for (const stage of deployed) console.log(` ${getRunCommand(pkgManager, `deploy:${stage}`)} # gkm build
|
|
15121
|
+
for (const stage of deployed) console.log(` ${getRunCommand(pkgManager, `deploy:${stage}`)} # gkm build, then sst deploy`);
|
|
15371
15122
|
console.log(` Uses your AWS credentials, in ${options.region}.`);
|
|
15372
15123
|
if (options.constructs.mail) console.log(" Set MAIL_FROM to a sender verified in SES first.");
|
|
15373
15124
|
console.log("");
|
|
@@ -16102,8 +15853,8 @@ function testDatabases(reconciled) {
|
|
|
16102
15853
|
* starts without the reference data the app needs.
|
|
16103
15854
|
*/
|
|
16104
15855
|
async function migrateTestStage(workspace, env) {
|
|
16105
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
16106
|
-
const { discover } = await Promise.resolve().then(() => require("./discover-
|
|
15856
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs"));
|
|
15857
|
+
const { discover } = await Promise.resolve().then(() => require("./discover-DXNviAh-.cjs")).then((n) => n.discover_exports);
|
|
16107
15858
|
const sources = {};
|
|
16108
15859
|
const manifest = await discover({
|
|
16109
15860
|
patterns: require_workspace$1.constructGlobs(workspace),
|
|
@@ -16468,29 +16219,13 @@ program.command("setup").description("Reconcile declared constructs — containe
|
|
|
16468
16219
|
process.exit(1);
|
|
16469
16220
|
}
|
|
16470
16221
|
});
|
|
16471
|
-
program.command("build").description("Build handlers and the manifest from declared constructs").option("--provider <provider>", "
|
|
16222
|
+
program.command("build").description("Build handlers and the manifest from declared constructs").option("--provider <provider>", "Build for aws or server (default: where gkm.config.ts deploys)").option("--enable-openapi", "Enable OpenAPI documentation generation for server builds").option("--production", "Build for production (no dev tools, bundled output)").option("--skip-bundle", "Skip bundling step in production build").option("--stage <stage>", "Inject encrypted secrets for deployment stage").option("--mark-optional", "Suffix optional env vars with ? in manifest envVars field (e.g. PORT?)").action(async (options) => {
|
|
16472
16223
|
try {
|
|
16473
16224
|
const globalOptions = program.opts();
|
|
16474
16225
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16475
|
-
if (options.provider)
|
|
16476
|
-
|
|
16477
|
-
|
|
16478
|
-
provider: options.provider,
|
|
16479
|
-
enableOpenApi: options.enableOpenapi || false,
|
|
16480
|
-
production: options.production || false,
|
|
16481
|
-
skipBundle: options.skipBundle || false,
|
|
16482
|
-
stage: options.stage,
|
|
16483
|
-
markOptional: options.markOptional || false
|
|
16484
|
-
});
|
|
16485
|
-
} else if (options.providers) await buildCommand({
|
|
16486
|
-
providers: [...new Set(options.providers.split(",").map((p) => p.trim()))],
|
|
16487
|
-
enableOpenApi: options.enableOpenapi || false,
|
|
16488
|
-
production: options.production || false,
|
|
16489
|
-
skipBundle: options.skipBundle || false,
|
|
16490
|
-
stage: options.stage,
|
|
16491
|
-
markOptional: options.markOptional || false
|
|
16492
|
-
});
|
|
16493
|
-
else await buildCommand({
|
|
16226
|
+
if (options.provider !== void 0 && !isMainProvider(options.provider)) throw new UnknownBuildProvider(options.provider);
|
|
16227
|
+
await buildCommand({
|
|
16228
|
+
...options.provider ? { provider: options.provider } : {},
|
|
16494
16229
|
enableOpenApi: options.enableOpenapi || false,
|
|
16495
16230
|
production: options.production || false,
|
|
16496
16231
|
skipBundle: options.skipBundle || false,
|
|
@@ -16549,7 +16284,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
16549
16284
|
try {
|
|
16550
16285
|
const globalOptions = program.opts();
|
|
16551
16286
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16552
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16287
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs"));
|
|
16553
16288
|
await migrateCommand({
|
|
16554
16289
|
...options,
|
|
16555
16290
|
...construct ? { construct } : {}
|
|
@@ -16563,7 +16298,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
16563
16298
|
try {
|
|
16564
16299
|
const globalOptions = program.opts();
|
|
16565
16300
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16566
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16301
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs"));
|
|
16567
16302
|
await seedCommand({
|
|
16568
16303
|
...options,
|
|
16569
16304
|
...construct ? { construct } : {}
|
|
@@ -16577,7 +16312,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
16577
16312
|
try {
|
|
16578
16313
|
const globalOptions = program.opts();
|
|
16579
16314
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16580
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16315
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-Dp5HFzuQ.cjs"));
|
|
16581
16316
|
await migrationCommand({
|
|
16582
16317
|
construct,
|
|
16583
16318
|
...name ? { name } : {}
|
|
@@ -16716,7 +16451,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16716
16451
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
16717
16452
|
process.exit(1);
|
|
16718
16453
|
}
|
|
16719
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-
|
|
16454
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-D9z2ymBW.cjs")).then((n) => n.workspace_exports);
|
|
16720
16455
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
16721
16456
|
if (!result) {
|
|
16722
16457
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|
|
@@ -16775,7 +16510,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
|
|
|
16775
16510
|
try {
|
|
16776
16511
|
const globalOptions = program.opts();
|
|
16777
16512
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16778
|
-
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-
|
|
16513
|
+
const { deployGithubCommand } = await Promise.resolve().then(() => require("./github-BrI1tv6u.cjs"));
|
|
16779
16514
|
await deployGithubCommand(options);
|
|
16780
16515
|
} catch (error) {
|
|
16781
16516
|
console.error(formatError(error));
|