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

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 (117) hide show
  1. package/dist/{add-BvOICikp.cjs → add-HF9POevk.cjs} +7 -7
  2. package/dist/{add-BvOICikp.cjs.map → add-HF9POevk.cjs.map} +1 -1
  3. package/dist/{add-D2XKszYP.mjs → add-UFiIrlTj.mjs} +2 -2
  4. package/dist/{add-D2XKszYP.mjs.map → add-UFiIrlTj.mjs.map} +1 -1
  5. package/dist/{bundler-CtHzKqnZ.mjs → bundler-C45BuRdY.mjs} +3 -3
  6. package/dist/{bundler-CtHzKqnZ.mjs.map → bundler-C45BuRdY.mjs.map} +1 -1
  7. package/dist/{bundler-C6T-1OLT.cjs → bundler-RAoSRuvp.cjs} +3 -3
  8. package/dist/{bundler-C6T-1OLT.cjs.map → bundler-RAoSRuvp.cjs.map} +1 -1
  9. package/dist/{cli-K6Vj_pPW.cjs → cli-C3hsEwLK.cjs} +4 -4
  10. package/dist/{cli-K6Vj_pPW.cjs.map → cli-C3hsEwLK.cjs.map} +1 -1
  11. package/dist/{cli-BgPyhx1i.mjs → cli-gvc3urUl.mjs} +3 -3
  12. package/dist/{cli-BgPyhx1i.mjs.map → cli-gvc3urUl.mjs.map} +1 -1
  13. package/dist/{compose-DByK353T.mjs → compose-C40Wk9m6.mjs} +36 -8
  14. package/dist/{compose-DByK353T.mjs.map → compose-C40Wk9m6.mjs.map} +1 -1
  15. package/dist/{compose-B7MC19eC.cjs → compose-CtUP07r3.cjs} +88 -60
  16. package/dist/{compose-B7MC19eC.cjs.map → compose-CtUP07r3.cjs.map} +1 -1
  17. package/dist/{config-Bql0AmJt.d.mts → config-L_6NivCp.d.mts} +3 -3
  18. package/dist/{config-Bql0AmJt.d.mts.map → config-L_6NivCp.d.mts.map} +1 -1
  19. package/dist/{config-DlNpHK8p.d.cts → config-Mr4rcXFC.d.cts} +3 -3
  20. package/dist/{config-DlNpHK8p.d.cts.map → config-Mr4rcXFC.d.cts.map} +1 -1
  21. package/dist/config.d.cts +3 -3
  22. package/dist/config.d.mts +3 -3
  23. package/dist/{databases-C2p5LGAp.cjs → databases-BY-pEImp.cjs} +185 -7
  24. package/dist/databases-BY-pEImp.cjs.map +1 -0
  25. package/dist/{databases-hUHTuwhx.mjs → databases-CzszQV0N.mjs} +153 -5
  26. package/dist/databases-CzszQV0N.mjs.map +1 -0
  27. package/dist/deploy/public.cjs +12 -11
  28. package/dist/deploy/public.d.cts +19 -3
  29. package/dist/deploy/public.d.cts.map +1 -1
  30. package/dist/deploy/public.d.mts +19 -3
  31. package/dist/deploy/public.d.mts.map +1 -1
  32. package/dist/deploy/public.mjs +6 -6
  33. package/dist/{deploy-BerP7ppB.mjs → deploy-BjsZpUQ3.mjs} +3 -3
  34. package/dist/{deploy-BerP7ppB.mjs.map → deploy-BjsZpUQ3.mjs.map} +1 -1
  35. package/dist/{deploy-Dt42xiQA.cjs → deploy-DPzauQsm.cjs} +9 -9
  36. package/dist/{deploy-Dt42xiQA.cjs.map → deploy-DPzauQsm.cjs.map} +1 -1
  37. package/dist/{dokploy-ssZQRK2C.mjs → dokploy-BoH0DMyS.mjs} +2 -2
  38. package/dist/{dokploy-ssZQRK2C.mjs.map → dokploy-BoH0DMyS.mjs.map} +1 -1
  39. package/dist/{dokploy-NG9UrVrP.cjs → dokploy-Cj1EHd4Y.cjs} +2 -2
  40. package/dist/{dokploy-NG9UrVrP.cjs.map → dokploy-Cj1EHd4Y.cjs.map} +1 -1
  41. package/dist/{encryption-CbMI24fI.cjs → encryption-D2z16vsS.cjs} +5 -5
  42. package/dist/{encryption-CbMI24fI.cjs.map → encryption-D2z16vsS.cjs.map} +1 -1
  43. package/dist/{encryption-De6MN0O5.mjs → encryption-MeDrE-rZ.mjs} +2 -2
  44. package/dist/{encryption-De6MN0O5.mjs.map → encryption-MeDrE-rZ.mjs.map} +1 -1
  45. package/dist/{engine-DOjGIgl4.mjs → engine-B-Yq0yQu.mjs} +53 -17
  46. package/dist/engine-B-Yq0yQu.mjs.map +1 -0
  47. package/dist/{engine-CoCsNoW_.cjs → engine-C3T39eTO.cjs} +118 -82
  48. package/dist/engine-C3T39eTO.cjs.map +1 -0
  49. package/dist/{github-D9vGqdLk.cjs → github-B8dDa8xf.cjs} +6 -6
  50. package/dist/{github-D9vGqdLk.cjs.map → github-B8dDa8xf.cjs.map} +1 -1
  51. package/dist/{github-CwX9z89E.mjs → github-Dyrjo0xd.mjs} +2 -2
  52. package/dist/{github-CwX9z89E.mjs.map → github-Dyrjo0xd.mjs.map} +1 -1
  53. package/dist/{index-BXO0vlme.d.mts → index-C0UmP_lg.d.mts} +2 -2
  54. package/dist/{index-BXO0vlme.d.mts.map → index-C0UmP_lg.d.mts.map} +1 -1
  55. package/dist/{index-Rs0Fua-q.d.cts → index-DTEPwLml.d.cts} +2 -2
  56. package/dist/{index-Rs0Fua-q.d.cts.map → index-DTEPwLml.d.cts.map} +1 -1
  57. package/dist/index.cjs +114 -114
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.mjs +41 -41
  60. package/dist/index.mjs.map +1 -1
  61. package/dist/{migrate-CNKaQl3K.mjs → migrate-A2CLFl9G.mjs} +3 -4
  62. package/dist/{migrate-CNKaQl3K.mjs.map → migrate-A2CLFl9G.mjs.map} +1 -1
  63. package/dist/{migrate-Cgoy58Sh.cjs → migrate-CTqICj1B.cjs} +8 -9
  64. package/dist/{migrate-Cgoy58Sh.cjs.map → migrate-CTqICj1B.cjs.map} +1 -1
  65. package/dist/{migrate-BQ4wVKq_.mjs → migrate-DWUbYY5r.mjs} +2 -2
  66. package/dist/{migrate-BQ4wVKq_.mjs.map → migrate-DWUbYY5r.mjs.map} +1 -1
  67. package/dist/{migrate-B4GBvCNY.cjs → migrate-DvIAITiG.cjs} +4 -4
  68. package/dist/{migrate-B4GBvCNY.cjs.map → migrate-DvIAITiG.cjs.map} +1 -1
  69. package/dist/openapi.d.cts +1 -1
  70. package/dist/openapi.d.mts +1 -1
  71. package/dist/reconcile/public.d.cts +1 -1
  72. package/dist/reconcile/public.d.mts +1 -1
  73. package/dist/{resolve-mvaystiE.mjs → resolve-CHwetPdo.mjs} +3 -3
  74. package/dist/{resolve-mvaystiE.mjs.map → resolve-CHwetPdo.mjs.map} +1 -1
  75. package/dist/{resolve-CEaqRBzY.cjs → resolve-DOXcAOcn.cjs} +3 -3
  76. package/dist/{resolve-CEaqRBzY.cjs.map → resolve-DOXcAOcn.cjs.map} +1 -1
  77. package/dist/{rollback-S2C-Y9pB.mjs → rollback-Cq5s3WnD.mjs} +3 -3
  78. package/dist/{rollback-S2C-Y9pB.mjs.map → rollback-Cq5s3WnD.mjs.map} +1 -1
  79. package/dist/{rollback-F3P-rA-r.cjs → rollback-DUoOaws3.cjs} +5 -5
  80. package/dist/{rollback-F3P-rA-r.cjs.map → rollback-DUoOaws3.cjs.map} +1 -1
  81. package/dist/{runtime-D9AxGzrw.d.cts → runtime-D6A-C6zh.d.cts} +2 -2
  82. package/dist/{runtime-D9AxGzrw.d.cts.map → runtime-D6A-C6zh.d.cts.map} +1 -1
  83. package/dist/{runtime-Dflki3Vs.d.mts → runtime-ekxfPNM-.d.mts} +2 -2
  84. package/dist/{runtime-Dflki3Vs.d.mts.map → runtime-ekxfPNM-.d.mts.map} +1 -1
  85. package/dist/sandbox/migrate-worker.cjs +22 -8
  86. package/dist/sandbox/migrate-worker.cjs.map +1 -1
  87. package/dist/sandbox/migrate-worker.mjs +22 -8
  88. package/dist/sandbox/migrate-worker.mjs.map +1 -1
  89. package/dist/{stale-C5FqIVc8.mjs → seeds-DiXON7R8.mjs} +61 -3
  90. package/dist/seeds-DiXON7R8.mjs.map +1 -0
  91. package/dist/{stale-BsiPJI7Y.cjs → seeds-qX13ubmO.cjs} +78 -2
  92. package/dist/seeds-qX13ubmO.cjs.map +1 -0
  93. package/dist/sniffer-BjG-1mlD.cjs.map +1 -1
  94. package/dist/sniffer-ByWtH28i.mjs.map +1 -1
  95. package/dist/target/public.cjs +1 -1
  96. package/dist/target/public.d.cts +2 -2
  97. package/dist/target/public.d.mts +2 -2
  98. package/dist/target/public.mjs +1 -1
  99. package/dist/{types-DKxkXsKC.d.mts → types-BzCavjGt.d.mts} +29 -2
  100. package/dist/types-BzCavjGt.d.mts.map +1 -0
  101. package/dist/{types-ByY0zi3n.d.cts → types-DZtj9jeI.d.cts} +29 -2
  102. package/dist/types-DZtj9jeI.d.cts.map +1 -0
  103. package/dist/workspace/index.d.cts +2 -2
  104. package/dist/workspace/index.d.mts +2 -2
  105. package/package.json +15 -15
  106. package/dist/databases-C2p5LGAp.cjs.map +0 -1
  107. package/dist/databases-hUHTuwhx.mjs.map +0 -1
  108. package/dist/engine-CoCsNoW_.cjs.map +0 -1
  109. package/dist/engine-DOjGIgl4.mjs.map +0 -1
  110. package/dist/provider-B3Sv_a74.cjs +0 -173
  111. package/dist/provider-B3Sv_a74.cjs.map +0 -1
  112. package/dist/provider-D7rQzzzf.mjs +0 -138
  113. package/dist/provider-D7rQzzzf.mjs.map +0 -1
  114. package/dist/stale-BsiPJI7Y.cjs.map +0 -1
  115. package/dist/stale-C5FqIVc8.mjs.map +0 -1
  116. package/dist/types-ByY0zi3n.d.cts.map +0 -1
  117. package/dist/types-DKxkXsKC.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-CEaqRBzY.cjs","names":["join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst implementation = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\n}\n","/**\n * From a target's name to the target.\n *\n * In this order, the first that has the name wins:\n *\n * 1. the host's own targets — what a program calling `deploy()` passes\n * 2. the built-ins — `dokploy`, `compose`, `sst`\n * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either\n * with options\n *\n * Built-ins come before the config so that a dependency cannot take over\n * `dokploy` by being listed under its name. A name nothing has is\n * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a\n * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody\n * has claimed can be claimed by anyone, and a deploy would then run their\n * code with the stage's credentials. A target is installed and named.\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tDeployTargetNotYetSupported,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { isDeployTarget } from './define';\nimport { importPackage } from './package';\nimport { declaredRuntime } from './runtime';\nimport type {\n\tAnyDeployTarget,\n\tDeployRuntime,\n\tDeployTargetEntry,\n\tTargetOptionsIssue,\n} from './types';\n\n/** Where a target came from. */\nexport type TargetSourceKind = 'host' | 'builtin' | 'config';\n\nexport interface ResolvedTarget {\n\t/** The name it was asked for by. */\n\tname: string;\n\ttarget: AnyDeployTarget;\n\tsource: TargetSourceKind;\n\t/** Its options as written in the config, before its schema parsed them. */\n\toptions: unknown;\n}\n\nexport interface ResolveTargetOptions {\n\t/** The workspace whose `deploy.targets` is consulted. */\n\tworkspace: {\n\t\troot: string;\n\t\tdeploy?: { targets?: Record<string, DeployTargetEntry> } | undefined;\n\t};\n\t/** The host's targets, consulted first. */\n\thost?: Record<string, AnyDeployTarget>;\n\t/** The stage being deployed, for what to do instead of a refused target. */\n\tstage: string;\n}\n\n/** A target package whose default export is not a target. */\nexport class TargetPackageInvalid extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names \"${packageName}\", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`,\n\t\t);\n\t\tthis.name = 'TargetPackageInvalid';\n\t}\n}\n\n/** A `deploy.targets` entry that is not a target, a package name or a pair. */\nexport class TargetEntryInvalid extends Error {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`,\n\t\t);\n\t\tthis.name = 'TargetEntryInvalid';\n\t}\n}\n\n/** A target whose `runtime` is not the one its package declares. */\nexport class TargetRuntimeMismatch extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly declared: DeployRuntime,\n\t\treadonly actual: DeployRuntime,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" runs on \"${actual}\", but ${packageName}'s package.json declares gkm.runtime \"${declared}\". gkm dev and gkm build chose backends for \"${declared}\", so the two must agree — fix the package.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeMismatch';\n\t}\n}\n\n/** Options a target's schema rejected. */\nexport class InvalidTargetOptions extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly issues: readonly TargetOptionsIssue[],\n\t) {\n\t\tconst lines = issues.map((issue) => {\n\t\t\tconst path = (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.');\n\t\t\treturn ` - ${path ? `${path}: ` : ''}${issue.message}`;\n\t\t});\n\t\tsuper(\n\t\t\t`The options for deploy target \"${target}\" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\\n${lines.join('\\n')}`,\n\t\t);\n\t\tthis.name = 'InvalidTargetOptions';\n\t}\n}\n\n/** The built-ins `gkm deploy` deploys through, loaded only when used. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<AnyDeployTarget>> = {\n\tdokploy: async () => (await import('./dokploy')).dokployTarget,\n\tcompose: async () => (await import('./compose/index')).composeTarget(),\n\tsst: async () => (await import('./sst/index')).sstTarget,\n};\n\n/** The target `name` means, in this workspace, for this host. */\nexport async function resolveTarget(\n\tname: string,\n\t{ workspace, host, stage }: ResolveTargetOptions,\n): Promise<ResolvedTarget> {\n\tif (host && Object.hasOwn(host, name)) {\n\t\treturn { name, target: host[name]!, source: 'host', options: undefined };\n\t}\n\n\tconst builtin = builtinTarget(name);\n\tif (builtin) {\n\t\tconst load = BUILTIN_LOADERS[name];\n\t\tif (builtin.status !== 'available' || !load) {\n\t\t\tthrow new DeployTargetNotYetSupported(name, builtin.instead?.(stage));\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\ttarget: await load(),\n\t\t\tsource: 'builtin',\n\t\t\toptions: undefined,\n\t\t};\n\t}\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst [implementation, options] = Array.isArray(entry)\n\t\t? (entry as readonly [unknown, unknown])\n\t\t: [entry, undefined];\n\n\tif (typeof implementation === 'string') {\n\t\t// Before the import: a package that does not say where it runs is\n\t\t// refused without running any of its code.\n\t\tconst declared = declaredRuntime(name, implementation, workspace.root);\n\t\tconst loaded = await importPackage(name, implementation, workspace.root);\n\t\tconst target = loaded.default;\n\t\tif (!isDeployTarget(target)) {\n\t\t\tthrow new TargetPackageInvalid(name, implementation);\n\t\t}\n\t\tif (target.runtime !== declared) {\n\t\t\tthrow new TargetRuntimeMismatch(\n\t\t\t\tname,\n\t\t\t\timplementation,\n\t\t\t\tdeclared,\n\t\t\t\ttarget.runtime,\n\t\t\t);\n\t\t}\n\t\treturn { name, target, source: 'config', options };\n\t}\n\n\tif (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);\n\treturn { name, target: implementation, source: 'config', options };\n}\n\n/** The target's options, parsed by its schema. */\nexport async function parseTargetOptions(\n\tresolved: ResolvedTarget,\n): Promise<unknown> {\n\tconst { name, target, options } = resolved;\n\tif (!target.options) {\n\t\tif (options !== undefined) {\n\t\t\tthrow new InvalidTargetOptions(name, [\n\t\t\t\t{ message: 'this target takes no options' },\n\t\t\t]);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst result = await target.options['~standard'].validate(options);\n\tif (result.issues) throw new InvalidTargetOptions(name, result.issues);\n\treturn result.value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resolve-DOXcAOcn.cjs","names":["join","existsSync","realpathSync","dirname","readFileSync","pathToFileURL","builtinTarget","configuredTarget","UnknownDeployTarget","configurableBuiltins","builtinTarget","DeployTargetNotYetSupported","configuredTarget","UnknownDeployTarget","configurableBuiltins","isDeployTarget"],"sources":["../src/target/package.ts","../src/target/runtime.ts","../src/target/resolve.ts"],"sourcesContent":["/**\n * A target package, found the way the project would find it.\n *\n * From the workspace root, never from the CLI's own location or the process's\n * working directory: the package is the project's dependency, and a CLI run\n * through `pnpm dlx` — or a host deploying a checkout elsewhere — has neither\n * in common with the project.\n */\n\nimport { existsSync, readFileSync, realpathSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nexport interface TargetPackageManifest {\n\tname?: string;\n\tmain?: string;\n\tmodule?: string;\n\texports?: unknown;\n\tgkm?: { runtime?: unknown };\n}\n\nexport interface LocatedPackage {\n\t/** The package's directory, symlinks resolved. */\n\tdir: string;\n\tmanifest: TargetPackageManifest;\n}\n\n/** A target package the project does not have installed. */\nexport class TargetPackageNotFound extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly from: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names the package \"${packageName}\", which is not installed in ${from}. Add it to the workspace root: pnpm add -D ${packageName}`,\n\t\t);\n\t\tthis.name = 'TargetPackageNotFound';\n\t}\n}\n\n/**\n * `name`'s directory and `package.json`, from the nearest `node_modules` at\n * or above `from` — Node's own lookup, without the exports map getting in\n * the way of reading `package.json`.\n */\nexport function locatePackage(\n\tname: string,\n\tfrom: string,\n): LocatedPackage | undefined {\n\tlet dir = from;\n\twhile (true) {\n\t\tconst manifestPath = join(dir, 'node_modules', name, 'package.json');\n\t\tif (existsSync(manifestPath)) {\n\t\t\treturn {\n\t\t\t\tdir: realpathSync(dirname(manifestPath)),\n\t\t\t\tmanifest: JSON.parse(\n\t\t\t\t\treadFileSync(manifestPath, 'utf-8'),\n\t\t\t\t) as TargetPackageManifest,\n\t\t\t};\n\t\t}\n\t\tconst parent = dirname(dir);\n\t\tif (parent === dir) return undefined;\n\t\tdir = parent;\n\t}\n}\n\n/** The first file a conditions object leads to, as an `import` would. */\nfunction pick(node: unknown): string | undefined {\n\tif (typeof node === 'string') return node;\n\tif (Array.isArray(node)) {\n\t\tfor (const option of node) {\n\t\t\tconst found = pick(option);\n\t\t\tif (found) return found;\n\t\t}\n\t\treturn undefined;\n\t}\n\tif (node && typeof node === 'object') {\n\t\tconst conditions = node as Record<string, unknown>;\n\t\tfor (const condition of ['import', 'node', 'default', 'require']) {\n\t\t\tif (condition in conditions) {\n\t\t\t\tconst found = pick(conditions[condition]);\n\t\t\t\tif (found) return found;\n\t\t\t}\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/** The file `import(name)` loads, relative to the package directory. */\nexport function packageEntry(manifest: TargetPackageManifest): string {\n\tconst { exports } = manifest;\n\tlet root: unknown = exports;\n\tif (exports && typeof exports === 'object' && !Array.isArray(exports)) {\n\t\tconst keys = Object.keys(exports);\n\t\t// A subpath map — `{ \".\": …, \"./x\": … }` — rather than one conditions\n\t\t// object for the root.\n\t\tif (keys.some((key) => key.startsWith('.'))) {\n\t\t\troot = (exports as Record<string, unknown>)['.'];\n\t\t}\n\t}\n\treturn pick(root) ?? manifest.module ?? manifest.main ?? 'index.js';\n}\n\n/** The module `name` is, imported from where the project would import it. */\nexport async function importPackage(\n\ttarget: string,\n\tname: string,\n\tfrom: string,\n): Promise<Record<string, unknown>> {\n\tconst located = locatePackage(name, from);\n\tif (!located) throw new TargetPackageNotFound(target, name, from);\n\n\tconst entry = join(located.dir, packageEntry(located.manifest));\n\treturn (await import(pathToFileURL(entry).href)) as Record<string, unknown>;\n}\n","/**\n * A target's runtime, without loading the target.\n *\n * `gkm dev` and `gkm build` choose a project's backends by it on every start,\n * synchronously, and must not import a deploy plugin to do so — a plugin may\n * pull in a cloud SDK, and a broken one would stop `gkm dev` for a project\n * that is only being developed. So a built-in's runtime is in the table, an\n * inline target carries its own, and a package declares it in its\n * `package.json`:\n *\n * ```json\n * { \"name\": \"@acme/gkm-target\", \"gkm\": { \"runtime\": \"server\" } }\n * ```\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { locatePackage, TargetPackageNotFound } from './package';\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\nconst RUNTIMES: readonly DeployRuntime[] = ['server', 'aws'];\n\n/** A target package whose `package.json` does not say where it runs. */\nexport class TargetRuntimeUndeclared extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\t/** What `gkm.runtime` held instead, when it held anything. */\n\t\treadonly found?: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" (${packageName}) does not declare its runtime${found === undefined ? '' : ` (gkm.runtime is ${JSON.stringify(found)})`}. Its package.json needs \"gkm\": { \"runtime\": \"server\" } or \"aws\", so gkm dev and gkm build can choose backends without loading it.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeUndeclared';\n\t}\n}\n\n/** What a workspace's deploy config is read for here. */\nexport interface TargetSource {\n\t/** Where the target packages are installed from. */\n\troot?: string;\n\tdeploy?:\n\t\t| { default?: string; targets?: Record<string, DeployTargetEntry> }\n\t\t| undefined;\n}\n\n/** The runtime a target package declares in `package.json#gkm.runtime`. */\nexport function declaredRuntime(\n\ttarget: string,\n\tpackageName: string,\n\troot: string | undefined,\n): DeployRuntime {\n\tconst located = root ? locatePackage(packageName, root) : undefined;\n\tif (!located) {\n\t\tthrow new TargetPackageNotFound(\n\t\t\ttarget,\n\t\t\tpackageName,\n\t\t\troot ?? 'the workspace',\n\t\t);\n\t}\n\tconst runtime = located.manifest.gkm?.runtime;\n\tif (!RUNTIMES.includes(runtime as DeployRuntime)) {\n\t\tthrow new TargetRuntimeUndeclared(target, packageName, runtime);\n\t}\n\treturn runtime as DeployRuntime;\n}\n\n/** The runtime of the target `name`, as the workspace resolves it. */\nexport function runtimeOf(\n\tname: string,\n\tworkspace: TargetSource,\n): DeployRuntime {\n\tconst builtin = builtinTarget(name);\n\tif (builtin) return builtin.runtime;\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst implementation = Array.isArray(entry) ? entry[0] : entry;\n\treturn typeof implementation === 'string'\n\t\t? declaredRuntime(name, implementation, workspace.root)\n\t\t: (implementation as { runtime: DeployRuntime }).runtime;\n}\n","/**\n * From a target's name to the target.\n *\n * In this order, the first that has the name wins:\n *\n * 1. the host's own targets — what a program calling `deploy()` passes\n * 2. the built-ins — `dokploy`, `compose`, `sst`\n * 3. `deploy.targets` in gkm.config.ts — a package, an object, or either\n * with options\n *\n * Built-ins come before the config so that a dependency cannot take over\n * `dokploy` by being listed under its name. A name nothing has is\n * `UnknownDeployTarget`. There is deliberately no fourth step that guesses a\n * package from the name (`acme` → `@acme/gkm-target`): an npm scope nobody\n * has claimed can be claimed by anyone, and a deploy would then run their\n * code with the stage's credentials. A target is installed and named.\n */\n\nimport {\n\tbuiltinTarget,\n\tconfigurableBuiltins,\n\tconfiguredTarget,\n\tDeployTargetNotYetSupported,\n\tUnknownDeployTarget,\n} from './builtins';\nimport { isDeployTarget } from './define';\nimport { importPackage } from './package';\nimport { declaredRuntime } from './runtime';\nimport type {\n\tAnyDeployTarget,\n\tDeployRuntime,\n\tDeployTargetEntry,\n\tTargetOptionsIssue,\n} from './types';\n\n/** Where a target came from. */\nexport type TargetSourceKind = 'host' | 'builtin' | 'config';\n\nexport interface ResolvedTarget {\n\t/** The name it was asked for by. */\n\tname: string;\n\ttarget: AnyDeployTarget;\n\tsource: TargetSourceKind;\n\t/** Its options as written in the config, before its schema parsed them. */\n\toptions: unknown;\n}\n\nexport interface ResolveTargetOptions {\n\t/** The workspace whose `deploy.targets` is consulted. */\n\tworkspace: {\n\t\troot: string;\n\t\tdeploy?: { targets?: Record<string, DeployTargetEntry> } | undefined;\n\t};\n\t/** The host's targets, consulted first. */\n\thost?: Record<string, AnyDeployTarget>;\n\t/** The stage being deployed, for what to do instead of a refused target. */\n\tstage: string;\n}\n\n/** A target package whose default export is not a target. */\nexport class TargetPackageInvalid extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} names \"${packageName}\", whose default export is not a deploy target. A target package exports one as default: export default defineTarget({ … }) from '@geekmidas/cli/target'.`,\n\t\t);\n\t\tthis.name = 'TargetPackageInvalid';\n\t}\n}\n\n/** A `deploy.targets` entry that is not a target, a package name or a pair. */\nexport class TargetEntryInvalid extends Error {\n\tconstructor(readonly target: string) {\n\t\tsuper(\n\t\t\t`deploy.targets.${target} must be a package name, a target object (defineTarget), or [package or target, options].`,\n\t\t);\n\t\tthis.name = 'TargetEntryInvalid';\n\t}\n}\n\n/** A target whose `runtime` is not the one its package declares. */\nexport class TargetRuntimeMismatch extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly packageName: string,\n\t\treadonly declared: DeployRuntime,\n\t\treadonly actual: DeployRuntime,\n\t) {\n\t\tsuper(\n\t\t\t`The deploy target \"${target}\" runs on \"${actual}\", but ${packageName}'s package.json declares gkm.runtime \"${declared}\". gkm dev and gkm build chose backends for \"${declared}\", so the two must agree — fix the package.`,\n\t\t);\n\t\tthis.name = 'TargetRuntimeMismatch';\n\t}\n}\n\n/** Options a target's schema rejected. */\nexport class InvalidTargetOptions extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\treadonly issues: readonly TargetOptionsIssue[],\n\t) {\n\t\tconst lines = issues.map((issue) => {\n\t\t\tconst path = (issue.path ?? [])\n\t\t\t\t.map((segment) =>\n\t\t\t\t\ttypeof segment === 'object' ? String(segment.key) : String(segment),\n\t\t\t\t)\n\t\t\t\t.join('.');\n\t\t\treturn ` - ${path ? `${path}: ` : ''}${issue.message}`;\n\t\t});\n\t\tsuper(\n\t\t\t`The options for deploy target \"${target}\" are invalid — fix them in deploy.targets.${target} in gkm.config.ts:\\n${lines.join('\\n')}`,\n\t\t);\n\t\tthis.name = 'InvalidTargetOptions';\n\t}\n}\n\n/** The built-ins `gkm deploy` deploys through, loaded only when used. */\nconst BUILTIN_LOADERS: Record<string, () => Promise<AnyDeployTarget>> = {\n\tdokploy: async () => (await import('./dokploy')).dokployTarget,\n\tcompose: async () => (await import('./compose/index')).composeTarget(),\n\tsst: async () => (await import('./sst/index')).sstTarget,\n};\n\n/** The target `name` means, in this workspace, for this host. */\nexport async function resolveTarget(\n\tname: string,\n\t{ workspace, host, stage }: ResolveTargetOptions,\n): Promise<ResolvedTarget> {\n\tif (host && Object.hasOwn(host, name)) {\n\t\treturn { name, target: host[name]!, source: 'host', options: undefined };\n\t}\n\n\tconst builtin = builtinTarget(name);\n\tif (builtin) {\n\t\tconst load = BUILTIN_LOADERS[name];\n\t\tif (builtin.status !== 'available' || !load) {\n\t\t\tthrow new DeployTargetNotYetSupported(name, builtin.instead?.(stage));\n\t\t}\n\t\treturn {\n\t\t\tname,\n\t\t\ttarget: await load(),\n\t\t\tsource: 'builtin',\n\t\t\toptions: undefined,\n\t\t};\n\t}\n\n\tconst entry = configuredTarget(workspace.deploy, name);\n\tif (entry === undefined) {\n\t\tthrow new UnknownDeployTarget(name, [\n\t\t\t...configurableBuiltins(),\n\t\t\t...Object.keys(workspace.deploy?.targets ?? {}),\n\t\t]);\n\t}\n\n\tconst [implementation, options] = Array.isArray(entry)\n\t\t? (entry as readonly [unknown, unknown])\n\t\t: [entry, undefined];\n\n\tif (typeof implementation === 'string') {\n\t\t// Before the import: a package that does not say where it runs is\n\t\t// refused without running any of its code.\n\t\tconst declared = declaredRuntime(name, implementation, workspace.root);\n\t\tconst loaded = await importPackage(name, implementation, workspace.root);\n\t\tconst target = loaded.default;\n\t\tif (!isDeployTarget(target)) {\n\t\t\tthrow new TargetPackageInvalid(name, implementation);\n\t\t}\n\t\tif (target.runtime !== declared) {\n\t\t\tthrow new TargetRuntimeMismatch(\n\t\t\t\tname,\n\t\t\t\timplementation,\n\t\t\t\tdeclared,\n\t\t\t\ttarget.runtime,\n\t\t\t);\n\t\t}\n\t\treturn { name, target, source: 'config', options };\n\t}\n\n\tif (!isDeployTarget(implementation)) throw new TargetEntryInvalid(name);\n\treturn { name, target: implementation, source: 'config', options };\n}\n\n/** The target's options, parsed by its schema. */\nexport async function parseTargetOptions(\n\tresolved: ResolvedTarget,\n): Promise<unknown> {\n\tconst { name, target, options } = resolved;\n\tif (!target.options) {\n\t\tif (options !== undefined) {\n\t\t\tthrow new InvalidTargetOptions(name, [\n\t\t\t\t{ message: 'this target takes no options' },\n\t\t\t]);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tconst result = await target.options['~standard'].validate(options);\n\tif (result.issues) throw new InvalidTargetOptions(name, result.issues);\n\treturn result.value;\n}\n"],"mappings":";;;;;;;;;;;;;;AA4BA,IAAa,wBAAb,cAA2C,MAAM;CAEtC;CACA;CACA;CAHV,YACC,QACA,aACA,MACC;EACD,MACC,kBAAkB,OAAO,sBAAsB,YAAY,+BAA+B,KAAK,8CAA8C,aAC9I;EANS,KAAA,SAAA;EACA,KAAA,cAAA;EACA,KAAA,OAAA;EAKT,KAAK,OAAO;CACb;AACD;;;;;;AAOA,SAAgB,cACf,MACA,MAC6B;CAC7B,IAAI,MAAM;CACV,OAAO,MAAM;EACZ,MAAM,gBAAA,GAAeA,UAAAA,KAAAA,CAAK,KAAK,gBAAgB,MAAM,cAAc;EACnE,KAAA,GAAIC,QAAAA,WAAAA,CAAW,YAAY,GAC1B,OAAO;GACN,MAAA,GAAKC,QAAAA,aAAAA,EAAAA,GAAaC,UAAAA,QAAAA,CAAQ,YAAY,CAAC;GACvC,UAAU,KAAK,OAAA,GACdC,QAAAA,aAAAA,CAAa,cAAc,OAAO,CACnC;EACD;EAED,MAAM,UAAA,GAASD,UAAAA,QAAAA,CAAQ,GAAG;EAC1B,IAAI,WAAW,KAAK,OAAO,KAAA;EAC3B,MAAM;CACP;AACD;;AAGA,SAAS,KAAK,MAAmC;CAChD,IAAI,OAAO,SAAS,UAAU,OAAO;CACrC,IAAI,MAAM,QAAQ,IAAI,GAAG;EACxB,KAAK,MAAM,UAAU,MAAM;GAC1B,MAAM,QAAQ,KAAK,MAAM;GACzB,IAAI,OAAO,OAAO;EACnB;EACA;CACD;CACA,IAAI,QAAQ,OAAO,SAAS,UAAU;EACrC,MAAM,aAAa;EACnB,KAAK,MAAM,aAAa;GAAC;GAAU;GAAQ;GAAW;EAAS,GAC9D,IAAI,aAAa,YAAY;GAC5B,MAAM,QAAQ,KAAK,WAAW,UAAU;GACxC,IAAI,OAAO,OAAO;EACnB;CAEF;AAED;;AAGA,SAAgB,aAAa,UAAyC;CACrE,MAAM,EAAE,YAAY;CACpB,IAAI,OAAgB;CACpB,IAAI,WAAW,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,GACtD;MAAA,OAAO,KAAK,OAGlB,CAAC,CAAC,MAAM,QAAQ,IAAI,WAAW,GAAG,CAAC,GACzC,OAAQ,QAAoC;CAAA;CAG9C,OAAO,KAAK,IAAI,KAAK,SAAS,UAAU,SAAS,QAAQ;AAC1D;;AAGA,eAAsB,cACrB,QACA,MACA,MACmC;CACnC,MAAM,UAAU,cAAc,MAAM,IAAI;CACxC,IAAI,CAAC,SAAS,MAAM,IAAI,sBAAsB,QAAQ,MAAM,IAAI;CAEhE,MAAM,SAAA,GAAQH,UAAAA,KAAAA,CAAK,QAAQ,KAAK,aAAa,QAAQ,QAAQ,CAAC;CAC9D,OAAQ,MAAM,QAAA,GAAOK,SAAAA,cAAAA,CAAc,KAAK,CAAC,CAAC;AAC3C;;;;;;;;;;;;;;;;;AC3FA,MAAM,WAAqC,CAAC,UAAU,KAAK;;AAG3D,IAAa,0BAAb,cAA6C,MAAM;CAExC;CACA;CAEA;CAJV,YACC,QACA,aAEA,OACC;EACD,MACC,sBAAsB,OAAO,KAAK,YAAY,gCAAgC,UAAU,KAAA,IAAY,KAAK,oBAAoB,KAAK,UAAU,KAAK,EAAE,GAAG,mIACvJ;EAPS,KAAA,SAAA;EACA,KAAA,cAAA;EAEA,KAAA,QAAA;EAKT,KAAK,OAAO;CACb;AACD;;AAYA,SAAgB,gBACf,QACA,aACA,MACgB;CAChB,MAAM,UAAU,OAAO,cAAc,aAAa,IAAI,IAAI,KAAA;CAC1D,IAAI,CAAC,SACJ,MAAM,IAAI,sBACT,QACA,aACA,QAAQ,eACT;CAED,MAAM,UAAU,QAAQ,SAAS,KAAK;CACtC,IAAI,CAAC,SAAS,SAAS,OAAwB,GAC9C,MAAM,IAAI,wBAAwB,QAAQ,aAAa,OAAO;CAE/D,OAAO;AACR;;AAGA,SAAgB,UACf,MACA,WACgB;CAChB,MAAM,UAAUC,eAAAA,cAAc,IAAI;CAClC,IAAI,SAAS,OAAO,QAAQ;CAE5B,MAAM,QAAQC,eAAAA,iBAAiB,UAAU,QAAQ,IAAI;CACrD,IAAI,UAAU,KAAA,GACb,MAAM,IAAIC,eAAAA,oBAAoB,MAAM,CACnC,GAAGC,eAAAA,qBAAqB,GACxB,GAAG,OAAO,KAAK,UAAU,QAAQ,WAAW,CAAC,CAAC,CAC/C,CAAC;CAGF,MAAM,iBAAiB,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;CACzD,OAAO,OAAO,mBAAmB,WAC9B,gBAAgB,MAAM,gBAAgB,UAAU,IAAI,IACnD,eAA8C;AACnD;;;;;;;;;;;;;;;;;;;;;AC/BA,IAAa,uBAAb,cAA0C,MAAM;CAErC;CACA;CAFV,YACC,QACA,aACC;EACD,MACC,kBAAkB,OAAO,UAAU,YAAY,0JAChD;EALS,KAAA,SAAA;EACA,KAAA,cAAA;EAKT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,qBAAb,cAAwC,MAAM;CACxB;CAArB,YAAY,QAAyB;EACpC,MACC,kBAAkB,OAAO,0FAC1B;EAHoB,KAAA,SAAA;EAIpB,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,wBAAb,cAA2C,MAAM;CAEtC;CACA;CACA;CACA;CAJV,YACC,QACA,aACA,UACA,QACC;EACD,MACC,sBAAsB,OAAO,aAAa,OAAO,SAAS,YAAY,wCAAwC,SAAS,+CAA+C,SAAS,4CAChL;EAPS,KAAA,SAAA;EACA,KAAA,cAAA;EACA,KAAA,WAAA;EACA,KAAA,SAAA;EAKT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,uBAAb,cAA0C,MAAM;CAErC;CACA;CAFV,YACC,QACA,QACC;EACD,MAAM,QAAQ,OAAO,KAAK,UAAU;GACnC,MAAM,QAAQ,MAAM,QAAQ,CAAC,EAAA,CAC3B,KAAK,YACL,OAAO,YAAY,WAAW,OAAO,QAAQ,GAAG,IAAI,OAAO,OAAO,CACnE,CAAC,CACA,KAAK,GAAG;GACV,OAAO,OAAO,OAAO,GAAG,KAAK,MAAM,KAAK,MAAM;EAC/C,CAAC;EACD,MACC,kCAAkC,OAAO,6CAA6C,OAAO,sBAAsB,MAAM,KAAK,IAAI,GACnI;EAbS,KAAA,SAAA;EACA,KAAA,SAAA;EAaT,KAAK,OAAO;CACb;AACD;;AAGA,MAAM,kBAAkE;CACvE,SAAS,aAAa,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,EAAA,CAAqB;CACjD,SAAS,aAAa,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,wBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,eAAA,EAAA,CAA2B,cAAc;CACrE,KAAK,aAAa,MAAA,QAAA,QAAA,CAAA,CAAA,WAAA,QAAM,oBAAA,CAAA,CAAA,CAAA,MAAA,MAAA,EAAA,WAAA,EAAA,CAAuB;AAChD;;AAGA,eAAsB,cACrB,MACA,EAAE,WAAW,MAAM,SACO;CAC1B,IAAI,QAAQ,OAAO,OAAO,MAAM,IAAI,GACnC,OAAO;EAAE;EAAM,QAAQ,KAAK;EAAQ,QAAQ;EAAQ,SAAS,KAAA;CAAU;CAGxE,MAAM,UAAUC,eAAAA,cAAc,IAAI;CAClC,IAAI,SAAS;EACZ,MAAM,OAAO,gBAAgB;EAC7B,IAAI,QAAQ,WAAW,eAAe,CAAC,MACtC,MAAM,IAAIC,eAAAA,4BAA4B,MAAM,QAAQ,UAAU,KAAK,CAAC;EAErE,OAAO;GACN;GACA,QAAQ,MAAM,KAAK;GACnB,QAAQ;GACR,SAAS,KAAA;EACV;CACD;CAEA,MAAM,QAAQC,eAAAA,iBAAiB,UAAU,QAAQ,IAAI;CACrD,IAAI,UAAU,KAAA,GACb,MAAM,IAAIC,eAAAA,oBAAoB,MAAM,CACnC,GAAGC,eAAAA,qBAAqB,GACxB,GAAG,OAAO,KAAK,UAAU,QAAQ,WAAW,CAAC,CAAC,CAC/C,CAAC;CAGF,MAAM,CAAC,gBAAgB,WAAW,MAAM,QAAQ,KAAK,IACjD,QACD,CAAC,OAAO,KAAA,CAAS;CAEpB,IAAI,OAAO,mBAAmB,UAAU;EAGvC,MAAM,WAAW,gBAAgB,MAAM,gBAAgB,UAAU,IAAI;EAErE,MAAM,UAAS,MADM,cAAc,MAAM,gBAAgB,UAAU,IAAI,EAAA,CACjD;EACtB,IAAI,CAACC,eAAAA,eAAe,MAAM,GACzB,MAAM,IAAI,qBAAqB,MAAM,cAAc;EAEpD,IAAI,OAAO,YAAY,UACtB,MAAM,IAAI,sBACT,MACA,gBACA,UACA,OAAO,OACR;EAED,OAAO;GAAE;GAAM;GAAQ,QAAQ;GAAU;EAAQ;CAClD;CAEA,IAAI,CAACA,eAAAA,eAAe,cAAc,GAAG,MAAM,IAAI,mBAAmB,IAAI;CACtE,OAAO;EAAE;EAAM,QAAQ;EAAgB,QAAQ;EAAU;CAAQ;AAClE;;AAGA,eAAsB,mBACrB,UACmB;CACnB,MAAM,EAAE,MAAM,QAAQ,YAAY;CAClC,IAAI,CAAC,OAAO,SAAS;EACpB,IAAI,YAAY,KAAA,GACf,MAAM,IAAI,qBAAqB,MAAM,CACpC,EAAE,SAAS,+BAA+B,CAC3C,CAAC;EAEF;CACD;CAEA,MAAM,SAAS,MAAM,OAAO,QAAQ,YAAY,CAAC,SAAS,OAAO;CACjE,IAAI,OAAO,QAAQ,MAAM,IAAI,qBAAqB,MAAM,OAAO,MAAM;CACrE,OAAO,OAAO;AACf"}
