@tiangong-lca/cli 0.0.15 → 0.0.16
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/assets/tidas-schemas/tidas_data_types.json +28 -3
- package/assets/tidas-schemas/tidas_flows.json +2 -1
- package/assets/tidas-schemas/tidas_lciamethods.json +7 -6
- package/dist/src/lib/dataset-bilingual.js +22 -1
- package/dist/src/lib/dataset-bilingual.js.map +1 -1
- package/dist/src/lib/lifecyclemodel-auto-build.js +5 -15
- package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -1
- package/dist/src/lib/tidas-languages.js +189 -0
- package/dist/src/lib/tidas-languages.js.map +1 -0
- package/dist/src/lib/tidas-sdk-package-validator.js +11 -4
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -1
- package/package.json +1 -1
|
@@ -11,12 +11,37 @@
|
|
|
11
11
|
"type": "string",
|
|
12
12
|
"description": "Free text with an unlimited length."
|
|
13
13
|
},
|
|
14
|
+
"Languages": {
|
|
15
|
+
"description": "TIDAS Languages enumeration.",
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": [
|
|
18
|
+
"aa", "ab", "ae", "af", "ak", "am", "an", "ar", "as", "av",
|
|
19
|
+
"ay", "az", "ba", "be", "bg", "bh", "bi", "bm", "bn", "bo",
|
|
20
|
+
"br", "bs", "ca", "ce", "ch", "co", "cr", "cs", "cu", "cv",
|
|
21
|
+
"cy", "da", "de", "dv", "dz", "ee", "el", "en", "eo", "es",
|
|
22
|
+
"et", "eu", "fa", "ff", "fi", "fj", "fo", "fr", "fy", "ga",
|
|
23
|
+
"gd", "gl", "gn", "gu", "gv", "ha", "he", "hi", "ho", "hr",
|
|
24
|
+
"ht", "hu", "hy", "hz", "ia", "id", "ie", "ig", "ii", "ik",
|
|
25
|
+
"io", "is", "it", "iu", "ja", "jv", "ka", "kg", "ki", "kj",
|
|
26
|
+
"kk", "kl", "km", "kn", "ko", "kr", "ks", "ku", "kv", "kw",
|
|
27
|
+
"ky", "la", "lb", "lg", "li", "ln", "lo", "lt", "lu", "lv",
|
|
28
|
+
"mg", "mh", "mi", "mk", "ml", "mn", "mo", "mr", "ms", "mt",
|
|
29
|
+
"my", "na", "nb", "nd", "ne", "ng", "nl", "nn", "no", "nr",
|
|
30
|
+
"nv", "ny", "oc", "oj", "om", "or", "os", "pa", "pi", "pl",
|
|
31
|
+
"ps", "pt", "qu", "rm", "rn", "ro", "ru", "rw", "sa", "sc",
|
|
32
|
+
"sd", "se", "sg", "si", "sk", "sl", "sm", "sn", "so", "sq",
|
|
33
|
+
"sr", "ss", "st", "su", "sv", "sw", "ta", "te", "tg", "th",
|
|
34
|
+
"ti", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty",
|
|
35
|
+
"ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh",
|
|
36
|
+
"yi", "yo", "za", "zh", "zu"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
14
39
|
"LocalizedTextItem": {
|
|
15
40
|
"description": "Language-tagged text with optional script checks for selected languages.",
|
|
16
41
|
"type": "object",
|
|
17
42
|
"properties": {
|
|
18
43
|
"@xml:lang": {
|
|
19
|
-
"
|
|
44
|
+
"$ref": "#/$defs/Languages"
|
|
20
45
|
},
|
|
21
46
|
"#text": {
|
|
22
47
|
"type": "string"
|
|
@@ -31,7 +56,7 @@
|
|
|
31
56
|
"if": {
|
|
32
57
|
"properties": {
|
|
33
58
|
"@xml:lang": {
|
|
34
|
-
"
|
|
59
|
+
"const": "zh"
|
|
35
60
|
}
|
|
36
61
|
},
|
|
37
62
|
"required": [
|
|
@@ -50,7 +75,7 @@
|
|
|
50
75
|
"if": {
|
|
51
76
|
"properties": {
|
|
52
77
|
"@xml:lang": {
|
|
53
|
-
"
|
|
78
|
+
"const": "en"
|
|
54
79
|
}
|
|
55
80
|
},
|
|
56
81
|
"required": [
|
|
@@ -212,6 +212,7 @@
|
|
|
212
212
|
"Natural resources",
|
|
213
213
|
"Natural environment",
|
|
214
214
|
"Human health",
|
|
215
|
+
"Man-made environment",
|
|
215
216
|
"Other"
|
|
216
217
|
]
|
|
217
218
|
},
|
|
@@ -570,7 +571,7 @@
|
|
|
570
571
|
"Cross-check with other data set",
|
|
571
572
|
"Expert judgement",
|
|
572
573
|
"Mass balance",
|
|
573
|
-
"Compliance with legal
|
|
574
|
+
"Compliance with legal limits",
|
|
574
575
|
"Compliance with ISO 14040 to 14044",
|
|
575
576
|
"Documentation",
|
|
576
577
|
"Evidence collection by means of plant visits and/or interviews"
|
|
@@ -597,7 +598,7 @@
|
|
|
597
598
|
"Cross-check with other data set",
|
|
598
599
|
"Expert judgement",
|
|
599
600
|
"Mass balance",
|
|
600
|
-
"Compliance with legal
|
|
601
|
+
"Compliance with legal limits",
|
|
601
602
|
"Compliance with ISO 14040 to 14044",
|
|
602
603
|
"Documentation",
|
|
603
604
|
"Evidence collection by means of plant visits and/or interviews"
|
|
@@ -653,7 +654,7 @@
|
|
|
653
654
|
"Cross-check with other data set",
|
|
654
655
|
"Expert judgement",
|
|
655
656
|
"Mass balance",
|
|
656
|
-
"Compliance with legal
|
|
657
|
+
"Compliance with legal limits",
|
|
657
658
|
"Compliance with ISO 14040 to 14044",
|
|
658
659
|
"Documentation",
|
|
659
660
|
"Evidence collection by means of plant visits and/or interviews"
|
|
@@ -680,7 +681,7 @@
|
|
|
680
681
|
"Cross-check with other data set",
|
|
681
682
|
"Expert judgement",
|
|
682
683
|
"Mass balance",
|
|
683
|
-
"Compliance with legal
|
|
684
|
+
"Compliance with legal limits",
|
|
684
685
|
"Compliance with ISO 14040 to 14044",
|
|
685
686
|
"Documentation",
|
|
686
687
|
"Evidence collection by means of plant visits and/or interviews"
|
|
@@ -1155,7 +1156,7 @@
|
|
|
1155
1156
|
"enum": [
|
|
1156
1157
|
"undefined",
|
|
1157
1158
|
"log-normal",
|
|
1158
|
-
"
|
|
1159
|
+
"normal",
|
|
1159
1160
|
"triangular",
|
|
1160
1161
|
"uniform"
|
|
1161
1162
|
]
|
|
@@ -1245,7 +1246,7 @@
|
|
|
1245
1246
|
"enum": [
|
|
1246
1247
|
"undefined",
|
|
1247
1248
|
"log-normal",
|
|
1248
|
-
"
|
|
1249
|
+
"normal",
|
|
1249
1250
|
"triangular",
|
|
1250
1251
|
"uniform"
|
|
1251
1252
|
]
|
|
@@ -5,6 +5,7 @@ import { CliError } from './errors.js';
|
|
|
5
5
|
import { cloneJson, isRecord, materializeDatasetRows, readDatasetRowsInput, trimToken, } from './dataset-local.js';
|
|
6
6
|
import { runDatasetValidate, } from './dataset-validate.js';
|
|
7
7
|
import { runFlowQa } from './flow-qa.js';
|
|
8
|
+
import { TIDAS_LANGUAGE_CODE_SET } from './tidas-languages.js';
|
|
8
9
|
import { runProcessQa } from './process-qa.js';
|
|
9
10
|
const DEFAULT_SOURCE_LANG = 'en';
|
|
10
11
|
const DEFAULT_TARGET_LANG = 'zh';
|
|
@@ -40,7 +41,14 @@ function normalizeType(value) {
|
|
|
40
41
|
}
|
|
41
42
|
function normalizeLang(value, fallback) {
|
|
42
43
|
const normalized = value?.trim().toLowerCase();
|
|
43
|
-
|
|
44
|
+
const lang = normalized || fallback;
|
|
45
|
+
if (!TIDAS_LANGUAGE_CODE_SET.has(lang)) {
|
|
46
|
+
throw new CliError(`Expected language to use a TIDAS Languages enumeration value, got: ${lang}`, {
|
|
47
|
+
code: 'DATASET_BILINGUAL_LANGUAGE_NOT_IN_TIDAS_ENUM',
|
|
48
|
+
exitCode: 2,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return lang;
|
|
44
52
|
}
|
|
45
53
|
function pointerEscape(segment) {
|
|
46
54
|
return segment.replace(/~/gu, '~0').replace(/\//gu, '~1');
|
|
@@ -66,6 +74,9 @@ function textPreview(value) {
|
|
|
66
74
|
function langOf(value) {
|
|
67
75
|
return trimToken(isRecord(value) ? value['@xml:lang'] : null)?.toLowerCase() ?? null;
|
|
68
76
|
}
|
|
77
|
+
function rawLangOf(value) {
|
|
78
|
+
return trimToken(isRecord(value) ? value['@xml:lang'] : null) ?? null;
|
|
79
|
+
}
|
|
69
80
|
function textOf(value) {
|
|
70
81
|
return trimToken(isRecord(value) ? value['#text'] : null);
|
|
71
82
|
}
|
|
@@ -276,6 +287,7 @@ function writeRowsJsonl(filePath, rows) {
|
|
|
276
287
|
function scanText(node, pathSegments, visit) {
|
|
277
288
|
const findings = [];
|
|
278
289
|
if (isLangRecord(node)) {
|
|
290
|
+
const rawLang = rawLangOf(node);
|
|
279
291
|
const lang = langOf(node);
|
|
280
292
|
const text = textOf(node);
|
|
281
293
|
if (!text) {
|
|
@@ -291,6 +303,14 @@ function scanText(node, pathSegments, visit) {
|
|
|
291
303
|
lang,
|
|
292
304
|
text_preview: textPreview(text),
|
|
293
305
|
};
|
|
306
|
+
if (rawLang && !TIDAS_LANGUAGE_CODE_SET.has(rawLang)) {
|
|
307
|
+
findings.push({
|
|
308
|
+
...base,
|
|
309
|
+
code: 'localized_text_language_not_in_tidas_enum',
|
|
310
|
+
severity: 'blocker',
|
|
311
|
+
message: 'Localized text @xml:lang is not a TIDAS Languages enumeration value.',
|
|
312
|
+
});
|
|
313
|
+
}
|
|
294
314
|
if (PLACEHOLDER_RE.test(text)) {
|
|
295
315
|
findings.push({
|
|
296
316
|
...base,
|
|
@@ -539,6 +559,7 @@ export const __testInternals = {
|
|
|
539
559
|
collectTranslationUnits,
|
|
540
560
|
normalizeType,
|
|
541
561
|
pointerFromSegments,
|
|
562
|
+
rawLangOf,
|
|
542
563
|
segmentsFromPointer,
|
|
543
564
|
scanRows,
|
|
544
565
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataset-bilingual.js","sourceRoot":"","sources":["../../../src/lib/dataset-bilingual.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n cloneJson,\n isRecord,\n materializeDatasetRows,\n readDatasetRowsInput,\n trimToken,\n type DatasetKind,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n runDatasetValidate,\n type DatasetValidateReport,\n type RunDatasetValidateOptions,\n} from './dataset-validate.js';\nimport { runFlowQa, type FlowQaReport, type RunFlowQaOptions } from './flow-qa.js';\nimport { runProcessQa, type ProcessQaReport, type RunProcessQaOptions } from './process-qa.js';\n\ntype BilingualDatasetType = 'auto' | DatasetKind;\ntype BilingualStatus = 'completed' | 'blocked';\ntype ScanSeverity = 'warning' | 'blocker';\n\nexport type BilingualTranslationUnit = {\n schema_version: 1;\n unit_id: string;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n source_lang: string;\n target_lang: string;\n source_text: string;\n current_target_text: string | null;\n context: {\n root_field: string | null;\n sibling_keys: string[];\n };\n};\n\nexport type DatasetBilingualExtractReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n requested_type: BilingualDatasetType;\n source_lang: string;\n target_lang: string;\n unit_count: number;\n row_count: number;\n files: {\n translation_units: string | null;\n report: string | null;\n };\n};\n\nexport type TranslationEvidenceEntry = {\n unit_id: string;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n source_lang: string;\n target_lang: string;\n source_text: string;\n translated_text: string;\n basis: string | null;\n review_status: string | null;\n reviewer: string | null;\n};\n\nexport type DatasetBilingualApplyReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n translations_path: string;\n out_path: string;\n target_lang: string;\n status: BilingualStatus;\n row_count: number;\n translation_count: number;\n applied_count: number;\n skipped_count: number;\n blockers: Array<{ code: string; message: string; unit_id?: string }>;\n files: {\n translated_rows: string;\n translation_evidence: string | null;\n report: string | null;\n };\n};\n\nexport type BilingualScanFinding = {\n code: string;\n severity: ScanSeverity;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n lang: string | null;\n message: string;\n text_preview: string;\n};\n\nexport type DatasetBilingualValidateReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n requested_type: BilingualDatasetType;\n status: BilingualStatus;\n row_count: number;\n scan: {\n finding_count: number;\n blocker_count: number;\n warning_count: number;\n findings: BilingualScanFinding[];\n };\n schema_gate: {\n status: DatasetValidateReport['status'];\n valid: number;\n invalid: number;\n report_file: string | null;\n };\n qa_gate: {\n status: 'completed' | 'not_run';\n process_report_file: string | null;\n flow_report_file: string | null;\n };\n files: {\n report: string | null;\n findings: string | null;\n };\n};\n\nexport type RunDatasetBilingualExtractOptions = {\n inputPath: string;\n type?: string | null;\n outDir?: string | null;\n sourceLang?: string | null;\n targetLang?: string | null;\n rawInput?: unknown;\n now?: Date;\n};\n\nexport type RunDatasetBilingualApplyOptions = {\n inputPath: string;\n translationsPath: string;\n outPath: string;\n outDir?: string | null;\n targetLang?: string | null;\n rawInput?: unknown;\n rawTranslations?: unknown;\n now?: Date;\n};\n\nexport type RunDatasetBilingualValidateOptions = {\n inputPath: string;\n type?: string | null;\n outDir?: string | null;\n rawInput?: unknown;\n now?: Date;\n datasetValidateImpl?: (options: RunDatasetValidateOptions) => Promise<DatasetValidateReport>;\n processQaImpl?: (options: RunProcessQaOptions) => Promise<ProcessQaReport>;\n flowQaImpl?: (options: RunFlowQaOptions) => Promise<FlowQaReport>;\n schemas?: RunDatasetValidateOptions['schemas'];\n};\n\ntype LangRecord = JsonObject & {\n '#text'?: unknown;\n '@xml:lang'?: unknown;\n};\n\ntype TranslationInput = {\n unit_id: string | null;\n row_index: number | null;\n field_path: string | null;\n source_lang: string | null;\n target_lang: string | null;\n source_text: string | null;\n translated_text: string | null;\n basis: string | null;\n review_status: string | null;\n reviewer: string | null;\n};\n\ntype ApplyTranslationResult =\n | { applied: true; evidence: TranslationEvidenceEntry }\n | { applied: false; blocker: string };\n\ntype PathVisit = {\n rowIndex: number;\n row: JsonObject;\n kind: DatasetKind | null;\n id: string | null;\n version: string | null;\n};\n\nconst DEFAULT_SOURCE_LANG = 'en';\nconst DEFAULT_TARGET_LANG = 'zh';\nconst PLACEHOLDER_RE = /\\b(?:TODO|TBD|FIXME|REPLACE_ME)\\b|待补充|占位/u;\nconst CJK_RE = /[\\u3400-\\u9fff]/u;\nconst LATIN_WORD_RE = /[A-Za-z]{3,}/gu;\nconst CJK_PLURAL_SUFFIX_RE = /[\\u3400-\\u9fff]+s\\b/u;\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction normalizeType(value: string | null | undefined): BilingualDatasetType {\n const normalized = value?.trim().toLowerCase();\n if (!normalized || normalized === 'auto') {\n return 'auto';\n }\n if (normalized === 'flow' || normalized === 'flows') {\n return 'flow';\n }\n if (normalized === 'process' || normalized === 'processes') {\n return 'process';\n }\n if (\n normalized === 'lifecyclemodel' ||\n normalized === 'lifecyclemodels' ||\n normalized === 'model' ||\n normalized === 'models'\n ) {\n return 'lifecyclemodel';\n }\n throw new CliError('Expected --type to be auto, flow, process, or lifecyclemodel.', {\n code: 'DATASET_BILINGUAL_TYPE_INVALID',\n exitCode: 2,\n details: value,\n });\n}\n\nfunction normalizeLang(value: string | null | undefined, fallback: string): string {\n const normalized = value?.trim().toLowerCase();\n return normalized || fallback;\n}\n\nfunction pointerEscape(segment: string): string {\n return segment.replace(/~/gu, '~0').replace(/\\//gu, '~1');\n}\n\nfunction pointerUnescape(segment: string): string {\n return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');\n}\n\nfunction pointerFromSegments(segments: string[]): string {\n return `/${segments.map(pointerEscape).join('/')}`;\n}\n\nfunction segmentsFromPointer(pointer: string): string[] {\n if (!pointer.startsWith('/')) {\n throw new CliError(`Expected JSON pointer field_path, got: ${pointer}`, {\n code: 'DATASET_BILINGUAL_FIELD_PATH_INVALID',\n exitCode: 2,\n });\n }\n return pointer.slice(1).split('/').map(pointerUnescape);\n}\n\nfunction textPreview(value: string): string {\n return value.length > 180 ? `${value.slice(0, 177)}...` : value;\n}\n\nfunction langOf(value: unknown): string | null {\n return trimToken(isRecord(value) ? value['@xml:lang'] : null)?.toLowerCase() ?? null;\n}\n\nfunction textOf(value: unknown): string | null {\n return trimToken(isRecord(value) ? value['#text'] : null);\n}\n\nfunction isLangRecord(value: unknown): value is LangRecord {\n return isRecord(value) && (typeof value['@xml:lang'] === 'string' || '#text' in value);\n}\n\nfunction isLangRecordArray(value: unknown): value is LangRecord[] {\n return Array.isArray(value) && value.some((item) => isLangRecord(item));\n}\n\nfunction hashUnit(parts: unknown[]): string {\n const hash = createHash('sha256');\n for (const part of parts) {\n hash.update(String(part ?? ''));\n hash.update('\\n');\n }\n return hash.digest('hex').slice(0, 24);\n}\n\nfunction filterRowsByType(\n rows: ReturnType<typeof materializeDatasetRows>,\n requestedType: BilingualDatasetType,\n): ReturnType<typeof materializeDatasetRows> {\n if (requestedType === 'auto') {\n return rows;\n }\n return rows.filter((row) => row.kind === requestedType);\n}\n\nfunction rootFieldFromPath(pathSegments: string[]): string | null {\n return pathSegments.find((segment) => !/^\\d+$/u.test(segment)) ?? null;\n}\n\nfunction siblingKeys(parent: unknown): string[] {\n if (!isRecord(parent)) {\n return [];\n }\n return Object.keys(parent).sort().slice(0, 20);\n}\n\nfunction collectTranslationUnitsFromNode(\n node: unknown,\n pathSegments: string[],\n parent: unknown,\n visit: PathVisit,\n sourceLang: string,\n targetLang: string,\n units: BilingualTranslationUnit[],\n): void {\n if (isLangRecordArray(node)) {\n const source = node.find((item) => langOf(item) === sourceLang);\n const target = node.find((item) => langOf(item) === targetLang);\n const sourceText = textOf(source);\n if (sourceText) {\n const fieldPath = pointerFromSegments(pathSegments);\n units.push({\n schema_version: 1,\n unit_id: hashUnit([\n visit.rowIndex,\n visit.id,\n visit.version,\n fieldPath,\n sourceLang,\n targetLang,\n sourceText,\n ]),\n row_index: visit.rowIndex,\n dataset_type: visit.kind,\n dataset_id: visit.id,\n dataset_version: visit.version,\n field_path: fieldPath,\n source_lang: sourceLang,\n target_lang: targetLang,\n source_text: sourceText,\n current_target_text: textOf(target),\n context: {\n root_field: rootFieldFromPath(pathSegments),\n sibling_keys: siblingKeys(parent),\n },\n });\n }\n return;\n }\n\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n collectTranslationUnitsFromNode(\n item,\n [...pathSegments, String(index)],\n node,\n visit,\n sourceLang,\n targetLang,\n units,\n ),\n );\n return;\n }\n\n if (isRecord(node)) {\n for (const [key, value] of Object.entries(node)) {\n collectTranslationUnitsFromNode(\n value,\n [...pathSegments, key],\n node,\n visit,\n sourceLang,\n targetLang,\n units,\n );\n }\n }\n}\n\nfunction collectTranslationUnits(\n rows: ReturnType<typeof materializeDatasetRows>,\n sourceLang: string,\n targetLang: string,\n): BilingualTranslationUnit[] {\n const units: BilingualTranslationUnit[] = [];\n for (const row of rows) {\n collectTranslationUnitsFromNode(\n row.row,\n [],\n null,\n {\n rowIndex: row.index,\n row: row.row,\n kind: row.kind,\n id: row.id,\n version: row.version,\n },\n sourceLang,\n targetLang,\n units,\n );\n }\n return units;\n}\n\nfunction outFiles(outDir: string | null | undefined): DatasetBilingualExtractReport['files'] {\n if (!outDir) {\n return {\n translation_units: null,\n report: null,\n };\n }\n const resolved = path.resolve(outDir);\n return {\n translation_units: path.join(resolved, 'outputs', 'trans-units.jsonl'),\n report: path.join(resolved, 'outputs', 'extract-report.json'),\n };\n}\n\nfunction readTranslationInputs(inputPath: string, rawInput?: unknown): TranslationInput[] {\n return readDatasetRowsInput(inputPath, rawInput).map((row) => {\n const translatedText =\n trimToken(row.translated_text) ??\n trimToken(row.translatedText) ??\n trimToken(row.translation) ??\n trimToken(row.target_text) ??\n trimToken(row.targetText);\n return {\n unit_id: trimToken(row.unit_id) ?? trimToken(row.unitId),\n row_index:\n typeof row.row_index === 'number'\n ? row.row_index\n : typeof row.rowIndex === 'number'\n ? row.rowIndex\n : null,\n field_path: trimToken(row.field_path) ?? trimToken(row.fieldPath),\n source_lang: trimToken(row.source_lang) ?? trimToken(row.sourceLang),\n target_lang: trimToken(row.target_lang) ?? trimToken(row.targetLang),\n source_text: trimToken(row.source_text) ?? trimToken(row.sourceText),\n translated_text: translatedText,\n basis: trimToken(row.basis) ?? trimToken(row.rationale),\n review_status: trimToken(row.review_status) ?? trimToken(row.reviewStatus),\n reviewer: trimToken(row.reviewer),\n };\n });\n}\n\nfunction resolvePointer(root: unknown, pointer: string): unknown {\n let current = root;\n for (const segment of segmentsFromPointer(pointer)) {\n if (Array.isArray(current)) {\n current = current[Number(segment)];\n } else if (isRecord(current)) {\n current = current[segment];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\nfunction cloneSourceLangRecord(container: LangRecord[], sourceLang: string): LangRecord {\n const source = container.find((item) => langOf(item) === sourceLang);\n const cloned = isRecord(source) ? cloneJson(source) : {};\n cloned['@xml:lang'] = '';\n cloned['#text'] = '';\n return cloned;\n}\n\nfunction applyTranslationToRows(options: {\n rows: JsonObject[];\n translation: TranslationInput;\n targetLang: string;\n}): ApplyTranslationResult {\n const translation = options.translation;\n if (translation.row_index === null || translation.row_index < 0) {\n return { applied: false, blocker: 'Translation is missing row_index.' };\n }\n if (!translation.field_path) {\n return { applied: false, blocker: 'Translation is missing field_path.' };\n }\n if (!translation.translated_text) {\n return { applied: false, blocker: 'Translation is missing translated_text.' };\n }\n\n const row = options.rows[translation.row_index];\n if (!row) {\n return { applied: false, blocker: `No input row exists at index ${translation.row_index}.` };\n }\n\n const container = resolvePointer(row, translation.field_path);\n if (!Array.isArray(container)) {\n return { applied: false, blocker: `field_path does not point to a language array.` };\n }\n\n let target = container.find((item) => isRecord(item) && langOf(item) === options.targetLang);\n if (!target) {\n target = cloneSourceLangRecord(container as LangRecord[], translation.source_lang ?? 'en');\n container.push(target);\n }\n target['@xml:lang'] = options.targetLang;\n target['#text'] = translation.translated_text;\n\n const materializedRows = materializeDatasetRows('memory', { rows: [row] });\n const materialized = materializedRows[0];\n return {\n applied: true,\n evidence: {\n unit_id:\n translation.unit_id ??\n hashUnit([\n translation.row_index,\n translation.field_path,\n translation.source_lang,\n options.targetLang,\n translation.source_text,\n ]),\n row_index: translation.row_index,\n dataset_type: materialized?.kind ?? null,\n dataset_id: materialized?.id ?? null,\n dataset_version: materialized?.version ?? null,\n field_path: translation.field_path,\n source_lang: translation.source_lang ?? 'en',\n target_lang: options.targetLang,\n source_text: translation.source_text ?? '',\n translated_text: translation.translated_text,\n basis: translation.basis,\n review_status: translation.review_status,\n reviewer: translation.reviewer,\n },\n };\n}\n\nfunction writeRowsJsonl(filePath: string, rows: JsonObject[]): string {\n return writeJsonLinesArtifact(filePath, rows);\n}\n\nfunction scanText(node: unknown, pathSegments: string[], visit: PathVisit): BilingualScanFinding[] {\n const findings: BilingualScanFinding[] = [];\n\n if (isLangRecord(node)) {\n const lang = langOf(node);\n const text = textOf(node);\n if (!text) {\n return findings;\n }\n const fieldPath = pointerFromSegments(pathSegments);\n const base = {\n row_index: visit.rowIndex,\n dataset_type: visit.kind,\n dataset_id: visit.id,\n dataset_version: visit.version,\n field_path: fieldPath,\n lang,\n text_preview: textPreview(text),\n };\n if (PLACEHOLDER_RE.test(text)) {\n findings.push({\n ...base,\n code: 'placeholder_text',\n severity: 'blocker',\n message: 'Text contains placeholder markers.',\n });\n }\n if (lang === 'en' && CJK_RE.test(text)) {\n findings.push({\n ...base,\n code: 'english_contains_cjk',\n severity: 'blocker',\n message: 'English text contains CJK characters.',\n });\n }\n if (lang === 'zh' && CJK_PLURAL_SUFFIX_RE.test(text)) {\n findings.push({\n ...base,\n code: 'mechanical_plural_suffix',\n severity: 'blocker',\n message: 'Chinese text contains mechanical mixed-language plural suffixes.',\n });\n }\n if (lang === 'zh') {\n const latinWords = text.match(LATIN_WORD_RE) ?? [];\n if (latinWords.length >= 8) {\n findings.push({\n ...base,\n code: 'zh_latin_word_density',\n severity: 'warning',\n message:\n 'Chinese text contains many Latin words; review for machine-translation residue.',\n });\n }\n }\n return findings;\n }\n\n if (Array.isArray(node)) {\n node.forEach((item, index) => {\n findings.push(...scanText(item, [...pathSegments, String(index)], visit));\n });\n return findings;\n }\n\n if (isRecord(node)) {\n for (const [key, value] of Object.entries(node)) {\n findings.push(...scanText(value, [...pathSegments, key], visit));\n }\n }\n\n return findings;\n}\n\nfunction scanRows(rows: ReturnType<typeof materializeDatasetRows>): BilingualScanFinding[] {\n return rows.flatMap((row) =>\n scanText(row.row, [], {\n rowIndex: row.index,\n row: row.row,\n kind: row.kind,\n id: row.id,\n version: row.version,\n }),\n );\n}\n\nfunction validateFiles(outDir: string | null | undefined): DatasetBilingualValidateReport['files'] {\n if (!outDir) {\n return {\n report: null,\n findings: null,\n };\n }\n const resolved = path.resolve(outDir);\n return {\n report: path.join(resolved, 'outputs', 'bilingual-validate-report.json'),\n findings: path.join(resolved, 'outputs', 'bilingual-findings.jsonl'),\n };\n}\n\nexport async function runDatasetBilingualExtract(\n options: RunDatasetBilingualExtractOptions,\n): Promise<DatasetBilingualExtractReport> {\n const requestedType = normalizeType(options.type);\n const sourceLang = normalizeLang(options.sourceLang, DEFAULT_SOURCE_LANG);\n const targetLang = normalizeLang(options.targetLang, DEFAULT_TARGET_LANG);\n const rows = filterRowsByType(\n materializeDatasetRows(options.inputPath, options.rawInput),\n requestedType,\n );\n const units = collectTranslationUnits(rows, sourceLang, targetLang);\n const files = outFiles(options.outDir);\n const report: DatasetBilingualExtractReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n requested_type: requestedType,\n source_lang: sourceLang,\n target_lang: targetLang,\n unit_count: units.length,\n row_count: rows.length,\n files,\n };\n\n if (files.translation_units) {\n writeJsonLinesArtifact(files.translation_units, units);\n }\n if (files.report) {\n writeJsonArtifact(files.report, report);\n }\n return report;\n}\n\nexport async function runDatasetBilingualApply(\n options: RunDatasetBilingualApplyOptions,\n): Promise<DatasetBilingualApplyReport> {\n const targetLang = normalizeLang(options.targetLang, DEFAULT_TARGET_LANG);\n if (!options.outPath) {\n throw new CliError('Missing required --out value.', {\n code: 'DATASET_BILINGUAL_OUT_REQUIRED',\n exitCode: 2,\n });\n }\n if (!options.translationsPath) {\n throw new CliError('Missing required --translations value.', {\n code: 'DATASET_BILINGUAL_TRANSLATIONS_REQUIRED',\n exitCode: 2,\n });\n }\n\n const rows = readDatasetRowsInput(options.inputPath, options.rawInput).map((row) =>\n cloneJson(row),\n );\n const translations = readTranslationInputs(options.translationsPath, options.rawTranslations);\n const blockers: DatasetBilingualApplyReport['blockers'] = [];\n const evidence: TranslationEvidenceEntry[] = [];\n let appliedCount = 0;\n let skippedCount = 0;\n\n for (const translation of translations) {\n const result = applyTranslationToRows({ rows, translation, targetLang });\n if (result.applied) {\n appliedCount += 1;\n evidence.push(result.evidence);\n } else {\n skippedCount += 1;\n blockers.push({\n code: 'translation_not_applied',\n message: result.blocker,\n unit_id: translation.unit_id ?? undefined,\n });\n }\n }\n\n const resolvedOut = path.resolve(options.outPath);\n const resolvedOutDir = options.outDir ? path.resolve(options.outDir) : path.dirname(resolvedOut);\n const evidenceFile = path.join(resolvedOutDir, 'outputs', 'translation-evidence.json');\n const reportFile = path.join(resolvedOutDir, 'outputs', 'bilingual-apply-report.json');\n writeRowsJsonl(resolvedOut, rows);\n writeJsonArtifact(evidenceFile, {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n entries: evidence,\n });\n\n const report: DatasetBilingualApplyReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n translations_path: options.translationsPath,\n out_path: resolvedOut,\n target_lang: targetLang,\n status: blockers.length > 0 ? 'blocked' : 'completed',\n row_count: rows.length,\n translation_count: translations.length,\n applied_count: appliedCount,\n skipped_count: skippedCount,\n blockers,\n files: {\n translated_rows: resolvedOut,\n translation_evidence: evidenceFile,\n report: reportFile,\n },\n };\n writeJsonArtifact(reportFile, report);\n return report;\n}\n\nexport async function runDatasetBilingualValidate(\n options: RunDatasetBilingualValidateOptions,\n): Promise<DatasetBilingualValidateReport> {\n const requestedType = normalizeType(options.type);\n const rows = filterRowsByType(\n materializeDatasetRows(options.inputPath, options.rawInput),\n requestedType,\n );\n const findings = scanRows(rows);\n const files = validateFiles(options.outDir);\n const datasetValidateImpl = options.datasetValidateImpl ?? runDatasetValidate;\n const schemaGateOutDir = options.outDir\n ? path.join(path.resolve(options.outDir), 'schema')\n : null;\n const schemaReport = await datasetValidateImpl({\n inputPath: options.inputPath,\n type: requestedType,\n outDir: schemaGateOutDir,\n rawInput: { rows: rows.map((row) => row.row) },\n now: options.now,\n schemas: options.schemas,\n });\n\n let processReport: ProcessQaReport | null = null;\n let flowReport: FlowQaReport | null = null;\n if (options.outDir && (requestedType === 'process' || requestedType === 'auto')) {\n const processRows = rows.filter((row) => row.kind === 'process').map((row) => row.row);\n if (processRows.length > 0) {\n const processRowsFile = path.join(path.resolve(options.outDir), 'qa-input-processes.jsonl');\n writeJsonLinesArtifact(processRowsFile, processRows);\n processReport = await (options.processQaImpl ?? runProcessQa)({\n rowsFile: processRowsFile,\n outDir: path.join(path.resolve(options.outDir), 'qa', 'process'),\n now: () => options.now ?? new Date(),\n });\n }\n }\n if (options.outDir && (requestedType === 'flow' || requestedType === 'auto')) {\n const flowRows = rows.filter((row) => row.kind === 'flow').map((row) => row.row);\n if (flowRows.length > 0) {\n const flowRowsFile = path.join(path.resolve(options.outDir), 'qa-input-flows.jsonl');\n writeJsonLinesArtifact(flowRowsFile, flowRows);\n flowReport = await (options.flowQaImpl ?? runFlowQa)({\n rowsFile: flowRowsFile,\n outDir: path.join(path.resolve(options.outDir), 'qa', 'flow'),\n now: () => options.now ?? new Date(),\n });\n }\n }\n\n const blockerCount = findings.filter((finding) => finding.severity === 'blocker').length;\n const warningCount = findings.filter((finding) => finding.severity === 'warning').length;\n const report: DatasetBilingualValidateReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n requested_type: requestedType,\n status: blockerCount > 0 || schemaReport.counts.invalid > 0 ? 'blocked' : 'completed',\n row_count: rows.length,\n scan: {\n finding_count: findings.length,\n blocker_count: blockerCount,\n warning_count: warningCount,\n findings,\n },\n schema_gate: {\n status: schemaReport.status,\n valid: schemaReport.counts.valid,\n invalid: schemaReport.counts.invalid,\n report_file: schemaReport.files.report,\n },\n qa_gate: {\n status: processReport || flowReport ? 'completed' : 'not_run',\n process_report_file: processReport?.files.report ?? null,\n flow_report_file: flowReport?.files.report ?? null,\n },\n files,\n };\n\n if (files.findings) {\n writeJsonLinesArtifact(files.findings, findings);\n }\n if (files.report) {\n writeJsonArtifact(files.report, report);\n }\n return report;\n}\n\nexport const __testInternals = {\n collectTranslationUnits,\n normalizeType,\n pointerFromSegments,\n segmentsFromPointer,\n scanRows,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"dataset-bilingual.js","sourceRoot":"","sources":["../../../src/lib/dataset-bilingual.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { writeJsonArtifact, writeJsonLinesArtifact } from './artifacts.js';\nimport { CliError } from './errors.js';\nimport {\n cloneJson,\n isRecord,\n materializeDatasetRows,\n readDatasetRowsInput,\n trimToken,\n type DatasetKind,\n type JsonObject,\n} from './dataset-local.js';\nimport {\n runDatasetValidate,\n type DatasetValidateReport,\n type RunDatasetValidateOptions,\n} from './dataset-validate.js';\nimport { runFlowQa, type FlowQaReport, type RunFlowQaOptions } from './flow-qa.js';\nimport { TIDAS_LANGUAGE_CODE_SET } from './tidas-languages.js';\nimport { runProcessQa, type ProcessQaReport, type RunProcessQaOptions } from './process-qa.js';\n\ntype BilingualDatasetType = 'auto' | DatasetKind;\ntype BilingualStatus = 'completed' | 'blocked';\ntype ScanSeverity = 'warning' | 'blocker';\n\nexport type BilingualTranslationUnit = {\n schema_version: 1;\n unit_id: string;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n source_lang: string;\n target_lang: string;\n source_text: string;\n current_target_text: string | null;\n context: {\n root_field: string | null;\n sibling_keys: string[];\n };\n};\n\nexport type DatasetBilingualExtractReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n requested_type: BilingualDatasetType;\n source_lang: string;\n target_lang: string;\n unit_count: number;\n row_count: number;\n files: {\n translation_units: string | null;\n report: string | null;\n };\n};\n\nexport type TranslationEvidenceEntry = {\n unit_id: string;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n source_lang: string;\n target_lang: string;\n source_text: string;\n translated_text: string;\n basis: string | null;\n review_status: string | null;\n reviewer: string | null;\n};\n\nexport type DatasetBilingualApplyReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n translations_path: string;\n out_path: string;\n target_lang: string;\n status: BilingualStatus;\n row_count: number;\n translation_count: number;\n applied_count: number;\n skipped_count: number;\n blockers: Array<{ code: string; message: string; unit_id?: string }>;\n files: {\n translated_rows: string;\n translation_evidence: string | null;\n report: string | null;\n };\n};\n\nexport type BilingualScanFinding = {\n code: string;\n severity: ScanSeverity;\n row_index: number;\n dataset_type: DatasetKind | null;\n dataset_id: string | null;\n dataset_version: string | null;\n field_path: string;\n lang: string | null;\n message: string;\n text_preview: string;\n};\n\nexport type DatasetBilingualValidateReport = {\n schema_version: 1;\n generated_at_utc: string;\n input_path: string;\n requested_type: BilingualDatasetType;\n status: BilingualStatus;\n row_count: number;\n scan: {\n finding_count: number;\n blocker_count: number;\n warning_count: number;\n findings: BilingualScanFinding[];\n };\n schema_gate: {\n status: DatasetValidateReport['status'];\n valid: number;\n invalid: number;\n report_file: string | null;\n };\n qa_gate: {\n status: 'completed' | 'not_run';\n process_report_file: string | null;\n flow_report_file: string | null;\n };\n files: {\n report: string | null;\n findings: string | null;\n };\n};\n\nexport type RunDatasetBilingualExtractOptions = {\n inputPath: string;\n type?: string | null;\n outDir?: string | null;\n sourceLang?: string | null;\n targetLang?: string | null;\n rawInput?: unknown;\n now?: Date;\n};\n\nexport type RunDatasetBilingualApplyOptions = {\n inputPath: string;\n translationsPath: string;\n outPath: string;\n outDir?: string | null;\n targetLang?: string | null;\n rawInput?: unknown;\n rawTranslations?: unknown;\n now?: Date;\n};\n\nexport type RunDatasetBilingualValidateOptions = {\n inputPath: string;\n type?: string | null;\n outDir?: string | null;\n rawInput?: unknown;\n now?: Date;\n datasetValidateImpl?: (options: RunDatasetValidateOptions) => Promise<DatasetValidateReport>;\n processQaImpl?: (options: RunProcessQaOptions) => Promise<ProcessQaReport>;\n flowQaImpl?: (options: RunFlowQaOptions) => Promise<FlowQaReport>;\n schemas?: RunDatasetValidateOptions['schemas'];\n};\n\ntype LangRecord = JsonObject & {\n '#text'?: unknown;\n '@xml:lang'?: unknown;\n};\n\ntype TranslationInput = {\n unit_id: string | null;\n row_index: number | null;\n field_path: string | null;\n source_lang: string | null;\n target_lang: string | null;\n source_text: string | null;\n translated_text: string | null;\n basis: string | null;\n review_status: string | null;\n reviewer: string | null;\n};\n\ntype ApplyTranslationResult =\n | { applied: true; evidence: TranslationEvidenceEntry }\n | { applied: false; blocker: string };\n\ntype PathVisit = {\n rowIndex: number;\n row: JsonObject;\n kind: DatasetKind | null;\n id: string | null;\n version: string | null;\n};\n\nconst DEFAULT_SOURCE_LANG = 'en';\nconst DEFAULT_TARGET_LANG = 'zh';\nconst PLACEHOLDER_RE = /\\b(?:TODO|TBD|FIXME|REPLACE_ME)\\b|待补充|占位/u;\nconst CJK_RE = /[\\u3400-\\u9fff]/u;\nconst LATIN_WORD_RE = /[A-Za-z]{3,}/gu;\nconst CJK_PLURAL_SUFFIX_RE = /[\\u3400-\\u9fff]+s\\b/u;\n\nfunction nowIso(now: Date = new Date()): string {\n return now.toISOString();\n}\n\nfunction normalizeType(value: string | null | undefined): BilingualDatasetType {\n const normalized = value?.trim().toLowerCase();\n if (!normalized || normalized === 'auto') {\n return 'auto';\n }\n if (normalized === 'flow' || normalized === 'flows') {\n return 'flow';\n }\n if (normalized === 'process' || normalized === 'processes') {\n return 'process';\n }\n if (\n normalized === 'lifecyclemodel' ||\n normalized === 'lifecyclemodels' ||\n normalized === 'model' ||\n normalized === 'models'\n ) {\n return 'lifecyclemodel';\n }\n throw new CliError('Expected --type to be auto, flow, process, or lifecyclemodel.', {\n code: 'DATASET_BILINGUAL_TYPE_INVALID',\n exitCode: 2,\n details: value,\n });\n}\n\nfunction normalizeLang(value: string | null | undefined, fallback: string): string {\n const normalized = value?.trim().toLowerCase();\n const lang = normalized || fallback;\n if (!TIDAS_LANGUAGE_CODE_SET.has(lang)) {\n throw new CliError(\n `Expected language to use a TIDAS Languages enumeration value, got: ${lang}`,\n {\n code: 'DATASET_BILINGUAL_LANGUAGE_NOT_IN_TIDAS_ENUM',\n exitCode: 2,\n },\n );\n }\n return lang;\n}\n\nfunction pointerEscape(segment: string): string {\n return segment.replace(/~/gu, '~0').replace(/\\//gu, '~1');\n}\n\nfunction pointerUnescape(segment: string): string {\n return segment.replace(/~1/gu, '/').replace(/~0/gu, '~');\n}\n\nfunction pointerFromSegments(segments: string[]): string {\n return `/${segments.map(pointerEscape).join('/')}`;\n}\n\nfunction segmentsFromPointer(pointer: string): string[] {\n if (!pointer.startsWith('/')) {\n throw new CliError(`Expected JSON pointer field_path, got: ${pointer}`, {\n code: 'DATASET_BILINGUAL_FIELD_PATH_INVALID',\n exitCode: 2,\n });\n }\n return pointer.slice(1).split('/').map(pointerUnescape);\n}\n\nfunction textPreview(value: string): string {\n return value.length > 180 ? `${value.slice(0, 177)}...` : value;\n}\n\nfunction langOf(value: unknown): string | null {\n return trimToken(isRecord(value) ? value['@xml:lang'] : null)?.toLowerCase() ?? null;\n}\n\nfunction rawLangOf(value: unknown): string | null {\n return trimToken(isRecord(value) ? value['@xml:lang'] : null) ?? null;\n}\n\nfunction textOf(value: unknown): string | null {\n return trimToken(isRecord(value) ? value['#text'] : null);\n}\n\nfunction isLangRecord(value: unknown): value is LangRecord {\n return isRecord(value) && (typeof value['@xml:lang'] === 'string' || '#text' in value);\n}\n\nfunction isLangRecordArray(value: unknown): value is LangRecord[] {\n return Array.isArray(value) && value.some((item) => isLangRecord(item));\n}\n\nfunction hashUnit(parts: unknown[]): string {\n const hash = createHash('sha256');\n for (const part of parts) {\n hash.update(String(part ?? ''));\n hash.update('\\n');\n }\n return hash.digest('hex').slice(0, 24);\n}\n\nfunction filterRowsByType(\n rows: ReturnType<typeof materializeDatasetRows>,\n requestedType: BilingualDatasetType,\n): ReturnType<typeof materializeDatasetRows> {\n if (requestedType === 'auto') {\n return rows;\n }\n return rows.filter((row) => row.kind === requestedType);\n}\n\nfunction rootFieldFromPath(pathSegments: string[]): string | null {\n return pathSegments.find((segment) => !/^\\d+$/u.test(segment)) ?? null;\n}\n\nfunction siblingKeys(parent: unknown): string[] {\n if (!isRecord(parent)) {\n return [];\n }\n return Object.keys(parent).sort().slice(0, 20);\n}\n\nfunction collectTranslationUnitsFromNode(\n node: unknown,\n pathSegments: string[],\n parent: unknown,\n visit: PathVisit,\n sourceLang: string,\n targetLang: string,\n units: BilingualTranslationUnit[],\n): void {\n if (isLangRecordArray(node)) {\n const source = node.find((item) => langOf(item) === sourceLang);\n const target = node.find((item) => langOf(item) === targetLang);\n const sourceText = textOf(source);\n if (sourceText) {\n const fieldPath = pointerFromSegments(pathSegments);\n units.push({\n schema_version: 1,\n unit_id: hashUnit([\n visit.rowIndex,\n visit.id,\n visit.version,\n fieldPath,\n sourceLang,\n targetLang,\n sourceText,\n ]),\n row_index: visit.rowIndex,\n dataset_type: visit.kind,\n dataset_id: visit.id,\n dataset_version: visit.version,\n field_path: fieldPath,\n source_lang: sourceLang,\n target_lang: targetLang,\n source_text: sourceText,\n current_target_text: textOf(target),\n context: {\n root_field: rootFieldFromPath(pathSegments),\n sibling_keys: siblingKeys(parent),\n },\n });\n }\n return;\n }\n\n if (Array.isArray(node)) {\n node.forEach((item, index) =>\n collectTranslationUnitsFromNode(\n item,\n [...pathSegments, String(index)],\n node,\n visit,\n sourceLang,\n targetLang,\n units,\n ),\n );\n return;\n }\n\n if (isRecord(node)) {\n for (const [key, value] of Object.entries(node)) {\n collectTranslationUnitsFromNode(\n value,\n [...pathSegments, key],\n node,\n visit,\n sourceLang,\n targetLang,\n units,\n );\n }\n }\n}\n\nfunction collectTranslationUnits(\n rows: ReturnType<typeof materializeDatasetRows>,\n sourceLang: string,\n targetLang: string,\n): BilingualTranslationUnit[] {\n const units: BilingualTranslationUnit[] = [];\n for (const row of rows) {\n collectTranslationUnitsFromNode(\n row.row,\n [],\n null,\n {\n rowIndex: row.index,\n row: row.row,\n kind: row.kind,\n id: row.id,\n version: row.version,\n },\n sourceLang,\n targetLang,\n units,\n );\n }\n return units;\n}\n\nfunction outFiles(outDir: string | null | undefined): DatasetBilingualExtractReport['files'] {\n if (!outDir) {\n return {\n translation_units: null,\n report: null,\n };\n }\n const resolved = path.resolve(outDir);\n return {\n translation_units: path.join(resolved, 'outputs', 'trans-units.jsonl'),\n report: path.join(resolved, 'outputs', 'extract-report.json'),\n };\n}\n\nfunction readTranslationInputs(inputPath: string, rawInput?: unknown): TranslationInput[] {\n return readDatasetRowsInput(inputPath, rawInput).map((row) => {\n const translatedText =\n trimToken(row.translated_text) ??\n trimToken(row.translatedText) ??\n trimToken(row.translation) ??\n trimToken(row.target_text) ??\n trimToken(row.targetText);\n return {\n unit_id: trimToken(row.unit_id) ?? trimToken(row.unitId),\n row_index:\n typeof row.row_index === 'number'\n ? row.row_index\n : typeof row.rowIndex === 'number'\n ? row.rowIndex\n : null,\n field_path: trimToken(row.field_path) ?? trimToken(row.fieldPath),\n source_lang: trimToken(row.source_lang) ?? trimToken(row.sourceLang),\n target_lang: trimToken(row.target_lang) ?? trimToken(row.targetLang),\n source_text: trimToken(row.source_text) ?? trimToken(row.sourceText),\n translated_text: translatedText,\n basis: trimToken(row.basis) ?? trimToken(row.rationale),\n review_status: trimToken(row.review_status) ?? trimToken(row.reviewStatus),\n reviewer: trimToken(row.reviewer),\n };\n });\n}\n\nfunction resolvePointer(root: unknown, pointer: string): unknown {\n let current = root;\n for (const segment of segmentsFromPointer(pointer)) {\n if (Array.isArray(current)) {\n current = current[Number(segment)];\n } else if (isRecord(current)) {\n current = current[segment];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\nfunction cloneSourceLangRecord(container: LangRecord[], sourceLang: string): LangRecord {\n const source = container.find((item) => langOf(item) === sourceLang);\n const cloned = isRecord(source) ? cloneJson(source) : {};\n cloned['@xml:lang'] = '';\n cloned['#text'] = '';\n return cloned;\n}\n\nfunction applyTranslationToRows(options: {\n rows: JsonObject[];\n translation: TranslationInput;\n targetLang: string;\n}): ApplyTranslationResult {\n const translation = options.translation;\n if (translation.row_index === null || translation.row_index < 0) {\n return { applied: false, blocker: 'Translation is missing row_index.' };\n }\n if (!translation.field_path) {\n return { applied: false, blocker: 'Translation is missing field_path.' };\n }\n if (!translation.translated_text) {\n return { applied: false, blocker: 'Translation is missing translated_text.' };\n }\n\n const row = options.rows[translation.row_index];\n if (!row) {\n return { applied: false, blocker: `No input row exists at index ${translation.row_index}.` };\n }\n\n const container = resolvePointer(row, translation.field_path);\n if (!Array.isArray(container)) {\n return { applied: false, blocker: `field_path does not point to a language array.` };\n }\n\n let target = container.find((item) => isRecord(item) && langOf(item) === options.targetLang);\n if (!target) {\n target = cloneSourceLangRecord(container as LangRecord[], translation.source_lang ?? 'en');\n container.push(target);\n }\n target['@xml:lang'] = options.targetLang;\n target['#text'] = translation.translated_text;\n\n const materializedRows = materializeDatasetRows('memory', { rows: [row] });\n const materialized = materializedRows[0];\n return {\n applied: true,\n evidence: {\n unit_id:\n translation.unit_id ??\n hashUnit([\n translation.row_index,\n translation.field_path,\n translation.source_lang,\n options.targetLang,\n translation.source_text,\n ]),\n row_index: translation.row_index,\n dataset_type: materialized?.kind ?? null,\n dataset_id: materialized?.id ?? null,\n dataset_version: materialized?.version ?? null,\n field_path: translation.field_path,\n source_lang: translation.source_lang ?? 'en',\n target_lang: options.targetLang,\n source_text: translation.source_text ?? '',\n translated_text: translation.translated_text,\n basis: translation.basis,\n review_status: translation.review_status,\n reviewer: translation.reviewer,\n },\n };\n}\n\nfunction writeRowsJsonl(filePath: string, rows: JsonObject[]): string {\n return writeJsonLinesArtifact(filePath, rows);\n}\n\nfunction scanText(node: unknown, pathSegments: string[], visit: PathVisit): BilingualScanFinding[] {\n const findings: BilingualScanFinding[] = [];\n\n if (isLangRecord(node)) {\n const rawLang = rawLangOf(node);\n const lang = langOf(node);\n const text = textOf(node);\n if (!text) {\n return findings;\n }\n const fieldPath = pointerFromSegments(pathSegments);\n const base = {\n row_index: visit.rowIndex,\n dataset_type: visit.kind,\n dataset_id: visit.id,\n dataset_version: visit.version,\n field_path: fieldPath,\n lang,\n text_preview: textPreview(text),\n };\n if (rawLang && !TIDAS_LANGUAGE_CODE_SET.has(rawLang)) {\n findings.push({\n ...base,\n code: 'localized_text_language_not_in_tidas_enum',\n severity: 'blocker',\n message: 'Localized text @xml:lang is not a TIDAS Languages enumeration value.',\n });\n }\n if (PLACEHOLDER_RE.test(text)) {\n findings.push({\n ...base,\n code: 'placeholder_text',\n severity: 'blocker',\n message: 'Text contains placeholder markers.',\n });\n }\n if (lang === 'en' && CJK_RE.test(text)) {\n findings.push({\n ...base,\n code: 'english_contains_cjk',\n severity: 'blocker',\n message: 'English text contains CJK characters.',\n });\n }\n if (lang === 'zh' && CJK_PLURAL_SUFFIX_RE.test(text)) {\n findings.push({\n ...base,\n code: 'mechanical_plural_suffix',\n severity: 'blocker',\n message: 'Chinese text contains mechanical mixed-language plural suffixes.',\n });\n }\n if (lang === 'zh') {\n const latinWords = text.match(LATIN_WORD_RE) ?? [];\n if (latinWords.length >= 8) {\n findings.push({\n ...base,\n code: 'zh_latin_word_density',\n severity: 'warning',\n message:\n 'Chinese text contains many Latin words; review for machine-translation residue.',\n });\n }\n }\n return findings;\n }\n\n if (Array.isArray(node)) {\n node.forEach((item, index) => {\n findings.push(...scanText(item, [...pathSegments, String(index)], visit));\n });\n return findings;\n }\n\n if (isRecord(node)) {\n for (const [key, value] of Object.entries(node)) {\n findings.push(...scanText(value, [...pathSegments, key], visit));\n }\n }\n\n return findings;\n}\n\nfunction scanRows(rows: ReturnType<typeof materializeDatasetRows>): BilingualScanFinding[] {\n return rows.flatMap((row) =>\n scanText(row.row, [], {\n rowIndex: row.index,\n row: row.row,\n kind: row.kind,\n id: row.id,\n version: row.version,\n }),\n );\n}\n\nfunction validateFiles(outDir: string | null | undefined): DatasetBilingualValidateReport['files'] {\n if (!outDir) {\n return {\n report: null,\n findings: null,\n };\n }\n const resolved = path.resolve(outDir);\n return {\n report: path.join(resolved, 'outputs', 'bilingual-validate-report.json'),\n findings: path.join(resolved, 'outputs', 'bilingual-findings.jsonl'),\n };\n}\n\nexport async function runDatasetBilingualExtract(\n options: RunDatasetBilingualExtractOptions,\n): Promise<DatasetBilingualExtractReport> {\n const requestedType = normalizeType(options.type);\n const sourceLang = normalizeLang(options.sourceLang, DEFAULT_SOURCE_LANG);\n const targetLang = normalizeLang(options.targetLang, DEFAULT_TARGET_LANG);\n const rows = filterRowsByType(\n materializeDatasetRows(options.inputPath, options.rawInput),\n requestedType,\n );\n const units = collectTranslationUnits(rows, sourceLang, targetLang);\n const files = outFiles(options.outDir);\n const report: DatasetBilingualExtractReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n requested_type: requestedType,\n source_lang: sourceLang,\n target_lang: targetLang,\n unit_count: units.length,\n row_count: rows.length,\n files,\n };\n\n if (files.translation_units) {\n writeJsonLinesArtifact(files.translation_units, units);\n }\n if (files.report) {\n writeJsonArtifact(files.report, report);\n }\n return report;\n}\n\nexport async function runDatasetBilingualApply(\n options: RunDatasetBilingualApplyOptions,\n): Promise<DatasetBilingualApplyReport> {\n const targetLang = normalizeLang(options.targetLang, DEFAULT_TARGET_LANG);\n if (!options.outPath) {\n throw new CliError('Missing required --out value.', {\n code: 'DATASET_BILINGUAL_OUT_REQUIRED',\n exitCode: 2,\n });\n }\n if (!options.translationsPath) {\n throw new CliError('Missing required --translations value.', {\n code: 'DATASET_BILINGUAL_TRANSLATIONS_REQUIRED',\n exitCode: 2,\n });\n }\n\n const rows = readDatasetRowsInput(options.inputPath, options.rawInput).map((row) =>\n cloneJson(row),\n );\n const translations = readTranslationInputs(options.translationsPath, options.rawTranslations);\n const blockers: DatasetBilingualApplyReport['blockers'] = [];\n const evidence: TranslationEvidenceEntry[] = [];\n let appliedCount = 0;\n let skippedCount = 0;\n\n for (const translation of translations) {\n const result = applyTranslationToRows({ rows, translation, targetLang });\n if (result.applied) {\n appliedCount += 1;\n evidence.push(result.evidence);\n } else {\n skippedCount += 1;\n blockers.push({\n code: 'translation_not_applied',\n message: result.blocker,\n unit_id: translation.unit_id ?? undefined,\n });\n }\n }\n\n const resolvedOut = path.resolve(options.outPath);\n const resolvedOutDir = options.outDir ? path.resolve(options.outDir) : path.dirname(resolvedOut);\n const evidenceFile = path.join(resolvedOutDir, 'outputs', 'translation-evidence.json');\n const reportFile = path.join(resolvedOutDir, 'outputs', 'bilingual-apply-report.json');\n writeRowsJsonl(resolvedOut, rows);\n writeJsonArtifact(evidenceFile, {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n entries: evidence,\n });\n\n const report: DatasetBilingualApplyReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n translations_path: options.translationsPath,\n out_path: resolvedOut,\n target_lang: targetLang,\n status: blockers.length > 0 ? 'blocked' : 'completed',\n row_count: rows.length,\n translation_count: translations.length,\n applied_count: appliedCount,\n skipped_count: skippedCount,\n blockers,\n files: {\n translated_rows: resolvedOut,\n translation_evidence: evidenceFile,\n report: reportFile,\n },\n };\n writeJsonArtifact(reportFile, report);\n return report;\n}\n\nexport async function runDatasetBilingualValidate(\n options: RunDatasetBilingualValidateOptions,\n): Promise<DatasetBilingualValidateReport> {\n const requestedType = normalizeType(options.type);\n const rows = filterRowsByType(\n materializeDatasetRows(options.inputPath, options.rawInput),\n requestedType,\n );\n const findings = scanRows(rows);\n const files = validateFiles(options.outDir);\n const datasetValidateImpl = options.datasetValidateImpl ?? runDatasetValidate;\n const schemaGateOutDir = options.outDir\n ? path.join(path.resolve(options.outDir), 'schema')\n : null;\n const schemaReport = await datasetValidateImpl({\n inputPath: options.inputPath,\n type: requestedType,\n outDir: schemaGateOutDir,\n rawInput: { rows: rows.map((row) => row.row) },\n now: options.now,\n schemas: options.schemas,\n });\n\n let processReport: ProcessQaReport | null = null;\n let flowReport: FlowQaReport | null = null;\n if (options.outDir && (requestedType === 'process' || requestedType === 'auto')) {\n const processRows = rows.filter((row) => row.kind === 'process').map((row) => row.row);\n if (processRows.length > 0) {\n const processRowsFile = path.join(path.resolve(options.outDir), 'qa-input-processes.jsonl');\n writeJsonLinesArtifact(processRowsFile, processRows);\n processReport = await (options.processQaImpl ?? runProcessQa)({\n rowsFile: processRowsFile,\n outDir: path.join(path.resolve(options.outDir), 'qa', 'process'),\n now: () => options.now ?? new Date(),\n });\n }\n }\n if (options.outDir && (requestedType === 'flow' || requestedType === 'auto')) {\n const flowRows = rows.filter((row) => row.kind === 'flow').map((row) => row.row);\n if (flowRows.length > 0) {\n const flowRowsFile = path.join(path.resolve(options.outDir), 'qa-input-flows.jsonl');\n writeJsonLinesArtifact(flowRowsFile, flowRows);\n flowReport = await (options.flowQaImpl ?? runFlowQa)({\n rowsFile: flowRowsFile,\n outDir: path.join(path.resolve(options.outDir), 'qa', 'flow'),\n now: () => options.now ?? new Date(),\n });\n }\n }\n\n const blockerCount = findings.filter((finding) => finding.severity === 'blocker').length;\n const warningCount = findings.filter((finding) => finding.severity === 'warning').length;\n const report: DatasetBilingualValidateReport = {\n schema_version: 1,\n generated_at_utc: nowIso(options.now),\n input_path: options.inputPath,\n requested_type: requestedType,\n status: blockerCount > 0 || schemaReport.counts.invalid > 0 ? 'blocked' : 'completed',\n row_count: rows.length,\n scan: {\n finding_count: findings.length,\n blocker_count: blockerCount,\n warning_count: warningCount,\n findings,\n },\n schema_gate: {\n status: schemaReport.status,\n valid: schemaReport.counts.valid,\n invalid: schemaReport.counts.invalid,\n report_file: schemaReport.files.report,\n },\n qa_gate: {\n status: processReport || flowReport ? 'completed' : 'not_run',\n process_report_file: processReport?.files.report ?? null,\n flow_report_file: flowReport?.files.report ?? null,\n },\n files,\n };\n\n if (files.findings) {\n writeJsonLinesArtifact(files.findings, findings);\n }\n if (files.report) {\n writeJsonArtifact(files.report, report);\n }\n return report;\n}\n\nexport const __testInternals = {\n collectTranslationUnits,\n normalizeType,\n pointerFromSegments,\n rawLangOf,\n segmentsFromPointer,\n scanRows,\n};\n"]}
|
|
@@ -3,6 +3,7 @@ import { existsSync, mkdirSync, readdirSync } from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { writeJsonArtifact, writeTextArtifact } from './artifacts.js';
|
|
5
5
|
import { CliError } from './errors.js';
|
|
6
|
+
import { TIDAS_LANGUAGE_CODE_SET } from './tidas-languages.js';
|
|
6
7
|
import { readJsonInput } from './io.js';
|
|
7
8
|
import { buildRunId, buildRunManifest, ensureRunLayout, writeLatestRunId, } from './run.js';
|
|
8
9
|
const UUID_NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8';
|
|
@@ -108,7 +109,8 @@ function langTextMap(value) {
|
|
|
108
109
|
if (!isRecord(item)) {
|
|
109
110
|
continue;
|
|
110
111
|
}
|
|
111
|
-
const
|
|
112
|
+
const candidateLang = nonEmptyString(item['@xml:lang'])?.toLowerCase() ?? 'en';
|
|
113
|
+
const lang = TIDAS_LANGUAGE_CODE_SET.has(candidateLang) ? candidateLang : 'en';
|
|
112
114
|
const text = nonEmptyString(item['#text']);
|
|
113
115
|
if (text && !mapping[lang]) {
|
|
114
116
|
mapping[lang] = text;
|
|
@@ -125,13 +127,6 @@ function localizedText(value, preferred = 'zh') {
|
|
|
125
127
|
if (mapping[preferred]) {
|
|
126
128
|
return mapping[preferred];
|
|
127
129
|
}
|
|
128
|
-
if (preferred.startsWith('zh')) {
|
|
129
|
-
for (const candidate of ['zh-cn', 'zh-hans', 'zh']) {
|
|
130
|
-
if (mapping[candidate]) {
|
|
131
|
-
return mapping[candidate];
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
130
|
if (mapping.en) {
|
|
136
131
|
return mapping.en;
|
|
137
132
|
}
|
|
@@ -139,7 +134,7 @@ function localizedText(value, preferred = 'zh') {
|
|
|
139
134
|
}
|
|
140
135
|
function multilangText(value) {
|
|
141
136
|
const mapping = langTextMap(value);
|
|
142
|
-
return [mapping.en ?? Object.values(mapping)[0] ?? '', mapping.zh ??
|
|
137
|
+
return [mapping.en ?? Object.values(mapping)[0] ?? '', mapping.zh ?? ''];
|
|
143
138
|
}
|
|
144
139
|
function multilangFromText(enText, zhText) {
|
|
145
140
|
const items = [];
|
|
@@ -174,12 +169,7 @@ function buildNameSummary(nameInfo) {
|
|
|
174
169
|
if (langOrder.length === 0) {
|
|
175
170
|
return [];
|
|
176
171
|
}
|
|
177
|
-
const fallback = (mapping, lang) => mapping[lang] ??
|
|
178
|
-
mapping.zh ??
|
|
179
|
-
mapping['zh-cn'] ??
|
|
180
|
-
mapping.en ??
|
|
181
|
-
Object.values(mapping)[0] ??
|
|
182
|
-
'';
|
|
172
|
+
const fallback = (mapping, lang) => mapping[lang] ?? mapping.zh ?? mapping.en ?? Object.values(mapping)[0] ?? '';
|
|
183
173
|
const summary = [];
|
|
184
174
|
langOrder.forEach((lang) => {
|
|
185
175
|
const text = [
|