@formfeed/engine 0.3.21 → 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 +153 -14
- package/index.js +153 -14
- package/package.json +1 -1
- package/types/index.d.cts +2 -0
- package/types/index.d.ts +2 -0
- 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/pdfa/index.d.cts +112 -0
- package/types/lib/pdfa/index.d.ts +112 -0
package/index.cjs
CHANGED
|
@@ -60,6 +60,12 @@ __export(index_exports, {
|
|
|
60
60
|
INVOICE_DATA_KEY: () => INVOICE_DATA_KEY,
|
|
61
61
|
OFFICE_FILLED_MAX_BYTES: () => OFFICE_FILLED_MAX_BYTES,
|
|
62
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,
|
|
63
69
|
PDFUA_STANDARD: () => PDFUA_STANDARD,
|
|
64
70
|
RenderError: () => RenderError,
|
|
65
71
|
RenderLimitError: () => RenderLimitError,
|
|
@@ -152,6 +158,8 @@ __export(index_exports, {
|
|
|
152
158
|
isApitemplateRegion: () => isApitemplateRegion,
|
|
153
159
|
isOfficeKind: () => isOfficeKind,
|
|
154
160
|
isOutputFormat: () => isOutputFormat,
|
|
161
|
+
isPdfaResult: () => isPdfaResult,
|
|
162
|
+
isPdfaSetting: () => isPdfaSetting,
|
|
155
163
|
isScss: () => isScss,
|
|
156
164
|
isUaSetting: () => isUaSetting,
|
|
157
165
|
jinja2Engine: () => jinja2Engine,
|
|
@@ -184,6 +192,10 @@ __export(index_exports, {
|
|
|
184
192
|
parseDesign: () => parseDesign,
|
|
185
193
|
parseSourceAttribute: () => parseSourceAttribute,
|
|
186
194
|
partialInclude: () => partialInclude,
|
|
195
|
+
pdfaFromEinvoice: () => pdfaFromEinvoice,
|
|
196
|
+
pdfaHeaderValue: () => pdfaHeaderValue,
|
|
197
|
+
pdfaResult: () => pdfaResult,
|
|
198
|
+
pdfaStandard: () => pdfaStandard,
|
|
187
199
|
printReset: () => printReset,
|
|
188
200
|
qrSvg: () => qrSvg,
|
|
189
201
|
readJsreportExport: () => readJsreportExport,
|
|
@@ -194,6 +206,7 @@ __export(index_exports, {
|
|
|
194
206
|
renderVersion: () => renderVersion,
|
|
195
207
|
resolveEinvoiceOptions: () => resolveEinvoiceOptions,
|
|
196
208
|
resolvePath: () => resolvePath,
|
|
209
|
+
resolvePdfa: () => resolvePdfa,
|
|
197
210
|
resolveTranslation: () => resolveTranslation,
|
|
198
211
|
resolveUa: () => resolveUa,
|
|
199
212
|
scanBlocks: () => scanBlocks,
|
|
@@ -324,7 +337,7 @@ function toNumber(value) {
|
|
|
324
337
|
// packages/engine/src/lib/codes/epc.ts
|
|
325
338
|
function epcPayload(input) {
|
|
326
339
|
const amount2 = input.amount === void 0 || input.amount === "" ? "" : `EUR${toNumber(input.amount).toFixed(2)}`;
|
|
327
|
-
|
|
340
|
+
const elements = [
|
|
328
341
|
"BCD",
|
|
329
342
|
"002",
|
|
330
343
|
"1",
|
|
@@ -336,8 +349,12 @@ function epcPayload(input) {
|
|
|
336
349
|
(input.purpose ?? "").slice(0, 4),
|
|
337
350
|
(input.reference ?? "").slice(0, 35),
|
|
338
351
|
input.reference ? "" : (input.text ?? "").slice(0, 140),
|
|
352
|
+
// the beneficiary to originator information, which a payment here has no field for
|
|
339
353
|
""
|
|
340
|
-
]
|
|
354
|
+
];
|
|
355
|
+
while (elements.length > 0 && elements[elements.length - 1] === "")
|
|
356
|
+
elements.pop();
|
|
357
|
+
return elements.join("\n");
|
|
341
358
|
}
|
|
342
359
|
var IBAN_LENGTHS = {
|
|
343
360
|
AD: 24,
|
|
@@ -394,34 +411,73 @@ function validateEpc(input) {
|
|
|
394
411
|
const problems = [];
|
|
395
412
|
const name = String(input.name ?? "").trim();
|
|
396
413
|
if (!name) problems.push({ field: "name", code: "required" });
|
|
397
|
-
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
|
+
});
|
|
398
421
|
const iban2 = normaliseIban(String(input.iban ?? ""));
|
|
399
422
|
if (!iban2) problems.push({ field: "iban", code: "required" });
|
|
400
|
-
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" });
|
|
401
425
|
else {
|
|
402
426
|
const expected = IBAN_LENGTHS[iban2.slice(0, 2)];
|
|
403
427
|
if (expected !== void 0 && iban2.length !== expected)
|
|
404
|
-
problems.push({
|
|
405
|
-
|
|
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" });
|
|
406
436
|
}
|
|
407
437
|
const bic = String(input.bic ?? "").replace(/\s/g, "").toUpperCase();
|
|
408
|
-
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" });
|
|
409
440
|
if (input.amount !== void 0 && input.amount !== "") {
|
|
410
441
|
const amount2 = toNumber(input.amount);
|
|
411
|
-
if (Number.isNaN(amount2))
|
|
412
|
-
|
|
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" });
|
|
413
446
|
}
|
|
414
447
|
const purpose = String(input.purpose ?? "");
|
|
415
|
-
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
|
+
});
|
|
416
455
|
const reference = String(input.reference ?? "").trim();
|
|
417
456
|
const text4 = String(input.text ?? "").trim();
|
|
418
|
-
if (reference && text4)
|
|
457
|
+
if (reference && text4)
|
|
458
|
+
problems.push({ field: "reference", code: "reference_or_text" });
|
|
419
459
|
if (reference.length > 35)
|
|
420
|
-
problems.push({
|
|
421
|
-
|
|
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
|
+
});
|
|
422
473
|
const bytes = byteLength(epcPayload(input));
|
|
423
474
|
if (bytes > EPC_MAX_BYTES)
|
|
424
|
-
problems.push({
|
|
475
|
+
problems.push({
|
|
476
|
+
field: "payload",
|
|
477
|
+
code: "too_long",
|
|
478
|
+
max: EPC_MAX_BYTES,
|
|
479
|
+
actual: bytes
|
|
480
|
+
});
|
|
425
481
|
return problems;
|
|
426
482
|
}
|
|
427
483
|
|
|
@@ -11501,6 +11557,89 @@ function staticAudit(input) {
|
|
|
11501
11557
|
return findings;
|
|
11502
11558
|
}
|
|
11503
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
|
+
|
|
11504
11643
|
// packages/engine/src/lib/office/errors.ts
|
|
11505
11644
|
var OfficeError = class extends Error {
|
|
11506
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
|
|
|
@@ -11278,6 +11321,89 @@ function staticAudit(input) {
|
|
|
11278
11321
|
return findings;
|
|
11279
11322
|
}
|
|
11280
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
|
+
|
|
11281
11407
|
// packages/engine/src/lib/office/errors.ts
|
|
11282
11408
|
var OfficeError = class extends Error {
|
|
11283
11409
|
constructor(code, message, details = {}) {
|
|
@@ -14201,6 +14327,12 @@ export {
|
|
|
14201
14327
|
INVOICE_DATA_KEY,
|
|
14202
14328
|
OFFICE_FILLED_MAX_BYTES,
|
|
14203
14329
|
OfficeTemplateError,
|
|
14330
|
+
PDFA_DEFAULT_LEVEL,
|
|
14331
|
+
PDFA_HEADER_LENGTH,
|
|
14332
|
+
PDFA_LEVELS,
|
|
14333
|
+
PDFA_MAX_MESSAGES,
|
|
14334
|
+
PDFA_REFUSALS,
|
|
14335
|
+
PDFA_STANDARDS,
|
|
14204
14336
|
PDFUA_STANDARD,
|
|
14205
14337
|
RenderError,
|
|
14206
14338
|
RenderLimitError,
|
|
@@ -14293,6 +14425,8 @@ export {
|
|
|
14293
14425
|
isApitemplateRegion,
|
|
14294
14426
|
isOfficeKind,
|
|
14295
14427
|
isOutputFormat,
|
|
14428
|
+
isPdfaResult,
|
|
14429
|
+
isPdfaSetting,
|
|
14296
14430
|
isScss,
|
|
14297
14431
|
isUaSetting,
|
|
14298
14432
|
jinja2Engine,
|
|
@@ -14325,6 +14459,10 @@ export {
|
|
|
14325
14459
|
parseDesign,
|
|
14326
14460
|
parseSourceAttribute,
|
|
14327
14461
|
partialInclude,
|
|
14462
|
+
pdfaFromEinvoice,
|
|
14463
|
+
pdfaHeaderValue,
|
|
14464
|
+
pdfaResult,
|
|
14465
|
+
pdfaStandard,
|
|
14328
14466
|
printReset,
|
|
14329
14467
|
qrSvg,
|
|
14330
14468
|
readJsreportExport,
|
|
@@ -14335,6 +14473,7 @@ export {
|
|
|
14335
14473
|
renderVersion,
|
|
14336
14474
|
resolveEinvoiceOptions,
|
|
14337
14475
|
resolvePath,
|
|
14476
|
+
resolvePdfa,
|
|
14338
14477
|
resolveTranslation,
|
|
14339
14478
|
resolveUa,
|
|
14340
14479
|
scanBlocks,
|
package/package.json
CHANGED
package/types/index.d.cts
CHANGED
|
@@ -35,6 +35,8 @@ export type { CheckOptions, DisplayCheck, DisplayValue, EinvoiceDisplay, Einvoic
|
|
|
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
|
@@ -35,6 +35,8 @@ export type { CheckOptions, DisplayCheck, DisplayValue, EinvoiceDisplay, Einvoic
|
|
|
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
|
|
@@ -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;
|