@tiangong-lca/cli 0.0.7 → 0.0.9

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 (59) hide show
  1. package/README.md +97 -16
  2. package/dist/src/cli.js +1429 -131
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/lib/dataset-author.js +100 -0
  5. package/dist/src/lib/dataset-author.js.map +1 -0
  6. package/dist/src/lib/dataset-bilingual.js +545 -0
  7. package/dist/src/lib/dataset-bilingual.js.map +1 -0
  8. package/dist/src/lib/dataset-contract.js +350 -0
  9. package/dist/src/lib/dataset-contract.js.map +1 -0
  10. package/dist/src/lib/dataset-evidence-search.js +636 -0
  11. package/dist/src/lib/dataset-evidence-search.js.map +1 -0
  12. package/dist/src/lib/dataset-import-lca.js +171 -0
  13. package/dist/src/lib/dataset-import-lca.js.map +1 -0
  14. package/dist/src/lib/dataset-remote-refresh.js +166 -0
  15. package/dist/src/lib/dataset-remote-refresh.js.map +1 -0
  16. package/dist/src/lib/dataset-remote-verify.js +543 -0
  17. package/dist/src/lib/dataset-remote-verify.js.map +1 -0
  18. package/dist/src/lib/dataset-validate.js +63 -7
  19. package/dist/src/lib/dataset-validate.js.map +1 -1
  20. package/dist/src/lib/flow-fetch-rows.js +12 -12
  21. package/dist/src/lib/flow-fetch-rows.js.map +1 -1
  22. package/dist/src/lib/flow-payload-validation.js +51 -0
  23. package/dist/src/lib/flow-payload-validation.js.map +1 -0
  24. package/dist/src/lib/flow-publish-reviewed-data.js +16 -0
  25. package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
  26. package/dist/src/lib/flow-publish-version.js +182 -12
  27. package/dist/src/lib/flow-publish-version.js.map +1 -1
  28. package/dist/src/lib/{review-flow.js → flow-qa.js} +86 -28
  29. package/dist/src/lib/flow-qa.js.map +1 -0
  30. package/dist/src/lib/identity-preflight.js +1021 -0
  31. package/dist/src/lib/identity-preflight.js.map +1 -0
  32. package/dist/src/lib/{review-lifecyclemodel.js → lifecyclemodel-qa.js} +54 -54
  33. package/dist/src/lib/lifecyclemodel-qa.js.map +1 -0
  34. package/dist/src/lib/process-auto-build.js +147 -0
  35. package/dist/src/lib/process-auto-build.js.map +1 -1
  36. package/dist/src/lib/process-dedup-review.js +51 -0
  37. package/dist/src/lib/process-dedup-review.js.map +1 -1
  38. package/dist/src/lib/process-flow-build-plan.js +1071 -0
  39. package/dist/src/lib/process-flow-build-plan.js.map +1 -0
  40. package/dist/src/lib/process-payload-validation.js +14 -7
  41. package/dist/src/lib/process-payload-validation.js.map +1 -1
  42. package/dist/src/lib/process-publish-build.js +122 -4
  43. package/dist/src/lib/process-publish-build.js.map +1 -1
  44. package/dist/src/lib/{review-process.js → process-qa.js} +259 -117
  45. package/dist/src/lib/process-qa.js.map +1 -0
  46. package/dist/src/lib/process-refresh-references.js +19 -10
  47. package/dist/src/lib/process-refresh-references.js.map +1 -1
  48. package/dist/src/lib/process-required-fields.js +810 -0
  49. package/dist/src/lib/process-required-fields.js.map +1 -0
  50. package/dist/src/lib/process-save-draft-run.js +4 -1
  51. package/dist/src/lib/process-save-draft-run.js.map +1 -1
  52. package/dist/src/lib/publish.js +100 -0
  53. package/dist/src/lib/publish.js.map +1 -1
  54. package/dist/src/lib/runtime-rulesets.js +283 -0
  55. package/dist/src/lib/runtime-rulesets.js.map +1 -0
  56. package/package.json +2 -2
  57. package/dist/src/lib/review-flow.js.map +0 -1
  58. package/dist/src/lib/review-lifecyclemodel.js.map +0 -1
  59. package/dist/src/lib/review-process.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-evidence-search.js","sourceRoot":"","sources":["../../../src/lib/dataset-evidence-search.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport { postJson } from './http.js';\nimport { readJsonInput } from './io.js';\n\ntype JsonObject = Record<string, unknown>;\n\nexport type EvidenceSearchMode = 'plan' | 'run';\nexport type EvidenceSearchProfile = 'shallow' | 'balanced' | 'deep';\nexport type EvidenceSearchStatus =\n | 'planned'\n | 'completed_with_evidence'\n | 'completed_with_partial_evidence'\n | 'completed_no_sufficient_evidence';\n\nexport type EvidenceSearchBudget = {\n max_queries: number;\n max_results_per_query: number;\n max_provider_calls: number;\n};\n\nexport type EvidenceSearchQuery = {\n query_id: string;\n text: string;\n purpose: string;\n source_tier: string;\n priority: number;\n expected_terms: string[];\n};\n\nexport type EvidenceSearchResult = {\n query_id: string | null;\n query: string | null;\n provider: string;\n rank: number;\n title: string;\n url: string;\n snippet: string | null;\n published_at: string | null;\n source_domain: string | null;\n source_tier: string;\n matched_terms: string[];\n score: number;\n};\n\nexport type EvidenceSearchDeclaration = {\n schema_version: 1;\n generated_at_utc: string;\n question: string;\n declaration_type: 'no_sufficient_evidence' | 'partial_temporal_evidence';\n statement: string;\n search_scope: {\n query_count: number;\n provider_count: number;\n normalized_result_count: number;\n authoritative_result_count: number;\n required_complete_year: boolean;\n requested_year: number | null;\n temporal_coverage_status: string;\n };\n limits: string[];\n};\n\nexport type EvidenceSearchReport = {\n schema_version: 1;\n generated_at_utc: string;\n mode: EvidenceSearchMode;\n status: EvidenceSearchStatus;\n question: string;\n field: {\n dataset_type: string | null;\n field_path: string | null;\n };\n profile: EvidenceSearchProfile;\n budget: EvidenceSearchBudget;\n plan: {\n query_count: number;\n queries: EvidenceSearchQuery[];\n };\n run: {\n provider_count: number;\n provider_call_count: number;\n normalized_result_count: number;\n authoritative_result_count: number;\n high_confidence_result_count: number;\n stop_reason: string;\n };\n evidence_quality: {\n sufficient: boolean;\n temporal_coverage_status: string;\n requested_year: number | null;\n required_complete_year: boolean;\n };\n files: {\n plan: string | null;\n results: string | null;\n report: string | null;\n declaration: string | null;\n };\n};\n\nexport type RunDatasetEvidenceSearchOptions = {\n mode: EvidenceSearchMode;\n query?: string | null;\n inputPath?: string | null;\n resultsPath?: string | null;\n providerUrl?: string | null;\n providerKey?: string | null;\n profile?: string | null;\n outDir?: string | null;\n maxQueries?: number | null;\n maxResultsPerQuery?: number | null;\n timeoutMs?: number | null;\n rawInput?: unknown;\n rawResults?: unknown;\n now?: Date;\n fetchImpl?: FetchLike;\n};\n\ntype EvidenceSearchRequest = {\n question: string;\n field: {\n dataset_type: string | null;\n field_path: string | null;\n };\n profile: EvidenceSearchProfile;\n budget: EvidenceSearchBudget;\n preferred_domains: string[];\n required_terms: string[];\n required_complete_year: boolean;\n requested_year: number | null;\n};\n\ntype ProviderQueryResult = {\n provider: string;\n query_id: string | null;\n query: string | null;\n items: unknown[];\n};\n\nconst DEFAULT_BUDGETS: Record<EvidenceSearchProfile, EvidenceSearchBudget> = {\n shallow: {\n max_queries: 4,\n max_results_per_query: 5,\n max_provider_calls: 4,\n },\n balanced: {\n max_queries: 8,\n max_results_per_query: 8,\n max_provider_calls: 8,\n },\n deep: {\n max_queries: 14,\n max_results_per_query: 10,\n max_provider_calls: 14,\n },\n};\n\nconst PUBLIC_OFFICIAL_DOMAINS = [\n 'gov.cn',\n 'stats.gov.cn',\n 'nea.gov.cn',\n 'ndrc.gov.cn',\n 'samr.gov.cn',\n];\n\nconst ELECTRICITY_TERMS = [\n '中国',\n '全国',\n '2026',\n '电力',\n '电源',\n '结构',\n '数据',\n '发电',\n '发电量',\n '装机',\n '火电',\n '水电',\n '核电',\n '风电',\n '太阳能',\n '非化石',\n 'coal',\n 'hydro',\n 'nuclear',\n 'wind',\n 'solar',\n 'generation',\n 'electricity',\n 'mix',\n];\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction trimToken(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const trimmed = value.trim();\n return trimmed ? trimmed : null;\n}\n\nfunction normalizeProfile(value: string | null | undefined): EvidenceSearchProfile {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return 'balanced';\n }\n if (normalized === 'shallow' || normalized === 'balanced' || normalized === 'deep') {\n return normalized;\n }\n throw new CliError(\"--profile must be 'shallow', 'balanced', or 'deep'.\", {\n code: 'EVIDENCE_SEARCH_PROFILE_INVALID',\n exitCode: 2,\n details: value,\n });\n}\n\nfunction readPositiveInteger(value: unknown, fallback: number, label: string): number {\n if (value === undefined || value === null || value === '') {\n return fallback;\n }\n const numberValue = typeof value === 'number' ? value : Number(value);\n if (!Number.isInteger(numberValue) || numberValue < 1) {\n throw new CliError(`${label} must be a positive integer.`, {\n code: 'EVIDENCE_SEARCH_BUDGET_INVALID',\n exitCode: 2,\n details: value,\n });\n }\n return numberValue;\n}\n\nfunction readStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) {\n return [];\n }\n return value.map((item) => trimToken(item)).filter((item): item is string => item !== null);\n}\n\nfunction readBoolean(value: unknown): boolean {\n return value === true;\n}\n\nfunction readRequestedYear(question: string, request: JsonObject): number | null {\n const rawTemporal = isRecord(request.required_evidence)\n ? trimToken(request.required_evidence.temporal_scope)\n : null;\n const source = rawTemporal ? `${question} ${rawTemporal}` : question;\n const match = /(?:19|20)\\d{2}/u.exec(source);\n return match ? Number(match[0]) : null;\n}\n\nfunction requestRequiresCompleteYear(request: JsonObject): boolean {\n if (!isRecord(request.required_evidence)) {\n return false;\n }\n return (\n readBoolean(request.required_evidence.require_complete_year) ||\n trimToken(request.required_evidence.temporal_coverage)?.toLowerCase() === 'annual_complete'\n );\n}\n\nfunction normalizeDomain(url: string): string | null {\n try {\n return new URL(url).hostname.toLowerCase().replace(/^www\\./u, '');\n } catch {\n return null;\n }\n}\n\nfunction domainMatches(domain: string | null, candidate: string): boolean {\n if (!domain) {\n return false;\n }\n const normalized = candidate.toLowerCase().replace(/^www\\./u, '');\n return domain === normalized || domain.endsWith(`.${normalized}`);\n}\n\nfunction classifySourceTier(domain: string | null, preferredDomains: string[]): string {\n if (preferredDomains.some((preferred) => domainMatches(domain, preferred))) {\n return 'preferred_domain';\n }\n if (PUBLIC_OFFICIAL_DOMAINS.some((official) => domainMatches(domain, official))) {\n return 'official_statistics';\n }\n if (domainMatches(domain, 'cec.org.cn') || domainMatches(domain, 'chinapower.org.cn')) {\n return 'industry_association';\n }\n if (domainMatches(domain, 'iea.org') || domainMatches(domain, 'ember-energy.org')) {\n return 'international_statistics';\n }\n return 'open_web';\n}\n\nfunction extractTerms(question: string, configuredTerms: string[]): string[] {\n const terms = new Set<string>();\n for (const term of configuredTerms) {\n terms.add(term.toLowerCase());\n }\n for (const term of ELECTRICITY_TERMS) {\n if (question.toLowerCase().includes(term.toLowerCase())) {\n terms.add(term.toLowerCase());\n }\n }\n const latinTerms = question.match(/[a-z0-9][a-z0-9-]{2,}/giu) ?? [];\n for (const term of latinTerms) {\n terms.add(term.toLowerCase());\n }\n return [...terms];\n}\n\nfunction dedupeStrings(values: string[]): string[] {\n const seen = new Set<string>();\n const result: string[] = [];\n for (const value of values) {\n const normalized = value.replace(/\\s+/gu, ' ').trim();\n const key = normalized.toLowerCase();\n if (normalized && !seen.has(key)) {\n seen.add(key);\n result.push(normalized);\n }\n }\n return result;\n}\n\nfunction buildQueryTexts(request: EvidenceSearchRequest): string[] {\n const yearText = request.requested_year ? String(request.requested_year) : '';\n const preferredQueries = request.preferred_domains.map(\n (domain) => `site:${domain} ${request.question}`,\n );\n const generated = [\n request.question,\n `site:stats.gov.cn ${request.question}`,\n `site:nea.gov.cn ${request.question}`,\n yearText\n ? `国家统计局 ${yearText} 发电量 火电 水电 核电 风电 太阳能`\n : '国家统计局 发电量 火电 水电 核电 风电 太阳能',\n yearText\n ? `国家能源局 ${yearText} 全国电力统计数据 发电装机容量 火电 水电 风电 太阳能`\n : '国家能源局 全国电力统计数据 发电装机容量 火电 水电 风电 太阳能',\n yearText\n ? `中电联 ${yearText} 电力供需形势 非化石能源 发电量 占比`\n : '中电联 电力供需形势 非化石能源 发电量 占比',\n yearText\n ? `China ${yearText} electricity generation mix coal hydro nuclear wind solar`\n : 'China electricity generation mix coal hydro nuclear wind solar',\n yearText\n ? `China ${yearText} installed power capacity mix thermal hydro nuclear wind solar`\n : 'China installed power capacity mix thermal hydro nuclear wind solar',\n ...preferredQueries,\n ];\n return dedupeStrings(generated).slice(0, request.budget.max_queries);\n}\n\nfunction buildSearchPlan(request: EvidenceSearchRequest): EvidenceSearchQuery[] {\n const expectedTerms = extractTerms(request.question, request.required_terms);\n return buildQueryTexts(request).map((text, index) => ({\n query_id: `q${String(index + 1).padStart(2, '0')}`,\n text,\n purpose: index === 0 ? 'broad_discovery' : 'source_targeted_discovery',\n source_tier: text.startsWith('site:') ? 'targeted' : 'general',\n priority: index + 1,\n expected_terms: expectedTerms,\n }));\n}\n\nfunction normalizeRequest(options: RunDatasetEvidenceSearchOptions): EvidenceSearchRequest {\n const rawInput = options.rawInput ?? (options.inputPath ? readJsonInput(options.inputPath) : {});\n const input = isRecord(rawInput) ? rawInput : {};\n const question = trimToken(options.query) ?? trimToken(input.question);\n if (!question) {\n throw new CliError('Evidence search requires --query or input.question.', {\n code: 'EVIDENCE_SEARCH_QUESTION_REQUIRED',\n exitCode: 2,\n });\n }\n\n const profile = normalizeProfile(options.profile ?? trimToken(input.profile));\n const defaultBudget = DEFAULT_BUDGETS[profile];\n const budgetInput = isRecord(input.budget) ? input.budget : {};\n const maxQueries = readPositiveInteger(\n options.maxQueries ?? budgetInput.max_queries,\n defaultBudget.max_queries,\n '--max-queries',\n );\n const maxResultsPerQuery = readPositiveInteger(\n options.maxResultsPerQuery ?? budgetInput.max_results_per_query,\n defaultBudget.max_results_per_query,\n '--max-results-per-query',\n );\n const budget = {\n max_queries: maxQueries,\n max_results_per_query: maxResultsPerQuery,\n max_provider_calls: maxQueries,\n };\n const fieldInput = isRecord(input.field) ? input.field : {};\n\n return {\n question,\n field: {\n dataset_type: trimToken(fieldInput.dataset_type),\n field_path: trimToken(fieldInput.field_path),\n },\n profile,\n budget,\n preferred_domains: readStringArray(input.preferred_domains),\n required_terms: readStringArray(input.required_terms),\n required_complete_year: requestRequiresCompleteYear(input),\n requested_year: readRequestedYear(question, input),\n };\n}\n\nfunction readResultsInput(resultsPath: string, rawResults?: unknown): unknown {\n if (rawResults !== undefined) {\n return rawResults;\n }\n const text = readFileSync(resultsPath, 'utf8');\n const trimmed = text.trim();\n if (!trimmed) {\n return [];\n }\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.parse(trimmed);\n } catch (error) {\n throw new CliError(`Search results file is not valid JSON: ${resultsPath}`, {\n code: 'EVIDENCE_SEARCH_RESULTS_INVALID_JSON',\n exitCode: 2,\n details: String(error),\n });\n }\n }\n return trimmed\n .split(/\\r?\\n/u)\n .map((line, index) => {\n try {\n return JSON.parse(line);\n } catch (error) {\n throw new CliError(`Search results file has invalid JSONL at line ${index + 1}.`, {\n code: 'EVIDENCE_SEARCH_RESULTS_INVALID_JSONL',\n exitCode: 2,\n details: String(error),\n });\n }\n })\n .filter((item) => item !== null);\n}\n\nfunction extractItems(value: JsonObject): unknown[] {\n for (const key of ['items', 'results', 'data', 'web_results']) {\n const candidate = value[key];\n if (Array.isArray(candidate)) {\n return candidate;\n }\n }\n return [];\n}\n\nfunction normalizeResultGroups(rawResults: unknown): ProviderQueryResult[] {\n const root = rawResults;\n if (isRecord(root) && Array.isArray(root.queries)) {\n return root.queries.filter(isRecord).map((queryGroup) => ({\n provider: trimToken(queryGroup.provider) ?? 'external',\n query_id: trimToken(queryGroup.query_id),\n query: trimToken(queryGroup.query ?? queryGroup.text),\n items: extractItems(queryGroup),\n }));\n }\n const rows = Array.isArray(root) ? root : [root];\n if (rows.every(isRecord) && rows.some((row) => extractItems(row).length > 0)) {\n return rows.filter(isRecord).map((queryGroup) => ({\n provider: trimToken(queryGroup.provider) ?? 'external',\n query_id: trimToken(queryGroup.query_id),\n query: trimToken(queryGroup.query ?? queryGroup.text),\n items: extractItems(queryGroup),\n }));\n }\n return [\n {\n provider: 'external',\n query_id: null,\n query: null,\n items: rows,\n },\n ];\n}\n\nfunction normalizeOneResult(options: {\n item: unknown;\n group: ProviderQueryResult;\n rank: number;\n terms: string[];\n preferredDomains: string[];\n}): EvidenceSearchResult | null {\n if (!isRecord(options.item)) {\n return null;\n }\n const title = trimToken(options.item.title ?? options.item.name);\n const url = trimToken(options.item.url ?? options.item.link ?? options.item.href);\n if (!title || !url) {\n return null;\n }\n const snippet = trimToken(\n options.item.snippet ?? options.item.description ?? options.item.summary ?? options.item.text,\n );\n const publishedAt = trimToken(\n options.item.published_at ?? options.item.publishedAt ?? options.item.date,\n );\n const sourceText = `${title} ${snippet ?? ''}`.toLowerCase();\n const matchedTerms = options.terms.filter((term) => sourceText.includes(term));\n const domain = normalizeDomain(url);\n const sourceTier = classifySourceTier(domain, options.preferredDomains);\n const authorityScore =\n sourceTier === 'official_statistics'\n ? 4\n : sourceTier === 'preferred_domain' || sourceTier === 'industry_association'\n ? 3\n : sourceTier === 'international_statistics'\n ? 2\n : 1;\n const termScore = Math.min(matchedTerms.length, 6);\n return {\n query_id: options.group.query_id,\n query: options.group.query,\n provider: options.group.provider,\n rank: options.rank,\n title,\n url,\n snippet,\n published_at: publishedAt,\n source_domain: domain,\n source_tier: sourceTier,\n matched_terms: matchedTerms,\n score: authorityScore + termScore,\n };\n}\n\nfunction normalizeResults(options: {\n rawResults: unknown;\n terms: string[];\n preferredDomains: string[];\n maxResultsPerQuery: number;\n}): EvidenceSearchResult[] {\n const byUrl = new Map<string, EvidenceSearchResult>();\n for (const group of normalizeResultGroups(options.rawResults)) {\n group.items.slice(0, options.maxResultsPerQuery).forEach((item, index) => {\n const result = normalizeOneResult({\n item,\n group,\n rank: index + 1,\n terms: options.terms,\n preferredDomains: options.preferredDomains,\n });\n if (!result) {\n return;\n }\n const previous = byUrl.get(result.url);\n if (!previous || result.score > previous.score) {\n byUrl.set(result.url, result);\n }\n });\n }\n return [...byUrl.values()].sort(\n (left, right) => right.score - left.score || left.rank - right.rank,\n );\n}\n\nasync function fetchProviderResults(options: {\n providerUrl: string;\n providerKey: string | null;\n plan: EvidenceSearchQuery[];\n request: EvidenceSearchRequest;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ rawResults: ProviderQueryResult[]; callCount: number }> {\n const rawResults: ProviderQueryResult[] = [];\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (options.providerKey) {\n headers.Authorization = `Bearer ${options.providerKey}`;\n }\n for (const query of options.plan.slice(0, options.request.budget.max_provider_calls)) {\n const payload = await postJson({\n url: options.providerUrl,\n headers,\n body: {\n query: query.text,\n query_id: query.query_id,\n limit: options.request.budget.max_results_per_query,\n context: {\n question: options.request.question,\n field: options.request.field,\n expected_terms: query.expected_terms,\n },\n },\n timeoutMs: options.timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n rawResults.push({\n provider: options.providerUrl,\n query_id: query.query_id,\n query: query.text,\n items: isRecord(payload) ? extractItems(payload) : Array.isArray(payload) ? payload : [],\n });\n }\n return { rawResults, callCount: rawResults.length };\n}\n\nfunction temporalCoverageStatus(request: EvidenceSearchRequest, now: Date): string {\n if (!request.required_complete_year || !request.requested_year) {\n return 'not_required';\n }\n const currentYear = now.getUTCFullYear();\n if (request.requested_year > currentYear) {\n return 'future_year';\n }\n if (request.requested_year === currentYear && now.getUTCMonth() < 11) {\n return 'incomplete_current_year';\n }\n return 'complete_year_possible';\n}\n\nfunction buildDeclaration(options: {\n generatedAt: string;\n request: EvidenceSearchRequest;\n queryCount: number;\n providerCount: number;\n resultCount: number;\n authoritativeResultCount: number;\n temporalStatus: string;\n partial: boolean;\n}): EvidenceSearchDeclaration {\n const declarationType = options.partial ? 'partial_temporal_evidence' : 'no_sufficient_evidence';\n const statement =\n declarationType === 'partial_temporal_evidence'\n ? 'The configured search found current-year or forecast evidence, but not complete annual evidence for the requested year.'\n : 'Within the configured search scope, query matrix, source policy, and budget, no sufficient evidence was found for the requested field.';\n return {\n schema_version: 1,\n generated_at_utc: options.generatedAt,\n question: options.request.question,\n declaration_type: declarationType,\n statement,\n search_scope: {\n query_count: options.queryCount,\n provider_count: options.providerCount,\n normalized_result_count: options.resultCount,\n authoritative_result_count: options.authoritativeResultCount,\n required_complete_year: options.request.required_complete_year,\n requested_year: options.request.requested_year,\n temporal_coverage_status: options.temporalStatus,\n },\n limits: [\n 'The command records deterministic search scope and result normalization; it does not prove that the open web contains no undiscoverable source.',\n 'Browser-only, paywalled, login-protected, or unindexed sources require separate readback or manual evidence capture.',\n 'A no-evidence or partial-evidence declaration is valid only for the configured query matrix, provider set, and budget.',\n ],\n };\n}\n\nfunction buildReport(options: {\n generatedAt: string;\n mode: EvidenceSearchMode;\n request: EvidenceSearchRequest;\n plan: EvidenceSearchQuery[];\n results: EvidenceSearchResult[];\n providerCount: number;\n providerCallCount: number;\n files: EvidenceSearchReport['files'];\n now: Date;\n}): EvidenceSearchReport {\n const authoritativeResultCount = options.results.filter((result) =>\n ['official_statistics', 'preferred_domain', 'industry_association'].includes(\n result.source_tier,\n ),\n ).length;\n const highConfidenceResultCount = options.results.filter((result) => result.score >= 7).length;\n const temporalStatus = temporalCoverageStatus(options.request, options.now);\n const hasEvidence = authoritativeResultCount > 0 || highConfidenceResultCount > 0;\n const partial =\n hasEvidence && ['future_year', 'incomplete_current_year'].includes(temporalStatus);\n const sufficient = hasEvidence && !partial;\n const status: EvidenceSearchStatus =\n options.mode === 'plan'\n ? 'planned'\n : sufficient\n ? 'completed_with_evidence'\n : partial\n ? 'completed_with_partial_evidence'\n : 'completed_no_sufficient_evidence';\n const stopReason =\n options.mode === 'plan'\n ? 'plan_only'\n : sufficient\n ? 'sufficient_authoritative_evidence_found'\n : partial\n ? 'complete_annual_scope_not_available'\n : 'budget_exhausted_without_sufficient_evidence';\n\n return {\n schema_version: 1,\n generated_at_utc: options.generatedAt,\n mode: options.mode,\n status,\n question: options.request.question,\n field: options.request.field,\n profile: options.request.profile,\n budget: options.request.budget,\n plan: {\n query_count: options.plan.length,\n queries: options.plan,\n },\n run: {\n provider_count: options.providerCount,\n provider_call_count: options.providerCallCount,\n normalized_result_count: options.results.length,\n authoritative_result_count: authoritativeResultCount,\n high_confidence_result_count: highConfidenceResultCount,\n stop_reason: stopReason,\n },\n evidence_quality: {\n sufficient,\n temporal_coverage_status: temporalStatus,\n requested_year: options.request.requested_year,\n required_complete_year: options.request.required_complete_year,\n },\n files: options.files,\n };\n}\n\nexport async function runDatasetEvidenceSearch(\n options: RunDatasetEvidenceSearchOptions,\n): Promise<EvidenceSearchReport> {\n const request = normalizeRequest(options);\n const plan = buildSearchPlan(request);\n const generatedAt = nowIso(options.now);\n const now = options.now ?? new Date();\n const outputDir = options.outDir ? path.resolve(options.outDir) : null;\n const planFile = outputDir ? path.join(outputDir, 'outputs', 'evidence-search-plan.json') : null;\n const resultsFile = outputDir\n ? path.join(outputDir, 'outputs', 'evidence-search-results.jsonl')\n : null;\n const reportFile = outputDir\n ? path.join(outputDir, 'outputs', 'evidence-search-report.json')\n : null;\n const declarationFile = outputDir\n ? path.join(outputDir, 'outputs', 'evidence-search-declaration.json')\n : null;\n\n if (planFile) {\n writeJsonArtifact(planFile, {\n schema_version: 1,\n generated_at_utc: generatedAt,\n question: request.question,\n field: request.field,\n profile: request.profile,\n budget: request.budget,\n queries: plan,\n });\n }\n\n let rawResults: unknown = [];\n let providerCount = 0;\n let providerCallCount = 0;\n\n if (options.mode === 'run') {\n if (options.resultsPath) {\n rawResults = readResultsInput(options.resultsPath, options.rawResults);\n providerCount += 1;\n }\n if (options.providerUrl) {\n if (!options.fetchImpl) {\n throw new CliError('Evidence search provider mode requires fetchImpl.', {\n code: 'EVIDENCE_SEARCH_FETCH_IMPL_REQUIRED',\n exitCode: 2,\n });\n }\n const providerResults = await fetchProviderResults({\n providerUrl: options.providerUrl,\n providerKey: options.providerKey ?? null,\n plan,\n request,\n timeoutMs: options.timeoutMs ?? 30_000,\n fetchImpl: options.fetchImpl,\n });\n rawResults = [...normalizeResultGroups(rawResults), ...providerResults.rawResults];\n providerCount += 1;\n providerCallCount += providerResults.callCount;\n }\n if (!options.resultsPath && !options.providerUrl) {\n throw new CliError('dataset evidence-search run requires --results or --provider-url.', {\n code: 'EVIDENCE_SEARCH_PROVIDER_REQUIRED',\n exitCode: 2,\n });\n }\n }\n\n const terms = extractTerms(request.question, request.required_terms);\n const results =\n options.mode === 'run'\n ? normalizeResults({\n rawResults,\n terms,\n preferredDomains: request.preferred_domains,\n maxResultsPerQuery: request.budget.max_results_per_query,\n })\n : [];\n if (resultsFile) {\n writeJsonLinesArtifact(resultsFile, results);\n }\n\n const preliminaryReport = buildReport({\n generatedAt,\n mode: options.mode,\n request,\n plan,\n results,\n providerCount,\n providerCallCount,\n files: {\n plan: planFile,\n results: resultsFile,\n report: reportFile,\n declaration: null,\n },\n now,\n });\n\n let finalDeclarationFile: string | null = null;\n if (\n outputDir &&\n options.mode === 'run' &&\n preliminaryReport.status !== 'completed_with_evidence'\n ) {\n const declaration = buildDeclaration({\n generatedAt,\n request,\n queryCount: plan.length,\n providerCount,\n resultCount: results.length,\n authoritativeResultCount: preliminaryReport.run.authoritative_result_count,\n temporalStatus: preliminaryReport.evidence_quality.temporal_coverage_status,\n partial: preliminaryReport.status === 'completed_with_partial_evidence',\n });\n finalDeclarationFile = writeJsonArtifact(declarationFile!, declaration);\n }\n\n const report = {\n ...preliminaryReport,\n files: {\n ...preliminaryReport.files,\n declaration: finalDeclarationFile,\n },\n };\n if (reportFile) {\n writeJsonArtifact(reportFile, report);\n }\n return report;\n}\n\nexport const __testInternals = {\n buildSearchPlan,\n classifySourceTier,\n normalizeResults,\n normalizeRequest,\n temporalCoverageStatus,\n};\n"]}
