arkos 1.3.4-canary.8 → 1.3.5-beta
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 +16 -6
- package/dist/cjs/exports/controllers/index.js +36 -5
- package/dist/cjs/exports/controllers/index.js.map +1 -1
- package/dist/cjs/modules/auth/auth.controller.js +22 -15
- package/dist/cjs/modules/auth/auth.controller.js.map +1 -1
- package/dist/cjs/modules/base/base.controller.js +3 -0
- package/dist/cjs/modules/base/base.controller.js.map +1 -1
- package/dist/cjs/modules/base/base.middlewares.js +70 -12
- package/dist/cjs/modules/base/base.middlewares.js.map +1 -1
- package/dist/cjs/modules/base/base.service.js +1 -2
- package/dist/cjs/modules/base/base.service.js.map +1 -1
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js +3 -6
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
- package/dist/cjs/modules/email/email.service.js +24 -27
- package/dist/cjs/modules/email/email.service.js.map +1 -1
- package/dist/cjs/modules/file-upload/file-upload.controller.js +6 -0
- package/dist/cjs/modules/file-upload/file-upload.controller.js.map +1 -1
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/utils/cli/generate.js +1 -2
- package/dist/cjs/utils/cli/generate.js.map +1 -1
- package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/auth-configs-template.js +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/auth-configs-template.js.map +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/controller-template.js +30 -7
- package/dist/cjs/utils/cli/utils/template-generator/templates/controller-template.js.map +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/middlewares-template.js +17 -17
- package/dist/cjs/utils/cli/utils/template-generator/templates/middlewares-template.js.map +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/query-options-template.js +4 -6
- package/dist/cjs/utils/cli/utils/template-generator/templates/query-options-template.js.map +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js +2 -4
- package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js +33 -11
- package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js.map +1 -1
- package/dist/cjs/utils/features/api.features.js +7 -7
- package/dist/cjs/utils/features/api.features.js.map +1 -1
- package/dist/esm/exports/controllers/index.js +2 -2
- package/dist/esm/exports/controllers/index.js.map +1 -1
- package/dist/esm/modules/auth/auth.controller.js +22 -15
- package/dist/esm/modules/auth/auth.controller.js.map +1 -1
- package/dist/esm/modules/base/base.controller.js +3 -0
- package/dist/esm/modules/base/base.controller.js.map +1 -1
- package/dist/esm/modules/base/base.middlewares.js +70 -11
- package/dist/esm/modules/base/base.middlewares.js.map +1 -1
- package/dist/esm/modules/base/base.service.js +1 -2
- package/dist/esm/modules/base/base.service.js.map +1 -1
- package/dist/esm/modules/base/utils/helpers/base.service.helpers.js +3 -6
- package/dist/esm/modules/base/utils/helpers/base.service.helpers.js.map +1 -1
- package/dist/esm/modules/email/email.service.js +24 -27
- package/dist/esm/modules/email/email.service.js.map +1 -1
- package/dist/esm/modules/file-upload/file-upload.controller.js +5 -1
- package/dist/esm/modules/file-upload/file-upload.controller.js.map +1 -1
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/utils/cli/generate.js +1 -2
- package/dist/esm/utils/cli/generate.js.map +1 -1
- package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/auth-configs-template.js +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/auth-configs-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/controller-template.js +30 -7
- package/dist/esm/utils/cli/utils/template-generator/templates/controller-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/middlewares-template.js +17 -17
- package/dist/esm/utils/cli/utils/template-generator/templates/middlewares-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/query-options-template.js +4 -6
- package/dist/esm/utils/cli/utils/template-generator/templates/query-options-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js +2 -4
- package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js +33 -11
- package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js.map +1 -1
- package/dist/esm/utils/features/api.features.js +7 -7
- package/dist/esm/utils/features/api.features.js.map +1 -1
- package/dist/types/exports/controllers/index.d.ts +2 -2
- package/dist/types/modules/base/base.middlewares.d.ts +0 -1
- package/dist/types/modules/file-upload/file-upload.controller.d.ts +1 -1
- package/dist/types/types/index.d.ts +13 -9
- package/package.json +1 -1
|
@@ -4,21 +4,43 @@ export function generateServiceTemplate(options) {
|
|
|
4
4
|
const ext = getUserFileExtension();
|
|
5
5
|
const isTypeScript = ext === "ts";
|
|
6
6
|
if (!modelName)
|
|
7
|
-
throw new Error("
|
|
8
|
-
const
|
|
9
|
-
|
|
7
|
+
throw new Error("Module name is required for service template");
|
|
8
|
+
const camelName = modelName.camel.toLowerCase();
|
|
9
|
+
let serviceType;
|
|
10
|
+
let serviceName;
|
|
11
|
+
let serviceImport;
|
|
12
|
+
if (camelName === "fileupload") {
|
|
13
|
+
serviceType = "fileUpload";
|
|
14
|
+
serviceName = "FileUploadService";
|
|
15
|
+
serviceImport = imports?.fileUploadService || "arkos/services";
|
|
16
|
+
}
|
|
17
|
+
else if (camelName === "auth") {
|
|
18
|
+
serviceType = "auth";
|
|
19
|
+
serviceName = "AuthService";
|
|
20
|
+
serviceImport = imports?.authService || "arkos/services";
|
|
21
|
+
}
|
|
22
|
+
else if (camelName === "email") {
|
|
23
|
+
serviceType = "email";
|
|
24
|
+
serviceName = "EmailService";
|
|
25
|
+
serviceImport = imports?.emailService || "arkos/services";
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
serviceType = "base";
|
|
29
|
+
serviceName = "BaseService";
|
|
30
|
+
serviceImport = imports?.baseService || "arkos/services";
|
|
31
|
+
}
|
|
32
|
+
const prismaImport = isTypeScript && serviceType === "base"
|
|
33
|
+
? `import { Prisma } from "@prisma/client";\n`
|
|
10
34
|
: "";
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const typeParameter = isTypeScript
|
|
15
|
-
? `<typeof prisma.${modelName.camel}>`
|
|
35
|
+
const serviceClassImport = `import { ${serviceName} } from "${serviceImport}";`;
|
|
36
|
+
const typeParameter = isTypeScript && serviceType === "base"
|
|
37
|
+
? `<Prisma.${modelName.pascal}Delegate>`
|
|
16
38
|
: "";
|
|
17
|
-
return `${
|
|
39
|
+
return `${prismaImport}${serviceClassImport}
|
|
18
40
|
|
|
19
|
-
class ${modelName.pascal}Service extends
|
|
41
|
+
class ${modelName.pascal}Service extends ${serviceName}${typeParameter} {}
|
|
20
42
|
|
|
21
|
-
const ${modelName.camel}Service = new ${modelName.pascal}Service("${modelName.kebab}");
|
|
43
|
+
const ${modelName.camel}Service = new ${modelName.pascal}Service(${serviceType === "base" ? `"${modelName.kebab}"` : ""});
|
|
22
44
|
|
|
23
45
|
export default ${modelName.camel}Service;
|
|
24
46
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-template.js","sourceRoot":"","sources":["../../../../../../../src/utils/cli/utils/template-generator/templates/service-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,UAAU,uBAAuB,CAAC,OAAwB;IAC9D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACvC,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,MAAM,YAAY,GAAG,GAAG,KAAK,IAAI,CAAC;IAElC,IAAI,CAAC,SAAS;QACZ,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"service-template.js","sourceRoot":"","sources":["../../../../../../../src/utils/cli/utils/template-generator/templates/service-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAGtE,MAAM,UAAU,uBAAuB,CAAC,OAAwB;IAC9D,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACvC,MAAM,GAAG,GAAG,oBAAoB,EAAE,CAAC;IACnC,MAAM,YAAY,GAAG,GAAG,KAAK,IAAI,CAAC;IAElC,IAAI,CAAC,SAAS;QACZ,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAElE,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IAChD,IAAI,WAAqD,CAAC;IAC1D,IAAI,WAAmB,CAAC;IACxB,IAAI,aAAqB,CAAC;IAE1B,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,WAAW,GAAG,YAAY,CAAC;QAC3B,WAAW,GAAG,mBAAmB,CAAC;QAClC,aAAa,GAAG,OAAO,EAAE,iBAAiB,IAAI,gBAAgB,CAAC;IACjE,CAAC;SAAM,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QAChC,WAAW,GAAG,MAAM,CAAC;QACrB,WAAW,GAAG,aAAa,CAAC;QAC5B,aAAa,GAAG,OAAO,EAAE,WAAW,IAAI,gBAAgB,CAAC;IAC3D,CAAC;SAAM,IAAI,SAAS,KAAK,OAAO,EAAE,CAAC;QACjC,WAAW,GAAG,OAAO,CAAC;QACtB,WAAW,GAAG,cAAc,CAAC;QAC7B,aAAa,GAAG,OAAO,EAAE,YAAY,IAAI,gBAAgB,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,MAAM,CAAC;QACrB,WAAW,GAAG,aAAa,CAAC;QAC5B,aAAa,GAAG,OAAO,EAAE,WAAW,IAAI,gBAAgB,CAAC;IAC3D,CAAC;IAED,MAAM,YAAY,GAChB,YAAY,IAAI,WAAW,KAAK,MAAM;QACpC,CAAC,CAAC,4CAA4C;QAC9C,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,kBAAkB,GAAG,YAAY,WAAW,YAAY,aAAa,IAAI,CAAC;IAEhF,MAAM,aAAa,GACjB,YAAY,IAAI,WAAW,KAAK,MAAM;QACpC,CAAC,CAAC,WAAW,SAAS,CAAC,MAAM,WAAW;QACxC,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,GAAG,YAAY,GAAG,kBAAkB;;QAErC,SAAS,CAAC,MAAM,mBAAmB,WAAW,GAAG,aAAa;;QAE9D,SAAS,CAAC,KAAK,iBAAiB,SAAS,CAAC,MAAM,WAAW,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE;;iBAEtG,SAAS,CAAC,KAAK;CAC/B,CAAC;AACF,CAAC","sourcesContent":["import { getUserFileExtension } from \"../../../../helpers/fs.helpers\";\nimport { TemplateOptions } from \"../../template-generators\";\n\nexport function generateServiceTemplate(options: TemplateOptions): string {\n const { modelName, imports } = options;\n const ext = getUserFileExtension();\n const isTypeScript = ext === \"ts\";\n\n if (!modelName)\n throw new Error(\"Module name is required for service template\");\n\n const camelName = modelName.camel.toLowerCase();\n let serviceType: \"fileUpload\" | \"auth\" | \"email\" | \"base\";\n let serviceName: string;\n let serviceImport: string;\n\n if (camelName === \"fileupload\") {\n serviceType = \"fileUpload\";\n serviceName = \"FileUploadService\";\n serviceImport = imports?.fileUploadService || \"arkos/services\";\n } else if (camelName === \"auth\") {\n serviceType = \"auth\";\n serviceName = \"AuthService\";\n serviceImport = imports?.authService || \"arkos/services\";\n } else if (camelName === \"email\") {\n serviceType = \"email\";\n serviceName = \"EmailService\";\n serviceImport = imports?.emailService || \"arkos/services\";\n } else {\n serviceType = \"base\";\n serviceName = \"BaseService\";\n serviceImport = imports?.baseService || \"arkos/services\";\n }\n\n const prismaImport =\n isTypeScript && serviceType === \"base\"\n ? `import { Prisma } from \"@prisma/client\";\\n`\n : \"\";\n\n const serviceClassImport = `import { ${serviceName} } from \"${serviceImport}\";`;\n\n const typeParameter =\n isTypeScript && serviceType === \"base\"\n ? `<Prisma.${modelName.pascal}Delegate>`\n : \"\";\n\n return `${prismaImport}${serviceClassImport}\n \nclass ${modelName.pascal}Service extends ${serviceName}${typeParameter} {}\n\nconst ${modelName.camel}Service = new ${modelName.pascal}Service(${serviceType === \"base\" ? `\"${modelName.kebab}\"` : \"\"});\n\nexport default ${modelName.camel}Service;\n`;\n}\n"]}
|
|
@@ -179,27 +179,27 @@ export default class APIFeatures {
|
|
|
179
179
|
return this;
|
|
180
180
|
}
|
|
181
181
|
_validateNoPasswordExposure(select, include, omit) {
|
|
182
|
-
const checkForPassword = (obj, path = []) => {
|
|
182
|
+
const checkForPassword = (obj, prismaKey, path = []) => {
|
|
183
183
|
for (const [key, value] of Object.entries(obj)) {
|
|
184
184
|
const currentPath = [...path, key];
|
|
185
185
|
if (key === "password" &&
|
|
186
186
|
(this.modelName?.toLowerCase() === "user" ||
|
|
187
187
|
currentPath.at(-3)?.toLowerCase?.() === "user")) {
|
|
188
|
-
if (value === false)
|
|
188
|
+
if (value === false && prismaKey === "omit")
|
|
189
189
|
throw new AppError("Cannot disable password omission protection", 400, { ...obj }, "CannotExposeUserPassword");
|
|
190
|
-
if (value === true &&
|
|
190
|
+
if (value === true && ["include", "select"].includes(prismaKey))
|
|
191
191
|
throw new AppError("User password exposure detected", 403, {}, "UserPasswordExposureDetected");
|
|
192
192
|
}
|
|
193
193
|
if (typeof value === "object" &&
|
|
194
194
|
value !== null &&
|
|
195
195
|
!Array.isArray(value)) {
|
|
196
|
-
checkForPassword(value, currentPath);
|
|
196
|
+
checkForPassword(value, prismaKey, currentPath);
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
199
|
};
|
|
200
|
-
checkForPassword(select);
|
|
201
|
-
checkForPassword(include);
|
|
202
|
-
checkForPassword(omit);
|
|
200
|
+
checkForPassword(select, "select");
|
|
201
|
+
checkForPassword(include, "include");
|
|
202
|
+
checkForPassword(omit, "omit");
|
|
203
203
|
}
|
|
204
204
|
paginate() {
|
|
205
205
|
const paginationOptions = (() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.features.js","sourceRoot":"","sources":["../../../../src/utils/features/api.features.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport { parseQueryParamsWithModifiers } from \"../helpers/api.features.helpers\";\nimport AppError from \"../../modules/error-handler/utils/app-error\";\nimport { getPrismaInstance } from \"../helpers/prisma.helpers\";\nimport { ArkosRequest } from \"../../types\";\nimport debuggerService from \"../../modules/debugger/debugger.service\";\n\ntype ModelName = string;\n\nexport default class APIFeatures {\n req?: ArkosRequest;\n searchParams: any;\n searchParamsWithModifiers: any;\n filters: Record<string, any> = {};\n reqFiltersSearchParam: any = {};\n modelName?: ModelName;\n excludedFields = [\n \"page\",\n \"filters\",\n \"sort\",\n \"limit\",\n \"fields\",\n \"addFields\",\n \"removeFields\",\n \"search\",\n \"include\",\n \"filterMode\",\n \"where\",\n \"prismaQueryOptions\",\n \"ignoredFields\",\n \"select\",\n \"omit\",\n ];\n\n constructor(req?: Request, modelName?: ModelName) {\n if (req) {\n const { filters = \"{}\", ...restOfQuery } = req.query;\n this.req = req;\n\n let parsedFilters = {};\n try {\n parsedFilters = JSON.parse(filters as string);\n } catch (error) {\n throw new AppError(\"Invalid req.query.filters JSON format\", 400);\n }\n\n this.searchParams = deepmerge(\n parseQueryParamsWithModifiers(restOfQuery),\n parseQueryParamsWithModifiers(parsedFilters)\n );\n\n debuggerService.handleTransformedQueryLog(this.searchParams);\n }\n\n if (modelName) this.modelName = modelName;\n this.filters = { ...this.filters };\n }\n\n filter() {\n if (!this.req)\n throw new Error(\n \"Trying to use APIFeatures.filter() without passing request on class constructor or APIFeatures.setup() method.\"\n );\n\n const searchableFields: Record<string, any>[] = [];\n const queryObj = { ...this.searchParams };\n\n this.excludedFields.forEach((el) => delete queryObj[el]);\n\n const topLevelOR = queryObj.OR;\n const topLevelAND = queryObj.AND;\n delete queryObj.OR;\n delete queryObj.AND;\n\n const whereObj = { ...this.req.params, ...queryObj };\n const whereLogicalOperatorFilters = Object.keys(whereObj).map((key) => ({\n [key]: whereObj[key],\n }));\n\n let whereOptions: any = {};\n\n if (whereLogicalOperatorFilters.length > 0) {\n whereOptions = {\n [(this.req.query?.filterMode as string) ?? \"OR\"]:\n whereLogicalOperatorFilters,\n };\n }\n\n if (topLevelOR) {\n if (whereOptions.OR) {\n whereOptions.OR = [...whereOptions.OR, ...topLevelOR];\n } else {\n whereOptions.OR = topLevelOR;\n }\n }\n\n if (topLevelAND) {\n if (whereOptions.AND) {\n whereOptions.AND = [...whereOptions.AND, ...topLevelAND];\n } else {\n whereOptions.AND = topLevelAND;\n }\n }\n\n if (!!this.searchParams.search) {\n const prisma = getPrismaInstance();\n\n if (!this.modelName)\n throw new Error(\"Model name is required for search functionality\");\n\n if (!prisma[this.modelName] || !prisma[this.modelName].fields)\n throw new Error(`Model '${this.modelName}' not found or has no fields`);\n\n Object.keys((prisma as any)[this.modelName].fields).forEach((key) => {\n const field = ((prisma as any)[this.modelName!].fields as any)[key];\n if (\n field?.typeName === \"String\" &&\n key !== \"id\" &&\n key !== \"password\" &&\n !field.isList &&\n !key?.includes?.(\"Id\") &&\n !key?.includes?.(\"ID\")\n ) {\n searchableFields.push({\n [`${key}`]: {\n contains: this.searchParams.search,\n mode: \"insensitive\",\n },\n });\n }\n });\n\n if (searchableFields.length > 0) {\n whereOptions = deepmerge(\n {\n OR: searchableFields,\n },\n whereOptions\n );\n }\n }\n\n const firstMerge = deepmerge(\n {\n where: whereOptions,\n },\n this.req.prismaQueryOptions || {}\n );\n\n this.filters = deepmerge(firstMerge, this.filters);\n this.searchParams = deepmerge(\n this.searchParams || {},\n this.req.prismaQueryOptions || {}\n );\n\n return this;\n }\n\n sort() {\n if (this.searchParams.sort) {\n const sortBy = this.searchParams?.sort\n ?.split(\",\")\n ?.map((field: string) => ({\n [field.startsWith(\"-\") ? field.substring(1) : field]:\n field.startsWith(\"-\") ? \"desc\" : \"asc\",\n }));\n this.filters = deepmerge(this.filters, { orderBy: sortBy });\n }\n\n return this;\n }\n\n limitFields() {\n let finalSelect: Record<string, any> = {};\n let finalInclude: Record<string, any> = {};\n let finalOmit: Record<string, any> = {};\n\n if (this.searchParams?.fields) {\n const fields = this.searchParams.fields.split(\",\");\n\n const regularFields = fields.filter(\n (field: string) => !field.startsWith(\"+\") && !field.startsWith(\"-\")\n );\n const includeFields = fields\n .filter((field: string) => field.startsWith(\"+\"))\n .map((field: string) => field.substring(1));\n const excludeFields = fields\n .filter((field: string) => field.startsWith(\"-\"))\n .map((field: string) => field.substring(1));\n\n if (regularFields.length > 0) {\n finalSelect = regularFields.reduce(\n (acc: Record<string, any>, field: string) => {\n acc[field] = true;\n return acc;\n },\n {} as Record<string, any>\n );\n }\n\n includeFields.forEach((field: string) => {\n finalInclude[field] = true;\n });\n\n excludeFields.forEach((field: string) => {\n finalOmit[field] = true;\n });\n }\n\n if (this.searchParams.include || this.filters.include)\n finalInclude = deepmerge(\n finalInclude,\n deepmerge(this.filters?.include || {}, this.searchParams?.include || {})\n );\n\n if (this.searchParams.select || this.filters.include)\n finalSelect = deepmerge(\n finalSelect,\n deepmerge(this.filters?.select || {}, this.searchParams?.select || {})\n );\n\n if (this.searchParams.omit || this.filters.omit)\n finalOmit = deepmerge(\n finalOmit,\n deepmerge(this.filters?.omit || {}, this.searchParams?.omit || {})\n );\n\n if (\n Object.keys(finalSelect).length > 0 &&\n Object.keys(finalInclude).length > 0\n ) {\n finalSelect = deepmerge(finalSelect, finalInclude);\n finalInclude = {};\n delete this.filters.include;\n delete this.searchParams.include;\n }\n\n this._validateNoPasswordExposure(finalSelect, finalInclude, finalOmit);\n\n // ALWAYS protect password field in finalOmit\n if (finalOmit.password === false)\n throw new AppError(\"Cannot disable password omission protection\", 400);\n\n if (this.modelName?.toLowerCase?.() === \"user\") finalOmit.password = true;\n\n if (Object.keys(finalSelect).length > 0) this.filters.select = finalSelect;\n\n if (Object.keys(finalInclude).length > 0)\n this.filters.include = finalInclude;\n\n if (Object.keys(finalOmit).length > 0) this.filters.omit = finalOmit;\n\n if (this.searchParams?.addFields || this.searchParams?.removeFields) {\n throw new AppError(\n \"The addFields and removeFields parameters are deprecated.\",\n 400\n );\n }\n\n return this;\n }\n\n private _validateNoPasswordExposure(\n select: Record<string, any>,\n include: Record<string, any>,\n omit: Record<string, any>\n ) {\n const checkForPassword = (\n obj: Record<string, any>,\n path: string[] = []\n ) => {\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (\n key === \"password\" &&\n (this.modelName?.toLowerCase() === \"user\" ||\n currentPath.at(-3)?.toLowerCase?.() === \"user\")\n ) {\n if (value === false)\n throw new AppError(\n \"Cannot disable password omission protection\",\n 400,\n { ...obj },\n \"CannotExposeUserPassword\"\n );\n\n if (value === true && !omit?.[\"password\"])\n throw new AppError(\n \"User password exposure detected\",\n 403,\n {},\n \"UserPasswordExposureDetected\"\n );\n }\n\n if (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n checkForPassword(value, currentPath);\n }\n }\n };\n\n checkForPassword(select);\n checkForPassword(include);\n checkForPassword(omit);\n }\n\n paginate(): APIFeatures {\n const paginationOptions = (() => {\n if (this.searchParams.limit === \"all\") return {};\n\n const page = parseInt(this.searchParams.page, 10) || 1;\n const limit = parseInt(this.searchParams.limit, 10) || 30;\n const skip = (page - 1) * limit;\n\n return { skip, take: limit };\n })();\n\n this.filters = {\n ...this.filters,\n ...paginationOptions,\n };\n return this;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.features.js","sourceRoot":"","sources":["../../../../src/utils/features/api.features.ts"],"names":[],"mappings":"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","sourcesContent":["import { Request } from \"express\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport { parseQueryParamsWithModifiers } from \"../helpers/api.features.helpers\";\nimport AppError from \"../../modules/error-handler/utils/app-error\";\nimport { getPrismaInstance } from \"../helpers/prisma.helpers\";\nimport { ArkosRequest } from \"../../types\";\nimport debuggerService from \"../../modules/debugger/debugger.service\";\n\ntype ModelName = string;\n\nexport default class APIFeatures {\n req?: ArkosRequest;\n searchParams: any;\n searchParamsWithModifiers: any;\n filters: Record<string, any> = {};\n reqFiltersSearchParam: any = {};\n modelName?: ModelName;\n excludedFields = [\n \"page\",\n \"filters\",\n \"sort\",\n \"limit\",\n \"fields\",\n \"addFields\",\n \"removeFields\",\n \"search\",\n \"include\",\n \"filterMode\",\n \"where\",\n \"prismaQueryOptions\",\n \"ignoredFields\",\n \"select\",\n \"omit\",\n ];\n\n constructor(req?: Request, modelName?: ModelName) {\n if (req) {\n const { filters = \"{}\", ...restOfQuery } = req.query;\n this.req = req;\n\n let parsedFilters = {};\n try {\n parsedFilters = JSON.parse(filters as string);\n } catch (error) {\n throw new AppError(\"Invalid req.query.filters JSON format\", 400);\n }\n\n this.searchParams = deepmerge(\n parseQueryParamsWithModifiers(restOfQuery),\n parseQueryParamsWithModifiers(parsedFilters)\n );\n\n debuggerService.handleTransformedQueryLog(this.searchParams);\n }\n\n if (modelName) this.modelName = modelName;\n this.filters = { ...this.filters };\n }\n\n filter() {\n if (!this.req)\n throw new Error(\n \"Trying to use APIFeatures.filter() without passing request on class constructor or APIFeatures.setup() method.\"\n );\n\n const searchableFields: Record<string, any>[] = [];\n const queryObj = { ...this.searchParams };\n\n this.excludedFields.forEach((el) => delete queryObj[el]);\n\n const topLevelOR = queryObj.OR;\n const topLevelAND = queryObj.AND;\n delete queryObj.OR;\n delete queryObj.AND;\n\n const whereObj = { ...this.req.params, ...queryObj };\n const whereLogicalOperatorFilters = Object.keys(whereObj).map((key) => ({\n [key]: whereObj[key],\n }));\n\n let whereOptions: any = {};\n\n if (whereLogicalOperatorFilters.length > 0) {\n whereOptions = {\n [(this.req.query?.filterMode as string) ?? \"OR\"]:\n whereLogicalOperatorFilters,\n };\n }\n\n if (topLevelOR) {\n if (whereOptions.OR) {\n whereOptions.OR = [...whereOptions.OR, ...topLevelOR];\n } else {\n whereOptions.OR = topLevelOR;\n }\n }\n\n if (topLevelAND) {\n if (whereOptions.AND) {\n whereOptions.AND = [...whereOptions.AND, ...topLevelAND];\n } else {\n whereOptions.AND = topLevelAND;\n }\n }\n\n if (!!this.searchParams.search) {\n const prisma = getPrismaInstance();\n\n if (!this.modelName)\n throw new Error(\"Model name is required for search functionality\");\n\n if (!prisma[this.modelName] || !prisma[this.modelName].fields)\n throw new Error(`Model '${this.modelName}' not found or has no fields`);\n\n Object.keys((prisma as any)[this.modelName].fields).forEach((key) => {\n const field = ((prisma as any)[this.modelName!].fields as any)[key];\n if (\n field?.typeName === \"String\" &&\n key !== \"id\" &&\n key !== \"password\" &&\n !field.isList &&\n !key?.includes?.(\"Id\") &&\n !key?.includes?.(\"ID\")\n ) {\n searchableFields.push({\n [`${key}`]: {\n contains: this.searchParams.search,\n mode: \"insensitive\",\n },\n });\n }\n });\n\n if (searchableFields.length > 0) {\n whereOptions = deepmerge(\n {\n OR: searchableFields,\n },\n whereOptions\n );\n }\n }\n\n const firstMerge = deepmerge(\n {\n where: whereOptions,\n },\n this.req.prismaQueryOptions || {}\n );\n\n this.filters = deepmerge(firstMerge, this.filters);\n this.searchParams = deepmerge(\n this.searchParams || {},\n this.req.prismaQueryOptions || {}\n );\n\n return this;\n }\n\n sort() {\n if (this.searchParams.sort) {\n const sortBy = this.searchParams?.sort\n ?.split(\",\")\n ?.map((field: string) => ({\n [field.startsWith(\"-\") ? field.substring(1) : field]:\n field.startsWith(\"-\") ? \"desc\" : \"asc\",\n }));\n this.filters = deepmerge(this.filters, { orderBy: sortBy });\n }\n\n return this;\n }\n\n limitFields() {\n let finalSelect: Record<string, any> = {};\n let finalInclude: Record<string, any> = {};\n let finalOmit: Record<string, any> = {};\n\n if (this.searchParams?.fields) {\n const fields = this.searchParams.fields.split(\",\");\n\n const regularFields = fields.filter(\n (field: string) => !field.startsWith(\"+\") && !field.startsWith(\"-\")\n );\n const includeFields = fields\n .filter((field: string) => field.startsWith(\"+\"))\n .map((field: string) => field.substring(1));\n const excludeFields = fields\n .filter((field: string) => field.startsWith(\"-\"))\n .map((field: string) => field.substring(1));\n\n if (regularFields.length > 0) {\n finalSelect = regularFields.reduce(\n (acc: Record<string, any>, field: string) => {\n acc[field] = true;\n return acc;\n },\n {} as Record<string, any>\n );\n }\n\n includeFields.forEach((field: string) => {\n finalInclude[field] = true;\n });\n\n excludeFields.forEach((field: string) => {\n finalOmit[field] = true;\n });\n }\n\n if (this.searchParams.include || this.filters.include)\n finalInclude = deepmerge(\n finalInclude,\n deepmerge(this.filters?.include || {}, this.searchParams?.include || {})\n );\n\n if (this.searchParams.select || this.filters.include)\n finalSelect = deepmerge(\n finalSelect,\n deepmerge(this.filters?.select || {}, this.searchParams?.select || {})\n );\n\n if (this.searchParams.omit || this.filters.omit)\n finalOmit = deepmerge(\n finalOmit,\n deepmerge(this.filters?.omit || {}, this.searchParams?.omit || {})\n );\n\n if (\n Object.keys(finalSelect).length > 0 &&\n Object.keys(finalInclude).length > 0\n ) {\n finalSelect = deepmerge(finalSelect, finalInclude);\n finalInclude = {};\n delete this.filters.include;\n delete this.searchParams.include;\n }\n\n this._validateNoPasswordExposure(finalSelect, finalInclude, finalOmit);\n\n // ALWAYS protect password field in finalOmit\n if (finalOmit.password === false)\n throw new AppError(\"Cannot disable password omission protection\", 400);\n\n if (this.modelName?.toLowerCase?.() === \"user\") finalOmit.password = true;\n\n if (Object.keys(finalSelect).length > 0) this.filters.select = finalSelect;\n\n if (Object.keys(finalInclude).length > 0)\n this.filters.include = finalInclude;\n\n if (Object.keys(finalOmit).length > 0) this.filters.omit = finalOmit;\n\n if (this.searchParams?.addFields || this.searchParams?.removeFields) {\n throw new AppError(\n \"The addFields and removeFields parameters are deprecated.\",\n 400\n );\n }\n\n return this;\n }\n\n private _validateNoPasswordExposure(\n select: Record<string, any>,\n include: Record<string, any>,\n omit: Record<string, any>\n ) {\n const checkForPassword = (\n obj: Record<string, any>,\n prismaKey: string,\n path: string[] = []\n ) => {\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (\n key === \"password\" &&\n (this.modelName?.toLowerCase() === \"user\" ||\n currentPath.at(-3)?.toLowerCase?.() === \"user\")\n ) {\n if (value === false && prismaKey === \"omit\")\n throw new AppError(\n \"Cannot disable password omission protection\",\n 400,\n { ...obj },\n \"CannotExposeUserPassword\"\n );\n\n if (value === true && [\"include\", \"select\"].includes(prismaKey))\n throw new AppError(\n \"User password exposure detected\",\n 403,\n {},\n \"UserPasswordExposureDetected\"\n );\n }\n\n if (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n checkForPassword(value, prismaKey, currentPath);\n }\n }\n };\n\n checkForPassword(select, \"select\");\n checkForPassword(include, \"include\");\n checkForPassword(omit, \"omit\");\n }\n\n paginate(): APIFeatures {\n const paginationOptions = (() => {\n if (this.searchParams.limit === \"all\") return {};\n\n const page = parseInt(this.searchParams.page, 10) || 1;\n const limit = parseInt(this.searchParams.limit, 10) || 30;\n const skip = (page - 1) * limit;\n\n return { skip, take: limit };\n })();\n\n this.filters = {\n ...this.filters,\n ...paginationOptions,\n };\n return this;\n }\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { BaseController } from "./../../modules/base/base.controller";
|
|
2
|
-
import fileUploadController from "../../modules/file-upload/file-upload.controller";
|
|
3
|
-
export { fileUploadController, BaseController };
|
|
2
|
+
import fileUploadController, { FileUploadController } from "../../modules/file-upload/file-upload.controller";
|
|
3
|
+
export { fileUploadController, FileUploadController, BaseController };
|
|
@@ -5,7 +5,6 @@ import { ClassConstructor } from "class-transformer";
|
|
|
5
5
|
import { ValidatorOptions } from "class-validator";
|
|
6
6
|
export declare function callNext(_: Request, _1: Response, next: NextFunction): void;
|
|
7
7
|
export declare function sendResponse(req: ArkosRequest, res: ArkosResponse): void;
|
|
8
|
-
export declare function addRouteMiddlwaresAndConfigs(): void;
|
|
9
8
|
export type ControllerActions = keyof PrismaQueryOptions<any> | keyof Omit<AuthPrismaQueryOptions<any>, keyof PrismaQueryOptions<any>>;
|
|
10
9
|
export declare function addPrismaQueryOptionsToRequest<T extends Record<string, any>>(prismaQueryOptions: PrismaQueryOptions<T> | AuthPrismaQueryOptions<T>, action: ControllerActions): (req: ArkosRequest, _: ArkosResponse, next: NextFunction) => void;
|
|
11
10
|
export declare function handleRequestLogs(req: Request, res: Response, next: NextFunction): void;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import { ErrorRequestHandler, NextFunction, Request, RequestHandler, Response } from "express";
|
|
2
2
|
export type PrismaOperations = "findMany";
|
|
3
|
-
export type
|
|
3
|
+
export type AuthPrismaQueryOptions<T extends Record<string, any>> = {
|
|
4
|
+
getMe?: Partial<Parameters<T["findUnique"]>[0]>;
|
|
5
|
+
updateMe?: Partial<Parameters<T["update"]>[0]>;
|
|
6
|
+
deleteMe?: Partial<Parameters<T["update"]>[0]>;
|
|
7
|
+
login?: Partial<Parameters<T["findFirst"]>[0]>;
|
|
8
|
+
signup?: Partial<Parameters<T["create"]>[0]>;
|
|
9
|
+
updatePassword?: Partial<Parameters<T["update"]>[0]>;
|
|
10
|
+
findManyAuthAction?: Partial<Parameters<T["findMany"]>[0]>;
|
|
11
|
+
findOneAuthAction?: Partial<Parameters<T["findFirst"]>[0]>;
|
|
12
|
+
};
|
|
13
|
+
type BasePrismaQueryOptions<T extends Record<string, any>> = {
|
|
4
14
|
queryOptions?: Partial<Parameters<T["findMany"]>[0]>;
|
|
5
15
|
global?: Partial<Parameters<T["findMany"]>[0]>;
|
|
6
16
|
find?: Partial<Parameters<T["findMany"]>[0]>;
|
|
@@ -19,14 +29,7 @@ export type PrismaQueryOptions<T extends Record<string, any>> = {
|
|
|
19
29
|
deleteOne?: Partial<Parameters<T["delete"]>[0]>;
|
|
20
30
|
deleteMany?: Partial<Parameters<T["deleteMany"]>[0]>;
|
|
21
31
|
};
|
|
22
|
-
export type
|
|
23
|
-
getMe?: Partial<Parameters<T["findUnique"]>[0]>;
|
|
24
|
-
updateMe?: Partial<Parameters<T["update"]>[0]>;
|
|
25
|
-
deleteMe?: Partial<Parameters<T["update"]>[0]>;
|
|
26
|
-
login?: Partial<Parameters<T["findFirst"]>[0]>;
|
|
27
|
-
signup?: Partial<Parameters<T["create"]>[0]>;
|
|
28
|
-
updatePassword?: Partial<Parameters<T["update"]>[0]>;
|
|
29
|
-
};
|
|
32
|
+
export type PrismaQueryOptions<T extends Record<string, any>, ModelName extends string = string> = ModelName extends "auth" ? AuthPrismaQueryOptions<T> : BasePrismaQueryOptions<T>;
|
|
30
33
|
export type PrismaModelDelegate = {
|
|
31
34
|
create: (args: {
|
|
32
35
|
data: never;
|
|
@@ -135,3 +138,4 @@ export interface ArkosRequestHandler extends RequestHandler {
|
|
|
135
138
|
}
|
|
136
139
|
export interface ArkosErrorRequestHandler extends ErrorRequestHandler {
|
|
137
140
|
}
|
|
141
|
+
export {};
|