arkos 1.5.11-beta → 1.5.12-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.
Files changed (39) hide show
  1. package/dist/cjs/app.js +39 -28
  2. package/dist/cjs/app.js.map +1 -1
  3. package/dist/cjs/modules/auth/auth.service.js +2 -0
  4. package/dist/cjs/modules/auth/auth.service.js.map +1 -1
  5. package/dist/cjs/modules/base/base.controller.js +15 -3
  6. package/dist/cjs/modules/base/base.controller.js.map +1 -1
  7. package/dist/cjs/modules/base/base.service.js +5 -0
  8. package/dist/cjs/modules/base/base.service.js.map +1 -1
  9. package/dist/cjs/modules/file-upload/file-upload.router.js +2 -0
  10. package/dist/cjs/modules/file-upload/file-upload.router.js.map +1 -1
  11. package/dist/cjs/types/new-arkos-config.js.map +1 -1
  12. package/dist/cjs/utils/bundler.js.map +1 -1
  13. package/dist/cjs/utils/cli/build.js +1 -2
  14. package/dist/cjs/utils/cli/build.js.map +1 -1
  15. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  16. package/dist/cjs/utils/features/api.features.js +20 -9
  17. package/dist/cjs/utils/features/api.features.js.map +1 -1
  18. package/dist/esm/app.js +40 -29
  19. package/dist/esm/app.js.map +1 -1
  20. package/dist/esm/modules/auth/auth.service.js +2 -0
  21. package/dist/esm/modules/auth/auth.service.js.map +1 -1
  22. package/dist/esm/modules/base/base.controller.js +15 -3
  23. package/dist/esm/modules/base/base.controller.js.map +1 -1
  24. package/dist/esm/modules/base/base.service.js +5 -0
  25. package/dist/esm/modules/base/base.service.js.map +1 -1
  26. package/dist/esm/modules/file-upload/file-upload.router.js +2 -0
  27. package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
  28. package/dist/esm/types/new-arkos-config.js.map +1 -1
  29. package/dist/esm/utils/bundler.js.map +1 -1
  30. package/dist/esm/utils/cli/build.js +1 -2
  31. package/dist/esm/utils/cli/build.js.map +1 -1
  32. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  33. package/dist/esm/utils/features/api.features.js +20 -9
  34. package/dist/esm/utils/features/api.features.js.map +1 -1
  35. package/dist/types/modules/auth/auth.service.d.ts +2 -6
  36. package/dist/types/modules/base/base.service.d.ts +3 -1
  37. package/dist/types/types/new-arkos-config.d.ts +79 -39
  38. package/dist/types/utils/bundler.d.ts +1 -1
  39. package/package.json +1 -1
package/dist/cjs/app.js CHANGED
@@ -58,6 +58,7 @@ const debugger_service_1 = __importDefault(require("./modules/debugger/debugger.
58
58
  const exports_1 = require("./exports/index.js");
59
59
  const arkos_config_helpers_1 = require("./utils/helpers/arkos-config.helpers.js");
60
60
  const url_helpers_1 = require("./utils/helpers/url-helpers.js");
61
+ const sheu_1 = __importDefault(require("./utils/sheu.js"));
61
62
  exports.app = (0, express_1.default)();
62
63
  const knowModulesRouter = (0, express_1.Router)();
63
64
  async function bootstrap(initConfig) {
@@ -104,33 +105,43 @@ async function bootstrap(initConfig) {
104
105
  }
105
106
  }
106
107
  if (middlewaresConfig?.cors !== false) {
107
- if (typeof middlewaresConfig?.cors === "function") {
108
- exports.app.use(middlewaresConfig.cors);
108
+ const corsConfig = middlewaresConfig?.cors || {};
109
+ if ("customHandler" in corsConfig)
110
+ sheu_1.default.warn("cors.customHandler is deprecated. Pass the handler directly: `cors: myHandler`. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs");
111
+ if ("allowedOrigins" in corsConfig)
112
+ sheu_1.default.warn("cors.allowedOrigins is deprecated. Use `cors: { origin: '...' }` directly instead. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs");
113
+ if ("options" in corsConfig)
114
+ sheu_1.default.warn("cors.options is deprecated. Pass cors.CorsOptions directly instead. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs");
115
+ const defaultOptions = {
116
+ origin: (0, arkos_config_helpers_1.isProduction)() ? "*" : true,
117
+ methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
118
+ allowedHeaders: ["Content-Type", "Authorization", "Connection"],
119
+ credentials: (0, arkos_config_helpers_1.isProduction)() ? false : true,
120
+ };
121
+ if (typeof corsConfig === "function") {
122
+ if (corsConfig.length >= 3) {
123
+ exports.app.use(corsConfig);
124
+ }
125
+ else {
126
+ exports.app.use((0, cors_1.default)(corsConfig));
127
+ }
128
+ }
129
+ else if (middlewaresConfig?.cors &&
130
+ typeof corsConfig === "object" &&
131
+ "customHandler" in corsConfig) {
132
+ exports.app.use((0, cors_1.default)(corsConfig.customHandler));
133
+ }
134
+ else if (middlewaresConfig?.cors &&
135
+ typeof corsConfig === "object" &&
136
+ !("allowedOrigins" in corsConfig)) {
137
+ exports.app.use((0, cors_1.default)((0, deepmerge_helper_1.default)(defaultOptions, corsConfig)));
109
138
  }
110
139
  else {
111
- exports.app.use((0, cors_1.default)(middlewaresConfig?.cors?.customHandler
112
- ? middlewaresConfig.cors.customHandler
113
- : (0, deepmerge_helper_1.default)({
114
- origin: (origin, cb) => {
115
- const allowed = middlewaresConfig?.cors
116
- ?.allowedOrigins;
117
- if (allowed === "*")
118
- cb(null, true);
119
- else if (Array.isArray(allowed))
120
- cb(null, !origin || allowed?.includes?.(origin));
121
- else if (typeof allowed === "string")
122
- cb(null, !origin || allowed === origin);
123
- else
124
- cb(null, false);
125
- },
126
- methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
127
- allowedHeaders: [
128
- "Content-Type",
129
- "Authorization",
130
- "Connection",
131
- ],
132
- credentials: true,
133
- }, middlewaresConfig?.cors?.options || {})));
140
+ const { allowedOrigins, options } = corsConfig;
141
+ exports.app.use((0, cors_1.default)((0, deepmerge_helper_1.default)(defaultOptions, {
142
+ origin: allowedOrigins ?? defaultOptions.origin,
143
+ ...(options || {}),
144
+ })));
134
145
  }
135
146
  }
136
147
  if (middlewaresConfig?.expressJson !== false) {
@@ -146,10 +157,10 @@ async function bootstrap(initConfig) {
146
157
  exports.app.use(middlewaresConfig.cookieParser);
147
158
  }
148
159
  else {
149
- const params = Array.isArray(middlewaresConfig?.cookieParser)
160
+ const params = typeof middlewaresConfig?.cookieParser == "object"
150
161
  ? middlewaresConfig.cookieParser
151
- : [];
152
- exports.app.use((0, cookie_parser_1.default)(...params));
162
+ : { secret: undefined, options: undefined };
163
+ exports.app.use((0, cookie_parser_1.default)(params.secret, params.options));
153
164
  }
154
165
  }
155
166
  if (middlewaresConfig?.queryParser !== false) {
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { IRouter, Router } from \"express\";\nimport cors from \"cors\";\nimport cookieParser from \"cookie-parser\";\nimport { getAuthRouter } from \"./modules/auth/auth.router\";\nimport {\n getPrismaModelsRouter,\n getAvailableResourcesAndRoutesRouter,\n} from \"./modules/base/base.router\";\nimport errorHandler from \"./modules/error-handler/error-handler.controller\";\nimport { rateLimit } from \"express-rate-limit\";\nimport compression from \"compression\";\nimport { handleRequestLogs } from \"./modules/base/base.middlewares\";\nimport { loadPrismaModule } from \"./utils/helpers/prisma.helpers\";\nimport { getFileUploadRouter } from \"./modules/file-upload/file-upload.router\";\nimport { queryParser } from \"./utils/helpers/query-parser.helpers\";\nimport deepmerge from \"./utils/helpers/deepmerge.helper\";\nimport { getSwaggerRouter } from \"./modules/swagger/swagger.router\";\nimport { loadAllModuleComponents } from \"./utils/dynamic-loader\";\nimport { AppError } from \"./exports/error-handler\";\nimport debuggerService from \"./modules/debugger/debugger.service\";\nimport { getArkosConfig } from \"./exports\";\nimport { ArkosInitConfig } from \"./types/arkos-config\";\nimport {\n isAuthenticationEnabled,\n validateArkosConfig,\n} from \"./utils/helpers/arkos-config.helpers\";\nimport { lenientDecode } from \"./utils/helpers/url-helpers\";\nexport const app: express.Express = express();\nconst knowModulesRouter = Router();\n\nexport async function bootstrap(\n initConfig: ArkosInitConfig\n): Promise<express.Express> {\n const arkosConfig = getArkosConfig();\n\n await Promise.all([\n loadPrismaModule(),\n loadAllModuleComponents(arkosConfig),\n initConfig?.configureApp && (await initConfig?.configureApp(app)),\n ]);\n\n validateArkosConfig();\n const middlewaresConfig = arkosConfig?.middlewares;\n\n if (middlewaresConfig?.requestLogger !== false) {\n if (typeof middlewaresConfig?.requestLogger === \"function\") {\n app.use(middlewaresConfig.requestLogger);\n } else {\n app.use(handleRequestLogs);\n }\n }\n\n if (middlewaresConfig?.compression !== false) {\n if (typeof middlewaresConfig?.compression === \"function\") {\n app.use(middlewaresConfig.compression);\n } else {\n app.use(compression(middlewaresConfig?.compression || {}));\n }\n }\n\n if (middlewaresConfig?.rateLimit !== false) {\n if (typeof middlewaresConfig?.rateLimit === \"function\") {\n app.use(middlewaresConfig.rateLimit);\n } else {\n app.use(\n rateLimit(\n deepmerge(\n {\n windowMs: 60 * 1000,\n limit: 300,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n handler: (_, res) => {\n res.status(429).json({\n message: \"Too many requests, please try again later\",\n });\n },\n },\n middlewaresConfig?.rateLimit || {}\n )\n )\n );\n }\n }\n\n if (middlewaresConfig?.cors !== false) {\n if (typeof middlewaresConfig?.cors === \"function\") {\n app.use(middlewaresConfig.cors);\n } else {\n app.use(\n cors(\n middlewaresConfig?.cors?.customHandler\n ? middlewaresConfig.cors.customHandler\n : deepmerge(\n {\n origin: (\n origin: string,\n cb: (err: Error | null, allow?: boolean) => void\n ) => {\n const allowed = (middlewaresConfig?.cors as any)\n ?.allowedOrigins;\n\n if (allowed === \"*\") cb(null, true);\n else if (Array.isArray(allowed))\n cb(null, !origin || allowed?.includes?.(origin));\n else if (typeof allowed === \"string\")\n cb(null, !origin || allowed === origin);\n else cb(null, false);\n },\n\n methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"],\n allowedHeaders: [\n \"Content-Type\",\n \"Authorization\",\n \"Connection\",\n ],\n credentials: true,\n },\n middlewaresConfig?.cors?.options || {}\n )\n )\n );\n }\n }\n\n if (middlewaresConfig?.expressJson !== false) {\n if (typeof middlewaresConfig?.expressJson === \"function\") {\n app.use(middlewaresConfig.expressJson);\n } else {\n app.use(express.json(middlewaresConfig?.expressJson || {}));\n }\n }\n\n if (middlewaresConfig?.cookieParser !== false) {\n if (typeof middlewaresConfig?.cookieParser === \"function\") {\n app.use(middlewaresConfig.cookieParser);\n } else {\n const params = Array.isArray(middlewaresConfig?.cookieParser)\n ? middlewaresConfig.cookieParser\n : [];\n app.use(cookieParser(...(params as any))); // FIXME: check types correctly\n }\n }\n\n if (middlewaresConfig?.queryParser !== false) {\n if (typeof middlewaresConfig?.queryParser === \"function\") {\n app.use(middlewaresConfig.queryParser);\n } else {\n app.use(\n queryParser(\n deepmerge(\n {\n parseNull: true,\n parseUndefined: true,\n parseBoolean: true,\n parseNumber: true,\n },\n middlewaresConfig?.queryParser || {}\n )\n )\n );\n }\n }\n\n app.use(debuggerService.logRequestInfo);\n\n const routersConfig = arkosConfig?.routers;\n\n if (routersConfig?.welcomeRoute !== false) {\n if (typeof routersConfig?.welcomeRoute === \"function\") {\n app.get(\"/api\", routersConfig.welcomeRoute);\n } else {\n app.get(\"/api\", (_, res) => {\n res.status(200).json({ message: arkosConfig.welcomeMessage });\n });\n }\n }\n\n if (initConfig?.use)\n for (const mwOrRouter of initConfig.use) {\n app.use(mwOrRouter as IRouter);\n }\n\n const fileUploadRouter = getFileUploadRouter(arkosConfig);\n knowModulesRouter.use(fileUploadRouter);\n\n if (isAuthenticationEnabled()) {\n const authRouter = getAuthRouter(arkosConfig) as any;\n knowModulesRouter.use(\"/api\", authRouter);\n }\n\n const modelsRouter = getPrismaModelsRouter(arkosConfig);\n knowModulesRouter.use(\"/api\", modelsRouter as any);\n\n app.use(knowModulesRouter);\n app.use(\"/api\", getAvailableResourcesAndRoutesRouter());\n\n if (\n arkosConfig.swagger &&\n (process.env.ARKOS_BUILD !== \"true\" ||\n arkosConfig.swagger.enableAfterBuild === true)\n )\n app.use(\"/api\", await getSwaggerRouter(arkosConfig, app));\n\n app.use(\"*\", (req) => {\n const url = lenientDecode(req.originalUrl);\n throw new AppError(\n `Route ${req.method.toUpperCase()} ${url} was not found`,\n 404,\n { route: `${req.method.toUpperCase()} ${url}` },\n \"RouteNotFound\"\n );\n });\n\n if (middlewaresConfig?.errorHandler !== false) {\n if (typeof middlewaresConfig?.errorHandler === \"function\") {\n app.use(middlewaresConfig.errorHandler);\n } else {\n app.use(errorHandler);\n }\n }\n\n return app;\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"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","sourcesContent":["import express, { IRouter, Router } from \"express\";\nimport cors from \"cors\";\nimport cookieParser from \"cookie-parser\";\nimport { getAuthRouter } from \"./modules/auth/auth.router\";\nimport {\n getPrismaModelsRouter,\n getAvailableResourcesAndRoutesRouter,\n} from \"./modules/base/base.router\";\nimport errorHandler from \"./modules/error-handler/error-handler.controller\";\nimport { rateLimit } from \"express-rate-limit\";\nimport compression from \"compression\";\nimport { handleRequestLogs } from \"./modules/base/base.middlewares\";\nimport { loadPrismaModule } from \"./utils/helpers/prisma.helpers\";\nimport { getFileUploadRouter } from \"./modules/file-upload/file-upload.router\";\nimport { queryParser } from \"./utils/helpers/query-parser.helpers\";\nimport deepmerge from \"./utils/helpers/deepmerge.helper\";\nimport { getSwaggerRouter } from \"./modules/swagger/swagger.router\";\nimport { loadAllModuleComponents } from \"./utils/dynamic-loader\";\nimport { AppError } from \"./exports/error-handler\";\nimport debuggerService from \"./modules/debugger/debugger.service\";\nimport { ArkosRequestHandler, getArkosConfig } from \"./exports\";\nimport { ArkosInitConfig } from \"./types/arkos-config\";\nimport {\n isAuthenticationEnabled,\n isProduction,\n validateArkosConfig,\n} from \"./utils/helpers/arkos-config.helpers\";\nimport { lenientDecode } from \"./utils/helpers/url-helpers\";\nimport sheu from \"./utils/sheu\";\nexport const app: express.Express = express();\nconst knowModulesRouter = Router();\n\nexport async function bootstrap(\n initConfig: ArkosInitConfig\n): Promise<express.Express> {\n const arkosConfig = getArkosConfig();\n\n await Promise.all([\n loadPrismaModule(),\n loadAllModuleComponents(arkosConfig),\n initConfig?.configureApp && (await initConfig?.configureApp(app)),\n ]);\n\n validateArkosConfig();\n const middlewaresConfig = arkosConfig?.middlewares;\n\n if (middlewaresConfig?.requestLogger !== false) {\n if (typeof middlewaresConfig?.requestLogger === \"function\") {\n app.use(middlewaresConfig.requestLogger);\n } else {\n app.use(handleRequestLogs);\n }\n }\n\n if (middlewaresConfig?.compression !== false) {\n if (typeof middlewaresConfig?.compression === \"function\") {\n app.use(middlewaresConfig.compression);\n } else {\n app.use(compression(middlewaresConfig?.compression || {}));\n }\n }\n\n if (middlewaresConfig?.rateLimit !== false) {\n if (typeof middlewaresConfig?.rateLimit === \"function\") {\n app.use(middlewaresConfig.rateLimit);\n } else {\n app.use(\n rateLimit(\n deepmerge(\n {\n windowMs: 60 * 1000,\n limit: 300,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n handler: (_, res) => {\n res.status(429).json({\n message: \"Too many requests, please try again later\",\n });\n },\n },\n middlewaresConfig?.rateLimit || {}\n )\n )\n );\n }\n }\n\n if (middlewaresConfig?.cors !== false) {\n const corsConfig = middlewaresConfig?.cors || {};\n\n if (\"customHandler\" in corsConfig)\n sheu.warn(\n \"cors.customHandler is deprecated. Pass the handler directly: `cors: myHandler`. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs\"\n );\n\n if (\"allowedOrigins\" in corsConfig)\n sheu.warn(\n \"cors.allowedOrigins is deprecated. Use `cors: { origin: '...' }` directly instead. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs\"\n );\n\n if (\"options\" in corsConfig)\n sheu.warn(\n \"cors.options is deprecated. Pass cors.CorsOptions directly instead. See https://www.arkosjs.com/blog/rethinking-cors-defaults-in-arkosjs\"\n );\n\n const defaultOptions = {\n origin: isProduction() ? \"*\" : true,\n methods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"],\n allowedHeaders: [\"Content-Type\", \"Authorization\", \"Connection\"],\n credentials: isProduction() ? false : true,\n };\n\n if (typeof corsConfig === \"function\") {\n if (corsConfig.length >= 3) {\n app.use(corsConfig as ArkosRequestHandler);\n } else {\n // cors.CorsOptionsDelegate — (req, cb)\n app.use(cors(corsConfig as cors.CorsOptionsDelegate));\n }\n } else if (\n middlewaresConfig?.cors &&\n typeof corsConfig === \"object\" &&\n \"customHandler\" in corsConfig\n ) {\n // { customHandler } shape — delegate entirely to user's handler\n app.use(cors(corsConfig.customHandler));\n } else if (\n middlewaresConfig?.cors &&\n typeof corsConfig === \"object\" &&\n !(\"allowedOrigins\" in corsConfig)\n ) {\n // Plain cors.CorsOptions passed directly at top level\n app.use(cors(deepmerge(defaultOptions, corsConfig as cors.CorsOptions)));\n } else {\n const { allowedOrigins, options } = corsConfig as {\n allowedOrigins?: string | string[] | \"*\";\n options?: cors.CorsOptions;\n };\n\n app.use(\n cors(\n deepmerge(defaultOptions, {\n origin: allowedOrigins ?? defaultOptions.origin,\n ...(options || {}),\n })\n )\n );\n }\n }\n\n if (middlewaresConfig?.expressJson !== false) {\n if (typeof middlewaresConfig?.expressJson === \"function\") {\n app.use(middlewaresConfig.expressJson);\n } else {\n app.use(express.json(middlewaresConfig?.expressJson || {}));\n }\n }\n\n if (middlewaresConfig?.cookieParser !== false) {\n if (typeof middlewaresConfig?.cookieParser === \"function\") {\n app.use(middlewaresConfig.cookieParser);\n } else {\n const params =\n typeof middlewaresConfig?.cookieParser == \"object\"\n ? middlewaresConfig.cookieParser\n : { secret: undefined, options: undefined };\n app.use(cookieParser(params.secret, params.options));\n }\n }\n\n if (middlewaresConfig?.queryParser !== false) {\n if (typeof middlewaresConfig?.queryParser === \"function\") {\n app.use(middlewaresConfig.queryParser);\n } else {\n app.use(\n queryParser(\n deepmerge(\n {\n parseNull: true,\n parseUndefined: true,\n parseBoolean: true,\n parseNumber: true,\n },\n middlewaresConfig?.queryParser || {}\n )\n )\n );\n }\n }\n\n app.use(debuggerService.logRequestInfo);\n\n const routersConfig = arkosConfig?.routers;\n\n if (routersConfig?.welcomeRoute !== false) {\n if (typeof routersConfig?.welcomeRoute === \"function\") {\n app.get(\"/api\", routersConfig.welcomeRoute);\n } else {\n app.get(\"/api\", (_, res) => {\n res.status(200).json({ message: arkosConfig.welcomeMessage });\n });\n }\n }\n\n if (initConfig?.use)\n for (const mwOrRouter of initConfig.use) {\n app.use(mwOrRouter as IRouter);\n }\n\n const fileUploadRouter = getFileUploadRouter(arkosConfig);\n knowModulesRouter.use(fileUploadRouter);\n\n if (isAuthenticationEnabled()) {\n const authRouter = getAuthRouter(arkosConfig) as any;\n knowModulesRouter.use(\"/api\", authRouter);\n }\n\n const modelsRouter = getPrismaModelsRouter(arkosConfig);\n knowModulesRouter.use(\"/api\", modelsRouter as any);\n\n app.use(knowModulesRouter);\n app.use(\"/api\", getAvailableResourcesAndRoutesRouter());\n\n if (\n arkosConfig.swagger &&\n (process.env.ARKOS_BUILD !== \"true\" ||\n arkosConfig.swagger.enableAfterBuild === true)\n )\n app.use(\"/api\", await getSwaggerRouter(arkosConfig, app));\n\n app.use(\"*\", (req) => {\n const url = lenientDecode(req.originalUrl);\n throw new AppError(\n `Route ${req.method.toUpperCase()} ${url} was not found`,\n 404,\n { route: `${req.method.toUpperCase()} ${url}` },\n \"RouteNotFound\"\n );\n });\n\n if (middlewaresConfig?.errorHandler !== false) {\n if (typeof middlewaresConfig?.errorHandler === \"function\") {\n app.use(middlewaresConfig.errorHandler);\n } else {\n app.use(errorHandler);\n }\n }\n\n return app;\n}\n"]}
@@ -77,6 +77,8 @@ class AuthService {
77
77
  return req.secure || req.headers["x-forwarded-proto"] === "https";
78
78
  })(),
79
79
  sameSite,
80
+ domain: authConfigs?.jwt?.cookie?.domain || process.env.JWT_COOKIE_DOMAIN,
81
+ ...arkosConfig?.authentication?.jwt?.cookie,
80
82
  };
