@fin.cx/einvoice 5.0.3 → 5.1.2

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 (116) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/einvoice.d.ts +4 -8
  3. package/dist_ts/einvoice.js +46 -7
  4. package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +21 -0
  5. package/dist_ts/formats/converters/xml-to-einvoice.converter.js +127 -0
  6. package/dist_ts/formats/semantic/bt-bg.model.d.ts +445 -0
  7. package/dist_ts/formats/semantic/bt-bg.model.js +12 -0
  8. package/dist_ts/formats/semantic/semantic.adapter.d.ts +87 -0
  9. package/dist_ts/formats/semantic/semantic.adapter.js +538 -0
  10. package/dist_ts/formats/semantic/semantic.validator.d.ts +48 -0
  11. package/dist_ts/formats/semantic/semantic.validator.js +596 -0
  12. package/dist_ts/formats/utils/currency.calculator.decimal.d.ts +98 -0
  13. package/dist_ts/formats/utils/currency.calculator.decimal.js +212 -0
  14. package/dist_ts/formats/utils/currency.utils.d.ts +99 -0
  15. package/dist_ts/formats/utils/currency.utils.js +250 -0
  16. package/dist_ts/formats/utils/decimal.d.ts +151 -0
  17. package/dist_ts/formats/utils/decimal.js +435 -0
  18. package/dist_ts/formats/validation/codelist.validator.d.ts +49 -0
  19. package/dist_ts/formats/validation/codelist.validator.js +188 -0
  20. package/dist_ts/formats/validation/conformance.harness.d.ts +99 -0
  21. package/dist_ts/formats/validation/conformance.harness.js +471 -0
  22. package/dist_ts/formats/validation/en16931.business-rules.validator.d.ts +58 -0
  23. package/dist_ts/formats/validation/en16931.business-rules.validator.js +459 -0
  24. package/dist_ts/formats/validation/facturx.validator.d.ts +75 -0
  25. package/dist_ts/formats/validation/facturx.validator.js +522 -0
  26. package/dist_ts/formats/validation/integrated.validator.d.ts +82 -0
  27. package/dist_ts/formats/validation/integrated.validator.js +311 -0
  28. package/dist_ts/formats/validation/peppol.validator.d.ts +77 -0
  29. package/dist_ts/formats/validation/peppol.validator.js +529 -0
  30. package/dist_ts/formats/validation/schematron.downloader.d.ts +71 -0
  31. package/dist_ts/formats/validation/schematron.downloader.js +254 -0
  32. package/dist_ts/formats/validation/schematron.integration.d.ts +60 -0
  33. package/dist_ts/formats/validation/schematron.integration.js +230 -0
  34. package/dist_ts/formats/validation/schematron.validator.d.ts +79 -0
  35. package/dist_ts/formats/validation/schematron.validator.js +288 -0
  36. package/dist_ts/formats/validation/schematron.worker.d.ts +50 -0
  37. package/dist_ts/formats/validation/schematron.worker.js +185 -0
  38. package/dist_ts/formats/validation/validation.types.d.ts +163 -0
  39. package/dist_ts/formats/validation/validation.types.js +181 -0
  40. package/dist_ts/formats/validation/vat-categories.validator.d.ts +87 -0
  41. package/dist_ts/formats/validation/vat-categories.validator.js +497 -0
  42. package/dist_ts/formats/validation/xrechnung.validator.d.ts +92 -0
  43. package/dist_ts/formats/validation/xrechnung.validator.js +417 -0
  44. package/dist_ts/interfaces/common.d.ts +1 -0
  45. package/dist_ts/interfaces/en16931-metadata.d.ts +83 -0
  46. package/dist_ts/interfaces/en16931-metadata.js +6 -0
  47. package/dist_ts/plugins.d.ts +3 -1
  48. package/dist_ts/plugins.js +7 -2
  49. package/dist_ts_install/download-schematron.d.ts +6 -0
  50. package/dist_ts_install/download-schematron.js +62 -0
  51. package/dist_ts_install/download-test-samples.d.ts +19 -0
  52. package/dist_ts_install/download-test-samples.js +169 -0
  53. package/dist_ts_install/download-xrechnung-rules.d.ts +7 -0
  54. package/dist_ts_install/download-xrechnung-rules.js +146 -0
  55. package/dist_ts_install/index.d.ts +8 -0
  56. package/dist_ts_install/index.js +246 -0
  57. package/package.json +9 -3
  58. package/readme.md +255 -810
  59. package/ts/00_commitinfo_data.ts +1 -1
  60. package/ts/einvoice.ts +63 -14
  61. package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
  62. package/ts/formats/semantic/bt-bg.model.ts +524 -0
  63. package/ts/formats/semantic/semantic.adapter.ts +600 -0
  64. package/ts/formats/semantic/semantic.validator.ts +654 -0
  65. package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
  66. package/ts/formats/utils/currency.utils.ts +299 -0
  67. package/ts/formats/utils/decimal.ts +509 -0
  68. package/ts/formats/validation/codelist.validator.ts +317 -0
  69. package/ts/formats/validation/conformance.harness.ts +591 -0
  70. package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
  71. package/ts/formats/validation/facturx.validator.ts +579 -0
  72. package/ts/formats/validation/integrated.validator.ts +405 -0
  73. package/ts/formats/validation/peppol.validator.ts +589 -0
  74. package/ts/formats/validation/schematron.downloader.ts +304 -0
  75. package/ts/formats/validation/schematron.integration.ts +285 -0
  76. package/ts/formats/validation/schematron.validator.ts +348 -0
  77. package/ts/formats/validation/schematron.worker.ts +221 -0
  78. package/ts/formats/validation/validation.types.ts +274 -0
  79. package/ts/formats/validation/vat-categories.validator.ts +845 -0
  80. package/ts/formats/validation/xrechnung.validator.ts +494 -0
  81. package/ts/interfaces/common.ts +1 -0
  82. package/ts/interfaces/en16931-metadata.ts +104 -0
  83. package/ts/plugins.ts +8 -0
  84. package/ts/tspublish.json +3 -0
  85. package/dist_ts/classes.decoder.d.ts +0 -40
  86. package/dist_ts/classes.decoder.js +0 -320
  87. package/dist_ts/classes.encoder.d.ts +0 -51
  88. package/dist_ts/classes.encoder.js +0 -293
  89. package/dist_ts/classes.xinvoice.d.ts +0 -136
  90. package/dist_ts/classes.xinvoice.js +0 -352
  91. package/dist_ts/formats/base.decoder.d.ts +0 -19
  92. package/dist_ts/formats/base.decoder.js +0 -130
  93. package/dist_ts/formats/base.validator.d.ts +0 -44
  94. package/dist_ts/formats/base.validator.js +0 -39
  95. package/dist_ts/formats/decoder.factory.d.ts +0 -15
  96. package/dist_ts/formats/decoder.factory.js +0 -46
  97. package/dist_ts/formats/factorx.decoder.d.ts +0 -18
  98. package/dist_ts/formats/factorx.decoder.js +0 -178
  99. package/dist_ts/formats/factorx.encoder.d.ts +0 -51
  100. package/dist_ts/formats/factorx.encoder.js +0 -293
  101. package/dist_ts/formats/facturx.decoder.d.ts +0 -18
  102. package/dist_ts/formats/facturx.decoder.js +0 -210
  103. package/dist_ts/formats/facturx.encoder.d.ts +0 -51
  104. package/dist_ts/formats/facturx.encoder.js +0 -293
  105. package/dist_ts/formats/facturx.validator.d.ts +0 -67
  106. package/dist_ts/formats/facturx.validator.js +0 -266
  107. package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
  108. package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
  109. package/dist_ts/formats/ubl.validator.d.ts +0 -82
  110. package/dist_ts/formats/ubl.validator.js +0 -306
  111. package/dist_ts/formats/validator.factory.d.ts +0 -18
  112. package/dist_ts/formats/validator.factory.js +0 -78
  113. package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
  114. package/dist_ts/formats/xinvoice.decoder.js +0 -332
  115. package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
  116. package/dist_ts/formats/xinvoice.encoder.js +0 -282
