bradb 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,5 +2,5 @@ export * from './src/types';
2
2
  export * from './src/controller';
3
3
  export * from './src/standard';
4
4
  export * from './src/relational';
5
- export * from './src/utils';
5
+ export * from './src/filters';
6
6
  export * from './src/errors';
package/dist/index.js CHANGED
@@ -18,5 +18,5 @@ __exportStar(require("./src/types"), exports);
18
18
  __exportStar(require("./src/controller"), exports);
19
19
  __exportStar(require("./src/standard"), exports);
20
20
  __exportStar(require("./src/relational"), exports);
21
- __exportStar(require("./src/utils"), exports);
21
+ __exportStar(require("./src/filters"), exports);
22
22
  __exportStar(require("./src/errors"), exports);
@@ -2,12 +2,12 @@ import { PgTable } from "drizzle-orm/pg-core";
2
2
  import { Request, Response } from "express";
3
3
  import { z } from "zod";
4
4
  import { CRUDService } from "./types";
5
- export declare class BaseController<T extends PgTable> {
6
- protected service: CRUDService;
7
- private schema;
5
+ export declare class BaseController<T extends PgTable, FSchema extends z.ZodObject> {
6
+ protected service: CRUDService<FSchema>;
7
+ private filterSchema;
8
8
  private createSchema;
9
9
  private updateSchema;
10
- constructor(service: CRUDService, base: z.ZodObject, filter: z.ZodSchema<Partial<T["$inferSelect"]>>);
10
+ constructor(service: CRUDService<FSchema>, base: z.ZodObject, filter: FSchema);
11
11
  getAll: (req: Request, res: Response) => Promise<void>;
12
12
  getById: (req: Request, res: Response) => Promise<void>;
13
13
  create: (req: Request, res: Response) => Promise<void>;
@@ -4,10 +4,10 @@ exports.BaseController = void 0;
4
4
  class BaseController {
5
5
  constructor(service, base, filter) {
6
6
  this.getAll = async (req, res) => {
7
- const filters = getFilters(req, this.schema.filter);
7
+ const filters = getFilters(req, this.filterSchema);
8
8
  const pagination = getPagination(req);
9
9
  const [items, total] = await Promise.all([
10
- this.service.findAll({ pagination, filters }),
10
+ this.service.findAll(filters, pagination.page, pagination.pageSize),
11
11
  this.service.count(filters)
12
12
  ]);
13
13
  res.status(200).json({
@@ -42,7 +42,7 @@ class BaseController {
42
42
  });
43
43
  // @ts-expect-error infer schema
44
44
  this.updateSchema = base.partial();
45
- this.schema = { base, filter };
45
+ this.filterSchema = filter;
46
46
  }
47
47
  }
48
48
  exports.BaseController = BaseController;
@@ -0,0 +1,4 @@
1
+ import { SQL } from "drizzle-orm";
2
+ import { Filter, FilterMap } from "./types";
3
+ import { ZodObject } from "zod";
4
+ export declare function buildFilters<FSchema extends ZodObject>(map: FilterMap<FSchema>, filters?: Filter<FSchema>): SQL<unknown> | undefined;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFilters = buildFilters;
4
+ const drizzle_orm_1 = require("drizzle-orm");
5
+ function buildFilters(map, filters) {
6
+ const conditions = [];
7
+ if (!filters)
8
+ return undefined;
9
+ for (const f of Object.keys(filters)) {
10
+ if (f in map) {
11
+ const func = map[f];
12
+ const value = filters[f];
13
+ if (value !== undefined && value !== null) {
14
+ conditions.push(func(value));
15
+ }
16
+ }
17
+ }
18
+ return conditions.length ? (0, drizzle_orm_1.and)(...conditions) : undefined;
19
+ }
@@ -1,5 +1,8 @@
1
- import { FilterMap, FindAllOptions } from "../src/types";
2
- import { DBQueryConfig, TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm";
1
+ import { Filter, FilterMap } from "../src/types";
2
+ import { BuildQueryResult, DBQueryConfig, TableRelationalConfig, TablesRelationalConfig } from "drizzle-orm";
3
3
  import { RelationalQueryBuilder } from "drizzle-orm/pg-core/query-builders/query";
4
- export declare function findAllRelational<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig, TTableConfig extends TableRelationalConfig = TableRelationalConfig>(map: FilterMap<any>, q: RelationalQueryBuilder<TSchema, TFields>, config: DBQueryConfig<any, true, TSchema, TTableConfig>): (options: FindAllOptions<any>) => Promise<(({ [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; } | undefined extends Record<string, unknown> ? { [Key in (import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]) & string as Key]: { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["notNull"] extends true ? { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["data"] : { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["data"] | null; } extends infer T_1 ? { [K_2 in keyof T_1]: T_1[K_2]; } : never : { [Key_1 in keyof TFields["columns"] & string as Key_1]: TFields["columns"][Key_1]["_"]["notNull"] extends true ? TFields["columns"][Key_1]["_"]["data"] : TFields["columns"][Key_1]["_"]["data"] | null; } extends infer T_2 ? { [K_4 in keyof T_2]: T_2[K_4]; } : never) & {} & ({ [K_5 in keyof TTableConfig["relations"]]?: true | DBQueryConfig<TTableConfig["relations"][K_5] extends import("drizzle-orm").One<string, boolean> ? "one" : "many", false, TSchema, import("drizzle-orm").FindTableByDBName<TSchema, TTableConfig["relations"][K_5]["referencedTableName"]>> | undefined; } | undefined extends Record<string, unknown> ? import("drizzle-orm").BuildRelationResult<TSchema, Record<string, unknown> & { [K_5 in keyof TTableConfig["relations"]]?: true | DBQueryConfig<TTableConfig["relations"][K_5] extends import("drizzle-orm").One<string, boolean> ? "one" : "many", false, TSchema, import("drizzle-orm").FindTableByDBName<TSchema, TTableConfig["relations"][K_5]["referencedTableName"]>> | undefined; }, TFields["relations"]> : {}) extends infer T ? { [K in keyof T]: T[K]; } : never)[]>;
5
- export declare function findOneRelational<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig, TTableConfig extends TableRelationalConfig = TableRelationalConfig>(q: RelationalQueryBuilder<TSchema, TFields>, config: DBQueryConfig<any, true, TSchema, TTableConfig>): (id: number) => Promise<({ [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; } | undefined extends Record<string, unknown> ? { [Key in (import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]) & string as Key]: { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["notNull"] extends true ? { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["data"] : { [K_4 in import("drizzle-orm").Equal<Exclude<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[(string | keyof TTableConfig["columns"]) & keyof TFields["columns"]], undefined>, false> extends true ? Exclude<keyof TFields["columns"], import("drizzle-orm").NonUndefinedKeysOnly<Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; }>> : { [K_3 in keyof (Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })]: import("drizzle-orm").Equal<(Record<string, unknown> & { [K_1 in keyof TTableConfig["columns"]]?: boolean | undefined; })[K_3], true> extends true ? K_3 : never; }[string | keyof TTableConfig["columns"]] & keyof TFields["columns"]]: TFields["columns"][K_4]; }[Key]["_"]["data"] | null; } extends infer T_1 ? { [K_2 in keyof T_1]: T_1[K_2]; } : never : { [Key_1 in keyof TFields["columns"] & string as Key_1]: TFields["columns"][Key_1]["_"]["notNull"] extends true ? TFields["columns"][Key_1]["_"]["data"] : TFields["columns"][Key_1]["_"]["data"] | null; } extends infer T_2 ? { [K_4 in keyof T_2]: T_2[K_4]; } : never) & {} & ({ [K_5 in keyof TTableConfig["relations"]]?: true | DBQueryConfig<TTableConfig["relations"][K_5] extends import("drizzle-orm").One<string, boolean> ? "one" : "many", false, TSchema, import("drizzle-orm").FindTableByDBName<TSchema, TTableConfig["relations"][K_5]["referencedTableName"]>> | undefined; } | undefined extends Record<string, unknown> ? import("drizzle-orm").BuildRelationResult<TSchema, Record<string, unknown> & { [K_5 in keyof TTableConfig["relations"]]?: true | DBQueryConfig<TTableConfig["relations"][K_5] extends import("drizzle-orm").One<string, boolean> ? "one" : "many", false, TSchema, import("drizzle-orm").FindTableByDBName<TSchema, TTableConfig["relations"][K_5]["referencedTableName"]>> | undefined; }, TFields["relations"]> : {}) extends infer T ? { [K in keyof T]: T[K]; } : never>;
4
+ import { ZodObject } from "zod";
5
+ export declare function RelationalBuilder<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig, FSchema extends ZodObject>(q: RelationalQueryBuilder<TSchema, TFields>, filterMap: FilterMap<FSchema>): {
6
+ findAll<TConfig extends DBQueryConfig<"many", true, TSchema, TFields>>(config?: TConfig): (filters?: Filter<FSchema>, page?: number, pageSize?: number) => Promise<BuildQueryResult<TSchema, TFields, TConfig>[]>;
7
+ findOne<TSelection extends Omit<DBQueryConfig<"many", true, TSchema, TFields>, "limit">>(config?: DBQueryConfig<any, true, TSchema, TFields>): (id: number) => Promise<BuildQueryResult<TSchema, TFields, TSelection>>;
8
+ };
@@ -1,34 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findAllRelational = findAllRelational;
4
- exports.findOneRelational = findOneRelational;
3
+ exports.RelationalBuilder = RelationalBuilder;
5
4
  const drizzle_orm_1 = require("drizzle-orm");
6
- const utils_1 = require("./utils");
7
- function findAllRelational(map, q, config) {
8
- return async (options) => {
9
- const { offset, limit } = (0, utils_1.getPagination)(options);
10
- const conditions = (0, utils_1.getConditions)(options, map);
11
- const items = q.findMany({
12
- ...config,
13
- where: (table, { isNull }) => (0, drizzle_orm_1.and)(isNull(table.deletedAt), ...conditions),
14
- limit: limit,
15
- offset: offset
16
- });
17
- return items;
5
+ const filters_1 = require("./filters");
6
+ const errors_1 = require("./errors");
7
+ const pg_core_1 = require("drizzle-orm/pg-core");
8
+ function RelationalBuilder(q, filterMap) {
9
+ const baseWhere = (table) => (0, drizzle_orm_1.isNull)(table.deletedAt);
10
+ return {
11
+ findAll(config) {
12
+ return async (filters, page = 1, pageSize = 10) => {
13
+ const offset = (page - 1) * pageSize;
14
+ const items = q.findMany({
15
+ ...config,
16
+ where: (table) => (0, drizzle_orm_1.and)(baseWhere(table), (0, filters_1.buildFilters)(filterMap, filters)),
17
+ limit: pageSize,
18
+ offset
19
+ });
20
+ return items;
21
+ };
22
+ },
23
+ findOne(config) {
24
+ return async (id) => {
25
+ const result = await q.findFirst({
26
+ ...config,
27
+ // TODO: Validate table contains 'id' field
28
+ where: (table, { eq }) => (0, drizzle_orm_1.and)(baseWhere(table), eq(table.id, id))
29
+ });
30
+ if (!result) {
31
+ // TODO: proper name
32
+ const t = "record";
33
+ throw new errors_1.NotFound(`${t} with id ${id} not found`);
34
+ }
35
+ return result;
36
+ };
37
+ }
18
38
  };
19
39
  }
20
- function findOneRelational(q, config) {
21
- return async (id) => {
22
- const result = await q.findFirst({
23
- ...config,
24
- // TODO: Validate table contains 'id' field
25
- where: (table, { eq, isNull }) => (0, drizzle_orm_1.and)(isNull(table.deletedAt), eq(table.id, id))
26
- });
27
- if (!result) {
28
- // TODO: proper name
29
- const t = "tabla";
30
- throw new Error(`${t} with id ${id} not found`);
40
+ function findByPkConditions(table, data) {
41
+ const { primaryKeys } = (0, pg_core_1.getTableConfig)(table);
42
+ const conditions = [];
43
+ for (const pk of primaryKeys) {
44
+ for (const column of pk.columns) {
45
+ const name = column.name;
46
+ // if (data[name] === undefined || data[name] === null) {
47
+ // throw new Error(`Missing value for pk column: ${column.name}`);
48
+ // }
49
+ conditions.push((0, drizzle_orm_1.eq)(table[name], data[name]));
31
50
  }
32
- return result;
33
- };
51
+ }
52
+ return conditions;
34
53
  }
@@ -1,24 +1,19 @@
1
- import { Filter, FilterMap, FindAllOptions, PrimaryKeyType, Table } from "./types";
1
+ import { Filter, FilterMap, PrimaryKeyType, Table } from "./types";
2
2
  import { PgSelect } from "drizzle-orm/pg-core";
3
3
  import { NodePgDatabase } from "drizzle-orm/node-postgres";
4
4
  import { InferInsertModel } from "drizzle-orm";
5
- export declare class ServiceBuilder<T extends Table, TSchema extends Record<string, unknown>> {
5
+ import { ZodObject } from "zod";
6
+ export declare class ServiceBuilder<T extends Table, TSchema extends Record<string, unknown>, FSchema extends ZodObject> {
6
7
  private readonly db;
7
8
  private readonly table;
8
9
  private readonly map;
9
10
  readonly tableName: string;
10
- constructor(db: NodePgDatabase<TSchema>, table: T, map: FilterMap<T>);
11
- findOne<S extends PgSelect>(select: S): (id: number) => Promise<{
12
- [x: string]: any;
13
- } | {
14
- [x: string]: any;
15
- } | {
16
- [x: string]: any;
17
- }>;
18
- findAll<S extends PgSelect<T["_"]["name"]>>(select: S): (options: FindAllOptions<T>) => Promise<({ [Key in keyof T["_"]["columns"] & string as Key]: T["_"]["columns"][Key]["_"]["notNull"] extends true ? T["_"]["columns"][Key]["_"]["data"] : T["_"]["columns"][Key]["_"]["data"] | null; } extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never)[]>;
11
+ constructor(db: NodePgDatabase<TSchema>, table: T, map: FilterMap<FSchema>);
12
+ findOne<S extends PgSelect>(select: S): (id: number) => Promise<S>;
13
+ findAll<S extends PgSelect>(select: S): (filters?: Filter<FSchema>, page?: number, pageSize?: number) => Promise<S>;
19
14
  create(): (data: InferInsertModel<T>) => Promise<{ [Key in keyof T["_"]["columns"] & string as Key]: T["_"]["columns"][Key]["_"]["notNull"] extends true ? T["_"]["columns"][Key]["_"]["data"] : T["_"]["columns"][Key]["_"]["data"] | null; } extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never>;
20
15
  update(): (id: PrimaryKeyType<T>, data: Partial<InferInsertModel<T>>) => Promise<{ [Key in keyof T["_"]["columns"] & string as Key]: T["_"]["columns"][Key]["_"]["notNull"] extends true ? T["_"]["columns"][Key]["_"]["data"] : T["_"]["columns"][Key]["_"]["data"] | null; } extends infer T_1 ? { [K in keyof T_1]: T_1[K]; } : never>;
21
16
  softDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
22
17
  hardDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
23
- count(): (filters: Filter<T>) => Promise<number>;
18
+ count(): (filters?: Filter<FSchema>) => Promise<number>;
24
19
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ServiceBuilder = void 0;
4
4
  const drizzle_orm_1 = require("drizzle-orm");
5
- const utils_1 = require("./utils");
5
+ const filters_1 = require("./filters");
6
6
  const errors_1 = require("./errors");
7
7
  class ServiceBuilder {
8
8
  constructor(db, table, map) {
@@ -14,22 +14,18 @@ class ServiceBuilder {
14
14
  findOne(select) {
15
15
  return async (id) => {
16
16
  const result = await select.where((0, drizzle_orm_1.eq)(this.table.id, id));
17
- if (result.length == 0) {
17
+ if (!result)
18
18
  throw notFoundWithId(this.tableName, id);
19
- }
20
- return result[0];
19
+ return result;
21
20
  };
22
21
  }
23
22
  findAll(select) {
24
- return async (options) => {
25
- const { offset, limit } = (0, utils_1.getPagination)(options);
26
- const conditions = (0, utils_1.getConditions)(options, this.map);
27
- const items = select
28
- .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.isNull)(this.table.deletedAt), ...conditions))
29
- .limit(limit)
30
- .offset(offset)
31
- .execute();
32
- return items;
23
+ return async (filters, page = 1, pageSize = 10) => {
24
+ const offset = (page - 1) * pageSize;
25
+ return await select
26
+ .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.isNull)(this.table.deletedAt), (0, filters_1.buildFilters)(this.map, filters)))
27
+ .limit(pageSize)
28
+ .offset(offset);
33
29
  };
34
30
  }
35
31
  create() {
@@ -85,7 +81,7 @@ class ServiceBuilder {
85
81
  const [result] = await this.db
86
82
  .select({ count: (0, drizzle_orm_1.count)() })
87
83
  .from(this.table)
88
- .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.isNull)(this.table.deletedAt), (0, utils_1.buildWhere)(filters, this.map)));
84
+ .where((0, drizzle_orm_1.and)((0, drizzle_orm_1.isNull)(this.table.deletedAt), (0, filters_1.buildFilters)(this.map, filters)));
89
85
  return result.count;
90
86
  };
91
87
  }
@@ -1,27 +1,31 @@
1
1
  import { SQL } from "drizzle-orm";
2
- import { PgColumn, PgTable } from "drizzle-orm/pg-core";
3
- export interface CRUDService {
2
+ import { AnyPgTable, PgColumn } from "drizzle-orm/pg-core";
3
+ import z, { ZodObject } from "zod";
4
+ export interface CRUDService<FSchema extends ZodObject> {
4
5
  findOne: (id: any) => Promise<any>;
5
- findAll: (options: FindAllOptions<any>) => Promise<any>;
6
- count: (filters: Filter<any>) => Promise<number>;
6
+ findAll: (filters?: Filter<FSchema>, page?: number, pageSize?: number) => Promise<any>;
7
+ count: (filters: Filter<FSchema>) => Promise<number>;
7
8
  create: (data: any) => Promise<any>;
8
9
  update: (id: any, data: Partial<any>) => Promise<any>;
9
10
  delete: (id: any) => Promise<any>;
10
11
  }
12
+ export type PrimaryKeyData<TTable extends AnyPgTable> = {
13
+ [K in keyof TTable["_"]["columns"] as TTable["_"]["columns"][K] extends {
14
+ _: {
15
+ isPrimaryKey: true;
16
+ };
17
+ } ? K : never]: TTable["_"]["columns"][K]["_"]["data"];
18
+ };
11
19
  export interface PaginationParams {
12
20
  page: number;
13
21
  pageSize: number;
14
22
  }
15
- export interface FindAllOptions<T extends PgTable> {
16
- pagination?: PaginationParams;
17
- filters?: Filter<T>;
18
- }
19
- export type Table = PgTable & {
23
+ export type Table = AnyPgTable & {
20
24
  id: PgColumn;
21
25
  deletedAt: PgColumn;
22
26
  };
23
- export type PrimaryKeyType<T extends PgTable> = T["_"]["columns"]["id"]["_"]["data"];
24
- export type Filter<T extends PgTable> = Partial<T["$inferSelect"]>;
25
- export type FilterMap<T extends PgTable> = {
26
- [K in keyof T["$inferSelect"]]?: (value: T["$inferSelect"][K]) => SQL;
27
+ export type PrimaryKeyType<T extends AnyPgTable> = T["_"]["columns"]["id"]["_"]["data"];
28
+ export type FilterMap<Schema extends z.ZodObject, Out = z.infer<Schema>> = {
29
+ [K in keyof Out]: (value: NonNullable<Out[K]>) => SQL;
27
30
  };
31
+ export type Filter<Schema extends ZodObject> = z.infer<Schema>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bradb",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,9 +0,0 @@
1
- import { PgTable } from "drizzle-orm/pg-core";
2
- import { SQL } from "drizzle-orm";
3
- import { Filter, FilterMap, FindAllOptions } from "./types";
4
- export declare function buildWhere<T extends PgTable>(filters: Filter<T>, map: FilterMap<T>): SQL<unknown> | undefined;
5
- export declare function getPagination<T extends PgTable>(options?: FindAllOptions<T>): {
6
- offset: number;
7
- limit: number;
8
- };
9
- export declare function getConditions<T extends PgTable>(options: FindAllOptions<any> | undefined, map: FilterMap<T>): SQL<unknown>[];
package/dist/src/utils.js DELETED
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildWhere = buildWhere;
4
- exports.getPagination = getPagination;
5
- exports.getConditions = getConditions;
6
- const drizzle_orm_1 = require("drizzle-orm");
7
- function buildWhere(filters, map) {
8
- const conditions = [];
9
- // iteramos sólo sobre las claves de 'map'
10
- for (const key of Object.keys(map)) {
11
- const value = filters[key];
12
- if (value !== undefined) {
13
- // TS sabe que `value` es M[typeof key]
14
- if (map[key]) {
15
- conditions.push(map[key](value));
16
- }
17
- }
18
- }
19
- return conditions.length ? (0, drizzle_orm_1.and)(...conditions) : undefined;
20
- }
21
- function withPagination(qb, pagination) {
22
- return qb.limit(pagination.pageSize).offset(pagination.page * pagination.pageSize);
23
- }
24
- function withFilters(table, qb, filters, map) {
25
- return qb.where(buildWhere(filters, map));
26
- }
27
- function getPagination(options = {}) {
28
- const page = options.pagination?.page || 1;
29
- const limit = options.pagination?.pageSize || 10;
30
- const offset = (page - 1) * limit;
31
- return { offset, limit };
32
- }
33
- function getConditions(options = {}, map) {
34
- const { filters } = options;
35
- const conditions = [];
36
- if (filters) {
37
- const whereSql = buildWhere(filters, map);
38
- conditions.push(whereSql);
39
- }
40
- return conditions;
41
- }