arkos 1.6.5-beta → 1.6.7-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/cjs/exports/index.js +3 -1
  2. package/dist/cjs/exports/index.js.map +1 -1
  3. package/dist/cjs/modules/email/email.service.js +13 -7
  4. package/dist/cjs/modules/email/email.service.js.map +1 -1
  5. package/dist/cjs/modules/error-handler/error-handler.controller.js +4 -3
  6. package/dist/cjs/modules/error-handler/error-handler.controller.js.map +1 -1
  7. package/dist/cjs/modules/file-upload/file-upload.router.js +9 -2
  8. package/dist/cjs/modules/file-upload/file-upload.router.js.map +1 -1
  9. package/dist/cjs/modules/swagger/swagger.router.js +40 -9
  10. package/dist/cjs/modules/swagger/swagger.router.js.map +1 -1
  11. package/dist/cjs/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +1 -1
  12. package/dist/cjs/modules/swagger/utils/helpers/openapi-schema-converter.js +4 -2
  13. package/dist/cjs/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
  14. package/dist/cjs/server.js +1 -1
  15. package/dist/cjs/server.js.map +1 -1
  16. package/dist/cjs/types/arkos.js.map +1 -1
  17. package/dist/cjs/types/index.js.map +1 -1
  18. package/dist/cjs/types/new-arkos-config.js.map +1 -1
  19. package/dist/cjs/types/upload.js +3 -0
  20. package/dist/cjs/types/upload.js.map +1 -0
  21. package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js +3 -9
  22. package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  23. package/dist/cjs/utils/arkos-router/index.js +15 -3
  24. package/dist/cjs/utils/arkos-router/index.js.map +1 -1
  25. package/dist/cjs/utils/arkos-router/types/index.js.map +1 -1
  26. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js +5 -0
  27. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  28. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  29. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +53 -17
  30. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -1
  31. package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js +18 -18
  32. package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -1
  33. package/dist/cjs/utils/features/api.features.js.map +1 -1
  34. package/dist/cjs/utils/helpers/arkos-config.helpers.js.map +1 -1
  35. package/dist/esm/exports/index.js +2 -1
  36. package/dist/esm/exports/index.js.map +1 -1
  37. package/dist/esm/modules/email/email.service.js +13 -7
  38. package/dist/esm/modules/email/email.service.js.map +1 -1
  39. package/dist/esm/modules/error-handler/error-handler.controller.js +4 -3
  40. package/dist/esm/modules/error-handler/error-handler.controller.js.map +1 -1
  41. package/dist/esm/modules/file-upload/file-upload.router.js +9 -2
  42. package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
  43. package/dist/esm/modules/swagger/swagger.router.js +7 -9
  44. package/dist/esm/modules/swagger/swagger.router.js.map +1 -1
  45. package/dist/esm/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +1 -1
  46. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js +4 -2
  47. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
  48. package/dist/esm/server.js +1 -1
  49. package/dist/esm/server.js.map +1 -1
  50. package/dist/esm/types/arkos.js.map +1 -1
  51. package/dist/esm/types/index.js.map +1 -1
  52. package/dist/esm/types/new-arkos-config.js.map +1 -1
  53. package/dist/esm/types/upload.js +2 -0
  54. package/dist/esm/types/upload.js.map +1 -0
  55. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js +3 -9
  56. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  57. package/dist/esm/utils/arkos-router/index.js +15 -3
  58. package/dist/esm/utils/arkos-router/index.js.map +1 -1
  59. package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
  60. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js +5 -0
  61. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  62. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  63. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +53 -17
  64. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -1
  65. package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js +18 -18
  66. package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -1
  67. package/dist/esm/utils/features/api.features.js.map +1 -1
  68. package/dist/esm/utils/helpers/arkos-config.helpers.js.map +1 -1
  69. package/dist/types/exports/index.d.ts +3 -1
  70. package/dist/types/types/arkos.d.ts +1 -1
  71. package/dist/types/types/index.d.ts +5 -5
  72. package/dist/types/types/new-arkos-config.d.ts +1 -1
  73. package/dist/types/types/upload.d.ts +10 -0
  74. package/dist/types/utils/arkos-router/types/index.d.ts +15 -14
  75. package/dist/types/utils/arkos-router/utils/helpers/upload-manager.d.ts +1 -0
  76. package/dist/types/utils/cli/utils/template-generator/templates/class-validator-dto-generator.d.ts +7 -0
  77. package/dist/types/utils/features/api.features.d.ts +1 -2
  78. package/dist/types/utils/helpers/arkos-config.helpers.d.ts +5 -0
  79. package/package.json +1 -1
