@tiangong-lca/cli 0.0.11 → 0.0.13
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/README.md +18 -7
- package/assets/tidas-schemas/tidas_contacts.json +312 -0
- package/assets/tidas-schemas/tidas_contacts_category.json +126 -0
- package/assets/tidas-schemas/tidas_data_types.json +359 -0
- package/assets/tidas-schemas/tidas_flowproperties.json +303 -0
- package/assets/tidas-schemas/tidas_flowproperties_category.json +61 -0
- package/assets/tidas-schemas/tidas_flows.json +809 -0
- package/assets/tidas-schemas/tidas_flows_elementary_category.json +720 -0
- package/assets/tidas-schemas/tidas_flows_product_category.json +59623 -0
- package/assets/tidas-schemas/tidas_lciamethods.json +1326 -0
- package/assets/tidas-schemas/tidas_lciamethods_category.json +685 -0
- package/assets/tidas-schemas/tidas_lifecyclemodels.json +1374 -0
- package/assets/tidas-schemas/tidas_locations_category.json +2593 -0
- package/assets/tidas-schemas/tidas_processes.json +1646 -0
- package/assets/tidas-schemas/tidas_processes_category.json +10795 -0
- package/assets/tidas-schemas/tidas_sources.json +228 -0
- package/assets/tidas-schemas/tidas_sources_category.json +100 -0
- package/assets/tidas-schemas/tidas_unitgroups.json +338 -0
- package/assets/tidas-schemas/tidas_unitgroups_category.json +61 -0
- package/dist/src/cli.js +847 -13
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-classification.js +947 -0
- package/dist/src/lib/dataset-classification.js.map +1 -0
- package/dist/src/lib/dataset-command.js +11 -0
- package/dist/src/lib/dataset-command.js.map +1 -1
- package/dist/src/lib/dataset-contract.js +2 -0
- package/dist/src/lib/dataset-contract.js.map +1 -1
- package/dist/src/lib/dataset-curation-queue.js +359 -2
- package/dist/src/lib/dataset-curation-queue.js.map +1 -1
- package/dist/src/lib/dataset-import-lca.js +18 -0
- package/dist/src/lib/dataset-import-lca.js.map +1 -1
- package/dist/src/lib/dataset-local.js +94 -1
- package/dist/src/lib/dataset-local.js.map +1 -1
- package/dist/src/lib/dataset-maintenance-clear-account.js +506 -0
- package/dist/src/lib/dataset-maintenance-clear-account.js.map +1 -0
- package/dist/src/lib/dataset-patch.js +797 -0
- package/dist/src/lib/dataset-patch.js.map +1 -0
- package/dist/src/lib/dataset-remote-verify.js +188 -3
- package/dist/src/lib/dataset-remote-verify.js.map +1 -1
- package/dist/src/lib/dataset-save-draft-run.js +725 -0
- package/dist/src/lib/dataset-save-draft-run.js.map +1 -0
- package/dist/src/lib/dataset-validate.js +32 -2
- package/dist/src/lib/dataset-validate.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +7 -2
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-qa.js +8 -0
- package/dist/src/lib/flow-qa.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +895 -117
- package/dist/src/lib/identity-preflight.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-qa.js +159 -34
- package/dist/src/lib/lifecyclemodel-qa.js.map +1 -1
- package/dist/src/lib/process-required-fields.js +62 -12
- package/dist/src/lib/process-required-fields.js.map +1 -1
- package/dist/src/lib/process-save-draft-run.js +10 -0
- package/dist/src/lib/process-save-draft-run.js.map +1 -1
- package/dist/src/lib/process-save-draft.js +59 -3
- package/dist/src/lib/process-save-draft.js.map +1 -1
- package/dist/src/lib/supabase-client.js +19 -8
- package/dist/src/lib/supabase-client.js.map +1 -1
- package/package.json +2 -1
|
@@ -32,6 +32,8 @@ export async function runDatasetCurationQueueBuild(options) {
|
|
|
32
32
|
const flowTasks = flowRows.map((row) => buildTask(outDir, row, []));
|
|
33
33
|
const processTasks = processRows.map((row) => {
|
|
34
34
|
const refs = extractProcessFlowRefs(row.payload);
|
|
35
|
+
const deferredRefs = extractDeferredProcessFlowRefs(row.payload);
|
|
36
|
+
const deferredRefKeys = deferredProcessFlowRefKeys(deferredRefs);
|
|
35
37
|
const dependsOn = new Set();
|
|
36
38
|
const missingRefs = [];
|
|
37
39
|
for (const ref of refs) {
|
|
@@ -39,7 +41,7 @@ export async function runDatasetCurationQueueBuild(options) {
|
|
|
39
41
|
if (taskId) {
|
|
40
42
|
dependsOn.add(taskId);
|
|
41
43
|
}
|
|
42
|
-
else if (!externalFlowIds.has(ref.id)) {
|
|
44
|
+
else if (!externalFlowIds.has(ref.id) && !deferredRefKeys.has(flowRefKey(ref))) {
|
|
43
45
|
missingRefs.push(ref);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
@@ -68,6 +70,7 @@ export async function runDatasetCurationQueueBuild(options) {
|
|
|
68
70
|
row,
|
|
69
71
|
task,
|
|
70
72
|
flowRefs: row.entityType === 'process' ? extractProcessFlowRefs(row.payload) : [],
|
|
73
|
+
deferredFlowRefs: row.entityType === 'process' ? extractDeferredProcessFlowRefs(row.payload) : [],
|
|
71
74
|
externalFlowIds,
|
|
72
75
|
flowRowsById,
|
|
73
76
|
});
|
|
@@ -134,6 +137,250 @@ export async function runDatasetCurationQueueBuild(options) {
|
|
|
134
137
|
writeText(blockersPath, jsonLines(blockers));
|
|
135
138
|
return report;
|
|
136
139
|
}
|
|
140
|
+
export async function runDatasetCurationQueueNext(options) {
|
|
141
|
+
const queue = readQueueRuntime(options.queueDir);
|
|
142
|
+
const scope = normalizeQueueScope(options);
|
|
143
|
+
const taskStates = buildTaskStates(queue.tasks).filter((state) => taskMatchesScope(state, scope));
|
|
144
|
+
const scopedTasks = queue.tasks.filter((task) => taskMatchesScope(task, scope));
|
|
145
|
+
const stateByTaskId = new Map(taskStates.map((state) => [state.task_id, state]));
|
|
146
|
+
const runnable = scopedTasks.filter((task) => stateByTaskId.get(task.task_id)?.status === 'pending');
|
|
147
|
+
const counts = countTaskStates(taskStates);
|
|
148
|
+
const status = queue.blockers.length > 0 ||
|
|
149
|
+
(taskStates.length > 0 && runnable.length === 0 && counts.complete < taskStates.length)
|
|
150
|
+
? 'blocked'
|
|
151
|
+
: counts.complete === taskStates.length
|
|
152
|
+
? 'complete'
|
|
153
|
+
: 'ready';
|
|
154
|
+
const nextTask = status === 'ready' && runnable[0] ? withQueueAction(runnable[0]) : null;
|
|
155
|
+
return {
|
|
156
|
+
schema_version: 1,
|
|
157
|
+
generated_at_utc: new Date().toISOString(),
|
|
158
|
+
status,
|
|
159
|
+
queue_dir: queue.queueDir,
|
|
160
|
+
scope,
|
|
161
|
+
counts: {
|
|
162
|
+
...counts,
|
|
163
|
+
runnable: runnable.length,
|
|
164
|
+
},
|
|
165
|
+
next_task: nextTask,
|
|
166
|
+
task_states: taskStates,
|
|
167
|
+
blockers: queue.blockers,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
export async function runDatasetCurationQueueVerify(options) {
|
|
171
|
+
const queue = readQueueRuntime(options.queueDir);
|
|
172
|
+
const scope = normalizeQueueScope(options);
|
|
173
|
+
const taskStates = buildTaskStates(queue.tasks).filter((state) => taskMatchesScope(state, scope));
|
|
174
|
+
const counts = countTaskStates(taskStates);
|
|
175
|
+
return {
|
|
176
|
+
schema_version: 1,
|
|
177
|
+
generated_at_utc: new Date().toISOString(),
|
|
178
|
+
status: queue.blockers.length === 0 && counts.complete === taskStates.length ? 'passed' : 'blocked',
|
|
179
|
+
queue_dir: queue.queueDir,
|
|
180
|
+
scope,
|
|
181
|
+
counts,
|
|
182
|
+
task_states: taskStates,
|
|
183
|
+
blockers: queue.blockers,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function readQueueRuntime(queueDirInput) {
|
|
187
|
+
const queueDir = requireExistingPath(queueDirInput, '--queue-dir');
|
|
188
|
+
const outputsDir = path.join(queueDir, 'outputs');
|
|
189
|
+
const tasksPath = path.join(outputsDir, 'curation-queue-tasks.jsonl');
|
|
190
|
+
const blockersPath = path.join(outputsDir, 'curation-queue-blockers.jsonl');
|
|
191
|
+
if (!existsSync(tasksPath)) {
|
|
192
|
+
throw new CliError(`curation queue tasks file does not exist: ${tasksPath}`, {
|
|
193
|
+
code: 'CURATION_QUEUE_TASKS_NOT_FOUND',
|
|
194
|
+
exitCode: 2,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
if (!existsSync(blockersPath)) {
|
|
198
|
+
throw new CliError(`curation queue blockers file does not exist: ${blockersPath}`, {
|
|
199
|
+
code: 'CURATION_QUEUE_BLOCKERS_NOT_FOUND',
|
|
200
|
+
exitCode: 2,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
queueDir: path.resolve(queueDir),
|
|
205
|
+
tasks: readJsonlFile(tasksPath).map((value, index) => parseQueueTask(value, tasksPath, index)),
|
|
206
|
+
blockers: readJsonlFile(blockersPath).map((value, index) => parseQueueBlocker(value, blockersPath, index)),
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function normalizeQueueScope(options) {
|
|
210
|
+
return {
|
|
211
|
+
entity_type: options.entityType ?? null,
|
|
212
|
+
task_id: options.taskId?.trim() || null,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function buildTaskStates(tasks) {
|
|
216
|
+
const completeTaskIds = new Set(tasks
|
|
217
|
+
.filter((task) => isCompleteCheckpointStatus(readCheckpointStatus(task.checkpoint_file)))
|
|
218
|
+
.map((task) => task.task_id));
|
|
219
|
+
return tasks.map((task) => {
|
|
220
|
+
const checkpointStatus = readCheckpointStatus(task.checkpoint_file);
|
|
221
|
+
const incompleteDependencies = task.depends_on.filter((taskId) => !completeTaskIds.has(taskId));
|
|
222
|
+
const status = taskRuntimeStatus(checkpointStatus, incompleteDependencies);
|
|
223
|
+
return {
|
|
224
|
+
task_id: task.task_id,
|
|
225
|
+
entity_type: task.entity_type,
|
|
226
|
+
entity_id: task.entity_id,
|
|
227
|
+
version: task.version,
|
|
228
|
+
status,
|
|
229
|
+
checkpoint_status: checkpointStatus,
|
|
230
|
+
checkpoint_file: task.checkpoint_file,
|
|
231
|
+
depends_on: task.depends_on,
|
|
232
|
+
incomplete_dependencies: incompleteDependencies,
|
|
233
|
+
reason: status === 'waiting_dependencies'
|
|
234
|
+
? 'dependency checkpoints are not complete'
|
|
235
|
+
: status === 'blocked'
|
|
236
|
+
? 'checkpoint status is blocked or failed'
|
|
237
|
+
: null,
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function taskRuntimeStatus(checkpointStatus, incompleteDependencies) {
|
|
242
|
+
if (isCompleteCheckpointStatus(checkpointStatus)) {
|
|
243
|
+
return 'complete';
|
|
244
|
+
}
|
|
245
|
+
if (checkpointStatus === 'blocked' || checkpointStatus === 'failed') {
|
|
246
|
+
return 'blocked';
|
|
247
|
+
}
|
|
248
|
+
if (incompleteDependencies.length > 0) {
|
|
249
|
+
return 'waiting_dependencies';
|
|
250
|
+
}
|
|
251
|
+
return 'pending';
|
|
252
|
+
}
|
|
253
|
+
function isCompleteCheckpointStatus(status) {
|
|
254
|
+
return (status === 'passed' || status === 'complete' || status === 'completed' || status === 'waived');
|
|
255
|
+
}
|
|
256
|
+
function readCheckpointStatus(checkpointFile) {
|
|
257
|
+
const resolvedPath = path.resolve(checkpointFile);
|
|
258
|
+
if (!existsSync(resolvedPath)) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const value = JSON.parse(readFileSync(resolvedPath, 'utf8'));
|
|
263
|
+
if (!isRecord(value)) {
|
|
264
|
+
return 'blocked';
|
|
265
|
+
}
|
|
266
|
+
const status = firstNonEmpty(value.status, value.state);
|
|
267
|
+
return status ? status.toLowerCase() : 'blocked';
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return 'blocked';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function taskMatchesScope(task, scope) {
|
|
274
|
+
if (scope.entity_type && task.entity_type !== scope.entity_type) {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
if (scope.task_id && task.task_id !== scope.task_id) {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
function countTaskStates(taskStates) {
|
|
283
|
+
return {
|
|
284
|
+
total: taskStates.length,
|
|
285
|
+
complete: taskStates.filter((state) => state.status === 'complete').length,
|
|
286
|
+
pending: taskStates.filter((state) => state.status === 'pending').length,
|
|
287
|
+
waiting_dependencies: taskStates.filter((state) => state.status === 'waiting_dependencies')
|
|
288
|
+
.length,
|
|
289
|
+
blocked: taskStates.filter((state) => state.status === 'blocked').length,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function withQueueAction(task) {
|
|
293
|
+
return {
|
|
294
|
+
...task,
|
|
295
|
+
action: {
|
|
296
|
+
kind: 'entity_curation_task',
|
|
297
|
+
input_artifact: task.input_rows_file,
|
|
298
|
+
output_artifacts: [task.checkpoint_file],
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function readJsonlFile(inputPath) {
|
|
303
|
+
const text = readFileSync(inputPath, 'utf8').trim();
|
|
304
|
+
if (!text) {
|
|
305
|
+
return [];
|
|
306
|
+
}
|
|
307
|
+
return text.split(/\r?\n/u).map((line, index) => {
|
|
308
|
+
try {
|
|
309
|
+
return JSON.parse(line);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
throw new CliError(`Invalid JSONL in ${inputPath} at line ${index + 1}: ${String(error)}`, {
|
|
313
|
+
code: 'CURATION_QUEUE_JSONL_INVALID',
|
|
314
|
+
exitCode: 2,
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function parseQueueTask(value, inputPath, index) {
|
|
320
|
+
if (!isRecord(value)) {
|
|
321
|
+
throw new CliError(`Invalid queue task in ${inputPath} at line ${index + 1}.`, {
|
|
322
|
+
code: 'CURATION_QUEUE_TASK_INVALID',
|
|
323
|
+
exitCode: 2,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
const entityType = value.entity_type;
|
|
327
|
+
if (entityType !== 'support' && entityType !== 'flow' && entityType !== 'process') {
|
|
328
|
+
throw new CliError(`Invalid queue task entity_type in ${inputPath} at line ${index + 1}.`, {
|
|
329
|
+
code: 'CURATION_QUEUE_TASK_INVALID',
|
|
330
|
+
exitCode: 2,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
schema_version: 1,
|
|
335
|
+
entity_type: entityType,
|
|
336
|
+
task_id: requireString(value.task_id, inputPath, index, 'task_id'),
|
|
337
|
+
entity_id: requireString(value.entity_id, inputPath, index, 'entity_id'),
|
|
338
|
+
version: requireString(value.version, inputPath, index, 'version'),
|
|
339
|
+
lock_key: requireString(value.lock_key, inputPath, index, 'lock_key'),
|
|
340
|
+
depends_on: Array.isArray(value.depends_on)
|
|
341
|
+
? value.depends_on.filter((item) => typeof item === 'string')
|
|
342
|
+
: [],
|
|
343
|
+
input_rows_file: requireString(value.input_rows_file, inputPath, index, 'input_rows_file'),
|
|
344
|
+
work_dir: requireString(value.work_dir, inputPath, index, 'work_dir'),
|
|
345
|
+
checkpoint_file: requireString(value.checkpoint_file, inputPath, index, 'checkpoint_file'),
|
|
346
|
+
run_plan_file: requireString(value.run_plan_file, inputPath, index, 'run_plan_file'),
|
|
347
|
+
closure_file: requireString(value.closure_file, inputPath, index, 'closure_file'),
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
function parseQueueBlocker(value, inputPath, index) {
|
|
351
|
+
if (!isRecord(value)) {
|
|
352
|
+
throw new CliError(`Invalid queue blocker in ${inputPath} at line ${index + 1}.`, {
|
|
353
|
+
code: 'CURATION_QUEUE_BLOCKER_INVALID',
|
|
354
|
+
exitCode: 2,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const entityType = value.entity_type;
|
|
358
|
+
if (entityType !== 'support' && entityType !== 'flow' && entityType !== 'process') {
|
|
359
|
+
throw new CliError(`Invalid queue blocker entity_type in ${inputPath} at line ${index + 1}.`, {
|
|
360
|
+
code: 'CURATION_QUEUE_BLOCKER_INVALID',
|
|
361
|
+
exitCode: 2,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
schema_version: 1,
|
|
366
|
+
code: requireString(value.code, inputPath, index, 'code'),
|
|
367
|
+
severity: 'blocker',
|
|
368
|
+
entity_type: entityType,
|
|
369
|
+
entity_id: typeof value.entity_id === 'string' ? value.entity_id : null,
|
|
370
|
+
version: typeof value.version === 'string' ? value.version : null,
|
|
371
|
+
message: requireString(value.message, inputPath, index, 'message'),
|
|
372
|
+
details: value.details,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function requireString(value, inputPath, index, field) {
|
|
376
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
377
|
+
return value;
|
|
378
|
+
}
|
|
379
|
+
throw new CliError(`Invalid or missing ${field} in ${inputPath} at line ${index + 1}.`, {
|
|
380
|
+
code: 'CURATION_QUEUE_TASK_INVALID',
|
|
381
|
+
exitCode: 2,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
137
384
|
function readQueueRows(inputPath, entityType) {
|
|
138
385
|
const rows = materializeDatasetRows(inputPath);
|
|
139
386
|
return rows.map((row) => queueRowFromDatasetRow(inputPath, entityType, row));
|
|
@@ -222,9 +469,11 @@ function buildDependencyClosure(options) {
|
|
|
222
469
|
return {
|
|
223
470
|
local_tasks: [],
|
|
224
471
|
external_refs: [],
|
|
472
|
+
deferred_refs: [],
|
|
225
473
|
unresolved_refs: [],
|
|
226
474
|
};
|
|
227
475
|
}
|
|
476
|
+
const deferredRefKeys = deferredProcessFlowRefKeys(options.deferredFlowRefs);
|
|
228
477
|
return {
|
|
229
478
|
local_tasks: options.flowRefs
|
|
230
479
|
.map((ref) => ({ ref, row: options.flowRowsById.get(ref.id) }))
|
|
@@ -244,8 +493,25 @@ function buildDependencyClosure(options) {
|
|
|
244
493
|
version: ref.version,
|
|
245
494
|
ref_path: ref.path,
|
|
246
495
|
})),
|
|
496
|
+
deferred_refs: options.flowRefs
|
|
497
|
+
.filter((ref) => !options.flowRowsById.has(ref.id) &&
|
|
498
|
+
!options.externalFlowIds.has(ref.id) &&
|
|
499
|
+
deferredRefKeys.has(flowRefKey(ref)))
|
|
500
|
+
.map((ref) => {
|
|
501
|
+
const deferredRef = deferredRefKeys.get(flowRefKey(ref));
|
|
502
|
+
return {
|
|
503
|
+
entity_type: 'flow',
|
|
504
|
+
entity_id: ref.id,
|
|
505
|
+
version: ref.version,
|
|
506
|
+
ref_path: ref.path,
|
|
507
|
+
action_item_code: deferredRef.actionItemCode,
|
|
508
|
+
reason: deferredRef.reason ?? null,
|
|
509
|
+
};
|
|
510
|
+
}),
|
|
247
511
|
unresolved_refs: options.flowRefs
|
|
248
|
-
.filter((ref) => !options.flowRowsById.has(ref.id) &&
|
|
512
|
+
.filter((ref) => !options.flowRowsById.has(ref.id) &&
|
|
513
|
+
!options.externalFlowIds.has(ref.id) &&
|
|
514
|
+
!deferredRefKeys.has(flowRefKey(ref)))
|
|
249
515
|
.map((ref) => ({
|
|
250
516
|
entity_type: 'flow',
|
|
251
517
|
entity_id: ref.id,
|
|
@@ -289,12 +555,76 @@ function buildRunPlan(task) {
|
|
|
289
555
|
},
|
|
290
556
|
};
|
|
291
557
|
}
|
|
558
|
+
function extractDeferredProcessFlowRefs(payload) {
|
|
559
|
+
const refs = new Map();
|
|
560
|
+
scanForDeferredProcessFlowRefs(payload, refs);
|
|
561
|
+
return [...refs.values()].sort((a, b) => `${a.id}@${a.version ?? ''}@${a.path}`.localeCompare(`${b.id}@${b.version ?? ''}@${b.path}`));
|
|
562
|
+
}
|
|
563
|
+
function scanForDeferredProcessFlowRefs(value, refs) {
|
|
564
|
+
if (Array.isArray(value)) {
|
|
565
|
+
value.forEach((item) => scanForDeferredProcessFlowRefs(item, refs));
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (!isRecord(value)) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
const traces = asList(value['tiangongfoundry:unresolvedTrace']);
|
|
572
|
+
for (const trace of traces) {
|
|
573
|
+
if (!isRecord(trace)) {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
const actionItemCode = firstNonEmpty(trace.action_item_code, trace.actionItemCode);
|
|
577
|
+
if (actionItemCode !== 'elementary_flow_identity_manual_review') {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
const id = firstNonEmpty(trace.reference_id, trace.referenceId, trace.ref_object_id);
|
|
581
|
+
const pathValue = firstNonEmpty(trace.blocked_path, trace.blockedPath, trace.path);
|
|
582
|
+
if (!id || !pathValue) {
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
const version = firstNonEmpty(trace.reference_version, trace.referenceVersion, trace.version);
|
|
586
|
+
const ref = {
|
|
587
|
+
id,
|
|
588
|
+
version,
|
|
589
|
+
path: normalizeReferencePath(pathValue),
|
|
590
|
+
actionItemCode,
|
|
591
|
+
reason: firstNonEmpty(trace.reason),
|
|
592
|
+
};
|
|
593
|
+
refs.set(flowRefKey(ref), ref);
|
|
594
|
+
}
|
|
595
|
+
for (const nested of Object.values(value)) {
|
|
596
|
+
scanForDeferredProcessFlowRefs(nested, refs);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function deferredProcessFlowRefKeys(refs) {
|
|
600
|
+
const keys = new Map();
|
|
601
|
+
for (const ref of refs) {
|
|
602
|
+
keys.set(flowRefKey(ref), ref);
|
|
603
|
+
}
|
|
604
|
+
return keys;
|
|
605
|
+
}
|
|
606
|
+
function flowRefKey(ref) {
|
|
607
|
+
return `${ref.id}@${ref.version ?? ''}@${normalizeReferencePath(ref.path)}`;
|
|
608
|
+
}
|
|
609
|
+
function normalizeReferencePath(value) {
|
|
610
|
+
return value
|
|
611
|
+
.replace(/^\/+/u, '')
|
|
612
|
+
.replace(/\/+/gu, '.')
|
|
613
|
+
.replace(/^\.+|\.+$/gu, '');
|
|
614
|
+
}
|
|
615
|
+
function isFoundryTracePathParts(pathParts) {
|
|
616
|
+
return (pathParts.includes('common:other') &&
|
|
617
|
+
pathParts.some((part) => part.startsWith('tiangongfoundry:') && part.toLowerCase().includes('trace')));
|
|
618
|
+
}
|
|
292
619
|
function extractProcessFlowRefs(payload) {
|
|
293
620
|
const refs = new Map();
|
|
294
621
|
scanForFlowRefs(payload, [], refs);
|
|
295
622
|
return [...refs.values()].sort((a, b) => `${a.id}@${a.version ?? ''}`.localeCompare(`${b.id}@${b.version ?? ''}`));
|
|
296
623
|
}
|
|
297
624
|
function scanForFlowRefs(value, pathParts, refs) {
|
|
625
|
+
if (isFoundryTracePathParts(pathParts)) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
298
628
|
if (Array.isArray(value)) {
|
|
299
629
|
value.forEach((item, index) => scanForFlowRefs(item, [...pathParts, String(index)], refs));
|
|
300
630
|
return;
|
|
@@ -340,6 +670,12 @@ function readExternalFlowRefs(inputPath) {
|
|
|
340
670
|
};
|
|
341
671
|
});
|
|
342
672
|
}
|
|
673
|
+
function asList(value) {
|
|
674
|
+
if (value === undefined || value === null) {
|
|
675
|
+
return [];
|
|
676
|
+
}
|
|
677
|
+
return Array.isArray(value) ? value : [value];
|
|
678
|
+
}
|
|
343
679
|
function normalizeProcessLimit(value) {
|
|
344
680
|
if (value === undefined) {
|
|
345
681
|
return null;
|
|
@@ -406,6 +742,27 @@ function jsonLines(rows) {
|
|
|
406
742
|
return rows.map((row) => JSON.stringify(row)).join('\n') + (rows.length > 0 ? '\n' : '');
|
|
407
743
|
}
|
|
408
744
|
export const __testInternals = {
|
|
745
|
+
buildTaskStates,
|
|
746
|
+
countTaskStates,
|
|
747
|
+
entityDirName,
|
|
748
|
+
entityDirPlural,
|
|
749
|
+
extractDeferredProcessFlowRefs,
|
|
409
750
|
extractProcessFlowRefs,
|
|
751
|
+
jsonLines,
|
|
752
|
+
normalizeReferencePath,
|
|
753
|
+
normalizeProcessLimit,
|
|
754
|
+
normalizeQueueScope,
|
|
755
|
+
parseQueueBlocker,
|
|
756
|
+
parseQueueTask,
|
|
757
|
+
readCheckpointStatus,
|
|
758
|
+
readJsonlFile,
|
|
759
|
+
readQueueRuntime,
|
|
760
|
+
requireExistingPath,
|
|
761
|
+
requirePath,
|
|
762
|
+
sanitizePathToken,
|
|
763
|
+
taskIdFor,
|
|
764
|
+
taskMatchesScope,
|
|
765
|
+
taskRuntimeStatus,
|
|
766
|
+
withQueueAction,
|
|
410
767
|
};
|
|
411
768
|
//# sourceMappingURL=dataset-curation-queue.js.map
|