bradb 1.0.1 → 1.2.0
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/README.md +29 -19
- package/dist/src/standard.d.ts +29 -24
- package/dist/src/standard.js +87 -82
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Bradb API Utilities
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**Bradb** is a utility library designed to dramatically speed up the development of RESTful APIs in Node.js. It natively integrates [Express](https://expressjs.com/), [Drizzle ORM](https://orm.drizzle.team/), and [Zod](https://zod.dev/) to provide a solid and efficient foundation for your projects.
|
|
4
4
|
|
|
5
|
-
The philosophy of `
|
|
5
|
+
The philosophy of `bradb` is simple: reduce repetitive boilerplate code to a minimum, allowing you to focus on business logic.
|
|
6
6
|
|
|
7
7
|
## Core Features
|
|
8
8
|
|
|
9
9
|
- **Base CRUD Controller:** Automatically generates endpoints for `getAll`, `getById`, `create`, `update`, and `delete`.
|
|
10
|
-
- **Standardized Services:**
|
|
10
|
+
- **Standardized Services:** A `ServiceBuilder` to create database access logic (`findAll`, `findOne`, `create`, etc.).
|
|
11
11
|
- **Automatic Pagination and Filtering:** Extracts pagination (`page`, `pageSize`) and filter parameters from the URL.
|
|
12
12
|
- **Validation with Zod:** Uses Zod schemas to validate input data.
|
|
13
13
|
- **Integrated Error Handling:** An Express `errorHandler` that catches and formats errors from `Zod`, `Drizzle`, and custom service errors.
|
|
@@ -15,7 +15,7 @@ The philosophy of `brad` is simple: reduce repetitive boilerplate code to a mini
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npm install
|
|
18
|
+
npm install bradb
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Make sure to also install the `peer` dependencies:
|
|
@@ -27,7 +27,7 @@ npm install -D @types/express @types/pg
|
|
|
27
27
|
|
|
28
28
|
## Quickstart Guide
|
|
29
29
|
|
|
30
|
-
Here is an example of how to structure an API with `
|
|
30
|
+
Here is an example of how to structure an API with `bradb`.
|
|
31
31
|
|
|
32
32
|
### 1. Define Your Drizzle Schema
|
|
33
33
|
|
|
@@ -47,13 +47,13 @@ export const serviceTable = pgTable("services", {
|
|
|
47
47
|
|
|
48
48
|
### 2. Create the Service
|
|
49
49
|
|
|
50
|
-
Use `
|
|
50
|
+
Use `bradb`'s `ServiceBuilder` to create a CRUD service for your table.
|
|
51
51
|
|
|
52
52
|
`src/services.ts`:
|
|
53
53
|
```typescript
|
|
54
54
|
import { db } from "./db"; // Your Drizzle instance
|
|
55
55
|
import { serviceTable } from "./schema";
|
|
56
|
-
import {
|
|
56
|
+
import { ServiceBuilder } from "bradb";
|
|
57
57
|
import { eq } from "drizzle-orm";
|
|
58
58
|
|
|
59
59
|
// Filter map for queries
|
|
@@ -61,23 +61,33 @@ const filterMap = {
|
|
|
61
61
|
name: (value: string) => eq(serviceTable.name, value)
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
const builder = new ServiceBuilder(db, serviceTable, filterMap);
|
|
65
|
+
|
|
64
66
|
export const serviceService = {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
delete:
|
|
70
|
-
|
|
71
|
-
|
|
67
|
+
create: builder.create(),
|
|
68
|
+
count: builder.count(),
|
|
69
|
+
delete: builder.softDelete(),
|
|
70
|
+
// or you can do a hard delete
|
|
71
|
+
// delete: builder.hardDelete,
|
|
72
|
+
update: builder.update(),
|
|
73
|
+
findAll: builder.findAll(
|
|
74
|
+
// Dont forget $dinamyc()
|
|
75
|
+
db.select().from(serviceTable).$dynamic()
|
|
76
|
+
),
|
|
77
|
+
findOne: builder.findOne(
|
|
78
|
+
// agrega el where eq y el Custom Error
|
|
79
|
+
db.select().from(serviceTable).$dynamic()
|
|
80
|
+
),
|
|
81
|
+
}
|
|
72
82
|
```
|
|
73
83
|
|
|
74
84
|
### 3. Create the Controller
|
|
75
85
|
|
|
76
|
-
Extend `
|
|
86
|
+
Extend `bradb`'s `BaseController`, passing it the service and Zod validation schemas.
|
|
77
87
|
|
|
78
88
|
`src/controllers.ts`:
|
|
79
89
|
```typescript
|
|
80
|
-
import { BaseController } from "
|
|
90
|
+
import { BaseController } from "bradb";
|
|
81
91
|
import { serviceService } from "./services";
|
|
82
92
|
import { serviceTable } from "./schema";
|
|
83
93
|
import { z } from "zod";
|
|
@@ -117,7 +127,7 @@ export default router;
|
|
|
117
127
|
```typescript
|
|
118
128
|
import express from "express";
|
|
119
129
|
import serviceRouter from "./router";
|
|
120
|
-
import { errorHandler } from "
|
|
130
|
+
import { errorHandler } from "bradb";
|
|
121
131
|
|
|
122
132
|
const app = express();
|
|
123
133
|
app.use(express.json());
|
|
@@ -130,4 +140,4 @@ app.use(errorHandler);
|
|
|
130
140
|
app.listen(3000, () => {
|
|
131
141
|
console.log(`Server is running on port 3000`);
|
|
132
142
|
});
|
|
133
|
-
```
|
|
143
|
+
```
|
package/dist/src/standard.d.ts
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
import { Filter, FilterMap, FindAllOptions, PrimaryKeyType, Table } from "./types";
|
|
2
|
-
import {
|
|
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
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer
|
|
23
|
-
|
|
24
|
-
}> ? (((TTableName extends any ? TTableName extends TTableName ? false : true : never) extends false ? false : true) extends infer
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
export declare class ServiceBuilder<T extends Table, TSchema extends Record<string, unknown>> {
|
|
6
|
+
private readonly db;
|
|
7
|
+
private readonly table;
|
|
8
|
+
private readonly map;
|
|
9
|
+
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)[]>;
|
|
19
|
+
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<(Record<T["_"]["name"], "not-null"> extends infer T_1 ? T_1 extends Record<T["_"]["name"], "not-null"> ? T_1 extends T_1 ? import("drizzle-orm/query-builders/select.types").GetSelectTableSelection<T> extends infer T_2 ? { [Key in keyof T_2]: T_2[Key] 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_4 ? { [Key_2 in keyof T_4]: import("drizzle-orm/query-builders/select.types").SelectResultField<T_4[Key_2], TDeep>; } : never) extends infer T_3 ? { [K in keyof T_3]: T_3[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<{
|
|
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>;
|
|
29
|
+
softDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
|
|
30
|
+
hardDelete(): (id: PrimaryKeyType<T>) => Promise<void>;
|
|
31
|
+
count(): (filters: Filter<T>) => Promise<number>;
|
|
32
|
+
}
|
package/dist/src/standard.js
CHANGED
|
@@ -1,88 +1,93 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.findAll = findAll;
|
|
5
|
-
exports.create = create;
|
|
6
|
-
exports.update = update;
|
|
7
|
-
exports.softDelete = softDelete;
|
|
8
|
-
exports.hardDelete = hardDelete;
|
|
9
|
-
exports.count = count;
|
|
3
|
+
exports.ServiceBuilder = void 0;
|
|
10
4
|
const drizzle_orm_1 = require("drizzle-orm");
|
|
11
5
|
const utils_1 = require("./utils");
|
|
12
6
|
const errors_1 = require("./errors");
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
7
|
+
class ServiceBuilder {
|
|
8
|
+
constructor(db, table, map) {
|
|
9
|
+
this.db = db;
|
|
10
|
+
this.table = table;
|
|
11
|
+
this.tableName = (0, drizzle_orm_1.getTableName)(table);
|
|
12
|
+
this.map = map;
|
|
13
|
+
}
|
|
14
|
+
findOne(select) {
|
|
15
|
+
return async (id) => {
|
|
16
|
+
const result = await select.where((0, drizzle_orm_1.eq)(this.table.id, id));
|
|
17
|
+
if (result.length == 0) {
|
|
18
|
+
throw new Error(`${this.tableName} with id ${id} not found`);
|
|
19
|
+
}
|
|
20
|
+
return result[0];
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
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;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
create() {
|
|
36
|
+
return async (data) => {
|
|
37
|
+
const [result] = await this.db
|
|
38
|
+
.insert(this.table)
|
|
39
|
+
.values(data)
|
|
40
|
+
.returning()
|
|
41
|
+
.catch(errors_1.handleSqlError);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
update() {
|
|
46
|
+
return async (id, data) => {
|
|
47
|
+
if (Object.keys(data).length == 0) {
|
|
48
|
+
throw new errors_1.BadRequest("update needs at least one field");
|
|
49
|
+
}
|
|
50
|
+
const result = await this.db
|
|
51
|
+
.update(this.table)
|
|
52
|
+
.set(data)
|
|
53
|
+
.where((0, drizzle_orm_1.eq)(this.table.id, id))
|
|
54
|
+
.returning()
|
|
55
|
+
.catch((e) => (0, errors_1.handleSqlError)(e));
|
|
56
|
+
if (!result) {
|
|
57
|
+
throw new errors_1.NotFound(`${this.tableName} with id ${id} not found`);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
softDelete() {
|
|
63
|
+
return async (id) => {
|
|
64
|
+
const { rowCount } = await this.db
|
|
65
|
+
.update(this.table)
|
|
66
|
+
.set({ deletedAt: new Date() })
|
|
67
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(this.table.id, id), (0, drizzle_orm_1.isNull)(this.table.deletedAt)));
|
|
68
|
+
if (rowCount == 0) {
|
|
69
|
+
throw new errors_1.NotFound(`${this.tableName} with id ${id} not found`);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
hardDelete() {
|
|
74
|
+
return async (id) => {
|
|
75
|
+
const { rowCount } = await this.db
|
|
76
|
+
.delete(this.table)
|
|
77
|
+
.where((0, drizzle_orm_1.eq)(this.table.id, id));
|
|
78
|
+
if (rowCount == 0) {
|
|
79
|
+
throw new errors_1.NotFound(`${this.tableName} with id ${id} not found`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
count() {
|
|
84
|
+
return async (filters) => {
|
|
85
|
+
const [result] = await this.db
|
|
86
|
+
.select({ count: (0, drizzle_orm_1.count)() })
|
|
87
|
+
.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)));
|
|
89
|
+
return result.count;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
88
92
|
}
|
|
93
|
+
exports.ServiceBuilder = ServiceBuilder;
|