@@ -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, RouterOptions } from \"express\";\nimport { IArkosRouter } from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport { extractArkosRoutes, extractPathParams } from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\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 arkosRouterOpenApiManager from \"./arkos-router-openapi-manager\";\nimport { applyArkosRouterProxy } from \"./utils/helpers/apply-arkos-router-proxy\";\nimport { Arkos } from \"../../types/arkos\";\n\nexport type ArkosRouterOptions = {\n /**\n * Prefix to apply to all routes in this router.\n * Nested routers inherit and concatenate prefixes from parent routers.\n *\n * @since 1.5.0-beta\n * @example\n * // All routes in this router will be prefixed with \"/api\"\n * prefix: \"/api\"\n */\n prefix?: string | RegExp | Array<string | RegExp>;\n /**\n * OpenAPI metadata to apply to all routes in this router.\n * Nested routers inherit from parent routers unless explicitly overridden.\n * Route-level openapi config fully replaces inherited values when defined.\n *\n * @since 1.6.0-beta\n * @example\n * openapi: {\n * tags: [\"Users\"],\n * security: [{ bearerAuth: [] }]\n * }\n */\n openapi?: {\n /**\n * Tags to apply to all routes in this router, used to group them in OpenAPI documentation.\n * Route-level tags fully replaces this value when defined.\n *\n * @since 1.6.0-beta\n * @example\n * // Group all routes in this router under \"Users\"\n * tags: [\"Users\"]\n */\n tags?: string[];\n /**\n * Security requirements to apply to all routes in this router.\n * Route-level security fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * // Require bearer auth for all routes in this router\n * security: [{ bearerAuth: [] }]\n *\n * // Explicitly make all routes public (overridable per route)\n * security: []\n */\n security?: OpenAPIV3.SecurityRequirementObject[];\n\n /**\n * Server definitions to apply to all routes in this router.\n * Follows the OpenAPI 3.0 Server Object specification.\n * Route-level servers fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * servers: [{ url: \"https://api.example.com/v2\", description: \"V2 API\" }]\n */\n servers?: OpenAPIV3.ServerObject[];\n /**\n * External documentation to apply to all routes in this router.\n * Route-level externalDocs fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * externalDocs: {\n * description: \"Find more information here\",\n * url: \"https://docs.example.com/users\"\n * }\n */\n externalDocs?: OpenAPIV3.ExternalDocumentationObject;\n };\n};\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 https://www.arkosjs.com/docs/reference/arkos-router} for configuration options\n * @since 1.4.0-beta\n */\nexport default function ArkosRouter(\n options?: RouterOptions & ArkosRouterOptions\n): IArkosRouter {\n const router = Router(options);\n return applyArkosRouterProxy(router, options) as IArkosRouter;\n}\n\nconst hasDuplicatedPath = (path: string) => /^(\\/.+)\\1/.test(path);\n\nexport function generateOpenAPIFromApp(app: Arkos) {\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, routeOptions }) => {\n if (config?.experimental?.openapi === false || hasDuplicatedPath(path))\n return;\n const originalPath = path;\n\n const pathParatemersFromRoutePath = extractPathParams(path);\n for (const parameter of pathParatemersFromRoutePath) {\n path = path.replaceAll(\n `:${parameter}`,\n parameter.endsWith(\"?\") ? `{${parameter}}?` : `{${parameter}}`\n );\n }\n\n let wildcardCount = (path.match(/\\*/g) || []).length;\n let wildcardIndex = 0;\n path = path.replace(/\\*/g, () => {\n wildcardIndex++;\n return wildcardCount === 1 ? \"{path}\" : `{path${wildcardIndex}}`;\n });\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.jsonSchemaToOpenApiParameters(\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 const allParameters: OpenAPIV3.ParameterObject[] = [\n ...(convertedOpenAPI.parameters || []),\n ...parameters,\n ];\n\n for (const parameter of pathParatemersFromRoutePath) {\n if (\n !allParameters.find(\n ({ name, in: paramIn }) =>\n name === parameter.replace(\"?\", \"\") && paramIn === \"path\"\n )\n )\n allParameters.push({\n name: parameter,\n in: \"path\",\n required: !parameter.includes(\"?\"),\n schema: { type: \"string\" },\n });\n }\n\n for (const param of allParameters) {\n if (\n !pathParatemersFromRoutePath.includes(param.name) &&\n !pathParatemersFromRoutePath.includes(`${param.name}?`) &&\n param.in === \"path\" &&\n param.name !== \"*\"\n )\n throw new Error(\n `ValidationError: Trying to define path parameter '${param.name}' but it is not present in your pathname ${originalPath}`\n );\n }\n\n delete convertedOpenAPI.parameters;\n const hasUploadFields =\n Object.keys(config?.experimental?.uploads || {}).length > 0;\n const multipartFormSchema =\n convertedOpenAPI?.requestBody?.content?.[\"multipart/form-data\"];\n\n if (hasUploadFields && multipartFormSchema)\n arkosRouterOpenApiManager.validateMultipartFormDocs(\n multipartFormSchema,\n path,\n config?.experimental?.uploads\n );\n\n (paths as any)[path][method.toLowerCase()] = {\n ...convertedOpenAPI,\n summary: openapi?.summary || `${path}`,\n description: openapi?.description || `${method} ${path}`,\n servers: openapi?.servers || routeOptions?.openapi?.servers || undefined,\n security:\n openapi?.security || routeOptions?.openapi?.security || undefined,\n externalDocs:\n openapi?.externalDocs ||\n routeOptions?.openapi?.externalDocs ||\n undefined,\n tags: openapi?.tags || routeOptions?.openapi?.tags || [\"Defaults\"],\n operationId: openapi.operationId || `${method.toLowerCase()}:${path}`,\n parameters: allParameters,\n ...(!convertedOpenAPI.requestBody &&\n config?.validation &&\n config?.validation?.body && {\n requestBody: {\n content: (() => {\n const schema = validatorToJsonSchema(\n config?.validation?.body as any\n );\n\n return {\n ...convertedOpenAPI?.requestBody?.content,\n ...(hasUploadFields && {\n \"multipart/form-data\": {\n schema: openApiSchemaConverter.flattenSchema(\n arkosRouterOpenApiManager.addUploadFields(\n config.experimental?.uploads!,\n schema\n )\n ),\n },\n }),\n \"application/json\": {\n schema,\n },\n };\n })(),\n },\n }),\n ...(!multipartFormSchema &&\n !(config as any)?.validation?.body &&\n hasUploadFields && {\n requestBody: {\n content: (() => {\n const schema =\n convertedOpenAPI?.requestBody?.content?.[\"application/json\"]\n ?.schema || {};\n\n return {\n \"multipart/form-data\": {\n schema: openApiSchemaConverter.flattenSchema(\n arkosRouterOpenApiManager.addUploadFields(\n config?.experimental?.uploads! || {},\n schema\n )\n ),\n },\n ...convertedOpenAPI?.requestBody?.content,\n };\n })(),\n },\n }),\n } as OpenAPIV3.PathItemObject;\n });\n\n return paths;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router, RouterOptions } from \"express\";\nimport { IArkosRouter } from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport { extractArkosRoutes, extractPathParams } from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\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 arkosRouterOpenApiManager from \"./arkos-router-openapi-manager\";\nimport { applyArkosRouterProxy } from \"./utils/helpers/apply-arkos-router-proxy\";\nimport { Arkos } from \"../../types/arkos\";\nimport uploadManager from \"./utils/helpers/upload-manager\";\n\nexport type ArkosRouterOptions = {\n /**\n * Prefix to apply to all routes in this router.\n * Nested routers inherit and concatenate prefixes from parent routers.\n *\n * @since 1.5.0-beta\n * @example\n * // All routes in this router will be prefixed with \"/api\"\n * prefix: \"/api\"\n */\n prefix?: string | RegExp | Array<string | RegExp>;\n /**\n * OpenAPI metadata to apply to all routes in this router.\n * Nested routers inherit from parent routers unless explicitly overridden.\n * Route-level openapi config fully replaces inherited values when defined.\n *\n * @since 1.6.0-beta\n * @example\n * openapi: {\n * tags: [\"Users\"],\n * security: [{ bearerAuth: [] }]\n * }\n */\n openapi?: {\n /**\n * Tags to apply to all routes in this router, used to group them in OpenAPI documentation.\n * Route-level tags fully replaces this value when defined.\n *\n * @since 1.6.0-beta\n * @example\n * // Group all routes in this router under \"Users\"\n * tags: [\"Users\"]\n */\n tags?: string[];\n /**\n * Security requirements to apply to all routes in this router.\n * Route-level security fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * // Require bearer auth for all routes in this router\n * security: [{ bearerAuth: [] }]\n *\n * // Explicitly make all routes public (overridable per route)\n * security: []\n */\n security?: OpenAPIV3.SecurityRequirementObject[];\n\n /**\n * Server definitions to apply to all routes in this router.\n * Follows the OpenAPI 3.0 Server Object specification.\n * Route-level servers fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * servers: [{ url: \"https://api.example.com/v2\", description: \"V2 API\" }]\n */\n servers?: OpenAPIV3.ServerObject[];\n /**\n * External documentation to apply to all routes in this router.\n * Route-level externalDocs fully replaces this value when defined.\n *\n * @since 1.6.2-canary.1\n * @example\n * externalDocs: {\n * description: \"Find more information here\",\n * url: \"https://docs.example.com/users\"\n * }\n */\n externalDocs?: OpenAPIV3.ExternalDocumentationObject;\n };\n};\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 https://www.arkosjs.com/docs/reference/arkos-router} for configuration options\n * @since 1.4.0-beta\n */\nexport default function ArkosRouter(\n options?: RouterOptions & ArkosRouterOptions\n): IArkosRouter {\n const router = Router(options);\n return applyArkosRouterProxy(router, options) as IArkosRouter;\n}\n\nconst hasDuplicatedPath = (path: string) => /^(\\/.+)\\1/.test(path);\n\nexport function generateOpenAPIFromApp(app: Arkos) {\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, routeOptions }) => {\n if (config?.experimental?.openapi === false || hasDuplicatedPath(path))\n return;\n const originalPath = path;\n\n const pathParatemersFromRoutePath = extractPathParams(path);\n for (const parameter of pathParatemersFromRoutePath) {\n path = path.replaceAll(\n `:${parameter}`,\n parameter.endsWith(\"?\") ? `{${parameter}}?` : `{${parameter}}`\n );\n }\n\n let wildcardCount = (path.match(/\\*/g) || []).length;\n let wildcardIndex = 0;\n path = path.replace(/\\*/g, () => {\n wildcardIndex++;\n return wildcardCount === 1 ? \"{path}\" : `{path${wildcardIndex}}`;\n });\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.jsonSchemaToOpenApiParameters(\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 const allParameters: OpenAPIV3.ParameterObject[] = [\n ...(convertedOpenAPI.parameters || []),\n ...parameters,\n ];\n\n for (const parameter of pathParatemersFromRoutePath) {\n if (\n !allParameters.find(\n ({ name, in: paramIn }) =>\n name === parameter.replace(\"?\", \"\") && paramIn === \"path\"\n )\n )\n allParameters.push({\n name: parameter,\n in: \"path\",\n required: !parameter.includes(\"?\"),\n schema: { type: \"string\" },\n });\n }\n\n for (const param of allParameters) {\n if (\n !pathParatemersFromRoutePath.includes(param.name) &&\n !pathParatemersFromRoutePath.includes(`${param.name}?`) &&\n param.in === \"path\" &&\n param.name !== \"*\"\n )\n throw new Error(\n `ValidationError: Trying to define path parameter '${param.name}' but it is not present in your pathname ${originalPath}`\n );\n }\n\n delete convertedOpenAPI.parameters;\n const hasUploadFields =\n Object.keys(config?.experimental?.uploads || {}).length > 0;\n const multipartFormSchema =\n convertedOpenAPI?.requestBody?.content?.[\"multipart/form-data\"];\n\n const allUploadFieldsAreRequired = hasUploadFields\n ? uploadManager.isAllFieldRequired(config?.experimental?.uploads!)\n : false;\n\n if (hasUploadFields && multipartFormSchema)\n arkosRouterOpenApiManager.validateMultipartFormDocs(\n multipartFormSchema,\n path,\n config?.experimental?.uploads\n );\n\n (paths as any)[path][method.toLowerCase()] = {\n ...convertedOpenAPI,\n summary: openapi?.summary || `${path}`,\n description: openapi?.description || `${method} ${path}`,\n servers: openapi?.servers || routeOptions?.openapi?.servers || undefined,\n security:\n openapi?.security || routeOptions?.openapi?.security || undefined,\n externalDocs:\n openapi?.externalDocs ||\n routeOptions?.openapi?.externalDocs ||\n undefined,\n tags: openapi?.tags || routeOptions?.openapi?.tags || [\"Defaults\"],\n operationId: openapi.operationId || `${method.toLowerCase()}:${path}`,\n parameters: allParameters,\n ...(!convertedOpenAPI.requestBody &&\n config?.validation &&\n config?.validation?.body && {\n requestBody: {\n content: (() => {\n const schema = validatorToJsonSchema(\n config?.validation?.body as any\n );\n\n return {\n ...convertedOpenAPI?.requestBody?.content,\n ...(hasUploadFields && {\n \"multipart/form-data\": {\n schema: openApiSchemaConverter.flattenSchema(\n arkosRouterOpenApiManager.addUploadFields(\n config.experimental?.uploads!,\n schema\n )\n ),\n },\n }),\n ...(!allUploadFieldsAreRequired && {\n \"application/json\": {\n schema,\n },\n }),\n };\n })(),\n },\n }),\n ...(!multipartFormSchema &&\n !(config as any)?.validation?.body &&\n hasUploadFields && {\n requestBody: {\n content: (() => {\n const schema =\n convertedOpenAPI?.requestBody?.content?.[\"application/json\"]\n ?.schema || {};\n\n delete convertedOpenAPI?.requestBody?.content?.[\n \"application/json\"\n ];\n\n return {\n \"multipart/form-data\": {\n schema: openApiSchemaConverter.flattenSchema(\n arkosRouterOpenApiManager.addUploadFields(\n config?.experimental?.uploads! || {},\n schema\n )\n ),\n },\n ...convertedOpenAPI?.requestBody?.content,\n ...(!allUploadFieldsAreRequired && {\n \"application/json\": {\n schema,\n },\n }),\n };\n })(),\n },\n }),\n } as OpenAPIV3.PathItemObject;\n });\n\n return paths;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/arkos-router/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import {\n Application,\n IRoute,\n IRouter,\n IRouterHandler,\n IRouterMatcher,\n Locals,\n} from \"express\";\nimport { z, 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 {\n ArkosAnyRequestHandler,\n ArkosErrorRequestHandler,\n ArkosRequestHandler,\n} from \"../../../types\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\nimport { BodyParserConfig } from \"./body-parser-config\";\nimport { ArkosRouterOptions } from \"..\";\nimport { Validator } from \"../../../types/validation/validator\";\n\nexport type ArkosUseConfig = Pick<\n ArkosRouteConfig,\n | \"authentication\"\n | \"rateLimit\"\n | \"compression\"\n | \"queryParser\"\n | \"bodyParser\"\n | \"disabled\"\n> & {\n path?: PathParams; // optional unlike ArkosRouteConfig where path is required\n};\n\ntype InferValidationType<T, Fallback> = T extends ZodSchema\n ? z.infer<T>\n : T extends new (...args: any[]) => infer I\n ? I\n : Fallback;\n\nexport type PathParams = string | RegExp | Array<string | RegExp>;\n\nexport type InternalIArkosRouter = IArkosRouter & {\n _arkos: {\n options?: ArkosRouterOptions;\n routes: Array<{\n handler: ArkosAnyRequestHandler;\n config: ArkosRouteConfig;\n method: string;\n }>;\n };\n};\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 RouterMethodHandler<T> = IRouterHandler<T> &\n IRouterMatcher<T> & {\n // (config: PathParams, ...handlers: Array<ArkosAnyRequestHandler>): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams>,\n ...handlers: Array<\n | ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n | Array<\n ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n >\n >\n ): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams>,\n ...handlers: Array<\n | ArkosErrorRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n | Array<\n ArkosErrorRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n >\n >\n ): T;\n\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams>,\n subApplication: Application\n ): T;\n };\n\nexport type ArkosRouteMethodHandler<T> = {\n (\n config: ArkosAnyRequestHandler | Omit<ArkosRouteConfig, \"path\">,\n ...handlers: Array<\n | ArkosRequestHandler\n | ArkosErrorRequestHandler\n | Array<ArkosRequestHandler | ArkosErrorRequestHandler>\n >\n ): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: Omit<ArkosRouteConfig<TQuery, TBody, TParams>, \"path\">,\n ...handlers: Array<\n | ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n | Array<\n ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n >\n >\n ): T;\n\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: Omit<ArkosRouteConfig<TQuery, TBody, TParams>, \"path\">,\n ...handlers: Array<\n | ArkosErrorRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n | Array<\n ArkosErrorRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n >\n >\n ): T;\n};\n\n/**\n * Handler function for `use` that accepts route configuration and middleware handlers.\n *\n * @param {ArkosUseConfig} config - The use configuration object or path.\n * @param {...ArkosAnyRequestHandler} handlers - Middleware handlers.\n * @returns {T} The router instance.\n */\n\nexport type UseMethodHandler<T> = IRouterHandler<T> &\n IRouterMatcher<T> & {\n (\n config: ArkosUseConfig,\n ...handlers: Array<ArkosRequestHandler | Array<ArkosRequestHandler>>\n ): T;\n (\n config: ArkosUseConfig,\n ...handlers: Array<\n ArkosErrorRequestHandler | Array<ArkosErrorRequestHandler>\n >\n ): T;\n (...handlers: Array<ArkosRequestHandler | Array<ArkosRequestHandler>>): T;\n };\n\nexport interface IArkosRoute extends IRoute {\n /** GET method handler with route configuration support */\n get: ArkosRouteMethodHandler<this>;\n /** POST method handler with route configuration support */\n post: ArkosRouteMethodHandler<this>;\n /** PUT method handler with route configuration support */\n put: ArkosRouteMethodHandler<this>;\n /** PATCH method handler with route configuration support */\n patch: ArkosRouteMethodHandler<this>;\n /** DELETE method handler with route configuration support */\n delete: ArkosRouteMethodHandler<this>;\n /** OPTIONS method handler with route configuration support */\n options: ArkosRouteMethodHandler<this>;\n /** HEAD method handler with route configuration support */\n head: ArkosRouteMethodHandler<this>;\n // /** TRACE method handler with route configuration support */\n trace: ArkosRouteMethodHandler<this>;\n /** ALL methods handler with route configuration support */\n all: ArkosRouteMethodHandler<this>;\n}\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 extends IRouter {\n /** GET method handler with route configuration support */\n get: RouterMethodHandler<this>;\n /** POST method handler with route configuration support */\n post: RouterMethodHandler<this>;\n /** PUT method handler with route configuration support */\n put: RouterMethodHandler<this>;\n /** PATCH method handler with route configuration support */\n patch: RouterMethodHandler<this>;\n /** DELETE method handler with route configuration support */\n delete: RouterMethodHandler<this>;\n /** OPTIONS method handler with route configuration support */\n options: RouterMethodHandler<this>;\n /** HEAD method handler with route configuration support */\n head: RouterMethodHandler<this>;\n // /** TRACE method handler with route configuration support */\n trace: RouterMethodHandler<this>;\n /** ALL methods handler with route configuration support */\n all: RouterMethodHandler<this>;\n use: UseMethodHandler<this>;\n route<T extends string>(prefix: T): IArkosRoute;\n route(prefix: PathParams): IArkosRoute;\n}\n\n/**\n * Configuration object for defining routes in Arkos.js.\n */\nexport type ArkosRouteConfig<\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n> = {\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: PathParams;\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 * - Set to `null` to forbidden all request inputs.\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 | null\n | {\n query?: TQuery;\n body?: TBody;\n params?: TParams;\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"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/arkos-router/types/index.ts"],"names":[],"mappings":"","sourcesContent":["import {\n Application,\n IRoute,\n IRouter,\n IRouterHandler,\n IRouterMatcher,\n Locals,\n} from \"express\";\nimport { z, 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 {\n ArkosAnyRequestHandler,\n ArkosErrorRequestHandler,\n ArkosRequestHandler,\n} from \"../../../types\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\nimport { BodyParserConfig } from \"./body-parser-config\";\nimport { ArkosRouterOptions } from \"..\";\nimport { Validator } from \"../../../types/validation/validator\";\n\nexport type ArkosUseConfig = Pick<\n ArkosRouteConfig,\n | \"authentication\"\n | \"rateLimit\"\n | \"compression\"\n | \"queryParser\"\n | \"bodyParser\"\n | \"disabled\"\n> & {\n path?: PathParams; // optional unlike ArkosRouteConfig where path is required\n};\n\ntype InferValidationType<T, Fallback> = T extends ZodSchema\n ? z.infer<T>\n : T extends new (...args: any[]) => infer I\n ? I\n : Fallback;\n\nexport type PathParams = string | RegExp | Array<string | RegExp>;\n\nexport type InternalIArkosRouter = IArkosRouter & {\n _arkos: {\n options?: ArkosRouterOptions;\n routes: Array<{\n handler: ArkosAnyRequestHandler;\n config: ArkosRouteConfig;\n method: string;\n }>;\n };\n};\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 IArkosRouterMethodHandler<T> = IRouterHandler<T> &\n IRouterMatcher<T> & {\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams>,\n ...handlers: Array<\n | ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n | Array<\n ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n >\n >\n ): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams> | PathParams,\n ...handlers: Array<\n | ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n | Array<\n | ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n | Array<\n ArkosErrorRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n any\n >\n >\n >\n >\n ): T;\n\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosRouteConfig<TQuery, TBody, TParams>,\n subApplication: Application\n ): T;\n };\n\nexport type ArkosRouteMethodHandler<T> = {\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: ArkosAnyRequestHandler | Omit<ArkosRouteConfig, \"path\">,\n ...handlers: Array<\n ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n >\n ): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: Omit<ArkosRouteConfig<TQuery, TBody, TParams>, \"path\">,\n ...handlers: Array<\n | ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n | Array<\n ArkosRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n >\n >\n ): T;\n <\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n >(\n config: Omit<ArkosRouteConfig<TQuery, TBody, TParams>, \"path\">,\n ...handlers: Array<\n | ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n | Array<\n ArkosAnyRequestHandler<\n InferValidationType<TParams, Record<string, string>>,\n any,\n InferValidationType<TBody, any>,\n InferValidationType<TQuery, qs.ParsedQs>,\n Locals\n >\n >\n >\n ): T;\n};\n\n/**\n * Handler function for `use` that accepts route configuration and middleware handlers.\n *\n * @param {ArkosUseConfig} config - The use configuration object or path.\n * @param {...ArkosAnyRequestHandler} handlers - Middleware handlers.\n * @returns {T} The router instance.\n */\n\nexport type UseMethodHandler<T> = IRouterHandler<T> &\n IRouterMatcher<T> & {\n (\n config: ArkosUseConfig,\n ...handlers: Array<ArkosRequestHandler | Array<ArkosRequestHandler>>\n ): T;\n (\n config: ArkosUseConfig,\n ...handlers: Array<\n ArkosErrorRequestHandler | Array<ArkosErrorRequestHandler>\n >\n ): T;\n (\n config: ArkosUseConfig,\n ...handlers: Array<\n | ArkosRequestHandler\n | ArkosErrorRequestHandler\n | Array<ArkosRequestHandler | ArkosErrorRequestHandler>\n >\n ): T;\n (\n ...handlers: Array<\n | ArkosRequestHandler\n | ArkosErrorRequestHandler\n | Array<ArkosRequestHandler | ArkosErrorRequestHandler>\n >\n ): T;\n };\n\nexport interface IArkosRoute extends IRoute {\n /** GET method handler with route configuration support */\n get: ArkosRouteMethodHandler<this>;\n /** POST method handler with route configuration support */\n post: ArkosRouteMethodHandler<this>;\n /** PUT method handler with route configuration support */\n put: ArkosRouteMethodHandler<this>;\n /** PATCH method handler with route configuration support */\n patch: ArkosRouteMethodHandler<this>;\n /** DELETE method handler with route configuration support */\n delete: ArkosRouteMethodHandler<this>;\n /** OPTIONS method handler with route configuration support */\n options: ArkosRouteMethodHandler<this>;\n /** HEAD method handler with route configuration support */\n head: ArkosRouteMethodHandler<this>;\n // /** TRACE method handler with route configuration support */\n trace: ArkosRouteMethodHandler<this>;\n /** ALL methods handler with route configuration support */\n all: ArkosRouteMethodHandler<this>;\n}\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 extends IRouter {\n /** GET method handler with route configuration support */\n get: IArkosRouterMethodHandler<this>;\n /** POST method handler with route configuration support */\n post: IArkosRouterMethodHandler<this>;\n /** PUT method handler with route configuration support */\n put: IArkosRouterMethodHandler<this>;\n /** PATCH method handler with route configuration support */\n patch: IArkosRouterMethodHandler<this>;\n /** DELETE method handler with route configuration support */\n delete: IArkosRouterMethodHandler<this>;\n /** OPTIONS method handler with route configuration support */\n options: IArkosRouterMethodHandler<this>;\n /** HEAD method handler with route configuration support */\n head: IArkosRouterMethodHandler<this>;\n // /** TRACE method handler with route configuration support */\n trace: IArkosRouterMethodHandler<this>;\n /** ALL methods handler with route configuration support */\n all: IArkosRouterMethodHandler<this>;\n use: UseMethodHandler<this>;\n route<T extends string>(prefix: T): IArkosRoute;\n route(prefix: PathParams): IArkosRoute;\n}\n\n/**\n * Configuration object for defining routes in Arkos.js.\n */\nexport type ArkosRouteConfig<\n TQuery extends Validator = any,\n TBody extends Validator = any,\n TParams extends Validator = any,\n> = {\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: PathParams;\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 * - Set to `null` to forbidden all request inputs.\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 | null\n | {\n query?: TQuery;\n body?: TBody;\n params?: TParams;\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"]}
@@ -278,6 +278,11 @@ class UploadManager {
278
278
  next();
279
279
  });
