arkos 1.4.0-canary.83 → 1.4.0-canary.85

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 (63) hide show
  1. package/dist/cjs/modules/auth/auth.router.js +12 -12
  2. package/dist/cjs/modules/auth/auth.router.js.map +1 -1
  3. package/dist/cjs/modules/base/base.middlewares.js +1 -0
  4. package/dist/cjs/modules/base/base.middlewares.js.map +1 -1
  5. package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js +10 -10
  6. package/dist/cjs/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
  7. package/dist/cjs/modules/swagger/utils/helpers/class-validator-to-json-schema.js +2 -2
  8. package/dist/cjs/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +1 -1
  9. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js +2 -2
  10. package/dist/cjs/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js.map +1 -1
  11. package/dist/cjs/utils/arkos-router/index.js +6 -5
  12. package/dist/cjs/utils/arkos-router/index.js.map +1 -1
  13. package/dist/cjs/utils/arkos-router/types/body-parser-config.js +3 -0
  14. package/dist/cjs/utils/arkos-router/types/body-parser-config.js.map +1 -0
  15. package/dist/cjs/utils/arkos-router/types/index.js.map +1 -1
  16. package/dist/cjs/utils/arkos-router/utils/helpers/index.js +14 -3
  17. package/dist/cjs/utils/arkos-router/utils/helpers/index.js.map +1 -1
  18. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js +5 -4
  19. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  20. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  21. package/dist/cjs/utils/helpers/api.features.helpers.js.map +1 -1
  22. package/dist/cjs/utils/helpers/dynamic-loader.helpers.js +34 -55
  23. package/dist/cjs/utils/helpers/dynamic-loader.helpers.js.map +1 -1
  24. package/dist/cjs/utils/helpers/query-parser.helpers.js +24 -0
  25. package/dist/cjs/utils/helpers/query-parser.helpers.js.map +1 -1
  26. package/dist/cjs/utils/helpers/routers.helpers.js +6 -4
  27. package/dist/cjs/utils/helpers/routers.helpers.js.map +1 -1
  28. package/dist/esm/modules/auth/auth.router.js +12 -12
  29. package/dist/esm/modules/auth/auth.router.js.map +1 -1
  30. package/dist/esm/modules/base/base.middlewares.js +1 -0
  31. package/dist/esm/modules/base/base.middlewares.js.map +1 -1
  32. package/dist/esm/modules/base/utils/helpers/base.router.helpers.js +10 -10
  33. package/dist/esm/modules/base/utils/helpers/base.router.helpers.js.map +1 -1
  34. package/dist/esm/modules/swagger/utils/helpers/class-validator-to-json-schema.js +1 -1
  35. package/dist/esm/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +1 -1
  36. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js +1 -1
  37. package/dist/esm/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.js.map +1 -1
  38. package/dist/esm/utils/arkos-router/index.js +6 -5
  39. package/dist/esm/utils/arkos-router/index.js.map +1 -1
  40. package/dist/esm/utils/arkos-router/types/body-parser-config.js +2 -0
  41. package/dist/esm/utils/arkos-router/types/body-parser-config.js.map +1 -0
  42. package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
  43. package/dist/esm/utils/arkos-router/utils/helpers/index.js +14 -3
  44. package/dist/esm/utils/arkos-router/utils/helpers/index.js.map +1 -1
  45. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js +5 -4
  46. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  47. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  48. package/dist/esm/utils/helpers/api.features.helpers.js.map +1 -1
  49. package/dist/esm/utils/helpers/arkos-config.helpers.js +2 -2
  50. package/dist/esm/utils/helpers/dynamic-loader.helpers.js +34 -55
  51. package/dist/esm/utils/helpers/dynamic-loader.helpers.js.map +1 -1
  52. package/dist/esm/utils/helpers/query-parser.helpers.js +24 -0
  53. package/dist/esm/utils/helpers/query-parser.helpers.js.map +1 -1
  54. package/dist/esm/utils/helpers/routers.helpers.js +6 -4
  55. package/dist/esm/utils/helpers/routers.helpers.js.map +1 -1
  56. package/dist/types/modules/auth/auth.router.d.ts +1 -1
  57. package/dist/types/modules/base/utils/helpers/base.router.helpers.d.ts +1 -1
  58. package/dist/types/utils/arkos-router/types/body-parser-config.d.ts +18 -0
  59. package/dist/types/utils/arkos-router/types/index.d.ts +2 -17
  60. package/dist/types/utils/arkos-router/utils/helpers/upload-manager.d.ts +2 -2
  61. package/dist/types/utils/helpers/query-parser.helpers.d.ts +1 -0
  62. package/dist/types/utils/helpers/routers.helpers.d.ts +2 -1
  63. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"generate-class-validator-json-schemas.js","sourceRoot":"","sources":["../../../../../../../src/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,kBAAkB,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,MAAM,UAAU,iCAAiC;IAC/C,MAAM,kBAAkB,GAAG;QACzB,GAAG,kBAAkB,CAAC,yBAAyB,EAAE;QACjD,MAAM;KACP,CAAC;IACF,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,MAAM,UAAU,GAAG,4BAA4B,CAAC;QAC9C,6BAA6B,EAAE,kBAAkB,EAAE;QACnD,+BAA+B,EAAE,sBAAsB;QACvD,gBAAgB,EAAE,uBAAuB;KAC1C,CAAC,CAAC;IAEH,kBAAkB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QACvC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAExD,IAAI,gBAAgB,EAAE,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE;gBACpE,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBACnD,IAAI,QAAQ,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBACjE,IAAI,CAAC;wBACH,MAAM,UAAU,GAAG,wBAAwB,CACzC,OAAO,EACP,SAAS,EACT,KAAK,CACN,CAAC;wBAEF,IAAI,OAAO,CAAC,UAAU,CAAC;4BACrB,MAAM,KAAK,CACT,qBAAqB,QAAQ,CAAC,IAAI,4BAA4B,oBAAoB,EAAE,uFAAuF,CAC5K,CAAC;wBAEJ,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACxD,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAClB,MAAM,IAAI,KAAK,CACb,iCAAiC,OAAO,IAAI,SAAS,KAAK,GAAG,CAAC,OAAO,EAAE,CACxE,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE;QACzD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC;IACvD,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { validationMetadatasToSchemas } from \"class-validator-jsonschema\";\nimport { getMetadataStorage } from \"class-validator\";\nimport { getModuleComponents } from \"../../../../../utils/dynamic-loader\";\nimport { getCorrectJsonSchemaName } from \"../swagger.router.helpers\";\nimport prismaSchemaParser from \"../../../../../utils/prisma/prisma-schema-parser\";\nimport { getUserFileExtension } from \"../../../../../utils/helpers/fs.helpers\";\nimport { defaultMetadataStorage } from \"class-transformer/cjs/storage\";\n\nexport function generateClassValidatorJsonSchemas() {\n const requiredAppModules = [\n ...prismaSchemaParser.getModelsAsArrayOfStrings(),\n \"auth\",\n ];\n const schemas: Record<string, any> = {};\n\n const jsonSchema = validationMetadatasToSchemas({\n classValidatorMetadataStorage: getMetadataStorage(),\n classTransformerMetadataStorage: defaultMetadataStorage,\n refPointerPrefix: \"#/components/schemas/\",\n });\n\n requiredAppModules.forEach((modelName) => {\n const moduleComponents = getModuleComponents(modelName);\n\n if (moduleComponents?.dtos) {\n Object.entries(moduleComponents.dtos).forEach(([dtoType, dtoClass]) => {\n const ignoredDtoTypes = [\"createone\", \"updateone\"];\n if (dtoClass && !ignoredDtoTypes.includes(dtoType.toLowerCase())) {\n try {\n const schemaName = getCorrectJsonSchemaName(\n dtoType,\n modelName,\n \"Dto\"\n );\n\n if (schemas[schemaName])\n throw Error(\n `Found more then 1 ${dtoClass.name} classes among your .dto.${getUserFileExtension()} files, there is no way to correctly generate json-schemas for swagger documentation.`\n );\n\n schemas[schemaName] = jsonSchema[dtoClass.name] || {};\n } catch (err: any) {\n throw new Error(\n `Failed to generate schema for ${dtoType} ${modelName}: ${err.message}`\n );\n }\n }\n });\n }\n });\n\n Object.entries(jsonSchema).forEach(([className, schema]) => {\n if (!schemas[className]) schemas[className] = schema;\n });\n return schemas;\n}\n"]}
