@supacloud/cli 0.12.2 → 0.12.4
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.js +45 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6462,6 +6462,16 @@ var MAX_MIGRATION_VERSION = 9223372036854775807n;
|
|
|
6462
6462
|
var FALLBACK_MIGRATION_VERSION_BASE = 8000000000000000000n;
|
|
6463
6463
|
var FALLBACK_MIGRATION_VERSION_RANGE = 1000000000000000000n;
|
|
6464
6464
|
var FALLBACK_MIGRATION_VERSION_LIMIT = FALLBACK_MIGRATION_VERSION_BASE + FALLBACK_MIGRATION_VERSION_RANGE;
|
|
6465
|
+
function readMigrationFile(dir, file) {
|
|
6466
|
+
const rawBytes = readFileSync2(join(dir, file));
|
|
6467
|
+
return {
|
|
6468
|
+
file,
|
|
6469
|
+
name: basename(file, ".sql"),
|
|
6470
|
+
version: migrationVersionFromFilename(file),
|
|
6471
|
+
sql: Buffer.from(rawBytes).toString("utf8"),
|
|
6472
|
+
rawBytes
|
|
6473
|
+
};
|
|
6474
|
+
}
|
|
6465
6475
|
function migrationVersionFromFilename(file) {
|
|
6466
6476
|
const match = basename(file).match(/^(\d{8,20})[_-]/);
|
|
6467
6477
|
if (match) {
|
|
@@ -6515,17 +6525,40 @@ function migrationRows(data) {
|
|
|
6515
6525
|
const rows = Array.isArray(data) ? data : data?.rows || [];
|
|
6516
6526
|
return Array.isArray(rows) ? rows.filter((row) => Boolean(row && typeof row === "object")) : [];
|
|
6517
6527
|
}
|
|
6518
|
-
function
|
|
6528
|
+
function migrationIdentityKey(version, name) {
|
|
6519
6529
|
return `${version}\x00${name}`;
|
|
6520
6530
|
}
|
|
6521
|
-
function
|
|
6531
|
+
function nameBoundMigrationMarkerKeys(data) {
|
|
6522
6532
|
const keys = new Set;
|
|
6523
6533
|
for (const row of migrationRows(data)) {
|
|
6524
6534
|
if (row.version == null || row.name == null || !Array.isArray(row.statements))
|
|
6525
6535
|
continue;
|
|
6526
|
-
if (row.statements.length !== 1
|
|
6536
|
+
if (row.statements.length !== 1)
|
|
6537
|
+
continue;
|
|
6538
|
+
const name = String(row.name);
|
|
6539
|
+
const marker = row.statements[0];
|
|
6540
|
+
if (marker !== `baseline:${name}` && marker !== `direct-apply:${name}`)
|
|
6541
|
+
continue;
|
|
6542
|
+
keys.add(migrationIdentityKey(String(row.version), String(row.name)));
|
|
6543
|
+
}
|
|
6544
|
+
return keys;
|
|
6545
|
+
}
|
|
6546
|
+
function historicalChecksumMarkerKeys(data, migrationFiles) {
|
|
6547
|
+
const filesByKey = new Map(migrationFiles.map((migration) => [migrationIdentityKey(migration.version, migration.name), migration]));
|
|
6548
|
+
const keys = new Set;
|
|
6549
|
+
for (const row of migrationRows(data)) {
|
|
6550
|
+
if (row.version == null || row.name == null || !Array.isArray(row.statements) || row.statements.length !== 1)
|
|
6551
|
+
continue;
|
|
6552
|
+
const marker = row.statements[0];
|
|
6553
|
+
if (typeof marker !== "string" || !/^sha256:[0-9a-f]{64}$/.test(marker))
|
|
6554
|
+
continue;
|
|
6555
|
+
const key = migrationIdentityKey(String(row.version), String(row.name));
|
|
6556
|
+
const migration = filesByKey.get(key);
|
|
6557
|
+
if (!migration)
|
|
6527
6558
|
continue;
|
|
6528
|
-
|
|
6559
|
+
const checksum = createHash("sha256").update(migration.rawBytes).digest("hex");
|
|
6560
|
+
if (marker === `sha256:${checksum}`)
|
|
6561
|
+
keys.add(key);
|
|
6529
6562
|
}
|
|
6530
6563
|
return keys;
|
|
6531
6564
|
}
|
|
@@ -6747,11 +6780,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
|
|
|
6747
6780
|
text = `No .sql migration files found in ${dir}`;
|
|
6748
6781
|
break;
|
|
6749
6782
|
}
|
|
6750
|
-
const migrationFiles = sortMigrationFiles(files.map((file) => (
|
|
6751
|
-
file,
|
|
6752
|
-
name: basename(file, ".sql"),
|
|
6753
|
-
version: migrationVersionFromFilename(file)
|
|
6754
|
-
})));
|
|
6783
|
+
const migrationFiles = sortMigrationFiles(files.map((file) => readMigrationFile(dir, file)));
|
|
6755
6784
|
const migrationsResult = await http.get(`/v1/projects/${ref}/database/migrations`);
|
|
6756
6785
|
if (!migrationsResult.ok) {
|
|
6757
6786
|
text = `❌ Failed to load applied migrations (${migrationsResult.status}): ${JSON.stringify(migrationsResult.data)}`;
|
|
@@ -6761,10 +6790,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
|
|
|
6761
6790
|
const appliedKeys = appliedMigrationKeys(migrationsResult.data);
|
|
6762
6791
|
const pending = migrationFiles.filter(({ name, version }) => !appliedKeys.has(name) && !appliedKeys.has(String(version)));
|
|
6763
6792
|
const alreadyApplied = migrationFiles.filter(({ name, version }) => appliedKeys.has(name) || appliedKeys.has(String(version)));
|
|
6764
|
-
const pendingWithSql = pending
|
|
6765
|
-
...migration,
|
|
6766
|
-
sql: readFileSync2(join(dir, migration.file), "utf-8")
|
|
6767
|
-
}));
|
|
6793
|
+
const pendingWithSql = pending;
|
|
6768
6794
|
let vectorEnabled = null;
|
|
6769
6795
|
if (pendingWithSql.some(({ sql }) => sqlReferencesVector(sql) || sqlCreatesVectorExtension(sql))) {
|
|
6770
6796
|
const extResult = await execSql("SELECT extname AS name FROM pg_extension WHERE extname = 'vector';");
|
|
@@ -6787,13 +6813,14 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
|
|
|
6787
6813
|
}
|
|
6788
6814
|
const applied = [];
|
|
6789
6815
|
const skipped = [];
|
|
6790
|
-
const
|
|
6791
|
-
|
|
6792
|
-
|
|
6816
|
+
const nameBoundMarkerKeys = nameBoundMigrationMarkerKeys(migrationsResult.data);
|
|
6817
|
+
const historicalChecksumKeys = historicalChecksumMarkerKeys(migrationsResult.data, migrationFiles);
|
|
6818
|
+
for (const { file, name, version, sql } of migrationFiles) {
|
|
6819
|
+
const migrationKey = migrationIdentityKey(version, name);
|
|
6820
|
+
if (nameBoundMarkerKeys.has(migrationKey) || historicalChecksumKeys.has(migrationKey)) {
|
|
6793
6821
|
skipped.push(file);
|
|
6794
6822
|
continue;
|
|
6795
6823
|
}
|
|
6796
|
-
const sql = readFileSync2(join(dir, file), "utf-8");
|
|
6797
6824
|
const r = await http.post(`/v1/projects/${ref}/database/migrations`, { name, sql, version });
|
|
6798
6825
|
if (r.ok) {
|
|
6799
6826
|
applied.push(file);
|
|
@@ -6831,11 +6858,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
|
|
|
6831
6858
|
text = `No .sql migration files found in ${dir}`;
|
|
6832
6859
|
break;
|
|
6833
6860
|
}
|
|
6834
|
-
const migrationFiles = sortMigrationFiles(files.map((file) => (
|
|
6835
|
-
file,
|
|
6836
|
-
name: basename(file, ".sql"),
|
|
6837
|
-
version: migrationVersionFromFilename(file)
|
|
6838
|
-
})));
|
|
6861
|
+
const migrationFiles = sortMigrationFiles(files.map((file) => readMigrationFile(dir, file)));
|
|
6839
6862
|
const r = await http.get(`/v1/projects/${ref}/database/migrations`);
|
|
6840
6863
|
if (!r.ok) {
|
|
6841
6864
|
text = `❌ Failed to load applied migrations (${r.status}): ${JSON.stringify(r.data)}`;
|