crud-query-parser 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +154 -35
- package/dist/adapters/array/index.d.mts +90 -0
- package/dist/adapters/array/index.d.ts +90 -0
- package/dist/adapters/array/index.js +2 -0
- package/dist/adapters/array/index.js.map +1 -0
- package/dist/adapters/array/index.mjs +2 -0
- package/dist/adapters/array/index.mjs.map +1 -0
- package/dist/adapters/dynamodb/index.d.mts +239 -0
- package/dist/adapters/dynamodb/index.d.ts +239 -0
- package/dist/adapters/dynamodb/index.js +2 -0
- package/dist/adapters/dynamodb/index.js.map +1 -0
- package/dist/adapters/dynamodb/index.mjs +2 -0
- package/dist/adapters/dynamodb/index.mjs.map +1 -0
- package/dist/adapters/mongodb/index.d.mts +163 -0
- package/dist/adapters/mongodb/index.d.ts +163 -0
- package/dist/adapters/mongodb/index.js +2 -0
- package/dist/adapters/mongodb/index.js.map +1 -0
- package/dist/adapters/mongodb/index.mjs +2 -0
- package/dist/adapters/mongodb/index.mjs.map +1 -0
- package/dist/adapters/sequelize/index.d.mts +190 -0
- package/dist/adapters/sequelize/index.d.ts +190 -0
- package/dist/adapters/sequelize/index.js +2 -0
- package/dist/adapters/sequelize/index.js.map +1 -0
- package/dist/adapters/sequelize/index.mjs +2 -0
- package/dist/adapters/sequelize/index.mjs.map +1 -0
- package/dist/adapters/typeorm/index.d.mts +4 -4
- package/dist/adapters/typeorm/index.d.ts +4 -4
- 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/crud-request-9u0s-DnI.d.mts +193 -0
- package/dist/crud-request-9u0s-DnI.d.ts +193 -0
- package/dist/{crud-request-where.builder-B5241Aht.d.ts → crud-request-where.builder-Cq0DKiuS.d.ts} +1 -1
- package/dist/{crud-request-where.builder-BwWLx0Bh.d.mts → crud-request-where.builder-D_V4JtjY.d.mts} +1 -1
- package/dist/filters/index.d.mts +1 -1
- package/dist/filters/index.d.ts +1 -1
- 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/express/index.d.mts +30 -0
- package/dist/helpers/express/index.d.ts +30 -0
- package/dist/helpers/express/index.js +2 -0
- package/dist/helpers/express/index.js.map +1 -0
- package/dist/helpers/express/index.mjs +2 -0
- package/dist/helpers/express/index.mjs.map +1 -0
- package/dist/helpers/nestjs/index.d.mts +4 -3
- package/dist/helpers/nestjs/index.d.ts +4 -3
- package/dist/helpers/nestjs/index.js +1 -1
- package/dist/helpers/nestjs/index.js.map +1 -1
- package/dist/helpers/nestjs/index.mjs +1 -1
- package/dist/helpers/nestjs/index.mjs.map +1 -1
- package/dist/index.d.mts +12 -4
- package/dist/index.d.ts +12 -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 +44 -5
- package/dist/parsers/crud/index.d.ts +44 -5
- 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-CEcyFcWr.d.ts → query-adapter-CZ_oD6Ui.d.ts} +3 -3
- package/dist/{query-adapter-CeTK3yxp.d.mts → query-adapter-HqVhBKtl.d.mts} +3 -3
- package/dist/{request-parser-BxVulcsX.d.ts → request-parser-C-cBNlki.d.ts} +4 -4
- package/dist/{request-parser-BMkszvGr.d.mts → request-parser-DYVGG34f.d.mts} +4 -4
- package/package.json +101 -4
- package/dist/crud-request-x16CuDRF.d.mts +0 -84
- package/dist/crud-request-x16CuDRF.d.ts +0 -84
@@ -1,2 +1,2 @@
|
|
1
|
-
var
|
1
|
+
var b=Object.defineProperty;var s=(r,e)=>b(r,"name",{value:e,configurable:!0});function T(r,e){if(e==null||typeof e=="number"||typeof e=="string"||typeof e=="boolean"||e instanceof Date)return e;throw new Error(`${r} must be a string, number, boolean or null`)}s(T,"ensurePrimitiveOrNull");function E(r,e,t=0){if(!Array.isArray(e)||e.length<t)throw new Error(`${r} must be an array with at least ${t} items`);return e}s(E,"ensureArray");function I(r,e){if(f(e)&&e!==!0)throw new Error(`${r} must be true, null or undefined`)}s(I,"ensureEmpty");function f(r){return r!=null}s(f,"isValid");var C={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(r){let e=C[r.operator],t="The value of the operator "+r.operator;if(e==="primitive"){T(t,r.value);return}if(e==="array"){E(t,r.value).forEach(n=>T(t+" children",n));return}if(e==="empty"){I(t,r.value);return}}s(N,"validateWhereField");var h=class r{constructor(e={and:[]},t){this.where=e;this.parent=t}static{s(this,"CrudRequestWhereBuilder")}addAnd(){if(!this.where.or)return this;let e={and:[]},t=new r(e,this);return this.where.or.push(e),t}addOr(){if(!this.where.and)return this;let e={or:[]},t=new r(e,this);return this.where.and.push(e),t}addField(e,t,i){let n={field:e,operator:t,value:i};if(N(n),this.where.and)this.where.and.push(n);else if(this.where.or)this.where.or.push(n);else throw new Error("Invalid where");return this}build(){return this.parent?this.parent.build():this.where}};function g(r){return r instanceof URLSearchParams?r.get.bind(r):e=>r[e]??null}s(g,"createParamGetter");function l(r,e){return Array.isArray(r)?r.filter(t=>typeof t=="string"):typeof r=="string"?e?r.split(e):[r]:[]}s(l,"getParamStringArray");function m(r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),!f(r))return;let e=Number(r);return isNaN(e)?void 0:e}s(m,"getParamNumber");function S(r){if(Array.isArray(r)&&(r=r.length>0?r[0]:void 0),typeof r=="string")return JSON.parse(r);if(typeof r=="object")return r}s(S,"getParamJSON");var y={$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 p(r,e,t=[]){if(typeof e!="object")return;let i=Object.keys(e);if(i.length===0)return;let{$or:n,$and:o,...a}=e;if(o){let u=o.length>1||i.length>1?r.addAnd():r;o.forEach(d=>p(u,d,t)),O(u,a,t);return}if(n&&i.length===1){let u=n.length>1?r.addOr():r;n.forEach(d=>p(u,d,t));return}if(n){let u=r.addAnd(),d=n.length>1?u.addOr():u;O(u,a,t),n.forEach(c=>p(d,c,t));return}i.length>1&&(r=r.addAnd()),O(r,a,t)}s(p,"parseCrudSearch");function O(r,e,t){for(let i of Object.keys(e)){let n=e[i];if(!f(n))continue;let o=[...t,...i.split(".")];if(Array.isArray(n)){n.forEach(a=>p(r,a,o));continue}W(r,o,n)}}s(O,"parseCrudSearchFields");function W(r,e,t){if(typeof t!="object"){r.addField(e,"eq",t);return}let i=Object.keys(t);for(let n of i)y[n]&&r.addField(e,y[n],t[n]);t.$or&&W(r.addOr(),e,t.$or)}s(W,"parseCrudSearchField");function P(r,e,t){if(e.length>0&&t.length>0){let i=r.addOr();R(i.addAnd(),e),R(i.addAnd(),t);return}if(t.length>0){R(r.addOr(),t);return}if(e.length>0){R(r.addAnd(),e);return}}s(P,"parseCrudFilters");function R(r,e){for(let t of e){let[i,n,o]=t.toString().split("||",3),a=y[n];a&&r.addField(i.split("."),a,o)}}s(R,"parseCrudFilter");var V=class{constructor(e={}){this.options=e}static{s(this,"CrudRequestParser")}getOpenAPIParameters(){let e={type:"array",items:{type:"string"}},t=[];return this.options.disableSelect||t.push({name:"fields",description:"Selects resource fields",required:!1,schema:e,style:"form",explode:!1}),this.options.disableWhere||t.push({name:"s",description:"Search condition",required:!1,schema:{type:"string"}}),this.options.disableOrder||t.push({name:"sort",description:"Sorting",required:!1,schema:e,style:"form",explode:!0}),this.options.disableRelations||t.push({name:"join",description:"Relations",required:!1,schema:e,style:"form",explode:!0}),this.options.disableLimit||t.push({name:"limit",description:"Page limit",required:!1,schema:{type:"integer"}}),this.options.disableOffset||t.push({name:"offset",description:"Offset amount",required:!1,schema:{type:"integer"}},{name:"page",description:"Page number",required:!1,schema:{type:"integer"}}),t}parse(e){let t=g(e),i=[],n=[],o=[],a=new h;this.options.disableSelect||this.parseSelect(i,t("fields")||t("select")),this.options.disableRelations||this.parseJoin(i,n,t("join")),this.options.disableOrder||this.parseOrder(o,t("sort")),this.options.disableWhere||this.parseSearch(a,t("s"),t("filter"),t("or"));let u=this.options.disableLimit?void 0:m(t("limit")||t("per_page")),d=this.options.disableOffset?void 0:m(t("offset")),c=this.options.disableOffset?void 0:m(t("page"));return{select:i,relations:n,order:o,where:a.build(),limit:u,offset:d,page:c}}parseSelect(e,t){l(t,",").forEach(n=>{e.push({field:n.split(".")})})}parseJoin(e,t,i){let n=l(i);for(let o of n){let[a,u]=o.split("||",2),d=a.split(".");t.push({field:d}),u&&u.split(",").forEach(q=>{e.push({field:[...d,q]})})}}parseOrder(e,t){let i=l(t);for(let n of i){let[o,a]=n.split(",");e.push({field:o.split("."),order:a?.toUpperCase()==="DESC"?"DESC":"ASC"})}}parseSearch(e,t,i,n){let o=S(t);if(!o){this.parseFilter(e,i,n);return}p(e,o)}parseFilter(e,t,i){let n=l(t),o=l(i);P(e,n,o)}};export{V as CrudRequestParser};
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
@@ -1 +1 @@
|
|
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"]}
|
1
|
+
{"version":3,"sources":["../../../src/utils/functions.ts","../../../src/utils/where.ts","../../../src/utils/crud-request-where.builder.ts","../../../src/utils/parser.ts","../../../src/parsers/crud/parseCrudSearch.ts","../../../src/parsers/crud/crud-request.parser.ts"],"sourcesContent":["export function ensurePrimitive(fieldName: string, data: any): number | string | boolean | Date {\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number or boolean`);\r\n}\r\n\r\nexport function ensurePrimitiveOrNull(fieldName: string, data: any): number | string | boolean | Date | undefined | null {\r\n if (data === null || data === undefined)\r\n return data;\r\n\r\n if (typeof data === 'number' || typeof data === 'string' || typeof data === 'boolean' || data instanceof Date)\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string, number, boolean or null`);\r\n}\r\n\r\nexport function ensureString(fieldName: string, data: any): string {\r\n if (typeof data === 'string')\r\n return data;\r\n\r\n throw new Error(`${fieldName} must be a string`);\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 - 1) : 0);\r\n}\r\n\r\nexport interface Type<T> extends Function { new (... args: any[]): T; }\r\n\r\nexport function createInstance<T extends object>(clazzOrInstance: T | Type<T> | undefined): T | undefined {\r\n if (typeof clazzOrInstance === 'function')\r\n return new clazzOrInstance();\r\n\r\n if (typeof clazzOrInstance === 'object')\r\n return clazzOrInstance as T;\r\n\r\n return undefined;\r\n}\r\n\r\nexport function escapeRegex(str: string): string {\r\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n}\r\n","import { CrudRequestWhereField, CrudRequestWhereOperator } from '../models/crud-request-where';\r\nimport { ensureArray, ensureEmpty, ensurePrimitiveOrNull } 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 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 ensurePrimitiveOrNull(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 => ensurePrimitiveOrNull(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 { RequestParamValue } from '../models/request-parser';\r\nimport { isValid } from './functions';\r\n\r\nexport function createParamGetter(query: Record<string, RequestParamValue> | URLSearchParams): (name: string) => RequestParamValue {\r\n if (query instanceof URLSearchParams) {\r\n return query.get.bind(query);\r\n }\r\n\r\n return (name: string) => query[name] ?? null;\r\n}\r\n\r\nexport function getParamString(value: RequestParamValue): string | undefined {\r\n if (Array.isArray(value))\r\n value = value[0];\r\n\r\n if (typeof value !== 'string')\r\n return undefined;\r\n\r\n return value;\r\n}\r\n\r\nexport function getParamStringArray(value: RequestParamValue, split?: string): string[] {\r\n if (Array.isArray(value))\r\n return value.filter(item => typeof item === 'string');\r\n\r\n if (typeof value === 'string')\r\n return split ? value.split(split) : [value];\r\n\r\n return [];\r\n}\r\n\r\nexport function getParamNumber(value: RequestParamValue): number | undefined {\r\n if (Array.isArray(value))\r\n value = value.length > 0 ? value[0] : undefined;\r\n\r\n if (!isValid(value))\r\n return undefined;\r\n\r\n const num = Number(value);\r\n\r\n return isNaN(num) ? undefined : num;\r\n}\r\n\r\nexport function getParamJSON<T>(value: RequestParamValue): T | undefined {\r\n if (Array.isArray(value))\r\n value = value.length > 0 ? value[0] : undefined;\r\n\r\n if (typeof value === 'string')\r\n return JSON.parse(value);\r\n\r\n if (typeof value === 'object')\r\n return value as T;\r\n\r\n return undefined;\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<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[] = []): void {\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<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<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<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<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 // { level: { $or: { $gt: 10, $lt: 5 } } }\r\n if (field.$or) {\r\n parseCrudSearchField(builder.addOr(), name, field.$or);\r\n }\r\n}\r\n\r\n/**\r\n * Parses the legacy \"filter\" and \"or\" parameters\r\n *\r\n * @param builder The where builder\r\n * @param andFilters The \"filter\" parameter\r\n * @param orFilters The \"or\" parameter\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 combination 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 combination 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\n/**\r\n * Parses the legacy \"filter\" or \"or\" parameters\r\n *\r\n * @param builder The where builder\r\n * @param rawFilters The parameter value\r\n */\r\nfunction parseCrudFilter(builder: CrudRequestWhereBuilder, rawFilters: string[]): void {\r\n for (const rawFilter of rawFilters) {\r\n const [name, op, value] = rawFilter.toString().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 { createParamGetter, getParamJSON, getParamNumber, getParamStringArray } from '../../utils/parser';\r\nimport { parseCrudFilters, parseCrudSearch } from './parseCrudSearch';\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 /**\r\n * @inheritDoc\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 /**\r\n * @inheritDoc\r\n */\r\n public parse(query: Record<string, RequestParamValue> | URLSearchParams): CrudRequest {\r\n const get = createParamGetter(query);\r\n\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, get('fields') || get('select'));\r\n\r\n if (!this.options.disableRelations)\r\n this.parseJoin(select, relations, get('join'));\r\n\r\n if (!this.options.disableOrder)\r\n this.parseOrder(ordering, get('sort'));\r\n\r\n if (!this.options.disableWhere)\r\n this.parseSearch(where, get('s'), get('filter'), get('or'));\r\n\r\n const limit = this.options.disableLimit ? undefined : getParamNumber(get('limit') || get('per_page'));\r\n const offset = this.options.disableOffset ? undefined : getParamNumber(get('offset'));\r\n const page = this.options.disableOffset ? undefined : getParamNumber(get('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 /**\r\n * Parses the select query parameter\r\n *\r\n * @param select The parsed select array\r\n * @param rawSelect The query parameter\r\n */\r\n protected parseSelect(select: ParsedRequestSelect, rawSelect: RequestParamValue): void {\r\n const selectFields = getParamStringArray(rawSelect, ',');\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 /**\r\n * Parses the join query parameter\r\n *\r\n * @param requestFields The parsed select array\r\n * @param relations The parsed relations array\r\n * @param rawJoin The query parameter\r\n */\r\n protected parseJoin(requestFields: ParsedRequestSelect, relations: CrudRequestRelation[], rawJoin: RequestParamValue): void {\r\n const joins = getParamStringArray(rawJoin);\r\n\r\n for (const join of joins) {\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\r\n /**\r\n * Parses the order query parameter\r\n *\r\n * @param ordering The order array\r\n * @param rawOrder The query parameter\r\n */\r\n protected parseOrder(ordering: CrudRequestOrder[], rawOrder: RequestParamValue): void {\r\n const order = getParamStringArray(rawOrder);\r\n\r\n for (const entry of order) {\r\n const [field, direction] = entry.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\r\n /**\r\n * Parses the search query parameter\r\n *\r\n * @param builder The condition builder\r\n * @param rawSearch The \"search\" query parameter\r\n * @param rawFilter The \"filter\" query parameter\r\n * @param rawOr The \"or\" query parameter\r\n */\r\n protected parseSearch(builder: CrudRequestWhereBuilder, rawSearch: RequestParamValue, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n const search = getParamJSON<SCondition>(rawSearch);\r\n\r\n if (!search) {\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 parseCrudSearch(builder, search);\r\n }\r\n\r\n /**\r\n * Parses the filter query parameter\r\n *\r\n * @param builder The condition builder\r\n * @param rawFilter The \"filter\" query parameter\r\n * @param rawOr The \"or\" query parameter\r\n */\r\n protected parseFilter(builder: CrudRequestWhereBuilder, rawFilter: RequestParamValue, rawOr: RequestParamValue): void {\r\n const andFilters = getParamStringArray(rawFilter);\r\n const orFilters = getParamStringArray(rawOr);\r\n\r\n parseCrudFilters(builder, andFilters, orFilters);\r\n }\r\n\r\n}\r\n"],"mappings":"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","names":["ensurePrimitiveOrNull","fieldName","data","__name","ensureArray","fieldName","data","minLength","__name","ensureEmpty","isValid","value","operatorValueTypes","validateWhereField","where","type","name","ensurePrimitiveOrNull","ensureArray","item","ensureEmpty","__name","CrudRequestWhereBuilder","_CrudRequestWhereBuilder","where","parent","__name","inside","builder","field","operator","value","whereField","validateWhereField","createParamGetter","query","name","__name","getParamStringArray","value","split","item","__name","getParamNumber","isValid","num","getParamJSON","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","get","createParamGetter","select","relations","ordering","where","CrudRequestWhereBuilder","limit","getParamNumber","offset","page","rawSelect","getParamStringArray","field","requestFields","rawJoin","joins","join","fieldPath","f","rawOrder","order","entry","direction","builder","rawSearch","rawFilter","rawOr","search","getParamJSON","parseCrudSearch","andFilters","orFilters","parseCrudFilters"]}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { C as CrudRequest } from './crud-request-9u0s-DnI.js';
|
2
2
|
|
3
3
|
interface GetManyResult<T> {
|
4
4
|
/**
|
@@ -14,7 +14,7 @@ interface GetManyResult<T> {
|
|
14
14
|
*/
|
15
15
|
total: number;
|
16
16
|
/**
|
17
|
-
* The current page number
|
17
|
+
* The current page number, starting at 1
|
18
18
|
*/
|
19
19
|
page: number;
|
20
20
|
/**
|
@@ -35,7 +35,7 @@ interface QueryAdapter<T, BaseEntity = any> {
|
|
35
35
|
* @param baseQuery The base query to start of
|
36
36
|
* @param request The parsed request object
|
37
37
|
*/
|
38
|
-
build
|
38
|
+
build(baseQuery: T, request: CrudRequest): T;
|
39
39
|
/**
|
40
40
|
* Fetches one entity based on a parsed request object
|
41
41
|
*
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { C as CrudRequest } from './crud-request-9u0s-DnI.mjs';
|
2
2
|
|
3
3
|
interface GetManyResult<T> {
|
4
4
|
/**
|
@@ -14,7 +14,7 @@ interface GetManyResult<T> {
|
|
14
14
|
*/
|
15
15
|
total: number;
|
16
16
|
/**
|
17
|
-
* The current page number
|
17
|
+
* The current page number, starting at 1
|
18
18
|
*/
|
19
19
|
page: number;
|
20
20
|
/**
|
@@ -35,7 +35,7 @@ interface QueryAdapter<T, BaseEntity = any> {
|
|
35
35
|
* @param baseQuery The base query to start of
|
36
36
|
* @param request The parsed request object
|
37
37
|
*/
|
38
|
-
build
|
38
|
+
build(baseQuery: T, request: CrudRequest): T;
|
39
39
|
/**
|
40
40
|
* Fetches one entity based on a parsed request object
|
41
41
|
*
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { C as CrudRequest } from './crud-request-9u0s-DnI.js';
|
2
2
|
|
3
3
|
interface OpenAPIParameter {
|
4
4
|
name: string;
|
@@ -14,14 +14,14 @@ interface OpenAPISchema {
|
|
14
14
|
items?: OpenAPISchema;
|
15
15
|
}
|
16
16
|
|
17
|
-
type RequestParamValue = string | string[] | undefined;
|
17
|
+
type RequestParamValue = string | string[] | object | object[] | undefined | null;
|
18
18
|
interface RequestParser {
|
19
19
|
/**
|
20
20
|
* Parses a query string into a parsed request object
|
21
21
|
*
|
22
|
-
* @param query The query string map
|
22
|
+
* @param query The query string map or URLSearchParams
|
23
23
|
*/
|
24
|
-
parse(query: Record<string, RequestParamValue>): CrudRequest;
|
24
|
+
parse(query: Record<string, RequestParamValue> | URLSearchParams): CrudRequest;
|
25
25
|
/**
|
26
26
|
* Gets the OpenAPI query parameters documentation
|
27
27
|
*/
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import {
|
1
|
+
import { C as CrudRequest } from './crud-request-9u0s-DnI.mjs';
|
2
2
|
|
3
3
|
interface OpenAPIParameter {
|
4
4
|
name: string;
|
@@ -14,14 +14,14 @@ interface OpenAPISchema {
|
|
14
14
|
items?: OpenAPISchema;
|
15
15
|
}
|
16
16
|
|
17
|
-
type RequestParamValue = string | string[] | undefined;
|
17
|
+
type RequestParamValue = string | string[] | object | object[] | undefined | null;
|
18
18
|
interface RequestParser {
|
19
19
|
/**
|
20
20
|
* Parses a query string into a parsed request object
|
21
21
|
*
|
22
|
-
* @param query The query string map
|
22
|
+
* @param query The query string map or URLSearchParams
|
23
23
|
*/
|
24
|
-
parse(query: Record<string, RequestParamValue>): CrudRequest;
|
24
|
+
parse(query: Record<string, RequestParamValue> | URLSearchParams): CrudRequest;
|
25
25
|
/**
|
26
26
|
* Gets the OpenAPI query parameters documentation
|
27
27
|
*/
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "crud-query-parser",
|
3
|
-
"version": "
|
3
|
+
"version": "1.1.0",
|
4
4
|
"description": "Parses HTTP requests and converts them into database queries",
|
5
5
|
"keywords": [
|
6
6
|
"crud",
|
@@ -8,8 +8,13 @@
|
|
8
8
|
"query",
|
9
9
|
"request",
|
10
10
|
"parser",
|
11
|
+
"mongodb",
|
12
|
+
"mongoose",
|
13
|
+
"dynamodb",
|
14
|
+
"sequelize",
|
11
15
|
"typeorm",
|
12
|
-
"nestjs"
|
16
|
+
"nestjs",
|
17
|
+
"express"
|
13
18
|
],
|
14
19
|
"license": "MIT",
|
15
20
|
"author": "Guilherme Chaguri",
|
@@ -19,14 +24,26 @@
|
|
19
24
|
},
|
20
25
|
"scripts": {
|
21
26
|
"build": "tsup",
|
27
|
+
"test": "vitest",
|
28
|
+
"coverage": "vitest run --coverage --coverage.include=src/**",
|
22
29
|
"prepublishOnly": "npm run build",
|
30
|
+
"sample:array": "ts-node ./samples/array/index.ts",
|
31
|
+
"sample:dynamodb": "ts-node ./samples/dynamodb/index.ts",
|
32
|
+
"sample:mongodb": "ts-node ./samples/mongodb/index.ts",
|
33
|
+
"sample:mongoose": "ts-node ./samples/mongoose/index.ts",
|
34
|
+
"sample:sequelize": "ts-node ./samples/sequelize/index.ts",
|
23
35
|
"sample:typeorm": "ts-node ./samples/typeorm/index.ts"
|
24
36
|
},
|
25
37
|
"tsup": {
|
26
38
|
"entry": [
|
27
39
|
"src/index.ts",
|
40
|
+
"src/adapters/array/index.ts",
|
41
|
+
"src/adapters/dynamodb/index.ts",
|
42
|
+
"src/adapters/mongodb/index.ts",
|
43
|
+
"src/adapters/sequelize/index.ts",
|
28
44
|
"src/adapters/typeorm/index.ts",
|
29
45
|
"src/parsers/crud/index.ts",
|
46
|
+
"src/helpers/express/index.ts",
|
30
47
|
"src/helpers/nestjs/index.ts",
|
31
48
|
"src/filters/index.ts"
|
32
49
|
],
|
@@ -62,6 +79,46 @@
|
|
62
79
|
"types": "./dist/index.d.ts"
|
63
80
|
}
|
64
81
|
},
|
82
|
+
"./adapters/array": {
|
83
|
+
"import": {
|
84
|
+
"default": "./dist/adapters/array/index.mjs",
|
85
|
+
"types": "./dist/adapters/array/index.d.mts"
|
86
|
+
},
|
87
|
+
"require": {
|
88
|
+
"default": "./dist/adapters/array/index.js",
|
89
|
+
"types": "./dist/adapters/array/index.d.ts"
|
90
|
+
}
|
91
|
+
},
|
92
|
+
"./adapters/dynamodb": {
|
93
|
+
"import": {
|
94
|
+
"default": "./dist/adapters/dynamodb/index.mjs",
|
95
|
+
"types": "./dist/adapters/dynamodb/index.d.mts"
|
96
|
+
},
|
97
|
+
"require": {
|
98
|
+
"default": "./dist/adapters/dynamodb/index.js",
|
99
|
+
"types": "./dist/adapters/dynamodb/index.d.ts"
|
100
|
+
}
|
101
|
+
},
|
102
|
+
"./adapters/mongodb": {
|
103
|
+
"import": {
|
104
|
+
"default": "./dist/adapters/mongodb/index.mjs",
|
105
|
+
"types": "./dist/adapters/mongodb/index.d.mts"
|
106
|
+
},
|
107
|
+
"require": {
|
108
|
+
"default": "./dist/adapters/mongodb/index.js",
|
109
|
+
"types": "./dist/adapters/mongodb/index.d.ts"
|
110
|
+
}
|
111
|
+
},
|
112
|
+
"./adapters/sequelize": {
|
113
|
+
"import": {
|
114
|
+
"default": "./dist/adapters/sequelize/index.mjs",
|
115
|
+
"types": "./dist/adapters/sequelize/index.d.mts"
|
116
|
+
},
|
117
|
+
"require": {
|
118
|
+
"default": "./dist/adapters/sequelize/index.js",
|
119
|
+
"types": "./dist/adapters/sequelize/index.d.ts"
|
120
|
+
}
|
121
|
+
},
|
65
122
|
"./adapters/typeorm": {
|
66
123
|
"import": {
|
67
124
|
"default": "./dist/adapters/typeorm/index.mjs",
|
@@ -82,6 +139,16 @@
|
|
82
139
|
"types": "./dist/parsers/crud/index.d.ts"
|
83
140
|
}
|
84
141
|
},
|
142
|
+
"./helpers/express": {
|
143
|
+
"import": {
|
144
|
+
"default": "./dist/helpers/express/index.mjs",
|
145
|
+
"types": "./dist/helpers/express/index.d.mts"
|
146
|
+
},
|
147
|
+
"require": {
|
148
|
+
"default": "./dist/helpers/express/index.js",
|
149
|
+
"types": "./dist/helpers/express/index.d.ts"
|
150
|
+
}
|
151
|
+
},
|
85
152
|
"./helpers/nestjs": {
|
86
153
|
"import": {
|
87
154
|
"default": "./dist/helpers/nestjs/index.mjs",
|
@@ -104,30 +171,60 @@
|
|
104
171
|
}
|
105
172
|
},
|
106
173
|
"peerDependencies": {
|
174
|
+
"@aws-sdk/client-dynamodb": ">=3.0.0",
|
175
|
+
"@aws-sdk/util-dynamodb": ">=3.0.0",
|
107
176
|
"@nestjs/core": ">=10.0.0",
|
108
177
|
"@nestjs/swagger": ">=7.0.0",
|
178
|
+
"mongodb": ">=5.0.0",
|
179
|
+
"mongoose": ">=8.0.0",
|
180
|
+
"sequelize": "6.x.x",
|
109
181
|
"typeorm": "0.2.x || 0.3.x"
|
110
182
|
},
|
111
183
|
"peerDependenciesMeta": {
|
184
|
+
"@aws-sdk/client-dynamodb": {
|
185
|
+
"optional": true
|
186
|
+
},
|
187
|
+
"@aws-sdk/util-dynamodb": {
|
188
|
+
"optional": true
|
189
|
+
},
|
112
190
|
"@nestjs/core": {
|
113
191
|
"optional": true
|
114
192
|
},
|
115
193
|
"@nestjs/swagger": {
|
116
194
|
"optional": true
|
117
195
|
},
|
196
|
+
"mongodb": {
|
197
|
+
"optional": true
|
198
|
+
},
|
199
|
+
"mongoose": {
|
200
|
+
"optional": true
|
201
|
+
},
|
202
|
+
"sequelize": {
|
203
|
+
"optional": true
|
204
|
+
},
|
118
205
|
"typeorm": {
|
119
206
|
"optional": true
|
120
207
|
}
|
121
208
|
},
|
122
209
|
"devDependencies": {
|
210
|
+
"@aws-sdk/client-dynamodb": "^3.699.0",
|
211
|
+
"@aws-sdk/util-dynamodb": "^3.699.0",
|
123
212
|
"@nestjs/common": "^10.3.9",
|
124
213
|
"@nestjs/swagger": "^7.3.1",
|
125
|
-
"@types/
|
214
|
+
"@types/better-sqlite3": "^7.6.11",
|
215
|
+
"@types/express": "^5.0.0",
|
216
|
+
"@types/node": "^22.10.3",
|
217
|
+
"@vitest/coverage-v8": "^2.1.8",
|
218
|
+
"better-sqlite3": "^9.6.0",
|
219
|
+
"mongodb": "^5.9.2",
|
220
|
+
"mongoose": "^8.9.5",
|
126
221
|
"reflect-metadata": "^0.2.2",
|
222
|
+
"sequelize": "^6.37.5",
|
127
223
|
"sqlite3": "^5.1.7",
|
128
224
|
"ts-node": "^10.9.2",
|
129
225
|
"tsup": "^8.1.0",
|
130
226
|
"typeorm": "^0.3.20",
|
131
|
-
"typescript": "^5.5.2"
|
227
|
+
"typescript": "^5.5.2",
|
228
|
+
"vitest": "^2.1.8"
|
132
229
|
}
|
133
230
|
}
|
@@ -1,84 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Field path
|
3
|
-
*
|
4
|
-
* For post.category.name, this would be ["post", "category", "name"]
|
5
|
-
*/
|
6
|
-
type FieldPath = string[];
|
7
|
-
|
8
|
-
type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;
|
9
|
-
interface CrudRequestWhereAND {
|
10
|
-
field?: never;
|
11
|
-
or?: never;
|
12
|
-
and: CrudRequestWhere[];
|
13
|
-
}
|
14
|
-
interface CrudRequestWhereOR {
|
15
|
-
field?: never;
|
16
|
-
or: CrudRequestWhere[];
|
17
|
-
and?: never;
|
18
|
-
}
|
19
|
-
interface CrudRequestWhereField {
|
20
|
-
/**
|
21
|
-
* Field path
|
22
|
-
*
|
23
|
-
* For post.category.name, this would be ["post", "category", "name"]
|
24
|
-
*/
|
25
|
-
field: FieldPath;
|
26
|
-
/**
|
27
|
-
* The operator of the comparison
|
28
|
-
*/
|
29
|
-
operator: CrudRequestWhereOperator;
|
30
|
-
/**
|
31
|
-
* The value to compare
|
32
|
-
*/
|
33
|
-
value: CrudRequestWhereValueType | CrudRequestWhereValueType[];
|
34
|
-
or?: never;
|
35
|
-
and?: never;
|
36
|
-
}
|
37
|
-
type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;
|
38
|
-
declare enum CrudRequestWhereOperator {
|
39
|
-
EQ = "eq",
|
40
|
-
NEQ = "neq",
|
41
|
-
GT = "gt",
|
42
|
-
GTE = "gte",
|
43
|
-
LT = "lt",
|
44
|
-
LTE = "lte",
|
45
|
-
STARTS = "starts",
|
46
|
-
ENDS = "ends",
|
47
|
-
CONTAINS = "contains",
|
48
|
-
NOT_CONTAINS = "not_contains",
|
49
|
-
IN = "in",
|
50
|
-
NOT_IN = "not_in",
|
51
|
-
BETWEEN = "between",
|
52
|
-
IS_NULL = "is_null",
|
53
|
-
NOT_NULL = "not_null",
|
54
|
-
EQ_LOWER = "eq_lower",
|
55
|
-
NEQ_LOWER = "neq_lower",
|
56
|
-
STARTS_LOWER = "starts_lower",
|
57
|
-
ENDS_LOWER = "ends_lower",
|
58
|
-
CONTAINS_LOWER = "contains_lower",
|
59
|
-
NOT_CONTAINS_LOWER = "not_contains_lower",
|
60
|
-
IN_LOWER = "in_lower",
|
61
|
-
NOT_IN_LOWER = "not_in_lower"
|
62
|
-
}
|
63
|
-
|
64
|
-
interface CrudRequestFields {
|
65
|
-
field: FieldPath;
|
66
|
-
}
|
67
|
-
interface CrudRequestRelation extends CrudRequestFields {
|
68
|
-
alias?: string;
|
69
|
-
}
|
70
|
-
interface CrudRequestOrder extends CrudRequestFields {
|
71
|
-
order: 'ASC' | 'DESC';
|
72
|
-
}
|
73
|
-
type ParsedRequestSelect = CrudRequestFields[];
|
74
|
-
interface CrudRequest {
|
75
|
-
select: ParsedRequestSelect;
|
76
|
-
relations: CrudRequestRelation[];
|
77
|
-
order: CrudRequestOrder[];
|
78
|
-
where: CrudRequestWhere;
|
79
|
-
limit?: number;
|
80
|
-
offset?: number;
|
81
|
-
page?: number;
|
82
|
-
}
|
83
|
-
|
84
|
-
export { type CrudRequestFields as C, type FieldPath as F, type ParsedRequestSelect as P, type CrudRequestRelation as a, type CrudRequestOrder as b, type CrudRequest as c, type CrudRequestWhere as d, type CrudRequestWhereAND as e, type CrudRequestWhereOR as f, type CrudRequestWhereField as g, type CrudRequestWhereValueType as h, CrudRequestWhereOperator as i };
|
@@ -1,84 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Field path
|
3
|
-
*
|
4
|
-
* For post.category.name, this would be ["post", "category", "name"]
|
5
|
-
*/
|
6
|
-
type FieldPath = string[];
|
7
|
-
|
8
|
-
type CrudRequestWhere = CrudRequestWhereAND | CrudRequestWhereOR | CrudRequestWhereField;
|
9
|
-
interface CrudRequestWhereAND {
|
10
|
-
field?: never;
|
11
|
-
or?: never;
|
12
|
-
and: CrudRequestWhere[];
|
13
|
-
}
|
14
|
-
interface CrudRequestWhereOR {
|
15
|
-
field?: never;
|
16
|
-
or: CrudRequestWhere[];
|
17
|
-
and?: never;
|
18
|
-
}
|
19
|
-
interface CrudRequestWhereField {
|
20
|
-
/**
|
21
|
-
* Field path
|
22
|
-
*
|
23
|
-
* For post.category.name, this would be ["post", "category", "name"]
|
24
|
-
*/
|
25
|
-
field: FieldPath;
|
26
|
-
/**
|
27
|
-
* The operator of the comparison
|
28
|
-
*/
|
29
|
-
operator: CrudRequestWhereOperator;
|
30
|
-
/**
|
31
|
-
* The value to compare
|
32
|
-
*/
|
33
|
-
value: CrudRequestWhereValueType | CrudRequestWhereValueType[];
|
34
|
-
or?: never;
|
35
|
-
and?: never;
|
36
|
-
}
|
37
|
-
type CrudRequestWhereValueType = string | number | boolean | Date | null | undefined;
|
38
|
-
declare enum CrudRequestWhereOperator {
|
39
|
-
EQ = "eq",
|
40
|
-
NEQ = "neq",
|
41
|
-
GT = "gt",
|
42
|
-
GTE = "gte",
|
43
|
-
LT = "lt",
|
44
|
-
LTE = "lte",
|
45
|
-
STARTS = "starts",
|
46
|
-
ENDS = "ends",
|
47
|
-
CONTAINS = "contains",
|
48
|
-
NOT_CONTAINS = "not_contains",
|
49
|
-
IN = "in",
|
50
|
-
NOT_IN = "not_in",
|
51
|
-
BETWEEN = "between",
|
52
|
-
IS_NULL = "is_null",
|
53
|
-
NOT_NULL = "not_null",
|
54
|
-
EQ_LOWER = "eq_lower",
|
55
|
-
NEQ_LOWER = "neq_lower",
|
56
|
-
STARTS_LOWER = "starts_lower",
|
57
|
-
ENDS_LOWER = "ends_lower",
|
58
|
-
CONTAINS_LOWER = "contains_lower",
|
59
|
-
NOT_CONTAINS_LOWER = "not_contains_lower",
|
60
|
-
IN_LOWER = "in_lower",
|
61
|
-
NOT_IN_LOWER = "not_in_lower"
|
62
|
-
}
|
63
|
-
|
64
|
-
interface CrudRequestFields {
|
65
|
-
field: FieldPath;
|
66
|
-
}
|
67
|
-
interface CrudRequestRelation extends CrudRequestFields {
|
68
|
-
alias?: string;
|
69
|
-
}
|
70
|
-
interface CrudRequestOrder extends CrudRequestFields {
|
71
|
-
order: 'ASC' | 'DESC';
|
72
|
-
}
|
73
|
-
type ParsedRequestSelect = CrudRequestFields[];
|
74
|
-
interface CrudRequest {
|
75
|
-
select: ParsedRequestSelect;
|
76
|
-
relations: CrudRequestRelation[];
|
77
|
-
order: CrudRequestOrder[];
|
78
|
-
where: CrudRequestWhere;
|
79
|
-
limit?: number;
|
80
|
-
offset?: number;
|
81
|
-
page?: number;
|
82
|
-
}
|
83
|
-
|
84
|
-
export { type CrudRequestFields as C, type FieldPath as F, type ParsedRequestSelect as P, type CrudRequestRelation as a, type CrudRequestOrder as b, type CrudRequest as c, type CrudRequestWhere as d, type CrudRequestWhereAND as e, type CrudRequestWhereOR as f, type CrudRequestWhereField as g, type CrudRequestWhereValueType as h, CrudRequestWhereOperator as i };
|