81
83
  }
82
84
  isPasswordHashed(password) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.service.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt, { SignOptions } from \"jsonwebtoken\";\nimport bcrypt from \"bcryptjs\";\nimport { User } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { callNext } from \"../base/base.middlewares\";\nimport { getArkosConfig } from \"../../server\";\nimport arkosEnv from \"../../utils/arkos-env\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../types\";\nimport {\n AuthJwtPayload,\n AccessAction,\n AccessControlConfig,\n AuthenticationControlConfig,\n AccessControlRules,\n DetailedAccessControlRule,\n} from \"../../types/auth\";\nimport { MsDuration, toMs } from \"./utils/helpers/auth.controller.helpers\";\nimport { appModules, getModuleComponents } from \"../../utils/dynamic-loader\";\nimport { kebabCase } from \"../../exports/utils\";\nimport {\n invaliAuthTokenError,\n loginRequiredError,\n} from \"./utils/auth-error-objects\";\nimport authActionService from \"./utils/services/auth-action.service\";\nimport {\n isAuthenticationEnabled,\n isUsingAuthentication,\n} from \"../../utils/helpers/arkos-config.helpers\";\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nexport class AuthService {\n /**\n * Object containing a combination of actions per resource, tracked by each set of calls of `authService.handleAccessControl`, this can be accessed through the `authService` object or through the endpoint\n */\n actionsPerResource: Record<string, Set<string>> = {};\n\n /**\n * Signs a JWT token for the user.\n *\n * @param {number | string} id - The unique identifier of the user to generate the token for.\n * @param {string | number} [expiresIn] - The expiration time for the token. Defaults to environment variable `JWT_EXPIRES_IN`.\n * @param {string} [secret] - The secret key used to sign the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {string} The signed JWT token.\n */\n signJwtToken(\n id: number | string,\n expiresIn?: MsDuration | number,\n secret?: string\n ): string {\n const { authentication: configs } = getArkosConfig();\n\n if (\n process.env.ARKOS_BUILD === \"true\" &&\n !process.env.JWT_SECRET &&\n !configs?.jwt?.secret\n )\n throw new AppError(\n \"Missing JWT secret on production!\",\n 500,\n \"MissingJWTOnProduction\"\n );\n\n secret =\n secret ||\n configs?.jwt?.secret ||\n process.env.JWT_SECRET ||\n arkosEnv.JWT_SECRET;\n\n expiresIn = (expiresIn ||\n configs?.jwt?.expiresIn ||\n process.env.JWT_EXPIRES_IN ||\n arkosEnv.JWT_EXPIRES_IN) as keyof SignOptions[\"expiresIn\"];\n\n return jwt.sign({ id }, secret, {\n expiresIn: expiresIn as MsDuration,\n });\n }\n\n /**\n * Retrieves cookie configuration options for JWT authentication.\n *\n * Merges configuration from multiple sources in order of precedence:\n * 1. Arkos configuration file\n * 2. Environment variables\n * 3. Request properties (for secure flag)\n * 4. Default fallback values\n *\n * @param req - ArkosRequest object used to determine if the connection is secure\n * @returns Cookie options object with expires, httpOnly, secure, and sameSite properties\n *\n * @example\n * ```typescript\n * const cookieOptions = authService.getJwtCookieOptions(req);\n * res.cookie('jwt', token, cookieOptions);\n * ```\n */\n getJwtCookieOptions(req: ArkosRequest) {\n const arkosConfig = getArkosConfig();\n const authConfigs = arkosConfig?.authentication;\n\n if (!req)\n throw new Error(\"Missing req object in order get jwt cookie options\");\n\n const sameSite =\n authConfigs?.jwt?.cookie?.sameSite ||\n (process.env.JWT_COOKIE_SAME_SITE as\n | \"none\"\n | \"lax\"\n | \"strict\"\n | undefined) ||\n \"lax\";\n\n return {\n expires: new Date(\n Date.now() +\n Number(\n toMs(\n authConfigs?.jwt?.expiresIn ||\n (process.env.JWT_EXPIRES_IN as MsDuration) ||\n (arkosEnv.JWT_EXPIRES_IN as MsDuration)\n )\n )\n ),\n httpOnly:\n authConfigs?.jwt?.cookie?.httpOnly ??\n (process.env.JWT_COOKIE_HTTP_ONLY !== undefined\n ? process.env.JWT_COOKIE_HTTP_ONLY === \"true\"\n : undefined) ??\n true,\n secure: (() => {\n if (authConfigs?.jwt?.cookie?.secure !== undefined)\n return authConfigs?.jwt?.cookie?.secure;\n else if (process.env.JWT_COOKIE_SECURE !== undefined)\n return process.env.JWT_COOKIE_SECURE === \"true\";\n else return req.secure || req.headers[\"x-forwarded-proto\"] === \"https\";\n })(),\n sameSite,\n };\n }\n\n /**\n * Is used by default internally by Arkos under `BaseService` class to check if the password is already hashed.\n *\n * This was just added to prevent unwanted errors when someone just forgets that the `BaseService` class will automatically hash the password field using `authService.hashPassword` by default.\n *\n * So now before `BaseService` hashes it will test it.\n *\n *\n * @param password The password to be tested if is hashed\n * @returns\n */\n isPasswordHashed(password: string) {\n return !Number.isNaN(bcrypt.getRounds(password) * 1);\n }\n\n /**\n * Compares a candidate password with the stored user password to check if they match.\n *\n * @param {string} candidatePassword - The password provided by the user during login.\n * @param {string} userPassword - The password stored in the database.\n * @returns {Promise<boolean>} Returns true if the passwords match, otherwise false.\n */\n async isCorrectPassword(\n candidatePassword: string,\n userPassword: string\n ): Promise<boolean> {\n return await bcrypt.compare(candidatePassword, userPassword);\n }\n\n /**\n * Hashes a plain text password using bcrypt.\n *\n * @param {string} password - The password to be hashed.\n * @returns {Promise<string>} Returns the hashed password.\n */\n async hashPassword(password: string): Promise<string> {\n return await bcrypt.hash(password, 12);\n }\n\n /**\n * Checks if a password is strong, requiring uppercase, lowercase, and numeric characters as the default.\n *\n * **NB**: You must pay attention when using custom validation with zod or class-validator, try to use the same regex always.\n *\n * **Note**: You can define it when calling arkos.init()\n * ```ts\n * arkos.init({\n * authentication: {\n * passwordValidation:{ regex: /your-desired-regex/, message: 'password must contain...'}\n * }\n * })\n * ```\n *\n * @param {string} password - The password to check.\n * @returns {boolean} Returns true if the password meets the strength criteria, otherwise false.\n */\n public isPasswordStrong(password: string): boolean {\n const initAuthConfigs = getArkosConfig()?.authentication;\n\n const strongPasswordRegex =\n initAuthConfigs?.passwordValidation?.regex ||\n /^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/;\n return strongPasswordRegex.test(password);\n }\n\n /**\n * Checks if a user has changed their password after the JWT was issued.\n *\n * @param {User} user - The user object containing the passwordChangedAt field.\n * @param {number} JWTTimestamp - The timestamp when the JWT was issued.\n * @returns {boolean} Returns true if the user changed their password after the JWT was issued, otherwise false.\n */\n userChangedPasswordAfter(user: User, JWTTimestamp: number): boolean {\n if (user.passwordChangedAt) {\n const convertedTimestamp = parseInt(\n String(new Date(user.passwordChangedAt).getTime() / 1000),\n 10\n );\n\n return JWTTimestamp < convertedTimestamp;\n }\n return false;\n }\n\n /**\n * Verifies the authenticity of a JWT token.\n *\n * @param {string} token - The JWT token to verify.\n * @param {string} [secret] - The secret key used to verify the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {Promise<AuthJwtPayload>} Returns the decoded JWT payload if the token is valid.\n * @throws {Error} Throws an error if the token is invalid or expired.\n */\n async verifyJwtToken(\n token: string,\n secret?: string\n ): Promise<AuthJwtPayload> {\n const { authentication: configs } = getArkosConfig();\n\n if (\n process.env.ARKOS_BUILD === \"true\" &&\n !process.env.JWT_SECRET &&\n !configs?.jwt?.secret\n )\n throw new AppError(\n \"Missing JWT secret in production\",\n 500,\n \"MissingJWTSecretInProduction\"\n );\n\n secret =\n secret ||\n configs?.jwt?.secret ||\n process.env.JWT_SECRET ||\n arkosEnv.JWT_SECRET;\n\n return new Promise((resolve, reject) => {\n jwt.verify(token, secret, (err, decoded) => {\n if (err) reject(err);\n else resolve(decoded as AuthJwtPayload);\n });\n });\n }\n\n private isWildcardAccess(config: AccessControlConfig): config is \"*\" {\n return config === \"*\";\n }\n\n private isRoleList(config: AccessControlConfig): config is string[] {\n return Array.isArray(config);\n }\n\n private isAccessRules(\n config: AccessControlConfig\n ): config is Partial<AccessControlRules> {\n return (\n typeof config === \"object\" && config !== null && !Array.isArray(config)\n );\n }\n\n private normalizeRuleToRoles(\n rule: string[] | DetailedAccessControlRule | \"*\" | undefined\n ): string[] {\n if (!rule) return [];\n if (rule === \"*\") return [\"*\"];\n if (Array.isArray(rule)) return rule;\n return rule.roles === \"*\" ? [\"*\"] : (rule.roles ?? []);\n }\n\n private resolveAuthorizedRoles(\n action: AccessAction,\n accessControl: AccessControlConfig\n ): string[] {\n if (this.isWildcardAccess(accessControl)) return [\"*\"];\n if (this.isRoleList(accessControl)) return accessControl;\n if (this.isAccessRules(accessControl))\n return this.normalizeRuleToRoles(accessControl[action]);\n return [];\n }\n\n /**\n * Checks if a user has permission for a specific action using static access control rules.\n * Validates user roles against predefined access control configuration.\n *\n * @param user - The user object containing role or roles field\n * @param action - The action being performed\n * @param accessControl - Access control configuration (array of roles or object with action-role mappings)\n * @returns True if user has permission, false otherwise\n * @throws Error if user doesn't have role/roles field\n */\n protected checkStaticAccessControl(\n user: User,\n action: string,\n accessControl: AccessControlConfig\n ) {\n if (!user?.role && !user.roles)\n throw Error(\n \"Validation Error: In order to use static authentication user needs at least role field or roles for multiple roles.\"\n );\n\n let authorizedRoles = this.resolveAuthorizedRoles(action, accessControl);\n\n const userRoles = Array.isArray(user?.roles) ? user.roles : [user.role];\n\n return (\n authorizedRoles?.[0] === \"*\" ||\n !!userRoles.some((role: string) => authorizedRoles.includes(role))\n );\n }\n\n /**\n * Checks if a user has permission for a specific action and resource using dynamic access control.\n * Queries the database to verify user's role permissions.\n *\n * @param userId - The unique identifier of the user\n * @param action - The action being performed\n * @param resource - The resource being accessed\n * @returns Promise resolving to true if user has permission, false otherwise\n */\n protected async checkDynamicAccessControl(\n userId: string,\n action: string,\n resource: string\n ) {\n const prisma = getPrismaInstance();\n return !!(await prisma.userRole.findFirst({\n where: {\n userId,\n role: {\n permissions: {\n some: {\n resource,\n action,\n },\n },\n },\n },\n select: { id: true },\n }));\n }\n\n /**\n * Middleware function to handle access control based on user roles and permissions.\n *\n * @param {AccessAction} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} resource - The resource name that the action is being performed on (e.g., \"User\", \"Post\").\n * @param {AccessControlConfig} accessControl - The access control configuration.\n * @returns {ArkosRequestHandler} The middleware function that checks if the user has permission to perform the action.\n */\n handleAccessControl(\n action: AccessAction,\n resource: string,\n accessControl?: AccessControlConfig\n ): ArkosRequestHandler {\n if (\n !accessControl &&\n appModules.some(\n (appModule) => kebabCase(appModule) === kebabCase(resource)\n )\n )\n accessControl = getModuleComponents(resource)?.authConfigs?.accessControl;\n\n authActionService.add(action, resource, accessControl);\n\n return catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (req.user) {\n const user = req.user as User;\n const configs = getArkosConfig();\n\n if (user.isSuperUser) {\n next();\n return;\n }\n\n const notEnoughPermissionsError = new AppError(\n \"You do not have permission to perfom this action\",\n 403,\n {},\n \"NotEnoughPermissions\"\n );\n\n if (configs?.authentication?.mode === \"dynamic\") {\n const hasPermission = await this.checkDynamicAccessControl(\n user.id,\n action,\n resource\n );\n\n if (!hasPermission) return next(notEnoughPermissionsError);\n } else if (configs?.authentication?.mode === \"static\") {\n if (!accessControl) return next(notEnoughPermissionsError);\n\n const hasPermission = this.checkStaticAccessControl(\n user,\n action,\n accessControl\n );\n\n if (!hasPermission) return next(notEnoughPermissionsError);\n }\n }\n\n next();\n }\n );\n }\n\n /**\n * Processes the cookies or authoriation token and returns the user.\n * @param req\n * @returns {Promise<User | null>} - if authentication is turned off in arkosConfig it returns null\n * @throws {AppError} Throws an error if the token is invalid or the user is not logged in.\n */\n async getAuthenticatedUser(req: ArkosRequest): Promise<User | null> {\n if (!isAuthenticationEnabled())\n throw Error(\n \"ValidationError: Trying to call AuthService.getAuthenticatedUser without setting up authentication\"\n );\n\n const prisma = getPrismaInstance();\n\n let token: string | undefined;\n\n if (\n req?.headers?.authorization &&\n req?.headers?.authorization.startsWith(\"Bearer\") &&\n req?.headers?.authorization.split?.(\" \")?.[1]\n )\n token = req?.headers?.authorization.split(\" \")[1];\n\n if (\n !token &&\n req?.cookies?.arkos_access_token !== \"no-token\" &&\n req.cookies\n ) {\n token = req?.cookies?.arkos_access_token;\n }\n\n if (!token) return null;\n\n let decoded: AuthJwtPayload | undefined;\n\n try {\n decoded = await this.verifyJwtToken(token);\n } catch (err) {\n throw invaliAuthTokenError;\n }\n\n if (!decoded?.id) throw invaliAuthTokenError;\n const user: any | null = await (prisma as any).user.findUnique({\n where: { id: String(decoded.id) },\n });\n\n if (!user)\n throw new AppError(\n \"The user belonging to this token does no longer exists\",\n 401,\n \"UserNoLongerExists\"\n );\n\n if (\n this.userChangedPasswordAfter(user, decoded.iat!) &&\n !req.path?.includes?.(\"logout\")\n )\n throw new AppError(\n \"User recently changed password! Please log in again.\",\n 401,\n \"PasswordChanged\"\n );\n\n req.accessToken = token;\n return user;\n }\n\n /**\n * Middleware function to authenticate the user based on the JWT token.\n *\n * @param {ArkosRequest} req - The request object.\n * @param {ArkosResponse} res - The response object.\n * @param {ArkosNextFunction} next - The next middleware function to be called.\n * @returns {void}\n */\n authenticate = catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (isAuthenticationEnabled()) {\n const user = (await this.getAuthenticatedUser(req)) as User;\n if (!user) throw loginRequiredError;\n req.user = user;\n }\n next();\n }\n );\n\n /**\n * Handles authentication control by checking the `authenticationControl` configuration in the `authConfigs`.\n *\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {AuthenticationControlConfig} authenticationControl - The authentication configuration object.\n * @returns {ArkosRequestHandler} The middleware function that checks if authentication is required.\n */\n handleAuthenticationControl(\n action: AccessAction,\n authenticationControl?: AuthenticationControlConfig | undefined\n ): ArkosRequestHandler {\n if (authenticationControl && typeof authenticationControl === \"object\") {\n if (authenticationControl[action] === false) return callNext;\n else if (authenticationControl[action] === true) return this.authenticate;\n } else return this.authenticate;\n\n return this.authenticate;\n }\n\n /**\n * Creates a permission checker function for a specific action and resource.\n *\n * PS: This method should be called during application initialization to build permission validators.\n *\n * @see {@link https://www.arkosjs.com/docs/advanced-guide/fine-grained-access-control}\n *\n * @param action - The action to check permission for (e.g., 'View', 'Create', 'Delete')\n * @param resource - The resource being accessed, must be in kebabCase (e.g., 'user', 'cart-item', 'order')\n * @param accessControl - Access control rules (required for static authentication mode), and it is automatically loaded for known modules such as all prisma models, auth and file-upload.\n * @returns A function that takes a user object and returns a boolean indicating permission status\n *\n * @example\n * ```typescript\n * const hasViewProductPermission = await authService.permission('View', 'product');\n *\n * // Later in handler:\n * const canAccess = await hasViewProductPermission(user);\n * if (canAccess) {\n * // User has permission\n * }\n * ```\n */\n permission(\n action: string,\n resource: string,\n accessControl?: AccessControlConfig\n ) {\n // Check if called during request handling (deep call stack indicates handler execution)\n const stack = new Error().stack;\n\n if (stack?.includes(\"node_modules/express/lib/router/index.js\"))\n throw new Error(\n \"authService.permission() should be called during application initialization level.\"\n );\n\n authActionService.add(action, resource, accessControl);\n\n return async (user: User | undefined): Promise<boolean> => {\n // getArkosConfig must not be called the same time as arkos.init()\n const configs = getArkosConfig();\n\n if (!isUsingAuthentication())\n throw Error(\n \"Validation Error: Trying to use authService.permission without setting up authentication.\"\n );\n\n if (!isAuthenticationEnabled()) return false;\n if (!user) throw loginRequiredError;\n if (user?.isSuperUser) return true;\n\n if (configs?.authentication?.mode === \"dynamic\") {\n return await this.checkDynamicAccessControl(user?.id, action, resource);\n } else if (configs?.authentication?.mode === \"static\") {\n if (!accessControl && appModules.includes(kebabCase(resource)))\n accessControl = getModuleComponents(kebabCase(resource))?.authConfigs\n ?.accessControl;\n\n return (\n !!accessControl &&\n this.checkStaticAccessControl(user as any, action, accessControl)\n );\n }\n return false;\n };\n }\n}\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nconst authService = new AuthService();\n\nexport default authService;\n"]}
