feat: package continuity plugin MVP docs and receipt store
This commit is contained in:
44
plugins/continuity/src/continuity/receipt-store.mjs
Normal file
44
plugins/continuity/src/continuity/receipt-store.mjs
Normal file
@@ -0,0 +1,44 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
function isNonEmptyString(value) {
|
||||
return typeof value === 'string' && value.trim().length > 0;
|
||||
}
|
||||
|
||||
export function slugifyReceiptSegment(value) {
|
||||
if (!isNonEmptyString(value)) return '';
|
||||
return value
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9._-]+/g, '-')
|
||||
.replace(/-+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
}
|
||||
|
||||
export function buildReceiptFilename({ planId, dispatchRunId }) {
|
||||
const planIdSafe = slugifyReceiptSegment(planId);
|
||||
const dispatchRunIdSafe = slugifyReceiptSegment(dispatchRunId);
|
||||
return {
|
||||
planIdSafe,
|
||||
dispatchRunIdSafe,
|
||||
filename: (planIdSafe && dispatchRunIdSafe)
|
||||
? `receipt-${planIdSafe}-${dispatchRunIdSafe}.json`
|
||||
: '',
|
||||
};
|
||||
}
|
||||
|
||||
export async function writeReceipt({ receiptDir, receipt }) {
|
||||
if (!isNonEmptyString(receiptDir)) {
|
||||
throw new Error('receiptDir: expected non-empty string');
|
||||
}
|
||||
|
||||
const { filename, planIdSafe, dispatchRunIdSafe } = buildReceiptFilename(receipt ?? {});
|
||||
if (!filename) {
|
||||
throw new Error(`receipt filename segments invalid: planId=${JSON.stringify(planIdSafe)}, dispatchRunId=${JSON.stringify(dispatchRunIdSafe)}`);
|
||||
}
|
||||
|
||||
await fs.mkdir(receiptDir, { recursive: true });
|
||||
const receiptPath = path.join(receiptDir, filename);
|
||||
await fs.writeFile(receiptPath, `${JSON.stringify(receipt, null, 2)}\n`, 'utf8');
|
||||
return receiptPath;
|
||||
}
|
||||
Reference in New Issue
Block a user