48 lines
1.2 KiB
TypeScript
48 lines
1.2 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,
|
|
): 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;
|
|
}
|
|
|
|
repo.record({
|
|
customerId: customer.id,
|
|
endpointId,
|
|
cents: quote.totalCents,
|
|
metadataBytes,
|
|
attachmentBytes,
|
|
timestamp: new Date(),
|
|
});
|
|
res.locals.quote = quote;
|
|
next();
|
|
};
|
|
}
|