280
280
  }
281
+ isAllFieldRequired(uploadConfig) {
282
+ if (!uploadConfig)
283
+ return false;
284
+ return uploadConfig.required !== false;
285
+ }
281
286
  }
282
287
  const uploadManager = new UploadManager();
283
288
  exports.default = 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\";\nimport { catchAsync } from \"../../../../exports/error-handler\";\nimport { pascalCase } from \"../../../helpers/change-case.helpers\";\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 /**\n * Validates that all required upload files are present in the request.\n * Checks req.file or req.files based on upload configuration type.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @throws {AppError} If required files are missing\n *\n * @example\n * // Single file upload - checks req.file\n * validateRequiredFiles(\n * { type: 'single', field: 'avatar', required: true },\n * req,\n * '/users/:id/avatar'\n * )\n *\n * @example\n * // Array file upload - checks req.files array\n * validateRequiredFiles(\n * { type: 'array', field: 'photos', required: true },\n * req,\n * '/gallery/upload'\n * )\n *\n * @example\n * // Multiple fields - checks req.files object\n * validateRequiredFiles(\n * { type: 'fields', fields: [{ name: 'avatar' }, { name: 'resume' }], required: true },\n * req,\n * '/profile/upload'\n * )\n */\n validateRequiredFiles(uploadConfig: UploadConfig) {\n return catchAsync((req: ArkosRequest, _: any, next: ArkosNextFunction) => {\n const errors: string[] = [];\n const errorCodes: string[] = [];\n\n if (uploadConfig.required === false) return next();\n\n if (uploadConfig.type === \"single\") {\n if (!req.file) {\n errors.push(\n `Required upload field '${uploadConfig.field}' is missing`\n );\n errorCodes.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"array\") {\n if (!req.files || !Array.isArray(req.files) || req.files.length === 0) {\n errors.push(\n `Required upload field '${uploadConfig.field}' is missing or empty`\n );\n errorCodes.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"fields\") {\n if (\n !req.files ||\n typeof req.files !== \"object\" ||\n Array.isArray(req.files)\n ) {\n errors.push(\n `Required upload fields are missing. Expected an object with fields: ${uploadConfig.fields.map((f) => f.name).join(\", \")}`\n );\n errorCodes.push(...uploadConfig.fields.map((f) => f.name));\n } else {\n for (const field of uploadConfig.fields) {\n const filesForField = (req.files as any)[field.name];\n if (\n !filesForField ||\n !Array.isArray(filesForField) ||\n filesForField.length === 0\n ) {\n errors.push(\n `Required upload field '${field.name}' is missing or empty`\n );\n errorCodes.push(field.name);\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AppError(\n errors[0],\n 400,\n `Missing${pascalCase(errorCodes[0]).replaceAll(\"_\", \"\")}FileField`,\n {\n errors,\n }\n );\n }\n\n next();\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 .replaceAll(process.cwd(), \"\")\n .replace(`/${fullBaseUploadDir}`, \"\")\n .replace(fullBaseUploadDir, \"\")\n .replace(/\\\\/g, \"/\");\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\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 =\n (baseRoute === \"/\"\n ? \"\"\n : baseRoute.startsWith(\"/\")\n ? baseRoute\n : `/${baseRoute}`) + normalizePath(file.path);\n\n if (config.attachToBody === false) return undefined;\n if (config.attachToBody === \"pathname\" || !config.attachToBody)\n return (file as any).pathname;\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"]}
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\";\nimport { pascalCase } from \"../../../helpers/change-case.helpers\";\nimport { ArkosFile } from \"../../../../types/upload\";\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: any) => {\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 /**\n * Validates that all required upload files are present in the request.\n * Checks req.file or req.files based on upload configuration type.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @throws {AppError} If required files are missing\n *\n * @example\n * // Single file upload - checks req.file\n * validateRequiredFiles(\n * { type: 'single', field: 'avatar', required: true },\n * req,\n * '/users/:id/avatar'\n * )\n *\n * @example\n * // Array file upload - checks req.files array\n * validateRequiredFiles(\n * { type: 'array', field: 'photos', required: true },\n * req,\n * '/gallery/upload'\n * )\n *\n * @example\n * // Multiple fields - checks req.files object\n * validateRequiredFiles(\n * { type: 'fields', fields: [{ name: 'avatar' }, { name: 'resume' }], required: true },\n * req,\n * '/profile/upload'\n * )\n */\n validateRequiredFiles(uploadConfig: UploadConfig) {\n return catchAsync((req: ArkosRequest, _: any, next: ArkosNextFunction) => {\n const errors: string[] = [];\n const errorCodes: string[] = [];\n\n if (uploadConfig.required === false) return next();\n\n if (uploadConfig.type === \"single\") {\n if (!req.file) {\n errors.push(\n `Required upload field '${uploadConfig.field}' is missing`\n );\n errorCodes.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"array\") {\n if (!req.files || !Array.isArray(req.files) || req.files.length === 0) {\n errors.push(\n `Required upload field '${uploadConfig.field}' is missing or empty`\n );\n errorCodes.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"fields\") {\n if (\n !req.files ||\n typeof req.files !== \"object\" ||\n Array.isArray(req.files)\n ) {\n errors.push(\n `Required upload fields are missing. Expected an object with fields: ${uploadConfig.fields.map((f) => f.name).join(\", \")}`\n );\n errorCodes.push(...uploadConfig.fields.map((f) => f.name));\n } else {\n for (const field of uploadConfig.fields) {\n const filesForField = (req.files as any)[field.name];\n if (\n !filesForField ||\n !Array.isArray(filesForField) ||\n filesForField.length === 0\n ) {\n errors.push(\n `Required upload field '${field.name}' is missing or empty`\n );\n errorCodes.push(field.name);\n }\n }\n }\n }\n\n if (errors.length > 0) {\n throw new AppError(\n errors[0],\n 400,\n `Missing${pascalCase(errorCodes[0]).replaceAll(\"_\", \"\")}FileField`,\n {\n errors,\n }\n );\n }\n\n next();\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 .replaceAll(process.cwd(), \"\")\n .replace(`/${fullBaseUploadDir}`, \"\")\n .replace(fullBaseUploadDir, \"\")\n .replace(/\\\\/g, \"/\");\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\n return `${baseURL}${baseRoute === \"/\" ? \"\" : baseRoute}${\n relativePath.startsWith(\"/\") ? relativePath : `/${relativePath}`\n }`;\n };\n\n const getAttachValue = (file: ArkosFile) => {\n const url = buildFileURL(file);\n\n file.url = url;\n file.pathname =\n (baseRoute === \"/\"\n ? \"\"\n : baseRoute.startsWith(\"/\")\n ? baseRoute\n : `/${baseRoute}`) + normalizePath(file.path);\n\n if (config.attachToBody === false) return undefined;\n if (config.attachToBody === \"pathname\" || !config.attachToBody)\n return (file as any).pathname;\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 isAllFieldRequired(uploadConfig: UploadConfig): boolean {\n if (!uploadConfig) return false;\n\n return uploadConfig.required !== false;\n }\n}\n\nconst uploadManager = new UploadManager();\n\nexport default uploadManager;\n"]}
@@ -19,6 +19,6 @@ function killServerChildProcess() {
19
19
  (0, start_1.killProductionServerChildProcess)();
20
20
  }
