@tiangong-lca/cli 0.0.6 → 0.0.7

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.
Files changed (58) hide show
  1. package/README.md +73 -30
  2. package/dist/src/cli.js +912 -113
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-local.js +231 -0
  5. package/dist/src/lib/dataset-local.js.map +1 -0
  6. package/dist/src/lib/dataset-references-rewrite.js +214 -0
  7. package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
  8. package/dist/src/lib/dataset-validate.js +191 -0
  9. package/dist/src/lib/dataset-validate.js.map +1 -0
  10. package/dist/src/lib/flow-regen-product.js +2 -10
  11. package/dist/src/lib/flow-regen-product.js.map +1 -1
  12. package/dist/src/lib/flow-remediate.js +4 -8
  13. package/dist/src/lib/flow-remediate.js.map +1 -1
  14. package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
  15. package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
  16. package/dist/src/lib/lifecyclemodel-graph.js +248 -0
  17. package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
  18. package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
  19. package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
  20. package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
  21. package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
  22. package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
  23. package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
  24. package/dist/src/lib/process-auto-build.js +11 -8
  25. package/dist/src/lib/process-auto-build.js.map +1 -1
  26. package/dist/src/lib/process-batch-build.js +6 -3
  27. package/dist/src/lib/process-batch-build.js.map +1 -1
  28. package/dist/src/lib/process-dedup-review.js +870 -0
  29. package/dist/src/lib/process-dedup-review.js.map +1 -0
  30. package/dist/src/lib/process-payload-validation.js +50 -0
  31. package/dist/src/lib/process-payload-validation.js.map +1 -0
  32. package/dist/src/lib/process-publish-build.js +4 -6
  33. package/dist/src/lib/process-publish-build.js.map +1 -1
  34. package/dist/src/lib/process-refresh-references.js +1028 -0
  35. package/dist/src/lib/process-refresh-references.js.map +1 -0
  36. package/dist/src/lib/process-resume-build.js +4 -6
  37. package/dist/src/lib/process-resume-build.js.map +1 -1
  38. package/dist/src/lib/process-save-draft-run.js +31 -12
  39. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  40. package/dist/src/lib/process-scope-statistics.js +859 -0
  41. package/dist/src/lib/process-scope-statistics.js.map +1 -0
  42. package/dist/src/lib/process-verify-rows.js +250 -0
  43. package/dist/src/lib/process-verify-rows.js.map +1 -0
  44. package/dist/src/lib/publish.js +1 -1
  45. package/dist/src/lib/publish.js.map +1 -1
  46. package/dist/src/lib/remote.js +4 -4
  47. package/dist/src/lib/remote.js.map +1 -1
  48. package/dist/src/lib/review-lifecyclemodel.js +2 -2
  49. package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
  50. package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
  51. package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
  52. package/dist/src/lib/tidas-sdk-validation.js +96 -0
  53. package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
  54. package/dist/src/lib/user-api-key.js +1 -1
  55. package/dist/src/lib/user-api-key.js.map +1 -1
  56. package/package.json +4 -4
  57. /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
  58. /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
