Test env NATS cluster cut-over
This commit is contained in:
commit
e3c7b2833b
71 changed files with 6840 additions and 0 deletions
89
src/lib/receiptPdf.js
Normal file
89
src/lib/receiptPdf.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* Branded PDF retrieval receipt (no native deps).
|
||||
* @module lib/receiptPdf
|
||||
*/
|
||||
|
||||
function pdfEscape(s) {
|
||||
return String(s).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
|
||||
}
|
||||
|
||||
function wrap(s, n) {
|
||||
const str = String(s || '');
|
||||
const out = [];
|
||||
for (let i = 0; i < str.length; i += n) out.push(str.slice(i, i + n));
|
||||
return out.length ? out : [''];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} receipt
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
export function buildReceiptPdf(receipt) {
|
||||
const lines = [];
|
||||
const add = (label, value) => {
|
||||
lines.push({ kind: 'label', text: label });
|
||||
wrap(value, 86).forEach((t) => lines.push({ kind: 'value', text: t }));
|
||||
lines.push({ kind: 'gap' });
|
||||
};
|
||||
add('Job ID', receipt.jobId);
|
||||
add('SHA-256', receipt.sha256 ?? '');
|
||||
add('Original timestamp', receipt.timestamp ?? '');
|
||||
add('Retrieved at', receipt.extraSeal?.retrievedAt ?? '');
|
||||
add('Tenant', receipt.extraSeal?.tenantId ?? '');
|
||||
add('Seal event', receipt.extraSeal?.event ?? '');
|
||||
add('Certificate', String(receipt.certificate ?? '').slice(0, 240));
|
||||
|
||||
const ops = [];
|
||||
ops.push('0.192 0.180 0.506 rg');
|
||||
ops.push('0 742 612 50 re f');
|
||||
ops.push('1 1 1 rg');
|
||||
ops.push('BT /F1 16 Tf 36 760 Td (Verae Time) Tj ET');
|
||||
ops.push('BT /F1 9 Tf 36 746 Td (CERTIFIED RETRIEVAL RECEIPT) Tj ET');
|
||||
ops.push('0.09 0.10 0.15 rg');
|
||||
let y = 710;
|
||||
for (const line of lines) {
|
||||
if (line.kind === 'gap') {
|
||||
y -= 8;
|
||||
continue;
|
||||
}
|
||||
const size = line.kind === 'label' ? 8 : 11;
|
||||
ops.push(`BT /F1 ${size} Tf 36 ${y} Td (${pdfEscape(line.text)}) Tj ET`);
|
||||
y -= line.kind === 'label' ? 12 : 14;
|
||||
}
|
||||
ops.push('0.192 0.180 0.506 rg');
|
||||
ops.push('36 48 540 0.8 re f');
|
||||
ops.push('0.42 0.44 0.52 rg');
|
||||
ops.push(
|
||||
'BT /F1 8 Tf 36 34 Td (This is a certified retrieval receipt. The extra-seal event is recorded with the hash. It is not a substitute for the chain record.) Tj ET',
|
||||
);
|
||||
ops.push(
|
||||
`BT /F1 8 Tf 36 22 Td (${pdfEscape('Verae Time x Zapier · type ' + (receipt.type || 'verae.retrieval-receipt'))}) Tj ET`,
|
||||
);
|
||||
|
||||
const stream = `${ops.join('\n')}\n`;
|
||||
const objects = [
|
||||
'1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj',
|
||||
'2 0 obj << /Type /Pages /Kids [3 0 R] /Count 1 >> endobj',
|
||||
'3 0 obj << /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >> endobj',
|
||||
`4 0 obj << /Length ${Buffer.byteLength(stream)} >> stream\n${stream}endstream endobj`,
|
||||
'5 0 obj << /Type /Font /Subtype /Type1 /BaseFont /Helvetica >> endobj',
|
||||
];
|
||||
|
||||
let offset = '%PDF-1.4\n'.length;
|
||||
const xref = [0];
|
||||
let body = '%PDF-1.4\n';
|
||||
for (const obj of objects) {
|
||||
xref.push(offset);
|
||||
const chunk = `${obj}\n`;
|
||||
body += chunk;
|
||||
offset += Buffer.byteLength(chunk);
|
||||
}
|
||||
const xrefStart = offset;
|
||||
let xrefTable = `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n`;
|
||||
for (let i = 1; i < xref.length; i += 1) {
|
||||
xrefTable += `${String(xref[i]).padStart(10, '0')} 00000 n \n`;
|
||||
}
|
||||
body += xrefTable;
|
||||
body += `trailer << /Size ${objects.length + 1} /Root 1 0 R >>\nstartxref\n${xrefStart}\n%%EOF\n`;
|
||||
return Buffer.from(body, 'utf8');
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue