@tiangong-lca/cli 0.0.6 → 0.0.8

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 (90) hide show
  1. package/README.md +154 -30
  2. package/dist/src/cli.js +2235 -149
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-author.js +100 -0
  5. package/dist/src/lib/dataset-author.js.map +1 -0
  6. package/dist/src/lib/dataset-bilingual.js +545 -0
  7. package/dist/src/lib/dataset-bilingual.js.map +1 -0
  8. package/dist/src/lib/dataset-contract.js +350 -0
  9. package/dist/src/lib/dataset-contract.js.map +1 -0
  10. package/dist/src/lib/dataset-evidence-search.js +636 -0
  11. package/dist/src/lib/dataset-evidence-search.js.map +1 -0
  12. package/dist/src/lib/dataset-import-lca.js +171 -0
  13. package/dist/src/lib/dataset-import-lca.js.map +1 -0
  14. package/dist/src/lib/dataset-local.js +231 -0
  15. package/dist/src/lib/dataset-local.js.map +1 -0
  16. package/dist/src/lib/dataset-references-rewrite.js +214 -0
  17. package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
  18. package/dist/src/lib/dataset-remote-refresh.js +166 -0
  19. package/dist/src/lib/dataset-remote-refresh.js.map +1 -0
  20. package/dist/src/lib/dataset-remote-verify.js +543 -0
  21. package/dist/src/lib/dataset-remote-verify.js.map +1 -0
  22. package/dist/src/lib/dataset-validate.js +247 -0
  23. package/dist/src/lib/dataset-validate.js.map +1 -0
  24. package/dist/src/lib/flow-payload-validation.js +51 -0
  25. package/dist/src/lib/flow-payload-validation.js.map +1 -0
  26. package/dist/src/lib/flow-publish-reviewed-data.js +16 -0
  27. package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
  28. package/dist/src/lib/flow-publish-version.js +182 -12
  29. package/dist/src/lib/flow-publish-version.js.map +1 -1
  30. package/dist/src/lib/flow-regen-product.js +2 -10
  31. package/dist/src/lib/flow-regen-product.js.map +1 -1
  32. package/dist/src/lib/flow-remediate.js +4 -8
  33. package/dist/src/lib/flow-remediate.js.map +1 -1
  34. package/dist/src/lib/identity-preflight.js +1021 -0
  35. package/dist/src/lib/identity-preflight.js.map +1 -0
  36. package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
  37. package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
  38. package/dist/src/lib/lifecyclemodel-graph.js +248 -0
  39. package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
  40. package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
  41. package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
  42. package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
  43. package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
  44. package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
  45. package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
  46. package/dist/src/lib/process-auto-build.js +158 -8
  47. package/dist/src/lib/process-auto-build.js.map +1 -1
  48. package/dist/src/lib/process-batch-build.js +6 -3
  49. package/dist/src/lib/process-batch-build.js.map +1 -1
  50. package/dist/src/lib/process-dedup-review.js +921 -0
  51. package/dist/src/lib/process-dedup-review.js.map +1 -0
  52. package/dist/src/lib/process-flow-build-plan.js +1071 -0
  53. package/dist/src/lib/process-flow-build-plan.js.map +1 -0
  54. package/dist/src/lib/process-payload-validation.js +57 -0
  55. package/dist/src/lib/process-payload-validation.js.map +1 -0
  56. package/dist/src/lib/process-publish-build.js +126 -10
  57. package/dist/src/lib/process-publish-build.js.map +1 -1
  58. package/dist/src/lib/process-refresh-references.js +1037 -0
  59. package/dist/src/lib/process-refresh-references.js.map +1 -0
  60. package/dist/src/lib/process-required-fields.js +810 -0
  61. package/dist/src/lib/process-required-fields.js.map +1 -0
  62. package/dist/src/lib/process-resume-build.js +4 -6
  63. package/dist/src/lib/process-resume-build.js.map +1 -1
  64. package/dist/src/lib/process-save-draft-run.js +35 -13
  65. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  66. package/dist/src/lib/process-scope-statistics.js +859 -0
  67. package/dist/src/lib/process-scope-statistics.js.map +1 -0
  68. package/dist/src/lib/process-verify-rows.js +250 -0
  69. package/dist/src/lib/process-verify-rows.js.map +1 -0
  70. package/dist/src/lib/publish.js +101 -1
  71. package/dist/src/lib/publish.js.map +1 -1
  72. package/dist/src/lib/remote.js +4 -4
  73. package/dist/src/lib/remote.js.map +1 -1
  74. package/dist/src/lib/review-flow.js +58 -0
  75. package/dist/src/lib/review-flow.js.map +1 -1
  76. package/dist/src/lib/review-lifecyclemodel.js +2 -2
  77. package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
  78. package/dist/src/lib/review-process.js +150 -2
  79. package/dist/src/lib/review-process.js.map +1 -1
  80. package/dist/src/lib/runtime-rulesets.js +283 -0
  81. package/dist/src/lib/runtime-rulesets.js.map +1 -0
  82. package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
  83. package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
  84. package/dist/src/lib/tidas-sdk-validation.js +96 -0
  85. package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
  86. package/dist/src/lib/user-api-key.js +1 -1
  87. package/dist/src/lib/user-api-key.js.map +1 -1
  88. package/package.json +5 -5
  89. /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
  90. /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
