arkos 1.1.22-test → 1.1.23-test

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.
@@ -34,9 +34,11 @@ function addPrismaQueryOptionsToRequestQuery(prismaQueryOptions, action) {
34
34
  return (req, res, next) => {
35
35
  const configs = (0, server_1.getArkosConfig)();
36
36
  const firstMerge = (0, deepmerge_helper_1.default)(prismaQueryOptions?.queryOptions || {}, prismaQueryOptions?.[action] || {});
37
+ console.log("firstMerge", JSON.stringify(firstMerge));
37
38
  req.prismaQueryOptions = (0, deepmerge_helper_1.default)(firstMerge, JSON.parse(configs?.request?.parameters?.allowDangerousPrismaQueryOptions
38
39
  ? req.query?.prismaQueryOptions
39
40
  : "{}"));
41
+ console.log("secondMerge", JSON.stringify(req.prismaQueryOptions));
40
42
  next();
41
43
  };
42
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":";;;;;AAiBA,4BAEC;AAED,oCAeC;AAED,oEAAiD;AAUjD,kFAyBC;AAMD,8CAwDC;AAcD,oGA2BC;AAxKD,yCAA8C;AAC9C,4FAA6D;AAC7D,+DAAyD;AACzD,4EAAmD;AACnD,kFAAyD;AAKzD,SAAgB,QAAQ,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB;IACtE,IAAI,EAAE,CAAC;AACT,CAAC;AAED,SAAgB,YAAY,CAC1B,GAAiB,EACjB,GAAkB,EAClB,IAAkB;IAElB,IAAI,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,GAAG;QACrC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAC5C,IAAI,GAAG,CAAC,YAAY,IAAI,GAAG,EAAE,cAAc;QAC9C,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;SAC5D,IAAI,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY;QACvD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;;QAE/C,GAAG;aACA,MAAM,CAAC,GAAG,CAAC;aACX,IAAI,CAAC,EAAE,OAAO,EAAE,4CAA4C,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,4BAA4B,KAAI,CAAC;AAUjD,SAAgB,mCAAmC,CAGjD,kBAAyC,EACzC,MAAmC;IAEnC,OAAO,CAAC,GAAiB,EAAE,GAAkB,EAAE,IAAkB,EAAE,EAAE;QACnE,MAAM,OAAO,GAAG,IAAA,uBAAc,GAAE,CAAC;QAEjC,MAAM,UAAU,GAAG,IAAA,0BAAS,EAC1B,kBAAkB,EAAE,YAAY,IAAI,EAAE,EACtC,kBAAkB,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CACZ,CAAC;QAEzB,GAAG,CAAC,kBAAkB,GAAG,IAAA,0BAAS,EAChC,UAAU,EACV,IAAI,CAAC,KAAK,CACR,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,gCAAgC;YAC5D,CAAC,CAAE,GAAG,CAAC,KAAK,EAAE,kBAA6B;YAC3C,CAAC,CAAC,IAAI,CACT,CACF,CAAC;QAEF,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAMD,SAAgB,iBAAiB,CAC/B,GAAY,EACZ,GAAa,EACb,IAAkB;IAGlB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAG7B,MAAM,YAAY,GAAG;QACnB,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,UAAU;QAChB,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,UAAU;QAClB,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU;KACpB,CAAC;IAGF,MAAM,cAAc,GAAG,CAAC,UAAkB,EAAE,EAAE;QAC5C,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG;YAAE,OAAO,UAAU,CAAC;QAC7D,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG;YAAE,OAAO,UAAU,CAAC;QAC7D,IAAI,UAAU,IAAI,GAAG,IAAI,UAAU,GAAG,GAAG;YAAE,OAAO,UAAU,CAAC;QAC7D,IAAI,UAAU,IAAI,GAAG;YAAE,OAAO,UAAU,CAAC;QACzC,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IAEF,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAGxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9C,MAAM,WAAW,GACf,YAAY,CAAC,GAAG,CAAC,MAAmC,CAAC,IAAI,SAAS,CAAC;QACrE,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAEnD,OAAO,CAAC,IAAI,CACV,iCAAiC,IAAI,WAAW,WAAW,GACzD,GAAG,CAAC,MACN,WAAW,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,WAAW,GAC3D,GAAG,CAAC,UACN,mBAAmB,QAAQ,WAAW,CACvC,CAAC;IAKJ,CAAC,CAAC,CAAC;IAEH,IAAI,EAAE,CAAC;AACT,CAAC;AAcD,SAAgB,4CAA4C,CAC1D,gBAAqD,EACrD,+BAAkD;IAElD,OAAO,IAAA,0BAAU,EACf,KAAK,EAAE,GAAiB,EAAE,GAAkB,EAAE,IAAuB,EAAE,EAAE;QACvE,MAAM,iBAAiB,GAAG,IAAA,uBAAc,GAAE,EAAE,UAAU,CAAC;QACvD,IAAI,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QAEpB,IAAI,iBAAiB,EAAE,QAAQ,KAAK,iBAAiB,IAAI,gBAAgB;YACvE,GAAG,CAAC,IAAI,GAAG,MAAM,IAAA,sBAAW,EAC1B,gBAAuC,EACvC,IAAI,EACJ,IAAA,0BAAS,EACP;gBACE,SAAS,EAAE,IAAI;gBACf,GAAG,+BAA+B;aACnC,EACD,iBAAiB,EAAE,iBAAiB,IAAI,EAAE,CAC3C,CACF,CAAC;aACC,IAAI,iBAAiB,EAAE,QAAQ,KAAK,KAAK,IAAI,gBAAgB;YAChE,GAAG,CAAC,IAAI,GAAG,MAAM,IAAA,yBAAc,EAAC,gBAAgC,EAAE,IAAI,CAAC,CAAC;QAE1E,IAAI,EAAE,CAAC;IACT,CAAC,CACF,CAAC;AACJ,CAAC","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport validateDto from \"../../utils/validate-dto\";\nimport validateSchema from \"../../utils/validate-schema\";\nimport { ZodSchema } from \"zod\";\nimport { ClassConstructor } from \"class-transformer\";\nimport { ValidatorOptions } from \"class-validator\";\n\nexport function callNext(req: Request, res: Response, next: NextFunction) {\n next();\n}\n\nexport function sendResponse(\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n) {\n if (Number(req?.responseStatus) === 204)\n res.status(Number(req?.responseStatus)).send();\n else if (req.responseData && req?.responseStatus)\n res.status(Number(req?.responseStatus)).json(req.responseData);\n else if (Number(req?.responseStatus) && !req.responseData)\n res.status(Number(req?.responseStatus)).send();\n else\n res\n .status(500)\n .json({ message: \"No status or data attached to the response\" });\n}\n\nexport function addRouteMiddlwaresAndConfigs() {}\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequestQuery<\n T extends Record<string, any>\n>(\n prismaQueryOptions: PrismaQueryOptions<T>,\n action: keyof PrismaQueryOptions<T>\n) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const firstMerge = deepmerge(\n prismaQueryOptions?.queryOptions || {},\n prismaQueryOptions?.[action] || {}\n ) as Record<string, any>;\n\n req.prismaQueryOptions = deepmerge(\n firstMerge,\n JSON.parse(\n configs?.request?.parameters?.allowDangerousPrismaQueryOptions\n ? (req.query?.prismaQueryOptions as string)\n : \"{}\"\n )\n );\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction\n) {\n // if (process.env.NODE_ENV === \"production\") return next()\n const startTime = Date.now(); // Capture the start time\n\n // Define colors for each HTTP method\n const methodColors = {\n GET: \"\\x1b[36m\", // Cyan\n POST: \"\\x1b[32m\", // Green\n PUT: \"\\x1b[33m\", // Orange/Yellow\n PATCH: \"\\x1b[33m\", // Orange/Yellow\n DELETE: \"\\x1b[31m\", // Red\n HEAD: \"\\x1b[34m\", // Blue\n OPTIONS: \"\\x1b[34m\", // Blue\n };\n\n // Function to determine status code color\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return \"\\x1b[32m\"; // Green\n if (statusCode >= 300 && statusCode < 400) return \"\\x1b[33m\"; // Orange/Yellow\n if (statusCode >= 400 && statusCode < 500) return \"\\x1b[33m\"; // Red\n if (statusCode >= 500) return \"\\x1b[31m\"; // White on Red background\n return \"\\x1b[0m\"; // Default (no color)\n };\n\n res.on(\"finish\", () => {\n const duration = Date.now() - startTime; // Calculate the time taken to process the request\n\n // Get the current date and time\n const now = new Date();\n const dayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const dayName = dayNames[now.getDay()];\n const dayOfMonth = now.getDate();\n const time = now.toTimeString().split(\" \")[0]; // Format as HH:MM:SS\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || \"\\x1b[0m\"; // Default to no color\n const statusColor = getStatusColor(res.statusCode); // Get the color for the status code\n\n console.info(\n `[\\x1b[36mINFO\\x1b[0m] \\x1b[90m${time}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${decodeURIComponent(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n );\n // Keep the commented-out example as it is\n // console.info(\n // `[\\x1b[36mINFO\\x1b[0m] ${dayName} ${dayOfMonth} ${time} ${methodColor}${req.method}\\x1b[0m ${req.originalUrl} \\x1b[32m${res.statusCode}\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n // );\n });\n\n next(); // Pass control to the next middleware or route handler\n}\n\n// Overload for 'auth'\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n): ArkosRequestHandler;\n\n// Overload for other models\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T>\n): ArkosRequestHandler;\n\n// Implementation\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T> | ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n) {\n return catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const validationConfigs = getArkosConfig()?.validation;\n let body = req.body;\n\n if (validationConfigs?.resolver === \"class-validator\" && schemaOrDtoClass)\n req.body = await validateDto(\n schemaOrDtoClass as ClassConstructor<T>,\n body,\n deepmerge(\n {\n whitelist: true,\n ...classValidatorValidationOptions,\n },\n validationConfigs?.validationOptions || {}\n )\n );\n else if (validationConfigs?.resolver === \"zod\" && schemaOrDtoClass)\n req.body = await validateSchema(schemaOrDtoClass as ZodSchema<T>, body);\n\n next();\n }\n );\n}\n"]}
1
+ {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport validateDto from \"../../utils/validate-dto\";\nimport validateSchema from \"../../utils/validate-schema\";\nimport { ZodSchema } from \"zod\";\nimport { ClassConstructor } from \"class-transformer\";\nimport { ValidatorOptions } from \"class-validator\";\n\nexport function callNext(req: Request, res: Response, next: NextFunction) {\n next();\n}\n\nexport function sendResponse(\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n) {\n if (Number(req?.responseStatus) === 204)\n res.status(Number(req?.responseStatus)).send();\n else if (req.responseData && req?.responseStatus)\n res.status(Number(req?.responseStatus)).json(req.responseData);\n else if (Number(req?.responseStatus) && !req.responseData)\n res.status(Number(req?.responseStatus)).send();\n else\n res\n .status(500)\n .json({ message: \"No status or data attached to the response\" });\n}\n\nexport function addRouteMiddlwaresAndConfigs() {}\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequestQuery<\n T extends Record<string, any>\n>(\n prismaQueryOptions: PrismaQueryOptions<T>,\n action: keyof PrismaQueryOptions<T>\n) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const firstMerge = deepmerge(\n prismaQueryOptions?.queryOptions || {},\n prismaQueryOptions?.[action] || {}\n ) as Record<string, any>;\n\n console.log(\"firstMerge\", JSON.stringify(firstMerge));\n\n req.prismaQueryOptions = deepmerge(\n firstMerge,\n JSON.parse(\n configs?.request?.parameters?.allowDangerousPrismaQueryOptions\n ? (req.query?.prismaQueryOptions as string)\n : \"{}\"\n )\n );\n\n console.log(\"secondMerge\", JSON.stringify(req.prismaQueryOptions));\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction\n) {\n // if (process.env.NODE_ENV === \"production\") return next()\n const startTime = Date.now(); // Capture the start time\n\n // Define colors for each HTTP method\n const methodColors = {\n GET: \"\\x1b[36m\", // Cyan\n POST: \"\\x1b[32m\", // Green\n PUT: \"\\x1b[33m\", // Orange/Yellow\n PATCH: \"\\x1b[33m\", // Orange/Yellow\n DELETE: \"\\x1b[31m\", // Red\n HEAD: \"\\x1b[34m\", // Blue\n OPTIONS: \"\\x1b[34m\", // Blue\n };\n\n // Function to determine status code color\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return \"\\x1b[32m\"; // Green\n if (statusCode >= 300 && statusCode < 400) return \"\\x1b[33m\"; // Orange/Yellow\n if (statusCode >= 400 && statusCode < 500) return \"\\x1b[33m\"; // Red\n if (statusCode >= 500) return \"\\x1b[31m\"; // White on Red background\n return \"\\x1b[0m\"; // Default (no color)\n };\n\n res.on(\"finish\", () => {\n const duration = Date.now() - startTime; // Calculate the time taken to process the request\n\n // Get the current date and time\n const now = new Date();\n const dayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const dayName = dayNames[now.getDay()];\n const dayOfMonth = now.getDate();\n const time = now.toTimeString().split(\" \")[0]; // Format as HH:MM:SS\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || \"\\x1b[0m\"; // Default to no color\n const statusColor = getStatusColor(res.statusCode); // Get the color for the status code\n\n console.info(\n `[\\x1b[36mINFO\\x1b[0m] \\x1b[90m${time}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${decodeURIComponent(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n );\n // Keep the commented-out example as it is\n // console.info(\n // `[\\x1b[36mINFO\\x1b[0m] ${dayName} ${dayOfMonth} ${time} ${methodColor}${req.method}\\x1b[0m ${req.originalUrl} \\x1b[32m${res.statusCode}\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n // );\n });\n\n next(); // Pass control to the next middleware or route handler\n}\n\n// Overload for 'auth'\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n): ArkosRequestHandler;\n\n// Overload for other models\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T>\n): ArkosRequestHandler;\n\n// Implementation\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T> | ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n) {\n return catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const validationConfigs = getArkosConfig()?.validation;\n let body = req.body;\n\n if (validationConfigs?.resolver === \"class-validator\" && schemaOrDtoClass)\n req.body = await validateDto(\n schemaOrDtoClass as ClassConstructor<T>,\n body,\n deepmerge(\n {\n whitelist: true,\n ...classValidatorValidationOptions,\n },\n validationConfigs?.validationOptions || {}\n )\n );\n else if (validationConfigs?.resolver === \"zod\" && schemaOrDtoClass)\n req.body = await validateSchema(schemaOrDtoClass as ZodSchema<T>, body);\n\n next();\n }\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"base.service.js","sourceRoot":"","sources":["../../../../src/modules/base/base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n camelCase,\n kebabCase,\n pascalCase,\n} from \"../../utils/helpers/change-case.helpers\";\nimport {\n getModels,\n getPrismaModelRelations,\n RelationFields,\n} from \"../../utils/helpers/models.helpers\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { handleRelationFieldsInBody } from \"./utils/helpers/base.service.helpers\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport authService from \"../auth/auth.service\";\n\n/**\n * Base service class for handling CRUD operations on a specific model.\n * This class provides standard implementation of data operations that can be extended\n * by model-specific service classes.\n *\n * @class BaseService\n *\n * @usage\n *\n * **Example:** creating a simple service\n *\n * ```ts\n * import prisma from 'your-prisma-path'\n *\n * const userService = new BaseService<typeof prisma.user>(\"user\")\n * ```\n *\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-service-class}\n */\nexport class BaseService<\n TModel extends Record<any, (args: any) => any> = Record<any, any>\n> {\n /**\n * The camelCase name of the model\n * @public\n */\n modelName: string;\n\n /**\n * Object containing singular and list relation fields for the model\n * @public\n */\n relationFields: RelationFields;\n\n /**\n * Instance of the Prisma client\n * @public\n */\n prisma: any;\n\n /**\n * Creates an instance of BaseService.\n * @param {string} modelName - The name of the model to perform operations on.\n */\n constructor(modelName: string) {\n this.modelName = camelCase(modelName);\n this.relationFields = getPrismaModelRelations(pascalCase(modelName))!;\n }\n\n /**\n * Creates a single record in the database.\n *\n * @param {Parameters<TModel[\"create\"]>[0][\"data\"]} data - The data to create the record with.\n * @param {Omit<Parameters<TModel[\"create\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<Promise<ReturnType<TModel[\"create\"]>>>} The created record.\n */\n async createOne(\n data: Parameters<TModel[\"create\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"create\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"create\"]>> {\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const prisma = getPrismaInstance();\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(\n data,\n {\n ...this.relationFields,\n },\n [\"delete\", \"disconnect\", \"update\"]\n );\n\n return await prisma[this.modelName].create(\n deepmerge(\n {\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Creates multiple records in the database.\n *\n * @param {Array<Omit<Parameters<TModel[\"createMany\"]>[0][\"data\"], never>[0]>} data - An array of data to create records with.\n * @param {Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"createMany\"]>>} The result of the createMany operation.\n */\n async createMany(\n data: Parameters<TModel[\"createMany\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"createMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].createMany(\n deepmerge({ data }, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Counts records based on provided filters.\n *\n * @param {Parameters<TModel[\"count\"]>[0]} filters - The filters to apply to the query.\n * @returns {Promise<number>} The count of records matching the filters.\n */\n async count(filters: Parameters<TModel[\"count\"]>[0]): Promise<number> {\n const prisma = getPrismaInstance();\n\n const where = filters.where || {};\n return await prisma[this.modelName].count({\n where,\n });\n }\n\n /**\n * Finds multiple records based on provided filters.\n *\n * @param {Parameters<TModel[\"findMany\"]>[0]['where']} filters - The filters to apply to the query.\n * @param {Partial<Parameters<TModel[\"findMany\"]>[0]>} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"findMany\"]>>} The found data.\n */\n async findMany(\n filters: Parameters<TModel[\"findMany\"]>[0][\"where\"],\n queryOptions?: Omit<Partial<Parameters<TModel[\"findMany\"]>[0]>, \"where\">\n ): Promise<ReturnType<TModel[\"findMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].findMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Finds a single record by its parameters.\n *\n * @param {Parameters<TModel[\"findFirst\"]>[0][\"where\"] | Parameters<TModel[\"findUnique\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise< ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>>} The found record or null if not found.\n */\n async findOne(\n filters:\n | Parameters<TModel[\"findFirst\"]>[0][\"where\"]\n | Parameters<TModel[\"findUnique\"]>[0][\"where\"],\n queryOptions?:\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n ): Promise<\n ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>\n > {\n const prisma = getPrismaInstance();\n\n if (\n Object.keys(filters).length === 1 &&\n \"id\" in filters &&\n (filters as any).id !== \"me\"\n )\n return prisma[this.modelName].findUnique(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n\n return await prisma[this.modelName].findFirst(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates a single record by its ID.\n *\n * @param {Parameters<TModel[\"update\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Parameters<TModel[\"update\"]>[0][\"data\"]} data - The data to update the record with.\n * @param {Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"update\"]>>} The updated record or null if not found.\n */\n async updateOne(\n filters: Parameters<TModel[\"update\"]>[0][\"where\"],\n data: Parameters<TModel[\"update\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">\n ): Promise<ReturnType<TModel[\"update\"]>> {\n const prisma = getPrismaInstance();\n\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(data, {\n ...this.relationFields,\n });\n\n return await prisma[this.modelName].update(\n deepmerge(\n {\n where: filters,\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates multiple records based on the provided filter and data.\n *\n * @param {Parameters<TModel[\"updateMany\"]>[0]['where']} filters - The filters to identify records to update.\n * @param {Parameters<TModel[\"updateMany\"]>[0][\"data\"]} data - The data to update the records with.\n * @param {Partial<Parameters<TModel[\"updateMany\"]>[0]>} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"updateMany\"]>>} The result of the updateMany operation.\n */\n async updateMany(\n filters: Parameters<TModel[\"updateMany\"]>[0][\"where\"],\n data: Parameters<TModel[\"updateMany\"]>[0][\"data\"],\n queryOptions?: Partial<Parameters<TModel[\"updateMany\"]>[0]>\n ): Promise<ReturnType<TModel[\"updateMany\"]>> {\n const prisma = getPrismaInstance();\n\n const firstMerge = deepmerge({ data }, (queryOptions as {}) || {});\n\n return await prisma[this.modelName].updateMany(\n deepmerge({ where: filters }, firstMerge)\n );\n }\n\n /**\n * Deletes a single record by its ID.\n *\n * @param {Parameters<TModel[\"delete\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"delete\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"delete\"]>>} The deleted record or null if an error occurs.\n */\n async deleteOne(\n filters: Parameters<TModel[\"delete\"]>[0][\"where\"],\n queryOptions?: Omit<Parameters<TModel[\"delete\"]>[0], \"where\">\n ): Promise<ReturnType<TModel[\"delete\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].delete(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Deletes multiple records based on the provided filter.\n *\n * @param {Parameters<TModel[\"deleteMany\"]>[0]['where']} filters - The filter to identify records to delete.\n * @param {Omit<Parameters<TModel[\"deleteMany\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"deleteMany\"]>>} The result of the deleteMany operation.\n */\n async deleteMany(\n filters: Record<string, any>,\n queryOptions: Partial<Parameters<TModel[\"deleteMany\"]>[0]> = {}\n ): Promise<ReturnType<TModel[\"deleteMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].deleteMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n}\n\n/**\n * Generates a set of base service instances for all available models.\n *\n * @returns {Record<string, BaseService>} A dictionary of base service instances, keyed by model name.\n */\nexport function getBaseServices(): Record<string, BaseService> {\n const models = getModels();\n const baseServices: Record<string, BaseService> = {};\n models.forEach((model) => {\n baseServices[`${camelCase(model)}`] = new BaseService(model);\n });\n return baseServices;\n}\n"]}
1
+ {"version":3,"file":"base.service.js","sourceRoot":"","sources":["../../../../src/modules/base/base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n camelCase,\n kebabCase,\n pascalCase,\n} from \"../../utils/helpers/change-case.helpers\";\nimport {\n getModels,\n getPrismaModelRelations,\n RelationFields,\n} from \"../../utils/helpers/models.helpers\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { handleRelationFieldsInBody } from \"./utils/helpers/base.service.helpers\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport authService from \"../auth/auth.service\";\nimport { PrismaModelDelegate } from \"../../types\";\n\n/**\n * Base service class for handling CRUD operations on a specific model.\n * This class provides standard implementation of data operations that can be extended\n * by model-specific service classes.\n *\n * @class BaseService\n *\n * @usage\n *\n * **Example:** creating a simple service\n *\n * ```ts\n * import prisma from 'your-prisma-path'\n *\n * const userService = new BaseService<typeof prisma.user>(\"user\")\n * ```\n *\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-service-class}\n */\nexport class BaseService<TModel extends PrismaModelDelegate = any> {\n /**\n * The camelCase name of the model\n * @public\n */\n modelName: string;\n\n /**\n * Object containing singular and list relation fields for the model\n * @public\n */\n relationFields: RelationFields;\n\n /**\n * Instance of the Prisma client\n * @public\n */\n prisma: any;\n\n /**\n * Creates an instance of BaseService.\n * @param {string} modelName - The name of the model to perform operations on.\n */\n constructor(modelName: string) {\n this.modelName = camelCase(modelName);\n this.relationFields = getPrismaModelRelations(pascalCase(modelName))!;\n }\n\n /**\n * Creates a single record in the database.\n *\n * @param {Parameters<TModel[\"create\"]>[0][\"data\"]} data - The data to create the record with.\n * @param {Omit<Parameters<TModel[\"create\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<Promise<ReturnType<TModel[\"create\"]>>>} The created record.\n */\n async createOne(\n data: Parameters<TModel[\"create\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"create\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"create\"]>> {\n if (kebabCase(this.modelName) === \"user\" && (data as any).password) {\n (data as any).password = await authService.hashPassword(\n (data as any).password\n );\n }\n\n const prisma = getPrismaInstance();\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(\n data,\n {\n ...this.relationFields,\n },\n [\"delete\", \"disconnect\", \"update\"]\n );\n\n return await prisma[this.modelName].create(\n deepmerge(\n {\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Creates multiple records in the database.\n *\n * @param {Array<Omit<Parameters<TModel[\"createMany\"]>[0][\"data\"], never>[0]>} data - An array of data to create records with.\n * @param {Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"createMany\"]>>} The result of the createMany operation.\n */\n async createMany(\n data: Parameters<TModel[\"createMany\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"createMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].createMany(\n deepmerge({ data }, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Counts records based on provided filters.\n *\n * @param {Parameters<TModel[\"count\"]>[0]} filters - The filters to apply to the query.\n * @returns {Promise<number>} The count of records matching the filters.\n */\n async count(filters: Parameters<TModel[\"count\"]>[0]): Promise<number> {\n const prisma = getPrismaInstance();\n\n const where = filters.where || {};\n return await prisma[this.modelName].count({\n where,\n });\n }\n\n /**\n * Finds multiple records based on provided filters.\n *\n * @param {Parameters<TModel[\"findMany\"]>[0]['where']} filters - The filters to apply to the query.\n * @param {Partial<Parameters<TModel[\"findMany\"]>[0]>} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"findMany\"]>>} The found data.\n */\n async findMany(\n filters: Parameters<TModel[\"findMany\"]>[0][\"where\"],\n queryOptions?: Omit<Partial<Parameters<TModel[\"findMany\"]>[0]>, \"where\">\n ): Promise<ReturnType<TModel[\"findMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].findMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Finds a single record by its parameters.\n *\n * @param {Parameters<TModel[\"findFirst\"]>[0][\"where\"] | Parameters<TModel[\"findUnique\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise< ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>>} The found record or null if not found.\n */\n async findOne(\n filters:\n | Parameters<TModel[\"findFirst\"]>[0][\"where\"]\n | Parameters<TModel[\"findUnique\"]>[0][\"where\"],\n queryOptions?:\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n ): Promise<\n ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>\n > {\n const prisma = getPrismaInstance();\n\n if (\n Object.keys(filters).length === 1 &&\n \"id\" in filters &&\n (filters as any).id !== \"me\"\n )\n return prisma[this.modelName].findUnique(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n\n return await prisma[this.modelName].findFirst(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates a single record by its ID.\n *\n * @param {Parameters<TModel[\"update\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Parameters<TModel[\"update\"]>[0][\"data\"]} data - The data to update the record with.\n * @param {Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"update\"]>>} The updated record or null if not found.\n */\n async updateOne(\n filters: Parameters<TModel[\"update\"]>[0][\"where\"],\n data: Parameters<TModel[\"update\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">\n ): Promise<ReturnType<TModel[\"update\"]>> {\n const prisma = getPrismaInstance();\n\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(data, {\n ...this.relationFields,\n });\n\n return await prisma[this.modelName].update(\n deepmerge(\n {\n where: filters,\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates multiple records based on the provided filter and data.\n *\n * @param {Parameters<TModel[\"updateMany\"]>[0]['where']} filters - The filters to identify records to update.\n * @param {Parameters<TModel[\"updateMany\"]>[0][\"data\"]} data - The data to update the records with.\n * @param {Partial<Parameters<TModel[\"updateMany\"]>[0]>} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"updateMany\"]>>} The result of the updateMany operation.\n */\n async updateMany(\n filters: Parameters<TModel[\"updateMany\"]>[0][\"where\"],\n data: Parameters<TModel[\"updateMany\"]>[0][\"data\"],\n queryOptions?: Partial<Parameters<TModel[\"updateMany\"]>[0]>\n ): Promise<ReturnType<TModel[\"updateMany\"]>> {\n const prisma = getPrismaInstance();\n\n const firstMerge = deepmerge({ data }, (queryOptions as {}) || {});\n\n return await prisma[this.modelName].updateMany(\n deepmerge({ where: filters }, firstMerge)\n );\n }\n\n /**\n * Deletes a single record by its ID.\n *\n * @param {Parameters<TModel[\"delete\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"delete\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"delete\"]>>} The deleted record or null if an error occurs.\n */\n async deleteOne(\n filters: Parameters<TModel[\"delete\"]>[0][\"where\"],\n queryOptions?: Omit<Parameters<TModel[\"delete\"]>[0], \"where\">\n ): Promise<ReturnType<TModel[\"delete\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].delete(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Deletes multiple records based on the provided filter.\n *\n * @param {Parameters<TModel[\"deleteMany\"]>[0]['where']} filters - The filter to identify records to delete.\n * @param {Omit<Parameters<TModel[\"deleteMany\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"deleteMany\"]>>} The result of the deleteMany operation.\n */\n async deleteMany(\n filters: Record<string, any>,\n queryOptions: Partial<Parameters<TModel[\"deleteMany\"]>[0]> = {}\n ): Promise<ReturnType<TModel[\"deleteMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].deleteMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n}\n\n/**\n * Generates a set of base service instances for all available models.\n *\n * @returns {Record<string, BaseService>} A dictionary of base service instances, keyed by model name.\n */\nexport function getBaseServices(): Record<string, BaseService> {\n const models = getModels();\n const baseServices: Record<string, BaseService> = {};\n models.forEach((model) => {\n baseServices[`${camelCase(model)}`] = new BaseService(model);\n });\n return baseServices;\n}\n"]}
package/dist/cjs/proxy.js CHANGED
@@ -1 +1 @@
1
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(r,e,o,t){t===void 0&&(t=o);var n=Object.getOwnPropertyDescriptor(e,o);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[o]}}),Object.defineProperty(r,t,n)}:function(r,e,o,t){t===void 0&&(t=o),r[t]=e[o]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(r,e){Object.defineProperty(r,"default",{enumerable:!0,value:e})}:function(r,e){r.default=e}),__importStar=this&&this.__importStar||function(){var r=function(e){return r=Object.getOwnPropertyNames||function(o){var t=[];for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[t.length]=n);return t},r(e)};return function(e){if(e&&e.__esModule)return e;var o={};if(e!=null)for(var t=r(e),n=0;n<t.length;n++)t[n]!=="default"&&__createBinding(o,e,t[n]);return __setModuleDefault(o,e),o}}();Object.defineProperty(exports,"__esModule",{value:!0}),exports.arkosProxy=void 0,exports.getCapturedConfig=getCapturedConfig;let capturedConfig=null;exports.arkosProxy={init:r=>(capturedConfig=r,Promise.resolve().then(()=>__importStar(require("../path/to/real/arkos"))).then(e=>e.initApp(r)))};function getCapturedConfig(){return capturedConfig}
1
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?function(r,e,i,t){t===void 0&&(t=i);var n=Object.getOwnPropertyDescriptor(e,i);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[i]}}),Object.defineProperty(r,t,n)}:function(r,e,i,t){t===void 0&&(t=i),r[t]=e[i]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(r,e){Object.defineProperty(r,"default",{enumerable:!0,value:e})}:function(r,e){r.default=e}),__importStar=this&&this.__importStar||function(){var r=function(e){return r=Object.getOwnPropertyNames||function(i){var t=[];for(var n in i)Object.prototype.hasOwnProperty.call(i,n)&&(t[t.length]=n);return t},r(e)};return function(e){if(e&&e.__esModule)return e;var i={};if(e!=null)for(var t=r(e),n=0;n<t.length;n++)t[n]!=="default"&&__createBinding(i,e,t[n]);return __setModuleDefault(i,e),i}}();Object.defineProperty(exports,"__esModule",{value:!0}),exports.arkosProxy=void 0,exports.getCapturedConfig=getCapturedConfig;let capturedConfig=null;exports.arkosProxy={init:r=>(capturedConfig=r,Promise.resolve().then(()=>__importStar(require("../path/to/real/arkos"))).then(e=>e.initApp(r)))};function getCapturedConfig(){return capturedConfig}
@@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AuthPermissionAction = void 0;
4
4
  var AuthPermissionAction;