@@ -0,0 +1,171 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { spawnSync } from 'node:child_process';
5
+ import { writeJsonArtifact } from './artifacts.js';
6
+ import { CliError } from './errors.js';
7
+ export function runDatasetImportLcaConvert(options) {
8
+ const inputPath = requireInputPath(options.inputPath);
9
+ const outputDir = requireOutputDir(options.outputDir);
10
+ const target = normalizeTarget(options.target);
11
+ const fromFormat = options.fromFormat?.trim() || 'auto';
12
+ const pythonBin = options.pythonBin?.trim() || 'python3';
13
+ const tidasToolsRoot = resolveTidasToolsRoot(options.tidasToolsDir, options.env ?? process.env);
14
+ const reportPath = path.resolve(options.reportPath ?? path.join(outputDir, 'conversion-report.json'));
15
+ const commandArgs = [
16
+ '-m',
17
+ 'tidas_tools.import_lca.cli',
18
+ '--input',
19
+ inputPath,
20
+ '--output-dir',
21
+ outputDir,
22
+ '--from-format',
23
+ fromFormat,
24
+ '--target',
25
+ target,
26
+ '--report',
27
+ reportPath,
28
+ '--language',
29
+ options.language?.trim() || 'en',
30
+ '--validation-jobs',
31
+ String(options.validationJobs ?? 1),
32
+ ];
33
+ if (options.mappingDir) {
34
+ commandArgs.push('--mapping-dir', path.resolve(options.mappingDir));
35
+ }
36
+ if (options.failOnWarning) {
37
+ commandArgs.push('--fail-on-warning');
38
+ }
39
+ if (options.detectOnly) {
40
+ commandArgs.push('--detect-only');
41
+ }
42
+ const run = (options.spawnImpl ?? spawnSync)(pythonBin, commandArgs, {
43
+ cwd: tidasToolsRoot,
44
+ env: {
45
+ ...(options.env ?? process.env),
46
+ PYTHONPATH: buildPythonPath(tidasToolsRoot, options.env ?? process.env),
47
+ },
48
+ encoding: 'utf8',
49
+ });
50
+ const conversionReport = readOptionalJson(reportPath);
51
+ const files = {
52
+ report: path.join(outputDir, 'outputs', 'import-lca-report.json'),
53
+ conversion_report: reportPath,
54
+ tidas_dir: options.detectOnly ? null : path.join(outputDir, 'tidas'),
55
+ ilcd_dir: !options.detectOnly && (target === 'ilcd' || target === 'both')
56
+ ? path.join(outputDir, 'ilcd')
57
+ : null,
58
+ mapping_csv: options.detectOnly ? null : path.join(outputDir, 'mapping.csv'),
59
+ };
60
+ const report = {
61
+ schema_version: 1,
62
+ status: run.status === 0 ? 'completed' : 'blocked',
63
+ generated_at_utc: (options.now ?? new Date()).toISOString(),
64
+ input_path: inputPath,
65
+ output_dir: outputDir,
66
+ from_format: fromFormat,
67
+ target,
68
+ detect_only: Boolean(options.detectOnly),
69
+ command: {
70
+ executable: pythonBin,
71
+ args: commandArgs,
72
+ cwd: tidasToolsRoot,
73
+ exit_code: run.status,
74
+ stdout: run.stdout ?? '',
75
+ stderr: run.stderr ?? '',
76
+ },
77
+ conversion_report: conversionReport,
78
+ files,
79
+ };
80
+ writeJsonArtifact(files.report, report);
81
+ return report;
82
+ }
83
+ function requireInputPath(value) {
84
+ if (!value?.trim()) {
85
+ throw new CliError('Missing required --input value.', {
86
+ code: 'DATASET_IMPORT_LCA_INPUT_REQUIRED',
87
+ exitCode: 2,
88
+ });
89
+ }
90
+ const resolved = path.resolve(value);
91
+ if (!existsSync(resolved)) {
92
+ throw new CliError(`Input path not found: ${resolved}`, {
93
+ code: 'DATASET_IMPORT_LCA_INPUT_NOT_FOUND',
94
+ exitCode: 2,
95
+ });
96
+ }
97
+ return resolved;
98
+ }
99
+ function requireOutputDir(value) {
100
+ if (!value?.trim()) {
101
+ throw new CliError('Missing required --output-dir value.', {
102
+ code: 'DATASET_IMPORT_LCA_OUTPUT_DIR_REQUIRED',
103
+ exitCode: 2,
104
+ });
105
+ }
106
+ return path.resolve(value);
107
+ }
108
+ function normalizeTarget(value) {
109
+ const target = value?.trim() || 'tidas';
110
+ if (target === 'tidas' || target === 'ilcd' || target === 'both') {
111
+ return target;
112
+ }
113
+ throw new CliError("--target must be 'tidas', 'ilcd', or 'both'.", {
114
+ code: 'DATASET_IMPORT_LCA_TARGET_INVALID',
115
+ exitCode: 2,
116
+ });
117
+ }
118
+ function resolveTidasToolsRoot(explicitValue, env, defaultCandidate) {
119
+ const cliRepoRoot = resolveCliRepoRoot();
120
+ if (explicitValue?.trim()) {
121
+ const resolved = path.resolve(explicitValue);
122
+ if (existsSync(path.join(resolved, 'src/tidas_tools/import_lca/cli.py'))) {
123
+ return resolved;
124
+ }
125
+ throw new CliError('Could not resolve a tidas-tools checkout for dataset import.', {
126
+ code: 'DATASET_IMPORT_LCA_TIDAS_TOOLS_NOT_FOUND',
127
+ exitCode: 2,
128
+ details: { candidates: [explicitValue] },
129
+ });
130
+ }
131
+ const candidates = [
132
+ env.TIDAS_TOOLS_DIR,
133
+ env.TIDAS_TOOLS_PATH,
134
+ defaultCandidate ?? path.resolve(cliRepoRoot, '../tidas-tools'),
135
+ ].filter((candidate) => Boolean(candidate?.trim()));
136
+ for (const candidate of candidates) {
137
+ const resolved = path.resolve(candidate);
138
+ if (existsSync(path.join(resolved, 'src/tidas_tools/import_lca/cli.py'))) {
139
+ return resolved;
140
+ }
141
+ }
142
+ throw new CliError('Could not resolve a tidas-tools checkout for dataset import.', {
143
+ code: 'DATASET_IMPORT_LCA_TIDAS_TOOLS_NOT_FOUND',
144
+ exitCode: 2,
145
+ details: { candidates },
146
+ });
147
+ }
148
+ function resolveCliRepoRoot(candidatesOverride) {
149
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
150
+ const candidates = candidatesOverride ?? [
151
+ path.resolve(moduleDir, '../..'),
152
+ path.resolve(moduleDir, '../../..'),
153
+ ];
154
+ return (candidates.find((candidate) => existsSync(path.join(candidate, 'package.json')) &&
155
+ existsSync(path.join(candidate, 'src/cli.ts'))) ?? candidates[0]);
156
+ }
157
+ function buildPythonPath(tidasToolsRoot, env) {
158
+ return [path.join(tidasToolsRoot, 'src'), env.PYTHONPATH].filter(Boolean).join(path.delimiter);
159
+ }
160
+ function readOptionalJson(filePath) {
161
+ if (!existsSync(filePath)) {
162
+ return null;
163
+ }
164
+ return JSON.parse(readFileSync(filePath, 'utf8'));
165
+ }
166
+ export const __testInternals = {
167
+ normalizeTarget,
168
+ resolveCliRepoRoot,
169
+ resolveTidasToolsRoot,
170
+ };
171
+ //# sourceMappingURL=dataset-import-lca.js.map
@@ -0,0 +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 { fileURLToPath } from 'node:url';\nimport { spawnSync, type SpawnSyncReturns } from 'node:child_process';\nimport { writeJsonArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\n\nexport type DatasetImportLcaTarget = 'tidas' | 'ilcd' | 'both';\n\nexport type DatasetImportLcaReport = {\n schema_version: 1;\n status: 'completed' | 'blocked';\n generated_at_utc: string;\n input_path: string;\n output_dir: string;\n from_format: string;\n target: DatasetImportLcaTarget;\n detect_only: boolean;\n command: {\n executable: string;\n args: string[];\n cwd: string;\n exit_code: number | null;\n stdout: string;\n stderr: string;\n };\n conversion_report: unknown | null;\n files: {\n report: string;\n conversion_report: string;\n tidas_dir: string | null;\n ilcd_dir: string | null;\n mapping_csv: string | null;\n };\n};\n\nexport type RunDatasetImportLcaConvertOptions = {\n inputPath: string;\n outputDir: string;\n fromFormat?: string | undefined;\n target?: string | undefined;\n language?: string | undefined;\n reportPath?: string | undefined;\n mappingDir?: string | undefined;\n failOnWarning?: boolean | undefined;\n validationJobs?: number | undefined;\n detectOnly?: boolean | undefined;\n pythonBin?: string | undefined;\n tidasToolsDir?: string | undefined;\n env?: NodeJS.ProcessEnv | undefined;\n now?: Date | undefined;\n spawnImpl?: typeof spawnSync | undefined;\n};\n\nexport function runDatasetImportLcaConvert(\n options: RunDatasetImportLcaConvertOptions,\n): DatasetImportLcaReport {\n const inputPath = requireInputPath(options.inputPath);\n const outputDir = requireOutputDir(options.outputDir);\n const target = normalizeTarget(options.target);\n const fromFormat = options.fromFormat?.trim() || 'auto';\n const pythonBin = options.pythonBin?.trim() || 'python3';\n const tidasToolsRoot = resolveTidasToolsRoot(options.tidasToolsDir, options.env ?? process.env);\n const reportPath = path.resolve(\n options.reportPath ?? path.join(outputDir, 'conversion-report.json'),\n );\n const commandArgs = [\n '-m',\n 'tidas_tools.import_lca.cli',\n '--input',\n inputPath,\n '--output-dir',\n outputDir,\n '--from-format',\n fromFormat,\n '--target',\n target,\n '--report',\n reportPath,\n '--language',\n options.language?.trim() || 'en',\n '--validation-jobs',\n String(options.validationJobs ?? 1),\n ];\n if (options.mappingDir) {\n commandArgs.push('--mapping-dir', path.resolve(options.mappingDir));\n }\n if (options.failOnWarning) {\n commandArgs.push('--fail-on-warning');\n }\n if (options.detectOnly) {\n commandArgs.push('--detect-only');\n }\n\n const run = (options.spawnImpl ?? spawnSync)(pythonBin, commandArgs, {\n cwd: tidasToolsRoot,\n env: {\n ...(options.env ?? process.env),\n PYTHONPATH: buildPythonPath(tidasToolsRoot, options.env ?? process.env),\n },\n encoding: 'utf8',\n }) as SpawnSyncReturns<string>;\n const conversionReport = readOptionalJson(reportPath);\n const files = {\n report: path.join(outputDir, 'outputs', 'import-lca-report.json'),\n conversion_report: reportPath,\n tidas_dir: options.detectOnly ? null : path.join(outputDir, 'tidas'),\n ilcd_dir:\n !options.detectOnly && (target === 'ilcd' || target === 'both')\n ? path.join(outputDir, 'ilcd')\n : null,\n mapping_csv: options.detectOnly ? null : path.join(outputDir, 'mapping.csv'),\n };\n const report: DatasetImportLcaReport = {\n schema_version: 1,\n status: run.status === 0 ? 'completed' : 'blocked',\n generated_at_utc: (options.now ?? new Date()).toISOString(),\n input_path: inputPath,\n output_dir: outputDir,\n from_format: fromFormat,\n target,\n detect_only: Boolean(options.detectOnly),\n command: {\n executable: pythonBin,\n args: commandArgs,\n cwd: tidasToolsRoot,\n exit_code: run.status,\n stdout: run.stdout ?? '',\n stderr: run.stderr ?? '',\n },\n conversion_report: conversionReport,\n files,\n };\n\n writeJsonArtifact(files.report, report);\n return report;\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 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 resolveTidasToolsRoot(\n explicitValue: string | undefined,\n env: NodeJS.ProcessEnv,\n defaultCandidate?: string,\n): string {\n const cliRepoRoot = resolveCliRepoRoot();\n if (explicitValue?.trim()) {\n const resolved = path.resolve(explicitValue);\n if (existsSync(path.join(resolved, 'src/tidas_tools/import_lca/cli.py'))) {\n return resolved;\n }\n throw new CliError('Could not resolve a tidas-tools checkout for dataset import.', {\n code: 'DATASET_IMPORT_LCA_TIDAS_TOOLS_NOT_FOUND',\n exitCode: 2,\n details: { candidates: [explicitValue] },\n });\n }\n\n const candidates = [\n env.TIDAS_TOOLS_DIR,\n env.TIDAS_TOOLS_PATH,\n defaultCandidate ?? path.resolve(cliRepoRoot, '../tidas-tools'),\n ].filter((candidate): candidate is string => Boolean(candidate?.trim()));\n\n for (const candidate of candidates) {\n const resolved = path.resolve(candidate);\n if (existsSync(path.join(resolved, 'src/tidas_tools/import_lca/cli.py'))) {\n return resolved;\n }\n }\n\n throw new CliError('Could not resolve a tidas-tools checkout for dataset import.', {\n code: 'DATASET_IMPORT_LCA_TIDAS_TOOLS_NOT_FOUND',\n exitCode: 2,\n details: { candidates },\n });\n}\n\nfunction resolveCliRepoRoot(candidatesOverride?: string[]): string {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = candidatesOverride ?? [\n path.resolve(moduleDir, '../..'),\n path.resolve(moduleDir, '../../..'),\n ];\n return (\n candidates.find(\n (candidate) =>\n existsSync(path.join(candidate, 'package.json')) &&\n existsSync(path.join(candidate, 'src/cli.ts')),\n ) ?? candidates[0]\n );\n}\n\nfunction buildPythonPath(tidasToolsRoot: string, env: NodeJS.ProcessEnv): string {\n return [path.join(tidasToolsRoot, 'src'), env.PYTHONPATH].filter(Boolean).join(path.delimiter);\n}\n\nfunction readOptionalJson(filePath: string): unknown | null {\n if (!existsSync(filePath)) {\n return null;\n }\n return JSON.parse(readFileSync(filePath, 'utf8'));\n}\n\nexport const __testInternals = {\n normalizeTarget,\n resolveCliRepoRoot,\n resolveTidasToolsRoot,\n};\n"]}
@@ -0,0 +1,166 @@
1
+ import path from 'node:path';
2
+ import { readFileSync } from 'node:fs';
3
+ import { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';
4
+ import { CliError } from './errors.js';
5
+ import { cloneJson, isRecord, readDatasetRowsInput, unwrapDatasetPayload, } from './dataset-local.js';
6
+ import { runDatasetRemoteVerify, } from './dataset-remote-verify.js';
7
+ function requireNonEmpty(value, label, code) {
8
+ const normalized = value.trim();
9
+ if (!normalized) {
10
+ throw new CliError(`Missing required ${label} value.`, {
11
+ code,
12
+ exitCode: 2,
13
+ });
14
+ }
15
+ return normalized;
16
+ }
17
+ function nowIso(now = new Date()) {
18
+ return now.toISOString();
19
+ }
20
+ function readJsonl(filePath) {
21
+ return readFileSync(filePath, 'utf8')
22
+ .split(/\r?\n/u)
23
+ .map((line) => line.trim())
24
+ .filter(Boolean)
25
+ .map((line) => JSON.parse(line))
26
+ .filter(isRecord);
27
+ }
28
+ function decodePointerSegment(segment) {
29
+ return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');
30
+ }
31
+ function pointerSegments(pointerPath) {
32
+ return pointerPath
33
+ .split('/')
34
+ .filter(Boolean)
35
+ .map((segment) => decodePointerSegment(segment));
36
+ }
37
+ function valueAtPointer(root, pointerPath) {
38
+ let current = root;
39
+ for (const segment of pointerSegments(pointerPath)) {
40
+ if (Array.isArray(current)) {
41
+ const index = Number(segment);
42
+ current = Number.isInteger(index) ? current[index] : undefined;
43
+ }
44
+ else if (isRecord(current)) {
45
+ current = current[segment];
46
+ }
47
+ else {
48
+ return undefined;
49
+ }
50
+ }
51
+ return current;
52
+ }
53
+ function referenceNodeForPatch(payload, check) {
54
+ if (check.path.endsWith('/@flowUUID')) {
55
+ const parentPath = check.path.slice(0, -'/@flowUUID'.length);
56
+ const parent = valueAtPointer(payload, parentPath);
57
+ return isRecord(parent) ? parent : null;
58
+ }
59
+ const node = valueAtPointer(payload, check.path);
60
+ return isRecord(node) ? node : null;
61
+ }
62
+ function refreshableCheck(check) {
63
+ return (check.role === 'reference' &&
64
+ Boolean(check.latest_version) &&
65
+ ['missing_version', 'version_missing', 'version_outdated'].includes(check.status));
66
+ }
67
+ function applyRemoteRefreshPatches(rows, checks) {
68
+ const patchedRows = cloneJson(rows);
69
+ const patches = [];
70
+ for (const check of checks.filter(refreshableCheck)) {
71
+ const row = patchedRows[check.row_index];
72
+ if (!row || !check.latest_version) {
73
+ continue;
74
+ }
75
+ const payload = unwrapDatasetPayload(row);
76
+ const node = referenceNodeForPatch(payload, check);
77
+ if (!node) {
78
+ continue;
79
+ }
80
+ const before = typeof node['@version'] === 'string' ? node['@version'] : null;
81
+ if (before === check.latest_version) {
82
+ continue;
83
+ }
84
+ node['@version'] = check.latest_version;
85
+ patches.push({
86
+ row_index: check.row_index,
87
+ role: check.role,
88
+ table: check.table,
89
+ id: check.id,
90
+ from_version: before,
91
+ to_version: check.latest_version,
92
+ path: check.path,
93
+ status_before: check.status,
94
+ });
95
+ }
96
+ return { rows: patchedRows, patches };
97
+ }
98
+ function buildFiles(outPath, outDir) {
99
+ const resolved = path.resolve(outDir);
100
+ return {
101
+ output_rows: path.resolve(outPath),
102
+ report: path.join(resolved, 'outputs', 'remote-refresh-report.json'),
103
+ patches: path.join(resolved, 'outputs', 'remote-refresh-patches.jsonl'),
104
+ pre_verification_report: path.join(resolved, 'pre-refresh-verify', 'outputs', 'remote-verification-report.json'),
105
+ post_verification_report: path.join(resolved, 'post-refresh-verify', 'outputs', 'remote-verification-report.json'),
106
+ };
107
+ }
108
+ export async function runDatasetRemoteRefresh(options) {
109
+ const inputPath = path.resolve(requireNonEmpty(options.inputPath, '--input', 'DATASET_REMOTE_REFRESH_INPUT_REQUIRED'));
110
+ const outPath = path.resolve(requireNonEmpty(options.outPath, '--out', 'DATASET_REMOTE_REFRESH_OUT_REQUIRED'));
111
+ const outDir = path.resolve(requireNonEmpty(options.outDir, '--out-dir', 'DATASET_REMOTE_REFRESH_OUT_DIR_REQUIRED'));
112
+ const runVerify = options.runDatasetRemoteVerifyImpl ?? runDatasetRemoteVerify;
113
+ const rows = readDatasetRowsInput(inputPath, options.rawInput);
114
+ const files = buildFiles(outPath, outDir);
115
+ const preReport = await runVerify({
116
+ inputPath,
117
+ outDir: path.join(outDir, 'pre-refresh-verify'),
118
+ rawInput: rows,
119
+ env: options.env,
120
+ fetchImpl: options.fetchImpl,
121
+ timeoutMs: options.timeoutMs,
122
+ now: options.now,
123
+ rootPolicy: options.rootPolicy,
124
+ });
125
+ const checks = readJsonl(path.join(outDir, 'pre-refresh-verify', 'outputs', 'remote-verification.jsonl'));
126
+ const { rows: patchedRows, patches } = applyRemoteRefreshPatches(rows, checks);
127
+ writeJsonLinesArtifact(outPath, patchedRows);
128
+ writeJsonLinesArtifact(files.patches, patches);
129
+ const postReport = await runVerify({
130
+ inputPath: outPath,
131
+ outDir: path.join(outDir, 'post-refresh-verify'),
132
+ rawInput: patchedRows,
133
+ env: options.env,
134
+ fetchImpl: options.fetchImpl,
135
+ timeoutMs: options.timeoutMs,
136
+ now: options.now,
137
+ rootPolicy: options.rootPolicy,
138
+ });
139
+ const report = {
140
+ schema_version: 1,
141
+ generated_at_utc: nowIso(options.now),
142
+ status: postReport.blockers.length > 0 ? 'completed_with_blockers' : 'completed',
143
+ root_policy: options.rootPolicy ?? 'existing',
144
+ input_path: inputPath,
145
+ out_path: outPath,
146
+ out_dir: outDir,
147
+ counts: {
148
+ rows: rows.length,
149
+ pre_refresh_blockers: preReport.blockers.length,
150
+ refreshable_references: checks.filter(refreshableCheck).length,
151
+ patched_references: patches.length,
152
+ post_refresh_blockers: postReport.blockers.length,
153
+ },
154
+ remaining_blockers: postReport.blockers,
155
+ files,
156
+ };
157
+ writeJsonArtifact(files.report, report);
158
+ return report;
159
+ }
160
+ export const __testInternals = {
161
+ applyRemoteRefreshPatches,
162
+ pointerSegments,
163
+ refreshableCheck,
164
+ valueAtPointer,
165
+ };
166
+ //# sourceMappingURL=dataset-remote-refresh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dataset-remote-refresh.js","sourceRoot":"","sources":["../../../src/lib/dataset-remote-refresh.ts"],"names":[],"mappings":"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","sourcesContent":["import path from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n cloneJson,\n isRecord,\n readDatasetRowsInput,\n unwrapDatasetPayload,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n runDatasetRemoteVerify,\n type DatasetRemoteVerificationReport,\n type RemoteVerificationCheck,\n type RunDatasetRemoteVerifyOptions,\n} from './dataset-remote-verify.js';\n\nexport type DatasetRemoteRefreshPatch = {\n row_index: number;\n role: string;\n table: string | null;\n id: string | null;\n from_version: string | null;\n to_version: string;\n path: string;\n status_before: string;\n};\n\nexport type DatasetRemoteRefreshReport = {\n schema_version: 1;\n generated_at_utc: string;\n status: 'completed' | 'completed_with_blockers';\n root_policy: NonNullable<RunDatasetRemoteVerifyOptions['rootPolicy']>;\n input_path: string;\n out_path: string;\n out_dir: string;\n counts: {\n rows: number;\n pre_refresh_blockers: number;\n refreshable_references: number;\n patched_references: number;\n post_refresh_blockers: number;\n };\n remaining_blockers: DatasetRemoteVerificationReport['blockers'];\n files: {\n output_rows: string;\n report: string;\n patches: string;\n pre_verification_report: string;\n post_verification_report: string;\n };\n};\n\nexport type RunDatasetRemoteRefreshOptions = {\n inputPath: string;\n outPath: string;\n outDir: string;\n rawInput?: unknown;\n env?: NodeJS.ProcessEnv;\n fetchImpl?: FetchLike;\n timeoutMs?: number;\n now?: Date;\n rootPolicy?: RunDatasetRemoteVerifyOptions['rootPolicy'];\n runDatasetRemoteVerifyImpl?: (\n options: RunDatasetRemoteVerifyOptions,\n ) => Promise<DatasetRemoteVerificationReport>;\n};\n\nfunction requireNonEmpty(value: string, label: string, code: string): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new CliError(`Missing required ${label} value.`, {\n code,\n exitCode: 2,\n });\n }\n return normalized;\n}\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction readJsonl(filePath: string): JsonObject[] {\n return readFileSync(filePath, 'utf8')\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line) => JSON.parse(line) as unknown)\n .filter(isRecord);\n}\n\nfunction decodePointerSegment(segment: string): string {\n return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');\n}\n\nfunction pointerSegments(pointerPath: string): string[] {\n return pointerPath\n .split('/')\n .filter(Boolean)\n .map((segment) => decodePointerSegment(segment));\n}\n\nfunction valueAtPointer(root: unknown, pointerPath: string): unknown {\n let current = root;\n for (const segment of pointerSegments(pointerPath)) {\n if (Array.isArray(current)) {\n const index = Number(segment);\n current = Number.isInteger(index) ? current[index] : undefined;\n } else if (isRecord(current)) {\n current = current[segment];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\nfunction referenceNodeForPatch(\n payload: JsonObject,\n check: RemoteVerificationCheck,\n): JsonObject | null {\n if (check.path.endsWith('/@flowUUID')) {\n const parentPath = check.path.slice(0, -'/@flowUUID'.length);\n const parent = valueAtPointer(payload, parentPath);\n return isRecord(parent) ? parent : null;\n }\n const node = valueAtPointer(payload, check.path);\n return isRecord(node) ? node : null;\n}\n\nfunction refreshableCheck(check: RemoteVerificationCheck): boolean {\n return (\n check.role === 'reference' &&\n Boolean(check.latest_version) &&\n ['missing_version', 'version_missing', 'version_outdated'].includes(check.status)\n );\n}\n\nfunction applyRemoteRefreshPatches(\n rows: JsonObject[],\n checks: RemoteVerificationCheck[],\n): { rows: JsonObject[]; patches: DatasetRemoteRefreshPatch[] } {\n const patchedRows = cloneJson(rows);\n const patches: DatasetRemoteRefreshPatch[] = [];\n\n for (const check of checks.filter(refreshableCheck)) {\n const row = patchedRows[check.row_index];\n if (!row || !check.latest_version) {\n continue;\n }\n const payload = unwrapDatasetPayload(row);\n const node = referenceNodeForPatch(payload, check);\n if (!node) {\n continue;\n }\n const before = typeof node['@version'] === 'string' ? node['@version'] : null;\n if (before === check.latest_version) {\n continue;\n }\n node['@version'] = check.latest_version;\n patches.push({\n row_index: check.row_index,\n role: check.role,\n table: check.table,\n id: check.id,\n from_version: before,\n to_version: check.latest_version,\n path: check.path,\n status_before: check.status,\n });\n }\n\n return { rows: patchedRows, patches };\n}\n\nfunction buildFiles(outPath: string, outDir: string): DatasetRemoteRefreshReport['files'] {\n const resolved = path.resolve(outDir);\n return {\n output_rows: path.resolve(outPath),\n report: path.join(resolved, 'outputs', 'remote-refresh-report.json'),\n patches: path.join(resolved, 'outputs', 'remote-refresh-patches.jsonl'),\n pre_verification_report: path.join(\n resolved,\n 'pre-refresh-verify',\n 'outputs',\n 'remote-verification-report.json',\n ),\n post_verification_report: path.join(\n resolved,\n 'post-refresh-verify',\n 'outputs',\n 'remote-verification-report.json',\n ),\n };\n}\n\nexport async function runDatasetRemoteRefresh(\n options: RunDatasetRemoteRefreshOptions,\n): Promise<DatasetRemoteRefreshReport> {\n const inputPath = path.resolve(\n requireNonEmpty(options.inputPath, '--input', 'DATASET_REMOTE_REFRESH_INPUT_REQUIRED'),\n );\n const outPath = path.resolve(\n requireNonEmpty(options.outPath, '--out', 'DATASET_REMOTE_REFRESH_OUT_REQUIRED'),\n );\n const outDir = path.resolve(\n requireNonEmpty(options.outDir, '--out-dir', 'DATASET_REMOTE_REFRESH_OUT_DIR_REQUIRED'),\n );\n const runVerify = options.runDatasetRemoteVerifyImpl ?? runDatasetRemoteVerify;\n const rows = readDatasetRowsInput(inputPath, options.rawInput);\n const files = buildFiles(outPath, outDir);\n\n const preReport = await runVerify({\n inputPath,\n outDir: path.join(outDir, 'pre-refresh-verify'),\n rawInput: rows,\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n rootPolicy: options.rootPolicy,\n });\n const checks = readJsonl(\n path.join(outDir, 'pre-refresh-verify', 'outputs', 'remote-verification.jsonl'),\n ) as RemoteVerificationCheck[];\n const { rows: patchedRows, patches } = applyRemoteRefreshPatches(rows, checks);\n writeJsonLinesArtifact(outPath, patchedRows);\n writeJsonLinesArtifact(files.patches, patches);\n\n const postReport = await runVerify({\n inputPath: outPath,\n outDir: path.join(outDir, 'post-refresh-verify'),\n rawInput: patchedRows,\n env: options.env,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n rootPolicy: options.rootPolicy,\n });\n\n const report: DatasetRemoteRefreshReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n status: postReport.blockers.length > 0 ? 'completed_with_blockers' : 'completed',\n root_policy: options.rootPolicy ?? 'existing',\n input_path: inputPath,\n out_path: outPath,\n out_dir: outDir,\n counts: {\n rows: rows.length,\n pre_refresh_blockers: preReport.blockers.length,\n refreshable_references: checks.filter(refreshableCheck).length,\n patched_references: patches.length,\n post_refresh_blockers: postReport.blockers.length,\n },\n remaining_blockers: postReport.blockers,\n files,\n };\n writeJsonArtifact(files.report, report);\n\n return report;\n}\n\nexport const __testInternals = {\n applyRemoteRefreshPatches,\n pointerSegments,\n refreshableCheck,\n valueAtPointer,\n};\n"]}