fix: expose client fetch and signed adjustments
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/metering",
|
||||
"version": "0.8.2",
|
||||
"version": "0.8.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
|
||||
@@ -90,6 +90,10 @@ export function defineMeter(options: MeterOptions) {
|
||||
Number.isSafeInteger(units) && units > 0
|
||||
? null
|
||||
: { ok: false, reason: `${label} must be a positive whole number` };
|
||||
const validSigned = (units: number): MeterResult | null =>
|
||||
Number.isSafeInteger(units) && units !== 0
|
||||
? null
|
||||
: { ok: false, reason: `${label} adjustment must be a non-zero whole number` };
|
||||
const fault = (error: unknown, operation: string): MeterResult => {
|
||||
options.onFault?.(error, operation);
|
||||
return {
|
||||
@@ -138,7 +142,15 @@ export function defineMeter(options: MeterOptions) {
|
||||
add("purchase", subjectId, units, reason, reference),
|
||||
refund: (subjectId: string, units: number, reason: string, reference = "") =>
|
||||
add("refund", subjectId, units, reason, reference),
|
||||
adjust: (subjectId: string, units: number, reason: string, reference = "") =>
|
||||
add("adjust", subjectId, units, reason, reference),
|
||||
async adjust(subjectId: string, units: number, reason: string, reference = "") {
|
||||
const invalid = validSigned(units);
|
||||
if (invalid) return invalid;
|
||||
try {
|
||||
await options.store.write(subjectId, units, "adjust", reason, reference);
|
||||
return { ok: true } as const;
|
||||
} catch (error) {
|
||||
return fault(error, "adjust");
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -40,3 +40,27 @@ test("meter distinguishes refusals from storage faults", async () => {
|
||||
fault: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("adjust accepts signed non-zero amounts while other additions stay positive", async () => {
|
||||
const writes: number[] = [];
|
||||
const meter = defineMeter({
|
||||
store: {
|
||||
balance: async () => 0,
|
||||
reserve: async () => true,
|
||||
write: async (_subject, units) => {
|
||||
writes.push(units);
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(await meter.adjust("u1", -25, "correction")).toEqual({ ok: true });
|
||||
expect(await meter.adjust("u1", 10, "correction")).toEqual({ ok: true });
|
||||
expect(await meter.adjust("u1", 0, "correction")).toEqual({
|
||||
ok: false,
|
||||
reason: "units adjustment must be a non-zero whole number",
|
||||
});
|
||||
expect(await meter.grant("u1", -1, "invalid")).toEqual({
|
||||
ok: false,
|
||||
reason: "units must be a positive whole number",
|
||||
});
|
||||
expect(writes).toEqual([-25, 10]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user