@@ -0,0 +1,288 @@
1
+ import * as plugins from '../../plugins.js';
2
+ import * as SaxonJS from 'saxon-js';
3
+ /**
4
+ * Schematron validation engine using Saxon-JS
5
+ * Provides official standards validation through Schematron rules
6
+ */
7
+ export class SchematronValidator {
8
+ constructor(schematronRules) {
9
+ this.isCompiled = false;
10
+ this.schematronRules = schematronRules || '';
11
+ }
12
+ /**
13
+ * Load Schematron rules from file or string
14
+ */
15
+ async loadSchematron(source, isFilePath = true) {
16
+ if (isFilePath) {
17
+ // Load from file
18
+ const smartfile = await import('@push.rocks/smartfile');
19
+ this.schematronRules = await smartfile.SmartFile.fromFilePath(source).then(f => f.contentBuffer.toString());
20
+ }
21
+ else {
22
+ // Use provided string
23
+ this.schematronRules = source;
24
+ }
25
+ // Reset compilation state
26
+ this.isCompiled = false;
27
+ }
28
+ /**
29
+ * Compile Schematron to XSLT using ISO Schematron skeleton
30
+ */
31
+ async compileSchematron() {
32
+ if (this.isCompiled)
33
+ return;
34
+ // The Schematron to XSLT transformation requires the ISO Schematron skeleton
35
+ // For now, we'll use a simplified approach with direct XSLT generation
36
+ // In production, we would use the official ISO Schematron skeleton XSLTs
37
+ try {
38
+ // Convert Schematron to XSLT
39
+ // This is a simplified version - in production we'd use the full ISO skeleton
40
+ const xslt = this.generateXSLTFromSchematron(this.schematronRules);
41
+ // Compile the XSLT with Saxon-JS
42
+ this.compiledStylesheet = await SaxonJS.compile({
43
+ stylesheetText: xslt,
44
+ warnings: 'silent'
45
+ });
46
+ this.isCompiled = true;
47
+ }
48
+ catch (error) {
49
+ throw new Error(`Failed to compile Schematron: ${error.message}`);
50
+ }
51
+ }
52
+ /**
53
+ * Validate an XML document against loaded Schematron rules
54
+ */
55
+ async validate(xmlContent, options = {}) {
56
+ if (!this.schematronRules) {
57
+ throw new Error('No Schematron rules loaded');
58
+ }
59
+ // Ensure Schematron is compiled
60
+ await this.compileSchematron();
61
+ const results = [];
62
+ try {
63
+ // Transform the XML with the compiled Schematron XSLT
64
+ const transformResult = await SaxonJS.transform({
65
+ stylesheetInternal: this.compiledStylesheet,
66
+ sourceText: xmlContent,
67
+ destination: 'serialized',
68
+ stylesheetParams: options.parameters || {}
69
+ });
70
+ // Parse the SVRL (Schematron Validation Report Language) output
71
+ results.push(...this.parseSVRL(transformResult.principalResult));
72
+ // Apply options filters
73
+ if (!options.includeWarnings) {
74
+ return results.filter(r => r.severity !== 'warning');
75
+ }
76
+ if (options.maxErrors && results.filter(r => r.severity === 'error').length > options.maxErrors) {
77
+ return results.slice(0, options.maxErrors);
78
+ }
79
+ return results;
80
+ }
81
+ catch (error) {
82
+ results.push({
83
+ ruleId: 'SCHEMATRON-ERROR',
84
+ source: 'SCHEMATRON',
85
+ severity: 'error',
86
+ message: `Schematron validation failed: ${error.message}`,
87
+ btReference: undefined,
88
+ bgReference: undefined
89
+ });
90
+ return results;
91
+ }
92
+ }
93
+ /**
94
+ * Parse SVRL output to ValidationResult array
95
+ */
96
+ parseSVRL(svrlXml) {
97
+ const results = [];
98
+ // Parse SVRL XML
99
+ const parser = new plugins.xmldom.DOMParser();
100
+ const doc = parser.parseFromString(svrlXml, 'text/xml');
101
+ // Get all failed assertions and successful reports
102
+ const failedAsserts = doc.getElementsByTagName('svrl:failed-assert');
103
+ const successfulReports = doc.getElementsByTagName('svrl:successful-report');
104
+ // Process failed assertions (these are errors)
105
+ for (let i = 0; i < failedAsserts.length; i++) {
106
+ const assert = failedAsserts[i];
107
+ const result = this.extractValidationResult(assert, 'error');
108
+ if (result)
109
+ results.push(result);
110
+ }
111
+ // Process successful reports (these can be warnings or info)
112
+ for (let i = 0; i < successfulReports.length; i++) {
113
+ const report = successfulReports[i];
114
+ const result = this.extractValidationResult(report, 'warning');
115
+ if (result)
116
+ results.push(result);
117
+ }
118
+ return results;
119
+ }
120
+ /**
121
+ * Extract ValidationResult from SVRL element
122
+ */
123
+ extractValidationResult(element, defaultSeverity) {
124
+ const text = element.getElementsByTagName('svrl:text')[0]?.textContent || '';
125
+ const location = element.getAttribute('location') || undefined;
126
+ const test = element.getAttribute('test') || '';
127
+ const id = element.getAttribute('id') || element.getAttribute('role') || 'UNKNOWN';
128
+ const flag = element.getAttribute('flag') || defaultSeverity;
129
+ // Determine severity from flag attribute
130
+ let severity = defaultSeverity;
131
+ if (flag.toLowerCase().includes('fatal') || flag.toLowerCase().includes('error')) {
132
+ severity = 'error';
133
+ }
134
+ else if (flag.toLowerCase().includes('warning')) {
135
+ severity = 'warning';
136
+ }
137
+ else if (flag.toLowerCase().includes('info')) {
138
+ severity = 'info';
139
+ }
140
+ // Extract BT/BG references if present
141
+ const btMatch = text.match(/\[BT-(\d+)\]/);
142
+ const bgMatch = text.match(/\[BG-(\d+)\]/);
143
+ return {
144
+ ruleId: id,
145
+ source: 'EN16931',
146
+ severity,
147
+ message: text,
148
+ syntaxPath: location,
149
+ btReference: btMatch ? `BT-${btMatch[1]}` : undefined,
150
+ bgReference: bgMatch ? `BG-${bgMatch[1]}` : undefined,
151
+ profile: 'EN16931'
152
+ };
153
+ }
154
+ /**
155
+ * Generate simplified XSLT from Schematron
156
+ * This is a placeholder - in production, use ISO Schematron skeleton
157
+ */
158
+ generateXSLTFromSchematron(schematron) {
159
+ // This is a simplified transformation
160
+ // In production, we would use the official ISO Schematron skeleton XSLTs
161
+ // (iso_schematron_skeleton.xsl, iso_svrl_for_xslt2.xsl, etc.)
162
+ // For now, return a basic XSLT that creates SVRL output
163
+ return `<?xml version="1.0" encoding="UTF-8"?>
164
+ <xsl:stylesheet version="3.0"
165
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
166
+ xmlns:svrl="http://purl.oclc.org/dsdl/svrl">
167
+
168
+ <xsl:output method="xml" indent="yes"/>
169
+
170
+ <xsl:template match="/">
171
+ <svrl:schematron-output>
172
+ <!-- This is a placeholder transformation -->
173
+ <!-- Real implementation would process Schematron patterns and rules -->
174
+ <svrl:active-pattern>
175
+ <xsl:attribute name="document">
176
+ <xsl:value-of select="base-uri(/)"/>
177
+ </xsl:attribute>
178
+ </svrl:active-pattern>
179
+ </svrl:schematron-output>
180
+ </xsl:template>
181
+ </xsl:stylesheet>`;
182
+ }
183
+ /**
184
+ * Check if validator has rules loaded
185
+ */
186
+ hasRules() {
187
+ return !!this.schematronRules;
188
+ }
189
+ /**
190
+ * Get list of available phases from Schematron
191
+ */
192
+ async getPhases() {
193
+ if (!this.schematronRules)
194
+ return [];
195
+ const parser = new plugins.xmldom.DOMParser();
196
+ const doc = parser.parseFromString(this.schematronRules, 'text/xml');
197
+ const phases = doc.getElementsByTagName('sch:phase');
198
+ const phaseNames = [];
199
+ for (let i = 0; i < phases.length; i++) {
200
+ const id = phases[i].getAttribute('id');
201
+ if (id)
202
+ phaseNames.push(id);
203
+ }
204
+ return phaseNames;
205
+ }
206
+ /**
207
+ * Validate with specific phase activated
208
+ */
209
+ async validateWithPhase(xmlContent, phase, options = {}) {
210
+ return this.validate(xmlContent, { ...options, phase });
211
+ }
212
+ }
213
+ /**
214
+ * Factory function to create validator with standard Schematron packs
215
+ */
216
+ export async function createStandardValidator(standard) {
217
+ const validator = new SchematronValidator();
218
+ // Load appropriate Schematron based on standard
219
+ // These paths would point to actual Schematron files in production
220
+ switch (standard) {
221
+ case 'EN16931':
222
+ // Would load from ConnectingEurope/eInvoicing-EN16931
223
+ await validator.loadSchematron('assets_downloaded/schematron/en16931/EN16931-UBL-validation.sch');
224
+ break;
225
+ case 'XRECHNUNG':
226
+ // Would load from itplr-kosit/xrechnung-schematron
227
+ await validator.loadSchematron('assets_downloaded/schematron/xrechnung/XRechnung-UBL-validation.sch');
228
+ break;
229
+ case 'PEPPOL':
230
+ // Would load from OpenPEPPOL/peppol-bis-invoice-3
231
+ await validator.loadSchematron('assets_downloaded/schematron/peppol/PEPPOL-EN16931-UBL.sch');
232
+ break;
233
+ case 'FACTURX':
234
+ // Would load from Factur-X specific Schematron
235
+ await validator.loadSchematron('assets_downloaded/schematron/facturx/Factur-X-EN16931-validation.sch');
236
+ break;
237
+ }
238
+ return validator;
239
+ }
240
+ /**
241
+ * Hybrid validator that combines TypeScript and Schematron validation
242
+ */
243
+ export class HybridValidator {
244
+ constructor(schematronValidator) {
245
+ this.tsValidators = [];
246
+ this.schematronValidator = schematronValidator || new SchematronValidator();
247
+ }
248
+ /**
249
+ * Add a TypeScript validator to the pipeline
250
+ */
251
+ addTSValidator(validator) {
252
+ this.tsValidators.push(validator);
253
+ }
254
+ /**
255
+ * Run all validators and merge results
256
+ */
257
+ async validate(xmlContent, options = {}) {
258
+ const results = [];
259
+ // Run TypeScript validators first (faster, better UX)
260
+ for (const validator of this.tsValidators) {
261
+ try {
262
+ results.push(...validator.validate(xmlContent));
263
+ }
264
+ catch (error) {
265
+ console.warn(`TS validator failed: ${error.message}`);
266
+ }
267
+ }
268
+ // Run Schematron validation if available
269
+ if (this.schematronValidator.hasRules()) {
270
+ try {
271
+ const schematronResults = await this.schematronValidator.validate(xmlContent, options);
272
+ results.push(...schematronResults);
273
+ }
274
+ catch (error) {
275
+ console.warn(`Schematron validation failed: ${error.message}`);
276
+ }
277
+ }
278
+ // Deduplicate results by ruleId
279
+ const seen = new Set();
280
+ return results.filter(r => {
281
+ if (seen.has(r.ruleId))
282
+ return false;
283
+ seen.add(r.ruleId);
284
+ return true;
285
+ });
286
+ }
287
+ }
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hdHJvbi52YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9mb3JtYXRzL3ZhbGlkYXRpb24vc2NoZW1hdHJvbi52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssT0FBTyxNQUFNLFVBQVUsQ0FBQztBQWFwQzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBSzlCLFlBQVksZUFBd0I7UUFGNUIsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUdsQyxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsSUFBSSxFQUFFLENBQUM7SUFDL0MsQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFjLEVBQUUsYUFBc0IsSUFBSTtRQUNwRSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2YsaUJBQWlCO1lBQ2pCLE1BQU0sU0FBUyxHQUFHLE1BQU0sTUFBTSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDeEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLFNBQVMsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUM5RyxDQUFDO2FBQU0sQ0FBQztZQUNOLHNCQUFzQjtZQUN0QixJQUFJLENBQUMsZUFBZSxHQUFHLE1BQU0sQ0FBQztRQUNoQyxDQUFDO1FBRUQsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7SUFFRDs7T0FFRztJQUNLLEtBQUssQ0FBQyxpQkFBaUI7UUFDN0IsSUFBSSxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFFNUIsNkVBQTZFO1FBQzdFLHVFQUF1RTtRQUN2RSx5RUFB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
@@ -0,0 +1,50 @@
1
+ import type { ValidationResult } from './validation.types.js';
2
+ import type { SchematronOptions } from './schematron.validator.js';
3
+ /**
4
+ * Worker pool for Schematron validation
5
+ * Provides non-blocking validation in worker threads
6
+ */
7
+ export declare class SchematronWorkerPool {
8
+ private workers;
9
+ private availableWorkers;
10
+ private taskQueue;
11
+ private maxWorkers;
12
+ private schematronRules;
13
+ constructor(maxWorkers?: number);
14
+ /**
15
+ * Initialize worker pool
16
+ */
17
+ initialize(schematronRules: string): Promise<void>;
18
+ /**
19
+ * Create a new worker
20
+ */
21
+ private createWorker;
22
+ /**
23
+ * Validate XML using worker pool
24
+ */
25
+ validate(xmlContent: string, options?: SchematronOptions): Promise<ValidationResult[]>;
26
+ /**
27
+ * Process queued validation tasks
28
+ */
29
+ private processTasks;
30
+ /**
31
+ * Parse SVRL output
32
+ */
33
+ private parseSVRL;
34
+ /**
35
+ * Generate XSLT from Schematron (simplified)
36
+ */
37
+ private generateXSLTFromSchematron;
38
+ /**
39
+ * Terminate all workers
40
+ */
41
+ terminate(): Promise<void>;
42
+ /**
43
+ * Get pool statistics
44
+ */
45
+ getStats(): {
46
+ totalWorkers: number;
47
+ availableWorkers: number;
48
+ queuedTasks: number;
49
+ };
50
+ }
@@ -0,0 +1,185 @@
1
+ import { Worker } from 'worker_threads';
2
+ import * as path from 'path';
3
+ /**
4
+ * Worker pool for Schematron validation
5
+ * Provides non-blocking validation in worker threads
6
+ */
7
+ export class SchematronWorkerPool {
8
+ constructor(maxWorkers = 4) {
9
+ this.workers = [];
10
+ this.availableWorkers = [];
11
+ this.taskQueue = [];
12
+ this.schematronRules = '';
13
+ this.maxWorkers = maxWorkers;
14
+ }
15
+ /**
16
+ * Initialize worker pool
17
+ */
18
+ async initialize(schematronRules) {
19
+ this.schematronRules = schematronRules;
20
+ // Create workers
21
+ for (let i = 0; i < this.maxWorkers; i++) {
22
+ await this.createWorker();
23
+ }
24
+ }
25
+ /**
26
+ * Create a new worker
27
+ */
28
+ async createWorker() {
29
+ const workerPath = path.join(import.meta.url, 'schematron.worker.impl.js');
30
+ const worker = new Worker(`
31
+ const { parentPort } = require('worker_threads');
32
+ const SaxonJS = require('saxon-js');
33
+
34
+ let compiledStylesheet = null;
35
+
36
+ parentPort.on('message', async (msg) => {
37
+ try {
38
+ if (msg.type === 'init') {
39
+ // Compile Schematron to XSLT
40
+ compiledStylesheet = await SaxonJS.compile({
41
+ stylesheetText: msg.xslt,
42
+ warnings: 'silent'
43
+ });
44
+ parentPort.postMessage({ type: 'ready' });
45
+ } else if (msg.type === 'validate') {
46
+ if (!compiledStylesheet) {
47
+ throw new Error('Worker not initialized');
48
+ }
49
+
50
+ // Transform XML with compiled Schematron
51
+ const result = await SaxonJS.transform({
52
+ stylesheetInternal: compiledStylesheet,
53
+ sourceText: msg.xmlContent,
54
+ destination: 'serialized',
55
+ stylesheetParams: msg.options.parameters || {}
56
+ });
57
+
58
+ parentPort.postMessage({
59
+ type: 'result',
60
+ svrl: result.principalResult
61
+ });
62
+ }
63
+ } catch (error) {
64
+ parentPort.postMessage({
65
+ type: 'error',
66
+ error: error.message
67
+ });
68
+ }
69
+ });
70
+ `, { eval: true });
71
+ // Initialize worker with Schematron rules
72
+ await new Promise((resolve, reject) => {
73
+ worker.once('message', (msg) => {
74
+ if (msg.type === 'ready') {
75
+ resolve();
76
+ }
77
+ else if (msg.type === 'error') {
78
+ reject(new Error(msg.error));
79
+ }
80
+ });
81
+ // Send initialization message
82
+ worker.postMessage({
83
+ type: 'init',
84
+ xslt: this.generateXSLTFromSchematron(this.schematronRules)
85
+ });
86
+ });
87
+ this.workers.push(worker);
88
+ this.availableWorkers.push(worker);
89
+ }
90
+ /**
91
+ * Validate XML using worker pool
92
+ */
93
+ async validate(xmlContent, options = {}) {
94
+ return new Promise((resolve, reject) => {
95
+ // Add task to queue
96
+ this.taskQueue.push({ xmlContent, options, resolve, reject });
97
+ this.processTasks();
98
+ });
99
+ }
100
+ /**
101
+ * Process queued validation tasks
102
+ */
103
+ processTasks() {
104
+ while (this.taskQueue.length > 0 && this.availableWorkers.length > 0) {
105
+ const task = this.taskQueue.shift();
106
+ const worker = this.availableWorkers.shift();
107
+ // Set up one-time listeners
108
+ const messageHandler = (msg) => {
109
+ if (msg.type === 'result') {
110
+ // Parse SVRL and return results
111
+ const results = this.parseSVRL(msg.svrl);
112
+ task.resolve(results);
113
+ // Return worker to pool
114
+ this.availableWorkers.push(worker);
115
+ worker.removeListener('message', messageHandler);
116
+ // Process next task
117
+ this.processTasks();
118
+ }
119
+ else if (msg.type === 'error') {
120
+ task.reject(new Error(msg.error));
121
+ // Return worker to pool
122
+ this.availableWorkers.push(worker);
123
+ worker.removeListener('message', messageHandler);
124
+ // Process next task
125
+ this.processTasks();
126
+ }
127
+ };
128
+ worker.on('message', messageHandler);
129
+ // Send validation task
130
+ worker.postMessage({
131
+ type: 'validate',
132
+ xmlContent: task.xmlContent,
133
+ options: task.options
134
+ });
135
+ }
136
+ }
137
+ /**
138
+ * Parse SVRL output
139
+ */
140
+ parseSVRL(svrlXml) {
141
+ const results = [];
142
+ // This would use the same parsing logic as SchematronValidator
143
+ // Simplified for brevity
144
+ return results;
145
+ }
146
+ /**
147
+ * Generate XSLT from Schematron (simplified)
148
+ */
149
+ generateXSLTFromSchematron(schematron) {
150
+ // Simplified - would use ISO Schematron skeleton in production
151
+ return `<?xml version="1.0" encoding="UTF-8"?>
152
+ <xsl:stylesheet version="3.0"
153
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
154
+ xmlns:svrl="http://purl.oclc.org/dsdl/svrl">
155
+
156
+ <xsl:output method="xml" indent="yes"/>
157
+
158
+ <xsl:template match="/">
159
+ <svrl:schematron-output>
160
+ <svrl:active-pattern document="{base-uri(/)}"/>
161
+ </svrl:schematron-output>
162
+ </xsl:template>
163
+ </xsl:stylesheet>`;
164
+ }
165
+ /**
166
+ * Terminate all workers
167
+ */
168
+ async terminate() {
169
+ await Promise.all(this.workers.map(w => w.terminate()));
170
+ this.workers = [];
171
+ this.availableWorkers = [];
172
+ this.taskQueue = [];
173
+ }
174
+ /**
175
+ * Get pool statistics
176
+ */
177
+ getStats() {
178
+ return {
179
+ totalWorkers: this.workers.length,
180
+ availableWorkers: this.availableWorkers.length,
181
+ queuedTasks: this.taskQueue.length
182
+ };
183
+ }
184
+ }
185
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hdHJvbi53b3JrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9mb3JtYXRzL3ZhbGlkYXRpb24vc2NoZW1hdHJvbi53b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBSTdCOzs7R0FHRztBQUNILE1BQU0sT0FBTyxvQkFBb0I7SUFZL0IsWUFBWSxhQUFxQixDQUFDO1FBWDFCLFlBQU8sR0FBYSxFQUFFLENBQUM7UUFDdkIscUJBQWdCLEdBQWEsRUFBRSxDQUFDO1FBQ2hDLGNBQVMsR0FLWixFQUFFLENBQUM7UUFFQSxvQkFBZSxHQUFXLEVBQUUsQ0FBQztRQUduQyxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsVUFBVSxDQUFDLGVBQXVCO1FBQzdDLElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFDO1FBRXZDLGlCQUFpQjtRQUNqQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxLQUFLLENBQUMsWUFBWTtRQUN4QixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLDJCQUEyQixDQUFDLENBQUM7UUFFM0UsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0F3Q3pCLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFF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