@chenchaolong/plugin-trade-compliance-workbench 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +10 -0
  2. package/dist/lib/catalog-import/catalog-document.parser.d.ts +18 -0
  3. package/dist/lib/catalog-import/catalog-document.parser.d.ts.map +1 -0
  4. package/dist/lib/catalog-import/catalog-document.parser.js +36 -0
  5. package/dist/lib/catalog-import/catalog-document.parser.js.map +1 -0
  6. package/dist/lib/catalog-import/catalog-import.pipeline.d.ts +30 -0
  7. package/dist/lib/catalog-import/catalog-import.pipeline.d.ts.map +1 -0
  8. package/dist/lib/catalog-import/catalog-import.pipeline.js +54 -0
  9. package/dist/lib/catalog-import/catalog-import.pipeline.js.map +1 -0
  10. package/dist/lib/catalog-import/confidence.d.ts +3 -0
  11. package/dist/lib/catalog-import/confidence.d.ts.map +1 -0
  12. package/dist/lib/catalog-import/confidence.js +52 -0
  13. package/dist/lib/catalog-import/confidence.js.map +1 -0
  14. package/dist/lib/catalog-import/contracts.d.ts +50 -0
  15. package/dist/lib/catalog-import/contracts.d.ts.map +1 -0
  16. package/dist/lib/catalog-import/contracts.js +2 -0
  17. package/dist/lib/catalog-import/contracts.js.map +1 -0
  18. package/dist/lib/catalog-import/docx.parser.d.ts +6 -0
  19. package/dist/lib/catalog-import/docx.parser.d.ts.map +1 -0
  20. package/dist/lib/catalog-import/docx.parser.js +130 -0
  21. package/dist/lib/catalog-import/docx.parser.js.map +1 -0
  22. package/dist/lib/catalog-import/header-mapping.d.ts +4 -0
  23. package/dist/lib/catalog-import/header-mapping.d.ts.map +1 -0
  24. package/dist/lib/catalog-import/header-mapping.js +34 -0
  25. package/dist/lib/catalog-import/header-mapping.js.map +1 -0
  26. package/dist/lib/catalog-import/pdf-layout.parser.d.ts +15 -0
  27. package/dist/lib/catalog-import/pdf-layout.parser.d.ts.map +1 -0
  28. package/dist/lib/catalog-import/pdf-layout.parser.js +133 -0
  29. package/dist/lib/catalog-import/pdf-layout.parser.js.map +1 -0
  30. package/dist/lib/catalog-import/pdf-table.normalizer.d.ts +4 -0
  31. package/dist/lib/catalog-import/pdf-table.normalizer.d.ts.map +1 -0
  32. package/dist/lib/catalog-import/pdf-table.normalizer.js +22 -0
  33. package/dist/lib/catalog-import/pdf-table.normalizer.js.map +1 -0
  34. package/dist/lib/catalog-import/spreadsheet.parser.d.ts +7 -0
  35. package/dist/lib/catalog-import/spreadsheet.parser.d.ts.map +1 -0
  36. package/dist/lib/catalog-import/spreadsheet.parser.js +118 -0
  37. package/dist/lib/catalog-import/spreadsheet.parser.js.map +1 -0
  38. package/dist/lib/constants.d.ts +3 -0
  39. package/dist/lib/constants.d.ts.map +1 -1
  40. package/dist/lib/constants.js +3 -0
  41. package/dist/lib/constants.js.map +1 -1
  42. package/dist/lib/entities/catalog.entity.d.ts +25 -1
  43. package/dist/lib/entities/catalog.entity.d.ts.map +1 -1
  44. package/dist/lib/entities/catalog.entity.js +94 -0
  45. package/dist/lib/entities/catalog.entity.js.map +1 -1
  46. package/dist/lib/entities/index.d.ts +2 -2
  47. package/dist/lib/entities/index.d.ts.map +1 -1
  48. package/dist/lib/entities/index.js +3 -2
  49. package/dist/lib/entities/index.js.map +1 -1
  50. package/dist/lib/entities/shared.entity.d.ts +3 -1
  51. package/dist/lib/entities/shared.entity.d.ts.map +1 -1
  52. package/dist/lib/entities/shared.entity.js +8 -0
  53. package/dist/lib/entities/shared.entity.js.map +1 -1
  54. package/dist/lib/import-jobs/import-command.builder.d.ts +4 -0
  55. package/dist/lib/import-jobs/import-command.builder.d.ts.map +1 -1
  56. package/dist/lib/import-jobs/import-command.builder.js +11 -0
  57. package/dist/lib/import-jobs/import-command.builder.js.map +1 -1
  58. package/dist/lib/import-jobs/import-job-callback.processor.d.ts.map +1 -1
  59. package/dist/lib/import-jobs/import-job-callback.processor.js +22 -0
  60. package/dist/lib/import-jobs/import-job-callback.processor.js.map +1 -1
  61. package/dist/lib/import-jobs/import-job.processor.d.ts.map +1 -1
  62. package/dist/lib/import-jobs/import-job.processor.js +32 -1
  63. package/dist/lib/import-jobs/import-job.processor.js.map +1 -1
  64. package/dist/lib/public-dto.d.ts +1 -1
  65. package/dist/lib/public-dto.d.ts.map +1 -1
  66. package/dist/lib/public-dto.js +2 -0
  67. package/dist/lib/public-dto.js.map +1 -1
  68. package/dist/lib/remote-components/trade-compliance-workbench/app.js +5 -5
  69. package/dist/lib/remote-ui/app-source.js +12 -0
  70. package/dist/lib/remote-ui/app-source.js.map +1 -1
  71. package/dist/lib/remote-ui/contracts.d.ts +9 -0
  72. package/dist/lib/remote-ui/contracts.d.ts.map +1 -1
  73. package/dist/lib/runtime-validation.d.ts +1 -1
  74. package/dist/lib/types.d.ts +26 -0
  75. package/dist/lib/types.d.ts.map +1 -1
  76. package/dist/lib/types.js +3 -0
  77. package/dist/lib/types.js.map +1 -1
  78. package/dist/lib/workbench-view.provider.d.ts +7 -0
  79. package/dist/lib/workbench-view.provider.d.ts.map +1 -1
  80. package/dist/lib/workbench-view.provider.js +1 -0
  81. package/dist/lib/workbench-view.provider.js.map +1 -1
  82. package/dist/lib/workbench.middleware.d.ts +89 -6
  83. package/dist/lib/workbench.middleware.d.ts.map +1 -1
  84. package/dist/lib/workbench.middleware.js +3 -0
  85. package/dist/lib/workbench.middleware.js.map +1 -1
  86. package/dist/lib/workbench.service.d.ts +56 -1
  87. package/dist/lib/workbench.service.d.ts.map +1 -1
  88. package/dist/lib/workbench.service.js +463 -7
  89. package/dist/lib/workbench.service.js.map +1 -1
  90. package/package.json +2 -1
