@geekmidas/cli 10.0.0-alpha.36 → 10.0.0-alpha.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ const require_discover = require("./discover-CroTIm0K.cjs");
5
5
  const require_config = require("./config-DgAHy8nY.cjs");
6
6
  const require_workspace = require("./workspace-CAJk6UmC.cjs");
7
7
  const require_storage = require("./storage-C2JC31V9.cjs");
8
- const require_workspace$1 = require("./workspace-C0X8xSXV.cjs");
8
+ const require_workspace$1 = require("./workspace-DUhLejv4.cjs");
9
9
  const require_OpenApiTsGenerator = require("./OpenApiTsGenerator-D1nhN98m.cjs");
10
10
  const require_openapi = require("./openapi.cjs");
11
11
  const require_ready = require("./ready-CXhoutix.cjs");
@@ -42,7 +42,7 @@ let _geekmidas_constructs_subscribers = require("@geekmidas/constructs/subscribe
42
42
  let _geekmidas_constructs_topic = require("@geekmidas/constructs/topic");
43
43
  let node_dns_promises = require("node:dns/promises");
44
44
  //#region package.json
45
- var version = "10.0.0-alpha.36";
45
+ var version = "10.0.0-alpha.37";
46
46
  //#endregion
47
47
  //#region src/auth/credentials.ts
48
48
  /**
@@ -1092,9 +1092,9 @@ async function workspaceDevCommand(workspace, options) {
1092
1092
  ...reconciled.env
1093
1093
  };
1094
1094
  if (options.migrate || options.seed) {
1095
- const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs"));
1095
+ const { prepareDevDatabases } = await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs"));
1096
1096
  await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
1097
- } else await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
1097
+ } else await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs")).then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
1098
1098
  logger$10.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
1099
1099
  });
1100
1100
  const appUrls = {};
@@ -8809,26 +8809,26 @@ function loadPackageJson() {
8809
8809
  * Run: pnpm --filter @geekmidas/cli sync-versions
8810
8810
  */
8811
8811
  const GEEKMIDAS_VERSIONS = {
8812
- "@geekmidas/audit": "~10.0.0-alpha.36",
8813
- "@geekmidas/auth": "~10.0.0-alpha.36",
8814
- "@geekmidas/cache": "~10.0.0-alpha.36",
8815
- "@geekmidas/client": "~10.0.0-alpha.36",
8816
- "@geekmidas/cloud": "~10.0.0-alpha.36",
8817
- "@geekmidas/constructs": "~10.0.0-alpha.36",
8818
- "@geekmidas/db": "~10.0.0-alpha.36",
8819
- "@geekmidas/emailkit": "~10.0.0-alpha.36",
8820
- "@geekmidas/envkit": "~10.0.0-alpha.36",
8821
- "@geekmidas/errors": "~10.0.0-alpha.36",
8822
- "@geekmidas/events": "~10.0.0-alpha.36",
8823
- "@geekmidas/logger": "~10.0.0-alpha.36",
8824
- "@geekmidas/manifest": "~10.0.0-alpha.36",
8825
- "@geekmidas/rate-limit": "~10.0.0-alpha.36",
8826
- "@geekmidas/schema": "~10.0.0-alpha.36",
8827
- "@geekmidas/services": "~10.0.0-alpha.36",
8828
- "@geekmidas/storage": "~10.0.0-alpha.36",
8829
- "@geekmidas/studio": "~10.0.0-alpha.36",
8830
- "@geekmidas/telescope": "~10.0.0-alpha.36",
8831
- "@geekmidas/testkit": "~10.0.0-alpha.36",
8812
+ "@geekmidas/audit": "~10.0.0-alpha.37",
8813
+ "@geekmidas/auth": "~10.0.0-alpha.37",
8814
+ "@geekmidas/cache": "~10.0.0-alpha.37",
8815
+ "@geekmidas/client": "~10.0.0-alpha.37",
8816
+ "@geekmidas/cloud": "~10.0.0-alpha.37",
8817
+ "@geekmidas/constructs": "~10.0.0-alpha.37",
8818
+ "@geekmidas/db": "~10.0.0-alpha.37",
8819
+ "@geekmidas/emailkit": "~10.0.0-alpha.37",
8820
+ "@geekmidas/envkit": "~10.0.0-alpha.37",
8821
+ "@geekmidas/errors": "~10.0.0-alpha.37",
8822
+ "@geekmidas/events": "~10.0.0-alpha.37",
8823
+ "@geekmidas/logger": "~10.0.0-alpha.37",
8824
+ "@geekmidas/manifest": "~10.0.0-alpha.37",
8825
+ "@geekmidas/rate-limit": "~10.0.0-alpha.37",
8826
+ "@geekmidas/schema": "~10.0.0-alpha.37",
8827
+ "@geekmidas/services": "~10.0.0-alpha.37",
8828
+ "@geekmidas/storage": "~10.0.0-alpha.37",
8829
+ "@geekmidas/studio": "~10.0.0-alpha.37",
8830
+ "@geekmidas/telescope": "~10.0.0-alpha.37",
8831
+ "@geekmidas/testkit": "~10.0.0-alpha.37",
8832
8832
  "@geekmidas/cli": `~${loadPackageJson().version}`
8833
8833
  };
8834
8834
  //#endregion
@@ -15160,7 +15160,7 @@ var NoStoredSecrets = class extends Error {
15160
15160
  }
15161
15161
  };
