@geekmidas/cli 10.0.0-alpha.52 → 10.0.0-alpha.53
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/{backends-BXcwhb7p.cjs → backends-D5aDWxuA.cjs} +2 -2
- package/dist/{backends-BXcwhb7p.cjs.map → backends-D5aDWxuA.cjs.map} +1 -1
- package/dist/{backends-CLq1wlQf.mjs → backends-Dfeu5Dgc.mjs} +2 -2
- package/dist/{backends-CLq1wlQf.mjs.map → backends-Dfeu5Dgc.mjs.map} +1 -1
- package/dist/{encryption-Cv-Ej9vR.mjs → encryption-O-XdeNxe.mjs} +2 -2
- package/dist/{encryption-Cv-Ej9vR.mjs.map → encryption-O-XdeNxe.mjs.map} +1 -1
- package/dist/{encryption-DCsdx4Po.cjs → encryption-tB4LqLKN.cjs} +2 -2
- package/dist/{encryption-DCsdx4Po.cjs.map → encryption-tB4LqLKN.cjs.map} +1 -1
- package/dist/index.cjs +75 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +75 -35
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-DmabhO_N.mjs → migrate-CHQyNzj-.mjs} +2 -2
- package/dist/{migrate-DmabhO_N.mjs.map → migrate-CHQyNzj-.mjs.map} +1 -1
- package/dist/{migrate-DCxK1NRd.cjs → migrate-SDIRUyY5.cjs} +2 -2
- package/dist/{migrate-DCxK1NRd.cjs.map → migrate-SDIRUyY5.cjs.map} +1 -1
- package/dist/{ready-tQLNHNya.mjs → ready-C8wG_d0v.mjs} +7 -3
- package/dist/ready-C8wG_d0v.mjs.map +1 -0
- package/dist/{ready-ClUpTxoL.cjs → ready-VkNwfJu7.cjs} +7 -3
- package/dist/ready-VkNwfJu7.cjs.map +1 -0
- package/dist/vitest.cjs +1 -1
- package/dist/vitest.mjs +1 -1
- package/dist/{workspace-BEGUDNwK.cjs → workspace-P_V5t4Uk.cjs} +3 -3
- package/dist/{workspace-BEGUDNwK.cjs.map → workspace-P_V5t4Uk.cjs.map} +1 -1
- package/dist/{workspace-fa5H6l7D.mjs → workspace-qcva2dTt.mjs} +3 -3
- package/dist/{workspace-fa5H6l7D.mjs.map → workspace-qcva2dTt.mjs.map} +1 -1
- package/package.json +14 -14
- package/dist/ready-ClUpTxoL.cjs.map +0 -1
- package/dist/ready-tQLNHNya.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_ready = require("./ready-
|
|
1
|
+
const require_ready = require("./ready-VkNwfJu7.cjs");
|
|
2
2
|
//#region src/workspace/backends.ts
|
|
3
3
|
/**
|
|
4
4
|
* Which backend each declared kind resolves to — decided by where the project
|
|
@@ -79,4 +79,4 @@ Object.defineProperty(exports, "storageBackendFor", {
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
//# sourceMappingURL=backends-
|
|
82
|
+
//# sourceMappingURL=backends-D5aDWxuA.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backends-
|
|
1
|
+
{"version":3,"file":"backends-D5aDWxuA.cjs","names":["DEFAULT_CACHE","DEFAULT_STORAGE","DEFAULT_EVENTS"],"sources":["../src/workspace/backends.ts"],"sourcesContent":["/**\n * Which backend each declared kind resolves to — decided by where the project\n * deploys, and by nothing else.\n *\n * These used to be read out of a `services:` block, where one key answered two\n * questions: *does this exist* and *what backs it*. The first is the manifest's\n * — a declared `Cache` is why there is a cache — and the second is the deploy\n * target's, because the right cache for a Lambda is not the right cache for a\n * box already running Postgres. With both answered elsewhere there was nothing\n * left for the block to say, so it is gone and these read the target.\n *\n * Mail has no answer here at all: every provider speaks SMTP, so the provider\n * is whichever one the stage's mail URL points at.\n */\n\nimport {\n\ttype CacheBackend,\n\tDEFAULT_CACHE,\n\tDEFAULT_EVENTS,\n\tDEFAULT_STORAGE,\n\ttype EventsBackend,\n\ttype MainProvider,\n\ttype StorageBackend,\n} from '../types.js';\n\n/**\n * Which family of defaults a workspace's deploy target belongs to.\n *\n * One question, asked once: **does this target run containers the project\n * controls?** Dokploy and a bare server do, so a bucket or a cache can live\n * beside the app; AWS, Vercel and Cloudflare do not, so the default has to be\n * something managed. That is the whole of the distinction, and it is why\n * `MainProvider` is the right axis rather than the deploy target's own name —\n * three targets share one answer.\n *\n * An AWS deploy names `deploy.default: 'sst'`, because it goes through SST.\n */\nexport function providerOf(workspace: {\n\tdeploy?: { default?: string } | undefined;\n}): MainProvider {\n\tconst target = workspace.deploy?.default;\n\n\treturn target === 'dokploy' || target === 'server' ? 'server' : 'aws';\n}\n\n/**\n * The cache backend a target implies.\n *\n * The same answer locally and deployed: a local `gkm dev` for an AWS app still\n * uses the Upstash protocol, because a backend that differed between the two\n * would be worse than a slower one.\n */\nexport function cacheBackendFor(on: MainProvider): CacheBackend {\n\treturn DEFAULT_CACHE[on];\n}\n\n/** Where a declared bucket lives on a target. */\nexport function storageBackendFor(on: MainProvider): StorageBackend {\n\treturn DEFAULT_STORAGE[on];\n}\n\n/**\n * Which broker carries declared queues and topics on a target.\n *\n * Only consulted when something declares one; a project with no `Topic` or\n * `Queue` has no events at all, whatever the target.\n */\nexport function eventsBackendFor(on: MainProvider): EventsBackend {\n\treturn DEFAULT_EVENTS[on];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,WAAW,WAEV;CAChB,MAAM,SAAS,UAAU,QAAQ;CAEjC,OAAO,WAAW,aAAa,WAAW,WAAW,WAAW;AACjE;;;;;;;;AASA,SAAgB,gBAAgB,IAAgC;CAC/D,OAAOA,cAAAA,cAAc;AACtB;;AAGA,SAAgB,kBAAkB,IAAkC;CACnE,OAAOC,cAAAA,gBAAgB;AACxB;;;;;;;AAQA,SAAgB,iBAAiB,IAAiC;CACjE,OAAOC,cAAAA,eAAe;AACvB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as DEFAULT_EVENTS, f as DEFAULT_STORAGE, u as DEFAULT_CACHE } from "./ready-
|
|
1
|
+
import { d as DEFAULT_EVENTS, f as DEFAULT_STORAGE, u as DEFAULT_CACHE } from "./ready-C8wG_d0v.mjs";
|
|
2
2
|
//#region src/workspace/backends.ts
|
|
3
3
|
/**
|
|
4
4
|
* Which backend each declared kind resolves to — decided by where the project
|
|
@@ -56,4 +56,4 @@ function eventsBackendFor(on) {
|
|
|
56
56
|
//#endregion
|
|
57
57
|
export { storageBackendFor as i, eventsBackendFor as n, providerOf as r, cacheBackendFor as t };
|
|
58
58
|
|
|
59
|
-
//# sourceMappingURL=backends-
|
|
59
|
+
//# sourceMappingURL=backends-Dfeu5Dgc.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backends-
|
|
1
|
+
{"version":3,"file":"backends-Dfeu5Dgc.mjs","names":[],"sources":["../src/workspace/backends.ts"],"sourcesContent":["/**\n * Which backend each declared kind resolves to — decided by where the project\n * deploys, and by nothing else.\n *\n * These used to be read out of a `services:` block, where one key answered two\n * questions: *does this exist* and *what backs it*. The first is the manifest's\n * — a declared `Cache` is why there is a cache — and the second is the deploy\n * target's, because the right cache for a Lambda is not the right cache for a\n * box already running Postgres. With both answered elsewhere there was nothing\n * left for the block to say, so it is gone and these read the target.\n *\n * Mail has no answer here at all: every provider speaks SMTP, so the provider\n * is whichever one the stage's mail URL points at.\n */\n\nimport {\n\ttype CacheBackend,\n\tDEFAULT_CACHE,\n\tDEFAULT_EVENTS,\n\tDEFAULT_STORAGE,\n\ttype EventsBackend,\n\ttype MainProvider,\n\ttype StorageBackend,\n} from '../types.js';\n\n/**\n * Which family of defaults a workspace's deploy target belongs to.\n *\n * One question, asked once: **does this target run containers the project\n * controls?** Dokploy and a bare server do, so a bucket or a cache can live\n * beside the app; AWS, Vercel and Cloudflare do not, so the default has to be\n * something managed. That is the whole of the distinction, and it is why\n * `MainProvider` is the right axis rather than the deploy target's own name —\n * three targets share one answer.\n *\n * An AWS deploy names `deploy.default: 'sst'`, because it goes through SST.\n */\nexport function providerOf(workspace: {\n\tdeploy?: { default?: string } | undefined;\n}): MainProvider {\n\tconst target = workspace.deploy?.default;\n\n\treturn target === 'dokploy' || target === 'server' ? 'server' : 'aws';\n}\n\n/**\n * The cache backend a target implies.\n *\n * The same answer locally and deployed: a local `gkm dev` for an AWS app still\n * uses the Upstash protocol, because a backend that differed between the two\n * would be worse than a slower one.\n */\nexport function cacheBackendFor(on: MainProvider): CacheBackend {\n\treturn DEFAULT_CACHE[on];\n}\n\n/** Where a declared bucket lives on a target. */\nexport function storageBackendFor(on: MainProvider): StorageBackend {\n\treturn DEFAULT_STORAGE[on];\n}\n\n/**\n * Which broker carries declared queues and topics on a target.\n *\n * Only consulted when something declares one; a project with no `Topic` or\n * `Queue` has no events at all, whatever the target.\n */\nexport function eventsBackendFor(on: MainProvider): EventsBackend {\n\treturn DEFAULT_EVENTS[on];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,WAAW,WAEV;CAChB,MAAM,SAAS,UAAU,QAAQ;CAEjC,OAAO,WAAW,aAAa,WAAW,WAAW,WAAW;AACjE;;;;;;;;AASA,SAAgB,gBAAgB,IAAgC;CAC/D,OAAO,cAAc;AACtB;;AAGA,SAAgB,kBAAkB,IAAkC;CACnE,OAAO,gBAAgB;AACxB;;;;;;;AAQA,SAAgB,iBAAiB,IAAiC;CACjE,OAAO,eAAe;AACvB"}
|
|
@@ -2,7 +2,7 @@ import { u as loadWorkspaceSettings } from "./config-SOkDH-n1.mjs";
|
|
|
2
2
|
import { D as assertDeployedStage } from "./workspace-bOsks1uk.mjs";
|
|
3
3
|
import { a as withCustomSecret } from "./storage-BzaUxmqe.mjs";
|
|
4
4
|
import { n as secretsStoreFor } from "./store-DeGATCS-.mjs";
|
|
5
|
-
import { r as providerOf } from "./backends-
|
|
5
|
+
import { r as providerOf } from "./backends-Dfeu5Dgc.mjs";
|
|
6
6
|
import { canonicalId, provideKey } from "@geekmidas/manifest";
|
|
7
7
|
import { parseKeyring, retireKey, rotateKeyring } from "@geekmidas/constructs/encryption";
|
|
8
8
|
//#region src/encryption/index.ts
|
|
@@ -87,4 +87,4 @@ async function updateKeyring(construct, { stage }, context, update) {
|
|
|
87
87
|
//#endregion
|
|
88
88
|
export { encryptionRetireCommand, encryptionRotateCommand };
|
|
89
89
|
|
|
90
|
-
//# sourceMappingURL=encryption-
|
|
90
|
+
//# sourceMappingURL=encryption-O-XdeNxe.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption-
|
|
1
|
+
{"version":3,"file":"encryption-O-XdeNxe.mjs","names":[],"sources":["../src/encryption/index.ts"],"sourcesContent":["/**\n * `gkm encryption:rotate` and `gkm encryption:retire` — the keyring of an\n * `Encryption` construct on a server stage.\n *\n * Rotating adds a key in front and keeps every older one, so what they wrote\n * still opens. Retiring removes one, and is the half that makes rotating worth\n * doing: until a key is gone, it still opens everything it ever wrote. It is\n * never automatic, because the only thing that knows nothing is left under a\n * key is the sweep that re-encrypted the column — so it is done after one,\n * deliberately, by name.\n *\n * Neither applies everywhere, and each says so rather than doing something\n * that looks right: a local stage's keyring is derived and would be replaced on\n * the next `gkm dev`, and on AWS the key is KMS's, which rotates it itself and\n * never strands a value.\n */\n\nimport {\n\tparseKeyring,\n\tretireKey,\n\trotateKeyring,\n} from '@geekmidas/constructs/encryption';\nimport { canonicalId, provideKey } from '@geekmidas/manifest';\nimport { loadWorkspaceSettings } from '../config';\nimport { withCustomSecret } from '../secrets/storage.js';\nimport { type SecretsStore, secretsStoreFor } from '../secrets/store.js';\nimport { providerOf } from '../workspace/backends.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\nconst logger = console;\n\nexport class LocalKeyringIsDerived extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly stage: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${stage}' is the local stage, where ${construct}'s keyring is derived from the project and stage — nothing stored there would be read. Rotate a deployed stage: gkm encryption:rotate ${construct} --stage <stage>.`,\n\t\t);\n\t\tthis.name = 'LocalKeyringIsDerived';\n\t}\n}\n\nexport class KmsRotatesItself extends Error {\n\tconstructor(readonly construct: string) {\n\t\tsuper(\n\t\t\t`${construct} is a KMS key on AWS: KMS rotates it yearly and keeps every version, so no value is ever stranded and there is no key to retire. Nothing to do here.`,\n\t\t);\n\t\tthis.name = 'KmsRotatesItself';\n\t}\n}\n\nexport class NoKeyringYet extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly stage: string,\n\t\treadonly key: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${stage}' has no ${key} yet. The first deploy generates ${construct}'s keyring: gkm deploy --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'NoKeyringYet';\n\t}\n}\n\nexport interface EncryptionCommandOptions {\n\tstage: string;\n}\n\n/** Where a command reads and writes; the real ones unless a test says. */\nexport interface EncryptionCommandContext {\n\tworkspace?: NormalizedWorkspace;\n\tstore?: SecretsStore;\n}\n\nexport async function encryptionRotateCommand(\n\tconstruct: string,\n\toptions: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext = {},\n): Promise<string> {\n\treturn updateKeyring(construct, options, context, (id, url) => {\n\t\tconst next = rotateKeyring(id, url);\n\t\tconst [current, ...older] = parseKeyring(id, next).keys.map(({ id }) => id);\n\n\t\tlogger.log(`\\n✓ ${id} on '${options.stage}' now writes with '${current}'.`);\n\t\tlogger.log(\n\t\t\t` Still opening: ${older.join(', ')}. Redeploy to start writing with '${current}', reencrypt what is stored, then: gkm encryption:retire ${id} <key> --stage ${options.stage}`,\n\t\t);\n\t\treturn next;\n\t});\n}\n\nexport async function encryptionRetireCommand(\n\tconstruct: string,\n\tkeyId: string,\n\toptions: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext = {},\n): Promise<string> {\n\treturn updateKeyring(construct, options, context, (id, url) => {\n\t\tconst next = retireKey(id, url, keyId);\n\n\t\tlogger.log(\n\t\t\t`\\n✓ ${id} on '${options.stage}' no longer holds '${keyId}'. Anything still under it cannot be read after the next deploy.`,\n\t\t);\n\t\treturn next;\n\t});\n}\n\nasync function updateKeyring(\n\tconstruct: string,\n\t{ stage }: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext,\n\tupdate: (id: string, url: string) => string,\n): Promise<string> {\n\tconst workspace = context.workspace ?? (await loadWorkspaceSettings());\n\tconst id = canonicalId(construct);\n\n\tif (stage === workspace.stages.local) {\n\t\tthrow new LocalKeyringIsDerived(id, stage);\n\t}\n\tassertDeployedStage(workspace.stages, stage);\n\tif (providerOf(workspace) === 'aws') throw new KmsRotatesItself(id);\n\n\tconst store = context.store ?? (await secretsStoreFor(workspace, stage));\n\tconst key = provideKey(id, 'url');\n\tconst secrets = await store.read(stage);\n\tconst url = secrets?.custom[key];\n\tif (!secrets || !url) throw new NoKeyringYet(id, stage, key);\n\n\tconst next = update(id, url);\n\tawait store.write(stage, withCustomSecret(secrets, key, next));\n\treturn next;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAM,SAAS;AAEf,IAAa,wBAAb,cAA2C,MAAM;CAEtC;CACA;CAFV,YACC,WACA,OACC;EACD,MACC,IAAI,MAAM,8BAA8B,UAAU,wIAAwI,UAAU,kBACrM;EALS,KAAA,YAAA;EACA,KAAA,QAAA;EAKT,KAAK,OAAO;CACb;AACD;AAEA,IAAa,mBAAb,cAAsC,MAAM;CACtB;CAArB,YAAY,WAA4B;EACvC,MACC,GAAG,UAAU,qJACd;EAHoB,KAAA,YAAA;EAIpB,KAAK,OAAO;CACb;AACD;AAEA,IAAa,eAAb,cAAkC,MAAM;CAE7B;CACA;CACA;CAHV,YACC,WACA,OACA,KACC;EACD,MACC,IAAI,MAAM,WAAW,IAAI,mCAAmC,UAAU,iCAAiC,MAAM,EAC9G;EANS,KAAA,YAAA;EACA,KAAA,QAAA;EACA,KAAA,MAAA;EAKT,KAAK,OAAO;CACb;AACD;AAYA,eAAsB,wBACrB,WACA,SACA,UAAoC,CAAC,GACnB;CAClB,OAAO,cAAc,WAAW,SAAS,UAAU,IAAI,QAAQ;EAC9D,MAAM,OAAO,cAAc,IAAI,GAAG;EAClC,MAAM,CAAC,SAAS,GAAG,SAAS,aAAa,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,SAAS,EAAE;EAE1E,OAAO,IAAI,OAAO,GAAG,OAAO,QAAQ,MAAM,qBAAqB,QAAQ,GAAG;EAC1E,OAAO,IACN,oBAAoB,MAAM,KAAK,IAAI,EAAE,oCAAoC,QAAQ,2DAA2D,GAAG,iBAAiB,QAAQ,OACzK;EACA,OAAO;CACR,CAAC;AACF;AAEA,eAAsB,wBACrB,WACA,OACA,SACA,UAAoC,CAAC,GACnB;CAClB,OAAO,cAAc,WAAW,SAAS,UAAU,IAAI,QAAQ;EAC9D,MAAM,OAAO,UAAU,IAAI,KAAK,KAAK;EAErC,OAAO,IACN,OAAO,GAAG,OAAO,QAAQ,MAAM,qBAAqB,MAAM,iEAC3D;EACA,OAAO;CACR,CAAC;AACF;AAEA,eAAe,cACd,WACA,EAAE,SACF,SACA,QACkB;CAClB,MAAM,YAAY,QAAQ,aAAc,MAAM,sBAAsB;CACpE,MAAM,KAAK,YAAY,SAAS;CAEhC,IAAI,UAAU,UAAU,OAAO,OAC9B,MAAM,IAAI,sBAAsB,IAAI,KAAK;CAE1C,oBAAoB,UAAU,QAAQ,KAAK;CAC3C,IAAI,WAAW,SAAS,MAAM,OAAO,MAAM,IAAI,iBAAiB,EAAE;CAElE,MAAM,QAAQ,QAAQ,SAAU,MAAM,gBAAgB,WAAW,KAAK;CACtE,MAAM,MAAM,WAAW,IAAI,KAAK;CAChC,MAAM,UAAU,MAAM,MAAM,KAAK,KAAK;CACtC,MAAM,MAAM,SAAS,OAAO;CAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,MAAM,IAAI,aAAa,IAAI,OAAO,GAAG;CAE3D,MAAM,OAAO,OAAO,IAAI,GAAG;CAC3B,MAAM,MAAM,MAAM,OAAO,iBAAiB,SAAS,KAAK,IAAI,CAAC;CAC7D,OAAO;AACR"}
|
|
@@ -2,7 +2,7 @@ const require_config = require("./config-Cvr5fCbn.cjs");
|
|
|
2
2
|
const require_workspace = require("./workspace-BcCiLzTO.cjs");
|
|
3
3
|
const require_storage = require("./storage-CSGoC3bK.cjs");
|
|
4
4
|
const require_store = require("./store-DQgxT_WR.cjs");
|
|
5
|
-
const require_backends = require("./backends-
|
|
5
|
+
const require_backends = require("./backends-D5aDWxuA.cjs");
|
|
6
6
|
let _geekmidas_manifest = require("@geekmidas/manifest");
|
|
7
7
|
let _geekmidas_constructs_encryption = require("@geekmidas/constructs/encryption");
|
|
8
8
|
//#region src/encryption/index.ts
|
|
@@ -88,4 +88,4 @@ async function updateKeyring(construct, { stage }, context, update) {
|
|
|
88
88
|
exports.encryptionRetireCommand = encryptionRetireCommand;
|
|
89
89
|
exports.encryptionRotateCommand = encryptionRotateCommand;
|
|
90
90
|
|
|
91
|
-
//# sourceMappingURL=encryption-
|
|
91
|
+
//# sourceMappingURL=encryption-tB4LqLKN.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption-
|
|
1
|
+
{"version":3,"file":"encryption-tB4LqLKN.cjs","names":["rotateKeyring","parseKeyring","retireKey","loadWorkspaceSettings","canonicalId","providerOf","secretsStoreFor","provideKey","withCustomSecret"],"sources":["../src/encryption/index.ts"],"sourcesContent":["/**\n * `gkm encryption:rotate` and `gkm encryption:retire` — the keyring of an\n * `Encryption` construct on a server stage.\n *\n * Rotating adds a key in front and keeps every older one, so what they wrote\n * still opens. Retiring removes one, and is the half that makes rotating worth\n * doing: until a key is gone, it still opens everything it ever wrote. It is\n * never automatic, because the only thing that knows nothing is left under a\n * key is the sweep that re-encrypted the column — so it is done after one,\n * deliberately, by name.\n *\n * Neither applies everywhere, and each says so rather than doing something\n * that looks right: a local stage's keyring is derived and would be replaced on\n * the next `gkm dev`, and on AWS the key is KMS's, which rotates it itself and\n * never strands a value.\n */\n\nimport {\n\tparseKeyring,\n\tretireKey,\n\trotateKeyring,\n} from '@geekmidas/constructs/encryption';\nimport { canonicalId, provideKey } from '@geekmidas/manifest';\nimport { loadWorkspaceSettings } from '../config';\nimport { withCustomSecret } from '../secrets/storage.js';\nimport { type SecretsStore, secretsStoreFor } from '../secrets/store.js';\nimport { providerOf } from '../workspace/backends.js';\nimport { assertDeployedStage } from '../workspace/stages.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\nconst logger = console;\n\nexport class LocalKeyringIsDerived extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly stage: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${stage}' is the local stage, where ${construct}'s keyring is derived from the project and stage — nothing stored there would be read. Rotate a deployed stage: gkm encryption:rotate ${construct} --stage <stage>.`,\n\t\t);\n\t\tthis.name = 'LocalKeyringIsDerived';\n\t}\n}\n\nexport class KmsRotatesItself extends Error {\n\tconstructor(readonly construct: string) {\n\t\tsuper(\n\t\t\t`${construct} is a KMS key on AWS: KMS rotates it yearly and keeps every version, so no value is ever stranded and there is no key to retire. Nothing to do here.`,\n\t\t);\n\t\tthis.name = 'KmsRotatesItself';\n\t}\n}\n\nexport class NoKeyringYet extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly stage: string,\n\t\treadonly key: string,\n\t) {\n\t\tsuper(\n\t\t\t`'${stage}' has no ${key} yet. The first deploy generates ${construct}'s keyring: gkm deploy --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'NoKeyringYet';\n\t}\n}\n\nexport interface EncryptionCommandOptions {\n\tstage: string;\n}\n\n/** Where a command reads and writes; the real ones unless a test says. */\nexport interface EncryptionCommandContext {\n\tworkspace?: NormalizedWorkspace;\n\tstore?: SecretsStore;\n}\n\nexport async function encryptionRotateCommand(\n\tconstruct: string,\n\toptions: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext = {},\n): Promise<string> {\n\treturn updateKeyring(construct, options, context, (id, url) => {\n\t\tconst next = rotateKeyring(id, url);\n\t\tconst [current, ...older] = parseKeyring(id, next).keys.map(({ id }) => id);\n\n\t\tlogger.log(`\\n✓ ${id} on '${options.stage}' now writes with '${current}'.`);\n\t\tlogger.log(\n\t\t\t` Still opening: ${older.join(', ')}. Redeploy to start writing with '${current}', reencrypt what is stored, then: gkm encryption:retire ${id} <key> --stage ${options.stage}`,\n\t\t);\n\t\treturn next;\n\t});\n}\n\nexport async function encryptionRetireCommand(\n\tconstruct: string,\n\tkeyId: string,\n\toptions: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext = {},\n): Promise<string> {\n\treturn updateKeyring(construct, options, context, (id, url) => {\n\t\tconst next = retireKey(id, url, keyId);\n\n\t\tlogger.log(\n\t\t\t`\\n✓ ${id} on '${options.stage}' no longer holds '${keyId}'. Anything still under it cannot be read after the next deploy.`,\n\t\t);\n\t\treturn next;\n\t});\n}\n\nasync function updateKeyring(\n\tconstruct: string,\n\t{ stage }: EncryptionCommandOptions,\n\tcontext: EncryptionCommandContext,\n\tupdate: (id: string, url: string) => string,\n): Promise<string> {\n\tconst workspace = context.workspace ?? (await loadWorkspaceSettings());\n\tconst id = canonicalId(construct);\n\n\tif (stage === workspace.stages.local) {\n\t\tthrow new LocalKeyringIsDerived(id, stage);\n\t}\n\tassertDeployedStage(workspace.stages, stage);\n\tif (providerOf(workspace) === 'aws') throw new KmsRotatesItself(id);\n\n\tconst store = context.store ?? (await secretsStoreFor(workspace, stage));\n\tconst key = provideKey(id, 'url');\n\tconst secrets = await store.read(stage);\n\tconst url = secrets?.custom[key];\n\tif (!secrets || !url) throw new NoKeyringYet(id, stage, key);\n\n\tconst next = update(id, url);\n\tawait store.write(stage, withCustomSecret(secrets, key, next));\n\treturn next;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA8BA,MAAM,SAAS;AAEf,IAAa,wBAAb,cAA2C,MAAM;CAEtC;CACA;CAFV,YACC,WACA,OACC;EACD,MACC,IAAI,MAAM,8BAA8B,UAAU,wIAAwI,UAAU,kBACrM;EALS,KAAA,YAAA;EACA,KAAA,QAAA;EAKT,KAAK,OAAO;CACb;AACD;AAEA,IAAa,mBAAb,cAAsC,MAAM;CACtB;CAArB,YAAY,WAA4B;EACvC,MACC,GAAG,UAAU,qJACd;EAHoB,KAAA,YAAA;EAIpB,KAAK,OAAO;CACb;AACD;AAEA,IAAa,eAAb,cAAkC,MAAM;CAE7B;CACA;CACA;CAHV,YACC,WACA,OACA,KACC;EACD,MACC,IAAI,MAAM,WAAW,IAAI,mCAAmC,UAAU,iCAAiC,MAAM,EAC9G;EANS,KAAA,YAAA;EACA,KAAA,QAAA;EACA,KAAA,MAAA;EAKT,KAAK,OAAO;CACb;AACD;AAYA,eAAsB,wBACrB,WACA,SACA,UAAoC,CAAC,GACnB;CAClB,OAAO,cAAc,WAAW,SAAS,UAAU,IAAI,QAAQ;EAC9D,MAAM,QAAA,GAAOA,iCAAAA,cAAAA,CAAc,IAAI,GAAG;EAClC,MAAM,CAAC,SAAS,GAAG,UAAA,GAASC,iCAAAA,aAAAA,CAAa,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,SAAS,EAAE;EAE1E,OAAO,IAAI,OAAO,GAAG,OAAO,QAAQ,MAAM,qBAAqB,QAAQ,GAAG;EAC1E,OAAO,IACN,oBAAoB,MAAM,KAAK,IAAI,EAAE,oCAAoC,QAAQ,2DAA2D,GAAG,iBAAiB,QAAQ,OACzK;EACA,OAAO;CACR,CAAC;AACF;AAEA,eAAsB,wBACrB,WACA,OACA,SACA,UAAoC,CAAC,GACnB;CAClB,OAAO,cAAc,WAAW,SAAS,UAAU,IAAI,QAAQ;EAC9D,MAAM,QAAA,GAAOC,iCAAAA,UAAAA,CAAU,IAAI,KAAK,KAAK;EAErC,OAAO,IACN,OAAO,GAAG,OAAO,QAAQ,MAAM,qBAAqB,MAAM,iEAC3D;EACA,OAAO;CACR,CAAC;AACF;AAEA,eAAe,cACd,WACA,EAAE,SACF,SACA,QACkB;CAClB,MAAM,YAAY,QAAQ,aAAc,MAAMC,eAAAA,sBAAsB;CACpE,MAAM,MAAA,GAAKC,oBAAAA,YAAAA,CAAY,SAAS;CAEhC,IAAI,UAAU,UAAU,OAAO,OAC9B,MAAM,IAAI,sBAAsB,IAAI,KAAK;CAE1C,kBAAA,oBAAoB,UAAU,QAAQ,KAAK;CAC3C,IAAIC,iBAAAA,WAAW,SAAS,MAAM,OAAO,MAAM,IAAI,iBAAiB,EAAE;CAElE,MAAM,QAAQ,QAAQ,SAAU,MAAMC,cAAAA,gBAAgB,WAAW,KAAK;CACtE,MAAM,OAAA,GAAMC,oBAAAA,WAAAA,CAAW,IAAI,KAAK;CAChC,MAAM,UAAU,MAAM,MAAM,KAAK,KAAK;CACtC,MAAM,MAAM,SAAS,OAAO;CAC5B,IAAI,CAAC,WAAW,CAAC,KAAK,MAAM,IAAI,aAAa,IAAI,OAAO,GAAG;CAE3D,MAAM,OAAO,OAAO,IAAI,GAAG;CAC3B,MAAM,MAAM,MAAM,OAAOC,gBAAAA,iBAAiB,SAAS,KAAK,IAAI,CAAC;CAC7D,OAAO;AACR"}
|
package/dist/index.cjs
CHANGED
|
@@ -6,11 +6,11 @@ const require_config = require("./config-Cvr5fCbn.cjs");
|
|
|
6
6
|
const require_workspace = require("./workspace-BcCiLzTO.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-
|
|
9
|
+
const require_workspace$1 = require("./workspace-P_V5t4Uk.cjs");
|
|
10
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_backends = require("./backends-
|
|
12
|
+
const require_ready = require("./ready-VkNwfJu7.cjs");
|
|
13
|
+
const require_backends = require("./backends-D5aDWxuA.cjs");
|
|
14
14
|
const require_emit = require("./emit-Dmc1nvdS.cjs");
|
|
15
15
|
let commander = require("commander");
|
|
16
16
|
let node_process = require("node:process");
|
|
@@ -48,7 +48,7 @@ let _geekmidas_constructs_queue = require("@geekmidas/constructs/queue");
|
|
|
48
48
|
let _geekmidas_constructs_topic = require("@geekmidas/constructs/topic");
|
|
49
49
|
let node_dns_promises = require("node:dns/promises");
|
|
50
50
|
//#region package.json
|
|
51
|
-
var version = "10.0.0-alpha.
|
|
51
|
+
var version = "10.0.0-alpha.53";
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region src/auth/credentials.ts
|
|
54
54
|
/**
|
|
@@ -573,7 +573,8 @@ var UnsupportedPlatform = class extends Error {
|
|
|
573
573
|
* So the holder is asked who it is. Every app process gkm starts is tagged with
|
|
574
574
|
* {@link APP_TAG_ENV} — the workspace and the app — and children inherit it, so
|
|
575
575
|
* whatever actually binds the port (`next-server`, a Metro worker, the tsx
|
|
576
|
-
* server) carries it
|
|
576
|
+
* server) carries it — or, when its own can't be read, one of its parents does.
|
|
577
|
+
* A held port whose holder carries this app's tag is a
|
|
577
578
|
* leftover, and is refused; anything else — untagged, another workspace's,
|
|
578
579
|
* unreadable — is not ours, and the app moves to the next free port.
|
|
579
580
|
*
|
|
@@ -631,13 +632,32 @@ function holderOf(port) {
|
|
|
631
632
|
const pid = Number(out.match(/^p(\d+)/m)?.[1]);
|
|
632
633
|
if (!pid) return void 0;
|
|
633
634
|
const command = out.match(/^c(.+)$/m)?.[1];
|
|
634
|
-
const tag =
|
|
635
|
+
const tag = lineageTagOf(pid);
|
|
635
636
|
return {
|
|
636
637
|
pid,
|
|
637
638
|
...command ? { command } : {},
|
|
638
639
|
...tag ? { tag } : {}
|
|
639
640
|
};
|
|
640
641
|
}
|
|
642
|
+
/** How far up a holder's parents to look before calling it untagged. */
|
|
643
|
+
const MAX_ANCESTORS = 8;
|
|
644
|
+
/**
|
|
645
|
+
* The tag of `pid`, or of its nearest parent that has one.
|
|
646
|
+
*
|
|
647
|
+
* A process can hide the tag it inherited: `next-server` renames itself, which
|
|
648
|
+
* on macOS overwrites the memory `ps eww` reads its environment from, so `ps`
|
|
649
|
+
* shows only its title. Its parent, the `next dev` gkm started, still carries
|
|
650
|
+
* the tag. A child is only ever started by its parent, so a tagged parent makes
|
|
651
|
+
* the holder this app's.
|
|
652
|
+
*/
|
|
653
|
+
function lineageTagOf(pid) {
|
|
654
|
+
let current = pid;
|
|
655
|
+
for (let depth = 0; current && current > 1; depth += 1) {
|
|
656
|
+
const tag = tagOf(current);
|
|
657
|
+
if (tag || depth === MAX_ANCESTORS) return tag;
|
|
658
|
+
current = parentOf(current);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
641
661
|
function tagOf(pid) {
|
|
642
662
|
const prefix = `${APP_TAG_ENV}=`;
|
|
643
663
|
try {
|
|
@@ -659,6 +679,26 @@ function tagOf(pid) {
|
|
|
659
679
|
return;
|
|
660
680
|
}
|
|
661
681
|
}
|
|
682
|
+
function parentOf(pid) {
|
|
683
|
+
try {
|
|
684
|
+
const ppid = Number((0, node_child_process.execFileSync)("ps", [
|
|
685
|
+
"-o",
|
|
686
|
+
"ppid=",
|
|
687
|
+
"-p",
|
|
688
|
+
String(pid)
|
|
689
|
+
], {
|
|
690
|
+
encoding: "utf8",
|
|
691
|
+
stdio: [
|
|
692
|
+
"ignore",
|
|
693
|
+
"pipe",
|
|
694
|
+
"ignore"
|
|
695
|
+
]
|
|
696
|
+
}).trim());
|
|
697
|
+
return ppid > 0 ? ppid : void 0;
|
|
698
|
+
} catch {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
662
702
|
/** The ports apps were given before, by app name. */
|
|
663
703
|
async function savedAppPorts(root) {
|
|
664
704
|
try {
|
|
@@ -1731,9 +1771,9 @@ async function workspaceDevCommand(configured, options) {
|
|
|
1731
1771
|
for (const { id, port } of fakes) logger$9.log(`🎭 ${id} fake: http://localhost:${port}`);
|
|
1732
1772
|
logger$9.log(options.migrate || options.seed ? "🗄️ Migrating the databases" : "🗄️ Checking for pending migrations");
|
|
1733
1773
|
if (options.migrate || options.seed) {
|
|
1734
|
-
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-
|
|
1774
|
+
const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs"));
|
|
1735
1775
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
1736
|
-
} else await Promise.resolve().then(() => require("./migrate-
|
|
1776
|
+
} else await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
1737
1777
|
logger$9.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
1738
1778
|
});
|
|
1739
1779
|
const appUrls = {};
|
|
@@ -9340,26 +9380,26 @@ function loadPackageJson() {
|
|
|
9340
9380
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
9341
9381
|
*/
|
|
9342
9382
|
const GEEKMIDAS_VERSIONS = {
|
|
9343
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
9344
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
9345
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
9346
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
9347
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
9348
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
9349
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
9350
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
9351
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
9352
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
9353
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
9354
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
9355
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
9356
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
9357
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
9358
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
9359
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
9360
|
-
"@geekmidas/studio": "~10.0.0-alpha.
|
|
9361
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
9362
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
9383
|
+
"@geekmidas/audit": "~10.0.0-alpha.53",
|
|
9384
|
+
"@geekmidas/auth": "~10.0.0-alpha.53",
|
|
9385
|
+
"@geekmidas/cache": "~10.0.0-alpha.53",
|
|
9386
|
+
"@geekmidas/client": "~10.0.0-alpha.53",
|
|
9387
|
+
"@geekmidas/cloud": "~10.0.0-alpha.53",
|
|
9388
|
+
"@geekmidas/constructs": "~10.0.0-alpha.53",
|
|
9389
|
+
"@geekmidas/db": "~10.0.0-alpha.53",
|
|
9390
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.53",
|
|
9391
|
+
"@geekmidas/envkit": "~10.0.0-alpha.53",
|
|
9392
|
+
"@geekmidas/errors": "~10.0.0-alpha.53",
|
|
9393
|
+
"@geekmidas/events": "~10.0.0-alpha.53",
|
|
9394
|
+
"@geekmidas/logger": "~10.0.0-alpha.53",
|
|
9395
|
+
"@geekmidas/manifest": "~10.0.0-alpha.53",
|
|
9396
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.53",
|
|
9397
|
+
"@geekmidas/schema": "~10.0.0-alpha.53",
|
|
9398
|
+
"@geekmidas/services": "~10.0.0-alpha.53",
|
|
9399
|
+
"@geekmidas/storage": "~10.0.0-alpha.53",
|
|
9400
|
+
"@geekmidas/studio": "~10.0.0-alpha.53",
|
|
9401
|
+
"@geekmidas/telescope": "~10.0.0-alpha.53",
|
|
9402
|
+
"@geekmidas/testkit": "~10.0.0-alpha.53",
|
|
9363
9403
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
9364
9404
|
};
|
|
9365
9405
|
//#endregion
|
|
@@ -16102,7 +16142,7 @@ function testDatabases(reconciled) {
|
|
|
16102
16142
|
* starts without the reference data the app needs.
|
|
16103
16143
|
*/
|
|
16104
16144
|
async function migrateTestStage(workspace, env) {
|
|
16105
|
-
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-
|
|
16145
|
+
const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs"));
|
|
16106
16146
|
const { discover } = await Promise.resolve().then(() => require("./discover-DXNviAh-.cjs")).then((n) => n.discover_exports);
|
|
16107
16147
|
const sources = {};
|
|
16108
16148
|
const manifest = await discover({
|
|
@@ -16533,7 +16573,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
16533
16573
|
try {
|
|
16534
16574
|
const globalOptions = program.opts();
|
|
16535
16575
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16536
|
-
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16576
|
+
const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs"));
|
|
16537
16577
|
await migrateCommand({
|
|
16538
16578
|
...options,
|
|
16539
16579
|
...construct ? { construct } : {}
|
|
@@ -16547,7 +16587,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
16547
16587
|
try {
|
|
16548
16588
|
const globalOptions = program.opts();
|
|
16549
16589
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16550
|
-
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16590
|
+
const { seedCommand } = await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs"));
|
|
16551
16591
|
await seedCommand({
|
|
16552
16592
|
...options,
|
|
16553
16593
|
...construct ? { construct } : {}
|
|
@@ -16561,7 +16601,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
16561
16601
|
try {
|
|
16562
16602
|
const globalOptions = program.opts();
|
|
16563
16603
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16564
|
-
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-
|
|
16604
|
+
const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-SDIRUyY5.cjs"));
|
|
16565
16605
|
await migrationCommand({
|
|
16566
16606
|
construct,
|
|
16567
16607
|
...name ? { name } : {}
|
|
@@ -16659,7 +16699,7 @@ program.command("encryption:rotate").description("Add a new current key to an En
|
|
|
16659
16699
|
try {
|
|
16660
16700
|
const globalOptions = program.opts();
|
|
16661
16701
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16662
|
-
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
16702
|
+
const { encryptionRotateCommand } = await Promise.resolve().then(() => require("./encryption-tB4LqLKN.cjs"));
|
|
16663
16703
|
await encryptionRotateCommand(construct, options);
|
|
16664
16704
|
} catch (error) {
|
|
16665
16705
|
console.error(formatError(error));
|
|
@@ -16670,7 +16710,7 @@ program.command("encryption:retire").description("Remove an old key from an Encr
|
|
|
16670
16710
|
try {
|
|
16671
16711
|
const globalOptions = program.opts();
|
|
16672
16712
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16673
|
-
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-
|
|
16713
|
+
const { encryptionRetireCommand } = await Promise.resolve().then(() => require("./encryption-tB4LqLKN.cjs"));
|
|
16674
16714
|
await encryptionRetireCommand(construct, key, options);
|
|
16675
16715
|
} catch (error) {
|
|
16676
16716
|
console.error(formatError(error));
|
|
@@ -16722,7 +16762,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16722
16762
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
16723
16763
|
process.exit(1);
|
|
16724
16764
|
}
|
|
16725
|
-
const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-
|
|
16765
|
+
const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-P_V5t4Uk.cjs")).then((n) => n.workspace_exports);
|
|
16726
16766
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
16727
16767
|
if (!result) {
|
|
16728
16768
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|