1
+ {"version":3,"file":"generate-class-validator-json-schemas.js","sourceRoot":"","sources":["../../../../../../../src/modules/swagger/utils/helpers/json-schema-generators/generate-class-validator-json-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,kBAAkB,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAE1E,MAAM,UAAU,iCAAiC;IAC/C,MAAM,kBAAkB,GAAG;QACzB,GAAG,kBAAkB,CAAC,yBAAyB,EAAE;QACjD,MAAM;KACP,CAAC;IACF,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,MAAM,UAAU,GAAG,4BAA4B,CAAC;QAC9C,6BAA6B,EAAE,kBAAkB,EAAE;QACnD,+BAA+B,EAAE,sBAAsB;QACvD,gBAAgB,EAAE,uBAAuB;KAC1C,CAAC,CAAC;IAEH,kBAAkB,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QACvC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAExD,IAAI,gBAAgB,EAAE,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE;gBACpE,MAAM,eAAe,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;gBACnD,IAAI,QAAQ,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBACjE,IAAI,CAAC;wBACH,MAAM,UAAU,GAAG,wBAAwB,CACzC,OAAO,EACP,SAAS,EACT,KAAK,CACN,CAAC;wBAEF,IAAI,OAAO,CAAC,UAAU,CAAC;4BACrB,MAAM,KAAK,CACT,qBAAqB,QAAQ,CAAC,IAAI,4BAA4B,oBAAoB,EAAE,uFAAuF,CAC5K,CAAC;wBAEJ,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACxD,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAClB,MAAM,IAAI,KAAK,CACb,iCAAiC,OAAO,IAAI,SAAS,KAAK,GAAG,CAAC,OAAO,EAAE,CACxE,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE;QACzD,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,OAAO,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC;IACvD,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { validationMetadatasToSchemas } from \"class-validator-jsonschema\";\nimport { getMetadataStorage } from \"class-validator\";\nimport { getModuleComponents } from \"../../../../../utils/dynamic-loader\";\nimport { getCorrectJsonSchemaName } from \"../swagger.router.helpers\";\nimport prismaSchemaParser from \"../../../../../utils/prisma/prisma-schema-parser\";\nimport { getUserFileExtension } from \"../../../../../utils/helpers/fs.helpers\";\nimport { defaultMetadataStorage } from \"class-transformer/cjs/storage.js\";\n\nexport function generateClassValidatorJsonSchemas() {\n const requiredAppModules = [\n ...prismaSchemaParser.getModelsAsArrayOfStrings(),\n \"auth\",\n ];\n const schemas: Record<string, any> = {};\n\n const jsonSchema = validationMetadatasToSchemas({\n classValidatorMetadataStorage: getMetadataStorage(),\n classTransformerMetadataStorage: defaultMetadataStorage,\n refPointerPrefix: \"#/components/schemas/\",\n });\n\n requiredAppModules.forEach((modelName) => {\n const moduleComponents = getModuleComponents(modelName);\n\n if (moduleComponents?.dtos) {\n Object.entries(moduleComponents.dtos).forEach(([dtoType, dtoClass]) => {\n const ignoredDtoTypes = [\"createone\", \"updateone\"];\n if (dtoClass && !ignoredDtoTypes.includes(dtoType.toLowerCase())) {\n try {\n const schemaName = getCorrectJsonSchemaName(\n dtoType,\n modelName,\n \"Dto\"\n );\n\n if (schemas[schemaName])\n throw Error(\n `Found more then 1 ${dtoClass.name} classes among your .dto.${getUserFileExtension()} files, there is no way to correctly generate json-schemas for swagger documentation.`\n );\n\n schemas[schemaName] = jsonSchema[dtoClass.name] || {};\n } catch (err: any) {\n throw new Error(\n `Failed to generate schema for ${dtoType} ${modelName}: ${err.message}`\n );\n }\n }\n });\n }\n });\n\n Object.entries(jsonSchema).forEach(([className, schema]) => {\n if (!schemas[className]) schemas[className] = schema;\n });\n return schemas;\n}\n"]}
@@ -28,8 +28,8 @@ export default function ArkosRouter() {
28
28
  return function (config, ...handlers) {
29
29
  if (config.disabled)
30
30
  return;
31
- const route = config.path;
32
- if (!route)
31
+ const path = config.path;
32
+ if (!path)
33
33
  throw Error("Please pass valid value for path field to use in your route");
34
34
  if (!RouteConfigValidator.isArkosRouteConfig(config))
35
35
  throw Error(`First argument of ArkosRouter().${prop}() must be a valid ArkosRouteConfig object with path field, but recevied ${typeof config === "object" ? JSON.stringify(config, null, 2) : config}`);
@@ -51,6 +51,7 @@ export default function ArkosRouter() {
51
51
  const validationConfig = arkosConfig.validation;
52
52
  const authenticationConfig = arkosConfig.authentication;
53
53
  const strictValidation = validationConfig?.strict;
54
+ const route = `${method.toUpperCase()} ${path}`;
54
55
  if (strictValidation &&
55
56
  (!("validation" in config) ||
56
57
  ("validation" in config &&
@@ -58,14 +59,14 @@ export default function ArkosRouter() {
58
59
  config.validation !== undefined)))
59
60
  throw Error("When using strict validation you must either pass { validation: false } in order to explicitly tell that no input will be received, or pass `undefined` for each input type e.g { validation: { query: undefined } } in order to deny the input of given request input.");
60
61
  if (!validationConfig?.resolver && config.validation)
61
- throw Error("Trying to pass validators into route config validation option without choosing a validation resolver under arkos.init({ validation: { resolver: '' } })");
62
+ throw Error(`Trying to pass validators into route ${route} config validation option without choosing a validation resolver under arkos.init({ validation: { resolver: '' } })`);
62
63
  if (config.authentication && !authenticationConfig?.mode)
63
- throw Error("Trying to authenticate a route without choosing an authentication mode under arkos.init({ authentication: { mode: '' } })");
64
+ throw Error(`Trying to authenticate route ${route} without choosing an authentication mode under arkos.init({ authentication: { mode: '' } })`);
64
65
  handlers = [...getMiddlewareStack(config), ...handlers];
65
66
  if (config.experimental?.uploads &&
66
67
  config.experimental.uploads.deleteOnError !== false)
67
68
  handlers.push(catchAsync(uploadManager.handleFileCleanup(config.experimental.uploads), { type: "error" }));
68
- return originalMethod.call(target, route, ...handlers);
69
+ return originalMethod.call(target, path, ...handlers);
69
70
  };
70
71
  }
71
72
  return originalMethod;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport { IArkosRouter, ArkosRouteConfig } from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport RouteConfigValidator from \"./route-config-validator\";\nimport RouteConfigRegistry from \"./route-config-registry\";\nimport { extractArkosRoutes, getMiddlewareStack } from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../types\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport classValidatorToJsonSchema from \"../../modules/swagger/utils/helpers/class-validator-to-json-schema\";\nimport openApiSchemaConverter from \"../../modules/swagger/utils/helpers/openapi-schema-converter\";\nimport uploadManager from \"./utils/helpers/upload-manager\";\n\n/**\n * Creates an enhanced Express Router with features like OpenAPI documentation capabilities and smart data validation.\n *\n * The ArkosRouter extends the standard Express Router with the ability to\n * automatically capture OpenAPI metadata from route configurations.\n *\n * @example\n * const router = ArkosRouter();\n *\n * router.get(\n * {\n * path: \"/users/:id\",\n * openapi: {\n * summary: \"Get user by ID\",\n * tags: [\"Users\"]\n * }\n * },\n * (req, res) => { ... }\n * );\n *\n * @returns {IArkosRouter} A proxied Express Router instance with enhanced OpenAPI capabilities\n *\n * @see {@link ArkosRouteConfig} for configuration options\n */\nexport default function ArkosRouter(): IArkosRouter {\n const router: IArkosRouter = Router();\n\n return new Proxy(router, {\n get(target, prop, receiver) {\n const originalMethod = Reflect.get(target, prop, receiver);\n\n const httpMethods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"all\",\n \"head\",\n \"trace\",\n \"options\",\n ];\n\n type ArkosAnyRequestHandler =\n | ArkosRequestHandler\n | ArkosErrorRequestHandler;\n\n if (httpMethods.includes(prop as string)) {\n return function (\n config: ArkosRouteConfig,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n if (config.disabled) return;\n\n const route = config.path;\n\n if (!route)\n throw Error(\n \"Please pass valid value for path field to use in your route\"\n );\n\n if (!RouteConfigValidator.isArkosRouteConfig(config))\n throw Error(\n `First argument of ArkosRouter().${prop as string}() must be a valid ArkosRouteConfig object with path field, but recevied ${typeof config === \"object\" ? JSON.stringify(config, null, 2) : config}`\n );\n\n const method = prop as string;\n\n if (handlers.length > 0) {\n handlers = handlers.map(\n (handler: ArkosAnyRequestHandler | ArkosAnyRequestHandler[]) => {\n return typeof handler === \"function\"\n ? catchAsync(handler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\n })\n : handler.map((nesteHandler: any) =>\n catchAsync(nesteHandler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\n })\n );\n }\n );\n\n const finalHandler = handlers[handlers.length - 1];\n RouteConfigRegistry.register(finalHandler, config, method);\n }\n\n const arkosConfig = getArkosConfig();\n const validationConfig = arkosConfig.validation;\n const authenticationConfig = arkosConfig.authentication;\n const strictValidation = validationConfig?.strict;\n\n if (\n strictValidation &&\n (!(\"validation\" in config) ||\n (\"validation\" in config &&\n !config.validation &&\n config.validation !== undefined))\n )\n throw Error(\n \"When using strict validation you must either pass { validation: false } in order to explicitly tell that no input will be received, or pass `undefined` for each input type e.g { validation: { query: undefined } } in order to deny the input of given request input.\"\n );\n\n if (!validationConfig?.resolver && config.validation)\n throw Error(\n \"Trying to pass validators into route config validation option without choosing a validation resolver under arkos.init({ validation: { resolver: '' } })\"\n );\n\n if (config.authentication && !authenticationConfig?.mode)\n throw Error(\n \"Trying to authenticate a route without choosing an authentication mode under arkos.init({ authentication: { mode: '' } })\"\n );\n\n handlers = [...getMiddlewareStack(config), ...handlers];\n\n if (\n config.experimental?.uploads &&\n config.experimental.uploads.deleteOnError !== false\n )\n handlers.push(\n catchAsync(\n uploadManager.handleFileCleanup(config.experimental.uploads),\n { type: \"error\" }\n )\n );\n\n return originalMethod.call(target, route, ...handlers);\n };\n }\n // }\n return originalMethod;\n },\n }) as IArkosRouter;\n}\n\nexport function generateOpenAPIFromApp(app: any) {\n const routes = extractArkosRoutes(app);\n const arkosConfig = getArkosConfig();\n\n let paths: Record<\n string,\n Record<string, Partial<OpenAPIV3.OperationObject>>\n > = {};\n\n routes.forEach(({ path, method, config }) => {\n if (config?.experimental?.openapi === false) return;\n\n if (!paths[path]) paths[path] = {};\n\n if (typeof config?.experimental?.openapi === \"boolean\") {\n config = {\n ...config,\n experimental: {\n ...config.experimental,\n openapi: {},\n },\n };\n }\n\n const openapi =\n typeof config?.experimental?.openapi === \"object\" &&\n config.experimental.openapi !== null\n ? config.experimental.openapi\n : {};\n\n const validatorToJsonSchema =\n arkosConfig?.validation?.resolver === \"zod\"\n ? zodToJsonSchema\n : classValidatorToJsonSchema;\n\n let parameters = [];\n const validationToParameterMapping = {\n query: \"query\",\n params: \"path\",\n headers: \"header\",\n cookies: \"cookie\",\n };\n\n if (typeof config?.validation !== \"boolean\" && config?.validation) {\n for (const [key, val] of Object.entries(config?.validation)) {\n if ([\"body\"].includes(key)) continue;\n if ((config?.validation as any)[key]) {\n const jsonSchema = validatorToJsonSchema(val as any);\n const params = openApiSchemaConverter.jsonSchemaToOpeApiParameters(\n (validationToParameterMapping as any)[key],\n jsonSchema\n );\n parameters.push(...params);\n }\n }\n }\n\n const convertedOpenAPI =\n openApiSchemaConverter.convertOpenAPIConfig(openapi);\n\n (paths as any)[path][method.toLowerCase()] = {\n summary: openapi?.summary || `${method} ${path}`,\n description: openapi?.description || `${method} ${path}`,\n tags: openapi?.tags || [\"Defaults\"],\n operationId: `${method.toLowerCase()}:${path}`,\n parameters: [...(convertedOpenAPI.parameters || []), ...parameters],\n ...(!convertedOpenAPI.requestBody &&\n config?.validation &&\n config?.validation?.body && {\n requestBody: {\n content: {\n \"application/json\": {\n schema: validatorToJsonSchema(config?.validation?.body as any),\n },\n },\n },\n }),\n ...convertedOpenAPI,\n };\n });\n\n return paths;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,OAAO,oBAAoB,MAAM,0BAA0B,CAAC;AAC5D,OAAO,mBAAmB,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEzD,OAAO,eAAe,MAAM,oBAAoB,CAAC;AACjD,OAAO,0BAA0B,MAAM,oEAAoE,CAAC;AAC5G,OAAO,sBAAsB,MAAM,8DAA8D,CAAC;AAClG,OAAO,aAAa,MAAM,gCAAgC,CAAC;AA0B3D,MAAM,CAAC,OAAO,UAAU,WAAW;IACjC,MAAM,MAAM,GAAiB,MAAM,EAAE,CAAC;IAEtC,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;QACvB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;YACxB,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAE3D,MAAM,WAAW,GAAG;gBAClB,KAAK;gBACL,MAAM;gBACN,KAAK;gBACL,OAAO;gBACP,QAAQ;gBACR,KAAK;gBACL,MAAM;gBACN,OAAO;gBACP,SAAS;aACV,CAAC;YAMF,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAc,CAAC,EAAE,CAAC;gBACzC,OAAO,UACL,MAAwB,EACxB,GAAG,QAAkC;oBAErC,IAAI,MAAM,CAAC,QAAQ;wBAAE,OAAO;oBAE5B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;oBAEzB,IAAI,CAAC,IAAI;wBACP,MAAM,KAAK,CACT,6DAA6D,CAC9D,CAAC;oBAEJ,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,MAAM,CAAC;wBAClD,MAAM,KAAK,CACT,mCAAmC,IAAc,4EAA4E,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CACrM,CAAC;oBAEJ,MAAM,MAAM,GAAG,IAAc,CAAC;oBAE9B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,QAAQ,GAAG,QAAQ,CAAC,GAAG,CACrB,CAAC,OAA0D,EAAE,EAAE;4BAC7D,OAAO,OAAO,OAAO,KAAK,UAAU;gCAClC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE;oCAClB,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;iCAC9C,CAAC;gCACJ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,YAAiB,EAAE,EAAE,CAChC,UAAU,CAAC,YAAY,EAAE;oCACvB,IAAI,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ;iCAC9C,CAAC,CACH,CAAC;wBACR,CAAC,CACF,CAAC;wBAEF,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;wBACnD,mBAAmB,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;oBAC7D,CAAC;oBAED,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;oBACrC,MAAM,gBAAgB,GAAG,WAAW,CAAC,UAAU,CAAC;oBAChD,MAAM,oBAAoB,GAAG,WAAW,CAAC,cAAc,CAAC;oBACxD,MAAM,gBAAgB,GAAG,gBAAgB,EAAE,MAAM,CAAC;oBAClD,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC;oBAEhD,IACE,gBAAgB;wBAChB,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,CAAC;4BACxB,CAAC,YAAY,IAAI,MAAM;gCACrB,CAAC,MAAM,CAAC,UAAU;gCAClB,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;wBAErC,MAAM,KAAK,CACT,yQAAyQ,CAC1Q,CAAC;oBAEJ,IAAI,CAAC,gBAAgB,EAAE,QAAQ,IAAI,MAAM,CAAC,UAAU;wBAClD,MAAM,KAAK,CACT,wCAAwC,KAAK,qHAAqH,CACnK,CAAC;oBAEJ,IAAI,MAAM,CAAC,cAAc,IAAI,CAAC,oBAAoB,EAAE,IAAI;wBACtD,MAAM,KAAK,CACT,gCAAgC,KAAK,6FAA6F,CACnI,CAAC;oBAEJ,QAAQ,GAAG,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC;oBAExD,IACE,MAAM,CAAC,YAAY,EAAE,OAAO;wBAC5B,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,aAAa,KAAK,KAAK;wBAEnD,QAAQ,CAAC,IAAI,CACX,UAAU,CACR,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAC5D,EAAE,IAAI,EAAE,OAAO,EAAE,CAClB,CACF,CAAC;oBAEJ,OAAO,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,CAAC;gBACxD,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,cAAc,CAAC;QACxB,CAAC;KACF,CAAiB,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,GAAQ;IAC7C,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,IAAI,KAAK,GAGL,EAAE,CAAC;IAEP,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1C,IAAI,MAAM,EAAE,YAAY,EAAE,OAAO,KAAK,KAAK;YAAE,OAAO;QAEpD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAEnC,IAAI,OAAO,MAAM,EAAE,YAAY,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;YACvD,MAAM,GAAG;gBACP,GAAG,MAAM;gBACT,YAAY,EAAE;oBACZ,GAAG,MAAM,CAAC,YAAY;oBACtB,OAAO,EAAE,EAAE;iBACZ;aACF,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GACX,OAAO,MAAM,EAAE,YAAY,EAAE,OAAO,KAAK,QAAQ;YACjD,MAAM,CAAC,YAAY,CAAC,OAAO,KAAK,IAAI;YAClC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO;YAC7B,CAAC,CAAC,EAAE,CAAC;QAET,MAAM,qBAAqB,GACzB,WAAW,EAAE,UAAU,EAAE,QAAQ,KAAK,KAAK;YACzC,CAAC,CAAC,eAAe;YACjB,CAAC,CAAC,0BAA0B,CAAC;QAEjC,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,MAAM,4BAA4B,GAAG;YACnC,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,QAAQ;SAClB,CAAC;QAEF,IAAI,OAAO,MAAM,EAAE,UAAU,KAAK,SAAS,IAAI,MAAM,EAAE,UAAU,EAAE,CAAC;YAClE,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;gBAC5D,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,SAAS;gBACrC,IAAI,CAAC,MAAM,EAAE,UAAkB,CAAA,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrC,MAAM,UAAU,GAAG,qBAAqB,CAAC,GAAU,CAAC,CAAC;oBACrD,MAAM,MAAM,GAAG,sBAAsB,CAAC,4BAA4B,CAC/D,4BAAoC,CAAC,GAAG,CAAC,EAC1C,UAAU,CACX,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,gBAAgB,GACpB,sBAAsB,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAEtD,KAAa,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,GAAG;YAC3C,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,GAAG,MAAM,IAAI,IAAI,EAAE;YAChD,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,GAAG,MAAM,IAAI,IAAI,EAAE;YACxD,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC;YACnC,WAAW,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE;YAC9C,UAAU,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC;YACnE,GAAG,CAAC,CAAC,gBAAgB,CAAC,WAAW;gBAC/B,MAAM,EAAE,UAAU;gBAClB,MAAM,EAAE,UAAU,EAAE,IAAI,IAAI;gBAC1B,WAAW,EAAE;oBACX,OAAO,EAAE;wBACP,kBAAkB,EAAE;4BAClB,MAAM,EAAE,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAW,CAAC;yBAC/D;qBACF;iBACF;aACF,CAAC;YACJ,GAAG,gBAAgB;SACpB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import { Router } from \"express\";\nimport { IArkosRouter, ArkosRouteConfig } from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport RouteConfigValidator from \"./route-config-validator\";\nimport RouteConfigRegistry from \"./route-config-registry\";\nimport { extractArkosRoutes, getMiddlewareStack } from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\nimport { catchAsync } from \"../../exports/error-handler\";\nimport { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../types\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport classValidatorToJsonSchema from \"../../modules/swagger/utils/helpers/class-validator-to-json-schema\";\nimport openApiSchemaConverter from \"../../modules/swagger/utils/helpers/openapi-schema-converter\";\nimport uploadManager from \"./utils/helpers/upload-manager\";\n\n/**\n * Creates an enhanced Express Router with features like OpenAPI documentation capabilities and smart data validation.\n *\n * The ArkosRouter extends the standard Express Router with the ability to\n * automatically capture OpenAPI metadata from route configurations.\n *\n * @example\n * const router = ArkosRouter();\n *\n * router.get(\n * {\n * path: \"/users/:id\",\n * openapi: {\n * summary: \"Get user by ID\",\n * tags: [\"Users\"]\n * }\n * },\n * (req, res) => { ... }\n * );\n *\n * @returns {IArkosRouter} A proxied Express Router instance with enhanced OpenAPI capabilities\n *\n * @see {@link ArkosRouteConfig} for configuration options\n */\nexport default function ArkosRouter(): IArkosRouter {\n const router: IArkosRouter = Router();\n\n return new Proxy(router, {\n get(target, prop, receiver) {\n const originalMethod = Reflect.get(target, prop, receiver);\n\n const httpMethods = [\n \"get\",\n \"post\",\n \"put\",\n \"patch\",\n \"delete\",\n \"all\",\n \"head\",\n \"trace\",\n \"options\",\n ];\n\n type ArkosAnyRequestHandler =\n | ArkosRequestHandler\n | ArkosErrorRequestHandler;\n\n if (httpMethods.includes(prop as string)) {\n return function (\n config: ArkosRouteConfig,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n if (config.disabled) return;\n\n const path = config.path;\n\n if (!path)\n throw Error(\n \"Please pass valid value for path field to use in your route\"\n );\n\n if (!RouteConfigValidator.isArkosRouteConfig(config))\n throw Error(\n `First argument of ArkosRouter().${prop as string}() must be a valid ArkosRouteConfig object with path field, but recevied ${typeof config === \"object\" ? JSON.stringify(config, null, 2) : config}`\n );\n\n const method = prop as string;\n\n if (handlers.length > 0) {\n handlers = handlers.map(\n (handler: ArkosAnyRequestHandler | ArkosAnyRequestHandler[]) => {\n return typeof handler === \"function\"\n ? catchAsync(handler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\n })\n : handler.map((nesteHandler: any) =>\n catchAsync(nesteHandler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\n })\n );\n }\n );\n\n const finalHandler = handlers[handlers.length - 1];\n RouteConfigRegistry.register(finalHandler, config, method);\n }\n\n const arkosConfig = getArkosConfig();\n const validationConfig = arkosConfig.validation;\n const authenticationConfig = arkosConfig.authentication;\n const strictValidation = validationConfig?.strict;\n const route = `${method.toUpperCase()} ${path}`;\n\n if (\n strictValidation &&\n (!(\"validation\" in config) ||\n (\"validation\" in config &&\n !config.validation &&\n config.validation !== undefined))\n )\n throw Error(\n \"When using strict validation you must either pass { validation: false } in order to explicitly tell that no input will be received, or pass `undefined` for each input type e.g { validation: { query: undefined } } in order to deny the input of given request input.\"\n );\n\n if (!validationConfig?.resolver && config.validation)\n throw Error(\n `Trying to pass validators into route ${route} config validation option without choosing a validation resolver under arkos.init({ validation: { resolver: '' } })`\n );\n\n if (config.authentication && !authenticationConfig?.mode)\n throw Error(\n `Trying to authenticate route ${route} without choosing an authentication mode under arkos.init({ authentication: { mode: '' } })`\n );\n\n handlers = [...getMiddlewareStack(config), ...handlers];\n\n if (\n config.experimental?.uploads &&\n config.experimental.uploads.deleteOnError !== false\n )\n handlers.push(\n catchAsync(\n uploadManager.handleFileCleanup(config.experimental.uploads),\n { type: \"error\" }\n )\n );\n\n return originalMethod.call(target, path, ...handlers);\n };\n }\n // }\n return originalMethod;\n },\n }) as IArkosRouter;\n}\n\nexport function generateOpenAPIFromApp(app: any) {\n const routes = extractArkosRoutes(app);\n const arkosConfig = getArkosConfig();\n\n let paths: Record<\n string,\n Record<string, Partial<OpenAPIV3.OperationObject>>\n > = {};\n\n routes.forEach(({ path, method, config }) => {\n if (config?.experimental?.openapi === false) return;\n\n if (!paths[path]) paths[path] = {};\n\n if (typeof config?.experimental?.openapi === \"boolean\") {\n config = {\n ...config,\n experimental: {\n ...config.experimental,\n openapi: {},\n },\n };\n }\n\n const openapi =\n typeof config?.experimental?.openapi === \"object\" &&\n config.experimental.openapi !== null\n ? config.experimental.openapi\n : {};\n\n const validatorToJsonSchema =\n arkosConfig?.validation?.resolver === \"zod\"\n ? zodToJsonSchema\n : classValidatorToJsonSchema;\n\n let parameters = [];\n const validationToParameterMapping = {\n query: \"query\",\n params: \"path\",\n headers: \"header\",\n cookies: \"cookie\",\n };\n\n if (typeof config?.validation !== \"boolean\" && config?.validation) {\n for (const [key, val] of Object.entries(config?.validation)) {\n if ([\"body\"].includes(key)) continue;\n if ((config?.validation as any)[key]) {\n const jsonSchema = validatorToJsonSchema(val as any);\n const params = openApiSchemaConverter.jsonSchemaToOpeApiParameters(\n (validationToParameterMapping as any)[key],\n jsonSchema\n );\n parameters.push(...params);\n }\n }\n }\n\n const convertedOpenAPI =\n openApiSchemaConverter.convertOpenAPIConfig(openapi);\n\n (paths as any)[path][method.toLowerCase()] = {\n summary: openapi?.summary || `${method} ${path}`,\n description: openapi?.description || `${method} ${path}`,\n tags: openapi?.tags || [\"Defaults\"],\n operationId: `${method.toLowerCase()}:${path}`,\n parameters: [...(convertedOpenAPI.parameters || []), ...parameters],\n ...(!convertedOpenAPI.requestBody &&\n config?.validation &&\n config?.validation?.body && {\n requestBody: {\n content: {\n \"application/json\": {\n schema: validatorToJsonSchema(config?.validation?.body as any),\n },\n },\n },\n }),\n ...convertedOpenAPI,\n };\n });\n\n return paths;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=body-parser-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"body-parser-config.js","sourceRoot":"","sources":["../../../../../src/utils/arkos-router/types/body-parser-config.ts"],"names":[],"mappings":"","sourcesContent":["import express from \"express\";\nimport { Options as MulterOptions } from \"multer\";\n\nexport type BodyParserConfig =\n | { parser: \"json\"; options?: Parameters<typeof express.json>[0] }\n | {\n parser: \"urlencoded\";\n options?: Parameters<typeof express.urlencoded>[0];\n }\n | { parser: \"raw\"; options?: Parameters<typeof express.raw>[0] }\n | { parser: \"multipart\"; options?: MulterOptions[\"limits\"] }\n | { parser: \"text\"; options?: Parameters<typeof express.text>[0] };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/arkos-router/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import { IRouter } from \"express\";\nimport { ZodSchema } from \"zod\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport { Options as QueryParserOptions } from \"../../../utils/helpers/query-parser.helpers\";\nimport { DetailedAccessControlRule } from \"../../../types/auth\";\nimport { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../../types\";\nimport express from \"express\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\n\n/**\n * Handler function for HTTP methods that accepts route configuration and request handlers.\n *\n * @param {ArkosRouteConfig} config - The route configuration object.\n * @param {...(ArkosRequestHandler | ArkosErrorRequestHandler)[]} handlers - Request and error handlers for the route.\n * @returns {IRouter} The Express router instance.\n */\ntype MethodHandler = (\n config: ArkosRouteConfig,\n ...handlers: (ArkosRequestHandler | ArkosErrorRequestHandler)[]\n) => IRouter;\n\n/**\n * Creates an enhanced Express Router with features like OpenAPI documentation capabilities and smart data validation.\n *\n * The ArkosRouter extends the standard Express Router with the ability to\n * automatically capture OpenAPI metadata from route configurations.\n *\n * @example\n * const router = ArkosRouter();\n *\n * router.get(\n * {\n * path: \"/users/:id\",\n * openapi: {\n * summary: \"Get user by ID\",\n * tags: [\"Users\"]\n * }\n * },\n * (req, res) => { ... }\n * );\n *\n * @returns {IArkosRouter} A proxied Express Router instance with enhanced OpenAPI capabilities\n *\n * @see {@link ArkosRouteConfig} for configuration options\n */\nexport interface IArkosRouter\n extends Omit<\n IRouter,\n | \"get\"\n | \"post\"\n | \"put\"\n | \"patch\"\n | \"delete\"\n | \"options\"\n | \"head\"\n | \"trace\"\n | \"all\"\n > {\n /** GET method handler with route configuration support */\n get: MethodHandler;\n /** POST method handler with route configuration support */\n post: MethodHandler;\n /** PUT method handler with route configuration support */\n put: MethodHandler;\n /** PATCH method handler with route configuration support */\n patch: MethodHandler;\n /** DELETE method handler with route configuration support */\n delete: MethodHandler;\n /** OPTIONS method handler with route configuration support */\n options: MethodHandler;\n /** HEAD method handler with route configuration support */\n head: MethodHandler;\n /** TRACE method handler with route configuration support */\n trace: MethodHandler;\n /** ALL methods handler with route configuration support */\n all: MethodHandler;\n}\n\n/**\n * Configuration object for defining routes in Arkos.js.\n */\nexport interface ArkosRouteConfig {\n /**\n * Disables the route by not mounting it internally.\n */\n disabled?: boolean;\n /**\n * The URL path pattern for the route.\n *\n * @example \"/api/users/:id\"\n */\n path: string;\n /**\n * Authentication and authorization configuration.\n *\n * @remarks\n * - Set to `true` to require authentication without specific permissions.\n * - Set to `false` or omit to allow unauthenticated access.\n * - Provide an object to specify resource-based access control with resource name, action, and optional custom rules.\n */\n authentication?:\n | boolean\n | {\n resource: string;\n action: string;\n rule?: DetailedAccessControlRule | string[];\n };\n /**\n * Request validation configuration using Zod schemas or class constructors.\n *\n * @remarks\n * - Set to `false` to disable all validation.\n * - Provide an object with `query`, `body`, and/or `params` properties to validate specific parts of the request.\n * - Each property accepts a Zod schema, a class constructor, or `false` to disable validation for that part.\n */\n validation?:\n | false\n | {\n query?: ZodSchema | (new (...args: any[]) => object) | false;\n body?: ZodSchema | (new (...args: any[]) => object) | false;\n params?: ZodSchema | (new (...args: any[]) => object) | false;\n };\n\n /**\n * Rate limiting configuration for this route.\n *\n * @see {@link https://www.npmjs.com/package/express-rate-limit express-rate-limit} for available options.\n */\n rateLimit?: Partial<RateLimitOptions>;\n\n /**\n * Allows to define options for npm package compression.\n * Nothing is passed by default.\n *\n * @see {@link https://www.npmjs.com/package/compression compression} for further details.\n */\n compression?: compression.CompressionOptions;\n /**\n * Options to define how query must be parsed.\n *\n * @example\n * ```\n * GET /api/product?saleId=null\n * ```\n *\n * Normally would parsed to { saleId: \"null\" } so query parser\n * trough setting option `parseNull` will transform { saleId: null }\n *\n * @default\n * ```\n * {\n * parseNull: true,\n * parseUndefined: true,\n * parseBoolean: true,\n * }\n * ```\n *\n * @remarks\n * parseNumber may convert fields that are string but you only passed\n * numbers to query pay attention to this.\n *\n * Soon a feature to converted the query to the end prisma type will be added.\n */\n queryParser?: QueryParserOptions;\n /**\n * Configuration for request body parsing.\n *\n * @property {(\"json\" | \"urlencoded\" | \"raw\" | \"text\")} parser - The type of body parser to use.\n * @property {object} [options] - Parser-specific options passed to the corresponding Express body parser middleware.\n *\n * @remarks\n * - When `parser` is `\"json\"`, options are passed to `express.json()`.\n * - When `parser` is `\"urlencoded\"`, options are passed to `express.urlencoded()`.\n * - When `parser` is `\"raw\"`, options are passed to `express.raw()`.\n * - When `parser` is `\"text\"`, options are passed to `express.text()`.\n * - Set to `false` to disable body parsing for this route.\n *\n * @see {@link https://expressjs.com/en/api.html#express.json Express body parser documentation}\n */\n bodyParser?:\n | { parser: \"json\"; options?: Parameters<typeof express.json>[0] }\n | {\n parser: \"urlencoded\";\n options?: Parameters<typeof express.urlencoded>[0];\n }\n | { parser: \"raw\"; options?: Parameters<typeof express.raw>[0] }\n | { parser: \"raw\"; options?: Parameters<typeof express.raw>[0] }\n | { parser: \"text\"; options?: Parameters<typeof express.text>[0] }\n | false;\n /**\n * Experimental features to be battled tested before being stable\n *\n * PS: These features may be changed without any previous warning.\n */\n experimental?: {\n /**\n * OpenAPI specification for this route.\n *\n * @remarks\n * - Set to `false` to exclude this route from OpenAPI documentation.\n * - Provide a partial OpenAPI operation object to document the route.\n */\n openapi?: false | OpenApiConfig;\n /**\n * Configuration for file upload handling in routes.\n * Supports single file, multiple files from same field, or multiple fields with files.\n */\n uploads?: UploadConfig;\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/arkos-router/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import { IRouter } from \"express\";\nimport { ZodSchema } from \"zod\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport { Options as QueryParserOptions } from \"../../../utils/helpers/query-parser.helpers\";\nimport { DetailedAccessControlRule } from \"../../../types/auth\";\nimport { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../../types\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\nimport { BodyParserConfig } from \"./body-parser-config\";\n\n/**\n * Handler function for HTTP methods that accepts route configuration and request handlers.\n *\n * @param {ArkosRouteConfig} config - The route configuration object.\n * @param {...(ArkosRequestHandler | ArkosErrorRequestHandler)[]} handlers - Request and error handlers for the route.\n * @returns {IRouter} The Express router instance.\n */\ntype MethodHandler = (\n config: ArkosRouteConfig,\n ...handlers: (ArkosRequestHandler | ArkosErrorRequestHandler)[]\n) => IRouter;\n\n/**\n * Creates an enhanced Express Router with features like OpenAPI documentation capabilities and smart data validation.\n *\n * The ArkosRouter extends the standard Express Router with the ability to\n * automatically capture OpenAPI metadata from route configurations.\n *\n * @example\n * const router = ArkosRouter();\n *\n * router.get(\n * {\n * path: \"/users/:id\",\n * openapi: {\n * summary: \"Get user by ID\",\n * tags: [\"Users\"]\n * }\n * },\n * (req, res) => { ... }\n * );\n *\n * @returns {IArkosRouter} A proxied Express Router instance with enhanced OpenAPI capabilities\n *\n * @see {@link ArkosRouteConfig} for configuration options\n */\nexport interface IArkosRouter\n extends Omit<\n IRouter,\n | \"get\"\n | \"post\"\n | \"put\"\n | \"patch\"\n | \"delete\"\n | \"options\"\n | \"head\"\n | \"trace\"\n | \"all\"\n > {\n /** GET method handler with route configuration support */\n get: MethodHandler;\n /** POST method handler with route configuration support */\n post: MethodHandler;\n /** PUT method handler with route configuration support */\n put: MethodHandler;\n /** PATCH method handler with route configuration support */\n patch: MethodHandler;\n /** DELETE method handler with route configuration support */\n delete: MethodHandler;\n /** OPTIONS method handler with route configuration support */\n options: MethodHandler;\n /** HEAD method handler with route configuration support */\n head: MethodHandler;\n /** TRACE method handler with route configuration support */\n trace: MethodHandler;\n /** ALL methods handler with route configuration support */\n all: MethodHandler;\n}\n\n/**\n * Configuration object for defining routes in Arkos.js.\n */\nexport interface ArkosRouteConfig {\n /**\n * Disables the route by not mounting it internally.\n */\n disabled?: boolean;\n /**\n * The URL path pattern for the route.\n *\n * @example \"/api/users/:id\"\n */\n path: string;\n /**\n * Authentication and authorization configuration.\n *\n * @remarks\n * - Set to `true` to require authentication without specific permissions.\n * - Set to `false` or omit to allow unauthenticated access.\n * - Provide an object to specify resource-based access control with resource name, action, and optional custom rules.\n */\n authentication?:\n | boolean\n | {\n resource: string;\n action: string;\n rule?: DetailedAccessControlRule | string[];\n };\n /**\n * Request validation configuration using Zod schemas or class constructors.\n *\n * @remarks\n * - Set to `false` to disable all validation.\n * - Provide an object with `query`, `body`, and/or `params` properties to validate specific parts of the request.\n * - Each property accepts a Zod schema, a class constructor, or `false` to disable validation for that part.\n */\n validation?:\n | false\n | {\n query?: ZodSchema | (new (...args: any[]) => object) | false;\n body?: ZodSchema | (new (...args: any[]) => object) | false;\n params?: ZodSchema | (new (...args: any[]) => object) | false;\n };\n\n /**\n * Rate limiting configuration for this route.\n *\n * @see {@link https://www.npmjs.com/package/express-rate-limit express-rate-limit} for available options.\n */\n rateLimit?: Partial<RateLimitOptions>;\n\n /**\n * Allows to define options for npm package compression.\n * Nothing is passed by default.\n *\n * @see {@link https://www.npmjs.com/package/compression compression} for further details.\n */\n compression?: compression.CompressionOptions;\n /**\n * Options to define how query must be parsed.\n *\n * @example\n * ```\n * GET /api/product?saleId=null\n * ```\n *\n * Normally would parsed to { saleId: \"null\" } so query parser\n * trough setting option `parseNull` will transform { saleId: null }\n *\n * @default\n * ```\n * {\n * parseNull: true,\n * parseUndefined: true,\n * parseBoolean: true,\n * }\n * ```\n *\n * @remarks\n * parseNumber may convert fields that are string but you only passed\n * numbers to query pay attention to this.\n *\n * Soon a feature to converted the query to the end prisma type will be added.\n */\n queryParser?: QueryParserOptions;\n /**\n * Configuration for request body parsing.\n *\n * @property {(\"json\" | \"urlencoded\" | \"raw\" | \"text\")} parser - The type of body parser to use.\n * @property {object} [options] - Parser-specific options passed to the corresponding Express body parser middleware.\n *\n * @remarks\n * - When `parser` is `\"json\"`, options are passed to `express.json()`.\n * - When `parser` is `\"urlencoded\"`, options are passed to `express.urlencoded()`.\n * - When `parser` is `\"raw\"`, options are passed to `express.raw()`.\n * - When `parser` is `\"text\"`, options are passed to `express.text()`.\n * - Set to `false` to disable body parsing for this route.\n *\n * @see {@link https://expressjs.com/en/api.html#express.json Express body parser documentation}\n */\n bodyParser?: BodyParserConfig | BodyParserConfig[] | false;\n /**\n * Experimental features to be battled tested before being stable\n *\n * PS: These features may be changed without any previous warning.\n */\n experimental?: {\n /**\n * OpenAPI specification for this route.\n *\n * @remarks\n * - Set to `false` to exclude this route from OpenAPI documentation.\n * - Provide a partial OpenAPI operation object to document the route.\n */\n openapi?: false | OpenApiConfig;\n /**\n * Configuration for file upload handling in routes.\n * Supports single file, multiple files from same field, or multiple fields with files.\n */\n uploads?: UploadConfig;\n };\n}\n"]}
