crud-query-parser 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +37 -11
- package/dist/adapters/typeorm/index.d.mts +104 -10
- package/dist/adapters/typeorm/index.d.ts +104 -10
- package/dist/adapters/typeorm/index.js +1 -1
- package/dist/adapters/typeorm/index.js.map +1 -1
- package/dist/adapters/typeorm/index.mjs +1 -1
- package/dist/adapters/typeorm/index.mjs.map +1 -1
- package/dist/{parsed-request-where.builder-DME55XmN.d.ts → crud-request-where.builder-B5241Aht.d.ts} +7 -7
- package/dist/{parsed-request-where.builder-DRZUAxu4.d.mts → crud-request-where.builder-BwWLx0Bh.d.mts} +7 -7
- package/dist/{crud-request-CvDKp6Iy.d.mts → crud-request-x16CuDRF.d.mts} +1 -0
- package/dist/{crud-request-CvDKp6Iy.d.ts → crud-request-x16CuDRF.d.ts} +1 -0
- package/dist/filters/index.d.mts +11 -2
- package/dist/filters/index.d.ts +11 -2
- package/dist/filters/index.js +1 -1
- package/dist/filters/index.js.map +1 -1
- package/dist/filters/index.mjs +1 -1
- package/dist/filters/index.mjs.map +1 -1
- package/dist/helpers/nestjs/index.d.mts +2 -2
- package/dist/helpers/nestjs/index.d.ts +2 -2
- package/dist/helpers/nestjs/index.js.map +1 -1
- package/dist/helpers/nestjs/index.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/parsers/crud/index.d.mts +34 -9
- package/dist/parsers/crud/index.d.ts +34 -9
- package/dist/parsers/crud/index.js +1 -1
- package/dist/parsers/crud/index.js.map +1 -1
- package/dist/parsers/crud/index.mjs +1 -1
- package/dist/parsers/crud/index.mjs.map +1 -1
- package/dist/{query-adapter-Vebxws3V.d.ts → query-adapter-CEcyFcWr.d.ts} +1 -1
- package/dist/{query-adapter-BliD9hJN.d.mts → query-adapter-CeTK3yxp.d.mts} +1 -1
- package/dist/{request-parser-WaQBZsYG.d.mts → request-parser-BMkszvGr.d.mts} +1 -1
- package/dist/{request-parser-B-fK5GnP.d.ts → request-parser-BxVulcsX.d.ts} +1 -1
- package/package.json +133 -118
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../src/models/crud-request-where.ts","../src/utils/parsed-request-where.builder.ts"],"sourcesContent":["import { FieldPath } from './field-path';\r\n\r\nexport type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;\r\n\r\nexport interface CrudRequestWhereAND {\r\n field?: never;\r\n or?: never;\r\n and: CrudRequestWhere[];\r\n}\r\n\r\nexport interface CrudRequestWhereOR {\r\n field?: never;\r\n or: CrudRequestWhere[];\r\n and?: never;\r\n}\r\n\r\nexport interface CrudRequestWhereField {\r\n\r\n /**\r\n * Field path\r\n *\r\n * For post.category.name, this would be [\"post\", \"category\", \"name\"]\r\n */\r\n field: FieldPath;\r\n\r\n /**\r\n * The operator of the comparison\r\n */\r\n operator: CrudRequestWhereOperator;\r\n\r\n /**\r\n * The value to compare\r\n */\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[];\r\n\r\n or?: never;\r\n and?: never;\r\n}\r\n\r\nexport type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;\r\n\r\nexport enum CrudRequestWhereOperator {\r\n EQ = 'eq',\r\n NEQ = 'neq',\r\n GT = 'gt',\r\n GTE = 'gte',\r\n LT = 'lt',\r\n LTE = 'lte',\r\n STARTS = 'starts',\r\n ENDS = 'ends',\r\n CONTAINS = 'contains',\r\n NOT_CONTAINS = 'not_contains',\r\n IN = 'in',\r\n NOT_IN = 'not_in',\r\n BETWEEN = 'between',\r\n IS_NULL = 'is_null',\r\n NOT_NULL = 'not_null',\r\n EQ_LOWER = 'eq_lower',\r\n NEQ_LOWER = 'neq_lower',\r\n STARTS_LOWER = 'starts_lower',\r\n ENDS_LOWER = 'ends_lower',\r\n CONTAINS_LOWER = 'contains_lower',\r\n NOT_CONTAINS_LOWER = 'not_contains_lower',\r\n IN_LOWER = 'in_lower',\r\n NOT_IN_LOWER = 'not_in_lower',\r\n}\r\n","import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class ParsedRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: ParsedRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): ParsedRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): ParsedRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(field: string[], operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType): ParsedRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\r\n }\r\n\r\n}\r\n"],"mappings":"+EAyCO,IAAKA,OACVA,EAAA,GAAK,KACLA,EAAA,IAAM,MACNA,EAAA,GAAK,KACLA,EAAA,IAAM,MACNA,EAAA,GAAK,KACLA,EAAA,IAAM,MACNA,EAAA,OAAS,SACTA,EAAA,KAAO,OACPA,EAAA,SAAW,WACXA,EAAA,aAAe,eACfA,EAAA,GAAK,KACLA,EAAA,OAAS,SACTA,EAAA,QAAU,UACVA,EAAA,QAAU,UACVA,EAAA,SAAW,WACXA,EAAA,SAAW,WACXA,EAAA,UAAY,YACZA,EAAA,aAAe,eACfA,EAAA,WAAa,aACbA,EAAA,eAAiB,iBACjBA,EAAA,mBAAqB,qBACrBA,EAAA,SAAW,WACXA,EAAA,aAAe,eAvBLA,OAAA,IC7BL,IAAMC,EAAN,MAAMC,CAA0B,CAErC,YACmBC,EAAkD,CAAE,IAAK,CAAC,CAAE,EAC5DC,EACjB,CAFiB,WAAAD,EACA,YAAAC,CACf,CAjBN,MAYuC,CAAAC,EAAA,kCAU9B,QAAoC,CACzC,GAAI,CAAC,KAAK,MAAM,GACd,OAAO,KAGT,IAAMC,EAA8B,CAAE,IAAK,CAAC,CAAE,EACxCC,EAAU,IAAIL,EAA0BI,EAAQ,IAAI,EAE1D,YAAK,MAAM,GAAG,KAAKA,CAAM,EAElBC,CACT,CAKO,OAAmC,CACxC,GAAI,CAAC,KAAK,MAAM,IACd,OAAO,KAGT,IAAMD,EAA6B,CAAE,GAAI,CAAC,CAAE,EACtCC,EAAU,IAAIL,EAA0BI,EAAQ,IAAI,EAE1D,YAAK,MAAM,IAAI,KAAKA,CAAM,EAEnBC,CACT,CASO,SAASC,EAAiBC,EAAoCC,EAA6D,CAChI,IAAMC,EAAoC,CACxC,MAAAH,EACA,SAAAC,EACA,MAAAC,CACF,EAEA,GAAI,KAAK,MAAM,IACb,KAAK,MAAM,IAAI,KAAKC,CAAU,UACrB,KAAK,MAAM,GACpB,KAAK,MAAM,GAAG,KAAKA,CAAU,MAE7B,OAAM,IAAI,MAAM,eAAe,EAGjC,OAAO,IACT,CAKO,OAA0B,CAC/B,OAAI,KAAK,OACA,KAAK,OAAO,MAAM,EAGpB,KAAK,KACd,CAEF","names":["CrudRequestWhereOperator","ParsedRequestWhereBuilder","_ParsedRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField"]}
|
1
|
+
{"version":3,"sources":["../src/models/crud-request-where.ts","../src/utils/functions.ts","../src/utils/where.ts","../src/utils/crud-request-where.builder.ts"],"sourcesContent":["import { FieldPath } from './field-path';\r\n\r\nexport type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;\r\n\r\nexport interface CrudRequestWhereAND {\r\n field?: never;\r\n or?: never;\r\n and: CrudRequestWhere[];\r\n}\r\n\r\nexport interface CrudRequestWhereOR {\r\n field?: never;\r\n or: CrudRequestWhere[];\r\n and?: never;\r\n}\r\n\r\nexport interface CrudRequestWhereField {\r\n\r\n /**\r\n * Field path\r\n *\r\n * For post.category.name, this would be [\"post\", \"category\", \"name\"]\r\n */\r\n field: FieldPath;\r\n\r\n /**\r\n * The operator of the comparison\r\n */\r\n operator: CrudRequestWhereOperator;\r\n\r\n /**\r\n * The value to compare\r\n */\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[];\r\n\r\n or?: never;\r\n and?: never;\r\n}\r\n\r\nexport type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;\r\n\r\nexport enum CrudRequestWhereOperator {\r\n EQ = 'eq',\r\n NEQ = 'neq',\r\n GT = 'gt',\r\n GTE = 'gte',\r\n LT = 'lt',\r\n LTE = 'lte',\r\n STARTS = 'starts',\r\n ENDS = 'ends',\r\n CONTAINS = 'contains',\r\n NOT_CONTAINS = 'not_contains',\r\n IN = 'in',\r\n NOT_IN = 'not_in',\r\n BETWEEN = 'between',\r\n IS_NULL = 'is_null',\r\n NOT_NULL = 'not_null',\r\n EQ_LOWER = 'eq_lower',\r\n NEQ_LOWER = 'neq_lower',\r\n STARTS_LOWER = 'starts_lower',\r\n ENDS_LOWER = 'ends_lower',\r\n CONTAINS_LOWER = 'contains_lower',\r\n NOT_CONTAINS_LOWER = 'not_contains_lower',\r\n IN_LOWER = 'in_lower',\r\n NOT_IN_LOWER = 'not_in_lower',\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 ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\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\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * page : 0);\r\n}\r\n","import { CrudRequestWhereField, CrudRequestWhereOperator } from '../models/crud-request-where';\r\nimport { ensureArray, ensureEmpty, ensurePrimitive } from './functions';\r\n\r\nexport enum WhereOperatorValueType {\r\n PRIMITIVE = 'primitive',\r\n ARRAY = 'array',\r\n EMPTY = 'empty'\r\n}\r\n\r\nconst operatorValueTypes: Record<CrudRequestWhereOperator, WhereOperatorValueType> = {\r\n [CrudRequestWhereOperator.EQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.NOT_IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.BETWEEN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.IS_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.NOT_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.EQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n};\r\n\r\nexport function getWhereOperatorValueType(op: CrudRequestWhereOperator): WhereOperatorValueType {\r\n return operatorValueTypes[op];\r\n}\r\n\r\nexport function validateWhereField(where: CrudRequestWhereField): void {\r\n const type = operatorValueTypes[where.operator];\r\n const name = 'The value of the operator ' + where.operator;\r\n\r\n if (type === WhereOperatorValueType.PRIMITIVE) {\r\n ensurePrimitive(name, where.value);\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.ARRAY) {\r\n const items = ensureArray(name, where.value);\r\n\r\n items.forEach(item => ensurePrimitive(name + ' children', item));\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.EMPTY) {\r\n ensureEmpty(name, where.value);\r\n\r\n return;\r\n }\r\n}\r\n","import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\nimport { validateWhereField } from './where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class CrudRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: CrudRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): CrudRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): CrudRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(\r\n field: string[],\r\n operator: CrudRequestWhereOperator,\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[],\r\n ): CrudRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n validateWhereField(whereField);\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["CrudRequestWhereOperator","ensurePrimitive","fieldName","data","__name","ensureArray","minLength","ensureEmpty","isValid","value","operatorValueTypes","validateWhereField","where","type","operatorValueTypes","name","ensurePrimitive","ensureArray","item","ensureEmpty","__name","CrudRequestWhereBuilder","_CrudRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","validateWhereField"]}
|
@@ -1,22 +1,47 @@
|
|
1
|
-
import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-
|
2
|
-
import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-
|
3
|
-
import {
|
1
|
+
import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-BMkszvGr.mjs';
|
2
|
+
import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-x16CuDRF.mjs';
|
3
|
+
import { C as CrudRequestWhereBuilder } from '../../crud-request-where.builder-BwWLx0Bh.mjs';
|
4
4
|
|
5
|
+
interface CrudRequestParserOptions {
|
6
|
+
/**
|
7
|
+
* Whether the `fields` and `select` parameters will be disabled
|
8
|
+
*/
|
9
|
+
disableSelect?: boolean;
|
10
|
+
/**
|
11
|
+
* Whether the `s`, `filter` and `or` parameters will be disabled
|
12
|
+
*/
|
13
|
+
disableWhere?: boolean;
|
14
|
+
/**
|
15
|
+
* Whether the `sort` parameter will be disabled
|
16
|
+
*/
|
17
|
+
disableOrder?: boolean;
|
18
|
+
/**
|
19
|
+
* Whether the `join` parameter will be disabled
|
20
|
+
*/
|
21
|
+
disableRelations?: boolean;
|
22
|
+
/**
|
23
|
+
* Whether the `limit` and `per_page` parameters will be disabled
|
24
|
+
*/
|
25
|
+
disableLimit?: boolean;
|
26
|
+
/**
|
27
|
+
* Whether the `offset` and `page` parameters will be disabled
|
28
|
+
*/
|
29
|
+
disableOffset?: boolean;
|
30
|
+
}
|
5
31
|
/**
|
6
32
|
* Parses a request based on the @nestjsx/crud format.
|
7
33
|
*/
|
8
34
|
declare class CrudRequestParser implements RequestParser {
|
35
|
+
protected readonly options: CrudRequestParserOptions;
|
36
|
+
constructor(options?: CrudRequestParserOptions);
|
9
37
|
getOpenAPIParameters(): OpenAPIParameter[];
|
10
38
|
parse(query: Record<string, RequestParamValue>): CrudRequest;
|
11
39
|
protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void;
|
12
40
|
protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void;
|
13
41
|
protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void;
|
14
42
|
protected parseNumber(raw: RequestParamValue): number | undefined;
|
15
|
-
protected
|
16
|
-
|
17
|
-
offset: number | undefined;
|
18
|
-
};
|
19
|
-
protected parseSearch(builder: ParsedRequestWhereBuilder, rawSearch: RequestParamValue): void;
|
43
|
+
protected parseSearch(builder: CrudRequestWhereBuilder, rawSearch: RequestParamValue, rawFilter: RequestParamValue, rawOr: RequestParamValue): void;
|
44
|
+
protected parseFilter(builder: CrudRequestWhereBuilder, rawFilter: RequestParamValue, rawOr: RequestParamValue): void;
|
20
45
|
}
|
21
46
|
|
22
|
-
export { CrudRequestParser };
|
47
|
+
export { CrudRequestParser, type CrudRequestParserOptions };
|
@@ -1,22 +1,47 @@
|
|
1
|
-
import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-
|
2
|
-
import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-
|
3
|
-
import {
|
1
|
+
import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-BxVulcsX.js';
|
2
|
+
import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-x16CuDRF.js';
|
3
|
+
import { C as CrudRequestWhereBuilder } from '../../crud-request-where.builder-B5241Aht.js';
|
4
4
|
|
5
|
+
interface CrudRequestParserOptions {
|
6
|
+
/**
|
7
|
+
* Whether the `fields` and `select` parameters will be disabled
|
8
|
+
*/
|
9
|
+
disableSelect?: boolean;
|
10
|
+
/**
|
11
|
+
* Whether the `s`, `filter` and `or` parameters will be disabled
|
12
|
+
*/
|
13
|
+
disableWhere?: boolean;
|
14
|
+
/**
|
15
|
+
* Whether the `sort` parameter will be disabled
|
16
|
+
*/
|
17
|
+
disableOrder?: boolean;
|
18
|
+
/**
|
19
|
+
* Whether the `join` parameter will be disabled
|
20
|
+
*/
|
21
|
+
disableRelations?: boolean;
|
22
|
+
/**
|
23
|
+
* Whether the `limit` and `per_page` parameters will be disabled
|
24
|
+
*/
|
25
|
+
disableLimit?: boolean;
|
26
|
+
/**
|
27
|
+
* Whether the `offset` and `page` parameters will be disabled
|
28
|
+
*/
|
29
|
+
disableOffset?: boolean;
|
30
|
+
}
|
5
31
|
/**
|
6
32
|
* Parses a request based on the @nestjsx/crud format.
|
7
33
|
*/
|
8
34
|
declare class CrudRequestParser implements RequestParser {
|
35
|
+
protected readonly options: CrudRequestParserOptions;
|
36
|
+
constructor(options?: CrudRequestParserOptions);
|
9
37
|
getOpenAPIParameters(): OpenAPIParameter[];
|
10
38
|
parse(query: Record<string, RequestParamValue>): CrudRequest;
|
11
39
|
protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void;
|
12
40
|
protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void;
|
13
41
|
protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void;
|
14
42
|
protected parseNumber(raw: RequestParamValue): number | undefined;
|
15
|
-
protected
|
16
|
-
|
17
|
-
offset: number | undefined;
|
18
|
-
};
|
19
|
-
protected parseSearch(builder: ParsedRequestWhereBuilder, rawSearch: RequestParamValue): void;
|
43
|
+
protected parseSearch(builder: CrudRequestWhereBuilder, rawSearch: RequestParamValue, rawFilter: RequestParamValue, rawOr: RequestParamValue): void;
|
44
|
+
protected parseFilter(builder: CrudRequestWhereBuilder, rawFilter: RequestParamValue, rawOr: RequestParamValue): void;
|
20
45
|
}
|
21
46
|
|
22
|
-
export { CrudRequestParser };
|
47
|
+
export { CrudRequestParser, type CrudRequestParserOptions };
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";var
|
1
|
+
"use strict";var h=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var o=(t,e)=>h(t,"name",{value:e,configurable:!0});var P=(t,e)=>{for(var r in e)h(t,r,{get:e[r],enumerable:!0})},_=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of S(e))!C.call(t,i)&&i!==r&&h(t,i,{get:()=>e[i],enumerable:!(s=A(e,i))||s.enumerable});return t};var q=t=>_(h({},"__esModule",{value:!0}),t);var g={};P(g,{CrudRequestParser:()=>E});module.exports=q(g);function T(t,e){if(e!=null&&!(typeof e=="number"||typeof e=="string"||typeof e=="boolean")&&!(e instanceof Date))throw new Error(`${t} must be a string, number, boolean or null`)}o(T,"ensurePrimitive");function I(t,e,r=0){if(!Array.isArray(e)||e.length<r)throw new Error(`${t} must be an array with at least ${r} items`);return e}o(I,"ensureArray");function y(t,e){if(p(e)&&e!==!0)throw new Error(`${t} must be true, null or undefined`)}o(y,"ensureEmpty");function p(t){return t!=null}o(p,"isValid");var b={eq:"primitive",neq:"primitive",gt:"primitive",lt:"primitive",gte:"primitive",lte:"primitive",starts:"primitive",ends:"primitive",contains:"primitive",not_contains:"primitive",in:"array",not_in:"array",between:"array",is_null:"empty",not_null:"empty",eq_lower:"primitive",neq_lower:"primitive",starts_lower:"primitive",ends_lower:"primitive",contains_lower:"primitive",not_contains_lower:"primitive",in_lower:"primitive",not_in_lower:"primitive"};function N(t){let e=b[t.operator],r="The value of the operator "+t.operator;if(e==="primitive"){T(r,t.value);return}if(e==="array"){I(r,t.value).forEach(i=>T(r+" children",i));return}if(e==="empty"){y(r,t.value);return}}o(N,"validateWhereField");var f=class t{constructor(e={and:[]},r){this.where=e;this.parent=r}static{o(this,"CrudRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},r=new t(e,this);return this.where.or.push(e),r}addOr(){if(!this.where.and)return this;let e={or:[]},r=new t(e,this);return this.where.and.push(e),r}addField(e,r,s){let i={field:e,operator:r,value:s};if(N(i),this.where.and)this.where.and.push(i);else if(this.where.or)this.where.or.push(i);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};var O={$eq:"eq",$ne:"neq",$gt:"gt",$lt:"lt",$gte:"gte",$lte:"lte",$starts:"starts",$ends:"ends",$cont:"contains",$excl:"not_contains",$in:"in",$notin:"not_in",$between:"between",$isnull:"is_null",$notnull:"not_null",$eqL:"eq_lower",$neL:"neq_lower",$startsL:"starts_lower",$endsL:"ends_lower",$contL:"contains_lower",$exclL:"not_contains_lower",$inL:"in_lower",$notinL:"not_in_lower"};function l(t,e,r=[]){if(typeof e!="object")return;let s=Object.keys(e);if(s.length===0)return;let{$or:i,$and:n,...a}=e;if(n){let u=n.length>1||s.length>1?t.addAnd():t;n.forEach(d=>l(u,d,r)),m(u,a,r);return}if(i&&s.length===1){let u=i.length>1?t.addOr():t;i.forEach(d=>l(u,d,r));return}if(i){let u=t.addAnd(),d=i.length>1?u.addOr():u;m(u,a,r),i.forEach(R=>l(d,R,r));return}s.length>1&&(t=t.addAnd()),m(t,a,r)}o(l,"parseCrudSearch");function m(t,e,r){for(let s of Object.keys(e)){let i=e[s];if(!p(i))continue;let n=[...r,...s.split(".")];if(Array.isArray(i)){i.forEach(a=>l(t,a,n));continue}W(t,n,i)}}o(m,"parseCrudSearchFields");function W(t,e,r){if(typeof r!="object"){t.addField(e,"eq",r);return}let s=Object.keys(r);for(let i of s)O[i]&&t.addField(e,O[i],r[i]);r.$or&&W(t.addOr(),e,r.$or)}o(W,"parseCrudSearchField");function V(t,e,r){if(e.length>0&&r.length>0){let s=t.addOr();c(s.addAnd(),e),c(s.addAnd(),r);return}if(r.length>0){c(t.addOr(),r);return}if(e.length>0){c(t.addAnd(),e);return}}o(V,"parseCrudFilters");function c(t,e){for(let r of e){let[s,i,n]=r.split("||",3),a=O[i];a&&t.addField(s.split("."),a,n)}}o(c,"parseCrudFilter");var E=class{constructor(e={}){this.options=e}static{o(this,"CrudRequestParser")}getOpenAPIParameters(){let e={type:"array",items:{type:"string"}},r=[];return this.options.disableSelect||r.push({name:"fields",description:"Selects resource fields",required:!1,schema:e,style:"form",explode:!1}),this.options.disableWhere||r.push({name:"s",description:"Search condition",required:!1,schema:{type:"string"}}),this.options.disableOrder||r.push({name:"sort",description:"Sorting",required:!1,schema:e,style:"form",explode:!0}),this.options.disableRelations||r.push({name:"join",description:"Relations",required:!1,schema:e,style:"form",explode:!0}),this.options.disableLimit||r.push({name:"limit",description:"Page limit",required:!1,schema:{type:"integer"}}),this.options.disableOffset||r.push({name:"offset",description:"Offset amount",required:!1,schema:{type:"integer"}},{name:"page",description:"Page number",required:!1,schema:{type:"integer"}}),r}parse(e){let r=[],s=[],i=[],n=new f;this.options.disableSelect||this.parseSelect(r,e.fields||e.select),this.options.disableRelations||this.parseJoin(r,s,e.join),this.options.disableOrder||this.parseOrder(i,e.sort),this.options.disableWhere||this.parseSearch(n,e.s,e.filter,e.or);let a=this.options.disableLimit?void 0:this.parseNumber(e.limit||e.per_page),u=this.options.disableOffset?void 0:this.parseNumber(e.offset),d=this.options.disableOffset?void 0:this.parseNumber(e.page);return{select:r,relations:s,order:i,where:n.build(),limit:a,offset:u,page:d}}parseSelect(e,r){if(!r)return;(Array.isArray(r)?r:r.split(",")).forEach(i=>{e.push({field:i.split(".")})})}parseJoin(e,r,s){if(!s)return;if(Array.isArray(s)){s.forEach(d=>this.parseJoin(e,r,d));return}let i=s.toString(),[n,a]=i.split("||",2),u=n.split(".");r.push({field:u}),a&&a.split(",").forEach(R=>{e.push({field:[...u,R]})})}parseOrder(e,r){if(!r)return;if(Array.isArray(r)){r.forEach(n=>this.parseOrder(e,n));return}let[s,i]=r.split(",");e.push({field:s.split("."),order:i?.toUpperCase()==="DESC"?"DESC":"ASC"})}parseNumber(e){if(Array.isArray(e)&&(e=e.length>0?e[0]:void 0),!p(e))return;let r=+e;return isNaN(r)?void 0:r}parseSearch(e,r,s,i){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!r){this.parseFilter(e,s,i);return}let n=JSON.parse(r);l(e,n)}parseFilter(e,r,s){let i=[],n=[];r&&(i=Array.isArray(r)?r:[r]),s&&(n=Array.isArray(s)?s:[s]),V(e,i,n)}};0&&(module.exports={CrudRequestParser});
|
2
2
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/parsers/crud/index.ts","../../../src/utils/parsed-request-where.builder.ts","../../../src/utils/functions.ts","../../../src/parsers/crud/parseCrudSearch.ts","../../../src/parsers/crud/crud-request.parser.ts"],"sourcesContent":["\r\nexport * from './crud-request.parser';\r\n","import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class ParsedRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: ParsedRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): ParsedRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): ParsedRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(field: string[], operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType): ParsedRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\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","import { ParsedRequestWhereBuilder } from '../../utils/parsed-request-where.builder';\r\nimport { CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { SCondition, SField, SFieldOperator, SFields } from './types';\r\nimport { isValid } from '../../utils/functions';\r\n\r\n/**\r\n * Parses a crud request condition and inserts into a ParsedRequestWhereBuilder\r\n *\r\n * @param builder The builder that the condition will be inserted to\r\n * @param cond The condition that must be parsed\r\n * @param context The field context\r\n */\r\nexport function parseCrudSearch(builder: ParsedRequestWhereBuilder, cond: SCondition, context: string[] = []) {\r\n if (typeof cond !== 'object')\r\n return;\r\n\r\n const keys = Object.keys(cond);\r\n\r\n if (keys.length === 0)\r\n return;\r\n\r\n const { $or, $and, ...innerFields } = cond;\r\n\r\n // { $and: [..., ...] }\r\n if ($and) {\r\n const andBuilder = $and.length > 1 || keys.length > 1 ? builder.addAnd() : builder;\r\n\r\n $and.forEach(c => parseCrudSearch(andBuilder, c, context));\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n return;\r\n }\r\n\r\n // { $or: [..., ...] }\r\n if ($or && keys.length === 1) {\r\n const orBuilder = $or.length > 1 ? builder.addOr() : builder;\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n // { $or: [...], field1: ..., field2: ... }\r\n if ($or) {\r\n const andBuilder = builder.addAnd();\r\n const orBuilder = $or.length > 1 ? andBuilder.addOr() : andBuilder;\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n if (keys.length > 1)\r\n builder = builder.addAnd();\r\n\r\n parseCrudSearchFields(builder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n}\r\n\r\n/**\r\n * Parses an object from the crud request full of fields\r\n *\r\n * @param builder The builder\r\n * @param fields The fields object\r\n * @param context The context\r\n */\r\nfunction parseCrudSearchFields(builder: ParsedRequestWhereBuilder, fields: Omit<Omit<SFields, '$or'>, '$and'>, context: string[]): void {\r\n // { name: 'John', age: { $gte: 18 }, 'posts.name': { $cont: 'Greetings' } }\r\n for (const name of Object.keys(fields)) {\r\n const field = fields[name];\r\n\r\n if (!isValid(field))\r\n continue;\r\n\r\n const fieldPath = [...context, ...name.split('.')];\r\n\r\n // { name: [{ $or: [...] }] }\r\n if (Array.isArray(field)) {\r\n field.forEach(f => parseCrudSearch(builder, f, fieldPath));\r\n continue;\r\n }\r\n\r\n parseCrudSearchField(builder, fieldPath, field);\r\n }\r\n}\r\n\r\n/**\r\n * Parses a single field\r\n *\r\n * @param builder The builder\r\n * @param name The name path\r\n * @param field The field value or operator\r\n */\r\nfunction parseCrudSearchField(builder: ParsedRequestWhereBuilder, name: string[], field: SField): void {\r\n // Primitive Value\r\n // { field: 'text', field2: 12, field3: true }\r\n if (typeof field !== 'object') {\r\n builder.addField(name, CrudRequestWhereOperator.EQ, field);\r\n return;\r\n }\r\n\r\n type OperatorType = Exclude<Exclude<keyof SFieldOperator, '$or'>, '$and'>;\r\n\r\n // Operator\r\n // { field: { $gte: 10 } }\r\n const operatorMap: Record<OperatorType, CrudRequestWhereOperator> = {\r\n $eq: CrudRequestWhereOperator.EQ,\r\n $ne: CrudRequestWhereOperator.NEQ,\r\n $gt: CrudRequestWhereOperator.GT,\r\n $lt: CrudRequestWhereOperator.LT,\r\n $gte: CrudRequestWhereOperator.GTE,\r\n $lte: CrudRequestWhereOperator.LTE,\r\n $starts: CrudRequestWhereOperator.STARTS,\r\n $ends: CrudRequestWhereOperator.ENDS,\r\n $cont: CrudRequestWhereOperator.CONTAINS,\r\n $excl: CrudRequestWhereOperator.NOT_CONTAINS,\r\n $in: CrudRequestWhereOperator.IN,\r\n $notin: CrudRequestWhereOperator.NOT_IN,\r\n $between: CrudRequestWhereOperator.BETWEEN,\r\n $isnull: CrudRequestWhereOperator.IS_NULL,\r\n $notnull: CrudRequestWhereOperator.NOT_NULL,\r\n $eqL: CrudRequestWhereOperator.EQ_LOWER,\r\n $neL: CrudRequestWhereOperator.NEQ_LOWER,\r\n $startsL: CrudRequestWhereOperator.STARTS_LOWER,\r\n $endsL: CrudRequestWhereOperator.ENDS_LOWER,\r\n $contL: CrudRequestWhereOperator.CONTAINS_LOWER,\r\n $exclL: CrudRequestWhereOperator.NOT_CONTAINS_LOWER,\r\n $inL: CrudRequestWhereOperator.IN_LOWER,\r\n $notinL: CrudRequestWhereOperator.NOT_IN_LOWER,\r\n };\r\n\r\n const keys = Object.keys(field) as OperatorType[];\r\n\r\n for (let key of keys) {\r\n if (!operatorMap[key])\r\n continue;\r\n\r\n const value = field[key];\r\n\r\n if (Array.isArray(value))\r\n value.forEach(val => builder.addField(name, operatorMap[key], val));\r\n else\r\n builder.addField(name, operatorMap[key], value);\r\n }\r\n\r\n if (field.$or) {\r\n parseCrudSearchField(builder.addOr(), name, field.$or);\r\n }\r\n}\r\n","import { RequestParamValue, RequestParser } from '../../models/request-parser';\r\nimport {\r\n CrudRequest,\r\n CrudRequestOrder,\r\n CrudRequestRelation,\r\n ParsedRequestSelect\r\n} from '../../models/crud-request';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\nimport { ParsedRequestWhereBuilder } from '../../utils/parsed-request-where.builder';\r\nimport { parseCrudSearch } from './parseCrudSearch';\r\nimport { isValid } from '../../utils/functions';\r\nimport { SCondition } from './types';\r\n\r\n/**\r\n * Parses a request based on the @nestjsx/crud format.\r\n */\r\nexport class CrudRequestParser implements RequestParser {\r\n\r\n public getOpenAPIParameters(): OpenAPIParameter[] {\r\n const arraySchema = {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n },\r\n };\r\n\r\n return [\r\n {\r\n name: 'fields',\r\n description: 'Selects resource fields',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: false,\r\n },\r\n {\r\n name: 's',\r\n description: 'Search condition',\r\n required: false,\r\n schema: {\r\n type: 'string',\r\n },\r\n },\r\n {\r\n name: 'sort',\r\n description: 'Search condition',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n },\r\n {\r\n name: 'join',\r\n description: 'Relations',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n },\r\n {\r\n name: 'limit',\r\n description: 'Page limit',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n {\r\n name: 'offset',\r\n description: 'Offset amount',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n {\r\n name: 'page',\r\n description: 'Page number',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n ];\r\n }\r\n\r\n public parse(query: Record<string, RequestParamValue>): CrudRequest {\r\n const select: ParsedRequestSelect = [];\r\n const relations: CrudRequestRelation[] = [];\r\n const ordering: CrudRequestOrder[] = [];\r\n const where = new ParsedRequestWhereBuilder();\r\n\r\n this.parseSelect(select, query['fields'] || query['select']);\r\n this.parseJoin(select, relations, query['join']);\r\n this.parseOrder(ordering, query['sort']);\r\n this.parseSearch(where, query['s']);\r\n\r\n const { limit, offset } = this.parseLimits(query['limit'], query['offset'], query['page']);\r\n\r\n return {\r\n select,\r\n relations,\r\n order: ordering,\r\n where: where.build(),\r\n limit,\r\n offset,\r\n };\r\n }\r\n\r\n protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void {\r\n if (!rawSelect)\r\n return;\r\n\r\n const selectFields = Array.isArray(rawSelect) ? rawSelect : rawSelect.split(',');\r\n\r\n selectFields.forEach(field => {\r\n select.push({\r\n field: field.split('.'),\r\n });\r\n });\r\n }\r\n\r\n protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void {\r\n if (!rawJoin)\r\n return;\r\n\r\n if (Array.isArray(rawJoin)) {\r\n rawJoin.forEach(value => this.parseJoin(requestFields, relations, value));\r\n return;\r\n }\r\n\r\n const join = rawJoin.toString();\r\n\r\n const [field, select] = join.split('||', 2);\r\n const fieldPath = field.split('.');\r\n\r\n relations.push({\r\n field: fieldPath,\r\n });\r\n\r\n if (select) {\r\n const selectFields = select.split(',');\r\n\r\n selectFields.forEach(f => {\r\n requestFields.push({\r\n field: [...fieldPath, f],\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void {\r\n if (!rawOrder)\r\n return;\r\n\r\n if (Array.isArray(rawOrder)) {\r\n rawOrder.forEach(value => this.parseOrder(ordering, value));\r\n return;\r\n }\r\n\r\n const [field, direction] = rawOrder.split(',');\r\n\r\n ordering.push({\r\n field: field.split('.'),\r\n order: direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC',\r\n });\r\n }\r\n\r\n protected parseNumber(raw: RequestParamValue): number | undefined {\r\n if (Array.isArray(raw))\r\n raw = raw.length > 0 ? raw[0] : undefined;\r\n\r\n if (!isValid(raw))\r\n return undefined;\r\n\r\n const num = +raw;\r\n\r\n return isNaN(num) ? undefined : num;\r\n }\r\n\r\n protected parseLimits(rawLimit: RequestParamValue, rawOffset: RequestParamValue, rawPage: RequestParamValue) {\r\n const limit = this.parseNumber(rawLimit);\r\n let offset = this.parseNumber(rawOffset);\r\n\r\n if (limit && !offset) {\r\n const page = this.parseNumber(rawPage);\r\n\r\n if (page)\r\n offset = limit * page;\r\n }\r\n\r\n return { limit, offset };\r\n }\r\n\r\n protected parseSearch(builder: ParsedRequestWhereBuilder, rawSearch: RequestParamValue): void {\r\n if (Array.isArray(rawSearch))\r\n rawSearch = rawSearch.length > 0 ? rawSearch[0] : undefined;\r\n\r\n if (!rawSearch)\r\n return;\r\n\r\n const search: SCondition = JSON.parse(rawSearch);\r\n\r\n parseCrudSearch(builder, search);\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["crud_exports","__export","CrudRequestParser","__toCommonJS","ParsedRequestWhereBuilder","_ParsedRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","isValid","value","__name","parseCrudSearch","builder","cond","context","keys","$or","$and","innerFields","andBuilder","c","parseCrudSearchFields","orBuilder","__name","fields","name","field","isValid","fieldPath","f","parseCrudSearchField","operatorMap","key","value","val","CrudRequestParser","__name","arraySchema","query","select","relations","ordering","where","ParsedRequestWhereBuilder","limit","offset","rawSelect","field","requestFields","rawJoin","value","join","fieldPath","f","rawOrder","direction","raw","isValid","num","rawLimit","rawOffset","rawPage","page","builder","rawSearch","search","parseCrudSearch"]}
|
1
|
+
{"version":3,"sources":["../../../src/parsers/crud/index.ts","../../../src/utils/functions.ts","../../../src/utils/where.ts","../../../src/utils/crud-request-where.builder.ts","../../../src/parsers/crud/parseCrudSearch.ts","../../../src/parsers/crud/crud-request.parser.ts"],"sourcesContent":["\r\nexport * from './crud-request.parser';\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 ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\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\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * page : 0);\r\n}\r\n","import { CrudRequestWhereField, CrudRequestWhereOperator } from '../models/crud-request-where';\r\nimport { ensureArray, ensureEmpty, ensurePrimitive } from './functions';\r\n\r\nexport enum WhereOperatorValueType {\r\n PRIMITIVE = 'primitive',\r\n ARRAY = 'array',\r\n EMPTY = 'empty'\r\n}\r\n\r\nconst operatorValueTypes: Record<CrudRequestWhereOperator, WhereOperatorValueType> = {\r\n [CrudRequestWhereOperator.EQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.NOT_IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.BETWEEN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.IS_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.NOT_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.EQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n};\r\n\r\nexport function getWhereOperatorValueType(op: CrudRequestWhereOperator): WhereOperatorValueType {\r\n return operatorValueTypes[op];\r\n}\r\n\r\nexport function validateWhereField(where: CrudRequestWhereField): void {\r\n const type = operatorValueTypes[where.operator];\r\n const name = 'The value of the operator ' + where.operator;\r\n\r\n if (type === WhereOperatorValueType.PRIMITIVE) {\r\n ensurePrimitive(name, where.value);\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.ARRAY) {\r\n const items = ensureArray(name, where.value);\r\n\r\n items.forEach(item => ensurePrimitive(name + ' children', item));\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.EMPTY) {\r\n ensureEmpty(name, where.value);\r\n\r\n return;\r\n }\r\n}\r\n","import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\nimport { validateWhereField } from './where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class CrudRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: CrudRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): CrudRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): CrudRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(\r\n field: string[],\r\n operator: CrudRequestWhereOperator,\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[],\r\n ): CrudRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n validateWhereField(whereField);\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\r\n }\r\n\r\n}\r\n","import { CrudRequestWhereBuilder } from '../../utils/crud-request-where.builder';\r\nimport { CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { SCondition, SField, SFieldOperator, SFields } from './types';\r\nimport { isValid } from '../../utils/functions';\r\n\r\ntype OperatorType = Exclude<Exclude<keyof SFieldOperator, '$or'>, '$and'>;\r\n\r\n// Operator\r\n// { field: { $gte: 10 } }\r\nconst operatorMap: Record<OperatorType, CrudRequestWhereOperator> = {\r\n $eq: CrudRequestWhereOperator.EQ,\r\n $ne: CrudRequestWhereOperator.NEQ,\r\n $gt: CrudRequestWhereOperator.GT,\r\n $lt: CrudRequestWhereOperator.LT,\r\n $gte: CrudRequestWhereOperator.GTE,\r\n $lte: CrudRequestWhereOperator.LTE,\r\n $starts: CrudRequestWhereOperator.STARTS,\r\n $ends: CrudRequestWhereOperator.ENDS,\r\n $cont: CrudRequestWhereOperator.CONTAINS,\r\n $excl: CrudRequestWhereOperator.NOT_CONTAINS,\r\n $in: CrudRequestWhereOperator.IN,\r\n $notin: CrudRequestWhereOperator.NOT_IN,\r\n $between: CrudRequestWhereOperator.BETWEEN,\r\n $isnull: CrudRequestWhereOperator.IS_NULL,\r\n $notnull: CrudRequestWhereOperator.NOT_NULL,\r\n $eqL: CrudRequestWhereOperator.EQ_LOWER,\r\n $neL: CrudRequestWhereOperator.NEQ_LOWER,\r\n $startsL: CrudRequestWhereOperator.STARTS_LOWER,\r\n $endsL: CrudRequestWhereOperator.ENDS_LOWER,\r\n $contL: CrudRequestWhereOperator.CONTAINS_LOWER,\r\n $exclL: CrudRequestWhereOperator.NOT_CONTAINS_LOWER,\r\n $inL: CrudRequestWhereOperator.IN_LOWER,\r\n $notinL: CrudRequestWhereOperator.NOT_IN_LOWER,\r\n};\r\n\r\n/**\r\n * Parses a crud request condition and inserts into a CrudRequestWhereBuilder\r\n *\r\n * @param builder The builder that the condition will be inserted to\r\n * @param cond The condition that must be parsed\r\n * @param context The field context\r\n */\r\nexport function parseCrudSearch(builder: CrudRequestWhereBuilder, cond: SCondition, context: string[] = []) {\r\n if (typeof cond !== 'object')\r\n return;\r\n\r\n const keys = Object.keys(cond);\r\n\r\n if (keys.length === 0)\r\n return;\r\n\r\n const { $or, $and, ...innerFields } = cond;\r\n\r\n // { $and: [..., ...] }\r\n if ($and) {\r\n const andBuilder = $and.length > 1 || keys.length > 1 ? builder.addAnd() : builder;\r\n\r\n $and.forEach(c => parseCrudSearch(andBuilder, c, context));\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n return;\r\n }\r\n\r\n // { $or: [..., ...] }\r\n if ($or && keys.length === 1) {\r\n const orBuilder = $or.length > 1 ? builder.addOr() : builder;\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n // { $or: [...], field1: ..., field2: ... }\r\n if ($or) {\r\n const andBuilder = builder.addAnd();\r\n const orBuilder = $or.length > 1 ? andBuilder.addOr() : andBuilder;\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n if (keys.length > 1)\r\n builder = builder.addAnd();\r\n\r\n parseCrudSearchFields(builder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n}\r\n\r\n/**\r\n * Parses an object from the crud request full of fields\r\n *\r\n * @param builder The builder\r\n * @param fields The fields object\r\n * @param context The context\r\n */\r\nfunction parseCrudSearchFields(builder: CrudRequestWhereBuilder, fields: Omit<Omit<SFields, '$or'>, '$and'>, context: string[]): void {\r\n // { name: 'John', age: { $gte: 18 }, 'posts.name': { $cont: 'Greetings' } }\r\n for (const name of Object.keys(fields)) {\r\n const field = fields[name];\r\n\r\n if (!isValid(field))\r\n continue;\r\n\r\n const fieldPath = [...context, ...name.split('.')];\r\n\r\n // { name: [{ $or: [...] }] }\r\n if (Array.isArray(field)) {\r\n field.forEach(f => parseCrudSearch(builder, f, fieldPath));\r\n continue;\r\n }\r\n\r\n parseCrudSearchField(builder, fieldPath, field);\r\n }\r\n}\r\n\r\n/**\r\n * Parses a single field\r\n *\r\n * @param builder The builder\r\n * @param name The name path\r\n * @param field The field value or operator\r\n */\r\nfunction parseCrudSearchField(builder: CrudRequestWhereBuilder, name: string[], field: SField): void {\r\n // Primitive Value\r\n // { field: 'text', field2: 12, field3: true }\r\n if (typeof field !== 'object') {\r\n builder.addField(name, CrudRequestWhereOperator.EQ, field);\r\n return;\r\n }\r\n\r\n const keys = Object.keys(field) as OperatorType[];\r\n\r\n for (let key of keys) {\r\n if (!operatorMap[key])\r\n continue;\r\n\r\n builder.addField(name, operatorMap[key], field[key]);\r\n }\r\n\r\n if (field.$or) {\r\n parseCrudSearchField(builder.addOr(), name, field.$or);\r\n }\r\n}\r\n\r\nexport function parseCrudFilters(builder: CrudRequestWhereBuilder, andFilters: string[], orFilters: string[]): void {\r\n // Based on rules from https://github.com/nestjsx/crud/wiki/Requests#or\r\n // \"If present both or and filter in any amount (one or miltiple each) then both interpreted\r\n // as a combitation of AND conditions and compared with each other by OR condition\"\r\n // \"If there are one or and one filter then it will be interpreted as OR condition\"\r\n if (andFilters.length > 0 && orFilters.length > 0) {\r\n const or = builder.addOr();\r\n\r\n parseCrudFilter(or.addAnd(), andFilters);\r\n parseCrudFilter(or.addAnd(), orFilters);\r\n\r\n return;\r\n }\r\n\r\n // \"If there are multiple or present (without filter) then it will be interpreted as a compination of OR conditions\"\r\n if (orFilters.length > 0) {\r\n parseCrudFilter(builder.addOr(), orFilters);\r\n\r\n return;\r\n }\r\n\r\n if (andFilters.length > 0) {\r\n parseCrudFilter(builder.addAnd(), andFilters);\r\n\r\n return;\r\n }\r\n}\r\n\r\nfunction parseCrudFilter(builder: CrudRequestWhereBuilder, rawFilters: string[]): void {\r\n for (const rawFilter of rawFilters) {\r\n const [name, op, value] = rawFilter.split('||', 3);\r\n const operator = operatorMap[op as OperatorType];\r\n\r\n if (!operator)\r\n continue;\r\n\r\n builder.addField(name.split('.'), operator, value);\r\n }\r\n}\r\n","import { RequestParamValue, RequestParser } from '../../models/request-parser';\r\nimport { CrudRequest, CrudRequestOrder, CrudRequestRelation, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\nimport { CrudRequestWhereBuilder } from '../../utils/crud-request-where.builder';\r\nimport { parseCrudFilters, parseCrudSearch } from './parseCrudSearch';\r\nimport { isValid } from '../../utils/functions';\r\nimport { SCondition } from './types';\r\n\r\nexport interface CrudRequestParserOptions {\r\n /**\r\n * Whether the `fields` and `select` parameters will be disabled\r\n */\r\n disableSelect?: boolean;\r\n\r\n /**\r\n * Whether the `s`, `filter` and `or` parameters will be disabled\r\n */\r\n disableWhere?: boolean;\r\n\r\n /**\r\n * Whether the `sort` parameter will be disabled\r\n */\r\n disableOrder?: boolean;\r\n\r\n /**\r\n * Whether the `join` parameter will be disabled\r\n */\r\n disableRelations?: boolean;\r\n\r\n /**\r\n * Whether the `limit` and `per_page` parameters will be disabled\r\n */\r\n disableLimit?: boolean;\r\n\r\n /**\r\n * Whether the `offset` and `page` parameters will be disabled\r\n */\r\n disableOffset?: boolean;\r\n}\r\n\r\n/**\r\n * Parses a request based on the @nestjsx/crud format.\r\n */\r\nexport class CrudRequestParser implements RequestParser {\r\n\r\n constructor(\r\n protected readonly options: CrudRequestParserOptions = {},\r\n ) {\r\n }\r\n\r\n public getOpenAPIParameters(): OpenAPIParameter[] {\r\n // We'll not add the `per_page`, `filter`, `or` and `select` parameters here\r\n // as those are only kept for compatibility purposes and not recommended.\r\n // TODO improve docs\r\n\r\n const arraySchema = {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n },\r\n };\r\n\r\n const params: OpenAPIParameter[] = [];\r\n\r\n if (!this.options.disableSelect) {\r\n params.push({\r\n name: 'fields',\r\n description: 'Selects resource fields',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: false,\r\n });\r\n }\r\n\r\n if (!this.options.disableWhere) {\r\n params.push({\r\n name: 's',\r\n description: 'Search condition',\r\n required: false,\r\n schema: {\r\n type: 'string',\r\n },\r\n });\r\n }\r\n\r\n if (!this.options.disableOrder) {\r\n params.push({\r\n name: 'sort',\r\n description: 'Sorting',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n });\r\n }\r\n\r\n if (!this.options.disableRelations) {\r\n params.push({\r\n name: 'join',\r\n description: 'Relations',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n });\r\n }\r\n\r\n if (!this.options.disableLimit) {\r\n params.push({\r\n name: 'limit',\r\n description: 'Page limit',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n });\r\n }\r\n\r\n if (!this.options.disableOffset) {\r\n params.push({\r\n name: 'offset',\r\n description: 'Offset amount',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n }, {\r\n name: 'page',\r\n description: 'Page number',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n });\r\n }\r\n\r\n return params;\r\n }\r\n\r\n public parse(query: Record<string, RequestParamValue>): CrudRequest {\r\n const select: ParsedRequestSelect = [];\r\n const relations: CrudRequestRelation[] = [];\r\n const ordering: CrudRequestOrder[] = [];\r\n const where = new CrudRequestWhereBuilder();\r\n\r\n if (!this.options.disableSelect)\r\n this.parseSelect(select, query['fields'] || query['select']);\r\n\r\n if (!this.options.disableRelations)\r\n this.parseJoin(select, relations, query['join']);\r\n\r\n if (!this.options.disableOrder)\r\n this.parseOrder(ordering, query['sort']);\r\n\r\n if (!this.options.disableWhere)\r\n this.parseSearch(where, query['s'], query['filter'], query['or']);\r\n\r\n const limit = this.options.disableLimit ? undefined : this.parseNumber(query['limit'] || query['per_page']);\r\n const offset = this.options.disableOffset ? undefined : this.parseNumber(query['offset']);\r\n const page = this.options.disableOffset ? undefined : this.parseNumber(query['page']);\r\n\r\n return {\r\n select,\r\n relations,\r\n order: ordering,\r\n where: where.build(),\r\n limit,\r\n offset,\r\n page,\r\n };\r\n }\r\n\r\n protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void {\r\n if (!rawSelect)\r\n return;\r\n\r\n const selectFields = Array.isArray(rawSelect) ? rawSelect : rawSelect.split(',');\r\n\r\n selectFields.forEach(field => {\r\n select.push({\r\n field: field.split('.'),\r\n });\r\n });\r\n }\r\n\r\n protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void {\r\n if (!rawJoin)\r\n return;\r\n\r\n if (Array.isArray(rawJoin)) {\r\n rawJoin.forEach(value => this.parseJoin(requestFields, relations, value));\r\n return;\r\n }\r\n\r\n const join = rawJoin.toString();\r\n\r\n const [field, select] = join.split('||', 2);\r\n const fieldPath = field.split('.');\r\n\r\n relations.push({\r\n field: fieldPath,\r\n });\r\n\r\n if (select) {\r\n const selectFields = select.split(',');\r\n\r\n selectFields.forEach(f => {\r\n requestFields.push({\r\n field: [...fieldPath, f],\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void {\r\n if (!rawOrder)\r\n return;\r\n\r\n if (Array.isArray(rawOrder)) {\r\n rawOrder.forEach(value => this.parseOrder(ordering, value));\r\n return;\r\n }\r\n\r\n const [field, direction] = rawOrder.split(',');\r\n\r\n ordering.push({\r\n field: field.split('.'),\r\n order: direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC',\r\n });\r\n }\r\n\r\n protected parseNumber(raw: RequestParamValue): number | undefined {\r\n if (Array.isArray(raw))\r\n raw = raw.length > 0 ? raw[0] : undefined;\r\n\r\n if (!isValid(raw))\r\n return undefined;\r\n\r\n const num = +raw;\r\n\r\n return isNaN(num) ? undefined : num;\r\n }\r\n\r\n protected parseSearch(builder: CrudRequestWhereBuilder, rawSearch: RequestParamValue, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n if (Array.isArray(rawSearch))\r\n rawSearch = rawSearch.length > 0 ? rawSearch[0] : undefined;\r\n\r\n if (!rawSearch) {\r\n // In case the search is not defined, we'll read the filter and or parameters\r\n this.parseFilter(builder, rawFilter, rawOr);\r\n return;\r\n }\r\n\r\n const search: SCondition = JSON.parse(rawSearch);\r\n\r\n parseCrudSearch(builder, search);\r\n }\r\n\r\n protected parseFilter(builder: CrudRequestWhereBuilder, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n let andFilters: string[] = [];\r\n let orFilters: string[] = [];\r\n\r\n if (rawFilter)\r\n andFilters = Array.isArray(rawFilter) ? rawFilter : [rawFilter];\r\n\r\n if (rawOr)\r\n orFilters = Array.isArray(rawOr) ? rawOr : [rawOr];\r\n\r\n parseCrudFilters(builder, andFilters, orFilters);\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["crud_exports","__export","CrudRequestParser","__toCommonJS","ensurePrimitive","fieldName","data","__name","ensureArray","minLength","ensureEmpty","isValid","value","operatorValueTypes","validateWhereField","where","type","operatorValueTypes","name","ensurePrimitive","ensureArray","item","ensureEmpty","__name","CrudRequestWhereBuilder","_CrudRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","validateWhereField","operatorMap","parseCrudSearch","builder","cond","context","keys","$or","$and","innerFields","andBuilder","c","parseCrudSearchFields","orBuilder","__name","fields","name","field","isValid","fieldPath","f","parseCrudSearchField","key","parseCrudFilters","andFilters","orFilters","or","parseCrudFilter","rawFilters","rawFilter","op","value","operator","CrudRequestParser","options","__name","arraySchema","params","query","select","relations","ordering","where","CrudRequestWhereBuilder","limit","offset","page","rawSelect","field","requestFields","rawJoin","value","join","fieldPath","f","rawOrder","direction","raw","isValid","num","builder","rawSearch","rawFilter","rawOr","search","parseCrudSearch","andFilters","orFilters","parseCrudFilters"]}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
var
|
1
|
+
var V=Object.defineProperty;var o=(t,e)=>V(t,"name",{value:e,configurable:!0});function R(t,e){if(e!=null&&!(typeof e=="number"||typeof e=="string"||typeof e=="boolean")&&!(e instanceof Date))throw new Error(`${t} must be a string, number, boolean or null`)}o(R,"ensurePrimitive");function O(t,e,r=0){if(!Array.isArray(e)||e.length<r)throw new Error(`${t} must be an array with at least ${r} items`);return e}o(O,"ensureArray");function E(t,e){if(p(e)&&e!==!0)throw new Error(`${t} must be true, null or undefined`)}o(E,"ensureEmpty");function p(t){return t!=null}o(p,"isValid");var S={eq:"primitive",neq:"primitive",gt:"primitive",lt:"primitive",gte:"primitive",lte:"primitive",starts:"primitive",ends:"primitive",contains:"primitive",not_contains:"primitive",in:"array",not_in:"array",between:"array",is_null:"empty",not_null:"empty",eq_lower:"primitive",neq_lower:"primitive",starts_lower:"primitive",ends_lower:"primitive",contains_lower:"primitive",not_contains_lower:"primitive",in_lower:"primitive",not_in_lower:"primitive"};function I(t){let e=S[t.operator],r="The value of the operator "+t.operator;if(e==="primitive"){R(r,t.value);return}if(e==="array"){O(r,t.value).forEach(i=>R(r+" children",i));return}if(e==="empty"){E(r,t.value);return}}o(I,"validateWhereField");var h=class t{constructor(e={and:[]},r){this.where=e;this.parent=r}static{o(this,"CrudRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},r=new t(e,this);return this.where.or.push(e),r}addOr(){if(!this.where.and)return this;let e={or:[]},r=new t(e,this);return this.where.and.push(e),r}addField(e,r,s){let i={field:e,operator:r,value:s};if(I(i),this.where.and)this.where.and.push(i);else if(this.where.or)this.where.or.push(i);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};var m={$eq:"eq",$ne:"neq",$gt:"gt",$lt:"lt",$gte:"gte",$lte:"lte",$starts:"starts",$ends:"ends",$cont:"contains",$excl:"not_contains",$in:"in",$notin:"not_in",$between:"between",$isnull:"is_null",$notnull:"not_null",$eqL:"eq_lower",$neL:"neq_lower",$startsL:"starts_lower",$endsL:"ends_lower",$contL:"contains_lower",$exclL:"not_contains_lower",$inL:"in_lower",$notinL:"not_in_lower"};function l(t,e,r=[]){if(typeof e!="object")return;let s=Object.keys(e);if(s.length===0)return;let{$or:i,$and:n,...a}=e;if(n){let u=n.length>1||s.length>1?t.addAnd():t;n.forEach(d=>l(u,d,r)),T(u,a,r);return}if(i&&s.length===1){let u=i.length>1?t.addOr():t;i.forEach(d=>l(u,d,r));return}if(i){let u=t.addAnd(),d=i.length>1?u.addOr():u;T(u,a,r),i.forEach(c=>l(d,c,r));return}s.length>1&&(t=t.addAnd()),T(t,a,r)}o(l,"parseCrudSearch");function T(t,e,r){for(let s of Object.keys(e)){let i=e[s];if(!p(i))continue;let n=[...r,...s.split(".")];if(Array.isArray(i)){i.forEach(a=>l(t,a,n));continue}y(t,n,i)}}o(T,"parseCrudSearchFields");function y(t,e,r){if(typeof r!="object"){t.addField(e,"eq",r);return}let s=Object.keys(r);for(let i of s)m[i]&&t.addField(e,m[i],r[i]);r.$or&&y(t.addOr(),e,r.$or)}o(y,"parseCrudSearchField");function N(t,e,r){if(e.length>0&&r.length>0){let s=t.addOr();f(s.addAnd(),e),f(s.addAnd(),r);return}if(r.length>0){f(t.addOr(),r);return}if(e.length>0){f(t.addAnd(),e);return}}o(N,"parseCrudFilters");function f(t,e){for(let r of e){let[s,i,n]=r.split("||",3),a=m[i];a&&t.addField(s.split("."),a,n)}}o(f,"parseCrudFilter");var W=class{constructor(e={}){this.options=e}static{o(this,"CrudRequestParser")}getOpenAPIParameters(){let e={type:"array",items:{type:"string"}},r=[];return this.options.disableSelect||r.push({name:"fields",description:"Selects resource fields",required:!1,schema:e,style:"form",explode:!1}),this.options.disableWhere||r.push({name:"s",description:"Search condition",required:!1,schema:{type:"string"}}),this.options.disableOrder||r.push({name:"sort",description:"Sorting",required:!1,schema:e,style:"form",explode:!0}),this.options.disableRelations||r.push({name:"join",description:"Relations",required:!1,schema:e,style:"form",explode:!0}),this.options.disableLimit||r.push({name:"limit",description:"Page limit",required:!1,schema:{type:"integer"}}),this.options.disableOffset||r.push({name:"offset",description:"Offset amount",required:!1,schema:{type:"integer"}},{name:"page",description:"Page number",required:!1,schema:{type:"integer"}}),r}parse(e){let r=[],s=[],i=[],n=new h;this.options.disableSelect||this.parseSelect(r,e.fields||e.select),this.options.disableRelations||this.parseJoin(r,s,e.join),this.options.disableOrder||this.parseOrder(i,e.sort),this.options.disableWhere||this.parseSearch(n,e.s,e.filter,e.or);let a=this.options.disableLimit?void 0:this.parseNumber(e.limit||e.per_page),u=this.options.disableOffset?void 0:this.parseNumber(e.offset),d=this.options.disableOffset?void 0:this.parseNumber(e.page);return{select:r,relations:s,order:i,where:n.build(),limit:a,offset:u,page:d}}parseSelect(e,r){if(!r)return;(Array.isArray(r)?r:r.split(",")).forEach(i=>{e.push({field:i.split(".")})})}parseJoin(e,r,s){if(!s)return;if(Array.isArray(s)){s.forEach(d=>this.parseJoin(e,r,d));return}let i=s.toString(),[n,a]=i.split("||",2),u=n.split(".");r.push({field:u}),a&&a.split(",").forEach(c=>{e.push({field:[...u,c]})})}parseOrder(e,r){if(!r)return;if(Array.isArray(r)){r.forEach(n=>this.parseOrder(e,n));return}let[s,i]=r.split(",");e.push({field:s.split("."),order:i?.toUpperCase()==="DESC"?"DESC":"ASC"})}parseNumber(e){if(Array.isArray(e)&&(e=e.length>0?e[0]:void 0),!p(e))return;let r=+e;return isNaN(r)?void 0:r}parseSearch(e,r,s,i){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!r){this.parseFilter(e,s,i);return}let n=JSON.parse(r);l(e,n)}parseFilter(e,r,s){let i=[],n=[];r&&(i=Array.isArray(r)?r:[r]),s&&(n=Array.isArray(s)?s:[s]),N(e,i,n)}};export{W as CrudRequestParser};
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../../src/utils/parsed-request-where.builder.ts","../../../src/utils/functions.ts","../../../src/parsers/crud/parseCrudSearch.ts","../../../src/parsers/crud/crud-request.parser.ts"],"sourcesContent":["import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class ParsedRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: ParsedRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): ParsedRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): ParsedRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new ParsedRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(field: string[], operator: CrudRequestWhereOperator, value: CrudRequestWhereValueType): ParsedRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\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","import { ParsedRequestWhereBuilder } from '../../utils/parsed-request-where.builder';\r\nimport { CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { SCondition, SField, SFieldOperator, SFields } from './types';\r\nimport { isValid } from '../../utils/functions';\r\n\r\n/**\r\n * Parses a crud request condition and inserts into a ParsedRequestWhereBuilder\r\n *\r\n * @param builder The builder that the condition will be inserted to\r\n * @param cond The condition that must be parsed\r\n * @param context The field context\r\n */\r\nexport function parseCrudSearch(builder: ParsedRequestWhereBuilder, cond: SCondition, context: string[] = []) {\r\n if (typeof cond !== 'object')\r\n return;\r\n\r\n const keys = Object.keys(cond);\r\n\r\n if (keys.length === 0)\r\n return;\r\n\r\n const { $or, $and, ...innerFields } = cond;\r\n\r\n // { $and: [..., ...] }\r\n if ($and) {\r\n const andBuilder = $and.length > 1 || keys.length > 1 ? builder.addAnd() : builder;\r\n\r\n $and.forEach(c => parseCrudSearch(andBuilder, c, context));\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n return;\r\n }\r\n\r\n // { $or: [..., ...] }\r\n if ($or && keys.length === 1) {\r\n const orBuilder = $or.length > 1 ? builder.addOr() : builder;\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n // { $or: [...], field1: ..., field2: ... }\r\n if ($or) {\r\n const andBuilder = builder.addAnd();\r\n const orBuilder = $or.length > 1 ? andBuilder.addOr() : andBuilder;\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n if (keys.length > 1)\r\n builder = builder.addAnd();\r\n\r\n parseCrudSearchFields(builder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n}\r\n\r\n/**\r\n * Parses an object from the crud request full of fields\r\n *\r\n * @param builder The builder\r\n * @param fields The fields object\r\n * @param context The context\r\n */\r\nfunction parseCrudSearchFields(builder: ParsedRequestWhereBuilder, fields: Omit<Omit<SFields, '$or'>, '$and'>, context: string[]): void {\r\n // { name: 'John', age: { $gte: 18 }, 'posts.name': { $cont: 'Greetings' } }\r\n for (const name of Object.keys(fields)) {\r\n const field = fields[name];\r\n\r\n if (!isValid(field))\r\n continue;\r\n\r\n const fieldPath = [...context, ...name.split('.')];\r\n\r\n // { name: [{ $or: [...] }] }\r\n if (Array.isArray(field)) {\r\n field.forEach(f => parseCrudSearch(builder, f, fieldPath));\r\n continue;\r\n }\r\n\r\n parseCrudSearchField(builder, fieldPath, field);\r\n }\r\n}\r\n\r\n/**\r\n * Parses a single field\r\n *\r\n * @param builder The builder\r\n * @param name The name path\r\n * @param field The field value or operator\r\n */\r\nfunction parseCrudSearchField(builder: ParsedRequestWhereBuilder, name: string[], field: SField): void {\r\n // Primitive Value\r\n // { field: 'text', field2: 12, field3: true }\r\n if (typeof field !== 'object') {\r\n builder.addField(name, CrudRequestWhereOperator.EQ, field);\r\n return;\r\n }\r\n\r\n type OperatorType = Exclude<Exclude<keyof SFieldOperator, '$or'>, '$and'>;\r\n\r\n // Operator\r\n // { field: { $gte: 10 } }\r\n const operatorMap: Record<OperatorType, CrudRequestWhereOperator> = {\r\n $eq: CrudRequestWhereOperator.EQ,\r\n $ne: CrudRequestWhereOperator.NEQ,\r\n $gt: CrudRequestWhereOperator.GT,\r\n $lt: CrudRequestWhereOperator.LT,\r\n $gte: CrudRequestWhereOperator.GTE,\r\n $lte: CrudRequestWhereOperator.LTE,\r\n $starts: CrudRequestWhereOperator.STARTS,\r\n $ends: CrudRequestWhereOperator.ENDS,\r\n $cont: CrudRequestWhereOperator.CONTAINS,\r\n $excl: CrudRequestWhereOperator.NOT_CONTAINS,\r\n $in: CrudRequestWhereOperator.IN,\r\n $notin: CrudRequestWhereOperator.NOT_IN,\r\n $between: CrudRequestWhereOperator.BETWEEN,\r\n $isnull: CrudRequestWhereOperator.IS_NULL,\r\n $notnull: CrudRequestWhereOperator.NOT_NULL,\r\n $eqL: CrudRequestWhereOperator.EQ_LOWER,\r\n $neL: CrudRequestWhereOperator.NEQ_LOWER,\r\n $startsL: CrudRequestWhereOperator.STARTS_LOWER,\r\n $endsL: CrudRequestWhereOperator.ENDS_LOWER,\r\n $contL: CrudRequestWhereOperator.CONTAINS_LOWER,\r\n $exclL: CrudRequestWhereOperator.NOT_CONTAINS_LOWER,\r\n $inL: CrudRequestWhereOperator.IN_LOWER,\r\n $notinL: CrudRequestWhereOperator.NOT_IN_LOWER,\r\n };\r\n\r\n const keys = Object.keys(field) as OperatorType[];\r\n\r\n for (let key of keys) {\r\n if (!operatorMap[key])\r\n continue;\r\n\r\n const value = field[key];\r\n\r\n if (Array.isArray(value))\r\n value.forEach(val => builder.addField(name, operatorMap[key], val));\r\n else\r\n builder.addField(name, operatorMap[key], value);\r\n }\r\n\r\n if (field.$or) {\r\n parseCrudSearchField(builder.addOr(), name, field.$or);\r\n }\r\n}\r\n","import { RequestParamValue, RequestParser } from '../../models/request-parser';\r\nimport {\r\n CrudRequest,\r\n CrudRequestOrder,\r\n CrudRequestRelation,\r\n ParsedRequestSelect\r\n} from '../../models/crud-request';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\nimport { ParsedRequestWhereBuilder } from '../../utils/parsed-request-where.builder';\r\nimport { parseCrudSearch } from './parseCrudSearch';\r\nimport { isValid } from '../../utils/functions';\r\nimport { SCondition } from './types';\r\n\r\n/**\r\n * Parses a request based on the @nestjsx/crud format.\r\n */\r\nexport class CrudRequestParser implements RequestParser {\r\n\r\n public getOpenAPIParameters(): OpenAPIParameter[] {\r\n const arraySchema = {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n },\r\n };\r\n\r\n return [\r\n {\r\n name: 'fields',\r\n description: 'Selects resource fields',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: false,\r\n },\r\n {\r\n name: 's',\r\n description: 'Search condition',\r\n required: false,\r\n schema: {\r\n type: 'string',\r\n },\r\n },\r\n {\r\n name: 'sort',\r\n description: 'Search condition',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n },\r\n {\r\n name: 'join',\r\n description: 'Relations',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n },\r\n {\r\n name: 'limit',\r\n description: 'Page limit',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n {\r\n name: 'offset',\r\n description: 'Offset amount',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n {\r\n name: 'page',\r\n description: 'Page number',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n },\r\n ];\r\n }\r\n\r\n public parse(query: Record<string, RequestParamValue>): CrudRequest {\r\n const select: ParsedRequestSelect = [];\r\n const relations: CrudRequestRelation[] = [];\r\n const ordering: CrudRequestOrder[] = [];\r\n const where = new ParsedRequestWhereBuilder();\r\n\r\n this.parseSelect(select, query['fields'] || query['select']);\r\n this.parseJoin(select, relations, query['join']);\r\n this.parseOrder(ordering, query['sort']);\r\n this.parseSearch(where, query['s']);\r\n\r\n const { limit, offset } = this.parseLimits(query['limit'], query['offset'], query['page']);\r\n\r\n return {\r\n select,\r\n relations,\r\n order: ordering,\r\n where: where.build(),\r\n limit,\r\n offset,\r\n };\r\n }\r\n\r\n protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void {\r\n if (!rawSelect)\r\n return;\r\n\r\n const selectFields = Array.isArray(rawSelect) ? rawSelect : rawSelect.split(',');\r\n\r\n selectFields.forEach(field => {\r\n select.push({\r\n field: field.split('.'),\r\n });\r\n });\r\n }\r\n\r\n protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void {\r\n if (!rawJoin)\r\n return;\r\n\r\n if (Array.isArray(rawJoin)) {\r\n rawJoin.forEach(value => this.parseJoin(requestFields, relations, value));\r\n return;\r\n }\r\n\r\n const join = rawJoin.toString();\r\n\r\n const [field, select] = join.split('||', 2);\r\n const fieldPath = field.split('.');\r\n\r\n relations.push({\r\n field: fieldPath,\r\n });\r\n\r\n if (select) {\r\n const selectFields = select.split(',');\r\n\r\n selectFields.forEach(f => {\r\n requestFields.push({\r\n field: [...fieldPath, f],\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void {\r\n if (!rawOrder)\r\n return;\r\n\r\n if (Array.isArray(rawOrder)) {\r\n rawOrder.forEach(value => this.parseOrder(ordering, value));\r\n return;\r\n }\r\n\r\n const [field, direction] = rawOrder.split(',');\r\n\r\n ordering.push({\r\n field: field.split('.'),\r\n order: direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC',\r\n });\r\n }\r\n\r\n protected parseNumber(raw: RequestParamValue): number | undefined {\r\n if (Array.isArray(raw))\r\n raw = raw.length > 0 ? raw[0] : undefined;\r\n\r\n if (!isValid(raw))\r\n return undefined;\r\n\r\n const num = +raw;\r\n\r\n return isNaN(num) ? undefined : num;\r\n }\r\n\r\n protected parseLimits(rawLimit: RequestParamValue, rawOffset: RequestParamValue, rawPage: RequestParamValue) {\r\n const limit = this.parseNumber(rawLimit);\r\n let offset = this.parseNumber(rawOffset);\r\n\r\n if (limit && !offset) {\r\n const page = this.parseNumber(rawPage);\r\n\r\n if (page)\r\n offset = limit * page;\r\n }\r\n\r\n return { limit, offset };\r\n }\r\n\r\n protected parseSearch(builder: ParsedRequestWhereBuilder, rawSearch: RequestParamValue): void {\r\n if (Array.isArray(rawSearch))\r\n rawSearch = rawSearch.length > 0 ? rawSearch[0] : undefined;\r\n\r\n if (!rawSearch)\r\n return;\r\n\r\n const search: SCondition = JSON.parse(rawSearch);\r\n\r\n parseCrudSearch(builder, search);\r\n }\r\n\r\n}\r\n"],"mappings":"+EAYO,IAAMA,EAAN,MAAMC,CAA0B,CAErC,YACmBC,EAAkD,CAAE,IAAK,CAAC,CAAE,EAC5DC,EACjB,CAFiB,WAAAD,EACA,YAAAC,CACf,CAjBN,MAYuC,CAAAC,EAAA,kCAU9B,QAAoC,CACzC,GAAI,CAAC,KAAK,MAAM,GACd,OAAO,KAGT,IAAMC,EAA8B,CAAE,IAAK,CAAC,CAAE,EACxCC,EAAU,IAAIL,EAA0BI,EAAQ,IAAI,EAE1D,YAAK,MAAM,GAAG,KAAKA,CAAM,EAElBC,CACT,CAKO,OAAmC,CACxC,GAAI,CAAC,KAAK,MAAM,IACd,OAAO,KAGT,IAAMD,EAA6B,CAAE,GAAI,CAAC,CAAE,EACtCC,EAAU,IAAIL,EAA0BI,EAAQ,IAAI,EAE1D,YAAK,MAAM,IAAI,KAAKA,CAAM,EAEnBC,CACT,CASO,SAASC,EAAiBC,EAAoCC,EAA6D,CAChI,IAAMC,EAAoC,CACxC,MAAAH,EACA,SAAAC,EACA,MAAAC,CACF,EAEA,GAAI,KAAK,MAAM,IACb,KAAK,MAAM,IAAI,KAAKC,CAAU,UACrB,KAAK,MAAM,GACpB,KAAK,MAAM,GAAG,KAAKA,CAAU,MAE7B,OAAM,IAAI,MAAM,eAAe,EAGjC,OAAO,IACT,CAKO,OAA0B,CAC/B,OAAI,KAAK,OACA,KAAK,OAAO,MAAM,EAGpB,KAAK,KACd,CAEF,EC1DO,SAASC,EAAQC,EAA6B,CACnD,OAAOA,GAAU,IACnB,CAFgBC,EAAAF,EAAA,WCjBT,SAASG,EAAgBC,EAAoCC,EAAkBC,EAAoB,CAAC,EAAG,CAC5G,GAAI,OAAOD,GAAS,SAClB,OAEF,IAAME,EAAO,OAAO,KAAKF,CAAI,EAE7B,GAAIE,EAAK,SAAW,EAClB,OAEF,GAAM,CAAE,IAAAC,EAAK,KAAAC,EAAM,GAAGC,CAAY,EAAIL,EAGtC,GAAII,EAAM,CACR,IAAME,EAAaF,EAAK,OAAS,GAAKF,EAAK,OAAS,EAAIH,EAAQ,OAAO,EAAIA,EAE3EK,EAAK,QAAQG,GAAKT,EAAgBQ,EAAYC,EAAGN,CAAO,CAAC,EAEzDO,EAAsBF,EAAYD,EAAmDJ,CAAO,EAE5F,MACF,CAGA,GAAIE,GAAOD,EAAK,SAAW,EAAG,CAC5B,IAAMO,EAAYN,EAAI,OAAS,EAAIJ,EAAQ,MAAM,EAAIA,EAErDI,EAAI,QAAQI,GAAKT,EAAgBW,EAAWF,EAAGN,CAAO,CAAC,EAEvD,MACF,CAGA,GAAIE,EAAK,CACP,IAAMG,EAAaP,EAAQ,OAAO,EAC5BU,EAAYN,EAAI,OAAS,EAAIG,EAAW,MAAM,EAAIA,EAExDE,EAAsBF,EAAYD,EAAmDJ,CAAO,EAE5FE,EAAI,QAAQI,GAAKT,EAAgBW,EAAWF,EAAGN,CAAO,CAAC,EAEvD,MACF,CAEIC,EAAK,OAAS,IAChBH,EAAUA,EAAQ,OAAO,GAE3BS,EAAsBT,EAASM,EAAmDJ,CAAO,CAC3F,CA/CgBS,EAAAZ,EAAA,mBAwDhB,SAASU,EAAsBT,EAAoCY,EAA4CV,EAAyB,CAEtI,QAAWW,KAAQ,OAAO,KAAKD,CAAM,EAAG,CACtC,IAAME,EAAQF,EAAOC,CAAI,EAEzB,GAAI,CAACE,EAAQD,CAAK,EAChB,SAEF,IAAME,EAAY,CAAC,GAAGd,EAAS,GAAGW,EAAK,MAAM,GAAG,CAAC,EAGjD,GAAI,MAAM,QAAQC,CAAK,EAAG,CACxBA,EAAM,QAAQG,GAAKlB,EAAgBC,EAASiB,EAAGD,CAAS,CAAC,EACzD,QACF,CAEAE,EAAqBlB,EAASgB,EAAWF,CAAK,CAChD,CACF,CAlBSH,EAAAF,EAAA,yBA2BT,SAASS,EAAqBlB,EAAoCa,EAAgBC,EAAqB,CAGrG,GAAI,OAAOA,GAAU,SAAU,CAC7Bd,EAAQ,SAASa,OAAmCC,CAAK,EACzD,MACF,CAMA,IAAMK,EAA8D,CAClE,SACA,UACA,SACA,SACA,WACA,WACA,iBACA,aACA,iBACA,qBACA,SACA,gBACA,mBACA,kBACA,oBACA,gBACA,iBACA,wBACA,oBACA,wBACA,4BACA,gBACA,sBACF,EAEMhB,EAAO,OAAO,KAAKW,CAAK,EAE9B,QAASM,KAAOjB,EAAM,CACpB,GAAI,CAACgB,EAAYC,CAAG,EAClB,SAEF,IAAMC,EAAQP,EAAMM,CAAG,EAEnB,MAAM,QAAQC,CAAK,EACrBA,EAAM,QAAQC,GAAOtB,EAAQ,SAASa,EAAMM,EAAYC,CAAG,EAAGE,CAAG,CAAC,EAElEtB,EAAQ,SAASa,EAAMM,EAAYC,CAAG,EAAGC,CAAK,CAClD,CAEIP,EAAM,KACRI,EAAqBlB,EAAQ,MAAM,EAAGa,EAAMC,EAAM,GAAG,CAEzD,CAvDSH,EAAAO,EAAA,wBC/EF,IAAMK,EAAN,KAAiD,CAhBxD,MAgBwD,CAAAC,EAAA,0BAE/C,sBAA2C,CAChD,IAAMC,EAAc,CAClB,KAAM,QACN,MAAO,CACL,KAAM,QACR,CACF,EAEA,MAAO,CACL,CACE,KAAM,SACN,YAAa,0BACb,SAAU,GACV,OAAQA,EACR,MAAO,OACP,QAAS,EACX,EACA,CACE,KAAM,IACN,YAAa,mBACb,SAAU,GACV,OAAQ,CACN,KAAM,QACR,CACF,EACA,CACE,KAAM,OACN,YAAa,mBACb,SAAU,GACV,OAAQA,EACR,MAAO,OACP,QAAS,EACX,EACA,CACE,KAAM,OACN,YAAa,YACb,SAAU,GACV,OAAQA,EACR,MAAO,OACP,QAAS,EACX,EACA,CACE,KAAM,QACN,YAAa,aACb,SAAU,GACV,OAAQ,CACN,KAAM,SACR,CACF,EACA,CACE,KAAM,SACN,YAAa,gBACb,SAAU,GACV,OAAQ,CACN,KAAM,SACR,CACF,EACA,CACE,KAAM,OACN,YAAa,cACb,SAAU,GACV,OAAQ,CACN,KAAM,SACR,CACF,CACF,CACF,CAEO,MAAMC,EAAuD,CAClE,IAAMC,EAA8B,CAAC,EAC/BC,EAAmC,CAAC,EACpCC,EAA+B,CAAC,EAChCC,EAAQ,IAAIC,EAElB,KAAK,YAAYJ,EAAQD,EAAM,QAAaA,EAAM,MAAS,EAC3D,KAAK,UAAUC,EAAQC,EAAWF,EAAM,IAAO,EAC/C,KAAK,WAAWG,EAAUH,EAAM,IAAO,EACvC,KAAK,YAAYI,EAAOJ,EAAM,CAAI,EAElC,GAAM,CAAE,MAAAM,EAAO,OAAAC,CAAO,EAAI,KAAK,YAAYP,EAAM,MAAUA,EAAM,OAAWA,EAAM,IAAO,EAEzF,MAAO,CACL,OAAAC,EACA,UAAAC,EACA,MAAOC,EACP,MAAOC,EAAM,MAAM,EACnB,MAAAE,EACA,OAAAC,CACF,CACF,CAEU,YAAYN,EAA6BO,EAAoC,CACrF,GAAI,CAACA,EACH,QAEmB,MAAM,QAAQA,CAAS,EAAIA,EAAYA,EAAU,MAAM,GAAG,GAElE,QAAQC,GAAS,CAC5BR,EAAO,KAAK,CACV,MAAOQ,EAAM,MAAM,GAAG,CACxB,CAAC,CACH,CAAC,CACH,CAEU,UAAUC,EAAoCR,EAAkCS,EAAkC,CAC1H,GAAI,CAACA,EACH,OAEF,GAAI,MAAM,QAAQA,CAAO,EAAG,CAC1BA,EAAQ,QAAQC,GAAS,KAAK,UAAUF,EAAeR,EAAWU,CAAK,CAAC,EACxE,MACF,CAEA,IAAMC,EAAOF,EAAQ,SAAS,EAExB,CAACF,EAAOR,CAAM,EAAIY,EAAK,MAAM,KAAM,CAAC,EACpCC,EAAYL,EAAM,MAAM,GAAG,EAEjCP,EAAU,KAAK,CACb,MAAOY,CACT,CAAC,EAEGb,GACmBA,EAAO,MAAM,GAAG,EAExB,QAAQ,GAAK,CACxBS,EAAc,KAAK,CACjB,MAAO,CAAC,GAAGI,EAAW,CAAC,CACzB,CAAC,CACH,CAAC,CAEL,CAEU,WAAWX,EAA8BY,EAAmC,CACpF,GAAI,CAACA,EACH,OAEF,GAAI,MAAM,QAAQA,CAAQ,EAAG,CAC3BA,EAAS,QAAQH,GAAS,KAAK,WAAWT,EAAUS,CAAK,CAAC,EAC1D,MACF,CAEA,GAAM,CAACH,EAAOO,CAAS,EAAID,EAAS,MAAM,GAAG,EAE7CZ,EAAS,KAAK,CACZ,MAAOM,EAAM,MAAM,GAAG,EACtB,MAAOO,GAAW,YAAY,IAAM,OAAS,OAAS,KACxD,CAAC,CACH,CAEU,YAAYC,EAA4C,CAIhE,GAHI,MAAM,QAAQA,CAAG,IACnBA,EAAMA,EAAI,OAAS,EAAIA,EAAI,CAAC,EAAI,QAE9B,CAACC,EAAQD,CAAG,EACd,OAEF,IAAME,EAAM,CAACF,EAEb,OAAO,MAAME,CAAG,EAAI,OAAYA,CAClC,CAEU,YAAYC,EAA6BC,EAA8BC,EAA4B,CAC3G,IAAMhB,EAAQ,KAAK,YAAYc,CAAQ,EACnCb,EAAS,KAAK,YAAYc,CAAS,EAEvC,GAAIf,GAAS,CAACC,EAAQ,CACpB,IAAMgB,EAAO,KAAK,YAAYD,CAAO,EAEjCC,IACFhB,EAASD,EAAQiB,EACrB,CAEA,MAAO,CAAE,MAAAjB,EAAO,OAAAC,CAAO,CACzB,CAEU,YAAYiB,EAAoCC,EAAoC,CAI5F,GAHI,MAAM,QAAQA,CAAS,IACzBA,EAAYA,EAAU,OAAS,EAAIA,EAAU,CAAC,EAAI,QAEhD,CAACA,EACH,OAEF,IAAMC,EAAqB,KAAK,MAAMD,CAAS,EAE/CE,EAAgBH,EAASE,CAAM,CACjC,CAEF","names":["ParsedRequestWhereBuilder","_ParsedRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","isValid","value","__name","parseCrudSearch","builder","cond","context","keys","$or","$and","innerFields","andBuilder","c","parseCrudSearchFields","orBuilder","__name","fields","name","field","isValid","fieldPath","f","parseCrudSearchField","operatorMap","key","value","val","CrudRequestParser","__name","arraySchema","query","select","relations","ordering","where","ParsedRequestWhereBuilder","limit","offset","rawSelect","field","requestFields","rawJoin","value","join","fieldPath","rawOrder","direction","raw","isValid","num","rawLimit","rawOffset","rawPage","page","builder","rawSearch","search","parseCrudSearch"]}
|
1
|
+
{"version":3,"sources":["../../../src/utils/functions.ts","../../../src/utils/where.ts","../../../src/utils/crud-request-where.builder.ts","../../../src/parsers/crud/parseCrudSearch.ts","../../../src/parsers/crud/crud-request.parser.ts"],"sourcesContent":["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 ensureEmpty(fieldName: string, data: any) {\r\n if (isValid(data) && data !== true)\r\n throw new Error(`${fieldName} must be true, null or undefined`);\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\nexport function getOffset(offset: number | undefined, limit?: number, page?: number): number {\r\n return offset ?? (limit && page ? limit * page : 0);\r\n}\r\n","import { CrudRequestWhereField, CrudRequestWhereOperator } from '../models/crud-request-where';\r\nimport { ensureArray, ensureEmpty, ensurePrimitive } from './functions';\r\n\r\nexport enum WhereOperatorValueType {\r\n PRIMITIVE = 'primitive',\r\n ARRAY = 'array',\r\n EMPTY = 'empty'\r\n}\r\n\r\nconst operatorValueTypes: Record<CrudRequestWhereOperator, WhereOperatorValueType> = {\r\n [CrudRequestWhereOperator.EQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LT]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.GTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.LTE]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.NOT_IN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.BETWEEN]: WhereOperatorValueType.ARRAY,\r\n [CrudRequestWhereOperator.IS_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.NOT_NULL]: WhereOperatorValueType.EMPTY,\r\n [CrudRequestWhereOperator.EQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NEQ_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.STARTS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.ENDS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_CONTAINS_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n [CrudRequestWhereOperator.NOT_IN_LOWER]: WhereOperatorValueType.PRIMITIVE,\r\n};\r\n\r\nexport function getWhereOperatorValueType(op: CrudRequestWhereOperator): WhereOperatorValueType {\r\n return operatorValueTypes[op];\r\n}\r\n\r\nexport function validateWhereField(where: CrudRequestWhereField): void {\r\n const type = operatorValueTypes[where.operator];\r\n const name = 'The value of the operator ' + where.operator;\r\n\r\n if (type === WhereOperatorValueType.PRIMITIVE) {\r\n ensurePrimitive(name, where.value);\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.ARRAY) {\r\n const items = ensureArray(name, where.value);\r\n\r\n items.forEach(item => ensurePrimitive(name + ' children', item));\r\n\r\n return;\r\n }\r\n\r\n if (type === WhereOperatorValueType.EMPTY) {\r\n ensureEmpty(name, where.value);\r\n\r\n return;\r\n }\r\n}\r\n","import {\r\n CrudRequestWhere,\r\n CrudRequestWhereAND,\r\n CrudRequestWhereField,\r\n CrudRequestWhereOperator,\r\n CrudRequestWhereOR,\r\n CrudRequestWhereValueType\r\n} from '../models/crud-request-where';\r\nimport { validateWhereField } from './where';\r\n\r\n/**\r\n * A helper class that makes it easier to create a CrudRequestWhere\r\n */\r\nexport class CrudRequestWhereBuilder {\r\n\r\n constructor(\r\n private readonly where: CrudRequestWhereAND | CrudRequestWhereOR = { and: [] },\r\n private readonly parent?: CrudRequestWhereBuilder,\r\n ) { }\r\n\r\n /**\r\n * Adds an AND bracket\r\n */\r\n public addAnd(): CrudRequestWhereBuilder {\r\n if (!this.where.or) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereAND = { and: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.or.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds an OR bracket\r\n */\r\n public addOr(): CrudRequestWhereBuilder {\r\n if (!this.where.and) {\r\n return this;\r\n }\r\n\r\n const inside: CrudRequestWhereOR = { or: [] };\r\n const builder = new CrudRequestWhereBuilder(inside, this);\r\n\r\n this.where.and.push(inside);\r\n\r\n return builder;\r\n }\r\n\r\n /**\r\n * Adds a field comparison\r\n *\r\n * @param field The field path\r\n * @param operator The comparison operator\r\n * @param value The value to compare\r\n */\r\n public addField(\r\n field: string[],\r\n operator: CrudRequestWhereOperator,\r\n value: CrudRequestWhereValueType | CrudRequestWhereValueType[],\r\n ): CrudRequestWhereBuilder {\r\n const whereField: CrudRequestWhereField = {\r\n field,\r\n operator,\r\n value,\r\n };\r\n\r\n validateWhereField(whereField);\r\n\r\n if (this.where.and) {\r\n this.where.and.push(whereField);\r\n } else if (this.where.or) {\r\n this.where.or.push(whereField);\r\n } else {\r\n throw new Error('Invalid where');\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Constructs the final where condition\r\n */\r\n public build(): CrudRequestWhere {\r\n if (this.parent) {\r\n return this.parent.build();\r\n }\r\n\r\n return this.where;\r\n }\r\n\r\n}\r\n","import { CrudRequestWhereBuilder } from '../../utils/crud-request-where.builder';\r\nimport { CrudRequestWhereOperator } from '../../models/crud-request-where';\r\nimport { SCondition, SField, SFieldOperator, SFields } from './types';\r\nimport { isValid } from '../../utils/functions';\r\n\r\ntype OperatorType = Exclude<Exclude<keyof SFieldOperator, '$or'>, '$and'>;\r\n\r\n// Operator\r\n// { field: { $gte: 10 } }\r\nconst operatorMap: Record<OperatorType, CrudRequestWhereOperator> = {\r\n $eq: CrudRequestWhereOperator.EQ,\r\n $ne: CrudRequestWhereOperator.NEQ,\r\n $gt: CrudRequestWhereOperator.GT,\r\n $lt: CrudRequestWhereOperator.LT,\r\n $gte: CrudRequestWhereOperator.GTE,\r\n $lte: CrudRequestWhereOperator.LTE,\r\n $starts: CrudRequestWhereOperator.STARTS,\r\n $ends: CrudRequestWhereOperator.ENDS,\r\n $cont: CrudRequestWhereOperator.CONTAINS,\r\n $excl: CrudRequestWhereOperator.NOT_CONTAINS,\r\n $in: CrudRequestWhereOperator.IN,\r\n $notin: CrudRequestWhereOperator.NOT_IN,\r\n $between: CrudRequestWhereOperator.BETWEEN,\r\n $isnull: CrudRequestWhereOperator.IS_NULL,\r\n $notnull: CrudRequestWhereOperator.NOT_NULL,\r\n $eqL: CrudRequestWhereOperator.EQ_LOWER,\r\n $neL: CrudRequestWhereOperator.NEQ_LOWER,\r\n $startsL: CrudRequestWhereOperator.STARTS_LOWER,\r\n $endsL: CrudRequestWhereOperator.ENDS_LOWER,\r\n $contL: CrudRequestWhereOperator.CONTAINS_LOWER,\r\n $exclL: CrudRequestWhereOperator.NOT_CONTAINS_LOWER,\r\n $inL: CrudRequestWhereOperator.IN_LOWER,\r\n $notinL: CrudRequestWhereOperator.NOT_IN_LOWER,\r\n};\r\n\r\n/**\r\n * Parses a crud request condition and inserts into a CrudRequestWhereBuilder\r\n *\r\n * @param builder The builder that the condition will be inserted to\r\n * @param cond The condition that must be parsed\r\n * @param context The field context\r\n */\r\nexport function parseCrudSearch(builder: CrudRequestWhereBuilder, cond: SCondition, context: string[] = []) {\r\n if (typeof cond !== 'object')\r\n return;\r\n\r\n const keys = Object.keys(cond);\r\n\r\n if (keys.length === 0)\r\n return;\r\n\r\n const { $or, $and, ...innerFields } = cond;\r\n\r\n // { $and: [..., ...] }\r\n if ($and) {\r\n const andBuilder = $and.length > 1 || keys.length > 1 ? builder.addAnd() : builder;\r\n\r\n $and.forEach(c => parseCrudSearch(andBuilder, c, context));\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n return;\r\n }\r\n\r\n // { $or: [..., ...] }\r\n if ($or && keys.length === 1) {\r\n const orBuilder = $or.length > 1 ? builder.addOr() : builder;\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n // { $or: [...], field1: ..., field2: ... }\r\n if ($or) {\r\n const andBuilder = builder.addAnd();\r\n const orBuilder = $or.length > 1 ? andBuilder.addOr() : andBuilder;\r\n\r\n parseCrudSearchFields(andBuilder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n\r\n $or.forEach(c => parseCrudSearch(orBuilder, c, context));\r\n\r\n return;\r\n }\r\n\r\n if (keys.length > 1)\r\n builder = builder.addAnd();\r\n\r\n parseCrudSearchFields(builder, innerFields as Omit<Omit<SFields, '$or'>, '$and'>, context);\r\n}\r\n\r\n/**\r\n * Parses an object from the crud request full of fields\r\n *\r\n * @param builder The builder\r\n * @param fields The fields object\r\n * @param context The context\r\n */\r\nfunction parseCrudSearchFields(builder: CrudRequestWhereBuilder, fields: Omit<Omit<SFields, '$or'>, '$and'>, context: string[]): void {\r\n // { name: 'John', age: { $gte: 18 }, 'posts.name': { $cont: 'Greetings' } }\r\n for (const name of Object.keys(fields)) {\r\n const field = fields[name];\r\n\r\n if (!isValid(field))\r\n continue;\r\n\r\n const fieldPath = [...context, ...name.split('.')];\r\n\r\n // { name: [{ $or: [...] }] }\r\n if (Array.isArray(field)) {\r\n field.forEach(f => parseCrudSearch(builder, f, fieldPath));\r\n continue;\r\n }\r\n\r\n parseCrudSearchField(builder, fieldPath, field);\r\n }\r\n}\r\n\r\n/**\r\n * Parses a single field\r\n *\r\n * @param builder The builder\r\n * @param name The name path\r\n * @param field The field value or operator\r\n */\r\nfunction parseCrudSearchField(builder: CrudRequestWhereBuilder, name: string[], field: SField): void {\r\n // Primitive Value\r\n // { field: 'text', field2: 12, field3: true }\r\n if (typeof field !== 'object') {\r\n builder.addField(name, CrudRequestWhereOperator.EQ, field);\r\n return;\r\n }\r\n\r\n const keys = Object.keys(field) as OperatorType[];\r\n\r\n for (let key of keys) {\r\n if (!operatorMap[key])\r\n continue;\r\n\r\n builder.addField(name, operatorMap[key], field[key]);\r\n }\r\n\r\n if (field.$or) {\r\n parseCrudSearchField(builder.addOr(), name, field.$or);\r\n }\r\n}\r\n\r\nexport function parseCrudFilters(builder: CrudRequestWhereBuilder, andFilters: string[], orFilters: string[]): void {\r\n // Based on rules from https://github.com/nestjsx/crud/wiki/Requests#or\r\n // \"If present both or and filter in any amount (one or miltiple each) then both interpreted\r\n // as a combitation of AND conditions and compared with each other by OR condition\"\r\n // \"If there are one or and one filter then it will be interpreted as OR condition\"\r\n if (andFilters.length > 0 && orFilters.length > 0) {\r\n const or = builder.addOr();\r\n\r\n parseCrudFilter(or.addAnd(), andFilters);\r\n parseCrudFilter(or.addAnd(), orFilters);\r\n\r\n return;\r\n }\r\n\r\n // \"If there are multiple or present (without filter) then it will be interpreted as a compination of OR conditions\"\r\n if (orFilters.length > 0) {\r\n parseCrudFilter(builder.addOr(), orFilters);\r\n\r\n return;\r\n }\r\n\r\n if (andFilters.length > 0) {\r\n parseCrudFilter(builder.addAnd(), andFilters);\r\n\r\n return;\r\n }\r\n}\r\n\r\nfunction parseCrudFilter(builder: CrudRequestWhereBuilder, rawFilters: string[]): void {\r\n for (const rawFilter of rawFilters) {\r\n const [name, op, value] = rawFilter.split('||', 3);\r\n const operator = operatorMap[op as OperatorType];\r\n\r\n if (!operator)\r\n continue;\r\n\r\n builder.addField(name.split('.'), operator, value);\r\n }\r\n}\r\n","import { RequestParamValue, RequestParser } from '../../models/request-parser';\r\nimport { CrudRequest, CrudRequestOrder, CrudRequestRelation, ParsedRequestSelect } from '../../models/crud-request';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\nimport { CrudRequestWhereBuilder } from '../../utils/crud-request-where.builder';\r\nimport { parseCrudFilters, parseCrudSearch } from './parseCrudSearch';\r\nimport { isValid } from '../../utils/functions';\r\nimport { SCondition } from './types';\r\n\r\nexport interface CrudRequestParserOptions {\r\n /**\r\n * Whether the `fields` and `select` parameters will be disabled\r\n */\r\n disableSelect?: boolean;\r\n\r\n /**\r\n * Whether the `s`, `filter` and `or` parameters will be disabled\r\n */\r\n disableWhere?: boolean;\r\n\r\n /**\r\n * Whether the `sort` parameter will be disabled\r\n */\r\n disableOrder?: boolean;\r\n\r\n /**\r\n * Whether the `join` parameter will be disabled\r\n */\r\n disableRelations?: boolean;\r\n\r\n /**\r\n * Whether the `limit` and `per_page` parameters will be disabled\r\n */\r\n disableLimit?: boolean;\r\n\r\n /**\r\n * Whether the `offset` and `page` parameters will be disabled\r\n */\r\n disableOffset?: boolean;\r\n}\r\n\r\n/**\r\n * Parses a request based on the @nestjsx/crud format.\r\n */\r\nexport class CrudRequestParser implements RequestParser {\r\n\r\n constructor(\r\n protected readonly options: CrudRequestParserOptions = {},\r\n ) {\r\n }\r\n\r\n public getOpenAPIParameters(): OpenAPIParameter[] {\r\n // We'll not add the `per_page`, `filter`, `or` and `select` parameters here\r\n // as those are only kept for compatibility purposes and not recommended.\r\n // TODO improve docs\r\n\r\n const arraySchema = {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n },\r\n };\r\n\r\n const params: OpenAPIParameter[] = [];\r\n\r\n if (!this.options.disableSelect) {\r\n params.push({\r\n name: 'fields',\r\n description: 'Selects resource fields',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: false,\r\n });\r\n }\r\n\r\n if (!this.options.disableWhere) {\r\n params.push({\r\n name: 's',\r\n description: 'Search condition',\r\n required: false,\r\n schema: {\r\n type: 'string',\r\n },\r\n });\r\n }\r\n\r\n if (!this.options.disableOrder) {\r\n params.push({\r\n name: 'sort',\r\n description: 'Sorting',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n });\r\n }\r\n\r\n if (!this.options.disableRelations) {\r\n params.push({\r\n name: 'join',\r\n description: 'Relations',\r\n required: false,\r\n schema: arraySchema,\r\n style: 'form',\r\n explode: true,\r\n });\r\n }\r\n\r\n if (!this.options.disableLimit) {\r\n params.push({\r\n name: 'limit',\r\n description: 'Page limit',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n });\r\n }\r\n\r\n if (!this.options.disableOffset) {\r\n params.push({\r\n name: 'offset',\r\n description: 'Offset amount',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n }, {\r\n name: 'page',\r\n description: 'Page number',\r\n required: false,\r\n schema: {\r\n type: 'integer',\r\n },\r\n });\r\n }\r\n\r\n return params;\r\n }\r\n\r\n public parse(query: Record<string, RequestParamValue>): CrudRequest {\r\n const select: ParsedRequestSelect = [];\r\n const relations: CrudRequestRelation[] = [];\r\n const ordering: CrudRequestOrder[] = [];\r\n const where = new CrudRequestWhereBuilder();\r\n\r\n if (!this.options.disableSelect)\r\n this.parseSelect(select, query['fields'] || query['select']);\r\n\r\n if (!this.options.disableRelations)\r\n this.parseJoin(select, relations, query['join']);\r\n\r\n if (!this.options.disableOrder)\r\n this.parseOrder(ordering, query['sort']);\r\n\r\n if (!this.options.disableWhere)\r\n this.parseSearch(where, query['s'], query['filter'], query['or']);\r\n\r\n const limit = this.options.disableLimit ? undefined : this.parseNumber(query['limit'] || query['per_page']);\r\n const offset = this.options.disableOffset ? undefined : this.parseNumber(query['offset']);\r\n const page = this.options.disableOffset ? undefined : this.parseNumber(query['page']);\r\n\r\n return {\r\n select,\r\n relations,\r\n order: ordering,\r\n where: where.build(),\r\n limit,\r\n offset,\r\n page,\r\n };\r\n }\r\n\r\n protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void {\r\n if (!rawSelect)\r\n return;\r\n\r\n const selectFields = Array.isArray(rawSelect) ? rawSelect : rawSelect.split(',');\r\n\r\n selectFields.forEach(field => {\r\n select.push({\r\n field: field.split('.'),\r\n });\r\n });\r\n }\r\n\r\n protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void {\r\n if (!rawJoin)\r\n return;\r\n\r\n if (Array.isArray(rawJoin)) {\r\n rawJoin.forEach(value => this.parseJoin(requestFields, relations, value));\r\n return;\r\n }\r\n\r\n const join = rawJoin.toString();\r\n\r\n const [field, select] = join.split('||', 2);\r\n const fieldPath = field.split('.');\r\n\r\n relations.push({\r\n field: fieldPath,\r\n });\r\n\r\n if (select) {\r\n const selectFields = select.split(',');\r\n\r\n selectFields.forEach(f => {\r\n requestFields.push({\r\n field: [...fieldPath, f],\r\n });\r\n });\r\n }\r\n }\r\n\r\n protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void {\r\n if (!rawOrder)\r\n return;\r\n\r\n if (Array.isArray(rawOrder)) {\r\n rawOrder.forEach(value => this.parseOrder(ordering, value));\r\n return;\r\n }\r\n\r\n const [field, direction] = rawOrder.split(',');\r\n\r\n ordering.push({\r\n field: field.split('.'),\r\n order: direction?.toUpperCase() === 'DESC' ? 'DESC' : 'ASC',\r\n });\r\n }\r\n\r\n protected parseNumber(raw: RequestParamValue): number | undefined {\r\n if (Array.isArray(raw))\r\n raw = raw.length > 0 ? raw[0] : undefined;\r\n\r\n if (!isValid(raw))\r\n return undefined;\r\n\r\n const num = +raw;\r\n\r\n return isNaN(num) ? undefined : num;\r\n }\r\n\r\n protected parseSearch(builder: CrudRequestWhereBuilder, rawSearch: RequestParamValue, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n if (Array.isArray(rawSearch))\r\n rawSearch = rawSearch.length > 0 ? rawSearch[0] : undefined;\r\n\r\n if (!rawSearch) {\r\n // In case the search is not defined, we'll read the filter and or parameters\r\n this.parseFilter(builder, rawFilter, rawOr);\r\n return;\r\n }\r\n\r\n const search: SCondition = JSON.parse(rawSearch);\r\n\r\n parseCrudSearch(builder, search);\r\n }\r\n\r\n protected parseFilter(builder: CrudRequestWhereBuilder, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n let andFilters: string[] = [];\r\n let orFilters: string[] = [];\r\n\r\n if (rawFilter)\r\n andFilters = Array.isArray(rawFilter) ? rawFilter : [rawFilter];\r\n\r\n if (rawOr)\r\n orFilters = Array.isArray(rawOr) ? rawOr : [rawOr];\r\n\r\n parseCrudFilters(builder, andFilters, orFilters);\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["ensurePrimitive","fieldName","data","__name","ensureArray","minLength","ensureEmpty","isValid","value","operatorValueTypes","validateWhereField","where","type","operatorValueTypes","name","ensurePrimitive","ensureArray","item","ensureEmpty","__name","CrudRequestWhereBuilder","_CrudRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","validateWhereField","operatorMap","parseCrudSearch","builder","cond","context","keys","$or","$and","innerFields","andBuilder","c","parseCrudSearchFields","orBuilder","__name","fields","name","field","isValid","fieldPath","f","parseCrudSearchField","key","parseCrudFilters","andFilters","orFilters","or","parseCrudFilter","rawFilters","rawFilter","op","value","operator","CrudRequestParser","options","__name","arraySchema","params","query","select","relations","ordering","where","CrudRequestWhereBuilder","limit","offset","page","rawSelect","field","requestFields","rawJoin","value","join","fieldPath","f","rawOrder","direction","raw","isValid","num","builder","rawSearch","rawFilter","rawOr","search","parseCrudSearch","andFilters","orFilters","parseCrudFilters"]}
|