60 lines
2.0 KiB
TypeScript
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' }),
|
|
};
|
|
}
|