@noormdev/sdk 1.5.0 → 1.5.1
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.
|
@@ -97661,5 +97661,5 @@ async function listVaultSecretKeysChecked(gate, db, dialect) {
|
|
|
97661
97661
|
}
|
|
97662
97662
|
|
|
97663
97663
|
export { assertPolicy, assertVaultPolicy, checkConfigPolicy, deleteVaultSecret, deleteVaultSecretChecked, detectAgentHarness, encryptVaultKey, getAllVaultSecrets, getNoormTables, getVaultKey, getVaultKeyChecked, getVaultSecret, getVaultStatus, guarded, initializeVault, initializeVaultChecked, listVaultSecretKeys, listVaultSecretKeysChecked, noormDb, resolveLegacyAccess, setVaultSecret, setVaultSecretChecked, vaultSecretExists };
|
|
97664
|
-
//# sourceMappingURL=chunk-
|
|
97665
|
-
//# sourceMappingURL=chunk-
|
|
97664
|
+
//# sourceMappingURL=chunk-24L5UNQR.js.map
|
|
97665
|
+
//# sourceMappingURL=chunk-24L5UNQR.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1274,7 +1274,7 @@ export interface NoormExecutionsTable {
|
|
|
1274
1274
|
status: ExecutionStatus;
|
|
1275
1275
|
/** Error details (empty = no error) */
|
|
1276
1276
|
error_message: Generated<string>;
|
|
1277
|
-
/** '
|
|
1277
|
+
/** Why a failure left this file unreached, e.g. 'change failed'; older rows may hold 'unchanged' or 'already applied' */
|
|
1278
1278
|
skip_reason: Generated<string>;
|
|
1279
1279
|
/** Execution time (0 = never ran) */
|
|
1280
1280
|
duration_ms: Generated<number>;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
2
|
import { processFile, es_default, DtReader, isTemplate, FORMAT_VERSION, DT_EXTENSIONS, encryptWithPassphrase, ENCODED_TYPES } from './chunk-M7Q44VFJ.js';
|
|
3
3
|
import './chunk-UOFJT5PY.js';
|
|
4
|
-
import { resolveLegacyAccess, checkConfigPolicy, initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, noormDb, getNoormTables, encryptVaultKey, assertVaultPolicy, assertPolicy, detectAgentHarness, guarded } from './chunk-
|
|
4
|
+
import { resolveLegacyAccess, checkConfigPolicy, initializeVault, getVaultStatus, setVaultSecret, getVaultSecret, getAllVaultSecrets, listVaultSecretKeys, deleteVaultSecret, vaultSecretExists, getVaultKey, noormDb, getNoormTables, encryptVaultKey, assertVaultPolicy, assertPolicy, detectAgentHarness, guarded } from './chunk-24L5UNQR.js';
|
|
5
5
|
import { observer, getEnvConfigName, ObserverRelay, isDebug } from './chunk-6LG4ENOJ.js';
|
|
6
6
|
export { observer as noormObserver } from './chunk-6LG4ENOJ.js';
|
|
7
7
|
import { explainConnectionError, DatabaseConnectionError } from './chunk-OXTXFKWJ.js';
|
|
@@ -4786,6 +4786,33 @@ function hydrateDate(value, dialect) {
|
|
|
4786
4786
|
}
|
|
4787
4787
|
return /* @__PURE__ */ new Date(`${value.replace(" ", "T")}Z`);
|
|
4788
4788
|
}
|
|
4789
|
+
function decideNeedsRunFile(record, checksum, force) {
|
|
4790
|
+
if (force) {
|
|
4791
|
+
return { needsRun: true, reason: "force" };
|
|
4792
|
+
}
|
|
4793
|
+
if (record instanceof Error || !record) {
|
|
4794
|
+
return { needsRun: true, reason: "new" };
|
|
4795
|
+
}
|
|
4796
|
+
if (record.exec_status === "failed") {
|
|
4797
|
+
return {
|
|
4798
|
+
needsRun: true,
|
|
4799
|
+
reason: "failed",
|
|
4800
|
+
previousChecksum: record.checksum
|
|
4801
|
+
};
|
|
4802
|
+
}
|
|
4803
|
+
if (record.checksum !== checksum) {
|
|
4804
|
+
return {
|
|
4805
|
+
needsRun: true,
|
|
4806
|
+
reason: "changed",
|
|
4807
|
+
previousChecksum: record.checksum
|
|
4808
|
+
};
|
|
4809
|
+
}
|
|
4810
|
+
return {
|
|
4811
|
+
needsRun: false,
|
|
4812
|
+
skipReason: "already applied",
|
|
4813
|
+
previousChecksum: record.checksum
|
|
4814
|
+
};
|
|
4815
|
+
}
|
|
4789
4816
|
var ChangeHistory = class {
|
|
4790
4817
|
#db;
|
|
4791
4818
|
#ndb;
|
|
@@ -4965,31 +4992,19 @@ var ChangeHistory = class {
|
|
|
4965
4992
|
};
|
|
4966
4993
|
}
|
|
4967
4994
|
/**
|
|
4968
|
-
*
|
|
4969
|
-
*
|
|
4970
|
-
*
|
|
4971
|
-
*
|
|
4972
|
-
*
|
|
4973
|
-
*
|
|
4974
|
-
*
|
|
4975
|
-
*
|
|
4976
|
-
*
|
|
4977
|
-
*
|
|
4978
|
-
*
|
|
4979
|
-
*
|
|
4980
|
-
*
|
|
4981
|
-
* Also excludes `skipped` rows: `status: 'skipped'` is written for two
|
|
4982
|
-
* different meanings — `skipRemainingFiles` writes it for files never
|
|
4983
|
-
* reached after an earlier failure (must re-run), while this method's
|
|
4984
|
-
* own per-file-skip path (called from `executor.ts`) writes it for a
|
|
4985
|
-
* file that matched a prior success (must stay skipped). A `skipped`
|
|
4986
|
-
* row is never itself a decision basis: a success-match skip still has
|
|
4987
|
-
* its covering `success` row further back in history (found once the
|
|
4988
|
-
* `skipped` row is excluded), and a never-reached skip has no terminal
|
|
4989
|
-
* row at all, so the lookup falls through to `{ needsRun: true, reason:
|
|
4990
|
-
* 'new' }` below and the file runs. Both resolve correctly without
|
|
4991
|
-
* consulting the ambiguous row — excluding it here is what prevents a
|
|
4992
|
-
* third attempt from re-running a file a prior success already covered.
|
|
4995
|
+
* Fetch the newest qualifying execution row per filepath for one
|
|
4996
|
+
* change and direction.
|
|
4997
|
+
*
|
|
4998
|
+
* Two SELECTs for any number of files: the direction boundary, then the
|
|
4999
|
+
* same query form as `Tracker.latestExecutions`.
|
|
5000
|
+
*
|
|
5001
|
+
* Rows are scoped to this change's name+direction+config, so file A's
|
|
5002
|
+
* success under one change never satisfies file A's check under another.
|
|
5003
|
+
*
|
|
5004
|
+
* `pending` and `skipped` rows never count. Neither records an outcome:
|
|
5005
|
+
* `pending` is a file its batch never reached, and `skipped` is written by
|
|
5006
|
+
* `skipRemainingFiles` for the same reason, or by older versions for a
|
|
5007
|
+
* file that matched a success still further back in history.
|
|
4993
5008
|
*
|
|
4994
5009
|
* A prior success only licenses a skip while it is still *standing*.
|
|
4995
5010
|
* Two things retire it, and neither is visible on the execution row
|
|
@@ -5010,72 +5025,56 @@ var ChangeHistory = class {
|
|
|
5010
5025
|
*
|
|
5011
5026
|
* @param name - Change name
|
|
5012
5027
|
* @param direction - 'change' or 'revert'
|
|
5013
|
-
* @
|
|
5014
|
-
*
|
|
5015
|
-
* @
|
|
5016
|
-
*
|
|
5028
|
+
* @returns Map of relative filepath to its newest qualifying row, or the lookup error
|
|
5029
|
+
*
|
|
5030
|
+
* @example
|
|
5031
|
+
* ```typescript
|
|
5032
|
+
* const [latest, err] = await history.latestFileExecutions('2024-01-15-add-users', 'change')
|
|
5033
|
+
* const result = decideNeedsRunFile(err ?? latest.get(filepath), checksum, false)
|
|
5034
|
+
* ```
|
|
5017
5035
|
*/
|
|
5018
|
-
async
|
|
5019
|
-
|
|
5020
|
-
return { needsRun: true, reason: "force" };
|
|
5021
|
-
}
|
|
5036
|
+
async latestFileExecutions(name, direction) {
|
|
5037
|
+
const { executions, change } = this.#tables;
|
|
5022
5038
|
const opposite = direction === "change" ? "revert" : "change";
|
|
5023
5039
|
const [boundary, boundaryErr] = await attempt(
|
|
5024
|
-
() => this.#ndb.selectFrom(
|
|
5040
|
+
() => this.#ndb.selectFrom(change).select(["id"]).where("name", "=", name).where("change_type", "=", "change").where("direction", "=", opposite).where("config_name", "=", this.#configName).orderBy("id", "desc").limit(1).executeTakeFirst()
|
|
5025
5041
|
);
|
|
5026
5042
|
if (boundaryErr) {
|
|
5027
5043
|
observer.emit("error", {
|
|
5028
5044
|
source: "change",
|
|
5029
5045
|
error: boundaryErr,
|
|
5030
|
-
context: { name,
|
|
5046
|
+
context: { name, operation: "latest-file-executions-boundary" }
|
|
5031
5047
|
});
|
|
5032
|
-
return
|
|
5048
|
+
return [null, boundaryErr];
|
|
5033
5049
|
}
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5050
|
+
let qualifying = this.#ndb.selectFrom(executions).innerJoin(change, `${change}.id`, `${executions}.change_id`).where(`${change}.name`, "=", name).where(`${change}.direction`, "=", direction).where(`${change}.config_name`, "=", this.#configName).where(`${change}.status`, "not in", ["reverted", "stale"]).where(`${executions}.status`, "not in", ["pending", "skipped"]);
|
|
5051
|
+
if (boundary) {
|
|
5052
|
+
qualifying = qualifying.where(`${change}.id`, ">", boundary.id);
|
|
5053
|
+
}
|
|
5054
|
+
const newestIds = qualifying.select((eb) => eb.fn.max(`${executions}.id`).as("id")).groupBy(`${executions}.filepath`).as("newest");
|
|
5055
|
+
const [rows, err] = await attempt(
|
|
5056
|
+
() => (
|
|
5039
5057
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
return query.orderBy(`${this.#tables.executions}.id`, "desc").limit(1).executeTakeFirst();
|
|
5048
|
-
});
|
|
5058
|
+
this.#ndb.selectFrom(executions).innerJoin(newestIds, "newest.id", `${executions}.id`).select((eb) => [
|
|
5059
|
+
eb.ref(`${executions}.filepath`).as("filepath"),
|
|
5060
|
+
eb.ref(`${executions}.checksum`).as("checksum"),
|
|
5061
|
+
eb.ref(`${executions}.status`).as("exec_status")
|
|
5062
|
+
]).execute()
|
|
5063
|
+
)
|
|
5064
|
+
);
|
|
5049
5065
|
if (err) {
|
|
5050
5066
|
observer.emit("error", {
|
|
5051
5067
|
source: "change",
|
|
5052
5068
|
error: err,
|
|
5053
|
-
context: { name,
|
|
5069
|
+
context: { name, operation: "latest-file-executions" }
|
|
5054
5070
|
});
|
|
5055
|
-
return
|
|
5056
|
-
}
|
|
5057
|
-
if (!record) {
|
|
5058
|
-
return { needsRun: true, reason: "new" };
|
|
5059
|
-
}
|
|
5060
|
-
if (record.exec_status === "failed") {
|
|
5061
|
-
return {
|
|
5062
|
-
needsRun: true,
|
|
5063
|
-
reason: "failed",
|
|
5064
|
-
previousChecksum: record.checksum
|
|
5065
|
-
};
|
|
5071
|
+
return [null, err];
|
|
5066
5072
|
}
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
reason: "changed",
|
|
5071
|
-
previousChecksum: record.checksum
|
|
5072
|
-
};
|
|
5073
|
+
const latest = /* @__PURE__ */ new Map();
|
|
5074
|
+
for (const { filepath, ...record } of rows) {
|
|
5075
|
+
latest.set(filepath, record);
|
|
5073
5076
|
}
|
|
5074
|
-
return
|
|
5075
|
-
needsRun: false,
|
|
5076
|
-
skipReason: "already applied",
|
|
5077
|
-
previousChecksum: record.checksum
|
|
5078
|
-
};
|
|
5077
|
+
return [latest, null];
|
|
5079
5078
|
}
|
|
5080
5079
|
// ─────────────────────────────────────────────────────────
|
|
5081
5080
|
// Create Records
|
|
@@ -5113,9 +5112,10 @@ var ChangeHistory = class {
|
|
|
5113
5112
|
return id;
|
|
5114
5113
|
}
|
|
5115
5114
|
/**
|
|
5116
|
-
* Create pending file records for
|
|
5115
|
+
* Create pending file records for the files about to run.
|
|
5117
5116
|
*
|
|
5118
|
-
*
|
|
5117
|
+
* The pending rows let `skipRemainingFiles` mark the files a
|
|
5118
|
+
* failure left unreached.
|
|
5119
5119
|
*
|
|
5120
5120
|
* @returns Error message if creation failed, null on success
|
|
5121
5121
|
*/
|
|
@@ -5481,6 +5481,44 @@ var ChangeHistory = class {
|
|
|
5481
5481
|
};
|
|
5482
5482
|
|
|
5483
5483
|
// src/core/runner/tracker.ts
|
|
5484
|
+
function decideNeedsRun(record, checksum, force) {
|
|
5485
|
+
if (record instanceof Error) {
|
|
5486
|
+
return { needsRun: true, reason: "error" };
|
|
5487
|
+
}
|
|
5488
|
+
if (!record) {
|
|
5489
|
+
return { needsRun: true, reason: "new" };
|
|
5490
|
+
}
|
|
5491
|
+
if (record.exec_status === "failed") {
|
|
5492
|
+
return {
|
|
5493
|
+
needsRun: true,
|
|
5494
|
+
reason: "failed",
|
|
5495
|
+
previousChecksum: record.checksum
|
|
5496
|
+
};
|
|
5497
|
+
}
|
|
5498
|
+
const isUnchangedSkip = record.exec_status === "skipped" && record.skip_reason === "unchanged";
|
|
5499
|
+
if (record.exec_status === "pending" || record.exec_status === "skipped" && !isUnchangedSkip) {
|
|
5500
|
+
return { needsRun: true, reason: "new" };
|
|
5501
|
+
}
|
|
5502
|
+
if (record.change_status === "stale") {
|
|
5503
|
+
return {
|
|
5504
|
+
needsRun: true,
|
|
5505
|
+
reason: "stale",
|
|
5506
|
+
previousChecksum: record.checksum
|
|
5507
|
+
};
|
|
5508
|
+
}
|
|
5509
|
+
if (record.checksum !== checksum) {
|
|
5510
|
+
return {
|
|
5511
|
+
needsRun: true,
|
|
5512
|
+
reason: "changed",
|
|
5513
|
+
previousChecksum: record.checksum
|
|
5514
|
+
};
|
|
5515
|
+
}
|
|
5516
|
+
return {
|
|
5517
|
+
needsRun: false,
|
|
5518
|
+
skipReason: "unchanged",
|
|
5519
|
+
previousChecksum: record.checksum
|
|
5520
|
+
};
|
|
5521
|
+
}
|
|
5484
5522
|
var Tracker = class {
|
|
5485
5523
|
#db;
|
|
5486
5524
|
#ndb;
|
|
@@ -5495,89 +5533,45 @@ var Tracker = class {
|
|
|
5495
5533
|
this.#dialect = dialect;
|
|
5496
5534
|
}
|
|
5497
5535
|
/**
|
|
5498
|
-
*
|
|
5536
|
+
* Fetch the newest execution row per filepath for this config.
|
|
5499
5537
|
*
|
|
5500
|
-
*
|
|
5501
|
-
*
|
|
5502
|
-
* -
|
|
5503
|
-
* - Previous execution failed
|
|
5504
|
-
* - Parent change is stale (schema was torn down)
|
|
5505
|
-
* - Checksum differs (file changed)
|
|
5538
|
+
* One SELECT for any number of files, so a batch can decide every file
|
|
5539
|
+
* with `decideNeedsRun` before writing any tracking rows. Query form:
|
|
5540
|
+
* `docs/design/prefetch-run-gate.md`.
|
|
5506
5541
|
*
|
|
5507
|
-
* @
|
|
5508
|
-
*
|
|
5509
|
-
* @
|
|
5510
|
-
*
|
|
5511
|
-
*
|
|
5512
|
-
*
|
|
5513
|
-
*
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
`${this.#tables.executions}.change_id`
|
|
5527
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5528
|
-
).select((eb) => [
|
|
5529
|
-
eb.ref(`${this.#tables.executions}.checksum`).as("checksum"),
|
|
5530
|
-
eb.ref(`${this.#tables.executions}.status`).as("exec_status"),
|
|
5531
|
-
eb.ref(`${this.#tables.executions}.skip_reason`).as("skip_reason"),
|
|
5532
|
-
eb.ref(`${this.#tables.change}.status`).as("change_status")
|
|
5533
|
-
]).where(`${this.#tables.executions}.filepath`, "=", filepath).where(`${this.#tables.change}.config_name`, "=", this.#configName);
|
|
5534
|
-
if (excludeOperationId !== void 0) {
|
|
5535
|
-
query = query.where(`${this.#tables.executions}.change_id`, "<>", excludeOperationId);
|
|
5536
|
-
}
|
|
5537
|
-
const [record, err] = await attempt(
|
|
5538
|
-
() => query.orderBy(`${this.#tables.executions}.id`, "desc").limit(1).executeTakeFirst()
|
|
5542
|
+
* @returns Map of filepath to its newest record, or the lookup error
|
|
5543
|
+
*
|
|
5544
|
+
* @example
|
|
5545
|
+
* ```typescript
|
|
5546
|
+
* const [latest, err] = await tracker.latestExecutions()
|
|
5547
|
+
* const result = decideNeedsRun(err ?? latest.get(filepath), checksum, false)
|
|
5548
|
+
* ```
|
|
5549
|
+
*/
|
|
5550
|
+
async latestExecutions() {
|
|
5551
|
+
const { executions, change } = this.#tables;
|
|
5552
|
+
const newestIds = this.#ndb.selectFrom(executions).innerJoin(change, `${change}.id`, `${executions}.change_id`).where(`${change}.config_name`, "=", this.#configName).select((eb) => eb.fn.max(`${executions}.id`).as("id")).groupBy(`${executions}.filepath`).as("newest");
|
|
5553
|
+
const [rows, err] = await attempt(
|
|
5554
|
+
() => this.#ndb.selectFrom(executions).innerJoin(change, `${change}.id`, `${executions}.change_id`).innerJoin(newestIds, "newest.id", `${executions}.id`).select((eb) => [
|
|
5555
|
+
eb.ref(`${executions}.filepath`).as("filepath"),
|
|
5556
|
+
eb.ref(`${executions}.checksum`).as("checksum"),
|
|
5557
|
+
eb.ref(`${executions}.status`).as("exec_status"),
|
|
5558
|
+
eb.ref(`${executions}.skip_reason`).as("skip_reason"),
|
|
5559
|
+
eb.ref(`${change}.status`).as("change_status")
|
|
5560
|
+
]).execute()
|
|
5539
5561
|
);
|
|
5540
5562
|
if (err) {
|
|
5541
5563
|
observer.emit("error", {
|
|
5542
5564
|
source: "runner",
|
|
5543
5565
|
error: err,
|
|
5544
|
-
context: {
|
|
5566
|
+
context: { operation: "latest-executions" }
|
|
5545
5567
|
});
|
|
5546
|
-
return
|
|
5547
|
-
}
|
|
5548
|
-
if (!record) {
|
|
5549
|
-
return { needsRun: true, reason: "new" };
|
|
5550
|
-
}
|
|
5551
|
-
if (record.exec_status === "failed") {
|
|
5552
|
-
return {
|
|
5553
|
-
needsRun: true,
|
|
5554
|
-
reason: "failed",
|
|
5555
|
-
previousChecksum: record.checksum
|
|
5556
|
-
};
|
|
5557
|
-
}
|
|
5558
|
-
const isUnchangedSkip = record.exec_status === "skipped" && record.skip_reason === "unchanged";
|
|
5559
|
-
if (record.exec_status === "pending" || record.exec_status === "skipped" && !isUnchangedSkip) {
|
|
5560
|
-
return { needsRun: true, reason: "new" };
|
|
5561
|
-
}
|
|
5562
|
-
if (record.change_status === "stale") {
|
|
5563
|
-
return {
|
|
5564
|
-
needsRun: true,
|
|
5565
|
-
reason: "stale",
|
|
5566
|
-
previousChecksum: record.checksum
|
|
5567
|
-
};
|
|
5568
|
+
return [null, err];
|
|
5568
5569
|
}
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
reason: "changed",
|
|
5573
|
-
previousChecksum: record.checksum
|
|
5574
|
-
};
|
|
5570
|
+
const latest = /* @__PURE__ */ new Map();
|
|
5571
|
+
for (const { filepath, ...record } of rows) {
|
|
5572
|
+
latest.set(filepath, record);
|
|
5575
5573
|
}
|
|
5576
|
-
return
|
|
5577
|
-
needsRun: false,
|
|
5578
|
-
skipReason: "unchanged",
|
|
5579
|
-
previousChecksum: record.checksum
|
|
5580
|
-
};
|
|
5574
|
+
return [latest, null];
|
|
5581
5575
|
}
|
|
5582
5576
|
/**
|
|
5583
5577
|
* Create a new operation record.
|
|
@@ -5613,35 +5607,6 @@ var Tracker = class {
|
|
|
5613
5607
|
}
|
|
5614
5608
|
return id;
|
|
5615
5609
|
}
|
|
5616
|
-
/**
|
|
5617
|
-
* Record a file execution.
|
|
5618
|
-
*
|
|
5619
|
-
* Creates a child record in __noorm_executions__ linked
|
|
5620
|
-
* to the parent operation.
|
|
5621
|
-
*
|
|
5622
|
-
* @param data - Execution data
|
|
5623
|
-
*/
|
|
5624
|
-
async recordExecution(data2) {
|
|
5625
|
-
const [, err] = await attempt(
|
|
5626
|
-
() => this.#ndb.insertInto(this.#tables.executions).values({
|
|
5627
|
-
change_id: data2.changeId,
|
|
5628
|
-
filepath: data2.filepath,
|
|
5629
|
-
file_type: "sql",
|
|
5630
|
-
checksum: data2.checksum,
|
|
5631
|
-
status: data2.status,
|
|
5632
|
-
skip_reason: data2.skipReason ?? "",
|
|
5633
|
-
error_message: data2.errorMessage ?? "",
|
|
5634
|
-
duration_ms: Math.round(data2.durationMs ?? 0)
|
|
5635
|
-
}).execute()
|
|
5636
|
-
);
|
|
5637
|
-
if (err) {
|
|
5638
|
-
observer.emit("error", {
|
|
5639
|
-
source: "runner",
|
|
5640
|
-
error: err,
|
|
5641
|
-
context: { filepath: data2.filepath, operation: "record-execution" }
|
|
5642
|
-
});
|
|
5643
|
-
}
|
|
5644
|
-
}
|
|
5645
5610
|
/**
|
|
5646
5611
|
* Finalize an operation.
|
|
5647
5612
|
*
|
|
@@ -5689,10 +5654,10 @@ var Tracker = class {
|
|
|
5689
5654
|
// Batch File Operations (Shared by Runner and Changes)
|
|
5690
5655
|
// ─────────────────────────────────────────────────────────
|
|
5691
5656
|
/**
|
|
5692
|
-
* Create pending file records for
|
|
5657
|
+
* Create pending file records for the files about to run.
|
|
5693
5658
|
*
|
|
5694
|
-
*
|
|
5695
|
-
*
|
|
5659
|
+
* The pending rows let `skipRemainingFiles` mark the files a
|
|
5660
|
+
* failure left unreached.
|
|
5696
5661
|
*
|
|
5697
5662
|
* @param operationId - Parent operation ID
|
|
5698
5663
|
* @param files - Files to create records for
|
|
@@ -5732,23 +5697,15 @@ var Tracker = class {
|
|
|
5732
5697
|
* @param durationMs - Execution time
|
|
5733
5698
|
* @param errorMessage - Error message if failed
|
|
5734
5699
|
* @param skipReason - Skip reason if skipped
|
|
5735
|
-
* @param checksum - Checksum of the SQL that actually reached the
|
|
5736
|
-
* database. `createFileRecords` seeds the pending row with the *raw*
|
|
5737
|
-
* file hash because rendering every template upfront would execute them
|
|
5738
|
-
* twice; for a `.sql.tmpl` that hash is not what `needsRun` compares
|
|
5739
|
-
* against, so leaving it in place made template dedup unreachable.
|
|
5740
|
-
* Omitted leaves the seeded value alone — correct only where no render
|
|
5741
|
-
* happened (e.g. the file could not be read).
|
|
5742
5700
|
* @returns Error message if update failed, null on success
|
|
5743
5701
|
*/
|
|
5744
|
-
async updateFileExecution(operationId, filepath, status, durationMs, errorMessage, skipReason
|
|
5702
|
+
async updateFileExecution(operationId, filepath, status, durationMs, errorMessage, skipReason) {
|
|
5745
5703
|
const [result, err] = await attempt(
|
|
5746
5704
|
() => this.#ndb.updateTable(this.#tables.executions).set({
|
|
5747
5705
|
status,
|
|
5748
5706
|
duration_ms: Math.round(durationMs),
|
|
5749
5707
|
error_message: errorMessage ?? "",
|
|
5750
|
-
skip_reason: skipReason ?? ""
|
|
5751
|
-
...checksum === void 0 ? {} : { checksum }
|
|
5708
|
+
skip_reason: skipReason ?? ""
|
|
5752
5709
|
}).where("change_id", "=", operationId).where("filepath", "=", filepath).executeTakeFirst()
|
|
5753
5710
|
);
|
|
5754
5711
|
if (err) {
|
|
@@ -5842,7 +5799,6 @@ var Tracker = class {
|
|
|
5842
5799
|
/**
|
|
5843
5800
|
* Check if a change needs to run by name.
|
|
5844
5801
|
*
|
|
5845
|
-
* Similar to needsRun but checks by change name instead of filepath.
|
|
5846
5802
|
* Used for change sets where we track by change name, not individual files.
|
|
5847
5803
|
*
|
|
5848
5804
|
* @param name - Change name
|
|
@@ -7007,6 +6963,12 @@ async function executeFiles(context, change, files, direction, checksum, force,
|
|
|
7007
6963
|
return result;
|
|
7008
6964
|
}
|
|
7009
6965
|
async function runFileBatch(context, change, expandedFiles, direction, checksum, force, history, executor, startTime, watcher) {
|
|
6966
|
+
const fileChecksums = /* @__PURE__ */ new Map();
|
|
6967
|
+
for (const file of expandedFiles) {
|
|
6968
|
+
const [cs] = await attempt(() => computeChecksum(file.path));
|
|
6969
|
+
fileChecksums.set(file.path, cs ?? "");
|
|
6970
|
+
}
|
|
6971
|
+
const skipReasons = await findSkippedFiles(context, change.name, direction, expandedFiles, fileChecksums, force, history);
|
|
7010
6972
|
const [operationId, createErr] = await attempt(
|
|
7011
6973
|
() => history.createOperation({
|
|
7012
6974
|
name: change.name,
|
|
@@ -7022,14 +6984,9 @@ async function runFileBatch(context, change, expandedFiles, direction, checksum,
|
|
|
7022
6984
|
});
|
|
7023
6985
|
return createFailedResult(change.name, direction, createErr.message, startTime);
|
|
7024
6986
|
}
|
|
7025
|
-
const fileChecksums = /* @__PURE__ */ new Map();
|
|
7026
|
-
for (const file of expandedFiles) {
|
|
7027
|
-
const [cs] = await attempt(() => computeChecksum(file.path));
|
|
7028
|
-
fileChecksums.set(file.path, cs ?? "");
|
|
7029
|
-
}
|
|
7030
6987
|
const createRecordsErr = await history.createFileRecords(
|
|
7031
6988
|
operationId,
|
|
7032
|
-
expandedFiles.map((f) => ({
|
|
6989
|
+
expandedFiles.filter((_, i) => !skipReasons[i]).map((f) => ({
|
|
7033
6990
|
filepath: path.relative(context.projectRoot, f.path),
|
|
7034
6991
|
fileType: f.type,
|
|
7035
6992
|
checksum: fileChecksums.get(f.path) ?? ""
|
|
@@ -7069,36 +7026,15 @@ async function runFileBatch(context, change, expandedFiles, direction, checksum,
|
|
|
7069
7026
|
const fileStart = performance.now();
|
|
7070
7027
|
const relPath = path.relative(context.projectRoot, file.path);
|
|
7071
7028
|
const fileChecksum = fileChecksums.get(file.path) ?? "";
|
|
7072
|
-
const
|
|
7073
|
-
|
|
7074
|
-
direction,
|
|
7075
|
-
relPath,
|
|
7076
|
-
fileChecksum,
|
|
7077
|
-
force
|
|
7078
|
-
);
|
|
7079
|
-
if (!needsRunFileResult.needsRun) {
|
|
7029
|
+
const skipReason = skipReasons[i];
|
|
7030
|
+
if (skipReason) {
|
|
7080
7031
|
results.push({
|
|
7081
7032
|
filepath: file.path,
|
|
7082
7033
|
checksum: fileChecksum,
|
|
7083
7034
|
status: "skipped",
|
|
7084
|
-
skipReason
|
|
7035
|
+
skipReason,
|
|
7085
7036
|
durationMs: 0
|
|
7086
7037
|
});
|
|
7087
|
-
const skipUpdateErr = await history.updateFileExecution(
|
|
7088
|
-
operationId,
|
|
7089
|
-
relPath,
|
|
7090
|
-
"skipped",
|
|
7091
|
-
0,
|
|
7092
|
-
void 0,
|
|
7093
|
-
needsRunFileResult.skipReason
|
|
7094
|
-
);
|
|
7095
|
-
if (skipUpdateErr) {
|
|
7096
|
-
observer.emit("error", {
|
|
7097
|
-
source: "change",
|
|
7098
|
-
error: new Error(skipUpdateErr),
|
|
7099
|
-
context: { filepath: relPath, operation: "update-skipped-record" }
|
|
7100
|
-
});
|
|
7101
|
-
}
|
|
7102
7038
|
continue;
|
|
7103
7039
|
}
|
|
7104
7040
|
const [sqlContent, loadErr] = await attempt(() => loadAndRenderFile(context, file.path));
|
|
@@ -7233,6 +7169,22 @@ async function runFileBatch(context, change, expandedFiles, direction, checksum,
|
|
|
7233
7169
|
operationId
|
|
7234
7170
|
};
|
|
7235
7171
|
}
|
|
7172
|
+
async function findSkippedFiles(context, changeName, direction, files, fileChecksums, force, history) {
|
|
7173
|
+
const skipReasons = [];
|
|
7174
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7175
|
+
const [latest, latestErr] = force ? [null, null] : await history.latestFileExecutions(changeName, direction);
|
|
7176
|
+
for (const file of files) {
|
|
7177
|
+
const relPath = path.relative(context.projectRoot, file.path);
|
|
7178
|
+
if (seen.has(relPath)) {
|
|
7179
|
+
skipReasons.push("already applied");
|
|
7180
|
+
continue;
|
|
7181
|
+
}
|
|
7182
|
+
seen.add(relPath);
|
|
7183
|
+
const decision = decideNeedsRunFile(latestErr ?? latest?.get(relPath), fileChecksums.get(file.path) ?? "", force);
|
|
7184
|
+
skipReasons.push(decision.needsRun ? void 0 : decision.skipReason);
|
|
7185
|
+
}
|
|
7186
|
+
return skipReasons;
|
|
7187
|
+
}
|
|
7236
7188
|
async function executePreview(context, change, files, direction, output, startTime) {
|
|
7237
7189
|
const expandedFiles = await expandFiles(files, context.sqlDir);
|
|
7238
7190
|
const results = [];
|
|
@@ -7903,7 +7855,7 @@ async function resolveVaultKey(db, dialect) {
|
|
|
7903
7855
|
async function buildSecretsContext(stateManager, configName, db, vaultKey, dialect) {
|
|
7904
7856
|
const secrets = {};
|
|
7905
7857
|
if (db && vaultKey) {
|
|
7906
|
-
const { getAllVaultSecrets: getAllVaultSecrets2 } = await import('./storage-
|
|
7858
|
+
const { getAllVaultSecrets: getAllVaultSecrets2 } = await import('./storage-NQA4H7PK.js');
|
|
7907
7859
|
const vaultSecrets = await getAllVaultSecrets2(db, vaultKey, dialect ?? "postgres");
|
|
7908
7860
|
for (const [key, secret] of Object.entries(vaultSecrets)) {
|
|
7909
7861
|
secrets[key] = secret.value;
|
|
@@ -8675,48 +8627,20 @@ async function runBuild(context, sqlPath, options = {}, preFilteredFiles) {
|
|
|
8675
8627
|
}
|
|
8676
8628
|
async function runFile(context, filepath, options = {}) {
|
|
8677
8629
|
assertRunPolicy(context, "run:file");
|
|
8678
|
-
const opts = { ...DEFAULT_RUN_OPTIONS_INTERNAL, ...options };
|
|
8679
8630
|
observer.emit("run:file", {
|
|
8680
8631
|
filepath,
|
|
8681
8632
|
configName: context.configName
|
|
8682
8633
|
});
|
|
8683
|
-
|
|
8684
|
-
|
|
8685
|
-
|
|
8686
|
-
}
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
configName: context.configName,
|
|
8694
|
-
executedBy: formatIdentity(context.identity)
|
|
8695
|
-
})
|
|
8696
|
-
);
|
|
8697
|
-
if (createErr) {
|
|
8698
|
-
observer.emit("error", {
|
|
8699
|
-
source: "runner",
|
|
8700
|
-
error: createErr,
|
|
8701
|
-
context: { filepath, operation: "create-operation" }
|
|
8702
|
-
});
|
|
8703
|
-
return {
|
|
8704
|
-
filepath,
|
|
8705
|
-
checksum: "",
|
|
8706
|
-
status: "failed",
|
|
8707
|
-
error: createErr.message
|
|
8708
|
-
};
|
|
8709
|
-
}
|
|
8710
|
-
const watcher = createWatcher(context);
|
|
8711
|
-
const result = await executeSingleFile(context, filepath, opts, tracker, operationId, watcher).finally(() => watcher.close());
|
|
8712
|
-
await tracker.finalizeOperation(
|
|
8713
|
-
operationId,
|
|
8714
|
-
result.status === "failed" || result.error ? "failed" : "success",
|
|
8715
|
-
Math.round(result.durationMs ?? 0),
|
|
8716
|
-
result.checksum,
|
|
8717
|
-
result.error
|
|
8718
|
-
);
|
|
8719
|
-
return result;
|
|
8634
|
+
const batch = await executeFiles2(context, [{ path: filepath, type: "sql" }], options, {
|
|
8635
|
+
changeType: "run",
|
|
8636
|
+
operationName: `run:${(/* @__PURE__ */ new Date()).toISOString()}`
|
|
8637
|
+
});
|
|
8638
|
+
return batch.files[0] ?? {
|
|
8639
|
+
filepath,
|
|
8640
|
+
checksum: "",
|
|
8641
|
+
status: batch.error === RUN_CANCELLED ? "skipped" : "failed",
|
|
8642
|
+
error: batch.error
|
|
8643
|
+
};
|
|
8720
8644
|
}
|
|
8721
8645
|
async function runDir(context, dirpath, options = {}) {
|
|
8722
8646
|
assertRunPolicy(context, "run:dir");
|
|
@@ -8859,6 +8783,19 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8859
8783
|
};
|
|
8860
8784
|
}
|
|
8861
8785
|
const tracker = execOptions.tracker ?? new Tracker(context.db, context.configName, context.dialect ?? "postgres");
|
|
8786
|
+
const isChange = execOptions.changeType === "change";
|
|
8787
|
+
const prepared = await prepareFiles(context, files);
|
|
8788
|
+
const gated = isChange ? prepared : await applyRunGate(tracker, prepared, opts.force);
|
|
8789
|
+
if (!isChange && gated.every((entry) => entry.skipReason !== void 0)) {
|
|
8790
|
+
return {
|
|
8791
|
+
status: "success",
|
|
8792
|
+
files: gated.map(skipFile),
|
|
8793
|
+
filesRun: 0,
|
|
8794
|
+
filesSkipped: gated.length,
|
|
8795
|
+
filesFailed: 0,
|
|
8796
|
+
durationMs: performance.now() - start
|
|
8797
|
+
};
|
|
8798
|
+
}
|
|
8862
8799
|
const [operationId, createErr] = await attempt(
|
|
8863
8800
|
() => tracker.createOperation({
|
|
8864
8801
|
name: execOptions.operationName,
|
|
@@ -8879,20 +8816,11 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8879
8816
|
performance.now() - start
|
|
8880
8817
|
);
|
|
8881
8818
|
}
|
|
8882
|
-
const
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
checksum = err ? "" : computed;
|
|
8888
|
-
}
|
|
8889
|
-
fileRecords.push({
|
|
8890
|
-
filepath: path.relative(context.projectRoot, file.path),
|
|
8891
|
-
fileType: file.type,
|
|
8892
|
-
checksum
|
|
8893
|
-
});
|
|
8894
|
-
}
|
|
8895
|
-
const createRecordsErr = await tracker.createFileRecords(operationId, fileRecords);
|
|
8819
|
+
const runSet = gated.filter((entry) => !entry.skipReason);
|
|
8820
|
+
const createRecordsErr = await tracker.createFileRecords(
|
|
8821
|
+
operationId,
|
|
8822
|
+
runSet.map((entry) => ({ filepath: entry.relFilepath, fileType: entry.file.type, checksum: entry.checksum }))
|
|
8823
|
+
);
|
|
8896
8824
|
if (createRecordsErr) {
|
|
8897
8825
|
observer.emit("error", {
|
|
8898
8826
|
source: "runner:create-file-records",
|
|
@@ -8909,26 +8837,21 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8909
8837
|
let failed = false;
|
|
8910
8838
|
let cancelled = false;
|
|
8911
8839
|
const watcher = createWatcher(context);
|
|
8840
|
+
const lastRunIndex = gated.map((entry) => !entry.skipReason).lastIndexOf(true);
|
|
8912
8841
|
try {
|
|
8913
|
-
for (let i = 0; i <
|
|
8914
|
-
const
|
|
8915
|
-
|
|
8842
|
+
for (let i = 0; i < gated.length; i++) {
|
|
8843
|
+
const entry = gated[i];
|
|
8844
|
+
if (entry.skipReason) {
|
|
8845
|
+
results.push(skipFile(entry));
|
|
8846
|
+
continue;
|
|
8847
|
+
}
|
|
8916
8848
|
if (context.signal?.aborted) {
|
|
8917
8849
|
failed = true;
|
|
8918
8850
|
cancelled = true;
|
|
8919
8851
|
await skipRemaining(tracker, operationId, RUN_CANCELLED);
|
|
8920
8852
|
break;
|
|
8921
8853
|
}
|
|
8922
|
-
const result = await executeSingleFileWithUpdate(
|
|
8923
|
-
context,
|
|
8924
|
-
file.path,
|
|
8925
|
-
fileRecord.checksum,
|
|
8926
|
-
opts,
|
|
8927
|
-
tracker,
|
|
8928
|
-
operationId,
|
|
8929
|
-
execOptions.changeType,
|
|
8930
|
-
watcher
|
|
8931
|
-
);
|
|
8854
|
+
const result = await executeSingleFileWithUpdate(context, entry, tracker, operationId, watcher);
|
|
8932
8855
|
if (!result) {
|
|
8933
8856
|
failed = true;
|
|
8934
8857
|
cancelled = true;
|
|
@@ -8936,13 +8859,13 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8936
8859
|
break;
|
|
8937
8860
|
}
|
|
8938
8861
|
results.push(result);
|
|
8939
|
-
cancelled = (context.signal?.aborted ?? false) && (i <
|
|
8862
|
+
cancelled = (context.signal?.aborted ?? false) && (i < lastRunIndex || result.status === "failed");
|
|
8940
8863
|
if (cancelled || result.status === "failed" && opts.abortOnError) {
|
|
8941
8864
|
failed = true;
|
|
8942
8865
|
await skipRemaining(
|
|
8943
8866
|
tracker,
|
|
8944
8867
|
operationId,
|
|
8945
|
-
cancelled ? RUN_CANCELLED : `Skipped: failure in ${path.basename(file.path)}`
|
|
8868
|
+
cancelled ? RUN_CANCELLED : `Skipped: failure in ${path.basename(entry.file.path)}`
|
|
8946
8869
|
);
|
|
8947
8870
|
break;
|
|
8948
8871
|
}
|
|
@@ -8963,7 +8886,7 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8963
8886
|
if (filesFailed > 0 || failed) {
|
|
8964
8887
|
status = filesRun > 0 ? "partial" : "failed";
|
|
8965
8888
|
}
|
|
8966
|
-
const combinedChecksum = execOptions.checksum ?? computeCombinedChecksum(
|
|
8889
|
+
const combinedChecksum = execOptions.checksum ?? computeCombinedChecksum(gated.map((entry) => entry.checksum));
|
|
8967
8890
|
const finalStatus = status === "success" ? "success" : "failed";
|
|
8968
8891
|
const finalizeErr = await tracker.finalizeOperation(
|
|
8969
8892
|
operationId,
|
|
@@ -8990,6 +8913,43 @@ async function executeFiles2(context, files, runOptions, execOptions) {
|
|
|
8990
8913
|
error: cancelled ? RUN_CANCELLED : void 0
|
|
8991
8914
|
};
|
|
8992
8915
|
}
|
|
8916
|
+
async function prepareFiles(context, files) {
|
|
8917
|
+
const prepared = [];
|
|
8918
|
+
for (const file of files) {
|
|
8919
|
+
const relFilepath = path.relative(context.projectRoot, file.path);
|
|
8920
|
+
const [loaded, loadError] = await attempt(async () => {
|
|
8921
|
+
const sql28 = await loadAndRenderFile2(context, file.path);
|
|
8922
|
+
return { sql: sql28, checksum: computeChecksumFromContent(sql28) };
|
|
8923
|
+
});
|
|
8924
|
+
if (loadError) {
|
|
8925
|
+
prepared.push({ file, relFilepath, checksum: "", sql: "", loadError });
|
|
8926
|
+
continue;
|
|
8927
|
+
}
|
|
8928
|
+
prepared.push({ file, relFilepath, ...loaded });
|
|
8929
|
+
}
|
|
8930
|
+
return prepared;
|
|
8931
|
+
}
|
|
8932
|
+
async function applyRunGate(tracker, prepared, force) {
|
|
8933
|
+
if (force) return prepared;
|
|
8934
|
+
const [latest, latestErr] = await tracker.latestExecutions();
|
|
8935
|
+
return prepared.map((entry) => {
|
|
8936
|
+
if (entry.loadError) return entry;
|
|
8937
|
+
const decision = decideNeedsRun(latestErr ?? latest.get(entry.relFilepath), entry.checksum);
|
|
8938
|
+
return decision.skipReason ? { ...entry, skipReason: decision.skipReason } : entry;
|
|
8939
|
+
});
|
|
8940
|
+
}
|
|
8941
|
+
function skipFile(entry) {
|
|
8942
|
+
observer.emit("file:skip", {
|
|
8943
|
+
filepath: entry.file.path,
|
|
8944
|
+
reason: entry.skipReason
|
|
8945
|
+
});
|
|
8946
|
+
return {
|
|
8947
|
+
filepath: entry.file.path,
|
|
8948
|
+
checksum: entry.checksum,
|
|
8949
|
+
status: "skipped",
|
|
8950
|
+
skipReason: entry.skipReason
|
|
8951
|
+
};
|
|
8952
|
+
}
|
|
8993
8953
|
async function executeFilesInternal(context, files, options, changeType, sqlPath) {
|
|
8994
8954
|
const fileInputs = files.map((f) => ({
|
|
8995
8955
|
path: f,
|
|
@@ -9003,17 +8963,16 @@ async function executeFilesInternal(context, files, options, changeType, sqlPath
|
|
|
9003
8963
|
};
|
|
9004
8964
|
return executeFiles2(context, fileInputs, options, execOptions);
|
|
9005
8965
|
}
|
|
9006
|
-
async function executeSingleFileWithUpdate(context,
|
|
8966
|
+
async function executeSingleFileWithUpdate(context, entry, tracker, operationId, watcher) {
|
|
9007
8967
|
const start = performance.now();
|
|
9008
|
-
const
|
|
9009
|
-
|
|
9010
|
-
if (loadErr) {
|
|
8968
|
+
const { file: { path: filepath }, relFilepath, checksum } = entry;
|
|
8969
|
+
if (entry.loadError) {
|
|
9011
8970
|
const durationMs2 = performance.now() - start;
|
|
9012
8971
|
const result2 = {
|
|
9013
8972
|
filepath,
|
|
9014
|
-
checksum
|
|
8973
|
+
checksum,
|
|
9015
8974
|
status: "failed",
|
|
9016
|
-
error:
|
|
8975
|
+
error: entry.loadError.message,
|
|
9017
8976
|
durationMs: durationMs2
|
|
9018
8977
|
};
|
|
9019
8978
|
await tracker.updateFileExecution(
|
|
@@ -9021,56 +8980,29 @@ async function executeSingleFileWithUpdate(context, filepath, checksum, options,
|
|
|
9021
8980
|
relFilepath,
|
|
9022
8981
|
"failed",
|
|
9023
8982
|
Math.round(durationMs2),
|
|
9024
|
-
|
|
8983
|
+
entry.loadError.message
|
|
9025
8984
|
);
|
|
9026
8985
|
observer.emit("file:after", {
|
|
9027
8986
|
filepath,
|
|
9028
8987
|
status: "failed",
|
|
9029
8988
|
durationMs: durationMs2,
|
|
9030
|
-
error:
|
|
8989
|
+
error: entry.loadError.message
|
|
9031
8990
|
});
|
|
9032
8991
|
return result2;
|
|
9033
8992
|
}
|
|
9034
|
-
const [renderedChecksum, checksumErr] = attemptSync(() => computeChecksumFromContent(sqlContent));
|
|
9035
|
-
const finalChecksum = checksumErr ? checksum : renderedChecksum;
|
|
9036
8993
|
observer.emit("file:before", {
|
|
9037
8994
|
filepath,
|
|
9038
|
-
checksum
|
|
8995
|
+
checksum,
|
|
9039
8996
|
configName: context.configName
|
|
9040
8997
|
});
|
|
9041
|
-
|
|
9042
|
-
const needsRunResult = await tracker.needsRun(relFilepath, finalChecksum, options.force, operationId);
|
|
9043
|
-
if (!needsRunResult.needsRun) {
|
|
9044
|
-
const result2 = {
|
|
9045
|
-
filepath,
|
|
9046
|
-
checksum: finalChecksum,
|
|
9047
|
-
status: "skipped",
|
|
9048
|
-
skipReason: needsRunResult.skipReason
|
|
9049
|
-
};
|
|
9050
|
-
await tracker.updateFileExecution(
|
|
9051
|
-
operationId,
|
|
9052
|
-
relFilepath,
|
|
9053
|
-
"skipped",
|
|
9054
|
-
0,
|
|
9055
|
-
void 0,
|
|
9056
|
-
needsRunResult.skipReason,
|
|
9057
|
-
finalChecksum
|
|
9058
|
-
);
|
|
9059
|
-
observer.emit("file:skip", {
|
|
9060
|
-
filepath,
|
|
9061
|
-
reason: needsRunResult.skipReason
|
|
9062
|
-
});
|
|
9063
|
-
return result2;
|
|
9064
|
-
}
|
|
9065
|
-
}
|
|
9066
|
-
const execErrMsg = await runWatched(context, watcher, filepath, sqlContent);
|
|
8998
|
+
const execErrMsg = await runWatched(context, watcher, filepath, entry.sql);
|
|
9067
8999
|
if (execErrMsg === NOT_STARTED) return null;
|
|
9068
9000
|
const durationMs = performance.now() - start;
|
|
9069
9001
|
if (execErrMsg) {
|
|
9070
9002
|
const error = execErrMsg + await describePriorSuccesses(tracker, relFilepath, operationId);
|
|
9071
9003
|
const result2 = {
|
|
9072
9004
|
filepath,
|
|
9073
|
-
checksum
|
|
9005
|
+
checksum,
|
|
9074
9006
|
status: "failed",
|
|
9075
9007
|
error,
|
|
9076
9008
|
durationMs
|
|
@@ -9080,9 +9012,7 @@ async function executeSingleFileWithUpdate(context, filepath, checksum, options,
|
|
|
9080
9012
|
relFilepath,
|
|
9081
9013
|
"failed",
|
|
9082
9014
|
Math.round(durationMs),
|
|
9083
|
-
error
|
|
9084
|
-
void 0,
|
|
9085
|
-
finalChecksum
|
|
9015
|
+
error
|
|
9086
9016
|
);
|
|
9087
9017
|
observer.emit("file:after", {
|
|
9088
9018
|
filepath,
|
|
@@ -9094,7 +9024,7 @@ async function executeSingleFileWithUpdate(context, filepath, checksum, options,
|
|
|
9094
9024
|
}
|
|
9095
9025
|
const result = {
|
|
9096
9026
|
filepath,
|
|
9097
|
-
checksum
|
|
9027
|
+
checksum,
|
|
9098
9028
|
status: "success",
|
|
9099
9029
|
durationMs
|
|
9100
9030
|
};
|
|
@@ -9102,10 +9032,7 @@ async function executeSingleFileWithUpdate(context, filepath, checksum, options,
|
|
|
9102
9032
|
operationId,
|
|
9103
9033
|
relFilepath,
|
|
9104
9034
|
"success",
|
|
9105
|
-
Math.round(durationMs)
|
|
9106
|
-
void 0,
|
|
9107
|
-
void 0,
|
|
9108
|
-
finalChecksum
|
|
9035
|
+
Math.round(durationMs)
|
|
9109
9036
|
);
|
|
9110
9037
|
observer.emit("file:after", {
|
|
9111
9038
|
filepath,
|
|
@@ -9114,143 +9041,6 @@ async function executeSingleFileWithUpdate(context, filepath, checksum, options,
|
|
|
9114
9041
|
});
|
|
9115
9042
|
return result;
|
|
9116
9043
|
}
|
|
9117
|
-
async function executeSingleFile(context, filepath, options, tracker, operationId, watcher) {
|
|
9118
|
-
const start = performance.now();
|
|
9119
|
-
const relFilepath = path.relative(context.projectRoot, filepath);
|
|
9120
|
-
const [sqlContent, loadErr] = await attempt(() => loadAndRenderFile2(context, filepath));
|
|
9121
|
-
if (loadErr) {
|
|
9122
|
-
const durationMs2 = performance.now() - start;
|
|
9123
|
-
const result2 = {
|
|
9124
|
-
filepath,
|
|
9125
|
-
checksum: "",
|
|
9126
|
-
status: "failed",
|
|
9127
|
-
error: loadErr.message,
|
|
9128
|
-
durationMs: durationMs2
|
|
9129
|
-
};
|
|
9130
|
-
await tracker.recordExecution({
|
|
9131
|
-
changeId: operationId,
|
|
9132
|
-
filepath: relFilepath,
|
|
9133
|
-
checksum: "",
|
|
9134
|
-
status: "failed",
|
|
9135
|
-
errorMessage: loadErr.message,
|
|
9136
|
-
durationMs: Math.round(durationMs2)
|
|
9137
|
-
});
|
|
9138
|
-
observer.emit("file:after", {
|
|
9139
|
-
filepath,
|
|
9140
|
-
status: "failed",
|
|
9141
|
-
durationMs: durationMs2,
|
|
9142
|
-
error: loadErr.message
|
|
9143
|
-
});
|
|
9144
|
-
return result2;
|
|
9145
|
-
}
|
|
9146
|
-
const [checksum, checksumErr] = attemptSync(() => computeChecksumFromContent(sqlContent));
|
|
9147
|
-
if (checksumErr) {
|
|
9148
|
-
const result2 = {
|
|
9149
|
-
filepath,
|
|
9150
|
-
checksum: "",
|
|
9151
|
-
status: "failed",
|
|
9152
|
-
error: checksumErr.message,
|
|
9153
|
-
durationMs: performance.now() - start
|
|
9154
|
-
};
|
|
9155
|
-
await tracker.recordExecution({
|
|
9156
|
-
changeId: operationId,
|
|
9157
|
-
filepath: relFilepath,
|
|
9158
|
-
checksum: "",
|
|
9159
|
-
status: "failed",
|
|
9160
|
-
errorMessage: checksumErr.message,
|
|
9161
|
-
durationMs: Math.round(result2.durationMs ?? 0)
|
|
9162
|
-
});
|
|
9163
|
-
observer.emit("file:after", {
|
|
9164
|
-
filepath,
|
|
9165
|
-
status: "failed",
|
|
9166
|
-
durationMs: result2.durationMs ?? 0,
|
|
9167
|
-
error: checksumErr.message
|
|
9168
|
-
});
|
|
9169
|
-
return result2;
|
|
9170
|
-
}
|
|
9171
|
-
observer.emit("file:before", {
|
|
9172
|
-
filepath,
|
|
9173
|
-
checksum,
|
|
9174
|
-
configName: context.configName
|
|
9175
|
-
});
|
|
9176
|
-
const needsRunResult = await tracker.needsRun(relFilepath, checksum, options.force);
|
|
9177
|
-
if (!needsRunResult.needsRun) {
|
|
9178
|
-
const result2 = {
|
|
9179
|
-
filepath,
|
|
9180
|
-
checksum,
|
|
9181
|
-
status: "skipped",
|
|
9182
|
-
skipReason: needsRunResult.skipReason
|
|
9183
|
-
};
|
|
9184
|
-
await tracker.recordExecution({
|
|
9185
|
-
changeId: operationId,
|
|
9186
|
-
filepath: relFilepath,
|
|
9187
|
-
checksum,
|
|
9188
|
-
status: "skipped",
|
|
9189
|
-
skipReason: needsRunResult.skipReason
|
|
9190
|
-
});
|
|
9191
|
-
observer.emit("file:skip", {
|
|
9192
|
-
filepath,
|
|
9193
|
-
reason: needsRunResult.skipReason
|
|
9194
|
-
});
|
|
9195
|
-
return result2;
|
|
9196
|
-
}
|
|
9197
|
-
const execErrMsg = await runWatched(context, watcher, filepath, sqlContent);
|
|
9198
|
-
const durationMs = performance.now() - start;
|
|
9199
|
-
if (execErrMsg === NOT_STARTED) {
|
|
9200
|
-
await tracker.recordExecution({
|
|
9201
|
-
changeId: operationId,
|
|
9202
|
-
filepath: relFilepath,
|
|
9203
|
-
checksum,
|
|
9204
|
-
status: "skipped",
|
|
9205
|
-
skipReason: RUN_CANCELLED
|
|
9206
|
-
});
|
|
9207
|
-
return { filepath, checksum, status: "skipped", error: RUN_CANCELLED };
|
|
9208
|
-
}
|
|
9209
|
-
if (execErrMsg) {
|
|
9210
|
-
const error = execErrMsg + await describePriorSuccesses(tracker, relFilepath, operationId);
|
|
9211
|
-
const result2 = {
|
|
9212
|
-
filepath,
|
|
9213
|
-
checksum,
|
|
9214
|
-
status: "failed",
|
|
9215
|
-
error,
|
|
9216
|
-
durationMs
|
|
9217
|
-
};
|
|
9218
|
-
await tracker.recordExecution({
|
|
9219
|
-
changeId: operationId,
|
|
9220
|
-
filepath: relFilepath,
|
|
9221
|
-
checksum,
|
|
9222
|
-
status: "failed",
|
|
9223
|
-
errorMessage: error,
|
|
9224
|
-
durationMs: Math.round(durationMs)
|
|
9225
|
-
});
|
|
9226
|
-
observer.emit("file:after", {
|
|
9227
|
-
filepath,
|
|
9228
|
-
status: "failed",
|
|
9229
|
-
durationMs,
|
|
9230
|
-
error
|
|
9231
|
-
});
|
|
9232
|
-
return result2;
|
|
9233
|
-
}
|
|
9234
|
-
const result = {
|
|
9235
|
-
filepath,
|
|
9236
|
-
checksum,
|
|
9237
|
-
status: "success",
|
|
9238
|
-
durationMs
|
|
9239
|
-
};
|
|
9240
|
-
await tracker.recordExecution({
|
|
9241
|
-
changeId: operationId,
|
|
9242
|
-
filepath: relFilepath,
|
|
9243
|
-
checksum,
|
|
9244
|
-
status: "success",
|
|
9245
|
-
durationMs: Math.round(durationMs)
|
|
9246
|
-
});
|
|
9247
|
-
observer.emit("file:after", {
|
|
9248
|
-
filepath,
|
|
9249
|
-
status: "success",
|
|
9250
|
-
durationMs
|
|
9251
|
-
});
|
|
9252
|
-
return result;
|
|
9253
|
-
}
|
|
9254
9044
|
async function loadAndRenderFile2(context, filepath) {
|
|
9255
9045
|
if (isTemplate(filepath)) {
|
|
9256
9046
|
const result = await processFile(filepath, {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createRequire } from 'module';
|
|
2
|
-
export { deleteVaultSecret, deleteVaultSecretChecked, getAllVaultSecrets, getVaultKey, getVaultKeyChecked, getVaultSecret, getVaultStatus, initializeVault, initializeVaultChecked, listVaultSecretKeys, listVaultSecretKeysChecked, setVaultSecret, setVaultSecretChecked, vaultSecretExists } from './chunk-
|
|
2
|
+
export { deleteVaultSecret, deleteVaultSecretChecked, getAllVaultSecrets, getVaultKey, getVaultKeyChecked, getVaultSecret, getVaultStatus, initializeVault, initializeVaultChecked, listVaultSecretKeys, listVaultSecretKeysChecked, setVaultSecret, setVaultSecretChecked, vaultSecretExists } from './chunk-24L5UNQR.js';
|
|
3
3
|
import './chunk-6LG4ENOJ.js';
|
|
4
4
|
import './chunk-TXDGFA44.js';
|
|
5
5
|
import './chunk-D2XW2UOP.js';
|
|
6
6
|
|
|
7
7
|
createRequire(import.meta.url);
|
|
8
|
-
//# sourceMappingURL=storage-
|
|
9
|
-
//# sourceMappingURL=storage-
|
|
8
|
+
//# sourceMappingURL=storage-NQA4H7PK.js.map
|
|
9
|
+
//# sourceMappingURL=storage-NQA4H7PK.js.map
|