@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 +105 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +105 -32
- package/dist/index.mjs.map +1 -1
- package/dist/{migrate-BsW4xBEO.cjs → migrate-Cgga-OGi.cjs} +2 -2
- package/dist/{migrate-BsW4xBEO.cjs.map → migrate-Cgga-OGi.cjs.map} +1 -1
- package/dist/{migrate-CT8b3nt_.mjs → migrate-_2J3lFT5.mjs} +2 -2
- package/dist/{migrate-CT8b3nt_.mjs.map → migrate-_2J3lFT5.mjs.map} +1 -1
- package/dist/ready-CXhoutix.cjs.map +1 -1
- package/dist/ready-D1BCiaYU.mjs.map +1 -1
- package/dist/vitest.cjs +7 -3
- package/dist/vitest.cjs.map +1 -1
- package/dist/vitest.d.cts +5 -4
- package/dist/vitest.d.cts.map +1 -1
- package/dist/vitest.d.mts +5 -4
- package/dist/vitest.d.mts.map +1 -1
- package/dist/vitest.mjs +7 -3
- package/dist/vitest.mjs.map +1 -1
- package/dist/{workspace-EmXwO2qM.mjs → workspace-BtXCL1C8.mjs} +13 -4
- package/dist/{workspace-EmXwO2qM.mjs.map → workspace-BtXCL1C8.mjs.map} +1 -1
- package/dist/{workspace-C0X8xSXV.cjs → workspace-DUhLejv4.cjs} +36 -3
- package/dist/workspace-DUhLejv4.cjs.map +1 -0
- package/package.json +14 -14
- package/dist/workspace-C0X8xSXV.cjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { c as isPartitionedRoutes, i as ConstructGenerator, t as discover } from
|
|
|
4
4
|
import { a as loadConfig, c as parseModuleConfig, i as loadAppConfig, l as appKey, r as getAppNameFromCwd, s as loadWorkspaceConfig, u as derivedApps } from "./config-Dss1WwtH.mjs";
|
|
5
5
|
import { D as assertDeployedStage, E as TEST_STAGE, O as deployedProblems, T as InvalidStages, a as getAppBuildOrder, b as getDeployTargetError, k as stageProblems, m as stripPublicPrefix, o as getAppGkmConfig, p as getPublicEnvPrefix, t as allConstructGlobs, x as isDeployTargetSupported } from "./workspace-CsL76tpc.mjs";
|
|
6
6
|
import { c as getKeyPath, i as setCustomSecret, n as readStageSecrets, o as toEmbeddableSecrets, r as secretsExist, s as writeStageSecrets, t as maskPassword } from "./storage-BjTLjDDp.mjs";
|
|
7
|
-
import { _ as
|
|
7
|
+
import { C as loadEnvFiles, S as isPortAvailable, T as prepareEntryCredentials, _ as providerOf, b as createEntryWrapper, c as forgetState, d as pgClient, f as resourceName, g as eventsBackendFor, h as cacheBackendFor, i as reconcileWorkspace, l as applyPostgres, m as primaryPortKey, n as constructGlobs, o as COMPOSE_PATH, p as rootSite, r as derivedContainers, s as LOCAL_CA_PATH, t as backendsOf, u as quoteIdentifier, v as storageBackendFor, w as loadSecretsForApp, x as findAvailablePort, y as createCredentialsPreload } from "./workspace-BtXCL1C8.mjs";
|
|
8
8
|
import { n as EndpointGenerator, r as runtimeFor } from "./OpenApiTsGenerator-hDINScnz.mjs";
|
|
9
9
|
import { generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi.mjs";
|
|
10
10
|
import { a as writeTestHarness, i as TEST_MANIFEST_ENV, n as TEST_READY_FILE, o as cacheBackendsIn, s as driversFor, t as TEST_READY_ENV } from "./ready-D1BCiaYU.mjs";
|
|
@@ -37,7 +37,7 @@ import { Subscriber } from "@geekmidas/constructs/subscribers";
|
|
|
37
37
|
import { Topic } from "@geekmidas/constructs/topic";
|
|
38
38
|
import { lookup } from "node:dns/promises";
|
|
39
39
|
//#region package.json
|
|
40
|
-
var version = "10.0.0-alpha.
|
|
40
|
+
var version = "10.0.0-alpha.37";
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region src/auth/credentials.ts
|
|
43
43
|
/**
|
|
@@ -1087,9 +1087,9 @@ async function workspaceDevCommand(workspace, options) {
|
|
|
1087
1087
|
...reconciled.env
|
|
1088
1088
|
};
|
|
1089
1089
|
if (options.migrate || options.seed) {
|
|
1090
|
-
const { prepareDevDatabases } = await import("./migrate-
|
|
1090
|
+
const { prepareDevDatabases } = await import("./migrate-_2J3lFT5.mjs");
|
|
1091
1091
|
await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
|
|
1092
|
-
} else await import("./migrate-
|
|
1092
|
+
} else await import("./migrate-_2J3lFT5.mjs").then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
|
|
1093
1093
|
logger$10.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
|
|
1094
1094
|
});
|
|
1095
1095
|
const appUrls = {};
|
|
@@ -8798,26 +8798,26 @@ function loadPackageJson() {
|
|
|
8798
8798
|
* Run: pnpm --filter @geekmidas/cli sync-versions
|
|
8799
8799
|
*/
|
|
8800
8800
|
const GEEKMIDAS_VERSIONS = {
|
|
8801
|
-
"@geekmidas/audit": "~10.0.0-alpha.
|
|
8802
|
-
"@geekmidas/auth": "~10.0.0-alpha.
|
|
8803
|
-
"@geekmidas/cache": "~10.0.0-alpha.
|
|
8804
|
-
"@geekmidas/client": "~10.0.0-alpha.
|
|
8805
|
-
"@geekmidas/cloud": "~10.0.0-alpha.
|
|
8806
|
-
"@geekmidas/constructs": "~10.0.0-alpha.
|
|
8807
|
-
"@geekmidas/db": "~10.0.0-alpha.
|
|
8808
|
-
"@geekmidas/emailkit": "~10.0.0-alpha.
|
|
8809
|
-
"@geekmidas/envkit": "~10.0.0-alpha.
|
|
8810
|
-
"@geekmidas/errors": "~10.0.0-alpha.
|
|
8811
|
-
"@geekmidas/events": "~10.0.0-alpha.
|
|
8812
|
-
"@geekmidas/logger": "~10.0.0-alpha.
|
|
8813
|
-
"@geekmidas/manifest": "~10.0.0-alpha.
|
|
8814
|
-
"@geekmidas/rate-limit": "~10.0.0-alpha.
|
|
8815
|
-
"@geekmidas/schema": "~10.0.0-alpha.
|
|
8816
|
-
"@geekmidas/services": "~10.0.0-alpha.
|
|
8817
|
-
"@geekmidas/storage": "~10.0.0-alpha.
|
|
8818
|
-
"@geekmidas/studio": "~10.0.0-alpha.
|
|
8819
|
-
"@geekmidas/telescope": "~10.0.0-alpha.
|
|
8820
|
-
"@geekmidas/testkit": "~10.0.0-alpha.
|
|
8801
|
+
"@geekmidas/audit": "~10.0.0-alpha.37",
|
|
8802
|
+
"@geekmidas/auth": "~10.0.0-alpha.37",
|
|
8803
|
+
"@geekmidas/cache": "~10.0.0-alpha.37",
|
|
8804
|
+
"@geekmidas/client": "~10.0.0-alpha.37",
|
|
8805
|
+
"@geekmidas/cloud": "~10.0.0-alpha.37",
|
|
8806
|
+
"@geekmidas/constructs": "~10.0.0-alpha.37",
|
|
8807
|
+
"@geekmidas/db": "~10.0.0-alpha.37",
|
|
8808
|
+
"@geekmidas/emailkit": "~10.0.0-alpha.37",
|
|
8809
|
+
"@geekmidas/envkit": "~10.0.0-alpha.37",
|
|
8810
|
+
"@geekmidas/errors": "~10.0.0-alpha.37",
|
|
8811
|
+
"@geekmidas/events": "~10.0.0-alpha.37",
|
|
8812
|
+
"@geekmidas/logger": "~10.0.0-alpha.37",
|
|
8813
|
+
"@geekmidas/manifest": "~10.0.0-alpha.37",
|
|
8814
|
+
"@geekmidas/rate-limit": "~10.0.0-alpha.37",
|
|
8815
|
+
"@geekmidas/schema": "~10.0.0-alpha.37",
|
|
8816
|
+
"@geekmidas/services": "~10.0.0-alpha.37",
|
|
8817
|
+
"@geekmidas/storage": "~10.0.0-alpha.37",
|
|
8818
|
+
"@geekmidas/studio": "~10.0.0-alpha.37",
|
|
8819
|
+
"@geekmidas/telescope": "~10.0.0-alpha.37",
|
|
8820
|
+
"@geekmidas/testkit": "~10.0.0-alpha.37",
|
|
8821
8821
|
"@geekmidas/cli": `~${loadPackageJson().version}`
|
|
8822
8822
|
};
|
|
8823
8823
|
//#endregion
|
|
@@ -15149,7 +15149,7 @@ var NoStoredSecrets = class extends Error {
|
|
|
15149
15149
|
}
|
|
15150
15150
|
};
|
|
15151
15151
|
async function reconcile(secrets, workspace, stage) {
|
|
15152
|
-
const { derivedContainers } = await import("./workspace-
|
|
15152
|
+
const { derivedContainers } = await import("./workspace-BtXCL1C8.mjs").then((n) => n.a);
|
|
15153
15153
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
15154
15154
|
return result ? {
|
|
15155
15155
|
secrets: result.secrets,
|
|
@@ -15448,6 +15448,56 @@ function printSummary(workspace, stage) {
|
|
|
15448
15448
|
logger$1.log("");
|
|
15449
15449
|
}
|
|
15450
15450
|
//#endregion
|
|
15451
|
+
//#region src/test/teardown.ts
|
|
15452
|
+
/**
|
|
15453
|
+
* Dropping the test stage's databases when a suite ends.
|
|
15454
|
+
*
|
|
15455
|
+
* Reconcile never drops — the line it draws is at data. The test stage's data
|
|
15456
|
+
* is the exception: every test runs in a transaction rolled back after it, so
|
|
15457
|
+
* nothing in these databases is anyone's, and a database kept between runs is
|
|
15458
|
+
* one whose migrations already ran — an edited migration is never applied to
|
|
15459
|
+
* it again. So each run starts from a database it created, and drops it when
|
|
15460
|
+
* the suite ends: the Vitest global setup's teardown.
|
|
15461
|
+
*/
|
|
15462
|
+
/**
|
|
15463
|
+
* Drop the databases the last setup recorded, and forget the test stage's
|
|
15464
|
+
* reconcile, so the next run provisions them from nothing.
|
|
15465
|
+
*
|
|
15466
|
+
* A no-op when nothing is recorded — no run yet, or one already torn down —
|
|
15467
|
+
* so running it twice, or before a setup, is harmless.
|
|
15468
|
+
*/
|
|
15469
|
+
async function dropTestDatabases(cwd, root, sql = pgClient) {
|
|
15470
|
+
const readyPath = join(cwd, TEST_READY_FILE);
|
|
15471
|
+
const ready = await readReady(readyPath);
|
|
15472
|
+
const recorded = ready?.databases;
|
|
15473
|
+
if (!ready || !recorded) return [];
|
|
15474
|
+
const client = sql(recorded.port);
|
|
15475
|
+
for (const name of recorded.names) {
|
|
15476
|
+
if (!name.endsWith(`_test`)) throw new NotATestDatabase(name);
|
|
15477
|
+
await client.query(void 0, `DROP DATABASE IF EXISTS ${quoteIdentifier(name)} WITH (FORCE)`);
|
|
15478
|
+
}
|
|
15479
|
+
await forgetState(root, TEST_STAGE);
|
|
15480
|
+
const { databases: _dropped, ...rest } = ready;
|
|
15481
|
+
await writeFile(readyPath, JSON.stringify(rest, null, 2));
|
|
15482
|
+
return recorded.names;
|
|
15483
|
+
}
|
|
15484
|
+
async function readReady(path) {
|
|
15485
|
+
try {
|
|
15486
|
+
return JSON.parse(await readFile(path, "utf-8"));
|
|
15487
|
+
} catch {
|
|
15488
|
+
return;
|
|
15489
|
+
}
|
|
15490
|
+
}
|
|
15491
|
+
/** A name recorded for the test stage without the test stage's suffix. */
|
|
15492
|
+
var NotATestDatabase = class extends Error {
|
|
15493
|
+
database;
|
|
15494
|
+
constructor(database) {
|
|
15495
|
+
super(`Refusing to drop '${database}': only the test stage's databases (named '…_${TEST_STAGE}') are dropped after a suite. Delete ${TEST_READY_FILE} if it was edited by hand.`);
|
|
15496
|
+
this.database = database;
|
|
15497
|
+
this.name = "NotATestDatabase";
|
|
15498
|
+
}
|
|
15499
|
+
};
|
|
15500
|
+
//#endregion
|
|
15451
15501
|
//#region src/test/index.ts
|
|
15452
15502
|
/**
|
|
15453
15503
|
* Run tests with secrets, dependency URLs, and .env files loaded.
|
|
@@ -15456,6 +15506,10 @@ function printSummary(workspace, stage) {
|
|
|
15456
15506
|
async function testCommand(options = {}) {
|
|
15457
15507
|
const cwd = process.cwd();
|
|
15458
15508
|
const stage = options.stage ?? await loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace.stages.local).catch(() => void 0);
|
|
15509
|
+
if (options.teardown) {
|
|
15510
|
+
await teardown(cwd);
|
|
15511
|
+
return;
|
|
15512
|
+
}
|
|
15459
15513
|
if (!stage) throw new NoStageToTest();
|
|
15460
15514
|
console.log(`\n🧪 Running tests with ${stage} environment...\n`);
|
|
15461
15515
|
if (options.autoSetup || Boolean(process.env.GKM_AUTO_SETUP)) {
|
|
@@ -15464,6 +15518,7 @@ async function testCommand(options = {}) {
|
|
|
15464
15518
|
}
|
|
15465
15519
|
const defaultEnv = loadEnvFiles(".env");
|
|
15466
15520
|
if (defaultEnv.loaded.length > 0) console.log(` 📦 Loaded env: ${defaultEnv.loaded.join(", ")}`);
|
|
15521
|
+
if (!options.prepare) await teardown(cwd);
|
|
15467
15522
|
const result = await prepareEntryCredentials({
|
|
15468
15523
|
stage,
|
|
15469
15524
|
startDocker: !options.prepare,
|
|
@@ -15504,7 +15559,8 @@ async function testCommand(options = {}) {
|
|
|
15504
15559
|
const readyPath = join(cwd, TEST_READY_FILE);
|
|
15505
15560
|
await writeFile(readyPath, JSON.stringify({
|
|
15506
15561
|
env: result.secretsJsonPath,
|
|
15507
|
-
...manifestPath ? { manifest: manifestPath } : {}
|
|
15562
|
+
...manifestPath ? { manifest: manifestPath } : {},
|
|
15563
|
+
...testDatabases(result.reconciled)
|
|
15508
15564
|
}, null, 2));
|
|
15509
15565
|
if (options.setup) {
|
|
15510
15566
|
console.log(` 🧪 Test stage ready: ${TEST_READY_FILE}`);
|
|
@@ -15543,12 +15599,29 @@ async function testCommand(options = {}) {
|
|
|
15543
15599
|
});
|
|
15544
15600
|
});
|
|
15545
15601
|
}
|
|
15602
|
+
/** Drop what the last setup created — see `dropTestDatabases`. */
|
|
15603
|
+
async function teardown(cwd) {
|
|
15604
|
+
const dropped = await dropTestDatabases(cwd, await loadWorkspaceConfig(cwd).then((loaded) => loaded.workspace.root).catch(() => cwd));
|
|
15605
|
+
if (dropped.length > 0) console.log(` 🧹 Dropped ${dropped.join(", ")}`);
|
|
15606
|
+
}
|
|
15607
|
+
/**
|
|
15608
|
+
* The test stage's Postgres databases, to drop when the suite ends — those
|
|
15609
|
+
* the plan provisions, on the port the shared container answers.
|
|
15610
|
+
*/
|
|
15611
|
+
function testDatabases(reconciled) {
|
|
15612
|
+
const port = reconciled?.ports[primaryPortKey("postgres")];
|
|
15613
|
+
const names = (reconciled?.plan.resources ?? []).filter((resource) => resource.kind === "database" && resource.provisions && resource.container === "postgres").map((resource) => resource.name);
|
|
15614
|
+
return port !== void 0 && names.length > 0 ? { databases: {
|
|
15615
|
+
port,
|
|
15616
|
+
names
|
|
15617
|
+
} } : {};
|
|
15618
|
+
}
|
|
15546
15619
|
/**
|
|
15547
15620
|
* Migrate the test stage just reconciled, then seed it: a test run never
|
|
15548
15621
|
* starts without the reference data the app needs.
|
|
15549
15622
|
*/
|
|
15550
15623
|
async function migrateTestStage(workspace, env) {
|
|
15551
|
-
const { migrateAndSeed } = await import("./migrate-
|
|
15624
|
+
const { migrateAndSeed } = await import("./migrate-_2J3lFT5.mjs");
|
|
15552
15625
|
const { discover } = await import("./discover-CMxesskG.mjs").then((n) => n.n);
|
|
15553
15626
|
const sources = {};
|
|
15554
15627
|
const manifest = await discover({
|
|
@@ -15976,7 +16049,7 @@ program.command("exec").description("Run a command with secrets injected into Cr
|
|
|
15976
16049
|
process.exit(1);
|
|
15977
16050
|
}
|
|
15978
16051
|
});
|
|
15979
|
-
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) => {
|
|
16052
|
+
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) => {
|
|
15980
16053
|
try {
|
|
15981
16054
|
const globalOptions = program.opts();
|
|
15982
16055
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
@@ -15993,7 +16066,7 @@ program.command("migrate").description("Apply each database construct's migratio
|
|
|
15993
16066
|
try {
|
|
15994
16067
|
const globalOptions = program.opts();
|
|
15995
16068
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
15996
|
-
const { migrateCommand } = await import("./migrate-
|
|
16069
|
+
const { migrateCommand } = await import("./migrate-_2J3lFT5.mjs");
|
|
15997
16070
|
await migrateCommand({
|
|
15998
16071
|
...options,
|
|
15999
16072
|
...construct ? { construct } : {}
|
|
@@ -16007,7 +16080,7 @@ program.command("seed").description("Migrate, then run each database construct's
|
|
|
16007
16080
|
try {
|
|
16008
16081
|
const globalOptions = program.opts();
|
|
16009
16082
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16010
|
-
const { seedCommand } = await import("./migrate-
|
|
16083
|
+
const { seedCommand } = await import("./migrate-_2J3lFT5.mjs");
|
|
16011
16084
|
await seedCommand({
|
|
16012
16085
|
...options,
|
|
16013
16086
|
...construct ? { construct } : {}
|
|
@@ -16021,7 +16094,7 @@ program.command("migration").description("Write a construct's next migration: an
|
|
|
16021
16094
|
try {
|
|
16022
16095
|
const globalOptions = program.opts();
|
|
16023
16096
|
if (globalOptions.cwd) process.chdir(globalOptions.cwd);
|
|
16024
|
-
const { migrationCommand } = await import("./migrate-
|
|
16097
|
+
const { migrationCommand } = await import("./migrate-_2J3lFT5.mjs");
|
|
16025
16098
|
await migrationCommand({
|
|
16026
16099
|
construct,
|
|
16027
16100
|
...name ? { name } : {}
|
|
@@ -16189,7 +16262,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
|
|
|
16189
16262
|
console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
|
|
16190
16263
|
process.exit(1);
|
|
16191
16264
|
}
|
|
16192
|
-
const { derivedContainers } = await import("./workspace-
|
|
16265
|
+
const { derivedContainers } = await import("./workspace-BtXCL1C8.mjs").then((n) => n.a);
|
|
16193
16266
|
const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
|
|
16194
16267
|
if (!result) {
|
|
16195
16268
|
console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
|