5
5
  (function (AuthPermissionAction) {
6
- AuthPermissionAction["create"] = "create";
7
- AuthPermissionAction["view"] = "view";
8
- AuthPermissionAction["update"] = "update";
9
- AuthPermissionAction["delete"] = "delete";
6
+ AuthPermissionAction["Create"] = "Create";
7
+ AuthPermissionAction["View"] = "View";
8
+ AuthPermissionAction["Update"] = "Update";
9
+ AuthPermissionAction["Delete"] = "Delete";
10
10
  })(AuthPermissionAction || (exports.AuthPermissionAction = AuthPermissionAction = {}));
11
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":";;;AAmCA,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,oCAApB,oBAAoB,QAK/B","sourcesContent":["import { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T extends Record<string, any>> = {\n queryOptions?: Partial<Parameters<T[\"findMany\"]>[0]>;\n findOne?: Partial<Parameters<T[\"findFirst\"]>[0]>;\n findMany?: Partial<Parameters<T[\"findMany\"]>[0]>;\n deleteMany?: Partial<Parameters<T[\"deleteMany\"]>[0]>;\n updateMany?: Partial<Parameters<T[\"updateMany\"]>[0]>;\n createMany?: Partial<Parameters<T[\"createMany\"]>[0]>;\n createOne?: Partial<Parameters<T[\"create\"]>[0]>;\n updateOne?: Partial<Parameters<T[\"update\"]>[0]>;\n deleteOne?: Partial<Parameters<T[\"delete\"]>[0]>;\n};\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n create = \"create\",\n view = \"view\",\n update = \"update\",\n delete = \"delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest<Body = any, Query = any> extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n body: Body;\n prismaQueryOptions?: Record<string, any>;\n // query: Query extends Request['ParsedQs'];\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":";;;AAwDA,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,oCAApB,oBAAoB,QAK/B","sourcesContent":["import { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T extends Record<string, any>> = {\n queryOptions?: Partial<Parameters<T[\"findMany\"]>[0]>;\n findOne?: Partial<Parameters<T[\"findFirst\"]>[0]>;\n findMany?: Partial<Parameters<T[\"findMany\"]>[0]>;\n deleteMany?: Partial<Parameters<T[\"deleteMany\"]>[0]>;\n updateMany?: Partial<Parameters<T[\"updateMany\"]>[0]>;\n createMany?: Partial<Parameters<T[\"createMany\"]>[0]>;\n createOne?: Partial<Parameters<T[\"create\"]>[0]>;\n updateOne?: Partial<Parameters<T[\"update\"]>[0]>;\n deleteOne?: Partial<Parameters<T[\"delete\"]>[0]>;\n};\n\n/**\n * Interface defining the minimum structure required for Prisma model delegates\n * This allows us to constraint TModel without requiring Prisma imports\n */\nexport interface PrismaModelDelegate {\n create: (args: { data: any; [key: string]: any }) => Promise<any>;\n createMany: (args: { data: any; [key: string]: any }) => Promise<any>;\n findMany: (args: { where?: any; [key: string]: any }) => Promise<any[]>;\n findFirst: (args: { where: any; [key: string]: any }) => Promise<any>;\n findUnique: (args: { where: any; [key: string]: any }) => Promise<any>;\n update: (args: { where: any; data: any; [key: string]: any }) => Promise<any>;\n updateMany: (args: {\n where: any;\n data: any;\n [key: string]: any;\n }) => Promise<any>;\n delete: (args: { where: any; [key: string]: any }) => Promise<any>;\n deleteMany: (args: { where: any; [key: string]: any }) => Promise<any>;\n count: (args: { where?: any; [key: string]: any }) => Promise<number>;\n}\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n Create = \"Create\",\n View = \"View\",\n Update = \"Update\",\n Delete = \"Delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest<Body = any, Query = any> extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n body: Body;\n prismaQueryOptions?: Record<string, any>;\n // query: Query extends Request['ParsedQs'];\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
@@ -23,9 +23,11 @@ export function addPrismaQueryOptionsToRequestQuery(prismaQueryOptions, action)
23
23
  return (req, res, next) => {
24
24
  const configs = getArkosConfig();
25
25
  const firstMerge = deepmerge(prismaQueryOptions?.queryOptions || {}, prismaQueryOptions?.[action] || {});
26
+ console.log("firstMerge", JSON.stringify(firstMerge));
26
27
  req.prismaQueryOptions = deepmerge(firstMerge, JSON.parse(configs?.request?.parameters?.allowDangerousPrismaQueryOptions
27
28
  ? req.query?.prismaQueryOptions
28
29
  : "{}"));
30
+ console.log("secondMerge", JSON.stringify(req.prismaQueryOptions));
29
31
  next();
30
32
  };
31
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport validateDto from \"../../utils/validate-dto\";\nimport validateSchema from \"../../utils/validate-schema\";\nimport { ZodSchema } from \"zod\";\nimport { ClassConstructor } from \"class-transformer\";\nimport { ValidatorOptions } from \"class-validator\";\n\nexport function callNext(req: Request, res: Response, next: NextFunction) {\n next();\n}\n\nexport function sendResponse(\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n) {\n if (Number(req?.responseStatus) === 204)\n res.status(Number(req?.responseStatus)).send();\n else if (req.responseData && req?.responseStatus)\n res.status(Number(req?.responseStatus)).json(req.responseData);\n else if (Number(req?.responseStatus) && !req.responseData)\n res.status(Number(req?.responseStatus)).send();\n else\n res\n .status(500)\n .json({ message: \"No status or data attached to the response\" });\n}\n\nexport function addRouteMiddlwaresAndConfigs() {}\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequestQuery<\n T extends Record<string, any>\n>(\n prismaQueryOptions: PrismaQueryOptions<T>,\n action: keyof PrismaQueryOptions<T>\n) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const firstMerge = deepmerge(\n prismaQueryOptions?.queryOptions || {},\n prismaQueryOptions?.[action] || {}\n ) as Record<string, any>;\n\n req.prismaQueryOptions = deepmerge(\n firstMerge,\n JSON.parse(\n configs?.request?.parameters?.allowDangerousPrismaQueryOptions\n ? (req.query?.prismaQueryOptions as string)\n : \"{}\"\n )\n );\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction\n) {\n // if (process.env.NODE_ENV === \"production\") return next()\n const startTime = Date.now(); // Capture the start time\n\n // Define colors for each HTTP method\n const methodColors = {\n GET: \"\\x1b[36m\", // Cyan\n POST: \"\\x1b[32m\", // Green\n PUT: \"\\x1b[33m\", // Orange/Yellow\n PATCH: \"\\x1b[33m\", // Orange/Yellow\n DELETE: \"\\x1b[31m\", // Red\n HEAD: \"\\x1b[34m\", // Blue\n OPTIONS: \"\\x1b[34m\", // Blue\n };\n\n // Function to determine status code color\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return \"\\x1b[32m\"; // Green\n if (statusCode >= 300 && statusCode < 400) return \"\\x1b[33m\"; // Orange/Yellow\n if (statusCode >= 400 && statusCode < 500) return \"\\x1b[33m\"; // Red\n if (statusCode >= 500) return \"\\x1b[31m\"; // White on Red background\n return \"\\x1b[0m\"; // Default (no color)\n };\n\n res.on(\"finish\", () => {\n const duration = Date.now() - startTime; // Calculate the time taken to process the request\n\n // Get the current date and time\n const now = new Date();\n const dayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const dayName = dayNames[now.getDay()];\n const dayOfMonth = now.getDate();\n const time = now.toTimeString().split(\" \")[0]; // Format as HH:MM:SS\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || \"\\x1b[0m\"; // Default to no color\n const statusColor = getStatusColor(res.statusCode); // Get the color for the status code\n\n console.info(\n `[\\x1b[36mINFO\\x1b[0m] \\x1b[90m${time}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${decodeURIComponent(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n );\n // Keep the commented-out example as it is\n // console.info(\n // `[\\x1b[36mINFO\\x1b[0m] ${dayName} ${dayOfMonth} ${time} ${methodColor}${req.method}\\x1b[0m ${req.originalUrl} \\x1b[32m${res.statusCode}\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n // );\n });\n\n next(); // Pass control to the next middleware or route handler\n}\n\n// Overload for 'auth'\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n): ArkosRequestHandler;\n\n// Overload for other models\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T>\n): ArkosRequestHandler;\n\n// Implementation\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T> | ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n) {\n return catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const validationConfigs = getArkosConfig()?.validation;\n let body = req.body;\n\n if (validationConfigs?.resolver === \"class-validator\" && schemaOrDtoClass)\n req.body = await validateDto(\n schemaOrDtoClass as ClassConstructor<T>,\n body,\n deepmerge(\n {\n whitelist: true,\n ...classValidatorValidationOptions,\n },\n validationConfigs?.validationOptions || {}\n )\n );\n else if (validationConfigs?.resolver === \"zod\" && schemaOrDtoClass)\n req.body = await validateSchema(schemaOrDtoClass as ZodSchema<T>, body);\n\n next();\n }\n );\n}\n"]}
1
+ {"version":3,"file":"base.middlewares.js","sourceRoot":"","sources":["../../../../src/modules/base/base.middlewares.ts"],"names":[],"mappings":"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","sourcesContent":["import { NextFunction, Request, Response } from \"express\";\nimport {\n PrismaQueryOptions,\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport validateDto from \"../../utils/validate-dto\";\nimport validateSchema from \"../../utils/validate-schema\";\nimport { ZodSchema } from \"zod\";\nimport { ClassConstructor } from \"class-transformer\";\nimport { ValidatorOptions } from \"class-validator\";\n\nexport function callNext(req: Request, res: Response, next: NextFunction) {\n next();\n}\n\nexport function sendResponse(\n req: ArkosRequest,\n res: ArkosResponse,\n next: NextFunction\n) {\n if (Number(req?.responseStatus) === 204)\n res.status(Number(req?.responseStatus)).send();\n else if (req.responseData && req?.responseStatus)\n res.status(Number(req?.responseStatus)).json(req.responseData);\n else if (Number(req?.responseStatus) && !req.responseData)\n res.status(Number(req?.responseStatus)).send();\n else\n res\n .status(500)\n .json({ message: \"No status or data attached to the response\" });\n}\n\nexport function addRouteMiddlwaresAndConfigs() {}\n\n/**\n * Middleware to add Prisma query options to the request's query parameters.\n *\n * @template T - The type of the Prisma model.\n * @param {PrismaQueryOptions<T>} prismaQueryOptions - The Prisma query options to attach.\n * @param {ControllerActions} action - The controller action to apply.\n * @returns A middleware function that attaches the query options to the request.\n */\nexport function addPrismaQueryOptionsToRequestQuery<\n T extends Record<string, any>\n>(\n prismaQueryOptions: PrismaQueryOptions<T>,\n action: keyof PrismaQueryOptions<T>\n) {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const configs = getArkosConfig();\n\n const firstMerge = deepmerge(\n prismaQueryOptions?.queryOptions || {},\n prismaQueryOptions?.[action] || {}\n ) as Record<string, any>;\n\n console.log(\"firstMerge\", JSON.stringify(firstMerge));\n\n req.prismaQueryOptions = deepmerge(\n firstMerge,\n JSON.parse(\n configs?.request?.parameters?.allowDangerousPrismaQueryOptions\n ? (req.query?.prismaQueryOptions as string)\n : \"{}\"\n )\n );\n\n console.log(\"secondMerge\", JSON.stringify(req.prismaQueryOptions));\n\n next();\n };\n}\n\n/**\n * Logs request events with colored text such as errors, requests responses.\n *\n */\nexport function handleRequestLogs(\n req: Request,\n res: Response,\n next: NextFunction\n) {\n // if (process.env.NODE_ENV === \"production\") return next()\n const startTime = Date.now(); // Capture the start time\n\n // Define colors for each HTTP method\n const methodColors = {\n GET: \"\\x1b[36m\", // Cyan\n POST: \"\\x1b[32m\", // Green\n PUT: \"\\x1b[33m\", // Orange/Yellow\n PATCH: \"\\x1b[33m\", // Orange/Yellow\n DELETE: \"\\x1b[31m\", // Red\n HEAD: \"\\x1b[34m\", // Blue\n OPTIONS: \"\\x1b[34m\", // Blue\n };\n\n // Function to determine status code color\n const getStatusColor = (statusCode: number) => {\n if (statusCode >= 200 && statusCode < 300) return \"\\x1b[32m\"; // Green\n if (statusCode >= 300 && statusCode < 400) return \"\\x1b[33m\"; // Orange/Yellow\n if (statusCode >= 400 && statusCode < 500) return \"\\x1b[33m\"; // Red\n if (statusCode >= 500) return \"\\x1b[31m\"; // White on Red background\n return \"\\x1b[0m\"; // Default (no color)\n };\n\n res.on(\"finish\", () => {\n const duration = Date.now() - startTime; // Calculate the time taken to process the request\n\n // Get the current date and time\n const now = new Date();\n const dayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const dayName = dayNames[now.getDay()];\n const dayOfMonth = now.getDate();\n const time = now.toTimeString().split(\" \")[0]; // Format as HH:MM:SS\n\n const methodColor =\n methodColors[req.method as keyof typeof methodColors] || \"\\x1b[0m\"; // Default to no color\n const statusColor = getStatusColor(res.statusCode); // Get the color for the status code\n\n console.info(\n `[\\x1b[36mINFO\\x1b[0m] \\x1b[90m${time}\\x1b[0m ${methodColor}${\n req.method\n }\\x1b[0m ${decodeURIComponent(req.originalUrl)} ${statusColor}${\n res.statusCode\n }\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n );\n // Keep the commented-out example as it is\n // console.info(\n // `[\\x1b[36mINFO\\x1b[0m] ${dayName} ${dayOfMonth} ${time} ${methodColor}${req.method}\\x1b[0m ${req.originalUrl} \\x1b[32m${res.statusCode}\\x1b[0m \\x1b[35m${duration}ms\\x1b[0m`\n // );\n });\n\n next(); // Pass control to the next middleware or route handler\n}\n\n// Overload for 'auth'\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n): ArkosRequestHandler;\n\n// Overload for other models\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T>\n): ArkosRequestHandler;\n\n// Implementation\nexport function handleRequestBodyValidationAndTransformation<T extends object>(\n schemaOrDtoClass?: ZodSchema<T> | ClassConstructor<T>,\n classValidatorValidationOptions?: ValidatorOptions\n) {\n return catchAsync(\n async (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const validationConfigs = getArkosConfig()?.validation;\n let body = req.body;\n\n if (validationConfigs?.resolver === \"class-validator\" && schemaOrDtoClass)\n req.body = await validateDto(\n schemaOrDtoClass as ClassConstructor<T>,\n body,\n deepmerge(\n {\n whitelist: true,\n ...classValidatorValidationOptions,\n },\n validationConfigs?.validationOptions || {}\n )\n );\n else if (validationConfigs?.resolver === \"zod\" && schemaOrDtoClass)\n req.body = await validateSchema(schemaOrDtoClass as ZodSchema<T>, body);\n\n next();\n }\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"base.service.js","sourceRoot":"","sources":["../../../../src/modules/base/base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n camelCase,\n kebabCase,\n pascalCase,\n} from \"../../utils/helpers/change-case.helpers\";\nimport {\n getModels,\n getPrismaModelRelations,\n RelationFields,\n} from \"../../utils/helpers/models.helpers\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { handleRelationFieldsInBody } from \"./utils/helpers/base.service.helpers\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport authService from \"../auth/auth.service\";\n\n/**\n * Base service class for handling CRUD operations on a specific model.\n * This class provides standard implementation of data operations that can be extended\n * by model-specific service classes.\n *\n * @class BaseService\n *\n * @usage\n *\n * **Example:** creating a simple service\n *\n * ```ts\n * import prisma from 'your-prisma-path'\n *\n * const userService = new BaseService<typeof prisma.user>(\"user\")\n * ```\n *\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-service-class}\n */\nexport class BaseService<\n TModel extends Record<any, (args: any) => any> = Record<any, any>\n> {\n /**\n * The camelCase name of the model\n * @public\n */\n modelName: string;\n\n /**\n * Object containing singular and list relation fields for the model\n * @public\n */\n relationFields: RelationFields;\n\n /**\n * Instance of the Prisma client\n * @public\n */\n prisma: any;\n\n /**\n * Creates an instance of BaseService.\n * @param {string} modelName - The name of the model to perform operations on.\n */\n constructor(modelName: string) {\n this.modelName = camelCase(modelName);\n this.relationFields = getPrismaModelRelations(pascalCase(modelName))!;\n }\n\n /**\n * Creates a single record in the database.\n *\n * @param {Parameters<TModel[\"create\"]>[0][\"data\"]} data - The data to create the record with.\n * @param {Omit<Parameters<TModel[\"create\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<Promise<ReturnType<TModel[\"create\"]>>>} The created record.\n */\n async createOne(\n data: Parameters<TModel[\"create\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"create\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"create\"]>> {\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const prisma = getPrismaInstance();\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(\n data,\n {\n ...this.relationFields,\n },\n [\"delete\", \"disconnect\", \"update\"]\n );\n\n return await prisma[this.modelName].create(\n deepmerge(\n {\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Creates multiple records in the database.\n *\n * @param {Array<Omit<Parameters<TModel[\"createMany\"]>[0][\"data\"], never>[0]>} data - An array of data to create records with.\n * @param {Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"createMany\"]>>} The result of the createMany operation.\n */\n async createMany(\n data: Parameters<TModel[\"createMany\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"createMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].createMany(\n deepmerge({ data }, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Counts records based on provided filters.\n *\n * @param {Parameters<TModel[\"count\"]>[0]} filters - The filters to apply to the query.\n * @returns {Promise<number>} The count of records matching the filters.\n */\n async count(filters: Parameters<TModel[\"count\"]>[0]): Promise<number> {\n const prisma = getPrismaInstance();\n\n const where = filters.where || {};\n return await prisma[this.modelName].count({\n where,\n });\n }\n\n /**\n * Finds multiple records based on provided filters.\n *\n * @param {Parameters<TModel[\"findMany\"]>[0]['where']} filters - The filters to apply to the query.\n * @param {Partial<Parameters<TModel[\"findMany\"]>[0]>} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"findMany\"]>>} The found data.\n */\n async findMany(\n filters: Parameters<TModel[\"findMany\"]>[0][\"where\"],\n queryOptions?: Omit<Partial<Parameters<TModel[\"findMany\"]>[0]>, \"where\">\n ): Promise<ReturnType<TModel[\"findMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].findMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Finds a single record by its parameters.\n *\n * @param {Parameters<TModel[\"findFirst\"]>[0][\"where\"] | Parameters<TModel[\"findUnique\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise< ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>>} The found record or null if not found.\n */\n async findOne(\n filters:\n | Parameters<TModel[\"findFirst\"]>[0][\"where\"]\n | Parameters<TModel[\"findUnique\"]>[0][\"where\"],\n queryOptions?:\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n ): Promise<\n ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>\n > {\n const prisma = getPrismaInstance();\n\n if (\n Object.keys(filters).length === 1 &&\n \"id\" in filters &&\n (filters as any).id !== \"me\"\n )\n return prisma[this.modelName].findUnique(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n\n return await prisma[this.modelName].findFirst(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates a single record by its ID.\n *\n * @param {Parameters<TModel[\"update\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Parameters<TModel[\"update\"]>[0][\"data\"]} data - The data to update the record with.\n * @param {Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"update\"]>>} The updated record or null if not found.\n */\n async updateOne(\n filters: Parameters<TModel[\"update\"]>[0][\"where\"],\n data: Parameters<TModel[\"update\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">\n ): Promise<ReturnType<TModel[\"update\"]>> {\n const prisma = getPrismaInstance();\n\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(data, {\n ...this.relationFields,\n });\n\n return await prisma[this.modelName].update(\n deepmerge(\n {\n where: filters,\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates multiple records based on the provided filter and data.\n *\n * @param {Parameters<TModel[\"updateMany\"]>[0]['where']} filters - The filters to identify records to update.\n * @param {Parameters<TModel[\"updateMany\"]>[0][\"data\"]} data - The data to update the records with.\n * @param {Partial<Parameters<TModel[\"updateMany\"]>[0]>} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"updateMany\"]>>} The result of the updateMany operation.\n */\n async updateMany(\n filters: Parameters<TModel[\"updateMany\"]>[0][\"where\"],\n data: Parameters<TModel[\"updateMany\"]>[0][\"data\"],\n queryOptions?: Partial<Parameters<TModel[\"updateMany\"]>[0]>\n ): Promise<ReturnType<TModel[\"updateMany\"]>> {\n const prisma = getPrismaInstance();\n\n const firstMerge = deepmerge({ data }, (queryOptions as {}) || {});\n\n return await prisma[this.modelName].updateMany(\n deepmerge({ where: filters }, firstMerge)\n );\n }\n\n /**\n * Deletes a single record by its ID.\n *\n * @param {Parameters<TModel[\"delete\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"delete\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"delete\"]>>} The deleted record or null if an error occurs.\n */\n async deleteOne(\n filters: Parameters<TModel[\"delete\"]>[0][\"where\"],\n queryOptions?: Omit<Parameters<TModel[\"delete\"]>[0], \"where\">\n ): Promise<ReturnType<TModel[\"delete\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].delete(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Deletes multiple records based on the provided filter.\n *\n * @param {Parameters<TModel[\"deleteMany\"]>[0]['where']} filters - The filter to identify records to delete.\n * @param {Omit<Parameters<TModel[\"deleteMany\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"deleteMany\"]>>} The result of the deleteMany operation.\n */\n async deleteMany(\n filters: Record<string, any>,\n queryOptions: Partial<Parameters<TModel[\"deleteMany\"]>[0]> = {}\n ): Promise<ReturnType<TModel[\"deleteMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].deleteMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n}\n\n/**\n * Generates a set of base service instances for all available models.\n *\n * @returns {Record<string, BaseService>} A dictionary of base service instances, keyed by model name.\n */\nexport function getBaseServices(): Record<string, BaseService> {\n const models = getModels();\n const baseServices: Record<string, BaseService> = {};\n models.forEach((model) => {\n baseServices[`${camelCase(model)}`] = new BaseService(model);\n });\n return baseServices;\n}\n"]}
1
+ {"version":3,"file":"base.service.js","sourceRoot":"","sources":["../../../../src/modules/base/base.service.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n camelCase,\n kebabCase,\n pascalCase,\n} from \"../../utils/helpers/change-case.helpers\";\nimport {\n getModels,\n getPrismaModelRelations,\n RelationFields,\n} from \"../../utils/helpers/models.helpers\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { handleRelationFieldsInBody } from \"./utils/helpers/base.service.helpers\";\nimport { getPrismaInstance } from \"../../utils/helpers/prisma.helpers\";\nimport authService from \"../auth/auth.service\";\nimport { PrismaModelDelegate } from \"../../types\";\n\n/**\n * Base service class for handling CRUD operations on a specific model.\n * This class provides standard implementation of data operations that can be extended\n * by model-specific service classes.\n *\n * @class BaseService\n *\n * @usage\n *\n * **Example:** creating a simple service\n *\n * ```ts\n * import prisma from 'your-prisma-path'\n *\n * const userService = new BaseService<typeof prisma.user>(\"user\")\n * ```\n *\n *\n * @see {@link https://www.arkosjs.com/docs/api-reference/the-base-service-class}\n */\nexport class BaseService<TModel extends PrismaModelDelegate = any> {\n /**\n * The camelCase name of the model\n * @public\n */\n modelName: string;\n\n /**\n * Object containing singular and list relation fields for the model\n * @public\n */\n relationFields: RelationFields;\n\n /**\n * Instance of the Prisma client\n * @public\n */\n prisma: any;\n\n /**\n * Creates an instance of BaseService.\n * @param {string} modelName - The name of the model to perform operations on.\n */\n constructor(modelName: string) {\n this.modelName = camelCase(modelName);\n this.relationFields = getPrismaModelRelations(pascalCase(modelName))!;\n }\n\n /**\n * Creates a single record in the database.\n *\n * @param {Parameters<TModel[\"create\"]>[0][\"data\"]} data - The data to create the record with.\n * @param {Omit<Parameters<TModel[\"create\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<Promise<ReturnType<TModel[\"create\"]>>>} The created record.\n */\n async createOne(\n data: Parameters<TModel[\"create\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"create\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"create\"]>> {\n if (kebabCase(this.modelName) === \"user\" && (data as any).password) {\n (data as any).password = await authService.hashPassword(\n (data as any).password\n );\n }\n\n const prisma = getPrismaInstance();\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(\n data,\n {\n ...this.relationFields,\n },\n [\"delete\", \"disconnect\", \"update\"]\n );\n\n return await prisma[this.modelName].create(\n deepmerge(\n {\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Creates multiple records in the database.\n *\n * @param {Array<Omit<Parameters<TModel[\"createMany\"]>[0][\"data\"], never>[0]>} data - An array of data to create records with.\n * @param {Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"createMany\"]>>} The result of the createMany operation.\n */\n async createMany(\n data: Parameters<TModel[\"createMany\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"createMany\"]>[0], \"data\">\n ): Promise<ReturnType<TModel[\"createMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].createMany(\n deepmerge({ data }, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Counts records based on provided filters.\n *\n * @param {Parameters<TModel[\"count\"]>[0]} filters - The filters to apply to the query.\n * @returns {Promise<number>} The count of records matching the filters.\n */\n async count(filters: Parameters<TModel[\"count\"]>[0]): Promise<number> {\n const prisma = getPrismaInstance();\n\n const where = filters.where || {};\n return await prisma[this.modelName].count({\n where,\n });\n }\n\n /**\n * Finds multiple records based on provided filters.\n *\n * @param {Parameters<TModel[\"findMany\"]>[0]['where']} filters - The filters to apply to the query.\n * @param {Partial<Parameters<TModel[\"findMany\"]>[0]>} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"findMany\"]>>} The found data.\n */\n async findMany(\n filters: Parameters<TModel[\"findMany\"]>[0][\"where\"],\n queryOptions?: Omit<Partial<Parameters<TModel[\"findMany\"]>[0]>, \"where\">\n ): Promise<ReturnType<TModel[\"findMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].findMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n\n /**\n * Finds a single record by its parameters.\n *\n * @param {Parameters<TModel[\"findFirst\"]>[0][\"where\"] | Parameters<TModel[\"findUnique\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise< ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>>} The found record or null if not found.\n */\n async findOne(\n filters:\n | Parameters<TModel[\"findFirst\"]>[0][\"where\"]\n | Parameters<TModel[\"findUnique\"]>[0][\"where\"],\n queryOptions?:\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n | Omit<Parameters<TModel[\"findFirst\"]>[0], \"where\">\n ): Promise<\n ReturnType<TModel[\"findFirst\"]> | ReturnType<TModel[\"findUnique\"]>\n > {\n const prisma = getPrismaInstance();\n\n if (\n Object.keys(filters).length === 1 &&\n \"id\" in filters &&\n (filters as any).id !== \"me\"\n )\n return prisma[this.modelName].findUnique(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n\n return await prisma[this.modelName].findFirst(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates a single record by its ID.\n *\n * @param {Parameters<TModel[\"update\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Parameters<TModel[\"update\"]>[0][\"data\"]} data - The data to update the record with.\n * @param {Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">} [queryOptions] - Additional query options to modify the Prisma query.\n * @returns {Promise<ReturnType<TModel[\"update\"]>>} The updated record or null if not found.\n */\n async updateOne(\n filters: Parameters<TModel[\"update\"]>[0][\"where\"],\n data: Parameters<TModel[\"update\"]>[0][\"data\"],\n queryOptions?: Omit<Parameters<TModel[\"update\"]>[0], \"where\" | \"data\">\n ): Promise<ReturnType<TModel[\"update\"]>> {\n const prisma = getPrismaInstance();\n\n if (kebabCase(this.modelName) === \"user\" && data.password) {\n data.password = await authService.hashPassword(data.password);\n }\n\n const dataWithRelationFieldsHandled = handleRelationFieldsInBody(data, {\n ...this.relationFields,\n });\n\n return await prisma[this.modelName].update(\n deepmerge(\n {\n where: filters,\n data: dataWithRelationFieldsHandled,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Updates multiple records based on the provided filter and data.\n *\n * @param {Parameters<TModel[\"updateMany\"]>[0]['where']} filters - The filters to identify records to update.\n * @param {Parameters<TModel[\"updateMany\"]>[0][\"data\"]} data - The data to update the records with.\n * @param {Partial<Parameters<TModel[\"updateMany\"]>[0]>} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"updateMany\"]>>} The result of the updateMany operation.\n */\n async updateMany(\n filters: Parameters<TModel[\"updateMany\"]>[0][\"where\"],\n data: Parameters<TModel[\"updateMany\"]>[0][\"data\"],\n queryOptions?: Partial<Parameters<TModel[\"updateMany\"]>[0]>\n ): Promise<ReturnType<TModel[\"updateMany\"]>> {\n const prisma = getPrismaInstance();\n\n const firstMerge = deepmerge({ data }, (queryOptions as {}) || {});\n\n return await prisma[this.modelName].updateMany(\n deepmerge({ where: filters }, firstMerge)\n );\n }\n\n /**\n * Deletes a single record by its ID.\n *\n * @param {Parameters<TModel[\"delete\"]>[0][\"where\"]} filters - The parameters to find the record by.\n * @param {Omit<Parameters<TModel[\"delete\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"delete\"]>>} The deleted record or null if an error occurs.\n */\n async deleteOne(\n filters: Parameters<TModel[\"delete\"]>[0][\"where\"],\n queryOptions?: Omit<Parameters<TModel[\"delete\"]>[0], \"where\">\n ): Promise<ReturnType<TModel[\"delete\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].delete(\n deepmerge(\n {\n where: filters,\n },\n (queryOptions as {}) || {}\n )\n );\n }\n\n /**\n * Deletes multiple records based on the provided filter.\n *\n * @param {Parameters<TModel[\"deleteMany\"]>[0]['where']} filters - The filter to identify records to delete.\n * @param {Omit<Parameters<TModel[\"deleteMany\"]>[0], \"where\">} [queryOptions] - Additional query options.\n * @returns {Promise<ReturnType<TModel[\"deleteMany\"]>>} The result of the deleteMany operation.\n */\n async deleteMany(\n filters: Record<string, any>,\n queryOptions: Partial<Parameters<TModel[\"deleteMany\"]>[0]> = {}\n ): Promise<ReturnType<TModel[\"deleteMany\"]>> {\n const prisma = getPrismaInstance();\n\n return await prisma[this.modelName].deleteMany(\n deepmerge(filters, (queryOptions as {}) || {})\n );\n }\n}\n\n/**\n * Generates a set of base service instances for all available models.\n *\n * @returns {Record<string, BaseService>} A dictionary of base service instances, keyed by model name.\n */\nexport function getBaseServices(): Record<string, BaseService> {\n const models = getModels();\n const baseServices: Record<string, BaseService> = {};\n models.forEach((model) => {\n baseServices[`${camelCase(model)}`] = new BaseService(model);\n });\n return baseServices;\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  export var AuthPermissionAction;
2
2
  (function (AuthPermissionAction) {
3
- AuthPermissionAction["create"] = "create";
4
- AuthPermissionAction["view"] = "view";
5
- AuthPermissionAction["update"] = "update";
6
- AuthPermissionAction["delete"] = "delete";
3
+ AuthPermissionAction["Create"] = "Create";
4
+ AuthPermissionAction["View"] = "View";
5
+ AuthPermissionAction["Update"] = "Update";
6
+ AuthPermissionAction["Delete"] = "Delete";
7
7
  })(AuthPermissionAction || (AuthPermissionAction = {}));
8
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAmCA,MAAM,CAAN,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,KAApB,oBAAoB,QAK/B","sourcesContent":["import { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T extends Record<string, any>> = {\n queryOptions?: Partial<Parameters<T[\"findMany\"]>[0]>;\n findOne?: Partial<Parameters<T[\"findFirst\"]>[0]>;\n findMany?: Partial<Parameters<T[\"findMany\"]>[0]>;\n deleteMany?: Partial<Parameters<T[\"deleteMany\"]>[0]>;\n updateMany?: Partial<Parameters<T[\"updateMany\"]>[0]>;\n createMany?: Partial<Parameters<T[\"createMany\"]>[0]>;\n createOne?: Partial<Parameters<T[\"create\"]>[0]>;\n updateOne?: Partial<Parameters<T[\"update\"]>[0]>;\n deleteOne?: Partial<Parameters<T[\"delete\"]>[0]>;\n};\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n create = \"create\",\n view = \"view\",\n update = \"update\",\n delete = \"delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest<Body = any, Query = any> extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n body: Body;\n prismaQueryOptions?: Record<string, any>;\n // query: Query extends Request['ParsedQs'];\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAwDA,MAAM,CAAN,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,KAApB,oBAAoB,QAK/B","sourcesContent":["import { NextFunction, Request, RequestHandler, Response } from \"express\";\n\nexport type PrismaOperations = \"findMany\";\n\nexport type PrismaQueryOptions<T extends Record<string, any>> = {\n queryOptions?: Partial<Parameters<T[\"findMany\"]>[0]>;\n findOne?: Partial<Parameters<T[\"findFirst\"]>[0]>;\n findMany?: Partial<Parameters<T[\"findMany\"]>[0]>;\n deleteMany?: Partial<Parameters<T[\"deleteMany\"]>[0]>;\n updateMany?: Partial<Parameters<T[\"updateMany\"]>[0]>;\n createMany?: Partial<Parameters<T[\"createMany\"]>[0]>;\n createOne?: Partial<Parameters<T[\"create\"]>[0]>;\n updateOne?: Partial<Parameters<T[\"update\"]>[0]>;\n deleteOne?: Partial<Parameters<T[\"delete\"]>[0]>;\n};\n\n/**\n * Interface defining the minimum structure required for Prisma model delegates\n * This allows us to constraint TModel without requiring Prisma imports\n */\nexport interface PrismaModelDelegate {\n create: (args: { data: any; [key: string]: any }) => Promise<any>;\n createMany: (args: { data: any; [key: string]: any }) => Promise<any>;\n findMany: (args: { where?: any; [key: string]: any }) => Promise<any[]>;\n findFirst: (args: { where: any; [key: string]: any }) => Promise<any>;\n findUnique: (args: { where: any; [key: string]: any }) => Promise<any>;\n update: (args: { where: any; data: any; [key: string]: any }) => Promise<any>;\n updateMany: (args: {\n where: any;\n data: any;\n [key: string]: any;\n }) => Promise<any>;\n delete: (args: { where: any; [key: string]: any }) => Promise<any>;\n deleteMany: (args: { where: any; [key: string]: any }) => Promise<any>;\n count: (args: { where?: any; [key: string]: any }) => Promise<number>;\n}\n\nexport interface UserRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n roleId: string;\n role: AuthRole;\n user: User;\n userId: string;\n}\n\nexport interface AuthRole {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n name: string;\n permissions: AuthPermission[];\n userRoles: UserRole[];\n}\n\nexport enum AuthPermissionAction {\n Create = \"Create\",\n View = \"View\",\n Update = \"Update\",\n Delete = \"Delete\",\n}\n\nexport interface AuthPermission {\n id: string;\n createdAt: Date;\n deletedAt?: Date;\n resource: string;\n action: AuthPermissionAction;\n roleId: string;\n role: AuthRole;\n}\n\nexport interface User {\n id: string;\n isStaff: boolean;\n isSuperUser: boolean;\n password: string;\n passwordChangedAt?: Date;\n deletedSelfAccountAt: Date;\n isActive: boolean;\n roles?: UserRole[] | any[];\n role?: UserRole | any;\n}\n\nexport interface ArkosRequest<Body = any, Query = any> extends Request {\n user?: User & Record<string, any>;\n relationFields?: Record<string, boolean>;\n include?: Record<string, any>;\n responseData?: Record<string, any> | null | undefined;\n additionalData?: Record<string, any> | null | undefined;\n responseStatus?: number | string | null | undefined;\n body: Body;\n prismaQueryOptions?: Record<string, any>;\n // query: Query extends Request['ParsedQs'];\n}\n\nexport interface ArkosResponse extends Response {}\nexport interface ArkosNextFunction extends NextFunction {}\nexport interface ArkosRequestHandler extends RequestHandler {}\n"]}
@@ -1,5 +1,6 @@
1
1
  import { RelationFields } from "../../utils/helpers/models.helpers";
2
- export declare class BaseService<TModel extends Record<any, (args: any) => any> = Record<any, any>> {
2
+ import { PrismaModelDelegate } from "../../types";
3
+ export declare class BaseService<TModel extends PrismaModelDelegate = any> {
3
4
  modelName: string;
4
5
  relationFields: RelationFields;
5
6
  prisma: any;
@@ -11,6 +11,50 @@ export type PrismaQueryOptions<T extends Record<string, any>> = {
11
11
  updateOne?: Partial<Parameters<T["update"]>[0]>;
12
12
  deleteOne?: Partial<Parameters<T["delete"]>[0]>;
13
13
  };
14
+ export interface PrismaModelDelegate {
15
+ create: (args: {
16
+ data: any;
17
+ [key: string]: any;
18
+ }) => Promise<any>;
19
+ createMany: (args: {
20
+ data: any;
21
+ [key: string]: any;
22
+ }) => Promise<any>;
23
+ findMany: (args: {
24
+ where?: any;
25
+ [key: string]: any;
26
+ }) => Promise<any[]>;
27
+ findFirst: (args: {
28
+ where: any;
29
+ [key: string]: any;
30
+ }) => Promise<any>;
31
+ findUnique: (args: {
32
+ where: any;
33
+ [key: string]: any;
34
+ }) => Promise<any>;
35
+ update: (args: {
36
+ where: any;
37
+ data: any;
38
+ [key: string]: any;
39
+ }) => Promise<any>;
40
+ updateMany: (args: {
41
+ where: any;
42
+ data: any;
43
+ [key: string]: any;
44
+ }) => Promise<any>;
45
+ delete: (args: {
46
+ where: any;
47
+ [key: string]: any;
48
+ }) => Promise<any>;
49
+ deleteMany: (args: {
50
+ where: any;
51
+ [key: string]: any;
52
+ }) => Promise<any>;
53
+ count: (args: {
54
+ where?: any;
55
+ [key: string]: any;
56
+ }) => Promise<number>;
57
+ }
14
58
  export interface UserRole {
15
59
  id: string;
16
60
  createdAt: Date;
@@ -29,10 +73,10 @@ export interface AuthRole {
29
73
  userRoles: UserRole[];
30
74
  }
31
75
  export declare enum AuthPermissionAction {
32
- create = "create",
33
- view = "view",
34
- update = "update",
35
- delete = "delete"
76
+ Create = "Create",
77
+ View = "View",
78
+ Update = "Update",
79
+ Delete = "Delete"
36
80
  }
37
81
  export interface AuthPermission {
38
82
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkos",
3
- "version": "1.1.22-test",
3
+ "version": "1.1.23-test",
4
4
  "description": "The Express & Prisma Framework For RESTful API",
5
5
  "main": "dist/cjs/exports/index.js",
6
6
  "module": "dist/es2020/exports/index.js",