Files
Investidor-V2/resources/js/lib/iva-offer-package.ts
T

60 lines
2.0 KiB
TypeScript

import JSZip from 'jszip';
import type { OfferPreparation } from './iva-offer-preparations.ts';
import {
recordOfferWorkflow,
offerAttachmentValid,
offerWrittenRequest,
} from './iva-offer-workflow.ts';
export async function buildOfferPackage(
row: OfferPreparation,
load: (url: string) => Promise<ArrayBuffer>,
) {
const item = recordOfferWorkflow(row, 'form'),
w = item.workflow!,
zip = new JSZip();
for (const [folder, attachment] of [
['despacho', w.decisionAttachment],
['formulario', w.formAttachment],
] as const) {
if (!attachment) continue;
if (!offerAttachmentValid(attachment))
throw Error('Referência de anexo inválida.');
const bytes = await load(attachment.url),
hash = Array.from(
new Uint8Array(await crypto.subtle.digest('SHA-256', bytes)),
)
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
if (hash !== attachment.sha256)
throw Error(
'O anexo diverge do hash registado;conjunto não emitido.',
);
zip.file(
folder + '/' + attachment.name.replace(/[^\p{L}\p{N}._-]/gu, '_'),
bytes,
);
}
zip.file('pedido.txt', offerWrittenRequest(item, w));
zip.file(
'preparacao-formulario.txt',
`${w.formName}\nFonte/aplicabilidade:${w.formSource}\n${w.formContent}\nDespacho:${item.request?.decisionRef};SHA256:${w.decisionAttachment!.sha256}\nApresentação fora do InvesteMoz.`,
);
zip.file(
'manifesto.json',
JSON.stringify(
{
branch: item.branch,
request: item.request,
workflow: w,
scope: 'Submissão externa;conteúdo de preparação e anexos,não recibo de entrega à autoridade.',
},
null,
2,
),
);
return {
row: item,
bytes: await zip.generateAsync({ type: 'uint8array' }),
};
}