@devdogsuga/devtools 0.1.51-next.545 → 0.1.51-next.548
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/{cli-DNZ-6WEI.js → cli-DV6tvG1E.js} +207 -25
- package/dist/launch.js +8 -7
- package/dist/{load-yn7JCcS2.js → load-aeN4iX1h.js} +1 -1
- package/dist/{load-Z2CXCpyx.js → load-lrgJ5Kz7.js} +1 -1
- package/dist/{menu-oQE5IqAI.js → menu-CZK0L1Vf.js} +3 -3
- package/dist/{root-DfH38DFq.js → root-IVsv7i8N.js} +1 -1
- package/dist/{root-PA8K5G2d.js → root-RaJ8ECCO.js} +13 -1
- package/dist/{run-CRBte7p0.js → run-D5iI9zve.js} +3 -3
- package/dist/{session-DzgtIg6K.js → session-DdF8eqv3.js} +1 -1
- package/dist/{session-CuexI1f9.js → session-bPPOkolU.js} +1 -1
- package/dist/{stack-BRevXgI3.js → stack-CzNe6rxl.js} +1 -1
- package/dist/stack-VZ-1SmuM.js +2 -0
- package/dist/{telemetry-BDTAGquh.js → telemetry-BDOwjuoC.js} +4 -3
- package/dist/telemetry.js +1 -1
- package/dist/with-env.js +2 -2
- package/package.json +1 -1
- package/dist/stack-Cl_B_dt7.js +0 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as execSync, r as spawnProcess } from "./spawn-BvLQzc_K.js";
|
|
2
|
-
import { n as discoverRepoRoot, r as findRepoRoot } from "./root-
|
|
3
|
-
import { A as findApp, M as listApps, N as resolveAppPath, O as appWorkspaceRoot, P as resolveLayout, _ as dryRunKind, c as supabaseRoot, d as loadEnvLoad, f as loadEnvSession, g as runInGroup, h as reportRan, i as runWithStderr, j as layoutAt, k as devdogsugaRootOrNull, l as getEnvSync, n as reportRuns, o as supabase, p as repoPeerUrl, r as run$1, t as dbPush, u as loadEnv, v as isDryRun, x as wouldRunLine } from "./run-
|
|
4
|
-
import { A as renderHelp, C as loadProductConfig, D as catalog, M as probeEnvironment, O as helpPath, T as isProductMode, _ as explain, a as recordEnteredTier, b as ProductConfigError, c as nonEmpty, d as sessionLabel, g as errorMessage, h as bail, i as beginInvocation, j as describeEnvironment, k as renderCommandList, l as resolveDbConnection, n as bareGroupStartPath, o as recordResolved, r as runMenu, s as reproducibleCommand, t as bareGroupStartFlags, u as sessionIsLocal, v as explainError, w as activeCatalog, x as currentProduct, y as unwrap } from "./menu-
|
|
2
|
+
import { n as discoverRepoRoot, r as findRepoRoot } from "./root-RaJ8ECCO.js";
|
|
3
|
+
import { A as findApp, M as listApps, N as resolveAppPath, O as appWorkspaceRoot, P as resolveLayout, _ as dryRunKind, c as supabaseRoot, d as loadEnvLoad, f as loadEnvSession, g as runInGroup, h as reportRan, i as runWithStderr, j as layoutAt, k as devdogsugaRootOrNull, l as getEnvSync, n as reportRuns, o as supabase, p as repoPeerUrl, r as run$1, t as dbPush, u as loadEnv, v as isDryRun, x as wouldRunLine } from "./run-D5iI9zve.js";
|
|
4
|
+
import { A as renderHelp, C as loadProductConfig, D as catalog, M as probeEnvironment, O as helpPath, T as isProductMode, _ as explain, a as recordEnteredTier, b as ProductConfigError, c as nonEmpty, d as sessionLabel, g as errorMessage, h as bail, i as beginInvocation, j as describeEnvironment, k as renderCommandList, l as resolveDbConnection, n as bareGroupStartPath, o as recordResolved, r as runMenu, s as reproducibleCommand, t as bareGroupStartFlags, u as sessionIsLocal, v as explainError, w as activeCatalog, x as currentProduct, y as unwrap } from "./menu-CZK0L1Vf.js";
|
|
5
5
|
import { a as isVersionRequest, c as cliName, m as positionals, o as ownPackageDir, p as flagValue, s as ownVersion } from "./failure-log-MSdCgvLc.js";
|
|
6
|
-
import { f as hasYes, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive } from "./telemetry-
|
|
7
|
-
import { t as runStackCommand } from "./stack-
|
|
6
|
+
import { f as hasYes, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive } from "./telemetry-BDOwjuoC.js";
|
|
7
|
+
import { t as runStackCommand } from "./stack-CzNe6rxl.js";
|
|
8
8
|
import { register } from "node:module";
|
|
9
9
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
@@ -7058,7 +7058,7 @@ function commandLine(command, args) {
|
|
|
7058
7058
|
function cliLine(cli, args) {
|
|
7059
7059
|
return commandLine(cli.command, [...cli.prefix, ...args]);
|
|
7060
7060
|
}
|
|
7061
|
-
function versionOf(output) {
|
|
7061
|
+
function versionOf$1(output) {
|
|
7062
7062
|
return /\b(\d+\.\d+\.\d+)\b/.exec(output)?.[1] ?? null;
|
|
7063
7063
|
}
|
|
7064
7064
|
async function resolveSupabaseCli(root, pin, run, fileExists = existsSync) {
|
|
@@ -7076,7 +7076,7 @@ async function resolveSupabaseCli(root, pin, run, fileExists = existsSync) {
|
|
|
7076
7076
|
});
|
|
7077
7077
|
for (const candidate of candidates) try {
|
|
7078
7078
|
const result = await run(candidate.command, ["--version"], { cwd: root });
|
|
7079
|
-
if (result.code === 0 && versionOf(result.stdout) === pin) return candidate;
|
|
7079
|
+
if (result.code === 0 && versionOf$1(result.stdout) === pin) return candidate;
|
|
7080
7080
|
} catch {}
|
|
7081
7081
|
try {
|
|
7082
7082
|
if ((await run("pnpm", ["--version"], { cwd: root })).code === 0) return {
|
|
@@ -7229,19 +7229,36 @@ async function resolveTarget(product, cli, run, preference) {
|
|
|
7229
7229
|
* project, and the SQL runs in one transaction.
|
|
7230
7230
|
*/
|
|
7231
7231
|
var DevDataError = class extends Error {
|
|
7232
|
+
/** A failure the contributor or the product's SQL caused, not a devtools bug: never sent to Sentry. */
|
|
7233
|
+
expected = true;
|
|
7232
7234
|
constructor(message) {
|
|
7233
7235
|
super(message);
|
|
7234
7236
|
this.name = "DevDataError";
|
|
7235
7237
|
}
|
|
7236
7238
|
};
|
|
7237
7239
|
/**
|
|
7238
|
-
* Whether `err` is
|
|
7239
|
-
*
|
|
7240
|
-
*
|
|
7240
|
+
* Whether `err` is the product's own SQL being wrong: a Postgres error whose
|
|
7241
|
+
* SQLSTATE class is a cardinality violation (21), data exception (22),
|
|
7242
|
+
* integrity constraint violation (23) or syntax error or access rule
|
|
7243
|
+
* violation (42). Everything else is not the file's fault and reports as a
|
|
7244
|
+
* normal failure: a refused or dropped connection (class 08 and
|
|
7245
|
+
* `ECONNREFUSED`), an operator shutdown (57, `admin_shutdown`), a server out
|
|
7246
|
+
* of resources (53), a transaction that was rolled back (40), and so on.
|
|
7241
7247
|
*/
|
|
7242
|
-
function
|
|
7248
|
+
function isSqlFileError(err) {
|
|
7243
7249
|
const code = err?.code;
|
|
7244
|
-
return code === "
|
|
7250
|
+
return typeof code === "string" && /^(21|22|23|42)[0-9A-Z]{3}$/.test(code);
|
|
7251
|
+
}
|
|
7252
|
+
/**
|
|
7253
|
+
* The line of `text` a Postgres error points at, from the error's 1-based
|
|
7254
|
+
* character `position`, or null when it carries none.
|
|
7255
|
+
*/
|
|
7256
|
+
function errorLine(err, text) {
|
|
7257
|
+
const raw = err?.position;
|
|
7258
|
+
const position = typeof raw === "string" ? Number(raw) : raw;
|
|
7259
|
+
if (typeof position !== "number" || !Number.isInteger(position)) return null;
|
|
7260
|
+
if (position < 1 || position > text.length + 1) return null;
|
|
7261
|
+
return text.slice(0, position - 1).split("\n").length;
|
|
7245
7262
|
}
|
|
7246
7263
|
function postgresSession(dbUrl) {
|
|
7247
7264
|
const sql = postgres(dbUrl, {
|
|
@@ -7273,6 +7290,24 @@ function postgresSession(dbUrl) {
|
|
|
7273
7290
|
lastSignInAt: row.last_sign_in_at?.toISOString() ?? null
|
|
7274
7291
|
} : null;
|
|
7275
7292
|
},
|
|
7293
|
+
async appliedMigrations() {
|
|
7294
|
+
const [table] = await sql`
|
|
7295
|
+
select to_regclass('supabase_migrations.schema_migrations')::text as present`;
|
|
7296
|
+
if (!table?.present) return null;
|
|
7297
|
+
return (await sql`
|
|
7298
|
+
select version from supabase_migrations.schema_migrations`).map((r) => r.version);
|
|
7299
|
+
},
|
|
7300
|
+
async missingSchemas(schemas) {
|
|
7301
|
+
const rows = await sql`
|
|
7302
|
+
select nspname from pg_namespace where nspname = any(${[...schemas]})`;
|
|
7303
|
+
const present = new Set(rows.map((r) => r.nspname));
|
|
7304
|
+
return schemas.filter((name) => !present.has(name));
|
|
7305
|
+
},
|
|
7306
|
+
async exec(text) {
|
|
7307
|
+
await sql.begin(async (tx) => {
|
|
7308
|
+
await tx.unsafe(text);
|
|
7309
|
+
});
|
|
7310
|
+
},
|
|
7276
7311
|
async runAs(memberId, text) {
|
|
7277
7312
|
await sql.begin(async (tx) => {
|
|
7278
7313
|
await tx`select set_config('devtools.member_id', ${memberId}, true)`;
|
|
@@ -7296,10 +7331,9 @@ async function runDevData(product, target, open, options) {
|
|
|
7296
7331
|
const text = readFileSync(file, "utf8");
|
|
7297
7332
|
const session = open(target.dbUrl);
|
|
7298
7333
|
try {
|
|
7334
|
+
const missing = await session.missingSchemas(product.config.supabase.schemas);
|
|
7335
|
+
if (missing.length > 0) throw new DevDataError(`This database does not have ${product.config.name}'s ${missing.length === 1 ? "schema" : "schemas"} yet (missing: ${missing.join(", ")}). Run \`devtools setup\` first, or \`devtools db sync\` if you have already set up.`);
|
|
7299
7336
|
return await seed(session, devData.file, text, options, log);
|
|
7300
|
-
} catch (err) {
|
|
7301
|
-
if (isMissingSchemaError(err)) throw new DevDataError(`This database does not have ${product.config.name}'s tables yet (${err.message}). Run \`devtools setup\` first, or \`devtools db sync\` if you have already set up.`);
|
|
7302
|
-
throw err;
|
|
7303
7337
|
} finally {
|
|
7304
7338
|
await session.close();
|
|
7305
7339
|
}
|
|
@@ -7312,7 +7346,13 @@ async function seed(session, file, text, options, log) {
|
|
|
7312
7346
|
log(`Would run ${file} (${text.split("\n").length} lines) in one transaction.`);
|
|
7313
7347
|
return null;
|
|
7314
7348
|
}
|
|
7315
|
-
|
|
7349
|
+
try {
|
|
7350
|
+
await session.runAs(member.id, text);
|
|
7351
|
+
} catch (err) {
|
|
7352
|
+
if (!isSqlFileError(err)) throw err;
|
|
7353
|
+
const line = errorLine(err, text);
|
|
7354
|
+
throw new DevDataError(`${file}${line === null ? "" : `:${line}`}: ${err.message}. This is a problem in the product's dev-data SQL, not in devtools; nothing was seeded (the file runs in one transaction).`);
|
|
7355
|
+
}
|
|
7316
7356
|
return {
|
|
7317
7357
|
member,
|
|
7318
7358
|
file
|
|
@@ -7546,6 +7586,15 @@ function typesAssetName(product, hash) {
|
|
|
7546
7586
|
* Without that, the diff would start from an empty database and write the whole
|
|
7547
7587
|
* schema as one migration, which `db push` rejects as already applied.
|
|
7548
7588
|
*
|
|
7589
|
+
* The record only says what *should* be in the database. Before the diff,
|
|
7590
|
+
* sync therefore compares the database itself with the record (`supabase db
|
|
7591
|
+
* diff --from <database> --to migrations`, restricted to the product's
|
|
7592
|
+
* schemas) and re-applies whatever is missing: a dropped table, a dropped
|
|
7593
|
+
* schema, a database reset behind the record's back. The migration ledger is
|
|
7594
|
+
* never trusted to decide anything; it is rewritten to list the record when it
|
|
7595
|
+
* is missing or short. "The database already matches" is therefore a
|
|
7596
|
+
* statement about the live database.
|
|
7597
|
+
*
|
|
7549
7598
|
* It never resets the database. A reset wipes `auth.custom_oauth_providers`,
|
|
7550
7599
|
* which is where "Sign in with DevDogs" is registered (Q83); `--rebuild` is
|
|
7551
7600
|
* the explicit escape hatch for a database that has drifted from its record,
|
|
@@ -7597,6 +7646,7 @@ async function dbSync(product, cli, target, run, options) {
|
|
|
7597
7646
|
"--db-url",
|
|
7598
7647
|
"<DB_URL>"
|
|
7599
7648
|
])} (this machine has no record of what the project has had applied)`);
|
|
7649
|
+
if (options.open) log(`Would run: ${cliLine(cli, liveDiffArgs(product, target).slice(cli.prefix.length))} (and restore anything the database lost)`);
|
|
7600
7650
|
log(`Would run: ${cliLine(cli, generateArgs.slice(cli.prefix.length))}`);
|
|
7601
7651
|
log(target.kind === "local" ? `Would run: ${cliLine(cli, [
|
|
7602
7652
|
"migration",
|
|
@@ -7620,6 +7670,7 @@ async function dbSync(product, cli, target, run, options) {
|
|
|
7620
7670
|
const restored = migrationFiles(migrationsDir).length;
|
|
7621
7671
|
if (fetched.code === 0 && restored > 0) log(`Restored ${restored} applied migration${restored === 1 ? "" : "s"} from the project's history.`);
|
|
7622
7672
|
}
|
|
7673
|
+
const restored = await restoreDatabase(product, cli, target, run, options, log);
|
|
7623
7674
|
const before = new Set(migrationFiles(migrationsDir));
|
|
7624
7675
|
let generated = await run(cli.command, generateArgs, { cwd: product.root });
|
|
7625
7676
|
if (generated.code !== 0 && isContainerFailure(generated)) {
|
|
@@ -7629,11 +7680,11 @@ async function dbSync(product, cli, target, run, options) {
|
|
|
7629
7680
|
if (generated.code !== 0) throw new SyncError(isContainerFailure(generated) ? "Could not diff the schema: Docker is needed for the shadow database. Start Docker and try again." : "Could not diff the schema against what this database has had applied.", generated.stderr || generated.stdout);
|
|
7630
7681
|
const created = migrationFiles(migrationsDir).filter((f) => !before.has(f));
|
|
7631
7682
|
if (created.length === 0) {
|
|
7632
|
-
log("The database already matches supabase/schemas.");
|
|
7683
|
+
if (!restored.applied) log("The database already matches supabase/schemas.");
|
|
7633
7684
|
return {
|
|
7634
7685
|
migration: null,
|
|
7635
|
-
applied:
|
|
7636
|
-
destructive:
|
|
7686
|
+
applied: restored.applied,
|
|
7687
|
+
destructive: restored.destructive
|
|
7637
7688
|
};
|
|
7638
7689
|
}
|
|
7639
7690
|
const migration = created[created.length - 1];
|
|
@@ -7667,8 +7718,137 @@ async function dbSync(product, cli, target, run, options) {
|
|
|
7667
7718
|
return {
|
|
7668
7719
|
migration,
|
|
7669
7720
|
applied: true,
|
|
7670
|
-
destructive
|
|
7721
|
+
destructive: [...restored.destructive, ...destructive]
|
|
7722
|
+
};
|
|
7723
|
+
}
|
|
7724
|
+
/** `20261011120000` from `20261011120000_devtools_sync.sql`. */
|
|
7725
|
+
function versionOf(file) {
|
|
7726
|
+
return file.split("_")[0] ?? file;
|
|
7727
|
+
}
|
|
7728
|
+
function liveDiffArgs(product, target) {
|
|
7729
|
+
return [
|
|
7730
|
+
"db",
|
|
7731
|
+
"diff",
|
|
7732
|
+
"--from",
|
|
7733
|
+
target.kind === "local" ? "local" : target.dbUrl,
|
|
7734
|
+
"--to",
|
|
7735
|
+
"migrations",
|
|
7736
|
+
"--use-pg-delta",
|
|
7737
|
+
"--schema",
|
|
7738
|
+
product.config.supabase.schemas.join(","),
|
|
7739
|
+
"--output-format",
|
|
7740
|
+
"json"
|
|
7741
|
+
];
|
|
7742
|
+
}
|
|
7743
|
+
/**
|
|
7744
|
+
* The SQL that turns the database into what the record describes, from the
|
|
7745
|
+
* CLI's pg-delta diff (database to migrations baseline). Empty when they
|
|
7746
|
+
* agree. Only the product's own schemas are compared, so the platform's
|
|
7747
|
+
* (auth, storage, ...) never show up as drift.
|
|
7748
|
+
*/
|
|
7749
|
+
async function liveDiff(product, cli, target, run, log) {
|
|
7750
|
+
const args = [...cli.prefix, ...liveDiffArgs(product, target)];
|
|
7751
|
+
let result = await run(cli.command, args, { cwd: product.root });
|
|
7752
|
+
if (result.code !== 0 && isContainerFailure(result)) {
|
|
7753
|
+
log("The shadow database did not start; trying once more.");
|
|
7754
|
+
result = await run(cli.command, args, { cwd: product.root });
|
|
7755
|
+
}
|
|
7756
|
+
if (result.code !== 0) throw new SyncError(isContainerFailure(result) ? "Could not compare the database with its record: Docker is needed for the shadow database. Start Docker and try again." : "Could not compare the database with what devtools recorded as applied.", result.stderr || result.stdout);
|
|
7757
|
+
for (const line of result.stdout.split("\n").reverse()) {
|
|
7758
|
+
const text = line.trim();
|
|
7759
|
+
if (!text.startsWith("{")) continue;
|
|
7760
|
+
try {
|
|
7761
|
+
const parsed = JSON.parse(text);
|
|
7762
|
+
if (typeof parsed.diff === "string") return parsed.diff;
|
|
7763
|
+
} catch {}
|
|
7764
|
+
}
|
|
7765
|
+
throw new SyncError("Could not read the result of comparing the database with its record.", result.stdout || result.stderr);
|
|
7766
|
+
}
|
|
7767
|
+
/**
|
|
7768
|
+
* Makes the database agree with the local record, from the database itself.
|
|
7769
|
+
* The declarative diff only compares `supabase/schemas` with
|
|
7770
|
+
* `supabase/migrations`, so a database that lost objects behind the record's
|
|
7771
|
+
* back (a table dropped by hand, a hosted project reset from the dashboard, a
|
|
7772
|
+
* checkout switched from the local stack to a hosted project) would read as
|
|
7773
|
+
* "already matches". So, with a record to compare against:
|
|
7774
|
+
*
|
|
7775
|
+
* 1. the database is diffed against the record, per configured schema, and
|
|
7776
|
+
* whatever it lacks is created again (data in what remains is untouched);
|
|
7777
|
+
* statements that drop something need the same approval as any change;
|
|
7778
|
+
* 2. the migration ledger is made to list every migration in the record
|
|
7779
|
+
* (marking them applied, which they now are), so the next
|
|
7780
|
+
* `migration up` applies only what is new.
|
|
7781
|
+
*
|
|
7782
|
+
* A missing or unreadable ledger decides nothing by itself: it is rewritten,
|
|
7783
|
+
* never read as "start over". A database that cannot be reached is left to
|
|
7784
|
+
* the apply step to report.
|
|
7785
|
+
*/
|
|
7786
|
+
async function restoreDatabase(product, cli, target, run, options, log) {
|
|
7787
|
+
const nothing = {
|
|
7788
|
+
applied: false,
|
|
7789
|
+
destructive: []
|
|
7671
7790
|
};
|
|
7791
|
+
const files = migrationFiles(product.paths.migrationsDir);
|
|
7792
|
+
if (!options.open || files.length === 0) return nothing;
|
|
7793
|
+
let session;
|
|
7794
|
+
let missing;
|
|
7795
|
+
let ledger;
|
|
7796
|
+
try {
|
|
7797
|
+
session = options.open(target.dbUrl);
|
|
7798
|
+
missing = await session.missingSchemas(product.config.supabase.schemas);
|
|
7799
|
+
} catch (err) {
|
|
7800
|
+
log(`Could not check what the database has (${err.message}); trusting the local record.`);
|
|
7801
|
+
await session?.close().catch(() => void 0);
|
|
7802
|
+
return nothing;
|
|
7803
|
+
}
|
|
7804
|
+
try {
|
|
7805
|
+
try {
|
|
7806
|
+
ledger = await session.appliedMigrations();
|
|
7807
|
+
} catch (err) {
|
|
7808
|
+
ledger = void 0;
|
|
7809
|
+
log(`Could not read the migration history (${err.message}); deciding from the schemas alone.`);
|
|
7810
|
+
}
|
|
7811
|
+
const sql = (await liveDiff(product, cli, target, run, log)).trim();
|
|
7812
|
+
let applied = false;
|
|
7813
|
+
let destructive = [];
|
|
7814
|
+
if (sql) {
|
|
7815
|
+
destructive = destructiveStatements(sql);
|
|
7816
|
+
if (destructive.length > 0 && !options.yes) {
|
|
7817
|
+
if (!(options.confirmDestructive ? await options.confirmDestructive(sql, destructive) : false)) throw new SyncError(`The database differs from supabase/schemas and putting it right drops data in your development database (${destructive.length} statement${destructive.length === 1 ? "" : "s"}). Re-run with --yes to allow it.`, destructive.join(";\n"));
|
|
7818
|
+
}
|
|
7819
|
+
log(missing.length > 0 ? `The database is missing ${missing.length === 1 ? "schema" : "schemas"} ${missing.join(", ")}; creating ${missing.length === 1 ? "it" : "them"} again from supabase/schemas.` : "The database has lost part of supabase/schemas (a dropped table, view or function, perhaps); restoring it. Existing data is kept.");
|
|
7820
|
+
try {
|
|
7821
|
+
await session.exec(sql);
|
|
7822
|
+
} catch (err) {
|
|
7823
|
+
throw new SyncError("Could not restore what the database lost. `devtools db sync --rebuild` starts over (it wipes local data).", err.message);
|
|
7824
|
+
}
|
|
7825
|
+
applied = true;
|
|
7826
|
+
}
|
|
7827
|
+
if (ledger !== void 0) {
|
|
7828
|
+
const known = new Set(ledger ?? []);
|
|
7829
|
+
const unlisted = files.map(versionOf).filter((version) => !known.has(version));
|
|
7830
|
+
if (unlisted.length > 0) {
|
|
7831
|
+
if (ledger === null) log("The database has no migration history table; recreating it from the local record.");
|
|
7832
|
+
const repaired = await run(cli.command, [
|
|
7833
|
+
...cli.prefix,
|
|
7834
|
+
"migration",
|
|
7835
|
+
"repair",
|
|
7836
|
+
"--status",
|
|
7837
|
+
"applied",
|
|
7838
|
+
"--db-url",
|
|
7839
|
+
target.dbUrl,
|
|
7840
|
+
...unlisted
|
|
7841
|
+
], { cwd: product.root });
|
|
7842
|
+
if (repaired.code !== 0) throw new SyncError("Could not record the applied migrations in the database's history.", repaired.stderr || repaired.stdout);
|
|
7843
|
+
}
|
|
7844
|
+
}
|
|
7845
|
+
return {
|
|
7846
|
+
applied,
|
|
7847
|
+
destructive
|
|
7848
|
+
};
|
|
7849
|
+
} finally {
|
|
7850
|
+
await session.close().catch(() => void 0);
|
|
7851
|
+
}
|
|
7672
7852
|
}
|
|
7673
7853
|
function isContainerFailure(result) {
|
|
7674
7854
|
return /docker|container|image/i.test(result.stderr + result.stdout);
|
|
@@ -7932,7 +8112,8 @@ async function runSync(product, deps, rest) {
|
|
|
7932
8112
|
yes: hasYes(rest),
|
|
7933
8113
|
confirmDestructive: deps.interactive() ? confirmDestructive : void 0,
|
|
7934
8114
|
dryRun,
|
|
7935
|
-
log: (line) => log.info(line)
|
|
8115
|
+
log: (line) => log.info(line),
|
|
8116
|
+
open: deps.openSql
|
|
7936
8117
|
});
|
|
7937
8118
|
if (rest.includes("--rebuild") && !dryRun) try {
|
|
7938
8119
|
const row = await reRegisterSavedProvider(product.paths.toolingFile, target);
|
|
@@ -7957,7 +8138,7 @@ async function regenerateAfterSync(product, cli, target, result, deps) {
|
|
|
7957
8138
|
log.info(`Would regenerate ${product.config.types.out}.`);
|
|
7958
8139
|
return;
|
|
7959
8140
|
}
|
|
7960
|
-
if (!result.
|
|
8141
|
+
if (!result.applied && typesAreCurrent(product)) return;
|
|
7961
8142
|
try {
|
|
7962
8143
|
await generateTypes(product, cli, target, deps.run, (line) => log.info(line));
|
|
7963
8144
|
log.success(`Regenerated ${product.config.types.out}.`);
|
|
@@ -8003,7 +8184,7 @@ function createProductHandlers(deps = defaultDeps) {
|
|
|
8003
8184
|
switch (sub) {
|
|
8004
8185
|
case "sync": {
|
|
8005
8186
|
const { result, cli, target } = await runSync(product, deps, flags);
|
|
8006
|
-
if (result.
|
|
8187
|
+
if (result.applied) log.success("Your database now matches supabase/schemas.");
|
|
8007
8188
|
await regenerateAfterSync(product, cli, target, result, deps);
|
|
8008
8189
|
return DONE;
|
|
8009
8190
|
}
|
|
@@ -8233,9 +8414,10 @@ async function runSetup(product, deps, rest) {
|
|
|
8233
8414
|
const result = await dbSync(product, cli, target, deps.run, {
|
|
8234
8415
|
yes: hasYes(rest),
|
|
8235
8416
|
confirmDestructive: deps.interactive() ? confirmDestructive : void 0,
|
|
8236
|
-
log: (line) => log.info(line)
|
|
8417
|
+
log: (line) => log.info(line),
|
|
8418
|
+
open: deps.openSql
|
|
8237
8419
|
});
|
|
8238
|
-
log.success(result.
|
|
8420
|
+
log.success(result.applied ? "Applied supabase/schemas to your database." : "Your database already matched supabase/schemas.");
|
|
8239
8421
|
if (target.kind === "local") await waitForRest(target, deps, product);
|
|
8240
8422
|
if (rest.includes("--download-types")) try {
|
|
8241
8423
|
await downloadTypes(product, {
|
package/dist/launch.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { n as discoverRepoRoot, r as findRepoRoot, t as RepoNotFoundError } from "./root-
|
|
2
|
-
import { b as setDryRun, d as loadEnvLoad, f as loadEnvSession, m as formatCommand, v as isDryRun, y as resolveDryRun } from "./run-
|
|
3
|
-
import { D as catalog, E as setProductMode, N as setEnvironmentRoot, O as helpPath, S as findProductRoot, c as nonEmpty, f as enterSessionEnvironment, g as errorMessage, h as bail, m as setMenuEnvHook, n as bareGroupStartPath, p as realEnvEntryDeps, y as unwrap } from "./menu-
|
|
1
|
+
import { i as markOutsideCheckout, n as discoverRepoRoot, r as findRepoRoot, t as RepoNotFoundError } from "./root-RaJ8ECCO.js";
|
|
2
|
+
import { b as setDryRun, d as loadEnvLoad, f as loadEnvSession, m as formatCommand, v as isDryRun, y as resolveDryRun } from "./run-D5iI9zve.js";
|
|
3
|
+
import { D as catalog, E as setProductMode, N as setEnvironmentRoot, O as helpPath, S as findProductRoot, c as nonEmpty, f as enterSessionEnvironment, g as errorMessage, h as bail, m as setMenuEnvHook, n as bareGroupStartPath, p as realEnvEntryDeps, y as unwrap } from "./menu-CZK0L1Vf.js";
|
|
4
4
|
import { a as isVersionRequest, c as cliName, t as installFailureLog } from "./failure-log-MSdCgvLc.js";
|
|
5
|
-
import { c as lastSentryEventId, f as hasYes, h as stripTierFlag, m as stripNoEnvFlag, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive } from "./telemetry-
|
|
5
|
+
import { c as lastSentryEventId, f as hasYes, h as stripTierFlag, m as stripNoEnvFlag, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as isNonInteractive } from "./telemetry-BDOwjuoC.js";
|
|
6
6
|
import { confirm, select } from "@clack/prompts";
|
|
7
7
|
//#region ../cli-core/src/session.ts
|
|
8
8
|
/**
|
|
@@ -172,7 +172,7 @@ function outsideRepoMessage(rest) {
|
|
|
172
172
|
/** The offer's stack start (`env-entry.ts` holds the TTY prompt, this holds
|
|
173
173
|
* the lifecycle command), imported lazily like the rest of the commands. */
|
|
174
174
|
async function startStack() {
|
|
175
|
-
const { runStackCommand } = await import("./stack-
|
|
175
|
+
const { runStackCommand } = await import("./stack-VZ-1SmuM.js");
|
|
176
176
|
return runStackCommand("start");
|
|
177
177
|
}
|
|
178
178
|
/**
|
|
@@ -183,11 +183,12 @@ async function startStack() {
|
|
|
183
183
|
* post-tier-resolution path.
|
|
184
184
|
*/
|
|
185
185
|
async function dispatch(argv) {
|
|
186
|
-
const { main } = await import("./cli-
|
|
186
|
+
const { main } = await import("./cli-DV6tvG1E.js");
|
|
187
187
|
try {
|
|
188
188
|
await main(argv);
|
|
189
189
|
} catch (err) {
|
|
190
|
-
|
|
190
|
+
const outside = markOutsideCheckout(err);
|
|
191
|
+
process.stderr.write(`devtools: ${outside ? outsideRepoMessage(argv) : errorMessage(err)}\n`);
|
|
191
192
|
await captureDevtoolsError(err);
|
|
192
193
|
process.exit(1);
|
|
193
194
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as LocalStackOfflineError, c as applyDeployTierAliases, d as loadEnvironment, f as locateRepoRoot, h as selectEnvFiles, i as LOCAL_STACK_PORT, l as applyWranglerLocalDatabaseAlias, m as probeLocalStack, n as GENERATED_FILE, o as MissingEnvFileError, p as parseRawAssignments, r as HYPERDRIVE_LOCAL_CONNECTION_ENV, s as SHELL_KEYS_ENV, t as DEV_DB_ENV, u as isDevDatabase } from "./load-
|
|
1
|
+
import { a as LocalStackOfflineError, c as applyDeployTierAliases, d as loadEnvironment, f as locateRepoRoot, h as selectEnvFiles, i as LOCAL_STACK_PORT, l as applyWranglerLocalDatabaseAlias, m as probeLocalStack, n as GENERATED_FILE, o as MissingEnvFileError, p as parseRawAssignments, r as HYPERDRIVE_LOCAL_CONNECTION_ENV, s as SHELL_KEYS_ENV, t as DEV_DB_ENV, u as isDevDatabase } from "./load-lrgJ5Kz7.js";
|
|
2
2
|
export { DEV_DB_ENV, GENERATED_FILE, HYPERDRIVE_LOCAL_CONNECTION_ENV, LOCAL_STACK_PORT, LocalStackOfflineError, MissingEnvFileError, SHELL_KEYS_ENV, applyDeployTierAliases, applyWranglerLocalDatabaseAlias, isDevDatabase, loadEnvironment, locateRepoRoot, parseRawAssignments, probeLocalStack, selectEnvFiles };
|
|
@@ -521,7 +521,7 @@ async function probeLocalStack(port = LOCAL_STACK_PORT, timeoutMs = 250) {
|
|
|
521
521
|
* worse failure than a rejected promise.
|
|
522
522
|
*/
|
|
523
523
|
async function locateRepoRoot() {
|
|
524
|
-
const { discoverRepoRoot, RepoNotFoundError } = await import("./root-
|
|
524
|
+
const { discoverRepoRoot, RepoNotFoundError } = await import("./root-IVsv7i8N.js");
|
|
525
525
|
const fromCwd = discoverRepoRoot();
|
|
526
526
|
if (fromCwd !== null) return fromCwd;
|
|
527
527
|
const { existsSync } = await import("node:fs");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as execSync } from "./spawn-BvLQzc_K.js";
|
|
2
|
-
import { n as discoverRepoRoot } from "./root-
|
|
3
|
-
import { C as containerPrefix, D as readProjectId, E as listContainerNames, P as resolveLayout, S as STACK_API_PORT, T as foreignStackProjectId, d as loadEnvLoad, k as devdogsugaRootOrNull, s as supabaseCapture, u as loadEnv, w as foreignStackMessage } from "./run-
|
|
2
|
+
import { n as discoverRepoRoot } from "./root-RaJ8ECCO.js";
|
|
3
|
+
import { C as containerPrefix, D as readProjectId, E as listContainerNames, P as resolveLayout, S as STACK_API_PORT, T as foreignStackProjectId, d as loadEnvLoad, k as devdogsugaRootOrNull, s as supabaseCapture, u as loadEnv, w as foreignStackMessage } from "./run-D5iI9zve.js";
|
|
4
4
|
import { d as YES, f as createCatalog, i as suppressFailureLog, l as JSON_FLAG, m as positionals, u as SCOPES } from "./failure-log-MSdCgvLc.js";
|
|
5
|
-
import { l as reportDevtoolsError, p as isNonInteractive } from "./telemetry-
|
|
5
|
+
import { l as reportDevtoolsError, p as isNonInteractive } from "./telemetry-BDOwjuoC.js";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
7
|
import { dirname, join, resolve } from "node:path";
|
|
8
8
|
import { z } from "zod";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as discoverRepoRoot, t as RepoNotFoundError } from "./root-
|
|
1
|
+
import { n as discoverRepoRoot, t as RepoNotFoundError } from "./root-RaJ8ECCO.js";
|
|
2
2
|
export { RepoNotFoundError, discoverRepoRoot };
|
|
@@ -73,5 +73,17 @@ function findRepoRoot() {
|
|
|
73
73
|
if (cachedRoot === null) throw new RepoNotFoundError();
|
|
74
74
|
return cachedRoot;
|
|
75
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether `err` is the user running a checkout-requiring command with no
|
|
78
|
+
* DevDogsUGA checkout above the working directory, and if so marks it
|
|
79
|
+
* `expected` so telemetry drops it. A `RepoNotFoundError` raised while a
|
|
80
|
+
* checkout does exist (a `findRepoRoot()` call that should not have needed
|
|
81
|
+
* one, as in DEVTOOLS-D) is a bug and stays reportable.
|
|
82
|
+
*/
|
|
83
|
+
function markOutsideCheckout(err, startDir = process.cwd()) {
|
|
84
|
+
if (!(err instanceof RepoNotFoundError) || discoverRepoRoot(startDir) !== null) return false;
|
|
85
|
+
Object.assign(err, { expected: true });
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
76
88
|
//#endregion
|
|
77
|
-
export { discoverRepoRoot as n, findRepoRoot as r, RepoNotFoundError as t };
|
|
89
|
+
export { markOutsideCheckout as i, discoverRepoRoot as n, findRepoRoot as r, RepoNotFoundError as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as execSync, r as spawnProcess, t as exec } from "./spawn-BvLQzc_K.js";
|
|
2
|
-
import { r as findRepoRoot, t as RepoNotFoundError } from "./root-
|
|
2
|
+
import { r as findRepoRoot, t as RepoNotFoundError } from "./root-RaJ8ECCO.js";
|
|
3
3
|
import { c as cliName, r as noteRan } from "./failure-log-MSdCgvLc.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
@@ -631,11 +631,11 @@ function getEnvSync() {
|
|
|
631
631
|
}
|
|
632
632
|
/** The env loader (`loadEnvironment` and the tier/file selection). Bundled. */
|
|
633
633
|
function loadEnvLoad() {
|
|
634
|
-
return import("./load-
|
|
634
|
+
return import("./load-aeN4iX1h.js");
|
|
635
635
|
}
|
|
636
636
|
/** The session policy (tier resolution, `enterEnvironment`). Bundled. */
|
|
637
637
|
function loadEnvSession() {
|
|
638
|
-
return import("./session-
|
|
638
|
+
return import("./session-DdF8eqv3.js");
|
|
639
639
|
}
|
|
640
640
|
//#endregion
|
|
641
641
|
//#region ../cli-core/src/db/run.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as parseSessionSelector, c as rememberDevDatabase, i as enterEnvironment, l as rememberedDevDatabase, n as availableTiers, o as resolveSessionTier, r as developmentRemoteCandidate, s as askSession, t as SESSION_SELECTORS } from "./session-
|
|
1
|
+
import { a as parseSessionSelector, c as rememberDevDatabase, i as enterEnvironment, l as rememberedDevDatabase, n as availableTiers, o as resolveSessionTier, r as developmentRemoteCandidate, s as askSession, t as SESSION_SELECTORS } from "./session-bPPOkolU.js";
|
|
2
2
|
export { SESSION_SELECTORS, askSession, availableTiers, developmentRemoteCandidate, enterEnvironment, parseSessionSelector, rememberDevDatabase, rememberedDevDatabase, resolveSessionTier };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as loadEnvironment, g as DEPLOY_ENVIRONMENTS, m as probeLocalStack, p as parseRawAssignments, t as DEV_DB_ENV, u as isDevDatabase, v as fileFor, y as isDeployEnvironment } from "./load-
|
|
1
|
+
import { d as loadEnvironment, g as DEPLOY_ENVIRONMENTS, m as probeLocalStack, p as parseRawAssignments, t as DEV_DB_ENV, u as isDevDatabase, v as fileFor, y as isDeployEnvironment } from "./load-lrgJ5Kz7.js";
|
|
2
2
|
//#region ../cli-core/src/env-runtime/ask.ts
|
|
3
3
|
/**
|
|
4
4
|
* The interactive half of session resolution, shared by `with-env` and the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as readProjectId, E as listContainerNames, P as resolveLayout, S as STACK_API_PORT, T as foreignStackProjectId, a as seedBuckets, d as loadEnvLoad, f as loadEnvSession, o as supabase, s as supabaseCapture, v as isDryRun, w as foreignStackMessage } from "./run-
|
|
1
|
+
import { D as readProjectId, E as listContainerNames, P as resolveLayout, S as STACK_API_PORT, T as foreignStackProjectId, a as seedBuckets, d as loadEnvLoad, f as loadEnvSession, o as supabase, s as supabaseCapture, v as isDryRun, w as foreignStackMessage } from "./run-D5iI9zve.js";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { writeFile } from "node:fs/promises";
|
|
4
4
|
//#region src/db/session-refresh.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as discoverRepoRoot
|
|
1
|
+
import { n as discoverRepoRoot } from "./root-RaJ8ECCO.js";
|
|
2
2
|
import { c as cliName, n as noteError, s as ownVersion } from "./failure-log-MSdCgvLc.js";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import * as Sentry from "@sentry/node";
|
|
@@ -301,7 +301,9 @@ function hasRealCaller(inRepo, isTTY) {
|
|
|
301
301
|
}
|
|
302
302
|
/**
|
|
303
303
|
* A failure the person caused and can fix without anyone's help: the wrong
|
|
304
|
-
* directory, a bad flag, a database that has not been set up.
|
|
304
|
+
* directory, a bad flag, a database that has not been set up. A `RepoNotFoundError` is
|
|
305
|
+
* not on this list by class: only the dispatcher marks the genuine
|
|
306
|
+
* outside-a-checkout case `expected` (`markOutsideCheckout`). These are
|
|
305
307
|
* printed and exit non-zero but are not bugs, so they are never sent to Sentry
|
|
306
308
|
* (the failure log still records them). Matched by name as well as class so
|
|
307
309
|
* that `UsageError` (`ui.ts`, which imports this module) and the product
|
|
@@ -309,7 +311,6 @@ function hasRealCaller(inRepo, isTTY) {
|
|
|
309
311
|
* opts in by setting `expected = true`.
|
|
310
312
|
*/
|
|
311
313
|
function isExpectedFailure(err) {
|
|
312
|
-
if (err instanceof RepoNotFoundError) return true;
|
|
313
314
|
if (!(err instanceof Error)) return false;
|
|
314
315
|
return err.name === "UsageError" || err.expected === true;
|
|
315
316
|
}
|
package/dist/telemetry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as hasRealCaller, c as lastSentryEventId, d as resolveDevtoolsDsn, i as devtoolsTelemetryEnabled, l as reportDevtoolsError, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as isExpectedFailure, t as captureDevtoolsDeprecation, u as reportDevtoolsFailure } from "./telemetry-
|
|
1
|
+
import { a as hasRealCaller, c as lastSentryEventId, d as resolveDevtoolsDsn, i as devtoolsTelemetryEnabled, l as reportDevtoolsError, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as isExpectedFailure, t as captureDevtoolsDeprecation, u as reportDevtoolsFailure } from "./telemetry-BDOwjuoC.js";
|
|
2
2
|
export { captureDevtoolsDeprecation, captureDevtoolsError, devtoolsEnvironment, devtoolsTelemetryEnabled, hasRealCaller, initDevtoolsTelemetry, isExpectedFailure, lastSentryEventId, reportDevtoolsError, reportDevtoolsFailure, resolveDevtoolsDsn };
|
package/dist/with-env.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as spawnProcess, t as exec } from "./spawn-BvLQzc_K.js";
|
|
2
|
-
import { _ as UnknownEnvironmentError, a as LocalStackOfflineError, c as applyDeployTierAliases, d as loadEnvironment, l as applyWranglerLocalDatabaseAlias, m as probeLocalStack, n as GENERATED_FILE, o as MissingEnvFileError } from "./load-
|
|
3
|
-
import { n as availableTiers, s as askSession, t as SESSION_SELECTORS } from "./session-
|
|
2
|
+
import { _ as UnknownEnvironmentError, a as LocalStackOfflineError, c as applyDeployTierAliases, d as loadEnvironment, l as applyWranglerLocalDatabaseAlias, m as probeLocalStack, n as GENERATED_FILE, o as MissingEnvFileError } from "./load-lrgJ5Kz7.js";
|
|
3
|
+
import { n as availableTiers, s as askSession, t as SESSION_SELECTORS } from "./session-bPPOkolU.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { existsSync, statSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname, join, resolve } from "node:path";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devdogsuga/devtools",
|
|
3
|
-
"version": "0.1.51-next.
|
|
3
|
+
"version": "0.1.51-next.548",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Contributor CLI for DevDogs repositories (the platform monorepo, DogDays, DogPack): the real tools with the session's tier filled in, `setup`, `db sync`, `db types`, `dev-data`, a menu over them, the checks CI runs, and the `with-env` launcher. Ships built JS; run via `pnpm devtools` in a product repo, `pnpm dlx @devdogsuga/devtools` (or the `devtools` bin once installed) from inside a clone.",
|
package/dist/stack-Cl_B_dt7.js
DELETED