@@ -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"]}
@@ -0,0 +1,166 @@
1
+ import path from 'node:path';
2
+ import { readFileSync } from 'node:fs';
3
+ import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
4
+ import { CliError } from './errors.js';
5
+ import { cloneJson, isRecord, readDatasetRowsInput, unwrapDatasetPayload, } from './dataset-local.js';
6
+ import { runDatasetRemoteVerify, } from './dataset-remote-verify.js';
7
+ function requireNonEmpty(value, label, code) {
8
+ const normalized = value.trim();
9
+ if (!normalized) {
10
+ throw new CliError(`Missing required ${label} value.`, {
11
+ code,
12
+ exitCode: 2,
13
+ });
14
+ }
15
+ return normalized;
16
+ }
17
+ function nowIso(now = new Date()) {
18
+ return now.toISOString();
19
+ }
20
+ function readJsonl(filePath) {
21
+ return readFileSync(filePath, 'utf8')
22
+ .split(/\r?\n/u)
23
+ .map((line) => line.trim())
24
+ .filter(Boolean)
25
+ .map((line) => JSON.parse(line))
26
+ .filter(isRecord);
27
+ }
28
+ function decodePointerSegment(segment) {
29
+ return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');
30
+ }
31
+ function pointerSegments(pointerPath) {
32
+ return pointerPath
33
+ .split('/')
34
+ .filter(Boolean)
35
+ .map((segment) => decodePointerSegment(segment));
36
+ }
37
+ function valueAtPointer(root, pointerPath) {
38
+ let current = root;
39
+ for (const segment of pointerSegments(pointerPath)) {
40
+ if (Array.isArray(current)) {
41
+ const index = Number(segment);
42
+ current = Number.isInteger(index) ? current[index] : undefined;
43
+ }
44
+ else if (isRecord(current)) {
45
+ current = current[segment];
46
+ }
47
+ else {
48
+ return undefined;
49
+ }
50
+ }
51
+ return current;
52
+ }
53
+ function referenceNodeForPatch(payload, check) {
54
+ if (check.path.endsWith('/@flowUUID')) {
55
+ const parentPath = check.path.slice(0, -'/@flowUUID'.length);
56
+ const parent = valueAtPointer(payload, parentPath);
57
+ return isRecord(parent) ? parent : null;
58
+ }
59
+ const node = valueAtPointer(payload, check.path);
60
+ return isRecord(node) ? node : null;
61
+ }
62
+ function refreshableCheck(check) {
63
+ return (check.role === 'reference' &&
64
+ Boolean(check.latest_version) &&
65
+ ['missing_version', 'version_missing', 'version_outdated'].includes(check.status));
66
+ }
67
+ function applyRemoteRefreshPatches(rows, checks) {
68
+ const patchedRows = cloneJson(rows);
69
+ const patches = [];
70
+ for (const check of checks.filter(refreshableCheck)) {
71
+ const row = patchedRows[check.row_index];
72
+ if (!row || !check.latest_version) {
73
+ continue;
74
+ }
75
+ const payload = unwrapDatasetPayload(row);
76
+ const node = referenceNodeForPatch(payload, check);
77
+ if (!node) {
78
+ continue;
79
+ }
80
+ const before = typeof node['@version'] === 'string' ? node['@version'] : null;
81
+ if (before === check.latest_version) {
82
+ continue;
83
+ }
84
+ node['@version'] = check.latest_version;
85
+ patches.push({
86
+ row_index: check.row_index,
87
+ role: check.role,
88
+ table: check.table,
89
+ id: check.id,
90
+ from_version: before,
91
+ to_version: check.latest_version,
92
+ path: check.path,
93
+ status_before: check.status,
94
+ });
95
+ }
96
+ return { rows: patchedRows, patches };
97
+ }
98
+ function buildFiles(outPath, outDir) {
99
+ const resolved = path.resolve(outDir);
100
+ return {
101
+ output_rows: path.resolve(outPath),
102
+ report: path.join(resolved, 'outputs', 'remote-refresh-report.json'),
103
+ patches: path.join(resolved, 'outputs', 'remote-refresh-patches.jsonl'),
104
+ pre_verification_report: path.join(resolved, 'pre-refresh-verify', 'outputs', 'remote-verification-report.json'),
105
+ post_verification_report: path.join(resolved, 'post-refresh-verify', 'outputs', 'remote-verification-report.json'),
106
+ };
107
+ }
108
+ export async function runDatasetRemoteRefresh(options) {
109
+ const inputPath = path.resolve(requireNonEmpty(options.inputPath, '--input', 'DATASET_REMOTE_REFRESH_INPUT_REQUIRED'));
110
+ const outPath = path.resolve(requireNonEmpty(options.outPath, '--out', 'DATASET_REMOTE_REFRESH_OUT_REQUIRED'));
111
+ const outDir = path.resolve(requireNonEmpty(options.outDir, '--out-dir', 'DATASET_REMOTE_REFRESH_OUT_DIR_REQUIRED'));
112
+ const runVerify = options.runDatasetRemoteVerifyImpl ?? runDatasetRemoteVerify;
113
+ const rows = readDatasetRowsInput(inputPath, options.rawInput);
114
+ const files = buildFiles(outPath, outDir);
115
+ const preReport = await runVerify({
116
+ inputPath,
117
+ outDir: path.join(outDir, 'pre-refresh-verify'),
118
+ rawInput: rows,
119
+ env: options.env,
120
+ fetchImpl: options.fetchImpl,
121
+ timeoutMs: options.timeoutMs,
122
+ now: options.now,
123
+ rootPolicy: options.rootPolicy,
124
+ });
125
+ const checks = readJsonl(path.join(outDir, 'pre-refresh-verify', 'outputs', 'remote-verification.jsonl'));
126
+ const { rows: patchedRows, patches } = applyRemoteRefreshPatches(rows, checks);
127
+ writeJsonLinesArtifact(outPath, patchedRows);
128
+ writeJsonLinesArtifact(files.patches, patches);
129
+ const postReport = await runVerify({
130
+ inputPath: outPath,
131
+ outDir: path.join(outDir, 'post-refresh-verify'),
132
+ rawInput: patchedRows,
133
+ env: options.env,
134
+ fetchImpl: options.fetchImpl,
135
+ timeoutMs: options.timeoutMs,
136
+ now: options.now,
137
+ rootPolicy: options.rootPolicy,
138
+ });
139
+ const report = {
140
+ schema_version: 1,
141
+ generated_at_utc: nowIso(options.now),
142
+ status: postReport.blockers.length > 0 ? 'completed_with_blockers' : 'completed',
143
+ root_policy: options.rootPolicy ?? 'existing',
144
+ input_path: inputPath,
145
+ out_path: outPath,
146
+ out_dir: outDir,
147
+ counts: {
148
+ rows: rows.length,
149
+ pre_refresh_blockers: preReport.blockers.length,
150
+ refreshable_references: checks.filter(refreshableCheck).length,
151
+ patched_references: patches.length,
152
+ post_refresh_blockers: postReport.blockers.length,
153
+ },
154
+ remaining_blockers: postReport.blockers,
155
+ files,
156
+ };
157
+ writeJsonArtifact(files.report, report);
158
+ return report;
159
+ }
160
+ export const __testInternals = {
161
+ applyRemoteRefreshPatches,
162
+ pointerSegments,
163
+ refreshableCheck,
164
+ valueAtPointer,
165
+ };
166
+ //# sourceMappingURL=dataset-remote-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-remote-refresh.js","sourceRoot":"","sources":["../../../src/lib/dataset-remote-refresh.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n cloneJson,\n isRecord,\n readDatasetRowsInput,\n unwrapDatasetPayload,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n runDatasetRemoteVerify,\n type DatasetRemoteVerificationReport,\n type RemoteVerificationCheck,\n type RunDatasetRemoteVerifyOptions,\n} from './dataset-remote-verify.js';\n\nexport type DatasetRemoteRefreshPatch = {\n row_index: number;\n role: string;\n table: string | null;\n id: string | null;\n from_version: string | null;\n to_version: string;\n path: string;\n status_before: string;\n};\n\nexport type DatasetRemoteRefreshReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed' | 'completed_with_blockers';\n root_policy: NonNullable<RunDatasetRemoteVerifyOptions['rootPolicy']>;\n input_path: string;\n out_path: string;\n out_dir: string;\n counts: {\n rows: number;\n pre_refresh_blockers: number;\n refreshable_references: number;\n patched_references: number;\n post_refresh_blockers: number;\n };\n remaining_blockers: DatasetRemoteVerificationReport['blockers'];\n files: {\n output_rows: string;\n report: string;\n patches: string;\n pre_verification_report: string;\n post_verification_report: string;\n };\n};\n\nexport type RunDatasetRemoteRefreshOptions = {\n inputPath: string;\n outPath: string;\n outDir: string;\n rawInput?: unknown;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n now?: Date;\n rootPolicy?: RunDatasetRemoteVerifyOptions['rootPolicy'];\n runDatasetRemoteVerifyImpl?: (\n options: RunDatasetRemoteVerifyOptions,\n ) => Promise<DatasetRemoteVerificationReport>;\n};\n\nfunction requireNonEmpty(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label} value.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction readJsonl(filePath: string): JsonObject[] {\n return readFileSync(filePath, 'utf8')\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => JSON.parse(line) as unknown)\n .filter(isRecord);\n}\n\nfunction decodePointerSegment(segment: string): string {\n return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');\n}\n\nfunction pointerSegments(pointerPath: string): string[] {\n return pointerPath\n .split('/')\n .filter(Boolean)\n .map((segment) => decodePointerSegment(segment));\n}\n\nfunction valueAtPointer(root: unknown, pointerPath: string): unknown {\n let current = root;\n for (const segment of pointerSegments(pointerPath)) {\n if (Array.isArray(current)) {\n const index = Number(segment);\n current = Number.isInteger(index) ? current[index] : undefined;\n } else if (isRecord(current)) {\n current = current[segment];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\nfunction referenceNodeForPatch(\n payload: JsonObject,\n check: RemoteVerificationCheck,\n): JsonObject | null {\n if (check.path.endsWith('/@flowUUID')) {\n const parentPath = check.path.slice(0, -'/@flowUUID'.length);\n const parent = valueAtPointer(payload, parentPath);\n return isRecord(parent) ? parent : null;\n }\n const node = valueAtPointer(payload, check.path);\n return isRecord(node) ? node : null;\n}\n\nfunction refreshableCheck(check: RemoteVerificationCheck): boolean {\n return (\n check.role === 'reference' &&\n Boolean(check.latest_version) &&\n ['missing_version', 'version_missing', 'version_outdated'].includes(check.status)\n );\n}\n\nfunction applyRemoteRefreshPatches(\n rows: JsonObject[],\n checks: RemoteVerificationCheck[],\n): { rows: JsonObject[]; patches: DatasetRemoteRefreshPatch[] } {\n const patchedRows = cloneJson(rows);\n const patches: DatasetRemoteRefreshPatch[] = [];\n\n for (const check of checks.filter(refreshableCheck)) {\n const row = patchedRows[check.row_index];\n if (!row || !check.latest_version) {\n continue;\n }\n const payload = unwrapDatasetPayload(row);\n const node = referenceNodeForPatch(payload, check);\n if (!node) {\n continue;\n }\n const before = typeof node['@version'] === 'string' ? node['@version'] : null;\n if (before === check.latest_version) {\n continue;\n }\n node['@version'] = check.latest_version;\n patches.push({\n row_index: check.row_index,\n role: check.role,\n table: check.table,\n id: check.id,\n from_version: before,\n to_version: check.latest_version,\n path: check.path,\n status_before: check.status,\n });\n }\n\n return { rows: patchedRows, patches };\n}\n\nfunction buildFiles(outPath: string, outDir: string): DatasetRemoteRefreshReport['files'] {\n const resolved = path.resolve(outDir);\n return {\n output_rows: path.resolve(outPath),\n report: path.join(resolved, 'outputs', 'remote-refresh-report.json'),\n patches: path.join(resolved, 'outputs', 'remote-refresh-patches.jsonl'),\n pre_verification_report: path.join(\n resolved,\n 'pre-refresh-verify',\n 'outputs',\n 'remote-verification-report.json',\n ),\n post_verification_report: path.join(\n resolved,\n 'post-refresh-verify',\n 'outputs',\n 'remote-verification-report.json',\n ),\n };\n}\n\nexport async function runDatasetRemoteRefresh(\n options: RunDatasetRemoteRefreshOptions,\n): Promise<DatasetRemoteRefreshReport> {\n const inputPath = path.resolve(\n requireNonEmpty(options.inputPath, '--input', 'DATASET_REMOTE_REFRESH_INPUT_REQUIRED'),\n );\n const outPath = path.resolve(\n requireNonEmpty(options.outPath, '--out', 'DATASET_REMOTE_REFRESH_OUT_REQUIRED'),\n );\n const outDir = path.resolve(\n requireNonEmpty(options.outDir, '--out-dir', 'DATASET_REMOTE_REFRESH_OUT_DIR_REQUIRED'),\n );\n const runVerify = options.runDatasetRemoteVerifyImpl ?? runDatasetRemoteVerify;\n const rows = readDatasetRowsInput(inputPath, options.rawInput);\n const files = buildFiles(outPath, outDir);\n\n const preReport = await runVerify({\n inputPath,\n outDir: path.join(outDir, 'pre-refresh-verify'),\n rawInput: rows,\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n rootPolicy: options.rootPolicy,\n });\n const checks = readJsonl(\n path.join(outDir, 'pre-refresh-verify', 'outputs', 'remote-verification.jsonl'),\n ) as RemoteVerificationCheck[];\n const { rows: patchedRows, patches } = applyRemoteRefreshPatches(rows, checks);\n writeJsonLinesArtifact(outPath, patchedRows);\n writeJsonLinesArtifact(files.patches, patches);\n\n const postReport = await runVerify({\n inputPath: outPath,\n outDir: path.join(outDir, 'post-refresh-verify'),\n rawInput: patchedRows,\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n rootPolicy: options.rootPolicy,\n });\n\n const report: DatasetRemoteRefreshReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n status: postReport.blockers.length > 0 ? 'completed_with_blockers' : 'completed',\n root_policy: options.rootPolicy ?? 'existing',\n input_path: inputPath,\n out_path: outPath,\n out_dir: outDir,\n counts: {\n rows: rows.length,\n pre_refresh_blockers: preReport.blockers.length,\n refreshable_references: checks.filter(refreshableCheck).length,\n patched_references: patches.length,\n post_refresh_blockers: postReport.blockers.length,\n },\n remaining_blockers: postReport.blockers,\n files,\n };\n writeJsonArtifact(files.report, report);\n\n return report;\n}\n\nexport const __testInternals = {\n applyRemoteRefreshPatches,\n pointerSegments,\n refreshableCheck,\n valueAtPointer,\n};\n"]}