1
+ {"version":3,"file":"auth.service.js","sourceRoot":"","sources":["../../../../src/modules/auth/auth.service.ts"],"names":[],"mappings":"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","sourcesContent":["import jwt, { SignOptions } from \"jsonwebtoken\";\nimport bcrypt from \"bcryptjs\";\nimport { User } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { callNext } from \"../base/base.middlewares\";\nimport { getArkosConfig } from \"../../server\";\nimport arkosEnv from \"../../utils/arkos-env\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport {\n ArkosRequest,\n ArkosResponse,\n ArkosNextFunction,\n ArkosRequestHandler,\n} from \"../../types\";\nimport {\n AuthJwtPayload,\n AccessAction,\n AccessControlConfig,\n AuthenticationControlConfig,\n AccessControlRules,\n DetailedAccessControlRule,\n} from \"../../types/auth\";\nimport { MsDuration, toMs } from \"./utils/helpers/auth.controller.helpers\";\nimport { appModules, getModuleComponents } from \"../../utils/dynamic-loader\";\nimport { kebabCase } from \"../../exports/utils\";\nimport {\n invaliAuthTokenError,\n loginRequiredError,\n} from \"./utils/auth-error-objects\";\nimport authActionService from \"./utils/services/auth-action.service\";\nimport {\n isAuthenticationEnabled,\n isUsingAuthentication,\n} from \"../../utils/helpers/arkos-config.helpers\";\nimport { CookieOptions } from \"express\";\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nexport class AuthService {\n /**\n * Object containing a combination of actions per resource, tracked by each set of calls of `authService.handleAccessControl`, this can be accessed through the `authService` object or through the endpoint\n */\n actionsPerResource: Record<string, Set<string>> = {};\n\n /**\n * Signs a JWT token for the user.\n *\n * @param {number | string} id - The unique identifier of the user to generate the token for.\n * @param {string | number} [expiresIn] - The expiration time for the token. Defaults to environment variable `JWT_EXPIRES_IN`.\n * @param {string} [secret] - The secret key used to sign the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {string} The signed JWT token.\n */\n signJwtToken(\n id: number | string,\n expiresIn?: MsDuration | number,\n secret?: string\n ): string {\n const { authentication: configs } = getArkosConfig();\n\n if (\n process.env.ARKOS_BUILD === \"true\" &&\n !process.env.JWT_SECRET &&\n !configs?.jwt?.secret\n )\n throw new AppError(\n \"Missing JWT secret on production!\",\n 500,\n \"MissingJWTOnProduction\"\n );\n\n secret =\n secret ||\n configs?.jwt?.secret ||\n process.env.JWT_SECRET ||\n arkosEnv.JWT_SECRET;\n\n expiresIn = (expiresIn ||\n configs?.jwt?.expiresIn ||\n process.env.JWT_EXPIRES_IN ||\n arkosEnv.JWT_EXPIRES_IN) as keyof SignOptions[\"expiresIn\"];\n\n return jwt.sign({ id }, secret, {\n expiresIn: expiresIn as MsDuration,\n });\n }\n\n /**\n * Retrieves cookie configuration options for JWT authentication.\n *\n * Merges configuration from multiple sources in order of precedence:\n * 1. Arkos configuration file\n * 2. Environment variables\n * 3. Request properties (for secure flag)\n * 4. Default fallback values\n *\n * @param req - ArkosRequest object used to determine if the connection is secure\n * @returns Cookie options object with expires, httpOnly, secure, and sameSite properties\n *\n * @example\n * ```typescript\n * const cookieOptions = authService.getJwtCookieOptions(req);\n * res.cookie('jwt', token, cookieOptions);\n * ```\n */\n getJwtCookieOptions(req: ArkosRequest) {\n const arkosConfig = getArkosConfig();\n const authConfigs = arkosConfig?.authentication;\n\n if (!req)\n throw new Error(\"Missing req object in order get jwt cookie options\");\n\n const sameSite =\n authConfigs?.jwt?.cookie?.sameSite ||\n (process.env.JWT_COOKIE_SAME_SITE as\n | \"none\"\n | \"lax\"\n | \"strict\"\n | undefined) ||\n \"lax\";\n\n return {\n expires: new Date(\n Date.now() +\n Number(\n toMs(\n authConfigs?.jwt?.expiresIn ||\n (process.env.JWT_EXPIRES_IN as MsDuration) ||\n (arkosEnv.JWT_EXPIRES_IN as MsDuration)\n )\n )\n ),\n httpOnly:\n authConfigs?.jwt?.cookie?.httpOnly ??\n (process.env.JWT_COOKIE_HTTP_ONLY !== undefined\n ? process.env.JWT_COOKIE_HTTP_ONLY === \"true\"\n : undefined) ??\n true,\n secure: (() => {\n if (authConfigs?.jwt?.cookie?.secure !== undefined)\n return authConfigs?.jwt?.cookie?.secure;\n else if (process.env.JWT_COOKIE_SECURE !== undefined)\n return process.env.JWT_COOKIE_SECURE === \"true\";\n else return req.secure || req.headers[\"x-forwarded-proto\"] === \"https\";\n })(),\n sameSite,\n domain: authConfigs?.jwt?.cookie?.domain || process.env.JWT_COOKIE_DOMAIN,\n ...arkosConfig?.authentication?.jwt?.cookie,\n } as CookieOptions;\n }\n\n /**\n * Is used by default internally by Arkos under `BaseService` class to check if the password is already hashed.\n *\n * This was just added to prevent unwanted errors when someone just forgets that the `BaseService` class will automatically hash the password field using `authService.hashPassword` by default.\n *\n * So now before `BaseService` hashes it will test it.\n *\n *\n * @param password The password to be tested if is hashed\n * @returns\n */\n isPasswordHashed(password: string) {\n return !Number.isNaN(bcrypt.getRounds(password) * 1);\n }\n\n /**\n * Compares a candidate password with the stored user password to check if they match.\n *\n * @param {string} candidatePassword - The password provided by the user during login.\n * @param {string} userPassword - The password stored in the database.\n * @returns {Promise<boolean>} Returns true if the passwords match, otherwise false.\n */\n async isCorrectPassword(\n candidatePassword: string,\n userPassword: string\n ): Promise<boolean> {\n return await bcrypt.compare(candidatePassword, userPassword);\n }\n\n /**\n * Hashes a plain text password using bcrypt.\n *\n * @param {string} password - The password to be hashed.\n * @returns {Promise<string>} Returns the hashed password.\n */\n async hashPassword(password: string): Promise<string> {\n return await bcrypt.hash(password, 12);\n }\n\n /**\n * Checks if a password is strong, requiring uppercase, lowercase, and numeric characters as the default.\n *\n * **NB**: You must pay attention when using custom validation with zod or class-validator, try to use the same regex always.\n *\n * **Note**: You can define it when calling arkos.init()\n * ```ts\n * arkos.init({\n * authentication: {\n * passwordValidation:{ regex: /your-desired-regex/, message: 'password must contain...'}\n * }\n * })\n * ```\n *\n * @param {string} password - The password to check.\n * @returns {boolean} Returns true if the password meets the strength criteria, otherwise false.\n */\n public isPasswordStrong(password: string): boolean {\n const initAuthConfigs = getArkosConfig()?.authentication;\n\n const strongPasswordRegex =\n initAuthConfigs?.passwordValidation?.regex ||\n /^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/;\n return strongPasswordRegex.test(password);\n }\n\n /**\n * Checks if a user has changed their password after the JWT was issued.\n *\n * @param {User} user - The user object containing the passwordChangedAt field.\n * @param {number} JWTTimestamp - The timestamp when the JWT was issued.\n * @returns {boolean} Returns true if the user changed their password after the JWT was issued, otherwise false.\n */\n userChangedPasswordAfter(user: User, JWTTimestamp: number): boolean {\n if (user.passwordChangedAt) {\n const convertedTimestamp = parseInt(\n String(new Date(user.passwordChangedAt).getTime() / 1000),\n 10\n );\n\n return JWTTimestamp < convertedTimestamp;\n }\n return false;\n }\n\n /**\n * Verifies the authenticity of a JWT token.\n *\n * @param {string} token - The JWT token to verify.\n * @param {string} [secret] - The secret key used to verify the token. Defaults to environment variable `JWT_SECRET`.\n * @returns {Promise<AuthJwtPayload>} Returns the decoded JWT payload if the token is valid.\n * @throws {Error} Throws an error if the token is invalid or expired.\n */\n async verifyJwtToken(\n token: string,\n secret?: string\n ): Promise<AuthJwtPayload> {\n const { authentication: configs } = getArkosConfig();\n\n if (\n process.env.ARKOS_BUILD === \"true\" &&\n !process.env.JWT_SECRET &&\n !configs?.jwt?.secret\n )\n throw new AppError(\n \"Missing JWT secret in production\",\n 500,\n \"MissingJWTSecretInProduction\"\n );\n\n secret =\n secret ||\n configs?.jwt?.secret ||\n process.env.JWT_SECRET ||\n arkosEnv.JWT_SECRET;\n\n return new Promise((resolve, reject) => {\n jwt.verify(token, secret, (err, decoded) => {\n if (err) reject(err);\n else resolve(decoded as AuthJwtPayload);\n });\n });\n }\n\n private isWildcardAccess(config: AccessControlConfig): config is \"*\" {\n return config === \"*\";\n }\n\n private isRoleList(config: AccessControlConfig): config is string[] {\n return Array.isArray(config);\n }\n\n private isAccessRules(\n config: AccessControlConfig\n ): config is Partial<AccessControlRules> {\n return (\n typeof config === \"object\" && config !== null && !Array.isArray(config)\n );\n }\n\n private normalizeRuleToRoles(\n rule: string[] | DetailedAccessControlRule | \"*\" | undefined\n ): string[] {\n if (!rule) return [];\n if (rule === \"*\") return [\"*\"];\n if (Array.isArray(rule)) return rule;\n return rule.roles === \"*\" ? [\"*\"] : (rule.roles ?? []);\n }\n\n private resolveAuthorizedRoles(\n action: AccessAction,\n accessControl: AccessControlConfig\n ): string[] {\n if (this.isWildcardAccess(accessControl)) return [\"*\"];\n if (this.isRoleList(accessControl)) return accessControl;\n if (this.isAccessRules(accessControl))\n return this.normalizeRuleToRoles(accessControl[action]);\n return [];\n }\n\n /**\n * Checks if a user has permission for a specific action using static access control rules.\n * Validates user roles against predefined access control configuration.\n *\n * @param user - The user object containing role or roles field\n * @param action - The action being performed\n * @param accessControl - Access control configuration (array of roles or object with action-role mappings)\n * @returns True if user has permission, false otherwise\n * @throws Error if user doesn't have role/roles field\n */\n protected checkStaticAccessControl(\n user: User,\n action: string,\n accessControl: AccessControlConfig\n ) {\n if (!user?.role && !user.roles)\n throw Error(\n \"Validation Error: In order to use static authentication user needs at least role field or roles for multiple roles.\"\n );\n\n let authorizedRoles = this.resolveAuthorizedRoles(action, accessControl);\n\n const userRoles = Array.isArray(user?.roles) ? user.roles : [user.role];\n\n return (\n authorizedRoles?.[0] === \"*\" ||\n !!userRoles.some((role: string) => authorizedRoles.includes(role))\n );\n }\n\n /**\n * Checks if a user has permission for a specific action and resource using dynamic access control.\n * Queries the database to verify user's role permissions.\n *\n * @param userId - The unique identifier of the user\n * @param action - The action being performed\n * @param resource - The resource being accessed\n * @returns Promise resolving to true if user has permission, false otherwise\n */\n protected async checkDynamicAccessControl(\n userId: string,\n action: string,\n resource: string\n ) {\n const prisma = getPrismaInstance();\n return !!(await prisma.userRole.findFirst({\n where: {\n userId,\n role: {\n permissions: {\n some: {\n resource,\n action,\n },\n },\n },\n },\n select: { id: true },\n }));\n }\n\n /**\n * Middleware function to handle access control based on user roles and permissions.\n *\n * @param {AccessAction} action - The action being performed (e.g., create, update, delete, view).\n * @param {string} resource - The resource name that the action is being performed on (e.g., \"User\", \"Post\").\n * @param {AccessControlConfig} accessControl - The access control configuration.\n * @returns {ArkosRequestHandler} The middleware function that checks if the user has permission to perform the action.\n */\n handleAccessControl(\n action: AccessAction,\n resource: string,\n accessControl?: AccessControlConfig\n ): ArkosRequestHandler {\n if (\n !accessControl &&\n appModules.some(\n (appModule) => kebabCase(appModule) === kebabCase(resource)\n )\n )\n accessControl = getModuleComponents(resource)?.authConfigs?.accessControl;\n\n authActionService.add(action, resource, accessControl);\n\n return catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (req.user) {\n const user = req.user as User;\n const configs = getArkosConfig();\n\n if (user.isSuperUser) {\n next();\n return;\n }\n\n const notEnoughPermissionsError = new AppError(\n \"You do not have permission to perfom this action\",\n 403,\n {},\n \"NotEnoughPermissions\"\n );\n\n if (configs?.authentication?.mode === \"dynamic\") {\n const hasPermission = await this.checkDynamicAccessControl(\n user.id,\n action,\n resource\n );\n\n if (!hasPermission) return next(notEnoughPermissionsError);\n } else if (configs?.authentication?.mode === \"static\") {\n if (!accessControl) return next(notEnoughPermissionsError);\n\n const hasPermission = this.checkStaticAccessControl(\n user,\n action,\n accessControl\n );\n\n if (!hasPermission) return next(notEnoughPermissionsError);\n }\n }\n\n next();\n }\n );\n }\n\n /**\n * Processes the cookies or authoriation token and returns the user.\n * @param req\n * @returns {Promise<User | null>} - if authentication is turned off in arkosConfig it returns null\n * @throws {AppError} Throws an error if the token is invalid or the user is not logged in.\n */\n async getAuthenticatedUser(req: ArkosRequest): Promise<User | null> {\n if (!isAuthenticationEnabled())\n throw Error(\n \"ValidationError: Trying to call AuthService.getAuthenticatedUser without setting up authentication\"\n );\n\n const prisma = getPrismaInstance();\n\n let token: string | undefined;\n\n if (\n req?.headers?.authorization &&\n req?.headers?.authorization.startsWith(\"Bearer\") &&\n req?.headers?.authorization.split?.(\" \")?.[1]\n )\n token = req?.headers?.authorization.split(\" \")[1];\n\n if (\n !token &&\n req?.cookies?.arkos_access_token !== \"no-token\" &&\n req.cookies\n ) {\n token = req?.cookies?.arkos_access_token;\n }\n\n if (!token) return null;\n\n let decoded: AuthJwtPayload | undefined;\n\n try {\n decoded = await this.verifyJwtToken(token);\n } catch (err) {\n throw invaliAuthTokenError;\n }\n\n if (!decoded?.id) throw invaliAuthTokenError;\n const user: any | null = await (prisma as any).user.findUnique({\n where: { id: String(decoded.id) },\n });\n\n if (!user)\n throw new AppError(\n \"The user belonging to this token does no longer exists\",\n 401,\n \"UserNoLongerExists\"\n );\n\n if (\n this.userChangedPasswordAfter(user, decoded.iat!) &&\n !req.path?.includes?.(\"logout\")\n )\n throw new AppError(\n \"User recently changed password! Please log in again.\",\n 401,\n \"PasswordChanged\"\n );\n\n req.accessToken = token;\n return user;\n }\n\n /**\n * Middleware function to authenticate the user based on the JWT token.\n *\n * @param {ArkosRequest} req - The request object.\n * @param {ArkosResponse} res - The response object.\n * @param {ArkosNextFunction} next - The next middleware function to be called.\n * @returns {void}\n */\n authenticate = catchAsync(\n async (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (isAuthenticationEnabled()) {\n const user = (await this.getAuthenticatedUser(req)) as User;\n if (!user) throw loginRequiredError;\n req.user = user;\n }\n next();\n }\n );\n\n /**\n * Handles authentication control by checking the `authenticationControl` configuration in the `authConfigs`.\n *\n * @param {ControllerActions} action - The action being performed (e.g., create, update, delete, view).\n * @param {AuthenticationControlConfig} authenticationControl - The authentication configuration object.\n * @returns {ArkosRequestHandler} The middleware function that checks if authentication is required.\n */\n handleAuthenticationControl(\n action: AccessAction,\n authenticationControl?: AuthenticationControlConfig | undefined\n ): ArkosRequestHandler {\n if (authenticationControl && typeof authenticationControl === \"object\") {\n if (authenticationControl[action] === false) return callNext;\n else if (authenticationControl[action] === true) return this.authenticate;\n } else return this.authenticate;\n\n return this.authenticate;\n }\n\n /**\n * Creates a permission checker function for a specific action and resource.\n *\n * PS: This method should be called during application initialization to build permission validators.\n *\n * @see {@link https://www.arkosjs.com/docs/advanced-guide/fine-grained-access-control}\n *\n * @param action - The action to check permission for (e.g., 'View', 'Create', 'Delete')\n * @param resource - The resource being accessed, must be in kebabCase (e.g., 'user', 'cart-item', 'order')\n * @param accessControl - Access control rules (required for static authentication mode), and it is automatically loaded for known modules such as all prisma models, auth and file-upload.\n * @returns A function that takes a user object and returns a boolean indicating permission status\n *\n * @example\n * ```typescript\n * const hasViewProductPermission = await authService.permission('View', 'product');\n *\n * // Later in handler:\n * const canAccess = await hasViewProductPermission(user);\n * if (canAccess) {\n * // User has permission\n * }\n * ```\n */\n permission(\n action: string,\n resource: string,\n accessControl?: AccessControlConfig\n ) {\n // Check if called during request handling (deep call stack indicates handler execution)\n const stack = new Error().stack;\n\n if (stack?.includes(\"node_modules/express/lib/router/index.js\"))\n throw new Error(\n \"authService.permission() should be called during application initialization level.\"\n );\n\n authActionService.add(action, resource, accessControl);\n\n return async (user: User | undefined): Promise<boolean> => {\n // getArkosConfig must not be called the same time as arkos.init()\n const configs = getArkosConfig();\n\n if (!isUsingAuthentication())\n throw Error(\n \"Validation Error: Trying to use authService.permission without setting up authentication.\"\n );\n\n if (!isAuthenticationEnabled()) return false;\n if (!user) throw loginRequiredError;\n if (user?.isSuperUser) return true;\n\n if (configs?.authentication?.mode === \"dynamic\") {\n return await this.checkDynamicAccessControl(user?.id, action, resource);\n } else if (configs?.authentication?.mode === \"static\") {\n if (!accessControl && appModules.includes(kebabCase(resource)))\n accessControl = getModuleComponents(kebabCase(resource))?.authConfigs\n ?.accessControl;\n\n return (\n !!accessControl &&\n this.checkStaticAccessControl(user as any, action, accessControl)\n );\n }\n return false;\n };\n }\n}\n\n/**\n * Handles various authentication-related tasks such as JWT signing, password hashing, and verifying user credentials.\n */\nconst authService = new AuthService();\n\nexport default authService;\n"]}
@@ -67,8 +67,21 @@ class BaseController {
67
67
  accessToken: req?.accessToken,
68
68
  }),
