@formfeed/engine 0.3.20 → 0.3.22
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/index.cjs +186 -15
- package/index.js +186 -15
- package/package.json +1 -1
- package/types/index.d.cts +3 -1
- package/types/index.d.ts +3 -1
- package/types/lib/assemble.d.cts +8 -0
- package/types/lib/assemble.d.ts +8 -0
- package/types/lib/codes/epc.d.cts +5 -1
- package/types/lib/codes/epc.d.ts +5 -1
- package/types/lib/einvoice/cii.d.cts +9 -0
- package/types/lib/einvoice/cii.d.ts +9 -0
- package/types/lib/einvoice/index.d.cts +4 -2
- package/types/lib/einvoice/index.d.ts +4 -2
- package/types/lib/einvoice/report.d.cts +15 -0
- package/types/lib/einvoice/report.d.ts +15 -0
- package/types/lib/pdfa/index.d.cts +112 -0
- package/types/lib/pdfa/index.d.ts +112 -0
package/index.cjs
CHANGED
|
@@ -47,10 +47,12 @@ __export(index_exports, {
|
|
|
47
47
|
DefaultHelperRegistry: () => DefaultHelperRegistry,
|
|
48
48
|
EINVOICE_FLAVOURS: () => EINVOICE_FLAVOURS,
|
|
49
49
|
EINVOICE_FLAVOUR_NAMES: () => EINVOICE_FLAVOUR_NAMES,
|
|
50
|
+
EINVOICE_HEADER_LENGTH: () => EINVOICE_HEADER_LENGTH,
|
|
50
51
|
EINVOICE_MAX_MESSAGES: () => EINVOICE_MAX_MESSAGES,
|
|
51
52
|
EINVOICE_PROFILES: () => EINVOICE_PROFILES,
|
|
52
53
|
EINVOICE_PROFILE_NAMES: () => EINVOICE_PROFILE_NAMES,
|
|
53
54
|
EINVOICE_SPEC_VERSIONS: () => EINVOICE_SPEC_VERSIONS,
|
|
55
|
+
EINVOICE_TEST_NOTE: () => EINVOICE_TEST_NOTE,
|
|
54
56
|
EINVOICE_XML_NAME: () => EINVOICE_XML_NAME,
|
|
55
57
|
EN16931_TERMS: () => EN16931_TERMS,
|
|
56
58
|
EPC_MAX_BYTES: () => EPC_MAX_BYTES,
|
|
@@ -58,6 +60,12 @@ __export(index_exports, {
|
|
|
58
60
|
INVOICE_DATA_KEY: () => INVOICE_DATA_KEY,
|
|
59
61
|
OFFICE_FILLED_MAX_BYTES: () => OFFICE_FILLED_MAX_BYTES,
|
|
60
62
|
OfficeTemplateError: () => OfficeTemplateError,
|
|
63
|
+
PDFA_DEFAULT_LEVEL: () => PDFA_DEFAULT_LEVEL,
|
|
64
|
+
PDFA_HEADER_LENGTH: () => PDFA_HEADER_LENGTH,
|
|
65
|
+
PDFA_LEVELS: () => PDFA_LEVELS,
|
|
66
|
+
PDFA_MAX_MESSAGES: () => PDFA_MAX_MESSAGES,
|
|
67
|
+
PDFA_REFUSALS: () => PDFA_REFUSALS,
|
|
68
|
+
PDFA_STANDARDS: () => PDFA_STANDARDS,
|
|
61
69
|
PDFUA_STANDARD: () => PDFUA_STANDARD,
|
|
62
70
|
RenderError: () => RenderError,
|
|
63
71
|
RenderLimitError: () => RenderLimitError,
|
|
@@ -106,6 +114,7 @@ __export(index_exports, {
|
|
|
106
114
|
editAttribute: () => editAttribute,
|
|
107
115
|
editableRegion: () => editableRegion,
|
|
108
116
|
editableRegionAt: () => editableRegionAt,
|
|
117
|
+
einvoiceHeaderValue: () => einvoiceHeaderValue,
|
|
109
118
|
einvoiceOptionsSchema: () => einvoiceOptionsSchema,
|
|
110
119
|
einvoiceResult: () => einvoiceResult,
|
|
111
120
|
einvoiceXml: () => einvoiceXml,
|
|
@@ -149,6 +158,8 @@ __export(index_exports, {
|
|
|
149
158
|
isApitemplateRegion: () => isApitemplateRegion,
|
|
150
159
|
isOfficeKind: () => isOfficeKind,
|
|
151
160
|
isOutputFormat: () => isOutputFormat,
|
|
161
|
+
isPdfaResult: () => isPdfaResult,
|
|
162
|
+
isPdfaSetting: () => isPdfaSetting,
|
|
152
163
|
isScss: () => isScss,
|
|
153
164
|
isUaSetting: () => isUaSetting,
|
|
154
165
|
jinja2Engine: () => jinja2Engine,
|
|
@@ -181,6 +192,10 @@ __export(index_exports, {
|
|
|
181
192
|
parseDesign: () => parseDesign,
|
|
182
193
|
parseSourceAttribute: () => parseSourceAttribute,
|
|
183
194
|
partialInclude: () => partialInclude,
|
|
195
|
+
pdfaFromEinvoice: () => pdfaFromEinvoice,
|
|
196
|
+
pdfaHeaderValue: () => pdfaHeaderValue,
|
|
197
|
+
pdfaResult: () => pdfaResult,
|
|
198
|
+
pdfaStandard: () => pdfaStandard,
|
|
184
199
|
printReset: () => printReset,
|
|
185
200
|
qrSvg: () => qrSvg,
|
|
186
201
|
readJsreportExport: () => readJsreportExport,
|
|
@@ -191,6 +206,7 @@ __export(index_exports, {
|
|
|
191
206
|
renderVersion: () => renderVersion,
|
|
192
207
|
resolveEinvoiceOptions: () => resolveEinvoiceOptions,
|
|
193
208
|
resolvePath: () => resolvePath,
|
|
209
|
+
resolvePdfa: () => resolvePdfa,
|
|
194
210
|
resolveTranslation: () => resolveTranslation,
|
|
195
211
|
resolveUa: () => resolveUa,
|
|
196
212
|
scanBlocks: () => scanBlocks,
|
|
@@ -321,7 +337,7 @@ function toNumber(value) {
|
|
|
321
337
|
// packages/engine/src/lib/codes/epc.ts
|
|
322
338
|
function epcPayload(input) {
|
|
323
339
|
const amount2 = input.amount === void 0 || input.amount === "" ? "" : `EUR${toNumber(input.amount).toFixed(2)}`;
|
|
324
|
-
|
|
340
|
+
const elements = [
|
|
325
341
|
"BCD",
|
|
326
342
|
"002",
|
|
327
343
|
"1",
|
|
@@ -333,8 +349,12 @@ function epcPayload(input) {
|
|
|
333
349
|
(input.purpose ?? "").slice(0, 4),
|
|
334
350
|
(input.reference ?? "").slice(0, 35),
|
|
335
351
|
input.reference ? "" : (input.text ?? "").slice(0, 140),
|
|
352
|
+
// the beneficiary to originator information, which a payment here has no field for
|
|
336
353
|
""
|
|
337
|
-
]
|
|
354
|
+
];
|
|
355
|
+
while (elements.length > 0 && elements[elements.length - 1] === "")
|
|
356
|
+
elements.pop();
|
|
357
|
+
return elements.join("\n");
|
|
338
358
|
}
|
|
339
359
|
var IBAN_LENGTHS = {
|
|
340
360
|
AD: 24,
|
|
@@ -391,34 +411,73 @@ function validateEpc(input) {
|
|
|
391
411
|
const problems = [];
|
|
392
412
|
const name = String(input.name ?? "").trim();
|
|
393
413
|
if (!name) problems.push({ field: "name", code: "required" });
|
|
394
|
-
else if (name.length > 70)
|
|
414
|
+
else if (name.length > 70)
|
|
415
|
+
problems.push({
|
|
416
|
+
field: "name",
|
|
417
|
+
code: "too_long",
|
|
418
|
+
max: 70,
|
|
419
|
+
actual: name.length
|
|
420
|
+
});
|
|
395
421
|
const iban2 = normaliseIban(String(input.iban ?? ""));
|
|
396
422
|
if (!iban2) problems.push({ field: "iban", code: "required" });
|
|
397
|
-
else if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(iban2))
|
|
423
|
+
else if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(iban2))
|
|
424
|
+
problems.push({ field: "iban", code: "iban_characters" });
|
|
398
425
|
else {
|
|
399
426
|
const expected = IBAN_LENGTHS[iban2.slice(0, 2)];
|
|
400
427
|
if (expected !== void 0 && iban2.length !== expected)
|
|
401
|
-
problems.push({
|
|
402
|
-
|
|
428
|
+
problems.push({
|
|
429
|
+
field: "iban",
|
|
430
|
+
code: "iban_country_length",
|
|
431
|
+
max: expected,
|
|
432
|
+
actual: iban2.length
|
|
433
|
+
});
|
|
434
|
+
else if (!ibanChecksum(iban2))
|
|
435
|
+
problems.push({ field: "iban", code: "iban_checksum" });
|
|
403
436
|
}
|
|
404
437
|
const bic = String(input.bic ?? "").replace(/\s/g, "").toUpperCase();
|
|
405
|
-
if (bic && !/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/.test(bic))
|
|
438
|
+
if (bic && !/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/.test(bic))
|
|
439
|
+
problems.push({ field: "bic", code: "bic_format" });
|
|
406
440
|
if (input.amount !== void 0 && input.amount !== "") {
|
|
407
441
|
const amount2 = toNumber(input.amount);
|
|
408
|
-
if (Number.isNaN(amount2))
|
|
409
|
-
|
|
442
|
+
if (Number.isNaN(amount2))
|
|
443
|
+
problems.push({ field: "amount", code: "not_a_number" });
|
|
444
|
+
else if (amount2 < 0.01 || amount2 > 99999999999e-2)
|
|
445
|
+
problems.push({ field: "amount", code: "out_of_range" });
|
|
410
446
|
}
|
|
411
447
|
const purpose = String(input.purpose ?? "");
|
|
412
|
-
if (purpose.length > 4)
|
|
448
|
+
if (purpose.length > 4)
|
|
449
|
+
problems.push({
|
|
450
|
+
field: "purpose",
|
|
451
|
+
code: "too_long",
|
|
452
|
+
max: 4,
|
|
453
|
+
actual: purpose.length
|
|
454
|
+
});
|
|
413
455
|
const reference = String(input.reference ?? "").trim();
|
|
414
456
|
const text4 = String(input.text ?? "").trim();
|
|
415
|
-
if (reference && text4)
|
|
457
|
+
if (reference && text4)
|
|
458
|
+
problems.push({ field: "reference", code: "reference_or_text" });
|
|
416
459
|
if (reference.length > 35)
|
|
417
|
-
problems.push({
|
|
418
|
-
|
|
460
|
+
problems.push({
|
|
461
|
+
field: "reference",
|
|
462
|
+
code: "too_long",
|
|
463
|
+
max: 35,
|
|
464
|
+
actual: reference.length
|
|
465
|
+
});
|
|
466
|
+
if (text4.length > 140)
|
|
467
|
+
problems.push({
|
|
468
|
+
field: "text",
|
|
469
|
+
code: "too_long",
|
|
470
|
+
max: 140,
|
|
471
|
+
actual: text4.length
|
|
472
|
+
});
|
|
419
473
|
const bytes = byteLength(epcPayload(input));
|
|
420
474
|
if (bytes > EPC_MAX_BYTES)
|
|
421
|
-
problems.push({
|
|
475
|
+
problems.push({
|
|
476
|
+
field: "payload",
|
|
477
|
+
code: "too_long",
|
|
478
|
+
max: EPC_MAX_BYTES,
|
|
479
|
+
actual: bytes
|
|
480
|
+
});
|
|
422
481
|
return problems;
|
|
423
482
|
}
|
|
424
483
|
|
|
@@ -9785,6 +9844,7 @@ var CII_GUIDELINES = {
|
|
|
9785
9844
|
en16931: "urn:cen.eu:en16931:2017"
|
|
9786
9845
|
};
|
|
9787
9846
|
var EINVOICE_XML_NAME = "factur-x.xml";
|
|
9847
|
+
var EINVOICE_TEST_NOTE = "TEST \u2013 keine Rechnung / test render, not an invoice";
|
|
9788
9848
|
function leaf(name, text4, attributes) {
|
|
9789
9849
|
if (text4 === void 0 || text4 === "") return void 0;
|
|
9790
9850
|
const kept = Object.entries(attributes ?? {}).filter(
|
|
@@ -10030,6 +10090,7 @@ function invoiceToCii(invoice, options) {
|
|
|
10030
10090
|
leaf("ram:ID", invoice.number),
|
|
10031
10091
|
leaf("ram:TypeCode", invoice.type_code),
|
|
10032
10092
|
date("ram:IssueDateTime", invoice.issue_date),
|
|
10093
|
+
options.test ? group2("ram:IncludedNote", [leaf("ram:Content", EINVOICE_TEST_NOTE)]) : void 0,
|
|
10033
10094
|
...invoice.notes.map(
|
|
10034
10095
|
(note2) => group2("ram:IncludedNote", [
|
|
10035
10096
|
leaf("ram:Content", note2.text),
|
|
@@ -10943,6 +11004,33 @@ function einvoiceResult(options, specVersion, validation, display) {
|
|
|
10943
11004
|
display: display ? { checked: display.checked, missing: display.missing } : null
|
|
10944
11005
|
};
|
|
10945
11006
|
}
|
|
11007
|
+
var EINVOICE_HEADER_LENGTH = 8e3;
|
|
11008
|
+
function einvoiceHeaderValue(result, limit = EINVOICE_HEADER_LENGTH) {
|
|
11009
|
+
const encode = (report) => encodeURIComponent(JSON.stringify(report));
|
|
11010
|
+
const full = encode(result);
|
|
11011
|
+
const validation = result.validation;
|
|
11012
|
+
if (full.length <= limit || !validation) return full;
|
|
11013
|
+
let messages = validation.messages.map((message) => ({
|
|
11014
|
+
...message,
|
|
11015
|
+
location: null
|
|
11016
|
+
}));
|
|
11017
|
+
const cut = () => ({
|
|
11018
|
+
...result,
|
|
11019
|
+
validation: { ...validation, messages, truncated: true }
|
|
11020
|
+
});
|
|
11021
|
+
let value = encode(cut());
|
|
11022
|
+
while (value.length > limit && messages.length > 0) {
|
|
11023
|
+
let last = messages.length - 1;
|
|
11024
|
+
for (let i = messages.length - 1; i >= 0; i--)
|
|
11025
|
+
if (messages[i].severity !== "error") {
|
|
11026
|
+
last = i;
|
|
11027
|
+
break;
|
|
11028
|
+
}
|
|
11029
|
+
messages = messages.filter((_, i) => i !== last);
|
|
11030
|
+
value = encode(cut());
|
|
11031
|
+
}
|
|
11032
|
+
return value;
|
|
11033
|
+
}
|
|
10946
11034
|
var EINVOICE_FLAVOUR_NAMES = {
|
|
10947
11035
|
"factur-x": "Factur-X",
|
|
10948
11036
|
zugferd: "ZUGFeRD"
|
|
@@ -11146,7 +11234,7 @@ function einvoiceXml(data, options) {
|
|
|
11146
11234
|
}
|
|
11147
11235
|
]
|
|
11148
11236
|
};
|
|
11149
|
-
const check = checkInvoice(block, options);
|
|
11237
|
+
const check = checkInvoice(block, { profile: options.profile });
|
|
11150
11238
|
if (!check.ok) return { ok: false, problems: check.problems };
|
|
11151
11239
|
return {
|
|
11152
11240
|
ok: true,
|
|
@@ -11469,6 +11557,89 @@ function staticAudit(input) {
|
|
|
11469
11557
|
return findings;
|
|
11470
11558
|
}
|
|
11471
11559
|
|
|
11560
|
+
// packages/engine/src/lib/pdfa/index.ts
|
|
11561
|
+
var PDFA_LEVELS = ["2b", "3b"];
|
|
11562
|
+
var PDFA_DEFAULT_LEVEL = "3b";
|
|
11563
|
+
var PDFA_STANDARDS = {
|
|
11564
|
+
"2b": "PDF/A-2b",
|
|
11565
|
+
"3b": "PDF/A-3b"
|
|
11566
|
+
};
|
|
11567
|
+
function resolvePdfa(setting) {
|
|
11568
|
+
if (setting === true) return PDFA_DEFAULT_LEVEL;
|
|
11569
|
+
return typeof setting === "string" && PDFA_LEVELS.includes(setting) ? setting : null;
|
|
11570
|
+
}
|
|
11571
|
+
function isPdfaSetting(value) {
|
|
11572
|
+
return value === null || typeof value === "boolean" || typeof value === "string" && PDFA_LEVELS.includes(value);
|
|
11573
|
+
}
|
|
11574
|
+
function pdfaStandard(level) {
|
|
11575
|
+
return PDFA_STANDARDS[level];
|
|
11576
|
+
}
|
|
11577
|
+
var PDFA_REFUSALS = {
|
|
11578
|
+
password: "pdf.pdfa cannot be combined with post.password: PDF/A does not allow encryption",
|
|
11579
|
+
einvoice: 'pdf.pdfa "2b" cannot be combined with an e-invoice: the invoice XML is an attachment, which PDF/A-2 does not allow. An e-invoice is a PDF/A-3b already; ask for "3b" or leave pdf.pdfa out',
|
|
11580
|
+
invalid: 'settings.pdf.pdfa is "2b", "3b", true, false or null'
|
|
11581
|
+
};
|
|
11582
|
+
var PDFA_MAX_MESSAGES = 50;
|
|
11583
|
+
var asMessage = (message) => ({
|
|
11584
|
+
severity: message.severity === "warning" ? "warning" : "error",
|
|
11585
|
+
rule: typeof message.rule === "string" ? message.rule : null,
|
|
11586
|
+
message: typeof message.message === "string" ? message.message : "",
|
|
11587
|
+
location: typeof message.location === "string" ? message.location : null
|
|
11588
|
+
});
|
|
11589
|
+
var capped = (messages, truncated) => {
|
|
11590
|
+
const sorted = [
|
|
11591
|
+
...messages.filter((message) => message.severity === "error"),
|
|
11592
|
+
...messages.filter((message) => message.severity !== "error")
|
|
11593
|
+
];
|
|
11594
|
+
return sorted.length > PDFA_MAX_MESSAGES || truncated ? { messages: sorted.slice(0, PDFA_MAX_MESSAGES), truncated: true } : { messages: sorted };
|
|
11595
|
+
};
|
|
11596
|
+
function pdfaResult(level, report, pdfSha256) {
|
|
11597
|
+
return {
|
|
11598
|
+
standard: PDFA_STANDARDS[level],
|
|
11599
|
+
conformant: report.valid === true,
|
|
11600
|
+
validator: report.validator,
|
|
11601
|
+
id: report.id,
|
|
11602
|
+
versions: { ...report.versions ?? {} },
|
|
11603
|
+
pdf_sha256: pdfSha256,
|
|
11604
|
+
...capped(
|
|
11605
|
+
(Array.isArray(report.messages) ? report.messages : []).map(asMessage),
|
|
11606
|
+
report.truncated === true
|
|
11607
|
+
)
|
|
11608
|
+
};
|
|
11609
|
+
}
|
|
11610
|
+
function pdfaFromEinvoice(validation) {
|
|
11611
|
+
if (!validation || validation.pdfa == null) return null;
|
|
11612
|
+
const messages = validation.messages.filter((message) => message.part === "pdf").map((message) => ({
|
|
11613
|
+
severity: message.severity,
|
|
11614
|
+
rule: message.rule,
|
|
11615
|
+
message: message.message,
|
|
11616
|
+
location: message.location
|
|
11617
|
+
}));
|
|
11618
|
+
const versions = { ...validation.versions ?? {} };
|
|
11619
|
+
return {
|
|
11620
|
+
standard: PDFA_STANDARDS["3b"],
|
|
11621
|
+
conformant: !messages.some((message) => message.severity === "error"),
|
|
11622
|
+
validator: `veraPDF ${versions["verapdf"] ?? "unknown"}`,
|
|
11623
|
+
id: validation.id ?? "",
|
|
11624
|
+
versions,
|
|
11625
|
+
pdf_sha256: validation.pdf_sha256 ?? null,
|
|
11626
|
+
...capped(messages, false)
|
|
11627
|
+
};
|
|
11628
|
+
}
|
|
11629
|
+
function isPdfaResult(value) {
|
|
11630
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
11631
|
+
const report = value;
|
|
11632
|
+
return typeof report.standard === "string" && Object.values(PDFA_STANDARDS).includes(report.standard) && typeof report.conformant === "boolean";
|
|
11633
|
+
}
|
|
11634
|
+
var PDFA_HEADER_LENGTH = 2e3;
|
|
11635
|
+
function pdfaHeaderValue(result, limit = PDFA_HEADER_LENGTH) {
|
|
11636
|
+
const value = encodeURIComponent(JSON.stringify(result));
|
|
11637
|
+
if (value.length <= limit) return value;
|
|
11638
|
+
return encodeURIComponent(
|
|
11639
|
+
JSON.stringify({ ...result, messages: [], truncated: true })
|
|
11640
|
+
);
|
|
11641
|
+
}
|
|
11642
|
+
|
|
11472
11643
|
// packages/engine/src/lib/office/errors.ts
|
|
11473
11644
|
var OfficeError = class extends Error {
|
|
11474
11645
|
constructor(code, message, details = {}) {
|
package/index.js
CHANGED
|
@@ -101,7 +101,7 @@ function toNumber(value) {
|
|
|
101
101
|
// packages/engine/src/lib/codes/epc.ts
|
|
102
102
|
function epcPayload(input) {
|
|
103
103
|
const amount2 = input.amount === void 0 || input.amount === "" ? "" : `EUR${toNumber(input.amount).toFixed(2)}`;
|
|
104
|
-
|
|
104
|
+
const elements = [
|
|
105
105
|
"BCD",
|
|
106
106
|
"002",
|
|
107
107
|
"1",
|
|
@@ -113,8 +113,12 @@ function epcPayload(input) {
|
|
|
113
113
|
(input.purpose ?? "").slice(0, 4),
|
|
114
114
|
(input.reference ?? "").slice(0, 35),
|
|
115
115
|
input.reference ? "" : (input.text ?? "").slice(0, 140),
|
|
116
|
+
// the beneficiary to originator information, which a payment here has no field for
|
|
116
117
|
""
|
|
117
|
-
]
|
|
118
|
+
];
|
|
119
|
+
while (elements.length > 0 && elements[elements.length - 1] === "")
|
|
120
|
+
elements.pop();
|
|
121
|
+
return elements.join("\n");
|
|
118
122
|
}
|
|
119
123
|
var IBAN_LENGTHS = {
|
|
120
124
|
AD: 24,
|
|
@@ -171,34 +175,73 @@ function validateEpc(input) {
|
|
|
171
175
|
const problems = [];
|
|
172
176
|
const name = String(input.name ?? "").trim();
|
|
173
177
|
if (!name) problems.push({ field: "name", code: "required" });
|
|
174
|
-
else if (name.length > 70)
|
|
178
|
+
else if (name.length > 70)
|
|
179
|
+
problems.push({
|
|
180
|
+
field: "name",
|
|
181
|
+
code: "too_long",
|
|
182
|
+
max: 70,
|
|
183
|
+
actual: name.length
|
|
184
|
+
});
|
|
175
185
|
const iban2 = normaliseIban(String(input.iban ?? ""));
|
|
176
186
|
if (!iban2) problems.push({ field: "iban", code: "required" });
|
|
177
|
-
else if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(iban2))
|
|
187
|
+
else if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(iban2))
|
|
188
|
+
problems.push({ field: "iban", code: "iban_characters" });
|
|
178
189
|
else {
|
|
179
190
|
const expected = IBAN_LENGTHS[iban2.slice(0, 2)];
|
|
180
191
|
if (expected !== void 0 && iban2.length !== expected)
|
|
181
|
-
problems.push({
|
|
182
|
-
|
|
192
|
+
problems.push({
|
|
193
|
+
field: "iban",
|
|
194
|
+
code: "iban_country_length",
|
|
195
|
+
max: expected,
|
|
196
|
+
actual: iban2.length
|
|
197
|
+
});
|
|
198
|
+
else if (!ibanChecksum(iban2))
|
|
199
|
+
problems.push({ field: "iban", code: "iban_checksum" });
|
|
183
200
|
}
|
|
184
201
|
const bic = String(input.bic ?? "").replace(/\s/g, "").toUpperCase();
|
|
185
|
-
if (bic && !/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/.test(bic))
|
|
202
|
+
if (bic && !/^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/.test(bic))
|
|
203
|
+
problems.push({ field: "bic", code: "bic_format" });
|
|
186
204
|
if (input.amount !== void 0 && input.amount !== "") {
|
|
187
205
|
const amount2 = toNumber(input.amount);
|
|
188
|
-
if (Number.isNaN(amount2))
|
|
189
|
-
|
|
206
|
+
if (Number.isNaN(amount2))
|
|
207
|
+
problems.push({ field: "amount", code: "not_a_number" });
|
|
208
|
+
else if (amount2 < 0.01 || amount2 > 99999999999e-2)
|
|
209
|
+
problems.push({ field: "amount", code: "out_of_range" });
|
|
190
210
|
}
|
|
191
211
|
const purpose = String(input.purpose ?? "");
|
|
192
|
-
if (purpose.length > 4)
|
|
212
|
+
if (purpose.length > 4)
|
|
213
|
+
problems.push({
|
|
214
|
+
field: "purpose",
|
|
215
|
+
code: "too_long",
|
|
216
|
+
max: 4,
|
|
217
|
+
actual: purpose.length
|
|
218
|
+
});
|
|
193
219
|
const reference = String(input.reference ?? "").trim();
|
|
194
220
|
const text4 = String(input.text ?? "").trim();
|
|
195
|
-
if (reference && text4)
|
|
221
|
+
if (reference && text4)
|
|
222
|
+
problems.push({ field: "reference", code: "reference_or_text" });
|
|
196
223
|
if (reference.length > 35)
|
|
197
|
-
problems.push({
|
|
198
|
-
|
|
224
|
+
problems.push({
|
|
225
|
+
field: "reference",
|
|
226
|
+
code: "too_long",
|
|
227
|
+
max: 35,
|
|
228
|
+
actual: reference.length
|
|
229
|
+
});
|
|
230
|
+
if (text4.length > 140)
|
|
231
|
+
problems.push({
|
|
232
|
+
field: "text",
|
|
233
|
+
code: "too_long",
|
|
234
|
+
max: 140,
|
|
235
|
+
actual: text4.length
|
|
236
|
+
});
|
|
199
237
|
const bytes = byteLength(epcPayload(input));
|
|
200
238
|
if (bytes > EPC_MAX_BYTES)
|
|
201
|
-
problems.push({
|
|
239
|
+
problems.push({
|
|
240
|
+
field: "payload",
|
|
241
|
+
code: "too_long",
|
|
242
|
+
max: EPC_MAX_BYTES,
|
|
243
|
+
actual: bytes
|
|
244
|
+
});
|
|
202
245
|
return problems;
|
|
203
246
|
}
|
|
204
247
|
|
|
@@ -9565,6 +9608,7 @@ var CII_GUIDELINES = {
|
|
|
9565
9608
|
en16931: "urn:cen.eu:en16931:2017"
|
|
9566
9609
|
};
|
|
9567
9610
|
var EINVOICE_XML_NAME = "factur-x.xml";
|
|
9611
|
+
var EINVOICE_TEST_NOTE = "TEST \u2013 keine Rechnung / test render, not an invoice";
|
|
9568
9612
|
function leaf(name, text4, attributes) {
|
|
9569
9613
|
if (text4 === void 0 || text4 === "") return void 0;
|
|
9570
9614
|
const kept = Object.entries(attributes ?? {}).filter(
|
|
@@ -9810,6 +9854,7 @@ function invoiceToCii(invoice, options) {
|
|
|
9810
9854
|
leaf("ram:ID", invoice.number),
|
|
9811
9855
|
leaf("ram:TypeCode", invoice.type_code),
|
|
9812
9856
|
date("ram:IssueDateTime", invoice.issue_date),
|
|
9857
|
+
options.test ? group2("ram:IncludedNote", [leaf("ram:Content", EINVOICE_TEST_NOTE)]) : void 0,
|
|
9813
9858
|
...invoice.notes.map(
|
|
9814
9859
|
(note2) => group2("ram:IncludedNote", [
|
|
9815
9860
|
leaf("ram:Content", note2.text),
|
|
@@ -10723,6 +10768,33 @@ function einvoiceResult(options, specVersion, validation, display) {
|
|
|
10723
10768
|
display: display ? { checked: display.checked, missing: display.missing } : null
|
|
10724
10769
|
};
|
|
10725
10770
|
}
|
|
10771
|
+
var EINVOICE_HEADER_LENGTH = 8e3;
|
|
10772
|
+
function einvoiceHeaderValue(result, limit = EINVOICE_HEADER_LENGTH) {
|
|
10773
|
+
const encode = (report) => encodeURIComponent(JSON.stringify(report));
|
|
10774
|
+
const full = encode(result);
|
|
10775
|
+
const validation = result.validation;
|
|
10776
|
+
if (full.length <= limit || !validation) return full;
|
|
10777
|
+
let messages = validation.messages.map((message) => ({
|
|
10778
|
+
...message,
|
|
10779
|
+
location: null
|
|
10780
|
+
}));
|
|
10781
|
+
const cut = () => ({
|
|
10782
|
+
...result,
|
|
10783
|
+
validation: { ...validation, messages, truncated: true }
|
|
10784
|
+
});
|
|
10785
|
+
let value = encode(cut());
|
|
10786
|
+
while (value.length > limit && messages.length > 0) {
|
|
10787
|
+
let last = messages.length - 1;
|
|
10788
|
+
for (let i = messages.length - 1; i >= 0; i--)
|
|
10789
|
+
if (messages[i].severity !== "error") {
|
|
10790
|
+
last = i;
|
|
10791
|
+
break;
|
|
10792
|
+
}
|
|
10793
|
+
messages = messages.filter((_, i) => i !== last);
|
|
10794
|
+
value = encode(cut());
|
|
10795
|
+
}
|
|
10796
|
+
return value;
|
|
10797
|
+
}
|
|
10726
10798
|
var EINVOICE_FLAVOUR_NAMES = {
|
|
10727
10799
|
"factur-x": "Factur-X",
|
|
10728
10800
|
zugferd: "ZUGFeRD"
|
|
@@ -10926,7 +10998,7 @@ function einvoiceXml(data, options) {
|
|
|
10926
10998
|
}
|
|
10927
10999
|
]
|
|
10928
11000
|
};
|
|
10929
|
-
const check = checkInvoice(block, options);
|
|
11001
|
+
const check = checkInvoice(block, { profile: options.profile });
|
|
10930
11002
|
if (!check.ok) return { ok: false, problems: check.problems };
|
|
10931
11003
|
return {
|
|
10932
11004
|
ok: true,
|
|
@@ -11249,6 +11321,89 @@ function staticAudit(input) {
|
|
|
11249
11321
|
return findings;
|
|
11250
11322
|
}
|
|
11251
11323
|
|
|
11324
|
+
// packages/engine/src/lib/pdfa/index.ts
|
|
11325
|
+
var PDFA_LEVELS = ["2b", "3b"];
|
|
11326
|
+
var PDFA_DEFAULT_LEVEL = "3b";
|
|
11327
|
+
var PDFA_STANDARDS = {
|
|
11328
|
+
"2b": "PDF/A-2b",
|
|
11329
|
+
"3b": "PDF/A-3b"
|
|
11330
|
+
};
|
|
11331
|
+
function resolvePdfa(setting) {
|
|
11332
|
+
if (setting === true) return PDFA_DEFAULT_LEVEL;
|
|
11333
|
+
return typeof setting === "string" && PDFA_LEVELS.includes(setting) ? setting : null;
|
|
11334
|
+
}
|
|
11335
|
+
function isPdfaSetting(value) {
|
|
11336
|
+
return value === null || typeof value === "boolean" || typeof value === "string" && PDFA_LEVELS.includes(value);
|
|
11337
|
+
}
|
|
11338
|
+
function pdfaStandard(level) {
|
|
11339
|
+
return PDFA_STANDARDS[level];
|
|
11340
|
+
}
|
|
11341
|
+
var PDFA_REFUSALS = {
|
|
11342
|
+
password: "pdf.pdfa cannot be combined with post.password: PDF/A does not allow encryption",
|
|
11343
|
+
einvoice: 'pdf.pdfa "2b" cannot be combined with an e-invoice: the invoice XML is an attachment, which PDF/A-2 does not allow. An e-invoice is a PDF/A-3b already; ask for "3b" or leave pdf.pdfa out',
|
|
11344
|
+
invalid: 'settings.pdf.pdfa is "2b", "3b", true, false or null'
|
|
11345
|
+
};
|
|
11346
|
+
var PDFA_MAX_MESSAGES = 50;
|
|
11347
|
+
var asMessage = (message) => ({
|
|
11348
|
+
severity: message.severity === "warning" ? "warning" : "error",
|
|
11349
|
+
rule: typeof message.rule === "string" ? message.rule : null,
|
|
11350
|
+
message: typeof message.message === "string" ? message.message : "",
|
|
11351
|
+
location: typeof message.location === "string" ? message.location : null
|
|
11352
|
+
});
|
|
11353
|
+
var capped = (messages, truncated) => {
|
|
11354
|
+
const sorted = [
|
|
11355
|
+
...messages.filter((message) => message.severity === "error"),
|
|
11356
|
+
...messages.filter((message) => message.severity !== "error")
|
|
11357
|
+
];
|
|
11358
|
+
return sorted.length > PDFA_MAX_MESSAGES || truncated ? { messages: sorted.slice(0, PDFA_MAX_MESSAGES), truncated: true } : { messages: sorted };
|
|
11359
|
+
};
|
|
11360
|
+
function pdfaResult(level, report, pdfSha256) {
|
|
11361
|
+
return {
|
|
11362
|
+
standard: PDFA_STANDARDS[level],
|
|
11363
|
+
conformant: report.valid === true,
|
|
11364
|
+
validator: report.validator,
|
|
11365
|
+
id: report.id,
|
|
11366
|
+
versions: { ...report.versions ?? {} },
|
|
11367
|
+
pdf_sha256: pdfSha256,
|
|
11368
|
+
...capped(
|
|
11369
|
+
(Array.isArray(report.messages) ? report.messages : []).map(asMessage),
|
|
11370
|
+
report.truncated === true
|
|
11371
|
+
)
|
|
11372
|
+
};
|
|
11373
|
+
}
|
|
11374
|
+
function pdfaFromEinvoice(validation) {
|
|
11375
|
+
if (!validation || validation.pdfa == null) return null;
|
|
11376
|
+
const messages = validation.messages.filter((message) => message.part === "pdf").map((message) => ({
|
|
11377
|
+
severity: message.severity,
|
|
11378
|
+
rule: message.rule,
|
|
11379
|
+
message: message.message,
|
|
11380
|
+
location: message.location
|
|
11381
|
+
}));
|
|
11382
|
+
const versions = { ...validation.versions ?? {} };
|
|
11383
|
+
return {
|
|
11384
|
+
standard: PDFA_STANDARDS["3b"],
|
|
11385
|
+
conformant: !messages.some((message) => message.severity === "error"),
|
|
11386
|
+
validator: `veraPDF ${versions["verapdf"] ?? "unknown"}`,
|
|
11387
|
+
id: validation.id ?? "",
|
|
11388
|
+
versions,
|
|
11389
|
+
pdf_sha256: validation.pdf_sha256 ?? null,
|
|
11390
|
+
...capped(messages, false)
|
|
11391
|
+
};
|
|
11392
|
+
}
|
|
11393
|
+
function isPdfaResult(value) {
|
|
11394
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
11395
|
+
const report = value;
|
|
11396
|
+
return typeof report.standard === "string" && Object.values(PDFA_STANDARDS).includes(report.standard) && typeof report.conformant === "boolean";
|
|
11397
|
+
}
|
|
11398
|
+
var PDFA_HEADER_LENGTH = 2e3;
|
|
11399
|
+
function pdfaHeaderValue(result, limit = PDFA_HEADER_LENGTH) {
|
|
11400
|
+
const value = encodeURIComponent(JSON.stringify(result));
|
|
11401
|
+
if (value.length <= limit) return value;
|
|
11402
|
+
return encodeURIComponent(
|
|
11403
|
+
JSON.stringify({ ...result, messages: [], truncated: true })
|
|
11404
|
+
);
|
|
11405
|
+
}
|
|
11406
|
+
|
|
11252
11407
|
// packages/engine/src/lib/office/errors.ts
|
|
11253
11408
|
var OfficeError = class extends Error {
|
|
11254
11409
|
constructor(code, message, details = {}) {
|
|
@@ -14159,10 +14314,12 @@ export {
|
|
|
14159
14314
|
DefaultHelperRegistry,
|
|
14160
14315
|
EINVOICE_FLAVOURS,
|
|
14161
14316
|
EINVOICE_FLAVOUR_NAMES,
|
|
14317
|
+
EINVOICE_HEADER_LENGTH,
|
|
14162
14318
|
EINVOICE_MAX_MESSAGES,
|
|
14163
14319
|
EINVOICE_PROFILES,
|
|
14164
14320
|
EINVOICE_PROFILE_NAMES,
|
|
14165
14321
|
EINVOICE_SPEC_VERSIONS,
|
|
14322
|
+
EINVOICE_TEST_NOTE,
|
|
14166
14323
|
EINVOICE_XML_NAME,
|
|
14167
14324
|
EN16931_TERMS,
|
|
14168
14325
|
EPC_MAX_BYTES,
|
|
@@ -14170,6 +14327,12 @@ export {
|
|
|
14170
14327
|
INVOICE_DATA_KEY,
|
|
14171
14328
|
OFFICE_FILLED_MAX_BYTES,
|
|
14172
14329
|
OfficeTemplateError,
|
|
14330
|
+
PDFA_DEFAULT_LEVEL,
|
|
14331
|
+
PDFA_HEADER_LENGTH,
|
|
14332
|
+
PDFA_LEVELS,
|
|
14333
|
+
PDFA_MAX_MESSAGES,
|
|
14334
|
+
PDFA_REFUSALS,
|
|
14335
|
+
PDFA_STANDARDS,
|
|
14173
14336
|
PDFUA_STANDARD,
|
|
14174
14337
|
RenderError,
|
|
14175
14338
|
RenderLimitError,
|
|
@@ -14218,6 +14381,7 @@ export {
|
|
|
14218
14381
|
editAttribute,
|
|
14219
14382
|
editableRegion,
|
|
14220
14383
|
editableRegionAt,
|
|
14384
|
+
einvoiceHeaderValue,
|
|
14221
14385
|
einvoiceOptionsSchema,
|
|
14222
14386
|
einvoiceResult,
|
|
14223
14387
|
einvoiceXml,
|
|
@@ -14261,6 +14425,8 @@ export {
|
|
|
14261
14425
|
isApitemplateRegion,
|
|
14262
14426
|
isOfficeKind,
|
|
14263
14427
|
isOutputFormat,
|
|
14428
|
+
isPdfaResult,
|
|
14429
|
+
isPdfaSetting,
|
|
14264
14430
|
isScss,
|
|
14265
14431
|
isUaSetting,
|
|
14266
14432
|
jinja2Engine,
|
|
@@ -14293,6 +14459,10 @@ export {
|
|
|
14293
14459
|
parseDesign,
|
|
14294
14460
|
parseSourceAttribute,
|
|
14295
14461
|
partialInclude,
|
|
14462
|
+
pdfaFromEinvoice,
|
|
14463
|
+
pdfaHeaderValue,
|
|
14464
|
+
pdfaResult,
|
|
14465
|
+
pdfaStandard,
|
|
14296
14466
|
printReset,
|
|
14297
14467
|
qrSvg,
|
|
14298
14468
|
readJsreportExport,
|
|
@@ -14303,6 +14473,7 @@ export {
|
|
|
14303
14473
|
renderVersion,
|
|
14304
14474
|
resolveEinvoiceOptions,
|
|
14305
14475
|
resolvePath,
|
|
14476
|
+
resolvePdfa,
|
|
14306
14477
|
resolveTranslation,
|
|
14307
14478
|
resolveUa,
|
|
14308
14479
|
scanBlocks,
|
package/package.json
CHANGED
package/types/index.d.cts
CHANGED
|
@@ -30,11 +30,13 @@ export type { ApplyResult, ChipKind, EditableRegion, EditItem, RegionChip, Regio
|
|
|
30
30
|
export { resolveTranslation, translationTarget } from './lib/translation.cjs';
|
|
31
31
|
export { DESIGN_LIMITS, DESIGN_VERSION, dataPathPattern, defaultLayer, designBytes, designOutputHash, designStarters, emitDesign, emptyDesign, genericFamily, googleFont, googleFonts, googleFontsUrl, imageIsEmpty, layerIdPattern, nearestWeight, nextLayerId, parseDesign, } from './lib/design/index.cjs';
|
|
32
32
|
export type { BarcodeLayer, BarcodeSymbology, Binding, CanvasSize, DesignDocument, DesignLayer, DesignStarter, EmittedDesign, FontChoice, GoogleFont, ImageLayer, ImageSource, LayerBase, LayerType, Paint, ParsedDesign, QrLayer, Shadow, ShapeLayer, Stroke, TextFormat, TextItem, TextLayer, TextStyle, } from './lib/design/index.cjs';
|
|
33
|
-
export { CII_GUIDELINES, CODE_LIST_RELEASE, DISPLAY_TERMS, EINVOICE_FLAVOURS, EINVOICE_FLAVOUR_NAMES, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILES, EINVOICE_PROFILE_NAMES, EINVOICE_SPEC_VERSIONS, EINVOICE_XML_NAME, EN16931_TERMS, INVOICE_DATA_KEY, VAT_CATEGORIES, capMessages, carriesTerm, checkInvoice, defaultEinvoiceOptions, displayCheck, displayMissingText, einvoiceOptionsSchema, einvoiceResult, einvoiceXml, htmlText, invoiceAmountText, invoiceLineOf, invoicePathSegments, invoiceSchema, invoiceSkeleton, invoiceToCii, locateJsonPath, resolveEinvoiceOptions, shownAmounts, } from './lib/einvoice/index.cjs';
|
|
33
|
+
export { CII_GUIDELINES, CODE_LIST_RELEASE, DISPLAY_TERMS, EINVOICE_FLAVOURS, EINVOICE_FLAVOUR_NAMES, EINVOICE_HEADER_LENGTH, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILES, EINVOICE_PROFILE_NAMES, EINVOICE_SPEC_VERSIONS, EINVOICE_TEST_NOTE, EINVOICE_XML_NAME, EN16931_TERMS, INVOICE_DATA_KEY, VAT_CATEGORIES, capMessages, carriesTerm, checkInvoice, defaultEinvoiceOptions, displayCheck, displayMissingText, einvoiceHeaderValue, einvoiceOptionsSchema, einvoiceResult, einvoiceXml, htmlText, invoiceAmountText, invoiceLineOf, invoicePathSegments, invoiceSchema, invoiceSkeleton, invoiceToCii, locateJsonPath, resolveEinvoiceOptions, shownAmounts, } from './lib/einvoice/index.cjs';
|
|
34
34
|
export type { CheckOptions, DisplayCheck, DisplayValue, EinvoiceDisplay, EinvoiceFlavour, EinvoiceMessage, EinvoiceOptions, EinvoiceOptionsInput, EinvoiceProfile, EinvoiceResult, EinvoiceTerm, EinvoiceValidation, EinvoiceXml, Identifier, Invoice, InvoiceAddress, InvoiceAllowance, InvoiceBreakdown, InvoiceCheck, InvoiceInput, InvoiceLine, InvoiceParty, InvoiceProblem, InvoiceProblemCode, InvoiceTax, JsonLocation, ResolvedEinvoice, VatCategory, } from './lib/einvoice/index.cjs';
|
|
35
35
|
export { ACCESSIBILITY_HEADER_LENGTH, ACCESSIBILITY_MAX_ELEMENTS, ACCESSIBILITY_MAX_FAILURES, AUDIT_CODES, AUDIT_RULES, AUDIT_SEVERITY, AUDIT_SNIPPET_LENGTH, AUDIT_TITLES, PDFUA_STANDARD, UA_CHECKS, UA_REFUSALS, accessibilityHeader, accessibilityHeaderValue, accessibilityResult, auditMessage, isUaSetting, resolveUa, } from './lib/accessibility/index.cjs';
|
|
36
36
|
export type { AccessibilityFailure, AccessibilityResult, AccessibilityWarning, AuditArgs, AuditCode, AuditFinding, AuditLink, AuditOptions, AuditReport, AuditSeverity, UaCheck, UaOptions, UaSetting, ValidatorFailure, ValidatorVerdict, } from './lib/accessibility/index.cjs';
|
|
37
37
|
export { staticAudit, staticAuditDiagnostics, } from './lib/accessibility/static.cjs';
|
|
38
|
+
export { PDFA_DEFAULT_LEVEL, PDFA_HEADER_LENGTH, PDFA_LEVELS, PDFA_MAX_MESSAGES, PDFA_REFUSALS, PDFA_STANDARDS, isPdfaResult, isPdfaSetting, pdfaFromEinvoice, pdfaHeaderValue, pdfaResult, pdfaStandard, resolvePdfa, } from './lib/pdfa/index.cjs';
|
|
39
|
+
export type { PdfaLevel, PdfaMessage, PdfaResult, PdfaSetting, PdfaStandard, PdfaValidatorReport, } from './lib/pdfa/index.cjs';
|
|
38
40
|
export type { StaticAuditDiagnostic, StaticAuditInput, } from './lib/accessibility/static.cjs';
|
|
39
41
|
export { auditRuntime } from './lib/generated/frames.cjs';
|
|
40
42
|
export { encodeTemplateText } from './lib/source-edit.cjs';
|
package/types/index.d.ts
CHANGED
|
@@ -30,11 +30,13 @@ export type { ApplyResult, ChipKind, EditableRegion, EditItem, RegionChip, Regio
|
|
|
30
30
|
export { resolveTranslation, translationTarget } from './lib/translation.js';
|
|
31
31
|
export { DESIGN_LIMITS, DESIGN_VERSION, dataPathPattern, defaultLayer, designBytes, designOutputHash, designStarters, emitDesign, emptyDesign, genericFamily, googleFont, googleFonts, googleFontsUrl, imageIsEmpty, layerIdPattern, nearestWeight, nextLayerId, parseDesign, } from './lib/design/index.js';
|
|
32
32
|
export type { BarcodeLayer, BarcodeSymbology, Binding, CanvasSize, DesignDocument, DesignLayer, DesignStarter, EmittedDesign, FontChoice, GoogleFont, ImageLayer, ImageSource, LayerBase, LayerType, Paint, ParsedDesign, QrLayer, Shadow, ShapeLayer, Stroke, TextFormat, TextItem, TextLayer, TextStyle, } from './lib/design/index.js';
|
|
33
|
-
export { CII_GUIDELINES, CODE_LIST_RELEASE, DISPLAY_TERMS, EINVOICE_FLAVOURS, EINVOICE_FLAVOUR_NAMES, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILES, EINVOICE_PROFILE_NAMES, EINVOICE_SPEC_VERSIONS, EINVOICE_XML_NAME, EN16931_TERMS, INVOICE_DATA_KEY, VAT_CATEGORIES, capMessages, carriesTerm, checkInvoice, defaultEinvoiceOptions, displayCheck, displayMissingText, einvoiceOptionsSchema, einvoiceResult, einvoiceXml, htmlText, invoiceAmountText, invoiceLineOf, invoicePathSegments, invoiceSchema, invoiceSkeleton, invoiceToCii, locateJsonPath, resolveEinvoiceOptions, shownAmounts, } from './lib/einvoice/index.js';
|
|
33
|
+
export { CII_GUIDELINES, CODE_LIST_RELEASE, DISPLAY_TERMS, EINVOICE_FLAVOURS, EINVOICE_FLAVOUR_NAMES, EINVOICE_HEADER_LENGTH, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILES, EINVOICE_PROFILE_NAMES, EINVOICE_SPEC_VERSIONS, EINVOICE_TEST_NOTE, EINVOICE_XML_NAME, EN16931_TERMS, INVOICE_DATA_KEY, VAT_CATEGORIES, capMessages, carriesTerm, checkInvoice, defaultEinvoiceOptions, displayCheck, displayMissingText, einvoiceHeaderValue, einvoiceOptionsSchema, einvoiceResult, einvoiceXml, htmlText, invoiceAmountText, invoiceLineOf, invoicePathSegments, invoiceSchema, invoiceSkeleton, invoiceToCii, locateJsonPath, resolveEinvoiceOptions, shownAmounts, } from './lib/einvoice/index.js';
|
|
34
34
|
export type { CheckOptions, DisplayCheck, DisplayValue, EinvoiceDisplay, EinvoiceFlavour, EinvoiceMessage, EinvoiceOptions, EinvoiceOptionsInput, EinvoiceProfile, EinvoiceResult, EinvoiceTerm, EinvoiceValidation, EinvoiceXml, Identifier, Invoice, InvoiceAddress, InvoiceAllowance, InvoiceBreakdown, InvoiceCheck, InvoiceInput, InvoiceLine, InvoiceParty, InvoiceProblem, InvoiceProblemCode, InvoiceTax, JsonLocation, ResolvedEinvoice, VatCategory, } from './lib/einvoice/index.js';
|
|
35
35
|
export { ACCESSIBILITY_HEADER_LENGTH, ACCESSIBILITY_MAX_ELEMENTS, ACCESSIBILITY_MAX_FAILURES, AUDIT_CODES, AUDIT_RULES, AUDIT_SEVERITY, AUDIT_SNIPPET_LENGTH, AUDIT_TITLES, PDFUA_STANDARD, UA_CHECKS, UA_REFUSALS, accessibilityHeader, accessibilityHeaderValue, accessibilityResult, auditMessage, isUaSetting, resolveUa, } from './lib/accessibility/index.js';
|
|
36
36
|
export type { AccessibilityFailure, AccessibilityResult, AccessibilityWarning, AuditArgs, AuditCode, AuditFinding, AuditLink, AuditOptions, AuditReport, AuditSeverity, UaCheck, UaOptions, UaSetting, ValidatorFailure, ValidatorVerdict, } from './lib/accessibility/index.js';
|
|
37
37
|
export { staticAudit, staticAuditDiagnostics, } from './lib/accessibility/static.js';
|
|
38
|
+
export { PDFA_DEFAULT_LEVEL, PDFA_HEADER_LENGTH, PDFA_LEVELS, PDFA_MAX_MESSAGES, PDFA_REFUSALS, PDFA_STANDARDS, isPdfaResult, isPdfaSetting, pdfaFromEinvoice, pdfaHeaderValue, pdfaResult, pdfaStandard, resolvePdfa, } from './lib/pdfa/index.js';
|
|
39
|
+
export type { PdfaLevel, PdfaMessage, PdfaResult, PdfaSetting, PdfaStandard, PdfaValidatorReport, } from './lib/pdfa/index.js';
|
|
38
40
|
export type { StaticAuditDiagnostic, StaticAuditInput, } from './lib/accessibility/static.js';
|
|
39
41
|
export { auditRuntime } from './lib/generated/frames.js';
|
|
40
42
|
export { encodeTemplateText } from './lib/source-edit.js';
|
package/types/lib/assemble.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { UaSetting } from './accessibility/index.cjs';
|
|
2
|
+
import type { PdfaSetting } from './pdfa/index.cjs';
|
|
2
3
|
import type { BrandContext } from './brand.cjs';
|
|
3
4
|
import type { EinvoiceOptionsInput } from './einvoice/schema.cjs';
|
|
4
5
|
import type { EngineId, RenderContext } from './types.cjs';
|
|
@@ -56,6 +57,13 @@ export interface TemplateSettings {
|
|
|
56
57
|
* implies `tagged`. Read it through `resolveUa`.
|
|
57
58
|
*/
|
|
58
59
|
ua?: UaSetting;
|
|
60
|
+
/**
|
|
61
|
+
* PDF/A (plan 26): the finished PDF is converted to PDF/A-2b or PDF/A-3b and held to it by the
|
|
62
|
+
* validator; a file that fails fails the render, there is no mode that delivers it. `true` is
|
|
63
|
+
* `'3b'`. An e-invoice is a PDF/A-3b already, so `'2b'` beside one is refused. Read it through
|
|
64
|
+
* `resolvePdfa`.
|
|
65
|
+
*/
|
|
66
|
+
pdfa?: PdfaSetting;
|
|
59
67
|
metadata?: {
|
|
60
68
|
title?: string;
|
|
61
69
|
author?: string;
|
package/types/lib/assemble.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { UaSetting } from './accessibility/index.js';
|
|
2
|
+
import type { PdfaSetting } from './pdfa/index.js';
|
|
2
3
|
import type { BrandContext } from './brand.js';
|
|
3
4
|
import type { EinvoiceOptionsInput } from './einvoice/schema.js';
|
|
4
5
|
import type { EngineId, RenderContext } from './types.js';
|
|
@@ -56,6 +57,13 @@ export interface TemplateSettings {
|
|
|
56
57
|
* implies `tagged`. Read it through `resolveUa`.
|
|
57
58
|
*/
|
|
58
59
|
ua?: UaSetting;
|
|
60
|
+
/**
|
|
61
|
+
* PDF/A (plan 26): the finished PDF is converted to PDF/A-2b or PDF/A-3b and held to it by the
|
|
62
|
+
* validator; a file that fails fails the render, there is no mode that delivers it. `true` is
|
|
63
|
+
* `'3b'`. An e-invoice is a PDF/A-3b already, so `'2b'` beside one is refused. Read it through
|
|
64
|
+
* `resolvePdfa`.
|
|
65
|
+
*/
|
|
66
|
+
pdfa?: PdfaSetting;
|
|
59
67
|
metadata?: {
|
|
60
68
|
title?: string;
|
|
61
69
|
author?: string;
|
|
@@ -29,7 +29,11 @@ export interface EpcPayment {
|
|
|
29
29
|
}
|
|
30
30
|
/** What a caller actually hands over: the same fields, none of them guaranteed to be there. */
|
|
31
31
|
export type EpcInput = Partial<EpcPayment>;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* EPC QR (GiroCode) payload, version 002, UTF-8, SCT. It ends with the last populated element:
|
|
34
|
+
* "The last populated element is not followed by any character or element separator" (EPC069-12
|
|
35
|
+
* v3.1 §2.2), so the empty elements after it are left out, line breaks and all.
|
|
36
|
+
*/
|
|
33
37
|
export declare function epcPayload(input: EpcInput): string;
|
|
34
38
|
/**
|
|
35
39
|
* What is wrong with a payment, as a code rather than a sentence: the engine has no locale, and the
|
package/types/lib/codes/epc.d.ts
CHANGED
|
@@ -29,7 +29,11 @@ export interface EpcPayment {
|
|
|
29
29
|
}
|
|
30
30
|
/** What a caller actually hands over: the same fields, none of them guaranteed to be there. */
|
|
31
31
|
export type EpcInput = Partial<EpcPayment>;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* EPC QR (GiroCode) payload, version 002, UTF-8, SCT. It ends with the last populated element:
|
|
34
|
+
* "The last populated element is not followed by any character or element separator" (EPC069-12
|
|
35
|
+
* v3.1 §2.2), so the empty elements after it are left out, line breaks and all.
|
|
36
|
+
*/
|
|
33
37
|
export declare function epcPayload(input: EpcInput): string;
|
|
34
38
|
/**
|
|
35
39
|
* What is wrong with a payment, as a code rather than a sentence: the engine has no locale, and the
|
|
@@ -13,6 +13,15 @@ import type { EinvoiceProfile } from './schema.cjs';
|
|
|
13
13
|
export declare const CII_GUIDELINES: Record<EinvoiceProfile, string>;
|
|
14
14
|
/** The name the XML has inside the PDF, under either of the specification's two names. */
|
|
15
15
|
export declare const EINVOICE_XML_NAME = "factur-x.xml";
|
|
16
|
+
/**
|
|
17
|
+
* The first note (BT-22) of a test render's invoice, on every plan (plan 25 §5.2): an XML carries
|
|
18
|
+
* no page mark, so the invoice says it of itself. No subject code: France's rules, which hold the
|
|
19
|
+
* subject codes of an invoice between French businesses, accept the note without one (measured
|
|
20
|
+
* with the sidecar on 2026-10-27). The wording waits for the Steuerberater (plan 25 §5.5).
|
|
21
|
+
*/
|
|
22
|
+
export declare const EINVOICE_TEST_NOTE = "TEST \u2013 keine Rechnung / test render, not an invoice";
|
|
16
23
|
export declare function invoiceToCii(invoice: Invoice, options: {
|
|
17
24
|
profile: EinvoiceProfile;
|
|
25
|
+
/** A test render's invoice: its first note says it is none (`EINVOICE_TEST_NOTE`). */
|
|
26
|
+
test?: boolean;
|
|
18
27
|
}): string;
|
|
@@ -13,6 +13,15 @@ import type { EinvoiceProfile } from './schema.js';
|
|
|
13
13
|
export declare const CII_GUIDELINES: Record<EinvoiceProfile, string>;
|
|
14
14
|
/** The name the XML has inside the PDF, under either of the specification's two names. */
|
|
15
15
|
export declare const EINVOICE_XML_NAME = "factur-x.xml";
|
|
16
|
+
/**
|
|
17
|
+
* The first note (BT-22) of a test render's invoice, on every plan (plan 25 §5.2): an XML carries
|
|
18
|
+
* no page mark, so the invoice says it of itself. No subject code: France's rules, which hold the
|
|
19
|
+
* subject codes of an invoice between French businesses, accept the note without one (measured
|
|
20
|
+
* with the sidecar on 2026-10-27). The wording waits for the Steuerberater (plan 25 §5.5).
|
|
21
|
+
*/
|
|
22
|
+
export declare const EINVOICE_TEST_NOTE = "TEST \u2013 keine Rechnung / test render, not an invoice";
|
|
16
23
|
export declare function invoiceToCii(invoice: Invoice, options: {
|
|
17
24
|
profile: EinvoiceProfile;
|
|
25
|
+
/** A test render's invoice: its first note says it is none (`EINVOICE_TEST_NOTE`). */
|
|
26
|
+
test?: boolean;
|
|
18
27
|
}): string;
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
import { type Invoice, type InvoiceProblem } from './check.cjs';
|
|
8
8
|
import type { EinvoiceFlavour, EinvoiceProfile } from './schema.cjs';
|
|
9
9
|
export { checkInvoice, type CheckOptions, type Identifier, type Invoice, type InvoiceAddress, type InvoiceAllowance, type InvoiceBreakdown, type InvoiceCheck, type InvoiceLine, type InvoiceParty, type InvoiceProblem, type InvoiceProblemCode, type InvoiceTax, } from './check.cjs';
|
|
10
|
-
export { CII_GUIDELINES, EINVOICE_XML_NAME, invoiceToCii } from './cii.cjs';
|
|
10
|
+
export { CII_GUIDELINES, EINVOICE_TEST_NOTE, EINVOICE_XML_NAME, invoiceToCii, } from './cii.cjs';
|
|
11
11
|
export { EN16931_TERMS, carriesTerm, type EinvoiceTerm } from './coverage.cjs';
|
|
12
12
|
export { CODE_LIST_RELEASE } from './codes.generated.cjs';
|
|
13
13
|
export { DISPLAY_TERMS, displayCheck, displayMissingText, shownAmounts, type DisplayCheck, type DisplayValue, } from './display.cjs';
|
|
14
14
|
export { EINVOICE_FLAVOURS, EINVOICE_PROFILES, VAT_CATEGORIES, defaultEinvoiceOptions, einvoiceOptionsSchema, invoiceSchema, resolveEinvoiceOptions, type EinvoiceFlavour, type EinvoiceOptions, type EinvoiceOptionsInput, type EinvoiceProfile, type InvoiceInput, type ResolvedEinvoice, type VatCategory, } from './schema.cjs';
|
|
15
15
|
export { invoicePathSegments, locateJsonPath, type JsonLocation, } from './locate.cjs';
|
|
16
|
-
export { EINVOICE_FLAVOUR_NAMES, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILE_NAMES, capMessages, einvoiceResult, invoiceLineOf, type EinvoiceDisplay, type EinvoiceMessage, type EinvoiceResult, type EinvoiceValidation, } from './report.cjs';
|
|
16
|
+
export { EINVOICE_FLAVOUR_NAMES, EINVOICE_HEADER_LENGTH, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILE_NAMES, capMessages, einvoiceHeaderValue, einvoiceResult, invoiceLineOf, type EinvoiceDisplay, type EinvoiceMessage, type EinvoiceResult, type EinvoiceValidation, } from './report.cjs';
|
|
17
17
|
export { htmlText } from './html-text.cjs';
|
|
18
18
|
export { invoiceSkeleton } from './skeleton.cjs';
|
|
19
19
|
/** Where the invoice sits in the render data. */
|
|
@@ -43,4 +43,6 @@ export type EinvoiceXml = {
|
|
|
43
43
|
*/
|
|
44
44
|
export declare function einvoiceXml(data: unknown, options: {
|
|
45
45
|
profile: EinvoiceProfile;
|
|
46
|
+
/** A test render's invoice, whose first note says it is none (`EINVOICE_TEST_NOTE`). */
|
|
47
|
+
test?: boolean;
|
|
46
48
|
}): EinvoiceXml;
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
import { type Invoice, type InvoiceProblem } from './check.js';
|
|
8
8
|
import type { EinvoiceFlavour, EinvoiceProfile } from './schema.js';
|
|
9
9
|
export { checkInvoice, type CheckOptions, type Identifier, type Invoice, type InvoiceAddress, type InvoiceAllowance, type InvoiceBreakdown, type InvoiceCheck, type InvoiceLine, type InvoiceParty, type InvoiceProblem, type InvoiceProblemCode, type InvoiceTax, } from './check.js';
|
|
10
|
-
export { CII_GUIDELINES, EINVOICE_XML_NAME, invoiceToCii } from './cii.js';
|
|
10
|
+
export { CII_GUIDELINES, EINVOICE_TEST_NOTE, EINVOICE_XML_NAME, invoiceToCii, } from './cii.js';
|
|
11
11
|
export { EN16931_TERMS, carriesTerm, type EinvoiceTerm } from './coverage.js';
|
|
12
12
|
export { CODE_LIST_RELEASE } from './codes.generated.js';
|
|
13
13
|
export { DISPLAY_TERMS, displayCheck, displayMissingText, shownAmounts, type DisplayCheck, type DisplayValue, } from './display.js';
|
|
14
14
|
export { EINVOICE_FLAVOURS, EINVOICE_PROFILES, VAT_CATEGORIES, defaultEinvoiceOptions, einvoiceOptionsSchema, invoiceSchema, resolveEinvoiceOptions, type EinvoiceFlavour, type EinvoiceOptions, type EinvoiceOptionsInput, type EinvoiceProfile, type InvoiceInput, type ResolvedEinvoice, type VatCategory, } from './schema.js';
|
|
15
15
|
export { invoicePathSegments, locateJsonPath, type JsonLocation, } from './locate.js';
|
|
16
|
-
export { EINVOICE_FLAVOUR_NAMES, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILE_NAMES, capMessages, einvoiceResult, invoiceLineOf, type EinvoiceDisplay, type EinvoiceMessage, type EinvoiceResult, type EinvoiceValidation, } from './report.js';
|
|
16
|
+
export { EINVOICE_FLAVOUR_NAMES, EINVOICE_HEADER_LENGTH, EINVOICE_MAX_MESSAGES, EINVOICE_PROFILE_NAMES, capMessages, einvoiceHeaderValue, einvoiceResult, invoiceLineOf, type EinvoiceDisplay, type EinvoiceMessage, type EinvoiceResult, type EinvoiceValidation, } from './report.js';
|
|
17
17
|
export { htmlText } from './html-text.js';
|
|
18
18
|
export { invoiceSkeleton } from './skeleton.js';
|
|
19
19
|
/** Where the invoice sits in the render data. */
|
|
@@ -43,4 +43,6 @@ export type EinvoiceXml = {
|
|
|
43
43
|
*/
|
|
44
44
|
export declare function einvoiceXml(data: unknown, options: {
|
|
45
45
|
profile: EinvoiceProfile;
|
|
46
|
+
/** A test render's invoice, whose first note says it is none (`EINVOICE_TEST_NOTE`). */
|
|
47
|
+
test?: boolean;
|
|
46
48
|
}): EinvoiceXml;
|
|
@@ -62,6 +62,21 @@ export declare const EINVOICE_MAX_MESSAGES = 50;
|
|
|
62
62
|
export declare function capMessages(messages: readonly EinvoiceMessage[], max?: number): Pick<EinvoiceValidation, 'messages' | 'truncated'>;
|
|
63
63
|
/** The result of a render that got as far as `validation` and `display` say. */
|
|
64
64
|
export declare function einvoiceResult(options: Pick<EinvoiceOptions, 'profile' | 'flavour'>, specVersion: string, validation: EinvoiceValidation | null, display: DisplayCheck | null): EinvoiceResult;
|
|
65
|
+
/**
|
|
66
|
+
* How long the report may be as a header value. A proxy answers a response whose headers grow past a
|
|
67
|
+
* few kilobytes with 502, and the e-invoice's report shares this room with a PDF/UA verdict
|
|
68
|
+
* (`ACCESSIBILITY_HEADER_LENGTH`) where a render made both.
|
|
69
|
+
*/
|
|
70
|
+
export declare const EINVOICE_HEADER_LENGTH = 8000;
|
|
71
|
+
/**
|
|
72
|
+
* The report as a response header carries it: the editor's true render reads the file from the body
|
|
73
|
+
* and the report from `X-Formfeed-Einvoice`, percent-encoded because a validator's message is not
|
|
74
|
+
* always ASCII. A report too long for `limit` loses, in this order, every finding's place, then the
|
|
75
|
+
* findings from the last, warnings before errors, and says so in `truncated` (plan 25 §5.5). What
|
|
76
|
+
* makes it a verdict always arrives: whether the file is valid, the rule set, the validator's id and
|
|
77
|
+
* versions, the hashes of the bytes it judged, and the display check.
|
|
78
|
+
*/
|
|
79
|
+
export declare function einvoiceHeaderValue(result: EinvoiceResult, limit?: number): string;
|
|
65
80
|
/** The names a person reads: `Factur-X` and `EN 16931` for `factur-x` and `en16931`. */
|
|
66
81
|
export declare const EINVOICE_FLAVOUR_NAMES: Record<EinvoiceFlavour, string>;
|
|
67
82
|
export declare const EINVOICE_PROFILE_NAMES: Record<EinvoiceProfile, string>;
|
|
@@ -62,6 +62,21 @@ export declare const EINVOICE_MAX_MESSAGES = 50;
|
|
|
62
62
|
export declare function capMessages(messages: readonly EinvoiceMessage[], max?: number): Pick<EinvoiceValidation, 'messages' | 'truncated'>;
|
|
63
63
|
/** The result of a render that got as far as `validation` and `display` say. */
|
|
64
64
|
export declare function einvoiceResult(options: Pick<EinvoiceOptions, 'profile' | 'flavour'>, specVersion: string, validation: EinvoiceValidation | null, display: DisplayCheck | null): EinvoiceResult;
|
|
65
|
+
/**
|
|
66
|
+
* How long the report may be as a header value. A proxy answers a response whose headers grow past a
|
|
67
|
+
* few kilobytes with 502, and the e-invoice's report shares this room with a PDF/UA verdict
|
|
68
|
+
* (`ACCESSIBILITY_HEADER_LENGTH`) where a render made both.
|
|
69
|
+
*/
|
|
70
|
+
export declare const EINVOICE_HEADER_LENGTH = 8000;
|
|
71
|
+
/**
|
|
72
|
+
* The report as a response header carries it: the editor's true render reads the file from the body
|
|
73
|
+
* and the report from `X-Formfeed-Einvoice`, percent-encoded because a validator's message is not
|
|
74
|
+
* always ASCII. A report too long for `limit` loses, in this order, every finding's place, then the
|
|
75
|
+
* findings from the last, warnings before errors, and says so in `truncated` (plan 25 §5.5). What
|
|
76
|
+
* makes it a verdict always arrives: whether the file is valid, the rule set, the validator's id and
|
|
77
|
+
* versions, the hashes of the bytes it judged, and the display check.
|
|
78
|
+
*/
|
|
79
|
+
export declare function einvoiceHeaderValue(result: EinvoiceResult, limit?: number): string;
|
|
65
80
|
/** The names a person reads: `Factur-X` and `EN 16931` for `factur-x` and `en16931`. */
|
|
66
81
|
export declare const EINVOICE_FLAVOUR_NAMES: Record<EinvoiceFlavour, string>;
|
|
67
82
|
export declare const EINVOICE_PROFILE_NAMES: Record<EinvoiceProfile, string>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { EinvoiceValidation } from '../einvoice/report.cjs';
|
|
2
|
+
/**
|
|
3
|
+
* `@formfeed/engine/pdfa` (plan 26): what `pdf.pdfa` asks for, what it cannot go with, and the
|
|
4
|
+
* report a render keeps of what the validator said. No template engine is imported here and nothing
|
|
5
|
+
* of Node, so the gateway Worker, the render-worker, the editor and the CLI all read the same names.
|
|
6
|
+
*
|
|
7
|
+
* PDF/A is ISO 19005, a file format for keeping documents: the fonts embedded, the colours defined,
|
|
8
|
+
* nothing that needs the network or a password. Whether an archive keeps them as a law asks (the
|
|
9
|
+
* GoBD, for one) is a matter of how the archive is run, not of the file, so nothing here or on any
|
|
10
|
+
* page says "revisionssicher", "GoBD-konform", "certified" or "archive-compliant": the report says
|
|
11
|
+
* which part and level a file was held to, and by which validator.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The levels a render can ask for. 3b is the default and what an e-invoice is; 2b is for archives
|
|
15
|
+
* that take PDF/A-2 and not PDF/A-3, which may carry any file as an attachment. PDF/A-1 forbids the
|
|
16
|
+
* transparency Chromium writes, so it is not offered.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PDFA_LEVELS: readonly ["2b", "3b"];
|
|
19
|
+
export type PdfaLevel = (typeof PDFA_LEVELS)[number];
|
|
20
|
+
/** What `true` stands for. */
|
|
21
|
+
export declare const PDFA_DEFAULT_LEVEL: PdfaLevel;
|
|
22
|
+
/** The standard a level names, as the report and the `X-Formfeed-PDF-A` header write it. */
|
|
23
|
+
export declare const PDFA_STANDARDS: {
|
|
24
|
+
readonly '2b': "PDF/A-2b";
|
|
25
|
+
readonly '3b': "PDF/A-3b";
|
|
26
|
+
};
|
|
27
|
+
export type PdfaStandard = (typeof PDFA_STANDARDS)[PdfaLevel];
|
|
28
|
+
/** `pdf.pdfa` as a template's settings or a request write it. */
|
|
29
|
+
export type PdfaSetting = PdfaLevel | boolean | null;
|
|
30
|
+
/**
|
|
31
|
+
* `pdf.pdfa` as a render takes it: a level, `true` for the default level, and anything else off.
|
|
32
|
+
* There is no check to choose (plan 26, decision 2): a file that fails PDF/A fails the render.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolvePdfa(setting: unknown): PdfaLevel | null;
|
|
35
|
+
/** Whether a `pdf.pdfa` value is one the API takes: a level, a boolean, or null. */
|
|
36
|
+
export declare function isPdfaSetting(value: unknown): value is PdfaSetting;
|
|
37
|
+
export declare function pdfaStandard(level: PdfaLevel): PdfaStandard;
|
|
38
|
+
/**
|
|
39
|
+
* What `pdf.pdfa` cannot go with, in the words every place that refuses it uses (the gateway before
|
|
40
|
+
* a render costs anything, the worker for whoever calls it directly, `formfeed validate`, the API's
|
|
41
|
+
* template validation). A merge, a watermark and Word and PowerPoint templates go with it, since all
|
|
42
|
+
* of them come before the conversion.
|
|
43
|
+
*/
|
|
44
|
+
export declare const PDFA_REFUSALS: {
|
|
45
|
+
readonly password: "pdf.pdfa cannot be combined with post.password: PDF/A does not allow encryption";
|
|
46
|
+
readonly einvoice: "pdf.pdfa \"2b\" cannot be combined with an e-invoice: the invoice XML is an attachment, which PDF/A-2 does not allow. An e-invoice is a PDF/A-3b already; ask for \"3b\" or leave pdf.pdfa out";
|
|
47
|
+
readonly invalid: "settings.pdf.pdfa is \"2b\", \"3b\", true, false or null";
|
|
48
|
+
};
|
|
49
|
+
/** How many findings a render keeps; a render row travels in every list and webhook. */
|
|
50
|
+
export declare const PDFA_MAX_MESSAGES = 50;
|
|
51
|
+
/** One rule of PDF/A the file failed, as the validator reports it. */
|
|
52
|
+
export interface PdfaMessage {
|
|
53
|
+
severity: 'error' | 'warning';
|
|
54
|
+
/** A clause of ISO 19005 and veraPDF's test number, `6.2.11.4.1-1`. */
|
|
55
|
+
rule: string | null;
|
|
56
|
+
message: string;
|
|
57
|
+
/** veraPDF's path to the object of the PDF. */
|
|
58
|
+
location: string | null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* `pdfa` on a render (plan 26): `null` unless the render asked for PDF/A or is an e-invoice with
|
|
62
|
+
* `pdf.pdfa` beside it. `conformant` is the validator's word on the file it judged; a render that
|
|
63
|
+
* succeeded delivered exactly that file, and one that failed delivered nothing.
|
|
64
|
+
*/
|
|
65
|
+
export interface PdfaResult {
|
|
66
|
+
standard: PdfaStandard;
|
|
67
|
+
conformant: boolean;
|
|
68
|
+
/** The validator and its version: its rule set moves between releases. */
|
|
69
|
+
validator: string;
|
|
70
|
+
/** The validator's own id for this report, which its log names too. */
|
|
71
|
+
id: string;
|
|
72
|
+
/** The versions of what converted and judged the file: `verapdf`, `pdfbox` (and `mustang` for an e-invoice). */
|
|
73
|
+
versions: Record<string, string>;
|
|
74
|
+
/** SHA-256 of the PDF that was judged: the delivered file when the render succeeded. */
|
|
75
|
+
pdf_sha256: string | null;
|
|
76
|
+
messages: PdfaMessage[];
|
|
77
|
+
/** More findings than the render keeps. */
|
|
78
|
+
truncated?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** The sidecar's report of `POST /pdf/pdfa` (`ArchiveReport` in `apps/conformance`). */
|
|
81
|
+
export interface PdfaValidatorReport {
|
|
82
|
+
id: string;
|
|
83
|
+
valid: boolean;
|
|
84
|
+
pdfa: string;
|
|
85
|
+
validator: string;
|
|
86
|
+
messages: Array<{
|
|
87
|
+
severity?: string;
|
|
88
|
+
rule?: string | null;
|
|
89
|
+
message?: string;
|
|
90
|
+
location?: string | null;
|
|
91
|
+
}>;
|
|
92
|
+
truncated?: boolean;
|
|
93
|
+
versions?: Record<string, string>;
|
|
94
|
+
}
|
|
95
|
+
/** The report a render keeps, from the sidecar's, with the hash of the file it judged. */
|
|
96
|
+
export declare function pdfaResult(level: PdfaLevel, report: PdfaValidatorReport, pdfSha256: string | null): PdfaResult;
|
|
97
|
+
/**
|
|
98
|
+
* The `pdfa` block of an e-invoice that asked for PDF/A too (plan 26, decision 8): an e-invoice is
|
|
99
|
+
* a PDF/A-3b, converted and judged once, so the block is made from the e-invoice's own validation
|
|
100
|
+
* and its PDF findings. Null while that validation ended at the XML, before there was a file.
|
|
101
|
+
*/
|
|
102
|
+
export declare function pdfaFromEinvoice(validation: EinvoiceValidation | null | undefined): PdfaResult | null;
|
|
103
|
+
/** Whether a stored value is a report: the API shows it, and null otherwise. */
|
|
104
|
+
export declare function isPdfaResult(value: unknown): value is PdfaResult;
|
|
105
|
+
/** How long the report may be as a header value: proxies refuse a response whose headers grow past a few kilobytes. */
|
|
106
|
+
export declare const PDFA_HEADER_LENGTH = 2000;
|
|
107
|
+
/**
|
|
108
|
+
* The report as the worker's binary answer carries it in `x-formfeed-pdfa`, percent-encoded: the
|
|
109
|
+
* gateway records it with the render and `preview-render` shows it. A file that was delivered
|
|
110
|
+
* passed, so its report is short; one that is too long anyway loses its findings and says so.
|
|
111
|
+
*/
|
|
112
|
+
export declare function pdfaHeaderValue(result: PdfaResult, limit?: number): string;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { EinvoiceValidation } from '../einvoice/report.js';
|
|
2
|
+
/**
|
|
3
|
+
* `@formfeed/engine/pdfa` (plan 26): what `pdf.pdfa` asks for, what it cannot go with, and the
|
|
4
|
+
* report a render keeps of what the validator said. No template engine is imported here and nothing
|
|
5
|
+
* of Node, so the gateway Worker, the render-worker, the editor and the CLI all read the same names.
|
|
6
|
+
*
|
|
7
|
+
* PDF/A is ISO 19005, a file format for keeping documents: the fonts embedded, the colours defined,
|
|
8
|
+
* nothing that needs the network or a password. Whether an archive keeps them as a law asks (the
|
|
9
|
+
* GoBD, for one) is a matter of how the archive is run, not of the file, so nothing here or on any
|
|
10
|
+
* page says "revisionssicher", "GoBD-konform", "certified" or "archive-compliant": the report says
|
|
11
|
+
* which part and level a file was held to, and by which validator.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The levels a render can ask for. 3b is the default and what an e-invoice is; 2b is for archives
|
|
15
|
+
* that take PDF/A-2 and not PDF/A-3, which may carry any file as an attachment. PDF/A-1 forbids the
|
|
16
|
+
* transparency Chromium writes, so it is not offered.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PDFA_LEVELS: readonly ["2b", "3b"];
|
|
19
|
+
export type PdfaLevel = (typeof PDFA_LEVELS)[number];
|
|
20
|
+
/** What `true` stands for. */
|
|
21
|
+
export declare const PDFA_DEFAULT_LEVEL: PdfaLevel;
|
|
22
|
+
/** The standard a level names, as the report and the `X-Formfeed-PDF-A` header write it. */
|
|
23
|
+
export declare const PDFA_STANDARDS: {
|
|
24
|
+
readonly '2b': "PDF/A-2b";
|
|
25
|
+
readonly '3b': "PDF/A-3b";
|
|
26
|
+
};
|
|
27
|
+
export type PdfaStandard = (typeof PDFA_STANDARDS)[PdfaLevel];
|
|
28
|
+
/** `pdf.pdfa` as a template's settings or a request write it. */
|
|
29
|
+
export type PdfaSetting = PdfaLevel | boolean | null;
|
|
30
|
+
/**
|
|
31
|
+
* `pdf.pdfa` as a render takes it: a level, `true` for the default level, and anything else off.
|
|
32
|
+
* There is no check to choose (plan 26, decision 2): a file that fails PDF/A fails the render.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolvePdfa(setting: unknown): PdfaLevel | null;
|
|
35
|
+
/** Whether a `pdf.pdfa` value is one the API takes: a level, a boolean, or null. */
|
|
36
|
+
export declare function isPdfaSetting(value: unknown): value is PdfaSetting;
|
|
37
|
+
export declare function pdfaStandard(level: PdfaLevel): PdfaStandard;
|
|
38
|
+
/**
|
|
39
|
+
* What `pdf.pdfa` cannot go with, in the words every place that refuses it uses (the gateway before
|
|
40
|
+
* a render costs anything, the worker for whoever calls it directly, `formfeed validate`, the API's
|
|
41
|
+
* template validation). A merge, a watermark and Word and PowerPoint templates go with it, since all
|
|
42
|
+
* of them come before the conversion.
|
|
43
|
+
*/
|
|
44
|
+
export declare const PDFA_REFUSALS: {
|
|
45
|
+
readonly password: "pdf.pdfa cannot be combined with post.password: PDF/A does not allow encryption";
|
|
46
|
+
readonly einvoice: "pdf.pdfa \"2b\" cannot be combined with an e-invoice: the invoice XML is an attachment, which PDF/A-2 does not allow. An e-invoice is a PDF/A-3b already; ask for \"3b\" or leave pdf.pdfa out";
|
|
47
|
+
readonly invalid: "settings.pdf.pdfa is \"2b\", \"3b\", true, false or null";
|
|
48
|
+
};
|
|
49
|
+
/** How many findings a render keeps; a render row travels in every list and webhook. */
|
|
50
|
+
export declare const PDFA_MAX_MESSAGES = 50;
|
|
51
|
+
/** One rule of PDF/A the file failed, as the validator reports it. */
|
|
52
|
+
export interface PdfaMessage {
|
|
53
|
+
severity: 'error' | 'warning';
|
|
54
|
+
/** A clause of ISO 19005 and veraPDF's test number, `6.2.11.4.1-1`. */
|
|
55
|
+
rule: string | null;
|
|
56
|
+
message: string;
|
|
57
|
+
/** veraPDF's path to the object of the PDF. */
|
|
58
|
+
location: string | null;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* `pdfa` on a render (plan 26): `null` unless the render asked for PDF/A or is an e-invoice with
|
|
62
|
+
* `pdf.pdfa` beside it. `conformant` is the validator's word on the file it judged; a render that
|
|
63
|
+
* succeeded delivered exactly that file, and one that failed delivered nothing.
|
|
64
|
+
*/
|
|
65
|
+
export interface PdfaResult {
|
|
66
|
+
standard: PdfaStandard;
|
|
67
|
+
conformant: boolean;
|
|
68
|
+
/** The validator and its version: its rule set moves between releases. */
|
|
69
|
+
validator: string;
|
|
70
|
+
/** The validator's own id for this report, which its log names too. */
|
|
71
|
+
id: string;
|
|
72
|
+
/** The versions of what converted and judged the file: `verapdf`, `pdfbox` (and `mustang` for an e-invoice). */
|
|
73
|
+
versions: Record<string, string>;
|
|
74
|
+
/** SHA-256 of the PDF that was judged: the delivered file when the render succeeded. */
|
|
75
|
+
pdf_sha256: string | null;
|
|
76
|
+
messages: PdfaMessage[];
|
|
77
|
+
/** More findings than the render keeps. */
|
|
78
|
+
truncated?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** The sidecar's report of `POST /pdf/pdfa` (`ArchiveReport` in `apps/conformance`). */
|
|
81
|
+
export interface PdfaValidatorReport {
|
|
82
|
+
id: string;
|
|
83
|
+
valid: boolean;
|
|
84
|
+
pdfa: string;
|
|
85
|
+
validator: string;
|
|
86
|
+
messages: Array<{
|
|
87
|
+
severity?: string;
|
|
88
|
+
rule?: string | null;
|
|
89
|
+
message?: string;
|
|
90
|
+
location?: string | null;
|
|
91
|
+
}>;
|
|
92
|
+
truncated?: boolean;
|
|
93
|
+
versions?: Record<string, string>;
|
|
94
|
+
}
|
|
95
|
+
/** The report a render keeps, from the sidecar's, with the hash of the file it judged. */
|
|
96
|
+
export declare function pdfaResult(level: PdfaLevel, report: PdfaValidatorReport, pdfSha256: string | null): PdfaResult;
|
|
97
|
+
/**
|
|
98
|
+
* The `pdfa` block of an e-invoice that asked for PDF/A too (plan 26, decision 8): an e-invoice is
|
|
99
|
+
* a PDF/A-3b, converted and judged once, so the block is made from the e-invoice's own validation
|
|
100
|
+
* and its PDF findings. Null while that validation ended at the XML, before there was a file.
|
|
101
|
+
*/
|
|
102
|
+
export declare function pdfaFromEinvoice(validation: EinvoiceValidation | null | undefined): PdfaResult | null;
|
|
103
|
+
/** Whether a stored value is a report: the API shows it, and null otherwise. */
|
|
104
|
+
export declare function isPdfaResult(value: unknown): value is PdfaResult;
|
|
105
|
+
/** How long the report may be as a header value: proxies refuse a response whose headers grow past a few kilobytes. */
|
|
106
|
+
export declare const PDFA_HEADER_LENGTH = 2000;
|
|
107
|
+
/**
|
|
108
|
+
* The report as the worker's binary answer carries it in `x-formfeed-pdfa`, percent-encoded: the
|
|
109
|
+
* gateway records it with the render and `preview-render` shows it. A file that was delivered
|
|
110
|
+
* passed, so its report is short; one that is too long anyway loses its findings and says so.
|
|
111
|
+
*/
|
|
112
|
+
export declare function pdfaHeaderValue(result: PdfaResult, limit?: number): string;
|