@nmakarov/cli-toolkit 0.40.0 → 0.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-runner.cjs +43 -8
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +43 -8
- package/dist/cli-runner.js.map +1 -1
- package/dist/filedatabase.cjs +40 -23
- package/dist/filedatabase.cjs.map +1 -1
- package/dist/filedatabase.js +40 -23
- package/dist/filedatabase.js.map +1 -1
- package/dist/http-client2.cjs +14 -3
- package/dist/http-client2.cjs.map +1 -1
- package/dist/http-client2.js +14 -3
- package/dist/http-client2.js.map +1 -1
- package/dist/index.cjs +83 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +83 -30
- package/dist/index.js.map +1 -1
- package/dist/mock-server.cjs +14 -3
- package/dist/mock-server.cjs.map +1 -1
- package/dist/mock-server.js +14 -3
- package/dist/mock-server.js.map +1 -1
- package/dist/tasks.cjs +57 -10
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +57 -10
- package/dist/tasks.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2456,23 +2456,18 @@ function defaultFileSynopsisFunction(fileEntry, data) {
|
|
|
2456
2456
|
const timestamps = [];
|
|
2457
2457
|
const statusCounts = {};
|
|
2458
2458
|
for (const item of data) {
|
|
2459
|
-
|
|
2460
|
-
let status = null;
|
|
2459
|
+
if (!item || typeof item !== "object") continue;
|
|
2461
2460
|
for (const [key, value] of Object.entries(item)) {
|
|
2462
2461
|
const k = key.toLowerCase();
|
|
2463
|
-
if (k
|
|
2464
|
-
ts = new Date(value).getTime();
|
|
2462
|
+
if (k.endsWith("modificationtimestamp") && value != null && value !== "") {
|
|
2463
|
+
const ts = new Date(value).getTime();
|
|
2464
|
+
if (!Number.isNaN(ts)) timestamps.push(ts);
|
|
2465
2465
|
}
|
|
2466
|
-
if (k === "standardstatus") {
|
|
2467
|
-
status = value;
|
|
2466
|
+
if (k === "standardstatus" && value != null && value !== "") {
|
|
2467
|
+
const status = String(value);
|
|
2468
|
+
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
2468
2469
|
}
|
|
2469
2470
|
}
|
|
2470
|
-
if (ts && !isNaN(ts)) {
|
|
2471
|
-
timestamps.push(ts);
|
|
2472
|
-
}
|
|
2473
|
-
if (status !== null && status !== void 0) {
|
|
2474
|
-
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
2475
|
-
}
|
|
2476
2471
|
}
|
|
2477
2472
|
const result = { ...fileEntry };
|
|
2478
2473
|
if (timestamps.length) {
|
|
@@ -2491,27 +2486,38 @@ function defaultVersionSynopsisFunction(metadata) {
|
|
|
2491
2486
|
const timestamps = [];
|
|
2492
2487
|
const statusCounts = {};
|
|
2493
2488
|
for (const file of metadata.files) {
|
|
2494
|
-
if (file
|
|
2489
|
+
if (file?.minModificationTimestamp) {
|
|
2495
2490
|
const minTs = new Date(file.minModificationTimestamp).getTime();
|
|
2496
|
-
if (!isNaN(minTs)) timestamps.push(minTs);
|
|
2491
|
+
if (!Number.isNaN(minTs)) timestamps.push(minTs);
|
|
2497
2492
|
}
|
|
2498
|
-
if (file
|
|
2493
|
+
if (file?.maxModificationTimestamp) {
|
|
2499
2494
|
const maxTs = new Date(file.maxModificationTimestamp).getTime();
|
|
2500
|
-
if (!isNaN(maxTs)) timestamps.push(maxTs);
|
|
2495
|
+
if (!Number.isNaN(maxTs)) timestamps.push(maxTs);
|
|
2501
2496
|
}
|
|
2502
|
-
if (file
|
|
2497
|
+
if (file?.StandardStatuses && typeof file.StandardStatuses === "object") {
|
|
2503
2498
|
for (const [status, count] of Object.entries(file.StandardStatuses)) {
|
|
2504
|
-
statusCounts[status] = (statusCounts[status] || 0) + count;
|
|
2499
|
+
statusCounts[status] = (statusCounts[status] || 0) + Number(count || 0);
|
|
2505
2500
|
}
|
|
2506
2501
|
}
|
|
2507
2502
|
}
|
|
2508
2503
|
const result = { ...metadata };
|
|
2504
|
+
const synopsis = {
|
|
2505
|
+
...metadata.synopsis && typeof metadata.synopsis === "object" ? metadata.synopsis : {}
|
|
2506
|
+
};
|
|
2509
2507
|
if (timestamps.length) {
|
|
2510
|
-
|
|
2511
|
-
|
|
2508
|
+
const minIso = new Date(Math.min(...timestamps)).toISOString();
|
|
2509
|
+
const maxIso = new Date(Math.max(...timestamps)).toISOString();
|
|
2510
|
+
result.minModificationTimestamp = minIso;
|
|
2511
|
+
result.maxModificationTimestamp = maxIso;
|
|
2512
|
+
synopsis.minModificationTimestamp = minIso;
|
|
2513
|
+
synopsis.maxModificationTimestamp = maxIso;
|
|
2512
2514
|
}
|
|
2513
2515
|
if (Object.keys(statusCounts).length > 0) {
|
|
2514
2516
|
result.StandardStatuses = statusCounts;
|
|
2517
|
+
synopsis.StandardStatuses = statusCounts;
|
|
2518
|
+
}
|
|
2519
|
+
if (Object.keys(synopsis).length) {
|
|
2520
|
+
result.synopsis = synopsis;
|
|
2515
2521
|
}
|
|
2516
2522
|
return result;
|
|
2517
2523
|
}
|
|
@@ -2534,6 +2540,9 @@ var FileDatabase = class _FileDatabase {
|
|
|
2534
2540
|
currentRecord = 0;
|
|
2535
2541
|
hasReadFirstPage = false;
|
|
2536
2542
|
lastFileData = null;
|
|
2543
|
+
/** Cache of the last JSON file parsed during paginated reads (avoid re-parse per page). */
|
|
2544
|
+
readFileCache = null;
|
|
2545
|
+
// { filePath: string, data: any[] } | null
|
|
2537
2546
|
metadata;
|
|
2538
2547
|
// Synopsis calculation functions
|
|
2539
2548
|
fileSynopsisFunction = null;
|
|
@@ -3300,7 +3309,6 @@ var FileDatabase = class _FileDatabase {
|
|
|
3300
3309
|
let effectivePageSize;
|
|
3301
3310
|
if (nextPage && this.hasReadFirstPage) {
|
|
3302
3311
|
effectivePageSize = pageSize || this.pageSize;
|
|
3303
|
-
this.currentRecord += effectivePageSize;
|
|
3304
3312
|
} else if (!nextPage) {
|
|
3305
3313
|
effectivePageSize = pageSize !== void 0 ? pageSize : this.metadata.totalRecords;
|
|
3306
3314
|
this.currentRecord = 0;
|
|
@@ -3329,8 +3337,14 @@ var FileDatabase = class _FileDatabase {
|
|
|
3329
3337
|
const file = this.metadata.files[i];
|
|
3330
3338
|
const filePath = import_path4.default.join(this.getDestinationPath(this.currentVersion || void 0), file.fileName);
|
|
3331
3339
|
try {
|
|
3332
|
-
|
|
3333
|
-
|
|
3340
|
+
let fileData;
|
|
3341
|
+
if (this.readFileCache?.filePath === filePath && Array.isArray(this.readFileCache.data)) {
|
|
3342
|
+
fileData = this.readFileCache.data;
|
|
3343
|
+
} else {
|
|
3344
|
+
const rawData = await import_fs4.default.promises.readFile(filePath, "utf8");
|
|
3345
|
+
fileData = deserializeData(rawData, this.metadata.dataType);
|
|
3346
|
+
this.readFileCache = { filePath, data: fileData };
|
|
3347
|
+
}
|
|
3334
3348
|
let startIndex = 0;
|
|
3335
3349
|
if (i === currentFileIndex) {
|
|
3336
3350
|
startIndex = this.currentRecord - cumulativeRecords;
|
|
@@ -3344,6 +3358,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3344
3358
|
throw new FileDatabaseError(`Failed to read file ${file.fileName}: ${error.message}`);
|
|
3345
3359
|
}
|
|
3346
3360
|
}
|
|
3361
|
+
this.currentRecord += recordsRead;
|
|
3347
3362
|
if (result.length > 0) {
|
|
3348
3363
|
if (nextPage || pageSize !== void 0 && pageSize < this.metadata.totalRecords) {
|
|
3349
3364
|
this.hasReadFirstPage = true;
|
|
@@ -3357,6 +3372,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3357
3372
|
setStartRecord(startRecord) {
|
|
3358
3373
|
this.currentRecord = startRecord - 1;
|
|
3359
3374
|
this.hasReadFirstPage = false;
|
|
3375
|
+
this.readFileCache = null;
|
|
3360
3376
|
}
|
|
3361
3377
|
/**
|
|
3362
3378
|
* Reset read pagination state
|
|
@@ -3364,6 +3380,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3364
3380
|
resetPagination() {
|
|
3365
3381
|
this.currentRecord = 0;
|
|
3366
3382
|
this.hasReadFirstPage = false;
|
|
3383
|
+
this.readFileCache = null;
|
|
3367
3384
|
}
|
|
3368
3385
|
/**
|
|
3369
3386
|
* List filenames in the table directory.
|
|
@@ -6457,22 +6474,46 @@ async function ensureTaskTables(context, options = {}) {
|
|
|
6457
6474
|
}
|
|
6458
6475
|
}
|
|
6459
6476
|
const { actions } = await ensureSchema(db, spec, { dryRun, logger: context.logger });
|
|
6477
|
+
const legacyDrops = await dropLegacyTaskNameColumn(db, [tasksTable, historyTable], {
|
|
6478
|
+
dryRun,
|
|
6479
|
+
log,
|
|
6480
|
+
label
|
|
6481
|
+
});
|
|
6482
|
+
const allActions = [...actions, ...legacyDrops];
|
|
6460
6483
|
if (dryRun) {
|
|
6461
|
-
if (
|
|
6484
|
+
if (allActions.length === 0) {
|
|
6462
6485
|
log.info?.(`[tasks-schema] dryRun \u2014 ${label}: queue "${queueName}" already up to date; no DDL`);
|
|
6463
6486
|
} else {
|
|
6464
6487
|
log.info?.(
|
|
6465
|
-
`[tasks-schema] dryRun \u2014 ${label}: would run ${
|
|
6488
|
+
`[tasks-schema] dryRun \u2014 ${label}: would run ${allActions.length} statement(s) for queue "${queueName}":`
|
|
6466
6489
|
);
|
|
6467
|
-
for (const s of
|
|
6490
|
+
for (const s of allActions) log.info?.(` - ${s}`);
|
|
6468
6491
|
}
|
|
6469
|
-
} else if (
|
|
6492
|
+
} else if (allActions.length > 0) {
|
|
6470
6493
|
log.info?.(
|
|
6471
|
-
`[tasks-schema] ${label}: applied ${
|
|
6494
|
+
`[tasks-schema] ${label}: applied ${allActions.length} DDL statement(s) for queue "${queueName}"`
|
|
6472
6495
|
);
|
|
6473
6496
|
}
|
|
6474
6497
|
}
|
|
6475
6498
|
}
|
|
6499
|
+
async function dropLegacyTaskNameColumn(db, tableNames, { dryRun, log, label }) {
|
|
6500
|
+
const actions = [];
|
|
6501
|
+
for (const table of tableNames) {
|
|
6502
|
+
if (!await db.tableExists(table).catch(() => false)) continue;
|
|
6503
|
+
const hasTask = await db.schema.hasColumn(table, "task");
|
|
6504
|
+
const hasName = await db.schema.hasColumn(table, "name");
|
|
6505
|
+
if (!hasTask || !hasName) continue;
|
|
6506
|
+
const sql = `ALTER TABLE "${table}" DROP COLUMN IF EXISTS "task"`;
|
|
6507
|
+
actions.push(sql);
|
|
6508
|
+
if (dryRun) {
|
|
6509
|
+
log?.info?.(`[tasks-schema] dryRun \u2014 ${label}: ${sql}`);
|
|
6510
|
+
} else {
|
|
6511
|
+
await db.raw(sql);
|
|
6512
|
+
log?.info?.(`[tasks-schema] ${label}: dropped legacy column ${table}.task`);
|
|
6513
|
+
}
|
|
6514
|
+
}
|
|
6515
|
+
return actions;
|
|
6516
|
+
}
|
|
6476
6517
|
async function enqueueTask(context, options) {
|
|
6477
6518
|
const db = getDb(context);
|
|
6478
6519
|
const queueName = options.queueName ?? "tasks";
|
|
@@ -6489,7 +6530,7 @@ async function enqueueTask(context, options) {
|
|
|
6489
6530
|
} else if (schedule) {
|
|
6490
6531
|
nextRunAt = nextTimeMatch(schedule, /* @__PURE__ */ new Date());
|
|
6491
6532
|
}
|
|
6492
|
-
|
|
6533
|
+
const row = {
|
|
6493
6534
|
id,
|
|
6494
6535
|
name,
|
|
6495
6536
|
params: toJsonColumn(options.params ?? null),
|
|
@@ -6503,9 +6544,21 @@ async function enqueueTask(context, options) {
|
|
|
6503
6544
|
server_name: options.serverName ?? null,
|
|
6504
6545
|
status: "idle",
|
|
6505
6546
|
status_changed_at: db.fn.now()
|
|
6506
|
-
}
|
|
6547
|
+
};
|
|
6548
|
+
if (await tableHasLegacyTaskColumn(db, tasksTable)) {
|
|
6549
|
+
row.task = name;
|
|
6550
|
+
}
|
|
6551
|
+
await db(tasksTable).insert(row);
|
|
6507
6552
|
return id;
|
|
6508
6553
|
}
|
|
6554
|
+
var legacyTaskColumnCache = /* @__PURE__ */ new Map();
|
|
6555
|
+
async function tableHasLegacyTaskColumn(db, tableName) {
|
|
6556
|
+
const key = `${db?.config?.name ?? "db"}:${tableName}`;
|
|
6557
|
+
if (!legacyTaskColumnCache.has(key)) {
|
|
6558
|
+
legacyTaskColumnCache.set(key, await db.schema.hasColumn(tableName, "task"));
|
|
6559
|
+
}
|
|
6560
|
+
return legacyTaskColumnCache.get(key);
|
|
6561
|
+
}
|
|
6509
6562
|
async function updateTaskProgress(context, tasksTable, taskId, progress) {
|
|
6510
6563
|
const db = getDb(context);
|
|
6511
6564
|
await db(tasksTable).where({ id: taskId }).update({
|