69
69
  ]);
70
+ const take = serviceArgs[1]?.take ?? null;
71
+ const skip = serviceArgs[1]?.skip ?? 0;
72
+ const limit = take ?? total;
73
+ const currentPage = limit > 0 ? Math.floor(skip / limit) + 1 : 1;
74
+ const totalPages = limit > 0 ? Math.ceil(total / limit) : 1;
70
75
  data = records;
71
- additionalData = { total, results: records.length };
76
+ additionalData = {
77
+ total,
78
+ results: records.length,
79
+ page: currentPage,
80
+ pages: totalPages,
81
+ limit,
82
+ hasNextPage: currentPage < totalPages,
83
+ hasPrevPage: currentPage > 1,
84
+ };
72
85
  }
73
86
  const error = config.errorHandler
74
87
  ? config.errorHandler(data, req, this.modelName)
@@ -256,8 +269,7 @@ class BaseController {
256
269
  defaultResponseBuilder(data, additionalData, operationType) {
257
270
  if (operationType === "findMany" && additionalData)
258
271
  return {
259
- total: additionalData.total,
260
- results: additionalData.results,
272
+ ...additionalData,
261
273
  data,
262
274
  };
263
275
  if (operationType.includes("Many") &&
@@ -1 +1 @@
1
- {"version":3,"file":"base.controller.js","sourceRoot":"","sources":["../../../../src/modules/base/base.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { ArkosRequest, ArkosResponse, ArkosNextFunction } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport { BaseService } from \"./base.service\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { kebabCase, pascalCase } from \"../../utils/helpers/change-case.helpers\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport pluralize from \"pluralize\";\nimport sheu from \"../../utils/sheu\";\nimport prismaSchemaParser from \"../../utils/prisma/prisma-schema-parser\";\nimport { APIFeatures } from \"../../exports/utils\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\n\nexport interface OperationHooks {\n beforeQuery?: (req: ArkosRequest) => void | Promise<void>;\n afterQuery?: (\n queryData: { where: any; queryOptions: any },\n req: ArkosRequest\n ) => void | Promise<void>;\n beforeService?: (args: any[], req: ArkosRequest) => any[] | Promise<any[]>;\n afterService?: (data: any, req: ArkosRequest) => any | Promise<any>;\n beforeResponse?: (responseData: any, req: ArkosRequest) => any | Promise<any>;\n}\n\ninterface OperationConfig {\n operationType: string;\n serviceMethod: string;\n successStatus: number;\n queryFeatures: (\"filter\" | \"sort\" | \"limitFields\" | \"paginate\")[];\n requiresQueryForBulk?: boolean;\n preventORFilter?: boolean;\n responseBuilder?: (data: any, additionalData?: any) => any;\n errorHandler?: (\n data: any,\n req: ArkosRequest,\n modelName: string\n ) => AppError | null;\n usesRequestParams?: boolean;\n usesRequestBody?: boolean;\n hooks?: OperationHooks;\n}\n\n/**\n * The `BaseController` class provides standardized RESTful API endpoints\n * for any Prisma model based on its name. It supports automatic integration\n * with Prisma services and dynamic middleware hooks for extending behaviors.\n *\n * This controller includes:\n * - `createOne` / `createMany`\n * - `findOne` / `findMany`\n * - `updateOne` / `updateMany`\n * - `deleteOne` / `deleteMany`\n *\n * It handles:\n * - Prisma query options\n * - APIFeatures: filtering, sorting, pagination, field limiting\n * - Middleware hooks: `afterCreateOne`, `afterUpdateMany`, etc.\n *\n * @class BaseController\n *\n * @param {string} modelName - The Prisma model name this controller handles.\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-controller-class}\n *--\n * **See about how Arkos handles routers**\n * @see {@link https://www.arkosjs.com/docs/guide/adding-custom-routers}\n */\nexport class BaseController {\n /**\n * Service instance to handle business logic operations\n * @private\n */\n private service: BaseService<any>;\n\n /**\n * Name of the model this controller handles\n * @private\n */\n private modelName: string;\n\n /**\n * Model-specific interceptors loaded from model modules\n * @private\n */\n private interceptors: any;\n\n /**\n * Creates a new BaseController instance\n * @param {string} modelName - The name of the model for which this controller will handle operations\n */\n constructor(modelName: string) {\n const components = getModuleComponents(modelName);\n\n this.modelName = modelName;\n this.service = new BaseService(modelName);\n this.interceptors = components?.interceptors || {};\n }\n\n private executeOperation = (config: OperationConfig) => {\n return catchAsync(\n async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (config.hooks?.beforeQuery) await config.hooks.beforeQuery(req);\n\n if (config.requiresQueryForBulk) {\n if (\n Object.keys(req.query).every((key) =>\n [\"filterMode\", \"prismaQueryOptions\"].includes(key)\n )\n ) {\n return next(\n new AppError(\n `Filter criteria not provided for bulk ${config.operationType.replace(/Many$/, \"\")}.`,\n 400,\n {},\n \"MissingRequestQueryParameters\"\n )\n );\n }\n }\n\n if (config.preventORFilter && req.query.filterMode === \"OR\") {\n throw new AppError(\n `req.query.filterMode === OR is not valid for ${config.operationType} operation`,\n 400\n );\n }\n\n if (config.preventORFilter) req.query.filterMode = \"AND\";\n\n let apiFeatures = new APIFeatures(req, this.modelName);\n\n config.queryFeatures.forEach((feature) => {\n switch (feature) {\n case \"filter\":\n apiFeatures = apiFeatures.filter();\n break;\n case \"sort\":\n apiFeatures = apiFeatures.sort();\n break;\n case \"limitFields\":\n apiFeatures = apiFeatures.limitFields();\n break;\n case \"paginate\":\n apiFeatures = apiFeatures.paginate();\n break;\n }\n });\n\n const { where, ...queryOptions } = apiFeatures.filters;\n\n if (config.hooks?.afterQuery)\n await config.hooks.afterQuery({ where, queryOptions }, req);\n\n let serviceArgs = this.buildServiceArgs(\n config,\n req,\n where,\n queryOptions\n );\n\n if (config.hooks?.beforeService)\n serviceArgs = await config.hooks.beforeService(serviceArgs, req);\n\n const serviceMethod = this.service[\n config.serviceMethod as keyof BaseService<any>\n ] as Function;\n let result = await serviceMethod.apply(this.service, serviceArgs);\n\n if (config.hooks?.afterService)\n result = await config.hooks.afterService(result, req);\n\n let data = result;\n let additionalData: any = null;\n\n if (config.operationType === \"findMany\") {\n const [records, total] = await Promise.all([\n result,\n this.service.count(where, {\n user: req?.user,\n accessToken: req?.accessToken,\n }),\n ]);\n data = records;\n additionalData = { total, results: records.length };\n }\n\n const error = config.errorHandler\n ? config.errorHandler(data, req, this.modelName)\n : this.defaultErrorHandler(data, req, config.operationType);\n\n if (error) return next(error);\n\n let responseData = config.responseBuilder\n ? config.responseBuilder(data, additionalData)\n : this.defaultResponseBuilder(\n data,\n additionalData,\n config.operationType\n );\n\n if (config.hooks?.beforeResponse) {\n responseData = await config.hooks.beforeResponse(responseData, req);\n }\n\n const interceptorName = `after${config.operationType.charAt(0).toUpperCase()}${config.operationType.slice(1)}`;\n\n if (this.interceptors[interceptorName]) {\n this.setResponseData(req, res, responseData, config.successStatus);\n next();\n return;\n }\n\n if (config.operationType === \"deleteOne\") {\n res.status(config.successStatus).send();\n return;\n }\n\n res.status(config.successStatus).json(responseData);\n }\n );\n };\n\n /**\n * Sets response data for both legacy (req.responseData) and modern (res.locals) support\n */\n private setResponseData(\n req: ArkosRequest,\n res: ArkosResponse,\n data: any,\n status: number\n ): void {\n (res as any).originalData = data;\n req.responseData = data;\n res.locals.data = data;\n (res as any).originalStatus = status;\n req.responseStatus = status;\n res.locals.status = status;\n\n // Special handling for deleteOne\n if (status === 204) {\n req.additionalData = data;\n res.locals.additionalData = data;\n (res as any).originalAdditionalData = data;\n }\n }\n\n /**\n * Builds service method arguments based on operation configuration\n */\n private buildServiceArgs(\n config: OperationConfig,\n req: ArkosRequest,\n where: any,\n queryOptions: any\n ): any[] {\n const context = { user: req?.user, accessToken: req?.accessToken };\n const mergedOptions = deepmerge(req.prismaQueryOptions || {}, queryOptions);\n\n switch (config.operationType) {\n case \"createOne\":\n case \"createMany\":\n return [req.body, mergedOptions, context];\n\n case \"findMany\":\n return [where, queryOptions, context];\n\n case \"findOne\":\n return [{ ...req.params, ...where }, mergedOptions, context];\n\n case \"updateOne\":\n return [{ ...req.params, ...where }, req.body, mergedOptions, context];\n\n case \"updateMany\":\n // Remove include for bulk operations\n delete queryOptions.include;\n return [where, req.body, queryOptions, context];\n\n case \"batchUpdate\":\n return [req.body, mergedOptions, context];\n\n case \"deleteOne\":\n return [{ ...req.params, ...where }, context];\n\n case \"deleteMany\":\n return [where, context];\n\n case \"batchDelete\":\n return [req.body, context];\n\n default:\n throw new Error(`Unknown operation type: ${config.operationType}`);\n }\n }\n\n /**\n * Default error handler for operations\n */\n private defaultErrorHandler(\n data: any,\n req: ArkosRequest,\n operationType: string\n ): AppError | null {\n if (!data || (Array.isArray(data) && data.length === 0)) {\n // Handle different error scenarios\n if (operationType.includes(\"create\") || operationType.includes(\"batch\")) {\n return new AppError(\n \"Failed to create the resources. Please check your input.\",\n 400,\n { body: req.body }\n );\n }\n\n if (\n operationType === \"findOne\" ||\n operationType === \"updateOne\" ||\n operationType === \"deleteOne\"\n ) {\n if (\n Object.keys(req.params).length === 1 &&\n \"id\" in req.params &&\n req.params.id !== \"me\"\n ) {\n return new AppError(\n `${pascalCase(String(this.modelName))} with ID ${req.params?.id} not found`,\n 404,\n {},\n \"NotFound\"\n );\n } else {\n return new AppError(\n `${pascalCase(String(this.modelName))} not found`,\n 404,\n {},\n \"NotFound\"\n );\n }\n }\n\n if (operationType === \"updateMany\" || operationType === \"deleteMany\") {\n const isUpdate = operationType === \"updateMany\";\n return new AppError(\n isUpdate\n ? `${pluralize(pascalCase(String(this.modelName)))} not found`\n : `No records found to delete`,\n 404,\n {},\n \"NotFound\"\n );\n }\n }\n\n // Special handling for operations that return count\n if (\n data &&\n typeof data === \"object\" &&\n \"count\" in data &&\n data.count === 0\n ) {\n return new AppError(\n operationType === \"updateMany\"\n ? `${pluralize(pascalCase(String(this.modelName)))} not found`\n : `No records found to delete`,\n 404,\n {},\n \"NotFound\"\n );\n }\n\n return null;\n }\n\n /**\n * Default response builder for operations\n */\n private defaultResponseBuilder(\n data: any,\n additionalData: any,\n operationType: string\n ): any {\n if (operationType === \"findMany\" && additionalData)\n return {\n total: additionalData.total,\n results: additionalData.results,\n data,\n };\n\n if (\n operationType.includes(\"Many\") &&\n data &&\n typeof data === \"object\" &&\n \"count\" in data\n )\n return { results: data.count, data };\n\n if (operationType.includes(\"batch\") && Array.isArray(data))\n return { results: data.length, data };\n\n return { data };\n }\n\n /**\n * Creates a single resource\n */\n createOne = this.executeOperation({\n operationType: \"createOne\",\n serviceMethod: \"createOne\",\n successStatus: 201,\n queryFeatures: [\"limitFields\"],\n usesRequestBody: true,\n });\n\n /**\n * Creates multiple resources in a single operation\n */\n createMany = this.executeOperation({\n operationType: \"createMany\",\n serviceMethod: \"createMany\",\n successStatus: 201,\n queryFeatures: [\"limitFields\"],\n usesRequestBody: true,\n hooks: {\n async beforeQuery(req) {\n if (!req.body || (Array.isArray(req.body) && req.body.length === 0))\n throw new AppError(\n \"Expected request body array to contain at least on item but received none\",\n 400,\n { body: req.body },\n \"MissingArrayRequestBody\"\n );\n },\n },\n });\n\n /**\n * Retrieves multiple resources with filtering, sorting, pagination, and field selection\n */\n findMany = this.executeOperation({\n operationType: \"findMany\",\n serviceMethod: \"findMany\",\n successStatus: 200,\n queryFeatures: [\"filter\", \"sort\", \"limitFields\", \"paginate\"],\n });\n\n /**\n * Retrieves a single resource by its identifier\n */\n findOne = this.executeOperation({\n operationType: \"findOne\",\n serviceMethod: \"findOne\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestParams: true,\n });\n\n /**\n * Updates a single resource by its identifier\n */\n updateOne = this.executeOperation({\n operationType: \"updateOne\",\n serviceMethod: \"updateOne\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestParams: true,\n usesRequestBody: true,\n });\n\n /**\n * Updates multiple resources that match specified criteria\n */\n updateMany = this.executeOperation({\n operationType: \"updateMany\",\n serviceMethod: \"updateMany\",\n successStatus: 200,\n queryFeatures: [\"filter\", \"limitFields\"],\n requiresQueryForBulk: true,\n preventORFilter: true,\n usesRequestBody: true,\n });\n\n /**\n * Updates multiple resources with different data in a single transaction\n */\n batchUpdate = this.executeOperation({\n operationType: \"batchUpdate\",\n serviceMethod: \"batchUpdate\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestBody: true,\n });\n\n /**\n * Deletes a single resource by its identifier\n */\n deleteOne = this.executeOperation({\n operationType: \"deleteOne\",\n serviceMethod: \"deleteOne\",\n successStatus: 204,\n queryFeatures: [\"filter\"],\n usesRequestParams: true,\n });\n\n /**\n * Deletes multiple resources that match specified criteria\n */\n deleteMany = this.executeOperation({\n operationType: \"deleteMany\",\n serviceMethod: \"deleteMany\",\n successStatus: 200,\n queryFeatures: [\"filter\"],\n requiresQueryForBulk: true,\n preventORFilter: true,\n });\n\n /**\n * Deletes multiple resources with different filters in a single transaction\n */\n batchDelete = this.executeOperation({\n operationType: \"batchDelete\",\n serviceMethod: \"batchDelete\",\n successStatus: 200,\n queryFeatures: [\"filter\"],\n usesRequestBody: true,\n });\n}\n\n/**\n * Returns a list of all available resource endpoints based on the application's models\n *\n * Will soon be removed\n *\n * @param {ArkosRequest} req - Express request object\n * @param {ArkosResponse} res - Express response object\n * @param {ArkosNextFunction} next - Express next function\n * @returns {Promise<void>}\n */\nexport const getAvailableResources = catchAsync(\n async (_: any, res: ArkosResponse) => {\n sheu.warn(\n \"This route `/api/available-resources` will be deprecated from 1.4.0-beta, consider using /api/auth-actions instead.\"\n );\n\n res.status(200).json({\n data: [\n ...prismaSchemaParser\n .getModelsAsArrayOfStrings()\n .map((model) => kebabCase(model)),\n \"file-upload\",\n ],\n });\n }\n);\n"]}
1
+ {"version":3,"file":"base.controller.js","sourceRoot":"","sources":["../../../../src/modules/base/base.controller.ts"],"names":[],"mappings":";;;;;;AACA,qFAA4D;AAC5D,iDAA6C;AAC7C,iFAAwD;AACxD,iFAAgF;AAChF,+DAAiE;AACjE,0DAAkC;AAClC,4DAAoC;AACpC,mGAAyE;AACzE,+CAAkD;AAClD,4FAA6D;AAwD7D,MAAa,cAAc;IAuBzB,YAAY,SAAiB;QAQrB,qBAAgB,GAAG,CAAC,MAAuB,EAAE,EAAE;YACrD,OAAO,IAAA,qBAAU,EACf,KAAK,EACH,GAAiB,EACjB,GAAkB,EAClB,IAAuB,EACvB,EAAE;gBACF,IAAI,MAAM,CAAC,KAAK,EAAE,WAAW;oBAAE,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBAEnE,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;oBAChC,IACE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CACnC,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CACnD,EACD,CAAC;wBACD,OAAO,IAAI,CACT,IAAI,mBAAQ,CACV,yCAAyC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EACrF,GAAG,EACH,EAAE,EACF,+BAA+B,CAChC,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,IAAI,MAAM,CAAC,eAAe,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC5D,MAAM,IAAI,mBAAQ,CAChB,gDAAgD,MAAM,CAAC,aAAa,YAAY,EAChF,GAAG,CACJ,CAAC;gBACJ,CAAC;gBAED,IAAI,MAAM,CAAC,eAAe;oBAAE,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;gBAEzD,IAAI,WAAW,GAAG,IAAI,mBAAW,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAEvD,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;oBACvC,QAAQ,OAAO,EAAE,CAAC;wBAChB,KAAK,QAAQ;4BACX,WAAW,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;4BACnC,MAAM;wBACR,KAAK,MAAM;4BACT,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;4BACjC,MAAM;wBACR,KAAK,aAAa;4BAChB,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;4BACxC,MAAM;wBACR,KAAK,UAAU;4BACb,WAAW,GAAG,WAAW,CAAC,QAAQ,EAAE,CAAC;4BACrC,MAAM;oBACV,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;gBAEvD,IAAI,MAAM,CAAC,KAAK,EAAE,UAAU;oBAC1B,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,GAAG,CAAC,CAAC;gBAE9D,IAAI,WAAW,GAAG,IAAI,CAAC,gBAAgB,CACrC,MAAM,EACN,GAAG,EACH,KAAK,EACL,YAAY,CACb,CAAC;gBAEF,IAAI,MAAM,CAAC,KAAK,EAAE,aAAa;oBAC7B,WAAW,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBAEnE,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAChC,MAAM,CAAC,aAAuC,CACnC,CAAC;gBACd,IAAI,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBAElE,IAAI,MAAM,CAAC,KAAK,EAAE,YAAY;oBAC5B,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAExD,IAAI,IAAI,GAAG,MAAM,CAAC;gBAClB,IAAI,cAAc,GAAQ,IAAI,CAAC;gBAE/B,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;oBACxC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;wBACzC,MAAM;wBACN,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE;4BACxB,IAAI,EAAE,GAAG,EAAE,IAAI;4BACf,WAAW,EAAE,GAAG,EAAE,WAAW;yBAC9B,CAAC;qBACH,CAAC,CAAC;oBAEH,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;oBAC1C,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC;oBAEvC,MAAM,KAAK,GAAG,IAAI,IAAI,KAAK,CAAC;oBAC5B,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjE,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAE5D,IAAI,GAAG,OAAO,CAAC;oBACf,cAAc,GAAG;wBACf,KAAK;wBACL,OAAO,EAAE,OAAO,CAAC,MAAM;wBACvB,IAAI,EAAE,WAAW;wBACjB,KAAK,EAAE,UAAU;wBACjB,KAAK;wBACL,WAAW,EAAE,WAAW,GAAG,UAAU;wBACrC,WAAW,EAAE,WAAW,GAAG,CAAC;qBAC7B,CAAC;gBACJ,CAAC;gBAED,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY;oBAC/B,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC;oBAChD,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;gBAE9D,IAAI,KAAK;oBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;gBAE9B,IAAI,YAAY,GAAG,MAAM,CAAC,eAAe;oBACvC,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,cAAc,CAAC;oBAC9C,CAAC,CAAC,IAAI,CAAC,sBAAsB,CACzB,IAAI,EACJ,cAAc,EACd,MAAM,CAAC,aAAa,CACrB,CAAC;gBAEN,IAAI,MAAM,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC;oBACjC,YAAY,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;gBACtE,CAAC;gBAED,MAAM,eAAe,GAAG,QAAQ,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE/G,IAAI,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC;oBACvC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;oBACnE,IAAI,EAAE,CAAC;oBACP,OAAO;gBACT,CAAC;gBAED,IAAI,MAAM,CAAC,aAAa,KAAK,WAAW,EAAE,CAAC;oBACzC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC;oBACxC,OAAO;gBACT,CAAC;gBAED,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACtD,CAAC,CACF,CAAC;QACJ,CAAC,CAAC;QAsLF,cAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAChC,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,aAAa,CAAC;YAC9B,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAKH,eAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;YACjC,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,aAAa,CAAC;YAC9B,eAAe,EAAE,IAAI;YACrB,KAAK,EAAE;gBACL,KAAK,CAAC,WAAW,CAAC,GAAG;oBACnB,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC;wBACjE,MAAM,IAAI,mBAAQ,CAChB,2EAA2E,EAC3E,GAAG,EACH,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAClB,yBAAyB,CAC1B,CAAC;gBACN,CAAC;aACF;SACF,CAAC,CAAC;QAKH,aAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAC/B,aAAa,EAAE,UAAU;YACzB,aAAa,EAAE,UAAU;YACzB,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,CAAC;SAC7D,CAAC,CAAC;QAKH,YAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAC9B,aAAa,EAAE,SAAS;YACxB,aAAa,EAAE,SAAS;YACxB,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;YACxC,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QAKH,cAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAChC,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;YACxC,iBAAiB,EAAE,IAAI;YACvB,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAKH,eAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;YACjC,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC;YACxC,oBAAoB,EAAE,IAAI;YAC1B,eAAe,EAAE,IAAI;YACrB,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAKH,gBAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAClC,aAAa,EAAE,aAAa;YAC5B,aAAa,EAAE,aAAa;YAC5B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC;YACxC,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAKH,cAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAChC,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,WAAW;YAC1B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,QAAQ,CAAC;YACzB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAC;QAKH,eAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC;YACjC,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,YAAY;YAC3B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,QAAQ,CAAC;YACzB,oBAAoB,EAAE,IAAI;YAC1B,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAKH,gBAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC;YAClC,aAAa,EAAE,aAAa;YAC5B,aAAa,EAAE,aAAa;YAC5B,aAAa,EAAE,GAAG;YAClB,aAAa,EAAE,CAAC,QAAQ,CAAC;YACzB,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAlcD,MAAM,UAAU,GAAG,IAAA,oCAAmB,EAAC,SAAS,CAAC,CAAC;QAElD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,0BAAW,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,YAAY,GAAG,UAAU,EAAE,YAAY,IAAI,EAAE,CAAC;IACrD,CAAC;IAqJO,eAAe,CACrB,GAAiB,EACjB,GAAkB,EAClB,IAAS,EACT,MAAc;QAEb,GAAW,CAAC,YAAY,GAAG,IAAI,CAAC;QACjC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC;QACxB,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACtB,GAAW,CAAC,cAAc,GAAG,MAAM,CAAC;QACrC,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC;QAC5B,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;QAG3B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;YAChC,GAAW,CAAC,sBAAsB,GAAG,IAAI,CAAC;QAC7C,CAAC;IACH,CAAC;IAKO,gBAAgB,CACtB,MAAuB,EACvB,GAAiB,EACjB,KAAU,EACV,YAAiB;QAEjB,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;QACnE,MAAM,aAAa,GAAG,IAAA,0BAAS,EAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,EAAE,YAAY,CAAC,CAAC;QAE5E,QAAQ,MAAM,CAAC,aAAa,EAAE,CAAC;YAC7B,KAAK,WAAW,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAE5C,KAAK,UAAU;gBACb,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YAExC,KAAK,SAAS;gBACZ,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAE/D,KAAK,WAAW;gBACd,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAEzE,KAAK,YAAY;gBAEf,OAAO,YAAY,CAAC,OAAO,CAAC;gBAC5B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;YAElD,KAAK,aAAa;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAE5C,KAAK,WAAW;gBACd,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;YAEhD,KAAK,YAAY;gBACf,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAE1B,KAAK,aAAa;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAE7B;gBACE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAKO,mBAAmB,CACzB,IAAS,EACT,GAAiB,EACjB,aAAqB;QAErB,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YAExD,IAAI,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxE,OAAO,IAAI,mBAAQ,CACjB,0DAA0D,EAC1D,GAAG,EACH,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CACnB,CAAC;YACJ,CAAC;YAED,IACE,aAAa,KAAK,SAAS;gBAC3B,aAAa,KAAK,WAAW;gBAC7B,aAAa,KAAK,WAAW,EAC7B,CAAC;gBACD,IACE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;oBACpC,IAAI,IAAI,GAAG,CAAC,MAAM;oBAClB,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,EACtB,CAAC;oBACD,OAAO,IAAI,mBAAQ,CACjB,GAAG,IAAA,gCAAU,EAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,EAAE,YAAY,EAC3E,GAAG,EACH,EAAE,EACF,UAAU,CACX,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,IAAI,mBAAQ,CACjB,GAAG,IAAA,gCAAU,EAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,YAAY,EACjD,GAAG,EACH,EAAE,EACF,UAAU,CACX,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,IAAI,aAAa,KAAK,YAAY,IAAI,aAAa,KAAK,YAAY,EAAE,CAAC;gBACrE,MAAM,QAAQ,GAAG,aAAa,KAAK,YAAY,CAAC;gBAChD,OAAO,IAAI,mBAAQ,CACjB,QAAQ;oBACN,CAAC,CAAC,GAAG,IAAA,mBAAS,EAAC,IAAA,gCAAU,EAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY;oBAC9D,CAAC,CAAC,4BAA4B,EAChC,GAAG,EACH,EAAE,EACF,UAAU,CACX,CAAC;YACJ,CAAC;QACH,CAAC;QAGD,IACE,IAAI;YACJ,OAAO,IAAI,KAAK,QAAQ;YACxB,OAAO,IAAI,IAAI;YACf,IAAI,CAAC,KAAK,KAAK,CAAC,EAChB,CAAC;YACD,OAAO,IAAI,mBAAQ,CACjB,aAAa,KAAK,YAAY;gBAC5B,CAAC,CAAC,GAAG,IAAA,mBAAS,EAAC,IAAA,gCAAU,EAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY;gBAC9D,CAAC,CAAC,4BAA4B,EAChC,GAAG,EACH,EAAE,EACF,UAAU,CACX,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAKO,sBAAsB,CAC5B,IAAS,EACT,cAAmB,EACnB,aAAqB;QAErB,IAAI,aAAa,KAAK,UAAU,IAAI,cAAc;YAChD,OAAO;gBACL,GAAG,cAAc;gBACjB,IAAI;aACL,CAAC;QAEJ,IACE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC9B,IAAI;YACJ,OAAO,IAAI,KAAK,QAAQ;YACxB,OAAO,IAAI,IAAI;YAEf,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;QAEvC,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YACxD,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QAExC,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;CA6HF;AA3dD,wCA2dC;AAYY,QAAA,qBAAqB,GAAG,IAAA,qBAAU,EAC7C,KAAK,EAAE,CAAM,EAAE,GAAkB,EAAE,EAAE;IACnC,cAAI,CAAC,IAAI,CACP,qHAAqH,CACtH,CAAC;IAEF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,IAAI,EAAE;YACJ,GAAG,8BAAkB;iBAClB,yBAAyB,EAAE;iBAC3B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAA,+BAAS,EAAC,KAAK,CAAC,CAAC;YACnC,aAAa;SACd;KACF,CAAC,CAAC;AACL,CAAC,CACF,CAAC","sourcesContent":["import { ArkosRequest, ArkosResponse, ArkosNextFunction } from \"../../types\";\nimport catchAsync from \"../error-handler/utils/catch-async\";\nimport { BaseService } from \"./base.service\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { kebabCase, pascalCase } from \"../../utils/helpers/change-case.helpers\";\nimport { getModuleComponents } from \"../../utils/dynamic-loader\";\nimport pluralize from \"pluralize\";\nimport sheu from \"../../utils/sheu\";\nimport prismaSchemaParser from \"../../utils/prisma/prisma-schema-parser\";\nimport { APIFeatures } from \"../../exports/utils\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\n\nexport interface OperationHooks {\n beforeQuery?: (req: ArkosRequest) => void | Promise<void>;\n afterQuery?: (\n queryData: { where: any; queryOptions: any },\n req: ArkosRequest\n ) => void | Promise<void>;\n beforeService?: (args: any[], req: ArkosRequest) => any[] | Promise<any[]>;\n afterService?: (data: any, req: ArkosRequest) => any | Promise<any>;\n beforeResponse?: (responseData: any, req: ArkosRequest) => any | Promise<any>;\n}\n\ninterface OperationConfig {\n operationType: string;\n serviceMethod: string;\n successStatus: number;\n queryFeatures: (\"filter\" | \"sort\" | \"limitFields\" | \"paginate\")[];\n requiresQueryForBulk?: boolean;\n preventORFilter?: boolean;\n responseBuilder?: (data: any, additionalData?: any) => any;\n errorHandler?: (\n data: any,\n req: ArkosRequest,\n modelName: string\n ) => AppError | null;\n usesRequestParams?: boolean;\n usesRequestBody?: boolean;\n hooks?: OperationHooks;\n}\n\n/**\n * The `BaseController` class provides standardized RESTful API endpoints\n * for any Prisma model based on its name. It supports automatic integration\n * with Prisma services and dynamic middleware hooks for extending behaviors.\n *\n * This controller includes:\n * - `createOne` / `createMany`\n * - `findOne` / `findMany`\n * - `updateOne` / `updateMany`\n * - `deleteOne` / `deleteMany`\n *\n * It handles:\n * - Prisma query options\n * - APIFeatures: filtering, sorting, pagination, field limiting\n * - Middleware hooks: `afterCreateOne`, `afterUpdateMany`, etc.\n *\n * @class BaseController\n *\n * @param {string} modelName - The Prisma model name this controller handles.\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-controller-class}\n *--\n * **See about how Arkos handles routers**\n * @see {@link https://www.arkosjs.com/docs/guide/adding-custom-routers}\n */\nexport class BaseController {\n /**\n * Service instance to handle business logic operations\n * @private\n */\n private service: BaseService<any>;\n\n /**\n * Name of the model this controller handles\n * @private\n */\n private modelName: string;\n\n /**\n * Model-specific interceptors loaded from model modules\n * @private\n */\n private interceptors: any;\n\n /**\n * Creates a new BaseController instance\n * @param {string} modelName - The name of the model for which this controller will handle operations\n */\n constructor(modelName: string) {\n const components = getModuleComponents(modelName);\n\n this.modelName = modelName;\n this.service = new BaseService(modelName);\n this.interceptors = components?.interceptors || {};\n }\n\n private executeOperation = (config: OperationConfig) => {\n return catchAsync(\n async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (config.hooks?.beforeQuery) await config.hooks.beforeQuery(req);\n\n if (config.requiresQueryForBulk) {\n if (\n Object.keys(req.query).every((key) =>\n [\"filterMode\", \"prismaQueryOptions\"].includes(key)\n )\n ) {\n return next(\n new AppError(\n `Filter criteria not provided for bulk ${config.operationType.replace(/Many$/, \"\")}.`,\n 400,\n {},\n \"MissingRequestQueryParameters\"\n )\n );\n }\n }\n\n if (config.preventORFilter && req.query.filterMode === \"OR\") {\n throw new AppError(\n `req.query.filterMode === OR is not valid for ${config.operationType} operation`,\n 400\n );\n }\n\n if (config.preventORFilter) req.query.filterMode = \"AND\";\n\n let apiFeatures = new APIFeatures(req, this.modelName);\n\n config.queryFeatures.forEach((feature) => {\n switch (feature) {\n case \"filter\":\n apiFeatures = apiFeatures.filter();\n break;\n case \"sort\":\n apiFeatures = apiFeatures.sort();\n break;\n case \"limitFields\":\n apiFeatures = apiFeatures.limitFields();\n break;\n case \"paginate\":\n apiFeatures = apiFeatures.paginate();\n break;\n }\n });\n\n const { where, ...queryOptions } = apiFeatures.filters;\n\n if (config.hooks?.afterQuery)\n await config.hooks.afterQuery({ where, queryOptions }, req);\n\n let serviceArgs = this.buildServiceArgs(\n config,\n req,\n where,\n queryOptions\n );\n\n if (config.hooks?.beforeService)\n serviceArgs = await config.hooks.beforeService(serviceArgs, req);\n\n const serviceMethod = this.service[\n config.serviceMethod as keyof BaseService<any>\n ] as Function;\n let result = await serviceMethod.apply(this.service, serviceArgs);\n\n if (config.hooks?.afterService)\n result = await config.hooks.afterService(result, req);\n\n let data = result;\n let additionalData: any = null;\n\n if (config.operationType === \"findMany\") {\n const [records, total] = await Promise.all([\n result,\n this.service.count(where, {\n user: req?.user,\n accessToken: req?.accessToken,\n }),\n ]);\n\n const take = serviceArgs[1]?.take ?? null;\n const skip = serviceArgs[1]?.skip ?? 0;\n\n const limit = take ?? total;\n const currentPage = limit > 0 ? Math.floor(skip / limit) + 1 : 1;\n const totalPages = limit > 0 ? Math.ceil(total / limit) : 1;\n\n data = records;\n additionalData = {\n total,\n results: records.length,\n page: currentPage,\n pages: totalPages,\n limit,\n hasNextPage: currentPage < totalPages,\n hasPrevPage: currentPage > 1,\n };\n }\n\n const error = config.errorHandler\n ? config.errorHandler(data, req, this.modelName)\n : this.defaultErrorHandler(data, req, config.operationType);\n\n if (error) return next(error);\n\n let responseData = config.responseBuilder\n ? config.responseBuilder(data, additionalData)\n : this.defaultResponseBuilder(\n data,\n additionalData,\n config.operationType\n );\n\n if (config.hooks?.beforeResponse) {\n responseData = await config.hooks.beforeResponse(responseData, req);\n }\n\n const interceptorName = `after${config.operationType.charAt(0).toUpperCase()}${config.operationType.slice(1)}`;\n\n if (this.interceptors[interceptorName]) {\n this.setResponseData(req, res, responseData, config.successStatus);\n next();\n return;\n }\n\n if (config.operationType === \"deleteOne\") {\n res.status(config.successStatus).send();\n return;\n }\n\n res.status(config.successStatus).json(responseData);\n }\n );\n };\n\n /**\n * Sets response data for both legacy (req.responseData) and modern (res.locals) support\n */\n private setResponseData(\n req: ArkosRequest,\n res: ArkosResponse,\n data: any,\n status: number\n ): void {\n (res as any).originalData = data;\n req.responseData = data;\n res.locals.data = data;\n (res as any).originalStatus = status;\n req.responseStatus = status;\n res.locals.status = status;\n\n // Special handling for deleteOne\n if (status === 204) {\n req.additionalData = data;\n res.locals.additionalData = data;\n (res as any).originalAdditionalData = data;\n }\n }\n\n /**\n * Builds service method arguments based on operation configuration\n */\n private buildServiceArgs(\n config: OperationConfig,\n req: ArkosRequest,\n where: any,\n queryOptions: any\n ): any[] {\n const context = { user: req?.user, accessToken: req?.accessToken };\n const mergedOptions = deepmerge(req.prismaQueryOptions || {}, queryOptions);\n\n switch (config.operationType) {\n case \"createOne\":\n case \"createMany\":\n return [req.body, mergedOptions, context];\n\n case \"findMany\":\n return [where, queryOptions, context];\n\n case \"findOne\":\n return [{ ...req.params, ...where }, mergedOptions, context];\n\n case \"updateOne\":\n return [{ ...req.params, ...where }, req.body, mergedOptions, context];\n\n case \"updateMany\":\n // Remove include for bulk operations\n delete queryOptions.include;\n return [where, req.body, queryOptions, context];\n\n case \"batchUpdate\":\n return [req.body, mergedOptions, context];\n\n case \"deleteOne\":\n return [{ ...req.params, ...where }, context];\n\n case \"deleteMany\":\n return [where, context];\n\n case \"batchDelete\":\n return [req.body, context];\n\n default:\n throw new Error(`Unknown operation type: ${config.operationType}`);\n }\n }\n\n /**\n * Default error handler for operations\n */\n private defaultErrorHandler(\n data: any,\n req: ArkosRequest,\n operationType: string\n ): AppError | null {\n if (!data || (Array.isArray(data) && data.length === 0)) {\n // Handle different error scenarios\n if (operationType.includes(\"create\") || operationType.includes(\"batch\")) {\n return new AppError(\n \"Failed to create the resources. Please check your input.\",\n 400,\n { body: req.body }\n );\n }\n\n if (\n operationType === \"findOne\" ||\n operationType === \"updateOne\" ||\n operationType === \"deleteOne\"\n ) {\n if (\n Object.keys(req.params).length === 1 &&\n \"id\" in req.params &&\n req.params.id !== \"me\"\n ) {\n return new AppError(\n `${pascalCase(String(this.modelName))} with ID ${req.params?.id} not found`,\n 404,\n {},\n \"NotFound\"\n );\n } else {\n return new AppError(\n `${pascalCase(String(this.modelName))} not found`,\n 404,\n {},\n \"NotFound\"\n );\n }\n }\n\n if (operationType === \"updateMany\" || operationType === \"deleteMany\") {\n const isUpdate = operationType === \"updateMany\";\n return new AppError(\n isUpdate\n ? `${pluralize(pascalCase(String(this.modelName)))} not found`\n : `No records found to delete`,\n 404,\n {},\n \"NotFound\"\n );\n }\n }\n\n // Special handling for operations that return count\n if (\n data &&\n typeof data === \"object\" &&\n \"count\" in data &&\n data.count === 0\n ) {\n return new AppError(\n operationType === \"updateMany\"\n ? `${pluralize(pascalCase(String(this.modelName)))} not found`\n : `No records found to delete`,\n 404,\n {},\n \"NotFound\"\n );\n }\n\n return null;\n }\n\n /**\n * Default response builder for operations\n */\n private defaultResponseBuilder(\n data: any,\n additionalData: any,\n operationType: string\n ): any {\n if (operationType === \"findMany\" && additionalData)\n return {\n ...additionalData,\n data,\n };\n\n if (\n operationType.includes(\"Many\") &&\n data &&\n typeof data === \"object\" &&\n \"count\" in data\n )\n return { results: data.count, data };\n\n if (operationType.includes(\"batch\") && Array.isArray(data))\n return { results: data.length, data };\n\n return { data };\n }\n\n /**\n * Creates a single resource\n */\n createOne = this.executeOperation({\n operationType: \"createOne\",\n serviceMethod: \"createOne\",\n successStatus: 201,\n queryFeatures: [\"limitFields\"],\n usesRequestBody: true,\n });\n\n /**\n * Creates multiple resources in a single operation\n */\n createMany = this.executeOperation({\n operationType: \"createMany\",\n serviceMethod: \"createMany\",\n successStatus: 201,\n queryFeatures: [\"limitFields\"],\n usesRequestBody: true,\n hooks: {\n async beforeQuery(req) {\n if (!req.body || (Array.isArray(req.body) && req.body.length === 0))\n throw new AppError(\n \"Expected request body array to contain at least on item but received none\",\n 400,\n { body: req.body },\n \"MissingArrayRequestBody\"\n );\n },\n },\n });\n\n /**\n * Retrieves multiple resources with filtering, sorting, pagination, and field selection\n */\n findMany = this.executeOperation({\n operationType: \"findMany\",\n serviceMethod: \"findMany\",\n successStatus: 200,\n queryFeatures: [\"filter\", \"sort\", \"limitFields\", \"paginate\"],\n });\n\n /**\n * Retrieves a single resource by its identifier\n */\n findOne = this.executeOperation({\n operationType: \"findOne\",\n serviceMethod: \"findOne\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestParams: true,\n });\n\n /**\n * Updates a single resource by its identifier\n */\n updateOne = this.executeOperation({\n operationType: \"updateOne\",\n serviceMethod: \"updateOne\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestParams: true,\n usesRequestBody: true,\n });\n\n /**\n * Updates multiple resources that match specified criteria\n */\n updateMany = this.executeOperation({\n operationType: \"updateMany\",\n serviceMethod: \"updateMany\",\n successStatus: 200,\n queryFeatures: [\"filter\", \"limitFields\"],\n requiresQueryForBulk: true,\n preventORFilter: true,\n usesRequestBody: true,\n });\n\n /**\n * Updates multiple resources with different data in a single transaction\n */\n batchUpdate = this.executeOperation({\n operationType: \"batchUpdate\",\n serviceMethod: \"batchUpdate\",\n successStatus: 200,\n queryFeatures: [\"limitFields\", \"filter\"],\n usesRequestBody: true,\n });\n\n /**\n * Deletes a single resource by its identifier\n */\n deleteOne = this.executeOperation({\n operationType: \"deleteOne\",\n serviceMethod: \"deleteOne\",\n successStatus: 204,\n queryFeatures: [\"filter\"],\n usesRequestParams: true,\n });\n\n /**\n * Deletes multiple resources that match specified criteria\n */\n deleteMany = this.executeOperation({\n operationType: \"deleteMany\",\n serviceMethod: \"deleteMany\",\n successStatus: 200,\n queryFeatures: [\"filter\"],\n requiresQueryForBulk: true,\n preventORFilter: true,\n });\n\n /**\n * Deletes multiple resources with different filters in a single transaction\n */\n batchDelete = this.executeOperation({\n operationType: \"batchDelete\",\n serviceMethod: \"batchDelete\",\n successStatus: 200,\n queryFeatures: [\"filter\"],\n usesRequestBody: true,\n });\n}\n\n/**\n * Returns a list of all available resource endpoints based on the application's models\n *\n * Will soon be removed\n *\n * @param {ArkosRequest} req - Express request object\n * @param {ArkosResponse} res - Express response object\n * @param {ArkosNextFunction} next - Express next function\n * @returns {Promise<void>}\n */\nexport const getAvailableResources = catchAsync(\n async (_: any, res: ArkosResponse) => {\n sheu.warn(\n \"This route `/api/available-resources` will be deprecated from 1.4.0-beta, consider using /api/auth-actions instead.\"\n );\n\n res.status(200).json({\n data: [\n ...prismaSchemaParser\n .getModelsAsArrayOfStrings()\n .map((model) => kebabCase(model)),\n \"file-upload\",\n ],\n });\n }\n);\n"]}
@@ -86,6 +86,11 @@ class BaseService {
86
86
  list: modelFields?.filter((field) => field.isRelation && field.isArray) || [],
87
87
  };
88
88
  }
89
+ get prisma() {
90
+ if (!this.prismaInstace)
91
+ this.prismaInstace = (0, prisma_helpers_1.getPrismaInstance)();
92
+ return this.prismaInstace;
93
+ }
89
94
  async executeHooks(hookType, operationType, params, context) {
90
95
  const serviceHooks = (0, dynamic_loader_1.getModuleComponents)(this.modelName)?.hooks;
91
96
  if (!serviceHooks)