crud-query-parser 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Guilherme de Oliveira Chaguri
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,154 @@
1
+ # crud-query-parser
2
+
3
+ This library parses HTTP requests and converts them to TypeORM query builders, allowing advanced filtering, column selection, pagination and relations.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @crud-query-parser/core
9
+ ```
10
+
11
+ ### Other modules
12
+
13
+ - `@crud-query-parser/typeorm`: TypeORM adapter
14
+ - `@crud-query-parser/nestjs`: NestJS utilities
15
+
16
+ ## Usage
17
+
18
+ You have to pick a request parser and a query adapter.
19
+
20
+ ```ts
21
+ const userRepository = AppDataSource.getRepository(UserEntity); // TypeORM repository
22
+
23
+ // ...
24
+
25
+ // The request query object
26
+ // This object will likely come from the HTTP request
27
+ const requestQuery = { ... };
28
+
29
+ // Parses the query into a CrudRequest object
30
+ const crudRequest = parser.parse(requestQuery);
31
+
32
+ // Using the query adapter, you can query in your ORM from the CrudRequest
33
+ const result = adapter.getMany(userRepository.createQueryBuilder(), crudRequest); // GetManyResult<UserEntity>
34
+
35
+ // The result object has properties like data, page, total
36
+ console.log(result);
37
+ ```
38
+
39
+ ## Request parsers
40
+
41
+ ### CRUD
42
+
43
+ This parser fully compatible with `@nestjsx/crud`
44
+
45
+ ```ts
46
+ import { CrudRequestParser } from 'crud-query-parser/parsers/crud';
47
+
48
+ const parser = new CrudRequestParser();
49
+ ```
50
+
51
+ ## Database adapters
52
+
53
+ ### TypeORM
54
+
55
+ This adapter works with TypeORM 0.3.x and 0.2.x
56
+
57
+ ```ts
58
+ import { TypeormQueryAdapter } from 'crud-query-parser/adapters/typeorm';
59
+
60
+ const adapter = new TypeormQueryAdapter();
61
+
62
+ //
63
+ ```
64
+
65
+ ## Helpers
66
+
67
+ ### NestJS
68
+
69
+ The NestJS integration has OpenAPI support and decorators that automatically parses the request.
70
+
71
+ Sample code:
72
+
73
+ ```ts
74
+ @Controller('users')
75
+ export class UserController {
76
+
77
+ @Get()
78
+ @Crud(CrudRequestParser)
79
+ public async getMany(@ParseCrudRequest() crudRequest: CrudRequest) {
80
+ return this.service.getMany(crudRequest);
81
+ }
82
+
83
+ }
84
+ ```
85
+
86
+ ## Filters
87
+
88
+ You may need to filter what the user can or cannot query. You can modify the `CrudRequest` object as needed.
89
+
90
+ There are a few filters provided by the library, which are listed below.
91
+
92
+ ### Enforce a "where" condition
93
+
94
+ This filter will add the condition on top of all other where conditions
95
+
96
+ ```ts
97
+ import { ensureCondition } from 'crud-query-parser/filters';
98
+
99
+ // ...
100
+
101
+ crudRequest = ensureCondition(crudRequest, {
102
+ field: ['isActive'],
103
+ operator: ParsedRequestWhereOperator.EQ,
104
+ value: true,
105
+ });
106
+ ```
107
+
108
+ ### Ensure page limit
109
+
110
+ This filter will ensure that the requested limit does not go above the maximum.
111
+ It also sets the default limit whenever the limit is omitted.
112
+
113
+ ```ts
114
+ import { ensureLimit } from 'crud-query-parser/filters';
115
+
116
+ // ...
117
+
118
+ const defaultLimit = 25;
119
+ const maxLimit = 100;
120
+
121
+ crudRequest = ensureLimit(crudRequest, defaultLimit, maxLimit);
122
+ ```
123
+
124
+ ### Filter property access
125
+
126
+ This filter removes any property from the request that is not in the allowlist.
127
+ It removes unallowed properties from the select fields, where conditions, relations and sorting.
128
+
129
+ ```ts
130
+ import { filterProperties } from 'crud-query-parser/filters';
131
+
132
+ // ...
133
+
134
+ crudRequest = filterProperties(crudRequest, [
135
+ 'id',
136
+ 'name',
137
+ 'posts',
138
+ 'posts.id',
139
+ 'posts.name',
140
+ ]);
141
+ ```
142
+
143
+ ### Filter relations
144
+
145
+ This filter removes any relation from the request that is not in the allowlist.
146
+ It's the same as the `filterProperties` but only filters relations.
147
+
148
+ ```ts
149
+ import { filterRelations } from 'crud-query-parser/filters';
150
+
151
+ // ...
152
+
153
+ crudRequest = filterRelations(crudRequest, ['posts']);
154
+ ```
@@ -0,0 +1,84 @@
1
+ import { SelectQueryBuilder, ObjectLiteral, WhereExpressionBuilder } from 'typeorm';
2
+ import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-BliD9hJN.mjs';
3
+ import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder, d as CrudRequestWhere, g as CrudRequestWhereField } from '../../crud-request-CvDKp6Iy.mjs';
4
+
5
+ /**
6
+ * Adapts queries to TypeORM query builder object
7
+ */
8
+ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
9
+ /**
10
+ * @inheritDoc
11
+ */
12
+ build<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
13
+ /**
14
+ * @inheritDoc
15
+ */
16
+ getOne<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<E | null>;
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ getMany<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<GetManyResult<E>>;
21
+ /**
22
+ * Creates a query filtered from the parsed request
23
+ *
24
+ * @param qb The base query builder
25
+ * @param query The parsed query
26
+ */
27
+ protected createBaseQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
28
+ /**
29
+ * Paginates a query based on the parsed request
30
+ *
31
+ * @param qb The query builder
32
+ * @param query The parsed query
33
+ */
34
+ protected paginateQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
35
+ /**
36
+ * Adapts a select
37
+ *
38
+ * @param qb The query builder
39
+ * @param select The parsed select fields
40
+ */
41
+ protected adaptSelect<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, select: ParsedRequestSelect): void;
42
+ /**
43
+ * Adapts the join relation list
44
+ *
45
+ * @param qb The query builder
46
+ * @param relations The parsed relation list
47
+ */
48
+ protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void;
49
+ /**
50
+ * Adapts the order by list
51
+ *
52
+ * @param qb The query builder
53
+ * @param ordering The parsed ordering
54
+ */
55
+ protected adaptOrder<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, ordering: CrudRequestOrder[]): void;
56
+ /**
57
+ * Adapts a where condition
58
+ *
59
+ * @param qb The query builder
60
+ * @param where The quere condition
61
+ * @param or Whether this where condition is AND/OR
62
+ * @param params The registered parameter name list
63
+ */
64
+ protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void;
65
+ /**
66
+ * Creates a query parameter name based on a field
67
+ *
68
+ * @param paramsDefined The array the parameter will be registered onto
69
+ * @param field The field path
70
+ */
71
+ protected createParam(paramsDefined: string[], field: string[]): string;
72
+ /**
73
+ * Maps where operators to a pseudo-SQL statement and a parameter map
74
+ *
75
+ * @param where The where condition
76
+ * @param param The parameter name
77
+ */
78
+ protected mapWhereOperators(where: CrudRequestWhereField, param: string): {
79
+ where: string;
80
+ params: ObjectLiteral;
81
+ };
82
+ }
83
+
84
+ export { TypeormQueryAdapter };
@@ -0,0 +1,84 @@
1
+ import { SelectQueryBuilder, ObjectLiteral, WhereExpressionBuilder } from 'typeorm';
2
+ import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-Vebxws3V.js';
3
+ import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder, d as CrudRequestWhere, g as CrudRequestWhereField } from '../../crud-request-CvDKp6Iy.js';
4
+
5
+ /**
6
+ * Adapts queries to TypeORM query builder object
7
+ */
8
+ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
9
+ /**
10
+ * @inheritDoc
11
+ */
12
+ build<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
13
+ /**
14
+ * @inheritDoc
15
+ */
16
+ getOne<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<E | null>;
17
+ /**
18
+ * @inheritDoc
19
+ */
20
+ getMany<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<GetManyResult<E>>;
21
+ /**
22
+ * Creates a query filtered from the parsed request
23
+ *
24
+ * @param qb The base query builder
25
+ * @param query The parsed query
26
+ */
27
+ protected createBaseQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
28
+ /**
29
+ * Paginates a query based on the parsed request
30
+ *
31
+ * @param qb The query builder
32
+ * @param query The parsed query
33
+ */
34
+ protected paginateQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E>;
35
+ /**
36
+ * Adapts a select
37
+ *
38
+ * @param qb The query builder
39
+ * @param select The parsed select fields
40
+ */
41
+ protected adaptSelect<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, select: ParsedRequestSelect): void;
42
+ /**
43
+ * Adapts the join relation list
44
+ *
45
+ * @param qb The query builder
46
+ * @param relations The parsed relation list
47
+ */
48
+ protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void;
49
+ /**
50
+ * Adapts the order by list
51
+ *
52
+ * @param qb The query builder
53
+ * @param ordering The parsed ordering
54
+ */
55
+ protected adaptOrder<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, ordering: CrudRequestOrder[]): void;
56
+ /**
57
+ * Adapts a where condition
58
+ *
59
+ * @param qb The query builder
60
+ * @param where The quere condition
61
+ * @param or Whether this where condition is AND/OR
62
+ * @param params The registered parameter name list
63
+ */
64
+ protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void;
65
+ /**
66
+ * Creates a query parameter name based on a field
67
+ *
68
+ * @param paramsDefined The array the parameter will be registered onto
69
+ * @param field The field path
70
+ */
71
+ protected createParam(paramsDefined: string[], field: string[]): string;
72
+ /**
73
+ * Maps where operators to a pseudo-SQL statement and a parameter map
74
+ *
75
+ * @param where The where condition
76
+ * @param param The parameter name
77
+ */
78
+ protected mapWhereOperators(where: CrudRequestWhereField, param: string): {
79
+ where: string;
80
+ params: ObjectLiteral;
81
+ };
82
+ }
83
+
84
+ export { TypeormQueryAdapter };
@@ -0,0 +1,2 @@
1
+ "use strict";var c=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var u=(i,t)=>c(i,"name",{value:t,configurable:!0});var O=(i,t)=>{for(var e in t)c(i,e,{get:t[e],enumerable:!0})},S=(i,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of _(t))!y.call(i,s)&&s!==e&&c(i,s,{get:()=>t[s],enumerable:!(r=f(t,s))||r.enumerable});return i};var w=i=>S(c({},"__esModule",{value:!0}),i);var R={};O(R,{TypeormQueryAdapter:()=>N});module.exports=w(R);var E=require("typeorm");function a(i,t,e=0){if(!Array.isArray(t)||t.length<e)throw new Error(`${i} must be an array with at least ${e} items`);return t}u(a,"ensureArray");function d(i,t){if(t)throw new Error(`${i} must be null`)}u(d,"ensureFalsy");var N=class{static{u(this,"TypeormQueryAdapter")}build(t,e){return t=this.createBaseQuery(t,e),t=this.paginateQuery(t,e),t}async getOne(t,e){return await this.createBaseQuery(t,e).getOne()??null}async getMany(t,e){let r=this.createBaseQuery(t,e),n=await this.paginateQuery(r.clone(),e).getMany(),o=await r.getCount(),l=e.offset??0,$=e.limit??o,L=n.length,h=Math.floor(l/$)+1,T=Math.ceil(o/$);return{data:n,count:L,page:h,pageCount:T,total:o}}createBaseQuery(t,e){let r=[];return this.adaptSelect(t,e.select),this.adaptRelations(t,e.relations),this.adaptWhere(t,e.where,!1,r),this.adaptOrder(t,e.order),t}paginateQuery(t,e){return t.limit(e.limit).offset(e.offset)}adaptSelect(t,e){t.addSelect(e.map(r=>r.field.join(".")))}adaptRelations(t,e){for(let r of e){let s=r.field.join("."),n=r.alias||s.replace(".","_");t.leftJoin(s,n)}}adaptOrder(t,e){for(let r of e){let s=r.field.join(".");t.addOrderBy(s,r.order)}}adaptWhere(t,e,r,s){let n=(r?t.orWhere:t.andWhere).bind(t);if(e.or&&e.or.length>0)n(new E.Brackets(o=>e.or.forEach(l=>this.adaptWhere(o,l,!0,s))));else if(e.and&&e.and.length>0)n(new E.Brackets(o=>e.and.forEach(l=>this.adaptWhere(o,l,!1,s))));else if(e.field){let o=this.createParam(s,e.field),l=this.mapWhereOperators(e,o);n(l.where,l.params)}}createParam(t,e){let r=e.length>0?e[e.length-1]:"",s,n=0;do s="req_"+r+"_"+n,n++;while(t.includes(s));return t.push(s),s}mapWhereOperators(t,e){let r=t.field.join("."),s=t.operator,n=t.value;switch(s){case"eq":return{where:`${r} = :${e}`,params:{[e]:n}};case"neq":return{where:`${r} != :${e}`,params:{[e]:n}};case"gt":return{where:`${r} > :${e}`,params:{[e]:n}};case"gte":return{where:`${r} >= :${e}`,params:{[e]:n}};case"lt":return{where:`${r} < :${e}`,params:{[e]:n}};case"lte":return{where:`${r} <= :${e}`,params:{[e]:n}};case"starts":return{where:`${r} LIKE :${e}`,params:{[e]:`${n}%`}};case"ends":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}`}};case"contains":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains":return{where:`${r} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in":return n=a("IN operator",n,1),{where:`${r} IN (:...${e})`,params:{[e]:n}};case"not_in":return n=a("NOT IN operator",n,1),{where:`${r} NOT IN (:...${e})`,params:{[e]:n}};case"between":let o=a("BETWEEN operator",n,2);return{where:`${r} BETWEEN :${e}_start AND :${e}_end`,params:{[`${e}_start`]:o[0],[`${e}_end`]:o[1]}};case"is_null":return d("IS NULL operator",n),{where:`${r} IS NULL`,params:{}};case"not_null":return d("NOT NULL operator",n),{where:`${r} IS NOT NULL`,params:{}};case"eq_lower":return{where:`LOWER(${r}) = :${e}`,params:{[e]:n}};case"neq_lower":return{where:`LOWER(${r}) != :${e}`,params:{[e]:n}};case"starts_lower":return{where:`LOWER(${r}) LIKE :${e}`,params:{[e]:`${n}%`}};case"ends_lower":return{where:`LOWER(${r}) LIKE :${e}`,params:{[e]:`%${n}`}};case"contains_lower":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains_lower":return{where:`${r} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in_lower":return a("IN operator",n,1),{where:`${r} IN (...:${e})`,params:{[e]:n}};case"not_in_lower":return a("NOT IN operator",n,1),{where:`${r} NOT IN (...:${e})`,params:{[e]:n}};default:throw new Error(`Unknown operator "${s}"`)}}};0&&(module.exports={TypeormQueryAdapter});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/typeorm/index.ts","../../../src/adapters/typeorm/typeorm.query-adapter.ts","../../../src/utils/functions.ts"],"sourcesContent":["\r\nexport * from './typeorm.query-adapter';\r\n","import { Brackets, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport {\r\n CrudRequest,\r\n CrudRequestOrder,\r\n CrudRequestRelation,\r\n ParsedRequestSelect\r\n} from '../../models/crud-request';\r\nimport {\r\n CrudRequestWhere,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator\r\n} from '../../models/crud-request-where';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { ensureArray, ensureFalsy } from '../../utils/functions';\r\n\r\n/**\r\n * Adapts queries to TypeORM query builder object\r\n */\r\nexport class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n qb = this.createBaseQuery(qb, query);\r\n qb = this.paginateQuery(qb, query);\r\n\r\n return qb;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<E | null> {\r\n const query = this.createBaseQuery(qb, request);\r\n const entity = await query.getOne();\r\n\r\n return entity ?? null;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<GetManyResult<E>> {\r\n const fullQuery = this.createBaseQuery(qb, request);\r\n const paginatedQuery = this.paginateQuery(fullQuery.clone(), request);\r\n\r\n const data = await paginatedQuery.getMany();\r\n const total = await fullQuery.getCount();\r\n\r\n const offset = request.offset ?? 0;\r\n const limit = request.limit ?? total;\r\n\r\n const count = data.length;\r\n const page = Math.floor(offset / limit) + 1;\r\n const pageCount = Math.ceil(total / limit);\r\n\r\n return {\r\n data,\r\n count,\r\n page,\r\n pageCount,\r\n total,\r\n };\r\n }\r\n\r\n /**\r\n * Creates a query filtered from the parsed request\r\n *\r\n * @param qb The base query builder\r\n * @param query The parsed query\r\n */\r\n protected createBaseQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n const paramsDefined: string[] = [];\r\n\r\n this.adaptSelect(qb, query.select);\r\n this.adaptRelations(qb, query.relations);\r\n this.adaptWhere(qb, query.where, false, paramsDefined);\r\n this.adaptOrder(qb, query.order);\r\n\r\n return qb;\r\n }\r\n\r\n /**\r\n * Paginates a query based on the parsed request\r\n *\r\n * @param qb The query builder\r\n * @param query The parsed query\r\n */\r\n protected paginateQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n return qb.limit(query.limit).offset(query.offset);\r\n }\r\n\r\n /**\r\n * Adapts a select\r\n *\r\n * @param qb The query builder\r\n * @param select The parsed select fields\r\n */\r\n protected adaptSelect<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, select: ParsedRequestSelect): void {\r\n qb.addSelect(select.map(s => s.field.join('.')));\r\n }\r\n\r\n /**\r\n * Adapts the join relation list\r\n *\r\n * @param qb The query builder\r\n * @param relations The parsed relation list\r\n */\r\n protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void {\r\n for (const relation of relations) {\r\n const path = relation.field.join('.');\r\n const alias = relation.alias || path.replace('.', '_');\r\n\r\n qb.leftJoin(path, alias);\r\n }\r\n }\r\n\r\n /**\r\n * Adapts the order by list\r\n *\r\n * @param qb The query builder\r\n * @param ordering The parsed ordering\r\n */\r\n protected adaptOrder<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, ordering: CrudRequestOrder[]): void {\r\n for (const order of ordering) {\r\n const path = order.field.join('.');\r\n\r\n qb.addOrderBy(path, order.order);\r\n }\r\n }\r\n\r\n /**\r\n * Adapts a where condition\r\n *\r\n * @param qb The query builder\r\n * @param where The quere condition\r\n * @param or Whether this where condition is AND/OR\r\n * @param params The registered parameter name list\r\n */\r\n protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void {\r\n const addWhere = (or ? qb.orWhere : qb.andWhere).bind(qb);\r\n\r\n if (where.or && where.or.length > 0) {\r\n addWhere(new Brackets(\r\n wqb => where.or!.forEach(item => this.adaptWhere(wqb, item, true, params))\r\n ));\r\n } else if (where.and && where.and.length > 0) {\r\n addWhere(new Brackets(\r\n wqb => where.and!.forEach(item => this.adaptWhere(wqb, item, false, params))\r\n ));\r\n } else if (where.field) {\r\n const param = this.createParam(params, where.field);\r\n const query = this.mapWhereOperators(where as CrudRequestWhereField, param);\r\n\r\n addWhere(query.where, query.params);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a query parameter name based on a field\r\n *\r\n * @param paramsDefined The array the parameter will be registered onto\r\n * @param field The field path\r\n */\r\n protected createParam(paramsDefined: string[], field: string[]): string {\r\n const name = field.length > 0 ? field[field.length - 1] : '';\r\n let param: string;\r\n let iteration: number = 0;\r\n\r\n do {\r\n param = 'req_' + name + '_' + iteration;\r\n iteration++;\r\n } while (paramsDefined.includes(param));\r\n\r\n paramsDefined.push(param);\r\n return param;\r\n }\r\n\r\n /**\r\n * Maps where operators to a pseudo-SQL statement and a parameter map\r\n *\r\n * @param where The where condition\r\n * @param param The parameter name\r\n */\r\n protected mapWhereOperators(where: CrudRequestWhereField, param: string): { where: string, params: ObjectLiteral } {\r\n const field = where.field.join('.');\r\n const operator = where.operator;\r\n let value: unknown = where.value;\r\n\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return { where: `${field} = :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return { where: `${field} != :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return { where: `${field} > :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return { where: `${field} >= :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return { where: `${field} < :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return { where: `${field} <= :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return { where: `${field} NOT LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.IN:\r\n value = ensureArray('IN operator', value, 1);\r\n\r\n return { where: `${field} IN (:...${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n value = ensureArray('NOT IN operator', value, 1);\r\n\r\n return { where: `${field} NOT IN (:...${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return {\r\n where: `${field} BETWEEN :${param}_start AND :${param}_end`,\r\n params: { [`${param}_start`]: arr[0], [`${param}_end`]: arr[1] },\r\n };\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n ensureFalsy('IS NULL operator', value);\r\n\r\n return { where: `${field} IS NULL`, params: {} };\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n ensureFalsy('NOT NULL operator', value);\r\n\r\n return { where: `${field} IS NOT NULL`, params: {} };\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return { where: `LOWER(${field}) = :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return { where: `LOWER(${field}) != :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return { where: `LOWER(${field}) LIKE :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { where: `LOWER(${field}) LIKE :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { where: `${field} NOT LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.IN_LOWER:\r\n ensureArray('IN operator', value, 1);\r\n\r\n return { where: `${field} IN (...:${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER:\r\n ensureArray('NOT IN operator', value, 1);\r\n\r\n return { where: `${field} NOT IN (...:${param})`, params: { [param]: value } };\r\n\r\n default:\r\n throw new Error(`Unknown operator \"${operator}\"`);\r\n }\r\n }\r\n\r\n}\r\n","import { CrudRequestFields } from '../models/crud-request';\r\n\r\n/*export function setFieldByPath<T>(obj: ParsedRequestFields<T>, field: string, value: T): void {\r\n const parts = field.split('.');\r\n\r\n while (parts.length > 1) {\r\n const name = parts.shift();\r\n\r\n if (!Array.isArray(obj[name]))\r\n obj[name] = {};\r\n\r\n obj = obj[name] as ParsedRequestFields<T>;\r\n }\r\n\r\n obj[parts.shift()] = value;\r\n}*/\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureFalsy(fieldName: string, data: any) {\r\n if (data)\r\n throw new Error(`${fieldName} must be null`);\r\n}\r\n\r\nexport function isValid(value: any): value is object {\r\n return value !== null && value !== undefined;\r\n}\r\n"],"mappings":"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","names":["typeorm_exports","__export","TypeormQueryAdapter","__toCommonJS","import_typeorm","ensureArray","fieldName","data","minLength","__name","ensureFalsy","TypeormQueryAdapter","__name","qb","query","request","fullQuery","data","total","offset","limit","count","page","pageCount","paramsDefined","select","s","relations","relation","path","alias","ordering","order","where","or","params","addWhere","wqb","item","param","field","name","iteration","operator","value","ensureArray","arr","ensureFalsy"]}
@@ -0,0 +1,2 @@
1
+ var T=Object.defineProperty;var u=(l,t)=>T(l,"name",{value:t,configurable:!0});import{Brackets as E}from"typeorm";function a(l,t,e=0){if(!Array.isArray(t)||t.length<e)throw new Error(`${l} must be an array with at least ${e} items`);return t}u(a,"ensureArray");function c(l,t){if(t)throw new Error(`${l} must be null`)}u(c,"ensureFalsy");var N=class{static{u(this,"TypeormQueryAdapter")}build(t,e){return t=this.createBaseQuery(t,e),t=this.paginateQuery(t,e),t}async getOne(t,e){return await this.createBaseQuery(t,e).getOne()??null}async getMany(t,e){let r=this.createBaseQuery(t,e),n=await this.paginateQuery(r.clone(),e).getMany(),i=await r.getCount(),o=e.offset??0,d=e.limit??i,$=n.length,L=Math.floor(o/d)+1,h=Math.ceil(i/d);return{data:n,count:$,page:L,pageCount:h,total:i}}createBaseQuery(t,e){let r=[];return this.adaptSelect(t,e.select),this.adaptRelations(t,e.relations),this.adaptWhere(t,e.where,!1,r),this.adaptOrder(t,e.order),t}paginateQuery(t,e){return t.limit(e.limit).offset(e.offset)}adaptSelect(t,e){t.addSelect(e.map(r=>r.field.join(".")))}adaptRelations(t,e){for(let r of e){let s=r.field.join("."),n=r.alias||s.replace(".","_");t.leftJoin(s,n)}}adaptOrder(t,e){for(let r of e){let s=r.field.join(".");t.addOrderBy(s,r.order)}}adaptWhere(t,e,r,s){let n=(r?t.orWhere:t.andWhere).bind(t);if(e.or&&e.or.length>0)n(new E(i=>e.or.forEach(o=>this.adaptWhere(i,o,!0,s))));else if(e.and&&e.and.length>0)n(new E(i=>e.and.forEach(o=>this.adaptWhere(i,o,!1,s))));else if(e.field){let i=this.createParam(s,e.field),o=this.mapWhereOperators(e,i);n(o.where,o.params)}}createParam(t,e){let r=e.length>0?e[e.length-1]:"",s,n=0;do s="req_"+r+"_"+n,n++;while(t.includes(s));return t.push(s),s}mapWhereOperators(t,e){let r=t.field.join("."),s=t.operator,n=t.value;switch(s){case"eq":return{where:`${r} = :${e}`,params:{[e]:n}};case"neq":return{where:`${r} != :${e}`,params:{[e]:n}};case"gt":return{where:`${r} > :${e}`,params:{[e]:n}};case"gte":return{where:`${r} >= :${e}`,params:{[e]:n}};case"lt":return{where:`${r} < :${e}`,params:{[e]:n}};case"lte":return{where:`${r} <= :${e}`,params:{[e]:n}};case"starts":return{where:`${r} LIKE :${e}`,params:{[e]:`${n}%`}};case"ends":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}`}};case"contains":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains":return{where:`${r} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in":return n=a("IN operator",n,1),{where:`${r} IN (:...${e})`,params:{[e]:n}};case"not_in":return n=a("NOT IN operator",n,1),{where:`${r} NOT IN (:...${e})`,params:{[e]:n}};case"between":let i=a("BETWEEN operator",n,2);return{where:`${r} BETWEEN :${e}_start AND :${e}_end`,params:{[`${e}_start`]:i[0],[`${e}_end`]:i[1]}};case"is_null":return c("IS NULL operator",n),{where:`${r} IS NULL`,params:{}};case"not_null":return c("NOT NULL operator",n),{where:`${r} IS NOT NULL`,params:{}};case"eq_lower":return{where:`LOWER(${r}) = :${e}`,params:{[e]:n}};case"neq_lower":return{where:`LOWER(${r}) != :${e}`,params:{[e]:n}};case"starts_lower":return{where:`LOWER(${r}) LIKE :${e}`,params:{[e]:`${n}%`}};case"ends_lower":return{where:`LOWER(${r}) LIKE :${e}`,params:{[e]:`%${n}`}};case"contains_lower":return{where:`${r} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains_lower":return{where:`${r} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in_lower":return a("IN operator",n,1),{where:`${r} IN (...:${e})`,params:{[e]:n}};case"not_in_lower":return a("NOT IN operator",n,1),{where:`${r} NOT IN (...:${e})`,params:{[e]:n}};default:throw new Error(`Unknown operator "${s}"`)}}};export{N as TypeormQueryAdapter};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/adapters/typeorm/typeorm.query-adapter.ts","../../../src/utils/functions.ts"],"sourcesContent":["import { Brackets, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport {\r\n CrudRequest,\r\n CrudRequestOrder,\r\n CrudRequestRelation,\r\n ParsedRequestSelect\r\n} from '../../models/crud-request';\r\nimport {\r\n CrudRequestWhere,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator\r\n} from '../../models/crud-request-where';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { ensureArray, ensureFalsy } from '../../utils/functions';\r\n\r\n/**\r\n * Adapts queries to TypeORM query builder object\r\n */\r\nexport class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public build<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n qb = this.createBaseQuery(qb, query);\r\n qb = this.paginateQuery(qb, query);\r\n\r\n return qb;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getOne<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<E | null> {\r\n const query = this.createBaseQuery(qb, request);\r\n const entity = await query.getOne();\r\n\r\n return entity ?? null;\r\n }\r\n\r\n /**\r\n * @inheritDoc\r\n */\r\n public async getMany<E extends ObjectLiteral>(qb: SelectQueryBuilder<E | any>, request: CrudRequest): Promise<GetManyResult<E>> {\r\n const fullQuery = this.createBaseQuery(qb, request);\r\n const paginatedQuery = this.paginateQuery(fullQuery.clone(), request);\r\n\r\n const data = await paginatedQuery.getMany();\r\n const total = await fullQuery.getCount();\r\n\r\n const offset = request.offset ?? 0;\r\n const limit = request.limit ?? total;\r\n\r\n const count = data.length;\r\n const page = Math.floor(offset / limit) + 1;\r\n const pageCount = Math.ceil(total / limit);\r\n\r\n return {\r\n data,\r\n count,\r\n page,\r\n pageCount,\r\n total,\r\n };\r\n }\r\n\r\n /**\r\n * Creates a query filtered from the parsed request\r\n *\r\n * @param qb The base query builder\r\n * @param query The parsed query\r\n */\r\n protected createBaseQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n const paramsDefined: string[] = [];\r\n\r\n this.adaptSelect(qb, query.select);\r\n this.adaptRelations(qb, query.relations);\r\n this.adaptWhere(qb, query.where, false, paramsDefined);\r\n this.adaptOrder(qb, query.order);\r\n\r\n return qb;\r\n }\r\n\r\n /**\r\n * Paginates a query based on the parsed request\r\n *\r\n * @param qb The query builder\r\n * @param query The parsed query\r\n */\r\n protected paginateQuery<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, query: CrudRequest): SelectQueryBuilder<E> {\r\n return qb.limit(query.limit).offset(query.offset);\r\n }\r\n\r\n /**\r\n * Adapts a select\r\n *\r\n * @param qb The query builder\r\n * @param select The parsed select fields\r\n */\r\n protected adaptSelect<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, select: ParsedRequestSelect): void {\r\n qb.addSelect(select.map(s => s.field.join('.')));\r\n }\r\n\r\n /**\r\n * Adapts the join relation list\r\n *\r\n * @param qb The query builder\r\n * @param relations The parsed relation list\r\n */\r\n protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void {\r\n for (const relation of relations) {\r\n const path = relation.field.join('.');\r\n const alias = relation.alias || path.replace('.', '_');\r\n\r\n qb.leftJoin(path, alias);\r\n }\r\n }\r\n\r\n /**\r\n * Adapts the order by list\r\n *\r\n * @param qb The query builder\r\n * @param ordering The parsed ordering\r\n */\r\n protected adaptOrder<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, ordering: CrudRequestOrder[]): void {\r\n for (const order of ordering) {\r\n const path = order.field.join('.');\r\n\r\n qb.addOrderBy(path, order.order);\r\n }\r\n }\r\n\r\n /**\r\n * Adapts a where condition\r\n *\r\n * @param qb The query builder\r\n * @param where The quere condition\r\n * @param or Whether this where condition is AND/OR\r\n * @param params The registered parameter name list\r\n */\r\n protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void {\r\n const addWhere = (or ? qb.orWhere : qb.andWhere).bind(qb);\r\n\r\n if (where.or && where.or.length > 0) {\r\n addWhere(new Brackets(\r\n wqb => where.or!.forEach(item => this.adaptWhere(wqb, item, true, params))\r\n ));\r\n } else if (where.and && where.and.length > 0) {\r\n addWhere(new Brackets(\r\n wqb => where.and!.forEach(item => this.adaptWhere(wqb, item, false, params))\r\n ));\r\n } else if (where.field) {\r\n const param = this.createParam(params, where.field);\r\n const query = this.mapWhereOperators(where as CrudRequestWhereField, param);\r\n\r\n addWhere(query.where, query.params);\r\n }\r\n }\r\n\r\n /**\r\n * Creates a query parameter name based on a field\r\n *\r\n * @param paramsDefined The array the parameter will be registered onto\r\n * @param field The field path\r\n */\r\n protected createParam(paramsDefined: string[], field: string[]): string {\r\n const name = field.length > 0 ? field[field.length - 1] : '';\r\n let param: string;\r\n let iteration: number = 0;\r\n\r\n do {\r\n param = 'req_' + name + '_' + iteration;\r\n iteration++;\r\n } while (paramsDefined.includes(param));\r\n\r\n paramsDefined.push(param);\r\n return param;\r\n }\r\n\r\n /**\r\n * Maps where operators to a pseudo-SQL statement and a parameter map\r\n *\r\n * @param where The where condition\r\n * @param param The parameter name\r\n */\r\n protected mapWhereOperators(where: CrudRequestWhereField, param: string): { where: string, params: ObjectLiteral } {\r\n const field = where.field.join('.');\r\n const operator = where.operator;\r\n let value: unknown = where.value;\r\n\r\n switch (operator) {\r\n case CrudRequestWhereOperator.EQ:\r\n return { where: `${field} = :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NEQ:\r\n return { where: `${field} != :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GT:\r\n return { where: `${field} > :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.GTE:\r\n return { where: `${field} >= :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LT:\r\n return { where: `${field} < :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.LTE:\r\n return { where: `${field} <= :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.STARTS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS:\r\n return { where: `${field} NOT LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.IN:\r\n value = ensureArray('IN operator', value, 1);\r\n\r\n return { where: `${field} IN (:...${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NOT_IN:\r\n value = ensureArray('NOT IN operator', value, 1);\r\n\r\n return { where: `${field} NOT IN (:...${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.BETWEEN:\r\n const arr = ensureArray('BETWEEN operator', value, 2);\r\n\r\n return {\r\n where: `${field} BETWEEN :${param}_start AND :${param}_end`,\r\n params: { [`${param}_start`]: arr[0], [`${param}_end`]: arr[1] },\r\n };\r\n\r\n case CrudRequestWhereOperator.IS_NULL:\r\n ensureFalsy('IS NULL operator', value);\r\n\r\n return { where: `${field} IS NULL`, params: {} };\r\n\r\n case CrudRequestWhereOperator.NOT_NULL:\r\n ensureFalsy('NOT NULL operator', value);\r\n\r\n return { where: `${field} IS NOT NULL`, params: {} };\r\n\r\n case CrudRequestWhereOperator.EQ_LOWER:\r\n return { where: `LOWER(${field}) = :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NEQ_LOWER:\r\n return { where: `LOWER(${field}) != :${param}`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.STARTS_LOWER:\r\n return { where: `LOWER(${field}) LIKE :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { where: `LOWER(${field}) LIKE :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { where: `${field} LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { where: `${field} NOT LIKE :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.IN_LOWER:\r\n ensureArray('IN operator', value, 1);\r\n\r\n return { where: `${field} IN (...:${param})`, params: { [param]: value } };\r\n\r\n case CrudRequestWhereOperator.NOT_IN_LOWER:\r\n ensureArray('NOT IN operator', value, 1);\r\n\r\n return { where: `${field} NOT IN (...:${param})`, params: { [param]: value } };\r\n\r\n default:\r\n throw new Error(`Unknown operator \"${operator}\"`);\r\n }\r\n }\r\n\r\n}\r\n","import { CrudRequestFields } from '../models/crud-request';\r\n\r\n/*export function setFieldByPath<T>(obj: ParsedRequestFields<T>, field: string, value: T): void {\r\n const parts = field.split('.');\r\n\r\n while (parts.length > 1) {\r\n const name = parts.shift();\r\n\r\n if (!Array.isArray(obj[name]))\r\n obj[name] = {};\r\n\r\n obj = obj[name] as ParsedRequestFields<T>;\r\n }\r\n\r\n obj[parts.shift()] = value;\r\n}*/\r\n\r\nexport function ensureArray<T>(fieldName: string, data: T[] | any, minLength: number = 0): T[] {\r\n if (!Array.isArray(data) || data.length < minLength)\r\n throw new Error(`${fieldName} must be an array with at least ${minLength} items`);\r\n\r\n return data;\r\n}\r\n\r\nexport function ensureFalsy(fieldName: string, data: any) {\r\n if (data)\r\n throw new Error(`${fieldName} must be null`);\r\n}\r\n\r\nexport function isValid(value: any): value is object {\r\n return value !== null && value !== undefined;\r\n}\r\n"],"mappings":"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","names":["Brackets","ensureArray","fieldName","data","minLength","__name","ensureFalsy","TypeormQueryAdapter","__name","qb","query","request","fullQuery","data","total","offset","limit","count","page","pageCount","paramsDefined","select","s","relations","relation","path","alias","ordering","order","where","or","params","addWhere","Brackets","wqb","item","param","field","name","iteration","operator","value","ensureArray","arr","ensureFalsy"]}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Field path
3
+ *
4
+ * For post.category.name, this would be ["post", "category", "name"]
5
+ */
6
+ type FieldPath = string[];
7
+
8
+ type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;
9
+ interface CrudRequestWhereAND {
10
+ field?: never;
11
+ or?: never;
12
+ and: CrudRequestWhere[];
13
+ }
14
+ interface CrudRequestWhereOR {
15
+ field?: never;
16
+ or: CrudRequestWhere[];
17
+ and?: never;
18
+ }
19
+ interface CrudRequestWhereField {
20
+ /**
21
+ * Field path
22
+ *
23
+ * For post.category.name, this would be ["post", "category", "name"]
24
+ */
25
+ field: FieldPath;
26
+ /**
27
+ * The operator of the comparison
28
+ */
29
+ operator: CrudRequestWhereOperator;
30
+ /**
31
+ * The value to compare
32
+ */
33
+ value: CrudRequestWhereValueType | CrudRequestWhereValueType[];
34
+ or?: never;
35
+ and?: never;
36
+ }
37
+ type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;
38
+ declare enum CrudRequestWhereOperator {
39
+ EQ = "eq",
40
+ NEQ = "neq",
41
+ GT = "gt",
42
+ GTE = "gte",
43
+ LT = "lt",
44
+ LTE = "lte",
45
+ STARTS = "starts",
46
+ ENDS = "ends",
47
+ CONTAINS = "contains",
48
+ NOT_CONTAINS = "not_contains",
49
+ IN = "in",
50
+ NOT_IN = "not_in",
51
+ BETWEEN = "between",
52
+ IS_NULL = "is_null",
53
+ NOT_NULL = "not_null",
54
+ EQ_LOWER = "eq_lower",
55
+ NEQ_LOWER = "neq_lower",
56
+ STARTS_LOWER = "starts_lower",
57
+ ENDS_LOWER = "ends_lower",
58
+ CONTAINS_LOWER = "contains_lower",
59
+ NOT_CONTAINS_LOWER = "not_contains_lower",
60
+ IN_LOWER = "in_lower",
61
+ NOT_IN_LOWER = "not_in_lower"
62
+ }
63
+
64
+ interface CrudRequestFields {
65
+ field: FieldPath;
66
+ }
67
+ interface CrudRequestRelation extends CrudRequestFields {
68
+ alias?: string;
69
+ }
70
+ interface CrudRequestOrder extends CrudRequestFields {
71
+ order: 'ASC' | 'DESC';
72
+ }
73
+ type ParsedRequestSelect = CrudRequestFields[];
74
+ interface CrudRequest {
75
+ select: ParsedRequestSelect;
76
+ relations: CrudRequestRelation[];
77
+ order: CrudRequestOrder[];
78
+ where: CrudRequestWhere;
79
+ limit?: number;
80
+ offset?: number;
81
+ }
82
+
83
+ export { type CrudRequestFields as C, type FieldPath as F, type ParsedRequestSelect as P, type CrudRequestRelation as a, type CrudRequestOrder as b, type CrudRequest as c, type CrudRequestWhere as d, type CrudRequestWhereAND as e, type CrudRequestWhereOR as f, type CrudRequestWhereField as g, type CrudRequestWhereValueType as h, CrudRequestWhereOperator as i };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Field path
3
+ *
4
+ * For post.category.name, this would be ["post", "category", "name"]
5
+ */
6
+ type FieldPath = string[];
7
+
8
+ type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;
9
+ interface CrudRequestWhereAND {
10
+ field?: never;
11
+ or?: never;
12
+ and: CrudRequestWhere[];
13
+ }
14
+ interface CrudRequestWhereOR {
15
+ field?: never;
16
+ or: CrudRequestWhere[];
17
+ and?: never;
18
+ }
19
+ interface CrudRequestWhereField {
20
+ /**
21
+ * Field path
22
+ *
23
+ * For post.category.name, this would be ["post", "category", "name"]
24
+ */
25
+ field: FieldPath;
26
+ /**
27
+ * The operator of the comparison
28
+ */
29
+ operator: CrudRequestWhereOperator;
30
+ /**
31
+ * The value to compare
32
+ */
33
+ value: CrudRequestWhereValueType | CrudRequestWhereValueType[];
34
+ or?: never;
35
+ and?: never;
36
+ }
37
+ type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;
38
+ declare enum CrudRequestWhereOperator {
39
+ EQ = "eq",
40
+ NEQ = "neq",
41
+ GT = "gt",
42
+ GTE = "gte",
43
+ LT = "lt",
44
+ LTE = "lte",
45
+ STARTS = "starts",
46
+ ENDS = "ends",
47
+ CONTAINS = "contains",
48
+ NOT_CONTAINS = "not_contains",
49
+ IN = "in",
50
+ NOT_IN = "not_in",
51
+ BETWEEN = "between",
52
+ IS_NULL = "is_null",
53
+ NOT_NULL = "not_null",
54
+ EQ_LOWER = "eq_lower",
55
+ NEQ_LOWER = "neq_lower",
56
+ STARTS_LOWER = "starts_lower",
57
+ ENDS_LOWER = "ends_lower",
58
+ CONTAINS_LOWER = "contains_lower",
59
+ NOT_CONTAINS_LOWER = "not_contains_lower",
60
+ IN_LOWER = "in_lower",
61
+ NOT_IN_LOWER = "not_in_lower"
62
+ }
63
+
64
+ interface CrudRequestFields {
65
+ field: FieldPath;
66
+ }
67
+ interface CrudRequestRelation extends CrudRequestFields {
68
+ alias?: string;
69
+ }
70
+ interface CrudRequestOrder extends CrudRequestFields {
71
+ order: 'ASC' | 'DESC';
72
+ }
73
+ type ParsedRequestSelect = CrudRequestFields[];
74
+ interface CrudRequest {
75
+ select: ParsedRequestSelect;
76
+ relations: CrudRequestRelation[];
77
+ order: CrudRequestOrder[];
78
+ where: CrudRequestWhere;
79
+ limit?: number;
80
+ offset?: number;
81
+ }
82
+
83
+ export { type CrudRequestFields as C, type FieldPath as F, type ParsedRequestSelect as P, type CrudRequestRelation as a, type CrudRequestOrder as b, type CrudRequest as c, type CrudRequestWhere as d, type CrudRequestWhereAND as e, type CrudRequestWhereOR as f, type CrudRequestWhereField as g, type CrudRequestWhereValueType as h, CrudRequestWhereOperator as i };
@@ -0,0 +1,37 @@
1
+ import { c as CrudRequest, d as CrudRequestWhere } from '../crud-request-CvDKp6Iy.mjs';
2
+
3
+ /**
4
+ * Ensures a condition is always applied to the query
5
+ *
6
+ * @param request The parsed request
7
+ * @param condition The condition that needs to be applied
8
+ */
9
+ declare function ensureCondition(request: CrudRequest, condition: CrudRequestWhere): CrudRequest;
10
+
11
+ /**
12
+ * Ensures that the limit will be set following a maximum rule
13
+ *
14
+ * @param request The parsed request
15
+ * @param defaultLimit The default limit number
16
+ * @param maxLimit The maximum allowed limit number
17
+ */
18
+ declare function ensureLimit(request: CrudRequest, defaultLimit: number, maxLimit: number): CrudRequest;
19
+
20
+ /**
21
+ * Filters access to an allowlist of properties and relations.
22
+ * No selecting, filtering, sorting and joining can be done on a property that is not listed.
23
+ *
24
+ * @param request The parsed request
25
+ * @param allowedProperties The list of properties (in case of a field path, separated by dot) that will be allowed
26
+ */
27
+ declare function filterProperties(request: CrudRequest, allowedProperties: string[]): CrudRequest;
28
+
29
+ /**
30
+ * Filters access to an allowlist of relations.
31
+ *
32
+ * @param request The parsed request
33
+ * @param allowedRelations The list of relations (in case of a field path, separated by dot) that will be allowed
34
+ */
35
+ declare function filterRelations(request: CrudRequest, allowedRelations: string[]): CrudRequest;
36
+
37
+ export { ensureCondition, ensureLimit, filterProperties, filterRelations };