@@ -6,6 +6,8 @@ import express from "express";
6
6
  import compression from "compression";
7
7
  import { queryParser } from "../../../helpers/query-parser.helpers.js";
8
8
  import uploadManager from "./upload-manager.js";
9
+ import multer from "multer";
10
+ import { catchAsync } from "../../../../exports/error-handler/index.js";
9
11
  export function extractArkosRoutes(app, basePath = "") {
10
12
  const routes = [];
11
13
  function extractFromStack(stack, prefix = "") {
@@ -66,9 +68,18 @@ export function getMiddlewareStack(config) {
66
68
  middlewares.push(compression(config.compression));
67
69
  if (config.queryParser)
68
70
  middlewares.push(queryParser(config.queryParser));
69
- if (typeof config?.bodyParser === "object" &&
70
- ["json", "urlencoded", "raw", "text"].includes(config?.bodyParser?.parser))
71
- middlewares.push(express[config.bodyParser.parser](config.bodyParser.options));
71
+ if (config?.bodyParser) {
72
+ const parsers = Array.isArray(config.bodyParser)
73
+ ? config.bodyParser
74
+ : [config.bodyParser];
75
+ parsers.forEach((parser) => {
76
+ if (typeof parser === "object" && parser.parser)
77
+ if (parser.parser !== "multipart")
78
+ middlewares.push(catchAsync(express[parser.parser](parser.options)));
79
+ else if (parser.parser === "multipart")
80
+ middlewares.push(catchAsync(multer({ limits: parser.options }).none()));
81
+ });
82
+ }
72
83
  if (config.experimental?.uploads) {
73
84
  middlewares.push(uploadManager.handleUpload(config.experimental.uploads));
74
85
  middlewares.push(validateRequestInputs(config));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/utils/arkos-router/utils/helpers/index.ts"],"names":[],"mappings":"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","sourcesContent":["import rateLimit from \"express-rate-limit\";\nimport authService from \"../../../../modules/auth/auth.service\";\nimport { validateRequestInputs } from \"../../../../modules/base/base.middlewares\";\nimport RouteConfigRegistry from \"../../route-config-registry\";\nimport { ArkosRouteConfig } from \"../../types\";\nimport express from \"express\";\nimport compression from \"compression\";\nimport { queryParser } from \"../../../helpers/query-parser.helpers\";\nimport uploadManager from \"./upload-manager\";\n\nexport function extractArkosRoutes(\n app: any,\n basePath = \"\"\n): Array<{\n path: string;\n method: string;\n config?: ArkosRouteConfig;\n}> {\n const routes: Array<{\n path: string;\n method: string;\n config?: ArkosRouteConfig;\n }> = [];\n\n function extractFromStack(stack: any[], prefix = \"\") {\n stack.forEach((layer: any) => {\n if (layer.route) {\n const fullPath = prefix + layer.route.path;\n const methods = Object.keys(layer.route.methods);\n\n methods.forEach((method) => {\n const handlers = layer.route.stack || [];\n let config: ArkosRouteConfig | undefined;\n\n for (const handler of handlers) {\n const foundConfig = RouteConfigRegistry.get(handler.handle);\n\n if (foundConfig) {\n config = foundConfig;\n routes.push({\n path: fullPath,\n method: method.toUpperCase(),\n config,\n });\n\n break;\n }\n }\n });\n } else if (layer.name === \"router\" && layer.handle?.stack) {\n let nestedPrefix = prefix;\n\n if (layer.regexp) {\n const match = layer.regexp\n .toString()\n .match(/\\/\\^?(\\\\\\/[^?]+|\\/[^?]+)/);\n if (match) {\n nestedPrefix = prefix + \"/\" + match[1].replace(/\\\\\\//g, \"/\");\n nestedPrefix = nestedPrefix\n .replace(/\\/\\//g, \"/\")\n .replace(/\\/$/, \"\");\n }\n }\n\n extractFromStack(layer.handle.stack, nestedPrefix);\n }\n });\n }\n\n const stack = app._router?.stack || app.stack;\n if (stack) extractFromStack(stack, basePath);\n\n return routes;\n}\n\nexport function getMiddlewareStack(config: ArkosRouteConfig) {\n const middlewares = [];\n\n if (config.authentication) middlewares.push(authService.authenticate);\n\n if (\n typeof config.authentication === \"object\" &&\n config.authentication.action &&\n config.authentication.resource\n )\n middlewares.push(\n authService.handleAccessControl(\n config.authentication.action,\n config.authentication.resource,\n { [config.authentication.action]: config.authentication?.rule }\n )\n );\n\n if (config.rateLimit) middlewares.push(rateLimit(config.rateLimit));\n if (config.compression) middlewares.push(compression(config.compression));\n if (config.queryParser) middlewares.push(queryParser(config.queryParser));\n\n if (\n typeof config?.bodyParser === \"object\" &&\n [\"json\", \"urlencoded\", \"raw\", \"text\"].includes(config?.bodyParser?.parser)\n )\n middlewares.push(\n express[config.bodyParser.parser](config.bodyParser.options)\n );\n\n if (config.experimental?.uploads) {\n middlewares.push(uploadManager.handleUpload(config.experimental.uploads));\n\n middlewares.push(validateRequestInputs(config));\n\n middlewares.push(\n uploadManager.handlePostUpload(config.experimental.uploads)\n );\n } else middlewares.push(validateRequestInputs(config));\n\n return middlewares;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/utils/arkos-router/utils/helpers/index.ts"],"names":[],"mappings":"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","sourcesContent":["import rateLimit from \"express-rate-limit\";\nimport authService from \"../../../../modules/auth/auth.service\";\nimport { validateRequestInputs } from \"../../../../modules/base/base.middlewares\";\nimport RouteConfigRegistry from \"../../route-config-registry\";\nimport { ArkosRouteConfig } from \"../../types\";\nimport express from \"express\";\nimport compression from \"compression\";\nimport { queryParser } from \"../../../helpers/query-parser.helpers\";\nimport uploadManager from \"./upload-manager\";\nimport multer from \"multer\";\nimport { catchAsync } from \"../../../../exports/error-handler\";\n\nexport function extractArkosRoutes(\n app: any,\n basePath = \"\"\n): Array<{\n path: string;\n method: string;\n config?: ArkosRouteConfig;\n}> {\n const routes: Array<{\n path: string;\n method: string;\n config?: ArkosRouteConfig;\n }> = [];\n\n function extractFromStack(stack: any[], prefix = \"\") {\n stack.forEach((layer: any) => {\n if (layer.route) {\n const fullPath = prefix + layer.route.path;\n const methods = Object.keys(layer.route.methods);\n\n methods.forEach((method) => {\n const handlers = layer.route.stack || [];\n let config: ArkosRouteConfig | undefined;\n\n for (const handler of handlers) {\n const foundConfig = RouteConfigRegistry.get(handler.handle);\n\n if (foundConfig) {\n config = foundConfig;\n routes.push({\n path: fullPath,\n method: method.toUpperCase(),\n config,\n });\n\n break;\n }\n }\n });\n } else if (layer.name === \"router\" && layer.handle?.stack) {\n let nestedPrefix = prefix;\n\n if (layer.regexp) {\n const match = layer.regexp\n .toString()\n .match(/\\/\\^?(\\\\\\/[^?]+|\\/[^?]+)/);\n if (match) {\n nestedPrefix = prefix + \"/\" + match[1].replace(/\\\\\\//g, \"/\");\n nestedPrefix = nestedPrefix\n .replace(/\\/\\//g, \"/\")\n .replace(/\\/$/, \"\");\n }\n }\n\n extractFromStack(layer.handle.stack, nestedPrefix);\n }\n });\n }\n\n const stack = app._router?.stack || app.stack;\n if (stack) extractFromStack(stack, basePath);\n\n return routes;\n}\n\nexport function getMiddlewareStack(config: ArkosRouteConfig) {\n const middlewares = [];\n\n if (config.authentication) middlewares.push(authService.authenticate);\n\n if (\n typeof config.authentication === \"object\" &&\n config.authentication.action &&\n config.authentication.resource\n )\n middlewares.push(\n authService.handleAccessControl(\n config.authentication.action,\n config.authentication.resource,\n { [config.authentication.action]: config.authentication?.rule }\n )\n );\n\n if (config.rateLimit) middlewares.push(rateLimit(config.rateLimit));\n if (config.compression) middlewares.push(compression(config.compression));\n if (config.queryParser) middlewares.push(queryParser(config.queryParser));\n\n if (config?.bodyParser) {\n const parsers = Array.isArray(config.bodyParser)\n ? config.bodyParser\n : [config.bodyParser];\n\n parsers.forEach((parser) => {\n if (typeof parser === \"object\" && parser.parser)\n if (parser.parser !== \"multipart\")\n middlewares.push(catchAsync(express[parser.parser](parser.options)));\n else if (parser.parser === \"multipart\")\n middlewares.push(\n catchAsync(multer({ limits: parser.options }).none())\n );\n });\n }\n\n if (config.experimental?.uploads) {\n middlewares.push(uploadManager.handleUpload(config.experimental.uploads));\n\n middlewares.push(validateRequestInputs(config));\n\n middlewares.push(\n uploadManager.handlePostUpload(config.experimental.uploads)\n );\n } else middlewares.push(validateRequestInputs(config));\n\n return middlewares;\n}\n"]}
@@ -9,6 +9,7 @@ import sheu from "../../../sheu.js";
9
9
  import AppError from "../../../../modules/error-handler/utils/app-error.js";
10
10
  import { extractRequestInfo, generateRelativePath, } from "../../../../modules/file-upload/utils/helpers/file-upload.helpers.js";
11
11
  import deepmerge from "../../../helpers/deepmerge.helper.js";
12
+ import { catchAsync } from "../../../../exports/error-handler/index.js";
12
13
  function determineUploadDir(file) {
13
14
  if (file.mimetype.includes?.("image"))
14
15
  return "/images";
@@ -72,7 +73,7 @@ class UploadManager {
72
73
  return upload;
73
74
  }
74
75
  handleUpload(config, oldFilePath) {
75
- return (req, res, next) => {
76
+ return catchAsync((req, res, next) => {
76
77
  const middleware = this.getMiddleware(config);
77
78
  req.headers["x-upload-dir"] = config.uploadDir;
78
79
  middleware(req, res, async (err) => {
@@ -92,7 +93,7 @@ class UploadManager {
92
93
  }
93
94
  next();
94
95
  });
95
- };
96
+ });
96
97
  }
97
98
  handleFileCleanup(config) {
98
99
  return async (err, req, _, next) => {
@@ -133,7 +134,7 @@ class UploadManager {
133
134
  };
134
135
  }
135
136
  handlePostUpload(config) {
136
- return (req, _, next) => {
137
+ return catchAsync((req, _, next) => {
137
138
  const { baseURL, baseRoute } = extractRequestInfo(req);
138
139
  const arkosConfig = getArkosConfig();
139
140
  const normalizePath = (filePath) => {
@@ -223,7 +224,7 @@ class UploadManager {
223
224
  throw new AppError(`File uploads post processing failed ${err.message}`, 500, "FileUploadPostProcessError");
224
225
  }
225
226
  next();
226
- };
227
+ });
227
228
  }
228
229
  }
229
230
  const uploadManager = new UploadManager();
@@ -1 +1 @@
1
- {"version":3,"file":"upload-manager.js","sourceRoot":"","sources":["../../../../../../src/utils/arkos-router/utils/helpers/upload-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import multer from \"multer\";\nimport { UploadConfig } from \"../../types/upload-config\";\nimport {\n documentsExtensions,\n imagesExtenstions,\n videosExtensions,\n} from \"../../../../modules/file-upload/utils/helpers/file-extensions\";\nimport {\n ArkosNextFunction,\n ArkosRequest,\n ArkosResponse,\n getArkosConfig,\n} from \"../../../../exports\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { removeBothSlashes } from \"../../../helpers/text.helpers\";\nimport { promisify } from \"util\";\nimport sheu from \"../../../sheu\";\nimport AppError from \"../../../../modules/error-handler/utils/app-error\";\nimport { RequestHandler } from \"express\";\nimport {\n extractRequestInfo,\n generateRelativePath,\n} from \"../../../../modules/file-upload/utils/helpers/file-upload.helpers\";\nimport deepmerge from \"../../../helpers/deepmerge.helper\";\n\nfunction determineUploadDir(file: Express.Multer.File) {\n if (file.mimetype.includes?.(\"image\")) return \"/images\";\n if (file.mimetype.includes?.(\"video\")) return \"/videos\";\n if (imagesExtenstions.has(file.mimetype.split(\"/\")[1])) return \"/images\";\n if (videosExtensions.has(file.mimetype.split(\"/\")[1])) return \"/videos\";\n if (documentsExtensions.has(file.mimetype.split(\"/\")[1])) return \"/documents\";\n return \"/files\";\n}\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n const arkosConfig = getArkosConfig();\n const baseUploadDir = arkosConfig.fileUpload?.baseUploadDir || \"/uploads\";\n let uploadDir =\n (req.headers[\"x-upload-dir\"] as string) || determineUploadDir(file);\n req.headers[\"x-upload-dir\"] = uploadDir;\n\n const fullUploadDir = path.resolve(\n path.join(\n process.cwd(),\n baseUploadDir.replaceAll(\"//\", \"/\"),\n uploadDir.replaceAll(\"//\", \"/\")\n )\n );\n\n if (!fs.existsSync(fullUploadDir))\n fs.mkdirSync(fullUploadDir, { recursive: true });\n\n cb(null, fullUploadDir);\n },\n filename: (_, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n const ext = path.extname(file.originalname);\n cb(null, `${file.originalname.replace(ext, \"\")}-${uniqueSuffix}${ext}`);\n },\n});\n\nclass UploadManager {\n private getUpload({\n maxSize = 1024 * 1024 * 5,\n allowedFileTypes = /.*/,\n }: {\n maxSize?: number;\n allowedFileTypes?: string[] | RegExp;\n }): multer.Multer {\n return multer({\n storage,\n fileFilter: (req, file, cb) =>\n this.fileFilter(req, file, cb, allowedFileTypes),\n limits: { fileSize: maxSize },\n });\n }\n\n getMiddleware(config: UploadConfig): RequestHandler {\n let upload;\n if (config.type === \"single\")\n upload = this.getUpload(config)[config.type](config.field);\n else if (config.type === \"array\")\n upload = this.getUpload(config)[config.type](\n config.field,\n config.maxCount || 5\n );\n else upload = this.getUpload(config)[config.type](config.fields);\n return upload;\n }\n\n handleUpload(config: UploadConfig, oldFilePath?: string) {\n return (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const middleware = this.getMiddleware(config);\n req.headers[\"x-upload-dir\"] = config.uploadDir;\n middleware(req, res, async (err) => {\n if (err) return next(err);\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n sheu.warn(err);\n }\n }\n\n next();\n });\n };\n }\n\n handleFileCleanup(config: UploadConfig) {\n return async (\n err: any,\n req: ArkosRequest,\n _: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n const deleteFile = async (file: Express.Multer.File) => {\n try {\n await fs.promises.unlink(file.path);\n } catch (error: any) {\n sheu.warn(\n `Failed to delete file: ${file.path} because ${error.message}`,\n { timestamp: true }\n );\n }\n };\n\n try {\n if (config.type === \"single\" && req.file) {\n await deleteFile(req.file);\n delete req.file;\n } else if (config.type === \"array\" && Array.isArray(req.files)) {\n for (const file of req.files) {\n await deleteFile(file);\n }\n delete req.files;\n } else if (\n config.type === \"fields\" &&\n req.files &&\n !Array.isArray(req.files)\n ) {\n for (const fieldName in req.files) {\n for (const file of req.files[fieldName]) {\n await deleteFile(file);\n }\n }\n delete req.files;\n }\n } catch (error: any) {\n sheu.warn(`File cleanup error: ${error.message}`, { timestamp: true });\n }\n\n next(err);\n };\n }\n\n handlePostUpload(config: UploadConfig) {\n return (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n const { baseURL, baseRoute } = extractRequestInfo(req);\n const arkosConfig = getArkosConfig();\n\n const normalizePath = (filePath: string): string => {\n let fullBaseUploadDir = path.resolve(\n path.join(process.cwd(), arkosConfig.fileUpload?.baseUploadDir!)\n );\n fullBaseUploadDir = fullBaseUploadDir.replace(process.cwd(), \"\");\n\n return filePath\n .replace(/\\\\/g, \"/\")\n .replaceAll(process.cwd(), \"\")\n .replace(`/${fullBaseUploadDir}`, \"\")\n .replace(fullBaseUploadDir, \"\");\n };\n\n const buildFileURL = (file: Express.Multer.File): string => {\n const relativePath = generateRelativePath(\n file.path,\n req.headers[\"x-upload-dir\"] as string\n );\n return `${baseURL}${baseRoute === \"/\" ? \"\" : baseRoute}${\n relativePath.startsWith(\"/\") ? relativePath : `/${relativePath}`\n }`;\n };\n\n const getAttachValue = (file: Express.Multer.File): any => {\n const url = buildFileURL(file);\n\n (file as any).url = url;\n (file as any).pathname = normalizePath(file.path);\n\n if (config.attachToBody === false) return undefined;\n if (config.attachToBody === \"pathname\" || !config.attachToBody)\n return (\n (baseRoute === \"/\"\n ? \"\"\n : baseRoute.startsWith(\"/\")\n ? baseRoute\n : `/${baseRoute}`) + normalizePath(file.path)\n );\n if (config.attachToBody === \"url\") return url;\n if (config.attachToBody === \"file\") return file;\n\n return undefined;\n };\n\n const setNestedValue = (obj: any, path: string, value: any) => {\n const keys = path.match(/[^\\[\\]]+/g) || [];\n\n let current = obj;\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!current[key]) {\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n }\n current = current[key];\n }\n\n const lastKey = keys[keys.length - 1];\n current[lastKey] = value;\n };\n\n try {\n if (config.type === \"single\" && req.file) {\n const value = getAttachValue(req.file);\n\n if (value !== undefined && config.field) {\n const bodyUpdate: any = {};\n setNestedValue(bodyUpdate, config.field, value);\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n } else if (config.type === \"array\" && Array.isArray(req.files)) {\n const values = req.files\n .map((file) => getAttachValue(file))\n .filter((v) => v !== undefined);\n\n if (values.length > 0 && config.field) {\n const bodyUpdate: any = {};\n setNestedValue(bodyUpdate, config.field, values);\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n } else if (\n config.type === \"fields\" &&\n req.files &&\n !Array.isArray(req.files)\n ) {\n const bodyUpdate: any = {};\n\n for (const fieldName in req.files) {\n const files = req.files[fieldName];\n const values = files\n .map((file) => getAttachValue(file))\n .filter((v) => v !== undefined);\n\n if (values.length > 0) {\n const valueToAttach = values.length === 1 ? values[0] : values;\n setNestedValue(bodyUpdate, fieldName, valueToAttach);\n }\n }\n\n if (Object.keys(bodyUpdate).length > 0) {\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n }\n } catch (err: any) {\n throw new AppError(\n `File uploads post processing failed ${err.message}`,\n 500,\n \"FileUploadPostProcessError\"\n );\n }\n\n next();\n };\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (\n _: any,\n file: any,\n cb: any,\n allowedFileTypes: string[] | RegExp\n ) => {\n const ext = path.extname(file.originalname).toLowerCase();\n let isAllowed = false;\n if (Array.isArray(allowedFileTypes))\n isAllowed = allowedFileTypes.includes(ext);\n else isAllowed = allowedFileTypes.test(ext);\n\n if (isAllowed) cb(null, true);\n else\n cb(\n new AppError(\n `File type not allowed, allowed files are ${String(allowedFileTypes).replaceAll(\"/\", \"\").split(\"|\").join(\", \")}`,\n 400,\n \"FileTypeNotAllowed\",\n { filename: file.originalname }\n )\n );\n };\n}\n\nconst uploadManager = new UploadManager();\n\nexport default uploadManager;\n"]}
1
+ {"version":3,"file":"upload-manager.js","sourceRoot":"","sources":["../../../../../../src/utils/arkos-router/utils/helpers/upload-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import multer from \"multer\";\nimport { UploadConfig } from \"../../types/upload-config\";\nimport {\n documentsExtensions,\n imagesExtenstions,\n videosExtensions,\n} from \"../../../../modules/file-upload/utils/helpers/file-extensions\";\nimport {\n ArkosNextFunction,\n ArkosRequest,\n ArkosResponse,\n getArkosConfig,\n} from \"../../../../exports\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { removeBothSlashes } from \"../../../helpers/text.helpers\";\nimport { promisify } from \"util\";\nimport sheu from \"../../../sheu\";\nimport AppError from \"../../../../modules/error-handler/utils/app-error\";\nimport { RequestHandler } from \"express\";\nimport {\n extractRequestInfo,\n generateRelativePath,\n} from \"../../../../modules/file-upload/utils/helpers/file-upload.helpers\";\nimport deepmerge from \"../../../helpers/deepmerge.helper\";\nimport { catchAsync } from \"../../../../exports/error-handler\";\n\nfunction determineUploadDir(file: Express.Multer.File) {\n if (file.mimetype.includes?.(\"image\")) return \"/images\";\n if (file.mimetype.includes?.(\"video\")) return \"/videos\";\n if (imagesExtenstions.has(file.mimetype.split(\"/\")[1])) return \"/images\";\n if (videosExtensions.has(file.mimetype.split(\"/\")[1])) return \"/videos\";\n if (documentsExtensions.has(file.mimetype.split(\"/\")[1])) return \"/documents\";\n return \"/files\";\n}\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n const arkosConfig = getArkosConfig();\n const baseUploadDir = arkosConfig.fileUpload?.baseUploadDir || \"/uploads\";\n let uploadDir =\n (req.headers[\"x-upload-dir\"] as string) || determineUploadDir(file);\n req.headers[\"x-upload-dir\"] = uploadDir;\n\n const fullUploadDir = path.resolve(\n path.join(\n process.cwd(),\n baseUploadDir.replaceAll(\"//\", \"/\"),\n uploadDir.replaceAll(\"//\", \"/\")\n )\n );\n\n if (!fs.existsSync(fullUploadDir))\n fs.mkdirSync(fullUploadDir, { recursive: true });\n\n cb(null, fullUploadDir);\n },\n filename: (_, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n const ext = path.extname(file.originalname);\n cb(null, `${file.originalname.replace(ext, \"\")}-${uniqueSuffix}${ext}`);\n },\n});\n\nclass UploadManager {\n private getUpload({\n maxSize = 1024 * 1024 * 5,\n allowedFileTypes = /.*/,\n }: {\n maxSize?: number;\n allowedFileTypes?: string[] | RegExp;\n }): multer.Multer {\n return multer({\n storage,\n fileFilter: (req, file, cb) =>\n this.fileFilter(req, file, cb, allowedFileTypes),\n limits: { fileSize: maxSize },\n });\n }\n\n getMiddleware(config: UploadConfig): RequestHandler {\n let upload;\n if (config.type === \"single\")\n upload = this.getUpload(config)[config.type](config.field);\n else if (config.type === \"array\")\n upload = this.getUpload(config)[config.type](\n config.field,\n config.maxCount || 5\n );\n else upload = this.getUpload(config)[config.type](config.fields);\n return upload;\n }\n\n handleUpload(config: UploadConfig, oldFilePath?: string) {\n return catchAsync(\n (req: ArkosRequest, res: ArkosResponse, next: ArkosNextFunction) => {\n const middleware = this.getMiddleware(config);\n req.headers[\"x-upload-dir\"] = config.uploadDir;\n middleware(req, res, async (err) => {\n if (err) return next(err);\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n sheu.warn(err);\n }\n }\n\n next();\n });\n }\n );\n }\n\n handleFileCleanup(config: UploadConfig) {\n return async (\n err: any,\n req: ArkosRequest,\n _: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n const deleteFile = async (file: Express.Multer.File) => {\n try {\n await fs.promises.unlink(file.path);\n } catch (error: any) {\n sheu.warn(\n `Failed to delete file: ${file.path} because ${error.message}`,\n { timestamp: true }\n );\n }\n };\n\n try {\n if (config.type === \"single\" && req.file) {\n await deleteFile(req.file);\n delete req.file;\n } else if (config.type === \"array\" && Array.isArray(req.files)) {\n for (const file of req.files) {\n await deleteFile(file);\n }\n delete req.files;\n } else if (\n config.type === \"fields\" &&\n req.files &&\n !Array.isArray(req.files)\n ) {\n for (const fieldName in req.files) {\n for (const file of req.files[fieldName]) {\n await deleteFile(file);\n }\n }\n delete req.files;\n }\n } catch (error: any) {\n sheu.warn(`File cleanup error: ${error.message}`, { timestamp: true });\n }\n\n next(err);\n };\n }\n\n handlePostUpload(config: UploadConfig) {\n return catchAsync(\n (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n const { baseURL, baseRoute } = extractRequestInfo(req);\n const arkosConfig = getArkosConfig();\n\n const normalizePath = (filePath: string): string => {\n let fullBaseUploadDir = path.resolve(\n path.join(process.cwd(), arkosConfig.fileUpload?.baseUploadDir!)\n );\n fullBaseUploadDir = fullBaseUploadDir.replace(process.cwd(), \"\");\n\n return filePath\n .replace(/\\\\/g, \"/\")\n .replaceAll(process.cwd(), \"\")\n .replace(`/${fullBaseUploadDir}`, \"\")\n .replace(fullBaseUploadDir, \"\");\n };\n\n const buildFileURL = (file: Express.Multer.File): string => {\n const relativePath = generateRelativePath(\n file.path,\n req.headers[\"x-upload-dir\"] as string\n );\n return `${baseURL}${baseRoute === \"/\" ? \"\" : baseRoute}${\n relativePath.startsWith(\"/\") ? relativePath : `/${relativePath}`\n }`;\n };\n\n const getAttachValue = (file: Express.Multer.File): any => {\n const url = buildFileURL(file);\n\n (file as any).url = url;\n (file as any).pathname = normalizePath(file.path);\n\n if (config.attachToBody === false) return undefined;\n if (config.attachToBody === \"pathname\" || !config.attachToBody)\n return (\n (baseRoute === \"/\"\n ? \"\"\n : baseRoute.startsWith(\"/\")\n ? baseRoute\n : `/${baseRoute}`) + normalizePath(file.path)\n );\n if (config.attachToBody === \"url\") return url;\n if (config.attachToBody === \"file\") return file;\n\n return undefined;\n };\n\n const setNestedValue = (obj: any, path: string, value: any) => {\n const keys = path.match(/[^\\[\\]]+/g) || [];\n\n let current = obj;\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i];\n if (!current[key]) {\n const nextKey = keys[i + 1];\n current[key] = /^\\d+$/.test(nextKey) ? [] : {};\n }\n current = current[key];\n }\n\n const lastKey = keys[keys.length - 1];\n current[lastKey] = value;\n };\n\n try {\n if (config.type === \"single\" && req.file) {\n const value = getAttachValue(req.file);\n\n if (value !== undefined && config.field) {\n const bodyUpdate: any = {};\n setNestedValue(bodyUpdate, config.field, value);\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n } else if (config.type === \"array\" && Array.isArray(req.files)) {\n const values = req.files\n .map((file) => getAttachValue(file))\n .filter((v) => v !== undefined);\n\n if (values.length > 0 && config.field) {\n const bodyUpdate: any = {};\n setNestedValue(bodyUpdate, config.field, values);\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n } else if (\n config.type === \"fields\" &&\n req.files &&\n !Array.isArray(req.files)\n ) {\n const bodyUpdate: any = {};\n\n for (const fieldName in req.files) {\n const files = req.files[fieldName];\n const values = files\n .map((file) => getAttachValue(file))\n .filter((v) => v !== undefined);\n\n if (values.length > 0) {\n const valueToAttach = values.length === 1 ? values[0] : values;\n setNestedValue(bodyUpdate, fieldName, valueToAttach);\n }\n }\n\n if (Object.keys(bodyUpdate).length > 0) {\n req.body = deepmerge(req.body || {}, bodyUpdate);\n }\n }\n } catch (err: any) {\n throw new AppError(\n `File uploads post processing failed ${err.message}`,\n 500,\n \"FileUploadPostProcessError\"\n );\n }\n\n next();\n }\n );\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (\n _: any,\n file: any,\n cb: any,\n allowedFileTypes: string[] | RegExp\n ) => {\n const ext = path.extname(file.originalname).toLowerCase();\n let isAllowed = false;\n if (Array.isArray(allowedFileTypes))\n isAllowed = allowedFileTypes.includes(ext);\n else isAllowed = allowedFileTypes.test(ext);\n\n if (isAllowed) cb(null, true);\n else\n cb(\n new AppError(\n `File type not allowed, allowed files are ${String(allowedFileTypes).replaceAll(\"/\", \"\").split(\"|\").join(\", \")}`,\n 400,\n \"FileTypeNotAllowed\",\n { filename: file.originalname }\n )\n );\n };\n}\n\nconst uploadManager = new UploadManager();\n\nexport default uploadManager;\n"]}
@@ -11,6 +11,6 @@ export function killServerChildProcess() {
11
11
  killProductionServerChildProcess();
12
12
  }
13
13
  export function getVersion() {
14
- return "1.4.0-canary.83";
14
+ return "1.4.0-canary.85";
15
15
  }
16
16
  //# sourceMappingURL=cli.helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.features.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/api.features.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import deepmerge from \"./deepmerge.helper\";\n\n/**\n * Configuration types for field type mapping\n */\ninterface FieldConfig {\n dateFields: string[];\n booleanFields: string[];\n numericFields: string[];\n}\n\n/**\n * Type for the structured filter object returned by the parser\n */\ntype ParsedFilter = {\n [key: string]: any;\n orderBy?: Record<string, \"asc\" | \"desc\">;\n OR?: Record<string, any>[];\n};\n\n/**\n * Default configuration for field types\n */\nconst DEFAULT_FIELD_CONFIG: FieldConfig = {\n dateFields: [\"createdAt\", \"updatedAt\", \"deletedAt\", \"date\"],\n booleanFields: [\"isActive\", \"isDeleted\", \"isPublished\", \"isArchived\"],\n numericFields: [\"age\", \"price\", \"quantity\", \"amount\", \"rating\"],\n};\n\n/**\n * Parses query parameters into a structured filter object compatible with Prisma queries.\n * Supports various operators and data type conversions with deep merge strategy.\n *\n * @param query - Object containing query parameters\n * @param fieldConfig - Optional configuration for field type mapping\n * @returns Structured filter object for database queries\n *\n * @example\n * // Basic usage\n * parseQueryParamsWithModifiers({ name__contains: 'john' })\n * // => { name: { contains: 'john', mode: 'sensitive' } }\n *\n * @example\n * // Deep merge example\n * parseQueryParamsWithModifiers({\n * 'some__data': '1',\n * 'some__info': '2'\n * })\n * // => { some: { data: '1', info: '2' } }\n *\n * @example\n * // Complex query\n * parseQueryParamsWithModifiers({\n * name__not__equals: 'john',\n * age__gt: '25',\n * tags__in: 'tag1,tag2',\n * orderBy__createdAt: 'desc'\n * })\n */\nexport function parseQueryParamsWithModifiers(\n query: Record<string, any>,\n fieldConfig: FieldConfig = DEFAULT_FIELD_CONFIG\n): ParsedFilter {\n const entries = Object.entries(JSON.parse(JSON.stringify(query)));\n let result: ParsedFilter = {};\n\n for (const [key, value] of entries) {\n const parts = key.split(\"__\");\n if (!value && value !== false && value !== \"false\" && parts.length < 2)\n continue;\n\n // Convert value to string if it's not already\n const stringValue = Array.isArray(value) ? value[0]?.toString() : value;\n\n let currentResult: any = {};\n\n if (parts.length < 2) {\n currentResult[key] =\n typeof value === \"string\" && !Number.isNaN(value)\n ? convertValue(stringValue, parts[0], fieldConfig)\n : value;\n } else {\n const fieldName = parts[0];\n\n // Handle ordering\n if (fieldName === \"orderBy\" && parts.length === 2) {\n currentResult.orderBy = {};\n currentResult.orderBy[parts[1]] = stringValue as \"asc\" | \"desc\";\n } else if (parts.length === 1) {\n // Handle simple equals case\n currentResult[fieldName] = {\n equals: convertValue(stringValue, fieldName, fieldConfig),\n };\n } else {\n // Build nested structure\n let nestedObj: any = {};\n let currentLevel = nestedObj;\n let currentKey = fieldName;\n\n // Create the nested path\n for (let i = 1; i < parts.length - 1; i++) {\n currentLevel[currentKey] = {};\n currentLevel = currentLevel[currentKey];\n currentKey = parts[i];\n }\n\n const lastOperator = parts[parts.length - 1];\n\n // Handle special operators\n switch (lastOperator) {\n case \"icontains\":\n currentLevel[currentKey] = {\n contains: stringValue,\n mode: \"insensitive\",\n };\n break;\n\n case \"contains\":\n currentLevel[currentKey] = {\n contains: stringValue,\n mode: \"sensitive\",\n };\n break;\n\n case \"in\":\n case \"notIn\":\n currentLevel[currentKey] = {\n [lastOperator]: stringValue\n .split(\",\")\n .map((v: string) =>\n convertValue(v.trim(), fieldName, fieldConfig)\n ),\n };\n break;\n\n case \"or\":\n const values: string[] = stringValue.split(\",\");\n nestedObj.OR = values.map((val) => ({\n [fieldName]: {\n equals: convertValue(val.trim(), fieldName, fieldConfig),\n },\n }));\n break;\n\n case \"isNull\":\n currentLevel[currentKey] = {\n equals: stringValue.toLowerCase() === \"true\" ? null : undefined,\n };\n break;\n\n case \"isEmpty\":\n currentLevel[currentKey] = {\n equals: stringValue.toLowerCase() === \"true\" ? \"\" : undefined,\n };\n break;\n\n default:\n currentLevel[currentKey] = {\n [lastOperator]: convertValue(stringValue, fieldName, fieldConfig),\n };\n }\n\n currentResult = nestedObj;\n }\n }\n\n // Deep merge the current result with the accumulated result\n result = deepmerge(result, currentResult);\n }\n\n return result;\n}\n\n/**\n * Converts string values to appropriate types based on field configuration\n *\n * @example\n * // Example usage:\n * const query = {\n * name__not__equals: 'uanela',\n * email__contains: 'example.com',\n * description__icontains: 'test',\n * age__gt: '25',\n * status: 'active',\n * tags__in: 'tag1,tag2,tag3',\n * createdAt__gt: '2024-01-01',\n * isActive: 'true',\n * orderBy__createdAt: 'desc',\n * some__data: '1',\n * some__info: '2'\n * };\n *\n * const result = parseQueryParamsWithModifiers(query);\n * // Result will properly merge nested objects instead of overwriting\n */\nfunction convertValue(\n value: string,\n fieldName: string,\n config: FieldConfig\n): any {\n // Handle date fields\n if (config.dateFields?.includes?.(fieldName) && value) {\n return new Date(value);\n }\n\n // Handle boolean fields\n if (config.booleanFields?.includes?.(fieldName) && value) {\n return value.toLowerCase() === \"true\";\n }\n\n // Handle numeric fields\n if (config.numericFields?.includes?.(fieldName) && value) {\n return Number(value);\n }\n\n return value;\n}\n"]}
1
+ {"version":3,"file":"api.features.helpers.js","sourceRoot":"","sources":["../../../../src/utils/helpers/api.features.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import deepmerge from \"./deepmerge.helper\";\n\n/**\n * Configuration types for field type mapping\n */\ninterface FieldConfig {\n dateFields: string[];\n booleanFields: string[];\n numericFields: string[];\n}\n\n/**\n * Type for the structured filter object returned by the parser\n */\ntype ParsedFilter = {\n [key: string]: any;\n orderBy?: Record<string, \"asc\" | \"desc\">;\n OR?: Record<string, any>[];\n};\n\n/**\n * Default configuration for field types\n */\nconst DEFAULT_FIELD_CONFIG: FieldConfig = {\n dateFields: [\"createdAt\", \"updatedAt\", \"deletedAt\", \"date\"],\n booleanFields: [\"isActive\", \"isDeleted\", \"isPublished\", \"isArchived\"],\n numericFields: [\"age\", \"price\", \"quantity\", \"amount\", \"rating\"],\n};\n\n/**\n * Parses query parameters into a structured filter object compatible with Prisma queries.\n * Supports various operators and data type conversions with deep merge strategy.\n *\n * @param query - Object containing query parameters\n * @param fieldConfig - Optional configuration for field type mapping\n * @returns Structured filter object for database queries\n *\n * @example\n * // Basic usage\n * parseQueryParamsWithModifiers({ name__contains: 'john' })\n * // => { name: { contains: 'john', mode: 'sensitive' } }\n *\n * @example\n * // Deep merge example\n * parseQueryParamsWithModifiers({\n * 'some__data': '1',\n * 'some__info': '2'\n * })\n * // => { some: { data: '1', info: '2' } }\n *\n * @example\n * // Complex query\n * parseQueryParamsWithModifiers({\n * name__not__equals: 'john',\n * age__gt: '25',\n * tags__in: 'tag1,tag2',\n * orderBy__createdAt: 'desc'\n * })\n */\nexport function parseQueryParamsWithModifiers(\n query: Record<string, any>,\n fieldConfig: FieldConfig = DEFAULT_FIELD_CONFIG\n): ParsedFilter {\n const entries = Object.entries(JSON.parse(JSON.stringify(query)));\n let result: ParsedFilter = {};\n\n for (const [key, value] of entries) {\n const parts = key.split(\"__\");\n if (!value && value !== false && value !== \"false\" && parts.length < 2)\n continue;\n\n const stringValue = Array.isArray(value) ? value[0]?.toString() : value;\n\n let currentResult: any = {};\n\n if (parts.length < 2) {\n currentResult[key] =\n typeof value === \"string\" && !Number.isNaN(value)\n ? convertValue(stringValue, parts[0], fieldConfig)\n : value;\n } else {\n const fieldName = parts[0];\n\n if (fieldName === \"orderBy\" && parts.length === 2) {\n currentResult.orderBy = {};\n currentResult.orderBy[parts[1]] = stringValue as \"asc\" | \"desc\";\n } else if (parts.length === 1) {\n currentResult[fieldName] = {\n equals: convertValue(stringValue, fieldName, fieldConfig),\n };\n } else {\n let nestedObj: any = {};\n let currentLevel = nestedObj;\n let currentKey = fieldName;\n\n for (let i = 1; i < parts.length - 1; i++) {\n currentLevel[currentKey] = {};\n currentLevel = currentLevel[currentKey];\n currentKey = parts[i];\n }\n\n const lastOperator = parts[parts.length - 1];\n\n switch (lastOperator) {\n case \"icontains\":\n currentLevel[currentKey] = {\n contains: stringValue,\n mode: \"insensitive\",\n };\n break;\n\n case \"contains\":\n currentLevel[currentKey] = {\n contains: stringValue,\n mode: \"sensitive\",\n };\n break;\n\n case \"in\":\n case \"notIn\":\n currentLevel[currentKey] = {\n [lastOperator]: stringValue\n .split(\",\")\n .map((v: string) =>\n convertValue(v.trim(), fieldName, fieldConfig)\n ),\n };\n break;\n\n case \"or\":\n const values: string[] = stringValue.split(\",\");\n nestedObj.OR = values.map((val) => ({\n [fieldName]: {\n equals: convertValue(val.trim(), fieldName, fieldConfig),\n },\n }));\n break;\n\n case \"isNull\":\n currentLevel[currentKey] = {\n equals: stringValue.toLowerCase() === \"true\" ? null : undefined,\n };\n break;\n\n case \"isEmpty\":\n currentLevel[currentKey] = {\n equals: stringValue.toLowerCase() === \"true\" ? \"\" : undefined,\n };\n break;\n\n default:\n currentLevel[currentKey] = {\n [lastOperator]: convertValue(stringValue, fieldName, fieldConfig),\n };\n }\n\n currentResult = nestedObj;\n }\n }\n\n // Deep merge the current result with the accumulated result\n result = deepmerge(result, currentResult);\n }\n\n return result;\n}\n\n/**\n * Converts string values to appropriate types based on field configuration\n *\n * @example\n * // Example usage:\n * const query = {\n * name__not__equals: 'uanela',\n * email__contains: 'example.com',\n * description__icontains: 'test',\n * age__gt: '25',\n * status: 'active',\n * tags__in: 'tag1,tag2,tag3',\n * createdAt__gt: '2024-01-01',\n * isActive: 'true',\n * orderBy__createdAt: 'desc',\n * some__data: '1',\n * some__info: '2'\n * };\n *\n * const result = parseQueryParamsWithModifiers(query);\n * // Result will properly merge nested objects instead of overwriting\n */\nfunction convertValue(\n value: string,\n fieldName: string,\n config: FieldConfig\n): any {\n // Handle date fields\n if (config.dateFields?.includes?.(fieldName) && value) {\n return new Date(value);\n }\n\n // Handle boolean fields\n if (config.booleanFields?.includes?.(fieldName) && value) {\n return value.toLowerCase() === \"true\";\n }\n\n // Handle numeric fields\n if (config.numericFields?.includes?.(fieldName) && value) {\n return Number(value);\n }\n\n return value;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import deepmerge from "./deepmerge.helper.js";
2
- import { importModule } from "./global.helpers";
3
- import { getUserFileExtension, crd } from "./fs.helpers";
2
+ import { importModule } from "./global.helpers.js";
3
+ import { getUserFileExtension, crd } from "./fs.helpers.js";
4
4
 
5
5
  const definedArkosConfig = process.env.CLI !== "true" ? await importModule(`${crd()}/arkos.config.${getUserFileExtension()}`) : () => {};
6
6
  export function isUsingAuthentication() {
@@ -1,8 +1,7 @@
1
1
  import fs from "fs";
2
- import deepmerge from "./deepmerge.helper.js";
3
2
  export function applyStrictRoutingRules(appModule, arkosConfig, moduleConfig) {
4
3
  const strictMode = arkosConfig?.routers?.strict || false;
5
- let config = moduleConfig || {};
4
+ let config = moduleConfig ? { ...moduleConfig } : {};
6
5
  appModule = appModule.toLowerCase();
7
6
  const allEndpoints = appModule === "auth"
8
7
  ? [
@@ -30,18 +29,15 @@ export function applyStrictRoutingRules(appModule, arkosConfig, moduleConfig) {
30
29
  const hadBooleanDisable = typeof config.disable === "boolean";
31
30
  if (hadBooleanDisable) {
32
31
  const disableValue = config.disable;
33
- const disableObject = {};
34
- const endpointConfigs = {};
32
+ config.disable = {};
35
33
  for (const endpoint of allEndpoints) {
36
- disableObject[endpoint] = disableValue;
37
- endpointConfigs[endpoint] = deepmerge(config[endpoint] || {}, {
38
- disabled: disableValue,
39
- });
34
+ config.disable[endpoint] = disableValue;
35
+ if (!config[endpoint]) {
36
+ config[endpoint] = {};
37
+ }
38
+ config[endpoint].disabled = disableValue;
40
39
  }
41
- return deepmerge(config, {
42
- disable: disableObject,
43
- ...endpointConfigs,
44
- });
40
+ return config;
45
41
  }
46
42
  if (strictMode === true) {
47
43
  const strictDefaults = appModule === "auth"
@@ -72,30 +68,7 @@ export function applyStrictRoutingRules(appModule, arkosConfig, moduleConfig) {
72
68
  updateMany: true,
73
69
  deleteMany: true,
74
70
  };
75
- const disableConfig = deepmerge(strictDefaults, config?.disable || {});
76
- const endpointConfigs = {};
77
- for (const endpoint of Object.keys(strictDefaults)) {
78
- endpointConfigs[endpoint] = deepmerge({ disabled: strictDefaults[endpoint] }, config[endpoint] || {});
79
- }
80
- const syncedDisable = { ...disableConfig };
81
- for (const endpoint of allEndpoints) {
82
- const endpointDisabled = config[endpoint]?.disabled;
83
- if (endpointDisabled !== undefined) {
84
- syncedDisable[endpoint] = endpointDisabled;
85
- }
86
- }
87
- const syncedEndpoints = { ...endpointConfigs };
88
- for (const endpoint of allEndpoints) {
89
- if (syncedDisable[endpoint] !== undefined) {
90
- syncedEndpoints[endpoint] = deepmerge(syncedEndpoints[endpoint] || {}, {
91
- disabled: syncedDisable[endpoint],
92
- });
93
- }
94
- }
95
- return deepmerge(config, {
96
- disable: syncedDisable,
97
- ...syncedEndpoints,
98
- });
71
+ applyDisabledFlags(config, allEndpoints, strictDefaults);
99
72
  }
100
73
  else if (strictMode === "no-bulk" &&
101
74
  !["auth", "file-upload"].includes(appModule.toLowerCase())) {
@@ -104,30 +77,36 @@ export function applyStrictRoutingRules(appModule, arkosConfig, moduleConfig) {
104
77
  updateMany: true,
105
78
  deleteMany: true,
106
79
  };
107
- const disableConfig = deepmerge(noBulkDefaults, config.disable || {});
108
- const endpointConfigs = {};
109
- for (const endpoint of Object.keys(noBulkDefaults)) {
110
- endpointConfigs[endpoint] = deepmerge({ disabled: noBulkDefaults[endpoint] }, config[endpoint] || {});
80
+ applyDisabledFlags(config, allEndpoints, noBulkDefaults);
81
+ }
82
+ return config;
83
+ }
84
+ function applyDisabledFlags(config, allEndpoints, defaults) {
85
+ if (!config.disable || typeof config.disable === "boolean") {
86
+ config.disable = {};
87
+ }
88
+ for (const endpoint of allEndpoints) {
89
+ const defaultDisabled = defaults[endpoint];
90
+ const userDisableOverride = config.disable[endpoint];
91
+ const endpointDisabled = config[endpoint]?.disabled;
92
+ let finalDisabled;
93
+ if (endpointDisabled !== undefined) {
94
+ finalDisabled = endpointDisabled;
111
95
  }
112
- const syncedDisable = { ...disableConfig };
113
- for (const endpoint of allEndpoints) {
114
- const endpointDisabled = config[endpoint]?.disabled;
115
- if (endpointDisabled !== undefined) {
116
- syncedDisable[endpoint] = endpointDisabled;
117
- }
96
+ else if (userDisableOverride !== undefined) {
97
+ finalDisabled = userDisableOverride;
118
98
  }
119
- const syncedEndpoints = { ...endpointConfigs };
120
- for (const endpoint of allEndpoints) {
121
- if (syncedDisable[endpoint] !== undefined) {
122
- syncedEndpoints[endpoint] = deepmerge({ disabled: syncedDisable[endpoint] }, syncedEndpoints[endpoint] || {});
99
+ else if (defaultDisabled !== undefined) {
100
+ finalDisabled = defaultDisabled;
101
+ }
102
+ if (finalDisabled !== undefined) {
103
+ config.disable[endpoint] = finalDisabled;
104
+ if (!config[endpoint]) {
105
+ config[endpoint] = {};
123
106
  }
107
+ config[endpoint].disabled = finalDisabled;
124
108
  }
125
- return deepmerge(config, {
126
- disable: syncedDisable,
127
- ...syncedEndpoints,
128
- });
129
109
  }
130
- return config;
131
110
  }
132
111
  export function validateRouterConfigConsistency(appModule, config) {
133
112
  if (!config.disable || typeof config.disable === "boolean")