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 +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 +7 -12
- package/dist/src/standard.js +10 -14
- 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,24 +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
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
|
|
18
|
+
count(): (filters?: Filter<FSchema>) => Promise<number>;
|
|
24
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
|
|
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 (
|
|
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() {
|
|
@@ -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,
|
|
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
|
}
|
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
|
-
}
|