21
21
  function getVersion() {
22
- return "1.6.5-beta";
22
+ return "1.6.7-beta";
23
23
  }
24
24
  //# sourceMappingURL=cli.helpers.js.map
@@ -52,7 +52,7 @@ class ClassValidatorDtoGenerator {
52
52
  transformersUsed.add("Type");
53
53
  if (!nestedDtoClasses.find((c) => c.includes(`class ${compositeDtoName}`))) {
54
54
  const nestedFields = compositeType.fields.map((f) => {
55
- const { decorators, type } = this.generateClassValidatorField(f, false, validatorsUsed);
55
+ const { decorators, type } = this.generateClassValidatorField(f, false, validatorsUsed, transformersUsed);
56
56
  const mod = isTypeScript ? (f.isOptional ? "?" : "!") : "";
57
57
  return `${decorators} ${f.name}${mod}: ${type};`;
58
58
  });
@@ -87,7 +87,7 @@ class ClassValidatorDtoGenerator {
87
87
  validatorsUsed.add("ValidateNested");
88
88
  transformersUsed.add("Type");
89
89
  const relationDtoName = `${referencedModel.name}ForCreate${modelName.pascal}Dto`;
90
- const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript);
90
+ const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed);
91
91
  if (!dtoFields.find((dtoField) => dtoField.includes(relationDtoName)))
92
92
  nestedDtoClasses.push(nestedDtoClass);
93
93
  dtoFields.push(`${optionalDecorator} @ValidateNested()\n @Type(() => ${relationDtoName})\n ${field.name}${typeModifier}: ${relationDtoName};`);
@@ -97,7 +97,7 @@ class ClassValidatorDtoGenerator {
97
97
  if (prisma_schema_parser_1.default.isEnum(field.type)) {
98
98
  enumsUsed.add(field.type);
99
99
  }
100
- const { decorators, type } = this.generateClassValidatorField(field, isUserModule, validatorsUsed);
100
+ const { decorators, type } = this.generateClassValidatorField(field, isUserModule, validatorsUsed, transformersUsed);
101
101
  const isOptional = field.isOptional || field.defaultValue !== undefined;
102
102
  const typeModifier = isTypeScript ? (isOptional ? "?" : "!") : "";
103
103
  dtoFields.push(`${decorators} ${field.name}${typeModifier}: ${type};`);
@@ -145,7 +145,7 @@ ${dtoFields.join("\n\n")}
145
145
  transformersUsed.add("Type");
146
146
  if (!nestedDtoClasses.find((c) => c.includes(`class ${compositeDtoName}`))) {
147
147
  const nestedFields = compositeType.fields.map((f) => {
148
- const { decorators, type } = this.generateClassValidatorFieldForUpdate(f, false, validatorsUsed);
148
+ const { decorators, type } = this.generateClassValidatorFieldForUpdate(f, false, validatorsUsed, transformersUsed);
149
149
  const mod = isTypeScript ? "?" : "";
150
150
  return `${decorators} ${f.name}${mod}: ${type};`;
151
151
  });
@@ -171,7 +171,7 @@ ${dtoFields.join("\n\n")}
171
171
  validatorsUsed.add("IsNotEmpty");
172
172
  transformersUsed.add("Type");
173
173
  const relationDtoName = `${referencedModel.name}ForUpdate${modelName.pascal}Dto`;
174
- const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript);
174
+ const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed);
175
175
  if (!dtoFields.find((dtoField) => dtoField.includes(relationDtoName)))
176
176
  nestedDtoClasses.push(nestedDtoClass);
177
177
  const typeModifier = isTypeScript ? "?" : "";
@@ -182,7 +182,7 @@ ${dtoFields.join("\n\n")}
182
182
  if (prisma_schema_parser_1.default.isEnum(field.type)) {
183
183
  enumsUsed.add(field.type);
184
184
  }
185
- const { decorators, type } = this.generateClassValidatorFieldForUpdate(field, isUserModule, validatorsUsed);
185
+ const { decorators, type } = this.generateClassValidatorFieldForUpdate(field, isUserModule, validatorsUsed, transformersUsed);
186
186
  const typeModifier = isTypeScript ? "?" : "";
187
187
  dtoFields.push(`${decorators} ${field.name}${typeModifier}: ${type};`);
188
188
  }