15162
15162
  async function reconcile(secrets, workspace, stage) {
15163
- const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-C0X8xSXV.cjs")).then((n) => n.workspace_exports);
15163
+ const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-DUhLejv4.cjs")).then((n) => n.workspace_exports);
15164
15164
  const result = require_reconcile.reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
15165
15165
  return result ? {
15166
15166
  secrets: result.secrets,
@@ -15459,6 +15459,56 @@ function printSummary(workspace, stage) {
15459
15459
  logger$1.log("");
15460
15460
  }
15461
15461
  //#endregion
15462
+ //#region src/test/teardown.ts
15463
+ /**
15464
+ * Dropping the test stage's databases when a suite ends.
15465
+ *
15466
+ * Reconcile never drops — the line it draws is at data. The test stage's data
15467
+ * is the exception: every test runs in a transaction rolled back after it, so
15468
+ * nothing in these databases is anyone's, and a database kept between runs is
15469
+ * one whose migrations already ran — an edited migration is never applied to
15470
+ * it again. So each run starts from a database it created, and drops it when
15471
+ * the suite ends: the Vitest global setup's teardown.
15472
+ */
15473
+ /**
15474
+ * Drop the databases the last setup recorded, and forget the test stage's
15475
+ * reconcile, so the next run provisions them from nothing.
15476
+ *
15477
+ * A no-op when nothing is recorded — no run yet, or one already torn down —
15478
+ * so running it twice, or before a setup, is harmless.
15479
+ */
15480
+ async function dropTestDatabases(cwd, root, sql = require_workspace$1.pgClient) {
15481
+ const readyPath = (0, node_path.join)(cwd, require_ready.TEST_READY_FILE);
15482
+ const ready = await readReady(readyPath);
15483
+ const recorded = ready?.databases;
15484
+ if (!ready || !recorded) return [];
15485
+ const client = sql(recorded.port);
15486
+ for (const name of recorded.names) {
15487
+ if (!name.endsWith(`_test`)) throw new NotATestDatabase(name);
15488
+ await client.query(void 0, `DROP DATABASE IF EXISTS ${require_workspace$1.quoteIdentifier(name)} WITH (FORCE)`);
15489
+ }
15490
+ await require_workspace$1.forgetState(root, require_workspace.TEST_STAGE);
15491
+ const { databases: _dropped, ...rest } = ready;
15492
+ await (0, node_fs_promises.writeFile)(readyPath, JSON.stringify(rest, null, 2));
15493
+ return recorded.names;
15494
+ }
15495
+ async function readReady(path) {
15496
+ try {
15497
+ return JSON.parse(await (0, node_fs_promises.readFile)(path, "utf-8"));
15498
+ } catch {
15499
+ return;
15500
+ }
15501
+ }
15502
+ /** A name recorded for the test stage without the test stage's suffix. */
15503
+ var NotATestDatabase = class extends Error {
15504
+ database;
15505
+ constructor(database) {
15506
+ super(`Refusing to drop '${database}': only the test stage's databases (named '…_${require_workspace.TEST_STAGE}') are dropped after a suite. Delete ${require_ready.TEST_READY_FILE} if it was edited by hand.`);
15507
+ this.database = database;
15508
+ this.name = "NotATestDatabase";
15509
+ }
15510
+ };
15511
+ //#endregion
15462
15512
  //#region src/test/index.ts
15463
15513
  /**
15464
15514
  * Run tests with secrets, dependency URLs, and .env files loaded.
@@ -15467,6 +15517,10 @@ function printSummary(workspace, stage) {
15467
15517
  async function testCommand(options = {}) {
15468
15518
  const cwd = process.cwd();
15469
15519
  const stage = options.stage ?? await require_config.loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace.stages.local).catch(() => void 0);
15520
+ if (options.teardown) {
15521
+ await teardown(cwd);
15522
+ return;
15523
+ }
15470
15524
  if (!stage) throw new NoStageToTest();
15471
15525
  console.log(`\n🧪 Running tests with ${stage} environment...\n`);
15472
15526
  if (options.autoSetup || Boolean(process.env.GKM_AUTO_SETUP)) {
@@ -15475,6 +15529,7 @@ async function testCommand(options = {}) {
15475
15529
  }
15476
15530
  const defaultEnv = require_workspace$1.loadEnvFiles(".env");
15477
15531
  if (defaultEnv.loaded.length > 0) console.log(` 📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
15532
+ if (!options.prepare) await teardown(cwd);
15478
15533
  const result = await require_workspace$1.prepareEntryCredentials({
15479
15534
  stage,
15480
15535
  startDocker: !options.prepare,
@@ -15515,7 +15570,8 @@ async function testCommand(options = {}) {
15515
15570
  const readyPath = (0, node_path.join)(cwd, require_ready.TEST_READY_FILE);
15516
15571
  await (0, node_fs_promises.writeFile)(readyPath, JSON.stringify({
15517
15572
  env: result.secretsJsonPath,
15518
- ...manifestPath ? { manifest: manifestPath } : {}
15573
+ ...manifestPath ? { manifest: manifestPath } : {},
15574
+ ...testDatabases(result.reconciled)
15519
15575
  }, null, 2));
15520
15576
  if (options.setup) {
15521
15577
  console.log(` 🧪 Test stage ready: ${require_ready.TEST_READY_FILE}`);
@@ -15554,12 +15610,29 @@ async function testCommand(options = {}) {
15554
15610
  });
15555
15611
  });
15556
15612
  }
15613
+ /** Drop what the last setup created — see `dropTestDatabases`. */
15614
+ async function teardown(cwd) {
15615
+ const dropped = await dropTestDatabases(cwd, await require_config.loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace.root).catch(() => cwd));
15616
+ if (dropped.length > 0) console.log(` 🧹 Dropped ${dropped.join(", ")}`);
15617
+ }
15618
+ /**
15619
+ * The test stage's Postgres databases, to drop when the suite ends — those
15620
+ * the plan provisions, on the port the shared container answers.
15621
+ */
15622
+ function testDatabases(reconciled) {
15623
+ const port = reconciled?.ports[require_workspace$1.primaryPortKey("postgres")];
15624
+ const names = (reconciled?.plan.resources ?? []).filter((resource) => resource.kind === "database" && resource.provisions && resource.container === "postgres").map((resource) => resource.name);
15625
+ return port !== void 0 && names.length > 0 ? { databases: {
15626
+ port,
15627
+ names
15628
+ } } : {};
15629
+ }
15557
15630
  /**
15558
15631
  * Migrate the test stage just reconciled, then seed it: a test run never
15559
15632
  * starts without the reference data the app needs.
15560
15633
  */
15561
15634
  async function migrateTestStage(workspace, env) {
15562
- const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs"));
15635
+ const { migrateAndSeed } = await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs"));
15563
15636
  const { discover } = await Promise.resolve().then(() => require("./discover-CroTIm0K.cjs")).then((n) => n.discover_exports);
15564
15637
  const sources = {};
15565
15638
  const manifest = await discover({
@@ -15987,7 +16060,7 @@ program.command("exec").description("Run a command with secrets injected into Cr
15987
16060
  process.exit(1);
15988
16061
  }
15989
16062
  });
15990
- program.command("test").description("Run tests with secrets loaded from environment").option("--stage <stage>", "Stage to load secrets from (default: stages.local)").option("--run", "Run tests once without watch mode").option("--watch", "Enable watch mode").option("--coverage", "Generate coverage report").option("--ui", "Open Vitest UI").option("--auto-setup", "Generate a fresh stage (secrets + key) from the workspace config when none exists (for CI; also via GKM_AUTO_SETUP)").option("--prepare", "Write the test manifest and #test harness, then stop — for a typecheck that runs before the suite").option("--setup", "Reconcile, migrate and seed the test stage and write the harness, then stop — what @geekmidas/cli/vitest runs").argument("[pattern]", "Pattern to filter tests").action(async (pattern, options) => {
16063
+ program.command("test").description("Run tests with secrets loaded from environment").option("--stage <stage>", "Stage to load secrets from (default: stages.local)").option("--run", "Run tests once without watch mode").option("--watch", "Enable watch mode").option("--coverage", "Generate coverage report").option("--ui", "Open Vitest UI").option("--auto-setup", "Generate a fresh stage (secrets + key) from the workspace config when none exists (for CI; also via GKM_AUTO_SETUP)").option("--prepare", "Write the test manifest and #test harness, then stop — for a typecheck that runs before the suite").option("--setup", "Reconcile, migrate and seed the test stage and write the harness, then stop — what @geekmidas/cli/vitest runs").option("--teardown", "Drop the test stage's databases the last setup created, then stop — what @geekmidas/cli/vitest runs when the suite ends").argument("[pattern]", "Pattern to filter tests").action(async (pattern, options) => {
15991
16064
  try {
15992
16065
  const globalOptions = program.opts();
15993
16066
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -16004,7 +16077,7 @@ program.command("migrate").description("Apply each database construct's migratio
16004
16077
  try {
16005
16078
  const globalOptions = program.opts();
16006
16079
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16007
- const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs"));
16080
+ const { migrateCommand } = await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs"));
16008
16081
  await migrateCommand({
16009
16082
  ...options,
16010
16083
  ...construct ? { construct } : {}
@@ -16018,7 +16091,7 @@ program.command("seed").description("Migrate, then run each database construct's
16018
16091
  try {
16019
16092
  const globalOptions = program.opts();
16020
16093
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16021
- const { seedCommand } = await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs"));
16094
+ const { seedCommand } = await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs"));
16022
16095
  await seedCommand({
16023
16096
  ...options,
16024
16097
  ...construct ? { construct } : {}
@@ -16032,7 +16105,7 @@ program.command("migration").description("Write a construct's next migration: an
16032
16105
  try {
16033
16106
  const globalOptions = program.opts();
16034
16107
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16035
- const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-BsW4xBEO.cjs"));
16108
+ const { migrationCommand } = await Promise.resolve().then(() => require("./migrate-Cgga-OGi.cjs"));
16036
16109
  await migrationCommand({
16037
16110
  construct,
16038
16111
  ...name ? { name } : {}
@@ -16200,7 +16273,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
16200
16273
  console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
16201
16274
  process.exit(1);
16202
16275
  }
16203
- const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-C0X8xSXV.cjs")).then((n) => n.workspace_exports);
16276
+ const { derivedContainers } = await Promise.resolve().then(() => require("./workspace-DUhLejv4.cjs")).then((n) => n.workspace_exports);
16204
16277
  const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
16205
16278
  if (!result) {
16206
16279
  console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);