0.1.6Updated a month ago
import type { PostgresClient } from "@infinity-beyond/modules/data_store/postgres.ts";

type CleanupMethod = (rows: any[]) => any[];

export class DataTypeQuery<ArgumentFormat extends any[], MapData extends Record<string, any>, ReturnType = any> {
  readonly query: string
  readonly cleanup?: CleanupMethod;

  constructor(query: string, cleanup?: CleanupMethod) {
    this.query = query;
    this.cleanup = cleanup;
  }

  populate(classInstance: MapData) {
    return MappedDataTypeQuery<ArgumentFormat, MapData, ReturnType>(this, classInstance);
  }
}

const MappedDataTypeQuery = <
  ArgumentFormat extends any[],
  MapData extends Record<string, any>,
  ReturnType = any
>(parent: DataTypeQuery<ArgumentFormat, MapData>, classInstance: MapData) => {
  const mapped_query: string = parent.query.replace(/\{(\w+)\}/g, (_, name: string) => {
    if(Object.hasOwn(classInstance, name)) return classInstance[name];

    return `{${name}}`;
  });

  return {
    async execute(client: PostgresClient, ...args: ArgumentFormat) {
      const response = (await client.query<ReturnType>(...[ mapped_query, args ]));
  
      if(parent.cleanup) {
        response.rows = parent.cleanup(response.rows);
      }
  
      return response;
    }
  }
}