import { Paginate, PaginationParams } from "@infinity-beyond/modules/pagination.ts";
import { REST_Wrapper } from "@infinity-beyond/classes/rest_wrapper.ts";
import { HandleBody } from "@infinity-beyond/infinity.ts";
import type { Ledger } from "@infinity-ledger/ledger.ts";
import type { LedgerEntry } from "@infinity-ledger/ledger.types/ledger.entry.ts";
export class LedgerRest<EntityName extends string> extends REST_Wrapper {
constructor(instance: Ledger<EntityName, any>) {
super();
this.post('/', async (req, ctx) => {
const { body, error_response} = await HandleBody<LedgerEntry>(req, (verify, entry) => {
verify(!!entry.key).fail('[key] not provided');
verify(typeof entry.amount == 'number').fail('[amount] must be a number');
verify(entry.source?.length > 0).fail('[source] must be a string, and have a value');
});
if(error_response) return error_response;
const response = await instance.ConsumeEntries({
key: body.key,
amount: body.amount,
source: body.source,
description: body.description,
reference: body.reference,
request_id: ctx.state.request.request_id
});
return Response.json(response, { status: response.success ? 200 : 400 });
});
this.get('/:key', async (req, ctx) => {
const key = ctx.params.key;
const { page, page_size } = PaginationParams(req);
const {
balance = 0,
entry_count: total_entries = 0,
history: entries = [],
} = await instance.UserData(key, page_size, page) ?? {};
return Response.json(Paginate(req, entries, total_entries, { balance, total_entries }));
});
this.post('/:key', async (req, ctx) => {
const { body, error_response} = await HandleBody<LedgerEntry>(req, (verify, entry) => {
verify(typeof entry.amount == 'number').fail('[amount] must be a number');
verify(entry.source?.length > 0).fail('[source] must be a string, and have a value');
});
if(error_response) return error_response;
const response = await instance.ConsumeEntries({
key: ctx.params.key,
amount: body.amount,
source: body.source,
description: body.description,
reference: body.reference,
request_id: ctx.state.request.request_id
});
return Response.json(response, { status: response.success ? 200 : 400 });
});
this.get('/:key/entry/:entry_id', async (_req, ctx) => {
const key = ctx.params.key;
const entry_id = Number(ctx.params.entry_id);
if(!Number.isSafeInteger(entry_id)) return Response.json({}, { status: 404 });
const entry_data = await instance.EntryData(entry_id);
if(!entry_data) return Response.json({}, { status: 404 });
if(entry_data.entry.key !== key) return Response.json({}, { status: 404 });
return Response.json(entry_data);
});
}
}