@noormdev/sdk 1.0.0-alpha.16 → 1.0.0-alpha.17

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import { processFile, DtReader, isTemplate, FORMAT_VERSION, DT_EXTENSIONS, encryptWithPassphrase, ENCODED_TYPES, GZIP_THRESHOLD, GZIP_RATIO_THRESHOLD } from './chunk-BTXUEWYQ.js';
2
- import { NOORM_TABLES, initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, encryptVaultKey } from './chunk-ZRZ7AECF.js';
2
+ import { initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, noormDb, getNoormTables, encryptVaultKey } from './chunk-LJDHQEWW.js';
3
3
  import { observer } from './chunk-4HW4CS2C.js';
4
4
  import { constants, existsSync, readFileSync, mkdirSync, writeFileSync, createWriteStream } from 'fs';
5
5
  import path, { join, dirname } from 'path';
@@ -1889,7 +1889,7 @@ async function createConnection(config, configName = "__default__") {
1889
1889
  destroy: wrappedDestroy
1890
1890
  };
1891
1891
  observer.emit("connection:open", { configName, dialect: config.dialect });
1892
- await waitForIdentityToLoad(trackedConn.db);
1892
+ await waitForIdentityToLoad(trackedConn.db, config.dialect);
1893
1893
  return trackedConn;
1894
1894
  }
