zappier-edge/src/meter.ts

51 lines
1.4 KiB
TypeScript

import { RequestHandler } from 'express';
import { PricingContext, Quote, quoteCall } from './pricing';
import { UsageRepo } from './usage';
export function meter(
endpointId: string,
repo: UsageRepo,
pricing: PricingContext,
onRecord?: (entry: { customerId: string; endpointId: string; cents: number }) => void,
): RequestHandler {
return (req, res, next) => {
const customer = req.customer;
if (!customer) {
res.status(401).json({ error: 'unauthenticated' });
return;
}
const metadataBytes = Buffer.byteLength(
JSON.stringify(req.body?.metadata ?? {}),
'utf8',
);
const files = (req.files as Express.Multer.File[] | undefined) ?? [];
const attachmentBytes = files.reduce((sum, f) => sum + f.size, 0);
let quote: Quote;
try {
quote = quoteCall(
pricing,
customer.tierId,
endpointId,
{ metadataBytes, attachmentBytes },
customer.multiplierOverride,
);
} catch (err) {
res.status(403).json({ error: (err as Error).message });
return;
}
const entry = {
customerId: customer.id,
endpointId,
cents: quote.totalCents,
metadataBytes,
attachmentBytes,
timestamp: new Date(),
};
repo.record(entry);
onRecord?.({ customerId: customer.id, endpointId, cents: quote.totalCents });
res.locals.quote = quote;
next();
};
}