@@ -0,0 +1,231 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { CliError } from './errors.js';
4
+ import { readJsonInput } from './io.js';
5
+ export function isRecord(value) {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ }
8
+ export function cloneJson(value) {
9
+ return JSON.parse(JSON.stringify(value));
10
+ }
11
+ export function trimToken(value) {
12
+ if (typeof value !== 'string') {
13
+ return null;
14
+ }
15
+ const trimmed = value.trim();
16
+ return trimmed || null;
17
+ }
18
+ export function firstNonEmpty(...values) {
19
+ for (const value of values) {
20
+ const token = trimToken(value);
21
+ if (token) {
22
+ return token;
23
+ }
24
+ }
25
+ return null;
26
+ }
27
+ function readJsonLinesInput(inputPath) {
28
+ const resolved = path.resolve(inputPath);
29
+ if (!existsSync(resolved)) {
30
+ throw new CliError(`Input file not found: ${resolved}`, {
31
+ code: 'INPUT_NOT_FOUND',
32
+ exitCode: 2,
33
+ });
34
+ }
35
+ return readFileSync(resolved, 'utf8')
36
+ .split(/\r?\n/u)
37
+ .map((line) => line.trim())
38
+ .filter(Boolean)
39
+ .map((line, index) => {
40
+ let parsed;
41
+ try {
42
+ parsed = JSON.parse(line);
43
+ }
44
+ catch (error) {
45
+ throw new CliError(`Input file contains invalid JSONL at line ${index + 1}: ${resolved}`, {
46
+ code: 'INPUT_INVALID_JSONL',
47
+ exitCode: 2,
48
+ details: String(error),
49
+ });
50
+ }
51
+ if (!isRecord(parsed)) {
52
+ throw new CliError(`Expected JSON object rows in JSONL input: ${resolved} (line ${index + 1})`, {
53
+ code: 'INPUT_INVALID_JSONL_ROW',
54
+ exitCode: 2,
55
+ });
56
+ }
57
+ return parsed;
58
+ });
59
+ }
60
+ function normalizeStructuredRows(value, inputPath) {
61
+ const rows = isRecord(value) && Array.isArray(value.rows) ? value.rows : value;
62
+ const normalizedRows = Array.isArray(rows) ? rows : [rows];
63
+ return normalizedRows.map((row, index) => {
64
+ if (!isRecord(row)) {
65
+ throw new CliError(`Expected JSON object rows in dataset input: ${inputPath} (index ${index})`, {
66
+ code: 'DATASET_INPUT_INVALID_ROW',
67
+ exitCode: 2,
68
+ });
69
+ }
70
+ return row;
71
+ });
72
+ }
73
+ export function readDatasetRowsInput(inputPath, rawInput) {
74
+ if (!inputPath) {
75
+ throw new CliError('Missing required --input value.', {
76
+ code: 'DATASET_INPUT_REQUIRED',
77
+ exitCode: 2,
78
+ });
79
+ }
80
+ if (rawInput !== undefined) {
81
+ return normalizeStructuredRows(rawInput, inputPath);
82
+ }
83
+ const resolved = path.resolve(inputPath);
84
+ return resolved.toLowerCase().endsWith('.jsonl')
85
+ ? readJsonLinesInput(resolved)
86
+ : normalizeStructuredRows(readJsonInput(resolved), resolved);
87
+ }
88
+ export function datasetRoot(payload, kind) {
89
+ if (kind === 'flow') {
90
+ return isRecord(payload.flowDataSet) ? payload.flowDataSet : payload;
91
+ }
92
+ if (kind === 'process') {
93
+ return isRecord(payload.processDataSet) ? payload.processDataSet : payload;
94
+ }
95
+ return isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;
96
+ }
97
+ export function detectDatasetKind(value) {
98
+ const payload = unwrapDatasetPayload(value);
99
+ if (isRecord(payload.flowDataSet)) {
100
+ return 'flow';
101
+ }
102
+ if (isRecord(payload.processDataSet)) {
103
+ return 'process';
104
+ }
105
+ if (isRecord(payload.lifeCycleModelDataSet)) {
106
+ return 'lifecyclemodel';
107
+ }
108
+ if (isRecord(value.flow)) {
109
+ return 'flow';
110
+ }
111
+ if (isRecord(value.process)) {
112
+ return 'process';
113
+ }
114
+ if (isRecord(value.lifecyclemodel)) {
115
+ return 'lifecyclemodel';
116
+ }
117
+ return null;
118
+ }
119
+ export function unwrapDatasetPayload(row) {
120
+ for (const key of ['json_ordered', 'jsonOrdered', 'json', 'payload']) {
121
+ if (isRecord(row[key])) {
122
+ return row[key];
123
+ }
124
+ }
125
+ if (isRecord(row.flow)) {
126
+ return row.flow;
127
+ }
128
+ if (isRecord(row.process)) {
129
+ return row.process;
130
+ }
131
+ if (isRecord(row.lifecyclemodel)) {
132
+ return row.lifecyclemodel;
133
+ }
134
+ return row;
135
+ }
136
+ function flowIdentity(payload) {
137
+ const root = datasetRoot(payload, 'flow');
138
+ const information = isRecord(root.flowInformation) ? root.flowInformation : {};
139
+ const dataSetInformation = isRecord(information.dataSetInformation)
140
+ ? information.dataSetInformation
141
+ : {};
142
+ const administrativeInformation = isRecord(root.administrativeInformation)
143
+ ? root.administrativeInformation
144
+ : {};
145
+ const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
146
+ ? administrativeInformation.publicationAndOwnership
147
+ : {};
148
+ return {
149
+ id: firstNonEmpty(dataSetInformation['common:UUID']),
150
+ version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
151
+ };
152
+ }
153
+ function processIdentity(payload) {
154
+ const root = datasetRoot(payload, 'process');
155
+ const information = isRecord(root.processInformation) ? root.processInformation : {};
156
+ const dataSetInformation = isRecord(information.dataSetInformation)
157
+ ? information.dataSetInformation
158
+ : {};
159
+ const administrativeInformation = isRecord(root.administrativeInformation)
160
+ ? root.administrativeInformation
161
+ : {};
162
+ const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
163
+ ? administrativeInformation.publicationAndOwnership
164
+ : {};
165
+ return {
166
+ id: firstNonEmpty(dataSetInformation['common:UUID']),
167
+ version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
168
+ };
169
+ }
170
+ function lifecyclemodelIdentity(payload) {
171
+ const root = datasetRoot(payload, 'lifecyclemodel');
172
+ const information = isRecord(root.lifeCycleModelInformation)
173
+ ? root.lifeCycleModelInformation
174
+ : {};
175
+ const dataSetInformation = isRecord(information.dataSetInformation)
176
+ ? information.dataSetInformation
177
+ : {};
178
+ const administrativeInformation = isRecord(root.administrativeInformation)
179
+ ? root.administrativeInformation
180
+ : {};
181
+ const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
182
+ ? administrativeInformation.publicationAndOwnership
183
+ : {};
184
+ return {
185
+ id: firstNonEmpty(dataSetInformation['common:UUID']),
186
+ version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
187
+ };
188
+ }
189
+ export function datasetIdentity(row, payload, kind) {
190
+ if (kind === 'flow') {
191
+ const identity = flowIdentity(payload);
192
+ return {
193
+ id: firstNonEmpty(row.id, identity.id),
194
+ version: firstNonEmpty(row.version, identity.version),
195
+ };
196
+ }
197
+ if (kind === 'process') {
198
+ const identity = processIdentity(payload);
199
+ return {
200
+ id: firstNonEmpty(row.id, identity.id),
201
+ version: firstNonEmpty(row.version, identity.version),
202
+ };
203
+ }
204
+ if (kind === 'lifecyclemodel') {
205
+ const identity = lifecyclemodelIdentity(payload);
206
+ return {
207
+ id: firstNonEmpty(row.id, identity.id),
208
+ version: firstNonEmpty(row.version, identity.version),
209
+ };
210
+ }
211
+ return {
212
+ id: firstNonEmpty(row.id),
213
+ version: firstNonEmpty(row.version),
214
+ };
215
+ }
216
+ export function materializeDatasetRows(inputPath, rawInput) {
217
+ return readDatasetRowsInput(inputPath, rawInput).map((row, index) => {
218
+ const payload = unwrapDatasetPayload(row);
219
+ const kind = detectDatasetKind(row);
220
+ const identity = datasetIdentity(row, payload, kind);
221
+ return {
222
+ index,
223
+ row,
224
+ payload,
225
+ kind,
226
+ id: identity.id,
227
+ version: identity.version,
228
+ };
229
+ });
230
+ }
231
+ //# sourceMappingURL=dataset-local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-local.js","sourceRoot":"","sources":["../../../src/lib/dataset-local.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport { readJsonInput } from './io.js';\n\nexport type JsonObject = Record<string, unknown>;\n\nexport type DatasetKind = 'flow' | 'process' | 'lifecyclemodel';\n\nexport type DatasetRowInput = {\n index: number;\n row: JsonObject;\n payload: JsonObject;\n kind: DatasetKind | null;\n id: string | null;\n version: string | null;\n};\n\nexport function isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function trimToken(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nexport function firstNonEmpty(...values: unknown[]): string | null {\n for (const value of values) {\n const token = trimToken(value);\n if (token) {\n return token;\n }\n }\n return null;\n}\n\nfunction readJsonLinesInput(inputPath: string): JsonObject[] {\n const resolved = path.resolve(inputPath);\n if (!existsSync(resolved)) {\n throw new CliError(`Input file not found: ${resolved}`, {\n code: 'INPUT_NOT_FOUND',\n exitCode: 2,\n });\n }\n\n return readFileSync(resolved, 'utf8')\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line, index) => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch (error) {\n throw new CliError(`Input file contains invalid JSONL at line ${index + 1}: ${resolved}`, {\n code: 'INPUT_INVALID_JSONL',\n exitCode: 2,\n details: String(error),\n });\n }\n if (!isRecord(parsed)) {\n throw new CliError(\n `Expected JSON object rows in JSONL input: ${resolved} (line ${index + 1})`,\n {\n code: 'INPUT_INVALID_JSONL_ROW',\n exitCode: 2,\n },\n );\n }\n return parsed;\n });\n}\n\nfunction normalizeStructuredRows(value: unknown, inputPath: string): JsonObject[] {\n const rows = isRecord(value) && Array.isArray(value.rows) ? value.rows : value;\n const normalizedRows = Array.isArray(rows) ? rows : [rows];\n return normalizedRows.map((row, index) => {\n if (!isRecord(row)) {\n throw new CliError(\n `Expected JSON object rows in dataset input: ${inputPath} (index ${index})`,\n {\n code: 'DATASET_INPUT_INVALID_ROW',\n exitCode: 2,\n },\n );\n }\n return row;\n });\n}\n\nexport function readDatasetRowsInput(inputPath: string, rawInput?: unknown): JsonObject[] {\n if (!inputPath) {\n throw new CliError('Missing required --input value.', {\n code: 'DATASET_INPUT_REQUIRED',\n exitCode: 2,\n });\n }\n\n if (rawInput !== undefined) {\n return normalizeStructuredRows(rawInput, inputPath);\n }\n\n const resolved = path.resolve(inputPath);\n return resolved.toLowerCase().endsWith('.jsonl')\n ? readJsonLinesInput(resolved)\n : normalizeStructuredRows(readJsonInput(resolved), resolved);\n}\n\nexport function datasetRoot(payload: JsonObject, kind: DatasetKind): JsonObject {\n if (kind === 'flow') {\n return isRecord(payload.flowDataSet) ? payload.flowDataSet : payload;\n }\n if (kind === 'process') {\n return isRecord(payload.processDataSet) ? payload.processDataSet : payload;\n }\n return isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;\n}\n\nexport function detectDatasetKind(value: JsonObject): DatasetKind | null {\n const payload = unwrapDatasetPayload(value);\n if (isRecord(payload.flowDataSet)) {\n return 'flow';\n }\n if (isRecord(payload.processDataSet)) {\n return 'process';\n }\n if (isRecord(payload.lifeCycleModelDataSet)) {\n return 'lifecyclemodel';\n }\n if (isRecord(value.flow)) {\n return 'flow';\n }\n if (isRecord(value.process)) {\n return 'process';\n }\n if (isRecord(value.lifecyclemodel)) {\n return 'lifecyclemodel';\n }\n return null;\n}\n\nexport function unwrapDatasetPayload(row: JsonObject): JsonObject {\n for (const key of ['json_ordered', 'jsonOrdered', 'json', 'payload'] as const) {\n if (isRecord(row[key])) {\n return row[key];\n }\n }\n if (isRecord(row.flow)) {\n return row.flow;\n }\n if (isRecord(row.process)) {\n return row.process;\n }\n if (isRecord(row.lifecyclemodel)) {\n return row.lifecyclemodel;\n }\n return row;\n}\n\nfunction flowIdentity(payload: JsonObject): { id: string | null; version: string | null } {\n const root = datasetRoot(payload, 'flow');\n const information = isRecord(root.flowInformation) ? root.flowInformation : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nfunction processIdentity(payload: JsonObject): { id: string | null; version: string | null } {\n const root = datasetRoot(payload, 'process');\n const information = isRecord(root.processInformation) ? root.processInformation : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nfunction lifecyclemodelIdentity(payload: JsonObject): {\n id: string | null;\n version: string | null;\n} {\n const root = datasetRoot(payload, 'lifecyclemodel');\n const information = isRecord(root.lifeCycleModelInformation)\n ? root.lifeCycleModelInformation\n : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nexport function datasetIdentity(\n row: JsonObject,\n payload: JsonObject,\n kind: DatasetKind | null,\n): { id: string | null; version: string | null } {\n if (kind === 'flow') {\n const identity = flowIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n if (kind === 'process') {\n const identity = processIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n if (kind === 'lifecyclemodel') {\n const identity = lifecyclemodelIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n return {\n id: firstNonEmpty(row.id),\n version: firstNonEmpty(row.version),\n };\n}\n\nexport function materializeDatasetRows(inputPath: string, rawInput?: unknown): DatasetRowInput[] {\n return readDatasetRowsInput(inputPath, rawInput).map((row, index) => {\n const payload = unwrapDatasetPayload(row);\n const kind = detectDatasetKind(row);\n const identity = datasetIdentity(row, payload, kind);\n return {\n index,\n row,\n payload,\n kind,\n id: identity.id,\n version: identity.version,\n };\n });\n}\n"]}
@@ -0,0 +1,214 @@
1
+ import path from 'node:path';
2
+ import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
3
+ import { CliError } from './errors.js';
4
+ import { cloneJson, firstNonEmpty, isRecord, materializeDatasetRows, unwrapDatasetPayload, } from './dataset-local.js';
5
+ import { runLifecyclemodelSaveDraft, } from './lifecyclemodel-save-draft-run.js';
6
+ import { runProcessSaveDraft } from './process-save-draft-run.js';
7
+ function parseReference(value, label) {
8
+ const match = /^(flow):([^@\s]+)(?:@([^@\s]+))?$/u.exec(value.trim());
9
+ if (!match) {
10
+ throw new CliError(`Expected ${label} reference like flow:<id>@<version>.`, {
11
+ code: 'DATASET_REFERENCE_INVALID',
12
+ exitCode: 2,
13
+ details: value,
14
+ });
15
+ }
16
+ return {
17
+ kind: 'flow',
18
+ id: match[2],
19
+ version: match[3] ?? null,
20
+ };
21
+ }
22
+ function normalizeTypes(values) {
23
+ const raw = values && values.length > 0 ? values.flatMap((value) => value.split(',')) : [];
24
+ const normalized = raw
25
+ .map((value) => value.trim().toLowerCase())
26
+ .filter(Boolean)
27
+ .map((value) => {
28
+ if (value === 'process' || value === 'processes') {
29
+ return 'process';
30
+ }
31
+ if (value === 'lifecyclemodel' ||
32
+ value === 'lifecyclemodels' ||
33
+ value === 'model' ||
34
+ value === 'models') {
35
+ return 'lifecyclemodel';
36
+ }
37
+ throw new CliError('Expected --type or --types to contain process and/or lifecyclemodel.', {
38
+ code: 'DATASET_REFERENCE_TYPES_INVALID',
39
+ exitCode: 2,
40
+ details: value,
41
+ });
42
+ });
43
+ return normalized.length > 0 ? [...new Set(normalized)] : ['process', 'lifecyclemodel'];
44
+ }
45
+ function joinPath(base, key) {
46
+ return base ? `${base}.${String(key)}` : String(key);
47
+ }
48
+ function rewriteProcessReferences(value, from, to, pathPrefix, change) {
49
+ if (Array.isArray(value)) {
50
+ value.forEach((item, index) => rewriteProcessReferences(item, from, to, joinPath(pathPrefix, index), change));
51
+ return;
52
+ }
53
+ if (!isRecord(value)) {
54
+ return;
55
+ }
56
+ const reference = value.referenceToFlowDataSet;
57
+ if (isRecord(reference) && reference['@refObjectId'] === from.id) {
58
+ const versionMatches = !from.version || reference['@version'] === from.version;
59
+ if (versionMatches) {
60
+ if (reference['@refObjectId'] !== to.id) {
61
+ change(joinPath(pathPrefix, 'referenceToFlowDataSet.@refObjectId'), '@refObjectId', reference['@refObjectId'], to.id);
62
+ reference['@refObjectId'] = to.id;
63
+ }
64
+ if (to.version && reference['@version'] !== to.version) {
65
+ change(joinPath(pathPrefix, 'referenceToFlowDataSet.@version'), '@version', typeof reference['@version'] === 'string' ? reference['@version'] : null, to.version);
66
+ reference['@version'] = to.version;
67
+ }
68
+ }
69
+ }
70
+ Object.entries(value).forEach(([key, child]) => rewriteProcessReferences(child, from, to, joinPath(pathPrefix, key), change));
71
+ }
72
+ function rewriteLifecyclemodelReferences(value, from, to, pathPrefix, change) {
73
+ if (Array.isArray(value)) {
74
+ value.forEach((item, index) => rewriteLifecyclemodelReferences(item, from, to, joinPath(pathPrefix, index), change));
75
+ return;
76
+ }
77
+ if (!isRecord(value)) {
78
+ return;
79
+ }
80
+ if (value['@flowUUID'] === from.id && value['@flowUUID'] !== to.id) {
81
+ change(joinPath(pathPrefix, '@flowUUID'), '@flowUUID', value['@flowUUID'], to.id);
82
+ value['@flowUUID'] = to.id;
83
+ }
84
+ Object.entries(value).forEach(([key, child]) => rewriteLifecyclemodelReferences(child, from, to, joinPath(pathPrefix, key), change));
85
+ }
86
+ function buildFiles(outDir) {
87
+ return {
88
+ patched_rows: path.join(outDir, 'outputs', 'patched-rows.jsonl'),
89
+ rewrite_plan: path.join(outDir, 'outputs', 'rewrite-plan.json'),
90
+ summary: path.join(outDir, 'outputs', 'summary.json'),
91
+ };
92
+ }
93
+ export async function runDatasetReferencesRewrite(options) {
94
+ if (!options.outDir) {
95
+ throw new CliError('Missing required --out-dir value.', {
96
+ code: 'DATASET_REFERENCES_REWRITE_OUT_DIR_REQUIRED',
97
+ exitCode: 2,
98
+ });
99
+ }
100
+ const from = parseReference(options.from, '--from');
101
+ const to = parseReference(options.to, '--to');
102
+ const types = normalizeTypes(options.types);
103
+ const rows = materializeDatasetRows(options.inputPath, options.rawInput);
104
+ const outDir = path.resolve(options.outDir);
105
+ const files = buildFiles(outDir);
106
+ const changes = [];
107
+ const patchedRows = [];
108
+ const processRows = [];
109
+ const lifecyclemodelRows = [];
110
+ rows.forEach((row) => {
111
+ const patched = cloneJson(row.row);
112
+ if (row.kind && types.includes(row.kind)) {
113
+ const payload = unwrapDatasetPayload(patched);
114
+ const addChange = (pathValue, field, before, after) => {
115
+ changes.push({
116
+ row_index: row.index,
117
+ dataset_type: row.kind,
118
+ dataset_id: row.id,
119
+ dataset_version: row.version,
120
+ path: pathValue,
121
+ field,
122
+ before,
123
+ after,
124
+ });
125
+ };
126
+ const beforeCount = changes.length;
127
+ if (row.kind === 'process') {
128
+ rewriteProcessReferences(payload, from, to, '', addChange);
129
+ }
130
+ else if (row.kind === 'lifecyclemodel') {
131
+ rewriteLifecyclemodelReferences(payload, from, to, '', addChange);
132
+ }
133
+ if (changes.length > beforeCount) {
134
+ if (row.kind === 'process') {
135
+ processRows.push(patched);
136
+ }
137
+ else if (row.kind === 'lifecyclemodel') {
138
+ lifecyclemodelRows.push(patched);
139
+ }
140
+ }
141
+ }
142
+ patchedRows.push(patched);
143
+ });
144
+ writeJsonLinesArtifact(files.patched_rows, patchedRows);
145
+ writeJsonArtifact(files.rewrite_plan, {
146
+ from,
147
+ to,
148
+ filters: {
149
+ types,
150
+ scope: firstNonEmpty(options.scope),
151
+ },
152
+ changes,
153
+ });
154
+ const commit = options.commit === true;
155
+ const processSaveDraftImpl = options.runProcessSaveDraftImpl ?? runProcessSaveDraft;
156
+ const lifecyclemodelSaveDraftImpl = options.runLifecyclemodelSaveDraftImpl ?? runLifecyclemodelSaveDraft;
157
+ const processReport = commit && processRows.length > 0
158
+ ? await processSaveDraftImpl({
159
+ inputPath: files.patched_rows,
160
+ rawInput: processRows,
161
+ outDir: path.join(outDir, 'process-save-draft'),
162
+ commit: true,
163
+ env: options.env,
164
+ fetchImpl: options.fetchImpl,
165
+ })
166
+ : null;
167
+ const lifecyclemodelReport = commit && lifecyclemodelRows.length > 0
168
+ ? await lifecyclemodelSaveDraftImpl({
169
+ inputPath: files.patched_rows,
170
+ rawInput: lifecyclemodelRows,
171
+ outDir: path.join(outDir, 'lifecyclemodel-save-draft'),
172
+ commit: true,
173
+ env: options.env,
174
+ fetchImpl: options.fetchImpl,
175
+ })
176
+ : null;
177
+ const commitFailed = processReport?.status === 'completed_with_failures' ||
178
+ lifecyclemodelReport?.status === 'completed_with_failures';
179
+ const report = {
180
+ generated_at_utc: (options.now ?? new Date()).toISOString(),
181
+ input_path: path.resolve(options.inputPath),
182
+ out_dir: outDir,
183
+ mode: commit ? 'commit' : 'dry_run',
184
+ status: commitFailed ? 'completed_with_failures' : 'completed',
185
+ from,
186
+ to,
187
+ filters: {
188
+ types,
189
+ scope: firstNonEmpty(options.scope),
190
+ },
191
+ counts: {
192
+ input_rows: rows.length,
193
+ patched_rows: processRows.length + lifecyclemodelRows.length,
194
+ changes: changes.length,
195
+ process_rows: processRows.length,
196
+ lifecyclemodel_rows: lifecyclemodelRows.length,
197
+ },
198
+ files,
199
+ changes,
200
+ commit_reports: {
201
+ processes: processReport,
202
+ lifecyclemodels: lifecyclemodelReport,
203
+ },
204
+ };
205
+ writeJsonArtifact(files.summary, report);
206
+ return report;
207
+ }
208
+ export const __testInternals = {
209
+ normalizeTypes,
210
+ parseReference,
211
+ rewriteLifecyclemodelReferences,
212
+ rewriteProcessReferences,
213
+ };
214
+ //# sourceMappingURL=dataset-references-rewrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-references-rewrite.js","sourceRoot":"","sources":["../../../src/lib/dataset-references-rewrite.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n cloneJson,\n firstNonEmpty,\n isRecord,\n materializeDatasetRows,\n unwrapDatasetPayload,\n type DatasetKind,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n runLifecyclemodelSaveDraft,\n type LifecyclemodelSaveDraftReport,\n} from './lifecyclemodel-save-draft-run.js';\nimport { runProcessSaveDraft, type ProcessSaveDraftReport } from './process-save-draft-run.js';\n\ntype ReferenceKind = 'flow';\n\ntype ParsedReference = {\n kind: ReferenceKind;\n id: string;\n version: string | null;\n};\n\nexport type DatasetReferencesRewriteChange = {\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n path: string;\n field: '@refObjectId' | '@version' | '@flowUUID';\n before: string | null;\n after: string | null;\n};\n\nexport type DatasetReferencesRewriteReport = {\n generated_at_utc: string;\n input_path: string;\n out_dir: string;\n mode: 'dry_run' | 'commit';\n status: 'completed' | 'completed_with_failures';\n from: ParsedReference;\n to: ParsedReference;\n filters: {\n types: DatasetKind[];\n scope: string | null;\n };\n counts: {\n input_rows: number;\n patched_rows: number;\n changes: number;\n process_rows: number;\n lifecyclemodel_rows: number;\n };\n files: {\n patched_rows: string;\n rewrite_plan: string;\n summary: string;\n };\n changes: DatasetReferencesRewriteChange[];\n commit_reports: {\n processes: ProcessSaveDraftReport | null;\n lifecyclemodels: LifecyclemodelSaveDraftReport | null;\n };\n};\n\nexport type RunDatasetReferencesRewriteOptions = {\n inputPath: string;\n outDir: string;\n from: string;\n to: string;\n types?: string[] | null;\n scope?: string | null;\n commit?: boolean | null;\n rawInput?: unknown;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n now?: Date;\n runProcessSaveDraftImpl?: typeof runProcessSaveDraft;\n runLifecyclemodelSaveDraftImpl?: typeof runLifecyclemodelSaveDraft;\n};\n\nfunction parseReference(value: string, label: string): ParsedReference {\n const match = /^(flow):([^@\\s]+)(?:@([^@\\s]+))?$/u.exec(value.trim());\n if (!match) {\n throw new CliError(`Expected ${label} reference like flow:<id>@<version>.`, {\n code: 'DATASET_REFERENCE_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return {\n kind: 'flow',\n id: match[2],\n version: match[3] ?? null,\n };\n}\n\nfunction normalizeTypes(values: string[] | null | undefined): DatasetKind[] {\n const raw = values && values.length > 0 ? values.flatMap((value) => value.split(',')) : [];\n const normalized = raw\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean)\n .map((value) => {\n if (value === 'process' || value === 'processes') {\n return 'process' as const;\n }\n if (\n value === 'lifecyclemodel' ||\n value === 'lifecyclemodels' ||\n value === 'model' ||\n value === 'models'\n ) {\n return 'lifecyclemodel' as const;\n }\n throw new CliError('Expected --type or --types to contain process and/or lifecyclemodel.', {\n code: 'DATASET_REFERENCE_TYPES_INVALID',\n exitCode: 2,\n details: value,\n });\n });\n return normalized.length > 0 ? [...new Set(normalized)] : ['process', 'lifecyclemodel'];\n}\n\nfunction joinPath(base: string, key: string | number): string {\n return base ? `${base}.${String(key)}` : String(key);\n}\n\nfunction rewriteProcessReferences(\n value: unknown,\n from: ParsedReference,\n to: ParsedReference,\n pathPrefix: string,\n change: (\n path: string,\n field: '@refObjectId' | '@version',\n before: string | null,\n after: string | null,\n ) => void,\n): void {\n if (Array.isArray(value)) {\n value.forEach((item, index) =>\n rewriteProcessReferences(item, from, to, joinPath(pathPrefix, index), change),\n );\n return;\n }\n if (!isRecord(value)) {\n return;\n }\n\n const reference = value.referenceToFlowDataSet;\n if (isRecord(reference) && reference['@refObjectId'] === from.id) {\n const versionMatches = !from.version || reference['@version'] === from.version;\n if (versionMatches) {\n if (reference['@refObjectId'] !== to.id) {\n change(\n joinPath(pathPrefix, 'referenceToFlowDataSet.@refObjectId'),\n '@refObjectId',\n reference['@refObjectId'],\n to.id,\n );\n reference['@refObjectId'] = to.id;\n }\n if (to.version && reference['@version'] !== to.version) {\n change(\n joinPath(pathPrefix, 'referenceToFlowDataSet.@version'),\n '@version',\n typeof reference['@version'] === 'string' ? reference['@version'] : null,\n to.version,\n );\n reference['@version'] = to.version;\n }\n }\n }\n\n Object.entries(value).forEach(([key, child]) =>\n rewriteProcessReferences(child, from, to, joinPath(pathPrefix, key), change),\n );\n}\n\nfunction rewriteLifecyclemodelReferences(\n value: unknown,\n from: ParsedReference,\n to: ParsedReference,\n pathPrefix: string,\n change: (path: string, field: '@flowUUID', before: string | null, after: string | null) => void,\n): void {\n if (Array.isArray(value)) {\n value.forEach((item, index) =>\n rewriteLifecyclemodelReferences(item, from, to, joinPath(pathPrefix, index), change),\n );\n return;\n }\n if (!isRecord(value)) {\n return;\n }\n\n if (value['@flowUUID'] === from.id && value['@flowUUID'] !== to.id) {\n change(joinPath(pathPrefix, '@flowUUID'), '@flowUUID', value['@flowUUID'], to.id);\n value['@flowUUID'] = to.id;\n }\n\n Object.entries(value).forEach(([key, child]) =>\n rewriteLifecyclemodelReferences(child, from, to, joinPath(pathPrefix, key), change),\n );\n}\n\nfunction buildFiles(outDir: string): DatasetReferencesRewriteReport['files'] {\n return {\n patched_rows: path.join(outDir, 'outputs', 'patched-rows.jsonl'),\n rewrite_plan: path.join(outDir, 'outputs', 'rewrite-plan.json'),\n summary: path.join(outDir, 'outputs', 'summary.json'),\n };\n}\n\nexport async function runDatasetReferencesRewrite(\n options: RunDatasetReferencesRewriteOptions,\n): Promise<DatasetReferencesRewriteReport> {\n if (!options.outDir) {\n throw new CliError('Missing required --out-dir value.', {\n code: 'DATASET_REFERENCES_REWRITE_OUT_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n\n const from = parseReference(options.from, '--from');\n const to = parseReference(options.to, '--to');\n\n const types = normalizeTypes(options.types);\n const rows = materializeDatasetRows(options.inputPath, options.rawInput);\n const outDir = path.resolve(options.outDir);\n const files = buildFiles(outDir);\n const changes: DatasetReferencesRewriteChange[] = [];\n const patchedRows: JsonObject[] = [];\n const processRows: JsonObject[] = [];\n const lifecyclemodelRows: JsonObject[] = [];\n\n rows.forEach((row) => {\n const patched = cloneJson(row.row);\n if (row.kind && types.includes(row.kind)) {\n const payload = unwrapDatasetPayload(patched);\n const addChange = (\n pathValue: string,\n field: '@refObjectId' | '@version' | '@flowUUID',\n before: string | null,\n after: string | null,\n ): void => {\n changes.push({\n row_index: row.index,\n dataset_type: row.kind,\n dataset_id: row.id,\n dataset_version: row.version,\n path: pathValue,\n field,\n before,\n after,\n });\n };\n const beforeCount = changes.length;\n if (row.kind === 'process') {\n rewriteProcessReferences(payload, from, to, '', addChange);\n } else if (row.kind === 'lifecyclemodel') {\n rewriteLifecyclemodelReferences(payload, from, to, '', addChange);\n }\n if (changes.length > beforeCount) {\n if (row.kind === 'process') {\n processRows.push(patched);\n } else if (row.kind === 'lifecyclemodel') {\n lifecyclemodelRows.push(patched);\n }\n }\n }\n patchedRows.push(patched);\n });\n\n writeJsonLinesArtifact(files.patched_rows, patchedRows);\n writeJsonArtifact(files.rewrite_plan, {\n from,\n to,\n filters: {\n types,\n scope: firstNonEmpty(options.scope),\n },\n changes,\n });\n\n const commit = options.commit === true;\n const processSaveDraftImpl = options.runProcessSaveDraftImpl ?? runProcessSaveDraft;\n const lifecyclemodelSaveDraftImpl =\n options.runLifecyclemodelSaveDraftImpl ?? runLifecyclemodelSaveDraft;\n const processReport =\n commit && processRows.length > 0\n ? await processSaveDraftImpl({\n inputPath: files.patched_rows,\n rawInput: processRows,\n outDir: path.join(outDir, 'process-save-draft'),\n commit: true,\n env: options.env,\n fetchImpl: options.fetchImpl,\n })\n : null;\n const lifecyclemodelReport =\n commit && lifecyclemodelRows.length > 0\n ? await lifecyclemodelSaveDraftImpl({\n inputPath: files.patched_rows,\n rawInput: lifecyclemodelRows,\n outDir: path.join(outDir, 'lifecyclemodel-save-draft'),\n commit: true,\n env: options.env,\n fetchImpl: options.fetchImpl,\n })\n : null;\n\n const commitFailed =\n processReport?.status === 'completed_with_failures' ||\n lifecyclemodelReport?.status === 'completed_with_failures';\n const report: DatasetReferencesRewriteReport = {\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n input_path: path.resolve(options.inputPath),\n out_dir: outDir,\n mode: commit ? 'commit' : 'dry_run',\n status: commitFailed ? 'completed_with_failures' : 'completed',\n from,\n to,\n filters: {\n types,\n scope: firstNonEmpty(options.scope),\n },\n counts: {\n input_rows: rows.length,\n patched_rows: processRows.length + lifecyclemodelRows.length,\n changes: changes.length,\n process_rows: processRows.length,\n lifecyclemodel_rows: lifecyclemodelRows.length,\n },\n files,\n changes,\n commit_reports: {\n processes: processReport,\n lifecyclemodels: lifecyclemodelReport,\n },\n };\n writeJsonArtifact(files.summary, report);\n return report;\n}\n\nexport const __testInternals = {\n normalizeTypes,\n parseReference,\n rewriteLifecyclemodelReferences,\n rewriteProcessReferences,\n};\n"]}