@tiangong-lca/cli 0.0.19 → 0.0.22

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-maintenance-verify.js","sourceRoot":"","sources":["../../../src/lib/dataset-maintenance-verify.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { writeJsonArtifact } from './artifacts.js';\nimport { collectRemoteReferences } from './dataset-remote-verify.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n isJsonObject,\n maintenanceRowKey,\n parseMaintenancePlan,\n readJsonFile,\n readJsonLinesIfPresent,\n resolveMaintenancePlanArtifactPath,\n sha256Json,\n snapshotRemoteRow,\n type DatasetMaintenancePlan,\n type DatasetMaintenancePlanAction,\n type DatasetMaintenanceRemoteRow,\n type JsonObject,\n} from './dataset-maintenance-contract.js';\nimport { maintenanceProjectedReferenceFingerprint } from './dataset-maintenance-plan.js';\nimport {\n fetchMaintenanceAccountRows,\n fetchMaintenanceExactRows,\n normalizeMaintenancePageSize,\n resolveMaintenanceRemoteContext,\n} from './dataset-maintenance-remote.js';\n\nexport type DatasetMaintenanceVerifyIssue = {\n code: string;\n message: string;\n action_id?: string;\n table?: string;\n id?: string;\n version?: string;\n details?: unknown;\n};\n\nexport type DatasetMaintenanceVerifyReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'passed' | 'failed';\n task_id: string;\n operation: DatasetMaintenancePlan['operation'];\n operation_id: string;\n target_mode: DatasetMaintenancePlan['target_mode'];\n plan_sha256: string;\n actor: { user_id: string; email: string };\n summary: {\n actions: number;\n action_checks_passed: number;\n protected_rows: number;\n protected_checks_passed: number;\n progress_successes: number;\n atomic_plan_proofs?: number;\n atomic_batches?: number;\n atomic_batch_successes?: number;\n exchange_rewrite_logs?: number;\n dangling_deleted_target_references: number;\n issues: number;\n };\n action_checks: Array<{\n action_id: string;\n status: 'passed' | 'failed';\n observed: 'desired_payload' | 'absent' | 'mismatch';\n }>;\n issues: DatasetMaintenanceVerifyIssue[];\n artifacts: {\n plan: string;\n approval_record: string;\n apply_progress: string;\n commit_report: string;\n alias_plan_progress?: string;\n alias_batch_progress?: string;\n alias_exchange_progress?: string;\n report: string;\n };\n};\n\nexport type RunDatasetMaintenanceVerifyOptions = {\n planPath: string;\n outDir?: string;\n pageSize?: number;\n timeoutMs?: number;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n now?: Date;\n};\n\nconst POSITIVE_INTEGER_TEXT = /^[1-9]\\d*$/u;\n\nfunction issue(\n code: string,\n message: string,\n action?: DatasetMaintenancePlanAction,\n details?: unknown,\n): DatasetMaintenanceVerifyIssue {\n return {\n code,\n message,\n ...(action\n ? {\n action_id: action.action_id,\n table: action.table,\n id: action.id,\n version: action.version,\n }\n : {}),\n ...(details === undefined ? {} : { details }),\n };\n}\n\nfunction desiredPayload(planDir: string, action: DatasetMaintenancePlanAction): JsonObject | null {\n if (!action.desired_payload) {\n return null;\n }\n const raw = readJsonFile(\n resolveMaintenancePlanArtifactPath(\n planDir,\n action.desired_payload.path,\n 'Maintenance desired payload path',\n ),\n 'Maintenance desired payload',\n );\n return isJsonObject(raw) && sha256Json(raw) === action.desired_payload.sha256 ? raw : null;\n}\n\nfunction deletedTargetReferences(options: {\n rows: DatasetMaintenanceRemoteRow[];\n deletes: DatasetMaintenancePlanAction[];\n}): Array<{\n target_action_id: string;\n source_key: string;\n path: string;\n}> {\n const payloadRows = options.rows\n .filter((row) => row.json_ordered)\n .map((row) => ({ ...row, json_ordered: row.json_ordered as JsonObject }));\n const references = collectRemoteReferences(payloadRows).filter(\n (reference) => reference.role === 'reference',\n );\n return references.flatMap((reference) => {\n const source = payloadRows[reference.row_index];\n if (!reference.table || !reference.id) {\n return [];\n }\n return options.deletes\n .filter(\n (target) =>\n target.table === reference.table &&\n target.id === reference.id &&\n (!reference.version || target.version === reference.version),\n )\n .map((target) => ({\n target_action_id: target.action_id,\n source_key: maintenanceRowKey(source!),\n path: reference.path,\n }));\n });\n}\n\nexport async function runDatasetMaintenanceVerify(\n options: RunDatasetMaintenanceVerifyOptions,\n): Promise<DatasetMaintenanceVerifyReport> {\n const planPath = path.resolve(options.planPath);\n const planDir = path.dirname(planPath);\n const outDir = path.resolve(options.outDir ?? path.join(planDir, 'verify'));\n const reportPath = path.join(outDir, 'readback-verify-report.json');\n const approvalRecordPath = path.join(planDir, 'approval-record.json');\n const progressPath = path.join(planDir, 'apply-progress.jsonl');\n const commitReportPath = path.join(planDir, 'commit-report.json');\n const aliasPlanProgressPath = path.join(planDir, 'alias-plan-progress.jsonl');\n const aliasBatchProgressPath = path.join(planDir, 'alias-batch-progress.jsonl');\n const aliasExchangeProgressPath = path.join(planDir, 'alias-exchange-progress.jsonl');\n const pageSize = normalizeMaintenancePageSize(options.pageSize);\n const plan = parseMaintenancePlan(readJsonFile(planPath, 'Maintenance plan'));\n const context = await resolveMaintenanceRemoteContext({\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n });\n if (\n context.account.user_id !== plan.account.user_id ||\n context.account.email !== plan.account.email\n ) {\n throw new CliError('Current authenticated account does not match the maintenance plan.', {\n code: 'DATASET_MAINTENANCE_ACCOUNT_MISMATCH',\n exitCode: 1,\n });\n }\n\n const problems: DatasetMaintenanceVerifyIssue[] = [];\n const current = await fetchMaintenanceAccountRows({\n context,\n userId: plan.account.user_id,\n pageSize,\n });\n const currentByKey = new Map(current.rows.map((row) => [maintenanceRowKey(row), row]));\n const actionChecks: DatasetMaintenanceVerifyReport['action_checks'] = [];\n for (const action of plan.actions) {\n const exact = await fetchMaintenanceExactRows({\n context,\n table: action.table,\n id: action.id,\n version: action.version,\n });\n if (action.action === 'delete') {\n const passed = exact.rows.length === 0;\n if (!passed) {\n problems.push(\n issue('DELETE_TARGET_STILL_VISIBLE', 'Deleted target is still visible.', action),\n );\n }\n actionChecks.push({\n action_id: action.action_id,\n status: passed ? 'passed' : 'failed',\n observed: passed ? 'absent' : 'mismatch',\n });\n continue;\n }\n const payload = desiredPayload(planDir, action);\n const row = exact.rows.length === 1 ? exact.rows[0] : null;\n const snapshot = row ? snapshotRemoteRow(row) : null;\n const passed = Boolean(\n row &&\n payload &&\n snapshot?.payload_sha256 === action.desired_payload?.sha256 &&\n row.user_id === action.expected_user_id &&\n row.state_code === 0 &&\n row.model_id === action.before?.model_id &&\n row.rule_verification === action.before?.rule_verification,\n );\n if (!passed) {\n problems.push(\n issue(\n 'SAVE_DRAFT_READBACK_MISMATCH',\n 'Saved draft payload, owner, state, model_id, or rule_verification did not match the plan.',\n action,\n ),\n );\n }\n actionChecks.push({\n action_id: action.action_id,\n status: passed ? 'passed' : 'failed',\n observed: passed ? 'desired_payload' : 'mismatch',\n });\n }\n\n const progress = readJsonLinesIfPresent(progressPath);\n const actionsById = new Map(plan.actions.map((action) => [action.action_id, action]));\n\n let aliasBatchSuccesses = 0;\n let aliasExchangeLogs = 0;\n let aliasPlanProofs = 0;\n let aliasPlanProof: {\n plan_request_sha256: string;\n summary_audit_id: string;\n batches: Map<string, { batch_request_sha256: string; summary_audit_id: string }>;\n } | null = null;\n const aliasBatchProofs = new Map<\n string,\n {\n batch_request_sha256: string;\n summary_audit_id: string;\n plan_request_sha256: string;\n plan_summary_audit_id: string;\n }\n >();\n if (plan.operation === 'merge-support-aliases') {\n const orderedBatches = [\n plan.alias_batches!.find((batch) => batch.dimension === 'time')!,\n plan.alias_batches!.find((batch) => batch.dimension === 'length_time')!,\n ];\n let successfulPlanSeen = false;\n for (const [index, entry] of readJsonLinesIfPresent(aliasPlanProgressPath).entries()) {\n const batchProofs = isJsonObject(entry) && Array.isArray(entry.batches) ? entry.batches : [];\n const validSuccessBatches =\n batchProofs.length === 2 &&\n batchProofs.every((proof, batchIndex) => {\n const batch = orderedBatches[batchIndex]!;\n return Boolean(\n isJsonObject(proof) &&\n proof.batch_id === batch.batch_id &&\n proof.dimension === batch.dimension &&\n typeof proof.batch_request_sha256 === 'string' &&\n /^[a-f0-9]{64}$/u.test(proof.batch_request_sha256) &&\n typeof proof.summary_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(proof.summary_audit_id),\n );\n });\n const batchRequestHashes = batchProofs\n .filter(isJsonObject)\n .map((proof) => proof.batch_request_sha256);\n const batchSummaryAuditIds = batchProofs\n .filter(isJsonObject)\n .map((proof) => proof.summary_audit_id);\n const valid = Boolean(\n isJsonObject(entry) &&\n entry.schema_version === 1 &&\n entry.plan_sha256 === plan.plan_sha256 &&\n entry.operation_id === plan.operation_id &&\n entry.target_mode === 'owner_draft' &&\n isJsonObject(entry.actor) &&\n entry.actor.user_id === plan.account.user_id &&\n entry.actor.email === plan.account.email &&\n typeof entry.started_at_utc === 'string' &&\n typeof entry.ended_at_utc === 'string' &&\n entry.batch_count === 2 &&\n entry.row_count === 52 &&\n entry.exchange_count === 59 &&\n (entry.result === 'success' || entry.result === 'failed') &&\n (entry.result === 'success'\n ? !successfulPlanSeen &&\n typeof entry.plan_request_sha256 === 'string' &&\n /^[a-f0-9]{64}$/u.test(entry.plan_request_sha256) &&\n typeof entry.idempotent_replay === 'boolean' &&\n typeof entry.summary_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(entry.summary_audit_id) &&\n validSuccessBatches &&\n new Set(batchRequestHashes).size === 2 &&\n new Set(batchSummaryAuditIds).size === 2 &&\n !batchSummaryAuditIds.includes(entry.summary_audit_id) &&\n entry.error === null\n : entry.plan_request_sha256 === null &&\n entry.idempotent_replay === null &&\n entry.summary_audit_id === null &&\n batchProofs.length === 0 &&\n typeof entry.error === 'string'),\n );\n if (!valid) {\n problems.push({\n code: 'ALIAS_PLAN_PROGRESS_INVALID',\n message: 'alias-plan-progress.jsonl contains an invalid or foreign entry.',\n details: { line: index + 1 },\n });\n } else if (isJsonObject(entry) && entry.result === 'success') {\n successfulPlanSeen = true;\n aliasPlanProof = {\n plan_request_sha256: entry.plan_request_sha256 as string,\n summary_audit_id: entry.summary_audit_id as string,\n batches: new Map(\n batchProofs.map((proof) => {\n const value = proof as JsonObject;\n return [\n value.batch_id as string,\n {\n batch_request_sha256: value.batch_request_sha256 as string,\n summary_audit_id: value.summary_audit_id as string,\n },\n ] as const;\n }),\n ),\n };\n }\n }\n if (!aliasPlanProof) {\n problems.push({\n code: 'ALIAS_PLAN_SUCCESS_LOG_MISSING',\n message: 'No successful whole-plan progress proof exists.',\n });\n } else {\n aliasPlanProofs = 1;\n }\n for (const batch of plan.alias_batches!) {\n for (const snapshot of [\n batch.target_snapshots.unitgroup!,\n batch.target_snapshots.flowproperty!,\n batch.target_snapshots.source_unitgroup!,\n ]) {\n const exact = await fetchMaintenanceExactRows({\n context,\n table: snapshot.table,\n id: snapshot.id,\n version: snapshot.version,\n });\n const row = exact.rows.length === 1 ? exact.rows[0] : null;\n if (\n !row ||\n row.user_id !== plan.account.user_id ||\n row.state_code !== 0 ||\n snapshotRemoteRow(row).row_sha256 !== snapshot.row_sha256\n ) {\n problems.push({\n code: 'ALIAS_SUPPORT_READBACK_MISMATCH',\n message: 'Alias target/source support snapshot changed after planning.',\n table: snapshot.table,\n id: snapshot.id,\n version: snapshot.version,\n details: { batch_id: batch.batch_id },\n });\n }\n }\n }\n\n const batchesById = new Map(plan.alias_batches!.map((batch) => [batch.batch_id, batch]));\n const successfulBatches = new Set<string>();\n for (const [index, entry] of readJsonLinesIfPresent(aliasBatchProgressPath).entries()) {\n const batch =\n isJsonObject(entry) && typeof entry.batch_id === 'string'\n ? batchesById.get(entry.batch_id)\n : null;\n const planBatchProof = batch ? aliasPlanProof?.batches.get(batch.batch_id) : null;\n const valid = Boolean(\n isJsonObject(entry) &&\n entry.schema_version === 1 &&\n entry.plan_sha256 === plan.plan_sha256 &&\n entry.operation_id === plan.operation_id &&\n entry.target_mode === 'owner_draft' &&\n batch &&\n entry.dimension === batch.dimension &&\n entry.factor === batch.factor &&\n entry.row_count === batch.summary.rows &&\n entry.exchange_count === batch.summary.exchanges &&\n isJsonObject(entry.actor) &&\n entry.actor.user_id === plan.account.user_id &&\n entry.actor.email === plan.account.email &&\n typeof entry.started_at_utc === 'string' &&\n typeof entry.ended_at_utc === 'string' &&\n entry.result === 'success' &&\n !successfulBatches.has(batch.batch_id) &&\n planBatchProof &&\n typeof entry.batch_request_sha256 === 'string' &&\n /^[a-f0-9]{64}$/u.test(entry.batch_request_sha256) &&\n entry.batch_request_sha256 === planBatchProof.batch_request_sha256 &&\n typeof entry.idempotent_replay === 'boolean' &&\n typeof entry.summary_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(entry.summary_audit_id) &&\n entry.summary_audit_id === planBatchProof.summary_audit_id &&\n entry.plan_request_sha256 === aliasPlanProof?.plan_request_sha256 &&\n entry.plan_summary_audit_id === aliasPlanProof?.summary_audit_id &&\n entry.error === null,\n );\n if (!valid) {\n problems.push({\n code: 'ALIAS_BATCH_PROGRESS_INVALID',\n message: 'alias-batch-progress.jsonl contains an invalid or foreign entry.',\n details: { line: index + 1 },\n });\n } else if (isJsonObject(entry) && entry.result === 'success' && batch) {\n successfulBatches.add(batch.batch_id);\n aliasBatchProofs.set(batch.batch_id, {\n batch_request_sha256: entry.batch_request_sha256 as string,\n summary_audit_id: entry.summary_audit_id as string,\n plan_request_sha256: entry.plan_request_sha256 as string,\n plan_summary_audit_id: entry.plan_summary_audit_id as string,\n });\n }\n }\n for (const batch of plan.alias_batches!) {\n if (!successfulBatches.has(batch.batch_id)) {\n problems.push({\n code: 'ALIAS_BATCH_SUCCESS_LOG_MISSING',\n message: 'No successful atomic batch progress entry exists.',\n details: { batch_id: batch.batch_id },\n });\n }\n }\n aliasBatchSuccesses = successfulBatches.size;\n\n const expectedRewrites = new Map(\n plan.alias_batches!.flatMap((batch) =>\n batch.exchange_rewrites.map(\n (rewrite) =>\n [\n `${batch.batch_id}\\u0000${rewrite.action_id}\\u0000${rewrite.exchange_index}\\u0000${rewrite.data_set_internal_id}` as string,\n { batch, rewrite },\n ] as const,\n ),\n ),\n );\n const loggedKeys = new Set<string>();\n for (const [index, entry] of readJsonLinesIfPresent(aliasExchangeProgressPath).entries()) {\n const key =\n isJsonObject(entry) &&\n typeof entry.batch_id === 'string' &&\n typeof entry.action_id === 'string' &&\n typeof entry.exchange_index === 'number' &&\n typeof entry.data_set_internal_id === 'string'\n ? `${entry.batch_id}\\u0000${entry.action_id}\\u0000${entry.exchange_index}\\u0000${entry.data_set_internal_id}`\n : '';\n const expected = expectedRewrites.get(key);\n const batchProof = expected ? aliasBatchProofs.get(expected.batch.batch_id) : null;\n const action = expected ? actionsById.get(expected.rewrite.action_id) : null;\n const rowProofCandidates = expected\n ? progress.filter(\n (candidate) =>\n isJsonObject(candidate) &&\n candidate.schema_version === 1 &&\n candidate.plan_sha256 === plan.plan_sha256 &&\n candidate.operation_id === plan.operation_id &&\n candidate.action_id === expected.rewrite.action_id &&\n candidate.action === 'update_json_ordered' &&\n candidate.table === action?.table &&\n candidate.id === action?.id &&\n candidate.version === action?.version &&\n candidate.batch_id === expected.batch.batch_id &&\n candidate.batch_request_sha256 === batchProof?.batch_request_sha256 &&\n candidate.summary_audit_id === batchProof?.summary_audit_id &&\n typeof candidate.database_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(candidate.database_audit_id) &&\n candidate.result === 'success',\n )\n : [];\n const rowProof = rowProofCandidates.length === 1 ? rowProofCandidates[0] : null;\n const rowAuditId =\n isJsonObject(rowProof) && typeof rowProof.database_audit_id === 'string'\n ? rowProof.database_audit_id\n : null;\n const valid = Boolean(\n isJsonObject(entry) &&\n expected &&\n batchProof &&\n rowProof &&\n entry.schema_version === 1 &&\n entry.plan_sha256 === plan.plan_sha256 &&\n entry.operation_id === plan.operation_id &&\n entry.target_mode === 'owner_draft' &&\n entry.factor === expected.batch.factor &&\n entry.result === 'success' &&\n typeof entry.batch_request_sha256 === 'string' &&\n /^[a-f0-9]{64}$/u.test(entry.batch_request_sha256) &&\n entry.batch_request_sha256 === batchProof.batch_request_sha256 &&\n typeof entry.database_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(entry.database_audit_id) &&\n entry.database_audit_id === rowAuditId &&\n entry.summary_audit_id === batchProof.summary_audit_id &&\n entry.plan_request_sha256 === batchProof.plan_request_sha256 &&\n entry.plan_request_sha256 === aliasPlanProof?.plan_request_sha256 &&\n entry.plan_summary_audit_id === batchProof.plan_summary_audit_id &&\n entry.plan_summary_audit_id === aliasPlanProof?.summary_audit_id &&\n isJsonObject(entry.actor) &&\n entry.actor.user_id === plan.account.user_id &&\n entry.actor.email === plan.account.email &&\n typeof entry.logged_at_utc === 'string' &&\n sha256Json({\n action_id: entry.action_id,\n process_id: entry.process_id,\n process_version: entry.process_version,\n exchange_index: entry.exchange_index,\n data_set_internal_id: entry.data_set_internal_id,\n flow_id: entry.flow_id,\n flow_version: entry.flow_version,\n direction: entry.direction,\n before_exchange_sha256: entry.before_exchange_sha256,\n before_mean_amount: entry.before_mean_amount,\n before_resulting_amount: entry.before_resulting_amount,\n after_mean_amount: entry.after_mean_amount,\n after_resulting_amount: entry.after_resulting_amount,\n after_exchange_sha256: entry.after_exchange_sha256,\n }) === sha256Json(expected.rewrite) &&\n !loggedKeys.has(key),\n );\n if (!valid) {\n problems.push({\n code: 'ALIAS_EXCHANGE_PROGRESS_INVALID',\n message:\n 'alias-exchange-progress.jsonl contains an invalid, duplicate, or foreign entry.',\n details: { line: index + 1 },\n });\n } else {\n loggedKeys.add(key);\n }\n }\n for (const key of expectedRewrites.keys()) {\n if (!loggedKeys.has(key)) {\n problems.push({\n code: 'ALIAS_EXCHANGE_SUCCESS_LOG_MISSING',\n message: 'An approved exchange rewrite lacks a durable success entry.',\n details: { key },\n });\n }\n }\n aliasExchangeLogs = loggedKeys.size;\n }\n\n let protectedPassed = 0;\n for (const protectedRow of plan.protected_rows) {\n const row = currentByKey.get(maintenanceRowKey(protectedRow));\n if (row && snapshotRemoteRow(row).row_sha256 === protectedRow.row_sha256) {\n protectedPassed += 1;\n } else {\n problems.push({\n code: 'PROTECTED_ROW_CHANGED',\n message: 'Protected row changed or disappeared after maintenance.',\n table: protectedRow.table,\n id: protectedRow.id,\n version: protectedRow.version,\n });\n }\n }\n const expectedFinalKeys = new Set([\n ...plan.protected_rows.map(maintenanceRowKey),\n ...plan.actions.filter((action) => action.action !== 'delete').map(maintenanceRowKey),\n ]);\n for (const row of current.rows) {\n if (!expectedFinalKeys.has(maintenanceRowKey(row))) {\n problems.push({\n code: 'UNEXPECTED_ACCOUNT_ROW',\n message: 'Unexpected current-account row exists after maintenance.',\n table: row.table,\n id: row.id,\n version: row.version,\n });\n }\n }\n\n const referenceSha256 = sha256Json(maintenanceProjectedReferenceFingerprint(current.rows));\n if (referenceSha256 !== plan.projected_reference_sha256) {\n problems.push({\n code: 'PROJECTED_REFERENCE_CLOSURE_MISMATCH',\n message: 'Readback reference closure differs from the approved plan.',\n details: { expected: plan.projected_reference_sha256, actual: referenceSha256 },\n });\n }\n const danglingReferences = deletedTargetReferences({\n rows: current.rows,\n deletes: plan.actions.filter((action) => action.action === 'delete'),\n });\n if (danglingReferences.length) {\n problems.push({\n code: 'DELETED_TARGET_REFERENCED',\n message: 'Readback contains references to a deleted target.',\n details: danglingReferences,\n });\n }\n\n if (!existsSync(approvalRecordPath)) {\n problems.push({\n code: 'APPROVAL_RECORD_MISSING',\n message: 'approval-record.json is missing.',\n });\n } else {\n const approvalRecord = readJsonFile(approvalRecordPath, 'Maintenance approval record');\n if (\n !isJsonObject(approvalRecord) ||\n approvalRecord.schema_version !== 1 ||\n approvalRecord.plan_sha256 !== plan.plan_sha256 ||\n approvalRecord.task_id !== plan.task_id ||\n approvalRecord.operation !== plan.operation ||\n approvalRecord.operation_id !== plan.operation_id ||\n approvalRecord.target_mode !== plan.target_mode ||\n !isJsonObject(approvalRecord.account) ||\n approvalRecord.account.user_id !== plan.account.user_id ||\n approvalRecord.account.email !== plan.account.email ||\n approvalRecord.confirmed_email !== plan.account.email ||\n !isJsonObject(approvalRecord.row_counts) ||\n sha256Json(approvalRecord.row_counts) !== sha256Json(plan.summary)\n ) {\n problems.push({\n code: 'APPROVAL_RECORD_INVALID',\n message: 'approval-record.json does not match the immutable plan and actor.',\n });\n }\n }\n\n const successfulActionIds = new Set<string>();\n for (const [index, entry] of progress.entries()) {\n const action =\n isJsonObject(entry) && typeof entry.action_id === 'string'\n ? actionsById.get(entry.action_id)\n : null;\n const aliasProof = action?.batch_id ? aliasBatchProofs.get(action.batch_id) : null;\n const valid = Boolean(\n isJsonObject(entry) &&\n entry.schema_version === 1 &&\n action &&\n entry.plan_sha256 === plan.plan_sha256 &&\n entry.operation_id === plan.operation_id &&\n entry.action === action.action &&\n entry.table === action.table &&\n entry.id === action.id &&\n entry.version === action.version &&\n entry.reason_code === action.reason_code &&\n entry.before_sha256 === action.before?.row_sha256 &&\n typeof entry.started_at_utc === 'string' &&\n typeof entry.ended_at_utc === 'string' &&\n isJsonObject(entry.actor) &&\n entry.actor.user_id === plan.account.user_id &&\n entry.actor.email === plan.account.email &&\n isJsonObject(entry.audit_context) &&\n entry.audit_context.plan_sha256 === plan.plan_sha256 &&\n entry.audit_context.operation_id === plan.operation_id &&\n entry.audit_context.action_id === action.action_id &&\n entry.audit_context.reason_code === action.reason_code &&\n entry.audit_context.source === 'tiangong-lca dataset maintenance apply' &&\n (action.action !== 'update_json_ordered' ||\n (aliasProof &&\n entry.target_mode === 'owner_draft' &&\n entry.audit_context.target_mode === 'owner_draft' &&\n entry.batch_id === action.batch_id &&\n typeof entry.batch_request_sha256 === 'string' &&\n /^[a-f0-9]{64}$/u.test(entry.batch_request_sha256) &&\n entry.batch_request_sha256 === aliasProof.batch_request_sha256 &&\n typeof entry.database_audit_id === 'string' &&\n POSITIVE_INTEGER_TEXT.test(entry.database_audit_id) &&\n entry.summary_audit_id === aliasProof.summary_audit_id &&\n entry.plan_request_sha256 === aliasProof.plan_request_sha256 &&\n entry.plan_request_sha256 === aliasPlanProof?.plan_request_sha256 &&\n entry.plan_summary_audit_id === aliasProof.plan_summary_audit_id &&\n entry.plan_summary_audit_id === aliasPlanProof?.summary_audit_id)) &&\n (action.action === 'update_json_ordered' ||\n (!('target_mode' in entry) &&\n !('target_mode' in entry.audit_context) &&\n !('batch_id' in entry) &&\n !('batch_request_sha256' in entry) &&\n !('database_audit_id' in entry) &&\n !('summary_audit_id' in entry) &&\n !('plan_request_sha256' in entry) &&\n !('plan_summary_audit_id' in entry))) &&\n isJsonObject(entry.rollback) &&\n sha256Json(entry.rollback) === sha256Json(action.rollback) &&\n (entry.result === 'success' || entry.result === 'failed') &&\n (entry.result === 'success'\n ? typeof entry.remote_result_sha256 === 'string' &&\n entry.error === null &&\n (action.action === 'delete'\n ? entry.after_sha256 === null\n : typeof entry.after_sha256 === 'string')\n : entry.remote_result_sha256 === null &&\n entry.after_sha256 === null &&\n typeof entry.error === 'string'),\n );\n if (!valid) {\n problems.push({\n code: 'APPLY_PROGRESS_ENTRY_INVALID',\n message: 'apply-progress.jsonl contains an invalid or foreign entry.',\n details: { line: index + 1, action_id: action?.action_id ?? null },\n });\n continue;\n }\n if (isJsonObject(entry) && entry.result === 'success' && action) {\n if (successfulActionIds.has(action.action_id)) {\n problems.push({\n code: 'APPLY_PROGRESS_SUCCESS_DUPLICATE',\n message: 'apply-progress.jsonl contains more than one success proof for an action.',\n details: { line: index + 1, action_id: action.action_id },\n });\n continue;\n }\n successfulActionIds.add(action.action_id);\n }\n }\n for (const action of plan.actions) {\n if (!successfulActionIds.has(action.action_id)) {\n problems.push(\n issue('ACTION_SUCCESS_LOG_MISSING', 'No successful apply-progress entry exists.', action),\n );\n }\n }\n if (!existsSync(commitReportPath)) {\n problems.push({ code: 'COMMIT_REPORT_MISSING', message: 'commit-report.json is missing.' });\n } else {\n const commitReport = readJsonFile(commitReportPath, 'Maintenance commit report');\n const commitActions =\n isJsonObject(commitReport) && Array.isArray(commitReport.actions) ? commitReport.actions : [];\n const commitActionsById = new Map(\n commitActions\n .filter(\n (entry): entry is JsonObject =>\n isJsonObject(entry) && typeof entry.action_id === 'string',\n )\n .map((entry) => [entry.action_id as string, entry]),\n );\n const commitActionsMatch =\n commitActions.length === plan.actions.length &&\n commitActionsById.size === plan.actions.length &&\n plan.actions.every((action) => {\n const entry = commitActionsById.get(action.action_id);\n return Boolean(\n entry &&\n entry.action === action.action &&\n entry.table === action.table &&\n entry.id === action.id &&\n entry.version === action.version &&\n entry.status === 'success' &&\n entry.error === null,\n );\n });\n const aliasCommitProofMatches =\n plan.operation !== 'merge-support-aliases' ||\n Boolean(\n isJsonObject(commitReport) &&\n isJsonObject(commitReport.alias_plan_proof) &&\n aliasPlanProof &&\n commitReport.alias_plan_proof.plan_request_sha256 === aliasPlanProof.plan_request_sha256 &&\n commitReport.alias_plan_proof.summary_audit_id === aliasPlanProof.summary_audit_id &&\n commitReport.alias_plan_proof.batch_count === 2 &&\n commitReport.alias_plan_proof.row_count === 52 &&\n commitReport.alias_plan_proof.exchange_count === 59 &&\n typeof commitReport.alias_plan_proof.idempotent_replay === 'boolean' &&\n isJsonObject(commitReport.artifacts) &&\n commitReport.artifacts.alias_plan_progress === aliasPlanProgressPath &&\n commitReport.artifacts.alias_batch_progress === aliasBatchProgressPath &&\n commitReport.artifacts.alias_exchange_progress === aliasExchangeProgressPath,\n );\n if (\n !isJsonObject(commitReport) ||\n commitReport.schema_version !== 1 ||\n commitReport.plan_sha256 !== plan.plan_sha256 ||\n commitReport.task_id !== plan.task_id ||\n commitReport.operation !== plan.operation ||\n commitReport.operation_id !== plan.operation_id ||\n commitReport.target_mode !== plan.target_mode ||\n commitReport.status !== 'completed' ||\n !isJsonObject(commitReport.actor) ||\n commitReport.actor.user_id !== plan.account.user_id ||\n commitReport.actor.email !== plan.account.email ||\n !isJsonObject(commitReport.summary) ||\n commitReport.summary.actions !== plan.actions.length ||\n commitReport.summary.success !== plan.actions.length ||\n commitReport.summary.failed !== 0 ||\n commitReport.summary.pending !== 0 ||\n !commitActionsMatch ||\n !aliasCommitProofMatches\n ) {\n problems.push({\n code: 'COMMIT_REPORT_INCOMPLETE',\n message: 'commit-report.json does not prove full successful completion for this plan.',\n });\n }\n }\n\n const report: DatasetMaintenanceVerifyReport = {\n schema_version: 1,\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n status: problems.length ? 'failed' : 'passed',\n task_id: plan.task_id,\n operation: plan.operation,\n operation_id: plan.operation_id,\n target_mode: plan.target_mode,\n plan_sha256: plan.plan_sha256,\n actor: { user_id: context.account.user_id, email: context.account.email },\n summary: {\n actions: plan.actions.length,\n action_checks_passed: actionChecks.filter((check) => check.status === 'passed').length,\n protected_rows: plan.protected_rows.length,\n protected_checks_passed: protectedPassed,\n progress_successes: successfulActionIds.size,\n ...(plan.operation === 'merge-support-aliases'\n ? {\n atomic_plan_proofs: aliasPlanProofs,\n atomic_batches: plan.alias_batches!.length,\n atomic_batch_successes: aliasBatchSuccesses,\n exchange_rewrite_logs: aliasExchangeLogs,\n }\n : {}),\n dangling_deleted_target_references: danglingReferences.length,\n issues: problems.length,\n },\n action_checks: actionChecks,\n issues: problems,\n artifacts: {\n plan: planPath,\n approval_record: approvalRecordPath,\n apply_progress: progressPath,\n commit_report: commitReportPath,\n ...(plan.operation === 'merge-support-aliases'\n ? {\n alias_plan_progress: aliasPlanProgressPath,\n alias_batch_progress: aliasBatchProgressPath,\n alias_exchange_progress: aliasExchangeProgressPath,\n }\n : {}),\n report: reportPath,\n },\n };\n writeJsonArtifact(reportPath, report);\n return report;\n}\n\nexport const __testInternals = {\n deletedTargetReferences,\n desiredPayload,\n issue,\n};\n"]}
@@ -0,0 +1,522 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
4
+ import { CliError } from './errors.js';
5
+ import { buildSupabaseAuthHeaders, deriveSupabaseProjectBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
6
+ import { resolveSupabaseUserSession } from './supabase-session.js';
7
+ const DEFAULT_BUCKET = 'external_docs';
8
+ const DEFAULT_TIMEOUT_MS = 30_000;
9
+ const MIME_TYPES = {
10
+ '.pdf': 'application/pdf',
11
+ '.jpg': 'image/jpeg',
12
+ '.jpeg': 'image/jpeg',
13
+ '.png': 'image/png',
14
+ '.gif': 'image/gif',
15
+ '.bmp': 'image/bmp',
16
+ '.webp': 'image/webp',
17
+ '.svg': 'image/svg+xml',
18
+ '.csv': 'text/csv',
19
+ '.txt': 'text/plain',
20
+ '.xml': 'application/xml',
21
+ '.json': 'application/json',
22
+ '.zip': 'application/zip',
23
+ '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
24
+ };
25
+ function isRecord(value) {
26
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
27
+ }
28
+ function trimToken(value) {
29
+ if (typeof value !== 'string') {
30
+ return null;
31
+ }
32
+ const trimmed = value.trim();
33
+ return trimmed ? trimmed : null;
34
+ }
35
+ function caughtErrorMessage(error) {
36
+ return error instanceof Error ? error.message : String(error);
37
+ }
38
+ function readFileBytes(filePath) {
39
+ // Copy into a fresh ArrayBuffer-backed view so the bytes are a valid BlobPart
40
+ // (readFileSync's Buffer is typed over ArrayBufferLike, which Blob rejects).
41
+ return new Uint8Array(readFileSync(filePath));
42
+ }
43
+ function normalizeTimeoutMs(value) {
44
+ if (value === undefined) {
45
+ return DEFAULT_TIMEOUT_MS;
46
+ }
47
+ if (!Number.isInteger(value) || value < 1) {
48
+ throw new CliError('--timeout-ms must be a positive integer.', {
49
+ code: 'DATASET_SOURCE_UPLOAD_TIMEOUT_INVALID',
50
+ exitCode: 2,
51
+ details: value,
52
+ });
53
+ }
54
+ return value;
55
+ }
56
+ export function classifyDigitalFileUri(uri) {
57
+ const trimmed = typeof uri === 'string' ? uri.trim() : '';
58
+ if (!trimmed) {
59
+ return 'empty';
60
+ }
61
+ if (/^https?:\/\//iu.test(trimmed)) {
62
+ return 'remote';
63
+ }
64
+ return 'local';
65
+ }
66
+ export function digitalFileBasename(uri) {
67
+ const normalized = uri.trim().replace(/\\/gu, '/');
68
+ const slash = normalized.lastIndexOf('/');
69
+ return slash >= 0 ? normalized.slice(slash + 1) : normalized;
70
+ }
71
+ export function mimeTypeForFile(fileName) {
72
+ const ext = path.extname(fileName).toLowerCase();
73
+ return MIME_TYPES[ext] ?? 'application/octet-stream';
74
+ }
75
+ function buildExternalDocsIndex(externalDocsDir) {
76
+ let entries;
77
+ try {
78
+ entries = readdirSync(externalDocsDir, { withFileTypes: true })
79
+ .filter((entry) => entry.isFile())
80
+ .map((entry) => entry.name);
81
+ }
82
+ catch (error) {
83
+ throw new CliError(`Cannot read external docs directory: ${externalDocsDir}`, {
84
+ code: 'DATASET_SOURCE_UPLOAD_EXTERNAL_DOCS_DIR_UNREADABLE',
85
+ exitCode: 2,
86
+ details: caughtErrorMessage(error),
87
+ });
88
+ }
89
+ const index = new Map();
90
+ for (const name of entries) {
91
+ index.set(name.toLowerCase(), name);
92
+ }
93
+ return index;
94
+ }
95
+ function digitalFileNode(row) {
96
+ const root = isRecord(row.sourceDataSet) ? row.sourceDataSet : row;
97
+ const sourceInformation = isRecord(root.sourceInformation)
98
+ ? root.sourceInformation
99
+ : null;
100
+ if (!sourceInformation) {
101
+ return null;
102
+ }
103
+ const dataSetInformation = isRecord(sourceInformation.dataSetInformation)
104
+ ? sourceInformation.dataSetInformation
105
+ : null;
106
+ return dataSetInformation;
107
+ }
108
+ function sourceIdentity(row) {
109
+ const dataSetInformation = digitalFileNode(row);
110
+ const id = dataSetInformation ? trimToken(dataSetInformation['common:UUID']) : null;
111
+ const root = isRecord(row.sourceDataSet) ? row.sourceDataSet : row;
112
+ const administrative = isRecord(root.administrativeInformation)
113
+ ? root.administrativeInformation
114
+ : null;
115
+ const publication = administrative && isRecord(administrative.publicationAndOwnership)
116
+ ? administrative.publicationAndOwnership
117
+ : null;
118
+ const version = publication ? trimToken(publication['common:dataSetVersion']) : null;
119
+ return { id, version };
120
+ }
121
+ function entryUri(entry) {
122
+ if (typeof entry === 'string') {
123
+ return entry;
124
+ }
125
+ if (isRecord(entry)) {
126
+ const uri = entry['@uri'];
127
+ return typeof uri === 'string' ? uri : '';
128
+ }
129
+ return '';
130
+ }
131
+ function withRewrittenUri(entry, rewrittenUri) {
132
+ if (typeof entry === 'string') {
133
+ return rewrittenUri;
134
+ }
135
+ if (isRecord(entry)) {
136
+ return { ...entry, '@uri': rewrittenUri };
137
+ }
138
+ return entry;
139
+ }
140
+ function resolveReferences(identity, entries, fileIndex, bucket) {
141
+ return entries.map((entry, entryIndex) => {
142
+ const original = entryUri(entry);
143
+ const kind = classifyDigitalFileUri(original);
144
+ if (kind !== 'local') {
145
+ return {
146
+ entryIndex,
147
+ reference: {
148
+ source_id: identity.id,
149
+ source_version: identity.version,
150
+ original_uri: original,
151
+ kind,
152
+ resolved_file: null,
153
+ bucket_key: null,
154
+ rewritten_uri: original,
155
+ status: 'left_as_is',
156
+ },
157
+ };
158
+ }
159
+ const basename = digitalFileBasename(original);
160
+ const resolved = fileIndex.get(basename.toLowerCase()) ?? null;
161
+ if (!resolved) {
162
+ return {
163
+ entryIndex,
164
+ reference: {
165
+ source_id: identity.id,
166
+ source_version: identity.version,
167
+ original_uri: original,
168
+ kind,
169
+ resolved_file: null,
170
+ bucket_key: null,
171
+ rewritten_uri: original,
172
+ status: 'unresolved',
173
+ },
174
+ };
175
+ }
176
+ return {
177
+ entryIndex,
178
+ reference: {
179
+ source_id: identity.id,
180
+ source_version: identity.version,
181
+ original_uri: original,
182
+ kind,
183
+ resolved_file: resolved,
184
+ bucket_key: resolved,
185
+ rewritten_uri: `../${bucket}/${resolved}`,
186
+ status: 'rewritten',
187
+ },
188
+ };
189
+ });
190
+ }
191
+ export function digitalFileEntries(value) {
192
+ if (value === undefined || value === null) {
193
+ return [];
194
+ }
195
+ return Array.isArray(value) ? value : [value];
196
+ }
197
+ function rewriteDigitalFileValue(value, resolved) {
198
+ const entries = digitalFileEntries(value);
199
+ const rewritten = entries.map((entry, entryIndex) => {
200
+ const match = resolved.find((item) => item.entryIndex === entryIndex);
201
+ if (match && match.reference.status === 'rewritten' && match.reference.rewritten_uri) {
202
+ return withRewrittenUri(entry, match.reference.rewritten_uri);
203
+ }
204
+ return entry;
205
+ });
206
+ return Array.isArray(value) ? rewritten : (rewritten[0] ?? value);
207
+ }
208
+ function loadSourceRows(inputPath) {
209
+ const resolved = path.resolve(inputPath);
210
+ let stats;
211
+ try {
212
+ stats = statSync(resolved);
213
+ }
214
+ catch (error) {
215
+ throw new CliError(`Cannot read --input path: ${inputPath}`, {
216
+ code: 'DATASET_SOURCE_UPLOAD_INPUT_UNREADABLE',
217
+ exitCode: 2,
218
+ details: caughtErrorMessage(error),
219
+ });
220
+ }
221
+ const files = [];
222
+ if (stats.isDirectory()) {
223
+ const walk = (dir) => {
224
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
225
+ const entryPath = path.join(dir, entry.name);
226
+ if (entry.isDirectory()) {
227
+ walk(entryPath);
228
+ }
229
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith('.json')) {
230
+ files.push(entryPath);
231
+ }
232
+ }
233
+ };
234
+ walk(resolved);
235
+ }
236
+ else {
237
+ files.push(resolved);
238
+ }
239
+ const rows = [];
240
+ for (const file of files) {
241
+ const text = readFileSync(file, 'utf8');
242
+ if (file.toLowerCase().endsWith('.jsonl')) {
243
+ for (const line of text.split(/\r?\n/u)) {
244
+ const trimmed = line.trim();
245
+ if (!trimmed) {
246
+ continue;
247
+ }
248
+ rows.push({ path: file, row: parseRowObject(trimmed, file) });
249
+ }
250
+ continue;
251
+ }
252
+ const parsed = parseJson(text, file);
253
+ if (Array.isArray(parsed)) {
254
+ for (const item of parsed) {
255
+ if (isRecord(item)) {
256
+ rows.push({ path: file, row: item });
257
+ }
258
+ }
259
+ }
260
+ else if (isRecord(parsed)) {
261
+ rows.push({ path: file, row: parsed });
262
+ }
263
+ else {
264
+ throw new CliError(`Source row is not a JSON object: ${file}`, {
265
+ code: 'DATASET_SOURCE_UPLOAD_INPUT_NOT_OBJECT',
266
+ exitCode: 2,
267
+ });
268
+ }
269
+ }
270
+ return rows;
271
+ }
272
+ function parseJson(text, file) {
273
+ try {
274
+ return JSON.parse(text);
275
+ }
276
+ catch (error) {
277
+ throw new CliError(`Cannot parse source JSON: ${file}`, {
278
+ code: 'DATASET_SOURCE_UPLOAD_INPUT_INVALID_JSON',
279
+ exitCode: 2,
280
+ details: caughtErrorMessage(error),
281
+ });
282
+ }
283
+ }
284
+ function parseRowObject(text, file) {
285
+ const parsed = parseJson(text, file);
286
+ if (!isRecord(parsed)) {
287
+ throw new CliError(`Source row is not a JSON object: ${file}`, {
288
+ code: 'DATASET_SOURCE_UPLOAD_INPUT_NOT_OBJECT',
289
+ exitCode: 2,
290
+ });
291
+ }
292
+ return parsed;
293
+ }
294
+ async function uploadObject(options) {
295
+ const encodedKey = options.key
296
+ .split('/')
297
+ .map((segment) => encodeURIComponent(segment))
298
+ .join('/');
299
+ const url = `${options.storageBaseUrl}/object/${options.bucket}/${encodedKey}`;
300
+ const response = await options.fetchImpl(url, {
301
+ method: 'POST',
302
+ headers: {
303
+ ...buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),
304
+ 'content-type': options.contentType,
305
+ 'x-upsert': 'true',
306
+ },
307
+ body: new Blob([options.body], { type: options.contentType }),
308
+ signal: AbortSignal.timeout(options.timeoutMs),
309
+ });
310
+ if (!response.ok) {
311
+ const detail = await response.text();
312
+ throw new CliError(`HTTP ${response.status} returned uploading ${options.key}`, {
313
+ code: 'DATASET_SOURCE_UPLOAD_OBJECT_FAILED',
314
+ exitCode: 1,
315
+ details: { url, body: detail },
316
+ });
317
+ }
318
+ }
319
+ async function verifyObject(options) {
320
+ const encodedKey = options.key
321
+ .split('/')
322
+ .map((segment) => encodeURIComponent(segment))
323
+ .join('/');
324
+ const url = `${options.storageBaseUrl}/object/sign/${options.bucket}/${encodedKey}`;
325
+ const response = await options.fetchImpl(url, {
326
+ method: 'POST',
327
+ headers: {
328
+ ...buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),
329
+ 'content-type': 'application/json',
330
+ },
331
+ body: JSON.stringify({ expiresIn: 60 }),
332
+ signal: AbortSignal.timeout(options.timeoutMs),
333
+ });
334
+ if (!response.ok) {
335
+ const detail = await response.text();
336
+ throw new CliError(`HTTP ${response.status} returned verifying ${options.key}`, {
337
+ code: 'DATASET_SOURCE_UPLOAD_VERIFY_FAILED',
338
+ exitCode: 1,
339
+ details: { url, body: detail },
340
+ });
341
+ }
342
+ }
343
+ export async function runDatasetSourceUploadAttachments(options) {
344
+ const now = options.now ?? new Date();
345
+ const generatedAtUtc = now.toISOString();
346
+ const timeoutMs = normalizeTimeoutMs(options.timeoutMs);
347
+ const commit = Boolean(options.commit);
348
+ const verify = Boolean(options.verify);
349
+ const bucket = trimToken(options.bucket) ?? DEFAULT_BUCKET;
350
+ const outDir = path.resolve(options.outDir ?? 'dataset-source-upload-attachments');
351
+ const externalDocsDir = path.resolve(options.externalDocsDir);
352
+ const fileIndex = buildExternalDocsIndex(externalDocsDir);
353
+ const sourceRows = loadSourceRows(options.inputPath);
354
+ const references = [];
355
+ const filesByKey = new Map();
356
+ const rewrittenRows = [];
357
+ let sourcesRewritten = 0;
358
+ for (const { row } of sourceRows) {
359
+ const identity = sourceIdentity(row);
360
+ const node = digitalFileNode(row);
361
+ const rawValue = node ? node.referenceToDigitalFile : undefined;
362
+ const entries = digitalFileEntries(rawValue);
363
+ if (entries.length === 0 || !node) {
364
+ rewrittenRows.push(row);
365
+ continue;
366
+ }
367
+ const resolved = resolveReferences(identity, entries, fileIndex, bucket);
368
+ let rowChanged = false;
369
+ for (const item of resolved) {
370
+ references.push(item.reference);
371
+ if (item.reference.status === 'rewritten' && item.reference.bucket_key) {
372
+ rowChanged = rowChanged || item.reference.rewritten_uri !== item.reference.original_uri;
373
+ const key = item.reference.bucket_key;
374
+ const existing = filesByKey.get(key);
375
+ const sourceLabel = `${identity.id ?? 'unknown'}@${identity.version ?? 'unknown'}`;
376
+ if (existing) {
377
+ existing.referenced_by.add(sourceLabel);
378
+ }
379
+ else {
380
+ const filePath = path.join(externalDocsDir, item.reference.resolved_file);
381
+ filesByKey.set(key, {
382
+ source_path: filePath,
383
+ size_bytes: statSync(filePath).size,
384
+ content_type: mimeTypeForFile(item.reference.resolved_file),
385
+ referenced_by: new Set([sourceLabel]),
386
+ });
387
+ }
388
+ }
389
+ }
390
+ if (rowChanged) {
391
+ sourcesRewritten += 1;
392
+ node.referenceToDigitalFile = rewriteDigitalFileValue(rawValue, resolved);
393
+ }
394
+ rewrittenRows.push(row);
395
+ }
396
+ const runtime = requireSupabaseRestRuntime(options.env);
397
+ const projectBaseUrl = deriveSupabaseProjectBaseUrl(runtime.apiBaseUrl);
398
+ const storageBaseUrl = `${projectBaseUrl}/storage/v1`;
399
+ const files = [];
400
+ let filesUploaded = 0;
401
+ let filesFailed = 0;
402
+ if (commit && filesByKey.size > 0) {
403
+ const session = await resolveSupabaseUserSession({
404
+ runtime,
405
+ fetchImpl: options.fetchImpl,
406
+ timeoutMs,
407
+ now,
408
+ });
409
+ for (const [key, info] of filesByKey) {
410
+ const base = {
411
+ bucket_key: key,
412
+ source_path: info.source_path,
413
+ size_bytes: info.size_bytes,
414
+ content_type: info.content_type,
415
+ referenced_by: [...info.referenced_by].sort(),
416
+ status: 'planned',
417
+ error: null,
418
+ };
419
+ try {
420
+ await uploadObject({
421
+ storageBaseUrl,
422
+ bucket,
423
+ key,
424
+ body: readFileBytes(info.source_path),
425
+ contentType: info.content_type,
426
+ publishableKey: runtime.publishableKey,
427
+ accessToken: session.accessToken,
428
+ fetchImpl: options.fetchImpl,
429
+ timeoutMs,
430
+ });
431
+ if (verify) {
432
+ await verifyObject({
433
+ storageBaseUrl,
434
+ bucket,
435
+ key,
436
+ publishableKey: runtime.publishableKey,
437
+ accessToken: session.accessToken,
438
+ fetchImpl: options.fetchImpl,
439
+ timeoutMs,
440
+ });
441
+ }
442
+ filesUploaded += 1;
443
+ files.push({ ...base, status: verify ? 'verified' : 'uploaded' });
444
+ }
445
+ catch (error) {
446
+ filesFailed += 1;
447
+ files.push({ ...base, status: 'failed', error: caughtErrorMessage(error) });
448
+ }
449
+ }
450
+ }
451
+ else {
452
+ for (const [key, info] of filesByKey) {
453
+ files.push({
454
+ bucket_key: key,
455
+ source_path: info.source_path,
456
+ size_bytes: info.size_bytes,
457
+ content_type: info.content_type,
458
+ referenced_by: [...info.referenced_by].sort(),
459
+ status: 'planned',
460
+ error: null,
461
+ });
462
+ }
463
+ }
464
+ const localRefs = references.filter((ref) => ref.kind === 'local').length;
465
+ const remoteRefs = references.filter((ref) => ref.kind === 'remote').length;
466
+ const unresolvedRefs = references.filter((ref) => ref.status === 'unresolved').length;
467
+ const artifacts = {
468
+ report: path.join(outDir, 'attachments-report.json'),
469
+ rewritten_sources: path.join(outDir, 'rewritten-sources.jsonl'),
470
+ };
471
+ const status = commit
472
+ ? filesFailed > 0
473
+ ? 'completed_with_failures'
474
+ : 'uploaded_attachments'
475
+ : unresolvedRefs > 0
476
+ ? 'completed_with_unresolved_refs'
477
+ : 'planned_attachment_upload';
478
+ const report = {
479
+ schema_version: 1,
480
+ generated_at_utc: generatedAtUtc,
481
+ status,
482
+ mode: commit ? 'commit' : 'dry-run',
483
+ bucket,
484
+ external_docs_dir: externalDocsDir,
485
+ summary: {
486
+ sources_scanned: sourceRows.length,
487
+ local_refs: localRefs,
488
+ remote_refs: remoteRefs,
489
+ unresolved_refs: unresolvedRefs,
490
+ files_planned: filesByKey.size,
491
+ files_uploaded: filesUploaded,
492
+ files_failed: filesFailed,
493
+ sources_rewritten: sourcesRewritten,
494
+ },
495
+ files,
496
+ references,
497
+ artifacts,
498
+ };
499
+ writeJsonArtifact(artifacts.report, report);
500
+ writeJsonLinesArtifact(artifacts.rewritten_sources, rewrittenRows);
501
+ return report;
502
+ }
503
+ export const __testInternals = {
504
+ buildExternalDocsIndex,
505
+ caughtErrorMessage,
506
+ classifyDigitalFileUri,
507
+ digitalFileBasename,
508
+ digitalFileEntries,
509
+ digitalFileNode,
510
+ entryUri,
511
+ loadSourceRows,
512
+ mimeTypeForFile,
513
+ normalizeTimeoutMs,
514
+ parseJson,
515
+ parseRowObject,
516
+ resolveReferences,
517
+ rewriteDigitalFileValue,
518
+ sourceIdentity,
519
+ trimToken,
520
+ withRewrittenUri,
521
+ };
522
+ //# sourceMappingURL=dataset-source-upload-attachments.js.map