@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.js
CHANGED
|
@@ -2283,23 +2283,18 @@ function defaultFileSynopsisFunction(fileEntry, data) {
|
|
|
2283
2283
|
const timestamps = [];
|
|
2284
2284
|
const statusCounts = {};
|
|
2285
2285
|
for (const item of data) {
|
|
2286
|
-
|
|
2287
|
-
let status = null;
|
|
2286
|
+
if (!item || typeof item !== "object") continue;
|
|
2288
2287
|
for (const [key, value] of Object.entries(item)) {
|
|
2289
2288
|
const k = key.toLowerCase();
|
|
2290
|
-
if (k
|
|
2291
|
-
ts = new Date(value).getTime();
|
|
2289
|
+
if (k.endsWith("modificationtimestamp") && value != null && value !== "") {
|
|
2290
|
+
const ts = new Date(value).getTime();
|
|
2291
|
+
if (!Number.isNaN(ts)) timestamps.push(ts);
|
|
2292
2292
|
}
|
|
2293
|
-
if (k === "standardstatus") {
|
|
2294
|
-
status = value;
|
|
2293
|
+
if (k === "standardstatus" && value != null && value !== "") {
|
|
2294
|
+
const status = String(value);
|
|
2295
|
+
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
2295
2296
|
}
|
|
2296
2297
|
}
|
|
2297
|
-
if (ts && !isNaN(ts)) {
|
|
2298
|
-
timestamps.push(ts);
|
|
2299
|
-
}
|
|
2300
|
-
if (status !== null && status !== void 0) {
|
|
2301
|
-
statusCounts[status] = (statusCounts[status] || 0) + 1;
|
|
2302
|
-
}
|
|
2303
2298
|
}
|
|
2304
2299
|
const result = { ...fileEntry };
|
|
2305
2300
|
if (timestamps.length) {
|
|
@@ -2318,27 +2313,38 @@ function defaultVersionSynopsisFunction(metadata) {
|
|
|
2318
2313
|
const timestamps = [];
|
|
2319
2314
|
const statusCounts = {};
|
|
2320
2315
|
for (const file of metadata.files) {
|
|
2321
|
-
if (file
|
|
2316
|
+
if (file?.minModificationTimestamp) {
|
|
2322
2317
|
const minTs = new Date(file.minModificationTimestamp).getTime();
|
|
2323
|
-
if (!isNaN(minTs)) timestamps.push(minTs);
|
|
2318
|
+
if (!Number.isNaN(minTs)) timestamps.push(minTs);
|
|
2324
2319
|
}
|
|
2325
|
-
if (file
|
|
2320
|
+
if (file?.maxModificationTimestamp) {
|
|
2326
2321
|
const maxTs = new Date(file.maxModificationTimestamp).getTime();
|
|
2327
|
-
if (!isNaN(maxTs)) timestamps.push(maxTs);
|
|
2322
|
+
if (!Number.isNaN(maxTs)) timestamps.push(maxTs);
|
|
2328
2323
|
}
|
|
2329
|
-
if (file
|
|
2324
|
+
if (file?.StandardStatuses && typeof file.StandardStatuses === "object") {
|
|
2330
2325
|
for (const [status, count] of Object.entries(file.StandardStatuses)) {
|
|
2331
|
-
statusCounts[status] = (statusCounts[status] || 0) + count;
|
|
2326
|
+
statusCounts[status] = (statusCounts[status] || 0) + Number(count || 0);
|
|
2332
2327
|
}
|
|
2333
2328
|
}
|
|
2334
2329
|
}
|
|
2335
2330
|
const result = { ...metadata };
|
|
2331
|
+
const synopsis = {
|
|
2332
|
+
...metadata.synopsis && typeof metadata.synopsis === "object" ? metadata.synopsis : {}
|
|
2333
|
+
};
|
|
2336
2334
|
if (timestamps.length) {
|
|
2337
|
-
|
|
2338
|
-
|
|
2335
|
+
const minIso = new Date(Math.min(...timestamps)).toISOString();
|
|
2336
|
+
const maxIso = new Date(Math.max(...timestamps)).toISOString();
|
|
2337
|
+
result.minModificationTimestamp = minIso;
|
|
2338
|
+
result.maxModificationTimestamp = maxIso;
|
|
2339
|
+
synopsis.minModificationTimestamp = minIso;
|
|
2340
|
+
synopsis.maxModificationTimestamp = maxIso;
|
|
2339
2341
|
}
|
|
2340
2342
|
if (Object.keys(statusCounts).length > 0) {
|
|
2341
2343
|
result.StandardStatuses = statusCounts;
|
|
2344
|
+
synopsis.StandardStatuses = statusCounts;
|
|
2345
|
+
}
|
|
2346
|
+
if (Object.keys(synopsis).length) {
|
|
2347
|
+
result.synopsis = synopsis;
|
|
2342
2348
|
}
|
|
2343
2349
|
return result;
|
|
2344
2350
|
}
|
|
@@ -2361,6 +2367,9 @@ var FileDatabase = class _FileDatabase {
|
|
|
2361
2367
|
currentRecord = 0;
|
|
2362
2368
|
hasReadFirstPage = false;
|
|
2363
2369
|
lastFileData = null;
|
|
2370
|
+
/** Cache of the last JSON file parsed during paginated reads (avoid re-parse per page). */
|
|
2371
|
+
readFileCache = null;
|
|
2372
|
+
// { filePath: string, data: any[] } | null
|
|
2364
2373
|
metadata;
|
|
2365
2374
|
// Synopsis calculation functions
|
|
2366
2375
|
fileSynopsisFunction = null;
|
|
@@ -3127,7 +3136,6 @@ var FileDatabase = class _FileDatabase {
|
|
|
3127
3136
|
let effectivePageSize;
|
|
3128
3137
|
if (nextPage && this.hasReadFirstPage) {
|
|
3129
3138
|
effectivePageSize = pageSize || this.pageSize;
|
|
3130
|
-
this.currentRecord += effectivePageSize;
|
|
3131
3139
|
} else if (!nextPage) {
|
|
3132
3140
|
effectivePageSize = pageSize !== void 0 ? pageSize : this.metadata.totalRecords;
|
|
3133
3141
|
this.currentRecord = 0;
|
|
@@ -3156,8 +3164,14 @@ var FileDatabase = class _FileDatabase {
|
|
|
3156
3164
|
const file = this.metadata.files[i];
|
|
3157
3165
|
const filePath = path3.join(this.getDestinationPath(this.currentVersion || void 0), file.fileName);
|
|
3158
3166
|
try {
|
|
3159
|
-
|
|
3160
|
-
|
|
3167
|
+
let fileData;
|
|
3168
|
+
if (this.readFileCache?.filePath === filePath && Array.isArray(this.readFileCache.data)) {
|
|
3169
|
+
fileData = this.readFileCache.data;
|
|
3170
|
+
} else {
|
|
3171
|
+
const rawData = await fs3.promises.readFile(filePath, "utf8");
|
|
3172
|
+
fileData = deserializeData(rawData, this.metadata.dataType);
|
|
3173
|
+
this.readFileCache = { filePath, data: fileData };
|
|
3174
|
+
}
|
|
3161
3175
|
let startIndex = 0;
|
|
3162
3176
|
if (i === currentFileIndex) {
|
|
3163
3177
|
startIndex = this.currentRecord - cumulativeRecords;
|
|
@@ -3171,6 +3185,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3171
3185
|
throw new FileDatabaseError(`Failed to read file ${file.fileName}: ${error.message}`);
|
|
3172
3186
|
}
|
|
3173
3187
|
}
|
|
3188
|
+
this.currentRecord += recordsRead;
|
|
3174
3189
|
if (result.length > 0) {
|
|
3175
3190
|
if (nextPage || pageSize !== void 0 && pageSize < this.metadata.totalRecords) {
|
|
3176
3191
|
this.hasReadFirstPage = true;
|
|
@@ -3184,6 +3199,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3184
3199
|
setStartRecord(startRecord) {
|
|
3185
3200
|
this.currentRecord = startRecord - 1;
|
|
3186
3201
|
this.hasReadFirstPage = false;
|
|
3202
|
+
this.readFileCache = null;
|
|
3187
3203
|
}
|
|
3188
3204
|
/**
|
|
3189
3205
|
* Reset read pagination state
|
|
@@ -3191,6 +3207,7 @@ var FileDatabase = class _FileDatabase {
|
|
|
3191
3207
|
resetPagination() {
|
|
3192
3208
|
this.currentRecord = 0;
|
|
3193
3209
|
this.hasReadFirstPage = false;
|
|
3210
|
+
this.readFileCache = null;
|
|
3194
3211
|
}
|
|
3195
3212
|
/**
|
|
3196
3213
|
* List filenames in the table directory.
|
|
@@ -6310,22 +6327,46 @@ async function ensureTaskTables(context, options = {}) {
|
|
|
6310
6327
|
}
|
|
6311
6328
|
}
|
|
6312
6329
|
const { actions } = await ensureSchema(db, spec, { dryRun, logger: context.logger });
|
|
6330
|
+
const legacyDrops = await dropLegacyTaskNameColumn(db, [tasksTable, historyTable], {
|
|
6331
|
+
dryRun,
|
|
6332
|
+
log,
|
|
6333
|
+
label
|
|
6334
|
+
});
|
|
6335
|
+
const allActions = [...actions, ...legacyDrops];
|
|
6313
6336
|
if (dryRun) {
|
|
6314
|
-
if (
|
|
6337
|
+
if (allActions.length === 0) {
|
|
6315
6338
|
log.info?.(`[tasks-schema] dryRun \u2014 ${label}: queue "${queueName}" already up to date; no DDL`);
|
|
6316
6339
|
} else {
|
|
6317
6340
|
log.info?.(
|
|
6318
|
-
`[tasks-schema] dryRun \u2014 ${label}: would run ${
|
|
6341
|
+
`[tasks-schema] dryRun \u2014 ${label}: would run ${allActions.length} statement(s) for queue "${queueName}":`
|
|
6319
6342
|
);
|
|
6320
|
-
for (const s of
|
|
6343
|
+
for (const s of allActions) log.info?.(` - ${s}`);
|
|
6321
6344
|
}
|
|
6322
|
-
} else if (
|
|
6345
|
+
} else if (allActions.length > 0) {
|
|
6323
6346
|
log.info?.(
|
|
6324
|
-
`[tasks-schema] ${label}: applied ${
|
|
6347
|
+
`[tasks-schema] ${label}: applied ${allActions.length} DDL statement(s) for queue "${queueName}"`
|
|
6325
6348
|
);
|
|
6326
6349
|
}
|
|
6327
6350
|
}
|
|
6328
6351
|
}
|
|
6352
|
+
async function dropLegacyTaskNameColumn(db, tableNames, { dryRun, log, label }) {
|
|
6353
|
+
const actions = [];
|
|
6354
|
+
for (const table of tableNames) {
|
|
6355
|
+
if (!await db.tableExists(table).catch(() => false)) continue;
|
|
6356
|
+
const hasTask = await db.schema.hasColumn(table, "task");
|
|
6357
|
+
const hasName = await db.schema.hasColumn(table, "name");
|
|
6358
|
+
if (!hasTask || !hasName) continue;
|
|
6359
|
+
const sql = `ALTER TABLE "${table}" DROP COLUMN IF EXISTS "task"`;
|
|
6360
|
+
actions.push(sql);
|
|
6361
|
+
if (dryRun) {
|
|
6362
|
+
log?.info?.(`[tasks-schema] dryRun \u2014 ${label}: ${sql}`);
|
|
6363
|
+
} else {
|
|
6364
|
+
await db.raw(sql);
|
|
6365
|
+
log?.info?.(`[tasks-schema] ${label}: dropped legacy column ${table}.task`);
|
|
6366
|
+
}
|
|
6367
|
+
}
|
|
6368
|
+
return actions;
|
|
6369
|
+
}
|
|
6329
6370
|
async function enqueueTask(context, options) {
|
|
6330
6371
|
const db = getDb(context);
|
|
6331
6372
|
const queueName = options.queueName ?? "tasks";
|
|
@@ -6342,7 +6383,7 @@ async function enqueueTask(context, options) {
|
|
|
6342
6383
|
} else if (schedule) {
|
|
6343
6384
|
nextRunAt = nextTimeMatch(schedule, /* @__PURE__ */ new Date());
|
|
6344
6385
|
}
|
|
6345
|
-
|
|
6386
|
+
const row = {
|
|
6346
6387
|
id,
|
|
6347
6388
|
name,
|
|
6348
6389
|
params: toJsonColumn(options.params ?? null),
|
|
@@ -6356,9 +6397,21 @@ async function enqueueTask(context, options) {
|
|
|
6356
6397
|
server_name: options.serverName ?? null,
|
|
6357
6398
|
status: "idle",
|
|
6358
6399
|
status_changed_at: db.fn.now()
|
|
6359
|
-
}
|
|
6400
|
+
};
|
|
6401
|
+
if (await tableHasLegacyTaskColumn(db, tasksTable)) {
|
|
6402
|
+
row.task = name;
|
|
6403
|
+
}
|
|
6404
|
+
await db(tasksTable).insert(row);
|
|
6360
6405
|
return id;
|
|
6361
6406
|
}
|
|
6407
|
+
var legacyTaskColumnCache = /* @__PURE__ */ new Map();
|
|
6408
|
+
async function tableHasLegacyTaskColumn(db, tableName) {
|
|
6409
|
+
const key = `${db?.config?.name ?? "db"}:${tableName}`;
|
|
6410
|
+
if (!legacyTaskColumnCache.has(key)) {
|
|
6411
|
+
legacyTaskColumnCache.set(key, await db.schema.hasColumn(tableName, "task"));
|
|
6412
|
+
}
|
|
6413
|
+
return legacyTaskColumnCache.get(key);
|
|
6414
|
+
}
|
|
6362
6415
|
async function updateTaskProgress(context, tasksTable, taskId, progress) {
|
|
6363
6416
|
const db = getDb(context);
|
|
6364
6417
|
await db(tasksTable).where({ id: taskId }).update({
|