feat: add payment module
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import { serialize } from "node:v8";
|
||||
|
||||
import { takeAll, takeOne } from "@platform/parse";
|
||||
import postgres, { type Options, type Sql, type TransactionSql } from "postgres";
|
||||
import transit from "transit-js";
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
import { takeAll, takeOne } from "./parser.ts";
|
||||
|
||||
const storage = new AsyncLocalStorage<TransactionSql>();
|
||||
|
||||
const transitReader = transit.reader("json");
|
||||
const transitWriter = transit.writer("json");
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Database
|
||||
@@ -24,7 +28,16 @@ export class Client {
|
||||
*
|
||||
* @param db - Dependency container token to retrieve.
|
||||
*/
|
||||
constructor(readonly config: Options<{}>) {}
|
||||
constructor(
|
||||
readonly config: Options<{
|
||||
transit: {
|
||||
to: 16384;
|
||||
from: [16384];
|
||||
serialize: (value: unknown) => string;
|
||||
parse: (value: unknown) => any;
|
||||
};
|
||||
}>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* SQL instance to perform queries against.
|
||||
@@ -51,7 +64,34 @@ export class Client {
|
||||
*/
|
||||
#getResolvedInstance(): Sql {
|
||||
if (this.#db === undefined) {
|
||||
this.#db = postgres(this.config);
|
||||
this.#db = postgres({
|
||||
...this.config,
|
||||
connection: {
|
||||
fallback_output_format: "transit",
|
||||
},
|
||||
types: {
|
||||
transit: {
|
||||
to: 16384,
|
||||
from: [16384],
|
||||
serialize: (value: unknown) => {
|
||||
return transitWriter.write(value);
|
||||
},
|
||||
parse: (value: string) => {
|
||||
return transitReader.read(value);
|
||||
},
|
||||
},
|
||||
int64: {
|
||||
from: [20],
|
||||
parse: (value: string) => {
|
||||
const res = parseInt(value, 10);
|
||||
if (Number.isSafeInteger(res) === false) {
|
||||
throw Error(`Could not convert to integer reliably: ${value}`);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
} as unknown as postgres.PostgresType,
|
||||
},
|
||||
});
|
||||
}
|
||||
return this.#db;
|
||||
}
|
||||
@@ -106,6 +146,30 @@ export class Client {
|
||||
many: (strings: TemplateStringsArray, ...values: any[]) => this.sql(strings, ...values).then(takeAll(schema)),
|
||||
};
|
||||
}
|
||||
|
||||
boolean(value: boolean) {
|
||||
return this.sql.typed(value, 16);
|
||||
}
|
||||
|
||||
int64(value: number) {
|
||||
return this.sql.typed(value, 20);
|
||||
}
|
||||
|
||||
int32(value: number) {
|
||||
return this.sql.typed(value, 23);
|
||||
}
|
||||
|
||||
text(value: string) {
|
||||
return this.sql.typed(value, 25);
|
||||
}
|
||||
|
||||
float64(value: number) {
|
||||
return this.sql.typed(value, 701);
|
||||
}
|
||||
|
||||
transit(value: object) {
|
||||
return this.sql.typed(value, 16384);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import { getEnvironmentVariable } from "@platform/config/environment.ts";
|
||||
import { getEnvironmentVariable } from "@platform/config";
|
||||
import z from "zod";
|
||||
|
||||
export const config = {
|
||||
xtdb: {
|
||||
host: getEnvironmentVariable({
|
||||
key: "DB_XTDB_HOST",
|
||||
type: z.string(),
|
||||
fallback: "localhost",
|
||||
}),
|
||||
port: getEnvironmentVariable({
|
||||
key: "DB_XTDB_PORT",
|
||||
type: z.coerce.number(),
|
||||
fallback: "5432",
|
||||
}),
|
||||
user: getEnvironmentVariable({
|
||||
key: "DB_XTDB_USER",
|
||||
type: z.string(),
|
||||
fallback: "xtdb",
|
||||
}),
|
||||
pass: getEnvironmentVariable({
|
||||
key: "DB_XTDB_PASSWORD",
|
||||
type: z.string(),
|
||||
fallback: "xtdb",
|
||||
}),
|
||||
},
|
||||
host: getEnvironmentVariable({
|
||||
key: "DB_XTDB_HOST",
|
||||
type: z.string(),
|
||||
fallback: "localhost",
|
||||
}),
|
||||
port: getEnvironmentVariable({
|
||||
key: "DB_XTDB_PORT",
|
||||
type: z.coerce.number(),
|
||||
fallback: "5432",
|
||||
}),
|
||||
user: getEnvironmentVariable({
|
||||
key: "DB_XTDB_USER",
|
||||
type: z.string(),
|
||||
fallback: "xtdb",
|
||||
}),
|
||||
pass: getEnvironmentVariable({
|
||||
key: "DB_XTDB_PASSWORD",
|
||||
type: z.string(),
|
||||
fallback: "xtdb",
|
||||
}),
|
||||
};
|
||||
|
||||
6
platform/database/mod.ts
Normal file
6
platform/database/mod.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Client } from "./client.ts";
|
||||
import { config } from "./config.ts";
|
||||
|
||||
export * from "./client.ts";
|
||||
|
||||
export const db = new Client(config);
|
||||
@@ -3,9 +3,16 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./mod.ts",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@platform/config": "workspace:*",
|
||||
"@platform/parse": "workspace:*",
|
||||
"@types/transit-js": "0.8.3",
|
||||
"postgres": "3.4.7",
|
||||
"zod": "4.1.12"
|
||||
"transit-js": "0.8.874",
|
||||
"zod": "4.1.13"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
import type z from "zod";
|
||||
import type { ZodType } from "zod";
|
||||
|
||||
/**
|
||||
* Takes a single record from a list of database rows.
|
||||
*
|
||||
* @param rows - List of rows to retrieve record from.
|
||||
*/
|
||||
export function takeOne<TSchema extends ZodType>(
|
||||
schema: TSchema,
|
||||
): (records: unknown[]) => z.output<TSchema> | undefined {
|
||||
return (records: unknown[]) => {
|
||||
if (records[0] === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return schema.parse(records[0]);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes all records from a list of database rows and validates each one.
|
||||
*
|
||||
* @param schema - Zod schema to validate each record against.
|
||||
*/
|
||||
export function takeAll<TSchema extends ZodType>(schema: TSchema): (records: unknown[]) => z.output<TSchema>[] {
|
||||
return (records: unknown[]) => {
|
||||
return records.map((record) => schema.parse(record));
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user