@tiangong-lca/cli 0.1.8 → 0.1.10

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 (77) hide show
  1. package/README.md +18 -5
  2. package/assets/runtime/cli-runtime-descriptor.schema.json +138 -0
  3. package/assets/runtime/cli-runtime-expectation.schema.json +38 -0
  4. package/assets/runtime/runtime-bootstrap-lock.schema.json +254 -0
  5. package/assets/runtime/runtime-command-result.schema.json +95 -0
  6. package/assets/runtime/runtime-manifest.schema.json +380 -0
  7. package/dist/src/cli.d.ts +2 -0
  8. package/dist/src/cli.js +48 -2
  9. package/dist/src/cli.js.map +1 -1
  10. package/dist/src/lib/dataset-import-lca.js +2 -2
  11. package/dist/src/lib/dataset-import-lca.js.map +1 -1
  12. package/dist/src/lib/dataset-support-cache.d.ts +48 -0
  13. package/dist/src/lib/dataset-support-cache.js +265 -0
  14. package/dist/src/lib/dataset-support-cache.js.map +1 -0
  15. package/dist/src/lib/runtime/archive-writer.d.ts +7 -0
  16. package/dist/src/lib/runtime/archive-writer.js +89 -0
  17. package/dist/src/lib/runtime/archive-writer.js.map +1 -0
  18. package/dist/src/lib/runtime/archive.d.ts +2 -0
  19. package/dist/src/lib/runtime/archive.js +122 -0
  20. package/dist/src/lib/runtime/archive.js.map +1 -0
  21. package/dist/src/lib/runtime/command.d.ts +8 -0
  22. package/dist/src/lib/runtime/command.js +57 -0
  23. package/dist/src/lib/runtime/command.js.map +1 -0
  24. package/dist/src/lib/runtime/descriptor.d.ts +11 -0
  25. package/dist/src/lib/runtime/descriptor.js +126 -0
  26. package/dist/src/lib/runtime/descriptor.js.map +1 -0
  27. package/dist/src/lib/runtime/download.d.ts +9 -0
  28. package/dist/src/lib/runtime/download.js +118 -0
  29. package/dist/src/lib/runtime/download.js.map +1 -0
  30. package/dist/src/lib/runtime/exec-command.d.ts +7 -0
  31. package/dist/src/lib/runtime/exec-command.js +83 -0
  32. package/dist/src/lib/runtime/exec-command.js.map +1 -0
  33. package/dist/src/lib/runtime/execute.d.ts +11 -0
  34. package/dist/src/lib/runtime/execute.js +125 -0
  35. package/dist/src/lib/runtime/execute.js.map +1 -0
  36. package/dist/src/lib/runtime/files.d.ts +7 -0
  37. package/dist/src/lib/runtime/files.js +91 -0
  38. package/dist/src/lib/runtime/files.js.map +1 -0
  39. package/dist/src/lib/runtime/host.d.ts +8 -0
  40. package/dist/src/lib/runtime/host.js +37 -0
  41. package/dist/src/lib/runtime/host.js.map +1 -0
  42. package/dist/src/lib/runtime/leases.d.ts +12 -0
  43. package/dist/src/lib/runtime/leases.js +72 -0
  44. package/dist/src/lib/runtime/leases.js.map +1 -0
  45. package/dist/src/lib/runtime/managed-command.d.ts +6 -0
  46. package/dist/src/lib/runtime/managed-command.js +99 -0
  47. package/dist/src/lib/runtime/managed-command.js.map +1 -0
  48. package/dist/src/lib/runtime/manager.d.ts +33 -0
  49. package/dist/src/lib/runtime/manager.js +196 -0
  50. package/dist/src/lib/runtime/manager.js.map +1 -0
  51. package/dist/src/lib/runtime/manifest-types.d.ts +73 -0
  52. package/dist/src/lib/runtime/manifest-types.js +4 -0
  53. package/dist/src/lib/runtime/manifest-types.js.map +1 -0
  54. package/dist/src/lib/runtime/manifest-values.d.ts +15 -0
  55. package/dist/src/lib/runtime/manifest-values.js +124 -0
  56. package/dist/src/lib/runtime/manifest-values.js.map +1 -0
  57. package/dist/src/lib/runtime/manifest.d.ts +7 -0
  58. package/dist/src/lib/runtime/manifest.js +220 -0
  59. package/dist/src/lib/runtime/manifest.js.map +1 -0
  60. package/dist/src/lib/runtime/process.d.ts +3 -0
  61. package/dist/src/lib/runtime/process.js +55 -0
  62. package/dist/src/lib/runtime/process.js.map +1 -0
  63. package/dist/src/lib/runtime/storage.d.ts +8 -0
  64. package/dist/src/lib/runtime/storage.js +142 -0
  65. package/dist/src/lib/runtime/storage.js.map +1 -0
  66. package/dist/src/lib/runtime/types.d.ts +45 -0
  67. package/dist/src/lib/runtime/types.js +9 -0
  68. package/dist/src/lib/runtime/types.js.map +1 -0
  69. package/dist/src/lib/supabase-data-api-contract.d.ts +4 -4
  70. package/dist/src/lib/supabase-data-api-contract.js +2 -0
  71. package/dist/src/lib/supabase-data-api-contract.js.map +1 -1
  72. package/dist/src/main.js +13 -1
  73. package/dist/src/main.js.map +1 -1
  74. package/dist/src/runtime.d.ts +15 -0
  75. package/dist/src/runtime.js +22 -0
  76. package/dist/src/runtime.js.map +1 -0
  77. package/package.json +8 -2
@@ -328,14 +328,14 @@ function resolveTidasBinary(explicitValue, env) {
328
328
  }
