@geekmidas/cli 10.0.0-alpha.78 → 10.0.0-alpha.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/{add-D2XKszYP.mjs → add-CIxT-Iq6.mjs} +2 -2
  2. package/dist/{add-D2XKszYP.mjs.map → add-CIxT-Iq6.mjs.map} +1 -1
  3. package/dist/{add-BvOICikp.cjs → add-DJ0VE-y-.cjs} +7 -7
  4. package/dist/{add-BvOICikp.cjs.map → add-DJ0VE-y-.cjs.map} +1 -1
  5. package/dist/{aws-Bja4zGSs.mjs → aws-B-6uEhgP.mjs} +8 -2
  6. package/dist/{aws-Bja4zGSs.mjs.map → aws-B-6uEhgP.mjs.map} +1 -1
  7. package/dist/{aws-CQAuluiu.cjs → aws-BTawF0F-.cjs} +19 -2
  8. package/dist/{aws-CQAuluiu.cjs.map → aws-BTawF0F-.cjs.map} +1 -1
  9. package/dist/{bundler-C6T-1OLT.cjs → bundler-BlbSLFLn.cjs} +3 -3
  10. package/dist/{bundler-C6T-1OLT.cjs.map → bundler-BlbSLFLn.cjs.map} +1 -1
  11. package/dist/{bundler-CtHzKqnZ.mjs → bundler-D4pl87A5.mjs} +3 -3
  12. package/dist/{bundler-CtHzKqnZ.mjs.map → bundler-D4pl87A5.mjs.map} +1 -1
  13. package/dist/{cli-BgPyhx1i.mjs → cli-7aLfgIGt.mjs} +3 -3
  14. package/dist/{cli-BgPyhx1i.mjs.map → cli-7aLfgIGt.mjs.map} +1 -1
  15. package/dist/{cli-K6Vj_pPW.cjs → cli-BkNZBe_-.cjs} +4 -4
  16. package/dist/{cli-K6Vj_pPW.cjs.map → cli-BkNZBe_-.cjs.map} +1 -1
  17. package/dist/{compose-B7MC19eC.cjs → compose-Bn4OJONR.cjs} +88 -60
  18. package/dist/{compose-B7MC19eC.cjs.map → compose-Bn4OJONR.cjs.map} +1 -1
  19. package/dist/{compose-DByK353T.mjs → compose-n7K8H5j8.mjs} +36 -8
  20. package/dist/{compose-DByK353T.mjs.map → compose-n7K8H5j8.mjs.map} +1 -1
  21. package/dist/{config-Bql0AmJt.d.mts → config-L_6NivCp.d.mts} +3 -3
  22. package/dist/{config-Bql0AmJt.d.mts.map → config-L_6NivCp.d.mts.map} +1 -1
  23. package/dist/{config-DlNpHK8p.d.cts → config-Mr4rcXFC.d.cts} +3 -3
  24. package/dist/{config-DlNpHK8p.d.cts.map → config-Mr4rcXFC.d.cts.map} +1 -1
  25. package/dist/config.d.cts +3 -3
  26. package/dist/config.d.mts +3 -3
  27. package/dist/{databases-C2p5LGAp.cjs → databases-BY-pEImp.cjs} +185 -7
  28. package/dist/databases-BY-pEImp.cjs.map +1 -0
  29. package/dist/{databases-hUHTuwhx.mjs → databases-CzszQV0N.mjs} +153 -5
  30. package/dist/databases-CzszQV0N.mjs.map +1 -0
  31. package/dist/deploy/public.cjs +12 -11
  32. package/dist/deploy/public.d.cts +19 -3
  33. package/dist/deploy/public.d.cts.map +1 -1
  34. package/dist/deploy/public.d.mts +19 -3
  35. package/dist/deploy/public.d.mts.map +1 -1
  36. package/dist/deploy/public.mjs +6 -6
  37. package/dist/{deploy-BerP7ppB.mjs → deploy-DK4Y6ev4.mjs} +3 -3
  38. package/dist/{deploy-BerP7ppB.mjs.map → deploy-DK4Y6ev4.mjs.map} +1 -1
  39. package/dist/{deploy-Dt42xiQA.cjs → deploy-Ppnh8MHS.cjs} +9 -9
  40. package/dist/{deploy-Dt42xiQA.cjs.map → deploy-Ppnh8MHS.cjs.map} +1 -1
  41. package/dist/{dokploy-ssZQRK2C.mjs → dokploy-Bjq05wkw.mjs} +2 -2
  42. package/dist/{dokploy-ssZQRK2C.mjs.map → dokploy-Bjq05wkw.mjs.map} +1 -1
  43. package/dist/{dokploy-NG9UrVrP.cjs → dokploy-CJvdoNc3.cjs} +2 -2
  44. package/dist/{dokploy-NG9UrVrP.cjs.map → dokploy-CJvdoNc3.cjs.map} +1 -1
  45. package/dist/{encryption-De6MN0O5.mjs → encryption-BrsOJFFz.mjs} +2 -2
  46. package/dist/{encryption-De6MN0O5.mjs.map → encryption-BrsOJFFz.mjs.map} +1 -1
  47. package/dist/{encryption-CbMI24fI.cjs → encryption-CAyR6D7B.cjs} +5 -5
  48. package/dist/{encryption-CbMI24fI.cjs.map → encryption-CAyR6D7B.cjs.map} +1 -1
  49. package/dist/{engine-CoCsNoW_.cjs → engine-DzBZR5D0.cjs} +118 -82
  50. package/dist/engine-DzBZR5D0.cjs.map +1 -0
  51. package/dist/{engine-DOjGIgl4.mjs → engine-ba9CvjTo.mjs} +53 -17
  52. package/dist/engine-ba9CvjTo.mjs.map +1 -0
  53. package/dist/github-BLjU59Ye.cjs +669 -0
  54. package/dist/github-BLjU59Ye.cjs.map +1 -0
  55. package/dist/github-CVdbVlT5.mjs +669 -0
  56. package/dist/github-CVdbVlT5.mjs.map +1 -0
  57. package/dist/{index-BXO0vlme.d.mts → index-C0UmP_lg.d.mts} +2 -2
  58. package/dist/{index-BXO0vlme.d.mts.map → index-C0UmP_lg.d.mts.map} +1 -1
  59. package/dist/{index-Rs0Fua-q.d.cts → index-DTEPwLml.d.cts} +2 -2
  60. package/dist/{index-Rs0Fua-q.d.cts.map → index-DTEPwLml.d.cts.map} +1 -1
  61. package/dist/index.cjs +114 -114
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.mjs +41 -41
  64. package/dist/index.mjs.map +1 -1
  65. package/dist/{migrate-Cgoy58Sh.cjs → migrate-DkB833Jj.cjs} +8 -9
  66. package/dist/{migrate-Cgoy58Sh.cjs.map → migrate-DkB833Jj.cjs.map} +1 -1
  67. package/dist/{migrate-CNKaQl3K.mjs → migrate-DlBgATa-.mjs} +3 -4
  68. package/dist/{migrate-CNKaQl3K.mjs.map → migrate-DlBgATa-.mjs.map} +1 -1
  69. package/dist/{migrate-B4GBvCNY.cjs → migrate-iEdyEx4S.cjs} +4 -4
  70. package/dist/{migrate-B4GBvCNY.cjs.map → migrate-iEdyEx4S.cjs.map} +1 -1
  71. package/dist/{migrate-BQ4wVKq_.mjs → migrate-pfu4aYzX.mjs} +2 -2
  72. package/dist/{migrate-BQ4wVKq_.mjs.map → migrate-pfu4aYzX.mjs.map} +1 -1
  73. package/dist/openapi.d.cts +1 -1
  74. package/dist/openapi.d.mts +1 -1
  75. package/dist/reconcile/public.d.cts +1 -1
  76. package/dist/reconcile/public.d.mts +1 -1
  77. package/dist/{resolve-CEaqRBzY.cjs → resolve-4_5N67Fk.cjs} +3 -3
  78. package/dist/{resolve-CEaqRBzY.cjs.map → resolve-4_5N67Fk.cjs.map} +1 -1
  79. package/dist/{resolve-mvaystiE.mjs → resolve-CQPn66jr.mjs} +3 -3
  80. package/dist/{resolve-mvaystiE.mjs.map → resolve-CQPn66jr.mjs.map} +1 -1
  81. package/dist/{rollback-S2C-Y9pB.mjs → rollback-C0cbdsM-.mjs} +3 -3
  82. package/dist/{rollback-S2C-Y9pB.mjs.map → rollback-C0cbdsM-.mjs.map} +1 -1
  83. package/dist/{rollback-F3P-rA-r.cjs → rollback-CgYUPLbq.cjs} +5 -5
  84. package/dist/{rollback-F3P-rA-r.cjs.map → rollback-CgYUPLbq.cjs.map} +1 -1
  85. package/dist/{runtime-D9AxGzrw.d.cts → runtime-D6A-C6zh.d.cts} +2 -2
  86. package/dist/{runtime-D9AxGzrw.d.cts.map → runtime-D6A-C6zh.d.cts.map} +1 -1
  87. package/dist/{runtime-Dflki3Vs.d.mts → runtime-ekxfPNM-.d.mts} +2 -2
  88. package/dist/{runtime-Dflki3Vs.d.mts.map → runtime-ekxfPNM-.d.mts.map} +1 -1
  89. package/dist/sandbox/migrate-worker.cjs +22 -8
  90. package/dist/sandbox/migrate-worker.cjs.map +1 -1
  91. package/dist/sandbox/migrate-worker.mjs +22 -8
  92. package/dist/sandbox/migrate-worker.mjs.map +1 -1
  93. package/dist/{secretsManager-Ti0oZwsS.mjs → secretsManager-Chs9VV2r.mjs} +8 -2
  94. package/dist/{secretsManager-Ti0oZwsS.mjs.map → secretsManager-Chs9VV2r.mjs.map} +1 -1
  95. package/dist/{secretsManager-DUXW3fQt.cjs → secretsManager-DcMlHnRC.cjs} +19 -2
  96. package/dist/{secretsManager-DUXW3fQt.cjs.map → secretsManager-DcMlHnRC.cjs.map} +1 -1
  97. package/dist/{stale-C5FqIVc8.mjs → seeds-BdkFpW0P.mjs} +64 -6
  98. package/dist/seeds-BdkFpW0P.mjs.map +1 -0
  99. package/dist/{stale-BsiPJI7Y.cjs → seeds-ZljwYV_p.cjs} +81 -5
  100. package/dist/seeds-ZljwYV_p.cjs.map +1 -0
  101. package/dist/sniffer-BjG-1mlD.cjs.map +1 -1
  102. package/dist/sniffer-ByWtH28i.mjs.map +1 -1
  103. package/dist/target/public.cjs +1 -1
  104. package/dist/target/public.d.cts +2 -2
  105. package/dist/target/public.d.mts +2 -2
  106. package/dist/target/public.mjs +1 -1
  107. package/dist/{types-DKxkXsKC.d.mts → types-BzCavjGt.d.mts} +29 -2
  108. package/dist/types-BzCavjGt.d.mts.map +1 -0
  109. package/dist/{types-ByY0zi3n.d.cts → types-DZtj9jeI.d.cts} +29 -2
  110. package/dist/types-DZtj9jeI.d.cts.map +1 -0
  111. package/dist/workspace/index.d.cts +2 -2
  112. package/dist/workspace/index.d.mts +2 -2
  113. package/package.json +15 -15
  114. package/dist/databases-C2p5LGAp.cjs.map +0 -1
  115. package/dist/databases-hUHTuwhx.mjs.map +0 -1
  116. package/dist/engine-CoCsNoW_.cjs.map +0 -1
  117. package/dist/engine-DOjGIgl4.mjs.map +0 -1
  118. package/dist/github-CwX9z89E.mjs +0 -213
  119. package/dist/github-CwX9z89E.mjs.map +0 -1
  120. package/dist/github-D9vGqdLk.cjs +0 -213
  121. package/dist/github-D9vGqdLk.cjs.map +0 -1
  122. package/dist/provider-B3Sv_a74.cjs +0 -173
  123. package/dist/provider-B3Sv_a74.cjs.map +0 -1
  124. package/dist/provider-D7rQzzzf.mjs +0 -138
  125. package/dist/provider-D7rQzzzf.mjs.map +0 -1
  126. package/dist/stale-BsiPJI7Y.cjs.map +0 -1
  127. package/dist/stale-C5FqIVc8.mjs.map +0 -1
  128. package/dist/types-ByY0zi3n.d.cts.map +0 -1
  129. package/dist/types-DKxkXsKC.d.mts.map +0 -1
@@ -3,7 +3,7 @@ import { r as discover } from "./discover-BPelzeGW.mjs";
3
3
  import { t as appKey } from "./derive-B4vDpzgP.mjs";
4
4
  import { k as assertDeployedStage } from "./workspace-BBdqmkch.mjs";
5
5
  import { loadWorkspaceSettings } from "./config.mjs";
6
- import { B as requiredStageKeys, Kt as secretsStoreFor, X as constructGlobs, cn as initStageSecrets, ft as appEnvKeys } from "./stale-C5FqIVc8.mjs";
6
+ import { $ as constructGlobs, U as requiredStageKeys, Yt as secretsStoreFor, dn as initStageSecrets, ht as appEnvKeys } from "./seeds-BdkFpW0P.mjs";
7
7
  import { i as issueLine, o as loadCredentialSchemas } from "./credentialSchemas-BJqRJNK4.mjs";
8
8
  import { provideKey } from "@geekmidas/manifest";
9
9
  import prompts from "prompts";
