@nmakarov/cli-toolkit 0.43.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/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
- let ts = null;
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 === "modificationtimestamp") {
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.minModificationTimestamp) {
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.maxModificationTimestamp) {
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.StandardStatuses && typeof file.StandardStatuses === "object") {
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
- result.minModificationTimestamp = new Date(Math.min(...timestamps)).toISOString();
2511
- result.maxModificationTimestamp = new Date(Math.max(...timestamps)).toISOString();
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
  }
@@ -6468,22 +6474,46 @@ async function ensureTaskTables(context, options = {}) {
6468
6474
  }
6469
6475
  }
6470
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];
6471
6483
  if (dryRun) {
6472
- if (actions.length === 0) {
6484
+ if (allActions.length === 0) {
6473
6485
  log.info?.(`[tasks-schema] dryRun \u2014 ${label}: queue "${queueName}" already up to date; no DDL`);
6474
6486
  } else {
6475
6487
  log.info?.(
6476
- `[tasks-schema] dryRun \u2014 ${label}: would run ${actions.length} statement(s) for queue "${queueName}":`
6488
+ `[tasks-schema] dryRun \u2014 ${label}: would run ${allActions.length} statement(s) for queue "${queueName}":`
6477
6489
  );
6478
- for (const s of actions) log.info?.(` - ${s}`);
6490
+ for (const s of allActions) log.info?.(` - ${s}`);
6479
6491
  }
6480
- } else if (actions.length > 0) {
6492
+ } else if (allActions.length > 0) {
6481
6493
  log.info?.(
6482
- `[tasks-schema] ${label}: applied ${actions.length} DDL statement(s) for queue "${queueName}"`
6494
+ `[tasks-schema] ${label}: applied ${allActions.length} DDL statement(s) for queue "${queueName}"`
6483
6495
  );
6484
6496
  }
6485
6497
  }
6486
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
+ }
6487
6517
  async function enqueueTask(context, options) {
6488
6518
  const db = getDb(context);
6489
6519
  const queueName = options.queueName ?? "tasks";
@@ -6500,7 +6530,7 @@ async function enqueueTask(context, options) {
6500
6530
  } else if (schedule) {
6501
6531
  nextRunAt = nextTimeMatch(schedule, /* @__PURE__ */ new Date());
6502
6532
  }
6503
- await db(tasksTable).insert({
6533
+ const row = {
6504
6534
  id,
6505
6535
  name,
6506
6536
  params: toJsonColumn(options.params ?? null),
@@ -6514,9 +6544,21 @@ async function enqueueTask(context, options) {
6514
6544
  server_name: options.serverName ?? null,
6515
6545
  status: "idle",
6516
6546
  status_changed_at: db.fn.now()
6517
- });
6547
+ };
6548
+ if (await tableHasLegacyTaskColumn(db, tasksTable)) {
6549
+ row.task = name;
6550
+ }
6551
+ await db(tasksTable).insert(row);
6518
6552
  return id;
6519
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
+ }
6520
6562
  async function updateTaskProgress(context, tasksTable, taskId, progress) {
6521
6563
  const db = getDb(context);
6522
6564
  await db(tasksTable).where({ id: taskId }).update({