@@ -221,7 +221,7 @@ ${dtoFields.join("\n\n")}
221
221
  if (prisma_schema_parser_1.default.isEnum(field.type)) {
222
222
  enumsUsed.add(field.type);
223
223
  }
224
- const { decorators, type } = this.generateClassValidatorField(field, isUserModule, validatorsUsed);
224
+ const { decorators, type } = this.generateClassValidatorField(field, isUserModule, validatorsUsed, transformersUsed);
225
225
  const isOptional = field.isOptional;
226
226
  const typeModifier = isTypeScript ? (isOptional ? "?" : "!") : "";
227
227
  dtoFields.push(`${decorators} ${field.name}${typeModifier}: ${type};`);
@@ -291,7 +291,7 @@ ${dtoFields.join("\n\n")}
291
291
  validatorsUsed.add("ValidateNested");
292
292
  transformersUsed.add("Type");
293
293
  const relationDtoName = `${referencedModel.name}ForQuery${modelName.pascal}Dto`;
294
- const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript);
294
+ const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed);
295
295
  if (!dtoFields.find((dtoField) => dtoField.includes(relationDtoName)) &&
296
296
  !timestampDtoFields.find((dtoField) => dtoField.includes(relationDtoName))) {
297
297
  nestedDtoClasses.push(nestedDtoClass);
@@ -321,7 +321,8 @@ ${dtoFields.join("\n\n")}
321
321
  }