@@ -3,9 +3,9 @@ import { i as LocalSandbox, r as storedCredentials } from "./credentials-pAtB70k
3
3
  import { c as withSandbox } from "./sandbox-Dm247NGx.mjs";
4
4
  import { k as assertDeployedStage } from "./workspace-BBdqmkch.mjs";
5
5
  import { findWorkspaceRoot, loadWorkspaceConfig } from "./config.mjs";
6
- import { m as DeployJournal, n as createEmptyState, s as recordRollback } from "./stale-C5FqIVc8.mjs";
6
+ import { _ as DeployJournal, a as createEmptyState, u as recordRollback } from "./seeds-DiXON7R8.mjs";
7
7
  import { g as createStateStore } from "./sniffer-ByWtH28i.mjs";
8
- import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-DOjGIgl4.mjs";
8
+ import { i as dokployApi, l as restoreImage, p as verifySettings } from "./engine-B-Yq0yQu.mjs";
9
9
  import { resolve } from "node:path";
10
10
  //#region src/target/dokploy/rollback.ts
11
11
  /**
@@ -129,4 +129,4 @@ async function rollbackStage(input) {
129
129
  //#endregion
130
130
  export { rollback_exports as a, rollbackStage as i, RollbackNeedsApp as n, StageNeverDeployed as r, NothingToRollBack as t };
131
131
 
132
- //# sourceMappingURL=rollback-S2C-Y9pB.mjs.map
132
+ //# sourceMappingURL=rollback-Cq5s3WnD.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-S2C-Y9pB.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-Cq5s3WnD.mjs","names":[],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
@@ -3,9 +3,9 @@ const require_credentials = require("./credentials-BVs7mrtw.cjs");
3
3
  const require_sandbox = require("./sandbox-CL--ZDui.cjs");
4
4
  const require_workspace = require("./workspace-Bp8FEkF-.cjs");
5
5
  const require_config = require("./config.cjs");
6
- const require_stale = require("./stale-BsiPJI7Y.cjs");
6
+ const require_seeds = require("./seeds-qX13ubmO.cjs");
7
7
  const require_sniffer = require("./sniffer-BjG-1mlD.cjs");
8
- const require_engine = require("./engine-CoCsNoW_.cjs");
8
+ const require_engine = require("./engine-C3T39eTO.cjs");
9
9
  let node_path = require("node:path");
10
10
  //#region src/target/dokploy/rollback.ts
11
11
  /**
@@ -80,7 +80,7 @@ async function rollbackStage(input) {
80
80
  if (!await store.read(input.stage)) throw new StageNeverDeployed(input.stage);
81
81
  const lock = await store.lock(input.stage, { operation: "rollback" });
82
82
  try {
83
- const journal = await require_stale.DeployJournal.open(store, input.stage, () => require_stale.createEmptyState(input.stage, "", ""));
83
+ const journal = await require_seeds.DeployJournal.open(store, input.stage, () => require_seeds.createEmptyState(input.stage, "", ""));
84
84
  const { state } = journal;
85
85
  const releases = state.releases ?? {};
86
86
  const restorable = Object.keys(releases).filter((app) => releases[app].previous);
@@ -111,7 +111,7 @@ async function rollbackStage(input) {
111
111
  verify,
112
112
  signal
113
113
  });
114
- require_stale.recordRollback(state, app, previous);
114
+ require_seeds.recordRollback(state, app, previous);
115
115
  await journal.save();
116
116
  log(` ✓ ${app} is running ${previous.ref}`);
117
117
  rolled.push({
@@ -158,4 +158,4 @@ Object.defineProperty(exports, "rollback_exports", {
158
158
  }
159
159
  });
160
160
 
161
- //# sourceMappingURL=rollback-F3P-rA-r.cjs.map
161
+ //# sourceMappingURL=rollback-DUoOaws3.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rollback-F3P-rA-r.cjs","names":["storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rollback-DUoOaws3.cjs","names":["storedCredentials","LocalSandbox","findWorkspaceRoot","resolve","withSandbox","loadWorkspaceConfig","createStateStore","DeployJournal","createEmptyState","dokployApi","verifySettings","restoreImage"],"sources":["../src/target/dokploy/rollback.ts"],"sourcesContent":["/**\n * `gkm deploy:rollback`: a stage's apps put back on the release before the\n * one they run, by hand — for a release that passed its checks and turned out\n * wrong anyway.\n *\n * One app by default, because an app is what usually broke: rolling the API\n * back over a site fix that shipped beside it undoes the fix too. `atomic`\n * rolls back every app that has a release to go back to, for apps that only\n * work together — an API and the site built against its newer contract.\n *\n * It restores images and nothing else. The environment an app runs with is\n * the stage's, resolved on every deploy, and migrations are forward-only: a\n * migration that the older code cannot run against is undone by a new\n * migration, never by a rollback.\n */\n\nimport { resolve } from 'node:path';\nimport { findWorkspaceRoot, loadWorkspaceConfig } from '../../config';\nimport {\n\ttype CredentialProvider,\n\tstoredCredentials,\n} from '../../deploy/credentials';\nimport { DeployJournal } from '../../deploy/journal';\nimport { createStateStore } from '../../deploy/StateStore';\nimport {\n\tcreateEmptyState,\n\ttype ReleasedImage,\n\trecordRollback,\n} from '../../deploy/state';\nimport { LocalSandbox } from '../../sandbox/local';\nimport { type Sandbox, withSandbox } from '../../sandbox/sandbox';\nimport { assertDeployedStage } from '../../workspace/stages';\nimport { dokployApi, restoreImage, verifySettings } from './engine';\n\nexport interface RollbackInput {\n\t/** The project: the directory holding `gkm.config.ts`, or one inside it. */\n\tcwd: string;\n\tstage: string;\n\t/** The app to roll back. */\n\tapp?: string;\n\t/** Every app with an earlier release, instead of one. */\n\tatomic?: boolean;\n\t/** Defaults to the environment, then the logins `gkm login` stored. */\n\tcredentials?: CredentialProvider;\n\tsignal?: AbortSignal;\n\t/** Each progress line. Defaults to none. */\n\tlog?: (line: string) => void;\n\t/** Where the config is loaded. Defaults to a `LocalSandbox` on the project. */\n\tsandbox?: Sandbox;\n}\n\n/** One app rolled back. */\nexport interface RolledBack {\n\tapp: string;\n\tfrom: ReleasedImage;\n\tto: ReleasedImage;\n}\n\n/** Neither an app nor every app was asked for. */\nexport class RollbackNeedsApp extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\t/** The apps that have a release to go back to. */\n\t\treadonly apps: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Say what to roll back: --app <name> for one app (${apps.join(', ') || 'none has an earlier release'}), ` +\n\t\t\t\t`or --atomic for every app of \"${stage}\" together.`,\n\t\t);\n\t\tthis.name = 'RollbackNeedsApp';\n\t}\n}\n\n/** An app has no release before the one it runs. */\nexport class NothingToRollBack extends Error {\n\tconstructor(\n\t\treadonly stage: string,\n\t\treadonly app: string,\n\t) {\n\t\tsuper(\n\t\t\t`\"${app}\" has no earlier release on \"${stage}\" to roll back to: it has been released once, ` +\n\t\t\t\t'or every earlier release was itself rolled back. Deploy the version you want instead.',\n\t\t);\n\t\tthis.name = 'NothingToRollBack';\n\t}\n}\n\n/** The stage was never deployed through Dokploy from this state. */\nexport class StageNeverDeployed extends Error {\n\tconstructor(readonly stage: string) {\n\t\tsuper(\n\t\t\t`\"${stage}\" has no deploy state, so there is nothing to roll back. ` +\n\t\t\t\t'Check the stage name, and that `state` in gkm.config.ts points at the store the deploys write to.',\n\t\t);\n\t\tthis.name = 'StageNeverDeployed';\n\t}\n}\n\n/**\n * Roll a stage's app — or, `atomic`, all of them — back to its previous\n * release, holding the stage's lock as a deploy does.\n */\nexport async function rollbackStage(\n\tinput: RollbackInput,\n): Promise<RolledBack[]> {\n\tconst signal = input.signal ?? new AbortController().signal;\n\tconst log = input.log ?? (() => {});\n\tconst credentials = input.credentials ?? storedCredentials();\n\tconst sandbox =\n\t\tinput.sandbox ??\n\t\tnew LocalSandbox({ root: findWorkspaceRoot(resolve(input.cwd)) });\n\n\treturn withSandbox(sandbox, async () => {\n\t\tconst { workspace } = await loadWorkspaceConfig(resolve(input.cwd), {\n\t\t\tsandbox,\n\t\t});\n\t\tassertDeployedStage(workspace.stages, input.stage);\n\n\t\tconst store = await createStateStore({\n\t\t\tconfig: workspace.state,\n\t\t\tworkspaceRoot: workspace.root,\n\t\t\tworkspaceName: workspace.name,\n\t\t});\n\t\tif (!(await store.read(input.stage))) {\n\t\t\tthrow new StageNeverDeployed(input.stage);\n\t\t}\n\n\t\tconst lock = await store.lock(input.stage, { operation: 'rollback' });\n\t\ttry {\n\t\t\tconst journal = await DeployJournal.open(store, input.stage, () =>\n\t\t\t\tcreateEmptyState(input.stage, '', ''),\n\t\t\t);\n\t\t\tconst { state } = journal;\n\t\t\tconst releases = state.releases ?? {};\n\t\t\tconst restorable = Object.keys(releases).filter(\n\t\t\t\t(app) => releases[app]!.previous,\n\t\t\t);\n\n\t\t\tlet apps: string[];\n\t\t\tif (input.atomic) {\n\t\t\t\tapps = restorable;\n\t\t\t\tif (apps.length === 0) {\n\t\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t\t}\n\t\t\t} else if (input.app) {\n\t\t\t\tif (!releases[input.app]?.previous) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, input.app);\n\t\t\t\t}\n\t\t\t\tapps = [input.app];\n\t\t\t} else {\n\t\t\t\tthrow new RollbackNeedsApp(input.stage, restorable);\n\t\t\t}\n\n\t\t\tconst { api } = await dokployApi(workspace, { credentials, signal });\n\t\t\tconst verify = verifySettings(workspace.deploy.dokploy?.verify);\n\t\t\tconst rolled: RolledBack[] = [];\n\n\t\t\tfor (const app of apps) {\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tconst { current, previous } = releases[app]!;\n\t\t\t\tconst applicationId = state.applications[app];\n\t\t\t\tif (!previous || !applicationId) {\n\t\t\t\t\tthrow new NothingToRollBack(input.stage, app);\n\t\t\t\t}\n\n\t\t\t\tlog(`⏪ ${app}: ${current.ref} → ${previous.ref}`);\n\t\t\t\tawait restoreImage(api, {\n\t\t\t\t\tapplicationId,\n\t\t\t\t\timage: previous,\n\t\t\t\t\tregistryId: state.registryId,\n\t\t\t\t\tverify,\n\t\t\t\t\tsignal,\n\t\t\t\t});\n\t\t\t\trecordRollback(state, app, previous);\n\t\t\t\tawait journal.save();\n\t\t\t\tlog(` ✓ ${app} is running ${previous.ref}`);\n\t\t\t\trolled.push({ app, from: current, to: previous });\n\t\t\t}\n\n\t\t\treturn rolled;\n\t\t} finally {\n\t\t\tawait lock.release();\n\t\t}\n\t});\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-ByY0zi3n.cjs";
1
+ import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-DZtj9jeI.cjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends Error {
@@ -87,4 +87,4 @@ declare class TargetRuntimeUndeclared extends Error {
87
87
  }
88
88
  //#endregion
89
89
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
90
- //# sourceMappingURL=runtime-D9AxGzrw.d.cts.map
90
+ //# sourceMappingURL=runtime-D6A-C6zh.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-D9AxGzrw.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-D6A-C6zh.d.cts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
@@ -1,4 +1,4 @@
1
- import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-DKxkXsKC.mjs";
1
+ import { Q as TargetOptionsIssue, W as DeployRuntime } from "./types-BzCavjGt.mjs";
2
2
  //#region src/target/builtins.d.ts
3
3
  /** A target name that is neither built in nor in `deploy.targets`. */
4
4
  declare class UnknownDeployTarget extends Error {
@@ -87,4 +87,4 @@ declare class TargetRuntimeUndeclared extends Error {
87
87
  }
88
88
  //#endregion
89
89
  export { TargetRuntimeMismatch as a, DeployTargetNotYetSupported as c, TargetPackageInvalid as i, UnknownDeployTarget as l, InvalidTargetOptions as n, ProviderRemoved as o, TargetEntryInvalid as r, TargetPackageNotFound as s, TargetRuntimeUndeclared as t };
90
- //# sourceMappingURL=runtime-Dflki3Vs.d.mts.map
90
+ //# sourceMappingURL=runtime-ekxfPNM-.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-Dflki3Vs.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
1
+ {"version":3,"file":"runtime-ekxfPNM-.d.mts","names":[],"sources":["../src/target/builtins.ts","../src/target/package.ts","../src/target/provider.ts","../src/target/resolve.ts","../src/target/runtime.ts"],"mappings":";;;cA+Da,4BAA4B;WAE9B;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;cAUE,oCAAoC;WAEtC;;WAEA;EAHV,YACU,gBAEA;;EAAA;;;;;cCrDE,8BAA8B;WAEhC;WACA;WACA;EAHV,YACU,gBACA,qBACA;;;;;;;;;;;;;cCZE,wBAAwB;WAE1B;;WAEA;EAHV,YACU,kBAEA;;EAAA;;;;;cCoCE,6BAA6B;WAE/B;WACA;EAFV,YACU,gBACA;;;cAUE,2BAA2B;WAClB;EAArB,YAAqB;;;cAST,8BAA8B;WAEhC;WACA;WACA,UAAU;WACV,QAAQ;EAJlB,YACU,gBACA,qBACA,UAAU,eACV,QAAQ;;;cAUN,6BAA6B;WAE/B;WACA,iBAAiB;EAF3B,YACU,gBACA,iBAAiB;;;;;cC1Ef,gCAAgC;WAElC;WACA;;WAEA;EAJV,YACU,gBACA,qBAEA;;EAAA"}
@@ -1,19 +1,19 @@
1
1
  const require_discover = require("../discover-D1It5r_h.cjs");
2
2
  const require_sandbox = require("../sandbox-CL--ZDui.cjs");
3
3
  const require_workerRuntime = require("../workerRuntime-BXfhbe13.cjs");
4
- const require_databases = require("../databases-C2p5LGAp.cjs");
4
+ const require_databases = require("../databases-BY-pEImp.cjs");
5
5
  let node_path = require("node:path");
6
6
  let node_fs_promises = require("node:fs/promises");
7
7
  //#region src/sandbox/migrate-worker.ts
8
8
  /**
9
- * Applies a deployed stage's migrations in a sandbox — the migrator
10
- * `gkm migrate` runs, against URLs the deploy hands it as secret files.
9
+ * Applies a deployed stage's migrations, then runs its seeds, in a sandbox —
10
+ * what `gkm seed` runs, against URLs the deploy hands it as secret files.
11
11
  *
12
12
  * Usage (by the Dokploy target's release, never by hand):
13
- * node --import=<tsx> migrate-worker.ts '{"root":"…","manifest":{…},"patterns":[…]}'
13
+ * node --import=<tsx> migrate-worker.ts '{"root":"…","stage":"…","manifest":{…},"patterns":[…]}'
14
14
  *
15
- * Migrations are the project's own code, which is why they run here rather
16
- * than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,
15
+ * Migrations and seeds are the project's own code, which is why they run
16
+ * here rather than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,
17
17
  * named by its key, and is read into this process's memory only: never into
18
18
  * `process.env`, where a child the migration starts would inherit it.
19
19
  */
@@ -35,23 +35,37 @@ async function main() {
35
35
  cwd: request.root,
36
36
  sources
37
37
  });
38
- const runs = await require_databases.migrateDatabases({
38
+ const options = {
39
39
  root: request.root,
40
40
  manifest: request.manifest,
41
41
  sources,
42
42
  env: await mountedSecrets()
43
+ };
44
+ const runs = await require_databases.migrateDatabases(options);
45
+ const seeds = await require_databases.seedDatabases({
46
+ ...options,
47
+ stage: request.stage
43
48
  });
44
49
  require_workerRuntime.answer({
45
50
  reason: "migrated",
46
51
  runs: runs.map(({ target, applied }) => ({
52
+ construct: target.id,
47
53
  migrations: target.migrations,
48
54
  applied
55
+ })),
56
+ seeds: seeds.map(({ target, seeded }) => ({
57
+ construct: target.id,
58
+ seeds: target.seeds,
59
+ seeded
49
60
  }))
50
61
  });
51
62
  } catch (error) {
52
63
  require_workerRuntime.answer({
53
64
  reason: "failed",
54
- error: require_workerRuntime.errorData(error)
65
+ error: {
66
+ ...require_workerRuntime.errorData(error),
67
+ ...error instanceof require_databases.SeedFailed ? { cause: require_workerRuntime.errorData(error.cause) } : {}
68
+ }
55
69
  });
56
70
  }
57
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-worker.cjs","names":["SECRETS_DIR_ENV","readdir","readFile","join","registerAdjacentTsconfig","discover","migrateDatabases","errorData"],"sources":["../../src/sandbox/migrate-worker.ts"],"sourcesContent":["/**\n * Applies a deployed stage's migrations in a sandbox — the migrator\n * `gkm migrate` runs, against URLs the deploy hands it as secret files.\n *\n * Usage (by the Dokploy target's release, never by hand):\n * node --import=<tsx> migrate-worker.ts '{\"root\":\"…\",\"manifest\":{…},\"patterns\":[…]}'\n *\n * Migrations are the project's own code, which is why they run here rather\n * than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,\n * named by its key, and is read into this process's memory only: never into\n * `process.env`, where a child the migration starts would inherit it.\n */\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport { migrateDatabases } from '../migrate/databases';\nimport { type ConstructSource, discover } from '../reconcile/discover';\nimport { SECRETS_DIR_ENV } from './sandbox';\nimport { answer, errorData, registerAdjacentTsconfig } from './workerRuntime';\n\n/** Every secret file the sandbox mounted, by name. */\nasync function mountedSecrets(): Promise<Record<string, string>> {\n\tconst dir = process.env[SECRETS_DIR_ENV];\n\tif (!dir) return {};\n\n\tconst secrets: Record<string, string> = {};\n\tfor (const name of await readdir(dir)) {\n\t\tsecrets[name] = (await readFile(join(dir, name), 'utf8')).trim();\n\t}\n\treturn secrets;\n}\n\nasync function main(): Promise<void> {\n\ttry {\n\t\tconst request = JSON.parse(process.argv[2] ?? '{}') as {\n\t\t\troot: string;\n\t\t\tmanifest: ConstructManifest;\n\t\t\tpatterns: string[];\n\t\t};\n\t\tawait registerAdjacentTsconfig();\n\n\t\t// Where each construct is declared, so a migration runs with the Kysely\n\t\t// its own file resolves. The manifest itself is the deploy's: what it\n\t\t// provisioned is what gets migrated, not a second reading of the files.\n\t\tconst sources: Record<string, ConstructSource> = {};\n\t\tif (request.patterns.length > 0) {\n\t\t\tawait discover({\n\t\t\t\tpatterns: request.patterns,\n\t\t\t\tcwd: request.root,\n\t\t\t\tsources,\n\t\t\t});\n\t\t}\n\n\t\tconst runs = await migrateDatabases({\n\t\t\troot: request.root,\n\t\t\tmanifest: request.manifest,\n\t\t\tsources,\n\t\t\tenv: await mountedSecrets(),\n\t\t});\n\n\t\tanswer({\n\t\t\treason: 'migrated',\n\t\t\truns: runs.map(({ target, applied }) => ({\n\t\t\t\tmigrations: target.migrations,\n\t\t\t\tapplied,\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\tanswer({ reason: 'failed', error: errorData(error) });\n\t}\n}\n\nvoid main();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,eAAe,iBAAkD;CAChE,MAAM,MAAM,QAAQ,IAAIA,gBAAAA;CACxB,IAAI,CAAC,KAAK,OAAO,CAAC;CAElB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,QAAAA,CAAQ,GAAG,GACnC,QAAQ,SAAS,OAAA,GAAMC,iBAAAA,SAAAA,EAAAA,GAASC,UAAAA,KAAAA,CAAK,KAAK,IAAI,GAAG,MAAM,EAAA,CAAG,KAAK;CAEhE,OAAO;AACR;AAEA,eAAe,OAAsB;CACpC,IAAI;EACH,MAAM,UAAU,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI;EAKlD,MAAMC,sBAAAA,yBAAyB;EAK/B,MAAM,UAA2C,CAAC;EAClD,IAAI,QAAQ,SAAS,SAAS,GAC7B,MAAMC,iBAAAA,SAAS;GACd,UAAU,QAAQ;GAClB,KAAK,QAAQ;GACb;EACD,CAAC;EAGF,MAAM,OAAO,MAAMC,kBAAAA,iBAAiB;GACnC,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB;GACA,KAAK,MAAM,eAAe;EAC3B,CAAC;EAED,sBAAA,OAAO;GACN,QAAQ;GACR,MAAM,KAAK,KAAK,EAAE,QAAQ,eAAe;IACxC,YAAY,OAAO;IACnB;GACD,EAAE;EACH,CAAC;CACF,SAAS,OAAO;EACf,sBAAA,OAAO;GAAE,QAAQ;GAAU,OAAOC,sBAAAA,UAAU,KAAK;EAAE,CAAC;CACrD;AACD;AAEK,KAAK"}
1
+ {"version":3,"file":"migrate-worker.cjs","names":["SECRETS_DIR_ENV","readdir","readFile","join","registerAdjacentTsconfig","discover","migrateDatabases","seedDatabases","errorData","SeedFailed"],"sources":["../../src/sandbox/migrate-worker.ts"],"sourcesContent":["/**\n * Applies a deployed stage's migrations, then runs its seeds, in a sandbox —\n * what `gkm seed` runs, against URLs the deploy hands it as secret files.\n *\n * Usage (by the Dokploy target's release, never by hand):\n * node --import=<tsx> migrate-worker.ts '{\"root\":\"…\",\"stage\":\"…\",\"manifest\":{…},\"patterns\":[…]}'\n *\n * Migrations and seeds are the project's own code, which is why they run\n * here rather than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,\n * named by its key, and is read into this process's memory only: never into\n * `process.env`, where a child the migration starts would inherit it.\n */\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\tmigrateDatabases,\n\tSeedFailed,\n\tseedDatabases,\n} from '../migrate/databases';\nimport { type ConstructSource, discover } from '../reconcile/discover';\nimport { SECRETS_DIR_ENV } from './sandbox';\nimport { answer, errorData, registerAdjacentTsconfig } from './workerRuntime';\n\n/** Every secret file the sandbox mounted, by name. */\nasync function mountedSecrets(): Promise<Record<string, string>> {\n\tconst dir = process.env[SECRETS_DIR_ENV];\n\tif (!dir) return {};\n\n\tconst secrets: Record<string, string> = {};\n\tfor (const name of await readdir(dir)) {\n\t\tsecrets[name] = (await readFile(join(dir, name), 'utf8')).trim();\n\t}\n\treturn secrets;\n}\n\nasync function main(): Promise<void> {\n\ttry {\n\t\tconst request = JSON.parse(process.argv[2] ?? '{}') as {\n\t\t\troot: string;\n\t\t\tstage: string;\n\t\t\tmanifest: ConstructManifest;\n\t\t\tpatterns: string[];\n\t\t};\n\t\tawait registerAdjacentTsconfig();\n\n\t\t// Where each construct is declared, so a migration runs with the Kysely\n\t\t// its own file resolves. The manifest itself is the deploy's: what it\n\t\t// provisioned is what gets migrated, not a second reading of the files.\n\t\tconst sources: Record<string, ConstructSource> = {};\n\t\tif (request.patterns.length > 0) {\n\t\t\tawait discover({\n\t\t\t\tpatterns: request.patterns,\n\t\t\t\tcwd: request.root,\n\t\t\t\tsources,\n\t\t\t});\n\t\t}\n\n\t\tconst options = {\n\t\t\troot: request.root,\n\t\t\tmanifest: request.manifest,\n\t\t\tsources,\n\t\t\tenv: await mountedSecrets(),\n\t\t};\n\t\tconst runs = await migrateDatabases(options);\n\t\t// Every seed, every time, after the schema it was written for.\n\t\tconst seeds = await seedDatabases({ ...options, stage: request.stage });\n\n\t\tanswer({\n\t\t\treason: 'migrated',\n\t\t\truns: runs.map(({ target, applied }) => ({\n\t\t\t\tconstruct: target.id,\n\t\t\t\tmigrations: target.migrations,\n\t\t\t\tapplied,\n\t\t\t})),\n\t\t\tseeds: seeds.map(({ target, seeded }) => ({\n\t\t\t\tconstruct: target.id,\n\t\t\t\tseeds: target.seeds,\n\t\t\t\tseeded,\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\t// A seed's cause is the database's error — an Error, which `errorData`\n\t\t// leaves out — and it is what says what to fix.\n\t\tanswer({\n\t\t\treason: 'failed',\n\t\t\terror: {\n\t\t\t\t...errorData(error),\n\t\t\t\t...(error instanceof SeedFailed\n\t\t\t\t\t? { cause: errorData(error.cause) }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}\n}\n\nvoid main();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA,eAAe,iBAAkD;CAChE,MAAM,MAAM,QAAQ,IAAIA,gBAAAA;CACxB,IAAI,CAAC,KAAK,OAAO,CAAC;CAElB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,QAAAA,CAAQ,GAAG,GACnC,QAAQ,SAAS,OAAA,GAAMC,iBAAAA,SAAAA,EAAAA,GAASC,UAAAA,KAAAA,CAAK,KAAK,IAAI,GAAG,MAAM,EAAA,CAAG,KAAK;CAEhE,OAAO;AACR;AAEA,eAAe,OAAsB;CACpC,IAAI;EACH,MAAM,UAAU,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI;EAMlD,MAAMC,sBAAAA,yBAAyB;EAK/B,MAAM,UAA2C,CAAC;EAClD,IAAI,QAAQ,SAAS,SAAS,GAC7B,MAAMC,iBAAAA,SAAS;GACd,UAAU,QAAQ;GAClB,KAAK,QAAQ;GACb;EACD,CAAC;EAGF,MAAM,UAAU;GACf,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB;GACA,KAAK,MAAM,eAAe;EAC3B;EACA,MAAM,OAAO,MAAMC,kBAAAA,iBAAiB,OAAO;EAE3C,MAAM,QAAQ,MAAMC,kBAAAA,cAAc;GAAE,GAAG;GAAS,OAAO,QAAQ;EAAM,CAAC;EAEtE,sBAAA,OAAO;GACN,QAAQ;GACR,MAAM,KAAK,KAAK,EAAE,QAAQ,eAAe;IACxC,WAAW,OAAO;IAClB,YAAY,OAAO;IACnB;GACD,EAAE;GACF,OAAO,MAAM,KAAK,EAAE,QAAQ,cAAc;IACzC,WAAW,OAAO;IAClB,OAAO,OAAO;IACd;GACD,EAAE;EACH,CAAC;CACF,SAAS,OAAO;EAGf,sBAAA,OAAO;GACN,QAAQ;GACR,OAAO;IACN,GAAGC,sBAAAA,UAAU,KAAK;IAClB,GAAI,iBAAiBC,kBAAAA,aAClB,EAAE,OAAOD,sBAAAA,UAAU,MAAM,KAAK,EAAE,IAChC,CAAC;GACL;EACD,CAAC;CACF;AACD;AAEK,KAAK"}
@@ -1,19 +1,19 @@
1
1
  import { r as discover } from "../discover-BPelzeGW.mjs";
2
2
  import { t as SECRETS_DIR_ENV } from "../sandbox-Dm247NGx.mjs";
3
3
  import { a as registerAdjacentTsconfig, n as answer, r as errorData } from "../workerRuntime-CsOyBRx2.mjs";
4
- import { u as migrateDatabases } from "../databases-hUHTuwhx.mjs";
4
+ import { o as SeedFailed, p as seedDatabases, u as migrateDatabases } from "../databases-CzszQV0N.mjs";
5
5
  import { join } from "node:path";
6
6
  import { readFile, readdir } from "node:fs/promises";
7
7
  //#region src/sandbox/migrate-worker.ts
8
8
  /**
9
- * Applies a deployed stage's migrations in a sandbox — the migrator
10
- * `gkm migrate` runs, against URLs the deploy hands it as secret files.
9
+ * Applies a deployed stage's migrations, then runs its seeds, in a sandbox —
10
+ * what `gkm seed` runs, against URLs the deploy hands it as secret files.
11
11
  *
12
12
  * Usage (by the Dokploy target's release, never by hand):
13
- * node --import=<tsx> migrate-worker.ts '{"root":"…","manifest":{…},"patterns":[…]}'
13
+ * node --import=<tsx> migrate-worker.ts '{"root":"…","stage":"…","manifest":{…},"patterns":[…]}'
14
14
  *
15
- * Migrations are the project's own code, which is why they run here rather
16
- * than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,
15
+ * Migrations and seeds are the project's own code, which is why they run
16
+ * here rather than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,
17
17
  * named by its key, and is read into this process's memory only: never into
18
18
  * `process.env`, where a child the migration starts would inherit it.
19
19
  */
@@ -35,23 +35,37 @@ async function main() {
35
35
  cwd: request.root,
36
36
  sources
37
37
  });
38
- const runs = await migrateDatabases({
38
+ const options = {
39
39
  root: request.root,
40
40
  manifest: request.manifest,
41
41
  sources,
42
42
  env: await mountedSecrets()
43
+ };
44
+ const runs = await migrateDatabases(options);
45
+ const seeds = await seedDatabases({
46
+ ...options,
47
+ stage: request.stage
43
48
  });
44
49
  answer({
45
50
  reason: "migrated",
46
51
  runs: runs.map(({ target, applied }) => ({
52
+ construct: target.id,
47
53
  migrations: target.migrations,
48
54
  applied
55
+ })),
56
+ seeds: seeds.map(({ target, seeded }) => ({
57
+ construct: target.id,
58
+ seeds: target.seeds,
59
+ seeded
49
60
  }))
50
61
  });
51
62
  } catch (error) {
52
63
  answer({
53
64
  reason: "failed",
54
- error: errorData(error)
65
+ error: {
66
+ ...errorData(error),
67
+ ...error instanceof SeedFailed ? { cause: errorData(error.cause) } : {}
68
+ }
55
69
  });
56
70
  }
57
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrate-worker.mjs","names":[],"sources":["../../src/sandbox/migrate-worker.ts"],"sourcesContent":["/**\n * Applies a deployed stage's migrations in a sandbox — the migrator\n * `gkm migrate` runs, against URLs the deploy hands it as secret files.\n *\n * Usage (by the Dokploy target's release, never by hand):\n * node --import=<tsx> migrate-worker.ts '{\"root\":\"…\",\"manifest\":{…},\"patterns\":[…]}'\n *\n * Migrations are the project's own code, which is why they run here rather\n * than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,\n * named by its key, and is read into this process's memory only: never into\n * `process.env`, where a child the migration starts would inherit it.\n */\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport { migrateDatabases } from '../migrate/databases';\nimport { type ConstructSource, discover } from '../reconcile/discover';\nimport { SECRETS_DIR_ENV } from './sandbox';\nimport { answer, errorData, registerAdjacentTsconfig } from './workerRuntime';\n\n/** Every secret file the sandbox mounted, by name. */\nasync function mountedSecrets(): Promise<Record<string, string>> {\n\tconst dir = process.env[SECRETS_DIR_ENV];\n\tif (!dir) return {};\n\n\tconst secrets: Record<string, string> = {};\n\tfor (const name of await readdir(dir)) {\n\t\tsecrets[name] = (await readFile(join(dir, name), 'utf8')).trim();\n\t}\n\treturn secrets;\n}\n\nasync function main(): Promise<void> {\n\ttry {\n\t\tconst request = JSON.parse(process.argv[2] ?? '{}') as {\n\t\t\troot: string;\n\t\t\tmanifest: ConstructManifest;\n\t\t\tpatterns: string[];\n\t\t};\n\t\tawait registerAdjacentTsconfig();\n\n\t\t// Where each construct is declared, so a migration runs with the Kysely\n\t\t// its own file resolves. The manifest itself is the deploy's: what it\n\t\t// provisioned is what gets migrated, not a second reading of the files.\n\t\tconst sources: Record<string, ConstructSource> = {};\n\t\tif (request.patterns.length > 0) {\n\t\t\tawait discover({\n\t\t\t\tpatterns: request.patterns,\n\t\t\t\tcwd: request.root,\n\t\t\t\tsources,\n\t\t\t});\n\t\t}\n\n\t\tconst runs = await migrateDatabases({\n\t\t\troot: request.root,\n\t\t\tmanifest: request.manifest,\n\t\t\tsources,\n\t\t\tenv: await mountedSecrets(),\n\t\t});\n\n\t\tanswer({\n\t\t\treason: 'migrated',\n\t\t\truns: runs.map(({ target, applied }) => ({\n\t\t\t\tmigrations: target.migrations,\n\t\t\t\tapplied,\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\tanswer({ reason: 'failed', error: errorData(error) });\n\t}\n}\n\nvoid main();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,eAAe,iBAAkD;CAChE,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,CAAC,KAAK,OAAO,CAAC;CAElB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,MAAM,QAAQ,GAAG,GACnC,QAAQ,SAAS,MAAM,SAAS,KAAK,KAAK,IAAI,GAAG,MAAM,EAAA,CAAG,KAAK;CAEhE,OAAO;AACR;AAEA,eAAe,OAAsB;CACpC,IAAI;EACH,MAAM,UAAU,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI;EAKlD,MAAM,yBAAyB;EAK/B,MAAM,UAA2C,CAAC;EAClD,IAAI,QAAQ,SAAS,SAAS,GAC7B,MAAM,SAAS;GACd,UAAU,QAAQ;GAClB,KAAK,QAAQ;GACb;EACD,CAAC;EAGF,MAAM,OAAO,MAAM,iBAAiB;GACnC,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB;GACA,KAAK,MAAM,eAAe;EAC3B,CAAC;EAED,OAAO;GACN,QAAQ;GACR,MAAM,KAAK,KAAK,EAAE,QAAQ,eAAe;IACxC,YAAY,OAAO;IACnB;GACD,EAAE;EACH,CAAC;CACF,SAAS,OAAO;EACf,OAAO;GAAE,QAAQ;GAAU,OAAO,UAAU,KAAK;EAAE,CAAC;CACrD;AACD;AAEK,KAAK"}
1
+ {"version":3,"file":"migrate-worker.mjs","names":[],"sources":["../../src/sandbox/migrate-worker.ts"],"sourcesContent":["/**\n * Applies a deployed stage's migrations, then runs its seeds, in a sandbox —\n * what `gkm seed` runs, against URLs the deploy hands it as secret files.\n *\n * Usage (by the Dokploy target's release, never by hand):\n * node --import=<tsx> migrate-worker.ts '{\"root\":\"…\",\"stage\":\"…\",\"manifest\":{…},\"patterns\":[…]}'\n *\n * Migrations and seeds are the project's own code, which is why they run\n * here rather than in the deploy. Each owner URL arrives as a file in `GKM_SECRETS_DIR`,\n * named by its key, and is read into this process's memory only: never into\n * `process.env`, where a child the migration starts would inherit it.\n */\n\nimport { readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { ConstructManifest } from '@geekmidas/manifest';\nimport {\n\tmigrateDatabases,\n\tSeedFailed,\n\tseedDatabases,\n} from '../migrate/databases';\nimport { type ConstructSource, discover } from '../reconcile/discover';\nimport { SECRETS_DIR_ENV } from './sandbox';\nimport { answer, errorData, registerAdjacentTsconfig } from './workerRuntime';\n\n/** Every secret file the sandbox mounted, by name. */\nasync function mountedSecrets(): Promise<Record<string, string>> {\n\tconst dir = process.env[SECRETS_DIR_ENV];\n\tif (!dir) return {};\n\n\tconst secrets: Record<string, string> = {};\n\tfor (const name of await readdir(dir)) {\n\t\tsecrets[name] = (await readFile(join(dir, name), 'utf8')).trim();\n\t}\n\treturn secrets;\n}\n\nasync function main(): Promise<void> {\n\ttry {\n\t\tconst request = JSON.parse(process.argv[2] ?? '{}') as {\n\t\t\troot: string;\n\t\t\tstage: string;\n\t\t\tmanifest: ConstructManifest;\n\t\t\tpatterns: string[];\n\t\t};\n\t\tawait registerAdjacentTsconfig();\n\n\t\t// Where each construct is declared, so a migration runs with the Kysely\n\t\t// its own file resolves. The manifest itself is the deploy's: what it\n\t\t// provisioned is what gets migrated, not a second reading of the files.\n\t\tconst sources: Record<string, ConstructSource> = {};\n\t\tif (request.patterns.length > 0) {\n\t\t\tawait discover({\n\t\t\t\tpatterns: request.patterns,\n\t\t\t\tcwd: request.root,\n\t\t\t\tsources,\n\t\t\t});\n\t\t}\n\n\t\tconst options = {\n\t\t\troot: request.root,\n\t\t\tmanifest: request.manifest,\n\t\t\tsources,\n\t\t\tenv: await mountedSecrets(),\n\t\t};\n\t\tconst runs = await migrateDatabases(options);\n\t\t// Every seed, every time, after the schema it was written for.\n\t\tconst seeds = await seedDatabases({ ...options, stage: request.stage });\n\n\t\tanswer({\n\t\t\treason: 'migrated',\n\t\t\truns: runs.map(({ target, applied }) => ({\n\t\t\t\tconstruct: target.id,\n\t\t\t\tmigrations: target.migrations,\n\t\t\t\tapplied,\n\t\t\t})),\n\t\t\tseeds: seeds.map(({ target, seeded }) => ({\n\t\t\t\tconstruct: target.id,\n\t\t\t\tseeds: target.seeds,\n\t\t\t\tseeded,\n\t\t\t})),\n\t\t});\n\t} catch (error) {\n\t\t// A seed's cause is the database's error — an Error, which `errorData`\n\t\t// leaves out — and it is what says what to fix.\n\t\tanswer({\n\t\t\treason: 'failed',\n\t\t\terror: {\n\t\t\t\t...errorData(error),\n\t\t\t\t...(error instanceof SeedFailed\n\t\t\t\t\t? { cause: errorData(error.cause) }\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t});\n\t}\n}\n\nvoid main();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA0BA,eAAe,iBAAkD;CAChE,MAAM,MAAM,QAAQ,IAAI;CACxB,IAAI,CAAC,KAAK,OAAO,CAAC;CAElB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,QAAQ,MAAM,QAAQ,GAAG,GACnC,QAAQ,SAAS,MAAM,SAAS,KAAK,KAAK,IAAI,GAAG,MAAM,EAAA,CAAG,KAAK;CAEhE,OAAO;AACR;AAEA,eAAe,OAAsB;CACpC,IAAI;EACH,MAAM,UAAU,KAAK,MAAM,QAAQ,KAAK,MAAM,IAAI;EAMlD,MAAM,yBAAyB;EAK/B,MAAM,UAA2C,CAAC;EAClD,IAAI,QAAQ,SAAS,SAAS,GAC7B,MAAM,SAAS;GACd,UAAU,QAAQ;GAClB,KAAK,QAAQ;GACb;EACD,CAAC;EAGF,MAAM,UAAU;GACf,MAAM,QAAQ;GACd,UAAU,QAAQ;GAClB;GACA,KAAK,MAAM,eAAe;EAC3B;EACA,MAAM,OAAO,MAAM,iBAAiB,OAAO;EAE3C,MAAM,QAAQ,MAAM,cAAc;GAAE,GAAG;GAAS,OAAO,QAAQ;EAAM,CAAC;EAEtE,OAAO;GACN,QAAQ;GACR,MAAM,KAAK,KAAK,EAAE,QAAQ,eAAe;IACxC,WAAW,OAAO;IAClB,YAAY,OAAO;IACnB;GACD,EAAE;GACF,OAAO,MAAM,KAAK,EAAE,QAAQ,cAAc;IACzC,WAAW,OAAO;IAClB,OAAO,OAAO;IACd;GACD,EAAE;EACH,CAAC;CACF,SAAS,OAAO;EAGf,OAAO;GACN,QAAQ;GACR,OAAO;IACN,GAAG,UAAU,KAAK;IAClB,GAAI,iBAAiB,aAClB,EAAE,OAAO,UAAU,MAAM,KAAK,EAAE,IAChC,CAAC;GACL;EACD,CAAC;CACF;AACD;AAEK,KAAK"}
@@ -5,7 +5,7 @@ import { t as appKey } from "./derive-B4vDpzgP.mjs";
5
5
  import { O as TEST_STAGE, R as UnknownSecretsStoreProvider, h as getPublicEnvPrefix, m as PUBLIC_ENV_PREFIXES, n as allConstructGlobs } from "./workspace-BBdqmkch.mjs";
6
6
  import { ConfigNotFound, NotInAnApp, loadWorkspaceAppInfo, loadWorkspaceConfig } from "./config.mjs";
7
7
  import { n as runtimeFor, r as generateTelemetryModule } from "./EndpointGenerator-DftalLYg.mjs";
8
- import { c as runtimeOf } from "./resolve-mvaystiE.mjs";
8
+ import { c as runtimeOf } from "./resolve-CHwetPdo.mjs";
9
9
  import { a as DEFAULT_STORAGE, i as DEFAULT_EVENTS$1, n as readFakes, o as holdsEveryCache, r as DEFAULT_CACHE, t as SubscriberGenerator } from "./SubscriberGenerator-5looQ3gB.mjs";
10
10
  import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
11
11
  import { constants, existsSync, readFileSync } from "node:fs";
@@ -6577,6 +6577,64 @@ function assertNoStaleSecrets(options) {
6577
6577
  if (stale.length > 0) throw new StaleStageSecrets(options.stage, stale);
6578
6578
  }
6579
6579
  //#endregion
6580
- export { workspace_exports as $, readKey as $t, DevServicesNeedServerTarget as A, eventsBackendFor as At, requiredStageKeys as B, findAvailablePort as Bt, validateImageRef as C, TURBO_VERSION as Ct, isOtlpDestination as D, imageBuildCredentials as Dt, resolveHost as E, findBuildRoot as Et, devServicesUsed as F, fakeKey as Ft, workerEntryDir as G, isRemoteStore as Gt, workerUnits as H, loadEnvFiles as Ht, externalServices as I, portKeys as It, FAKE_ENV as J, store_exports as Jt, QueueGenerator as K, secretsStoreFor as Kt, manifestServiceDeclarations as L, primaryPortKey as Lt, STORAGE_KEY_PAIR as M, storageBackendFor as Mt, UnknownDevService as N, DEFAULT_IMAGES as Nt, otelEnv as O, isImageBuild as Ot, assertExternalServices as P, describeServices as Pt, reconcileWorkspace as Q, projectKey as Qt, parseDevServices as R, createCredentialsPreload as Rt, workerDockerfileOf as S, imageLayout as St, isMainFrontendApp as T, detectPackageManager as Tt, WorkerGenerator as U, loadSecretsForApp as Ut, suppliedOnly as V, isPortAvailable as Vt, workerBundleName as W, prepareEntryCredentials as Wt, constructGlobs as X, getKeyPath as Xt, backendsOf as Y, FileSecretsStore as Yt, derivedContainers as Z, keystoreProject as Zt, DockerPushFailed as _, localRolePassword as _t, isDnsVerified as a, markerOf as an, bucketPolicies as at, ensureDockerignore as b, hostFor as bt, setApplicationId as c, initStageSecrets as cn, quoteIdentifier as ct, setDnsVerification as d, toEmbeddableSecrets as dn, pgClient as dt, applicationName as en, LOCAL_CA_PATH as et, setGeneratedSecret as f, withCustomSecret as fn, appEnvKeys as ft, DockerBuildFailed as g, envFor as gt, withGeneratedSecrets as h, workerEnvKeys as ht, getGeneratedSecret as i, isOwnedBy as in, applyPostgres as it, ExternalServicesNotConfigured as j, providerOf as jt, DEV_SERVICES as k, cacheBackendFor as kt, setBackupState as l, maskPassword as ln, composeFor as lt, DeployJournal as m, networkEnv as mt, createEmptyState as n, imageName as nn, applyBuckets as nt, recordRelease as o, ownershipMarker as on, postgresDatabaseNames as ot, setPostgresBackupId as p, dockerfileOf as pt, CronGenerator as q, storeFromConfig as qt, getBackupState as r, imageRef as rn, applyPolicies as rt, recordRollback as s, projectName as sn, postgresStatements as st, assertNoStaleSecrets as t, deployIdentity as tn, forgetState as tt, setDnsRecord as u, storage_exports as un, bucketClient as ut, appDockerfile as v, planFor as vt, NoDomainForStage as w, WORKER_PORT as wt, workerDockerfile as x, composeBuildPaths as xt, dockerCommand as y, resourceName as yt, reportDevServices as z, createEntryWrapper as zt };
6580
+ //#region src/target/seeds.ts
6581
+ /** A seed of a deployed stage failed; the release stopped before any app. */
6582
+ var DeploySeedsFailed = class extends Error {
6583
+ stage;
6584
+ construct;
6585
+ seed;
6586
+ cause;
6587
+ constructor(stage, construct, seed, cause) {
6588
+ super(`Seeding "${stage}" failed, so no app was released: ${construct}'s seed '${seed}' failed — ${causeMessage(cause)}. Its writes were rolled back; the migrations and the seeds before it stay applied. Seeds run on every deploy, so each must be an idempotent upsert: fix it and deploy again.`);
6589
+ this.stage = stage;
6590
+ this.construct = construct;
6591
+ this.seed = seed;
6592
+ this.cause = cause;
6593
+ this.name = "DeploySeedsFailed";
6594
+ }
6595
+ };
6596
+ /**
6597
+ * What went wrong underneath: a `SeedFailed`'s own cause (the database's
6598
+ * error), or — from a sandbox, where errors arrive as data — the same.
6599
+ */
6600
+ function causeMessage(cause) {
6601
+ const message = (value) => value && typeof value === "object" && "message" in value ? String(value.message) : void 0;
6602
+ return (cause && typeof cause === "object" && "cause" in cause ? message(cause.cause) : void 0) ?? message(cause) ?? String(cause);
6603
+ }
6604
+ /**
6605
+ * Say what a deploy's migrations and seeds did: a line per construct with
6606
+ * something applied or run — `🌱 db/database/seeds: ran 2`, then each seed —
6607
+ * and a `migration.applied` or `seed.ran` event beside it.
6608
+ */
6609
+ function reportDatabaseRuns(migrations, seeds, log, emit) {
6610
+ for (const { construct, folder, applied } of migrations) {
6611
+ if (applied.length === 0) continue;
6612
+ log(`🗄️ ${folder}: applied ${applied.length}`);
6613
+ for (const name of applied) log(` ✓ ${name}`);
6614
+ emit({
6615
+ type: "migration.applied",
6616
+ construct,
6617
+ folder,
6618
+ applied: [...applied]
6619
+ });
6620
+ }
6621
+ for (const { construct, folder, seeded } of seeds) {
6622
+ if (seeded.length === 0) continue;
6623
+ log(`🌱 ${folder}: ran ${seeded.length}`);
6624
+ for (const name of seeded) log(` ✓ ${name}`);
6625
+ emit({
6626
+ type: "seed.ran",
6627
+ construct,
6628
+ folder,
6629
+ seeded: [...seeded]
6630
+ });
6631
+ }
6632
+ }
6633
+ /** What a dry run lists: the seeds a deploy would run, construct by construct. */
6634
+ function reportPlannedSeeds(planned, log) {
6635
+ for (const { folder, seeds } of planned) log(`🌱 ${folder}: would run ${seeds.length} (${seeds.join(", ")})`);
6636
+ }
6637
+ //#endregion
6638
+ export { constructGlobs as $, getKeyPath as $t, isOtlpDestination as A, imageBuildCredentials as At, manifestServiceDeclarations as B, primaryPortKey as Bt, ensureDockerignore as C, hostFor as Ct, NoDomainForStage as D, WORKER_PORT as Dt, validateImageRef as E, TURBO_VERSION as Et, STORAGE_KEY_PAIR as F, storageBackendFor as Ft, workerUnits as G, loadEnvFiles as Gt, reportDevServices as H, createEntryWrapper as Ht, UnknownDevService as I, DEFAULT_IMAGES as It, workerEntryDir as J, isRemoteStore as Jt, WorkerGenerator as K, loadSecretsForApp as Kt, assertExternalServices as L, describeServices as Lt, DEV_SERVICES as M, cacheBackendFor as Mt, DevServicesNeedServerTarget as N, eventsBackendFor as Nt, isMainFrontendApp as O, detectPackageManager as Ot, ExternalServicesNotConfigured as P, providerOf as Pt, backendsOf as Q, FileSecretsStore as Qt, devServicesUsed as R, fakeKey as Rt, dockerCommand as S, resourceName as St, workerDockerfileOf as T, imageLayout as Tt, requiredStageKeys as U, findAvailablePort as Ut, parseDevServices as V, createCredentialsPreload as Vt, suppliedOnly as W, isPortAvailable as Wt, CronGenerator as X, storeFromConfig as Xt, QueueGenerator as Y, secretsStoreFor as Yt, FAKE_ENV as Z, store_exports as Zt, DeployJournal as _, networkEnv as _t, createEmptyState as a, imageName as an, applyBuckets as at, DockerPushFailed as b, localRolePassword as bt, isDnsVerified as c, markerOf as cn, bucketPolicies as ct, setApplicationId as d, initStageSecrets as dn, quoteIdentifier as dt, keystoreProject as en, derivedContainers as et, setBackupState as f, maskPassword as fn, composeFor as ft, setPostgresBackupId as g, dockerfileOf as gt, setGeneratedSecret as h, withCustomSecret as hn, appEnvKeys as ht, assertNoStaleSecrets as i, deployIdentity as in, forgetState as it, otelEnv as j, isImageBuild as jt, resolveHost as k, findBuildRoot as kt, recordRelease as l, ownershipMarker as ln, postgresDatabaseNames as lt, setDnsVerification as m, toEmbeddableSecrets as mn, pgClient as mt, reportDatabaseRuns as n, readKey as nn, workspace_exports as nt, getBackupState as o, imageRef as on, applyPolicies as ot, setDnsRecord as p, storage_exports as pn, bucketClient as pt, workerBundleName as q, prepareEntryCredentials as qt, reportPlannedSeeds as r, applicationName as rn, LOCAL_CA_PATH as rt, getGeneratedSecret as s, isOwnedBy as sn, applyPostgres as st, DeploySeedsFailed as t, projectKey as tn, reconcileWorkspace as tt, recordRollback as u, projectName as un, postgresStatements as ut, withGeneratedSecrets as v, workerEnvKeys as vt, workerDockerfile as w, composeBuildPaths as wt, appDockerfile as x, planFor as xt, DockerBuildFailed as y, envFor as yt, externalServices as z, portKeys as zt };
6581
6639
 
6582
- //# sourceMappingURL=stale-C5FqIVc8.mjs.map
6640
+ //# sourceMappingURL=seeds-DiXON7R8.mjs.map