bradb 1.2.0 → 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 +1 -1
- package/dist/index.js +1 -1
- package/dist/src/controller.d.ts +4 -4
- package/dist/src/controller.js +3 -3
- package/dist/src/filters.d.ts +4 -0
- package/dist/src/filters.js +19 -0
- package/dist/src/relational.d.ts +7 -4
- package/dist/src/relational.js +46 -27
- package/dist/src/standard.d.ts +8 -21
- package/dist/src/standard.js +18 -19
- package/dist/src/types.d.ts +17 -13
- package/package.json +1 -1
- package/dist/src/utils.d.ts +0 -9
- package/dist/src/utils.js +0 -41
package/dist/index.d.ts
CHANGED
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/
|
|
21
|
+
__exportStar(require("./src/filters"), exports);
|
|
22
22
|
__exportStar(require("./src/errors"), exports);
|
package/dist/src/controller.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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>;
|
package/dist/src/controller.js
CHANGED
|
@@ -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.
|
|
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(
|
|
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.
|
|
45
|
+
this.filterSchema = filter;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
exports.BaseController = BaseController;
|
|
@@ -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
|
+
}
|
package/dist/src/relational.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
5
|
-
export declare function
|
|
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
|
+
};
|
package/dist/src/relational.js
CHANGED
|
@@ -1,34 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.findOneRelational = findOneRelational;
|
|
3
|
+
exports.RelationalBuilder = RelationalBuilder;
|
|
5
4
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
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
|
-
|
|
33
|
-
|
|
51
|
+
}
|
|
52
|
+
return conditions;
|
|
34
53
|
}
|
package/dist/src/standard.d.ts
CHANGED
|
@@ -1,32 +1,19 @@
|
|
|
1
|
-
import { Filter, FilterMap,
|
|
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
|
-
|
|
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<
|
|
11
|
-
findOne<S extends PgSelect>(select: S): (id: number) => Promise<
|
|
12
|
-
|
|
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
|
-
update(): (id: PrimaryKeyType<T>, data: Partial<InferInsertModel<T>>) => Promise<
|
|
21
|
-
tableName: infer TTableName extends string;
|
|
22
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer T_5 ? T_5 extends ((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) ? T_5 extends true ? false : true : never : never) extends true ? import("drizzle-orm/query-builders/select.types").ApplyNullability<{ [K_1 in keyof { [Key_3 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_3], true>; }]: { [Key_3 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_3], true>; }[K_1]; }, TNullability[TTableName]> : TNullability extends TNullability ? { [Key_4 in keyof TField]: TField[Key_4] extends infer TField ? TField extends import("drizzle-orm").Table<import("drizzle-orm").TableConfig<import("drizzle-orm").Column<any, object, object>>> ? TField["_"]["name"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<(TField["_"]["columns"] extends infer T_7 ? { [Key_2 in keyof T_7]: import("drizzle-orm/query-builders/select.types").SelectResultField<T_7[Key_2], TDeep>; } : never) extends infer T_6 ? { [K in keyof T_6]: T_6[K]; } : never, TNullability[TField["_"]["name"]]> : never : TField extends import("drizzle-orm").Column<import("drizzle-orm").ColumnBaseConfig<import("drizzle-orm").ColumnDataType, string>, object, object> ? TField["_"]["tableName"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true>, TNullability[TField["_"]["tableName"]]> : never : TField extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> ? import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true> : TField extends Record<string, any> ? TField[keyof TField] extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> | import("drizzle-orm").AnyColumn<{
|
|
23
|
-
tableName: infer TTableName extends string;
|
|
24
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer T_8 ? T_8 extends ((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) ? T_8 extends true ? false : true : never : never) extends true ? import("drizzle-orm/query-builders/select.types").ApplyNullability<{ [K_1 in keyof { [Key_3 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_3], true>; }]: { [Key_3 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_3], true>; }[K_1]; }, TNullability[TTableName]> : TNullability extends TNullability ? /*elided*/ any : never : never : never : never; } : never : never : never : never; } : never : never : never : never) extends infer T_3 ? T_3 extends (Record<T["_"]["name"], "not-null"> extends infer T_4 ? T_4 extends Record<T["_"]["name"], "not-null"> ? T_4 extends T_4 ? import("drizzle-orm/query-builders/select.types").GetSelectTableSelection<T> extends infer T_5 ? { [Key_1 in keyof T_5]: T_5[Key_1] extends infer TField ? TField extends import("drizzle-orm").Table<import("drizzle-orm").TableConfig<import("drizzle-orm").Column<any, object, object>>> ? TField["_"]["name"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<(TField["_"]["columns"] extends infer T_7 ? { [Key_3 in keyof T_7]: import("drizzle-orm/query-builders/select.types").SelectResultField<T_7[Key_3], TDeep>; } : never) extends infer T_6 ? { [K in keyof T_6]: T_6[K]; } : never, TNullability[TField["_"]["name"]]> : never : TField extends import("drizzle-orm").Column<import("drizzle-orm").ColumnBaseConfig<import("drizzle-orm").ColumnDataType, string>, object, object> ? TField["_"]["tableName"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true>, TNullability[TField["_"]["tableName"]]> : never : TField extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> ? import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true> : TField extends Record<string, any> ? TField[keyof TField] extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> | import("drizzle-orm").AnyColumn<{
|
|
25
|
-
tableName: infer TTableName extends string;
|
|
26
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer T_8 ? T_8 extends ((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) ? T_8 extends true ? false : true : never : never) extends true ? import("drizzle-orm/query-builders/select.types").ApplyNullability<{ [K_1 in keyof { [Key_4 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_4], true>; }]: { [Key_4 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_4], true>; }[K_1]; }, TNullability[TTableName]> : TNullability extends TNullability ? { [Key_5 in keyof TField]: TField[Key_5] extends infer TField ? TField extends import("drizzle-orm").Table<import("drizzle-orm").TableConfig<import("drizzle-orm").Column<any, object, object>>> ? TField["_"]["name"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<(TField["_"]["columns"] extends infer T_10 ? { [Key_3 in keyof T_10]: import("drizzle-orm/query-builders/select.types").SelectResultField<T_10[Key_3], TDeep>; } : never) extends infer T_9 ? { [K in keyof T_9]: T_9[K]; } : never, TNullability[TField["_"]["name"]]> : never : TField extends import("drizzle-orm").Column<import("drizzle-orm").ColumnBaseConfig<import("drizzle-orm").ColumnDataType, string>, object, object> ? TField["_"]["tableName"] extends keyof TNullability ? import("drizzle-orm/query-builders/select.types").ApplyNullability<import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true>, TNullability[TField["_"]["tableName"]]> : never : TField extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> ? import("drizzle-orm/query-builders/select.types").SelectResultField<TField, true> : TField extends Record<string, any> ? TField[keyof TField] extends import("drizzle-orm").SQL<unknown> | import("drizzle-orm").SQL.Aliased<unknown> | import("drizzle-orm").AnyColumn<{
|
|
27
|
-
tableName: infer TTableName extends string;
|
|
28
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer T_11 ? T_11 extends ((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) ? T_11 extends true ? false : true : never : never) extends true ? import("drizzle-orm/query-builders/select.types").ApplyNullability<{ [K_1 in keyof { [Key_4 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_4], true>; }]: { [Key_4 in keyof TField]: import("drizzle-orm/query-builders/select.types").SelectResultField<TField[Key_4], true>; }[K_1]; }, TNullability[TTableName]> : TNullability extends TNullability ? /*elided*/ any : never : never : never : never; } : never : never : never : never; } : never : never : never : never) ? T_3 extends undefined ? import("pg").QueryResult<never> : T_3[] : never : never>;
|
|
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>;
|
|
29
16
|
softDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
|
|
30
17
|
hardDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
|
|
31
|
-
count(): (filters
|
|
18
|
+
count(): (filters?: Filter<FSchema>) => Promise<number>;
|
|
32
19
|
}
|
package/dist/src/standard.js
CHANGED
|
@@ -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
|
|
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
|
|
18
|
-
throw
|
|
19
|
-
|
|
20
|
-
return result[0];
|
|
17
|
+
if (!result)
|
|
18
|
+
throw notFoundWithId(this.tableName, id);
|
|
19
|
+
return result;
|
|
21
20
|
};
|
|
22
21
|
}
|
|
23
22
|
findAll(select) {
|
|
24
|
-
return async (
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.
|
|
29
|
-
.
|
|
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() {
|
|
@@ -47,14 +43,14 @@ class ServiceBuilder {
|
|
|
47
43
|
if (Object.keys(data).length == 0) {
|
|
48
44
|
throw new errors_1.BadRequest("update needs at least one field");
|
|
49
45
|
}
|
|
50
|
-
const result = await this.db
|
|
46
|
+
const [result] = await this.db
|
|
51
47
|
.update(this.table)
|
|
52
48
|
.set(data)
|
|
53
49
|
.where((0, drizzle_orm_1.eq)(this.table.id, id))
|
|
54
50
|
.returning()
|
|
55
51
|
.catch((e) => (0, errors_1.handleSqlError)(e));
|
|
56
52
|
if (!result) {
|
|
57
|
-
throw
|
|
53
|
+
throw notFoundWithId(this.tableName, id);
|
|
58
54
|
}
|
|
59
55
|
return result;
|
|
60
56
|
};
|
|
@@ -66,7 +62,7 @@ class ServiceBuilder {
|
|
|
66
62
|
.set({ deletedAt: new Date() })
|
|
67
63
|
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(this.table.id, id), (0, drizzle_orm_1.isNull)(this.table.deletedAt)));
|
|
68
64
|
if (rowCount == 0) {
|
|
69
|
-
throw
|
|
65
|
+
throw notFoundWithId(this.tableName, id);
|
|
70
66
|
}
|
|
71
67
|
};
|
|
72
68
|
}
|
|
@@ -76,7 +72,7 @@ class ServiceBuilder {
|
|
|
76
72
|
.delete(this.table)
|
|
77
73
|
.where((0, drizzle_orm_1.eq)(this.table.id, id));
|
|
78
74
|
if (rowCount == 0) {
|
|
79
|
-
throw
|
|
75
|
+
throw notFoundWithId(this.tableName, id);
|
|
80
76
|
}
|
|
81
77
|
};
|
|
82
78
|
}
|
|
@@ -85,9 +81,12 @@ 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,
|
|
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
|
}
|
|
92
88
|
}
|
|
93
89
|
exports.ServiceBuilder = ServiceBuilder;
|
|
90
|
+
function notFoundWithId(tableName, id) {
|
|
91
|
+
return new errors_1.NotFound(`${tableName} with id ${id} not found`);
|
|
92
|
+
}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
import { SQL } from "drizzle-orm";
|
|
2
|
-
import {
|
|
3
|
-
|
|
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: (
|
|
6
|
-
count: (filters: Filter<
|
|
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
|
|
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
|
|
24
|
-
export type
|
|
25
|
-
|
|
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
package/dist/src/utils.d.ts
DELETED
|
@@ -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
|
-
}
|