329
329
  function assertSupportedPlatform(platform, arch) {
330
330
  const supported = (platform === 'linux' && (arch === 'x64' || arch === 'arm64')) ||
331
- (platform === 'darwin' && (arch === 'x64' || arch === 'arm64')) ||
331
+ (platform === 'darwin' && arch === 'arm64') ||
332
332
  (platform === 'win32' && arch === 'x64');
333
333
  if (!supported) {
334
334
  throw new CliError(`No supported Rust tidas artifact exists for ${platform}/${arch}.`, {
335
335
  code: 'DATASET_IMPORT_LCA_PLATFORM_UNSUPPORTED',
336
336
  exitCode: 69,
337
337
  details: {
338
- supported: ['linux/x64', 'linux/arm64', 'darwin/x64', 'darwin/arm64', 'win32/x64'],
338
+ supported: ['linux/x64', 'linux/arm64', 'darwin/arm64', 'win32/x64'],
339
339
  },
340
340
  });
341
341
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dataset-import-lca.js","sourceRoot":"","sources":["../../../src/lib/dataset-import-lca.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { spawnSync, type SpawnSyncReturns } from 'node:child_process';\nimport { CliError } from './errors.js';\n\nconst OPERATION_REPORT_SCHEMA = 'tidas.operation-report.v1';\nconst INVOCATION_CONTEXT_SCHEMA = 'tidas.invocation-context.v1';\nconst IMPORT_REPORT_SCHEMA = 'tidas.import-execution-report.v1';\nconst SUPPORTED_TIDAS_VERSION = /^0\\.2\\.\\d+$/u;\n\nconst EXIT_CODES = {\n success: 0,\n 'data-issues': 2,\n usage: 64,\n unavailable: 69,\n internal: 70,\n io: 74,\n cancelled: 130,\n} as const;\n\nconst OPERATION_STATUSES = ['succeeded', 'completed-with-issues', 'failed', 'cancelled'] as const;\nconst COMPLETENESS_VALUES = ['complete', 'partial', 'not-started'] as const;\nconst SOURCE_FORMATS = [\n 'ecospold1',\n 'ecospold2',\n 'simapro-csv',\n 'openlca-jsonld',\n 'openlca-process-xlsx',\n 'ilcd',\n] as const;\n\ntype TidasExitClass = keyof typeof EXIT_CODES;\ntype TidasOperationStatus = (typeof OPERATION_STATUSES)[number];\ntype TidasCompleteness = (typeof COMPLETENESS_VALUES)[number];\nexport type DatasetImportLcaTarget = 'tidas' | 'ilcd' | 'both';\nexport type DatasetImportLcaSourceFormat = (typeof SOURCE_FORMATS)[number];\n\ntype TidasOperationReport = {\n schema_version: typeof OPERATION_REPORT_SCHEMA;\n command: 'version' | 'import';\n status: TidasOperationStatus;\n exit_class: TidasExitClass;\n completeness: TidasCompleteness;\n invocation: {\n schema_version: typeof INVOCATION_CONTEXT_SCHEMA;\n input_policy: 'explicit-path-or-dash';\n report_destination: 'stdout' | 'file';\n diagnostic_destination: 'stderr';\n [key: string]: unknown;\n };\n summary: Record<string, unknown>;\n diagnostics: unknown[];\n artifacts: unknown[];\n next_actions: unknown[];\n};\n\nexport type DatasetImportLcaReport = {\n schema_version: 'tiangong-lca.dataset-import-lca-report.v2';\n status: TidasOperationStatus;\n exit_class: TidasExitClass;\n exit_code: number;\n generated_at_utc: string;\n input_path: string;\n output_dir: string;\n from_format: DatasetImportLcaSourceFormat | 'auto';\n target: DatasetImportLcaTarget;\n tidas: {\n executable: string;\n version: string;\n operation_report_schema: typeof OPERATION_REPORT_SCHEMA;\n import_report_schema: typeof IMPORT_REPORT_SCHEMA;\n };\n command: {\n args: string[];\n cwd: string;\n stderr: string;\n };\n operation_report: TidasOperationReport;\n files: {\n report: string | null;\n native_import_report: string;\n issues: string;\n tidas_dir: string | null;\n ilcd_dir: string | null;\n mapping_csv: string | null;\n process_bundles_dir: string | null;\n };\n};\n\nexport type TidasProcessResult = {\n status: number | null;\n signal: NodeJS.Signals | null;\n stdout: string;\n stderr: string;\n error?: Error | undefined;\n};\n\nexport type RunDatasetImportLcaConvertOptions = {\n inputPath: string;\n outputDir: string;\n fromFormat?: string | undefined;\n target?: string | undefined;\n reportPath?: string | undefined;\n writeMapping?: boolean | undefined;\n processBundles?: boolean | undefined;\n failOnWarning?: boolean | undefined;\n maxEntryMib?: number | undefined;\n memoryBudgetMib?: number | undefined;\n queueCapacity?: number | undefined;\n tidasBin?: string | undefined;\n tidasConfig?: string | undefined;\n env?: NodeJS.ProcessEnv | undefined;\n cwd?: string | undefined;\n platform?: NodeJS.Platform | undefined;\n arch?: string | undefined;\n now?: Date | undefined;\n spawnImpl?: typeof spawnSync | undefined;\n};\n\nexport async function runDatasetImportLcaConvert(\n options: RunDatasetImportLcaConvertOptions,\n): Promise<DatasetImportLcaReport> {\n const inputPath = requireInputPath(options.inputPath);\n const outputDir = requireOutputDir(options.outputDir);\n const fromFormat = normalizeSourceFormat(options.fromFormat);\n const target = normalizeTarget(options.target);\n const env = options.env ?? process.env;\n const executable = resolveTidasBinary(options.tidasBin, env);\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const reportPath = options.reportPath?.trim() ? path.resolve(options.reportPath) : null;\n const configPath = options.tidasConfig?.trim() ? path.resolve(options.tidasConfig) : null;\n const spawnImpl = [spawnSync, options.spawnImpl].filter(Boolean).at(-1) as typeof spawnSync;\n\n assertSupportedPlatform(options.platform ?? process.platform, options.arch ?? process.arch);\n requirePositiveInteger('--max-entry-mib', options.maxEntryMib);\n requirePositiveInteger('--memory-budget-mib', options.memoryBudgetMib);\n requirePositiveInteger('--queue-capacity', options.queueCapacity);\n\n const versionArgs = ['version', '--format', 'json', '--progress', 'never'];\n const versionRun = runTidas(spawnImpl, executable, versionArgs, cwd, env);\n const versionReport = parseOperationReport(readProcessReport(versionRun, null), 'version');\n assertExitContract(versionRun, versionReport);\n const version = readCompatibleVersion(versionReport);\n\n const commandArgs = buildImportArgs({\n inputPath,\n outputDir,\n fromFormat,\n target,\n reportPath,\n configPath,\n writeMapping: Boolean(options.writeMapping),\n processBundles: options.processBundles !== false,\n failOnWarning: Boolean(options.failOnWarning),\n maxEntryMib: options.maxEntryMib,\n memoryBudgetMib: options.memoryBudgetMib,\n queueCapacity: options.queueCapacity,\n });\n const importRun = runTidas(spawnImpl, executable, commandArgs, cwd, env);\n const operationReport = parseOperationReport(readProcessReport(importRun, reportPath), 'import');\n assertExitContract(importRun, operationReport);\n assertImportContract(operationReport);\n\n return {\n schema_version: 'tiangong-lca.dataset-import-lca-report.v2',\n status: operationReport.status,\n exit_class: operationReport.exit_class,\n exit_code: EXIT_CODES[operationReport.exit_class],\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n input_path: inputPath,\n output_dir: outputDir,\n from_format: fromFormat,\n target,\n tidas: {\n executable,\n version,\n operation_report_schema: OPERATION_REPORT_SCHEMA,\n import_report_schema: IMPORT_REPORT_SCHEMA,\n },\n command: {\n args: commandArgs,\n cwd,\n stderr: importRun.stderr,\n },\n operation_report: operationReport,\n files: {\n report: reportPath,\n native_import_report: path.join(outputDir, 'import-report.json'),\n issues: path.join(outputDir, 'issues.jsonl'),\n tidas_dir:\n operationReport.completeness === 'complete' && (target === 'tidas' || target === 'both')\n ? path.join(outputDir, 'tidas')\n : null,\n ilcd_dir:\n operationReport.completeness === 'complete' && (target === 'ilcd' || target === 'both')\n ? path.join(outputDir, 'ilcd')\n : null,\n mapping_csv:\n operationReport.completeness === 'complete' && options.writeMapping\n ? path.join(outputDir, 'mapping.csv.gz')\n : null,\n process_bundles_dir:\n operationReport.completeness === 'complete' && options.processBundles !== false\n ? path.join(outputDir, 'process-bundles')\n : null,\n },\n };\n}\n\nfunction buildImportArgs(options: {\n inputPath: string;\n outputDir: string;\n fromFormat: DatasetImportLcaSourceFormat | 'auto';\n target: DatasetImportLcaTarget;\n reportPath: string | null;\n configPath: string | null;\n writeMapping: boolean;\n processBundles: boolean;\n failOnWarning: boolean;\n maxEntryMib: number | undefined;\n memoryBudgetMib: number | undefined;\n queueCapacity: number | undefined;\n}): string[] {\n const args = [\n 'import',\n options.inputPath,\n '--output',\n options.outputDir,\n '--target',\n options.target,\n '--format',\n 'json',\n '--progress',\n 'never',\n ];\n if (options.fromFormat !== 'auto') {\n args.push('--from-format', options.fromFormat);\n }\n if (options.reportPath) {\n args.push('--report', options.reportPath);\n }\n if (options.configPath) {\n args.push('--config', options.configPath);\n }\n if (options.writeMapping) {\n args.push('--write-mapping');\n }\n if (!options.processBundles) {\n args.push('--no-process-bundles');\n }\n if (options.failOnWarning) {\n args.push('--fail-on-warning');\n }\n if (options.maxEntryMib !== undefined) {\n args.push('--max-entry-mib', String(options.maxEntryMib));\n }\n if (options.memoryBudgetMib !== undefined) {\n args.push('--memory-budget-mib', String(options.memoryBudgetMib));\n }\n if (options.queueCapacity !== undefined) {\n args.push('--queue-capacity', String(options.queueCapacity));\n }\n return args;\n}\n\nfunction runTidas(\n spawnImpl: typeof spawnSync,\n executable: string,\n args: string[],\n cwd: string,\n env: NodeJS.ProcessEnv,\n): TidasProcessResult {\n const run = spawnImpl(executable, args, {\n cwd,\n env,\n encoding: 'utf8',\n windowsHide: true,\n }) as SpawnSyncReturns<string>;\n if (run.error) {\n throw new CliError(`Could not execute the Rust tidas binary: ${run.error.message}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_EXEC_FAILED',\n exitCode: 69,\n details: { executable },\n });\n }\n return {\n status: run.status,\n signal: run.signal,\n stdout: run.stdout ?? '',\n stderr: run.stderr ?? '',\n };\n}\n\nfunction readProcessReport(run: TidasProcessResult, reportPath: string | null): string {\n const cancelled = run.status === 130 || run.signal === 'SIGINT';\n if (reportPath) {\n if (!existsSync(reportPath)) {\n if (cancelled) {\n throw new CliError(\n 'tidas import was cancelled before a complete machine report was available.',\n {\n code: 'DATASET_IMPORT_LCA_CANCELLED',\n exitCode: 130,\n details: { signal: run.signal, stderr: run.stderr },\n },\n );\n }\n throw new CliError(`tidas did not write the requested machine report: ${reportPath}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_REPORT_MISSING',\n exitCode: 70,\n });\n }\n return readFileSync(reportPath, 'utf8');\n }\n if (!run.stdout.trim()) {\n throw new CliError(\n cancelled\n ? 'tidas import was cancelled before a complete machine report was available.'\n : 'tidas did not emit a machine-readable operation report.',\n {\n code: cancelled\n ? 'DATASET_IMPORT_LCA_CANCELLED'\n : 'DATASET_IMPORT_LCA_TIDAS_REPORT_MISSING',\n exitCode: cancelled ? 130 : 70,\n details: { signal: run.signal, stderr: run.stderr },\n },\n );\n }\n return run.stdout;\n}\n\nfunction parseOperationReport(text: string, command: 'version' | 'import'): TidasOperationReport {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch (error) {\n throw new CliError('tidas emitted invalid JSON instead of its machine operation report.', {\n code: 'DATASET_IMPORT_LCA_TIDAS_REPORT_INVALID',\n exitCode: 70,\n details: String(error),\n });\n }\n if (\n !isRecord(value) ||\n value.schema_version !== OPERATION_REPORT_SCHEMA ||\n value.command !== command ||\n !includesValue(OPERATION_STATUSES, value.status) ||\n !isExitClass(value.exit_class) ||\n !includesValue(COMPLETENESS_VALUES, value.completeness) ||\n !isRecord(value.invocation) ||\n value.invocation.schema_version !== INVOCATION_CONTEXT_SCHEMA ||\n value.invocation.input_policy !== 'explicit-path-or-dash' ||\n !['stdout', 'file'].includes(String(value.invocation.report_destination)) ||\n value.invocation.diagnostic_destination !== 'stderr' ||\n !isRecord(value.summary) ||\n !Array.isArray(value.diagnostics) ||\n !Array.isArray(value.artifacts) ||\n !Array.isArray(value.next_actions)\n ) {\n throw new CliError(\n `Incompatible tidas ${command} machine contract; expected ${OPERATION_REPORT_SCHEMA}.`,\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_CONTRACT_INCOMPATIBLE',\n exitCode: 69,\n },\n );\n }\n return value as TidasOperationReport;\n}\n\nfunction assertExitContract(run: TidasProcessResult, report: TidasOperationReport): void {\n const expected = EXIT_CODES[report.exit_class];\n if (run.status !== expected) {\n throw new CliError(\n `tidas exit status ${String(run.status)} disagrees with report exit class ${report.exit_class} (${expected}).`,\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_EXIT_MISMATCH',\n exitCode: 70,\n },\n );\n }\n}\n\nfunction readCompatibleVersion(report: TidasOperationReport): string {\n if (\n report.status !== 'succeeded' ||\n report.exit_class !== 'success' ||\n report.completeness !== 'complete' ||\n report.summary.operation_report_schema !== OPERATION_REPORT_SCHEMA ||\n typeof report.summary.binary_version !== 'string' ||\n !SUPPORTED_TIDAS_VERSION.test(report.summary.binary_version)\n ) {\n throw new CliError(\n 'Incompatible tidas binary: dataset import requires a stable contract-compatible 0.2.x release.',\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_VERSION_INCOMPATIBLE',\n exitCode: 69,\n details: { binary_version: report.summary.binary_version ?? null },\n },\n );\n }\n return report.summary.binary_version;\n}\n\nfunction assertImportContract(report: TidasOperationReport): void {\n if (report.status === 'succeeded' || report.status === 'completed-with-issues') {\n const importSummary = report.summary.import;\n if (!isRecord(importSummary) || importSummary.schema_version !== IMPORT_REPORT_SCHEMA) {\n throw new CliError(`Incompatible tidas import summary; expected ${IMPORT_REPORT_SCHEMA}.`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_IMPORT_CONTRACT_INCOMPATIBLE',\n exitCode: 69,\n });\n }\n }\n}\n\nfunction requireInputPath(value: string): string {\n if (!value?.trim()) {\n throw new CliError('Missing required --input value.', {\n code: 'DATASET_IMPORT_LCA_INPUT_REQUIRED',\n exitCode: 2,\n });\n }\n const resolved = path.resolve(value);\n if (!existsSync(resolved)) {\n throw new CliError(`Input path not found: ${resolved}`, {\n code: 'DATASET_IMPORT_LCA_INPUT_NOT_FOUND',\n exitCode: 2,\n });\n }\n return resolved;\n}\n\nfunction requireOutputDir(value: string): string {\n if (!value?.trim()) {\n throw new CliError('Missing required --output-dir value.', {\n code: 'DATASET_IMPORT_LCA_OUTPUT_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n return path.resolve(value);\n}\n\nfunction normalizeSourceFormat(value: string | undefined): DatasetImportLcaSourceFormat | 'auto' {\n const format = value?.trim() || 'auto';\n if (format === 'auto' || includesValue(SOURCE_FORMATS, format)) {\n return format;\n }\n throw new CliError(`--from-format must be auto or one of: ${SOURCE_FORMATS.join(', ')}.`, {\n code: 'DATASET_IMPORT_LCA_SOURCE_FORMAT_INVALID',\n exitCode: 2,\n });\n}\n\nfunction normalizeTarget(value: string | undefined): DatasetImportLcaTarget {\n const target = value?.trim() || 'tidas';\n if (target === 'tidas' || target === 'ilcd' || target === 'both') {\n return target;\n }\n throw new CliError(\"--target must be 'tidas', 'ilcd', or 'both'.\", {\n code: 'DATASET_IMPORT_LCA_TARGET_INVALID',\n exitCode: 2,\n });\n}\n\nfunction resolveTidasBinary(explicitValue: string | undefined, env: NodeJS.ProcessEnv): string {\n const candidate = explicitValue?.trim() || env.TIDAS_BIN?.trim() || 'tidas';\n if (path.isAbsolute(candidate) || candidate.includes('/') || candidate.includes('\\\\')) {\n const resolved = path.resolve(candidate);\n if (!existsSync(resolved)) {\n throw new CliError(`Rust tidas binary not found: ${resolved}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_NOT_FOUND',\n exitCode: 69,\n });\n }\n return resolved;\n }\n return candidate;\n}\n\nfunction assertSupportedPlatform(platform: NodeJS.Platform, arch: string): void {\n const supported =\n (platform === 'linux' && (arch === 'x64' || arch === 'arm64')) ||\n (platform === 'darwin' && (arch === 'x64' || arch === 'arm64')) ||\n (platform === 'win32' && arch === 'x64');\n if (!supported) {\n throw new CliError(`No supported Rust tidas artifact exists for ${platform}/${arch}.`, {\n code: 'DATASET_IMPORT_LCA_PLATFORM_UNSUPPORTED',\n exitCode: 69,\n details: {\n supported: ['linux/x64', 'linux/arm64', 'darwin/x64', 'darwin/arm64', 'win32/x64'],\n },\n });\n }\n}\n\nfunction requirePositiveInteger(flag: string, value: number | undefined): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new CliError(`${flag} must be a positive integer.`, {\n code: 'DATASET_IMPORT_LCA_RUNTIME_BOUND_INVALID',\n exitCode: 2,\n });\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction includesValue<T extends readonly string[]>(values: T, value: unknown): value is T[number] {\n return typeof value === 'string' && values.includes(value);\n}\n\nfunction isExitClass(value: unknown): value is TidasExitClass {\n return typeof value === 'string' && Object.hasOwn(EXIT_CODES, value);\n}\n\nexport const __testInternals = {\n assertImportContract,\n assertSupportedPlatform,\n buildImportArgs,\n normalizeSourceFormat,\n normalizeTarget,\n parseOperationReport,\n readCompatibleVersion,\n readProcessReport,\n requirePositiveInteger,\n resolveTidasBinary,\n};\n"]}
1
+ {"version":3,"file":"dataset-import-lca.js","sourceRoot":"","sources":["../../../src/lib/dataset-import-lca.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { spawnSync, type SpawnSyncReturns } from 'node:child_process';\nimport { CliError } from './errors.js';\n\nconst OPERATION_REPORT_SCHEMA = 'tidas.operation-report.v1';\nconst INVOCATION_CONTEXT_SCHEMA = 'tidas.invocation-context.v1';\nconst IMPORT_REPORT_SCHEMA = 'tidas.import-execution-report.v1';\nconst SUPPORTED_TIDAS_VERSION = /^0\\.2\\.\\d+$/u;\n\nconst EXIT_CODES = {\n success: 0,\n 'data-issues': 2,\n usage: 64,\n unavailable: 69,\n internal: 70,\n io: 74,\n cancelled: 130,\n} as const;\n\nconst OPERATION_STATUSES = ['succeeded', 'completed-with-issues', 'failed', 'cancelled'] as const;\nconst COMPLETENESS_VALUES = ['complete', 'partial', 'not-started'] as const;\nconst SOURCE_FORMATS = [\n 'ecospold1',\n 'ecospold2',\n 'simapro-csv',\n 'openlca-jsonld',\n 'openlca-process-xlsx',\n 'ilcd',\n] as const;\n\ntype TidasExitClass = keyof typeof EXIT_CODES;\ntype TidasOperationStatus = (typeof OPERATION_STATUSES)[number];\ntype TidasCompleteness = (typeof COMPLETENESS_VALUES)[number];\nexport type DatasetImportLcaTarget = 'tidas' | 'ilcd' | 'both';\nexport type DatasetImportLcaSourceFormat = (typeof SOURCE_FORMATS)[number];\n\ntype TidasOperationReport = {\n schema_version: typeof OPERATION_REPORT_SCHEMA;\n command: 'version' | 'import';\n status: TidasOperationStatus;\n exit_class: TidasExitClass;\n completeness: TidasCompleteness;\n invocation: {\n schema_version: typeof INVOCATION_CONTEXT_SCHEMA;\n input_policy: 'explicit-path-or-dash';\n report_destination: 'stdout' | 'file';\n diagnostic_destination: 'stderr';\n [key: string]: unknown;\n };\n summary: Record<string, unknown>;\n diagnostics: unknown[];\n artifacts: unknown[];\n next_actions: unknown[];\n};\n\nexport type DatasetImportLcaReport = {\n schema_version: 'tiangong-lca.dataset-import-lca-report.v2';\n status: TidasOperationStatus;\n exit_class: TidasExitClass;\n exit_code: number;\n generated_at_utc: string;\n input_path: string;\n output_dir: string;\n from_format: DatasetImportLcaSourceFormat | 'auto';\n target: DatasetImportLcaTarget;\n tidas: {\n executable: string;\n version: string;\n operation_report_schema: typeof OPERATION_REPORT_SCHEMA;\n import_report_schema: typeof IMPORT_REPORT_SCHEMA;\n };\n command: {\n args: string[];\n cwd: string;\n stderr: string;\n };\n operation_report: TidasOperationReport;\n files: {\n report: string | null;\n native_import_report: string;\n issues: string;\n tidas_dir: string | null;\n ilcd_dir: string | null;\n mapping_csv: string | null;\n process_bundles_dir: string | null;\n };\n};\n\nexport type TidasProcessResult = {\n status: number | null;\n signal: NodeJS.Signals | null;\n stdout: string;\n stderr: string;\n error?: Error | undefined;\n};\n\nexport type RunDatasetImportLcaConvertOptions = {\n inputPath: string;\n outputDir: string;\n fromFormat?: string | undefined;\n target?: string | undefined;\n reportPath?: string | undefined;\n writeMapping?: boolean | undefined;\n processBundles?: boolean | undefined;\n failOnWarning?: boolean | undefined;\n maxEntryMib?: number | undefined;\n memoryBudgetMib?: number | undefined;\n queueCapacity?: number | undefined;\n tidasBin?: string | undefined;\n tidasConfig?: string | undefined;\n env?: NodeJS.ProcessEnv | undefined;\n cwd?: string | undefined;\n platform?: NodeJS.Platform | undefined;\n arch?: string | undefined;\n now?: Date | undefined;\n spawnImpl?: typeof spawnSync | undefined;\n};\n\nexport async function runDatasetImportLcaConvert(\n options: RunDatasetImportLcaConvertOptions,\n): Promise<DatasetImportLcaReport> {\n const inputPath = requireInputPath(options.inputPath);\n const outputDir = requireOutputDir(options.outputDir);\n const fromFormat = normalizeSourceFormat(options.fromFormat);\n const target = normalizeTarget(options.target);\n const env = options.env ?? process.env;\n const executable = resolveTidasBinary(options.tidasBin, env);\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const reportPath = options.reportPath?.trim() ? path.resolve(options.reportPath) : null;\n const configPath = options.tidasConfig?.trim() ? path.resolve(options.tidasConfig) : null;\n const spawnImpl = [spawnSync, options.spawnImpl].filter(Boolean).at(-1) as typeof spawnSync;\n\n assertSupportedPlatform(options.platform ?? process.platform, options.arch ?? process.arch);\n requirePositiveInteger('--max-entry-mib', options.maxEntryMib);\n requirePositiveInteger('--memory-budget-mib', options.memoryBudgetMib);\n requirePositiveInteger('--queue-capacity', options.queueCapacity);\n\n const versionArgs = ['version', '--format', 'json', '--progress', 'never'];\n const versionRun = runTidas(spawnImpl, executable, versionArgs, cwd, env);\n const versionReport = parseOperationReport(readProcessReport(versionRun, null), 'version');\n assertExitContract(versionRun, versionReport);\n const version = readCompatibleVersion(versionReport);\n\n const commandArgs = buildImportArgs({\n inputPath,\n outputDir,\n fromFormat,\n target,\n reportPath,\n configPath,\n writeMapping: Boolean(options.writeMapping),\n processBundles: options.processBundles !== false,\n failOnWarning: Boolean(options.failOnWarning),\n maxEntryMib: options.maxEntryMib,\n memoryBudgetMib: options.memoryBudgetMib,\n queueCapacity: options.queueCapacity,\n });\n const importRun = runTidas(spawnImpl, executable, commandArgs, cwd, env);\n const operationReport = parseOperationReport(readProcessReport(importRun, reportPath), 'import');\n assertExitContract(importRun, operationReport);\n assertImportContract(operationReport);\n\n return {\n schema_version: 'tiangong-lca.dataset-import-lca-report.v2',\n status: operationReport.status,\n exit_class: operationReport.exit_class,\n exit_code: EXIT_CODES[operationReport.exit_class],\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n input_path: inputPath,\n output_dir: outputDir,\n from_format: fromFormat,\n target,\n tidas: {\n executable,\n version,\n operation_report_schema: OPERATION_REPORT_SCHEMA,\n import_report_schema: IMPORT_REPORT_SCHEMA,\n },\n command: {\n args: commandArgs,\n cwd,\n stderr: importRun.stderr,\n },\n operation_report: operationReport,\n files: {\n report: reportPath,\n native_import_report: path.join(outputDir, 'import-report.json'),\n issues: path.join(outputDir, 'issues.jsonl'),\n tidas_dir:\n operationReport.completeness === 'complete' && (target === 'tidas' || target === 'both')\n ? path.join(outputDir, 'tidas')\n : null,\n ilcd_dir:\n operationReport.completeness === 'complete' && (target === 'ilcd' || target === 'both')\n ? path.join(outputDir, 'ilcd')\n : null,\n mapping_csv:\n operationReport.completeness === 'complete' && options.writeMapping\n ? path.join(outputDir, 'mapping.csv.gz')\n : null,\n process_bundles_dir:\n operationReport.completeness === 'complete' && options.processBundles !== false\n ? path.join(outputDir, 'process-bundles')\n : null,\n },\n };\n}\n\nfunction buildImportArgs(options: {\n inputPath: string;\n outputDir: string;\n fromFormat: DatasetImportLcaSourceFormat | 'auto';\n target: DatasetImportLcaTarget;\n reportPath: string | null;\n configPath: string | null;\n writeMapping: boolean;\n processBundles: boolean;\n failOnWarning: boolean;\n maxEntryMib: number | undefined;\n memoryBudgetMib: number | undefined;\n queueCapacity: number | undefined;\n}): string[] {\n const args = [\n 'import',\n options.inputPath,\n '--output',\n options.outputDir,\n '--target',\n options.target,\n '--format',\n 'json',\n '--progress',\n 'never',\n ];\n if (options.fromFormat !== 'auto') {\n args.push('--from-format', options.fromFormat);\n }\n if (options.reportPath) {\n args.push('--report', options.reportPath);\n }\n if (options.configPath) {\n args.push('--config', options.configPath);\n }\n if (options.writeMapping) {\n args.push('--write-mapping');\n }\n if (!options.processBundles) {\n args.push('--no-process-bundles');\n }\n if (options.failOnWarning) {\n args.push('--fail-on-warning');\n }\n if (options.maxEntryMib !== undefined) {\n args.push('--max-entry-mib', String(options.maxEntryMib));\n }\n if (options.memoryBudgetMib !== undefined) {\n args.push('--memory-budget-mib', String(options.memoryBudgetMib));\n }\n if (options.queueCapacity !== undefined) {\n args.push('--queue-capacity', String(options.queueCapacity));\n }\n return args;\n}\n\nfunction runTidas(\n spawnImpl: typeof spawnSync,\n executable: string,\n args: string[],\n cwd: string,\n env: NodeJS.ProcessEnv,\n): TidasProcessResult {\n const run = spawnImpl(executable, args, {\n cwd,\n env,\n encoding: 'utf8',\n windowsHide: true,\n }) as SpawnSyncReturns<string>;\n if (run.error) {\n throw new CliError(`Could not execute the Rust tidas binary: ${run.error.message}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_EXEC_FAILED',\n exitCode: 69,\n details: { executable },\n });\n }\n return {\n status: run.status,\n signal: run.signal,\n stdout: run.stdout ?? '',\n stderr: run.stderr ?? '',\n };\n}\n\nfunction readProcessReport(run: TidasProcessResult, reportPath: string | null): string {\n const cancelled = run.status === 130 || run.signal === 'SIGINT';\n if (reportPath) {\n if (!existsSync(reportPath)) {\n if (cancelled) {\n throw new CliError(\n 'tidas import was cancelled before a complete machine report was available.',\n {\n code: 'DATASET_IMPORT_LCA_CANCELLED',\n exitCode: 130,\n details: { signal: run.signal, stderr: run.stderr },\n },\n );\n }\n throw new CliError(`tidas did not write the requested machine report: ${reportPath}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_REPORT_MISSING',\n exitCode: 70,\n });\n }\n return readFileSync(reportPath, 'utf8');\n }\n if (!run.stdout.trim()) {\n throw new CliError(\n cancelled\n ? 'tidas import was cancelled before a complete machine report was available.'\n : 'tidas did not emit a machine-readable operation report.',\n {\n code: cancelled\n ? 'DATASET_IMPORT_LCA_CANCELLED'\n : 'DATASET_IMPORT_LCA_TIDAS_REPORT_MISSING',\n exitCode: cancelled ? 130 : 70,\n details: { signal: run.signal, stderr: run.stderr },\n },\n );\n }\n return run.stdout;\n}\n\nfunction parseOperationReport(text: string, command: 'version' | 'import'): TidasOperationReport {\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch (error) {\n throw new CliError('tidas emitted invalid JSON instead of its machine operation report.', {\n code: 'DATASET_IMPORT_LCA_TIDAS_REPORT_INVALID',\n exitCode: 70,\n details: String(error),\n });\n }\n if (\n !isRecord(value) ||\n value.schema_version !== OPERATION_REPORT_SCHEMA ||\n value.command !== command ||\n !includesValue(OPERATION_STATUSES, value.status) ||\n !isExitClass(value.exit_class) ||\n !includesValue(COMPLETENESS_VALUES, value.completeness) ||\n !isRecord(value.invocation) ||\n value.invocation.schema_version !== INVOCATION_CONTEXT_SCHEMA ||\n value.invocation.input_policy !== 'explicit-path-or-dash' ||\n !['stdout', 'file'].includes(String(value.invocation.report_destination)) ||\n value.invocation.diagnostic_destination !== 'stderr' ||\n !isRecord(value.summary) ||\n !Array.isArray(value.diagnostics) ||\n !Array.isArray(value.artifacts) ||\n !Array.isArray(value.next_actions)\n ) {\n throw new CliError(\n `Incompatible tidas ${command} machine contract; expected ${OPERATION_REPORT_SCHEMA}.`,\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_CONTRACT_INCOMPATIBLE',\n exitCode: 69,\n },\n );\n }\n return value as TidasOperationReport;\n}\n\nfunction assertExitContract(run: TidasProcessResult, report: TidasOperationReport): void {\n const expected = EXIT_CODES[report.exit_class];\n if (run.status !== expected) {\n throw new CliError(\n `tidas exit status ${String(run.status)} disagrees with report exit class ${report.exit_class} (${expected}).`,\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_EXIT_MISMATCH',\n exitCode: 70,\n },\n );\n }\n}\n\nfunction readCompatibleVersion(report: TidasOperationReport): string {\n if (\n report.status !== 'succeeded' ||\n report.exit_class !== 'success' ||\n report.completeness !== 'complete' ||\n report.summary.operation_report_schema !== OPERATION_REPORT_SCHEMA ||\n typeof report.summary.binary_version !== 'string' ||\n !SUPPORTED_TIDAS_VERSION.test(report.summary.binary_version)\n ) {\n throw new CliError(\n 'Incompatible tidas binary: dataset import requires a stable contract-compatible 0.2.x release.',\n {\n code: 'DATASET_IMPORT_LCA_TIDAS_VERSION_INCOMPATIBLE',\n exitCode: 69,\n details: { binary_version: report.summary.binary_version ?? null },\n },\n );\n }\n return report.summary.binary_version;\n}\n\nfunction assertImportContract(report: TidasOperationReport): void {\n if (report.status === 'succeeded' || report.status === 'completed-with-issues') {\n const importSummary = report.summary.import;\n if (!isRecord(importSummary) || importSummary.schema_version !== IMPORT_REPORT_SCHEMA) {\n throw new CliError(`Incompatible tidas import summary; expected ${IMPORT_REPORT_SCHEMA}.`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_IMPORT_CONTRACT_INCOMPATIBLE',\n exitCode: 69,\n });\n }\n }\n}\n\nfunction requireInputPath(value: string): string {\n if (!value?.trim()) {\n throw new CliError('Missing required --input value.', {\n code: 'DATASET_IMPORT_LCA_INPUT_REQUIRED',\n exitCode: 2,\n });\n }\n const resolved = path.resolve(value);\n if (!existsSync(resolved)) {\n throw new CliError(`Input path not found: ${resolved}`, {\n code: 'DATASET_IMPORT_LCA_INPUT_NOT_FOUND',\n exitCode: 2,\n });\n }\n return resolved;\n}\n\nfunction requireOutputDir(value: string): string {\n if (!value?.trim()) {\n throw new CliError('Missing required --output-dir value.', {\n code: 'DATASET_IMPORT_LCA_OUTPUT_DIR_REQUIRED',\n exitCode: 2,\n });\n }\n return path.resolve(value);\n}\n\nfunction normalizeSourceFormat(value: string | undefined): DatasetImportLcaSourceFormat | 'auto' {\n const format = value?.trim() || 'auto';\n if (format === 'auto' || includesValue(SOURCE_FORMATS, format)) {\n return format;\n }\n throw new CliError(`--from-format must be auto or one of: ${SOURCE_FORMATS.join(', ')}.`, {\n code: 'DATASET_IMPORT_LCA_SOURCE_FORMAT_INVALID',\n exitCode: 2,\n });\n}\n\nfunction normalizeTarget(value: string | undefined): DatasetImportLcaTarget {\n const target = value?.trim() || 'tidas';\n if (target === 'tidas' || target === 'ilcd' || target === 'both') {\n return target;\n }\n throw new CliError(\"--target must be 'tidas', 'ilcd', or 'both'.\", {\n code: 'DATASET_IMPORT_LCA_TARGET_INVALID',\n exitCode: 2,\n });\n}\n\nfunction resolveTidasBinary(explicitValue: string | undefined, env: NodeJS.ProcessEnv): string {\n const candidate = explicitValue?.trim() || env.TIDAS_BIN?.trim() || 'tidas';\n if (path.isAbsolute(candidate) || candidate.includes('/') || candidate.includes('\\\\')) {\n const resolved = path.resolve(candidate);\n if (!existsSync(resolved)) {\n throw new CliError(`Rust tidas binary not found: ${resolved}`, {\n code: 'DATASET_IMPORT_LCA_TIDAS_NOT_FOUND',\n exitCode: 69,\n });\n }\n return resolved;\n }\n return candidate;\n}\n\nfunction assertSupportedPlatform(platform: NodeJS.Platform, arch: string): void {\n const supported =\n (platform === 'linux' && (arch === 'x64' || arch === 'arm64')) ||\n (platform === 'darwin' && arch === 'arm64') ||\n (platform === 'win32' && arch === 'x64');\n if (!supported) {\n throw new CliError(`No supported Rust tidas artifact exists for ${platform}/${arch}.`, {\n code: 'DATASET_IMPORT_LCA_PLATFORM_UNSUPPORTED',\n exitCode: 69,\n details: {\n supported: ['linux/x64', 'linux/arm64', 'darwin/arm64', 'win32/x64'],\n },\n });\n }\n}\n\nfunction requirePositiveInteger(flag: string, value: number | undefined): void {\n if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {\n throw new CliError(`${flag} must be a positive integer.`, {\n code: 'DATASET_IMPORT_LCA_RUNTIME_BOUND_INVALID',\n exitCode: 2,\n });\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction includesValue<T extends readonly string[]>(values: T, value: unknown): value is T[number] {\n return typeof value === 'string' && values.includes(value);\n}\n\nfunction isExitClass(value: unknown): value is TidasExitClass {\n return typeof value === 'string' && Object.hasOwn(EXIT_CODES, value);\n}\n\nexport const __testInternals = {\n assertImportContract,\n assertSupportedPlatform,\n buildImportArgs,\n normalizeSourceFormat,\n normalizeTarget,\n parseOperationReport,\n readCompatibleVersion,\n readProcessReport,\n requirePositiveInteger,\n resolveTidasBinary,\n};\n"]}
@@ -0,0 +1,48 @@
1
+ import { type ResolveAuthIdentitySession } from './auth-identity-receipt.js';
2
+ import type { FetchLike } from './http.js';
3
+ import { type DatasetMaintenanceSnapshotCompleteness } from './dataset-maintenance-pagination.js';
4
+ declare const TABLES: readonly ['flowproperties', 'unitgroups'];
5
+ type Table = (typeof TABLES)[number];
6
+ export type RunDatasetSupportCacheExportOptions = {
7
+ outDir: string;
8
+ env: NodeJS.ProcessEnv;
9
+ fetchImpl: FetchLike;
10
+ cliVersion: string;
11
+ stateCodes?: number[];
12
+ pageSize?: number;
13
+ timeoutMs?: number;
14
+ expectedProjectRef?: string;
15
+ expectedUserId?: string;
16
+ now?: Date;
17
+ resolveSessionImpl?: ResolveAuthIdentitySession;
18
+ monotonicNow?: () => number;
19
+ };
20
+ export type DatasetSupportCacheExportReport = {
21
+ schema_version: 1;
22
+ command: 'dataset support-cache export';
23
+ status: 'completed';
24
+ remote_write_mode: 'read-only';
25
+ captured_at_utc: string;
26
+ project_ref: string;
27
+ account: {
28
+ user_id: string;
29
+ session_source: string;
30
+ };
31
+ filters: {
32
+ state_codes: number[];
33
+ requested_page_size: number;
34
+ };
35
+ snapshot: {
36
+ status: 'observed-stable';
37
+ transactional_snapshot: false;
38
+ observations: 2;
39
+ };
40
+ completeness: DatasetMaintenanceSnapshotCompleteness<Table>[];
41
+ tables: Record<Table, {
42
+ rows: number;
43
+ sha256: string;
44
+ }>;
45
+ artifacts: Record<Table | 'identity' | 'report', string>;
46
+ };
47
+ export declare function runDatasetSupportCacheExport(options: RunDatasetSupportCacheExportOptions): Promise<DatasetSupportCacheExportReport>;
48
+ export {};
@@ -0,0 +1,265 @@
1
+ // data-api-relations: flowproperties, unitgroups
2
+ import { createHash } from 'node:crypto';
3
+ import { lstatSync, mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
4
+ import path from 'node:path';
5
+ import { runAuthIdentityReceipt, } from './auth-identity-receipt.js';
6
+ import { CliError } from './errors.js';
7
+ import { buildSnapshotCompleteness, fetchCompletePostgrestPages, parseExactContentRange, } from './dataset-maintenance-pagination.js';
8
+ import { buildSupabaseAuthHeaders, deriveSupabaseRestBaseUrl, requireSupabaseRestRuntime, } from './supabase-client.js';
9
+ import { applyDataApiProfileHeaders, buildDataApiUrl, resolveDataApiCapabilityFromUrl, } from './supabase-data-api-contract.js';
10
+ import { resolveSupabaseUserSession, } from './supabase-session.js';
11
+ const TABLES = ['flowproperties', 'unitgroups'];
12
+ const MAX_ROWS = 100_000;
13
+ const MAX_PAGES = 1_000;
14
+ const MAX_RESPONSE_BYTES = 8 * 1024 * 1024;
15
+ const MAX_TOTAL_BYTES = 64 * 1024 * 1024;
16
+ const MAX_DURATION_MS = 120_000;
17
+ function fail(code, message, exitCode = 1) {
18
+ throw new CliError(message, { code: `DATASET_SUPPORT_CACHE_${code}`, exitCode });
19
+ }
20
+ function integer(value, minimum, maximum, label) {
21
+ if (!Number.isSafeInteger(value) || value < minimum || value > maximum)
22
+ fail('OPTION_INVALID', `${label} is outside the supported integer range.`, 2);
23
+ return value;
24
+ }
25
+ function object(value) {
26
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
27
+ }
28
+ function rowsFrom(value, states) {
29
+ if (!Array.isArray(value))
30
+ fail('ROWS_INVALID', 'Support response must be an array.');
31
+ return value.map((row) => {
32
+ if (!object(row) ||
33
+ typeof row.id !== 'string' ||
34
+ !row.id.trim() ||
35
+ typeof row.version !== 'string' ||
36
+ !row.version.trim() ||
37
+ !Number.isSafeInteger(row.state_code) ||
38
+ !object(row.json))
39
+ fail('ROWS_INVALID', 'Support response contains an invalid row.');
40
+ if (!states.includes(row.state_code))
41
+ fail('STATE_FENCE_VIOLATION', 'Support response escaped the requested state filters.');
42
+ return {
43
+ id: row.id,
44
+ version: row.version,
45
+ state_code: row.state_code,
46
+ json: row.json,
47
+ };
48
+ });
49
+ }
50
+ async function readBounded(response) {
51
+ if (Number(response.headers.get('content-length')) > MAX_RESPONSE_BYTES)
52
+ fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');
53
+ if (!response.body) {
54
+ const text = await response.text();
55
+ if (Buffer.byteLength(text) > MAX_RESPONSE_BYTES)
56
+ fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');
57
+ return text;
58
+ }
59
+ const reader = response.body.getReader();
60
+ const chunks = [];
61
+ let bytes = 0;
62
+ try {
63
+ for (;;) {
64
+ const chunk = await reader.read();
65
+ if (chunk.done)
66
+ break;
67
+ bytes += chunk.value.byteLength;
68
+ if (bytes > MAX_RESPONSE_BYTES) {
69
+ await reader.cancel();
70
+ fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');
71
+ }
72
+ chunks.push(chunk.value);
73
+ }
74
+ }
75
+ finally {
76
+ reader.releaseLock();
77
+ }
78
+ return Buffer.concat(chunks).toString('utf8');
79
+ }
80
+ function rowBytes(rows) {
81
+ return rows.map((row) => JSON.stringify(row) + '\n').join('');
82
+ }
83
+ function digest(bytes) {
84
+ return createHash('sha256').update(bytes).digest('hex');
85
+ }
86
+ export async function runDatasetSupportCacheExport(options) {
87
+ if (!options.outDir.trim())
88
+ fail('OUT_DIR_REQUIRED', 'A fresh --out-dir is required.', 2);
89
+ const outDir = path.resolve(options.outDir);
90
+ if (lstatSync(outDir, { throwIfNoEntry: false }))
91
+ fail('OUTPUT_EXISTS', 'Support export output already exists.', 2);
92
+ const pageSize = integer(options.pageSize ?? 1000, 1, 5000, 'Page size');
93
+ const timeoutMs = integer(options.timeoutMs ?? 10000, 1, MAX_DURATION_MS, 'Timeout');
94
+ const states = [...new Set(options.stateCodes ?? [100])].sort((a, b) => a - b);
95
+ if (!states.length)
96
+ fail('OPTION_INVALID', 'At least one state code is required.', 2);
97
+ states.forEach((state) => integer(state, -2147483648, 2147483647, 'State code'));
98
+ const runtime = requireSupabaseRestRuntime(options.env);
99
+ if (runtime.authMode !== 'oauth')
100
+ fail('OAUTH_REQUIRED', 'Support export requires a CLI OAuth session.', 2);
101
+ const clock = options.monotonicNow ?? (() => performance.now());
102
+ const started = clock();
103
+ const overall = AbortSignal.timeout(MAX_DURATION_MS);
104
+ const fetchImpl = (url, init = {}) => options.fetchImpl(url, {
105
+ ...init,
106
+ signal: AbortSignal.any([overall, init.signal ?? AbortSignal.timeout(timeoutMs)]),
107
+ });
108
+ const resolver = options.resolveSessionImpl ?? resolveSupabaseUserSession;
109
+ const holder = {};
110
+ const identity = await runAuthIdentityReceipt({
111
+ env: options.env,
112
+ fetchImpl,
113
+ cliVersion: options.cliVersion,
114
+ expectedProjectRef: options.expectedProjectRef,
115
+ expectedUserId: options.expectedUserId,
116
+ timeoutMs,
117
+ now: options.now,
118
+ resolveSessionImpl: async (request) => {
119
+ holder.session = await resolver(request);
120
+ return holder.session;
121
+ },
122
+ });
123
+ // The canonical identity runner resolves a session before it can return this receipt.
124
+ const session = holder.session;
125
+ const restBase = deriveSupabaseRestBaseUrl(runtime.apiBaseUrl);
126
+ let totalBytes = 0;
127
+ const observations = [];
128
+ for (let observation = 0; observation < 2; observation += 1) {
129
+ const collected = {};
130
+ const results = [];
131
+ for (const table of TABLES) {
132
+ let pages = 0;
133
+ try {
134
+ const result = await fetchCompletePostgrestPages({
135
+ table,
136
+ requestedPageSize: pageSize,
137
+ rowIdentity: (row) => `${row.id}@${row.version}`,
138
+ fetchPage: async (offset) => {
139
+ if (++pages > MAX_PAGES)
140
+ fail('PAGE_LIMIT', 'Support export exceeded the page limit.');
141
+ if (clock() - started >= MAX_DURATION_MS)
142
+ fail('TIME_LIMIT', 'Support export exceeded the operation deadline.');
143
+ const url = new URL(buildDataApiUrl(restBase, { kind: 'relation', name: table }));
144
+ url.searchParams.set('select', 'id,version,state_code,json');
145
+ url.searchParams.set('state_code', `in.(${states.join(',')})`);
146
+ url.searchParams.set('order', 'id.asc,version.asc');
147
+ url.searchParams.set('limit', String(pageSize));
148
+ url.searchParams.set('offset', String(offset));
149
+ const headers = applyDataApiProfileHeaders({
150
+ ...buildSupabaseAuthHeaders(runtime.publishableKey, session.accessToken),
151
+ Prefer: 'count=exact',
152
+ }, resolveDataApiCapabilityFromUrl({ url: url.toString(), method: 'GET' }), 'GET');
153
+ const response = await fetchImpl(url.toString(), {
154
+ method: 'GET',
155
+ headers,
156
+ redirect: 'error',
157
+ });
158
+ if (!response.ok)
159
+ fail('READ_FAILED', 'Support export request was rejected.');
160
+ const range = response.headers.get('content-range');
161
+ if (parseExactContentRange(range).total > MAX_ROWS)
162
+ fail('ROW_LIMIT', 'Support export exceeded the row limit.');
163
+ const text = await readBounded(response);
164
+ totalBytes += Buffer.byteLength(text);
165
+ if (totalBytes > MAX_TOTAL_BYTES)
166
+ fail('BYTE_LIMIT', 'Support export exceeded the total byte limit.');
167
+ let value;
168
+ try {
169
+ value = JSON.parse(text);
170
+ }
171
+ catch {
172
+ fail('INVALID_JSON', 'Support response is not valid JSON.');
173
+ }
174
+ return {
175
+ rows: rowsFrom(value, states),
176
+ source_url: url.toString(),
177
+ content_range: range,
178
+ };
179
+ },
180
+ });
181
+ collected[table] = result.rows;
182
+ results.push({ table, completeness: result.completeness });
183
+ }
184
+ catch (error) {
185
+ if (error instanceof CliError && error.code.startsWith('DATASET_SUPPORT_CACHE_'))
186
+ throw error;
187
+ if (error instanceof CliError && error.code === 'DATASET_MAINTENANCE_SNAPSHOT_INCOMPLETE')
188
+ fail('SNAPSHOT_INCOMPLETE', 'Support pagination completeness could not be proven.');
189
+ fail('READ_FAILED', 'Support export request failed.');
190
+ }
191
+ }
192
+ observations.push({
193
+ rows: collected,
194
+ completeness: buildSnapshotCompleteness({
195
+ tables: TABLES,
196
+ requestedPageSize: pageSize,
197
+ results,
198
+ }),
199
+ });
200
+ }
201
+ const first = observations[0];
202
+ const second = observations[1];
203
+ const bytes = {
204
+ flowproperties: rowBytes(first.rows.flowproperties),
205
+ unitgroups: rowBytes(first.rows.unitgroups),
206
+ };
207
+ for (const table of TABLES) {
208
+ if (digest(bytes[table]) !== digest(rowBytes(second.rows[table])))
209
+ fail('CONTENT_DRIFT', 'Support rows changed between observations.');
210
+ }
211
+ const artifacts = {
212
+ flowproperties: path.join(outDir, 'flowproperties.jsonl'),
213
+ unitgroups: path.join(outDir, 'unitgroups.jsonl'),
214
+ identity: path.join(outDir, 'identity-receipt.json'),
215
+ report: path.join(outDir, 'export-report.json'),
216
+ };
217
+ const report = {
218
+ schema_version: 1,
219
+ command: 'dataset support-cache export',
220
+ status: 'completed',
221
+ remote_write_mode: 'read-only',
222
+ captured_at_utc: identity.captured_at_utc,
223
+ project_ref: identity.project.project_ref,
224
+ account: { user_id: identity.identity.user_id, session_source: identity.session.source },
225
+ filters: { state_codes: states, requested_page_size: pageSize },
226
+ snapshot: { status: 'observed-stable', transactional_snapshot: false, observations: 2 },
227
+ completeness: observations.map((item) => item.completeness),
228
+ tables: {
229
+ flowproperties: {
230
+ rows: first.rows.flowproperties.length,
231
+ sha256: digest(bytes.flowproperties),
232
+ },
233
+ unitgroups: { rows: first.rows.unitgroups.length, sha256: digest(bytes.unitgroups) },
234
+ },
235
+ artifacts,
236
+ };
237
+ if (clock() - started >= MAX_DURATION_MS)
238
+ fail('TIME_LIMIT', 'Support export exceeded the operation deadline.');
239
+ try {
240
+ mkdirSync(path.dirname(outDir), { recursive: true, mode: 0o700 });
241
+ mkdirSync(outDir, { mode: 0o700 });
242
+ }
243
+ catch (error) {
244
+ // Reservation failure must never clean another writer's output.
245
+ if (error.code === 'EEXIST')
246
+ fail('OUTPUT_EXISTS', 'Support export output already exists.', 2);
247
+ fail('ARTIFACT_WRITE_FAILED', 'Support export could not reserve its output directory.');
248
+ }
249
+ try {
250
+ for (const table of TABLES)
251
+ writeFileSync(artifacts[table], bytes[table], { flag: 'wx', mode: 0o600 });
252
+ writeFileSync(artifacts.identity, JSON.stringify(identity) + '\n', { flag: 'wx', mode: 0o600 });
253
+ writeFileSync(artifacts.report + '.tmp', JSON.stringify(report) + '\n', {
254
+ flag: 'wx',
255
+ mode: 0o600,
256
+ });
257
+ renameSync(artifacts.report + '.tmp', artifacts.report);
258
+ }
259
+ catch {
260
+ rmSync(outDir, { recursive: true, force: true });
261
+ fail('ARTIFACT_WRITE_FAILED', 'Support export could not publish its completion report.');
262
+ }
263
+ return report;
264
+ }
265
+ //# sourceMappingURL=dataset-support-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-support-cache.js","sourceRoot":"","sources":["../../../src/lib/dataset-support-cache.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClF,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,sBAAsB,GAEvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,GAEvB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,+BAA+B,GAChC,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,0BAA0B,GAE3B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,GAAG,CAAC,gBAAgB,EAAE,YAAY,CAAU,CAAC;AAGzD,MAAM,QAAQ,GAAG,OAAO,CAAC;AACzB,MAAM,SAAS,GAAG,KAAK,CAAC;AACxB,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACzC,MAAM,eAAe,GAAG,OAAO,CAAC;AAgChC,SAAS,IAAI,CAAC,IAAY,EAAE,OAAe,EAAE,QAAQ,GAAG,CAAC;IACvD,MAAM,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,yBAAyB,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,OAAO,CAAC,KAAa,EAAE,OAAe,EAAE,OAAe,EAAE,KAAa;IAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,OAAO,IAAI,KAAK,GAAG,OAAO;QACpE,IAAI,CAAC,gBAAgB,EAAE,GAAG,KAAK,0CAA0C,EAAE,CAAC,CAAC,CAAC;IAChF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc,EAAE,MAAyB;IACzD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,cAAc,EAAE,oCAAoC,CAAC,CAAC;IACtF,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,GAAY,EAAE,EAAE;QAChC,IACE,CAAC,MAAM,CAAC,GAAG,CAAC;YACZ,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ;YAC1B,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE;YACd,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;YAC/B,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;YACnB,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC;YACrC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAEjB,IAAI,CAAC,cAAc,EAAE,2CAA2C,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAoB,CAAC;YAC5C,IAAI,CAAC,uBAAuB,EAAE,uDAAuD,CAAC,CAAC;QACzF,OAAO;YACL,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,UAAU,EAAE,GAAG,CAAC,UAAoB;YACpC,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAsB;IAC/C,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,GAAG,kBAAkB;QACrE,IAAI,CAAC,YAAY,EAAE,2CAA2C,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,kBAAkB;YAC9C,IAAI,CAAC,YAAY,EAAE,2CAA2C,CAAC,CAAC;QAClE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,IAAI;gBAAE,MAAM;YACtB,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;YAChC,IAAI,KAAK,GAAG,kBAAkB,EAAE,CAAC;gBAC/B,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,EAAE,2CAA2C,CAAC,CAAC;YAClE,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAW;IAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,MAAM,CAAC,KAAa;IAC3B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAA4C;IAE5C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;QAAE,IAAI,CAAC,kBAAkB,EAAE,gCAAgC,EAAE,CAAC,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC;QAC9C,IAAI,CAAC,eAAe,EAAE,uCAAuC,EAAE,CAAC,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,IAAI,CAAC,gBAAgB,EAAE,sCAAsC,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC9B,IAAI,CAAC,gBAAgB,EAAE,8CAA8C,EAAE,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACrD,MAAM,SAAS,GAAc,CAAC,GAAG,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAC9C,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;QACrB,GAAG,IAAI;QACP,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;KAClF,CAAC,CAAC;IACL,MAAM,QAAQ,GAAG,OAAO,CAAC,kBAAkB,IAAI,0BAA0B,CAAC;IAC1E,MAAM,MAAM,GAA8C,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC;QAC5C,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,SAAS;QACT,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,kBAAkB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACpC,MAAM,CAAC,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;KACF,CAAC,CAAC;IACH,sFAAsF;IACtF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAQ,CAAC;IAChC,MAAM,QAAQ,GAAG,yBAAyB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,YAAY,GAGb,EAAE,CAAC;IACR,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,CAAC,EAAE,WAAW,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,EAA0B,CAAC;QAC7C,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC;oBAC/C,KAAK;oBACL,iBAAiB,EAAE,QAAQ;oBAC3B,WAAW,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE;oBACrD,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;wBAC1B,IAAI,EAAE,KAAK,GAAG,SAAS;4BAAE,IAAI,CAAC,YAAY,EAAE,yCAAyC,CAAC,CAAC;wBACvF,IAAI,KAAK,EAAE,GAAG,OAAO,IAAI,eAAe;4BACtC,IAAI,CAAC,YAAY,EAAE,iDAAiD,CAAC,CAAC;wBACxE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;wBAClF,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,4BAA4B,CAAC,CAAC;wBAC7D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAC/D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;wBACpD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;wBAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;wBAC/C,MAAM,OAAO,GAAG,0BAA0B,CACxC;4BACE,GAAG,wBAAwB,CAAC,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,WAAW,CAAC;4BACxE,MAAM,EAAE,aAAa;yBACtB,EACD,+BAA+B,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EACvE,KAAK,CACN,CAAC;wBACF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;4BAC/C,MAAM,EAAE,KAAK;4BACb,OAAO;4BACP,QAAQ,EAAE,OAAO;yBAClB,CAAC,CAAC;wBACH,IAAI,CAAC,QAAQ,CAAC,EAAE;4BAAE,IAAI,CAAC,aAAa,EAAE,sCAAsC,CAAC,CAAC;wBAC9E,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;wBACpD,IAAI,sBAAsB,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,QAAQ;4BAChD,IAAI,CAAC,WAAW,EAAE,wCAAwC,CAAC,CAAC;wBAC9D,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;wBACzC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;wBACtC,IAAI,UAAU,GAAG,eAAe;4BAC9B,IAAI,CAAC,YAAY,EAAE,+CAA+C,CAAC,CAAC;wBACtE,IAAI,KAAc,CAAC;wBACnB,IAAI,CAAC;4BACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBAC3B,CAAC;wBAAC,MAAM,CAAC;4BACP,IAAI,CAAC,cAAc,EAAE,qCAAqC,CAAC,CAAC;wBAC9D,CAAC;wBACD,OAAO;4BACL,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;4BAC7B,UAAU,EAAE,GAAG,CAAC,QAAQ,EAAE;4BAC1B,aAAa,EAAE,KAAK;yBACrB,CAAC;oBACJ,CAAC;iBACF,CAAC,CAAC;gBACH,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YAC7D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC;oBAC9E,MAAM,KAAK,CAAC;gBACd,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,yCAAyC;oBACvF,IAAI,CAAC,qBAAqB,EAAE,sDAAsD,CAAC,CAAC;gBACtF,IAAI,CAAC,aAAa,EAAE,gCAAgC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,YAAY,CAAC,IAAI,CAAC;YAChB,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,yBAAyB,CAAC;gBACtC,MAAM,EAAE,MAAM;gBACd,iBAAiB,EAAE,QAAQ;gBAC3B,OAAO;aACR,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAE,CAAC;IAChC,MAAM,KAAK,GAAG;QACZ,cAAc,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;QACnD,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;KAC5C,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/D,IAAI,CAAC,eAAe,EAAE,4CAA4C,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,SAAS,GAAG;QAChB,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,sBAAsB,CAAC;QACzD,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC;QACjD,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,uBAAuB,CAAC;QACpD,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC;KAChD,CAAC;IACF,MAAM,MAAM,GAAoC;QAC9C,cAAc,EAAE,CAAC;QACjB,OAAO,EAAE,8BAA8B;QACvC,MAAM,EAAE,WAAW;QACnB,iBAAiB,EAAE,WAAW;QAC9B,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW;QACzC,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;QACxF,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE;QAC/D,QAAQ,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE;QACvF,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC;QAC3D,MAAM,EAAE;YACN,cAAc,EAAE;gBACd,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM;gBACtC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC;aACrC;YACD,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;SACrF;QACD,SAAS;KACV,CAAC;IACF,IAAI,KAAK,EAAE,GAAG,OAAO,IAAI,eAAe;QACtC,IAAI,CAAC,YAAY,EAAE,iDAAiD,CAAC,CAAC;IACxE,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClE,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gEAAgE;QAChE,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YACpD,IAAI,CAAC,eAAe,EAAE,uCAAuC,EAAE,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,uBAAuB,EAAE,wDAAwD,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,MAAM;YACxB,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7E,aAAa,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChG,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE;YACtE,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QACH,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,uBAAuB,EAAE,yDAAyD,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["// data-api-relations: flowproperties, unitgroups\nimport { createHash } from 'node:crypto';\nimport { lstatSync, mkdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';\nimport path from 'node:path';\nimport {\n runAuthIdentityReceipt,\n type ResolveAuthIdentitySession,\n} from './auth-identity-receipt.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike, ResponseLike } from './http.js';\nimport {\n buildSnapshotCompleteness,\n fetchCompletePostgrestPages,\n parseExactContentRange,\n type DatasetMaintenanceSnapshotCompleteness,\n} from './dataset-maintenance-pagination.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseRestBaseUrl,\n requireSupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n applyDataApiProfileHeaders,\n buildDataApiUrl,\n resolveDataApiCapabilityFromUrl,\n} from './supabase-data-api-contract.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\n\nconst TABLES = ['flowproperties', 'unitgroups'] as const;\ntype Table = (typeof TABLES)[number];\ntype Row = { id: string; version: string; state_code: number; json: Record<string, unknown> };\nconst MAX_ROWS = 100_000;\nconst MAX_PAGES = 1_000;\nconst MAX_RESPONSE_BYTES = 8 * 1024 * 1024;\nconst MAX_TOTAL_BYTES = 64 * 1024 * 1024;\nconst MAX_DURATION_MS = 120_000;\n\nexport type RunDatasetSupportCacheExportOptions = {\n outDir: string;\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n stateCodes?: number[];\n pageSize?: number;\n timeoutMs?: number;\n expectedProjectRef?: string;\n expectedUserId?: string;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n monotonicNow?: () => number;\n};\n\nexport type DatasetSupportCacheExportReport = {\n schema_version: 1;\n command: 'dataset support-cache export';\n status: 'completed';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n project_ref: string;\n account: { user_id: string; session_source: string };\n filters: { state_codes: number[]; requested_page_size: number };\n snapshot: { status: 'observed-stable'; transactional_snapshot: false; observations: 2 };\n completeness: DatasetMaintenanceSnapshotCompleteness<Table>[];\n tables: Record<Table, { rows: number; sha256: string }>;\n artifacts: Record<Table | 'identity' | 'report', string>;\n};\n\nfunction fail(code: string, message: string, exitCode = 1): never {\n throw new CliError(message, { code: `DATASET_SUPPORT_CACHE_${code}`, exitCode });\n}\n\nfunction integer(value: number, minimum: number, maximum: number, label: string): number {\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum)\n fail('OPTION_INVALID', `${label} is outside the supported integer range.`, 2);\n return value;\n}\n\nfunction object(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction rowsFrom(value: unknown, states: readonly number[]): Row[] {\n if (!Array.isArray(value)) fail('ROWS_INVALID', 'Support response must be an array.');\n return value.map((row: unknown) => {\n if (\n !object(row) ||\n typeof row.id !== 'string' ||\n !row.id.trim() ||\n typeof row.version !== 'string' ||\n !row.version.trim() ||\n !Number.isSafeInteger(row.state_code) ||\n !object(row.json)\n )\n fail('ROWS_INVALID', 'Support response contains an invalid row.');\n if (!states.includes(row.state_code as number))\n fail('STATE_FENCE_VIOLATION', 'Support response escaped the requested state filters.');\n return {\n id: row.id,\n version: row.version,\n state_code: row.state_code as number,\n json: row.json,\n };\n });\n}\n\nasync function readBounded(response: ResponseLike): Promise<string> {\n if (Number(response.headers.get('content-length')) > MAX_RESPONSE_BYTES)\n fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text) > MAX_RESPONSE_BYTES)\n fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');\n return text;\n }\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let bytes = 0;\n try {\n for (;;) {\n const chunk = await reader.read();\n if (chunk.done) break;\n bytes += chunk.value.byteLength;\n if (bytes > MAX_RESPONSE_BYTES) {\n await reader.cancel();\n fail('BYTE_LIMIT', 'Support response exceeded the byte limit.');\n }\n chunks.push(chunk.value);\n }\n } finally {\n reader.releaseLock();\n }\n return Buffer.concat(chunks).toString('utf8');\n}\n\nfunction rowBytes(rows: Row[]): string {\n return rows.map((row) => JSON.stringify(row) + '\\n').join('');\n}\n\nfunction digest(bytes: string): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nexport async function runDatasetSupportCacheExport(\n options: RunDatasetSupportCacheExportOptions,\n): Promise<DatasetSupportCacheExportReport> {\n if (!options.outDir.trim()) fail('OUT_DIR_REQUIRED', 'A fresh --out-dir is required.', 2);\n const outDir = path.resolve(options.outDir);\n if (lstatSync(outDir, { throwIfNoEntry: false }))\n fail('OUTPUT_EXISTS', 'Support export output already exists.', 2);\n const pageSize = integer(options.pageSize ?? 1000, 1, 5000, 'Page size');\n const timeoutMs = integer(options.timeoutMs ?? 10000, 1, MAX_DURATION_MS, 'Timeout');\n const states = [...new Set(options.stateCodes ?? [100])].sort((a, b) => a - b);\n if (!states.length) fail('OPTION_INVALID', 'At least one state code is required.', 2);\n states.forEach((state) => integer(state, -2147483648, 2147483647, 'State code'));\n const runtime = requireSupabaseRestRuntime(options.env);\n if (runtime.authMode !== 'oauth')\n fail('OAUTH_REQUIRED', 'Support export requires a CLI OAuth session.', 2);\n const clock = options.monotonicNow ?? (() => performance.now());\n const started = clock();\n const overall = AbortSignal.timeout(MAX_DURATION_MS);\n const fetchImpl: FetchLike = (url, init = {}) =>\n options.fetchImpl(url, {\n ...init,\n signal: AbortSignal.any([overall, init.signal ?? AbortSignal.timeout(timeoutMs)]),\n });\n const resolver = options.resolveSessionImpl ?? resolveSupabaseUserSession;\n const holder: { session?: ResolvedSupabaseUserSession } = {};\n const identity = await runAuthIdentityReceipt({\n env: options.env,\n fetchImpl,\n cliVersion: options.cliVersion,\n expectedProjectRef: options.expectedProjectRef,\n expectedUserId: options.expectedUserId,\n timeoutMs,\n now: options.now,\n resolveSessionImpl: async (request) => {\n holder.session = await resolver(request);\n return holder.session;\n },\n });\n // The canonical identity runner resolves a session before it can return this receipt.\n const session = holder.session!;\n const restBase = deriveSupabaseRestBaseUrl(runtime.apiBaseUrl);\n let totalBytes = 0;\n const observations: Array<{\n rows: Record<Table, Row[]>;\n completeness: DatasetMaintenanceSnapshotCompleteness<Table>;\n }> = [];\n for (let observation = 0; observation < 2; observation += 1) {\n const collected = {} as Record<Table, Row[]>;\n const results = [];\n for (const table of TABLES) {\n let pages = 0;\n try {\n const result = await fetchCompletePostgrestPages({\n table,\n requestedPageSize: pageSize,\n rowIdentity: (row: Row) => `${row.id}@${row.version}`,\n fetchPage: async (offset) => {\n if (++pages > MAX_PAGES) fail('PAGE_LIMIT', 'Support export exceeded the page limit.');\n if (clock() - started >= MAX_DURATION_MS)\n fail('TIME_LIMIT', 'Support export exceeded the operation deadline.');\n const url = new URL(buildDataApiUrl(restBase, { kind: 'relation', name: table }));\n url.searchParams.set('select', 'id,version,state_code,json');\n url.searchParams.set('state_code', `in.(${states.join(',')})`);\n url.searchParams.set('order', 'id.asc,version.asc');\n url.searchParams.set('limit', String(pageSize));\n url.searchParams.set('offset', String(offset));\n const headers = applyDataApiProfileHeaders(\n {\n ...buildSupabaseAuthHeaders(runtime.publishableKey, session.accessToken),\n Prefer: 'count=exact',\n },\n resolveDataApiCapabilityFromUrl({ url: url.toString(), method: 'GET' }),\n 'GET',\n );\n const response = await fetchImpl(url.toString(), {\n method: 'GET',\n headers,\n redirect: 'error',\n });\n if (!response.ok) fail('READ_FAILED', 'Support export request was rejected.');\n const range = response.headers.get('content-range');\n if (parseExactContentRange(range).total > MAX_ROWS)\n fail('ROW_LIMIT', 'Support export exceeded the row limit.');\n const text = await readBounded(response);\n totalBytes += Buffer.byteLength(text);\n if (totalBytes > MAX_TOTAL_BYTES)\n fail('BYTE_LIMIT', 'Support export exceeded the total byte limit.');\n let value: unknown;\n try {\n value = JSON.parse(text);\n } catch {\n fail('INVALID_JSON', 'Support response is not valid JSON.');\n }\n return {\n rows: rowsFrom(value, states),\n source_url: url.toString(),\n content_range: range,\n };\n },\n });\n collected[table] = result.rows;\n results.push({ table, completeness: result.completeness });\n } catch (error) {\n if (error instanceof CliError && error.code.startsWith('DATASET_SUPPORT_CACHE_'))\n throw error;\n if (error instanceof CliError && error.code === 'DATASET_MAINTENANCE_SNAPSHOT_INCOMPLETE')\n fail('SNAPSHOT_INCOMPLETE', 'Support pagination completeness could not be proven.');\n fail('READ_FAILED', 'Support export request failed.');\n }\n }\n observations.push({\n rows: collected,\n completeness: buildSnapshotCompleteness({\n tables: TABLES,\n requestedPageSize: pageSize,\n results,\n }),\n });\n }\n const first = observations[0]!;\n const second = observations[1]!;\n const bytes = {\n flowproperties: rowBytes(first.rows.flowproperties),\n unitgroups: rowBytes(first.rows.unitgroups),\n };\n for (const table of TABLES) {\n if (digest(bytes[table]) !== digest(rowBytes(second.rows[table])))\n fail('CONTENT_DRIFT', 'Support rows changed between observations.');\n }\n const artifacts = {\n flowproperties: path.join(outDir, 'flowproperties.jsonl'),\n unitgroups: path.join(outDir, 'unitgroups.jsonl'),\n identity: path.join(outDir, 'identity-receipt.json'),\n report: path.join(outDir, 'export-report.json'),\n };\n const report: DatasetSupportCacheExportReport = {\n schema_version: 1,\n command: 'dataset support-cache export',\n status: 'completed',\n remote_write_mode: 'read-only',\n captured_at_utc: identity.captured_at_utc,\n project_ref: identity.project.project_ref,\n account: { user_id: identity.identity.user_id, session_source: identity.session.source },\n filters: { state_codes: states, requested_page_size: pageSize },\n snapshot: { status: 'observed-stable', transactional_snapshot: false, observations: 2 },\n completeness: observations.map((item) => item.completeness),\n tables: {\n flowproperties: {\n rows: first.rows.flowproperties.length,\n sha256: digest(bytes.flowproperties),\n },\n unitgroups: { rows: first.rows.unitgroups.length, sha256: digest(bytes.unitgroups) },\n },\n artifacts,\n };\n if (clock() - started >= MAX_DURATION_MS)\n fail('TIME_LIMIT', 'Support export exceeded the operation deadline.');\n try {\n mkdirSync(path.dirname(outDir), { recursive: true, mode: 0o700 });\n mkdirSync(outDir, { mode: 0o700 });\n } catch (error) {\n // Reservation failure must never clean another writer's output.\n if ((error as NodeJS.ErrnoException).code === 'EEXIST')\n fail('OUTPUT_EXISTS', 'Support export output already exists.', 2);\n fail('ARTIFACT_WRITE_FAILED', 'Support export could not reserve its output directory.');\n }\n try {\n for (const table of TABLES)\n writeFileSync(artifacts[table], bytes[table], { flag: 'wx', mode: 0o600 });\n writeFileSync(artifacts.identity, JSON.stringify(identity) + '\\n', { flag: 'wx', mode: 0o600 });\n writeFileSync(artifacts.report + '.tmp', JSON.stringify(report) + '\\n', {\n flag: 'wx',\n mode: 0o600,\n });\n renameSync(artifacts.report + '.tmp', artifacts.report);\n } catch {\n rmSync(outDir, { recursive: true, force: true });\n fail('ARTIFACT_WRITE_FAILED', 'Support export could not publish its completion report.');\n }\n return report;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { ComponentFile } from './manifest-types.js';
2
+ export declare function runtimeTarHeader(file: ComponentFile): Buffer;
3
+ /** Release-side writer. The producer supplies an explicit, already materialized production file inventory. */
4
+ export declare function writeRuntimeComponentArchive(root: string, files: readonly ComponentFile[], target: string): Promise<{
5
+ bytes: number;
6
+ sha256: string;
7
+ }>;
@@ -0,0 +1,89 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createGzip } from 'node:zlib';
4
+ import { pipeline } from 'node:stream/promises';
5
+ import { createHash } from 'node:crypto';
6
+ import { cachePath } from './storage.js';
7
+ import { hashRuntimeFile, runtimeError } from './files.js';
8
+ import { array, integer, relativeFile, sha, unique } from './manifest-values.js';
9
+ export function runtimeTarHeader(file) {
10
+ const parts = file.path.split('/');
11
+ let name = file.path, prefix = '';
12
+ if (Buffer.byteLength(name) > 100) {
13
+ for (let split = parts.length - 1; split > 0; split--) {
14
+ const head = parts.slice(0, split).join('/'), tail = parts.slice(split).join('/');
15
+ if (Buffer.byteLength(head) <= 155 && Buffer.byteLength(tail) <= 100) {
16
+ prefix = head;
17
+ name = tail;
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ const header = Buffer.alloc(512);
23
+ header.write(name, 0, 100, 'utf8');
24
+ header.write(prefix, 345, 155, 'utf8');
25
+ for (const [offset, length, value] of [
26
+ [100, 8, file.mode],
27
+ [108, 8, 0],
28
+ [116, 8, 0],
29
+ [124, 12, file.bytes],
30
+ [136, 12, 0],
31
+ ])
32
+ header.write(value.toString(8).padStart(length - 1, '0') + '\0', offset, length, 'ascii');
33
+ header.fill(32, 148, 156);
34
+ header[156] = 48;
35
+ header.write('ustar\0', 257, 6, 'ascii');
36
+ header.write('00', 263, 2, 'ascii');
37
+ const checksum = header.reduce((sum, value) => sum + value, 0);
38
+ header.write(checksum.toString(8).padStart(6, '0') + '\0 ', 148, 8, 'ascii');
39
+ return header;
40
+ }
41
+ /** Release-side writer. The producer supplies an explicit, already materialized production file inventory. */
42
+ export async function writeRuntimeComponentArchive(root, files, target) {
43
+ array(files, 50_000, 1);
44
+ unique(files.map((file) => relativeFile(file.path).toLowerCase()), 'archive file');
45
+ if (JSON.stringify(files.map((file) => file.path)) !==
46
+ JSON.stringify(files.map((file) => file.path).sort()))
47
+ runtimeError('RUNTIME_ARCHIVE_ORDER', 'Component archive files must be sorted by portable path.');
48
+ let total = 0;
49
+ for (const file of files) {
50
+ integer(file.bytes, 512 * 1024 * 1024);
51
+ sha(file.sha256);
52
+ if (file.mode !== 420 && file.mode !== 493)
53
+ runtimeError('RUNTIME_ARCHIVE_MODE', 'Component file modes must be 0644 or 0755.');
54
+ total += file.bytes;
55
+ if (total > 2 * 1024 * 1024 * 1024)
56
+ runtimeError('RUNTIME_ARCHIVE_SIZE', 'Component files exceed the unpacked size limit.');
57
+ }
58
+ for (const file of files) {
59
+ const actual = hashRuntimeFile(cachePath(root, file.path), file.path);
60
+ if (actual.bytes !== file.bytes || actual.sha256 !== file.sha256)
61
+ runtimeError('RUNTIME_ARCHIVE_SOURCE_CHANGED', 'Component source changed before packaging.');
62
+ }
63
+ async function* records() {
64
+ for (const file of files) {
65
+ yield runtimeTarHeader(file);
66
+ const hash = createHash('sha256');
67
+ let bytes = 0;
68
+ for await (const chunk of fs.createReadStream(cachePath(root, file.path))) {
69
+ const buffer = chunk;
70
+ bytes += buffer.length;
71
+ if (bytes > file.bytes)
72
+ runtimeError('RUNTIME_ARCHIVE_SOURCE_CHANGED', 'Component source grew while packaging.');
73
+ hash.update(buffer);
74
+ yield buffer;
75
+ }
76
+ if (bytes !== file.bytes || hash.digest('hex') !== file.sha256)
77
+ runtimeError('RUNTIME_ARCHIVE_SOURCE_CHANGED', 'Component source bytes changed while packaging.');
78
+ const padding = (512 - (file.bytes % 512)) % 512;
79
+ if (padding)
80
+ yield Buffer.alloc(padding);
81
+ }
82
+ yield Buffer.alloc(1024);
83
+ }
84
+ fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
85
+ await pipeline(records(), createGzip({ level: 9 }), fs.createWriteStream(target, { flags: 'wx', mode: 0o600 }));
86
+ const fact = hashRuntimeFile(target, 'archive');
87
+ return { bytes: fact.bytes, sha256: fact.sha256 };
88
+ }
89
+ //# sourceMappingURL=archive-writer.js.map