package/README.md CHANGED
@@ -45,6 +45,16 @@ pnpm visual:check
45
45
 
46
46
  该命令生成 38 张原型映射截图、9 张窄屏截图和 3 张布局契约截图,共 50 张,写入 `artifacts/visual-check/`。检查覆盖 route、页面标题、dialog、关键字段、操作列策略、184/56px 侧栏、内部滚动、首页八步四列流程、按钮图标,以及页面和控件的溢出、重叠问题。
47
47
 
48
+ ### 目录解析样本验证
49
+
50
+ 混合目录管线对 XLS/XLSX、结构化 DOCX 和带文本表格层的 PDF 使用代码解析;无法验证的局部来源块进入 ChatKit/人工复核,旧 DOC、图片和扫描 PDF 回退兼容模式。可使用明确提供的样本路径运行只读验证:
51
+
52
+ ```bash
53
+ pnpm verify:catalog-samples -- "/path/to/controlled-catalog.pdf" "/path/to/sanction-catalog.docx"
54
+ ```
55
+
56
+ 命令会先构建插件,再输出 PDF schema、自动接受数、复核原因、DOCX 实体/自然人数和别名统计;不会写入数据库。
57
+
48
58
  ## 演示数据初始化
49
59
 
50
60
  > 警告:以下命令会向 `XPERT_ORG_ID` 指定的真实组织写入演示业务数据和演示 XLSX 文件。请先确认目标组织,生产组织不要执行。
