@supacloud/cli 0.12.2 → 0.12.3

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 (2) hide show
  1. package/dist/index.js +36 -17
  2. 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) {
@@ -6529,6 +6539,25 @@ function baselineMigrationKeys(data) {
6529
6539
  }
6530
6540
  return keys;
6531
6541
  }
6542
+ function historicalChecksumMarkerKeys(data, migrationFiles) {
6543
+ const filesByKey = new Map(migrationFiles.map((migration) => [baselineMigrationKey(migration.version, migration.name), migration]));
6544
+ const keys = new Set;
6545
+ for (const row of migrationRows(data)) {
6546
+ if (row.version == null || row.name == null || !Array.isArray(row.statements) || row.statements.length !== 1)
6547
+ continue;
6548
+ const marker = row.statements[0];
6549
+ if (typeof marker !== "string" || !/^sha256:[0-9a-f]{64}$/.test(marker))
6550
+ continue;
6551
+ const key = baselineMigrationKey(String(row.version), String(row.name));
6552
+ const migration = filesByKey.get(key);
6553
+ if (!migration)
6554
+ continue;
6555
+ const checksum = createHash("sha256").update(migration.rawBytes).digest("hex");
6556
+ if (marker === `sha256:${checksum}`)
6557
+ keys.add(key);
6558
+ }
6559
+ return keys;
6560
+ }
6532
6561
  function isAlreadyAppliedMigrationResponse(response) {
6533
6562
  if (response.status !== 409 || !response.data || typeof response.data !== "object")
6534
6563
  return false;
@@ -6747,11 +6776,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
6747
6776
  text = `No .sql migration files found in ${dir}`;
6748
6777
  break;
6749
6778
  }
6750
- const migrationFiles = sortMigrationFiles(files.map((file) => ({
6751
- file,
6752
- name: basename(file, ".sql"),
6753
- version: migrationVersionFromFilename(file)
6754
- })));
6779
+ const migrationFiles = sortMigrationFiles(files.map((file) => readMigrationFile(dir, file)));
6755
6780
  const migrationsResult = await http.get(`/v1/projects/${ref}/database/migrations`);
6756
6781
  if (!migrationsResult.ok) {
6757
6782
  text = `❌ Failed to load applied migrations (${migrationsResult.status}): ${JSON.stringify(migrationsResult.data)}`;
@@ -6761,10 +6786,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
6761
6786
  const appliedKeys = appliedMigrationKeys(migrationsResult.data);
6762
6787
  const pending = migrationFiles.filter(({ name, version }) => !appliedKeys.has(name) && !appliedKeys.has(String(version)));
6763
6788
  const alreadyApplied = migrationFiles.filter(({ name, version }) => appliedKeys.has(name) || appliedKeys.has(String(version)));
6764
- const pendingWithSql = pending.map((migration) => ({
6765
- ...migration,
6766
- sql: readFileSync2(join(dir, migration.file), "utf-8")
6767
- }));
6789
+ const pendingWithSql = pending;
6768
6790
  let vectorEnabled = null;
6769
6791
  if (pendingWithSql.some(({ sql }) => sqlReferencesVector(sql) || sqlCreatesVectorExtension(sql))) {
6770
6792
  const extResult = await execSql("SELECT extname AS name FROM pg_extension WHERE extname = 'vector';");
@@ -6788,12 +6810,13 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
6788
6810
  const applied = [];
6789
6811
  const skipped = [];
6790
6812
  const baselineKeys = baselineMigrationKeys(migrationsResult.data);
6791
- for (const { file, name, version } of migrationFiles) {
6792
- if (baselineKeys.has(baselineMigrationKey(version, name))) {
6813
+ const historicalChecksumKeys = historicalChecksumMarkerKeys(migrationsResult.data, migrationFiles);
6814
+ for (const { file, name, version, sql } of migrationFiles) {
6815
+ const migrationKey = baselineMigrationKey(version, name);
6816
+ if (baselineKeys.has(migrationKey) || historicalChecksumKeys.has(migrationKey)) {
6793
6817
  skipped.push(file);
6794
6818
  continue;
6795
6819
  }
6796
- const sql = readFileSync2(join(dir, file), "utf-8");
6797
6820
  const r = await http.post(`/v1/projects/${ref}/database/migrations`, { name, sql, version });
6798
6821
  if (r.ok) {
6799
6822
  applied.push(file);
@@ -6831,11 +6854,7 @@ Actions: ${allActions.join(", ")}${readOnly ? " (read-only mode)" : ""}`, {
6831
6854
  text = `No .sql migration files found in ${dir}`;
6832
6855
  break;
6833
6856
  }
6834
- const migrationFiles = sortMigrationFiles(files.map((file) => ({
6835
- file,
6836
- name: basename(file, ".sql"),
6837
- version: migrationVersionFromFilename(file)
6838
- })));
6857
+ const migrationFiles = sortMigrationFiles(files.map((file) => readMigrationFile(dir, file)));
6839
6858
  const r = await http.get(`/v1/projects/${ref}/database/migrations`);
6840
6859
  if (!r.ok) {
6841
6860
  text = `❌ Failed to load applied migrations (${r.status}): ${JSON.stringify(r.data)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",