@@ -563,4 +563,4 @@ async function askFields(ask, io, shape) {
563
563
  //#endregion
564
564
  export { secretsAddCommand };
565
565
 
566
- //# sourceMappingURL=add-D2XKszYP.mjs.map
566
+ //# sourceMappingURL=add-CIxT-Iq6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-D2XKszYP.mjs","names":["z.url","z.email","s3Parse","s3Build"],"sources":["../src/secrets/stageKeys.ts","../src/secrets/add.ts"],"sourcesContent":["/**\n * The keys a workspace's stage must be given — across every app, each once,\n * with who reads it and whether the stage holds it.\n *\n * The keys themselves are `requiredStageKeys`'s, the list a deploy refuses a\n * stage by. What this adds is the workspace: which constructs its apps read\n * (`appEnvKeys`, the keys each app's environment is built from) and which of\n * the keys the stage has set.\n */\n\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport {\n\ttype CredentialDeclaration,\n\trequiredStageKeys,\n\ttype ServiceDeclaration,\n\ttype StageKey,\n} from '../deploy/devServices';\nimport { appEnvKeys } from '../reconcile/apps';\nimport { appKey } from '../workspace/derive';\n\n/** A stage key, and whether the stage's secrets hold it. */\nexport interface WorkspaceStageKey extends StageKey {\n\tset: boolean;\n}\n\nexport interface WorkspaceStageKeysInput {\n\tmanifest: ConstructManifest;\n\t/** Each owner's runnables' edges, from discovery. */\n\trunnables?: Readonly<Record<string, readonly string[]>>;\n\t/** Whether the stage is the workspace's local one. */\n\tlocal: boolean;\n\t/** What the stage's secrets hold, by key. */\n\tsupplied: Readonly<Record<string, string>>;\n\t/** The stage's base domain, for the examples. */\n\tdomain?: string;\n}\n\n/** The keys of each kind of construct an app reads, that the stage supplies. */\nfunction keysOf(id: string, kind: string): string[] {\n\tswitch (kind) {\n\t\tcase 'email':\n\t\t\treturn [provideKey(id, 'url'), provideKey(id, 'from')];\n\t\tcase 'objects':\n\t\tcase 'file-server':\n\t\t\treturn [provideKey(id, 'url')];\n\t\tcase 'external-api':\n\t\tcase 'credential':\n\t\t\treturn [provideKey(id, 'credentials')];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Every key the stage must be given for the constructs its apps read — a\n * file server's whenever its bucket is read, since its client reads both —\n * and every file server's bucket, which serves it whether or not an app\n * reads it directly.\n */\nexport function workspaceStageKeys(\n\tinput: WorkspaceStageKeysInput,\n): WorkspaceStageKey[] {\n\tconst { manifest } = input;\n\n\t// What each app's environment holds.\n\tconst reads = new Map<string, Set<string>>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\tif (kind !== 'rest-api' && kind !== 'site' && kind !== 'mobile-app') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = appKey(id);\n\t\tconst keys = appEnvKeys(manifest, name, input.runnables);\n\t\tif (keys) reads.set(name, keys);\n\t}\n\n\tconst readers = (id: string, kind: string) => {\n\t\tconst keys = keysOf(id, kind);\n\t\treturn [...reads]\n\t\t\t.filter(([, env]) => keys.some((key) => env.has(key)))\n\t\t\t.map(([app]) => app)\n\t\t\t.sort();\n\t};\n\n\tconst services: ServiceDeclaration[] = [];\n\tconst credentials: CredentialDeclaration[] = [];\n\tconst buckets = new Set<string>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\t// A file server's client reads its bucket's URL and its own, and an\n\t\t// app's edge is to the bucket: whoever reads the bucket reads both.\n\t\tconst apps =\n\t\t\tdeclaration.kind === 'file-server' && declaration.of\n\t\t\t\t? [\n\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t...readers(id, kind),\n\t\t\t\t\t\t\t...readers(declaration.of, 'objects'),\n\t\t\t\t\t\t]),\n\t\t\t\t\t].sort()\n\t\t\t\t: readers(id, kind);\n\t\tif (kind === 'external-api' || kind === 'credential') {\n\t\t\tif (apps.length > 0) credentials.push({ id, kind, apps });\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== 'email' && kind !== 'objects' && kind !== 'file-server') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (apps.length === 0) continue;\n\t\tconst of = declaration.kind === 'file-server' ? declaration.of : undefined;\n\t\tservices.push({ id, kind, ...(of ? { of } : {}), apps });\n\t\tif (of) buckets.add(of);\n\t}\n\tfor (const of of buckets) {\n\t\tif (services.some((s) => s.id === of)) continue;\n\t\tif (manifest[of]?.kind !== 'objects') continue;\n\t\tservices.push({ id: of, kind: 'objects', apps: readers(of, 'objects') });\n\t}\n\n\treturn requiredStageKeys({\n\t\tlocal: input.local,\n\t\tservices,\n\t\tcredentials,\n\t\t...(input.domain ? { domain: input.domain } : {}),\n\t}).map((key) => ({ ...key, set: input.supplied[key.key] !== undefined }));\n}\n","/**\n * `gkm secrets:add --stage <stage>` — the secrets a stage must be given,\n * built key by key.\n *\n * It offers exactly the keys a deploy would refuse the stage without\n * (`requiredStageKeys`), across every app in the workspace, each once: the\n * stage's buckets, mail and file servers where it is deployed, and every\n * third party's credentials. A key is built by what it is — a bucket from its\n * provider, mail from its SMTP server, credentials field by field from their\n * construct's schema — checked, and saved through the stage's own store, the\n * one `gkm secrets:set` writes. No value is ever printed.\n *\n * `--json` asks nothing: it prints the keys, for a script or an agent to set\n * with `gkm secrets:set`.\n */\n\nimport {\n\ttype S3Address,\n\tbuild as s3Build,\n\tparse as s3Parse,\n} from '@geekmidas/storage/s3-url';\nimport prompts, { type PromptObject } from 'prompts';\nimport { z } from 'zod';\nimport { loadWorkspaceSettings } from '../config';\nimport { discover } from '../reconcile/discover';\nimport { constructGlobs } from '../reconcile/workspace';\nimport { assertDeployedStage } from '../workspace/stages';\nimport {\n\ttype CredentialSchemaInfo,\n\ttype CredentialSchemas,\n\tissueLine,\n\tloadCredentialSchemas,\n} from './credentialSchemas';\nimport { type WorkspaceStageKey, workspaceStageKeys } from './stageKeys';\nimport { initStageSecrets } from './storage';\nimport { secretsStoreFor } from './store';\n\nexport interface SecretsAddOptions {\n\tstage: string;\n\t/** Only the keys the stage has not set. */\n\tmissing?: boolean;\n\t/** Print the keys as JSON and ask nothing. */\n\tjson?: boolean;\n\t/** The workspace — the current directory when absent. */\n\tcwd?: string;\n\t/** The CLI's home, for a file store's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n}\n\n/** Where the command writes, and whether there is anyone to ask. */\nexport interface SecretsAddIo {\n\t/** A line for the person at the terminal. */\n\tlog(line: string): void;\n\t/** `--json`'s output. */\n\twrite(chunk: string): void;\n\t/** Whether prompts can be answered. */\n\tinteractive: boolean;\n}\n\n/** What a run of the command came to. */\nexport interface SecretsAddResult {\n\t/** The keys offered. */\n\tkeys: WorkspaceStageKey[];\n\t/** The keys saved, in the order they were built. */\n\tsaved: string[];\n}\n\n/** One key as `--json` prints it. */\nexport interface StageKeyJson {\n\tkey: string;\n\tkind: WorkspaceStageKey['kind'];\n\tconstruct: string;\n\tapps: string[];\n\tset: boolean;\n}\n\n/** `gkm secrets:add` with nobody at a terminal to answer it. */\nexport class SecretsAddNeedsTerminal extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`gkm secrets:add asks for each key, and there is no terminal to ask ` +\n\t\t\t\t`at. List what the stage needs with ` +\n\t\t\t\t`gkm secrets:add --stage ${stage} --missing --json, and set each ` +\n\t\t\t\t`with gkm secrets:set <KEY> <value> --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'SecretsAddNeedsTerminal';\n\t}\n}\n\n/** The person stopped the builder; nothing was saved. */\nexport class SecretsAddCancelled extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(`Stopped. Nothing was saved to the stage '${stage}'.`);\n\t\tthis.name = 'SecretsAddCancelled';\n\t}\n}\n\nconst defaultIo = (): SecretsAddIo => ({\n\tlog: (line) => console.log(line),\n\twrite: (chunk) => {\n\t\tprocess.stdout.write(chunk);\n\t},\n\tinteractive: process.stdin.isTTY === true && process.stdout.isTTY === true,\n});\n\n/** `gkm secrets:add`. */\nexport async function secretsAddCommand(\n\toptions: SecretsAddOptions,\n\tio: SecretsAddIo = defaultIo(),\n): Promise<SecretsAddResult> {\n\tconst { stage } = options;\n\tconst workspace = await loadWorkspaceSettings(options.cwd ?? process.cwd());\n\tconst local = stage === workspace.stages.local;\n\tif (!local) assertDeployedStage(workspace.stages, stage);\n\n\tconst patterns = constructGlobs(workspace);\n\tconst runnables: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns,\n\t\tcwd: workspace.root,\n\t\trunnables,\n\t});\n\n\tconst store = await secretsStoreFor(workspace, stage, {\n\t\t...(options.home ? { home: options.home } : {}),\n\t});\n\tconst stored = await store.read(stage);\n\tconst domain = workspace.deploy?.domains?.[stage];\n\n\tconst all = workspaceStageKeys({\n\t\tmanifest,\n\t\trunnables,\n\t\tlocal,\n\t\tsupplied: stored?.custom ?? {},\n\t\t...(domain ? { domain } : {}),\n\t});\n\tconst keys = options.missing ? all.filter((k) => !k.set) : all;\n\n\tif (options.json) {\n\t\tconst listed: StageKeyJson[] = keys.map((k) => ({\n\t\t\tkey: k.key,\n\t\t\tkind: k.kind,\n\t\t\tconstruct: k.id,\n\t\t\tapps: [...(k.apps ?? [])],\n\t\t\tset: k.set,\n\t\t}));\n\t\tio.write(`${JSON.stringify(listed, null, 2)}\\n`);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tif (!io.interactive) throw new SecretsAddNeedsTerminal(stage);\n\n\tif (keys.length === 0) {\n\t\tio.log(\n\t\t\tall.length === 0\n\t\t\t\t? `Nothing to add: no construct on '${stage}' needs a key only the stage can supply.`\n\t\t\t\t: `Nothing to add: the stage '${stage}' has every key it needs.`,\n\t\t);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tconst ask = asker(stage);\n\tconst chosen: string[] = await ask({\n\t\ttype: 'multiselect',\n\t\tmessage: `Which keys for '${stage}'? (${store.name} store)`,\n\t\tchoices: keys.map((k) => ({\n\t\t\ttitle: `${k.key} ${KIND_LABEL[k.kind]} '${k.id}'${k.apps?.length ? ` · ${k.apps.join(', ')}` : ''}${k.set ? ' · set' : ''}`,\n\t\t\tvalue: k.key,\n\t\t\tselected: !k.set,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: 'space to toggle, enter to continue',\n\t});\n\tconst selected = keys.filter((k) => (chosen ?? []).includes(k.key));\n\n\tconst values: Record<string, string> = {};\n\tconst has = (key: string) =>\n\t\tvalues[key] !== undefined || stored?.custom?.[key] !== undefined;\n\tlet schemas: CredentialSchemas | undefined;\n\n\tfor (const entry of selected) {\n\t\tif (entry.set) {\n\t\t\tconst overwrite: boolean = await ask({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: `${entry.key} is set. Replace it?`,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tif (!overwrite) continue;\n\t\t}\n\t\tio.log(`\\n${entry.key} — ${entry.what}`);\n\n\t\tswitch (entry.kind) {\n\t\t\tcase 'bucket':\n\t\t\t\tObject.assign(values, await buildBucket(ask, io, entry, has));\n\t\t\t\tbreak;\n\t\t\tcase 'email':\n\t\t\t\tvalues[entry.key] = entry.key.endsWith('_FROM')\n\t\t\t\t\t? await askFrom(ask, io)\n\t\t\t\t\t: await buildSmtpUrl(ask, io);\n\t\t\t\tbreak;\n\t\t\tcase 'file-server':\n\t\t\t\tvalues[entry.key] = await askHttpUrl(ask, io, 'Its public URL');\n\t\t\t\tbreak;\n\t\t\tcase 'external-api':\n\t\t\tcase 'credential':\n\t\t\t\tschemas ??= await loadCredentialSchemas({\n\t\t\t\t\troot: workspace.root,\n\t\t\t\t\tpatterns,\n\t\t\t\t});\n\t\t\t\tvalues[entry.key] = await buildCredentials(ask, io, entry, schemas);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst saved = Object.keys(values);\n\tif (saved.length === 0) {\n\t\tio.log('\\nNothing was saved.');\n\t\treturn { keys, saved };\n\t}\n\n\tconst base = stored ?? initStageSecrets(stage);\n\tawait store.write(stage, {\n\t\t...base,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: { ...base.custom, ...values },\n\t});\n\tio.log(\n\t\t`\\n✓ Saved ${saved.join(', ')} to the stage '${stage}' (${store.name} store).`,\n\t);\n\treturn { keys, saved };\n}\n\nconst KIND_LABEL: Record<WorkspaceStageKey['kind'], string> = {\n\tbucket: 'bucket',\n\temail: 'email',\n\t'file-server': 'file server',\n\t'external-api': 'external API',\n\tcredential: 'credential',\n};\n\n/** One question, answered — or the run stopped. */\ntype Ask = <T = string>(question: Omit<PromptObject, 'name'>) => Promise<T>;\n\nfunction asker(stage: string): Ask {\n\treturn async <T>(question: Omit<PromptObject, 'name'>) => {\n\t\tconst answers = await prompts(\n\t\t\t{ ...question, name: 'value' } as PromptObject,\n\t\t\t{\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tthrow new SecretsAddCancelled(stage);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn answers.value as T;\n\t};\n}\n\n/** Ask until `accept` takes the answer; `accept` returns why it did not. */\nasync function askUntil<T>(\n\task: Ask,\n\tio: SecretsAddIo,\n\tquestion: Omit<PromptObject, 'name'>,\n\taccept: (value: T) => string | undefined,\n): Promise<T> {\n\tfor (;;) {\n\t\tconst value = await ask<T>(question);\n\t\tconst problem = accept(value);\n\t\tif (!problem) return value;\n\t\tio.log(` ✗ ${problem}`);\n\t}\n}\n\nconst required =\n\t(what: string) =>\n\t(value: string | undefined): string | undefined =>\n\t\tvalue?.trim() ? undefined : `${what} is required.`;\n\nconst text = (value: unknown) => String(value ?? '').trim();\n\n/** An `http(s)://` URL. */\nconst HttpUrl = z.url({ protocol: /^https?$/ });\n\nasync function askHttpUrl(\n\task: Ask,\n\tio: SecretsAddIo,\n\tmessage: string,\n): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(ask, io, { type: 'text', message }, (value) =>\n\t\t\tHttpUrl.safeParse(text(value)).success\n\t\t\t\t? undefined\n\t\t\t\t: 'An http:// or https:// URL is required.',\n\t\t),\n\t);\n}\n\nasync function askFrom(ask: Ask, io: SecretsAddIo): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'The address it sends from' },\n\t\t\t(value) =>\n\t\t\t\tz.email().safeParse(text(value)).success\n\t\t\t\t\t? undefined\n\t\t\t\t\t: 'An email address is required, e.g. noreply@example.com.',\n\t\t),\n\t);\n}\n\n/**\n * An SMTP server as the URL `@geekmidas/emailkit` reads: `smtp://` for\n * STARTTLS, `smtps://` for TLS from the first byte, with the user and\n * password percent-encoded.\n */\nasync function buildSmtpUrl(ask: Ask, io: SecretsAddIo): Promise<string> {\n\tconst host = text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'SMTP host' },\n\t\t\trequired('The host'),\n\t\t),\n\t);\n\tconst port = await askUntil<string | number>(\n\t\task,\n\t\tio,\n\t\t{ type: 'text', message: 'Port', initial: '587' },\n\t\t(value) => {\n\t\t\tconst n = Number(value);\n\t\t\treturn Number.isInteger(n) && n > 0 && n < 65536\n\t\t\t\t? undefined\n\t\t\t\t: 'A port number is required.';\n\t\t},\n\t);\n\tconst user = text(\n\t\tawait ask<string>({ type: 'text', message: 'User (empty for none)' }),\n\t);\n\tconst password = user\n\t\t? await ask<string>({ type: 'password', message: 'Password' })\n\t\t: '';\n\tconst tls = await ask<'starttls' | 'tls'>({\n\t\ttype: 'select',\n\t\tmessage: 'TLS',\n\t\tchoices: [\n\t\t\t{ title: 'STARTTLS (smtp://, usually port 587)', value: 'starttls' },\n\t\t\t{ title: 'TLS on connect (smtps://, usually port 465)', value: 'tls' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst url = new URL(`${tls === 'tls' ? 'smtps' : 'smtp'}://${host}`);\n\turl.port = String(Number(port));\n\tif (user) {\n\t\turl.username = encodeURIComponent(user);\n\t\turl.password = encodeURIComponent(password ?? '');\n\t}\n\treturn url.toString().replace(/\\/$/, '');\n}\n\n/**\n * A bucket's URL, from its provider — and, optionally, a key for it alone in\n * the URL, or the stage's shared pair. Credentials are never required: without\n * them the SDK's own chain signs, a role included.\n */\nasync function buildBucket(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\thas: (key: string) => boolean,\n): Promise<Record<string, string>> {\n\tconst provider = await ask<'s3' | 'r2' | 'compatible' | 'url'>({\n\t\ttype: 'select',\n\t\tmessage: 'Where is the bucket?',\n\t\tchoices: [\n\t\t\t{ title: 'AWS S3', value: 's3' },\n\t\t\t{ title: 'Cloudflare R2', value: 'r2' },\n\t\t\t{ title: 'MinIO, or another S3-compatible store', value: 'compatible' },\n\t\t\t{ title: 'Paste an s3:// URL', value: 'url' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst bucketName = async () =>\n\t\ttext(\n\t\t\tawait askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'text', message: 'Bucket name' },\n\t\t\t\trequired('The bucket name'),\n\t\t\t),\n\t\t);\n\n\tlet address: S3Address;\n\tswitch (provider) {\n\t\tcase 's3': {\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Region', initial: 'eu-west-1' },\n\t\t\t\t\trequired('The region'),\n\t\t\t\t),\n\t\t\t);\n\t\t\taddress = { bucket, region };\n\t\t\tbreak;\n\t\t}\n\t\tcase 'r2': {\n\t\t\tconst account = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tmessage: 'Cloudflare account id, or the R2 endpoint URL',\n\t\t\t\t\t},\n\t\t\t\t\trequired('The account id or endpoint'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst bucket = await bucketName();\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\tregion: 'auto',\n\t\t\t\tendpoint: /^https?:\\/\\//.test(account)\n\t\t\t\t\t? account\n\t\t\t\t\t: `https://${account}.r2.cloudflarestorage.com`,\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'compatible': {\n\t\t\tconst endpoint = await askHttpUrl(ask, io, 'Endpoint URL');\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait ask<string>({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tmessage: 'Region',\n\t\t\t\t\tinitial: 'us-east-1',\n\t\t\t\t}),\n\t\t\t);\n\t\t\tconst forcePathStyle = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: 'Path-style addressing? (MinIO needs it)',\n\t\t\t\tinitial: true,\n\t\t\t});\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\t...(region ? { region } : {}),\n\t\t\t\tendpoint,\n\t\t\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'url': {\n\t\t\tconst pasted = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'The s3:// URL' },\n\t\t\t\t(value) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ts3Parse(text(value));\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn `Not an s3:// URL the storage client can read (${(error as Error).name}).`;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t\taddress = s3Parse(text(pasted));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!address.accessKeyId) {\n\t\tconst own = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage: `A key for '${entry.id}' alone, in its URL? (optional)`,\n\t\t\tinitial: false,\n\t\t});\n\t\tif (own) {\n\t\t\tconst accessKeyId = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Access key id' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst secretAccessKey = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'Secret access key' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t\taddress = { ...address, accessKeyId, secretAccessKey };\n\t\t}\n\t}\n\n\tconst values: Record<string, string> = { [entry.key]: s3Build(address) };\n\n\tif (!address.accessKeyId && !has('AWS_ACCESS_KEY_ID')) {\n\t\tconst shared = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage:\n\t\t\t\t\"Set the stage's shared AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY? \" +\n\t\t\t\t'(optional: without them a role signs)',\n\t\t\tinitial: false,\n\t\t});\n\t\tif (shared) {\n\t\t\tvalues.AWS_ACCESS_KEY_ID = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'AWS_ACCESS_KEY_ID' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tvalues.AWS_SECRET_ACCESS_KEY = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'AWS_SECRET_ACCESS_KEY' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn values;\n}\n\n/** A field whose name says it is a secret, asked for without echo. */\nconst SECRET_FIELD = /secret|key|token|password/i;\n\ninterface JsonSchemaProperty {\n\ttype?: string | string[];\n\tenum?: unknown[];\n\tdescription?: string;\n}\n\n/** The properties of an object schema, or nothing for any other shape. */\nfunction objectProperties(\n\tinfo: CredentialSchemaInfo | undefined,\n):\n\t| { properties: Record<string, JsonSchemaProperty>; required: string[] }\n\t| undefined {\n\tconst schema = info?.jsonSchema;\n\tif (!schema || schema.type !== 'object') return undefined;\n\tconst properties = schema.properties;\n\tif (!properties || typeof properties !== 'object') return undefined;\n\treturn {\n\t\tproperties: properties as Record<string, JsonSchemaProperty>,\n\t\trequired: Array.isArray(schema.required)\n\t\t\t? (schema.required as string[])\n\t\t\t: [],\n\t};\n}\n\nfunction typesOf(property: JsonSchemaProperty): string[] {\n\tif (Array.isArray(property.type)) return property.type;\n\treturn property.type ? [property.type] : [];\n}\n\n/**\n * Credentials, field by field where the construct's schema is an object it\n * can describe, and as JSON otherwise — checked against the schema itself\n * before anything is kept, and asked again, with each issue's path, until\n * the schema takes it.\n */\nasync function buildCredentials(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\tschemas: CredentialSchemas,\n): Promise<string> {\n\tconst info = schemas.schemas.find((s) => s.key === entry.key);\n\tconst shape = objectProperties(info);\n\tif (!info) {\n\t\tio.log(\n\t\t\t` '${entry.id}' exposes no schema to check against; the value is stored as given.`,\n\t\t);\n\t}\n\n\tfor (;;) {\n\t\tconst raw = shape\n\t\t\t? JSON.stringify(await askFields(ask, io, shape))\n\t\t\t: text(\n\t\t\t\t\tawait ask<string>({\n\t\t\t\t\t\ttype: 'password',\n\t\t\t\t\t\tmessage: 'The value, as JSON (or one opaque string)',\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\tconst check = await schemas.check(entry.key, raw);\n\t\tif (check.ok) return raw;\n\t\tio.log(` ✗ The schema of '${entry.id}' refuses it:`);\n\t\tfor (const issue of check.issues) {\n\t\t\tio.log(` ${issueLine(entry.key, issue)}`);\n\t\t}\n\t\tio.log(' Again:');\n\t}\n}\n\nasync function askFields(\n\task: Ask,\n\tio: SecretsAddIo,\n\tshape: {\n\t\tproperties: Record<string, JsonSchemaProperty>;\n\t\trequired: string[];\n\t},\n): Promise<Record<string, unknown>> {\n\tconst value: Record<string, unknown> = {};\n\tfor (const [name, property] of Object.entries(shape.properties)) {\n\t\tconst optional = !shape.required.includes(name);\n\t\tconst label = `${name}${optional ? ' (optional)' : ''}${property.description ? ` — ${property.description}` : ''}`;\n\t\tconst types = typesOf(property);\n\n\t\tif (property.enum?.length) {\n\t\t\tconst choices = property.enum.map((option) => ({\n\t\t\t\ttitle: String(option),\n\t\t\t\tvalue: option,\n\t\t\t}));\n\t\t\tconst picked = await ask<unknown>({\n\t\t\t\ttype: 'select',\n\t\t\t\tmessage: label,\n\t\t\t\tchoices: optional\n\t\t\t\t\t? [{ title: '(none)', value: undefined }, ...choices]\n\t\t\t\t\t: choices,\n\t\t\t} as Omit<PromptObject, 'name'>);\n\t\t\tif (picked !== undefined) value[name] = picked;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (types.includes('boolean')) {\n\t\t\tvalue[name] = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: label,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst numeric = types.includes('number') || types.includes('integer');\n\t\tconst plain = types.length === 0 || types.includes('string');\n\t\tconst answer = await askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{\n\t\t\t\ttype: SECRET_FIELD.test(name) ? 'password' : 'text',\n\t\t\t\tmessage: label,\n\t\t\t},\n\t\t\t(given) => {\n\t\t\t\tconst typed = text(given);\n\t\t\t\tif (!typed) return optional ? undefined : `${name} is required.`;\n\t\t\t\tif (numeric && !plain && Number.isNaN(Number(typed))) {\n\t\t\t\t\treturn `${name} is a number.`;\n\t\t\t\t}\n\t\t\t\tif (!numeric && !plain) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tJSON.parse(typed);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn `${name} is JSON (${types.join(' or ')}).`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t);\n\t\tconst typed = text(answer);\n\t\tif (!typed) continue;\n\t\tvalue[name] = plain ? typed : numeric ? Number(typed) : JSON.parse(typed);\n\t}\n\treturn value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"add-CIxT-Iq6.mjs","names":["z.url","z.email","s3Parse","s3Build"],"sources":["../src/secrets/stageKeys.ts","../src/secrets/add.ts"],"sourcesContent":["/**\n * The keys a workspace's stage must be given — across every app, each once,\n * with who reads it and whether the stage holds it.\n *\n * The keys themselves are `requiredStageKeys`'s, the list a deploy refuses a\n * stage by. What this adds is the workspace: which constructs its apps read\n * (`appEnvKeys`, the keys each app's environment is built from) and which of\n * the keys the stage has set.\n */\n\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport {\n\ttype CredentialDeclaration,\n\trequiredStageKeys,\n\ttype ServiceDeclaration,\n\ttype StageKey,\n} from '../deploy/devServices';\nimport { appEnvKeys } from '../reconcile/apps';\nimport { appKey } from '../workspace/derive';\n\n/** A stage key, and whether the stage's secrets hold it. */\nexport interface WorkspaceStageKey extends StageKey {\n\tset: boolean;\n}\n\nexport interface WorkspaceStageKeysInput {\n\tmanifest: ConstructManifest;\n\t/** Each owner's runnables' edges, from discovery. */\n\trunnables?: Readonly<Record<string, readonly string[]>>;\n\t/** Whether the stage is the workspace's local one. */\n\tlocal: boolean;\n\t/** What the stage's secrets hold, by key. */\n\tsupplied: Readonly<Record<string, string>>;\n\t/** The stage's base domain, for the examples. */\n\tdomain?: string;\n}\n\n/** The keys of each kind of construct an app reads, that the stage supplies. */\nfunction keysOf(id: string, kind: string): string[] {\n\tswitch (kind) {\n\t\tcase 'email':\n\t\t\treturn [provideKey(id, 'url'), provideKey(id, 'from')];\n\t\tcase 'objects':\n\t\tcase 'file-server':\n\t\t\treturn [provideKey(id, 'url')];\n\t\tcase 'external-api':\n\t\tcase 'credential':\n\t\t\treturn [provideKey(id, 'credentials')];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Every key the stage must be given for the constructs its apps read — a\n * file server's whenever its bucket is read, since its client reads both —\n * and every file server's bucket, which serves it whether or not an app\n * reads it directly.\n */\nexport function workspaceStageKeys(\n\tinput: WorkspaceStageKeysInput,\n): WorkspaceStageKey[] {\n\tconst { manifest } = input;\n\n\t// What each app's environment holds.\n\tconst reads = new Map<string, Set<string>>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\tif (kind !== 'rest-api' && kind !== 'site' && kind !== 'mobile-app') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = appKey(id);\n\t\tconst keys = appEnvKeys(manifest, name, input.runnables);\n\t\tif (keys) reads.set(name, keys);\n\t}\n\n\tconst readers = (id: string, kind: string) => {\n\t\tconst keys = keysOf(id, kind);\n\t\treturn [...reads]\n\t\t\t.filter(([, env]) => keys.some((key) => env.has(key)))\n\t\t\t.map(([app]) => app)\n\t\t\t.sort();\n\t};\n\n\tconst services: ServiceDeclaration[] = [];\n\tconst credentials: CredentialDeclaration[] = [];\n\tconst buckets = new Set<string>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\t// A file server's client reads its bucket's URL and its own, and an\n\t\t// app's edge is to the bucket: whoever reads the bucket reads both.\n\t\tconst apps =\n\t\t\tdeclaration.kind === 'file-server' && declaration.of\n\t\t\t\t? [\n\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t...readers(id, kind),\n\t\t\t\t\t\t\t...readers(declaration.of, 'objects'),\n\t\t\t\t\t\t]),\n\t\t\t\t\t].sort()\n\t\t\t\t: readers(id, kind);\n\t\tif (kind === 'external-api' || kind === 'credential') {\n\t\t\tif (apps.length > 0) credentials.push({ id, kind, apps });\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== 'email' && kind !== 'objects' && kind !== 'file-server') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (apps.length === 0) continue;\n\t\tconst of = declaration.kind === 'file-server' ? declaration.of : undefined;\n\t\tservices.push({ id, kind, ...(of ? { of } : {}), apps });\n\t\tif (of) buckets.add(of);\n\t}\n\tfor (const of of buckets) {\n\t\tif (services.some((s) => s.id === of)) continue;\n\t\tif (manifest[of]?.kind !== 'objects') continue;\n\t\tservices.push({ id: of, kind: 'objects', apps: readers(of, 'objects') });\n\t}\n\n\treturn requiredStageKeys({\n\t\tlocal: input.local,\n\t\tservices,\n\t\tcredentials,\n\t\t...(input.domain ? { domain: input.domain } : {}),\n\t}).map((key) => ({ ...key, set: input.supplied[key.key] !== undefined }));\n}\n","/**\n * `gkm secrets:add --stage <stage>` — the secrets a stage must be given,\n * built key by key.\n *\n * It offers exactly the keys a deploy would refuse the stage without\n * (`requiredStageKeys`), across every app in the workspace, each once: the\n * stage's buckets, mail and file servers where it is deployed, and every\n * third party's credentials. A key is built by what it is — a bucket from its\n * provider, mail from its SMTP server, credentials field by field from their\n * construct's schema — checked, and saved through the stage's own store, the\n * one `gkm secrets:set` writes. No value is ever printed.\n *\n * `--json` asks nothing: it prints the keys, for a script or an agent to set\n * with `gkm secrets:set`.\n */\n\nimport {\n\ttype S3Address,\n\tbuild as s3Build,\n\tparse as s3Parse,\n} from '@geekmidas/storage/s3-url';\nimport prompts, { type PromptObject } from 'prompts';\nimport { z } from 'zod';\nimport { loadWorkspaceSettings } from '../config';\nimport { discover } from '../reconcile/discover';\nimport { constructGlobs } from '../reconcile/workspace';\nimport { assertDeployedStage } from '../workspace/stages';\nimport {\n\ttype CredentialSchemaInfo,\n\ttype CredentialSchemas,\n\tissueLine,\n\tloadCredentialSchemas,\n} from './credentialSchemas';\nimport { type WorkspaceStageKey, workspaceStageKeys } from './stageKeys';\nimport { initStageSecrets } from './storage';\nimport { secretsStoreFor } from './store';\n\nexport interface SecretsAddOptions {\n\tstage: string;\n\t/** Only the keys the stage has not set. */\n\tmissing?: boolean;\n\t/** Print the keys as JSON and ask nothing. */\n\tjson?: boolean;\n\t/** The workspace — the current directory when absent. */\n\tcwd?: string;\n\t/** The CLI's home, for a file store's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n}\n\n/** Where the command writes, and whether there is anyone to ask. */\nexport interface SecretsAddIo {\n\t/** A line for the person at the terminal. */\n\tlog(line: string): void;\n\t/** `--json`'s output. */\n\twrite(chunk: string): void;\n\t/** Whether prompts can be answered. */\n\tinteractive: boolean;\n}\n\n/** What a run of the command came to. */\nexport interface SecretsAddResult {\n\t/** The keys offered. */\n\tkeys: WorkspaceStageKey[];\n\t/** The keys saved, in the order they were built. */\n\tsaved: string[];\n}\n\n/** One key as `--json` prints it. */\nexport interface StageKeyJson {\n\tkey: string;\n\tkind: WorkspaceStageKey['kind'];\n\tconstruct: string;\n\tapps: string[];\n\tset: boolean;\n}\n\n/** `gkm secrets:add` with nobody at a terminal to answer it. */\nexport class SecretsAddNeedsTerminal extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`gkm secrets:add asks for each key, and there is no terminal to ask ` +\n\t\t\t\t`at. List what the stage needs with ` +\n\t\t\t\t`gkm secrets:add --stage ${stage} --missing --json, and set each ` +\n\t\t\t\t`with gkm secrets:set <KEY> <value> --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'SecretsAddNeedsTerminal';\n\t}\n}\n\n/** The person stopped the builder; nothing was saved. */\nexport class SecretsAddCancelled extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(`Stopped. Nothing was saved to the stage '${stage}'.`);\n\t\tthis.name = 'SecretsAddCancelled';\n\t}\n}\n\nconst defaultIo = (): SecretsAddIo => ({\n\tlog: (line) => console.log(line),\n\twrite: (chunk) => {\n\t\tprocess.stdout.write(chunk);\n\t},\n\tinteractive: process.stdin.isTTY === true && process.stdout.isTTY === true,\n});\n\n/** `gkm secrets:add`. */\nexport async function secretsAddCommand(\n\toptions: SecretsAddOptions,\n\tio: SecretsAddIo = defaultIo(),\n): Promise<SecretsAddResult> {\n\tconst { stage } = options;\n\tconst workspace = await loadWorkspaceSettings(options.cwd ?? process.cwd());\n\tconst local = stage === workspace.stages.local;\n\tif (!local) assertDeployedStage(workspace.stages, stage);\n\n\tconst patterns = constructGlobs(workspace);\n\tconst runnables: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns,\n\t\tcwd: workspace.root,\n\t\trunnables,\n\t});\n\n\tconst store = await secretsStoreFor(workspace, stage, {\n\t\t...(options.home ? { home: options.home } : {}),\n\t});\n\tconst stored = await store.read(stage);\n\tconst domain = workspace.deploy?.domains?.[stage];\n\n\tconst all = workspaceStageKeys({\n\t\tmanifest,\n\t\trunnables,\n\t\tlocal,\n\t\tsupplied: stored?.custom ?? {},\n\t\t...(domain ? { domain } : {}),\n\t});\n\tconst keys = options.missing ? all.filter((k) => !k.set) : all;\n\n\tif (options.json) {\n\t\tconst listed: StageKeyJson[] = keys.map((k) => ({\n\t\t\tkey: k.key,\n\t\t\tkind: k.kind,\n\t\t\tconstruct: k.id,\n\t\t\tapps: [...(k.apps ?? [])],\n\t\t\tset: k.set,\n\t\t}));\n\t\tio.write(`${JSON.stringify(listed, null, 2)}\\n`);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tif (!io.interactive) throw new SecretsAddNeedsTerminal(stage);\n\n\tif (keys.length === 0) {\n\t\tio.log(\n\t\t\tall.length === 0\n\t\t\t\t? `Nothing to add: no construct on '${stage}' needs a key only the stage can supply.`\n\t\t\t\t: `Nothing to add: the stage '${stage}' has every key it needs.`,\n\t\t);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tconst ask = asker(stage);\n\tconst chosen: string[] = await ask({\n\t\ttype: 'multiselect',\n\t\tmessage: `Which keys for '${stage}'? (${store.name} store)`,\n\t\tchoices: keys.map((k) => ({\n\t\t\ttitle: `${k.key} ${KIND_LABEL[k.kind]} '${k.id}'${k.apps?.length ? ` · ${k.apps.join(', ')}` : ''}${k.set ? ' · set' : ''}`,\n\t\t\tvalue: k.key,\n\t\t\tselected: !k.set,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: 'space to toggle, enter to continue',\n\t});\n\tconst selected = keys.filter((k) => (chosen ?? []).includes(k.key));\n\n\tconst values: Record<string, string> = {};\n\tconst has = (key: string) =>\n\t\tvalues[key] !== undefined || stored?.custom?.[key] !== undefined;\n\tlet schemas: CredentialSchemas | undefined;\n\n\tfor (const entry of selected) {\n\t\tif (entry.set) {\n\t\t\tconst overwrite: boolean = await ask({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: `${entry.key} is set. Replace it?`,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tif (!overwrite) continue;\n\t\t}\n\t\tio.log(`\\n${entry.key} — ${entry.what}`);\n\n\t\tswitch (entry.kind) {\n\t\t\tcase 'bucket':\n\t\t\t\tObject.assign(values, await buildBucket(ask, io, entry, has));\n\t\t\t\tbreak;\n\t\t\tcase 'email':\n\t\t\t\tvalues[entry.key] = entry.key.endsWith('_FROM')\n\t\t\t\t\t? await askFrom(ask, io)\n\t\t\t\t\t: await buildSmtpUrl(ask, io);\n\t\t\t\tbreak;\n\t\t\tcase 'file-server':\n\t\t\t\tvalues[entry.key] = await askHttpUrl(ask, io, 'Its public URL');\n\t\t\t\tbreak;\n\t\t\tcase 'external-api':\n\t\t\tcase 'credential':\n\t\t\t\tschemas ??= await loadCredentialSchemas({\n\t\t\t\t\troot: workspace.root,\n\t\t\t\t\tpatterns,\n\t\t\t\t});\n\t\t\t\tvalues[entry.key] = await buildCredentials(ask, io, entry, schemas);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst saved = Object.keys(values);\n\tif (saved.length === 0) {\n\t\tio.log('\\nNothing was saved.');\n\t\treturn { keys, saved };\n\t}\n\n\tconst base = stored ?? initStageSecrets(stage);\n\tawait store.write(stage, {\n\t\t...base,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: { ...base.custom, ...values },\n\t});\n\tio.log(\n\t\t`\\n✓ Saved ${saved.join(', ')} to the stage '${stage}' (${store.name} store).`,\n\t);\n\treturn { keys, saved };\n}\n\nconst KIND_LABEL: Record<WorkspaceStageKey['kind'], string> = {\n\tbucket: 'bucket',\n\temail: 'email',\n\t'file-server': 'file server',\n\t'external-api': 'external API',\n\tcredential: 'credential',\n};\n\n/** One question, answered — or the run stopped. */\ntype Ask = <T = string>(question: Omit<PromptObject, 'name'>) => Promise<T>;\n\nfunction asker(stage: string): Ask {\n\treturn async <T>(question: Omit<PromptObject, 'name'>) => {\n\t\tconst answers = await prompts(\n\t\t\t{ ...question, name: 'value' } as PromptObject,\n\t\t\t{\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tthrow new SecretsAddCancelled(stage);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn answers.value as T;\n\t};\n}\n\n/** Ask until `accept` takes the answer; `accept` returns why it did not. */\nasync function askUntil<T>(\n\task: Ask,\n\tio: SecretsAddIo,\n\tquestion: Omit<PromptObject, 'name'>,\n\taccept: (value: T) => string | undefined,\n): Promise<T> {\n\tfor (;;) {\n\t\tconst value = await ask<T>(question);\n\t\tconst problem = accept(value);\n\t\tif (!problem) return value;\n\t\tio.log(` ✗ ${problem}`);\n\t}\n}\n\nconst required =\n\t(what: string) =>\n\t(value: string | undefined): string | undefined =>\n\t\tvalue?.trim() ? undefined : `${what} is required.`;\n\nconst text = (value: unknown) => String(value ?? '').trim();\n\n/** An `http(s)://` URL. */\nconst HttpUrl = z.url({ protocol: /^https?$/ });\n\nasync function askHttpUrl(\n\task: Ask,\n\tio: SecretsAddIo,\n\tmessage: string,\n): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(ask, io, { type: 'text', message }, (value) =>\n\t\t\tHttpUrl.safeParse(text(value)).success\n\t\t\t\t? undefined\n\t\t\t\t: 'An http:// or https:// URL is required.',\n\t\t),\n\t);\n}\n\nasync function askFrom(ask: Ask, io: SecretsAddIo): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'The address it sends from' },\n\t\t\t(value) =>\n\t\t\t\tz.email().safeParse(text(value)).success\n\t\t\t\t\t? undefined\n\t\t\t\t\t: 'An email address is required, e.g. noreply@example.com.',\n\t\t),\n\t);\n}\n\n/**\n * An SMTP server as the URL `@geekmidas/emailkit` reads: `smtp://` for\n * STARTTLS, `smtps://` for TLS from the first byte, with the user and\n * password percent-encoded.\n */\nasync function buildSmtpUrl(ask: Ask, io: SecretsAddIo): Promise<string> {\n\tconst host = text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'SMTP host' },\n\t\t\trequired('The host'),\n\t\t),\n\t);\n\tconst port = await askUntil<string | number>(\n\t\task,\n\t\tio,\n\t\t{ type: 'text', message: 'Port', initial: '587' },\n\t\t(value) => {\n\t\t\tconst n = Number(value);\n\t\t\treturn Number.isInteger(n) && n > 0 && n < 65536\n\t\t\t\t? undefined\n\t\t\t\t: 'A port number is required.';\n\t\t},\n\t);\n\tconst user = text(\n\t\tawait ask<string>({ type: 'text', message: 'User (empty for none)' }),\n\t);\n\tconst password = user\n\t\t? await ask<string>({ type: 'password', message: 'Password' })\n\t\t: '';\n\tconst tls = await ask<'starttls' | 'tls'>({\n\t\ttype: 'select',\n\t\tmessage: 'TLS',\n\t\tchoices: [\n\t\t\t{ title: 'STARTTLS (smtp://, usually port 587)', value: 'starttls' },\n\t\t\t{ title: 'TLS on connect (smtps://, usually port 465)', value: 'tls' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst url = new URL(`${tls === 'tls' ? 'smtps' : 'smtp'}://${host}`);\n\turl.port = String(Number(port));\n\tif (user) {\n\t\turl.username = encodeURIComponent(user);\n\t\turl.password = encodeURIComponent(password ?? '');\n\t}\n\treturn url.toString().replace(/\\/$/, '');\n}\n\n/**\n * A bucket's URL, from its provider — and, optionally, a key for it alone in\n * the URL, or the stage's shared pair. Credentials are never required: without\n * them the SDK's own chain signs, a role included.\n */\nasync function buildBucket(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\thas: (key: string) => boolean,\n): Promise<Record<string, string>> {\n\tconst provider = await ask<'s3' | 'r2' | 'compatible' | 'url'>({\n\t\ttype: 'select',\n\t\tmessage: 'Where is the bucket?',\n\t\tchoices: [\n\t\t\t{ title: 'AWS S3', value: 's3' },\n\t\t\t{ title: 'Cloudflare R2', value: 'r2' },\n\t\t\t{ title: 'MinIO, or another S3-compatible store', value: 'compatible' },\n\t\t\t{ title: 'Paste an s3:// URL', value: 'url' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst bucketName = async () =>\n\t\ttext(\n\t\t\tawait askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'text', message: 'Bucket name' },\n\t\t\t\trequired('The bucket name'),\n\t\t\t),\n\t\t);\n\n\tlet address: S3Address;\n\tswitch (provider) {\n\t\tcase 's3': {\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Region', initial: 'eu-west-1' },\n\t\t\t\t\trequired('The region'),\n\t\t\t\t),\n\t\t\t);\n\t\t\taddress = { bucket, region };\n\t\t\tbreak;\n\t\t}\n\t\tcase 'r2': {\n\t\t\tconst account = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tmessage: 'Cloudflare account id, or the R2 endpoint URL',\n\t\t\t\t\t},\n\t\t\t\t\trequired('The account id or endpoint'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst bucket = await bucketName();\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\tregion: 'auto',\n\t\t\t\tendpoint: /^https?:\\/\\//.test(account)\n\t\t\t\t\t? account\n\t\t\t\t\t: `https://${account}.r2.cloudflarestorage.com`,\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'compatible': {\n\t\t\tconst endpoint = await askHttpUrl(ask, io, 'Endpoint URL');\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait ask<string>({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tmessage: 'Region',\n\t\t\t\t\tinitial: 'us-east-1',\n\t\t\t\t}),\n\t\t\t);\n\t\t\tconst forcePathStyle = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: 'Path-style addressing? (MinIO needs it)',\n\t\t\t\tinitial: true,\n\t\t\t});\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\t...(region ? { region } : {}),\n\t\t\t\tendpoint,\n\t\t\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'url': {\n\t\t\tconst pasted = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'The s3:// URL' },\n\t\t\t\t(value) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ts3Parse(text(value));\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn `Not an s3:// URL the storage client can read (${(error as Error).name}).`;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t\taddress = s3Parse(text(pasted));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!address.accessKeyId) {\n\t\tconst own = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage: `A key for '${entry.id}' alone, in its URL? (optional)`,\n\t\t\tinitial: false,\n\t\t});\n\t\tif (own) {\n\t\t\tconst accessKeyId = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Access key id' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst secretAccessKey = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'Secret access key' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t\taddress = { ...address, accessKeyId, secretAccessKey };\n\t\t}\n\t}\n\n\tconst values: Record<string, string> = { [entry.key]: s3Build(address) };\n\n\tif (!address.accessKeyId && !has('AWS_ACCESS_KEY_ID')) {\n\t\tconst shared = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage:\n\t\t\t\t\"Set the stage's shared AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY? \" +\n\t\t\t\t'(optional: without them a role signs)',\n\t\t\tinitial: false,\n\t\t});\n\t\tif (shared) {\n\t\t\tvalues.AWS_ACCESS_KEY_ID = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'AWS_ACCESS_KEY_ID' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tvalues.AWS_SECRET_ACCESS_KEY = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'AWS_SECRET_ACCESS_KEY' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn values;\n}\n\n/** A field whose name says it is a secret, asked for without echo. */\nconst SECRET_FIELD = /secret|key|token|password/i;\n\ninterface JsonSchemaProperty {\n\ttype?: string | string[];\n\tenum?: unknown[];\n\tdescription?: string;\n}\n\n/** The properties of an object schema, or nothing for any other shape. */\nfunction objectProperties(\n\tinfo: CredentialSchemaInfo | undefined,\n):\n\t| { properties: Record<string, JsonSchemaProperty>; required: string[] }\n\t| undefined {\n\tconst schema = info?.jsonSchema;\n\tif (!schema || schema.type !== 'object') return undefined;\n\tconst properties = schema.properties;\n\tif (!properties || typeof properties !== 'object') return undefined;\n\treturn {\n\t\tproperties: properties as Record<string, JsonSchemaProperty>,\n\t\trequired: Array.isArray(schema.required)\n\t\t\t? (schema.required as string[])\n\t\t\t: [],\n\t};\n}\n\nfunction typesOf(property: JsonSchemaProperty): string[] {\n\tif (Array.isArray(property.type)) return property.type;\n\treturn property.type ? [property.type] : [];\n}\n\n/**\n * Credentials, field by field where the construct's schema is an object it\n * can describe, and as JSON otherwise — checked against the schema itself\n * before anything is kept, and asked again, with each issue's path, until\n * the schema takes it.\n */\nasync function buildCredentials(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\tschemas: CredentialSchemas,\n): Promise<string> {\n\tconst info = schemas.schemas.find((s) => s.key === entry.key);\n\tconst shape = objectProperties(info);\n\tif (!info) {\n\t\tio.log(\n\t\t\t` '${entry.id}' exposes no schema to check against; the value is stored as given.`,\n\t\t);\n\t}\n\n\tfor (;;) {\n\t\tconst raw = shape\n\t\t\t? JSON.stringify(await askFields(ask, io, shape))\n\t\t\t: text(\n\t\t\t\t\tawait ask<string>({\n\t\t\t\t\t\ttype: 'password',\n\t\t\t\t\t\tmessage: 'The value, as JSON (or one opaque string)',\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\tconst check = await schemas.check(entry.key, raw);\n\t\tif (check.ok) return raw;\n\t\tio.log(` ✗ The schema of '${entry.id}' refuses it:`);\n\t\tfor (const issue of check.issues) {\n\t\t\tio.log(` ${issueLine(entry.key, issue)}`);\n\t\t}\n\t\tio.log(' Again:');\n\t}\n}\n\nasync function askFields(\n\task: Ask,\n\tio: SecretsAddIo,\n\tshape: {\n\t\tproperties: Record<string, JsonSchemaProperty>;\n\t\trequired: string[];\n\t},\n): Promise<Record<string, unknown>> {\n\tconst value: Record<string, unknown> = {};\n\tfor (const [name, property] of Object.entries(shape.properties)) {\n\t\tconst optional = !shape.required.includes(name);\n\t\tconst label = `${name}${optional ? ' (optional)' : ''}${property.description ? ` — ${property.description}` : ''}`;\n\t\tconst types = typesOf(property);\n\n\t\tif (property.enum?.length) {\n\t\t\tconst choices = property.enum.map((option) => ({\n\t\t\t\ttitle: String(option),\n\t\t\t\tvalue: option,\n\t\t\t}));\n\t\t\tconst picked = await ask<unknown>({\n\t\t\t\ttype: 'select',\n\t\t\t\tmessage: label,\n\t\t\t\tchoices: optional\n\t\t\t\t\t? [{ title: '(none)', value: undefined }, ...choices]\n\t\t\t\t\t: choices,\n\t\t\t} as Omit<PromptObject, 'name'>);\n\t\t\tif (picked !== undefined) value[name] = picked;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (types.includes('boolean')) {\n\t\t\tvalue[name] = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: label,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst numeric = types.includes('number') || types.includes('integer');\n\t\tconst plain = types.length === 0 || types.includes('string');\n\t\tconst answer = await askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{\n\t\t\t\ttype: SECRET_FIELD.test(name) ? 'password' : 'text',\n\t\t\t\tmessage: label,\n\t\t\t},\n\t\t\t(given) => {\n\t\t\t\tconst typed = text(given);\n\t\t\t\tif (!typed) return optional ? undefined : `${name} is required.`;\n\t\t\t\tif (numeric && !plain && Number.isNaN(Number(typed))) {\n\t\t\t\t\treturn `${name} is a number.`;\n\t\t\t\t}\n\t\t\t\tif (!numeric && !plain) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tJSON.parse(typed);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn `${name} is JSON (${types.join(' or ')}).`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t);\n\t\tconst typed = text(answer);\n\t\tif (!typed) continue;\n\t\tvalue[name] = plain ? typed : numeric ? Number(typed) : JSON.parse(typed);\n\t}\n\treturn value;\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ const require_discover = require("./discover-D1It5r_h.cjs");
4
4
  const require_derive = require("./derive-DAbo49sm.cjs");
5
5
  const require_workspace = require("./workspace-Bp8FEkF-.cjs");
6
6
  const require_config = require("./config.cjs");
7
- const require_stale = require("./stale-BsiPJI7Y.cjs");
7
+ const require_seeds = require("./seeds-ZljwYV_p.cjs");
8
8
  const require_credentialSchemas = require("./credentialSchemas-DCR4Wd1W.cjs");
9
9
  let _geekmidas_manifest = require("@geekmidas/manifest");
10
10
  let prompts = require("prompts");
@@ -44,7 +44,7 @@ function workspaceStageKeys(input) {
44
44
  const { kind } = declaration;
45
45
  if (kind !== "rest-api" && kind !== "site" && kind !== "mobile-app") continue;
46
46
  const name = require_derive.appKey(id);
47
- const keys = require_stale.appEnvKeys(manifest, name, input.runnables);
47
+ const keys = require_seeds.appEnvKeys(manifest, name, input.runnables);
48
48
  if (keys) reads.set(name, keys);
49
49
  }
50
50
  const readers = (id, kind) => {
@@ -85,7 +85,7 @@ function workspaceStageKeys(input) {
85
85
  apps: readers(of, "objects")
86
86
  });
87
87
  }