@@ -0,0 +1,18 @@
1
+ import type { SourceFileFormat } from '../types.js';
2
+ import type { CatalogCandidateKind, CatalogParseResult } from './contracts.js';
3
+ import { type PdfCatalogParseResult } from './pdf-layout.parser.js';
4
+ export type ParseCatalogDocumentInput = {
5
+ format: SourceFileFormat;
6
+ kind: CatalogCandidateKind;
7
+ buffer: Buffer | Uint8Array;
8
+ };
9
+ export type CatalogCompatibilityResult = {
10
+ mode: 'COMPATIBILITY_AGENT';
11
+ accepted: [];
12
+ reviewBlocks: [];
13
+ skipped: [];
14
+ reason: 'FORMAT_REQUIRES_AGENT' | 'PDF_STRUCTURE_UNAVAILABLE' | 'DOCX_STRUCTURE_UNAVAILABLE';
15
+ };
16
+ export type CatalogDocumentParseResult = CatalogParseResult | PdfCatalogParseResult | CatalogCompatibilityResult;
17
+ export declare function parseCatalogDocument(input: ParseCatalogDocumentInput): Promise<CatalogDocumentParseResult>;
18
+ //# sourceMappingURL=catalog-document.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-document.parser.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/catalog-document.parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAE9E,OAAO,EAAmB,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAGpF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,gBAAgB,CAAA;IACxB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,qBAAqB,CAAA;IAC3B,QAAQ,EAAE,EAAE,CAAA;IACZ,YAAY,EAAE,EAAE,CAAA;IAChB,OAAO,EAAE,EAAE,CAAA;IACX,MAAM,EAAE,uBAAuB,GAAG,2BAA2B,GAAG,4BAA4B,CAAA;CAC7F,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,0BAA0B,CAAA;AAMhH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAwBhH"}
@@ -0,0 +1,36 @@
1
+ import { parseDocxCatalog } from './docx.parser.js';
2
+ import { parsePdfCatalog } from './pdf-layout.parser.js';
3
+ import { parseSpreadsheetCatalog } from './spreadsheet.parser.js';
4
+ function compatibility(reason) {
5
+ return { mode: 'COMPATIBILITY_AGENT', accepted: [], reviewBlocks: [], skipped: [], reason };
6
+ }
7
+ export async function parseCatalogDocument(input) {
8
+ if (input.format === 'XLS' || input.format === 'XLSX') {
9
+ return parseSpreadsheetCatalog(input);
10
+ }
11
+ if (input.format === 'DOCX') {
12
+ if (input.kind !== 'SANCTION')
13
+ return compatibility('FORMAT_REQUIRES_AGENT');
14
+ try {
15
+ return await parseDocxCatalog(input);
16
+ }
17
+ catch {
18
+ return compatibility('DOCX_STRUCTURE_UNAVAILABLE');
19
+ }
20
+ }
21
+ if (input.format === 'PDF') {
22
+ if (input.kind !== 'CONTROLLED')
23
+ return compatibility('FORMAT_REQUIRES_AGENT');
24
+ try {
25
+ const result = await parsePdfCatalog(input.buffer);
26
+ return result.accepted.length > 0 || result.reviewBlocks.length > 0
27
+ ? result
28
+ : compatibility('PDF_STRUCTURE_UNAVAILABLE');
29
+ }
30
+ catch {
31
+ return compatibility('PDF_STRUCTURE_UNAVAILABLE');
32
+ }
33
+ }
34
+ return compatibility('FORMAT_REQUIRES_AGENT');
35
+ }
36
+ //# sourceMappingURL=catalog-document.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-document.parser.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/catalog-document.parser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,eAAe,EAA8B,MAAM,wBAAwB,CAAA;AACpF,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAkBjE,SAAS,aAAa,CAAC,MAA4C;IACjE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAA;AAC7F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAgC;IACzE,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QACtD,OAAO,uBAAuB,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;YAAE,OAAO,aAAa,CAAC,uBAAuB,CAAC,CAAA;QAC5E,IAAI,CAAC;YACH,OAAO,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,CAAC,4BAA4B,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,aAAa,CAAC,uBAAuB,CAAC,CAAA;QAC9E,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAClD,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;gBACjE,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAA;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,CAAC,2BAA2B,CAAC,CAAA;QACnD,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,uBAAuB,CAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { ImportTask } from '../entities/index.js';
2
+ import type { RequestScope } from '../types.js';
3
+ import type { TradeComplianceFileStorage } from '../adapters/file-storage.js';
4
+ import type { TradeComplianceWorkbenchService } from '../workbench.service.js';
5
+ import { type CatalogDocumentParseResult, type ParseCatalogDocumentInput } from './catalog-document.parser.js';
6
+ type FastCatalogTask = Pick<ImportTask, 'id' | 'documentType' | 'sourceFileId' | 'sourceFileName' | 'sourceFileFormat' | 'executionInput'>;
7
+ type CatalogParser = (input: ParseCatalogDocumentInput) => Promise<CatalogDocumentParseResult>;
8
+ type FastReadyObserver = (summary: {
9
+ taskId: string;
10
+ totalCandidates: number;
11
+ reviewCount: number;
12
+ }) => Promise<void>;
13
+ type FastCatalogService = Pick<TradeComplianceWorkbenchService, 'beginFastCatalogImport' | 'appendFastCatalogBatch' | 'finalizeFastCatalogImport'>;
14
+ export declare class CatalogImportPipeline {
15
+ private readonly service;
16
+ private readonly storage;
17
+ private readonly parser;
18
+ private readonly onFastReady?;
19
+ constructor(service: FastCatalogService, storage: Pick<TradeComplianceFileStorage, 'read'>, parser?: CatalogParser, onFastReady?: FastReadyObserver | undefined);
20
+ process(scope: RequestScope, task: FastCatalogTask): Promise<{
21
+ kind: "COMPATIBILITY_AGENT";
22
+ reason: "FORMAT_REQUIRES_AGENT" | "PDF_STRUCTURE_UNAVAILABLE" | "DOCX_STRUCTURE_UNAVAILABLE";
23
+ } | {
24
+ kind: "COMPLETED";
25
+ reason?: undefined;
26
+ }>;
27
+ private appendBatch;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=catalog-import.pipeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-import.pipeline.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/catalog-import.pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAA;AAC7E,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yBAAyB,CAAA;AAC9E,OAAO,EAAwB,KAAK,0BAA0B,EAAE,KAAK,yBAAyB,EAAE,MAAM,8BAA8B,CAAA;AAKpI,KAAK,eAAe,GAAG,IAAI,CACzB,UAAU,EACV,IAAI,GAAG,cAAc,GAAG,cAAc,GAAG,gBAAgB,GAAG,kBAAkB,GAAG,gBAAgB,CAClG,CAAA;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,yBAAyB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAA;AAC9F,KAAK,iBAAiB,GAAG,CAAC,OAAO,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAErH,KAAK,kBAAkB,GAAG,IAAI,CAC5B,+BAA+B,EAC/B,wBAAwB,GAAG,wBAAwB,GAAG,2BAA2B,CAClF,CAAA;AAED,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAHZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,IAAI,CAAC,0BAA0B,EAAE,MAAM,CAAC,EACjD,MAAM,GAAE,aAAoC,EAC5C,WAAW,CAAC,EAAE,iBAAiB,YAAA;IAG5C,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe;;;;;;;YA0C1C,WAAW;CAkB1B"}
@@ -0,0 +1,54 @@
1
+ import { parseCatalogDocument } from './catalog-document.parser.js';
2
+ const FAST_BATCH_SIZE = 100;
3
+ export class CatalogImportPipeline {
4
+ constructor(service, storage, parser = parseCatalogDocument, onFastReady) {
5
+ this.service = service;
6
+ this.storage = storage;
7
+ this.parser = parser;
8
+ this.onFastReady = onFastReady;
9
+ }
10
+ async process(scope, task) {
11
+ const kind = task.documentType === 'CONTROLLED_CATALOG' ? 'CONTROLLED' : 'SANCTION';
12
+ const buffer = await this.storage.read(task.sourceFileId);
13
+ const parsed = await this.parser({ format: task.sourceFileFormat, kind, buffer });
14
+ if (parsed.mode === 'COMPATIBILITY_AGENT') {
15
+ return { kind: 'COMPATIBILITY_AGENT', reason: parsed.reason };
16
+ }
17
+ const state = await this.service.beginFastCatalogImport(scope, {
18
+ taskId: task.id,
19
+ catalogType: task.executionInput?.catalogType,
20
+ replaceBatchId: task.executionInput?.replaceBatchId,
21
+ totalCandidates: parsed.accepted.length + parsed.reviewBlocks.length + parsed.skipped.length
22
+ });
23
+ await this.onFastReady?.({
24
+ taskId: task.id,
25
+ totalCandidates: parsed.accepted.length + parsed.reviewBlocks.length + parsed.skipped.length,
26
+ reviewCount: parsed.reviewBlocks.length
27
+ });
28
+ let cursor = Math.min(state.committedCursor, parsed.accepted.length);
29
+ if (parsed.accepted.length === 0) {
30
+ await this.appendBatch(scope, task.id, [], parsed.reviewBlocks, parsed.skipped, 0, 0);
31
+ }
32
+ else {
33
+ while (cursor < parsed.accepted.length) {
34
+ const endCursor = Math.min(cursor + FAST_BATCH_SIZE, parsed.accepted.length);
35
+ const finalBatch = endCursor === parsed.accepted.length;
36
+ await this.appendBatch(scope, task.id, parsed.accepted.slice(cursor, endCursor), finalBatch ? parsed.reviewBlocks : [], finalBatch ? parsed.skipped : [], cursor, endCursor);
37
+ cursor = endCursor;
38
+ }
39
+ }
40
+ await this.service.finalizeFastCatalogImport(scope, task.id);
41
+ return { kind: 'COMPLETED' };
42
+ }
43
+ async appendBatch(scope, taskId, candidates, reviewBlocks, skipped, startCursor, endCursor) {
44
+ return this.service.appendFastCatalogBatch(scope, {
45
+ taskId,
46
+ candidates,
47
+ reviewBlocks,
48
+ skipped,
49
+ startCursor,
50
+ endCursor
51
+ });
52
+ }
53
+ }
54
+ //# sourceMappingURL=catalog-import.pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-import.pipeline.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/catalog-import.pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CatalogCandidate, CatalogConfidenceDecision } from './contracts.js';
2
+ export declare function classifyCandidate(candidate: CatalogCandidate): CatalogConfidenceDecision;
3
+ //# sourceMappingURL=confidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/confidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAG1B,MAAM,gBAAgB,CAAA;AAsCvB,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,yBAAyB,CAmBxF"}
@@ -0,0 +1,52 @@
1
+ const HS_CODE_PATTERN = /^\d{8,10}$/;
2
+ const EFFECTIVE_DATE_PATTERN = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
3
+ const CONTROL_CODE_PATTERN = /^\d[A-Z]\d{3}(?:\.[a-z0-9]+)*$/;
4
+ const REVIEW_SIGNALS = new Set([
5
+ 'CROSS_PAGE_UNCERTAIN',
6
+ 'COLUMN_LAYOUT_DRIFT',
7
+ 'FIELD_CONFLICT'
8
+ ]);
9
+ function isBlank(value) {
10
+ return typeof value !== 'string' || value.trim().length === 0;
11
+ }
12
+ function hardFailure(candidate) {
13
+ if (candidate.evidence.length === 0 || candidate.evidence.some(item => isBlank(item.sourceLocation) || isBlank(item.sourceContent))) {
14
+ return 'SOURCE_EVIDENCE_MISSING';
15
+ }
16
+ if (candidate.kind === 'CONTROLLED' && isBlank(candidate.values.productName)) {
17
+ return 'PRODUCT_NAME_MISSING';
18
+ }
19
+ if (candidate.kind === 'SANCTION' && isBlank(candidate.values.companyName)) {
20
+ return 'COMPANY_NAME_MISSING';
21
+ }
22
+ if (candidate.values.hsCodes?.some(code => !HS_CODE_PATTERN.test(code))) {
23
+ return 'HS_CODE_INVALID';
24
+ }
25
+ if (candidate.values.effectiveDate !== undefined && !EFFECTIVE_DATE_PATTERN.test(candidate.values.effectiveDate)) {
26
+ return 'EFFECTIVE_DATE_INVALID';
27
+ }
28
+ if (candidate.values.controlCode !== undefined && !CONTROL_CODE_PATTERN.test(candidate.values.controlCode)) {
29
+ return 'CONTROL_CODE_INVALID';
30
+ }
31
+ return undefined;
32
+ }
33
+ export function classifyCandidate(candidate) {
34
+ const failure = hardFailure(candidate);
35
+ if (failure) {
36
+ return { confidence: 'LOW', autoPersist: false, reasons: [failure] };
37
+ }
38
+ const reviewReasons = candidate.signals.filter(signal => REVIEW_SIGNALS.has(signal));
39
+ if (reviewReasons.length > 0) {
40
+ return { confidence: 'MEDIUM', autoPersist: false, reasons: reviewReasons };
41
+ }
42
+ const unverifiableReasons = [];
43
+ if (!candidate.signals.includes('RECORD_START_EXPLICIT'))
44
+ unverifiableReasons.push('RECORD_START_UNVERIFIED');
45
+ if (!candidate.signals.includes('COLUMN_LAYOUT_STABLE'))
46
+ unverifiableReasons.push('COLUMN_LAYOUT_UNVERIFIED');
47
+ if (unverifiableReasons.length > 0) {
48
+ return { confidence: 'MEDIUM', autoPersist: false, reasons: unverifiableReasons };
49
+ }
50
+ return { confidence: 'HIGH', autoPersist: true, reasons: ['VERIFIABLE_STRUCTURE'] };
51
+ }
52
+ //# sourceMappingURL=confidence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/confidence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { CatalogConfidence } from '../types.js';
2
+ export type CatalogCandidateKind = 'CONTROLLED' | 'SANCTION';
3
+ export type CatalogEvidence = {
4
+ sourceLocation: string;
5
+ sourceContent: string;
6
+ };
7
+ export type CatalogSignal = 'STRUCTURED_SOURCE' | 'HEADER_MAPPED' | 'RECORD_START_EXPLICIT' | 'COLUMN_LAYOUT_STABLE' | 'CROSS_PAGE_UNCERTAIN' | 'COLUMN_LAYOUT_DRIFT' | 'FIELD_CONFLICT';
8
+ export type CatalogCandidateValues = {
9
+ productName?: string;
10
+ companyName?: string;
11
+ hsCodes?: string[];
12
+ effectiveDate?: string;
13
+ controlCode?: string;
14
+ [key: string]: unknown;
15
+ };
16
+ export type CatalogCandidate = {
17
+ kind: CatalogCandidateKind;
18
+ ordinal: number;
19
+ values: CatalogCandidateValues;
20
+ evidence: CatalogEvidence[];
21
+ signals: CatalogSignal[];
22
+ warnings: string[];
23
+ };
24
+ export type CatalogConfidenceReason = 'SOURCE_EVIDENCE_MISSING' | 'PRODUCT_NAME_MISSING' | 'COMPANY_NAME_MISSING' | 'HS_CODE_INVALID' | 'EFFECTIVE_DATE_INVALID' | 'CONTROL_CODE_INVALID' | 'CROSS_PAGE_UNCERTAIN' | 'COLUMN_LAYOUT_DRIFT' | 'FIELD_CONFLICT' | 'RECORD_START_UNVERIFIED' | 'COLUMN_LAYOUT_UNVERIFIED' | 'VERIFIABLE_STRUCTURE';
25
+ export type CatalogConfidenceDecision = {
26
+ confidence: CatalogConfidence;
27
+ autoPersist: boolean;
28
+ reasons: CatalogConfidenceReason[];
29
+ };
30
+ export type CatalogReviewDraft = {
31
+ ordinal: number;
32
+ kind: CatalogCandidateKind;
33
+ confidence: CatalogConfidence;
34
+ sourceLocation: string;
35
+ sourceContent: string;
36
+ payload: CatalogCandidateValues;
37
+ reasons: string[];
38
+ };
39
+ export type CatalogSkippedSource = {
40
+ sourceLocation: string;
41
+ sourceContent: string;
42
+ reason: string;
43
+ };
44
+ export type CatalogParseResult = {
45
+ mode: 'FAST_PIPELINE';
46
+ accepted: CatalogCandidate[];
47
+ reviewBlocks: CatalogReviewDraft[];
48
+ skipped: CatalogSkippedSource[];
49
+ };
50
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/contracts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,CAAA;AAE5D,MAAM,MAAM,eAAe,GAAG;IAC5B,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,aAAa,GACrB,mBAAmB,GACnB,eAAe,GACf,uBAAuB,GACvB,sBAAsB,GACtB,sBAAsB,GACtB,qBAAqB,GACrB,gBAAgB,CAAA;AAEpB,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,oBAAoB,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,sBAAsB,CAAA;IAC9B,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAC/B,yBAAyB,GACzB,sBAAsB,GACtB,sBAAsB,GACtB,iBAAiB,GACjB,wBAAwB,GACxB,sBAAsB,GACtB,sBAAsB,GACtB,qBAAqB,GACrB,gBAAgB,GAChB,yBAAyB,GACzB,0BAA0B,GAC1B,sBAAsB,CAAA;AAE1B,MAAM,MAAM,yBAAyB,GAAG;IACtC,UAAU,EAAE,iBAAiB,CAAA;IAC7B,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,uBAAuB,EAAE,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,oBAAoB,CAAA;IAC1B,UAAU,EAAE,iBAAiB,CAAA;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,sBAAsB,CAAA;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,eAAe,CAAA;IACrB,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAChC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/contracts.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { CatalogParseResult } from './contracts.js';
2
+ export type ParseDocxCatalogInput = {
3
+ buffer: Buffer | Uint8Array;
4
+ };
5
+ export declare function parseDocxCatalog(input: ParseDocxCatalogInput): Promise<CatalogParseResult>;
6
+ //# sourceMappingURL=docx.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx.parser.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/docx.parser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAG1E,MAAM,MAAM,qBAAqB,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAAA;CAAE,CAAA;AAmDnE,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAqEhG"}
@@ -0,0 +1,130 @@
1
+ import { load } from 'cheerio';
2
+ import JSZip from 'jszip';
3
+ import { classifyCandidate } from './confidence.js';
4
+ import { mapCatalogHeaders } from './header-mapping.js';
5
+ function normalizedText(value) {
6
+ return value.replace(/\u00a0/g, ' ').replace(/[ \t]+/g, ' ').replace(/\n\s*/g, '\n').trim();
7
+ }
8
+ function paragraphText($, paragraph) {
9
+ const parts = [];
10
+ $(paragraph).find('*').each((_, node) => {
11
+ if (node.type !== 'tag')
12
+ return;
13
+ if (node.name === 'w:t')
14
+ parts.push($(node).text());
15
+ if (node.name === 'w:br' || node.name === 'w:tab')
16
+ parts.push('\n');
17
+ });
18
+ return normalizedText(parts.join(''));
19
+ }
20
+ function cellText($, cell) {
21
+ return normalizedText($(cell).children('w\\:p').toArray().map(node => paragraphText($, node)).filter(Boolean).join('\n'));
22
+ }
23
+ function value(mapping, cells, field) {
24
+ const index = mapping.get(field);
25
+ return index === undefined ? '' : (cells[index] ?? '').trim();
26
+ }
27
+ function normalizeListingDate(input) {
28
+ const raw = input.trim();
29
+ if (/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/.test(raw))
30
+ return raw;
31
+ const match = /^(\d{1,2})[./-](\d{1,2})[./-](\d{4})$/.exec(raw);
32
+ if (!match)
33
+ return undefined;
34
+ const [, day, month, year] = match;
35
+ return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')}`;
36
+ }
37
+ function parseNames(raw) {
38
+ const lines = raw.split(/\n+/).map(item => item.trim()).filter(Boolean);
39
+ const companyName = lines.shift() ?? '';
40
+ const aliases = [];
41
+ for (const line of lines) {
42
+ const aka = /^(?:also known as|a\.?k\.?a\.?|aka)\s*:?\s*(.+)$/i.exec(line);
43
+ if (aka) {
44
+ for (const alias of aka[1].split(/\s*;\s*/).filter(Boolean))
45
+ aliases.push({ alias, aliasType: 'AKA' });
46
+ }
47
+ else if (/\p{Script=Cyrillic}/u.test(line)) {
48
+ aliases.push({ alias: line, aliasType: 'LOCAL_LANGUAGE' });
49
+ }
50
+ }
51
+ return { companyName, aliases };
52
+ }
53
+ export async function parseDocxCatalog(input) {
54
+ const zip = await JSZip.loadAsync(input.buffer);
55
+ const documentFile = zip.file('word/document.xml');
56
+ if (!documentFile)
57
+ throw new Error('DOCX_DOCUMENT_XML_MISSING');
58
+ const xml = await documentFile.async('string');
59
+ const $ = load(xml, { xmlMode: true });
60
+ const result = { mode: 'FAST_PIPELINE', accepted: [], reviewBlocks: [], skipped: [] };
61
+ let section;
62
+ let tableNumber = 0;
63
+ $('w\\:body').first().children().each((_, node) => {
64
+ if (node.type !== 'tag')
65
+ return;
66
+ if (node.name === 'w:p') {
67
+ const heading = paragraphText($, node);
68
+ if (/^persons$/i.test(heading))
69
+ section = 'Persons';
70
+ if (/^entities$/i.test(heading))
71
+ section = 'Entities';
72
+ return;
73
+ }
74
+ if (node.name !== 'w:tbl')
75
+ return;
76
+ tableNumber += 1;
77
+ const rows = $(node).children('w\\:tr').toArray().map((row, rowIndex) => ({
78
+ rowNumber: rowIndex + 1,
79
+ cells: $(row).children('w\\:tc').toArray().map(cell => cellText($, cell))
80
+ }));
81
+ if (rows.length === 0)
82
+ return;
83
+ const mapping = mapCatalogHeaders(rows[0].cells);
84
+ const tableSection = section;
85
+ for (const row of rows.slice(1)) {
86
+ const sourceLocation = `${tableSection ?? 'Unknown'} table ${tableNumber} row ${row.rowNumber}`;
87
+ const sourceContent = row.cells.join(' | ');
88
+ if (tableSection === 'Persons') {
89
+ result.skipped.push({ sourceLocation, sourceContent, reason: 'SANCTION_PERSON_OUT_OF_SCOPE' });
90
+ continue;
91
+ }
92
+ const rawName = value(mapping, row.cells, 'companyName');
93
+ const names = parseNames(rawName);
94
+ const rawDate = value(mapping, row.cells, 'effectiveDate');
95
+ const normalizedDate = normalizeListingDate(rawDate);
96
+ const parsedOrdinal = Number.parseInt(value(mapping, row.cells, 'ordinal'), 10);
97
+ const candidate = {
98
+ kind: 'SANCTION',
99
+ ordinal: Number.isFinite(parsedOrdinal) ? parsedOrdinal : row.rowNumber - 1,
100
+ values: {
101
+ companyName: names.companyName,
102
+ aliases: names.aliases,
103
+ countryOrRegion: value(mapping, row.cells, 'countryOrRegion') || undefined,
104
+ sanctionReason: value(mapping, row.cells, 'sanctionReason') || undefined,
105
+ effectiveDate: normalizedDate ?? (rawDate || undefined)
106
+ },
107
+ evidence: [{ sourceLocation, sourceContent }],
108
+ signals: tableSection === 'Entities' && mapping.has('companyName')
109
+ ? ['STRUCTURED_SOURCE', 'HEADER_MAPPED', 'RECORD_START_EXPLICIT', 'COLUMN_LAYOUT_STABLE']
110
+ : ['STRUCTURED_SOURCE'],
111
+ warnings: []
112
+ };
113
+ const decision = classifyCandidate(candidate);
114
+ if (decision.autoPersist)
115
+ result.accepted.push(candidate);
116
+ else
117
+ result.reviewBlocks.push({
118
+ ordinal: candidate.ordinal,
119
+ kind: candidate.kind,
120
+ confidence: decision.confidence,
121
+ sourceLocation,
122
+ sourceContent,
123
+ payload: candidate.values,
124
+ reasons: decision.reasons
125
+ });
126
+ }
127
+ });
128
+ return result;
129
+ }
130
+ //# sourceMappingURL=docx.parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx.parser.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/docx.parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export type CatalogField = 'ordinal' | 'productName' | 'referenceProductName' | 'hsCodes' | 'controlCode' | 'controlDescription' | 'companyName' | 'countryOrRegion' | 'sanctionReason' | 'effectiveDate';
2
+ export declare function normalizeHeader(value: unknown): string;
3
+ export declare function mapCatalogHeaders(cells: unknown[]): Map<CatalogField, number>;
4
+ //# sourceMappingURL=header-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-mapping.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/header-mapping.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,aAAa,GACb,sBAAsB,GACtB,SAAS,GACT,aAAa,GACb,oBAAoB,GACpB,aAAa,GACb,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,CAAA;AAenB,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKtD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAa7E"}
@@ -0,0 +1,34 @@
1
+ const HEADER_ALIASES = {
2
+ ordinal: ['序号', '编号', 'no', 'number'],
3
+ productName: ['商品名称', '物项名称', '物项名称及描述', '产品名称', '品名', 'descriptionofgoods'],
4
+ referenceProductName: ['参考商品名称', '参考品名', 'referenceproductname'],
5
+ hsCodes: ['海关商品编号', '海关编码', '商品编码', 'hscode', 'commoditycode'],
6
+ controlCode: ['管制编码', '出口管制编码', 'controlcode', 'eccn'],
7
+ controlDescription: ['管制说明', '商品描述', '技术说明', 'description', '备注'],
8
+ companyName: ['企业名称', '公司名称', '实体名称', 'name'],
9
+ countryOrRegion: ['国家或地区', '国家地区', 'countryorregion', 'identifyinginformation'],
10
+ sanctionReason: ['制裁原因', '列名原因', 'reasons', 'reason'],
11
+ effectiveDate: ['生效日期', '列名日期', 'dateoflisting', 'effectivedate']
12
+ };
13
+ export function normalizeHeader(value) {
14
+ return String(value ?? '')
15
+ .normalize('NFKC')
16
+ .toLowerCase()
17
+ .replace(/[\s\p{P}\p{S}]+/gu, '');
18
+ }
19
+ export function mapCatalogHeaders(cells) {
20
+ const mapping = new Map();
21
+ cells.forEach((cell, index) => {
22
+ const normalized = normalizeHeader(cell);
23
+ if (!normalized)
24
+ return;
25
+ for (const [field, aliases] of Object.entries(HEADER_ALIASES)) {
26
+ if (!mapping.has(field) && aliases.some(alias => normalized === normalizeHeader(alias))) {
27
+ mapping.set(field, index);
28
+ break;
29
+ }
30
+ }
31
+ });
32
+ return mapping;
33
+ }
34
+ //# sourceMappingURL=header-mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header-mapping.js","sourceRoot":"","sources":["../../../src/lib/catalog-import/header-mapping.ts"],"names":[],"mappings":"AAYA,MAAM,cAAc,GAAmC;IACrD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC;IACrC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,CAAC;IAC5E,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,sBAAsB,CAAC;IAChE,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,CAAC;IAC9D,WAAW,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,CAAC;IACtD,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC;IACjE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAC7C,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,wBAAwB,CAAC;IAC/E,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;IACrD,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,CAAC;CAClE,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;SACvB,SAAS,CAAC,MAAM,CAAC;SACjB,WAAW,EAAE;SACb,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAgB;IAChD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAA;IAC/C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;QACxC,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,CAA+B,EAAE,CAAC;YAC5F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,KAAK,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBACxF,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;gBACzB,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAA;IACF,OAAO,OAAO,CAAA;AAChB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { CatalogParseResult } from './contracts.js';
2
+ import { type PdfCatalogSchema } from './pdf-table.normalizer.js';
3
+ export type PdfCatalogSection = 'IMPORT' | 'EXPORT';
4
+ export type PdfLayoutPage = {
5
+ pageNumber: number;
6
+ section?: PdfCatalogSection;
7
+ text?: string;
8
+ tables: string[][][];
9
+ };
10
+ export type PdfCatalogParseResult = CatalogParseResult & {
11
+ schemas: PdfCatalogSchema[];
12
+ };
13
+ export declare function parsePdfLayoutPages(pages: PdfLayoutPage[]): PdfCatalogParseResult;
14
+ export declare function parsePdfCatalog(buffer: Buffer | Uint8Array): Promise<PdfCatalogParseResult>;
15
+ //# sourceMappingURL=pdf-layout.parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-layout.parser.d.ts","sourceRoot":"","sources":["../../../src/lib/catalog-import/pdf-layout.parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAE1E,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAExG,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEnD,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,kBAAkB,GAAG;IACvD,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B,CAAA;AAiCD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,qBAAqB,CA0EjF;AAQD,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgBjG"}