crud-query-parser 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -100,7 +100,7 @@ import { ensureCondition } from 'crud-query-parser/filters';
100
100
 
101
101
  crudRequest = ensureCondition(crudRequest, {
102
102
  field: ['isActive'],
103
- operator: ParsedRequestWhereOperator.EQ,
103
+ operator: CrudRequestWhereOperator.EQ,
104
104
  value: true,
105
105
  });
106
106
  ```
@@ -0,0 +1,18 @@
1
+ import * as _nestjs_common from '@nestjs/common';
2
+ import { Type } from '@nestjs/common';
3
+ import { a as RequestParser } from '../../request-parser-WaQBZsYG.mjs';
4
+ import '../../crud-request-CvDKp6Iy.mjs';
5
+
6
+ declare const CRUD_QUERY_PARSER = "crud-query-parser";
7
+ /**
8
+ * Defines which parser will be used for parsing the request
9
+ *
10
+ * @param parserContract The parser that will be used
11
+ */
12
+ declare function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator;
13
+ /**
14
+ * A parameter decorator that converts the query string into a `CrudRequest` object
15
+ */
16
+ declare const ParseCrudRequest: (...dataOrPipes: (RequestParser | Type<RequestParser> | _nestjs_common.PipeTransform<any, any> | Type<_nestjs_common.PipeTransform<any, any>>)[]) => ParameterDecorator;
17
+
18
+ export { CRUD_QUERY_PARSER, Crud, ParseCrudRequest };
@@ -0,0 +1,18 @@
1
+ import * as _nestjs_common from '@nestjs/common';
2
+ import { Type } from '@nestjs/common';
3
+ import { a as RequestParser } from '../../request-parser-B-fK5GnP.js';
4
+ import '../../crud-request-CvDKp6Iy.js';
5
+
6
+ declare const CRUD_QUERY_PARSER = "crud-query-parser";
7
+ /**
8
+ * Defines which parser will be used for parsing the request
9
+ *
10
+ * @param parserContract The parser that will be used
11
+ */
12
+ declare function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator;
13
+ /**
14
+ * A parameter decorator that converts the query string into a `CrudRequest` object
15
+ */
16
+ declare const ParseCrudRequest: (...dataOrPipes: (RequestParser | Type<RequestParser> | _nestjs_common.PipeTransform<any, any> | Type<_nestjs_common.PipeTransform<any, any>>)[]) => ParameterDecorator;
17
+
18
+ export { CRUD_QUERY_PARSER, Crud, ParseCrudRequest };
@@ -0,0 +1,2 @@
1
+ "use strict";var u=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var a=(e,r)=>u(e,"name",{value:r,configurable:!0});var q=(e,r)=>{for(var t in r)u(e,t,{get:r[t],enumerable:!0})},R=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of P(r))!m.call(e,n)&&n!==t&&u(e,n,{get:()=>r[n],enumerable:!(o=f(r,n))||o.enumerable});return e};var x=e=>R(u({},"__esModule",{value:!0}),e);var T={};q(T,{CRUD_QUERY_PARSER:()=>i,Crud:()=>y,ParseCrudRequest:()=>C});module.exports=x(T);var s=require("@nestjs/common");var c=(()=>{try{return require("@nestjs/swagger").ApiQuery}catch{return r=>()=>{}}})();function p(e){if(typeof e=="function")return new e;if(typeof e=="object")return e}a(p,"createInstance");function d(e,r){let t=[e.getHandler(),e.getClass()];for(let o of t){let n=Reflect.getMetadata(r,o);if(n)return n}}a(d,"getMetadataFromContext");var i="crud-query-parser";function y(e){let r=p(e);if(!r)throw new Error("The request parser passed to @Crud() is invalid");let t=r.getOpenAPIParameters().map(o=>c(o));return(0,s.applyDecorators)((0,s.SetMetadata)(i,r),...t)}a(y,"Crud");var C=(0,s.createParamDecorator)((e,r)=>{let t=r.switchToHttp().getRequest(),o=e?p(e):d(r,i);return o?o.parse(t.query):(new s.Logger("ParseCrudRequest").warn("No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()"),{where:{and:[]},select:[],order:[],relations:[]})});0&&(module.exports={CRUD_QUERY_PARSER,Crud,ParseCrudRequest});
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/helpers/nestjs/index.ts","../../../src/helpers/nestjs/decorators.ts","../../../src/helpers/nestjs/utils.ts"],"sourcesContent":["\r\nexport * from './decorators';\r\n","import { applyDecorators, createParamDecorator, ExecutionContext, Logger, SetMetadata, Type } from '@nestjs/common';\r\nimport { RequestParser } from '../../models/request-parser';\r\nimport { ApiQuery, createInstance, getMetadataFromContext } from './utils';\r\n\r\nexport const CRUD_QUERY_PARSER = 'crud-query-parser';\r\n\r\n/**\r\n * Defines which parser will be used for parsing the request\r\n *\r\n * @param parserContract The parser that will be used\r\n */\r\nexport function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator {\r\n const parser = createInstance(parserContract);\r\n\r\n if (!parser) {\r\n throw new Error('The request parser passed to @Crud() is invalid');\r\n }\r\n\r\n const openApi = parser.getOpenAPIParameters().map(param => ApiQuery(param));\r\n\r\n return applyDecorators(\r\n SetMetadata(CRUD_QUERY_PARSER, parser),\r\n ...openApi,\r\n );\r\n}\r\n\r\n/**\r\n * A parameter decorator that converts the query string into a `CrudRequest` object\r\n */\r\nexport const ParseCrudRequest = createParamDecorator<RequestParser | Type<RequestParser>>(\r\n (data: RequestParser | Type<RequestParser>, ctx: ExecutionContext) => {\r\n const request = ctx.switchToHttp().getRequest();\r\n const parser = data ? createInstance(data) : getMetadataFromContext<RequestParser>(ctx, CRUD_QUERY_PARSER);\r\n\r\n if (!parser) {\r\n new Logger('ParseCrudRequest').warn(`No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()`);\r\n\r\n return {\r\n where: { and: [] },\r\n select: [],\r\n order: [],\r\n relations: [],\r\n };\r\n }\r\n\r\n return parser.parse(request.query);\r\n },\r\n);\r\n\r\n","import { ExecutionContext, Type } from '@nestjs/common';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\n\r\nexport const ApiQuery = (() => {\r\n try {\r\n return require('@nestjs/swagger').ApiQuery;\r\n } catch (error) {\r\n return (options: OpenAPIParameter): MethodDecorator => {\r\n return () => {};\r\n };\r\n }\r\n})();\r\n\r\nexport function createInstance<T>(data: T | Type<T> | undefined): T | undefined {\r\n if (typeof data === 'function')\r\n return new data();\r\n\r\n if (typeof data === 'object')\r\n return data as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function getMetadataFromContext<T>(context: ExecutionContext, key: string): T | undefined {\r\n const targets = [\r\n context.getHandler(),\r\n context.getClass(),\r\n ];\r\n\r\n for (const target of targets) {\r\n const data = Reflect.getMetadata(key, target);\r\n\r\n if (data)\r\n return data;\r\n }\r\n\r\n return undefined;\r\n}\r\n"],"mappings":"4dAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,uBAAAE,EAAA,SAAAC,EAAA,qBAAAC,IAAA,eAAAC,EAAAL,GCAA,IAAAM,EAAmG,0BCG5F,IAAMC,GAAY,IAAM,CAC7B,GAAI,CACF,MAAO,SAAQ,iBAAiB,EAAE,QACpC,MAAgB,CACd,OAAQC,GACC,IAAM,CAAC,CAElB,CACF,GAAG,EAEI,SAASC,EAAkBC,EAA8C,CAC9E,GAAI,OAAOA,GAAS,WAClB,OAAO,IAAIA,EAEb,GAAI,OAAOA,GAAS,SAClB,OAAOA,CAGX,CARgBC,EAAAF,EAAA,kBAUT,SAASG,EAA0BC,EAA2BC,EAA4B,CAC/F,IAAMC,EAAU,CACdF,EAAQ,WAAW,EACnBA,EAAQ,SAAS,CACnB,EAEA,QAAWG,KAAUD,EAAS,CAC5B,IAAML,EAAO,QAAQ,YAAYI,EAAKE,CAAM,EAE5C,GAAIN,EACF,OAAOA,CACX,CAGF,CAdgBC,EAAAC,EAAA,0BDnBT,IAAMK,EAAoB,oBAO1B,SAASC,EAAKC,EAAuF,CAC1G,IAAMC,EAASC,EAAeF,CAAc,EAE5C,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,iDAAiD,EAGnE,IAAME,EAAUF,EAAO,qBAAqB,EAAE,IAAIG,GAASC,EAASD,CAAK,CAAC,EAE1E,SAAO,sBACL,eAAYN,EAAmBG,CAAM,EACrC,GAAGE,CACL,CACF,CAbgBG,EAAAP,EAAA,QAkBT,IAAMQ,KAAmB,wBAC9B,CAACC,EAA2CC,IAA0B,CACpE,IAAMC,EAAUD,EAAI,aAAa,EAAE,WAAW,EACxCR,EAASO,EAAON,EAAeM,CAAI,EAAIG,EAAsCF,EAAKX,CAAiB,EAEzG,OAAKG,EAWEA,EAAO,MAAMS,EAAQ,KAAK,GAV/B,IAAI,SAAO,kBAAkB,EAAE,KAAK,yFAAyF,EAEtH,CACL,MAAO,CAAE,IAAK,CAAC,CAAE,EACjB,OAAQ,CAAC,EACT,MAAO,CAAC,EACR,UAAW,CAAC,CACd,EAIJ,CACF","names":["nestjs_exports","__export","CRUD_QUERY_PARSER","Crud","ParseCrudRequest","__toCommonJS","import_common","ApiQuery","options","createInstance","data","__name","getMetadataFromContext","context","key","targets","target","CRUD_QUERY_PARSER","Crud","parserContract","parser","createInstance","openApi","param","ApiQuery","__name","ParseCrudRequest","data","ctx","request","getMetadataFromContext"]}
@@ -0,0 +1,2 @@
1
+ var c=Object.defineProperty;var n=(e,r)=>c(e,"name",{value:r,configurable:!0}),d=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(r,t)=>(typeof require<"u"?require:r)[t]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});import{applyDecorators as f,createParamDecorator as P,Logger as m,SetMetadata as q}from"@nestjs/common";var u=(()=>{try{return d("@nestjs/swagger").ApiQuery}catch{return r=>()=>{}}})();function s(e){if(typeof e=="function")return new e;if(typeof e=="object")return e}n(s,"createInstance");function p(e,r){let t=[e.getHandler(),e.getClass()];for(let o of t){let a=Reflect.getMetadata(r,o);if(a)return a}}n(p,"getMetadataFromContext");var i="crud-query-parser";function h(e){let r=s(e);if(!r)throw new Error("The request parser passed to @Crud() is invalid");let t=r.getOpenAPIParameters().map(o=>u(o));return f(q(i,r),...t)}n(h,"Crud");var w=P((e,r)=>{let t=r.switchToHttp().getRequest(),o=e?s(e):p(r,i);return o?o.parse(t.query):(new m("ParseCrudRequest").warn("No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()"),{where:{and:[]},select:[],order:[],relations:[]})});export{i as CRUD_QUERY_PARSER,h as Crud,w as ParseCrudRequest};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/helpers/nestjs/decorators.ts","../../../src/helpers/nestjs/utils.ts"],"sourcesContent":["import { applyDecorators, createParamDecorator, ExecutionContext, Logger, SetMetadata, Type } from '@nestjs/common';\r\nimport { RequestParser } from '../../models/request-parser';\r\nimport { ApiQuery, createInstance, getMetadataFromContext } from './utils';\r\n\r\nexport const CRUD_QUERY_PARSER = 'crud-query-parser';\r\n\r\n/**\r\n * Defines which parser will be used for parsing the request\r\n *\r\n * @param parserContract The parser that will be used\r\n */\r\nexport function Crud(parserContract: RequestParser | Type<RequestParser>): MethodDecorator & ClassDecorator {\r\n const parser = createInstance(parserContract);\r\n\r\n if (!parser) {\r\n throw new Error('The request parser passed to @Crud() is invalid');\r\n }\r\n\r\n const openApi = parser.getOpenAPIParameters().map(param => ApiQuery(param));\r\n\r\n return applyDecorators(\r\n SetMetadata(CRUD_QUERY_PARSER, parser),\r\n ...openApi,\r\n );\r\n}\r\n\r\n/**\r\n * A parameter decorator that converts the query string into a `CrudRequest` object\r\n */\r\nexport const ParseCrudRequest = createParamDecorator<RequestParser | Type<RequestParser>>(\r\n (data: RequestParser | Type<RequestParser>, ctx: ExecutionContext) => {\r\n const request = ctx.switchToHttp().getRequest();\r\n const parser = data ? createInstance(data) : getMetadataFromContext<RequestParser>(ctx, CRUD_QUERY_PARSER);\r\n\r\n if (!parser) {\r\n new Logger('ParseCrudRequest').warn(`No crud request parser found. Please, define one with @Crud() or pass to @CrudRequest()`);\r\n\r\n return {\r\n where: { and: [] },\r\n select: [],\r\n order: [],\r\n relations: [],\r\n };\r\n }\r\n\r\n return parser.parse(request.query);\r\n },\r\n);\r\n\r\n","import { ExecutionContext, Type } from '@nestjs/common';\r\nimport { OpenAPIParameter } from '../../models/openapi-parameter';\r\n\r\nexport const ApiQuery = (() => {\r\n try {\r\n return require('@nestjs/swagger').ApiQuery;\r\n } catch (error) {\r\n return (options: OpenAPIParameter): MethodDecorator => {\r\n return () => {};\r\n };\r\n }\r\n})();\r\n\r\nexport function createInstance<T>(data: T | Type<T> | undefined): T | undefined {\r\n if (typeof data === 'function')\r\n return new data();\r\n\r\n if (typeof data === 'object')\r\n return data as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function getMetadataFromContext<T>(context: ExecutionContext, key: string): T | undefined {\r\n const targets = [\r\n context.getHandler(),\r\n context.getClass(),\r\n ];\r\n\r\n for (const target of targets) {\r\n const data = Reflect.getMetadata(key, target);\r\n\r\n if (data)\r\n return data;\r\n }\r\n\r\n return undefined;\r\n}\r\n"],"mappings":"oUAAA,OAAS,mBAAAA,EAAiB,wBAAAC,EAAwC,UAAAC,EAAQ,eAAAC,MAAyB,iBCG5F,IAAMC,GAAY,IAAM,CAC7B,GAAI,CACF,MAAO,GAAQ,iBAAiB,EAAE,QACpC,MAAgB,CACd,OAAQC,GACC,IAAM,CAAC,CAElB,CACF,GAAG,EAEI,SAASC,EAAkBC,EAA8C,CAC9E,GAAI,OAAOA,GAAS,WAClB,OAAO,IAAIA,EAEb,GAAI,OAAOA,GAAS,SAClB,OAAOA,CAGX,CARgBC,EAAAF,EAAA,kBAUT,SAASG,EAA0BC,EAA2BC,EAA4B,CAC/F,IAAMC,EAAU,CACdF,EAAQ,WAAW,EACnBA,EAAQ,SAAS,CACnB,EAEA,QAAWG,KAAUD,EAAS,CAC5B,IAAML,EAAO,QAAQ,YAAYI,EAAKE,CAAM,EAE5C,GAAIN,EACF,OAAOA,CACX,CAGF,CAdgBC,EAAAC,EAAA,0BDnBT,IAAMK,EAAoB,oBAO1B,SAASC,EAAKC,EAAuF,CAC1G,IAAMC,EAASC,EAAeF,CAAc,EAE5C,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,iDAAiD,EAGnE,IAAME,EAAUF,EAAO,qBAAqB,EAAE,IAAIG,GAASC,EAASD,CAAK,CAAC,EAE1E,OAAOE,EACLC,EAAYT,EAAmBG,CAAM,EACrC,GAAGE,CACL,CACF,CAbgBK,EAAAT,EAAA,QAkBT,IAAMU,EAAmBC,EAC9B,CAACC,EAA2CC,IAA0B,CACpE,IAAMC,EAAUD,EAAI,aAAa,EAAE,WAAW,EACxCX,EAASU,EAAOT,EAAeS,CAAI,EAAIG,EAAsCF,EAAKd,CAAiB,EAEzG,OAAKG,EAWEA,EAAO,MAAMY,EAAQ,KAAK,GAV/B,IAAIE,EAAO,kBAAkB,EAAE,KAAK,yFAAyF,EAEtH,CACL,MAAO,CAAE,IAAK,CAAC,CAAE,EACjB,OAAQ,CAAC,EACT,MAAO,CAAC,EACR,UAAW,CAAC,CACd,EAIJ,CACF","names":["applyDecorators","createParamDecorator","Logger","SetMetadata","ApiQuery","options","createInstance","data","__name","getMetadataFromContext","context","key","targets","target","CRUD_QUERY_PARSER","Crud","parserContract","parser","createInstance","openApi","param","ApiQuery","applyDecorators","SetMetadata","__name","ParseCrudRequest","createParamDecorator","data","ctx","request","getMetadataFromContext","Logger"]}
package/dist/index.d.mts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { G as GetManyResult, Q as QueryAdapter } from './query-adapter-BliD9hJN.mjs';
2
- export { P as ParsedRequestWhereBuilder, R as RequestParamValue, a as RequestParser } from './parsed-request-where.builder-LCWNWCt6.mjs';
2
+ export { R as RequestParamValue, a as RequestParser } from './request-parser-WaQBZsYG.mjs';
3
3
  export { c as CrudRequest, C as CrudRequestFields, b as CrudRequestOrder, a as CrudRequestRelation, d as CrudRequestWhere, e as CrudRequestWhereAND, g as CrudRequestWhereField, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, F as FieldPath, P as ParsedRequestSelect } from './crud-request-CvDKp6Iy.mjs';
4
+ export { P as ParsedRequestWhereBuilder } from './parsed-request-where.builder-DRZUAxu4.mjs';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { G as GetManyResult, Q as QueryAdapter } from './query-adapter-Vebxws3V.js';
2
- export { P as ParsedRequestWhereBuilder, R as RequestParamValue, a as RequestParser } from './parsed-request-where.builder-CTGRmvAX.js';
2
+ export { R as RequestParamValue, a as RequestParser } from './request-parser-B-fK5GnP.js';
3
3
  export { c as CrudRequest, C as CrudRequestFields, b as CrudRequestOrder, a as CrudRequestRelation, d as CrudRequestWhere, e as CrudRequestWhereAND, g as CrudRequestWhereField, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, F as FieldPath, P as ParsedRequestSelect } from './crud-request-CvDKp6Iy.js';
4
+ export { P as ParsedRequestWhereBuilder } from './parsed-request-where.builder-DME55XmN.js';
@@ -1,14 +1,4 @@
1
- import { c as CrudRequest, e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.js';
2
-
3
- type RequestParamValue = string | string[] | undefined;
4
- interface RequestParser {
5
- /**
6
- * Parses a query string into a parsed request object
7
- *
8
- * @param query The query string map
9
- */
10
- parse(query: Record<string, RequestParamValue>): CrudRequest;
11
- }
1
+ import { e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.js';
12
2
 
13
3
  /**
14
4
  * A helper class that makes it easier to create a CrudRequestWhere
@@ -39,4 +29,4 @@ declare class ParsedRequestWhereBuilder {
39
29
  build(): CrudRequestWhere;
40
30
  }
41
31
 
42
- export { ParsedRequestWhereBuilder as P, type RequestParamValue as R, type RequestParser as a };
32
+ export { ParsedRequestWhereBuilder as P };
@@ -1,14 +1,4 @@
1
- import { c as CrudRequest, e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.mjs';
2
-
3
- type RequestParamValue = string | string[] | undefined;
4
- interface RequestParser {
5
- /**
6
- * Parses a query string into a parsed request object
7
- *
8
- * @param query The query string map
9
- */
10
- parse(query: Record<string, RequestParamValue>): CrudRequest;
11
- }
1
+ import { e as CrudRequestWhereAND, f as CrudRequestWhereOR, i as CrudRequestWhereOperator, h as CrudRequestWhereValueType, d as CrudRequestWhere } from './crud-request-CvDKp6Iy.mjs';
12
2
 
13
3
  /**
14
4
  * A helper class that makes it easier to create a CrudRequestWhere
@@ -39,4 +29,4 @@ declare class ParsedRequestWhereBuilder {
39
29
  build(): CrudRequestWhere;
40
30
  }
41
31
 
42
- export { ParsedRequestWhereBuilder as P, type RequestParamValue as R, type RequestParser as a };
32
+ export { ParsedRequestWhereBuilder as P };
@@ -1,10 +1,12 @@
1
- import { a as RequestParser, R as RequestParamValue, P as ParsedRequestWhereBuilder } from '../../parsed-request-where.builder-LCWNWCt6.mjs';
1
+ import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-WaQBZsYG.mjs';
2
2
  import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-CvDKp6Iy.mjs';
3
+ import { P as ParsedRequestWhereBuilder } from '../../parsed-request-where.builder-DRZUAxu4.mjs';
3
4
 
4
5
  /**
5
6
  * Parses a request based on the @nestjsx/crud format.
6
7
  */
7
8
  declare class CrudRequestParser implements RequestParser {
9
+ getOpenAPIParameters(): OpenAPIParameter[];
8
10
  parse(query: Record<string, RequestParamValue>): CrudRequest;
9
11
  protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void;
10
12
  protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void;
@@ -1,10 +1,12 @@
1
- import { a as RequestParser, R as RequestParamValue, P as ParsedRequestWhereBuilder } from '../../parsed-request-where.builder-CTGRmvAX.js';
1
+ import { a as RequestParser, O as OpenAPIParameter, R as RequestParamValue } from '../../request-parser-B-fK5GnP.js';
2
2
  import { c as CrudRequest, P as ParsedRequestSelect, a as CrudRequestRelation, b as CrudRequestOrder } from '../../crud-request-CvDKp6Iy.js';
3
+ import { P as ParsedRequestWhereBuilder } from '../../parsed-request-where.builder-DME55XmN.js';
3
4
 
4
5
  /**
5
6
  * Parses a request based on the @nestjsx/crud format.
6
7
  */
7
8
  declare class CrudRequestParser implements RequestParser {
9
+ getOpenAPIParameters(): OpenAPIParameter[];
8
10
  parse(query: Record<string, RequestParamValue>): CrudRequest;
9
11
  protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void;
10
12
  protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void;
@@ -1,2 +1,2 @@
1
- "use strict";var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var u=(s,e)=>c(s,"name",{value:e,configurable:!0});var S=(s,e)=>{for(var r in e)c(s,r,{get:e[r],enumerable:!0})},_=(s,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of T(e))!O.call(s,t)&&t!==r&&c(s,t,{get:()=>e[t],enumerable:!(i=E(e,t))||i.enumerable});return s};var $=s=>_(c({},"__esModule",{value:!0}),s);var A={};S(A,{CrudRequestParser:()=>m});module.exports=$(A);var h=class s{constructor(e={and:[]},r){this.where=e;this.parent=r}static{u(this,"ParsedRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},r=new s(e,this);return this.where.or.push(e),r}addOr(){if(!this.where.and)return this;let e={or:[]},r=new s(e,this);return this.where.and.push(e),r}addField(e,r,i){let t={field:e,operator:r,value:i};if(this.where.and)this.where.and.push(t);else if(this.where.or)this.where.or.push(t);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};function f(s){return s!=null}u(f,"isValid");function l(s,e,r=[]){if(typeof e!="object")return;let i=Object.keys(e);if(i.length===0)return;let{$or:t,$and:n,...o}=e;if(n){let d=n.length>1||i.length>1?s.addAnd():s;n.forEach(a=>l(d,a,r)),R(d,o,r);return}if(t&&i.length===1){let d=t.length>1?s.addOr():s;t.forEach(a=>l(d,a,r));return}if(t){let d=s.addAnd(),a=t.length>1?d.addOr():d;R(d,o,r),t.forEach(p=>l(a,p,r));return}i.length>1&&(s=s.addAnd()),R(s,o,r)}u(l,"parseCrudSearch");function R(s,e,r){for(let i of Object.keys(e)){let t=e[i];if(!f(t))continue;let n=[...r,...i.split(".")];if(Array.isArray(t)){t.forEach(o=>l(s,o,n));continue}N(s,n,t)}}u(R,"parseCrudSearchFields");function N(s,e,r){if(typeof r!="object"){s.addField(e,"eq",r);return}let i={$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"},t=Object.keys(r);for(let n of t){if(!i[n])continue;let o=r[n];Array.isArray(o)?o.forEach(d=>s.addField(e,i[n],d)):s.addField(e,i[n],o)}r.$or&&N(s.addOr(),e,r.$or)}u(N,"parseCrudSearchField");var m=class{static{u(this,"CrudRequestParser")}parse(e){let r=[],i=[],t=[],n=new h;this.parseSelect(r,e.fields||e.select),this.parseJoin(r,i,e.join),this.parseOrder(t,e.sort),this.parseSearch(n,e.s);let{limit:o,offset:d}=this.parseLimits(e.limit,e.offset,e.page);return{select:r,relations:i,order:t,where:n.build(),limit:o,offset:d}}parseSelect(e,r){if(!r)return;(Array.isArray(r)?r:r.split(",")).forEach(t=>{e.push({field:t.split(".")})})}parseJoin(e,r,i){if(!i)return;if(Array.isArray(i)){i.forEach(a=>this.parseJoin(e,r,a));return}let t=i.toString(),[n,o]=t.split("||",2),d=n.split(".");r.push({field:d}),o&&o.split(",").forEach(p=>{e.push({field:[...d,p]})})}parseOrder(e,r){if(!r)return;if(Array.isArray(r)){r.forEach(n=>this.parseOrder(e,n));return}let[i,t]=r.split(",");e.push({field:i.split("."),order:t?.toUpperCase()==="DESC"?"DESC":"ASC"})}parseNumber(e){if(Array.isArray(e)&&(e=e.length>0?e[0]:void 0),!f(e))return;let r=+e;return isNaN(r)?void 0:r}parseLimits(e,r,i){let t=this.parseNumber(e),n=this.parseNumber(r);if(t&&!n){let o=this.parseNumber(i);o&&(n=t*o)}return{limit:t,offset:n}}parseSearch(e,r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!r)return;let i=JSON.parse(r);l(e,i)}};0&&(module.exports={CrudRequestParser});
1
+ "use strict";var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var a=(s,e)=>c(s,"name",{value:e,configurable:!0});var S=(s,e)=>{for(var r in e)c(s,r,{get:e[r],enumerable:!0})},T=(s,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of O(e))!y.call(s,t)&&t!==r&&c(s,t,{get:()=>e[t],enumerable:!(i=E(e,t))||i.enumerable});return s};var q=s=>T(c({},"__esModule",{value:!0}),s);var A={};S(A,{CrudRequestParser:()=>R});module.exports=q(A);var p=class s{constructor(e={and:[]},r){this.where=e;this.parent=r}static{a(this,"ParsedRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},r=new s(e,this);return this.where.or.push(e),r}addOr(){if(!this.where.and)return this;let e={or:[]},r=new s(e,this);return this.where.and.push(e),r}addField(e,r,i){let t={field:e,operator:r,value:i};if(this.where.and)this.where.and.push(t);else if(this.where.or)this.where.or.push(t);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};function f(s){return s!=null}a(f,"isValid");function u(s,e,r=[]){if(typeof e!="object")return;let i=Object.keys(e);if(i.length===0)return;let{$or:t,$and:n,...o}=e;if(n){let d=n.length>1||i.length>1?s.addAnd():s;n.forEach(l=>u(d,l,r)),m(d,o,r);return}if(t&&i.length===1){let d=t.length>1?s.addOr():s;t.forEach(l=>u(d,l,r));return}if(t){let d=s.addAnd(),l=t.length>1?d.addOr():d;m(d,o,r),t.forEach(h=>u(l,h,r));return}i.length>1&&(s=s.addAnd()),m(s,o,r)}a(u,"parseCrudSearch");function m(s,e,r){for(let i of Object.keys(e)){let t=e[i];if(!f(t))continue;let n=[...r,...i.split(".")];if(Array.isArray(t)){t.forEach(o=>u(s,o,n));continue}N(s,n,t)}}a(m,"parseCrudSearchFields");function N(s,e,r){if(typeof r!="object"){s.addField(e,"eq",r);return}let i={$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"},t=Object.keys(r);for(let n of t){if(!i[n])continue;let o=r[n];Array.isArray(o)?o.forEach(d=>s.addField(e,i[n],d)):s.addField(e,i[n],o)}r.$or&&N(s.addOr(),e,r.$or)}a(N,"parseCrudSearchField");var R=class{static{a(this,"CrudRequestParser")}getOpenAPIParameters(){let e={type:"array",items:{type:"string"}};return[{name:"fields",description:"Selects resource fields",required:!1,schema:e,style:"form",explode:!1},{name:"s",description:"Search condition",required:!1,schema:{type:"string"}},{name:"sort",description:"Search condition",required:!1,schema:e,style:"form",explode:!0},{name:"join",description:"Relations",required:!1,schema:e,style:"form",explode:!0},{name:"limit",description:"Page limit",required:!1,schema:{type:"integer"}},{name:"offset",description:"Offset amount",required:!1,schema:{type:"integer"}},{name:"page",description:"Page number",required:!1,schema:{type:"integer"}}]}parse(e){let r=[],i=[],t=[],n=new p;this.parseSelect(r,e.fields||e.select),this.parseJoin(r,i,e.join),this.parseOrder(t,e.sort),this.parseSearch(n,e.s);let{limit:o,offset:d}=this.parseLimits(e.limit,e.offset,e.page);return{select:r,relations:i,order:t,where:n.build(),limit:o,offset:d}}parseSelect(e,r){if(!r)return;(Array.isArray(r)?r:r.split(",")).forEach(t=>{e.push({field:t.split(".")})})}parseJoin(e,r,i){if(!i)return;if(Array.isArray(i)){i.forEach(l=>this.parseJoin(e,r,l));return}let t=i.toString(),[n,o]=t.split("||",2),d=n.split(".");r.push({field:d}),o&&o.split(",").forEach(h=>{e.push({field:[...d,h]})})}parseOrder(e,r){if(!r)return;if(Array.isArray(r)){r.forEach(n=>this.parseOrder(e,n));return}let[i,t]=r.split(",");e.push({field:i.split("."),order:t?.toUpperCase()==="DESC"?"DESC":"ASC"})}parseNumber(e){if(Array.isArray(e)&&(e=e.length>0?e[0]:void 0),!f(e))return;let r=+e;return isNaN(r)?void 0:r}parseLimits(e,r,i){let t=this.parseNumber(e),n=this.parseNumber(r);if(t&&!n){let o=this.parseNumber(i);o&&(n=t*o)}return{limit:t,offset:n}}parseSearch(e,r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!r)return;let i=JSON.parse(r);u(e,i)}};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 { 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 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","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/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,2 +1,2 @@
1
- var N=Object.defineProperty;var u=(i,r)=>N(i,"name",{value:r,configurable:!0});var c=class i{constructor(r={and:[]},e){this.where=r;this.parent=e}static{u(this,"ParsedRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let r={and:[]},e=new i(r,this);return this.where.or.push(r),e}addOr(){if(!this.where.and)return this;let r={or:[]},e=new i(r,this);return this.where.and.push(r),e}addField(r,e,s){let t={field:r,operator:e,value:s};if(this.where.and)this.where.and.push(t);else if(this.where.or)this.where.or.push(t);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};function h(i){return i!=null}u(h,"isValid");function l(i,r,e=[]){if(typeof r!="object")return;let s=Object.keys(r);if(s.length===0)return;let{$or:t,$and:n,...o}=r;if(n){let d=n.length>1||s.length>1?i.addAnd():i;n.forEach(a=>l(d,a,e)),p(d,o,e);return}if(t&&s.length===1){let d=t.length>1?i.addOr():i;t.forEach(a=>l(d,a,e));return}if(t){let d=i.addAnd(),a=t.length>1?d.addOr():d;p(d,o,e),t.forEach(f=>l(a,f,e));return}s.length>1&&(i=i.addAnd()),p(i,o,e)}u(l,"parseCrudSearch");function p(i,r,e){for(let s of Object.keys(r)){let t=r[s];if(!h(t))continue;let n=[...e,...s.split(".")];if(Array.isArray(t)){t.forEach(o=>l(i,o,n));continue}R(i,n,t)}}u(p,"parseCrudSearchFields");function R(i,r,e){if(typeof e!="object"){i.addField(r,"eq",e);return}let s={$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"},t=Object.keys(e);for(let n of t){if(!s[n])continue;let o=e[n];Array.isArray(o)?o.forEach(d=>i.addField(r,s[n],d)):i.addField(r,s[n],o)}e.$or&&R(i.addOr(),r,e.$or)}u(R,"parseCrudSearchField");var m=class{static{u(this,"CrudRequestParser")}parse(r){let e=[],s=[],t=[],n=new c;this.parseSelect(e,r.fields||r.select),this.parseJoin(e,s,r.join),this.parseOrder(t,r.sort),this.parseSearch(n,r.s);let{limit:o,offset:d}=this.parseLimits(r.limit,r.offset,r.page);return{select:e,relations:s,order:t,where:n.build(),limit:o,offset:d}}parseSelect(r,e){if(!e)return;(Array.isArray(e)?e:e.split(",")).forEach(t=>{r.push({field:t.split(".")})})}parseJoin(r,e,s){if(!s)return;if(Array.isArray(s)){s.forEach(a=>this.parseJoin(r,e,a));return}let t=s.toString(),[n,o]=t.split("||",2),d=n.split(".");e.push({field:d}),o&&o.split(",").forEach(f=>{r.push({field:[...d,f]})})}parseOrder(r,e){if(!e)return;if(Array.isArray(e)){e.forEach(n=>this.parseOrder(r,n));return}let[s,t]=e.split(",");r.push({field:s.split("."),order:t?.toUpperCase()==="DESC"?"DESC":"ASC"})}parseNumber(r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!h(r))return;let e=+r;return isNaN(e)?void 0:e}parseLimits(r,e,s){let t=this.parseNumber(r),n=this.parseNumber(e);if(t&&!n){let o=this.parseNumber(s);o&&(n=t*o)}return{limit:t,offset:n}}parseSearch(r,e){if(Array.isArray(e)&&(e=e.length>0?e[0]:void 0),!e)return;let s=JSON.parse(e);l(r,s)}};export{m as CrudRequestParser};
1
+ var N=Object.defineProperty;var a=(i,e)=>N(i,"name",{value:e,configurable:!0});var c=class i{constructor(e={and:[]},r){this.where=e;this.parent=r}static{a(this,"ParsedRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},r=new i(e,this);return this.where.or.push(e),r}addOr(){if(!this.where.and)return this;let e={or:[]},r=new i(e,this);return this.where.and.push(e),r}addField(e,r,s){let t={field:e,operator:r,value:s};if(this.where.and)this.where.and.push(t);else if(this.where.or)this.where.or.push(t);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};function p(i){return i!=null}a(p,"isValid");function u(i,e,r=[]){if(typeof e!="object")return;let s=Object.keys(e);if(s.length===0)return;let{$or:t,$and:n,...o}=e;if(n){let d=n.length>1||s.length>1?i.addAnd():i;n.forEach(l=>u(d,l,r)),h(d,o,r);return}if(t&&s.length===1){let d=t.length>1?i.addOr():i;t.forEach(l=>u(d,l,r));return}if(t){let d=i.addAnd(),l=t.length>1?d.addOr():d;h(d,o,r),t.forEach(f=>u(l,f,r));return}s.length>1&&(i=i.addAnd()),h(i,o,r)}a(u,"parseCrudSearch");function h(i,e,r){for(let s of Object.keys(e)){let t=e[s];if(!p(t))continue;let n=[...r,...s.split(".")];if(Array.isArray(t)){t.forEach(o=>u(i,o,n));continue}m(i,n,t)}}a(h,"parseCrudSearchFields");function m(i,e,r){if(typeof r!="object"){i.addField(e,"eq",r);return}let s={$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"},t=Object.keys(r);for(let n of t){if(!s[n])continue;let o=r[n];Array.isArray(o)?o.forEach(d=>i.addField(e,s[n],d)):i.addField(e,s[n],o)}r.$or&&m(i.addOr(),e,r.$or)}a(m,"parseCrudSearchField");var R=class{static{a(this,"CrudRequestParser")}getOpenAPIParameters(){let e={type:"array",items:{type:"string"}};return[{name:"fields",description:"Selects resource fields",required:!1,schema:e,style:"form",explode:!1},{name:"s",description:"Search condition",required:!1,schema:{type:"string"}},{name:"sort",description:"Search condition",required:!1,schema:e,style:"form",explode:!0},{name:"join",description:"Relations",required:!1,schema:e,style:"form",explode:!0},{name:"limit",description:"Page limit",required:!1,schema:{type:"integer"}},{name:"offset",description:"Offset amount",required:!1,schema:{type:"integer"}},{name:"page",description:"Page number",required:!1,schema:{type:"integer"}}]}parse(e){let r=[],s=[],t=[],n=new c;this.parseSelect(r,e.fields||e.select),this.parseJoin(r,s,e.join),this.parseOrder(t,e.sort),this.parseSearch(n,e.s);let{limit:o,offset:d}=this.parseLimits(e.limit,e.offset,e.page);return{select:r,relations:s,order:t,where:n.build(),limit:o,offset:d}}parseSelect(e,r){if(!r)return;(Array.isArray(r)?r:r.split(",")).forEach(t=>{e.push({field:t.split(".")})})}parseJoin(e,r,s){if(!s)return;if(Array.isArray(s)){s.forEach(l=>this.parseJoin(e,r,l));return}let t=s.toString(),[n,o]=t.split("||",2),d=n.split(".");r.push({field:d}),o&&o.split(",").forEach(f=>{e.push({field:[...d,f]})})}parseOrder(e,r){if(!r)return;if(Array.isArray(r)){r.forEach(n=>this.parseOrder(e,n));return}let[s,t]=r.split(",");e.push({field:s.split("."),order:t?.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}parseLimits(e,r,s){let t=this.parseNumber(e),n=this.parseNumber(r);if(t&&!n){let o=this.parseNumber(s);o&&(n=t*o)}return{limit:t,offset:n}}parseSearch(e,r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!r)return;let s=JSON.parse(r);u(e,s)}};export{R 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 { 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 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":["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","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/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":"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","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"]}
@@ -0,0 +1,31 @@
1
+ import { c as CrudRequest } from './crud-request-CvDKp6Iy.js';
2
+
3
+ interface OpenAPIParameter {
4
+ name: string;
5
+ description?: string;
6
+ required?: boolean;
7
+ schema?: OpenAPISchema;
8
+ style?: string;
9
+ explode?: boolean;
10
+ }
11
+ interface OpenAPISchema {
12
+ type: string;
13
+ default?: string;
14
+ items?: OpenAPISchema;
15
+ }
16
+
17
+ type RequestParamValue = string | string[] | undefined;
18
+ interface RequestParser {
19
+ /**
20
+ * Parses a query string into a parsed request object
21
+ *
22
+ * @param query The query string map
23
+ */
24
+ parse(query: Record<string, RequestParamValue>): CrudRequest;
25
+ /**
26
+ * Gets the OpenAPI query parameters documentation
27
+ */
28
+ getOpenAPIParameters(): OpenAPIParameter[];
29
+ }
30
+
31
+ export type { OpenAPIParameter as O, RequestParamValue as R, RequestParser as a };
@@ -0,0 +1,31 @@
1
+ import { c as CrudRequest } from './crud-request-CvDKp6Iy.mjs';
2
+
3
+ interface OpenAPIParameter {
4
+ name: string;
5
+ description?: string;
6
+ required?: boolean;
7
+ schema?: OpenAPISchema;
8
+ style?: string;
9
+ explode?: boolean;
10
+ }
11
+ interface OpenAPISchema {
12
+ type: string;
13
+ default?: string;
14
+ items?: OpenAPISchema;
15
+ }
16
+
17
+ type RequestParamValue = string | string[] | undefined;
18
+ interface RequestParser {
19
+ /**
20
+ * Parses a query string into a parsed request object
21
+ *
22
+ * @param query The query string map
23
+ */
24
+ parse(query: Record<string, RequestParamValue>): CrudRequest;
25
+ /**
26
+ * Gets the OpenAPI query parameters documentation
27
+ */
28
+ getOpenAPIParameters(): OpenAPIParameter[];
29
+ }
30
+
31
+ export type { OpenAPIParameter as O, RequestParamValue as R, RequestParser as a };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crud-query-parser",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Parses HTTP requests and converts them into database queries",
5
5
  "license": "MIT",
6
6
  "author": "Guilherme Chaguri",
@@ -13,6 +13,7 @@
13
13
  "src/index.ts",
14
14
  "src/adapters/typeorm/index.ts",
15
15
  "src/parsers/crud/index.ts",
16
+ "src/helpers/nestjs/index.ts",
16
17
  "src/filters/index.ts"
17
18
  ],
18
19
  "target": "es2022",
@@ -67,6 +68,16 @@
67
68
  "types": "./dist/parsers/crud/index.d.ts"
68
69
  }
69
70
  },
71
+ "./helpers/nestjs": {
72
+ "import": {
73
+ "default": "./dist/helpers/nestjs/index.mjs",
74
+ "types": "./dist/helpers/nestjs/index.d.mts"
75
+ },
76
+ "require": {
77
+ "default": "./dist/helpers/nestjs/index.js",
78
+ "types": "./dist/helpers/nestjs/index.d.ts"
79
+ }
80
+ },
70
81
  "./filters": {
71
82
  "import": {
72
83
  "default": "./dist/filters/index.mjs",