@fin.cx/einvoice 5.0.2 → 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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/einvoice.d.ts +4 -8
- package/dist_ts/einvoice.js +46 -7
- package/dist_ts/formats/converters/xml-to-einvoice.converter.d.ts +21 -0
- package/dist_ts/formats/converters/xml-to-einvoice.converter.js +127 -0
- package/dist_ts/formats/semantic/bt-bg.model.d.ts +445 -0
- package/dist_ts/formats/semantic/bt-bg.model.js +12 -0
- package/dist_ts/formats/semantic/semantic.adapter.d.ts +87 -0
- package/dist_ts/formats/semantic/semantic.adapter.js +538 -0
- package/dist_ts/formats/semantic/semantic.validator.d.ts +48 -0
- package/dist_ts/formats/semantic/semantic.validator.js +596 -0
- package/dist_ts/formats/utils/currency.calculator.decimal.d.ts +98 -0
- package/dist_ts/formats/utils/currency.calculator.decimal.js +212 -0
- package/dist_ts/formats/utils/currency.utils.d.ts +99 -0
- package/dist_ts/formats/utils/currency.utils.js +250 -0
- package/dist_ts/formats/utils/decimal.d.ts +151 -0
- package/dist_ts/formats/utils/decimal.js +435 -0
- package/dist_ts/formats/validation/codelist.validator.d.ts +49 -0
- package/dist_ts/formats/validation/codelist.validator.js +188 -0
- package/dist_ts/formats/validation/conformance.harness.d.ts +99 -0
- package/dist_ts/formats/validation/conformance.harness.js +471 -0
- package/dist_ts/formats/validation/en16931.business-rules.validator.d.ts +58 -0
- package/dist_ts/formats/validation/en16931.business-rules.validator.js +459 -0
- package/dist_ts/formats/validation/facturx.validator.d.ts +75 -0
- package/dist_ts/formats/validation/facturx.validator.js +522 -0
- package/dist_ts/formats/validation/integrated.validator.d.ts +82 -0
- package/dist_ts/formats/validation/integrated.validator.js +311 -0
- package/dist_ts/formats/validation/peppol.validator.d.ts +77 -0
- package/dist_ts/formats/validation/peppol.validator.js +529 -0
- package/dist_ts/formats/validation/schematron.downloader.d.ts +71 -0
- package/dist_ts/formats/validation/schematron.downloader.js +254 -0
- package/dist_ts/formats/validation/schematron.integration.d.ts +60 -0
- package/dist_ts/formats/validation/schematron.integration.js +230 -0
- package/dist_ts/formats/validation/schematron.validator.d.ts +79 -0
- package/dist_ts/formats/validation/schematron.validator.js +288 -0
- package/dist_ts/formats/validation/schematron.worker.d.ts +50 -0
- package/dist_ts/formats/validation/schematron.worker.js +185 -0
- package/dist_ts/formats/validation/validation.types.d.ts +163 -0
- package/dist_ts/formats/validation/validation.types.js +181 -0
- package/dist_ts/formats/validation/vat-categories.validator.d.ts +87 -0
- package/dist_ts/formats/validation/vat-categories.validator.js +497 -0
- package/dist_ts/formats/validation/xrechnung.validator.d.ts +92 -0
- package/dist_ts/formats/validation/xrechnung.validator.js +417 -0
- package/dist_ts/interfaces/common.d.ts +1 -0
- package/dist_ts/interfaces/en16931-metadata.d.ts +83 -0
- package/dist_ts/interfaces/en16931-metadata.js +6 -0
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +7 -2
- package/dist_ts_install/download-schematron.d.ts +6 -0
- package/dist_ts_install/download-schematron.js +62 -0
- package/dist_ts_install/download-test-samples.d.ts +19 -0
- package/dist_ts_install/download-test-samples.js +169 -0
- package/dist_ts_install/download-xrechnung-rules.d.ts +7 -0
- package/dist_ts_install/download-xrechnung-rules.js +146 -0
- package/dist_ts_install/index.d.ts +8 -0
- package/dist_ts_install/index.js +246 -0
- package/package.json +13 -8
- package/readme.md +255 -810
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/einvoice.ts +63 -14
- package/ts/formats/converters/xml-to-einvoice.converter.ts +142 -0
- package/ts/formats/semantic/bt-bg.model.ts +524 -0
- package/ts/formats/semantic/semantic.adapter.ts +600 -0
- package/ts/formats/semantic/semantic.validator.ts +654 -0
- package/ts/formats/utils/currency.calculator.decimal.ts +323 -0
- package/ts/formats/utils/currency.utils.ts +299 -0
- package/ts/formats/utils/decimal.ts +509 -0
- package/ts/formats/validation/codelist.validator.ts +317 -0
- package/ts/formats/validation/conformance.harness.ts +591 -0
- package/ts/formats/validation/en16931.business-rules.validator.ts +694 -0
- package/ts/formats/validation/facturx.validator.ts +579 -0
- package/ts/formats/validation/integrated.validator.ts +405 -0
- package/ts/formats/validation/peppol.validator.ts +589 -0
- package/ts/formats/validation/schematron.downloader.ts +304 -0
- package/ts/formats/validation/schematron.integration.ts +285 -0
- package/ts/formats/validation/schematron.validator.ts +348 -0
- package/ts/formats/validation/schematron.worker.ts +221 -0
- package/ts/formats/validation/validation.types.ts +274 -0
- package/ts/formats/validation/vat-categories.validator.ts +845 -0
- package/ts/formats/validation/xrechnung.validator.ts +494 -0
- package/ts/interfaces/common.ts +1 -0
- package/ts/interfaces/en16931-metadata.ts +104 -0
- package/ts/plugins.ts +8 -0
- package/ts/tspublish.json +3 -0
- package/dist_ts/classes.decoder.d.ts +0 -40
- package/dist_ts/classes.decoder.js +0 -320
- package/dist_ts/classes.encoder.d.ts +0 -51
- package/dist_ts/classes.encoder.js +0 -293
- package/dist_ts/classes.xinvoice.d.ts +0 -136
- package/dist_ts/classes.xinvoice.js +0 -352
- package/dist_ts/formats/base.decoder.d.ts +0 -19
- package/dist_ts/formats/base.decoder.js +0 -130
- package/dist_ts/formats/base.validator.d.ts +0 -44
- package/dist_ts/formats/base.validator.js +0 -39
- package/dist_ts/formats/decoder.factory.d.ts +0 -15
- package/dist_ts/formats/decoder.factory.js +0 -46
- package/dist_ts/formats/factorx.decoder.d.ts +0 -18
- package/dist_ts/formats/factorx.decoder.js +0 -178
- package/dist_ts/formats/factorx.encoder.d.ts +0 -51
- package/dist_ts/formats/factorx.encoder.js +0 -293
- package/dist_ts/formats/facturx.decoder.d.ts +0 -18
- package/dist_ts/formats/facturx.decoder.js +0 -210
- package/dist_ts/formats/facturx.encoder.d.ts +0 -51
- package/dist_ts/formats/facturx.encoder.js +0 -293
- package/dist_ts/formats/facturx.validator.d.ts +0 -67
- package/dist_ts/formats/facturx.validator.js +0 -266
- package/dist_ts/formats/pdf/robust-pdf.extractor.d.ts +0 -40
- package/dist_ts/formats/pdf/robust-pdf.extractor.js +0 -324
- package/dist_ts/formats/ubl.validator.d.ts +0 -82
- package/dist_ts/formats/ubl.validator.js +0 -306
- package/dist_ts/formats/validator.factory.d.ts +0 -18
- package/dist_ts/formats/validator.factory.js +0 -78
- package/dist_ts/formats/xinvoice.decoder.d.ts +0 -28
- package/dist_ts/formats/xinvoice.decoder.js +0 -332
- package/dist_ts/formats/xinvoice.encoder.d.ts +0 -19
- 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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
|