@fin.cx/einvoice 6.2.0 → 7.0.1
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.js +3 -2
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.d.ts +7 -0
- package/dist_ts/formats/ubl/xrechnung/xrechnung.encoder.js +19 -3
- package/dist_ts/formats/validation/conformance.harness.js +1 -1
- package/dist_ts/formats/validation/schematron.downloader.d.ts +43 -15
- package/dist_ts/formats/validation/schematron.downloader.js +122 -77
- package/dist_ts/formats/validation/schematron.integration.d.ts +5 -1
- package/dist_ts/formats/validation/schematron.integration.js +16 -40
- package/dist_ts/formats/validation/schematron.validator.d.ts +35 -15
- package/dist_ts/formats/validation/schematron.validator.js +136 -138
- package/dist_ts/formats/validation/schematron.worker.d.ts +12 -9
- package/dist_ts/formats/validation/schematron.worker.js +148 -108
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +7 -2
- package/dist_ts_install/download-schematron.js +6 -3
- package/dist_ts_install/index.js +15 -11
- package/package.json +6 -8
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/einvoice.ts +2 -1
- package/ts/formats/ubl/xrechnung/xrechnung.encoder.ts +19 -2
- package/ts/formats/validation/conformance.harness.ts +1 -1
- package/ts/formats/validation/schematron.downloader.ts +146 -97
- package/ts/formats/validation/schematron.integration.ts +18 -44
- package/ts/formats/validation/schematron.validator.ts +181 -181
- package/ts/formats/validation/schematron.worker.ts +191 -135
- package/ts/plugins.ts +8 -0
- package/ts/vendor/modules.d.ts +0 -19
- package/dist_ts/vendor/saxonjs.d.ts +0 -23
- package/dist_ts/vendor/saxonjs.js +0 -9
- package/readme.hints.md +0 -1134
- package/readme.howtofixtests.md +0 -38
- package/readme.literature.md +0 -1
- package/readme.plan.md +0 -497
- package/ts/vendor/saxonjs.ts +0 -36
|
@@ -1,11 +1,69 @@
|
|
|
1
1
|
import { Worker } from 'worker_threads';
|
|
2
|
+
import { promises as fs } from 'fs';
|
|
2
3
|
import type { ValidationResult } from './validation.types.js';
|
|
3
|
-
import
|
|
4
|
+
import {
|
|
5
|
+
applySchematronOptions,
|
|
6
|
+
schematronReportToValidationResults,
|
|
7
|
+
type SchematronOptions,
|
|
8
|
+
} from './schematron.validator.js';
|
|
4
9
|
|
|
5
10
|
export interface ISchematronWorkerPoolInitializeOptions {
|
|
6
11
|
isFilePath?: boolean;
|
|
7
12
|
}
|
|
8
13
|
|
|
14
|
+
/**
|
|
15
|
+
* The worker body. It compiles the schema once and then answers validation
|
|
16
|
+
* messages with the report, which the pool maps exactly like the in-process
|
|
17
|
+
* validator does.
|
|
18
|
+
*
|
|
19
|
+
* The engine is imported from the URL the pool resolves, because an eval'd worker
|
|
20
|
+
* resolves a bare specifier against the working directory rather than this package.
|
|
21
|
+
*/
|
|
22
|
+
const WORKER_SOURCE = `
|
|
23
|
+
const { parentPort } = require('worker_threads');
|
|
24
|
+
const { readFileSync } = require('fs');
|
|
25
|
+
const { dirname, resolve } = require('path');
|
|
26
|
+
|
|
27
|
+
let source = null;
|
|
28
|
+
const schemasByPhase = new Map();
|
|
29
|
+
|
|
30
|
+
const compile = async (phase) => {
|
|
31
|
+
const key = phase || '';
|
|
32
|
+
if (!schemasByPhase.has(key)) {
|
|
33
|
+
const { Schematron } = await import(source.engineUrl);
|
|
34
|
+
schemasByPhase.set(key, Schematron.fromString(source.schematronSource, {
|
|
35
|
+
phase: phase || undefined,
|
|
36
|
+
baseUri: source.baseUri || undefined,
|
|
37
|
+
resolveInclude: (href, base) =>
|
|
38
|
+
readFileSync(resolve(dirname(base || source.baseUri || '.'), href), 'utf-8'),
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
return schemasByPhase.get(key);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
parentPort.on('message', async (msg) => {
|
|
45
|
+
try {
|
|
46
|
+
if (msg.type === 'init') {
|
|
47
|
+
source = {
|
|
48
|
+
schematronSource: msg.schematronSource,
|
|
49
|
+
baseUri: msg.baseUri,
|
|
50
|
+
engineUrl: msg.engineUrl,
|
|
51
|
+
};
|
|
52
|
+
await compile(undefined);
|
|
53
|
+
parentPort.postMessage({ type: 'ready' });
|
|
54
|
+
} else if (msg.type === 'validate') {
|
|
55
|
+
if (!source) {
|
|
56
|
+
throw new Error('Worker not initialized');
|
|
57
|
+
}
|
|
58
|
+
const schema = await compile(msg.options.phase);
|
|
59
|
+
parentPort.postMessage({ type: 'result', report: schema.validate(msg.xmlContent) });
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
parentPort.postMessage({ type: 'error', error: error.message });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
`;
|
|
66
|
+
|
|
9
67
|
/**
|
|
10
68
|
* Worker pool for Schematron validation
|
|
11
69
|
* Provides non-blocking validation in worker threads
|
|
@@ -20,134 +78,125 @@ export class SchematronWorkerPool {
|
|
|
20
78
|
reject: (error: Error) => void;
|
|
21
79
|
}> = [];
|
|
22
80
|
private maxWorkers: number;
|
|
23
|
-
private
|
|
24
|
-
private
|
|
25
|
-
|
|
81
|
+
private schematronSource?: string;
|
|
82
|
+
private baseUri?: string;
|
|
83
|
+
/** the task each busy worker is holding, so a thread that dies fails its task */
|
|
84
|
+
private tasksByWorker = new Map<Worker, { reject: (error: Error) => void }>();
|
|
85
|
+
|
|
26
86
|
constructor(maxWorkers: number = 4) {
|
|
27
87
|
this.maxWorkers = maxWorkers;
|
|
28
88
|
}
|
|
29
|
-
|
|
89
|
+
|
|
30
90
|
/**
|
|
31
91
|
* Initialize worker pool
|
|
32
92
|
*/
|
|
33
93
|
public async initialize(
|
|
34
|
-
|
|
35
|
-
options: ISchematronWorkerPoolInitializeOptions = {}
|
|
94
|
+
schematronSource: string,
|
|
95
|
+
options: ISchematronWorkerPoolInitializeOptions = {},
|
|
36
96
|
): Promise<void> {
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
97
|
+
await this.loadSchematron(schematronSource, options);
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
// Create workers
|
|
101
|
+
for (let i = 0; i < this.maxWorkers; i++) {
|
|
102
|
+
await this.createWorker();
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
// a pool that did not come up completely must not leave threads behind
|
|
106
|
+
await this.terminate();
|
|
107
|
+
throw error;
|
|
42
108
|
}
|
|
43
109
|
}
|
|
44
110
|
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
options: ISchematronWorkerPoolInitializeOptions
|
|
48
|
-
): void {
|
|
49
|
-
const
|
|
50
|
-
const isFilePath = options.isFilePath ?? /\.sef\.json$/i.test(stylesheetSource);
|
|
51
|
-
|
|
52
|
-
this.stylesheetFileName = undefined;
|
|
53
|
-
this.stylesheetInternal = undefined;
|
|
111
|
+
private async loadSchematron(
|
|
112
|
+
schematronSource: string,
|
|
113
|
+
options: ISchematronWorkerPoolInitializeOptions,
|
|
114
|
+
): Promise<void> {
|
|
115
|
+
const isFilePath = options.isFilePath ?? /\.sch$/i.test(schematronSource);
|
|
54
116
|
|
|
55
117
|
if (isFilePath) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
this.stylesheetFileName = stylesheetSource;
|
|
118
|
+
this.schematronSource = await fs.readFile(schematronSource, 'utf-8');
|
|
119
|
+
this.baseUri = schematronSource;
|
|
60
120
|
return;
|
|
61
121
|
}
|
|
62
122
|
|
|
63
|
-
if (
|
|
64
|
-
throw new Error(
|
|
123
|
+
if (schematronSource.trim().startsWith('{')) {
|
|
124
|
+
throw new Error(
|
|
125
|
+
'Schematron worker validation takes a Schematron schema, not a compiled XSLT stylesheet (SEF).',
|
|
126
|
+
);
|
|
65
127
|
}
|
|
66
128
|
|
|
67
|
-
this.
|
|
129
|
+
this.schematronSource = schematronSource;
|
|
130
|
+
this.baseUri = undefined;
|
|
68
131
|
}
|
|
69
|
-
|
|
132
|
+
|
|
70
133
|
/**
|
|
71
134
|
* Create a new worker
|
|
72
135
|
*/
|
|
73
136
|
private async createWorker(): Promise<void> {
|
|
74
|
-
const worker = new Worker(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
parentPort.postMessage({ type: 'ready' });
|
|
90
|
-
} else if (msg.type === 'validate') {
|
|
91
|
-
if (!stylesheetFileName && !stylesheetInternal) {
|
|
92
|
-
throw new Error('Worker not initialized');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const transformOptions = {
|
|
96
|
-
sourceText: msg.xmlContent,
|
|
97
|
-
destination: 'serialized',
|
|
98
|
-
stylesheetParams: msg.options.parameters || {}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
if (stylesheetFileName) {
|
|
102
|
-
transformOptions.stylesheetFileName = stylesheetFileName;
|
|
103
|
-
} else {
|
|
104
|
-
transformOptions.stylesheetInternal = stylesheetInternal;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const result = await SaxonJS.transform(transformOptions, 'async');
|
|
108
|
-
|
|
109
|
-
parentPort.postMessage({
|
|
110
|
-
type: 'result',
|
|
111
|
-
svrl: result.principalResult
|
|
112
|
-
});
|
|
137
|
+
const worker = new Worker(WORKER_SOURCE, { eval: true });
|
|
138
|
+
|
|
139
|
+
// Compile the schema inside the worker before it joins the pool.
|
|
140
|
+
try {
|
|
141
|
+
await new Promise<void>((resolve, reject) => {
|
|
142
|
+
worker.once('error', reject);
|
|
143
|
+
worker.once('exit', (code) =>
|
|
144
|
+
reject(new Error(`Schematron worker exited with code ${code} before it was ready`)),
|
|
145
|
+
);
|
|
146
|
+
worker.once('message', (msg) => {
|
|
147
|
+
if (msg.type === 'ready') {
|
|
148
|
+
resolve();
|
|
149
|
+
} else if (msg.type === 'error') {
|
|
150
|
+
reject(new Error(msg.error));
|
|
113
151
|
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// Initialize worker with a precompiled SEF stylesheet.
|
|
124
|
-
await new Promise<void>((resolve, reject) => {
|
|
125
|
-
worker.once('message', (msg) => {
|
|
126
|
-
if (msg.type === 'ready') {
|
|
127
|
-
resolve();
|
|
128
|
-
} else if (msg.type === 'error') {
|
|
129
|
-
reject(new Error(msg.error));
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
// Send initialization message
|
|
134
|
-
worker.postMessage({
|
|
135
|
-
type: 'init',
|
|
136
|
-
stylesheetFileName: this.stylesheetFileName,
|
|
137
|
-
stylesheetInternal: this.stylesheetInternal
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
worker.postMessage({
|
|
155
|
+
type: 'init',
|
|
156
|
+
schematronSource: this.schematronSource,
|
|
157
|
+
baseUri: this.baseUri,
|
|
158
|
+
engineUrl: import.meta.resolve('@push.rocks/smartxml/schematron'),
|
|
159
|
+
});
|
|
138
160
|
});
|
|
139
|
-
})
|
|
140
|
-
|
|
161
|
+
} catch (error) {
|
|
162
|
+
await worker.terminate();
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
worker.removeAllListeners('exit');
|
|
167
|
+
// a thread that dies later must not take its task down with it
|
|
168
|
+
worker.on('error', (error: unknown) =>
|
|
169
|
+
this.retireWorker(worker, error instanceof Error ? error : new Error(String(error))),
|
|
170
|
+
);
|
|
171
|
+
worker.on('exit', () =>
|
|
172
|
+
this.retireWorker(worker, new Error('Schematron worker exited unexpectedly')),
|
|
173
|
+
);
|
|
174
|
+
|
|
141
175
|
this.workers.push(worker);
|
|
142
176
|
this.availableWorkers.push(worker);
|
|
143
177
|
}
|
|
144
|
-
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Drops a thread that died, failing the task it was holding so no caller waits
|
|
181
|
+
* for an answer that can never come.
|
|
182
|
+
*/
|
|
183
|
+
private retireWorker(worker: Worker, error: Error): void {
|
|
184
|
+
this.workers = this.workers.filter((candidate) => candidate !== worker);
|
|
185
|
+
this.availableWorkers = this.availableWorkers.filter((candidate) => candidate !== worker);
|
|
186
|
+
const holder = this.tasksByWorker.get(worker);
|
|
187
|
+
if (holder) {
|
|
188
|
+
this.tasksByWorker.delete(worker);
|
|
189
|
+
holder.reject(error);
|
|
190
|
+
}
|
|
191
|
+
this.processTasks();
|
|
192
|
+
}
|
|
193
|
+
|
|
145
194
|
/**
|
|
146
195
|
* Validate XML using worker pool
|
|
147
196
|
*/
|
|
148
197
|
public async validate(
|
|
149
198
|
xmlContent: string,
|
|
150
|
-
options: SchematronOptions = {}
|
|
199
|
+
options: SchematronOptions = {},
|
|
151
200
|
): Promise<ValidationResult[]> {
|
|
152
201
|
return new Promise((resolve, reject) => {
|
|
153
202
|
// Add task to queue
|
|
@@ -155,7 +204,7 @@ export class SchematronWorkerPool {
|
|
|
155
204
|
this.processTasks();
|
|
156
205
|
});
|
|
157
206
|
}
|
|
158
|
-
|
|
207
|
+
|
|
159
208
|
/**
|
|
160
209
|
* Process queued validation tasks
|
|
161
210
|
*/
|
|
@@ -163,65 +212,72 @@ export class SchematronWorkerPool {
|
|
|
163
212
|
while (this.taskQueue.length > 0 && this.availableWorkers.length > 0) {
|
|
164
213
|
const task = this.taskQueue.shift()!;
|
|
165
214
|
const worker = this.availableWorkers.shift()!;
|
|
166
|
-
|
|
215
|
+
|
|
216
|
+
this.tasksByWorker.set(worker, task);
|
|
217
|
+
|
|
167
218
|
// Set up one-time listeners
|
|
219
|
+
const finish = (settle: () => void) => {
|
|
220
|
+
this.tasksByWorker.delete(worker);
|
|
221
|
+
worker.removeListener('message', messageHandler);
|
|
222
|
+
settle();
|
|
223
|
+
|
|
224
|
+
// Return worker to pool
|
|
225
|
+
this.availableWorkers.push(worker);
|
|
226
|
+
|
|
227
|
+
// Process next task
|
|
228
|
+
this.processTasks();
|
|
229
|
+
};
|
|
230
|
+
|
|
168
231
|
const messageHandler = (msg: any) => {
|
|
169
232
|
if (msg.type === 'result') {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
this.availableWorkers.push(worker);
|
|
176
|
-
worker.removeListener('message', messageHandler);
|
|
177
|
-
|
|
178
|
-
// Process next task
|
|
179
|
-
this.processTasks();
|
|
233
|
+
finish(() =>
|
|
234
|
+
task.resolve(
|
|
235
|
+
applySchematronOptions(schematronReportToValidationResults(msg.report), task.options),
|
|
236
|
+
),
|
|
237
|
+
);
|
|
180
238
|
} else if (msg.type === 'error') {
|
|
181
|
-
task.reject(new Error(msg.error));
|
|
182
|
-
|
|
183
|
-
// Return worker to pool
|
|
184
|
-
this.availableWorkers.push(worker);
|
|
185
|
-
worker.removeListener('message', messageHandler);
|
|
186
|
-
|
|
187
|
-
// Process next task
|
|
188
|
-
this.processTasks();
|
|
239
|
+
finish(() => task.reject(new Error(msg.error)));
|
|
189
240
|
}
|
|
190
241
|
};
|
|
191
|
-
|
|
242
|
+
|
|
192
243
|
worker.on('message', messageHandler);
|
|
193
|
-
|
|
244
|
+
|
|
194
245
|
// Send validation task
|
|
195
246
|
worker.postMessage({
|
|
196
247
|
type: 'validate',
|
|
197
248
|
xmlContent: task.xmlContent,
|
|
198
|
-
options: task.options
|
|
249
|
+
options: task.options,
|
|
199
250
|
});
|
|
200
251
|
}
|
|
201
252
|
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Parse SVRL output
|
|
205
|
-
*/
|
|
206
|
-
private parseSVRL(svrlXml: string): ValidationResult[] {
|
|
207
|
-
const results: ValidationResult[] = [];
|
|
208
|
-
|
|
209
|
-
// This would use the same parsing logic as SchematronValidator
|
|
210
|
-
// Simplified for brevity
|
|
211
|
-
|
|
212
|
-
return results;
|
|
213
|
-
}
|
|
214
|
-
|
|
253
|
+
|
|
215
254
|
/**
|
|
216
255
|
* Terminate all workers
|
|
217
256
|
*/
|
|
218
257
|
public async terminate(): Promise<void> {
|
|
219
|
-
|
|
258
|
+
const workers = this.workers;
|
|
220
259
|
this.workers = [];
|
|
221
260
|
this.availableWorkers = [];
|
|
261
|
+
|
|
262
|
+
// nobody may keep waiting for a pool that is shutting down
|
|
263
|
+
for (const holder of this.tasksByWorker.values()) {
|
|
264
|
+
holder.reject(new Error('Schematron worker pool was terminated'));
|
|
265
|
+
}
|
|
266
|
+
this.tasksByWorker.clear();
|
|
267
|
+
for (const task of this.taskQueue) {
|
|
268
|
+
task.reject(new Error('Schematron worker pool was terminated'));
|
|
269
|
+
}
|
|
222
270
|
this.taskQueue = [];
|
|
271
|
+
|
|
272
|
+
await Promise.all(
|
|
273
|
+
workers.map((worker) => {
|
|
274
|
+
worker.removeAllListeners('exit');
|
|
275
|
+
worker.removeAllListeners('error');
|
|
276
|
+
return worker.terminate();
|
|
277
|
+
}),
|
|
278
|
+
);
|
|
223
279
|
}
|
|
224
|
-
|
|
280
|
+
|
|
225
281
|
/**
|
|
226
282
|
* Get pool statistics
|
|
227
283
|
*/
|
|
@@ -233,7 +289,7 @@ export class SchematronWorkerPool {
|
|
|
233
289
|
return {
|
|
234
290
|
totalWorkers: this.workers.length,
|
|
235
291
|
availableWorkers: this.availableWorkers.length,
|
|
236
|
-
queuedTasks: this.taskQueue.length
|
|
292
|
+
queuedTasks: this.taskQueue.length,
|
|
237
293
|
};
|
|
238
294
|
}
|
|
239
295
|
}
|
package/ts/plugins.ts
CHANGED
|
@@ -10,9 +10,13 @@ import * as path from 'path';
|
|
|
10
10
|
import * as crypto from 'crypto';
|
|
11
11
|
|
|
12
12
|
// XML-related imports
|
|
13
|
+
import { readFileSync } from 'fs';
|
|
13
14
|
import { DOMParser, XMLSerializer, xmldom } from './vendor/xmldom.js';
|
|
14
15
|
import * as xpath from 'xpath';
|
|
15
16
|
|
|
17
|
+
// Standards-related imports
|
|
18
|
+
import * as smartxmlSchematron from '@push.rocks/smartxml/schematron';
|
|
19
|
+
|
|
16
20
|
// Compression-related imports
|
|
17
21
|
import { pako } from './vendor/pako.js';
|
|
18
22
|
|
|
@@ -27,10 +31,14 @@ export {
|
|
|
27
31
|
crypto,
|
|
28
32
|
|
|
29
33
|
// XML-related exports
|
|
34
|
+
readFileSync,
|
|
30
35
|
DOMParser,
|
|
31
36
|
XMLSerializer,
|
|
32
37
|
xmldom,
|
|
33
38
|
xpath,
|
|
39
|
+
|
|
40
|
+
// Standards-related exports
|
|
41
|
+
smartxmlSchematron,
|
|
34
42
|
|
|
35
43
|
// Compression-related exports
|
|
36
44
|
pako,
|
package/ts/vendor/modules.d.ts
CHANGED
|
@@ -11,22 +11,3 @@ declare module 'xmldom' {
|
|
|
11
11
|
declare module 'pako' {
|
|
12
12
|
export function inflate(input: Uint8Array | ArrayBuffer | string, options?: unknown): Uint8Array;
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
declare module 'saxon-js' {
|
|
16
|
-
export function compile(options: {
|
|
17
|
-
stylesheetText: string;
|
|
18
|
-
warnings?: string;
|
|
19
|
-
[key: string]: unknown;
|
|
20
|
-
}): Promise<unknown>;
|
|
21
|
-
|
|
22
|
-
export function transform(options: {
|
|
23
|
-
stylesheetInternal?: unknown;
|
|
24
|
-
sourceText: string;
|
|
25
|
-
destination?: string;
|
|
26
|
-
stylesheetParams?: Record<string, unknown>;
|
|
27
|
-
[key: string]: unknown;
|
|
28
|
-
}): Promise<{
|
|
29
|
-
principalResult: string;
|
|
30
|
-
[key: string]: unknown;
|
|
31
|
-
}>;
|
|
32
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface ISaxonJSCompileOptions {
|
|
2
|
-
stylesheetText: string;
|
|
3
|
-
warnings?: string;
|
|
4
|
-
[key: string]: unknown;
|
|
5
|
-
}
|
|
6
|
-
export interface ISaxonJSTransformOptions {
|
|
7
|
-
stylesheetInternal?: unknown;
|
|
8
|
-
stylesheetFileName?: string;
|
|
9
|
-
sourceText: string;
|
|
10
|
-
destination?: string;
|
|
11
|
-
stylesheetParams?: Record<string, unknown>;
|
|
12
|
-
[key: string]: unknown;
|
|
13
|
-
}
|
|
14
|
-
export interface ISaxonJSTransformResult {
|
|
15
|
-
principalResult: string;
|
|
16
|
-
[key: string]: unknown;
|
|
17
|
-
}
|
|
18
|
-
export interface ISaxonJSModule {
|
|
19
|
-
compile?: (options: ISaxonJSCompileOptions) => Promise<unknown>;
|
|
20
|
-
transform(options: ISaxonJSTransformOptions, executionMode?: 'async' | 'sync'): Promise<ISaxonJSTransformResult> | ISaxonJSTransformResult;
|
|
21
|
-
[key: string]: unknown;
|
|
22
|
-
}
|
|
23
|
-
export declare const loadSaxonJS: () => Promise<ISaxonJSModule>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
let cachedSaxonJS;
|
|
2
|
-
export const loadSaxonJS = async () => {
|
|
3
|
-
cachedSaxonJS ||= import('saxon-js').then((saxonJSRuntime) => {
|
|
4
|
-
const runtime = saxonJSRuntime.default ?? saxonJSRuntime;
|
|
5
|
-
return runtime;
|
|
6
|
-
});
|
|
7
|
-
return cachedSaxonJS;
|
|
8
|
-
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F4b25qcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL3ZlbmRvci9zYXhvbmpzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTBCQSxJQUFJLGFBQWtELENBQUM7QUFFdkQsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLEtBQUssSUFBNkIsRUFBRTtJQUM3RCxhQUFhLEtBQUssTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRSxFQUFFO1FBQzNELE1BQU0sT0FBTyxHQUFJLGNBQXNCLENBQUMsT0FBTyxJQUFJLGNBQWMsQ0FBQztRQUNsRSxPQUFPLE9BQXlCLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLGFBQWEsQ0FBQztBQUN2QixDQUFDLENBQUMifQ==
|