88
- return require_stale.requiredStageKeys({
88
+ return require_seeds.requiredStageKeys({
89
89
  local: input.local,
90
90
  services,
91
91
  credentials,
@@ -143,14 +143,14 @@ async function secretsAddCommand(options, io = defaultIo()) {
143
143
  const workspace = await require_config.loadWorkspaceSettings(options.cwd ?? process.cwd());
144
144
  const local = stage === workspace.stages.local;
145
145
  if (!local) require_workspace.assertDeployedStage(workspace.stages, stage);
146
- const patterns = require_stale.constructGlobs(workspace);
146
+ const patterns = require_seeds.constructGlobs(workspace);
147
147
  const runnables = {};
148
148
  const manifest = await require_discover.discover({
149
149
  patterns,
150
150
  cwd: workspace.root,
151
151
  runnables
152
152
  });
153
- const store = await require_stale.secretsStoreFor(workspace, stage, { ...options.home ? { home: options.home } : {} });
153
+ const store = await require_seeds.secretsStoreFor(workspace, stage, { ...options.home ? { home: options.home } : {} });
154
154
  const stored = await store.read(stage);
155
155
  const domain = workspace.deploy?.domains?.[stage];
156
156
  const all = workspaceStageKeys({
@@ -235,7 +235,7 @@ async function secretsAddCommand(options, io = defaultIo()) {
235
235
  saved
236
236
  };
237
237
  }
238
- const base = stored ?? require_stale.initStageSecrets(stage);
238
+ const base = stored ?? require_seeds.initStageSecrets(stage);
239
239
  await store.write(stage, {
240
240
  ...base,
241
241
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -565,4 +565,4 @@ async function askFields(ask, io, shape) {
565
565
  //#endregion
566
566
  exports.secretsAddCommand = secretsAddCommand;
567
567
 
568
- //# sourceMappingURL=add-BvOICikp.cjs.map
568
+ //# sourceMappingURL=add-DJ0VE-y-.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-BvOICikp.cjs","names":["provideKey","appKey","appEnvKeys","requiredStageKeys","loadWorkspaceSettings","constructGlobs","discover","secretsStoreFor","loadCredentialSchemas","initStageSecrets","s3Parse","s3Build","issueLine"],"sources":["../src/secrets/stageKeys.ts","../src/secrets/add.ts"],"sourcesContent":["/**\n * The keys a workspace's stage must be given — across every app, each once,\n * with who reads it and whether the stage holds it.\n *\n * The keys themselves are `requiredStageKeys`'s, the list a deploy refuses a\n * stage by. What this adds is the workspace: which constructs its apps read\n * (`appEnvKeys`, the keys each app's environment is built from) and which of\n * the keys the stage has set.\n */\n\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport {\n\ttype CredentialDeclaration,\n\trequiredStageKeys,\n\ttype ServiceDeclaration,\n\ttype StageKey,\n} from '../deploy/devServices';\nimport { appEnvKeys } from '../reconcile/apps';\nimport { appKey } from '../workspace/derive';\n\n/** A stage key, and whether the stage's secrets hold it. */\nexport interface WorkspaceStageKey extends StageKey {\n\tset: boolean;\n}\n\nexport interface WorkspaceStageKeysInput {\n\tmanifest: ConstructManifest;\n\t/** Each owner's runnables' edges, from discovery. */\n\trunnables?: Readonly<Record<string, readonly string[]>>;\n\t/** Whether the stage is the workspace's local one. */\n\tlocal: boolean;\n\t/** What the stage's secrets hold, by key. */\n\tsupplied: Readonly<Record<string, string>>;\n\t/** The stage's base domain, for the examples. */\n\tdomain?: string;\n}\n\n/** The keys of each kind of construct an app reads, that the stage supplies. */\nfunction keysOf(id: string, kind: string): string[] {\n\tswitch (kind) {\n\t\tcase 'email':\n\t\t\treturn [provideKey(id, 'url'), provideKey(id, 'from')];\n\t\tcase 'objects':\n\t\tcase 'file-server':\n\t\t\treturn [provideKey(id, 'url')];\n\t\tcase 'external-api':\n\t\tcase 'credential':\n\t\t\treturn [provideKey(id, 'credentials')];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Every key the stage must be given for the constructs its apps read — a\n * file server's whenever its bucket is read, since its client reads both —\n * and every file server's bucket, which serves it whether or not an app\n * reads it directly.\n */\nexport function workspaceStageKeys(\n\tinput: WorkspaceStageKeysInput,\n): WorkspaceStageKey[] {\n\tconst { manifest } = input;\n\n\t// What each app's environment holds.\n\tconst reads = new Map<string, Set<string>>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\tif (kind !== 'rest-api' && kind !== 'site' && kind !== 'mobile-app') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = appKey(id);\n\t\tconst keys = appEnvKeys(manifest, name, input.runnables);\n\t\tif (keys) reads.set(name, keys);\n\t}\n\n\tconst readers = (id: string, kind: string) => {\n\t\tconst keys = keysOf(id, kind);\n\t\treturn [...reads]\n\t\t\t.filter(([, env]) => keys.some((key) => env.has(key)))\n\t\t\t.map(([app]) => app)\n\t\t\t.sort();\n\t};\n\n\tconst services: ServiceDeclaration[] = [];\n\tconst credentials: CredentialDeclaration[] = [];\n\tconst buckets = new Set<string>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\t// A file server's client reads its bucket's URL and its own, and an\n\t\t// app's edge is to the bucket: whoever reads the bucket reads both.\n\t\tconst apps =\n\t\t\tdeclaration.kind === 'file-server' && declaration.of\n\t\t\t\t? [\n\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t...readers(id, kind),\n\t\t\t\t\t\t\t...readers(declaration.of, 'objects'),\n\t\t\t\t\t\t]),\n\t\t\t\t\t].sort()\n\t\t\t\t: readers(id, kind);\n\t\tif (kind === 'external-api' || kind === 'credential') {\n\t\t\tif (apps.length > 0) credentials.push({ id, kind, apps });\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== 'email' && kind !== 'objects' && kind !== 'file-server') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (apps.length === 0) continue;\n\t\tconst of = declaration.kind === 'file-server' ? declaration.of : undefined;\n\t\tservices.push({ id, kind, ...(of ? { of } : {}), apps });\n\t\tif (of) buckets.add(of);\n\t}\n\tfor (const of of buckets) {\n\t\tif (services.some((s) => s.id === of)) continue;\n\t\tif (manifest[of]?.kind !== 'objects') continue;\n\t\tservices.push({ id: of, kind: 'objects', apps: readers(of, 'objects') });\n\t}\n\n\treturn requiredStageKeys({\n\t\tlocal: input.local,\n\t\tservices,\n\t\tcredentials,\n\t\t...(input.domain ? { domain: input.domain } : {}),\n\t}).map((key) => ({ ...key, set: input.supplied[key.key] !== undefined }));\n}\n","/**\n * `gkm secrets:add --stage <stage>` — the secrets a stage must be given,\n * built key by key.\n *\n * It offers exactly the keys a deploy would refuse the stage without\n * (`requiredStageKeys`), across every app in the workspace, each once: the\n * stage's buckets, mail and file servers where it is deployed, and every\n * third party's credentials. A key is built by what it is — a bucket from its\n * provider, mail from its SMTP server, credentials field by field from their\n * construct's schema — checked, and saved through the stage's own store, the\n * one `gkm secrets:set` writes. No value is ever printed.\n *\n * `--json` asks nothing: it prints the keys, for a script or an agent to set\n * with `gkm secrets:set`.\n */\n\nimport {\n\ttype S3Address,\n\tbuild as s3Build,\n\tparse as s3Parse,\n} from '@geekmidas/storage/s3-url';\nimport prompts, { type PromptObject } from 'prompts';\nimport { z } from 'zod';\nimport { loadWorkspaceSettings } from '../config';\nimport { discover } from '../reconcile/discover';\nimport { constructGlobs } from '../reconcile/workspace';\nimport { assertDeployedStage } from '../workspace/stages';\nimport {\n\ttype CredentialSchemaInfo,\n\ttype CredentialSchemas,\n\tissueLine,\n\tloadCredentialSchemas,\n} from './credentialSchemas';\nimport { type WorkspaceStageKey, workspaceStageKeys } from './stageKeys';\nimport { initStageSecrets } from './storage';\nimport { secretsStoreFor } from './store';\n\nexport interface SecretsAddOptions {\n\tstage: string;\n\t/** Only the keys the stage has not set. */\n\tmissing?: boolean;\n\t/** Print the keys as JSON and ask nothing. */\n\tjson?: boolean;\n\t/** The workspace — the current directory when absent. */\n\tcwd?: string;\n\t/** The CLI's home, for a file store's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n}\n\n/** Where the command writes, and whether there is anyone to ask. */\nexport interface SecretsAddIo {\n\t/** A line for the person at the terminal. */\n\tlog(line: string): void;\n\t/** `--json`'s output. */\n\twrite(chunk: string): void;\n\t/** Whether prompts can be answered. */\n\tinteractive: boolean;\n}\n\n/** What a run of the command came to. */\nexport interface SecretsAddResult {\n\t/** The keys offered. */\n\tkeys: WorkspaceStageKey[];\n\t/** The keys saved, in the order they were built. */\n\tsaved: string[];\n}\n\n/** One key as `--json` prints it. */\nexport interface StageKeyJson {\n\tkey: string;\n\tkind: WorkspaceStageKey['kind'];\n\tconstruct: string;\n\tapps: string[];\n\tset: boolean;\n}\n\n/** `gkm secrets:add` with nobody at a terminal to answer it. */\nexport class SecretsAddNeedsTerminal extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`gkm secrets:add asks for each key, and there is no terminal to ask ` +\n\t\t\t\t`at. List what the stage needs with ` +\n\t\t\t\t`gkm secrets:add --stage ${stage} --missing --json, and set each ` +\n\t\t\t\t`with gkm secrets:set <KEY> <value> --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'SecretsAddNeedsTerminal';\n\t}\n}\n\n/** The person stopped the builder; nothing was saved. */\nexport class SecretsAddCancelled extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(`Stopped. Nothing was saved to the stage '${stage}'.`);\n\t\tthis.name = 'SecretsAddCancelled';\n\t}\n}\n\nconst defaultIo = (): SecretsAddIo => ({\n\tlog: (line) => console.log(line),\n\twrite: (chunk) => {\n\t\tprocess.stdout.write(chunk);\n\t},\n\tinteractive: process.stdin.isTTY === true && process.stdout.isTTY === true,\n});\n\n/** `gkm secrets:add`. */\nexport async function secretsAddCommand(\n\toptions: SecretsAddOptions,\n\tio: SecretsAddIo = defaultIo(),\n): Promise<SecretsAddResult> {\n\tconst { stage } = options;\n\tconst workspace = await loadWorkspaceSettings(options.cwd ?? process.cwd());\n\tconst local = stage === workspace.stages.local;\n\tif (!local) assertDeployedStage(workspace.stages, stage);\n\n\tconst patterns = constructGlobs(workspace);\n\tconst runnables: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns,\n\t\tcwd: workspace.root,\n\t\trunnables,\n\t});\n\n\tconst store = await secretsStoreFor(workspace, stage, {\n\t\t...(options.home ? { home: options.home } : {}),\n\t});\n\tconst stored = await store.read(stage);\n\tconst domain = workspace.deploy?.domains?.[stage];\n\n\tconst all = workspaceStageKeys({\n\t\tmanifest,\n\t\trunnables,\n\t\tlocal,\n\t\tsupplied: stored?.custom ?? {},\n\t\t...(domain ? { domain } : {}),\n\t});\n\tconst keys = options.missing ? all.filter((k) => !k.set) : all;\n\n\tif (options.json) {\n\t\tconst listed: StageKeyJson[] = keys.map((k) => ({\n\t\t\tkey: k.key,\n\t\t\tkind: k.kind,\n\t\t\tconstruct: k.id,\n\t\t\tapps: [...(k.apps ?? [])],\n\t\t\tset: k.set,\n\t\t}));\n\t\tio.write(`${JSON.stringify(listed, null, 2)}\\n`);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tif (!io.interactive) throw new SecretsAddNeedsTerminal(stage);\n\n\tif (keys.length === 0) {\n\t\tio.log(\n\t\t\tall.length === 0\n\t\t\t\t? `Nothing to add: no construct on '${stage}' needs a key only the stage can supply.`\n\t\t\t\t: `Nothing to add: the stage '${stage}' has every key it needs.`,\n\t\t);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tconst ask = asker(stage);\n\tconst chosen: string[] = await ask({\n\t\ttype: 'multiselect',\n\t\tmessage: `Which keys for '${stage}'? (${store.name} store)`,\n\t\tchoices: keys.map((k) => ({\n\t\t\ttitle: `${k.key} ${KIND_LABEL[k.kind]} '${k.id}'${k.apps?.length ? ` · ${k.apps.join(', ')}` : ''}${k.set ? ' · set' : ''}`,\n\t\t\tvalue: k.key,\n\t\t\tselected: !k.set,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: 'space to toggle, enter to continue',\n\t});\n\tconst selected = keys.filter((k) => (chosen ?? []).includes(k.key));\n\n\tconst values: Record<string, string> = {};\n\tconst has = (key: string) =>\n\t\tvalues[key] !== undefined || stored?.custom?.[key] !== undefined;\n\tlet schemas: CredentialSchemas | undefined;\n\n\tfor (const entry of selected) {\n\t\tif (entry.set) {\n\t\t\tconst overwrite: boolean = await ask({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: `${entry.key} is set. Replace it?`,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tif (!overwrite) continue;\n\t\t}\n\t\tio.log(`\\n${entry.key} — ${entry.what}`);\n\n\t\tswitch (entry.kind) {\n\t\t\tcase 'bucket':\n\t\t\t\tObject.assign(values, await buildBucket(ask, io, entry, has));\n\t\t\t\tbreak;\n\t\t\tcase 'email':\n\t\t\t\tvalues[entry.key] = entry.key.endsWith('_FROM')\n\t\t\t\t\t? await askFrom(ask, io)\n\t\t\t\t\t: await buildSmtpUrl(ask, io);\n\t\t\t\tbreak;\n\t\t\tcase 'file-server':\n\t\t\t\tvalues[entry.key] = await askHttpUrl(ask, io, 'Its public URL');\n\t\t\t\tbreak;\n\t\t\tcase 'external-api':\n\t\t\tcase 'credential':\n\t\t\t\tschemas ??= await loadCredentialSchemas({\n\t\t\t\t\troot: workspace.root,\n\t\t\t\t\tpatterns,\n\t\t\t\t});\n\t\t\t\tvalues[entry.key] = await buildCredentials(ask, io, entry, schemas);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst saved = Object.keys(values);\n\tif (saved.length === 0) {\n\t\tio.log('\\nNothing was saved.');\n\t\treturn { keys, saved };\n\t}\n\n\tconst base = stored ?? initStageSecrets(stage);\n\tawait store.write(stage, {\n\t\t...base,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: { ...base.custom, ...values },\n\t});\n\tio.log(\n\t\t`\\n✓ Saved ${saved.join(', ')} to the stage '${stage}' (${store.name} store).`,\n\t);\n\treturn { keys, saved };\n}\n\nconst KIND_LABEL: Record<WorkspaceStageKey['kind'], string> = {\n\tbucket: 'bucket',\n\temail: 'email',\n\t'file-server': 'file server',\n\t'external-api': 'external API',\n\tcredential: 'credential',\n};\n\n/** One question, answered — or the run stopped. */\ntype Ask = <T = string>(question: Omit<PromptObject, 'name'>) => Promise<T>;\n\nfunction asker(stage: string): Ask {\n\treturn async <T>(question: Omit<PromptObject, 'name'>) => {\n\t\tconst answers = await prompts(\n\t\t\t{ ...question, name: 'value' } as PromptObject,\n\t\t\t{\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tthrow new SecretsAddCancelled(stage);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn answers.value as T;\n\t};\n}\n\n/** Ask until `accept` takes the answer; `accept` returns why it did not. */\nasync function askUntil<T>(\n\task: Ask,\n\tio: SecretsAddIo,\n\tquestion: Omit<PromptObject, 'name'>,\n\taccept: (value: T) => string | undefined,\n): Promise<T> {\n\tfor (;;) {\n\t\tconst value = await ask<T>(question);\n\t\tconst problem = accept(value);\n\t\tif (!problem) return value;\n\t\tio.log(` ✗ ${problem}`);\n\t}\n}\n\nconst required =\n\t(what: string) =>\n\t(value: string | undefined): string | undefined =>\n\t\tvalue?.trim() ? undefined : `${what} is required.`;\n\nconst text = (value: unknown) => String(value ?? '').trim();\n\n/** An `http(s)://` URL. */\nconst HttpUrl = z.url({ protocol: /^https?$/ });\n\nasync function askHttpUrl(\n\task: Ask,\n\tio: SecretsAddIo,\n\tmessage: string,\n): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(ask, io, { type: 'text', message }, (value) =>\n\t\t\tHttpUrl.safeParse(text(value)).success\n\t\t\t\t? undefined\n\t\t\t\t: 'An http:// or https:// URL is required.',\n\t\t),\n\t);\n}\n\nasync function askFrom(ask: Ask, io: SecretsAddIo): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'The address it sends from' },\n\t\t\t(value) =>\n\t\t\t\tz.email().safeParse(text(value)).success\n\t\t\t\t\t? undefined\n\t\t\t\t\t: 'An email address is required, e.g. noreply@example.com.',\n\t\t),\n\t);\n}\n\n/**\n * An SMTP server as the URL `@geekmidas/emailkit` reads: `smtp://` for\n * STARTTLS, `smtps://` for TLS from the first byte, with the user and\n * password percent-encoded.\n */\nasync function buildSmtpUrl(ask: Ask, io: SecretsAddIo): Promise<string> {\n\tconst host = text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'SMTP host' },\n\t\t\trequired('The host'),\n\t\t),\n\t);\n\tconst port = await askUntil<string | number>(\n\t\task,\n\t\tio,\n\t\t{ type: 'text', message: 'Port', initial: '587' },\n\t\t(value) => {\n\t\t\tconst n = Number(value);\n\t\t\treturn Number.isInteger(n) && n > 0 && n < 65536\n\t\t\t\t? undefined\n\t\t\t\t: 'A port number is required.';\n\t\t},\n\t);\n\tconst user = text(\n\t\tawait ask<string>({ type: 'text', message: 'User (empty for none)' }),\n\t);\n\tconst password = user\n\t\t? await ask<string>({ type: 'password', message: 'Password' })\n\t\t: '';\n\tconst tls = await ask<'starttls' | 'tls'>({\n\t\ttype: 'select',\n\t\tmessage: 'TLS',\n\t\tchoices: [\n\t\t\t{ title: 'STARTTLS (smtp://, usually port 587)', value: 'starttls' },\n\t\t\t{ title: 'TLS on connect (smtps://, usually port 465)', value: 'tls' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst url = new URL(`${tls === 'tls' ? 'smtps' : 'smtp'}://${host}`);\n\turl.port = String(Number(port));\n\tif (user) {\n\t\turl.username = encodeURIComponent(user);\n\t\turl.password = encodeURIComponent(password ?? '');\n\t}\n\treturn url.toString().replace(/\\/$/, '');\n}\n\n/**\n * A bucket's URL, from its provider — and, optionally, a key for it alone in\n * the URL, or the stage's shared pair. Credentials are never required: without\n * them the SDK's own chain signs, a role included.\n */\nasync function buildBucket(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\thas: (key: string) => boolean,\n): Promise<Record<string, string>> {\n\tconst provider = await ask<'s3' | 'r2' | 'compatible' | 'url'>({\n\t\ttype: 'select',\n\t\tmessage: 'Where is the bucket?',\n\t\tchoices: [\n\t\t\t{ title: 'AWS S3', value: 's3' },\n\t\t\t{ title: 'Cloudflare R2', value: 'r2' },\n\t\t\t{ title: 'MinIO, or another S3-compatible store', value: 'compatible' },\n\t\t\t{ title: 'Paste an s3:// URL', value: 'url' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst bucketName = async () =>\n\t\ttext(\n\t\t\tawait askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'text', message: 'Bucket name' },\n\t\t\t\trequired('The bucket name'),\n\t\t\t),\n\t\t);\n\n\tlet address: S3Address;\n\tswitch (provider) {\n\t\tcase 's3': {\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Region', initial: 'eu-west-1' },\n\t\t\t\t\trequired('The region'),\n\t\t\t\t),\n\t\t\t);\n\t\t\taddress = { bucket, region };\n\t\t\tbreak;\n\t\t}\n\t\tcase 'r2': {\n\t\t\tconst account = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tmessage: 'Cloudflare account id, or the R2 endpoint URL',\n\t\t\t\t\t},\n\t\t\t\t\trequired('The account id or endpoint'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst bucket = await bucketName();\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\tregion: 'auto',\n\t\t\t\tendpoint: /^https?:\\/\\//.test(account)\n\t\t\t\t\t? account\n\t\t\t\t\t: `https://${account}.r2.cloudflarestorage.com`,\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'compatible': {\n\t\t\tconst endpoint = await askHttpUrl(ask, io, 'Endpoint URL');\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait ask<string>({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tmessage: 'Region',\n\t\t\t\t\tinitial: 'us-east-1',\n\t\t\t\t}),\n\t\t\t);\n\t\t\tconst forcePathStyle = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: 'Path-style addressing? (MinIO needs it)',\n\t\t\t\tinitial: true,\n\t\t\t});\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\t...(region ? { region } : {}),\n\t\t\t\tendpoint,\n\t\t\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'url': {\n\t\t\tconst pasted = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'The s3:// URL' },\n\t\t\t\t(value) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ts3Parse(text(value));\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn `Not an s3:// URL the storage client can read (${(error as Error).name}).`;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t\taddress = s3Parse(text(pasted));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!address.accessKeyId) {\n\t\tconst own = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage: `A key for '${entry.id}' alone, in its URL? (optional)`,\n\t\t\tinitial: false,\n\t\t});\n\t\tif (own) {\n\t\t\tconst accessKeyId = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Access key id' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst secretAccessKey = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'Secret access key' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t\taddress = { ...address, accessKeyId, secretAccessKey };\n\t\t}\n\t}\n\n\tconst values: Record<string, string> = { [entry.key]: s3Build(address) };\n\n\tif (!address.accessKeyId && !has('AWS_ACCESS_KEY_ID')) {\n\t\tconst shared = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage:\n\t\t\t\t\"Set the stage's shared AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY? \" +\n\t\t\t\t'(optional: without them a role signs)',\n\t\t\tinitial: false,\n\t\t});\n\t\tif (shared) {\n\t\t\tvalues.AWS_ACCESS_KEY_ID = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'AWS_ACCESS_KEY_ID' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tvalues.AWS_SECRET_ACCESS_KEY = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'AWS_SECRET_ACCESS_KEY' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn values;\n}\n\n/** A field whose name says it is a secret, asked for without echo. */\nconst SECRET_FIELD = /secret|key|token|password/i;\n\ninterface JsonSchemaProperty {\n\ttype?: string | string[];\n\tenum?: unknown[];\n\tdescription?: string;\n}\n\n/** The properties of an object schema, or nothing for any other shape. */\nfunction objectProperties(\n\tinfo: CredentialSchemaInfo | undefined,\n):\n\t| { properties: Record<string, JsonSchemaProperty>; required: string[] }\n\t| undefined {\n\tconst schema = info?.jsonSchema;\n\tif (!schema || schema.type !== 'object') return undefined;\n\tconst properties = schema.properties;\n\tif (!properties || typeof properties !== 'object') return undefined;\n\treturn {\n\t\tproperties: properties as Record<string, JsonSchemaProperty>,\n\t\trequired: Array.isArray(schema.required)\n\t\t\t? (schema.required as string[])\n\t\t\t: [],\n\t};\n}\n\nfunction typesOf(property: JsonSchemaProperty): string[] {\n\tif (Array.isArray(property.type)) return property.type;\n\treturn property.type ? [property.type] : [];\n}\n\n/**\n * Credentials, field by field where the construct's schema is an object it\n * can describe, and as JSON otherwise — checked against the schema itself\n * before anything is kept, and asked again, with each issue's path, until\n * the schema takes it.\n */\nasync function buildCredentials(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\tschemas: CredentialSchemas,\n): Promise<string> {\n\tconst info = schemas.schemas.find((s) => s.key === entry.key);\n\tconst shape = objectProperties(info);\n\tif (!info) {\n\t\tio.log(\n\t\t\t` '${entry.id}' exposes no schema to check against; the value is stored as given.`,\n\t\t);\n\t}\n\n\tfor (;;) {\n\t\tconst raw = shape\n\t\t\t? JSON.stringify(await askFields(ask, io, shape))\n\t\t\t: text(\n\t\t\t\t\tawait ask<string>({\n\t\t\t\t\t\ttype: 'password',\n\t\t\t\t\t\tmessage: 'The value, as JSON (or one opaque string)',\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\tconst check = await schemas.check(entry.key, raw);\n\t\tif (check.ok) return raw;\n\t\tio.log(` ✗ The schema of '${entry.id}' refuses it:`);\n\t\tfor (const issue of check.issues) {\n\t\t\tio.log(` ${issueLine(entry.key, issue)}`);\n\t\t}\n\t\tio.log(' Again:');\n\t}\n}\n\nasync function askFields(\n\task: Ask,\n\tio: SecretsAddIo,\n\tshape: {\n\t\tproperties: Record<string, JsonSchemaProperty>;\n\t\trequired: string[];\n\t},\n): Promise<Record<string, unknown>> {\n\tconst value: Record<string, unknown> = {};\n\tfor (const [name, property] of Object.entries(shape.properties)) {\n\t\tconst optional = !shape.required.includes(name);\n\t\tconst label = `${name}${optional ? ' (optional)' : ''}${property.description ? ` — ${property.description}` : ''}`;\n\t\tconst types = typesOf(property);\n\n\t\tif (property.enum?.length) {\n\t\t\tconst choices = property.enum.map((option) => ({\n\t\t\t\ttitle: String(option),\n\t\t\t\tvalue: option,\n\t\t\t}));\n\t\t\tconst picked = await ask<unknown>({\n\t\t\t\ttype: 'select',\n\t\t\t\tmessage: label,\n\t\t\t\tchoices: optional\n\t\t\t\t\t? [{ title: '(none)', value: undefined }, ...choices]\n\t\t\t\t\t: choices,\n\t\t\t} as Omit<PromptObject, 'name'>);\n\t\t\tif (picked !== undefined) value[name] = picked;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (types.includes('boolean')) {\n\t\t\tvalue[name] = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: label,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst numeric = types.includes('number') || types.includes('integer');\n\t\tconst plain = types.length === 0 || types.includes('string');\n\t\tconst answer = await askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{\n\t\t\t\ttype: SECRET_FIELD.test(name) ? 'password' : 'text',\n\t\t\t\tmessage: label,\n\t\t\t},\n\t\t\t(given) => {\n\t\t\t\tconst typed = text(given);\n\t\t\t\tif (!typed) return optional ? undefined : `${name} is required.`;\n\t\t\t\tif (numeric && !plain && Number.isNaN(Number(typed))) {\n\t\t\t\t\treturn `${name} is a number.`;\n\t\t\t\t}\n\t\t\t\tif (!numeric && !plain) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tJSON.parse(typed);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn `${name} is JSON (${types.join(' or ')}).`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t);\n\t\tconst typed = text(answer);\n\t\tif (!typed) continue;\n\t\tvalue[name] = plain ? typed : numeric ? Number(typed) : JSON.parse(typed);\n\t}\n\treturn value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"add-DJ0VE-y-.cjs","names":["provideKey","appKey","appEnvKeys","requiredStageKeys","loadWorkspaceSettings","constructGlobs","discover","secretsStoreFor","loadCredentialSchemas","initStageSecrets","s3Parse","s3Build","issueLine"],"sources":["../src/secrets/stageKeys.ts","../src/secrets/add.ts"],"sourcesContent":["/**\n * The keys a workspace's stage must be given — across every app, each once,\n * with who reads it and whether the stage holds it.\n *\n * The keys themselves are `requiredStageKeys`'s, the list a deploy refuses a\n * stage by. What this adds is the workspace: which constructs its apps read\n * (`appEnvKeys`, the keys each app's environment is built from) and which of\n * the keys the stage has set.\n */\n\nimport { type ConstructManifest, provideKey } from '@geekmidas/manifest';\nimport {\n\ttype CredentialDeclaration,\n\trequiredStageKeys,\n\ttype ServiceDeclaration,\n\ttype StageKey,\n} from '../deploy/devServices';\nimport { appEnvKeys } from '../reconcile/apps';\nimport { appKey } from '../workspace/derive';\n\n/** A stage key, and whether the stage's secrets hold it. */\nexport interface WorkspaceStageKey extends StageKey {\n\tset: boolean;\n}\n\nexport interface WorkspaceStageKeysInput {\n\tmanifest: ConstructManifest;\n\t/** Each owner's runnables' edges, from discovery. */\n\trunnables?: Readonly<Record<string, readonly string[]>>;\n\t/** Whether the stage is the workspace's local one. */\n\tlocal: boolean;\n\t/** What the stage's secrets hold, by key. */\n\tsupplied: Readonly<Record<string, string>>;\n\t/** The stage's base domain, for the examples. */\n\tdomain?: string;\n}\n\n/** The keys of each kind of construct an app reads, that the stage supplies. */\nfunction keysOf(id: string, kind: string): string[] {\n\tswitch (kind) {\n\t\tcase 'email':\n\t\t\treturn [provideKey(id, 'url'), provideKey(id, 'from')];\n\t\tcase 'objects':\n\t\tcase 'file-server':\n\t\t\treturn [provideKey(id, 'url')];\n\t\tcase 'external-api':\n\t\tcase 'credential':\n\t\t\treturn [provideKey(id, 'credentials')];\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\n/**\n * Every key the stage must be given for the constructs its apps read — a\n * file server's whenever its bucket is read, since its client reads both —\n * and every file server's bucket, which serves it whether or not an app\n * reads it directly.\n */\nexport function workspaceStageKeys(\n\tinput: WorkspaceStageKeysInput,\n): WorkspaceStageKey[] {\n\tconst { manifest } = input;\n\n\t// What each app's environment holds.\n\tconst reads = new Map<string, Set<string>>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\tif (kind !== 'rest-api' && kind !== 'site' && kind !== 'mobile-app') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst name = appKey(id);\n\t\tconst keys = appEnvKeys(manifest, name, input.runnables);\n\t\tif (keys) reads.set(name, keys);\n\t}\n\n\tconst readers = (id: string, kind: string) => {\n\t\tconst keys = keysOf(id, kind);\n\t\treturn [...reads]\n\t\t\t.filter(([, env]) => keys.some((key) => env.has(key)))\n\t\t\t.map(([app]) => app)\n\t\t\t.sort();\n\t};\n\n\tconst services: ServiceDeclaration[] = [];\n\tconst credentials: CredentialDeclaration[] = [];\n\tconst buckets = new Set<string>();\n\tfor (const [id, declaration] of Object.entries(manifest)) {\n\t\tconst { kind } = declaration;\n\t\t// A file server's client reads its bucket's URL and its own, and an\n\t\t// app's edge is to the bucket: whoever reads the bucket reads both.\n\t\tconst apps =\n\t\t\tdeclaration.kind === 'file-server' && declaration.of\n\t\t\t\t? [\n\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t...readers(id, kind),\n\t\t\t\t\t\t\t...readers(declaration.of, 'objects'),\n\t\t\t\t\t\t]),\n\t\t\t\t\t].sort()\n\t\t\t\t: readers(id, kind);\n\t\tif (kind === 'external-api' || kind === 'credential') {\n\t\t\tif (apps.length > 0) credentials.push({ id, kind, apps });\n\t\t\tcontinue;\n\t\t}\n\t\tif (kind !== 'email' && kind !== 'objects' && kind !== 'file-server') {\n\t\t\tcontinue;\n\t\t}\n\t\tif (apps.length === 0) continue;\n\t\tconst of = declaration.kind === 'file-server' ? declaration.of : undefined;\n\t\tservices.push({ id, kind, ...(of ? { of } : {}), apps });\n\t\tif (of) buckets.add(of);\n\t}\n\tfor (const of of buckets) {\n\t\tif (services.some((s) => s.id === of)) continue;\n\t\tif (manifest[of]?.kind !== 'objects') continue;\n\t\tservices.push({ id: of, kind: 'objects', apps: readers(of, 'objects') });\n\t}\n\n\treturn requiredStageKeys({\n\t\tlocal: input.local,\n\t\tservices,\n\t\tcredentials,\n\t\t...(input.domain ? { domain: input.domain } : {}),\n\t}).map((key) => ({ ...key, set: input.supplied[key.key] !== undefined }));\n}\n","/**\n * `gkm secrets:add --stage <stage>` — the secrets a stage must be given,\n * built key by key.\n *\n * It offers exactly the keys a deploy would refuse the stage without\n * (`requiredStageKeys`), across every app in the workspace, each once: the\n * stage's buckets, mail and file servers where it is deployed, and every\n * third party's credentials. A key is built by what it is — a bucket from its\n * provider, mail from its SMTP server, credentials field by field from their\n * construct's schema — checked, and saved through the stage's own store, the\n * one `gkm secrets:set` writes. No value is ever printed.\n *\n * `--json` asks nothing: it prints the keys, for a script or an agent to set\n * with `gkm secrets:set`.\n */\n\nimport {\n\ttype S3Address,\n\tbuild as s3Build,\n\tparse as s3Parse,\n} from '@geekmidas/storage/s3-url';\nimport prompts, { type PromptObject } from 'prompts';\nimport { z } from 'zod';\nimport { loadWorkspaceSettings } from '../config';\nimport { discover } from '../reconcile/discover';\nimport { constructGlobs } from '../reconcile/workspace';\nimport { assertDeployedStage } from '../workspace/stages';\nimport {\n\ttype CredentialSchemaInfo,\n\ttype CredentialSchemas,\n\tissueLine,\n\tloadCredentialSchemas,\n} from './credentialSchemas';\nimport { type WorkspaceStageKey, workspaceStageKeys } from './stageKeys';\nimport { initStageSecrets } from './storage';\nimport { secretsStoreFor } from './store';\n\nexport interface SecretsAddOptions {\n\tstage: string;\n\t/** Only the keys the stage has not set. */\n\tmissing?: boolean;\n\t/** Print the keys as JSON and ask nothing. */\n\tjson?: boolean;\n\t/** The workspace — the current directory when absent. */\n\tcwd?: string;\n\t/** The CLI's home, for a file store's keys. Defaults to `GKM_HOME`. */\n\thome?: string;\n}\n\n/** Where the command writes, and whether there is anyone to ask. */\nexport interface SecretsAddIo {\n\t/** A line for the person at the terminal. */\n\tlog(line: string): void;\n\t/** `--json`'s output. */\n\twrite(chunk: string): void;\n\t/** Whether prompts can be answered. */\n\tinteractive: boolean;\n}\n\n/** What a run of the command came to. */\nexport interface SecretsAddResult {\n\t/** The keys offered. */\n\tkeys: WorkspaceStageKey[];\n\t/** The keys saved, in the order they were built. */\n\tsaved: string[];\n}\n\n/** One key as `--json` prints it. */\nexport interface StageKeyJson {\n\tkey: string;\n\tkind: WorkspaceStageKey['kind'];\n\tconstruct: string;\n\tapps: string[];\n\tset: boolean;\n}\n\n/** `gkm secrets:add` with nobody at a terminal to answer it. */\nexport class SecretsAddNeedsTerminal extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`gkm secrets:add asks for each key, and there is no terminal to ask ` +\n\t\t\t\t`at. List what the stage needs with ` +\n\t\t\t\t`gkm secrets:add --stage ${stage} --missing --json, and set each ` +\n\t\t\t\t`with gkm secrets:set <KEY> <value> --stage ${stage}.`,\n\t\t);\n\t\tthis.name = 'SecretsAddNeedsTerminal';\n\t}\n}\n\n/** The person stopped the builder; nothing was saved. */\nexport class SecretsAddCancelled extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(`Stopped. Nothing was saved to the stage '${stage}'.`);\n\t\tthis.name = 'SecretsAddCancelled';\n\t}\n}\n\nconst defaultIo = (): SecretsAddIo => ({\n\tlog: (line) => console.log(line),\n\twrite: (chunk) => {\n\t\tprocess.stdout.write(chunk);\n\t},\n\tinteractive: process.stdin.isTTY === true && process.stdout.isTTY === true,\n});\n\n/** `gkm secrets:add`. */\nexport async function secretsAddCommand(\n\toptions: SecretsAddOptions,\n\tio: SecretsAddIo = defaultIo(),\n): Promise<SecretsAddResult> {\n\tconst { stage } = options;\n\tconst workspace = await loadWorkspaceSettings(options.cwd ?? process.cwd());\n\tconst local = stage === workspace.stages.local;\n\tif (!local) assertDeployedStage(workspace.stages, stage);\n\n\tconst patterns = constructGlobs(workspace);\n\tconst runnables: Record<string, string[]> = {};\n\tconst manifest = await discover({\n\t\tpatterns,\n\t\tcwd: workspace.root,\n\t\trunnables,\n\t});\n\n\tconst store = await secretsStoreFor(workspace, stage, {\n\t\t...(options.home ? { home: options.home } : {}),\n\t});\n\tconst stored = await store.read(stage);\n\tconst domain = workspace.deploy?.domains?.[stage];\n\n\tconst all = workspaceStageKeys({\n\t\tmanifest,\n\t\trunnables,\n\t\tlocal,\n\t\tsupplied: stored?.custom ?? {},\n\t\t...(domain ? { domain } : {}),\n\t});\n\tconst keys = options.missing ? all.filter((k) => !k.set) : all;\n\n\tif (options.json) {\n\t\tconst listed: StageKeyJson[] = keys.map((k) => ({\n\t\t\tkey: k.key,\n\t\t\tkind: k.kind,\n\t\t\tconstruct: k.id,\n\t\t\tapps: [...(k.apps ?? [])],\n\t\t\tset: k.set,\n\t\t}));\n\t\tio.write(`${JSON.stringify(listed, null, 2)}\\n`);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tif (!io.interactive) throw new SecretsAddNeedsTerminal(stage);\n\n\tif (keys.length === 0) {\n\t\tio.log(\n\t\t\tall.length === 0\n\t\t\t\t? `Nothing to add: no construct on '${stage}' needs a key only the stage can supply.`\n\t\t\t\t: `Nothing to add: the stage '${stage}' has every key it needs.`,\n\t\t);\n\t\treturn { keys, saved: [] };\n\t}\n\n\tconst ask = asker(stage);\n\tconst chosen: string[] = await ask({\n\t\ttype: 'multiselect',\n\t\tmessage: `Which keys for '${stage}'? (${store.name} store)`,\n\t\tchoices: keys.map((k) => ({\n\t\t\ttitle: `${k.key} ${KIND_LABEL[k.kind]} '${k.id}'${k.apps?.length ? ` · ${k.apps.join(', ')}` : ''}${k.set ? ' · set' : ''}`,\n\t\t\tvalue: k.key,\n\t\t\tselected: !k.set,\n\t\t})),\n\t\tinstructions: false,\n\t\thint: 'space to toggle, enter to continue',\n\t});\n\tconst selected = keys.filter((k) => (chosen ?? []).includes(k.key));\n\n\tconst values: Record<string, string> = {};\n\tconst has = (key: string) =>\n\t\tvalues[key] !== undefined || stored?.custom?.[key] !== undefined;\n\tlet schemas: CredentialSchemas | undefined;\n\n\tfor (const entry of selected) {\n\t\tif (entry.set) {\n\t\t\tconst overwrite: boolean = await ask({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: `${entry.key} is set. Replace it?`,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tif (!overwrite) continue;\n\t\t}\n\t\tio.log(`\\n${entry.key} — ${entry.what}`);\n\n\t\tswitch (entry.kind) {\n\t\t\tcase 'bucket':\n\t\t\t\tObject.assign(values, await buildBucket(ask, io, entry, has));\n\t\t\t\tbreak;\n\t\t\tcase 'email':\n\t\t\t\tvalues[entry.key] = entry.key.endsWith('_FROM')\n\t\t\t\t\t? await askFrom(ask, io)\n\t\t\t\t\t: await buildSmtpUrl(ask, io);\n\t\t\t\tbreak;\n\t\t\tcase 'file-server':\n\t\t\t\tvalues[entry.key] = await askHttpUrl(ask, io, 'Its public URL');\n\t\t\t\tbreak;\n\t\t\tcase 'external-api':\n\t\t\tcase 'credential':\n\t\t\t\tschemas ??= await loadCredentialSchemas({\n\t\t\t\t\troot: workspace.root,\n\t\t\t\t\tpatterns,\n\t\t\t\t});\n\t\t\t\tvalues[entry.key] = await buildCredentials(ask, io, entry, schemas);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst saved = Object.keys(values);\n\tif (saved.length === 0) {\n\t\tio.log('\\nNothing was saved.');\n\t\treturn { keys, saved };\n\t}\n\n\tconst base = stored ?? initStageSecrets(stage);\n\tawait store.write(stage, {\n\t\t...base,\n\t\tupdatedAt: new Date().toISOString(),\n\t\tcustom: { ...base.custom, ...values },\n\t});\n\tio.log(\n\t\t`\\n✓ Saved ${saved.join(', ')} to the stage '${stage}' (${store.name} store).`,\n\t);\n\treturn { keys, saved };\n}\n\nconst KIND_LABEL: Record<WorkspaceStageKey['kind'], string> = {\n\tbucket: 'bucket',\n\temail: 'email',\n\t'file-server': 'file server',\n\t'external-api': 'external API',\n\tcredential: 'credential',\n};\n\n/** One question, answered — or the run stopped. */\ntype Ask = <T = string>(question: Omit<PromptObject, 'name'>) => Promise<T>;\n\nfunction asker(stage: string): Ask {\n\treturn async <T>(question: Omit<PromptObject, 'name'>) => {\n\t\tconst answers = await prompts(\n\t\t\t{ ...question, name: 'value' } as PromptObject,\n\t\t\t{\n\t\t\t\tonCancel: () => {\n\t\t\t\t\tthrow new SecretsAddCancelled(stage);\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t\treturn answers.value as T;\n\t};\n}\n\n/** Ask until `accept` takes the answer; `accept` returns why it did not. */\nasync function askUntil<T>(\n\task: Ask,\n\tio: SecretsAddIo,\n\tquestion: Omit<PromptObject, 'name'>,\n\taccept: (value: T) => string | undefined,\n): Promise<T> {\n\tfor (;;) {\n\t\tconst value = await ask<T>(question);\n\t\tconst problem = accept(value);\n\t\tif (!problem) return value;\n\t\tio.log(` ✗ ${problem}`);\n\t}\n}\n\nconst required =\n\t(what: string) =>\n\t(value: string | undefined): string | undefined =>\n\t\tvalue?.trim() ? undefined : `${what} is required.`;\n\nconst text = (value: unknown) => String(value ?? '').trim();\n\n/** An `http(s)://` URL. */\nconst HttpUrl = z.url({ protocol: /^https?$/ });\n\nasync function askHttpUrl(\n\task: Ask,\n\tio: SecretsAddIo,\n\tmessage: string,\n): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(ask, io, { type: 'text', message }, (value) =>\n\t\t\tHttpUrl.safeParse(text(value)).success\n\t\t\t\t? undefined\n\t\t\t\t: 'An http:// or https:// URL is required.',\n\t\t),\n\t);\n}\n\nasync function askFrom(ask: Ask, io: SecretsAddIo): Promise<string> {\n\treturn text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'The address it sends from' },\n\t\t\t(value) =>\n\t\t\t\tz.email().safeParse(text(value)).success\n\t\t\t\t\t? undefined\n\t\t\t\t\t: 'An email address is required, e.g. noreply@example.com.',\n\t\t),\n\t);\n}\n\n/**\n * An SMTP server as the URL `@geekmidas/emailkit` reads: `smtp://` for\n * STARTTLS, `smtps://` for TLS from the first byte, with the user and\n * password percent-encoded.\n */\nasync function buildSmtpUrl(ask: Ask, io: SecretsAddIo): Promise<string> {\n\tconst host = text(\n\t\tawait askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{ type: 'text', message: 'SMTP host' },\n\t\t\trequired('The host'),\n\t\t),\n\t);\n\tconst port = await askUntil<string | number>(\n\t\task,\n\t\tio,\n\t\t{ type: 'text', message: 'Port', initial: '587' },\n\t\t(value) => {\n\t\t\tconst n = Number(value);\n\t\t\treturn Number.isInteger(n) && n > 0 && n < 65536\n\t\t\t\t? undefined\n\t\t\t\t: 'A port number is required.';\n\t\t},\n\t);\n\tconst user = text(\n\t\tawait ask<string>({ type: 'text', message: 'User (empty for none)' }),\n\t);\n\tconst password = user\n\t\t? await ask<string>({ type: 'password', message: 'Password' })\n\t\t: '';\n\tconst tls = await ask<'starttls' | 'tls'>({\n\t\ttype: 'select',\n\t\tmessage: 'TLS',\n\t\tchoices: [\n\t\t\t{ title: 'STARTTLS (smtp://, usually port 587)', value: 'starttls' },\n\t\t\t{ title: 'TLS on connect (smtps://, usually port 465)', value: 'tls' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst url = new URL(`${tls === 'tls' ? 'smtps' : 'smtp'}://${host}`);\n\turl.port = String(Number(port));\n\tif (user) {\n\t\turl.username = encodeURIComponent(user);\n\t\turl.password = encodeURIComponent(password ?? '');\n\t}\n\treturn url.toString().replace(/\\/$/, '');\n}\n\n/**\n * A bucket's URL, from its provider — and, optionally, a key for it alone in\n * the URL, or the stage's shared pair. Credentials are never required: without\n * them the SDK's own chain signs, a role included.\n */\nasync function buildBucket(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\thas: (key: string) => boolean,\n): Promise<Record<string, string>> {\n\tconst provider = await ask<'s3' | 'r2' | 'compatible' | 'url'>({\n\t\ttype: 'select',\n\t\tmessage: 'Where is the bucket?',\n\t\tchoices: [\n\t\t\t{ title: 'AWS S3', value: 's3' },\n\t\t\t{ title: 'Cloudflare R2', value: 'r2' },\n\t\t\t{ title: 'MinIO, or another S3-compatible store', value: 'compatible' },\n\t\t\t{ title: 'Paste an s3:// URL', value: 'url' },\n\t\t],\n\t\tinitial: 0,\n\t});\n\n\tconst bucketName = async () =>\n\t\ttext(\n\t\t\tawait askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'text', message: 'Bucket name' },\n\t\t\t\trequired('The bucket name'),\n\t\t\t),\n\t\t);\n\n\tlet address: S3Address;\n\tswitch (provider) {\n\t\tcase 's3': {\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Region', initial: 'eu-west-1' },\n\t\t\t\t\trequired('The region'),\n\t\t\t\t),\n\t\t\t);\n\t\t\taddress = { bucket, region };\n\t\t\tbreak;\n\t\t}\n\t\tcase 'r2': {\n\t\t\tconst account = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\tmessage: 'Cloudflare account id, or the R2 endpoint URL',\n\t\t\t\t\t},\n\t\t\t\t\trequired('The account id or endpoint'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst bucket = await bucketName();\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\tregion: 'auto',\n\t\t\t\tendpoint: /^https?:\\/\\//.test(account)\n\t\t\t\t\t? account\n\t\t\t\t\t: `https://${account}.r2.cloudflarestorage.com`,\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'compatible': {\n\t\t\tconst endpoint = await askHttpUrl(ask, io, 'Endpoint URL');\n\t\t\tconst bucket = await bucketName();\n\t\t\tconst region = text(\n\t\t\t\tawait ask<string>({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tmessage: 'Region',\n\t\t\t\t\tinitial: 'us-east-1',\n\t\t\t\t}),\n\t\t\t);\n\t\t\tconst forcePathStyle = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: 'Path-style addressing? (MinIO needs it)',\n\t\t\t\tinitial: true,\n\t\t\t});\n\t\t\taddress = {\n\t\t\t\tbucket,\n\t\t\t\t...(region ? { region } : {}),\n\t\t\t\tendpoint,\n\t\t\t\t...(forcePathStyle ? { forcePathStyle } : {}),\n\t\t\t};\n\t\t\tbreak;\n\t\t}\n\t\tcase 'url': {\n\t\t\tconst pasted = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'The s3:// URL' },\n\t\t\t\t(value) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ts3Parse(text(value));\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn `Not an s3:// URL the storage client can read (${(error as Error).name}).`;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t\taddress = s3Parse(text(pasted));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!address.accessKeyId) {\n\t\tconst own = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage: `A key for '${entry.id}' alone, in its URL? (optional)`,\n\t\t\tinitial: false,\n\t\t});\n\t\tif (own) {\n\t\t\tconst accessKeyId = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'Access key id' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst secretAccessKey = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'Secret access key' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t\taddress = { ...address, accessKeyId, secretAccessKey };\n\t\t}\n\t}\n\n\tconst values: Record<string, string> = { [entry.key]: s3Build(address) };\n\n\tif (!address.accessKeyId && !has('AWS_ACCESS_KEY_ID')) {\n\t\tconst shared = await ask<boolean>({\n\t\t\ttype: 'confirm',\n\t\t\tmessage:\n\t\t\t\t\"Set the stage's shared AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY? \" +\n\t\t\t\t'(optional: without them a role signs)',\n\t\t\tinitial: false,\n\t\t});\n\t\tif (shared) {\n\t\t\tvalues.AWS_ACCESS_KEY_ID = text(\n\t\t\t\tawait askUntil<string>(\n\t\t\t\t\task,\n\t\t\t\t\tio,\n\t\t\t\t\t{ type: 'text', message: 'AWS_ACCESS_KEY_ID' },\n\t\t\t\t\trequired('The access key id'),\n\t\t\t\t),\n\t\t\t);\n\t\t\tvalues.AWS_SECRET_ACCESS_KEY = await askUntil<string>(\n\t\t\t\task,\n\t\t\t\tio,\n\t\t\t\t{ type: 'password', message: 'AWS_SECRET_ACCESS_KEY' },\n\t\t\t\trequired('The secret access key'),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn values;\n}\n\n/** A field whose name says it is a secret, asked for without echo. */\nconst SECRET_FIELD = /secret|key|token|password/i;\n\ninterface JsonSchemaProperty {\n\ttype?: string | string[];\n\tenum?: unknown[];\n\tdescription?: string;\n}\n\n/** The properties of an object schema, or nothing for any other shape. */\nfunction objectProperties(\n\tinfo: CredentialSchemaInfo | undefined,\n):\n\t| { properties: Record<string, JsonSchemaProperty>; required: string[] }\n\t| undefined {\n\tconst schema = info?.jsonSchema;\n\tif (!schema || schema.type !== 'object') return undefined;\n\tconst properties = schema.properties;\n\tif (!properties || typeof properties !== 'object') return undefined;\n\treturn {\n\t\tproperties: properties as Record<string, JsonSchemaProperty>,\n\t\trequired: Array.isArray(schema.required)\n\t\t\t? (schema.required as string[])\n\t\t\t: [],\n\t};\n}\n\nfunction typesOf(property: JsonSchemaProperty): string[] {\n\tif (Array.isArray(property.type)) return property.type;\n\treturn property.type ? [property.type] : [];\n}\n\n/**\n * Credentials, field by field where the construct's schema is an object it\n * can describe, and as JSON otherwise — checked against the schema itself\n * before anything is kept, and asked again, with each issue's path, until\n * the schema takes it.\n */\nasync function buildCredentials(\n\task: Ask,\n\tio: SecretsAddIo,\n\tentry: WorkspaceStageKey,\n\tschemas: CredentialSchemas,\n): Promise<string> {\n\tconst info = schemas.schemas.find((s) => s.key === entry.key);\n\tconst shape = objectProperties(info);\n\tif (!info) {\n\t\tio.log(\n\t\t\t` '${entry.id}' exposes no schema to check against; the value is stored as given.`,\n\t\t);\n\t}\n\n\tfor (;;) {\n\t\tconst raw = shape\n\t\t\t? JSON.stringify(await askFields(ask, io, shape))\n\t\t\t: text(\n\t\t\t\t\tawait ask<string>({\n\t\t\t\t\t\ttype: 'password',\n\t\t\t\t\t\tmessage: 'The value, as JSON (or one opaque string)',\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\tconst check = await schemas.check(entry.key, raw);\n\t\tif (check.ok) return raw;\n\t\tio.log(` ✗ The schema of '${entry.id}' refuses it:`);\n\t\tfor (const issue of check.issues) {\n\t\t\tio.log(` ${issueLine(entry.key, issue)}`);\n\t\t}\n\t\tio.log(' Again:');\n\t}\n}\n\nasync function askFields(\n\task: Ask,\n\tio: SecretsAddIo,\n\tshape: {\n\t\tproperties: Record<string, JsonSchemaProperty>;\n\t\trequired: string[];\n\t},\n): Promise<Record<string, unknown>> {\n\tconst value: Record<string, unknown> = {};\n\tfor (const [name, property] of Object.entries(shape.properties)) {\n\t\tconst optional = !shape.required.includes(name);\n\t\tconst label = `${name}${optional ? ' (optional)' : ''}${property.description ? ` — ${property.description}` : ''}`;\n\t\tconst types = typesOf(property);\n\n\t\tif (property.enum?.length) {\n\t\t\tconst choices = property.enum.map((option) => ({\n\t\t\t\ttitle: String(option),\n\t\t\t\tvalue: option,\n\t\t\t}));\n\t\t\tconst picked = await ask<unknown>({\n\t\t\t\ttype: 'select',\n\t\t\t\tmessage: label,\n\t\t\t\tchoices: optional\n\t\t\t\t\t? [{ title: '(none)', value: undefined }, ...choices]\n\t\t\t\t\t: choices,\n\t\t\t} as Omit<PromptObject, 'name'>);\n\t\t\tif (picked !== undefined) value[name] = picked;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (types.includes('boolean')) {\n\t\t\tvalue[name] = await ask<boolean>({\n\t\t\t\ttype: 'confirm',\n\t\t\t\tmessage: label,\n\t\t\t\tinitial: false,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst numeric = types.includes('number') || types.includes('integer');\n\t\tconst plain = types.length === 0 || types.includes('string');\n\t\tconst answer = await askUntil<string>(\n\t\t\task,\n\t\t\tio,\n\t\t\t{\n\t\t\t\ttype: SECRET_FIELD.test(name) ? 'password' : 'text',\n\t\t\t\tmessage: label,\n\t\t\t},\n\t\t\t(given) => {\n\t\t\t\tconst typed = text(given);\n\t\t\t\tif (!typed) return optional ? undefined : `${name} is required.`;\n\t\t\t\tif (numeric && !plain && Number.isNaN(Number(typed))) {\n\t\t\t\t\treturn `${name} is a number.`;\n\t\t\t\t}\n\t\t\t\tif (!numeric && !plain) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tJSON.parse(typed);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn `${name} is JSON (${types.join(' or ')}).`;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t);\n\t\tconst typed = text(answer);\n\t\tif (!typed) continue;\n\t\tvalue[name] = plain ? typed : numeric ? Number(typed) : JSON.parse(typed);\n\t}\n\treturn value;\n}\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
1
2
  import { n as serializeWithin, t as awsClientConfig } from "./awsStore-B529csle.mjs";
2
3
  import { GetParameterCommand, ParameterNotFound, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
3
4
  //#region src/secrets/aws.ts
@@ -16,6 +17,11 @@ import { GetParameterCommand, ParameterNotFound, PutParameterCommand, SSMClient
16
17
  * the write is refused with {@link StageSecretsTooLarge} before AWS is
17
18
  * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.
18
19
  */
20
+ var aws_exports = /* @__PURE__ */ __exportAll({
21
+ AwsSecretsStore: () => AwsSecretsStore,
22
+ SSM_PARAMETER_LIMIT: () => SSM_PARAMETER_LIMIT,
23
+ secretsParameterName: () => secretsParameterName
24
+ });
19
25
  /** The most an SSM parameter holds: 8 KB, in the advanced tier. */
20
26
  const SSM_PARAMETER_LIMIT = 8192;
21
27
  /** The parameter a stage's secrets are kept in. */
@@ -60,6 +66,6 @@ var AwsSecretsStore = class {
60
66
  }
61
67
  };
62
68
  //#endregion
63
- export { AwsSecretsStore };
69
+ export { secretsParameterName as n, aws_exports as t };
64
70
 
65
- //# sourceMappingURL=aws-Bja4zGSs.mjs.map
71
+ //# sourceMappingURL=aws-B-6uEhgP.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"aws-Bja4zGSs.mjs","names":[],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await ssm.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait ssm.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\tValue: value,\n\t\t\t\tType: 'SecureString',\n\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAI,UAAU,MAAM,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;CAEA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,IAAI,KAC/B,IAAI,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiB,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;CAEA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQ,gBACb,OACA,KAAK,MACL,SACA,mBACD;EAGA,OAAM,MAFY,KAAK,IAAI,EAAA,CAEjB,KACT,IAAI,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF;CACD;AACD"}
1
+ {"version":3,"file":"aws-B-6uEhgP.mjs","names":[],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await ssm.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait ssm.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\tValue: value,\n\t\t\t\tType: 'SecureString',\n\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAI,UAAU,MAAM,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;CAEA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,IAAI,KAC/B,IAAI,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiB,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;CAEA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQ,gBACb,OACA,KAAK,MACL,SACA,mBACD;EAGA,OAAM,MAFY,KAAK,IAAI,EAAA,CAEjB,KACT,IAAI,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF;CACD;AACD"}
@@ -1,3 +1,4 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
1
2
  const require_awsStore = require("./awsStore-7VmS_cZR.cjs");
2
3
  let _aws_sdk_client_ssm = require("@aws-sdk/client-ssm");
3
4
  //#region src/secrets/aws.ts
@@ -16,6 +17,11 @@ let _aws_sdk_client_ssm = require("@aws-sdk/client-ssm");
16
17
  * the write is refused with {@link StageSecretsTooLarge} before AWS is
17
18
  * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.
18
19
  */
20
+ var aws_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({
21
+ AwsSecretsStore: () => AwsSecretsStore,
22
+ SSM_PARAMETER_LIMIT: () => SSM_PARAMETER_LIMIT,
23
+ secretsParameterName: () => secretsParameterName
24
+ });
19
25
  /** The most an SSM parameter holds: 8 KB, in the advanced tier. */
20
26
  const SSM_PARAMETER_LIMIT = 8192;
21
27
  /** The parameter a stage's secrets are kept in. */
@@ -60,6 +66,17 @@ var AwsSecretsStore = class {
60
66
  }
61
67
  };
62
68
  //#endregion
63
- exports.AwsSecretsStore = AwsSecretsStore;
69
+ Object.defineProperty(exports, "aws_exports", {
70
+ enumerable: true,
71
+ get: function() {
72
+ return aws_exports;
73
+ }
74
+ });
75
+ Object.defineProperty(exports, "secretsParameterName", {
76
+ enumerable: true,
77
+ get: function() {
78
+ return secretsParameterName;
79
+ }
80
+ });
64
81
 
65
- //# sourceMappingURL=aws-CQAuluiu.cjs.map
82
+ //# sourceMappingURL=aws-BTawF0F-.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"aws-CQAuluiu.cjs","names":["SSMClient","awsClientConfig","GetParameterCommand","ParameterNotFound","serializeWithin","PutParameterCommand"],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await ssm.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait ssm.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\tValue: value,\n\t\t\t\tType: 'SecureString',\n\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAIA,oBAAAA,UAAU,MAAMC,iBAAAA,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;CAEA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,IAAI,KAC/B,IAAIC,oBAAAA,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiBC,oBAAAA,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;CAEA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQC,iBAAAA,gBACb,OACA,KAAK,MACL,SACA,mBACD;EAGA,OAAM,MAFY,KAAK,IAAI,EAAA,CAEjB,KACT,IAAIC,oBAAAA,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF;CACD;AACD"}
1
+ {"version":3,"file":"aws-BTawF0F-.cjs","names":["SSMClient","awsClientConfig","GetParameterCommand","ParameterNotFound","serializeWithin","PutParameterCommand"],"sources":["../src/secrets/aws.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n *\n * Written in the Intelligent-Tiering tier: a stage under 4 KB stays a free\n * standard parameter, a larger one becomes advanced (up to 8 KB). Past 8 KB\n * the write is refused with {@link StageSecretsTooLarge} before AWS is\n * called; Secrets Manager (`secretsManager.ts`) holds up to 64 KB.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n} from '@aws-sdk/client-ssm';\nimport {\n\ttype AwsStoreOptions,\n\tawsClientConfig,\n\tserializeWithin,\n} from './awsStore.js';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport type AwsSecretsStoreOptions = AwsStoreOptions;\n\n/** The most an SSM parameter holds: 8 KB, in the advanced tier. */\nexport const SSM_PARAMETER_LIMIT = 8 * 1024;\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class AwsSecretsStore implements SecretsStore {\n\treadonly name = 'ssm';\n\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: AwsSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tthis.client = new SSMClient(await awsClientConfig(this.options));\n\t\treturn this.client;\n\t}\n\n\tasync read(stage: string): Promise<StageSecrets | null> {\n\t\tconst ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await ssm.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync write(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst value = serializeWithin(\n\t\t\tstage,\n\t\t\tthis.name,\n\t\t\tsecrets,\n\t\t\tSSM_PARAMETER_LIMIT,\n\t\t);\n\t\tconst ssm = await this.ssm();\n\n\t\tawait ssm.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\tValue: value,\n\t\t\t\tType: 'SecureString',\n\t\t\t\t// Standard (free) under 4 KB, advanced past it; never the other way.\n\t\t\t\tTier: 'Intelligent-Tiering',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,sBAAsB;;AAGnC,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAKvB;CAJ7B,OAAgB;CAEhB;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,KAAK,SAAS,IAAIA,oBAAAA,UAAU,MAAMC,iBAAAA,gBAAgB,KAAK,OAAO,CAAC;EAC/D,OAAO,KAAK;CACb;CAEA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,IAAI,KAC/B,IAAIC,oBAAAA,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiBC,oBAAAA,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;CAEA,MAAM,MAAM,OAAe,SAAsC;EAChE,MAAM,QAAQC,iBAAAA,gBACb,OACA,KAAK,MACL,SACA,mBACD;EAGA,OAAM,MAFY,KAAK,IAAI,EAAA,CAEjB,KACT,IAAIC,oBAAAA,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO;GACP,MAAM;GAEN,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF;CACD;AACD"}
@@ -82,8 +82,8 @@ async function bundleServer(options) {
82
82
  for (const ext of external) args.push(`--external:${ext}`);
83
83
  let masterKey;
84
84
  if (stage) {
85
- const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await Promise.resolve().then(() => require("./stale-BsiPJI7Y.cjs")).then((n) => n.storage_exports);
86
- const { FileSecretsStore, secretsStoreFor } = await Promise.resolve().then(() => require("./stale-BsiPJI7Y.cjs")).then((n) => n.store_exports);
85
+ const { toEmbeddableSecrets, validateEnvironmentVariables, initStageSecrets } = await Promise.resolve().then(() => require("./seeds-ZljwYV_p.cjs")).then((n) => n.storage_exports);
86
+ const { FileSecretsStore, secretsStoreFor } = await Promise.resolve().then(() => require("./seeds-ZljwYV_p.cjs")).then((n) => n.store_exports);
87
87
  const { ConfigNotFound, loadWorkspaceSettings } = await Promise.resolve().then(() => require("./config.cjs"));
88
88
  const { encryptSecrets, generateDefineOptions } = await Promise.resolve().then(() => require("./sniffer-BjG-1mlD.cjs")).then((n) => n.encryption_exports);
89
89
  const store = await loadWorkspaceSettings().then((workspace) => secretsStoreFor(workspace, stage), (error) => {
@@ -166,4 +166,4 @@ async function bundleServer(options) {
166
166
  //#endregion
167
167
  exports.bundleServer = bundleServer;
168
168
 
169
- //# sourceMappingURL=bundler-C6T-1OLT.cjs.map
169
+ //# sourceMappingURL=bundler-BlbSLFLn.cjs.map