crud-query-parser 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -5,14 +5,9 @@ This library parses HTTP requests and converts them to TypeORM query builders, a
5
5
  ## Install
6
6
 
7
7
  ```sh
8
- npm install @crud-query-parser/core
8
+ npm install crud-query-parser
9
9
  ```
10
10
 
11
- ### Other modules
12
-
13
- - `@crud-query-parser/typeorm`: TypeORM adapter
14
- - `@crud-query-parser/nestjs`: NestJS utilities
15
-
16
11
  ## Usage
17
12
 
18
13
  You have to pick a request parser and a query adapter.
@@ -40,12 +35,15 @@ console.log(result);
40
35
 
41
36
  ### CRUD
42
37
 
43
- This parser fully compatible with `@nestjsx/crud`
38
+ The CRUD parser is an implementation of the `@nestjsx/crud` [query params format](https://github.com/nestjsx/crud/wiki/Requests#query-params).
44
39
 
45
40
  ```ts
46
41
  import { CrudRequestParser } from 'crud-query-parser/parsers/crud';
47
42
 
48
43
  const parser = new CrudRequestParser();
44
+
45
+ // Then, you have to pass a query string object to it
46
+ // const crudRequest = parser.parse(request.query);
49
47
  ```
50
48
 
51
49
  ## Database adapters
@@ -59,7 +57,8 @@ import { TypeormQueryAdapter } from 'crud-query-parser/adapters/typeorm';
59
57
 
60
58
  const adapter = new TypeormQueryAdapter();
61
59
 
62
- //
60
+ // Then, you can pass a query builder to it:
61
+ // const result = adapter.getMany(repository.createQueryBuilder(), crudRequest);
63
62
  ```
64
63
 
65
64
  ## Helpers
@@ -74,15 +73,37 @@ Sample code:
74
73
  @Controller('users')
75
74
  export class UserController {
76
75
 
76
+ constructor(
77
+ private service: UserService,
78
+ ) {}
79
+
77
80
  @Get()
78
- @Crud(CrudRequestParser)
79
- public async getMany(@ParseCrudRequest() crudRequest: CrudRequest) {
81
+ @Crud(CrudRequestParser) // <- You specify which parser to use
82
+ public async getMany(@ParseCrudRequest() crudRequest: CrudRequest) { // <- The request query will be automatically parsed
80
83
  return this.service.getMany(crudRequest);
81
84
  }
82
85
 
83
86
  }
84
87
  ```
85
88
 
89
+ ```ts
90
+ @Injectable()
91
+ export class UserService {
92
+
93
+ protected crudAdapter = new TypeormQueryAdapter();
94
+
95
+ constructor(
96
+ @InjectRepository(UserEntity)
97
+ private repository: Repository<UserEntity>,
98
+ ) {}
99
+
100
+ public async getMany(crudRequest: CrudRequest) {
101
+ return await this.crudAdapter.getMany(this.repository.createQueryBuilder(), crudRequest);
102
+ }
103
+
104
+ }
105
+ ```
106
+
86
107
  ## Filters
87
108
 
88
109
  You may need to filter what the user can or cannot query. You can modify the `CrudRequest` object as needed.
@@ -100,7 +121,7 @@ import { ensureCondition } from 'crud-query-parser/filters';
100
121
 
101
122
  crudRequest = ensureCondition(crudRequest, {
102
123
  field: ['isActive'],
103
- operator: ParsedRequestWhereOperator.EQ,
124
+ operator: CrudRequestWhereOperator.EQ,
104
125
  value: true,
105
126
  });
106
127
  ```
@@ -2,10 +2,20 @@ import { SelectQueryBuilder, ObjectLiteral, WhereExpressionBuilder } from 'typeo
2
2
  import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-BliD9hJN.mjs';
3
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
4
 
5
+ interface TypeOrmQueryAdapterOptions {
6
+ /**
7
+ * Whether it will use ILIKE for case-insensitive operations.
8
+ *
9
+ * If undefined, it will be enabled by default for postgres and aurora-postgres databases
10
+ */
11
+ ilike?: boolean;
12
+ }
5
13
  /**
6
14
  * Adapts queries to TypeORM query builder object
7
15
  */
8
- declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
16
+ declare class TypeOrmQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
17
+ private readonly options;
18
+ constructor(options?: TypeOrmQueryAdapterOptions);
9
19
  /**
10
20
  * @inheritDoc
11
21
  */
@@ -44,8 +54,9 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
44
54
  *
45
55
  * @param qb The query builder
46
56
  * @param relations The parsed relation list
57
+ * @param select The parsed select fields
47
58
  */
48
- protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void;
59
+ protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[], select: ParsedRequestSelect): void;
49
60
  /**
50
61
  * Adapts the order by list
51
62
  *
@@ -56,12 +67,14 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
56
67
  /**
57
68
  * Adapts a where condition
58
69
  *
70
+ * @param alias The query builder alias
59
71
  * @param qb The query builder
60
72
  * @param where The quere condition
61
73
  * @param or Whether this where condition is AND/OR
62
74
  * @param params The registered parameter name list
75
+ * @param isILikeEnabled Whether the ILIKE operator can be used
63
76
  */
64
- protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void;
77
+ protected adaptWhere(alias: string, qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[], isILikeEnabled: boolean): void;
65
78
  /**
66
79
  * Creates a query parameter name based on a field
67
80
  *
@@ -72,13 +85,17 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
72
85
  /**
73
86
  * Maps where operators to a pseudo-SQL statement and a parameter map
74
87
  *
88
+ * @param alias The query builder alias
75
89
  * @param where The where condition
76
90
  * @param param The parameter name
91
+ * @param isILikeEnabled Whether the ILIKE operator can be used
77
92
  */
78
- protected mapWhereOperators(where: CrudRequestWhereField, param: string): {
93
+ protected mapWhereOperators(alias: string, where: CrudRequestWhereField, param: string, isILikeEnabled: boolean): {
79
94
  where: string;
80
95
  params: ObjectLiteral;
81
96
  };
97
+ protected createLowerLike(isILikeEnabled: boolean, field: string, not?: boolean): string;
98
+ protected isILikeEnabled(qb: SelectQueryBuilder<any>): boolean;
82
99
  }
83
100
 
84
- export { TypeormQueryAdapter };
101
+ export { TypeOrmQueryAdapter, type TypeOrmQueryAdapterOptions };
@@ -2,10 +2,20 @@ import { SelectQueryBuilder, ObjectLiteral, WhereExpressionBuilder } from 'typeo
2
2
  import { Q as QueryAdapter, G as GetManyResult } from '../../query-adapter-Vebxws3V.js';
3
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
4
 
5
+ interface TypeOrmQueryAdapterOptions {
6
+ /**
7
+ * Whether it will use ILIKE for case-insensitive operations.
8
+ *
9
+ * If undefined, it will be enabled by default for postgres and aurora-postgres databases
10
+ */
11
+ ilike?: boolean;
12
+ }
5
13
  /**
6
14
  * Adapts queries to TypeORM query builder object
7
15
  */
8
- declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
16
+ declare class TypeOrmQueryAdapter implements QueryAdapter<SelectQueryBuilder<any>, ObjectLiteral> {
17
+ private readonly options;
18
+ constructor(options?: TypeOrmQueryAdapterOptions);
9
19
  /**
10
20
  * @inheritDoc
11
21
  */
@@ -44,8 +54,9 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
44
54
  *
45
55
  * @param qb The query builder
46
56
  * @param relations The parsed relation list
57
+ * @param select The parsed select fields
47
58
  */
48
- protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[]): void;
59
+ protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[], select: ParsedRequestSelect): void;
49
60
  /**
50
61
  * Adapts the order by list
51
62
  *
@@ -56,12 +67,14 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
56
67
  /**
57
68
  * Adapts a where condition
58
69
  *
70
+ * @param alias The query builder alias
59
71
  * @param qb The query builder
60
72
  * @param where The quere condition
61
73
  * @param or Whether this where condition is AND/OR
62
74
  * @param params The registered parameter name list
75
+ * @param isILikeEnabled Whether the ILIKE operator can be used
63
76
  */
64
- protected adaptWhere(qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[]): void;
77
+ protected adaptWhere(alias: string, qb: WhereExpressionBuilder, where: CrudRequestWhere, or: boolean, params: string[], isILikeEnabled: boolean): void;
65
78
  /**
66
79
  * Creates a query parameter name based on a field
67
80
  *
@@ -72,13 +85,17 @@ declare class TypeormQueryAdapter implements QueryAdapter<SelectQueryBuilder<any
72
85
  /**
73
86
  * Maps where operators to a pseudo-SQL statement and a parameter map
74
87
  *
88
+ * @param alias The query builder alias
75
89
  * @param where The where condition
76
90
  * @param param The parameter name
91
+ * @param isILikeEnabled Whether the ILIKE operator can be used
77
92
  */
78
- protected mapWhereOperators(where: CrudRequestWhereField, param: string): {
93
+ protected mapWhereOperators(alias: string, where: CrudRequestWhereField, param: string, isILikeEnabled: boolean): {
79
94
  where: string;
80
95
  params: ObjectLiteral;
81
96
  };
97
+ protected createLowerLike(isILikeEnabled: boolean, field: string, not?: boolean): string;
98
+ protected isILikeEnabled(qb: SelectQueryBuilder<any>): boolean;
82
99
  }
83
100
 
84
- export { TypeormQueryAdapter };
101
+ export { TypeOrmQueryAdapter, type TypeOrmQueryAdapterOptions };
@@ -1,2 +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});
1
+ "use strict";var E=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var c=(o,t)=>E(o,"name",{value:t,configurable:!0});var _=(o,t)=>{for(var r in t)E(o,r,{get:t[r],enumerable:!0})},w=(o,t,r,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of g(t))!O.call(o,i)&&i!==r&&E(o,i,{get:()=>t[i],enumerable:!(e=T(t,i))||e.enumerable});return o};var S=o=>w(E({},"__esModule",{value:!0}),o);var R={};_(R,{TypeOrmQueryAdapter:()=>N});module.exports=S(R);var h=require("typeorm");function d(o,t,r=0){if(!Array.isArray(t)||t.length<r)throw new Error(`${o} must be an array with at least ${r} items`);return t}c(d,"ensureArray");function f(o,t){if(t)throw new Error(`${o} must be null`)}c(f,"ensureFalsy");function L(o){return o!=null}c(L,"isValid");function $(o,t){return o.length-1!==t.length?!1:t.every((r,e)=>o[e]===r)}c($,"pathHasBase");var N=class{constructor(t={}){this.options=t}static{c(this,"TypeOrmQueryAdapter")}build(t,r){return t=this.createBaseQuery(t,r),t=this.paginateQuery(t,r),t}async getOne(t,r){return await this.createBaseQuery(t,r).getOne()??null}async getMany(t,r){let e=this.createBaseQuery(t,r),s=await this.paginateQuery(e.clone(),r).getMany(),a=await e.getCount(),n=r.offset??0,l=r.limit??a,u=s.length,p=Math.floor(n/l)+1,y=Math.ceil(a/l);return{data:s,count:u,page:p,pageCount:y,total:a}}createBaseQuery(t,r){let e=[],i=this.isILikeEnabled(t);return this.adaptSelect(t,r.select),this.adaptRelations(t,r.relations,r.select),this.adaptWhere(t.alias,t,r.where,!1,e,i),this.adaptOrder(t,r.order),t}paginateQuery(t,r){return t.limit(r.limit).offset(r.offset)}adaptSelect(t,r){if(r.length===0)return;let e=r.filter(i=>i.field.length===1);t.select(e.map(i=>[t.alias,...i.field].join(".")))}adaptRelations(t,r,e){for(let i of r){let s=[t.alias,...i.field].join("."),a=i.alias||s.replace(".","_"),n=e.filter(l=>$(l.field,i.field));n.length===0?t.leftJoinAndSelect(s,a):(t.leftJoin(s,a),t.addSelect(n.map(l=>[a,l.field[l.field.length-1]].join("."))))}}adaptOrder(t,r){for(let e of r){let i=[t.alias,...e.field].join(".");t.addOrderBy(i,e.order)}}adaptWhere(t,r,e,i,s,a){let n=(i?r.orWhere:r.andWhere).bind(r);if(e.or&&e.or.length>0)n(new h.Brackets(l=>e.or.forEach(u=>this.adaptWhere(t,l,u,!0,s,a))));else if(e.and&&e.and.length>0)n(new h.Brackets(l=>e.and.forEach(u=>this.adaptWhere(t,l,u,!1,s,a))));else if(e.field){let l=this.createParam(s,e.field),u=this.mapWhereOperators(t,e,l,a);n(u.where,u.params)}}createParam(t,r){let e=r.length>0?r[r.length-1]:"",i,s=0;do i="req_"+e+"_"+s,s++;while(t.includes(i));return t.push(i),i}mapWhereOperators(t,r,e,i){let s=[t,...r.field].join("."),a=r.operator,n=r.value;switch(a){case"eq":return{where:`${s} = :${e}`,params:{[e]:n}};case"neq":return{where:`${s} != :${e}`,params:{[e]:n}};case"gt":return{where:`${s} > :${e}`,params:{[e]:n}};case"gte":return{where:`${s} >= :${e}`,params:{[e]:n}};case"lt":return{where:`${s} < :${e}`,params:{[e]:n}};case"lte":return{where:`${s} <= :${e}`,params:{[e]:n}};case"starts":return{where:`${s} LIKE :${e}`,params:{[e]:`${n}%`}};case"ends":return{where:`${s} LIKE :${e}`,params:{[e]:`%${n}`}};case"contains":return{where:`${s} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains":return{where:`${s} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in":return n=d("IN operator",n,1),{where:`${s} IN (:...${e})`,params:{[e]:n}};case"not_in":return n=d("NOT IN operator",n,1),{where:`${s} NOT IN (:...${e})`,params:{[e]:n}};case"between":let l=d("BETWEEN operator",n,2);return{where:`${s} BETWEEN :${e}_start AND :${e}_end`,params:{[`${e}_start`]:l[0],[`${e}_end`]:l[1]}};case"is_null":return f("IS NULL operator",n),{where:`${s} IS NULL`,params:{}};case"not_null":return f("NOT NULL operator",n),{where:`${s} IS NOT NULL`,params:{}};case"eq_lower":return{where:`LOWER(${s}) = :${e}`,params:{[e]:n}};case"neq_lower":return{where:`LOWER(${s}) != :${e}`,params:{[e]:n}};case"starts_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`${n}%`}};case"ends_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`%${n}`}};case"contains_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`%${n}%`}};case"not_contains_lower":return{where:`${this.createLowerLike(i,s,!0)} :${e}`,params:{[e]:`%${n}%`}};case"in_lower":return d("IN operator",n,1),{where:`LOWER(${s}) IN (...:${e})`,params:{[e]:n}};case"not_in_lower":return d("NOT IN operator",n,1),{where:`LOWER(${s}) NOT IN (...:${e})`,params:{[e]:n}};default:throw new Error(`Unknown operator "${a}"`)}}createLowerLike(t,r,e=!1){return t?e?`${r} NOT ILIKE`:`${r} ILIKE`:e?`LOWER(${r}) NOT LIKE`:`LOWER(${r}) LIKE`}isILikeEnabled(t){let r=this.options.ilike;if(L(r))return r;let e=t.connection.options.type;return e==="postgres"||e==="aurora-postgres"}};0&&(module.exports={TypeOrmQueryAdapter});
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/adapters/typeorm/index.ts","../../../src/adapters/typeorm/typeorm.query-adapter.ts","../../../src/utils/functions.ts","../../../src/utils/field-path.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 { CrudRequest, CrudRequestOrder, CrudRequestRelation, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { CrudRequestWhere, CrudRequestWhereField, CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { ensureArray, ensureFalsy, isValid } from '../../utils/functions';\r\nimport { pathHasBase } from '../../utils/field-path';\r\n\r\nexport interface TypeOrmQueryAdapterOptions {\r\n /**\r\n * Whether it will use ILIKE for case-insensitive operations.\r\n *\r\n * If undefined, it will be enabled by default for postgres and aurora-postgres databases\r\n */\r\n ilike?: boolean;\r\n}\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 constructor(\r\n private readonly options: TypeOrmQueryAdapterOptions = {},\r\n ) {}\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 const isILikeEnabled = this.isILikeEnabled(qb);\r\n\r\n this.adaptSelect(qb, query.select);\r\n this.adaptRelations(qb, query.relations, query.select);\r\n this.adaptWhere(qb.alias, qb, query.where, false, paramsDefined, isILikeEnabled);\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 if (select.length === 0)\r\n return;\r\n\r\n // Only fields that are one level deep\r\n const fields = select.filter(f => f.field.length === 1);\r\n\r\n qb.select(fields.map(s => [qb.alias, ...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 * @param select The parsed select fields\r\n */\r\n protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[], select: ParsedRequestSelect): void {\r\n for (const relation of relations) {\r\n const path = [qb.alias, ...relation.field].join('.');\r\n const alias = relation.alias || path.replace('.', '_');\r\n\r\n const fields = select.filter(f => pathHasBase(f.field, relation.field));\r\n\r\n if (fields.length === 0) {\r\n qb.leftJoinAndSelect(path, alias);\r\n } else {\r\n qb.leftJoin(path, alias);\r\n qb.addSelect(fields.map(f => [alias, f.field[f.field.length - 1]].join('.')));\r\n }\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 = [qb.alias, ...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 alias The query builder alias\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 * @param isILikeEnabled Whether the ILIKE operator can be used\r\n */\r\n protected adaptWhere(\r\n alias: string,\r\n qb: WhereExpressionBuilder,\r\n where: CrudRequestWhere,\r\n or: boolean,\r\n params: string[],\r\n isILikeEnabled: boolean,\r\n ): 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(alias, wqb, item, true, params, isILikeEnabled))\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(alias, wqb, item, false, params, isILikeEnabled))\r\n ));\r\n } else if (where.field) {\r\n const param = this.createParam(params, where.field);\r\n const query = this.mapWhereOperators(alias, where as CrudRequestWhereField, param, isILikeEnabled);\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 alias The query builder alias\r\n * @param where The where condition\r\n * @param param The parameter name\r\n * @param isILikeEnabled Whether the ILIKE operator can be used\r\n */\r\n protected mapWhereOperators(\r\n alias: string,\r\n where: CrudRequestWhereField,\r\n param: string,\r\n isILikeEnabled: boolean,\r\n ): { where: string, params: ObjectLiteral } {\r\n const field = [alias, ...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: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field, true)} :${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: `LOWER(${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: `LOWER(${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 protected createLowerLike(isILikeEnabled: boolean, field: string, not: boolean = false): string {\r\n if (isILikeEnabled)\r\n return not ? `${field} NOT ILIKE` : `${field} ILIKE`;\r\n\r\n return not ? `LOWER(${field}) NOT LIKE` : `LOWER(${field}) LIKE`;\r\n }\r\n\r\n protected isILikeEnabled(qb: SelectQueryBuilder<any>): boolean {\r\n const ilikeEnabled = this.options.ilike;\r\n\r\n if (isValid(ilikeEnabled))\r\n return ilikeEnabled;\r\n\r\n const type = qb.connection.options.type;\r\n return type === 'postgres' || type === 'aurora-postgres';\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 ensurePrimitive(fieldName: string, data: any) {\r\n if (data === null || data === undefined)\r\n return;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean')\r\n return;\r\n\r\n if (data instanceof Date)\r\n return;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\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<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n","/**\r\n * Checks whether two field paths are equal\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] is equal to [\"path\", \"to\", \"field\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathEquals(path1: string[], path2: string[]): boolean {\r\n if (path1.length !== path2.length)\r\n return false;\r\n\r\n return path1.every((p1, i) => path2[i] === p1);\r\n}\r\n\r\n/**\r\n * Checks whether a path starts with another path.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] starts with [\"path\"] or [\"path\", \"to\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathStartsWith(path: string[], start: string[]): boolean {\r\n if (path.length < start.length)\r\n return false;\r\n\r\n return start.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Checks whether the base of a path matches.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] has a base of [\"path\", \"to\"] but not [\"path\"]\r\n */\r\nexport function pathHasBase(path: string[], base: string[]): boolean {\r\n if (path.length - 1 !== base.length)\r\n return false;\r\n\r\n return base.every((start, i) => path[i] === start);\r\n}\r\n"],"mappings":"4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yBAAAE,IAAA,eAAAC,EAAAH,GCAA,IAAAI,EAAoF,mBC8B7E,SAASC,EAAeC,EAAmBC,EAAiBC,EAAoB,EAAQ,CAC7F,GAAI,CAAC,MAAM,QAAQD,CAAI,GAAKA,EAAK,OAASC,EACxC,MAAM,IAAI,MAAM,GAAGF,CAAS,mCAAmCE,CAAS,QAAQ,EAElF,OAAOD,CACT,CALgBE,EAAAJ,EAAA,eAOT,SAASK,EAAYJ,EAAmBC,EAAW,CACxD,GAAIA,EACF,MAAM,IAAI,MAAM,GAAGD,CAAS,eAAe,CAC/C,CAHgBG,EAAAC,EAAA,eAKT,SAASC,EAAWC,EAAyC,CAClE,OAAOA,GAAU,IACnB,CAFgBH,EAAAE,EAAA,WCbT,SAASE,EAAYC,EAAgBC,EAAyB,CACnE,OAAID,EAAK,OAAS,IAAMC,EAAK,OACpB,GAEFA,EAAK,MAAM,CAACC,EAAOC,IAAMH,EAAKG,CAAC,IAAMD,CAAK,CACnD,CALgBE,EAAAL,EAAA,eFTT,IAAMM,EAAN,KAA0F,CAE/F,YACmBC,EAAsC,CAAC,EACxD,CADiB,aAAAA,CAChB,CAxBL,MAoBiG,CAAAC,EAAA,4BASxF,MAA+BC,EAA2BC,EAA2C,CAC1G,OAAAD,EAAK,KAAK,gBAAgBA,EAAIC,CAAK,EACnCD,EAAK,KAAK,cAAcA,EAAIC,CAAK,EAE1BD,CACT,CAKA,MAAa,OAAgCA,EAAiCE,EAAyC,CAIrH,OAFe,MADD,KAAK,gBAAgBF,EAAIE,CAAO,EACnB,OAAO,GAEjB,IACnB,CAKA,MAAa,QAAiCF,EAAiCE,EAAiD,CAC9H,IAAMC,EAAY,KAAK,gBAAgBH,EAAIE,CAAO,EAG5CE,EAAO,MAFU,KAAK,cAAcD,EAAU,MAAM,EAAGD,CAAO,EAElC,QAAQ,EACpCG,EAAQ,MAAMF,EAAU,SAAS,EAEjCG,EAASJ,EAAQ,QAAU,EAC3BK,EAAQL,EAAQ,OAASG,EAEzBG,EAAQJ,EAAK,OACbK,EAAO,KAAK,MAAMH,EAASC,CAAK,EAAI,EACpCG,EAAY,KAAK,KAAKL,EAAQE,CAAK,EAEzC,MAAO,CACL,KAAAH,EACA,MAAAI,EACA,KAAAC,EACA,UAAAC,EACA,MAAAL,CACF,CACF,CAQU,gBAAyCL,EAA2BC,EAA2C,CACvH,IAAMU,EAA0B,CAAC,EAC3BC,EAAiB,KAAK,eAAeZ,CAAE,EAE7C,YAAK,YAAYA,EAAIC,EAAM,MAAM,EACjC,KAAK,eAAeD,EAAIC,EAAM,UAAWA,EAAM,MAAM,EACrD,KAAK,WAAWD,EAAG,MAAOA,EAAIC,EAAM,MAAO,GAAOU,EAAeC,CAAc,EAC/E,KAAK,WAAWZ,EAAIC,EAAM,KAAK,EAExBD,CACT,CAQU,cAAuCA,EAA2BC,EAA2C,CACrH,OAAOD,EAAG,MAAMC,EAAM,KAAK,EAAE,OAAOA,EAAM,MAAM,CAClD,CAQU,YAAqCD,EAA2Ba,EAAmC,CAC3G,GAAIA,EAAO,SAAW,EACpB,OAGF,IAAMC,EAASD,EAAO,OAAOE,GAAKA,EAAE,MAAM,SAAW,CAAC,EAEtDf,EAAG,OAAOc,EAAO,IAAIE,GAAK,CAAChB,EAAG,MAAO,GAAGgB,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAC7D,CASU,eAAwChB,EAA2BiB,EAAkCJ,EAAmC,CAChJ,QAAWK,KAAYD,EAAW,CAChC,IAAME,EAAO,CAACnB,EAAG,MAAO,GAAGkB,EAAS,KAAK,EAAE,KAAK,GAAG,EAC7CE,EAAQF,EAAS,OAASC,EAAK,QAAQ,IAAK,GAAG,EAE/CL,EAASD,EAAO,OAAOE,GAAKM,EAAYN,EAAE,MAAOG,EAAS,KAAK,CAAC,EAElEJ,EAAO,SAAW,EACpBd,EAAG,kBAAkBmB,EAAMC,CAAK,GAEhCpB,EAAG,SAASmB,EAAMC,CAAK,EACvBpB,EAAG,UAAUc,EAAO,IAAIC,GAAK,CAACK,EAAOL,EAAE,MAAMA,EAAE,MAAM,OAAS,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,EAEhF,CACF,CAQU,WAAoCf,EAA2BsB,EAAoC,CAC3G,QAAWC,KAASD,EAAU,CAC5B,IAAMH,EAAO,CAACnB,EAAG,MAAO,GAAGuB,EAAM,KAAK,EAAE,KAAK,GAAG,EAEhDvB,EAAG,WAAWmB,EAAMI,EAAM,KAAK,CACjC,CACF,CAYU,WACRH,EACApB,EACAwB,EACAC,EACAC,EACAd,EACM,CACN,IAAMe,GAAYF,EAAKzB,EAAG,QAAUA,EAAG,UAAU,KAAKA,CAAE,EAExD,GAAIwB,EAAM,IAAMA,EAAM,GAAG,OAAS,EAChCG,EAAS,IAAI,WACXC,GAAOJ,EAAM,GAAI,QAAQK,GAAQ,KAAK,WAAWT,EAAOQ,EAAKC,EAAM,GAAMH,EAAQd,CAAc,CAAC,CAClG,CAAC,UACQY,EAAM,KAAOA,EAAM,IAAI,OAAS,EACzCG,EAAS,IAAI,WACXC,GAAOJ,EAAM,IAAK,QAAQK,GAAQ,KAAK,WAAWT,EAAOQ,EAAKC,EAAM,GAAOH,EAAQd,CAAc,CAAC,CACpG,CAAC,UACQY,EAAM,MAAO,CACtB,IAAMM,EAAQ,KAAK,YAAYJ,EAAQF,EAAM,KAAK,EAC5CvB,EAAQ,KAAK,kBAAkBmB,EAAOI,EAAgCM,EAAOlB,CAAc,EAEjGe,EAAS1B,EAAM,MAAOA,EAAM,MAAM,CACpC,CACF,CAQU,YAAYU,EAAyBoB,EAAyB,CACtE,IAAMC,EAAOD,EAAM,OAAS,EAAIA,EAAMA,EAAM,OAAS,CAAC,EAAI,GACtDD,EACAG,EAAoB,EAExB,GACEH,EAAQ,OAASE,EAAO,IAAMC,EAC9BA,UACOtB,EAAc,SAASmB,CAAK,GAErC,OAAAnB,EAAc,KAAKmB,CAAK,EACjBA,CACT,CAUU,kBACRV,EACAI,EACAM,EACAlB,EAC0C,CAC1C,IAAMmB,EAAQ,CAACX,EAAO,GAAGI,EAAM,KAAK,EAAE,KAAK,GAAG,EACxCU,EAAWV,EAAM,SACnBW,EAAiBX,EAAM,MAE3B,OAAQU,EAAU,CAChB,SACE,MAAO,CAAE,MAAO,GAAGH,CAAK,OAAOD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAErE,UACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,QAAQD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAEtE,SACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,OAAOD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAErE,UACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,QAAQD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAEtE,SACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,OAAOD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAErE,UACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,QAAQD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAEtE,aACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,UAAUD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,GAAGK,CAAK,GAAI,CAAE,EAE9E,WACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,UAAUD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,EAAG,CAAE,EAE9E,eACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,UAAUD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,GAAI,CAAE,EAE/E,mBACE,MAAO,CAAE,MAAO,GAAGJ,CAAK,cAAcD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,GAAI,CAAE,EAEnF,SACE,OAAAA,EAAQC,EAAY,cAAeD,EAAO,CAAC,EAEpC,CAAE,MAAO,GAAGJ,CAAK,YAAYD,CAAK,IAAK,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAE3E,aACE,OAAAA,EAAQC,EAAY,kBAAmBD,EAAO,CAAC,EAExC,CAAE,MAAO,GAAGJ,CAAK,gBAAgBD,CAAK,IAAK,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAE/E,cACE,IAAME,EAAMD,EAAY,mBAAoBD,EAAO,CAAC,EAEpD,MAAO,CACL,MAAO,GAAGJ,CAAK,aAAaD,CAAK,eAAeA,CAAK,OACrD,OAAQ,CAAE,CAAC,GAAGA,CAAK,QAAQ,EAAGO,EAAI,CAAC,EAAG,CAAC,GAAGP,CAAK,MAAM,EAAGO,EAAI,CAAC,CAAE,CACjE,EAEF,cACE,OAAAC,EAAY,mBAAoBH,CAAK,EAE9B,CAAE,MAAO,GAAGJ,CAAK,WAAY,OAAQ,CAAC,CAAE,EAEjD,eACE,OAAAO,EAAY,oBAAqBH,CAAK,EAE/B,CAAE,MAAO,GAAGJ,CAAK,eAAgB,OAAQ,CAAC,CAAE,EAErD,eACE,MAAO,CAAE,MAAO,SAASA,CAAK,QAAQD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAE5E,gBACE,MAAO,CAAE,MAAO,SAASJ,CAAK,SAASD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAE7E,mBACE,MAAO,CAAE,MAAO,GAAG,KAAK,gBAAgBvB,EAAgBmB,CAAK,CAAC,KAAKD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,GAAGK,CAAK,GAAI,CAAE,EAE/G,iBACE,MAAO,CAAE,MAAO,GAAG,KAAK,gBAAgBvB,EAAgBmB,CAAK,CAAC,KAAKD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,EAAG,CAAE,EAE/G,qBACE,MAAO,CAAE,MAAO,GAAG,KAAK,gBAAgBvB,EAAgBmB,CAAK,CAAC,KAAKD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,GAAI,CAAE,EAEhH,yBACE,MAAO,CAAE,MAAO,GAAG,KAAK,gBAAgBvB,EAAgBmB,EAAO,EAAI,CAAC,KAAKD,CAAK,GAAI,OAAQ,CAAE,CAACA,CAAK,EAAG,IAAIK,CAAK,GAAI,CAAE,EAEtH,eACE,OAAAC,EAAY,cAAeD,EAAO,CAAC,EAE5B,CAAE,MAAO,SAASJ,CAAK,aAAaD,CAAK,IAAK,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAElF,mBACE,OAAAC,EAAY,kBAAmBD,EAAO,CAAC,EAEhC,CAAE,MAAO,SAASJ,CAAK,iBAAiBD,CAAK,IAAK,OAAQ,CAAE,CAACA,CAAK,EAAGK,CAAM,CAAE,EAEtF,QACE,MAAM,IAAI,MAAM,qBAAqBD,CAAQ,GAAG,CACpD,CACF,CAEU,gBAAgBtB,EAAyBmB,EAAeQ,EAAe,GAAe,CAC9F,OAAI3B,EACK2B,EAAM,GAAGR,CAAK,aAAe,GAAGA,CAAK,SAEvCQ,EAAM,SAASR,CAAK,aAAe,SAASA,CAAK,QAC1D,CAEU,eAAe/B,EAAsC,CAC7D,IAAMwC,EAAe,KAAK,QAAQ,MAElC,GAAIC,EAAQD,CAAY,EACtB,OAAOA,EAET,IAAME,EAAO1C,EAAG,WAAW,QAAQ,KACnC,OAAO0C,IAAS,YAAcA,IAAS,iBACzC,CAEF","names":["typeorm_exports","__export","TypeOrmQueryAdapter","__toCommonJS","import_typeorm","ensureArray","fieldName","data","minLength","__name","ensureFalsy","isValid","value","pathHasBase","path","base","start","i","__name","TypeOrmQueryAdapter","options","__name","qb","query","request","fullQuery","data","total","offset","limit","count","page","pageCount","paramsDefined","isILikeEnabled","select","fields","f","s","relations","relation","path","alias","pathHasBase","ordering","order","where","or","params","addWhere","wqb","item","param","field","name","iteration","operator","value","ensureArray","arr","ensureFalsy","not","ilikeEnabled","isValid","type"]}
@@ -1,2 +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};
1
+ var y=Object.defineProperty;var c=(a,t)=>y(a,"name",{value:t,configurable:!0});import{Brackets as N}from"typeorm";function d(a,t,r=0){if(!Array.isArray(t)||t.length<r)throw new Error(`${a} must be an array with at least ${r} items`);return t}c(d,"ensureArray");function E(a,t){if(t)throw new Error(`${a} must be null`)}c(E,"ensureFalsy");function f(a){return a!=null}c(f,"isValid");function h(a,t){return a.length-1!==t.length?!1:t.every((r,e)=>a[e]===r)}c(h,"pathHasBase");var L=class{constructor(t={}){this.options=t}static{c(this,"TypeOrmQueryAdapter")}build(t,r){return t=this.createBaseQuery(t,r),t=this.paginateQuery(t,r),t}async getOne(t,r){return await this.createBaseQuery(t,r).getOne()??null}async getMany(t,r){let e=this.createBaseQuery(t,r),s=await this.paginateQuery(e.clone(),r).getMany(),l=await e.getCount(),n=r.offset??0,o=r.limit??l,u=s.length,$=Math.floor(n/o)+1,p=Math.ceil(l/o);return{data:s,count:u,page:$,pageCount:p,total:l}}createBaseQuery(t,r){let e=[],i=this.isILikeEnabled(t);return this.adaptSelect(t,r.select),this.adaptRelations(t,r.relations,r.select),this.adaptWhere(t.alias,t,r.where,!1,e,i),this.adaptOrder(t,r.order),t}paginateQuery(t,r){return t.limit(r.limit).offset(r.offset)}adaptSelect(t,r){if(r.length===0)return;let e=r.filter(i=>i.field.length===1);t.select(e.map(i=>[t.alias,...i.field].join(".")))}adaptRelations(t,r,e){for(let i of r){let s=[t.alias,...i.field].join("."),l=i.alias||s.replace(".","_"),n=e.filter(o=>h(o.field,i.field));n.length===0?t.leftJoinAndSelect(s,l):(t.leftJoin(s,l),t.addSelect(n.map(o=>[l,o.field[o.field.length-1]].join("."))))}}adaptOrder(t,r){for(let e of r){let i=[t.alias,...e.field].join(".");t.addOrderBy(i,e.order)}}adaptWhere(t,r,e,i,s,l){let n=(i?r.orWhere:r.andWhere).bind(r);if(e.or&&e.or.length>0)n(new N(o=>e.or.forEach(u=>this.adaptWhere(t,o,u,!0,s,l))));else if(e.and&&e.and.length>0)n(new N(o=>e.and.forEach(u=>this.adaptWhere(t,o,u,!1,s,l))));else if(e.field){let o=this.createParam(s,e.field),u=this.mapWhereOperators(t,e,o,l);n(u.where,u.params)}}createParam(t,r){let e=r.length>0?r[r.length-1]:"",i,s=0;do i="req_"+e+"_"+s,s++;while(t.includes(i));return t.push(i),i}mapWhereOperators(t,r,e,i){let s=[t,...r.field].join("."),l=r.operator,n=r.value;switch(l){case"eq":return{where:`${s} = :${e}`,params:{[e]:n}};case"neq":return{where:`${s} != :${e}`,params:{[e]:n}};case"gt":return{where:`${s} > :${e}`,params:{[e]:n}};case"gte":return{where:`${s} >= :${e}`,params:{[e]:n}};case"lt":return{where:`${s} < :${e}`,params:{[e]:n}};case"lte":return{where:`${s} <= :${e}`,params:{[e]:n}};case"starts":return{where:`${s} LIKE :${e}`,params:{[e]:`${n}%`}};case"ends":return{where:`${s} LIKE :${e}`,params:{[e]:`%${n}`}};case"contains":return{where:`${s} LIKE :${e}`,params:{[e]:`%${n}%`}};case"not_contains":return{where:`${s} NOT LIKE :${e}`,params:{[e]:`%${n}%`}};case"in":return n=d("IN operator",n,1),{where:`${s} IN (:...${e})`,params:{[e]:n}};case"not_in":return n=d("NOT IN operator",n,1),{where:`${s} NOT IN (:...${e})`,params:{[e]:n}};case"between":let o=d("BETWEEN operator",n,2);return{where:`${s} BETWEEN :${e}_start AND :${e}_end`,params:{[`${e}_start`]:o[0],[`${e}_end`]:o[1]}};case"is_null":return E("IS NULL operator",n),{where:`${s} IS NULL`,params:{}};case"not_null":return E("NOT NULL operator",n),{where:`${s} IS NOT NULL`,params:{}};case"eq_lower":return{where:`LOWER(${s}) = :${e}`,params:{[e]:n}};case"neq_lower":return{where:`LOWER(${s}) != :${e}`,params:{[e]:n}};case"starts_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`${n}%`}};case"ends_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`%${n}`}};case"contains_lower":return{where:`${this.createLowerLike(i,s)} :${e}`,params:{[e]:`%${n}%`}};case"not_contains_lower":return{where:`${this.createLowerLike(i,s,!0)} :${e}`,params:{[e]:`%${n}%`}};case"in_lower":return d("IN operator",n,1),{where:`LOWER(${s}) IN (...:${e})`,params:{[e]:n}};case"not_in_lower":return d("NOT IN operator",n,1),{where:`LOWER(${s}) NOT IN (...:${e})`,params:{[e]:n}};default:throw new Error(`Unknown operator "${l}"`)}}createLowerLike(t,r,e=!1){return t?e?`${r} NOT ILIKE`:`${r} ILIKE`:e?`LOWER(${r}) NOT LIKE`:`LOWER(${r}) LIKE`}isILikeEnabled(t){let r=this.options.ilike;if(f(r))return r;let e=t.connection.options.type;return e==="postgres"||e==="aurora-postgres"}};export{L as TypeOrmQueryAdapter};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../../src/adapters/typeorm/typeorm.query-adapter.ts","../../../src/utils/functions.ts","../../../src/utils/field-path.ts"],"sourcesContent":["import { Brackets, ObjectLiteral, SelectQueryBuilder, WhereExpressionBuilder } from 'typeorm';\r\nimport { QueryAdapter } from '../../models/query-adapter';\r\nimport { CrudRequest, CrudRequestOrder, CrudRequestRelation, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { CrudRequestWhere, CrudRequestWhereField, CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { GetManyResult } from '../../models/get-many-result';\r\nimport { ensureArray, ensureFalsy, isValid } from '../../utils/functions';\r\nimport { pathHasBase } from '../../utils/field-path';\r\n\r\nexport interface TypeOrmQueryAdapterOptions {\r\n /**\r\n * Whether it will use ILIKE for case-insensitive operations.\r\n *\r\n * If undefined, it will be enabled by default for postgres and aurora-postgres databases\r\n */\r\n ilike?: boolean;\r\n}\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 constructor(\r\n private readonly options: TypeOrmQueryAdapterOptions = {},\r\n ) {}\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 const isILikeEnabled = this.isILikeEnabled(qb);\r\n\r\n this.adaptSelect(qb, query.select);\r\n this.adaptRelations(qb, query.relations, query.select);\r\n this.adaptWhere(qb.alias, qb, query.where, false, paramsDefined, isILikeEnabled);\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 if (select.length === 0)\r\n return;\r\n\r\n // Only fields that are one level deep\r\n const fields = select.filter(f => f.field.length === 1);\r\n\r\n qb.select(fields.map(s => [qb.alias, ...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 * @param select The parsed select fields\r\n */\r\n protected adaptRelations<E extends ObjectLiteral>(qb: SelectQueryBuilder<E>, relations: CrudRequestRelation[], select: ParsedRequestSelect): void {\r\n for (const relation of relations) {\r\n const path = [qb.alias, ...relation.field].join('.');\r\n const alias = relation.alias || path.replace('.', '_');\r\n\r\n const fields = select.filter(f => pathHasBase(f.field, relation.field));\r\n\r\n if (fields.length === 0) {\r\n qb.leftJoinAndSelect(path, alias);\r\n } else {\r\n qb.leftJoin(path, alias);\r\n qb.addSelect(fields.map(f => [alias, f.field[f.field.length - 1]].join('.')));\r\n }\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 = [qb.alias, ...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 alias The query builder alias\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 * @param isILikeEnabled Whether the ILIKE operator can be used\r\n */\r\n protected adaptWhere(\r\n alias: string,\r\n qb: WhereExpressionBuilder,\r\n where: CrudRequestWhere,\r\n or: boolean,\r\n params: string[],\r\n isILikeEnabled: boolean,\r\n ): 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(alias, wqb, item, true, params, isILikeEnabled))\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(alias, wqb, item, false, params, isILikeEnabled))\r\n ));\r\n } else if (where.field) {\r\n const param = this.createParam(params, where.field);\r\n const query = this.mapWhereOperators(alias, where as CrudRequestWhereField, param, isILikeEnabled);\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 alias The query builder alias\r\n * @param where The where condition\r\n * @param param The parameter name\r\n * @param isILikeEnabled Whether the ILIKE operator can be used\r\n */\r\n protected mapWhereOperators(\r\n alias: string,\r\n where: CrudRequestWhereField,\r\n param: string,\r\n isILikeEnabled: boolean,\r\n ): { where: string, params: ObjectLiteral } {\r\n const field = [alias, ...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: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `${value}%` } };\r\n\r\n case CrudRequestWhereOperator.ENDS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `%${value}` } };\r\n\r\n case CrudRequestWhereOperator.CONTAINS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field)} :${param}`, params: { [param]: `%${value}%` } };\r\n\r\n case CrudRequestWhereOperator.NOT_CONTAINS_LOWER:\r\n return { where: `${this.createLowerLike(isILikeEnabled, field, true)} :${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: `LOWER(${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: `LOWER(${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 protected createLowerLike(isILikeEnabled: boolean, field: string, not: boolean = false): string {\r\n if (isILikeEnabled)\r\n return not ? `${field} NOT ILIKE` : `${field} ILIKE`;\r\n\r\n return not ? `LOWER(${field}) NOT LIKE` : `LOWER(${field}) LIKE`;\r\n }\r\n\r\n protected isILikeEnabled(qb: SelectQueryBuilder<any>): boolean {\r\n const ilikeEnabled = this.options.ilike;\r\n\r\n if (isValid(ilikeEnabled))\r\n return ilikeEnabled;\r\n\r\n const type = qb.connection.options.type;\r\n return type === 'postgres' || type === 'aurora-postgres';\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 ensurePrimitive(fieldName: string, data: any) {\r\n if (data === null || data === undefined)\r\n return;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean')\r\n return;\r\n\r\n if (data instanceof Date)\r\n return;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\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<T>(value: T | undefined | null): value is T {\r\n return value !== null && value !== undefined;\r\n}\r\n","/**\r\n * Checks whether two field paths are equal\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] is equal to [\"path\", \"to\", \"field\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathEquals(path1: string[], path2: string[]): boolean {\r\n if (path1.length !== path2.length)\r\n return false;\r\n\r\n return path1.every((p1, i) => path2[i] === p1);\r\n}\r\n\r\n/**\r\n * Checks whether a path starts with another path.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] starts with [\"path\"] or [\"path\", \"to\"] but not [\"something\", \"else\"]\r\n */\r\nexport function pathStartsWith(path: string[], start: string[]): boolean {\r\n if (path.length < start.length)\r\n return false;\r\n\r\n return start.every((start, i) => path[i] === start);\r\n}\r\n\r\n/**\r\n * Checks whether the base of a path matches.\r\n *\r\n * E.g. [\"path\", \"to\", \"field\"] has a base of [\"path\", \"to\"] but not [\"path\"]\r\n */\r\nexport function pathHasBase(path: string[], base: string[]): boolean {\r\n if (path.length - 1 !== base.length)\r\n return false;\r\n\r\n return base.every((start, i) => path[i] === start);\r\n}\r\n"],"mappings":"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","names":["Brackets","ensureArray","fieldName","data","minLength","__name","ensureFalsy","isValid","value","pathHasBase","path","base","start","i","__name","TypeOrmQueryAdapter","options","__name","qb","query","request","fullQuery","data","total","offset","limit","count","page","pageCount","paramsDefined","isILikeEnabled","select","fields","f","s","relations","relation","path","alias","pathHasBase","ordering","order","where","or","params","addWhere","Brackets","wqb","item","param","field","name","iteration","operator","value","ensureArray","arr","ensureFalsy","not","ilikeEnabled","isValid","type"]}
@@ -0,0 +1,32 @@
1
+ import { e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.js';
2
+
3
+ /**
4
+ * A helper class that makes it easier to create a CrudRequestWhere
5
+ */
6
+ declare class CrudRequestWhereBuilder {
7
+ private readonly where;
8
+ private readonly parent?;
9
+ constructor(where?: CrudRequestWhereAND | CrudRequestWhereOR, parent?: CrudRequestWhereBuilder | undefined);
10
+ /**
11
+ * Adds an AND bracket
12
+ */
13
+ addAnd(): CrudRequestWhereBuilder;
14
+ /**
15
+ * Adds an OR bracket
16
+ */
17
+ addOr(): CrudRequestWhereBuilder;
18
+ /**
19
+ * Adds a field comparison
20
+ *
21
+ * @param field The field path
22
+ * @param operator The comparison operator
23
+ * @param value The value to compare
24
+ */
25
+ addField(field: string[], operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): CrudRequestWhereBuilder;
26
+ /**
27
+ * Constructs the final where condition
28
+ */
29
+ build(): CrudRequestWhere;
30
+ }
31
+
32
+ export { CrudRequestWhereBuilder as C };
@@ -0,0 +1,32 @@
1
+ import { e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.mjs';
2
+
3
+ /**
4
+ * A helper class that makes it easier to create a CrudRequestWhere
5
+ */
6
+ declare class CrudRequestWhereBuilder {
7
+ private readonly where;
8
+ private readonly parent?;
9
+ constructor(where?: CrudRequestWhereAND | CrudRequestWhereOR, parent?: CrudRequestWhereBuilder | undefined);
10
+ /**
11
+ * Adds an AND bracket
12
+ */
13
+ addAnd(): CrudRequestWhereBuilder;
14
+ /**
15
+ * Adds an OR bracket
16
+ */
17
+ addOr(): CrudRequestWhereBuilder;
18
+ /**
19
+ * Adds a field comparison
20
+ *
21
+ * @param field The field path
22
+ * @param operator The comparison operator
23
+ * @param value The value to compare
24
+ */
25
+ addField(field: string[], operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType | CrudRequestWhereValueType[]): CrudRequestWhereBuilder;
26
+ /**
27
+ * Constructs the final where condition
28
+ */
29
+ build(): CrudRequestWhere;
30
+ }
31
+
32
+ export { CrudRequestWhereBuilder as C };
@@ -0,0 +1,18 @@
1
+ import * as _nestjs_common from '@nestjs/common';
2
+ import { Type } from '@nestjs/common';
3
+ import { a as RequestParser } from '../../request-parser-WaQBZsYG.mjs';
4
+ import '../../crud-request-CvDKp6Iy.mjs';
5
+
6
+ declare const CRUD_QUERY_PARSER = "crud-query-parser";
7
+ /**
8
+ * Defines which parser will be used for parsing the request
9
+ *
10
+ * @param parserContract The parser that will be used
11
+ */
12
+ declare function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator;
13
+ /**
14
+ * A parameter decorator that converts the query string into a `CrudRequest` object
15
+ */
16
+ declare const ParseCrudRequest: (...dataOrPipes: (RequestParser | Type<RequestParser> | _nestjs_common.PipeTransform<any, any> | Type<_nestjs_common.PipeTransform<any, any>>)[]) => ParameterDecorator;
17
+
18
+ export { CRUD_QUERY_PARSER, Crud, ParseCrudRequest };
@@ -0,0 +1,18 @@
1
+ import * as _nestjs_common from '@nestjs/common';
2
+ import { Type } from '@nestjs/common';
3
+ import { a as RequestParser } from '../../request-parser-B-fK5GnP.js';
4
+ import '../../crud-request-CvDKp6Iy.js';
5
+
6
+ declare const CRUD_QUERY_PARSER = "crud-query-parser";
7
+ /**
8
+ * Defines which parser will be used for parsing the request
9
+ *
10
+ * @param parserContract The parser that will be used
11
+ */
12
+ declare function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator;
13
+ /**
14
+ * A parameter decorator that converts the query string into a `CrudRequest` object
15
+ */
16
+ declare const ParseCrudRequest: (...dataOrPipes: (RequestParser | Type<RequestParser> | _nestjs_common.PipeTransform<any, any> | Type<_nestjs_common.PipeTransform<any, any>>)[]) => ParameterDecorator;
17
+
18
+ export { CRUD_QUERY_PARSER, Crud, ParseCrudRequest };
@@ -0,0 +1,2 @@
1
+ "use strict";var u=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var a=(e,r)=>u(e,"name",{value:r,configurable:!0});var q=(e,r)=>{for(var t in r)u(e,t,{get:r[t],enumerable:!0})},R=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of P(r))!m.call(e,n)&&n!==t&&u(e,n,{get:()=>r[n],enumerable:!(o=f(r,n))||o.enumerable});return e};var x=e=>R(u({},"__esModule",{value:!0}),e);var T={};q(T,{CRUD_QUERY_PARSER:()=>i,Crud:()=>y,ParseCrudRequest:()=>C});module.exports=x(T);var s=require("@nestjs/common");var c=(()=>{try{return require("@nestjs/swagger").ApiQuery}catch{return r=>()=>{}}})();function p(e){if(typeof e=="function")return new e;if(typeof e=="object")return e}a(p,"createInstance");function d(e,r){let t=[e.getHandler(),e.getClass()];for(let o of t){let n=Reflect.getMetadata(r,o);if(n)return n}}a(d,"getMetadataFromContext");var i="crud-query-parser";function y(e){let r=p(e);if(!r)throw new Error("The request parser passed to @Crud() is invalid");let t=r.getOpenAPIParameters().map(o=>c(o));return(0,s.applyDecorators)((0,s.SetMetadata)(i,r),...t)}a(y,"Crud");var C=(0,s.createParamDecorator)((e,r)=>{let t=r.switchToHttp().getRequest(),o=e?p(e):d(r,i);return o?o.parse(t.query):(new s.Logger("ParseCrudRequest").warn("No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()"),{where:{and:[]},select:[],order:[],relations:[]})});0&&(module.exports={CRUD_QUERY_PARSER,Crud,ParseCrudRequest});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/helpers/nestjs/index.ts","../../../src/helpers/nestjs/decorators.ts","../../../src/helpers/nestjs/utils.ts"],"sourcesContent":["\r\nexport * from './decorators';\r\n","import { applyDecorators, createParamDecorator, ExecutionContext, Logger, SetMetadata, Type } from '@nestjs/common';\r\nimport { RequestParser } from '../../models/request-parser';\r\nimport { ApiQuery, createInstance, getMetadataFromContext } from './utils';\r\n\r\nexport const CRUD_QUERY_PARSER = 'crud-query-parser';\r\n\r\n/**\r\n * Defines which parser will be used for parsing the request\r\n *\r\n * @param parserContract The parser that will be used\r\n */\r\nexport function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator {\r\n const parser = createInstance(parserContract);\r\n\r\n if (!parser) {\r\n throw new Error('The request parser passed to @Crud() is invalid');\r\n }\r\n\r\n const openApi = parser.getOpenAPIParameters().map(param => ApiQuery(param));\r\n\r\n return applyDecorators(\r\n SetMetadata(CRUD_QUERY_PARSER, parser),\r\n ...openApi,\r\n );\r\n}\r\n\r\n/**\r\n * A parameter decorator that converts the query string into a `CrudRequest` object\r\n */\r\nexport const ParseCrudRequest = createParamDecorator<RequestParser | Type<RequestParser>>(\r\n (data: RequestParser | Type<RequestParser>, ctx: ExecutionContext) => {\r\n const request = ctx.switchToHttp().getRequest();\r\n const parser = data ? createInstance(data) : getMetadataFromContext<RequestParser>(ctx, CRUD_QUERY_PARSER);\r\n\r\n if (!parser) {\r\n new Logger('ParseCrudRequest').warn(`No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()`);\r\n\r\n return {\r\n where: { and: [] },\r\n select: [],\r\n order: [],\r\n relations: [],\r\n };\r\n }\r\n\r\n return parser.parse(request.query);\r\n },\r\n);\r\n\r\n","import { ExecutionContext, Type } from '@nestjs/common';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\n\r\nexport const ApiQuery = (() => {\r\n try {\r\n return require('@nestjs/swagger').ApiQuery;\r\n } catch (error) {\r\n return (options: OpenAPIParameter): MethodDecorator => {\r\n return () => {};\r\n };\r\n }\r\n})();\r\n\r\nexport function createInstance<T>(data: T | Type<T> | undefined): T | undefined {\r\n if (typeof data === 'function')\r\n return new data();\r\n\r\n if (typeof data === 'object')\r\n return data as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function getMetadataFromContext<T>(context: ExecutionContext, key: string): T | undefined {\r\n const targets = [\r\n context.getHandler(),\r\n context.getClass(),\r\n ];\r\n\r\n for (const target of targets) {\r\n const data = Reflect.getMetadata(key, target);\r\n\r\n if (data)\r\n return data;\r\n }\r\n\r\n return undefined;\r\n}\r\n"],"mappings":"4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,SAAAC,EAAA,qBAAAC,IAAA,eAAAC,EAAAL,GCAA,IAAAM,EAAmG,0BCG5F,IAAMC,GAAY,IAAM,CAC7B,GAAI,CACF,MAAO,SAAQ,iBAAiB,EAAE,QACpC,MAAgB,CACd,OAAQC,GACC,IAAM,CAAC,CAElB,CACF,GAAG,EAEI,SAASC,EAAkBC,EAA8C,CAC9E,GAAI,OAAOA,GAAS,WAClB,OAAO,IAAIA,EAEb,GAAI,OAAOA,GAAS,SAClB,OAAOA,CAGX,CARgBC,EAAAF,EAAA,kBAUT,SAASG,EAA0BC,EAA2BC,EAA4B,CAC/F,IAAMC,EAAU,CACdF,EAAQ,WAAW,EACnBA,EAAQ,SAAS,CACnB,EAEA,QAAWG,KAAUD,EAAS,CAC5B,IAAML,EAAO,QAAQ,YAAYI,EAAKE,CAAM,EAE5C,GAAIN,EACF,OAAOA,CACX,CAGF,CAdgBC,EAAAC,EAAA,0BDnBT,IAAMK,EAAoB,oBAO1B,SAASC,EAAKC,EAAuF,CAC1G,IAAMC,EAASC,EAAeF,CAAc,EAE5C,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,iDAAiD,EAGnE,IAAME,EAAUF,EAAO,qBAAqB,EAAE,IAAIG,GAASC,EAASD,CAAK,CAAC,EAE1E,SAAO,sBACL,eAAYN,EAAmBG,CAAM,EACrC,GAAGE,CACL,CACF,CAbgBG,EAAAP,EAAA,QAkBT,IAAMQ,KAAmB,wBAC9B,CAACC,EAA2CC,IAA0B,CACpE,IAAMC,EAAUD,EAAI,aAAa,EAAE,WAAW,EACxCR,EAASO,EAAON,EAAeM,CAAI,EAAIG,EAAsCF,EAAKX,CAAiB,EAEzG,OAAKG,EAWEA,EAAO,MAAMS,EAAQ,KAAK,GAV/B,IAAI,SAAO,kBAAkB,EAAE,KAAK,yFAAyF,EAEtH,CACL,MAAO,CAAE,IAAK,CAAC,CAAE,EACjB,OAAQ,CAAC,EACT,MAAO,CAAC,EACR,UAAW,CAAC,CACd,EAIJ,CACF","names":["nestjs_exports","__export","CRUD_QUERY_PARSER","Crud","ParseCrudRequest","__toCommonJS","import_common","ApiQuery","options","createInstance","data","__name","getMetadataFromContext","context","key","targets","target","CRUD_QUERY_PARSER","Crud","parserContract","parser","createInstance","openApi","param","ApiQuery","__name","ParseCrudRequest","data","ctx","request","getMetadataFromContext"]}