1895
1895
  var SYSTEM_DATABASES = {
@@ -1920,7 +1920,7 @@ async function testConnection(config, options = {}) {
1920
1920
  // src/core/version/types.ts
1921
1921
  var CURRENT_VERSIONS = Object.freeze({
1922
1922
  /** Database tracking tables schema version */
1923
- schema: 1,
1923
+ schema: 2,
1924
1924
  /** State file (state.enc) schema version */
1925
1925
  state: 1,
1926
1926
  /** Settings file (settings.yml) schema version */
@@ -2022,6 +2022,171 @@ var v1 = {
2022
2022
  await db.schema.dropTable("__noorm_version__").execute();
2023
2023
  }
2024
2024
  };
2025
+ var TABLE_MAP = [
2026
+ { old: "__noorm_version__", new: "version" },
2027
+ { old: "__noorm_change__", new: "change" },
2028
+ { old: "__noorm_executions__", new: "executions" },
2029
+ { old: "__noorm_lock__", new: "lock" },
2030
+ { old: "__noorm_identities__", new: "identities" },
2031
+ { old: "__noorm_vault__", new: "vault" }
2032
+ ];
2033
+ var INDEXES = [
2034
+ { name: "idx_executions_change_id", table: "executions", columns: ["change_id"] },
2035
+ { name: "idx_change_name_config", table: "change", columns: ["name", "config_name"] },
2036
+ { name: "idx_vault_secret_key", table: "vault", columns: ["secret_key"] }
2037
+ ];
2038
+ var v2 = {
2039
+ version: 2,
2040
+ description: "Move tracking tables to noorm schema",
2041
+ async up(db, dialect) {
2042
+ if (dialect === "sqlite" || dialect === "mysql") return;
2043
+ await db.transaction().execute(async (trx) => {
2044
+ if (dialect === "postgres") {
2045
+ await sql`CREATE SCHEMA IF NOT EXISTS noorm`.execute(trx);
2046
+ } else {
2047
+ await sql`IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'noorm') EXEC('CREATE SCHEMA noorm')`.execute(trx);
2048
+ }
2049
+ if (dialect === "postgres") {
2050
+ const { rows } = await sql`
2051
+ SELECT constraint_name
2052
+ FROM information_schema.table_constraints
2053
+ WHERE table_name = '__noorm_executions__'
2054
+ AND constraint_type = 'FOREIGN KEY'
2055
+ `.execute(trx);
2056
+ for (const row of rows) {
2057
+ await sql`ALTER TABLE __noorm_executions__ DROP CONSTRAINT ${sql.ref(row.constraint_name)}`.execute(trx);
2058
+ }
2059
+ } else {
2060
+ const { rows } = await sql`
2061
+ SELECT fk.name AS fk_name
2062
+ FROM sys.foreign_keys fk
2063
+ JOIN sys.tables t ON fk.parent_object_id = t.object_id
2064
+ WHERE t.name = '__noorm_executions__'
2065
+ `.execute(trx);
2066
+ for (const row of rows) {
2067
+ await sql`ALTER TABLE __noorm_executions__ DROP CONSTRAINT ${sql.ref(row.fk_name)}`.execute(trx);
2068
+ }
2069
+ }
2070
+ if (dialect === "postgres") {
2071
+ for (const idx of INDEXES) {
2072
+ await sql`DROP INDEX IF EXISTS ${sql.ref(idx.name)}`.execute(trx);
2073
+ }
2074
+ } else {
2075
+ const prefixedTables = {
2076
+ executions: "__noorm_executions__",
2077
+ change: "__noorm_change__",
2078
+ vault: "__noorm_vault__"
2079
+ };
2080
+ for (const idx of INDEXES) {
2081
+ const tableName = prefixedTables[idx.table];
2082
+ await sql`
2083
+ IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = ${idx.name})
2084
+ DROP INDEX ${sql.ref(idx.name)} ON ${sql.table(tableName)}
2085
+ `.execute(trx);
2086
+ }
2087
+ }
2088
+ for (const t of TABLE_MAP) {
2089
+ if (dialect === "postgres") {
2090
+ await sql`ALTER TABLE ${sql.table(t.old)} SET SCHEMA noorm`.execute(trx);
2091
+ } else {
2092
+ await sql`ALTER SCHEMA noorm TRANSFER ${sql.ref(`dbo.${t.old}`)}`.execute(trx);
2093
+ }
2094
+ }
2095
+ for (const t of TABLE_MAP) {
2096
+ if (dialect === "postgres") {
2097
+ await sql`ALTER TABLE ${sql.table(`noorm.${t.old}`)} RENAME TO ${sql.ref(t.new)}`.execute(trx);
2098
+ } else {
2099
+ await sql`EXEC sp_rename ${sql.raw(`'noorm.${t.old}'`)}, ${sql.raw(`'${t.new}'`)}`.execute(trx);
2100
+ }
2101
+ }
2102
+ await sql`
2103
+ ALTER TABLE ${sql.table("noorm.executions")}
2104
+ ADD CONSTRAINT fk_executions_change_id
2105
+ FOREIGN KEY (change_id) REFERENCES ${sql.table("noorm.change")}(id)
2106
+ ON DELETE CASCADE
2107
+ `.execute(trx);
2108
+ for (const idx of INDEXES) {
2109
+ const cols = idx.columns.join(", ");
2110
+ await sql`CREATE INDEX ${sql.ref(idx.name)} ON ${sql.table(`noorm.${idx.table}`)} (${sql.raw(cols)})`.execute(trx);
2111
+ }
2112
+ });
2113
+ },
2114
+ async down(db, dialect) {
2115
+ if (dialect === "sqlite" || dialect === "mysql") return;
2116
+ await db.transaction().execute(async (trx) => {
2117
+ if (dialect === "postgres") {
2118
+ const { rows } = await sql`
2119
+ SELECT constraint_name
2120
+ FROM information_schema.table_constraints
2121
+ WHERE table_schema = 'noorm'
2122
+ AND table_name = 'executions'
2123
+ AND constraint_type = 'FOREIGN KEY'
2124
+ `.execute(trx);
2125
+ for (const row of rows) {
2126
+ await sql`ALTER TABLE ${sql.table("noorm.executions")} DROP CONSTRAINT ${sql.ref(row.constraint_name)}`.execute(trx);
2127
+ }
2128
+ } else {
2129
+ const { rows } = await sql`
2130
+ SELECT fk.name AS fk_name
2131
+ FROM sys.foreign_keys fk
2132
+ JOIN sys.tables t ON fk.parent_object_id = t.object_id
2133
+ JOIN sys.schemas s ON t.schema_id = s.schema_id
2134
+ WHERE t.name = 'executions' AND s.name = 'noorm'
2135
+ `.execute(trx);
2136
+ for (const row of rows) {
2137
+ await sql`ALTER TABLE ${sql.table("noorm.executions")} DROP CONSTRAINT ${sql.ref(row.fk_name)}`.execute(trx);
2138
+ }
2139
+ }
2140
+ if (dialect === "postgres") {
2141
+ for (const idx of INDEXES) {
2142
+ await sql`DROP INDEX IF EXISTS ${sql.ref(`noorm.${idx.name}`)}`.execute(trx);
2143
+ }
2144
+ } else {
2145
+ for (const idx of INDEXES) {
2146
+ await sql`
2147
+ IF EXISTS (SELECT 1 FROM sys.indexes WHERE name = ${idx.name})
2148
+ DROP INDEX ${sql.ref(idx.name)} ON ${sql.table(`noorm.${idx.table}`)}
2149
+ `.execute(trx);
2150
+ }
2151
+ }
2152
+ for (const t of TABLE_MAP) {
2153
+ if (dialect === "postgres") {
2154
+ await sql`ALTER TABLE ${sql.table(`noorm.${t.new}`)} RENAME TO ${sql.ref(t.old)}`.execute(trx);
2155
+ } else {
2156
+ await sql`EXEC sp_rename ${sql.raw(`'noorm.${t.new}'`)}, ${sql.raw(`'${t.old}'`)}`.execute(trx);
2157
+ }
2158
+ }
2159
+ for (const t of TABLE_MAP) {
2160
+ if (dialect === "postgres") {
2161
+ await sql`ALTER TABLE ${sql.table(`noorm.${t.old}`)} SET SCHEMA public`.execute(trx);
2162
+ } else {
2163
+ await sql`ALTER SCHEMA dbo TRANSFER ${sql.ref(`noorm.${t.old}`)}`.execute(trx);
2164
+ }
2165
+ }
2166
+ await sql`
2167
+ ALTER TABLE __noorm_executions__
2168
+ ADD CONSTRAINT fk_executions_change_id
2169
+ FOREIGN KEY (change_id) REFERENCES __noorm_change__(id)
2170
+ ON DELETE CASCADE
2171
+ `.execute(trx);
2172
+ for (const idx of INDEXES) {
2173
+ const prefixedTables = {
2174
+ executions: "__noorm_executions__",
2175
+ change: "__noorm_change__",
2176
+ vault: "__noorm_vault__"
2177
+ };
2178
+ const tableName = prefixedTables[idx.table];
2179
+ const cols = idx.columns.join(", ");
2180
+ await sql`CREATE INDEX ${sql.ref(idx.name)} ON ${sql.table(tableName)} (${sql.raw(cols)})`.execute(trx);
2181
+ }
2182
+ if (dialect === "postgres") {
2183
+ await sql`DROP SCHEMA IF EXISTS noorm`.execute(trx);
2184
+ } else {
2185
+ await sql`IF EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'noorm') DROP SCHEMA noorm`.execute(trx);
2186
+ }
2187
+ });
2188
+ }
2189
+ };
2025
2190
 
2026
2191
  // src/core/update/checker.ts
2027
2192
  function getCurrentVersion() {
@@ -2029,26 +2194,43 @@ function getCurrentVersion() {
2029
2194
  }
2030
2195
 
2031
2196
  // src/core/version/schema/index.ts
2032
- var MIGRATIONS = [v1];
2033
- async function tablesExist(db) {
2034
- const [result, err] = await attempt(async () => {
2035
- await sql`SELECT 1 FROM __noorm_version__ LIMIT 1`.execute(db);
2197
+ var MIGRATIONS = [v1, v2];
2198
+ async function tablesExist(db, dialect) {
2199
+ const [legacyResult] = await attempt(async () => {
2200
+ await db.selectFrom("__noorm_version__").select("id").limit(1).executeTakeFirst();
2036
2201
  return true;
2037
2202
  });
2038
- if (err) return false;
2039
- return result;
2203
+ if (legacyResult) return true;
2204
+ if (dialect === "postgres" || dialect === "mssql") {
2205
+ const ndb = noormDb(db, dialect);
2206
+ const tables = getNoormTables(dialect);
2207
+ const [schemaResult] = await attempt(async () => {
2208
+ await ndb.selectFrom(tables.version).select("id").limit(1).executeTakeFirst();
2209
+ return true;
2210
+ });
2211
+ if (schemaResult) return true;
2212
+ }
2213
+ return false;
2040
2214
  }
2041
- async function getSchemaVersion(db) {
2042
- const exists = await tablesExist(db);
2215
+ async function getSchemaVersion(db, dialect) {
2216
+ const exists = await tablesExist(db, dialect);
2043
2217
  if (!exists) return 0;
2044
- const [result, err] = await attempt(async () => {
2218
+ const [legacyResult] = await attempt(async () => {
2045
2219
  return db.selectFrom("__noorm_version__").select("noorm_version").orderBy("id", "desc").limit(1).executeTakeFirst();
2046
2220
  });
2047
- if (err) return 0;
2048
- return result?.noorm_version ?? 0;
2221
+ if (legacyResult) return legacyResult.noorm_version ?? 0;
2222
+ if (dialect === "postgres" || dialect === "mssql") {
2223
+ const ndb = noormDb(db, dialect);
2224
+ const tables = getNoormTables(dialect);
2225
+ const [schemaResult] = await attempt(async () => {
2226
+ return ndb.selectFrom(tables.version).select("noorm_version").orderBy("id", "desc").limit(1).executeTakeFirst();
2227
+ });
2228
+ if (schemaResult) return schemaResult.noorm_version ?? 0;
2229
+ }
2230
+ return 0;
2049
2231
  }
2050
- async function checkSchemaVersion(db) {
2051
- const current = await getSchemaVersion(db);
2232
+ async function checkSchemaVersion(db, dialect) {
2233
+ const current = await getSchemaVersion(db, dialect);
2052
2234
  const expected = CURRENT_VERSIONS.schema;
2053
2235
  observer.emit("version:schema:checking", { current });
2054
2236
  return {
@@ -2070,7 +2252,9 @@ async function bootstrapSchema(db, dialect, options) {
2070
2252
  throw new MigrationError("schema", migration.version, err);
2071
2253
  }
2072
2254
  }
2073
- await db.insertInto("__noorm_version__").values({
2255
+ const ndb = noormDb(db, dialect);
2256
+ const tables = getNoormTables(dialect);
2257
+ await ndb.insertInto(tables.version).values({
2074
2258
  cli_version: getCurrentVersion(),
2075
2259
  noorm_version: CURRENT_VERSIONS.schema,
2076
2260
  state_version: CURRENT_VERSIONS.state,
@@ -2082,22 +2266,37 @@ async function bootstrapSchema(db, dialect, options) {
2082
2266
  to: CURRENT_VERSIONS.schema,
2083
2267
  durationMs
2084
2268
  });
2085
- await waitForIdentityToLoad(db);
2269
+ await waitForIdentityToLoad(db, dialect);
2086
2270
  }
2087
- async function getLatestVersionRecord(db) {
2088
- const exists = await tablesExist(db);
2271
+ async function getLatestVersionRecord(db, dialect) {
2272
+ const exists = await tablesExist(db, dialect);
2089
2273
  if (!exists) return null;
2090
- const [result, err] = await attempt(async () => {
2274
+ const [legacyResult] = await attempt(async () => {
2091
2275
  return db.selectFrom("__noorm_version__").select(["state_version", "settings_version"]).orderBy("id", "desc").limit(1).executeTakeFirst();
2092
2276
  });
2093
- if (err || !result) return null;
2094
- return {
2095
- stateVersion: result.state_version,
2096
- settingsVersion: result.settings_version
2097
- };
2277
+ if (legacyResult) {
2278
+ return {
2279
+ stateVersion: legacyResult.state_version,
2280
+ settingsVersion: legacyResult.settings_version
2281
+ };
2282
+ }
2283
+ if (dialect === "postgres" || dialect === "mssql") {
2284
+ const ndb = noormDb(db, dialect);
2285
+ const tables = getNoormTables(dialect);
2286
+ const [schemaResult] = await attempt(async () => {
2287
+ return ndb.selectFrom(tables.version).select(["state_version", "settings_version"]).orderBy("id", "desc").limit(1).executeTakeFirst();
2288
+ });
2289
+ if (schemaResult) {
2290
+ return {
2291
+ stateVersion: schemaResult.state_version,
2292
+ settingsVersion: schemaResult.settings_version
2293
+ };
2294
+ }
2295
+ }
2296
+ return null;
2098
2297
  }
2099
2298
  async function migrateSchema(db, dialect, options) {
2100
- const status = await checkSchemaVersion(db);
2299
+ const status = await checkSchemaVersion(db, dialect);
2101
2300
  if (status.isNewer) {
2102
2301
  observer.emit("version:mismatch", {
2103
2302
  layer: "schema",
@@ -2116,7 +2315,7 @@ async function migrateSchema(db, dialect, options) {
2116
2315
  from: status.current,
2117
2316
  to: CURRENT_VERSIONS.schema
2118
2317
  });
2119
- const existing = await getLatestVersionRecord(db);
2318
+ const existing = await getLatestVersionRecord(db, dialect);
2120
2319
  const pendingMigrations = MIGRATIONS.filter((m) => m.version > status.current);
2121
2320
  for (const migration of pendingMigrations) {
2122
2321
  const [, err] = await attempt(() => migration.up(db, dialect));
@@ -2124,7 +2323,9 @@ async function migrateSchema(db, dialect, options) {
2124
2323
  throw new MigrationError("schema", migration.version, err);
2125
2324
  }
2126
2325
  }
2127
- await db.insertInto("__noorm_version__").values({
2326
+ const ndb = noormDb(db, dialect);
2327
+ const tables = getNoormTables(dialect);
2328
+ await ndb.insertInto(tables.version).values({
2128
2329
  cli_version: getCurrentVersion(),
2129
2330
  noorm_version: CURRENT_VERSIONS.schema,
2130
2331
  state_version: existing?.stateVersion ?? CURRENT_VERSIONS.state,
@@ -2136,7 +2337,7 @@ async function migrateSchema(db, dialect, options) {
2136
2337
  to: CURRENT_VERSIONS.schema,
2137
2338
  durationMs
2138
2339
  });
2139
- await waitForIdentityToLoad(db);
2340
+ await waitForIdentityToLoad(db, dialect);
2140
2341
  }
2141
2342
  async function ensureSchemaVersion(db, dialect, options) {
2142
2343
  await migrateSchema(db, dialect);
@@ -2284,9 +2485,11 @@ addMaskedFields([
2284
2485
  ]);
2285
2486
 
2286
2487
  // src/core/identity/sync.ts
2287
- async function registerIdentity(db, identity) {
2488
+ async function registerIdentity(db, identity, dialect) {
2489
+ const ndb = noormDb(db, dialect);
2490
+ const tables = getNoormTables(dialect);
2288
2491
  const [existing, selectErr] = await attempt(
2289
- () => db.selectFrom("__noorm_identities__").select(["id"]).where("identity_hash", "=", identity.identityHash).executeTakeFirst()
2492
+ () => ndb.selectFrom(tables.identities).select(["id"]).where("identity_hash", "=", identity.identityHash).executeTakeFirst()
2290
2493
  );
2291
2494
  if (selectErr) {
2292
2495
  observer.emit("error", {
@@ -2302,7 +2505,7 @@ async function registerIdentity(db, identity) {
2302
2505
  }
2303
2506
  if (existing) {
2304
2507
  const [, updateErr] = await attempt(
2305
- () => db.updateTable("__noorm_identities__").set({ last_seen_at: /* @__PURE__ */ new Date() }).where("identity_hash", "=", identity.identityHash).execute()
2508
+ () => ndb.updateTable(tables.identities).set({ last_seen_at: /* @__PURE__ */ new Date() }).where("identity_hash", "=", identity.identityHash).execute()
2306
2509
  );
2307
2510
  if (updateErr) {
2308
2511
  observer.emit("error", {
@@ -2319,7 +2522,7 @@ async function registerIdentity(db, identity) {
2319
2522
  return { ok: true, registered: false };
2320
2523
  }
2321
2524
  const [, insertErr] = await attempt(
2322
- () => db.insertInto("__noorm_identities__").values({
2525
+ () => ndb.insertInto(tables.identities).values({
2323
2526
  identity_hash: identity.identityHash,
2324
2527
  email: identity.email,
2325
2528
  name: identity.name,
@@ -2362,11 +2565,11 @@ function resolveIdentity2(options = {}) {
2362
2565
  function getIdentityForConfig(config) {
2363
2566
  return resolveIdentity2({ configIdentity: config.identity });
2364
2567
  }
2365
- async function waitForIdentityToLoad(db) {
2568
+ async function waitForIdentityToLoad(db, dialect) {
2366
2569
  const identity = await loadExistingIdentity();
2367
2570
  if (!identity) observer.emit("identity:not-found");
2368
2571
  if (!identity) return;
2369
- const [, err] = await attempt(() => registerIdentity(db, identity));
2572
+ const [, err] = await attempt(() => registerIdentity(db, identity, dialect));
2370
2573
  if (err) observer.emit("error", {
2371
2574
  error: err,
2372
2575
  source: "identity:ensure",
@@ -2946,9 +3149,13 @@ function getExtension(filename) {
2946
3149
  }
2947
3150
  var ChangeHistory = class {
2948
3151
  #db;
3152
+ #ndb;
3153
+ #tables;
2949
3154
  #configName;
2950
- constructor(db, configName) {
3155
+ constructor(db, configName, dialect = "sqlite") {
2951
3156
  this.#db = db;
3157
+ this.#ndb = noormDb(db, dialect);
3158
+ this.#tables = getNoormTables(dialect);
2952
3159
  this.#configName = configName;
2953
3160
  }
2954
3161
  // ─────────────────────────────────────────────────────────
@@ -2965,7 +3172,7 @@ var ChangeHistory = class {
2965
3172
  */
2966
3173
  async getStatus(name) {
2967
3174
  const [record, err] = await attempt(
2968
- () => this.#db.selectFrom(NOORM_TABLES.change).select([
3175
+ () => this.#ndb.selectFrom(this.#tables.change).select([
2969
3176
  "name",
2970
3177
  "status",
2971
3178
  "executed_at",
@@ -2986,7 +3193,7 @@ var ChangeHistory = class {
2986
3193
  return null;
2987
3194
  }
2988
3195
  const [revertRecord] = await attempt(
2989
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["executed_at"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "revert").where("status", "=", "success").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3196
+ () => this.#ndb.selectFrom(this.#tables.change).select(["executed_at"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "revert").where("status", "=", "success").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
2990
3197
  );
2991
3198
  return {
2992
3199
  name: record.name,
@@ -3007,7 +3214,7 @@ var ChangeHistory = class {
3007
3214
  async getAllStatuses() {
3008
3215
  const statuses = /* @__PURE__ */ new Map();
3009
3216
  const [records, err] = await attempt(
3010
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["id", "name", "status", "executed_at", "executed_by", "error_message"]).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").execute()
3217
+ () => this.#ndb.selectFrom(this.#tables.change).select(["id", "name", "status", "executed_at", "executed_by", "error_message"]).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").execute()
3011
3218
  );
3012
3219
  if (err) {
3013
3220
  observer.emit("error", {
@@ -3031,7 +3238,7 @@ var ChangeHistory = class {
3031
3238
  }
3032
3239
  }
3033
3240
  const [reverts] = await attempt(
3034
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["name", "executed_at"]).where("change_type", "=", "change").where("direction", "=", "revert").where("status", "=", "success").where("config_name", "=", this.#configName).orderBy("id", "desc").execute()
3241
+ () => this.#ndb.selectFrom(this.#tables.change).select(["name", "executed_at"]).where("change_type", "=", "change").where("direction", "=", "revert").where("status", "=", "success").where("config_name", "=", this.#configName).orderBy("id", "desc").execute()
3035
3242
  );
3036
3243
  if (reverts) {
3037
3244
  const seenReverts = /* @__PURE__ */ new Set();
@@ -3061,7 +3268,7 @@ var ChangeHistory = class {
3061
3268
  return { needsRun: true, reason: "force" };
3062
3269
  }
3063
3270
  const [record, err] = await attempt(
3064
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["status", "checksum"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3271
+ () => this.#ndb.selectFrom(this.#tables.change).select(["status", "checksum"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3065
3272
  );
3066
3273
  if (err) {
3067
3274
  observer.emit("error", {
@@ -3126,7 +3333,7 @@ var ChangeHistory = class {
3126
3333
  */
3127
3334
  async createOperation(data2) {
3128
3335
  const [result, err] = await attempt(
3129
- () => this.#db.insertInto(NOORM_TABLES.change).values({
3336
+ () => this.#ndb.insertInto(this.#tables.change).values({
3130
3337
  name: data2.name,
3131
3338
  change_type: "change",
3132
3339
  direction: data2.direction,
@@ -3170,7 +3377,7 @@ var ChangeHistory = class {
3170
3377
  status: "pending"
3171
3378
  }));
3172
3379
  const [, err] = await attempt(
3173
- () => this.#db.insertInto(NOORM_TABLES.executions).values(values).execute()
3380
+ () => this.#ndb.insertInto(this.#tables.executions).values(values).execute()
3174
3381
  );
3175
3382
  if (err) {
3176
3383
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -3193,7 +3400,7 @@ var ChangeHistory = class {
3193
3400
  */
3194
3401
  async updateFileExecution(operationId, filepath, status, durationMs, errorMessage, skipReason) {
3195
3402
  const [result, err] = await attempt(
3196
- () => this.#db.updateTable(NOORM_TABLES.executions).set({
3403
+ () => this.#ndb.updateTable(this.#tables.executions).set({
3197
3404
  status,
3198
3405
  duration_ms: Math.round(durationMs),
3199
3406
  error_message: errorMessage ?? "",
@@ -3228,7 +3435,7 @@ var ChangeHistory = class {
3228
3435
  */
3229
3436
  async skipRemainingFiles(operationId, reason) {
3230
3437
  const [, err] = await attempt(
3231
- () => this.#db.updateTable(NOORM_TABLES.executions).set({
3438
+ () => this.#ndb.updateTable(this.#tables.executions).set({
3232
3439
  status: "skipped",
3233
3440
  skip_reason: reason
3234
3441
  }).where("change_id", "=", operationId).where("status", "=", "pending").execute()
@@ -3251,7 +3458,7 @@ var ChangeHistory = class {
3251
3458
  async finalizeOperation(operationId, status, checksum, durationMs, errorMessage) {
3252
3459
  const truncatedError = errorMessage ? errorMessage.slice(0, 2e3) : "";
3253
3460
  const [result, err] = await attempt(
3254
- () => this.#db.updateTable(NOORM_TABLES.change).set({
3461
+ () => this.#ndb.updateTable(this.#tables.change).set({
3255
3462
  status,
3256
3463
  checksum,
3257
3464
  duration_ms: Math.round(durationMs),
@@ -3292,7 +3499,7 @@ var ChangeHistory = class {
3292
3499
  */
3293
3500
  async recordReset(executedBy, reason) {
3294
3501
  const [result, err] = await attempt(
3295
- () => this.#db.insertInto(NOORM_TABLES.change).values({
3502
+ () => this.#ndb.insertInto(this.#tables.change).values({
3296
3503
  name: "__reset__",
3297
3504
  change_type: "change",
3298
3505
  direction: "change",
@@ -3322,14 +3529,14 @@ var ChangeHistory = class {
3322
3529
  */
3323
3530
  async deleteRecords(name) {
3324
3531
  const [operations, queryErr] = await attempt(
3325
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["id"]).where("name", "=", name).where("change_type", "=", "change").where("config_name", "=", this.#configName).execute()
3532
+ () => this.#ndb.selectFrom(this.#tables.change).select(["id"]).where("name", "=", name).where("change_type", "=", "change").where("config_name", "=", this.#configName).execute()
3326
3533
  );
3327
3534
  if (queryErr || !operations || operations.length === 0) {
3328
3535
  return;
3329
3536
  }
3330
3537
  const operationIds = operations.map((o) => o.id);
3331
3538
  const [, execErr] = await attempt(
3332
- () => this.#db.deleteFrom(NOORM_TABLES.executions).where("change_id", "in", operationIds).execute()
3539
+ () => this.#ndb.deleteFrom(this.#tables.executions).where("change_id", "in", operationIds).execute()
3333
3540
  );
3334
3541
  if (execErr) {
3335
3542
  observer.emit("error", {
@@ -3339,7 +3546,7 @@ var ChangeHistory = class {
3339
3546
  });
3340
3547
  }
3341
3548
  const [, changeErr] = await attempt(
3342
- () => this.#db.deleteFrom(NOORM_TABLES.change).where("id", "in", operationIds).execute()
3549
+ () => this.#ndb.deleteFrom(this.#tables.change).where("id", "in", operationIds).execute()
3343
3550
  );
3344
3551
  if (changeErr) {
3345
3552
  observer.emit("error", {
@@ -3359,7 +3566,7 @@ var ChangeHistory = class {
3359
3566
  * @param limit - Max records to return
3360
3567
  */
3361
3568
  async getHistory(name, limit) {
3362
- let query = this.#db.selectFrom(NOORM_TABLES.change).select([
3569
+ let query = this.#ndb.selectFrom(this.#tables.change).select([
3363
3570
  "id",
3364
3571
  "name",
3365
3572
  "direction",
@@ -3407,7 +3614,7 @@ var ChangeHistory = class {
3407
3614
  * @param limit - Max records to return
3408
3615
  */
3409
3616
  async getUnifiedHistory(changeTypes, limit) {
3410
- let query = this.#db.selectFrom(NOORM_TABLES.change).select([
3617
+ let query = this.#ndb.selectFrom(this.#tables.change).select([
3411
3618
  "id",
3412
3619
  "name",
3413
3620
  "change_type",
@@ -3463,7 +3670,7 @@ var ChangeHistory = class {
3463
3670
  */
3464
3671
  async getFileHistory(operationId) {
3465
3672
  const [records, err] = await attempt(
3466
- () => this.#db.selectFrom(NOORM_TABLES.executions).select([
3673
+ () => this.#ndb.selectFrom(this.#tables.executions).select([
3467
3674
  "id",
3468
3675
  "change_id",
3469
3676
  "filepath",
@@ -3513,9 +3720,13 @@ var ChangeHistory = class {
3513
3720
  };
3514
3721
  var Tracker = class {
3515
3722
  #db;
3723
+ #ndb;
3724
+ #tables;
3516
3725
  #configName;
3517
- constructor(db, configName) {
3726
+ constructor(db, configName, dialect = "sqlite") {
3518
3727
  this.#db = db;
3728
+ this.#ndb = noormDb(db, dialect);
3729
+ this.#tables = getNoormTables(dialect);
3519
3730
  this.#configName = configName;
3520
3731
  }
3521
3732
  /**
@@ -3538,15 +3749,16 @@ var Tracker = class {
3538
3749
  return { needsRun: true, reason: "force" };
3539
3750
  }
3540
3751
  const [record, err] = await attempt(
3541
- () => this.#db.selectFrom(NOORM_TABLES.executions).innerJoin(
3542
- NOORM_TABLES.change,
3543
- `${NOORM_TABLES.change}.id`,
3544
- `${NOORM_TABLES.executions}.change_id`
3752
+ () => this.#ndb.selectFrom(this.#tables.executions).innerJoin(
3753
+ this.#tables.change,
3754
+ `${this.#tables.change}.id`,
3755
+ `${this.#tables.executions}.change_id`
3756
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3545
3757
  ).select((eb) => [
3546
- eb.ref(`${NOORM_TABLES.executions}.checksum`).as("checksum"),
3547
- eb.ref(`${NOORM_TABLES.executions}.status`).as("exec_status"),
3548
- eb.ref(`${NOORM_TABLES.change}.status`).as("change_status")
3549
- ]).where(`${NOORM_TABLES.executions}.filepath`, "=", filepath).where(`${NOORM_TABLES.change}.config_name`, "=", this.#configName).orderBy(`${NOORM_TABLES.executions}.id`, "desc").limit(1).executeTakeFirst()
3758
+ eb.ref(`${this.#tables.executions}.checksum`).as("checksum"),
3759
+ eb.ref(`${this.#tables.executions}.status`).as("exec_status"),
3760
+ eb.ref(`${this.#tables.change}.status`).as("change_status")
3761
+ ]).where(`${this.#tables.executions}.filepath`, "=", filepath).where(`${this.#tables.change}.config_name`, "=", this.#configName).orderBy(`${this.#tables.executions}.id`, "desc").limit(1).executeTakeFirst()
3550
3762
  );
3551
3763
  if (err) {
3552
3764
  observer.emit("error", {
@@ -3602,7 +3814,7 @@ var Tracker = class {
3602
3814
  const direction = data2.direction ?? "commit";
3603
3815
  const dbDirection = direction === "commit" ? "change" : "revert";
3604
3816
  const [result, err] = await attempt(
3605
- () => this.#db.insertInto(NOORM_TABLES.change).values({
3817
+ () => this.#ndb.insertInto(this.#tables.change).values({
3606
3818
  name: data2.name,
3607
3819
  change_type: data2.changeType,
3608
3820
  direction: dbDirection,
@@ -3639,7 +3851,7 @@ var Tracker = class {
3639
3851
  */
3640
3852
  async recordExecution(data2) {
3641
3853
  const [, err] = await attempt(
3642
- () => this.#db.insertInto(NOORM_TABLES.executions).values({
3854
+ () => this.#ndb.insertInto(this.#tables.executions).values({
3643
3855
  change_id: data2.changeId,
3644
3856
  filepath: data2.filepath,
3645
3857
  file_type: "sql",
@@ -3673,7 +3885,7 @@ var Tracker = class {
3673
3885
  async finalizeOperation(operationId, status, durationMs, checksum, errorMessage) {
3674
3886
  const truncatedError = errorMessage ? errorMessage.slice(0, 2e3) : "";
3675
3887
  const [result, err] = await attempt(
3676
- () => this.#db.updateTable(NOORM_TABLES.change).set({
3888
+ () => this.#ndb.updateTable(this.#tables.change).set({
3677
3889
  status,
3678
3890
  duration_ms: Math.round(durationMs),
3679
3891
  checksum: checksum ?? "",
@@ -3724,7 +3936,7 @@ var Tracker = class {
3724
3936
  status: "pending"
3725
3937
  }));
3726
3938
  const [, err] = await attempt(
3727
- () => this.#db.insertInto(NOORM_TABLES.executions).values(values).execute()
3939
+ () => this.#ndb.insertInto(this.#tables.executions).values(values).execute()
3728
3940
  );
3729
3941
  if (err) {
3730
3942
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -3752,7 +3964,7 @@ var Tracker = class {
3752
3964
  */
3753
3965
  async updateFileExecution(operationId, filepath, status, durationMs, errorMessage, skipReason) {
3754
3966
  const [result, err] = await attempt(
3755
- () => this.#db.updateTable(NOORM_TABLES.executions).set({
3967
+ () => this.#ndb.updateTable(this.#tables.executions).set({
3756
3968
  status,
3757
3969
  duration_ms: Math.round(durationMs),
3758
3970
  error_message: errorMessage ?? "",
@@ -3792,7 +4004,7 @@ var Tracker = class {
3792
4004
  */
3793
4005
  async skipRemainingFiles(operationId, reason) {
3794
4006
  const [, err] = await attempt(
3795
- () => this.#db.updateTable(NOORM_TABLES.executions).set({
4007
+ () => this.#ndb.updateTable(this.#tables.executions).set({
3796
4008
  status: "skipped",
3797
4009
  skip_reason: reason
3798
4010
  }).where("change_id", "=", operationId).where("status", "=", "pending").execute()
@@ -3823,7 +4035,7 @@ var Tracker = class {
3823
4035
  return { needsRun: true, reason: "force" };
3824
4036
  }
3825
4037
  const [record, err] = await attempt(
3826
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["status", "checksum"]).where("name", "=", name).where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
4038
+ () => this.#ndb.selectFrom(this.#tables.change).select(["status", "checksum"]).where("name", "=", name).where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3827
4039
  );
3828
4040
  if (err) {
3829
4041
  observer.emit("error", {
@@ -3877,11 +4089,13 @@ var Tracker = class {
3877
4089
  var ChangeTracker = class extends Tracker {
3878
4090
  // Store db and configName for change-specific queries
3879
4091
  // (Tracker uses private fields, so we need our own references)
3880
- #db;
4092
+ #ndb;
4093
+ #tables;
3881
4094
  #configName;
3882
- constructor(db, configName) {
3883
- super(db, configName);
3884
- this.#db = db;
4095
+ constructor(db, configName, dialect = "sqlite") {
4096
+ super(db, configName, dialect);
4097
+ this.#ndb = noormDb(db, dialect);
4098
+ this.#tables = getNoormTables(dialect);
3885
4099
  this.#configName = configName;
3886
4100
  }
3887
4101
  /**
@@ -3893,7 +4107,7 @@ var ChangeTracker = class extends Tracker {
3893
4107
  */
3894
4108
  async canRevert(name, force) {
3895
4109
  const [record, err] = await attempt(
3896
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["status"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
4110
+ () => this.#ndb.selectFrom(this.#tables.change).select(["status"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3897
4111
  );
3898
4112
  if (err) {
3899
4113
  observer.emit("error", {
@@ -3933,11 +4147,11 @@ var ChangeTracker = class extends Tracker {
3933
4147
  */
3934
4148
  async markAsReverted(name) {
3935
4149
  const [record] = await attempt(
3936
- () => this.#db.selectFrom(NOORM_TABLES.change).select(["id"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
4150
+ () => this.#ndb.selectFrom(this.#tables.change).select(["id"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", "change").where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
3937
4151
  );
3938
4152
  if (record) {
3939
4153
  await attempt(
3940
- () => this.#db.updateTable(NOORM_TABLES.change).set({ status: "reverted" }).where("id", "=", record.id).execute()
4154
+ () => this.#ndb.updateTable(this.#tables.change).set({ status: "reverted" }).where("id", "=", record.id).execute()
3941
4155
  );
3942
4156
  }
3943
4157
  }
@@ -3953,7 +4167,7 @@ var ChangeTracker = class extends Tracker {
3953
4167
  */
3954
4168
  async markAllAsStale() {
3955
4169
  const [result, err] = await attempt(
3956
- () => this.#db.updateTable(NOORM_TABLES.change).set({ status: "stale" }).where("direction", "=", "change").where("status", "in", ["success", "failed", "pending"]).where("config_name", "=", this.#configName).execute()
4170
+ () => this.#ndb.updateTable(this.#tables.change).set({ status: "stale" }).where("direction", "=", "change").where("status", "in", ["success", "failed", "pending"]).where("config_name", "=", this.#configName).execute()
3957
4171
  );
3958
4172
  if (err) {
3959
4173
  observer.emit("error", {
@@ -4065,7 +4279,7 @@ var LockManager = class {
4065
4279
  observer.emit("lock:acquiring", { configName, identity });
4066
4280
  while (true) {
4067
4281
  await this.cleanupExpired(db, configName, opts.dialect);
4068
- const existing = await this.getLock(db, configName);
4282
+ const existing = await this.getLock(db, configName, opts.dialect);
4069
4283
  if (!existing) {
4070
4284
  const lock = await this.createLock(db, configName, identity, opts);
4071
4285
  observer.emit("lock:acquired", {
@@ -4117,18 +4331,21 @@ var LockManager = class {
4117
4331
  * @param db - Kysely database instance
4118
4332
  * @param configName - Config/database scope
4119
4333
  * @param identity - Identity of the lock holder
4334
+ * @param dialect - Database dialect for schema-aware table resolution
4120
4335
  * @throws LockNotFoundError if no lock exists
4121
4336
  * @throws LockOwnershipError if lock is held by someone else
4122
4337
  */
4123
- async release(db, configName, identity) {
4124
- const existing = await this.getLock(db, configName);
4338
+ async release(db, configName, identity, dialect) {
4339
+ const ndb = noormDb(db, dialect);
4340
+ const tables = getNoormTables(dialect);
4341
+ const existing = await this.getLock(db, configName, dialect);
4125
4342
  if (!existing) {
4126
4343
  throw new LockNotFoundError(configName, identity);
4127
4344
  }
4128
4345
  if (existing.lockedBy !== identity) {
4129
4346
  throw new LockOwnershipError(configName, identity, existing.lockedBy);
4130
4347
  }
4131
- await db.deleteFrom(NOORM_TABLES.lock).where("config_name", "=", configName).where("locked_by", "=", identity).execute();
4348
+ await ndb.deleteFrom(tables.lock).where("config_name", "=", configName).where("locked_by", "=", identity).execute();
4132
4349
  observer.emit("lock:released", { configName, identity });
4133
4350
  }
4134
4351
  /**
@@ -4139,14 +4356,17 @@ var LockManager = class {
4139
4356
  *
4140
4357
  * @param db - Kysely database instance
4141
4358
  * @param configName - Config/database scope
4359
+ * @param dialect - Database dialect for schema-aware table resolution
4142
4360
  * @returns true if a lock was released, false if none existed
4143
4361
  */
4144
- async forceRelease(db, configName) {
4145
- const existing = await this.getLock(db, configName);
4362
+ async forceRelease(db, configName, dialect) {
4363
+ const ndb = noormDb(db, dialect);
4364
+ const tables = getNoormTables(dialect);
4365
+ const existing = await this.getLock(db, configName, dialect);
4146
4366
  if (!existing) {
4147
4367
  return false;
4148
4368
  }
4149
- await db.deleteFrom(NOORM_TABLES.lock).where("config_name", "=", configName).execute();
4369
+ await ndb.deleteFrom(tables.lock).where("config_name", "=", configName).execute();
4150
4370
  observer.emit("lock:released", {
4151
4371
  configName,
4152
4372
  identity: existing.lockedBy
@@ -4167,11 +4387,12 @@ var LockManager = class {
4167
4387
  * @returns Result of the operation
4168
4388
  */
4169
4389
  async withLock(db, configName, identity, operation, options = {}) {
4390
+ const opts = { ...DEFAULT_LOCK_OPTIONS, ...options };
4170
4391
  await this.acquire(db, configName, identity, options);
4171
4392
  try {
4172
4393
  return await operation();
4173
4394
  } finally {
4174
- const [, err] = await attempt(() => this.release(db, configName, identity));
4395
+ const [, err] = await attempt(() => this.release(db, configName, identity, opts.dialect));
4175
4396
  if (err) {
4176
4397
  observer.emit("error", {
4177
4398
  source: "lock",
@@ -4189,12 +4410,13 @@ var LockManager = class {
4189
4410
  * @param db - Kysely database instance
4190
4411
  * @param configName - Config/database scope
4191
4412
  * @param identity - Expected lock holder
4413
+ * @param dialect - Database dialect for schema-aware table resolution
4192
4414
  * @throws LockExpiredError if lock has expired
4193
4415
  * @throws LockOwnershipError if lock is held by someone else
4194
4416
  * @throws LockNotFoundError if no lock exists
4195
4417
  */
4196
4418
  async validate(db, configName, identity, dialect = "postgres") {
4197
- const existing = await this.getLock(db, configName);
4419
+ const existing = await this.getLock(db, configName, dialect);
4198
4420
  if (!existing) {
4199
4421
  throw new LockNotFoundError(configName, identity);
4200
4422
  }
@@ -4216,7 +4438,8 @@ var LockManager = class {
4216
4438
  * @returns Updated lock state
4217
4439
  */
4218
4440
  async extend(db, configName, identity, options = {}) {
4219
- await this.validate(db, configName, identity);
4441
+ const opts = { ...DEFAULT_LOCK_OPTIONS, ...options };
4442
+ await this.validate(db, configName, identity, opts.dialect);
4220
4443
  return this.extendLock(db, configName, identity, options);
4221
4444
  }
4222
4445
  /**
@@ -4229,7 +4452,7 @@ var LockManager = class {
4229
4452
  */
4230
4453
  async status(db, configName, dialect = "postgres") {
4231
4454
  await this.cleanupExpired(db, configName, dialect);
4232
- const lock = await this.getLock(db, configName);
4455
+ const lock = await this.getLock(db, configName, dialect);
4233
4456
  return {
4234
4457
  isLocked: lock !== null,
4235
4458
  lock
@@ -4241,8 +4464,10 @@ var LockManager = class {
4241
4464
  /**
4242
4465
  * Get lock from database, or null if none exists.
4243
4466
  */
4244
- async getLock(db, configName) {
4245
- const row = await db.selectFrom(NOORM_TABLES.lock).selectAll().where("config_name", "=", configName).executeTakeFirst();
4467
+ async getLock(db, configName, dialect) {
4468
+ const ndb = noormDb(db, dialect);
4469
+ const tables = getNoormTables(dialect);
4470
+ const row = await ndb.selectFrom(tables.lock).selectAll().where("config_name", "=", configName).executeTakeFirst();
4246
4471
  if (!row) {
4247
4472
  return null;
4248
4473
  }
@@ -4257,9 +4482,11 @@ var LockManager = class {
4257
4482
  * Create a new lock in the database.
4258
4483
  */
4259
4484
  async createLock(db, configName, identity, opts) {
4485
+ const ndb = noormDb(db, opts.dialect);
4486
+ const tables = getNoormTables(opts.dialect);
4260
4487
  const now = /* @__PURE__ */ new Date();
4261
4488
  const expiresAt = new Date(now.getTime() + opts.timeout);
4262
- await db.insertInto(NOORM_TABLES.lock).values({
4489
+ await ndb.insertInto(tables.lock).values({
4263
4490
  config_name: configName,
4264
4491
  locked_by: identity,
4265
4492
  locked_at: formatDateForDialect(now, opts.dialect),
@@ -4279,6 +4506,8 @@ var LockManager = class {
4279
4506
  async extendLock(db, configName, identity, opts) {
4280
4507
  const dialect = opts.dialect ?? DEFAULT_LOCK_OPTIONS.dialect;
4281
4508
  const timeout = opts.timeout ?? DEFAULT_LOCK_OPTIONS.timeout;
4509
+ const ndb = noormDb(db, dialect);
4510
+ const tables = getNoormTables(dialect);
4282
4511
  const now = /* @__PURE__ */ new Date();
4283
4512
  const expiresAt = new Date(now.getTime() + timeout);
4284
4513
  const updateValues = {
@@ -4287,19 +4516,21 @@ var LockManager = class {
4287
4516
  if (opts.reason !== void 0) {
4288
4517
  updateValues["reason"] = opts.reason;
4289
4518
  }
4290
- await db.updateTable(NOORM_TABLES.lock).set(updateValues).where("config_name", "=", configName).where("locked_by", "=", identity).execute();
4291
- const lock = await this.getLock(db, configName);
4519
+ await ndb.updateTable(tables.lock).set(updateValues).where("config_name", "=", configName).where("locked_by", "=", identity).execute();
4520
+ const lock = await this.getLock(db, configName, dialect);
4292
4521
  return lock;
4293
4522
  }
4294
4523
  /**
4295
4524
  * Clean up expired locks.
4296
4525
  */
4297
4526
  async cleanupExpired(db, configName, dialect = "postgres") {
4527
+ const ndb = noormDb(db, dialect);
4528
+ const tables = getNoormTables(dialect);
4298
4529
  const now = /* @__PURE__ */ new Date();
4299
4530
  const nowForDb = formatDateForDialect(now, dialect);
4300
- const expired = await db.selectFrom(NOORM_TABLES.lock).select(["locked_by"]).where("config_name", "=", configName).where("expires_at", "<", nowForDb).executeTakeFirst();
4531
+ const expired = await ndb.selectFrom(tables.lock).select(["locked_by"]).where("config_name", "=", configName).where("expires_at", "<", nowForDb).executeTakeFirst();
4301
4532
  if (expired) {
4302
- await db.deleteFrom(NOORM_TABLES.lock).where("config_name", "=", configName).where("expires_at", "<", nowForDb).execute();
4533
+ await ndb.deleteFrom(tables.lock).where("config_name", "=", configName).where("expires_at", "<", nowForDb).execute();
4303
4534
  observer.emit("lock:expired", {
4304
4535
  configName,
4305
4536
  previousHolder: expired.locked_by
@@ -4358,7 +4589,7 @@ async function executeChange(context, change, options = {}) {
4358
4589
  return createFailedResult(change.name, "change", checksumErr.message, start);
4359
4590
  }
4360
4591
  const changeChecksum = computeCombinedChecksum(checksums);
4361
- const history = new ChangeHistory(context.db, context.configName);
4592
+ const history = new ChangeHistory(context.db, context.configName, context.dialect ?? "postgres");
4362
4593
  if (!opts.dryRun && !opts.preview) {
4363
4594
  const needsRunResult = await history.needsRun(
4364
4595
  change.name,
@@ -4407,7 +4638,7 @@ async function executeChange(context, change, options = {}) {
4407
4638
  start
4408
4639
  )
4409
4640
  );
4410
- await attempt(() => lockManager.release(context.db, context.configName, identity));
4641
+ await attempt(() => lockManager.release(context.db, context.configName, identity, context.dialect ?? "postgres"));
4411
4642
  if (execErr) {
4412
4643
  throw execErr;
4413
4644
  }
@@ -4430,8 +4661,8 @@ async function revertChange(context, change, options = {}) {
4430
4661
  return createFailedResult(change.name, "revert", checksumErr.message, start);
4431
4662
  }
4432
4663
  const revertChecksum = computeCombinedChecksum(checksums);
4433
- const history = new ChangeHistory(context.db, context.configName);
4434
- const tracker = new ChangeTracker(context.db, context.configName);
4664
+ const history = new ChangeHistory(context.db, context.configName, context.dialect ?? "postgres");
4665
+ const tracker = new ChangeTracker(context.db, context.configName, context.dialect ?? "postgres");
4435
4666
  if (!opts.dryRun && !opts.preview) {
4436
4667
  const canRevertResult = await tracker.canRevert(change.name, opts.force);
4437
4668
  if (!canRevertResult.canRevert) {
@@ -4479,7 +4710,7 @@ async function revertChange(context, change, options = {}) {
4479
4710
  start
4480
4711
  )
4481
4712
  );
4482
- await attempt(() => lockManager.release(context.db, context.configName, identity));
4713
+ await attempt(() => lockManager.release(context.db, context.configName, identity, context.dialect ?? "postgres"));
4483
4714
  if (execErr) {
4484
4715
  throw execErr;
4485
4716
  }
@@ -4893,7 +5124,7 @@ var ChangeManager = class {
4893
5124
  #history;
4894
5125
  constructor(context) {
4895
5126
  this.#context = context;
4896
- this.#history = new ChangeHistory(context.db, context.configName);
5127
+ this.#history = new ChangeHistory(context.db, context.configName, context.dialect ?? "postgres");
4897
5128
  }
4898
5129
  // ─────────────────────────────────────────────────────────
4899
5130
  // List
@@ -5513,7 +5744,7 @@ async function runFile(context, filepath, options = {}) {
5513
5744
  filepath,
5514
5745
  configName: context.configName
5515
5746
  });
5516
- const tracker = new Tracker(context.db, context.configName);
5747
+ const tracker = new Tracker(context.db, context.configName, context.dialect ?? "postgres");
5517
5748
  const operationName = `run:${(/* @__PURE__ */ new Date()).toISOString()}`;
5518
5749
  const [operationId, createErr] = await attempt(
5519
5750
  () => tracker.createOperation({
@@ -5645,7 +5876,7 @@ async function executeFiles2(context, files, runOptions, execOptions) {
5645
5876
  durationMs: durationMs2
5646
5877
  };
5647
5878
  }
5648
- const tracker = execOptions.tracker ?? new Tracker(context.db, context.configName);
5879
+ const tracker = execOptions.tracker ?? new Tracker(context.db, context.configName, context.dialect ?? "postgres");
5649
5880
  const [operationId, createErr] = await attempt(
5650
5881
  () => tracker.createOperation({
5651
5882
  name: execOptions.operationName,
@@ -6231,13 +6462,14 @@ var RunNamespace = class {
6231
6462
  configName: this.#state.config.name,
6232
6463
  identity: this.#state.identity,
6233
6464
  projectRoot: this.#state.projectRoot,
6465
+ dialect: this.#state.config.connection.dialect,
6234
6466
  config: this.#state.config,
6235
6467
  secrets: state.getAllSecrets(this.#state.config.name),
6236
6468
  globalSecrets: state.getAllGlobalSecrets()
6237
6469
  };
6238
6470
  }
6239
6471
  };
6240
- var EXCLUDED_SCHEMAS = ["pg_catalog", "information_schema", "pg_toast"];
6472
+ var EXCLUDED_SCHEMAS = ["pg_catalog", "information_schema", "pg_toast", "noorm"];
6241
6473
  var postgresExploreOperations = {
6242
6474
  async getOverview(db) {
6243
6475
  const [tables, views, procedures, functions, types, indexes, foreignKeys] = await Promise.all([
@@ -7435,7 +7667,7 @@ var mysqlExploreOperations = {
7435
7667
  };
7436
7668
  }
7437
7669
  };
7438
- var EXCLUDED_SCHEMAS2 = ["sys", "INFORMATION_SCHEMA", "guest"];
7670
+ var EXCLUDED_SCHEMAS2 = ["sys", "INFORMATION_SCHEMA", "guest", "noorm"];
7439
7671
  var mssqlExploreOperations = {
7440
7672
  async getOverview(db) {
7441
7673
  const [tables, views, procedures, functions, types, indexes, foreignKeys] = await Promise.all([
@@ -8649,10 +8881,10 @@ function getTeardownOperations(dialect) {
8649
8881
  }
8650
8882
 
8651
8883
  // src/core/teardown/operations.ts
8652
- var NOORM_TABLE_NAMES = new Set(Object.values(NOORM_TABLES));
8653
8884
  function isNoormTable2(name) {
8654
8885
  if (!name) return false;
8655
- return name.startsWith("__noorm_") || NOORM_TABLE_NAMES.has(name);
8886
+ if (name.startsWith("__noorm_")) return true;
8887
+ return false;
8656
8888
  }
8657
8889
  async function truncateData(db, dialect, options = {}) {
8658
8890
  const startTime = performance.now();
@@ -8825,11 +9057,13 @@ async function teardownSchema(db, dialect, options = {}) {
8825
9057
  if (options.configName && options.executedBy && !options.dryRun) {
8826
9058
  const tracker = new ChangeTracker(
8827
9059
  db,
8828
- options.configName
9060
+ options.configName,
9061
+ dialect
8829
9062
  );
8830
9063
  const history = new ChangeHistory(
8831
9064
  db,
8832
- options.configName
9065
+ options.configName,
9066
+ dialect
8833
9067
  );
8834
9068
  result.staleCount = await tracker.markAllAsStale();
8835
9069
  const parts = [
@@ -9058,7 +9292,8 @@ var LockNamespace = class {
9058
9292
  await lockManager.release(
9059
9293
  this.#kysely,
9060
9294
  this.#state.config.name,
9061
- identityStr
9295
+ identityStr,
9296
+ this.#state.config.connection.dialect
9062
9297
  );
9063
9298
  }
9064
9299
  /**
@@ -9110,7 +9345,8 @@ var LockNamespace = class {
9110
9345
  const lockManager = getLockManager();
9111
9346
  return lockManager.forceRelease(
9112
9347
  this.#kysely,
9113
- this.#state.config.name
9348
+ this.#state.config.name,
9349
+ this.#state.config.connection.dialect
9114
9350
  );
9115
9351
  }
9116
9352
  // ─────────────────────────────────────────────────────
@@ -9123,9 +9359,11 @@ var LockNamespace = class {
9123
9359
  return this.#state.connection.db;
9124
9360
  }
9125
9361
  };
9126
- async function getUsersWithoutVaultAccess(db) {
9362
+ async function getUsersWithoutVaultAccess(db, dialect) {
9363
+ const ndb = noormDb(db, dialect);
9364
+ const tables = getNoormTables(dialect);
9127
9365
  const [rows, err] = await attempt(async () => {
9128
- return db.selectFrom(NOORM_TABLES.identities).select([
9366
+ return ndb.selectFrom(tables.identities).select([
9129
9367
  "identity_hash",
9130
9368
  "public_key",
9131
9369
  "name",
@@ -9140,11 +9378,13 @@ async function getUsersWithoutVaultAccess(db) {
9140
9378
  email: r.email
9141
9379
  }));
9142
9380
  }
9143
- async function propagateVaultKey(db, vaultKey) {
9144
- const users = await getUsersWithoutVaultAccess(db);
9381
+ async function propagateVaultKey(db, vaultKey, dialect) {
9382
+ const ndb = noormDb(db, dialect);
9383
+ const tables = getNoormTables(dialect);
9384
+ const users = await getUsersWithoutVaultAccess(db, dialect);
9145
9385
  if (users.length === 0) {
9146
9386
  const [countResult2] = await attempt(async () => {
9147
- return db.selectFrom(NOORM_TABLES.identities).select(db.fn.count("id").as("count")).where("encrypted_vault_key", "is not", null).executeTakeFirst();
9387
+ return ndb.selectFrom(tables.identities).select(ndb.fn.count("id").as("count")).where("encrypted_vault_key", "is not", null).executeTakeFirst();
9148
9388
  });
9149
9389
  return {
9150
9390
  propagatedTo: [],
@@ -9156,7 +9396,7 @@ async function propagateVaultKey(db, vaultKey) {
9156
9396
  const encrypted = encryptVaultKey(vaultKey, user.publicKey);
9157
9397
  const encryptedJson = JSON.stringify(encrypted);
9158
9398
  const [, err] = await attempt(async () => {
9159
- return db.updateTable(NOORM_TABLES.identities).set({ encrypted_vault_key: encryptedJson }).where("identity_hash", "=", user.identityHash).execute();
9399
+ return ndb.updateTable(tables.identities).set({ encrypted_vault_key: encryptedJson }).where("identity_hash", "=", user.identityHash).execute();
9160
9400
  });
9161
9401
  if (!err) {
9162
9402
  propagatedTo.push(user.identityHash);
@@ -9167,7 +9407,7 @@ async function propagateVaultKey(db, vaultKey) {
9167
9407
  }
9168
9408
  }
9169
9409
  const [countResult] = await attempt(async () => {
9170
- return db.selectFrom(NOORM_TABLES.identities).select(db.fn.count("id").as("count")).where("encrypted_vault_key", "is not", null).executeTakeFirst();
9410
+ return ndb.selectFrom(tables.identities).select(ndb.fn.count("id").as("count")).where("encrypted_vault_key", "is not", null).executeTakeFirst();
9171
9411
  });
9172
9412
  const totalWithAccess = countResult ? Number(countResult.count) : 0;
9173
9413
  const alreadyHadAccess = totalWithAccess - propagatedTo.length;
@@ -9247,18 +9487,20 @@ async function copyVaultSecrets(sourceConfig, destConfig, keys, identityHash, pr
9247
9487
  const sourceVaultKey = await getVaultKey(
9248
9488
  ctx.source.db,
9249
9489
  identityHash,
9250
- privateKey
9490
+ privateKey,
9491
+ ctx.source.dialect
9251
9492
  );
9252
9493
  if (!sourceVaultKey) {
9253
9494
  throw new Error(`No vault access on source config "${sourceConfig.name}"`);
9254
9495
  }
9255
- const destStatus = await getVaultStatus(ctx.destination.db, identityHash);
9496
+ const destStatus = await getVaultStatus(ctx.destination.db, identityHash, ctx.destination.dialect);
9256
9497
  let destVaultKey = null;
9257
9498
  if (!destStatus.isInitialized) {
9258
9499
  const [newKey, initErr] = await initializeVault(
9259
9500
  ctx.destination.db,
9260
9501
  identityHash,
9261
- publicKey
9502
+ publicKey,
9503
+ ctx.destination.dialect
9262
9504
  );
9263
9505
  if (initErr) {
9264
9506
  throw new Error(`Failed to initialize vault on destination: ${initErr.message}`);
@@ -9270,13 +9512,14 @@ async function copyVaultSecrets(sourceConfig, destConfig, keys, identityHash, pr
9270
9512
  destVaultKey = await getVaultKey(
9271
9513
  ctx.destination.db,
9272
9514
  identityHash,
9273
- privateKey
9515
+ privateKey,
9516
+ ctx.destination.dialect
9274
9517
  );
9275
9518
  }
9276
9519
  if (!destVaultKey) {
9277
9520
  throw new Error("Failed to get vault key for destination");
9278
9521
  }
9279
- const allSourceSecrets = await getAllVaultSecrets(ctx.source.db, sourceVaultKey);
9522
+ const allSourceSecrets = await getAllVaultSecrets(ctx.source.db, sourceVaultKey, ctx.source.dialect);
9280
9523
  const secretsToCopy = keys === "all" ? Object.entries(allSourceSecrets) : Object.entries(allSourceSecrets).filter(([key]) => keys.includes(key));
9281
9524
  const result = {
9282
9525
  copied: [],
@@ -9294,7 +9537,7 @@ async function copyVaultSecrets(sourceConfig, destConfig, keys, identityHash, pr
9294
9537
  }
9295
9538
  }
9296
9539
  for (const [key, secret] of secretsToCopy) {
9297
- const exists = await vaultSecretExists(ctx.destination.db, key);
9540
+ const exists = await vaultSecretExists(ctx.destination.db, key, ctx.destination.dialect);
9298
9541
  if (exists && !force) {
9299
9542
  result.skipped.push(key);
9300
9543
  continue;
@@ -9305,7 +9548,8 @@ async function copyVaultSecrets(sourceConfig, destConfig, keys, identityHash, pr
9305
9548
  destVaultKey,
9306
9549
  key,
9307
9550
  secret.value,
9308
- setBy
9551
+ setBy,
9552
+ ctx.destination.dialect
9309
9553
  );
9310
9554
  if (setErr) {
9311
9555
  result.errors.push({ key, error: setErr.message });
@@ -9346,7 +9590,8 @@ var VaultNamespace = class {
9346
9590
  return initializeVault(
9347
9591
  this.#kysely,
9348
9592
  this.#identityHash,
9349
- this.#publicKey
9593
+ this.#publicKey,
9594
+ this.#dialect
9350
9595
  );
9351
9596
  }
9352
9597
  /**
@@ -9360,7 +9605,8 @@ var VaultNamespace = class {
9360
9605
  async status() {
9361
9606
  return getVaultStatus(
9362
9607
  this.#kysely,
9363
- this.#identityHash
9608
+ this.#identityHash,
9609
+ this.#dialect
9364
9610
  );
9365
9611
  }
9366
9612
  // ─────────────────────────────────────────────────────
@@ -9382,7 +9628,8 @@ var VaultNamespace = class {
9382
9628
  vaultKey,
9383
9629
  key,
9384
9630
  value,
9385
- formatIdentity(this.#state.identity)
9631
+ formatIdentity(this.#state.identity),
9632
+ this.#dialect
9386
9633
  );
9387
9634
  }
9388
9635
  /**
@@ -9399,7 +9646,8 @@ var VaultNamespace = class {
9399
9646
  return getVaultSecret(
9400
9647
  this.#kysely,
9401
9648
  vaultKey,
9402
- key
9649
+ key,
9650
+ this.#dialect
9403
9651
  );
9404
9652
  }
9405
9653
  /**
@@ -9415,7 +9663,8 @@ var VaultNamespace = class {
9415
9663
  if (!vaultKey) return {};
9416
9664
  return getAllVaultSecrets(
9417
9665
  this.#kysely,
9418
- vaultKey
9666
+ vaultKey,
9667
+ this.#dialect
9419
9668
  );
9420
9669
  }
9421
9670
  /**
@@ -9428,7 +9677,8 @@ var VaultNamespace = class {
9428
9677
  */
9429
9678
  async list() {
9430
9679
  return listVaultSecretKeys(
9431
- this.#kysely
9680
+ this.#kysely,
9681
+ this.#dialect
9432
9682
  );
9433
9683
  }
9434
9684
  /**
@@ -9442,7 +9692,8 @@ var VaultNamespace = class {
9442
9692
  async delete(key) {
9443
9693
  return deleteVaultSecret(
9444
9694
  this.#kysely,
9445
- key
9695
+ key,
9696
+ this.#dialect
9446
9697
  );
9447
9698
  }
9448
9699
  /**
@@ -9456,7 +9707,8 @@ var VaultNamespace = class {
9456
9707
  async exists(key) {
9457
9708
  return vaultSecretExists(
9458
9709
  this.#kysely,
9459
- key
9710
+ key,
9711
+ this.#dialect
9460
9712
  );
9461
9713
  }
9462
9714
  // ─────────────────────────────────────────────────────
@@ -9477,7 +9729,8 @@ var VaultNamespace = class {
9477
9729
  }
9478
9730
  return propagateVaultKey(
9479
9731
  this.#kysely,
9480
- vaultKey
9732
+ vaultKey,
9733
+ this.#dialect
9481
9734
  );
9482
9735
  }
9483
9736
  /**
@@ -9516,11 +9769,15 @@ var VaultNamespace = class {
9516
9769
  const identity = this.#state.identity;
9517
9770
  return identity["publicKey"] ?? "";
9518
9771
  }
9772
+ get #dialect() {
9773
+ return this.#state.config.connection.dialect;
9774
+ }
9519
9775
  async #getVaultKey(privateKey) {
9520
9776
  return getVaultKey(
9521
9777
  this.#kysely,
9522
9778
  this.#identityHash,
9523
- privateKey
9779
+ privateKey,
9780
+ this.#dialect
9524
9781
  );
9525
9782
  }
9526
9783
  };