@geekmidas/cli 10.0.0-alpha.74 → 10.0.0-alpha.76
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/dist/{LegacyStateStore-D_78eaHM.cjs → LegacyStateStore-DwngfJxr.cjs} +2 -2
- package/dist/{LegacyStateStore-D_78eaHM.cjs.map → LegacyStateStore-DwngfJxr.cjs.map} +1 -1
- package/dist/{LegacyStateStore-DTo7z924.mjs → LegacyStateStore-dyq07_Ir.mjs} +2 -2
- package/dist/{LegacyStateStore-DTo7z924.mjs.map → LegacyStateStore-dyq07_Ir.mjs.map} +1 -1
- package/dist/{LocalStateStore-BhrlQIXD.cjs → LocalStateStore-B0NCde8Z.cjs} +2 -2
- package/dist/{LocalStateStore-BhrlQIXD.cjs.map → LocalStateStore-B0NCde8Z.cjs.map} +1 -1
- package/dist/{LocalStateStore-CNjgkRk4.mjs → LocalStateStore-DLxCCatI.mjs} +2 -2
- package/dist/{LocalStateStore-CNjgkRk4.mjs.map → LocalStateStore-DLxCCatI.mjs.map} +1 -1
- package/dist/{S3StateStore-oCxRs6HM.cjs → S3StateStore-BOenb-3o.cjs} +2 -2
- package/dist/{S3StateStore-oCxRs6HM.cjs.map → S3StateStore-BOenb-3o.cjs.map} +1 -1
- package/dist/{S3StateStore-g2P7T_Mo.mjs → S3StateStore-CGK_4hlo.mjs} +2 -2
- package/dist/{S3StateStore-g2P7T_Mo.mjs.map → S3StateStore-CGK_4hlo.mjs.map} +1 -1
- package/dist/{SSMStateStore-CYenunmK.mjs → SSMStateStore-B_5_RqY-.mjs} +2 -2
- package/dist/{SSMStateStore-CYenunmK.mjs.map → SSMStateStore-B_5_RqY-.mjs.map} +1 -1
- package/dist/{SSMStateStore-DXp0m7XI.cjs → SSMStateStore-DYeD__7p.cjs} +2 -2
- package/dist/{SSMStateStore-DXp0m7XI.cjs.map → SSMStateStore-DYeD__7p.cjs.map} +1 -1
- package/dist/{add-BTH7WaH3.mjs → add-B7IMXzou.mjs} +3 -3
- package/dist/{add-BTH7WaH3.mjs.map → add-B7IMXzou.mjs.map} +1 -1
- package/dist/{add-Djrr12Xc.cjs → add-j2yI3cbS.cjs} +3 -3
- package/dist/{add-Djrr12Xc.cjs.map → add-j2yI3cbS.cjs.map} +1 -1
- package/dist/{aws-DojzQnLd.mjs → aws-Bja4zGSs.mjs} +13 -9
- package/dist/aws-Bja4zGSs.mjs.map +1 -0
- package/dist/{aws-DkHdTV-p.cjs → aws-CQAuluiu.cjs} +13 -9
- package/dist/aws-CQAuluiu.cjs.map +1 -0
- package/dist/awsStore-7VmS_cZR.cjs +54 -0
- package/dist/awsStore-7VmS_cZR.cjs.map +1 -0
- package/dist/awsStore-B529csle.mjs +43 -0
- package/dist/awsStore-B529csle.mjs.map +1 -0
- package/dist/{bundler-utHuESvL.cjs → bundler-Cf6OgaOe.cjs} +5 -5
- package/dist/bundler-Cf6OgaOe.cjs.map +1 -0
- package/dist/{bundler-BUojOkof.mjs → bundler-DO6bHhnb.mjs} +5 -5
- package/dist/bundler-DO6bHhnb.mjs.map +1 -0
- package/dist/{cli-CyYceKTS.mjs → cli-BCPOHmg9.mjs} +3 -3
- package/dist/{cli-CyYceKTS.mjs.map → cli-BCPOHmg9.mjs.map} +1 -1
- package/dist/{cli-Bx0sUzxH.cjs → cli-CNanUB7a.cjs} +3 -3
- package/dist/{cli-Bx0sUzxH.cjs.map → cli-CNanUB7a.cjs.map} +1 -1
- package/dist/{compose-DZp8DJ0A.mjs → compose-Dq4VCtu5.mjs} +221 -153
- package/dist/compose-Dq4VCtu5.mjs.map +1 -0
- package/dist/{compose-iuw8wfHk.cjs → compose-h_6oNnHC.cjs} +243 -151
- package/dist/compose-h_6oNnHC.cjs.map +1 -0
- package/dist/{config-B38YWicj.d.cts → config-CWyhLSY1.d.cts} +3 -3
- package/dist/{config-B38YWicj.d.cts.map → config-CWyhLSY1.d.cts.map} +1 -1
- package/dist/{config-DA0kRTQe.d.mts → config-CqAvPP-f.d.mts} +3 -3
- package/dist/{config-DA0kRTQe.d.mts.map → config-CqAvPP-f.d.mts.map} +1 -1
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +3 -3
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -1
- package/dist/deploy/public.cjs +7 -6
- package/dist/deploy/public.d.cts +14 -3
- package/dist/deploy/public.d.cts.map +1 -1
- package/dist/deploy/public.d.mts +14 -3
- package/dist/deploy/public.d.mts.map +1 -1
- package/dist/deploy/public.mjs +7 -7
- package/dist/{deploy-eWorhvQp.cjs → deploy-CT3R9de9.cjs} +27 -5
- package/dist/deploy-CT3R9de9.cjs.map +1 -0
- package/dist/{deploy-C17K7Imy.mjs → deploy-CVXEx7Nm.mjs} +22 -6
- package/dist/deploy-CVXEx7Nm.mjs.map +1 -0
- package/dist/{dokploy-DKa49Nqm.mjs → dokploy-CYm2ozFs.mjs} +2 -2
- package/dist/{dokploy-DKa49Nqm.mjs.map → dokploy-CYm2ozFs.mjs.map} +1 -1
- package/dist/{dokploy-DKzcI-RL.cjs → dokploy-eSGmlhhj.cjs} +2 -2
- package/dist/{dokploy-DKzcI-RL.cjs.map → dokploy-eSGmlhhj.cjs.map} +1 -1
- package/dist/{encryption-sTMz3aWi.mjs → encryption-DC0rsR1W.mjs} +3 -3
- package/dist/{encryption-sTMz3aWi.mjs.map → encryption-DC0rsR1W.mjs.map} +1 -1
- package/dist/{encryption-DSkJdoyk.cjs → encryption-vS3Qzw73.cjs} +3 -3
- package/dist/{encryption-DSkJdoyk.cjs.map → encryption-vS3Qzw73.cjs.map} +1 -1
- package/dist/{engine-B1b4I34Z.mjs → engine-BOO5TWZd.mjs} +193 -5
- package/dist/engine-BOO5TWZd.mjs.map +1 -0
- package/dist/{engine-Bh76sAHy.cjs → engine-C0N2d1i5.cjs} +196 -8
- package/dist/engine-C0N2d1i5.cjs.map +1 -0
- package/dist/{github-C9ODoyZU.mjs → github-CEaFDL6t.mjs} +6 -6
- package/dist/github-CEaFDL6t.mjs.map +1 -0
- package/dist/{github-BvN3CfxM.cjs → github-ClkdCOL9.cjs} +6 -6
- package/dist/github-ClkdCOL9.cjs.map +1 -0
- package/dist/{index-B-1lLGzy.d.mts → index-Ccu0f_2m.d.cts} +2 -2
- package/dist/{index-B-1lLGzy.d.mts.map → index-Ccu0f_2m.d.cts.map} +1 -1
- package/dist/{index-vMidfqhU.d.cts → index-DOxmDKqv.d.mts} +2 -2
- package/dist/{index-vMidfqhU.d.cts.map → index-DOxmDKqv.d.mts.map} +1 -1
- package/dist/index.cjs +106 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +105 -51
- package/dist/index.mjs.map +1 -1
- package/dist/migrate-BRbYtFXG.cjs +93 -0
- package/dist/migrate-BRbYtFXG.cjs.map +1 -0
- package/dist/migrate-D3NAT7Ns.mjs +93 -0
- package/dist/migrate-D3NAT7Ns.mjs.map +1 -0
- package/dist/{migrate-B0FCZNkp.cjs → migrate-D5_-ylI1.cjs} +3 -3
- package/dist/{migrate-B0FCZNkp.cjs.map → migrate-D5_-ylI1.cjs.map} +1 -1
- package/dist/{migrate-CTtJhGV9.mjs → migrate-DrO2p9Rl.mjs} +3 -3
- package/dist/{migrate-CTtJhGV9.mjs.map → migrate-DrO2p9Rl.mjs.map} +1 -1
- package/dist/openapi.cjs +16 -6
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +16 -6
- package/dist/openapi.mjs.map +1 -1
- package/dist/reconcile/public.d.cts +1 -1
- package/dist/reconcile/public.d.mts +1 -1
- package/dist/{resolve-DSAXj_47.mjs → resolve-C1muFos5.mjs} +3 -3
- package/dist/{resolve-DSAXj_47.mjs.map → resolve-C1muFos5.mjs.map} +1 -1
- package/dist/{resolve-D_BU-wKA.cjs → resolve-Fa1Ii0BK.cjs} +3 -3
- package/dist/{resolve-D_BU-wKA.cjs.map → resolve-Fa1Ii0BK.cjs.map} +1 -1
- package/dist/{rollback-DJy3t696.cjs → rollback-C9N5lKVf.cjs} +5 -5
- package/dist/{rollback-DJy3t696.cjs.map → rollback-C9N5lKVf.cjs.map} +1 -1
- package/dist/{rollback-CWYTUhfW.mjs → rollback-DeQzbRqM.mjs} +5 -5
- package/dist/{rollback-CWYTUhfW.mjs.map → rollback-DeQzbRqM.mjs.map} +1 -1
- package/dist/{runtime-BzZD5HHi.d.cts → runtime-BSvzPqXW.d.mts} +2 -2
- package/dist/{runtime-BzZD5HHi.d.cts.map → runtime-BSvzPqXW.d.mts.map} +1 -1
- package/dist/{runtime-Cm6J6L7n.d.mts → runtime-Cm7QA53H.d.cts} +2 -2
- package/dist/{runtime-Cm6J6L7n.d.mts.map → runtime-Cm7QA53H.d.cts.map} +1 -1
- package/dist/secretsManager-DUXW3fQt.cjs +70 -0
- package/dist/secretsManager-DUXW3fQt.cjs.map +1 -0
- package/dist/secretsManager-Ti0oZwsS.mjs +70 -0
- package/dist/secretsManager-Ti0oZwsS.mjs.map +1 -0
- package/dist/{sniffer-BFmdZpZ2.mjs → sniffer-DR8AlRCk.mjs} +67 -15
- package/dist/sniffer-DR8AlRCk.mjs.map +1 -0
- package/dist/{sniffer-C-T7dSMN.cjs → sniffer-Y6GQOCXB.cjs} +83 -13
- package/dist/sniffer-Y6GQOCXB.cjs.map +1 -0
- package/dist/{state-DCwRWyh-.cjs → state-C2qi0iQw.cjs} +241 -334
- package/dist/state-C2qi0iQw.cjs.map +1 -0
- package/dist/{state-DpkxSwzI.mjs → state-CUecOCNJ.mjs} +213 -306
- package/dist/state-CUecOCNJ.mjs.map +1 -0
- package/dist/target/public.cjs +1 -1
- package/dist/target/public.d.cts +2 -2
- package/dist/target/public.d.mts +2 -2
- package/dist/target/public.mjs +1 -1
- package/dist/{types-TzCChNrA.d.cts → types-BdptGBFS.d.cts} +59 -6
- package/dist/types-BdptGBFS.d.cts.map +1 -0
- package/dist/{types-Dp9lgx_S.d.mts → types-OxE0OAn2.d.mts} +59 -6
- package/dist/types-OxE0OAn2.d.mts.map +1 -0
- 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-vdrcRI-m.cjs → workspace-DOm81oUo.cjs} +54 -1
- package/dist/workspace-DOm81oUo.cjs.map +1 -0
- package/dist/{workspace-C7NqCsQF.mjs → workspace-QUTqYmVy.mjs} +43 -2
- package/dist/workspace-QUTqYmVy.mjs.map +1 -0
- package/package.json +18 -17
- package/dist/aws-DkHdTV-p.cjs.map +0 -1
- package/dist/aws-DojzQnLd.mjs.map +0 -1
- package/dist/bundler-BUojOkof.mjs.map +0 -1
- package/dist/bundler-utHuESvL.cjs.map +0 -1
- package/dist/compose-DZp8DJ0A.mjs.map +0 -1
- package/dist/compose-iuw8wfHk.cjs.map +0 -1
- package/dist/deploy-C17K7Imy.mjs.map +0 -1
- package/dist/deploy-eWorhvQp.cjs.map +0 -1
- package/dist/engine-B1b4I34Z.mjs.map +0 -1
- package/dist/engine-Bh76sAHy.cjs.map +0 -1
- package/dist/github-BvN3CfxM.cjs.map +0 -1
- package/dist/github-C9ODoyZU.mjs.map +0 -1
- package/dist/sniffer-BFmdZpZ2.mjs.map +0 -1
- package/dist/sniffer-C-T7dSMN.cjs.map +0 -1
- package/dist/state-DCwRWyh-.cjs.map +0 -1
- package/dist/state-DpkxSwzI.mjs.map +0 -1
- package/dist/types-Dp9lgx_S.d.mts.map +0 -1
- package/dist/types-TzCChNrA.d.cts.map +0 -1
- package/dist/workspace-C7NqCsQF.mjs.map +0 -1
- package/dist/workspace-vdrcRI-m.cjs.map +0 -1
|
@@ -2,10 +2,10 @@ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
|
|
|
2
2
|
const require_run = require("./run-fVZ-rLnc.cjs");
|
|
3
3
|
const require_discover = require("./discover-D1It5r_h.cjs");
|
|
4
4
|
const require_derive = require("./derive-DAbo49sm.cjs");
|
|
5
|
-
const require_workspace = require("./workspace-
|
|
5
|
+
const require_workspace = require("./workspace-DOm81oUo.cjs");
|
|
6
6
|
const require_config = require("./config.cjs");
|
|
7
7
|
const require_EndpointGenerator = require("./EndpointGenerator-CP6sBvQV.cjs");
|
|
8
|
-
const require_resolve = require("./resolve-
|
|
8
|
+
const require_resolve = require("./resolve-Fa1Ii0BK.cjs");
|
|
9
9
|
const require_SubscriberGenerator = require("./SubscriberGenerator-CajwOa5W.cjs");
|
|
10
10
|
let node_path = require("node:path");
|
|
11
11
|
let node_fs = require("node:fs");
|
|
@@ -276,7 +276,7 @@ function applicationName(identity, app) {
|
|
|
276
276
|
* old file stays, so an older CLI on the same machine keeps working.
|
|
277
277
|
*/
|
|
278
278
|
/** Key length for AES-256 encryption */
|
|
279
|
-
const KEY_LENGTH
|
|
279
|
+
const KEY_LENGTH = 32;
|
|
280
280
|
/** A keystore project key that is not `<namespace>/<project>`. */
|
|
281
281
|
var KeystoreProjectInvalid = class extends Error {
|
|
282
282
|
key;
|
|
@@ -369,7 +369,7 @@ async function generateKey(stage, project, flag = "w") {
|
|
|
369
369
|
recursive: true,
|
|
370
370
|
mode: 448
|
|
371
371
|
});
|
|
372
|
-
const key = (0, node_crypto.randomBytes)(KEY_LENGTH
|
|
372
|
+
const key = (0, node_crypto.randomBytes)(KEY_LENGTH).toString("hex");
|
|
373
373
|
await (0, node_fs_promises.writeFile)(keyPath, key, {
|
|
374
374
|
mode: 384,
|
|
375
375
|
encoding: "utf-8",
|
|
@@ -438,8 +438,8 @@ async function getOrCreateKey(stage, project) {
|
|
|
438
438
|
/** Where the files live, relative to the project root. */
|
|
439
439
|
const SECRETS_DIR = ".gkm/secrets";
|
|
440
440
|
/** AES-256-GCM configuration */
|
|
441
|
-
const ALGORITHM
|
|
442
|
-
const IV_LENGTH
|
|
441
|
+
const ALGORITHM = "aes-256-gcm";
|
|
442
|
+
const IV_LENGTH = 12;
|
|
443
443
|
/**
|
|
444
444
|
* A stage's secrets as an encrypted file on this machine:
|
|
445
445
|
* `.gkm/secrets/<stage>.json`, with its key in the CLI's home at
|
|
@@ -507,8 +507,8 @@ function packageName$1(root) {
|
|
|
507
507
|
}
|
|
508
508
|
function encrypt(secrets, keyHex) {
|
|
509
509
|
const key = Buffer.from(keyHex, "hex");
|
|
510
|
-
const iv = (0, node_crypto.randomBytes)(IV_LENGTH
|
|
511
|
-
const cipher = (0, node_crypto.createCipheriv)(ALGORITHM
|
|
510
|
+
const iv = (0, node_crypto.randomBytes)(IV_LENGTH);
|
|
511
|
+
const cipher = (0, node_crypto.createCipheriv)(ALGORITHM, key, iv);
|
|
512
512
|
const ciphertext = Buffer.concat([cipher.update(JSON.stringify(secrets), "utf-8"), cipher.final()]);
|
|
513
513
|
return {
|
|
514
514
|
version: 1,
|
|
@@ -519,7 +519,7 @@ function encrypt(secrets, keyHex) {
|
|
|
519
519
|
function decrypt(data, keyHex) {
|
|
520
520
|
const key = Buffer.from(keyHex, "hex");
|
|
521
521
|
const combined = Buffer.from(data.encrypted, "base64");
|
|
522
|
-
const decipher = (0, node_crypto.createDecipheriv)(ALGORITHM
|
|
522
|
+
const decipher = (0, node_crypto.createDecipheriv)(ALGORITHM, key, Buffer.from(data.iv, "hex"));
|
|
523
523
|
decipher.setAuthTag(combined.subarray(-16));
|
|
524
524
|
const plaintext = Buffer.concat([decipher.update(combined.subarray(0, -16)), decipher.final()]);
|
|
525
525
|
return JSON.parse(plaintext.toString("utf-8"));
|
|
@@ -529,7 +529,8 @@ function decrypt(data, keyHex) {
|
|
|
529
529
|
var store_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
530
530
|
FileSecretsStore: () => FileSecretsStore,
|
|
531
531
|
isRemoteStore: () => isRemoteStore,
|
|
532
|
-
secretsStoreFor: () => secretsStoreFor
|
|
532
|
+
secretsStoreFor: () => secretsStoreFor,
|
|
533
|
+
storeFromConfig: () => storeFromConfig
|
|
533
534
|
});
|
|
534
535
|
/**
|
|
535
536
|
* The store a stage's secrets are kept in — what every command reads and
|
|
@@ -541,13 +542,41 @@ var store_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
|
541
542
|
async function secretsStoreFor(workspace, stage, options = {}) {
|
|
542
543
|
const configured = workspace.secrets.store ?? "file";
|
|
543
544
|
if (stage === workspace.stages.local || configured === "file") return new FileSecretsStore(workspace.root, keystoreProject(workspace, options.home));
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
545
|
+
return storeFromConfig(workspace, configured, options);
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* The store a `secrets.store` value describes, for any stage — what
|
|
549
|
+
* {@link secretsStoreFor} answers for a deployed stage, and what
|
|
550
|
+
* `gkm secrets:migrate` builds for the store it copies to.
|
|
551
|
+
*/
|
|
552
|
+
async function storeFromConfig(workspace, config, options = {}) {
|
|
553
|
+
if (config === "file") return new FileSecretsStore(workspace.root, keystoreProject(workspace, options.home));
|
|
554
|
+
const profile = options.profile ? { profile: options.profile } : {};
|
|
555
|
+
switch (config.provider) {
|
|
556
|
+
case "ssm": {
|
|
557
|
+
const { AwsSecretsStore } = await Promise.resolve().then(() => require("./aws-CQAuluiu.cjs"));
|
|
558
|
+
return new AwsSecretsStore({
|
|
559
|
+
project: workspace.name,
|
|
560
|
+
region: config.region,
|
|
561
|
+
...profile
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
case "secrets-manager": {
|
|
565
|
+
const { kmsKeyId } = config;
|
|
566
|
+
const { SecretsManagerSecretsStore } = await Promise.resolve().then(() => require("./secretsManager-DUXW3fQt.cjs"));
|
|
567
|
+
return new SecretsManagerSecretsStore({
|
|
568
|
+
project: workspace.name,
|
|
569
|
+
region: config.region,
|
|
570
|
+
...kmsKeyId ? { kmsKeyId } : {},
|
|
571
|
+
...profile
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
default: {
|
|
575
|
+
const provider = config.provider;
|
|
576
|
+
if (typeof provider === "object" && provider !== null) return provider;
|
|
577
|
+
throw new require_workspace.UnknownSecretsStoreProvider(provider);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
551
580
|
}
|
|
552
581
|
/** Whether a stage's secrets live somewhere other than this machine. */
|
|
553
582
|
function isRemoteStore(workspace, stage) {
|
|
@@ -556,7 +585,7 @@ function isRemoteStore(workspace, stage) {
|
|
|
556
585
|
}
|
|
557
586
|
//#endregion
|
|
558
587
|
//#region src/credentials/index.ts
|
|
559
|
-
const logger$
|
|
588
|
+
const logger$1 = console;
|
|
560
589
|
/**
|
|
561
590
|
* Load environment files
|
|
562
591
|
* @internal Exported for testing
|
|
@@ -607,7 +636,7 @@ async function findAvailablePort(preferredPort, maxAttempts = 10) {
|
|
|
607
636
|
for (let i = 0; i < maxAttempts; i++) {
|
|
608
637
|
const port = preferredPort + i;
|
|
609
638
|
if (await isPortAvailable(port)) return port;
|
|
610
|
-
logger$
|
|
639
|
+
logger$1.log(`⚠️ Port ${port} is in use, trying ${port + 1}...`);
|
|
611
640
|
}
|
|
612
641
|
throw new Error(`Could not find an available port after trying ${maxAttempts} ports starting from ${preferredPort}`);
|
|
613
642
|
}
|
|
@@ -642,7 +671,7 @@ async function loadSecretsForApp(store, stage, appName) {
|
|
|
642
671
|
let secrets = {};
|
|
643
672
|
const stageSecrets = await store.read(stage);
|
|
644
673
|
if (stageSecrets) {
|
|
645
|
-
logger$
|
|
674
|
+
logger$1.log(`🔐 Loading secrets from stage: ${stage}`);
|
|
646
675
|
secrets = toEmbeddableSecrets(stageSecrets);
|
|
647
676
|
}
|
|
648
677
|
if (Object.keys(secrets).length === 0) return {};
|
|
@@ -748,7 +777,7 @@ async function prepareEntryCredentials(options) {
|
|
|
748
777
|
free: isPortAvailable,
|
|
749
778
|
holder: holderOf
|
|
750
779
|
});
|
|
751
|
-
for (const { app, from, to, holder } of assigned.moved) logger$
|
|
780
|
+
for (const { app, from, to, holder } of assigned.moved) logger$1.log(`↪️ ${app}: ${from} is held by ${describeHolder(holder)}, which is not this workspace's — using ${to}`);
|
|
752
781
|
workspace = withAppPorts(workspace, assigned.ports);
|
|
753
782
|
workspaceAppPort = assigned.ports[appName] ?? workspaceAppPort;
|
|
754
783
|
}
|
|
@@ -772,7 +801,7 @@ async function prepareEntryCredentials(options) {
|
|
|
772
801
|
});
|
|
773
802
|
Object.assign(credentials, reconciled.env);
|
|
774
803
|
declaredKeys.push(...Object.keys(reconciled.env));
|
|
775
|
-
if (Object.keys(reconciled.env).length > 0) logger$
|
|
804
|
+
if (Object.keys(reconciled.env).length > 0) logger$1.log(`🔌 Resolved ${Object.keys(reconciled.env).length} declared URL(s)`);
|
|
776
805
|
}
|
|
777
806
|
const secretsDir = (0, node_path.join)(secretsRoot, ".gkm");
|
|
778
807
|
await (0, node_fs_promises.mkdir)(secretsDir, { recursive: true });
|
|
@@ -1024,6 +1053,36 @@ function eventsBackendFor(on) {
|
|
|
1024
1053
|
return require_SubscriberGenerator.DEFAULT_EVENTS[on];
|
|
1025
1054
|
}
|
|
1026
1055
|
//#endregion
|
|
1056
|
+
//#region src/exec/imageBuild.ts
|
|
1057
|
+
/**
|
|
1058
|
+
* Set by a site's Dockerfile in its builder stage: this process is building
|
|
1059
|
+
* an image.
|
|
1060
|
+
*
|
|
1061
|
+
* Inside an image there is no stage to load secrets for and no local
|
|
1062
|
+
* container to resolve an address from — the public URLs the bundle inlines
|
|
1063
|
+
* arrived as the Dockerfile's build args, already in the environment. So
|
|
1064
|
+
* `gkm exec -- next build` there injects exactly those, and never the
|
|
1065
|
+
* `localhost` addresses a workspace resolves on a developer's machine.
|
|
1066
|
+
*/
|
|
1067
|
+
const IMAGE_BUILD_ENV = "GKM_IMAGE_BUILD";
|
|
1068
|
+
/** Whether this process is building an image. */
|
|
1069
|
+
function isImageBuild(env = process.env) {
|
|
1070
|
+
return env[IMAGE_BUILD_ENV] === "1";
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* What `gkm exec` injects inside an image build: the public values its build
|
|
1074
|
+
* args set — every `NEXT_PUBLIC_*`, `VITE_*` and `EXPO_PUBLIC_*` — and
|
|
1075
|
+
* nothing read from a secrets store, a file or a container.
|
|
1076
|
+
*/
|
|
1077
|
+
function imageBuildCredentials(env = process.env) {
|
|
1078
|
+
const credentials = {};
|
|
1079
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1080
|
+
if (value === void 0) continue;
|
|
1081
|
+
if (require_workspace.PUBLIC_ENV_PREFIXES.some((prefix) => key.startsWith(prefix))) credentials[key] = value;
|
|
1082
|
+
}
|
|
1083
|
+
return credentials;
|
|
1084
|
+
}
|
|
1085
|
+
//#endregion
|
|
1027
1086
|
//#region src/docker/templates.ts
|
|
1028
1087
|
/**
|
|
1029
1088
|
* The turbo every image prunes and builds with when the build root resolves
|
|
@@ -1281,23 +1340,22 @@ RUN --mount=type=cache,id=${pm.cacheId},target=${pm.cacheTarget} \\
|
|
|
1281
1340
|
*
|
|
1282
1341
|
* Nothing built on the host reaches the image — `.dockerignore` keeps every
|
|
1283
1342
|
* `dist` out — so a workspace package (a CLI that is a sibling package) is
|
|
1284
|
-
* built here:
|
|
1285
|
-
*
|
|
1343
|
+
* built here: turbo's build of the app's dependencies (`^build`) and nothing
|
|
1344
|
+
* else. The root's own `build` script is never run: the slice holds one app,
|
|
1345
|
+
* and a root `build` that is `gkm build` (what `gkm init` scaffolds) builds
|
|
1346
|
+
* every app the workspace declares, most of which are not in it. The app
|
|
1347
|
+
* itself is built after this, by `gkm build` or its framework.
|
|
1286
1348
|
*/
|
|
1287
1349
|
function builderStage(options, extra = {}) {
|
|
1288
|
-
const {
|
|
1350
|
+
const { turbo, monorepo } = layout(options);
|
|
1289
1351
|
const args = extra.args ?? [];
|
|
1290
1352
|
const argLines = args.length ? `\n# Build-time args: public values the bundler inlines\n${args.map((a) => `ARG ${a}=""`).join("\n")}\n${args.map((a) => `ENV ${a}=$${a}`).join("\n")}\n` : "";
|
|
1291
1353
|
const scopes = [options.turboPackage, ...options.prunePackages ?? []];
|
|
1292
|
-
const dependencies = monorepo ? `\nRUN ${turbo} run build ${scopes.map((s) => `--filter='${s}^...'`).join(" ")}` : "";
|
|
1293
1354
|
return `# Stage 3: Build
|
|
1294
1355
|
FROM deps AS builder
|
|
1295
1356
|
WORKDIR /app
|
|
1296
1357
|
${argLines}
|
|
1297
|
-
COPY --from=pruner /app/out/full/
|
|
1298
|
-
|
|
1299
|
-
# The workspace packages the app depends on, built from source.
|
|
1300
|
-
RUN ${pm.run} --if-present build${dependencies}`;
|
|
1358
|
+
COPY --from=pruner /app/out/full/ ./${monorepo ? `\n# The workspace packages the app depends on, built from source.\nRUN ${turbo} run build ${scopes.map((s) => `--filter='${s}^...'`).join(" ")}` : ""}`;
|
|
1301
1359
|
}
|
|
1302
1360
|
/**
|
|
1303
1361
|
* The PATH a command in the app's directory runs with: the app's binaries,
|
|
@@ -1322,7 +1380,48 @@ function binPath(options) {
|
|
|
1322
1380
|
* were installed.
|
|
1323
1381
|
*/
|
|
1324
1382
|
function gkmCommand(args) {
|
|
1325
|
-
return `GKM_BIN="$(node -e '
|
|
1383
|
+
return `GKM_BIN="$(node -e '${FIND_GKM_BIN}')" && node "$GKM_BIN" ${args}`;
|
|
1384
|
+
}
|
|
1385
|
+
/** Prints the `bin/gkm.mjs` Node resolves from the cwd, or fails saying so. */
|
|
1386
|
+
const FIND_GKM_BIN = `let d=process.cwd();const{existsSync:e}=require("fs"),{dirname:u,join:j}=require("path");for(;;){const p=j(d,"node_modules/@geekmidas/cli/bin/gkm.mjs");if(e(p)){console.log(p);break}if(u(d)===d){console.error("@geekmidas/cli is not installed where the app can resolve it");process.exit(1)}d=u(d)}`;
|
|
1387
|
+
/**
|
|
1388
|
+
* What a site's builder does with the gkm workspace it carries, before its
|
|
1389
|
+
* framework builds it — all of it inside the image, nothing from the host:
|
|
1390
|
+
*
|
|
1391
|
+
* - `gkm` on the PATH: the CLI the workspace installs, so a build script that
|
|
1392
|
+
* is `gkm exec -- next build` runs. Resolved from the gkm root rather than
|
|
1393
|
+
* through `node_modules/.bin`, where a CLI that is a workspace package has
|
|
1394
|
+
* no bin linked.
|
|
1395
|
+
* - `GKM_IMAGE_BUILD`, which has `gkm exec` inject the build args above — the
|
|
1396
|
+
* stage's public URLs — and never load a secret or resolve a local address.
|
|
1397
|
+
* - each backend's typed client, generated from its endpoints at the
|
|
1398
|
+
* workspace root's `.gkm/client/`, where the site's tsconfig paths point.
|
|
1399
|
+
*/
|
|
1400
|
+
function siteWorkspaceSteps(options) {
|
|
1401
|
+
const { gkmRoot } = layout(options);
|
|
1402
|
+
const root = `/app/${gkmRoot}`.replace(/\/\.$/, "");
|
|
1403
|
+
const clients = options.clients ?? [];
|
|
1404
|
+
const generate = clients.length ? `
|
|
1405
|
+
|
|
1406
|
+
# The typed client of each API this site calls, generated from its endpoints
|
|
1407
|
+
# into ${gkmRoot === "." ? "" : `${gkmRoot}/`}.gkm/client/ — offline, with no secret and no container.
|
|
1408
|
+
RUN ${clients.map(({ app, path }) => `cd /app/${path} && gkm openapi --app ${app}`).join(" && \\\n ")}` : "";
|
|
1409
|
+
return `# The gkm CLI the workspace installs, as \`gkm\`
|
|
1410
|
+
RUN cd ${root} && GKM_BIN="$(node -e '${FIND_GKM_BIN}')" && \\
|
|
1411
|
+
{ echo '#!/bin/sh'; echo "exec node \\"$GKM_BIN\\" \\"\\$@\\""; } > /usr/local/bin/gkm && \\
|
|
1412
|
+
chmod +x /usr/local/bin/gkm
|
|
1413
|
+
|
|
1414
|
+
# \`gkm exec\` in this build injects the build args, never a stage's secrets
|
|
1415
|
+
ENV ${IMAGE_BUILD_ENV}=1${generate}`;
|
|
1416
|
+
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Build the site with turbo. Loose env mode, so the task sees what the
|
|
1419
|
+
* Dockerfile set — the build args and `GKM_IMAGE_BUILD` — whatever the
|
|
1420
|
+
* project's turbo.json declares: the image's environment holds nothing else.
|
|
1421
|
+
*/
|
|
1422
|
+
function siteBuild(options) {
|
|
1423
|
+
const { turbo } = layout(options);
|
|
1424
|
+
return `RUN ${turbo} run build --filter='${options.turboPackage}' --env-mode=loose`;
|
|
1326
1425
|
}
|
|
1327
1426
|
/**
|
|
1328
1427
|
* The encrypted credentials, from a build secret — never an ARG, which is
|
|
@@ -1476,8 +1575,7 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \\
|
|
|
1476
1575
|
* @internal Exported for testing
|
|
1477
1576
|
*/
|
|
1478
1577
|
function generateNextjsDockerfile(options) {
|
|
1479
|
-
const { port, appPath,
|
|
1480
|
-
const { turbo } = layout(options);
|
|
1578
|
+
const { port, appPath, publicUrlArgs = ["NEXT_PUBLIC_API_URL", "NEXT_PUBLIC_AUTH_URL"] } = options;
|
|
1481
1579
|
return `# syntax=docker/dockerfile:1
|
|
1482
1580
|
# Next.js standalone Dockerfile, built from a turbo-pruned slice
|
|
1483
1581
|
|
|
@@ -1487,13 +1585,15 @@ ${depsStage(options)}
|
|
|
1487
1585
|
|
|
1488
1586
|
${builderStage(options, { args: publicUrlArgs })}
|
|
1489
1587
|
|
|
1588
|
+
${siteWorkspaceSteps(options)}
|
|
1589
|
+
|
|
1490
1590
|
# Ensure public directory exists (may be empty for scaffolded projects)
|
|
1491
1591
|
RUN mkdir -p ${appPath}/public
|
|
1492
1592
|
|
|
1493
1593
|
ENV NEXT_TELEMETRY_DISABLED=1
|
|
1494
1594
|
|
|
1495
1595
|
# Build the application
|
|
1496
|
-
|
|
1596
|
+
${siteBuild(options)}
|
|
1497
1597
|
|
|
1498
1598
|
# The runner needs the standalone server; without it there is nothing to run.
|
|
1499
1599
|
RUN if [ ! -d ${appPath}/.next/standalone ]; then \\
|
|
@@ -1681,8 +1781,7 @@ CMD ["node", "index.mjs"]
|
|
|
1681
1781
|
* @internal Exported for testing
|
|
1682
1782
|
*/
|
|
1683
1783
|
function generateNodeWebDockerfile(options) {
|
|
1684
|
-
const { port, appPath
|
|
1685
|
-
const { turbo } = layout(options);
|
|
1784
|
+
const { port, appPath } = options;
|
|
1686
1785
|
return `# syntax=docker/dockerfile:1
|
|
1687
1786
|
# Node SSR web Dockerfile (TanStack Start / Remix), from a turbo-pruned slice
|
|
1688
1787
|
|
|
@@ -1691,7 +1790,10 @@ ${prunerStage(options)}
|
|
|
1691
1790
|
${depsStage(options)}
|
|
1692
1791
|
|
|
1693
1792
|
${builderStage(options, { args: options.publicUrlArgs ?? [] })}
|
|
1694
|
-
|
|
1793
|
+
|
|
1794
|
+
${siteWorkspaceSteps(options)}
|
|
1795
|
+
|
|
1796
|
+
${siteBuild(options)}
|
|
1695
1797
|
|
|
1696
1798
|
FROM ${options.baseImage} AS runner
|
|
1697
1799
|
WORKDIR /app
|
|
@@ -1725,8 +1827,7 @@ CMD ["sh", "-c", "cd ${appPath} && npm start"]
|
|
|
1725
1827
|
* @internal Exported for testing
|
|
1726
1828
|
*/
|
|
1727
1829
|
function generateViteStaticDockerfile(options) {
|
|
1728
|
-
const { port, appPath
|
|
1729
|
-
const { turbo } = layout(options);
|
|
1830
|
+
const { port, appPath } = options;
|
|
1730
1831
|
return `# syntax=docker/dockerfile:1
|
|
1731
1832
|
# Vite SPA Dockerfile — a turbo-pruned slice built to static files, served by Caddy
|
|
1732
1833
|
|
|
@@ -1735,7 +1836,10 @@ ${prunerStage(options)}
|
|
|
1735
1836
|
${depsStage(options)}
|
|
1736
1837
|
|
|
1737
1838
|
${builderStage(options, { args: options.publicUrlArgs ?? [] })}
|
|
1738
|
-
|
|
1839
|
+
|
|
1840
|
+
${siteWorkspaceSteps(options)}
|
|
1841
|
+
|
|
1842
|
+
${siteBuild(options)}
|
|
1739
1843
|
|
|
1740
1844
|
FROM ${STATIC_SITE_IMAGE} AS runner
|
|
1741
1845
|
|
|
@@ -1844,7 +1948,7 @@ function fromBuildRoot(layout, path) {
|
|
|
1844
1948
|
return joined === "" ? "." : joined;
|
|
1845
1949
|
}
|
|
1846
1950
|
/** Everything a template needs about one app, relative to the build root. */
|
|
1847
|
-
function appImageOptions(layout, appName, app, workspaceRoot) {
|
|
1951
|
+
function appImageOptions(layout, appName, app, workspaceRoot, apps = {}) {
|
|
1848
1952
|
const turboPackage = packageName((0, node_path.isAbsolute)(app.path) ? app.path : (0, node_path.join)(workspaceRoot, app.path)) ?? appName;
|
|
1849
1953
|
return {
|
|
1850
1954
|
imageName: appName,
|
|
@@ -1860,10 +1964,49 @@ function appImageOptions(layout, appName, app, workspaceRoot) {
|
|
|
1860
1964
|
...app.type === "backend" ? {
|
|
1861
1965
|
gkmPaths: layout.gkmPaths,
|
|
1862
1966
|
...layout.workspacePackage && layout.workspacePackage !== turboPackage ? { prunePackages: [layout.workspacePackage] } : {}
|
|
1863
|
-
} : {}
|
|
1967
|
+
} : app.type === "web" ? siteWorkspace(layout, app, apps, workspaceRoot, turboPackage) : {}
|
|
1864
1968
|
};
|
|
1865
1969
|
}
|
|
1866
1970
|
/**
|
|
1971
|
+
* What a site's image carries of the gkm workspace: its config and construct
|
|
1972
|
+
* directories, the workspace's own package where it is nested in a monorepo
|
|
1973
|
+
* (it holds the CLI), and each backend the site calls — whose endpoints its
|
|
1974
|
+
* client is generated from, and whose package their imports resolve in.
|
|
1975
|
+
*/
|
|
1976
|
+
function siteWorkspace(layout, site, apps, workspaceRoot, turboPackage) {
|
|
1977
|
+
const clients = siteClients(site, apps);
|
|
1978
|
+
const packages = /* @__PURE__ */ new Set();
|
|
1979
|
+
if (layout.workspacePackage) packages.add(layout.workspacePackage);
|
|
1980
|
+
for (const { app } of clients) {
|
|
1981
|
+
const backend = apps[app];
|
|
1982
|
+
const name = packageName((0, node_path.isAbsolute)(backend.path) ? backend.path : (0, node_path.join)(workspaceRoot, backend.path));
|
|
1983
|
+
if (name) packages.add(name);
|
|
1984
|
+
}
|
|
1985
|
+
packages.delete(turboPackage);
|
|
1986
|
+
return {
|
|
1987
|
+
gkmPaths: layout.gkmPaths,
|
|
1988
|
+
...packages.size > 0 ? { prunePackages: [...packages].sort() } : {},
|
|
1989
|
+
...clients.length > 0 ? { clients: clients.map(({ app }) => ({
|
|
1990
|
+
app,
|
|
1991
|
+
path: fromBuildRoot(layout, apps[app].path)
|
|
1992
|
+
})) } : {}
|
|
1993
|
+
};
|
|
1994
|
+
}
|
|
1995
|
+
/**
|
|
1996
|
+
* The backends whose clients a site imports: each it depends on that gkm
|
|
1997
|
+
* builds from endpoints — not one with an entry of its own, and not one that
|
|
1998
|
+
* turned OpenAPI off.
|
|
1999
|
+
*/
|
|
2000
|
+
function siteClients(site, apps) {
|
|
2001
|
+
return site.dependencies.filter((name) => {
|
|
2002
|
+
const app = apps[name];
|
|
2003
|
+
if (!app || app.type !== "backend" || app.entry) return false;
|
|
2004
|
+
if (app.openapi === false) return false;
|
|
2005
|
+
if (typeof app.openapi === "object" && app.openapi.enabled === false) return false;
|
|
2006
|
+
return true;
|
|
2007
|
+
}).sort().map((app) => ({ app }));
|
|
2008
|
+
}
|
|
2009
|
+
/**
|
|
1867
2010
|
* The directories the workspace's construct globs start in, relative to its
|
|
1868
2011
|
* root: `./constructs/**\/*.ts` reads from `constructs`.
|
|
1869
2012
|
*/
|
|
@@ -5293,58 +5436,6 @@ logger.info({ port }, 'Worker started');
|
|
|
5293
5436
|
`;
|
|
5294
5437
|
}
|
|
5295
5438
|
//#endregion
|
|
5296
|
-
//#region src/secrets/encryption.ts
|
|
5297
|
-
var encryption_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
|
|
5298
|
-
encryptSecrets: () => encryptSecrets,
|
|
5299
|
-
generateDefineOptions: () => generateDefineOptions,
|
|
5300
|
-
keyFingerprint: () => keyFingerprint
|
|
5301
|
-
});
|
|
5302
|
-
/** AES-256-GCM configuration */
|
|
5303
|
-
const ALGORITHM = "aes-256-gcm";
|
|
5304
|
-
const KEY_LENGTH = 32;
|
|
5305
|
-
const IV_LENGTH = 12;
|
|
5306
|
-
/**
|
|
5307
|
-
* Encrypt secrets for embedding in a bundle.
|
|
5308
|
-
* Uses AES-256-GCM with a randomly generated ephemeral key.
|
|
5309
|
-
*
|
|
5310
|
-
* @param secrets - Key-value pairs to encrypt
|
|
5311
|
-
* @returns Encrypted payload with ephemeral master key
|
|
5312
|
-
*/
|
|
5313
|
-
function encryptSecrets(secrets) {
|
|
5314
|
-
const masterKey = (0, node_crypto.randomBytes)(KEY_LENGTH);
|
|
5315
|
-
const iv = (0, node_crypto.randomBytes)(IV_LENGTH);
|
|
5316
|
-
const plaintext = JSON.stringify(secrets);
|
|
5317
|
-
const cipher = (0, node_crypto.createCipheriv)(ALGORITHM, masterKey, iv);
|
|
5318
|
-
const ciphertext = Buffer.concat([cipher.update(plaintext, "utf-8"), cipher.final()]);
|
|
5319
|
-
const authTag = cipher.getAuthTag();
|
|
5320
|
-
return {
|
|
5321
|
-
encrypted: Buffer.concat([ciphertext, authTag]).toString("base64"),
|
|
5322
|
-
iv: iv.toString("hex"),
|
|
5323
|
-
masterKey: masterKey.toString("hex")
|
|
5324
|
-
};
|
|
5325
|
-
}
|
|
5326
|
-
/**
|
|
5327
|
-
* Generate the define options for tsdown/esbuild.
|
|
5328
|
-
* These will be injected at build time.
|
|
5329
|
-
*/
|
|
5330
|
-
function generateDefineOptions(payload) {
|
|
5331
|
-
return {
|
|
5332
|
-
__GKM_ENCRYPTED_CREDENTIALS__: JSON.stringify(payload.encrypted),
|
|
5333
|
-
__GKM_CREDENTIALS_IV__: JSON.stringify(payload.iv)
|
|
5334
|
-
};
|
|
5335
|
-
}
|
|
5336
|
-
/**
|
|
5337
|
-
* A short, one-way name for a master key: the first 8 hex characters of its
|
|
5338
|
-
* SHA-256.
|
|
5339
|
-
*
|
|
5340
|
-
* Printed where the key itself used to be, so a person can tell which key a
|
|
5341
|
-
* build used — and match it against the one they hold — without the output
|
|
5342
|
-
* carrying a value that decrypts every secret of the stage.
|
|
5343
|
-
*/
|
|
5344
|
-
function keyFingerprint(masterKey) {
|
|
5345
|
-
return (0, node_crypto.createHash)("sha256").update(masterKey).digest("hex").slice(0, 8);
|
|
5346
|
-
}
|
|
5347
|
-
//#endregion
|
|
5348
5439
|
//#region src/build/workers.ts
|
|
5349
5440
|
/** A worker with background work and no backend app to build it from. */
|
|
5350
5441
|
var WorkerHasNoApp = class extends Error {
|
|
@@ -5832,7 +5923,7 @@ function validateImageRef(ref) {
|
|
|
5832
5923
|
}
|
|
5833
5924
|
//#endregion
|
|
5834
5925
|
//#region src/docker/index.ts
|
|
5835
|
-
const logger
|
|
5926
|
+
const logger = require_discover.output;
|
|
5836
5927
|
/** `docker build` failed; what docker printed above says why. */
|
|
5837
5928
|
var DockerBuildFailed = class extends Error {
|
|
5838
5929
|
imageRef;
|
|
@@ -5883,7 +5974,7 @@ async function buildDockerImage(app, buildRoot, options) {
|
|
|
5883
5974
|
const tag = options.tag ?? "latest";
|
|
5884
5975
|
const registry = options.registry;
|
|
5885
5976
|
const fullImageName = validateImageRef(registry ? `${registry}/${app.imageName}:${tag}` : `${app.imageName}:${tag}`);
|
|
5886
|
-
logger
|
|
5977
|
+
logger.log(`\n🐳 Building Docker image: ${fullImageName}`);
|
|
5887
5978
|
try {
|
|
5888
5979
|
await require_run.run("docker", [
|
|
5889
5980
|
"build",
|
|
@@ -5897,7 +5988,7 @@ async function buildDockerImage(app, buildRoot, options) {
|
|
|
5897
5988
|
DOCKER_BUILDKIT: "1"
|
|
5898
5989
|
}
|
|
5899
5990
|
});
|
|
5900
|
-
logger
|
|
5991
|
+
logger.log(`✅ Docker image built: ${fullImageName}`);
|
|
5901
5992
|
} catch (error) {
|
|
5902
5993
|
throw new DockerBuildFailed(fullImageName, error);
|
|
5903
5994
|
}
|
|
@@ -5910,10 +6001,10 @@ async function pushDockerImage(imageName, options, cwd) {
|
|
|
5910
6001
|
const registry = options.registry;
|
|
5911
6002
|
if (!registry) throw new PushNeedsRegistry(imageName);
|
|
5912
6003
|
const fullImageName = validateImageRef(`${registry}/${imageName}:${tag}`);
|
|
5913
|
-
logger
|
|
6004
|
+
logger.log(`\n🚀 Pushing Docker image: ${fullImageName}`);
|
|
5914
6005
|
try {
|
|
5915
6006
|
await require_run.run("docker", ["push", fullImageName], { cwd });
|
|
5916
|
-
logger
|
|
6007
|
+
logger.log(`✅ Docker image pushed: ${fullImageName}`);
|
|
5917
6008
|
} catch (error) {
|
|
5918
6009
|
throw new DockerPushFailed(fullImageName, error);
|
|
5919
6010
|
}
|
|
@@ -5925,26 +6016,27 @@ async function pushDockerImage(imageName, options, cwd) {
|
|
|
5925
6016
|
async function workspaceDockerCommand(workspace, manifest, imageNames = {}, background = {}) {
|
|
5926
6017
|
const results = [];
|
|
5927
6018
|
const layout = imageLayout(workspace);
|
|
5928
|
-
logger
|
|
5929
|
-
logger
|
|
5930
|
-
logger
|
|
6019
|
+
logger.log(`\n🐳 Generating Dockerfiles for workspace: ${workspace.name}`);
|
|
6020
|
+
logger.log(` Build root: ${layout.buildRoot}`);
|
|
6021
|
+
logger.log(` Package manager: ${layout.tools.packageManager}${layout.tools.packageManagerVersion ? `@${layout.tools.packageManagerVersion}` : ""}, turbo@${layout.tools.turboVersion}`);
|
|
5931
6022
|
for (const [appName, app] of Object.entries(workspace.apps)) {
|
|
5932
6023
|
if (app.type === "mobile") {
|
|
5933
|
-
logger
|
|
6024
|
+
logger.log(`\n 📱 Skipping Docker for ${appName} (mobile app — deploy via framework toolchain)`);
|
|
5934
6025
|
continue;
|
|
5935
6026
|
}
|
|
5936
6027
|
const buildType = app.entry ? "entry" : app.type;
|
|
5937
|
-
logger
|
|
6028
|
+
logger.log(`\n 📄 Generating Dockerfile for ${appName} (${buildType})`);
|
|
5938
6029
|
const dockerfile = appDockerfile(appName, app, {
|
|
5939
6030
|
layout,
|
|
5940
6031
|
workspaceRoot: workspace.root,
|
|
6032
|
+
apps: workspace.apps,
|
|
5941
6033
|
...manifest ? { manifest } : {}
|
|
5942
6034
|
});
|
|
5943
6035
|
const path = dockerfileOf(appName, app.path);
|
|
5944
6036
|
const dockerfilePath = (0, node_path.join)(workspace.root, path);
|
|
5945
6037
|
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(dockerfilePath), { recursive: true });
|
|
5946
6038
|
await (0, node_fs_promises.writeFile)(dockerfilePath, dockerfile);
|
|
5947
|
-
logger
|
|
6039
|
+
logger.log(` Generated: ${path}`);
|
|
5948
6040
|
results.push({
|
|
5949
6041
|
appName,
|
|
5950
6042
|
type: app.type,
|
|
@@ -5953,7 +6045,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5953
6045
|
});
|
|
5954
6046
|
}
|
|
5955
6047
|
for (const worker of manifest ? workerUnits(workspace, manifest, background) : []) {
|
|
5956
|
-
logger
|
|
6048
|
+
logger.log(`\n 📄 Generating Dockerfile for ${worker.name} (worker ${worker.id}, built from ${worker.app})`);
|
|
5957
6049
|
const dockerfile = workerDockerfile(worker, workspace.apps[worker.app], {
|
|
5958
6050
|
layout,
|
|
5959
6051
|
workspaceRoot: workspace.root
|
|
@@ -5962,7 +6054,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5962
6054
|
const dockerfilePath = (0, node_path.join)(workspace.root, path);
|
|
5963
6055
|
await (0, node_fs_promises.mkdir)((0, node_path.dirname)(dockerfilePath), { recursive: true });
|
|
5964
6056
|
await (0, node_fs_promises.writeFile)(dockerfilePath, dockerfile);
|
|
5965
|
-
logger
|
|
6057
|
+
logger.log(` Generated: ${path}`);
|
|
5966
6058
|
results.push({
|
|
5967
6059
|
appName: worker.name,
|
|
5968
6060
|
type: "backend",
|
|
@@ -5971,13 +6063,13 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5971
6063
|
});
|
|
5972
6064
|
}
|
|
5973
6065
|
const dockerignorePath = await ensureDockerignore(layout.buildRoot);
|
|
5974
|
-
logger
|
|
6066
|
+
logger.log(`\n Ensured: ${dockerignorePath}`);
|
|
5975
6067
|
const composePath = await writeConstructsCompose(workspace);
|
|
5976
|
-
logger
|
|
5977
|
-
logger
|
|
6068
|
+
logger.log(`\n✅ Generated ${results.length} Dockerfile(s) + ${COMPOSE_PATH}`);
|
|
6069
|
+
logger.log(`\n📋 Build commands (from ${layout.buildRoot}):`);
|
|
5978
6070
|
for (const result of results) {
|
|
5979
6071
|
const icon = result.type === "backend" ? "⚙️" : result.type === "mobile" ? "📱" : "🌐";
|
|
5980
|
-
logger
|
|
6072
|
+
logger.log(` ${icon} docker build -f ${(0, node_path.relative)(layout.buildRoot, result.dockerfile)} -t ${result.imageName} .`);
|
|
5981
6073
|
}
|
|
5982
6074
|
printRunInstructions(workspace);
|
|
5983
6075
|
return {
|
|
@@ -5993,7 +6085,7 @@ async function workspaceDockerCommand(workspace, manifest, imageNames = {}, back
|
|
|
5993
6085
|
* framework. The one choice every builder of images makes.
|
|
5994
6086
|
*/
|
|
5995
6087
|
function appDockerfile(appName, app, options) {
|
|
5996
|
-
const image = appImageOptions(options.layout, appName, app, options.workspaceRoot);
|
|
6088
|
+
const image = appImageOptions(options.layout, appName, app, options.workspaceRoot, options.apps);
|
|
5997
6089
|
if (app.type === "web") return siteDockerfile(appName, app, {
|
|
5998
6090
|
image,
|
|
5999
6091
|
...options.manifest ? { manifest: options.manifest } : {},
|
|
@@ -6096,199 +6188,14 @@ async function writeConstructsCompose(workspace) {
|
|
|
6096
6188
|
stage: workspace.stages.local,
|
|
6097
6189
|
start: false
|
|
6098
6190
|
});
|
|
6099
|
-
logger
|
|
6191
|
+
logger.log(` Generated: ${COMPOSE_PATH} (project root)`);
|
|
6100
6192
|
return (0, node_path.join)(workspace.root, COMPOSE_PATH);
|
|
6101
6193
|
}
|
|
6102
6194
|
function printRunInstructions(workspace) {
|
|
6103
6195
|
const project = (0, node_fs.existsSync)((0, node_path.join)(workspace.root, "docker-compose.yml")) ? " -f docker-compose.yml" : "";
|
|
6104
|
-
logger
|
|
6105
|
-
logger
|
|
6106
|
-
logger
|
|
6107
|
-
}
|
|
6108
|
-
//#endregion
|
|
6109
|
-
//#region src/deploy/docker.ts
|
|
6110
|
-
const logger = require_discover.output;
|
|
6111
|
-
/**
|
|
6112
|
-
* The id the Dockerfile templates mount the encrypted credentials under:
|
|
6113
|
-
* `RUN --mount=type=secret,id=gkm_credentials`.
|
|
6114
|
-
*/
|
|
6115
|
-
const CREDENTIALS_SECRET_ID = "gkm_credentials";
|
|
6116
|
-
/**
|
|
6117
|
-
* Get the full image reference
|
|
6118
|
-
*/
|
|
6119
|
-
function getImageRef(registry, imageName, tag) {
|
|
6120
|
-
if (registry) return `${registry}/${imageName}:${tag}`;
|
|
6121
|
-
return `${imageName}:${tag}`;
|
|
6122
|
-
}
|
|
6123
|
-
/**
|
|
6124
|
-
* The `docker build` argv for an image.
|
|
6125
|
-
*
|
|
6126
|
-
* One element per value, so nothing in a ref or a build arg is read by a
|
|
6127
|
-
* shell, and `--opt=value` rather than `--opt value`, so a value that starts
|
|
6128
|
-
* with `-` cannot be taken for one of docker's own flags.
|
|
6129
|
-
*
|
|
6130
|
-
* @internal Exported for testing
|
|
6131
|
-
*/
|
|
6132
|
-
function dockerBuildArgs(options) {
|
|
6133
|
-
const { dockerfilePath, imageRef, buildArgs = [], credentialsFile } = options;
|
|
6134
|
-
return [
|
|
6135
|
-
"build",
|
|
6136
|
-
"--platform=linux/amd64",
|
|
6137
|
-
`--file=${dockerfilePath}`,
|
|
6138
|
-
`--tag=${imageRef}`,
|
|
6139
|
-
...buildArgs.map((arg) => `--build-arg=${arg}`),
|
|
6140
|
-
...credentialsFile ? [`--secret=id=${CREDENTIALS_SECRET_ID},src=${credentialsFile}`] : [],
|
|
6141
|
-
"."
|
|
6142
|
-
];
|
|
6143
|
-
}
|
|
6144
|
-
/**
|
|
6145
|
-
* The build arg that names which credentials an image embeds: a hash of the
|
|
6146
|
-
* ciphertext, which is not a secret. A BuildKit secret is no part of the
|
|
6147
|
-
* build cache's key, so without it a rebuild with credentials encrypted under
|
|
6148
|
-
* a new key would reuse the layer that embedded the old ones.
|
|
6149
|
-
*/
|
|
6150
|
-
function credentialsBuildArg(credentials) {
|
|
6151
|
-
return `GKM_CIPHERTEXT_HASH=${(0, node_crypto.createHash)("sha256").update(`${credentials.encrypted}\n${credentials.iv}`).digest("hex").slice(0, 16)}`;
|
|
6152
|
-
}
|
|
6153
|
-
/** The secret file's content: ciphertext, then IV, one per line. */
|
|
6154
|
-
function credentialsFileContent(credentials) {
|
|
6155
|
-
return `${credentials.encrypted}\n${credentials.iv}\n`;
|
|
6156
|
-
}
|
|
6157
|
-
/**
|
|
6158
|
-
* Write the encrypted credentials where `docker build --secret` reads them.
|
|
6159
|
-
*
|
|
6160
|
-
* Two lines — ciphertext, then IV — so a template can split them with `sed`
|
|
6161
|
-
* in any base image. Owner-only, in a directory of its own, and the returned
|
|
6162
|
-
* cleanup removes both whatever the build did.
|
|
6163
|
-
*
|
|
6164
|
-
* @internal Exported for testing
|
|
6165
|
-
*/
|
|
6166
|
-
async function writeCredentialsFile(credentials) {
|
|
6167
|
-
const dir = await (0, node_fs_promises.mkdtemp)((0, node_path.join)((0, node_os.tmpdir)(), "gkm-credentials-"));
|
|
6168
|
-
const path = (0, node_path.join)(dir, CREDENTIALS_SECRET_ID);
|
|
6169
|
-
await (0, node_fs_promises.writeFile)(path, credentialsFileContent(credentials), { mode: 384 });
|
|
6170
|
-
await (0, node_fs_promises.chmod)(path, 384);
|
|
6171
|
-
return {
|
|
6172
|
-
path,
|
|
6173
|
-
cleanup: () => (0, node_fs_promises.rm)(dir, {
|
|
6174
|
-
recursive: true,
|
|
6175
|
-
force: true
|
|
6176
|
-
})
|
|
6177
|
-
};
|
|
6178
|
-
}
|
|
6179
|
-
/**
|
|
6180
|
-
* Build Docker image
|
|
6181
|
-
* @param imageRef - Full image reference (registry/name:tag)
|
|
6182
|
-
* @param buildArgs - Build arguments to pass to docker build
|
|
6183
|
-
* @param credentials - Encrypted credentials, passed as a build secret
|
|
6184
|
-
*/
|
|
6185
|
-
async function buildImage(imageRef, buildArgs, credentials, { cwd, dockerfile, signal, stdio }) {
|
|
6186
|
-
logger.log(`\n🔨 Building Docker image: ${imageRef}`);
|
|
6187
|
-
logger.log(" Generating Dockerfile...");
|
|
6188
|
-
const { buildRoot } = await dockerCommand({ cwd });
|
|
6189
|
-
const dockerfilePath = (0, node_path.relative)(buildRoot, dockerfile);
|
|
6190
|
-
const secret = credentials ? await writeCredentialsFile(credentials) : void 0;
|
|
6191
|
-
try {
|
|
6192
|
-
await require_run.run("docker", dockerBuildArgs({
|
|
6193
|
-
dockerfilePath,
|
|
6194
|
-
imageRef,
|
|
6195
|
-
buildArgs: [...buildArgs ?? [], ...credentials ? [credentialsBuildArg(credentials)] : []],
|
|
6196
|
-
credentialsFile: secret?.path
|
|
6197
|
-
}), {
|
|
6198
|
-
cwd: buildRoot,
|
|
6199
|
-
env: {
|
|
6200
|
-
...process.env,
|
|
6201
|
-
DOCKER_BUILDKIT: "1"
|
|
6202
|
-
},
|
|
6203
|
-
...signal ? { signal } : {},
|
|
6204
|
-
...stdio ? { stdio } : {}
|
|
6205
|
-
});
|
|
6206
|
-
logger.log(`✅ Image built: ${imageRef}`);
|
|
6207
|
-
} catch (error) {
|
|
6208
|
-
throw new DockerBuildFailed(imageRef, error);
|
|
6209
|
-
} finally {
|
|
6210
|
-
await secret?.cleanup();
|
|
6211
|
-
}
|
|
6212
|
-
}
|
|
6213
|
-
/**
|
|
6214
|
-
* Push Docker image to registry
|
|
6215
|
-
*/
|
|
6216
|
-
async function pushImage(imageRef, { cwd, signal, stdio }) {
|
|
6217
|
-
logger.log(`\n☁️ Pushing image: ${imageRef}`);
|
|
6218
|
-
try {
|
|
6219
|
-
await require_run.run("docker", ["push", imageRef], {
|
|
6220
|
-
cwd,
|
|
6221
|
-
...signal ? { signal } : {},
|
|
6222
|
-
...stdio ? { stdio } : {}
|
|
6223
|
-
});
|
|
6224
|
-
logger.log(`✅ Image pushed: ${imageRef}`);
|
|
6225
|
-
} catch (error) {
|
|
6226
|
-
throw new DockerPushFailed(imageRef, error);
|
|
6227
|
-
}
|
|
6228
|
-
}
|
|
6229
|
-
/**
|
|
6230
|
-
* The digest the registry gave a pushed image, `sha256:…`.
|
|
6231
|
-
*
|
|
6232
|
-
* A tag can be pushed over — by the next deploy, or by anything else that
|
|
6233
|
-
* shares the repository — and the digest is what says which image a stage
|
|
6234
|
-
* actually ran. `RepoDigests` has one entry per repository the image was
|
|
6235
|
-
* pushed to, so the one for this ref's repository is picked by name.
|
|
6236
|
-
*
|
|
6237
|
-
* @internal Exported for testing
|
|
6238
|
-
*/
|
|
6239
|
-
async function pushedDigest(imageRef, { cwd, signal } = { cwd: process.cwd() }) {
|
|
6240
|
-
const repository = imageRef.split("@")[0].replace(/:[\w][\w.-]*$/, "");
|
|
6241
|
-
const output = await require_run.runOutput("docker", [
|
|
6242
|
-
"image",
|
|
6243
|
-
"inspect",
|
|
6244
|
-
"--format={{json .RepoDigests}}",
|
|
6245
|
-
imageRef
|
|
6246
|
-
], {
|
|
6247
|
-
cwd,
|
|
6248
|
-
...signal ? { signal } : {}
|
|
6249
|
-
});
|
|
6250
|
-
let digests;
|
|
6251
|
-
try {
|
|
6252
|
-
digests = JSON.parse(output.trim() || "[]");
|
|
6253
|
-
} catch {
|
|
6254
|
-
return;
|
|
6255
|
-
}
|
|
6256
|
-
if (!Array.isArray(digests)) return void 0;
|
|
6257
|
-
return digests.find((entry) => typeof entry === "string" && entry.startsWith(`${repository}@`))?.slice(repository.length + 1);
|
|
6258
|
-
}
|
|
6259
|
-
/**
|
|
6260
|
-
* Deploy using Docker (build and optionally push image)
|
|
6261
|
-
*/
|
|
6262
|
-
async function deployDocker(options) {
|
|
6263
|
-
const { stage, tag, skipPush, masterKey, config, buildArgs, credentials } = options;
|
|
6264
|
-
const imageName = config.imageName;
|
|
6265
|
-
const imageRef = validateImageRef(getImageRef(config.registry, imageName, tag));
|
|
6266
|
-
const cwd = options.cwd ?? process.cwd();
|
|
6267
|
-
const docker = {
|
|
6268
|
-
cwd,
|
|
6269
|
-
dockerfile: (0, node_path.join)(cwd, options.dockerfile ?? dockerfileOf(config.appName ?? imageName, options.appPath ?? ".")),
|
|
6270
|
-
...options.signal ? { signal: options.signal } : {},
|
|
6271
|
-
...options.stdio ? { stdio: options.stdio } : {}
|
|
6272
|
-
};
|
|
6273
|
-
await buildImage(imageRef, buildArgs, credentials, docker);
|
|
6274
|
-
let digest;
|
|
6275
|
-
if (!skipPush) {
|
|
6276
|
-
if (!config.registry) logger.warn("\n⚠️ No registry configured. Use --skip-push or configure docker.registry in gkm.config.ts");
|
|
6277
|
-
else {
|
|
6278
|
-
await pushImage(imageRef, docker);
|
|
6279
|
-
digest = await pushedDigest(imageRef, docker);
|
|
6280
|
-
}
|
|
6281
|
-
}
|
|
6282
|
-
logger.log("\n✅ Docker deployment ready!");
|
|
6283
|
-
logger.log(`\n📋 Deployment details:`);
|
|
6284
|
-
logger.log(` Image: ${imageRef}`);
|
|
6285
|
-
logger.log(` Stage: ${stage}`);
|
|
6286
|
-
if (masterKey) logger.log(`\n🔐 Run the container with GKM_MASTER_KEY set to the key with fingerprint ${keyFingerprint(masterKey)}.`);
|
|
6287
|
-
return {
|
|
6288
|
-
imageRef,
|
|
6289
|
-
...digest ? { digest } : {},
|
|
6290
|
-
masterKey
|
|
6291
|
-
};
|
|
6196
|
+
logger.log("\n📋 Run everything (the apps sit behind the \"apps\" profile):");
|
|
6197
|
+
logger.log(" gkm setup # starts the containers and creates what they hold");
|
|
6198
|
+
logger.log(` docker compose -f ${COMPOSE_PATH}${project} --profile apps up --build`);
|
|
6292
6199
|
}
|
|
6293
6200
|
//#endregion
|
|
6294
6201
|
//#region src/deploy/generated.ts
|
|
@@ -6628,6 +6535,18 @@ Object.defineProperty(exports, "DevServicesNeedServerTarget", {
|
|
|
6628
6535
|
return DevServicesNeedServerTarget;
|
|
6629
6536
|
}
|
|
6630
6537
|
});
|
|
6538
|
+
Object.defineProperty(exports, "DockerBuildFailed", {
|
|
6539
|
+
enumerable: true,
|
|
6540
|
+
get: function() {
|
|
6541
|
+
return DockerBuildFailed;
|
|
6542
|
+
}
|
|
6543
|
+
});
|
|
6544
|
+
Object.defineProperty(exports, "DockerPushFailed", {
|
|
6545
|
+
enumerable: true,
|
|
6546
|
+
get: function() {
|
|
6547
|
+
return DockerPushFailed;
|
|
6548
|
+
}
|
|
6549
|
+
});
|
|
6631
6550
|
Object.defineProperty(exports, "ExternalServicesNotConfigured", {
|
|
6632
6551
|
enumerable: true,
|
|
6633
6552
|
get: function() {
|
|
@@ -6796,24 +6715,6 @@ Object.defineProperty(exports, "createEntryWrapper", {
|
|
|
6796
6715
|
return createEntryWrapper;
|
|
6797
6716
|
}
|
|
6798
6717
|
});
|
|
6799
|
-
Object.defineProperty(exports, "credentialsBuildArg", {
|
|
6800
|
-
enumerable: true,
|
|
6801
|
-
get: function() {
|
|
6802
|
-
return credentialsBuildArg;
|
|
6803
|
-
}
|
|
6804
|
-
});
|
|
6805
|
-
Object.defineProperty(exports, "credentialsFileContent", {
|
|
6806
|
-
enumerable: true,
|
|
6807
|
-
get: function() {
|
|
6808
|
-
return credentialsFileContent;
|
|
6809
|
-
}
|
|
6810
|
-
});
|
|
6811
|
-
Object.defineProperty(exports, "deployDocker", {
|
|
6812
|
-
enumerable: true,
|
|
6813
|
-
get: function() {
|
|
6814
|
-
return deployDocker;
|
|
6815
|
-
}
|
|
6816
|
-
});
|
|
6817
6718
|
Object.defineProperty(exports, "deployIdentity", {
|
|
6818
6719
|
enumerable: true,
|
|
6819
6720
|
get: function() {
|
|
@@ -6850,16 +6751,10 @@ Object.defineProperty(exports, "dockerCommand", {
|
|
|
6850
6751
|
return dockerCommand;
|
|
6851
6752
|
}
|
|
6852
6753
|
});
|
|
6853
|
-
Object.defineProperty(exports, "
|
|
6854
|
-
enumerable: true,
|
|
6855
|
-
get: function() {
|
|
6856
|
-
return encryptSecrets;
|
|
6857
|
-
}
|
|
6858
|
-
});
|
|
6859
|
-
Object.defineProperty(exports, "encryption_exports", {
|
|
6754
|
+
Object.defineProperty(exports, "dockerfileOf", {
|
|
6860
6755
|
enumerable: true,
|
|
6861
6756
|
get: function() {
|
|
6862
|
-
return
|
|
6757
|
+
return dockerfileOf;
|
|
6863
6758
|
}
|
|
6864
6759
|
});
|
|
6865
6760
|
Object.defineProperty(exports, "ensureDockerignore", {
|
|
@@ -6934,6 +6829,12 @@ Object.defineProperty(exports, "hostFor", {
|
|
|
6934
6829
|
return hostFor;
|
|
6935
6830
|
}
|
|
6936
6831
|
});
|
|
6832
|
+
Object.defineProperty(exports, "imageBuildCredentials", {
|
|
6833
|
+
enumerable: true,
|
|
6834
|
+
get: function() {
|
|
6835
|
+
return imageBuildCredentials;
|
|
6836
|
+
}
|
|
6837
|
+
});
|
|
6937
6838
|
Object.defineProperty(exports, "imageLayout", {
|
|
6938
6839
|
enumerable: true,
|
|
6939
6840
|
get: function() {
|
|
@@ -6964,6 +6865,12 @@ Object.defineProperty(exports, "isDnsVerified", {
|
|
|
6964
6865
|
return isDnsVerified;
|
|
6965
6866
|
}
|
|
6966
6867
|
});
|
|
6868
|
+
Object.defineProperty(exports, "isImageBuild", {
|
|
6869
|
+
enumerable: true,
|
|
6870
|
+
get: function() {
|
|
6871
|
+
return isImageBuild;
|
|
6872
|
+
}
|
|
6873
|
+
});
|
|
6967
6874
|
Object.defineProperty(exports, "isMainFrontendApp", {
|
|
6968
6875
|
enumerable: true,
|
|
6969
6876
|
get: function() {
|
|
@@ -6994,12 +6901,6 @@ Object.defineProperty(exports, "isRemoteStore", {
|
|
|
6994
6901
|
return isRemoteStore;
|
|
6995
6902
|
}
|
|
6996
6903
|
});
|
|
6997
|
-
Object.defineProperty(exports, "keyFingerprint", {
|
|
6998
|
-
enumerable: true,
|
|
6999
|
-
get: function() {
|
|
7000
|
-
return keyFingerprint;
|
|
7001
|
-
}
|
|
7002
|
-
});
|
|
7003
6904
|
Object.defineProperty(exports, "keystoreProject", {
|
|
7004
6905
|
enumerable: true,
|
|
7005
6906
|
get: function() {
|
|
@@ -7234,6 +7135,12 @@ Object.defineProperty(exports, "storage_exports", {
|
|
|
7234
7135
|
return storage_exports;
|
|
7235
7136
|
}
|
|
7236
7137
|
});
|
|
7138
|
+
Object.defineProperty(exports, "storeFromConfig", {
|
|
7139
|
+
enumerable: true,
|
|
7140
|
+
get: function() {
|
|
7141
|
+
return storeFromConfig;
|
|
7142
|
+
}
|
|
7143
|
+
});
|
|
7237
7144
|
Object.defineProperty(exports, "store_exports", {
|
|
7238
7145
|
enumerable: true,
|
|
7239
7146
|
get: function() {
|
|
@@ -7313,4 +7220,4 @@ Object.defineProperty(exports, "workspace_exports", {
|
|
|
7313
7220
|
}
|
|
7314
7221
|
});
|
|
7315
7222
|
|
|
7316
|
-
//# sourceMappingURL=state-
|
|
7223
|
+
//# sourceMappingURL=state-C2qi0iQw.cjs.map
|