@tiangong-lca/cli 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -30
- package/dist/src/cli.js +2235 -149
- package/dist/src/cli.js.map +1 -1
- package/dist/src/lib/dataset-author.js +100 -0
- package/dist/src/lib/dataset-author.js.map +1 -0
- package/dist/src/lib/dataset-bilingual.js +545 -0
- package/dist/src/lib/dataset-bilingual.js.map +1 -0
- package/dist/src/lib/dataset-contract.js +350 -0
- package/dist/src/lib/dataset-contract.js.map +1 -0
- package/dist/src/lib/dataset-evidence-search.js +636 -0
- package/dist/src/lib/dataset-evidence-search.js.map +1 -0
- package/dist/src/lib/dataset-import-lca.js +171 -0
- package/dist/src/lib/dataset-import-lca.js.map +1 -0
- package/dist/src/lib/dataset-local.js +231 -0
- package/dist/src/lib/dataset-local.js.map +1 -0
- package/dist/src/lib/dataset-references-rewrite.js +214 -0
- package/dist/src/lib/dataset-references-rewrite.js.map +1 -0
- package/dist/src/lib/dataset-remote-refresh.js +166 -0
- package/dist/src/lib/dataset-remote-refresh.js.map +1 -0
- package/dist/src/lib/dataset-remote-verify.js +543 -0
- package/dist/src/lib/dataset-remote-verify.js.map +1 -0
- package/dist/src/lib/dataset-validate.js +247 -0
- package/dist/src/lib/dataset-validate.js.map +1 -0
- package/dist/src/lib/flow-payload-validation.js +51 -0
- package/dist/src/lib/flow-payload-validation.js.map +1 -0
- package/dist/src/lib/flow-publish-reviewed-data.js +16 -0
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -1
- package/dist/src/lib/flow-publish-version.js +182 -12
- package/dist/src/lib/flow-publish-version.js.map +1 -1
- package/dist/src/lib/flow-regen-product.js +2 -10
- package/dist/src/lib/flow-regen-product.js.map +1 -1
- package/dist/src/lib/flow-remediate.js +4 -8
- package/dist/src/lib/flow-remediate.js.map +1 -1
- package/dist/src/lib/identity-preflight.js +1021 -0
- package/dist/src/lib/identity-preflight.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-auto-build.js +11 -8
- package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-graph.js +248 -0
- package/dist/src/lib/lifecyclemodel-graph.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-publish-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-save-draft-run.js +245 -0
- package/dist/src/lib/lifecyclemodel-save-draft-run.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-validate-build.js +1 -1
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -1
- package/dist/src/lib/process-auto-build.js +158 -8
- package/dist/src/lib/process-auto-build.js.map +1 -1
- package/dist/src/lib/process-batch-build.js +6 -3
- package/dist/src/lib/process-batch-build.js.map +1 -1
- package/dist/src/lib/process-dedup-review.js +921 -0
- package/dist/src/lib/process-dedup-review.js.map +1 -0
- package/dist/src/lib/process-flow-build-plan.js +1071 -0
- package/dist/src/lib/process-flow-build-plan.js.map +1 -0
- package/dist/src/lib/process-payload-validation.js +57 -0
- package/dist/src/lib/process-payload-validation.js.map +1 -0
- package/dist/src/lib/process-publish-build.js +126 -10
- package/dist/src/lib/process-publish-build.js.map +1 -1
- package/dist/src/lib/process-refresh-references.js +1037 -0
- package/dist/src/lib/process-refresh-references.js.map +1 -0
- package/dist/src/lib/process-required-fields.js +810 -0
- package/dist/src/lib/process-required-fields.js.map +1 -0
- package/dist/src/lib/process-resume-build.js +4 -6
- package/dist/src/lib/process-resume-build.js.map +1 -1
- package/dist/src/lib/process-save-draft-run.js +35 -13
- package/dist/src/lib/process-save-draft-run.js.map +1 -1
- package/dist/src/lib/process-scope-statistics.js +859 -0
- package/dist/src/lib/process-scope-statistics.js.map +1 -0
- package/dist/src/lib/process-verify-rows.js +250 -0
- package/dist/src/lib/process-verify-rows.js.map +1 -0
- package/dist/src/lib/publish.js +101 -1
- package/dist/src/lib/publish.js.map +1 -1
- package/dist/src/lib/remote.js +4 -4
- package/dist/src/lib/remote.js.map +1 -1
- package/dist/src/lib/review-flow.js +58 -0
- package/dist/src/lib/review-flow.js.map +1 -1
- package/dist/src/lib/review-lifecyclemodel.js +2 -2
- package/dist/src/lib/review-lifecyclemodel.js.map +1 -1
- package/dist/src/lib/review-process.js +150 -2
- package/dist/src/lib/review-process.js.map +1 -1
- package/dist/src/lib/runtime-rulesets.js +283 -0
- package/dist/src/lib/runtime-rulesets.js.map +1 -0
- package/dist/src/lib/tidas-sdk-package-validator.js +28 -9
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/dist/src/lib/tidas-sdk-validation.js +96 -0
- package/dist/src/lib/tidas-sdk-validation.js.map +1 -0
- package/dist/src/lib/user-api-key.js +1 -1
- package/dist/src/lib/user-api-key.js.map +1 -1
- package/package.json +5 -5
- /package/bin/{tiangong.d.ts → tiangong-lca.d.ts} +0 -0
- /package/bin/{tiangong.js → tiangong-lca.js} +0 -0
|
@@ -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,231 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { CliError } from './errors.js';
|
|
4
|
+
import { readJsonInput } from './io.js';
|
|
5
|
+
export function isRecord(value) {
|
|
6
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
7
|
+
}
|
|
8
|
+
export function cloneJson(value) {
|
|
9
|
+
return JSON.parse(JSON.stringify(value));
|
|
10
|
+
}
|
|
11
|
+
export function trimToken(value) {
|
|
12
|
+
if (typeof value !== 'string') {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const trimmed = value.trim();
|
|
16
|
+
return trimmed || null;
|
|
17
|
+
}
|
|
18
|
+
export function firstNonEmpty(...values) {
|
|
19
|
+
for (const value of values) {
|
|
20
|
+
const token = trimToken(value);
|
|
21
|
+
if (token) {
|
|
22
|
+
return token;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
function readJsonLinesInput(inputPath) {
|
|
28
|
+
const resolved = path.resolve(inputPath);
|
|
29
|
+
if (!existsSync(resolved)) {
|
|
30
|
+
throw new CliError(`Input file not found: ${resolved}`, {
|
|
31
|
+
code: 'INPUT_NOT_FOUND',
|
|
32
|
+
exitCode: 2,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return readFileSync(resolved, 'utf8')
|
|
36
|
+
.split(/\r?\n/u)
|
|
37
|
+
.map((line) => line.trim())
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
.map((line, index) => {
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = JSON.parse(line);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new CliError(`Input file contains invalid JSONL at line ${index + 1}: ${resolved}`, {
|
|
46
|
+
code: 'INPUT_INVALID_JSONL',
|
|
47
|
+
exitCode: 2,
|
|
48
|
+
details: String(error),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (!isRecord(parsed)) {
|
|
52
|
+
throw new CliError(`Expected JSON object rows in JSONL input: ${resolved} (line ${index + 1})`, {
|
|
53
|
+
code: 'INPUT_INVALID_JSONL_ROW',
|
|
54
|
+
exitCode: 2,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return parsed;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function normalizeStructuredRows(value, inputPath) {
|
|
61
|
+
const rows = isRecord(value) && Array.isArray(value.rows) ? value.rows : value;
|
|
62
|
+
const normalizedRows = Array.isArray(rows) ? rows : [rows];
|
|
63
|
+
return normalizedRows.map((row, index) => {
|
|
64
|
+
if (!isRecord(row)) {
|
|
65
|
+
throw new CliError(`Expected JSON object rows in dataset input: ${inputPath} (index ${index})`, {
|
|
66
|
+
code: 'DATASET_INPUT_INVALID_ROW',
|
|
67
|
+
exitCode: 2,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return row;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
export function readDatasetRowsInput(inputPath, rawInput) {
|
|
74
|
+
if (!inputPath) {
|
|
75
|
+
throw new CliError('Missing required --input value.', {
|
|
76
|
+
code: 'DATASET_INPUT_REQUIRED',
|
|
77
|
+
exitCode: 2,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (rawInput !== undefined) {
|
|
81
|
+
return normalizeStructuredRows(rawInput, inputPath);
|
|
82
|
+
}
|
|
83
|
+
const resolved = path.resolve(inputPath);
|
|
84
|
+
return resolved.toLowerCase().endsWith('.jsonl')
|
|
85
|
+
? readJsonLinesInput(resolved)
|
|
86
|
+
: normalizeStructuredRows(readJsonInput(resolved), resolved);
|
|
87
|
+
}
|
|
88
|
+
export function datasetRoot(payload, kind) {
|
|
89
|
+
if (kind === 'flow') {
|
|
90
|
+
return isRecord(payload.flowDataSet) ? payload.flowDataSet : payload;
|
|
91
|
+
}
|
|
92
|
+
if (kind === 'process') {
|
|
93
|
+
return isRecord(payload.processDataSet) ? payload.processDataSet : payload;
|
|
94
|
+
}
|
|
95
|
+
return isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;
|
|
96
|
+
}
|
|
97
|
+
export function detectDatasetKind(value) {
|
|
98
|
+
const payload = unwrapDatasetPayload(value);
|
|
99
|
+
if (isRecord(payload.flowDataSet)) {
|
|
100
|
+
return 'flow';
|
|
101
|
+
}
|
|
102
|
+
if (isRecord(payload.processDataSet)) {
|
|
103
|
+
return 'process';
|
|
104
|
+
}
|
|
105
|
+
if (isRecord(payload.lifeCycleModelDataSet)) {
|
|
106
|
+
return 'lifecyclemodel';
|
|
107
|
+
}
|
|
108
|
+
if (isRecord(value.flow)) {
|
|
109
|
+
return 'flow';
|
|
110
|
+
}
|
|
111
|
+
if (isRecord(value.process)) {
|
|
112
|
+
return 'process';
|
|
113
|
+
}
|
|
114
|
+
if (isRecord(value.lifecyclemodel)) {
|
|
115
|
+
return 'lifecyclemodel';
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
export function unwrapDatasetPayload(row) {
|
|
120
|
+
for (const key of ['json_ordered', 'jsonOrdered', 'json', 'payload']) {
|
|
121
|
+
if (isRecord(row[key])) {
|
|
122
|
+
return row[key];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (isRecord(row.flow)) {
|
|
126
|
+
return row.flow;
|
|
127
|
+
}
|
|
128
|
+
if (isRecord(row.process)) {
|
|
129
|
+
return row.process;
|
|
130
|
+
}
|
|
131
|
+
if (isRecord(row.lifecyclemodel)) {
|
|
132
|
+
return row.lifecyclemodel;
|
|
133
|
+
}
|
|
134
|
+
return row;
|
|
135
|
+
}
|
|
136
|
+
function flowIdentity(payload) {
|
|
137
|
+
const root = datasetRoot(payload, 'flow');
|
|
138
|
+
const information = isRecord(root.flowInformation) ? root.flowInformation : {};
|
|
139
|
+
const dataSetInformation = isRecord(information.dataSetInformation)
|
|
140
|
+
? information.dataSetInformation
|
|
141
|
+
: {};
|
|
142
|
+
const administrativeInformation = isRecord(root.administrativeInformation)
|
|
143
|
+
? root.administrativeInformation
|
|
144
|
+
: {};
|
|
145
|
+
const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
|
|
146
|
+
? administrativeInformation.publicationAndOwnership
|
|
147
|
+
: {};
|
|
148
|
+
return {
|
|
149
|
+
id: firstNonEmpty(dataSetInformation['common:UUID']),
|
|
150
|
+
version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function processIdentity(payload) {
|
|
154
|
+
const root = datasetRoot(payload, 'process');
|
|
155
|
+
const information = isRecord(root.processInformation) ? root.processInformation : {};
|
|
156
|
+
const dataSetInformation = isRecord(information.dataSetInformation)
|
|
157
|
+
? information.dataSetInformation
|
|
158
|
+
: {};
|
|
159
|
+
const administrativeInformation = isRecord(root.administrativeInformation)
|
|
160
|
+
? root.administrativeInformation
|
|
161
|
+
: {};
|
|
162
|
+
const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
|
|
163
|
+
? administrativeInformation.publicationAndOwnership
|
|
164
|
+
: {};
|
|
165
|
+
return {
|
|
166
|
+
id: firstNonEmpty(dataSetInformation['common:UUID']),
|
|
167
|
+
version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function lifecyclemodelIdentity(payload) {
|
|
171
|
+
const root = datasetRoot(payload, 'lifecyclemodel');
|
|
172
|
+
const information = isRecord(root.lifeCycleModelInformation)
|
|
173
|
+
? root.lifeCycleModelInformation
|
|
174
|
+
: {};
|
|
175
|
+
const dataSetInformation = isRecord(information.dataSetInformation)
|
|
176
|
+
? information.dataSetInformation
|
|
177
|
+
: {};
|
|
178
|
+
const administrativeInformation = isRecord(root.administrativeInformation)
|
|
179
|
+
? root.administrativeInformation
|
|
180
|
+
: {};
|
|
181
|
+
const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)
|
|
182
|
+
? administrativeInformation.publicationAndOwnership
|
|
183
|
+
: {};
|
|
184
|
+
return {
|
|
185
|
+
id: firstNonEmpty(dataSetInformation['common:UUID']),
|
|
186
|
+
version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export function datasetIdentity(row, payload, kind) {
|
|
190
|
+
if (kind === 'flow') {
|
|
191
|
+
const identity = flowIdentity(payload);
|
|
192
|
+
return {
|
|
193
|
+
id: firstNonEmpty(row.id, identity.id),
|
|
194
|
+
version: firstNonEmpty(row.version, identity.version),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
if (kind === 'process') {
|
|
198
|
+
const identity = processIdentity(payload);
|
|
199
|
+
return {
|
|
200
|
+
id: firstNonEmpty(row.id, identity.id),
|
|
201
|
+
version: firstNonEmpty(row.version, identity.version),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
if (kind === 'lifecyclemodel') {
|
|
205
|
+
const identity = lifecyclemodelIdentity(payload);
|
|
206
|
+
return {
|
|
207
|
+
id: firstNonEmpty(row.id, identity.id),
|
|
208
|
+
version: firstNonEmpty(row.version, identity.version),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
id: firstNonEmpty(row.id),
|
|
213
|
+
version: firstNonEmpty(row.version),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
export function materializeDatasetRows(inputPath, rawInput) {
|
|
217
|
+
return readDatasetRowsInput(inputPath, rawInput).map((row, index) => {
|
|
218
|
+
const payload = unwrapDatasetPayload(row);
|
|
219
|
+
const kind = detectDatasetKind(row);
|
|
220
|
+
const identity = datasetIdentity(row, payload, kind);
|
|
221
|
+
return {
|
|
222
|
+
index,
|
|
223
|
+
row,
|
|
224
|
+
payload,
|
|
225
|
+
kind,
|
|
226
|
+
id: identity.id,
|
|
227
|
+
version: identity.version,
|
|
228
|
+
};
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=dataset-local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataset-local.js","sourceRoot":"","sources":["../../../src/lib/dataset-local.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport { readJsonInput } from './io.js';\n\nexport type JsonObject = Record<string, unknown>;\n\nexport type DatasetKind = 'flow' | 'process' | 'lifecyclemodel';\n\nexport type DatasetRowInput = {\n index: number;\n row: JsonObject;\n payload: JsonObject;\n kind: DatasetKind | null;\n id: string | null;\n version: string | null;\n};\n\nexport function isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function cloneJson<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function trimToken(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\nexport function firstNonEmpty(...values: unknown[]): string | null {\n for (const value of values) {\n const token = trimToken(value);\n if (token) {\n return token;\n }\n }\n return null;\n}\n\nfunction readJsonLinesInput(inputPath: string): JsonObject[] {\n const resolved = path.resolve(inputPath);\n if (!existsSync(resolved)) {\n throw new CliError(`Input file not found: ${resolved}`, {\n code: 'INPUT_NOT_FOUND',\n exitCode: 2,\n });\n }\n\n return readFileSync(resolved, 'utf8')\n .split(/\\r?\\n/u)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((line, index) => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch (error) {\n throw new CliError(`Input file contains invalid JSONL at line ${index + 1}: ${resolved}`, {\n code: 'INPUT_INVALID_JSONL',\n exitCode: 2,\n details: String(error),\n });\n }\n if (!isRecord(parsed)) {\n throw new CliError(\n `Expected JSON object rows in JSONL input: ${resolved} (line ${index + 1})`,\n {\n code: 'INPUT_INVALID_JSONL_ROW',\n exitCode: 2,\n },\n );\n }\n return parsed;\n });\n}\n\nfunction normalizeStructuredRows(value: unknown, inputPath: string): JsonObject[] {\n const rows = isRecord(value) && Array.isArray(value.rows) ? value.rows : value;\n const normalizedRows = Array.isArray(rows) ? rows : [rows];\n return normalizedRows.map((row, index) => {\n if (!isRecord(row)) {\n throw new CliError(\n `Expected JSON object rows in dataset input: ${inputPath} (index ${index})`,\n {\n code: 'DATASET_INPUT_INVALID_ROW',\n exitCode: 2,\n },\n );\n }\n return row;\n });\n}\n\nexport function readDatasetRowsInput(inputPath: string, rawInput?: unknown): JsonObject[] {\n if (!inputPath) {\n throw new CliError('Missing required --input value.', {\n code: 'DATASET_INPUT_REQUIRED',\n exitCode: 2,\n });\n }\n\n if (rawInput !== undefined) {\n return normalizeStructuredRows(rawInput, inputPath);\n }\n\n const resolved = path.resolve(inputPath);\n return resolved.toLowerCase().endsWith('.jsonl')\n ? readJsonLinesInput(resolved)\n : normalizeStructuredRows(readJsonInput(resolved), resolved);\n}\n\nexport function datasetRoot(payload: JsonObject, kind: DatasetKind): JsonObject {\n if (kind === 'flow') {\n return isRecord(payload.flowDataSet) ? payload.flowDataSet : payload;\n }\n if (kind === 'process') {\n return isRecord(payload.processDataSet) ? payload.processDataSet : payload;\n }\n return isRecord(payload.lifeCycleModelDataSet) ? payload.lifeCycleModelDataSet : payload;\n}\n\nexport function detectDatasetKind(value: JsonObject): DatasetKind | null {\n const payload = unwrapDatasetPayload(value);\n if (isRecord(payload.flowDataSet)) {\n return 'flow';\n }\n if (isRecord(payload.processDataSet)) {\n return 'process';\n }\n if (isRecord(payload.lifeCycleModelDataSet)) {\n return 'lifecyclemodel';\n }\n if (isRecord(value.flow)) {\n return 'flow';\n }\n if (isRecord(value.process)) {\n return 'process';\n }\n if (isRecord(value.lifecyclemodel)) {\n return 'lifecyclemodel';\n }\n return null;\n}\n\nexport function unwrapDatasetPayload(row: JsonObject): JsonObject {\n for (const key of ['json_ordered', 'jsonOrdered', 'json', 'payload'] as const) {\n if (isRecord(row[key])) {\n return row[key];\n }\n }\n if (isRecord(row.flow)) {\n return row.flow;\n }\n if (isRecord(row.process)) {\n return row.process;\n }\n if (isRecord(row.lifecyclemodel)) {\n return row.lifecyclemodel;\n }\n return row;\n}\n\nfunction flowIdentity(payload: JsonObject): { id: string | null; version: string | null } {\n const root = datasetRoot(payload, 'flow');\n const information = isRecord(root.flowInformation) ? root.flowInformation : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nfunction processIdentity(payload: JsonObject): { id: string | null; version: string | null } {\n const root = datasetRoot(payload, 'process');\n const information = isRecord(root.processInformation) ? root.processInformation : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nfunction lifecyclemodelIdentity(payload: JsonObject): {\n id: string | null;\n version: string | null;\n} {\n const root = datasetRoot(payload, 'lifecyclemodel');\n const information = isRecord(root.lifeCycleModelInformation)\n ? root.lifeCycleModelInformation\n : {};\n const dataSetInformation = isRecord(information.dataSetInformation)\n ? information.dataSetInformation\n : {};\n const administrativeInformation = isRecord(root.administrativeInformation)\n ? root.administrativeInformation\n : {};\n const publicationAndOwnership = isRecord(administrativeInformation.publicationAndOwnership)\n ? administrativeInformation.publicationAndOwnership\n : {};\n return {\n id: firstNonEmpty(dataSetInformation['common:UUID']),\n version: firstNonEmpty(publicationAndOwnership['common:dataSetVersion']),\n };\n}\n\nexport function datasetIdentity(\n row: JsonObject,\n payload: JsonObject,\n kind: DatasetKind | null,\n): { id: string | null; version: string | null } {\n if (kind === 'flow') {\n const identity = flowIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n if (kind === 'process') {\n const identity = processIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n if (kind === 'lifecyclemodel') {\n const identity = lifecyclemodelIdentity(payload);\n return {\n id: firstNonEmpty(row.id, identity.id),\n version: firstNonEmpty(row.version, identity.version),\n };\n }\n return {\n id: firstNonEmpty(row.id),\n version: firstNonEmpty(row.version),\n };\n}\n\nexport function materializeDatasetRows(inputPath: string, rawInput?: unknown): DatasetRowInput[] {\n return readDatasetRowsInput(inputPath, rawInput).map((row, index) => {\n const payload = unwrapDatasetPayload(row);\n const kind = detectDatasetKind(row);\n const identity = datasetIdentity(row, payload, kind);\n return {\n index,\n row,\n payload,\n kind,\n id: identity.id,\n version: identity.version,\n };\n });\n}\n"]}
|