322
322
  if (field.type === "Boolean") {
323
323
  validatorsUsed.add("IsBoolean");
324
- const fieldDef = ` @IsOptional()\n @IsBoolean()\n ${field.name}${typeModifier}: boolean;`;
324
+ transformersUsed.add("Transform");
325
+ const fieldDef = ` @IsOptional()\n @Transform(({ value }) => value === true || value === "true" || value === 1 || value === "1")\n @IsBoolean()\n ${field.name}${typeModifier}: boolean;`;
325
326
  if (timestampFields.includes(field.name)) {
326
327
  timestampDtoFields.push(fieldDef);
327
328
  }
@@ -437,14 +438,14 @@ ${allFields.join("\n\n")}
437
438
  }
438
439
  return classes.join("\n\n");
439
440
  }
440
- generateNestedDtoClass(field, referencedModel, dtoName, validatorsUsed, enumsUsed, isTypeScript) {
441
+ generateNestedDtoClass(field, referencedModel, dtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed) {
441
442
  const fields = [];
442
443
  const refFieldName = field.foreignReferenceField || "id";
443
444
  const refFieldAsPrismaField = referencedModel.fields.find((f) => f.name === refFieldName);
444
445
  if (refFieldAsPrismaField) {
445
446
  if (prisma_schema_parser_1.default.isEnum(refFieldAsPrismaField.type))
446
447
  enumsUsed.add(refFieldAsPrismaField.type);
447
- const { decorators, type } = this.generateClassValidatorField(refFieldAsPrismaField, false, validatorsUsed);
448
+ const { decorators, type } = this.generateClassValidatorField(refFieldAsPrismaField, false, validatorsUsed, transformersUsed);
448
449
  const typeModifier = isTypeScript ? "!" : "";
449
450
  fields.push(`${decorators} ${refFieldAsPrismaField.name}${typeModifier}: ${type};`);
450
451
  }
@@ -452,7 +453,32 @@ ${allFields.join("\n\n")}
452
453
  ${fields.join("\n\n")}
453
454
  }`;
454
455
  }
455
- generateClassValidatorField(field, isUserModule, validatorsUsed) {
456
+ generateTransformDecorator(field) {
457
+ const isArray = field.isArray;
458
+ switch (field.type) {
459
+ case "Int":
460
+ case "Float":
461
+ case "Decimal":
462
+ return isArray
463
+ ? `@Transform(({ value }) => (Array.isArray(value) ? value.map((v: any) => (v !== undefined && v !== null && v !== "" ? Number(v) : v)) : value))`
464
+ : `@Transform(({ value }) => (value !== undefined && value !== null && value !== "" ? Number(value) : value))`;
465
+ case "BigInt":
466
+ return isArray
467
+ ? `@Transform(({ value }) => (Array.isArray(value) ? value.map((v: any) => (v !== undefined && v !== null && v !== "" ? BigInt(v) : v)) : value))`
468
+ : `@Transform(({ value }) => (value !== undefined && value !== null && value !== "" ? BigInt(value) : value))`;
469
+ case "Boolean":
470
+ return isArray
471
+ ? `@Transform(({ value }) => (Array.isArray(value) ? value.map((v: any) => v === true || v === "true" || v === 1 || v === "1") : value))`
472
+ : `@Transform(({ value }) => value === true || value === "true" || value === 1 || value === "1")`;
473
+ case "DateTime":
474
+ return isArray
475
+ ? `@Transform(({ value }) => (Array.isArray(value) ? value.map((v: any) => (v ? new Date(v) : v)) : value))`
476
+ : `@Transform(({ value }) => (value ? new Date(value) : value))`;
477
+ default:
478
+ return null;
479
+ }
480
+ }
481
+ generateClassValidatorField(field, isUserModule, validatorsUsed, transformersUsed) {
456
482
  let decorators = [];
457
483
  let type = this.mapPrismaTypeToTS(field.type);
458
484
  const isOptional = field.isOptional || field.defaultValue !== undefined;
@@ -478,6 +504,11 @@ ${fields.join("\n\n")}
478
504
  type = field.isArray ? `${field.type}[]` : field.type;
479
505
  }
480
506
  else {
507
+ const transformDecorator = this.generateTransformDecorator(field);
508
+ if (transformDecorator) {
509
+ decorators.push(transformDecorator);
510
+ transformersUsed.add("Transform");
511
+ }
481
512
  const fieldValidators = this.getValidatorsForType(field, isUserModule);
482
513
  decorators.push(...fieldValidators);
483
514
  fieldValidators.forEach((decorator) => {
@@ -492,7 +523,7 @@ ${fields.join("\n\n")}
492
523
  type,
493
524
  };
494
525
  }
495
- generateClassValidatorFieldForUpdate(field, isUserModule, validatorsUsed) {
526
+ generateClassValidatorFieldForUpdate(field, isUserModule, validatorsUsed, transformersUsed) {
496
527
  let decorators = [];
497
528
  let type = this.mapPrismaTypeToTS(field.type);
498
529
  decorators.push("@IsOptional()");
@@ -515,6 +546,11 @@ ${fields.join("\n\n")}
515
546
  type = field.isArray ? `${field.type}[]` : field.type;
516
547
  }
517
548
  else {
549
+ const transformDecorator = this.generateTransformDecorator(field);
550
+ if (transformDecorator) {
551
+ decorators.push(transformDecorator);
552
+ transformersUsed.add("Transform");
553
+ }
518
554
  const fieldValidators = this.getValidatorsForType(field, isUserModule);
519
555
  decorators.push(...fieldValidators);
520
556
  fieldValidators.forEach((decorator) => {
@@ -673,7 +709,7 @@ ${usernameFields.join("\n\n")}
673
709
  validatorsUsed.add("ValidateNested");
674
710
  transformersUsed.add("Type");
675
711
  const relationDtoName = `${referencedModel.name}ForSignupDto`;
676
- const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript);
712
+ const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed);
677
713
  if (!dtoFields.find((d) => d.includes(relationDtoName)))
678
714
  nestedDtoClasses.push(nestedDtoClass);
679
715
  const typeModifier = isTypeScript ? (isOptional ? "?" : "!") : "";
@@ -692,7 +728,7 @@ ${usernameFields.join("\n\n")}
692
728
  dtoFields.push(` @IsNotEmpty()\n @IsString()\n @MinLength(8)\n @Matches(/[a-z]/, { message: "Must contain lowercase" })\n @Matches(/[A-Z]/, { message: "Must contain uppercase" })\n @Matches(/[0-9]/, { message: "Must contain number" })\n ${field.name}${typeModifier}: string;`);
693
729
  continue;
694
730
  }
695
- const { decorators, type } = this.generateClassValidatorField(field, true, validatorsUsed);
731
+ const { decorators, type } = this.generateClassValidatorField(field, true, validatorsUsed, transformersUsed);
696
732
  const isOptional = field.isOptional || field.defaultValue !== undefined;
697
733
  const typeModifier = isTypeScript ? (isOptional ? "?" : "!") : "";
698
734
  dtoFields.push(`${decorators} ${field.name}${typeModifier}: ${type};`);
@@ -752,7 +788,7 @@ ${dtoFields.join("\n\n")}
752
788
  validatorsUsed.add("ValidateNested");
753
789
  transformersUsed.add("Type");
754
790
  const relationDtoName = `${referencedModel.name}ForUpdateMeDto`;
755
- const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript);
791
+ const nestedDtoClass = this.generateNestedDtoClass(field, referencedModel, relationDtoName, validatorsUsed, enumsUsed, isTypeScript, transformersUsed);
756
792
  if (!dtoFields.find((d) => d.includes(relationDtoName)))
757
793
  nestedDtoClasses.push(nestedDtoClass);
758
794
  const typeModifier = isTypeScript ? "?" : "";
@@ -762,7 +798,7 @@ ${dtoFields.join("\n\n")}
762
798
  }
763
799
  if (prisma_schema_parser_1.default.isEnum(field.type))
764
800
  enumsUsed.add(field.type);
765
- const { decorators, type } = this.generateClassValidatorFieldForUpdate(field, true, validatorsUsed);
801
+ const { decorators, type } = this.generateClassValidatorFieldForUpdate(field, true, validatorsUsed, transformersUsed);
766
802
  const typeModifier = isTypeScript ? "?" : "";
767
803
  dtoFields.push(`${decorators} ${field.name}${typeModifier}: ${type};`);
768
804
  }