arkos 1.5.15-beta → 1.5.16-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 (67) 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 +14 -8
  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/utils/helpers/openapi-schema-converter.js +4 -2
  10. package/dist/cjs/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
  11. package/dist/cjs/types/index.js.map +1 -1
  12. package/dist/cjs/types/new-arkos-config.js.map +1 -1
  13. package/dist/cjs/types/{arkos-prisma-input.bak.js → upload.js} +1 -1
  14. package/dist/cjs/types/upload.js.map +1 -0
  15. package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js +3 -9
  16. package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  17. package/dist/cjs/utils/arkos-router/index.js +14 -3
  18. package/dist/cjs/utils/arkos-router/index.js.map +1 -1
  19. package/dist/cjs/utils/arkos-router/types/index.js.map +1 -1
  20. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js +5 -0
  21. package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  22. package/dist/cjs/utils/cli/utils/cli.helpers.js +1 -1
  23. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +49 -13
  24. package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -1
  25. package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js +18 -18
  26. package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -1
  27. package/dist/cjs/utils/helpers/arkos-config.helpers.js.map +1 -1
  28. package/dist/esm/exports/index.js +2 -1
  29. package/dist/esm/exports/index.js.map +1 -1
  30. package/dist/esm/modules/email/email.service.js +14 -8
  31. package/dist/esm/modules/email/email.service.js.map +1 -1
  32. package/dist/esm/modules/error-handler/error-handler.controller.js +4 -3
  33. package/dist/esm/modules/error-handler/error-handler.controller.js.map +1 -1
  34. package/dist/esm/modules/file-upload/file-upload.router.js +9 -2
  35. package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
  36. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js +4 -2
  37. package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
  38. package/dist/esm/types/index.js.map +1 -1
  39. package/dist/esm/types/new-arkos-config.js.map +1 -1
  40. package/dist/esm/types/upload.js +2 -0
  41. package/dist/esm/types/upload.js.map +1 -0
  42. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js +3 -9
  43. package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
  44. package/dist/esm/utils/arkos-router/index.js +14 -3
  45. package/dist/esm/utils/arkos-router/index.js.map +1 -1
  46. package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
  47. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js +5 -0
  48. package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
  49. package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
  50. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +49 -13
  51. package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -1
  52. package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js +18 -18
  53. package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -1
  54. package/dist/esm/utils/helpers/arkos-config.helpers.js.map +1 -1
  55. package/dist/types/exports/index.d.ts +3 -26
  56. package/dist/types/types/index.d.ts +5 -4
  57. package/dist/types/types/new-arkos-config.d.ts +2 -2
  58. package/dist/types/types/upload.d.ts +10 -0
  59. package/dist/types/utils/arkos-router/types/index.d.ts +4 -4
  60. package/dist/types/utils/arkos-router/utils/helpers/upload-manager.d.ts +1 -0
  61. package/dist/types/utils/cli/utils/template-generator/templates/class-validator-dto-generator.d.ts +7 -0
  62. package/dist/types/utils/helpers/arkos-config.helpers.d.ts +5 -0
  63. package/package.json +1 -1
  64. package/dist/cjs/types/arkos-prisma-input.bak.js.map +0 -1
  65. package/dist/esm/types/arkos-prisma-input.bak.js +0 -2
  66. package/dist/esm/types/arkos-prisma-input.bak.js.map +0 -1
  67. package/dist/types/types/arkos-prisma-input.bak.d.ts +0 -237
@@ -1 +1 @@
1
- {"version":3,"file":"new-arkos-config.js","sourceRoot":"","sources":["../../../src/types/new-arkos-config.ts"],"names":[],"mappings":"","sourcesContent":["import cors from \"cors\";\nimport express, { CookieOptions } from \"express\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport cookieParser from \"cookie-parser\";\nimport compression from \"compression\";\nimport { Options as QueryParserOptions } from \"../utils/helpers/query-parser.helpers\";\nimport { ValidatorOptions } from \"class-validator\";\nimport { MsDuration } from \"../modules/auth/utils/helpers/auth.controller.helpers\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport type { ApiReferenceConfiguration } from \"@scalar/express-api-reference\" with { \"resolution-mode\": \"import\" };\nimport nodemailer from \"nodemailer\";\nimport { ModuleComponents } from \"../utils/dynamic-loader\";\nimport { ArkosRequestHandler } from \".\";\n\n/**\n * Defines the initial configs of the api to be loaded at startup when arkos.init() is called.\n */\nexport type ArkosConfig = {\n /**\n * Allows to configure request configs\n */\n request?: {\n /**\n * Allows to configure request parameters\n */\n parameters?: {\n /**\n * Toggles allowing `VERY DANGEROUS` request paramateres under `req.query` for passing prisma query options.\n *\n * See more\n */\n allowDangerousPrismaQueryOptions?: boolean;\n };\n };\n /** Message you would like to send, as Json and 200 response when\n * ```curl\n * GET /api\n * ```\n *\n * ```json\n * { \"message\": \"Welcome to YourAppName\" }\n * ```\n *\n * default message is: Welcome to our Rest API generated by Arkos, find more about Arkos at www.arkosjs.com.\n *\n *\n * */\n welcomeMessage?: string;\n /**\n * Port where the application will run, can be set in 3 ways:\n *\n * 1. default is 8000\n * 2. PORT under environment variables (Lower precedence)\n * 3. this config option (Higher precedence)\n */\n port?: number | undefined;\n /**\n * Allows to listen on a different host than localhost only\n */\n host?: string;\n /**\n * Defines authentication related configurations, by default is undefined.\n *\n * See [www.arkosjs.com/docs/core-concepts/authentication-system](https://www.arkosjs.com/docs/core-concepts/authentication-system) for details.\n */\n authentication?: {\n enabled?: boolean;\n /**\n * Defines whether to use Static or Dynamic Role-Based Acess Control\n *\n * Visit [www.arkosjs.com/docs/core-concepts/authentication-system](https://www.arkosjs.com/docs/core-concepts/authentication-system) for more details.\n */\n mode: \"static\" | \"dynamic\";\n /**\n * Defines auth login related configurations to customize the api.\n */\n login?: {\n /**\n * Defines the field that will be used as username by the built-in auth system, by default arkos will look for the field \"username\" in your model User, hence when making login for example you must send:\n *\n * ```json\n * {\n * \"username\": \"johndoe\",\n * \"password\": \"somePassword123\"\n * }\n * ```\n *\n * **Note:** You can also modify the usernameField on the fly by passing it to the request query parameters. example:\n *\n * ```curl\n * POST /api/auth/login?usernameField=email\n * ```\n *\n * See more at [www.arkosjs.com/docs/core-concepts/authentication-system#login-with-different-fileds](https://www.arkosjs.com/docs/core-concepts/authentication-system#login-with-different-fileds)\n *\n * By specifing here another field for username, for example passing \"email\", \"companyCode\" or something else your json will be like:\n *\n * **Example with email**\n *\n * ```json\n * {\n * \"email\": \"john.doe@example.com\",\n * \"password\": \"somePassword123\"\n * }\n * ```\n */\n allowedUsernames?: string[];\n /** Defines wether to send the access token in response after login or only send as cookie, defeault is both.*/\n sendAccessTokenThrough?: \"cookie-only\" | \"response-only\" | \"both\";\n };\n /**\n * Specifies the regex pattern used by the authentication system to enforce password strength requirements.\n *\n * **Important**: If using validation libraries like Zod or class-validator, this will be completely overwritten.\n *\n * **Default**: ```/^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/``` - Ensures the password contains at least one uppercase letter, one lowercase letter, and one numeric digit.\n *\n * **message**: (Optional) A custom error message to display when the password does not meet the required strength criteria.\n */\n passwordValidation?: { regex: RegExp; message?: string };\n /**\n * Allows to specify the request rate limit for all authentication endpoints but `/api/users/me`.\n * \n * #### Default\n *{\n windowMs: 5000,\n limit: 10,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n }\n * \n * Passing an object not overriding all the default options will only\n * cause it to be deepmerged and not actually replace with empty fields\n * \n *@see This is are the options used on the `express-rate-limit` npm package used on epxress. read more about [https://www.npmjs.com/package/express-rate-limit](https://www.npmjs.com/package/express-rate-limit)\n */\n rateLimit?: Partial<RateLimitOptions>;\n /**\n * JWT (JSON Web Token) authentication configuration.\n *\n * You can override these values directly in code, or use environment variables:\n *\n * - `JWT_SECRET`: Secret used to sign and verify JWT tokens.\n * - `JWT_EXPIRES_IN`: Duration string or number indicating when the token should expire (e.g. \"30d\", 3600).\n * - `JWT_COOKIE_SECURE`: Whether the cookie is sent only over HTTPS. Default: `true` in production.\n * - `JWT_COOKIE_HTTP_ONLY`: Whether the cookie is HTTP-only. Default: `true`.\n * - `JWT_COOKIE_SAME_SITE`: Can be \"lax\", \"strict\", or \"none\". Defaults to \"lax\" in dev, \"none\" in prod.\n *\n *@see Values passed here take precedence over environment variables.\n */\n jwt?: {\n /** Secret key used for signing and verifying JWT tokens */\n secret?: string;\n /**\n * Duration after which the JWT token expires.\n * Accepts either a duration string (e.g. \"30d\", \"1h\") or a number in milliseconds.\n * Defaults to \"30d\" if not provided.\n */\n expiresIn?: MsDuration | number;\n /**\n * Configuration for the JWT cookie sent to the client\n */\n cookie?: {\n /**\n * Whether the cookie should be marked as secure (sent only over HTTPS).\n * Defaults to `true` in production and `false` in development.\n *\n * @env `JWT_COOKIE_SECURE`\n */\n secure?: boolean;\n /**\n * Whether the cookie should be marked as HTTP-only.\n * Default is `true` to prevent access via JavaScript.\n *\n * @env `JWT_COOKIE_HTTP_ONLY`\n */\n httpOnly?: boolean;\n /**\n * Controls the SameSite attribute of the cookie.\n * Defaults to \"none\" in production and \"lax\" in development.\n * Options: \"lax\" | \"strict\" | \"none\"\n *\n * @env `JWT_COOKIE_SAME_SITE`\n */\n sameSite?: \"lax\" | \"strict\" | \"none\";\n /**\n * Expiry date of the cookie in GMT. If not specified (undefined), creates a session cookie.\n *\n * @default `now() + authentication.jwt.expireIn | JWT_EXPIRES_IN`\n *\n * @since 1.5.11-beta\n */\n expires?: Date | undefined;\n /**\n * Domain for the cookie. Use a leading dot (e.g. `.example.com`) to include all subdomains.\n *\n * @env `JWT_COOKIE_DOMAIN`\n *\n * @since 1.5.11-beta\n */\n domain?: string | undefined;\n } & Omit<\n CookieOptions,\n \"secure\" | \"httpOnly\" | \"sameSite\" | \"expires\" | \"domain\"\n >;\n };\n };\n /** Allows to customize and toggle the built-in validation, by default it is set to `false`. If true is passed it will use validation with the default resolver set to `class-validator` if you intend to change the resolver to `zod` do the following:\n *\n *```ts\n * // src/app.ts\n * import arkos from 'arkos'\n *\n * arkos.init({\n * validation: {\n * resolver: \"zod\"\n * }\n * })\n * ```\n *\n * @See [www.arkosjs.com/docs/core-concepts/request-data-validation](https://www.arkosjs.com/docs/core-concepts/request-data-validation) for more details.\n */\n validation?: {\n /**\n * Defines whether to use strict request validation, it means in every request using `ArkosRouter()` you must pass the validation options with all options (e.g: query, params, body, etc.).\n *\n * **How It Works:**\n * - If it is true, Arkos will require all the options a stated above on the routes and if you don't pass it will throw an error.\n * **What if you don't want to pass a validator to some options?**\n * - You will need to pass `undefined` to the validator option (see example below), this way Arkos will throw an error if something is passed to `req.query` if you passed undefined as validator into `validation.query`\n *\n * ```ts\n * import { ArkosRouter } from \"arkos\"\n *\n * const router = ArkosRouter()\n *\n * router.get({\n * route: \"/api/posts\",\n * validation: {\n * query: undefined\n * }\n * })\n *\n * ```\n */\n strict?: boolean;\n } & (\n | {\n resolver: \"class-validator\";\n /**\n * ValidatorOptions to used while validating request data.\n *\n * **Default**:\n * ```ts\n * {\n * whitelist: true\n * forbidNonWhitelisted: true\n * }\n * ```\n */\n validationOptions?: ValidatorOptions;\n }\n | {\n resolver: \"zod\";\n validationOptions?: {\n /**\n * Throws an error for know whitelisted fields\n *\n * @default true\n */\n forbidNonWhitelisted?: boolean;\n };\n }\n );\n /**\n * Defines file upload configurations\n *\n * See {@link https://www.arkosjs.com/docs/guides/file-uploads/setup}\n */\n fileUpload?: {\n /**\n * Disables built-in file upload\n *\n * @since 1.5.11-beta\n */\n enabled?: boolean;\n /**\n * Defiens the base file upload directory, default is set to /uploads (on root directory)\n *\n * When setting up a path dir always now that root directory will be the starting reference.\n *\n * #### Example\n * passing `../my-arkos-uploaded-files`\n *\n * Will save uploaded files one level outside the root dir inside `my-arkos-uploaded-files`\n *\n * NB: You must be aware of permissions on your server to acess files outside your project directory.\n *\n */\n baseUploadDir?: string;\n /**\n * Changes the default `/api/uploads` base route for accessing file upload route.\n *\n * #### IMPORTANT\n * Changing this will not affect the `baseUploadDir` folder. You can\n * pass here `/api/files/my-user-files` and `baseUploadDir` be `/uploaded-files`.\n *\n */\n baseRoute?: string;\n /**\n * Defines options for `express.static(somePath, someOptions)`\n *\n * #### Default:\n *\n * ```ts\n *{\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: true,\n index: false,\n cacheControl: true,\n }\n * ```\n * \n * By passing your custom options have in mind that it\n * will be deepmerged with the default.\n * \n * Visit [https://expressjs.com/en/4x/api.html#express.static](https://expressjs.com/en/4x/api.html#express.static) for more understanding.\n * \n */\n expressStatic?: Parameters<typeof express.static>[1];\n /**\n * Defines upload restrictions for each file type: image, video, document or other.\n *\n * #### Important:\n * Passing an object without overriding everything will only cause it\n * to be deepmerged with the default options.\n *\n * See [www.arkosjs.com/docs/api-reference/default-supported-upload-files](https://www.arkosjs.com/docs/api-reference/default-supported-upload-files) for detailed explanation about default values.\n * ```\n */\n restrictions?: {\n images?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n videos?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n documents?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n files?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n };\n };\n /**\n * Defines express middlewares configurations\n */\n middlewares?: {\n /**\n * Allows to define options for npm package compression\n * Nothing is passed by default.\n *\n * See [www.npmjs.com/package/compression](https://www.npmjs.com/package/compression) for further details.\n */\n compression?: false | compression.CompressionOptions | ArkosRequestHandler;\n /**\n * Allows to specify the request rate limit for all endpoints.\n * \n * #### Default\n *```ts\n *{\n windowMs: 60 * 1000,\n limit: 1000,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n }\n ```\n * \n * Passing an object not overriding all the default options will only\n * cause it to be deepmerged and not actually replace with empty fields\n * \n * This is are the options used on the `express-rate-limit` npm package used on epxress. read more about [https://www.npmjs.com/package/express-rate-limit](https://www.npmjs.com/package/express-rate-limit)\n */\n rateLimit?: false | Partial<RateLimitOptions> | ArkosRequestHandler;\n /**\n * Configuration for CORS (Cross-Origin Resource Sharing).\n *\n * Accepts:\n * - `false` — disables CORS middleware entirely.\n * - `cors.CorsOptions` — passed directly to the `cors` middleware.\n * - `cors.CorsOptionsDelegate` — a delegate function passed directly to the `cors` middleware.\n * - `ArkosRequestHandler` — a full Express middleware that replaces the cors middleware entirely.\n * - An object with deprecated `allowedOrigins`, `options`, and `customHandler` properties.\n *\n * In development, defaults to `origin: true, credentials: true`.\n * In production, defaults to `origin: \"*\"` (equivalent to plain `cors()`).\n *\n * See https://www.npmjs.com/package/cors\n */\n cors?:\n | false\n | cors.CorsOptions\n | cors.CorsOptionsDelegate\n | {\n /**\n * Defines allowed origins to access the API.\n *\n * @deprecated Use `cors: { origin: string | string[] }` (cors.CorsOptions) directly instead.\n */\n allowedOrigins?: string | string[] | \"*\" | true;\n /**\n * Additional cors options.\n *\n * @deprecated Pass cors.CorsOptions directly instead: `cors: { origin: \"...\", credentials: true }`.\n */\n options?: cors.CorsOptions;\n /**\n * If you would like to override the entire middleware.\n *\n * @deprecated Pass the handler directly instead: `cors: myCorsHandler`.\n */\n customHandler?: cors.CorsOptionsDelegate;\n }\n | ArkosRequestHandler;\n /**\n * Defines options for the built-in express.json() middleware\n * Nothing is passed by default.\n */\n expressJson?:\n | false\n | Parameters<typeof express.json>[0]\n | ArkosRequestHandler;\n /**\n * Allows to pass paremeters to cookieParser from npm package cookie-parser\n * Nothing is passed by default.\n *\n * See [www.npmjs.com/package/cookie-parser](https://www.npmjs.com/package/cookie-parser) for further details.\n */\n cookieParser?:\n | false\n | {\n secret?: string | string[];\n options?: Parameters<typeof cookieParser>[1];\n }\n | ArkosRequestHandler /**\n * Options to define how query must be parsed.\n *\n * #### for 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 parseNumber: true,\n }\n * \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?: false | QueryParserOptions | ArkosRequestHandler;\n /**\n * Configuration for request logger middleware.\n *\n * Logs incoming HTTP requests with details such as method, URL, status code, and response time.\n * Useful for debugging and monitoring API traffic.\n */\n requestLogger?: false | ArkosRequestHandler;\n /**\n * Configuration for global error handler middleware.\n *\n * Catches and processes errors thrown in route handlers and other middlewares.\n * Provides a centralized way to format error responses and log errors.\n */\n errorHandler?: false | express.ErrorRequestHandler;\n };\n /**\n * Defines express/arkos routers configurations\n */\n routers?: {\n /**\n * Strict mode configuration for routing security\n *\n * @default false\n * - all CRUD + Auth (if using auth) endpoits are enabled and avialable by default.\n *\n * When enabled:\n * - If `true`: All CRUD endpoints start disabled and must be explicitly enabled\n * in each model's router configuration\n * - If `'no-bulk'`: Bulk operations (createMany, updateMany, deleteMany) are disabled\n * by default, while individual operations can be enabled per model\n *\n * This provides enhanced security by ensuring no routes are accidentally exposed.\n * Use this in production environments to follow the principle of least privilege.\n *\n * See documentation: https://www.arkosjs.com/docs/guide/security#strict-mode\n */\n strict?: boolean | \"no-bulk\";\n /**\n * Replace the default welcome endpoint handler\n * @param req Express request object\n * @param res Express response object\n * @param next Express next function\n */\n welcomeRoute?: false | ArkosRequestHandler;\n };\n /**\n * Allows to configure email configurations for sending emails through `emailService`\n *\n * See [www.arkosjs.com/docs/core-concepts/sending-emails](https://www.arkosjs.com/docs/core-concepts/sending-emails)\n */\n email?: {\n /**\n * Email name to used like:\n *\n * John Doe\\<john.doe@gmail.com>\n */\n name?: string;\n /**\n * Your email provider url\n */\n host: string;\n /**\n * Email provider SMTP port, Default is `465`\n */\n port?: number;\n /**\n * If smtp connection must be secure, Default is `true`\n */\n secure?: boolean;\n /**\n * Used to authenticate in your smtp server\n */\n auth: {\n /**\n * Email used for auth as well as sending emails\n */\n user: string;\n /**\n * Your SMTP password\n */\n pass: string;\n };\n } & Parameters<typeof nodemailer.createTransport>[0];\n /**\n * Defines Swagger and OpenApi specifications for auto generating swagger documentation UI using whether it is Prisma Schemas, Class-validator DTOs, Zod Schemas or JSON-Schemas.\n *\n * **Important**: Is worth mentioning that this works alongside `@scalar/express-api-reference` npm package, you define it's ApiReferenceConfiguration under ``. also consider checking the package documentation at []\n *\n * **Usage**\n *\n * ```ts\n * // src/app.ts\n *\n * import arkos from \"arkos\"\n *\n * arkos.init({\n * // other configs\n * swagger: {\n * mode: \"zod\",\n * options: {\n * defintion: {\n * info: {\n * openapi: \"3.0.0\",\n * title: \"API Generated By Arkos.js\",\n * description: \"This API was automatically generated by Arkos.js read more about at www.arkosjs.com\"\n * }\n * }\n * }\n * }\n * })\n * ```\n * @see {@link https://www.arkosjs.com/docs/core-concepts/open-api-documentation}\n */\n swagger?: {\n /**\n * By default Arkos will disable API Documentation when the project is built `npm run build`, it does not matter what node environment is set. If you want to use it even after the `arkos build` command just set this to `true`.\n * */\n enableAfterBuild?: boolean;\n /**\n * Endpoint where the Swagger UI will be available.\n *\n * @default \"/api/api-docs\"\n */\n endpoint?: string;\n /**\n * Determines how your API schemas should be generated.\n *\n * - \"prisma\": Generates schemas based on Prisma models\n * - \"class-validator\": Uses class-validator and class-transformer DTO classes\n * - \"zod\": Uses OpenAPI-compliant schemas directly\n */\n mode: \"prisma\" | \"class-validator\" | \"zod\";\n /**\n * Allows `Arkos.js` to fallback to prisma schema and use them as json schema for defining request body and response data\n * when a given zod Schema or class-validator Class is not found to be transformed to json schema.\n *\n * @default false\n */\n strict?: boolean;\n /**\n * Defines your swagger configurations\n */\n options?: {\n /**\n * Swagger definition according to OpenAPI Specification.\n */\n definition?: {\n /**\n * OpenAPI version.\n *\n * @default \"3.0.0\"\n */\n openapi?: string;\n\n /**\n * Information about your API.\n */\n info?: {\n /**\n * Title of the API documentation.\n *\n *\n * @example \"My API\"\n *\n * @default \"API Generated By Arkos.js\"\n */\n title?: string;\n\n /**\n * Version of the API.\n *\n * @example \"1.0.0\"\n */\n version?: string;\n\n /**\n * Description of the API.\n *\n * @default \"This API was automatically generated by Arkos.js read more about at www.arkosjs.com\"\n */\n description?: string;\n };\n\n /**\n * Server configurations for the API.\n *\n * @default [{ url: \"http://localhost:8000\", description: \"Development server\" }]\n *\n * This can be overridden automatically by Arkos based on CLI, .env, or `arkos.init()`.\n */\n servers?: {\n /**\n * Base URL of the server.\n *\n * @example \"http://localhost:8000\"\n */\n url: string;\n\n /**\n * Human-readable description of the server.\n *\n * @example \"Development Server\"\n */\n description?: string;\n }[];\n /**\n * Allows adding more paths for your OpenAPI documentation\n *\n * */\n paths?: OpenAPIV3.PathsObject;\n /**\n * (Optional) Additional metadata such as terms of service, contact, or license.\n *\n * See: https://swagger.io/specification/#infoObject\n */\n termsOfService?: string;\n contact?: {\n name?: string;\n url?: string;\n email?: string;\n };\n license?: {\n name: string;\n url?: string;\n };\n\n /**\n * Tags to group and describe endpoints.\n */\n tags?: {\n name: string;\n description?: string;\n }[];\n\n /**\n * Security definitions (e.g., Bearer Auth).\n */\n components?: {\n securitySchemes?: Record<string, any>;\n schemas?: Record<string, any>;\n };\n\n /**\n * Global security requirements.\n */\n security?: Array<Record<string, string[]>>;\n };\n\n /**\n * Glob patterns defining where Swagger should look for API route definitions and comments.\n *\n * @default \n * ```ts\n * [\"./src/routers/*.router.{ts,js}\", \"./src/modules/**\\/*.router.{ts,js}\"]\n ```\n *\n * Adjust depending on TypeScript or JavaScript usage.\n */\n apis?: string[];\n\n /**\n * Enables deep linking in the Swagger UI.\n *\n * @default true\n */\n deepLinking?: boolean;\n\n /**\n * Enable/disable the \"Try it out\" button globally.\n *\n * @default true\n */\n tryItOutEnabled?: boolean;\n\n /**\n * Whether to persist authorization data across page reloads.\n *\n * @default false\n */\n persistAuthorization?: boolean;\n };\n /**\n * Custom `@scalar/express-api-reference` package options.\n *\n * @see {@link https://guides.scalar.com/scalar/scalar-api-references/integrations/express}\n */\n scalarApiReferenceConfiguration?: Partial<ApiReferenceConfiguration>;\n };\n /**\n * Helps in debugging some of the variables values that are used inside arkos from dynamic loaded components towhat is used into the generated api.\n *\n */\n debugging?: {\n /**\n * Controls debugging over HTTP request level\n */\n requests?: {\n level?: 0 | 1 | 2 | 3;\n filter?: (\n | \"Query\"\n | \"Body\"\n | \"Params\"\n | \"TransformedQuery\"\n | \"ServiceArgs\"\n | \"PrismaFinalQueryArgs\"\n )[];\n };\n /**\n * Controls debugging over the dynamic loaded modules and it's components on app starting\n */\n dynamicLoader?: {\n /**\n * Adjusts logging details\n *\n * 1 - Loaded modules and list of it's components files\n * 2 - All from 1 and detailed inspection per module component\n * 3 - All from 1 and 2, plus the final router component after merged with autho generated router.\n */\n level?: 0 | 1 | 2 | 3;\n filters?: {\n /**\n * Allows filtering by specific modules.\n *\n * Supports only searching for the starting parts of the module name, e.g: If there is`user-profile`, `user`, `posts`, passing `[\"user\"]` will match both `user-profile` and `user`.\n */\n modules?: string[];\n /**\n * Allows filtering by component's names\n */\n components?: keyof ModuleComponents[];\n };\n };\n };\n /**\n * Allows to suppress specific warnings emitted by Arkos at startup or runtime.\n */\n warnings?: {\n /**\n * Suppresses specific warning messages.\n */\n suppress?: {\n /**\n * Suppresses Prisma-related warnings.\n */\n prisma?: {\n /**\n * Suppresses the warning emitted when no Prisma instance is found.\n */\n noInstanceFound?: boolean;\n /**\n * Suppresses the warning emitted when no Prisma schema is found.\n */\n noSchemaFound?: boolean;\n };\n };\n };\n};\n"]}
1
+ {"version":3,"file":"new-arkos-config.js","sourceRoot":"","sources":["../../../src/types/new-arkos-config.ts"],"names":[],"mappings":"","sourcesContent":["import cors from \"cors\";\nimport express, { CookieOptions } from \"express\";\nimport { Options as RateLimitOptions } from \"express-rate-limit\";\nimport cookieParser from \"cookie-parser\";\nimport compression from \"compression\";\nimport { Options as QueryParserOptions } from \"../utils/helpers/query-parser.helpers\";\nimport { ValidatorOptions } from \"class-validator\";\nimport { MsDuration } from \"../modules/auth/utils/helpers/auth.controller.helpers\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport type { ApiReferenceConfiguration } from \"@scalar/express-api-reference\" with { \"resolution-mode\": \"import\" };\nimport nodemailer from \"nodemailer\";\nimport { ModuleComponents } from \"../utils/dynamic-loader\";\nimport { ArkosRequestHandler } from \".\";\n\n/**\n * Defines the initial configs of the api to be loaded at startup when arkos.init() is called.\n */\nexport type ArkosConfig = {\n /**\n * Allows to configure request configs\n */\n request?: {\n /**\n * Allows to configure request parameters\n */\n parameters?: {\n /**\n * Toggles allowing `VERY DANGEROUS` request paramateres under `req.query` for passing prisma query options.\n *\n * See more\n */\n allowDangerousPrismaQueryOptions?: boolean;\n };\n };\n /** Message you would like to send, as Json and 200 response when\n * ```curl\n * GET /api\n * ```\n *\n * ```json\n * { \"message\": \"Welcome to YourAppName\" }\n * ```\n *\n * default message is: Welcome to our Rest API generated by Arkos, find more about Arkos at www.arkosjs.com.\n *\n *\n * */\n welcomeMessage?: string;\n /**\n * Port where the application will run, can be set in 3 ways:\n *\n * 1. default is 8000\n * 2. PORT under environment variables (Lower precedence)\n * 3. this config option (Higher precedence)\n */\n port?: number | undefined;\n /**\n * Allows to listen on a different host than localhost only\n */\n host?: string;\n /**\n * Defines authentication related configurations, by default is undefined.\n *\n * See [www.arkosjs.com/docs/core-concepts/authentication-system](https://www.arkosjs.com/docs/core-concepts/authentication-system) for details.\n */\n authentication?: {\n enabled?: boolean;\n /**\n * Defines whether to use Static or Dynamic Role-Based Acess Control\n *\n * Visit [www.arkosjs.com/docs/core-concepts/authentication-system](https://www.arkosjs.com/docs/core-concepts/authentication-system) for more details.\n */\n mode: \"static\" | \"dynamic\";\n /**\n * Defines auth login related configurations to customize the api.\n */\n login?: {\n /**\n * Defines the field that will be used as username by the built-in auth system, by default arkos will look for the field \"username\" in your model User, hence when making login for example you must send:\n *\n * ```json\n * {\n * \"username\": \"johndoe\",\n * \"password\": \"somePassword123\"\n * }\n * ```\n *\n * **Note:** You can also modify the usernameField on the fly by passing it to the request query parameters. example:\n *\n * ```curl\n * POST /api/auth/login?usernameField=email\n * ```\n *\n * See more at [www.arkosjs.com/docs/core-concepts/authentication-system#login-with-different-fileds](https://www.arkosjs.com/docs/core-concepts/authentication-system#login-with-different-fileds)\n *\n * By specifing here another field for username, for example passing \"email\", \"companyCode\" or something else your json will be like:\n *\n * **Example with email**\n *\n * ```json\n * {\n * \"email\": \"john.doe@example.com\",\n * \"password\": \"somePassword123\"\n * }\n * ```\n */\n allowedUsernames?: string[];\n /** Defines wether to send the access token in response after login or only send as cookie, defeault is both.*/\n sendAccessTokenThrough?: \"cookie-only\" | \"response-only\" | \"both\";\n };\n /**\n * Specifies the regex pattern used by the authentication system to enforce password strength requirements.\n *\n * **Important**: If using validation libraries like Zod or class-validator, this will be completely overwritten.\n *\n * **Default**: ```/^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).+$/``` - Ensures the password contains at least one uppercase letter, one lowercase letter, and one numeric digit.\n *\n * **message**: (Optional) A custom error message to display when the password does not meet the required strength criteria.\n */\n passwordValidation?: { regex: RegExp; message?: string };\n /**\n * Allows to specify the request rate limit for all authentication endpoints but `/api/users/me`.\n * \n * #### Default\n *{\n windowMs: 5000,\n limit: 10,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n }\n * \n * Passing an object not overriding all the default options will only\n * cause it to be deepmerged and not actually replace with empty fields\n * \n *@see This is are the options used on the `express-rate-limit` npm package used on epxress. read more about [https://www.npmjs.com/package/express-rate-limit](https://www.npmjs.com/package/express-rate-limit)\n */\n rateLimit?: Partial<RateLimitOptions>;\n /**\n * JWT (JSON Web Token) authentication configuration.\n *\n * You can override these values directly in code, or use environment variables:\n *\n * - `JWT_SECRET`: Secret used to sign and verify JWT tokens.\n * - `JWT_EXPIRES_IN`: Duration string or number indicating when the token should expire (e.g. \"30d\", 3600).\n * - `JWT_COOKIE_SECURE`: Whether the cookie is sent only over HTTPS. Default: `true` in production.\n * - `JWT_COOKIE_HTTP_ONLY`: Whether the cookie is HTTP-only. Default: `true`.\n * - `JWT_COOKIE_SAME_SITE`: Can be \"lax\", \"strict\", or \"none\". Defaults to \"lax\" in dev, \"none\" in prod.\n *\n *@see Values passed here take precedence over environment variables.\n */\n jwt?: {\n /** Secret key used for signing and verifying JWT tokens */\n secret?: string;\n /**\n * Duration after which the JWT token expires.\n * Accepts either a duration string (e.g. \"30d\", \"1h\") or a number in milliseconds.\n * Defaults to \"30d\" if not provided.\n */\n expiresIn?: MsDuration | number;\n /**\n * Configuration for the JWT cookie sent to the client\n */\n cookie?: {\n /**\n * Whether the cookie should be marked as secure (sent only over HTTPS).\n * Defaults to `true` in production and `false` in development.\n *\n * @env `JWT_COOKIE_SECURE`\n */\n secure?: boolean;\n /**\n * Whether the cookie should be marked as HTTP-only.\n * Default is `true` to prevent access via JavaScript.\n *\n * @env `JWT_COOKIE_HTTP_ONLY`\n */\n httpOnly?: boolean;\n /**\n * Controls the SameSite attribute of the cookie.\n * Defaults to \"none\" in production and \"lax\" in development.\n * Options: \"lax\" | \"strict\" | \"none\"\n *\n * @env `JWT_COOKIE_SAME_SITE`\n */\n sameSite?: \"lax\" | \"strict\" | \"none\";\n /**\n * Expiry date of the cookie in GMT. If not specified (undefined), creates a session cookie.\n *\n * @default `now() + authentication.jwt.expireIn | JWT_EXPIRES_IN`\n *\n * @since 1.5.11-beta\n */\n expires?: Date | undefined;\n /**\n * Domain for the cookie. Use a leading dot (e.g. `.example.com`) to include all subdomains.\n *\n * @env `JWT_COOKIE_DOMAIN`\n *\n * @since 1.5.11-beta\n */\n domain?: string | undefined;\n } & Omit<\n CookieOptions,\n \"secure\" | \"httpOnly\" | \"sameSite\" | \"expires\" | \"domain\"\n >;\n };\n };\n /** Allows to customize and toggle the built-in validation, by default it is set to `false`. If true is passed it will use validation with the default resolver set to `class-validator` if you intend to change the resolver to `zod` do the following:\n *\n *```ts\n * // src/app.ts\n * import arkos from 'arkos'\n *\n * arkos.init({\n * validation: {\n * resolver: \"zod\"\n * }\n * })\n * ```\n *\n * @See [www.arkosjs.com/docs/core-concepts/request-data-validation](https://www.arkosjs.com/docs/core-concepts/request-data-validation) for more details.\n */\n validation?: {\n /**\n * Defines whether to use strict request validation, it means in every request using `ArkosRouter()` you must pass the validation options with all options (e.g: query, params, body, etc.).\n *\n * **How It Works:**\n * - If it is true, Arkos will require all the options a stated above on the routes and if you don't pass it will throw an error.\n * **What if you don't want to pass a validator to some options?**\n * - You will need to pass `undefined` to the validator option (see example below), this way Arkos will throw an error if something is passed to `req.query` if you passed undefined as validator into `validation.query`\n *\n * ```ts\n * import { ArkosRouter } from \"arkos\"\n *\n * const router = ArkosRouter()\n *\n * router.get({\n * route: \"/api/posts\",\n * validation: {\n * query: undefined\n * }\n * })\n *\n * ```\n */\n strict?: boolean;\n } & (\n | {\n resolver: \"class-validator\";\n /**\n * ValidatorOptions to used while validating request data.\n *\n * **Default**:\n * ```ts\n * {\n * whitelist: true\n * forbidNonWhitelisted: true\n * }\n * ```\n */\n validationOptions?: ValidatorOptions;\n }\n | {\n resolver: \"zod\";\n validationOptions?: {\n /**\n * Throws an error for know whitelisted fields\n *\n * @default true\n */\n forbidNonWhitelisted?: boolean;\n };\n }\n );\n /**\n * Defines file upload configurations\n *\n * See {@link https://www.arkosjs.com/docs/guides/file-uploads/setup}\n */\n fileUpload?: {\n /**\n * Disables built-in file upload\n *\n * @since 1.5.11-beta\n */\n enabled?: boolean;\n /**\n * Defiens the base file upload directory, default is set to /uploads (on root directory)\n *\n * When setting up a path dir always now that root directory will be the starting reference.\n *\n * #### Example\n * passing `../my-arkos-uploaded-files`\n *\n * Will save uploaded files one level outside the root dir inside `my-arkos-uploaded-files`\n *\n * NB: You must be aware of permissions on your server to acess files outside your project directory.\n *\n */\n baseUploadDir?: string;\n /**\n * Changes the default `/api/uploads` base route for accessing file upload route.\n *\n * #### IMPORTANT\n * Changing this will not affect the `baseUploadDir` folder. You can\n * pass here `/api/files/my-user-files` and `baseUploadDir` be `/uploaded-files`.\n *\n */\n baseRoute?: string;\n /**\n * Defines options for `express.static(somePath, someOptions)`\n *\n * #### Default:\n *\n * ```ts\n *{\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: false,\n index: false,\n cacheControl: true,\n }\n * ```\n * \n * By passing your custom options have in mind that it\n * will be deepmerged with the default.\n * \n * Visit [https://expressjs.com/en/4x/api.html#express.static](https://expressjs.com/en/4x/api.html#express.static) for more understanding.\n * \n */\n expressStatic?: Parameters<typeof express.static>[1];\n /**\n * Defines upload restrictions for each file type: image, video, document or other.\n *\n * #### Important:\n * Passing an object without overriding everything will only cause it\n * to be deepmerged with the default options.\n *\n * See [www.arkosjs.com/docs/api-reference/default-supported-upload-files](https://www.arkosjs.com/docs/api-reference/default-supported-upload-files) for detailed explanation about default values.\n * ```\n */\n restrictions?: {\n images?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n videos?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n documents?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n files?: {\n maxCount?: number;\n maxSize?: number;\n supportedFilesRegex?: RegExp;\n };\n };\n };\n /**\n * Defines express middlewares configurations\n */\n middlewares?: {\n /**\n * Allows to define options for npm package compression\n * Nothing is passed by default.\n *\n * See [www.npmjs.com/package/compression](https://www.npmjs.com/package/compression) for further details.\n */\n compression?: false | compression.CompressionOptions | ArkosRequestHandler;\n /**\n * Allows to specify the request rate limit for all endpoints.\n * \n * #### Default\n *```ts\n *{\n windowMs: 60 * 1000,\n limit: 1000,\n standardHeaders: \"draft-7\",\n legacyHeaders: false,\n }\n ```\n * \n * Passing an object not overriding all the default options will only\n * cause it to be deepmerged and not actually replace with empty fields\n * \n * This is are the options used on the `express-rate-limit` npm package used on epxress. read more about [https://www.npmjs.com/package/express-rate-limit](https://www.npmjs.com/package/express-rate-limit)\n */\n rateLimit?: false | Partial<RateLimitOptions> | ArkosRequestHandler;\n /**\n * Configuration for CORS (Cross-Origin Resource Sharing).\n *\n * Accepts:\n * - `false` — disables CORS middleware entirely.\n * - `cors.CorsOptions` — passed directly to the `cors` middleware.\n * - `cors.CorsOptionsDelegate` — a delegate function passed directly to the `cors` middleware.\n * - `ArkosRequestHandler` — a full Express middleware that replaces the cors middleware entirely.\n * - An object with deprecated `allowedOrigins`, `options`, and `customHandler` properties.\n *\n * In development, defaults to `origin: true, credentials: true`.\n * In production, defaults to `origin: \"*\"` (equivalent to plain `cors()`).\n *\n * See https://www.npmjs.com/package/cors\n */\n cors?:\n | false\n | cors.CorsOptions\n | cors.CorsOptionsDelegate\n | {\n /**\n * Defines allowed origins to access the API.\n *\n * @deprecated Use `cors: { origin: string | string[] }` (cors.CorsOptions) directly instead.\n */\n allowedOrigins?: string | string[] | \"*\" | true;\n /**\n * Additional cors options.\n *\n * @deprecated Pass cors.CorsOptions directly instead: `cors: { origin: \"...\", credentials: true }`.\n */\n options?: cors.CorsOptions;\n /**\n * If you would like to override the entire middleware.\n *\n * @deprecated Pass the handler directly instead: `cors: myCorsHandler`.\n */\n customHandler?: cors.CorsOptionsDelegate;\n }\n | ArkosRequestHandler;\n /**\n * Defines options for the built-in express.json() middleware\n * Nothing is passed by default.\n */\n expressJson?:\n | false\n | Parameters<typeof express.json>[0]\n | ArkosRequestHandler;\n /**\n * Allows to pass paremeters to cookieParser from npm package cookie-parser\n * Nothing is passed by default.\n *\n * See [www.npmjs.com/package/cookie-parser](https://www.npmjs.com/package/cookie-parser) for further details.\n */\n cookieParser?:\n | false\n | {\n secret?: string | string[];\n options?: Parameters<typeof cookieParser>[1];\n }\n | ArkosRequestHandler /**\n * Options to define how query must be parsed.\n *\n * #### for 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 parseNumber: true,\n }\n * \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?: false | QueryParserOptions | ArkosRequestHandler;\n /**\n * Configuration for request logger middleware.\n *\n * Logs incoming HTTP requests with details such as method, URL, status code, and response time.\n * Useful for debugging and monitoring API traffic.\n */\n requestLogger?: false | ArkosRequestHandler;\n /**\n * Configuration for global error handler middleware.\n *\n * Catches and processes errors thrown in route handlers and other middlewares.\n * Provides a centralized way to format error responses and log errors.\n */\n errorHandler?: false | express.ErrorRequestHandler;\n };\n /**\n * Defines express/arkos routers configurations\n */\n routers?: {\n /**\n * Strict mode configuration for routing security\n *\n * @default false\n * - all CRUD + Auth (if using auth) endpoits are enabled and avialable by default.\n *\n * When enabled:\n * - If `true`: All CRUD endpoints start disabled and must be explicitly enabled\n * in each model's router configuration\n * - If `'no-bulk'`: Bulk operations (createMany, updateMany, deleteMany) are disabled\n * by default, while individual operations can be enabled per model\n *\n * This provides enhanced security by ensuring no routes are accidentally exposed.\n * Use this in production environments to follow the principle of least privilege.\n *\n * See documentation: https://www.arkosjs.com/docs/guide/security#strict-mode\n */\n strict?: boolean | \"no-bulk\";\n /**\n * Replace the default welcome endpoint handler\n * @param req Express request object\n * @param res Express response object\n * @param next Express next function\n */\n welcomeRoute?: false | ArkosRequestHandler;\n };\n /**\n * Allows to configure email configurations for sending emails through `emailService`\n *\n * See [www.arkosjs.com/docs/core-concepts/sending-emails](https://www.arkosjs.com/docs/guides/email-service)\n */\n email?: {\n /**\n * Email name to used like:\n *\n * John Doe\\<john.doe@gmail.com>\n */\n name?: string;\n /**\n * Your email provider url\n */\n host: string;\n /**\n * Email provider SMTP port, Default is `465`\n */\n port?: number;\n /**\n * If smtp connection must be secure, Default is `true`\n */\n secure?: boolean;\n /**\n * Used to authenticate in your smtp server\n */\n auth: {\n /**\n * Email used for auth as well as sending emails\n */\n user: string;\n /**\n * Your SMTP password\n */\n pass: string;\n };\n } & Parameters<typeof nodemailer.createTransport>[0];\n /**\n * Defines Swagger and OpenApi specifications for auto generating swagger documentation UI using whether it is Prisma Schemas, Class-validator DTOs, Zod Schemas or JSON-Schemas.\n *\n * **Important**: Is worth mentioning that this works alongside `@scalar/express-api-reference` npm package, you define it's ApiReferenceConfiguration under ``. also consider checking the package documentation at []\n *\n * **Usage**\n *\n * ```ts\n * // src/app.ts\n *\n * import arkos from \"arkos\"\n *\n * arkos.init({\n * // other configs\n * swagger: {\n * mode: \"zod\",\n * options: {\n * defintion: {\n * info: {\n * openapi: \"3.0.0\",\n * title: \"API Generated By Arkos.js\",\n * description: \"This API was automatically generated by Arkos.js read more about at www.arkosjs.com\"\n * }\n * }\n * }\n * }\n * })\n * ```\n * @see {@link https://www.arkosjs.com/docs/core-concepts/open-api-documentation}\n */\n swagger?: {\n /**\n * By default Arkos will disable API Documentation when the project is built `npm run build`, it does not matter what node environment is set. If you want to use it even after the `arkos build` command just set this to `true`.\n * */\n enableAfterBuild?: boolean;\n /**\n * Endpoint where the Swagger UI will be available.\n *\n * @default \"/api/api-docs\"\n */\n endpoint?: string;\n /**\n * Determines how your API schemas should be generated.\n *\n * - \"prisma\": Generates schemas based on Prisma models\n * - \"class-validator\": Uses class-validator and class-transformer DTO classes\n * - \"zod\": Uses OpenAPI-compliant schemas directly\n */\n mode: \"prisma\" | \"class-validator\" | \"zod\";\n /**\n * Allows `Arkos.js` to fallback to prisma schema and use them as json schema for defining request body and response data\n * when a given zod Schema or class-validator Class is not found to be transformed to json schema.\n *\n * @default false\n */\n strict?: boolean;\n /**\n * Defines your swagger configurations\n */\n options?: {\n /**\n * Swagger definition according to OpenAPI Specification.\n */\n definition?: {\n /**\n * OpenAPI version.\n *\n * @default \"3.0.0\"\n */\n openapi?: string;\n\n /**\n * Information about your API.\n */\n info?: {\n /**\n * Title of the API documentation.\n *\n *\n * @example \"My API\"\n *\n * @default \"API Generated By Arkos.js\"\n */\n title?: string;\n\n /**\n * Version of the API.\n *\n * @example \"1.0.0\"\n */\n version?: string;\n\n /**\n * Description of the API.\n *\n * @default \"This API was automatically generated by Arkos.js read more about at www.arkosjs.com\"\n */\n description?: string;\n };\n\n /**\n * Server configurations for the API.\n *\n * @default [{ url: \"http://localhost:8000\", description: \"Development server\" }]\n *\n * This can be overridden automatically by Arkos based on CLI, .env, or `arkos.init()`.\n */\n servers?: {\n /**\n * Base URL of the server.\n *\n * @example \"http://localhost:8000\"\n */\n url: string;\n\n /**\n * Human-readable description of the server.\n *\n * @example \"Development Server\"\n */\n description?: string;\n }[];\n /**\n * Allows adding more paths for your OpenAPI documentation\n *\n * */\n paths?: OpenAPIV3.PathsObject;\n /**\n * (Optional) Additional metadata such as terms of service, contact, or license.\n *\n * See: https://swagger.io/specification/#infoObject\n */\n termsOfService?: string;\n contact?: {\n name?: string;\n url?: string;\n email?: string;\n };\n license?: {\n name: string;\n url?: string;\n };\n\n /**\n * Tags to group and describe endpoints.\n */\n tags?: {\n name: string;\n description?: string;\n }[];\n\n /**\n * Security definitions (e.g., Bearer Auth).\n */\n components?: {\n securitySchemes?: Record<string, any>;\n schemas?: Record<string, any>;\n };\n\n /**\n * Global security requirements.\n */\n security?: Array<Record<string, string[]>>;\n };\n\n /**\n * Glob patterns defining where Swagger should look for API route definitions and comments.\n *\n * @default \n * ```ts\n * [\"./src/routers/*.router.{ts,js}\", \"./src/modules/**\\/*.router.{ts,js}\"]\n ```\n *\n * Adjust depending on TypeScript or JavaScript usage.\n */\n apis?: string[];\n\n /**\n * Enables deep linking in the Swagger UI.\n *\n * @default true\n */\n deepLinking?: boolean;\n\n /**\n * Enable/disable the \"Try it out\" button globally.\n *\n * @default true\n */\n tryItOutEnabled?: boolean;\n\n /**\n * Whether to persist authorization data across page reloads.\n *\n * @default false\n */\n persistAuthorization?: boolean;\n };\n /**\n * Custom `@scalar/express-api-reference` package options.\n *\n * @see {@link https://guides.scalar.com/scalar/scalar-api-references/integrations/express}\n */\n scalarApiReferenceConfiguration?: Partial<ApiReferenceConfiguration>;\n };\n /**\n * Helps in debugging some of the variables values that are used inside arkos from dynamic loaded components towhat is used into the generated api.\n *\n */\n debugging?: {\n /**\n * Controls debugging over HTTP request level\n */\n requests?: {\n level?: 0 | 1 | 2 | 3;\n filter?: (\n | \"Query\"\n | \"Body\"\n | \"Params\"\n | \"TransformedQuery\"\n | \"ServiceArgs\"\n | \"PrismaFinalQueryArgs\"\n )[];\n };\n /**\n * Controls debugging over the dynamic loaded modules and it's components on app starting\n */\n dynamicLoader?: {\n /**\n * Adjusts logging details\n *\n * 1 - Loaded modules and list of it's components files\n * 2 - All from 1 and detailed inspection per module component\n * 3 - All from 1 and 2, plus the final router component after merged with autho generated router.\n */\n level?: 0 | 1 | 2 | 3;\n filters?: {\n /**\n * Allows filtering by specific modules.\n *\n * Supports only searching for the starting parts of the module name, e.g: If there is`user-profile`, `user`, `posts`, passing `[\"user\"]` will match both `user-profile` and `user`.\n */\n modules?: string[];\n /**\n * Allows filtering by component's names\n */\n components?: keyof ModuleComponents[];\n };\n };\n };\n /**\n * Allows to suppress specific warnings emitted by Arkos at startup or runtime.\n */\n warnings?: {\n /**\n * Suppresses specific warning messages.\n */\n suppress?: {\n /**\n * Suppresses Prisma-related warnings.\n */\n prisma?: {\n /**\n * Suppresses the warning emitted when no Prisma instance is found.\n */\n noInstanceFound?: boolean;\n /**\n * Suppresses the warning emitted when no Prisma schema is found.\n */\n noSchemaFound?: boolean;\n };\n };\n };\n};\n"]}
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=arkos-prisma-input.bak.js.map
3
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../src/types/upload.ts"],"names":[],"mappings":"","sourcesContent":["export interface ArkosFile extends Express.Multer.File {\n /**\n * The file pathname without the server host\n */\n pathname?: string;\n /**\n * The file full URL\n */\n url?: string;\n}\n"]}
@@ -15,9 +15,7 @@ class ArkosRouterOpenAPIManager {
15
15
  uploadSchema.properties[uploadConfig.field] = {
16
16
  type: "string",
17
17
  format: "binary",
18
- ...(uploadConfig.maxSize && {
19
- description: `Max size: ${uploadConfig.maxSize} bytes`,
20
- }),
18
+ description: `Single file field${uploadConfig.maxSize ? `, max size: ${uploadConfig.maxSize} bytes` : ""}`,
21
19
  };
22
20
  if (uploadConfig.required !== false) {
23
21
  uploadSchema.required.push(uploadConfig.field);
@@ -31,9 +29,7 @@ class ArkosRouterOpenAPIManager {
31
29
  format: "binary",
32
30
  },
33
31
  ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),
34
- ...(uploadConfig.maxSize && {
35
- description: `Max size per file: ${uploadConfig.maxSize} bytes`,
36
- }),
32
+ description: `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : ""}`,
37
33
  };
38
34
  if (uploadConfig.required !== false) {
39
35
  uploadSchema.required.push(uploadConfig.field);
@@ -48,9 +44,7 @@ class ArkosRouterOpenAPIManager {
48
44
  format: "binary",
49
45
  },
50
46
  ...(field.maxCount && { maxItems: field.maxCount }),
51
- ...(uploadConfig.maxSize && {
52
- description: `Max size per file: ${uploadConfig.maxSize} bytes`,
53
- }),
47
+ description: `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : ""}`,
54
48
  };
55
49
  if (uploadConfig.required !== false) {
56
50
  uploadSchema.required.push(field.name);
@@ -1 +1 @@
1
- {"version":3,"file":"arkos-router-openapi-manager.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/arkos-router-openapi-manager.ts"],"names":[],"mappings":";;;;;AACA,mFAAoD;AAGpD,MAAM,yBAAyB;IAsB7B,eAAe,CACb,YAA0B,EAC1B,iBAAyC,EAAE;QAE3C,MAAM,YAAY,GAAQ;YACxB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG;gBAC5C,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,QAAQ;gBAChB,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI;oBAC1B,WAAW,EAAE,aAAa,YAAY,CAAC,OAAO,QAAQ;iBACvD,CAAC;aACH,CAAC;YACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG;gBAC5C,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;iBACjB;gBACD,GAAG,CAAC,YAAY,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC;gBACjE,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI;oBAC1B,WAAW,EAAE,sBAAsB,YAAY,CAAC,OAAO,QAAQ;iBAChE,CAAC;aACH,CAAC;YACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1C,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;oBACpC,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,QAAQ;qBACjB;oBACD,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnD,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI;wBAC1B,WAAW,EAAE,sBAAsB,YAAY,CAAC,OAAO,QAAQ;qBAChE,CAAC;iBACH,CAAC;gBACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;oBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;QAGD,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;QAErE,OAAO,IAAA,0BAAS,EAAC,cAAqB,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;IAkBD,yBAAyB,CACvB,0BAA+B,EAC/B,SAAiB,EACjB,YAA2B;QAE3B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,0BAA0B,EAAE,UAAU,IAAI,EAAE,CAAC;QAChE,MAAM,cAAc,GAAG,0BAA0B,EAAE,QAAQ,IAAI,EAAE,CAAC;QAElE,MAAM,cAAc,GAIf,EAAE,CAAC;QAER,IAAI,YAAY,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;gBACzC,YAAY,EAAE,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1C,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;gBACzC,YAAY,EAAE,OAAO;aACtB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3C,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxC,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;oBACzC,YAAY,EAAE,OAAO;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,cAAc,EAAE,CAAC;YAC9D,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAErC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CACT,yBAAyB,IAAI,iCAAiC,CAC/D,CAAC;gBACF,SAAS;YACX,CAAC;YAED,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,WAAW,CAAC,IAAI,KAAK,QAAQ;oBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,mCAAmC,WAAW,CAAC,IAAI,GAAG,CAC5E,CAAC;gBAEJ,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ;oBACjC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,qCAAqC,WAAW,CAAC,MAAM,IAAI,WAAW,GAAG,CAC/F,CAAC;YACN,CAAC;iBAAM,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;gBACpC,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,kCAAkC,WAAW,CAAC,IAAI,GAAG,CAC3E,CAAC;gBACJ,CAAC;qBAAM,IACL,CAAC,WAAW,CAAC,KAAK;oBAClB,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACnC,WAAW,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAErC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,0DAA0D,CAChF,CAAC;YACN,CAAC;YAED,MAAM,gBAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvD,IAAI,QAAQ,IAAI,CAAC,gBAAgB;gBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,8DAA8D,CACpF,CAAC;YAEJ,IAAI,CAAC,QAAQ,IAAI,gBAAgB;gBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,8DAA8D,CACpF,CAAC;QACN,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,kEAAkE,SAAS,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7H,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED,MAAM,yBAAyB,GAAG,IAAI,yBAAyB,EAAE,CAAC;AAElE,kBAAe,yBAAyB,CAAC","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport { UploadConfig } from \"./types/upload-config\";\n\nclass ArkosRouterOpenAPIManager {\n /**\n * Generates OpenAPI schema for file upload fields in multipart/form-data requests.\n * Converts upload configuration into OpenAPI-compliant schema and merges with existing body schema.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {any} existingSchema - Existing JSON schema from config.validation.body (optional)\n * @returns {{ schema: any }} OpenAPI schema object for multipart/form-data content type\n *\n * @example\n * // Single file upload\n * addUploadFields({ type: 'single', field: 'avatar', maxSize: 5242880 })\n * // Returns: { schema: { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } } }\n *\n * @example\n * // Array file upload\n * addUploadFields({ type: 'array', field: 'gallery', maxCount: 10 })\n *\n * @example\n * // Multiple fields upload\n * addUploadFields({ type: 'fields', fields: [{ name: 'avatar', maxCount: 1 }, { name: 'resume', maxCount: 1 }] })\n */\n addUploadFields(\n uploadConfig: UploadConfig,\n existingSchema: OpenAPIV3.SchemaObject = {}\n ): OpenAPIV3.SchemaObject {\n const uploadSchema: any = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n if (uploadConfig.type === \"single\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"string\",\n format: \"binary\",\n ...(uploadConfig.maxSize && {\n description: `Max size: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"array\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),\n ...(uploadConfig.maxSize && {\n description: `Max size per file: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n uploadSchema.properties[field.name] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(field.maxCount && { maxItems: field.maxCount }),\n ...(uploadConfig.maxSize && {\n description: `Max size per file: ${uploadConfig.maxSize} bytes`,\n }),\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(field.name);\n }\n }\n }\n\n // Clean up empty required array\n if (uploadSchema.required.length === 0) delete uploadSchema.required;\n\n return deepmerge(existingSchema as any, uploadSchema);\n }\n\n /**\n * Validates that a user-defined multipart/form-data schema includes all required upload fields\n * with correct types, formats, and required flags.\n *\n * @param {any} userDefinedMultipartSchema - The schema object from openapi.requestBody.content['multipart/form-data'].schema\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {string} routePath - The route path for error context\n * @throws {Error} If upload fields are missing or incorrectly defined\n *\n * @example\n * validateMultipartFormDocs(\n * { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } },\n * { type: 'single', field: 'avatar', required: true },\n * '/users/:id/avatar'\n * )\n */\n validateMultipartFormDocs(\n userDefinedMultipartSchema: any,\n routePath: string,\n uploadConfig?: UploadConfig\n ): void {\n const errors: string[] = [];\n const properties = userDefinedMultipartSchema?.properties || {};\n const requiredFields = userDefinedMultipartSchema?.required || [];\n\n const expectedFields: Array<{\n name: string;\n required: boolean;\n expectedType: \"single\" | \"array\";\n }> = [];\n\n if (uploadConfig?.type === \"single\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"single\",\n });\n } else if (uploadConfig?.type === \"array\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n } else if (uploadConfig?.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n expectedFields.push({\n name: field.name,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n }\n }\n\n for (const { name, required, expectedType } of expectedFields) {\n const fieldSchema = properties[name];\n\n if (!fieldSchema) {\n errors.push(\n `Missing upload field '${name}' in multipart/form-data schema`\n );\n continue;\n }\n\n if (expectedType === \"single\") {\n if (fieldSchema.type !== \"string\")\n errors.push(\n `Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`\n );\n\n if (fieldSchema.format !== \"binary\")\n errors.push(\n `Upload field '${name}' must have format 'binary', got '${fieldSchema.format || \"undefined\"}'`\n );\n } else if (expectedType === \"array\") {\n if (fieldSchema.type !== \"array\") {\n errors.push(\n `Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`\n );\n } else if (\n !fieldSchema.items ||\n fieldSchema.items.type !== \"string\" ||\n fieldSchema.items.format !== \"binary\"\n )\n errors.push(\n `Upload field '${name}' must have items with type 'string' and format 'binary'`\n );\n }\n\n const isMarkedRequired = requiredFields.includes(name);\n if (required && !isMarkedRequired)\n errors.push(\n `Upload field '${name}' is required in config but not marked as required in schema`\n );\n\n if (!required && isMarkedRequired)\n errors.push(\n `Upload field '${name}' is not required in config but marked as required in schema`\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `ValidationError: Invalid multipart/form-data schema for route '${routePath}':\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`\n );\n }\n }\n}\n\nconst arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();\n\nexport default arkosRouterOpenApiManager;\n"]}
1
+ {"version":3,"file":"arkos-router-openapi-manager.js","sourceRoot":"","sources":["../../../../src/utils/arkos-router/arkos-router-openapi-manager.ts"],"names":[],"mappings":";;;;;AACA,mFAAoD;AAGpD,MAAM,yBAAyB;IAsB7B,eAAe,CACb,YAA0B,EAC1B,iBAAyC,EAAE;QAE3C,MAAM,YAAY,GAAQ;YACxB,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb,CAAC;QAEF,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACnC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG;gBAC5C,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,QAAQ;gBAChB,WAAW,EAAE,oBAAoB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;aAC3G,CAAC;YACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzC,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG;gBAC5C,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,QAAQ;iBACjB;gBACD,GAAG,CAAC,YAAY,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,YAAY,CAAC,QAAQ,EAAE,CAAC;gBACjE,WAAW,EAAE,mBAAmB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;aACnH,CAAC;YACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC1C,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxC,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG;oBACpC,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE;wBACL,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,QAAQ;qBACjB;oBACD,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnD,WAAW,EAAE,mBAAmB,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE;iBACnH,CAAC;gBACF,IAAI,YAAY,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;oBACpC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;QACH,CAAC;QAGD,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,YAAY,CAAC,QAAQ,CAAC;QAErE,OAAO,IAAA,0BAAS,EAAC,cAAqB,EAAE,YAAY,CAAC,CAAC;IACxD,CAAC;IAkBD,yBAAyB,CACvB,0BAA+B,EAC/B,SAAiB,EACjB,YAA2B;QAE3B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,0BAA0B,EAAE,UAAU,IAAI,EAAE,CAAC;QAChE,MAAM,cAAc,GAAG,0BAA0B,EAAE,QAAQ,IAAI,EAAE,CAAC;QAElE,MAAM,cAAc,GAIf,EAAE,CAAC;QAER,IAAI,YAAY,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;gBACzC,YAAY,EAAE,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;YAC1C,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,YAAY,CAAC,KAAK;gBACxB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;gBACzC,YAAY,EAAE,OAAO;aACtB,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3C,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;gBACxC,cAAc,CAAC,IAAI,CAAC;oBAClB,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,QAAQ,EAAE,YAAY,CAAC,QAAQ,KAAK,KAAK;oBACzC,YAAY,EAAE,OAAO;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,cAAc,EAAE,CAAC;YAC9D,MAAM,WAAW,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAErC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CACT,yBAAyB,IAAI,iCAAiC,CAC/D,CAAC;gBACF,SAAS;YACX,CAAC;YAED,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;gBAC9B,IAAI,WAAW,CAAC,IAAI,KAAK,QAAQ;oBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,mCAAmC,WAAW,CAAC,IAAI,GAAG,CAC5E,CAAC;gBAEJ,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ;oBACjC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,qCAAqC,WAAW,CAAC,MAAM,IAAI,WAAW,GAAG,CAC/F,CAAC;YACN,CAAC;iBAAM,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;gBACpC,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACjC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,kCAAkC,WAAW,CAAC,IAAI,GAAG,CAC3E,CAAC;gBACJ,CAAC;qBAAM,IACL,CAAC,WAAW,CAAC,KAAK;oBAClB,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ;oBACnC,WAAW,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ;oBAErC,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,0DAA0D,CAChF,CAAC;YACN,CAAC;YAED,MAAM,gBAAgB,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACvD,IAAI,QAAQ,IAAI,CAAC,gBAAgB;gBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,8DAA8D,CACpF,CAAC;YAEJ,IAAI,CAAC,QAAQ,IAAI,gBAAgB;gBAC/B,MAAM,CAAC,IAAI,CACT,iBAAiB,IAAI,8DAA8D,CACpF,CAAC;QACN,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,kEAAkE,SAAS,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7H,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED,MAAM,yBAAyB,GAAG,IAAI,yBAAyB,EAAE,CAAC;AAElE,kBAAe,yBAAyB,CAAC","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport deepmerge from \"../helpers/deepmerge.helper\";\nimport { UploadConfig } from \"./types/upload-config\";\n\nclass ArkosRouterOpenAPIManager {\n /**\n * Generates OpenAPI schema for file upload fields in multipart/form-data requests.\n * Converts upload configuration into OpenAPI-compliant schema and merges with existing body schema.\n *\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {any} existingSchema - Existing JSON schema from config.validation.body (optional)\n * @returns {{ schema: any }} OpenAPI schema object for multipart/form-data content type\n *\n * @example\n * // Single file upload\n * addUploadFields({ type: 'single', field: 'avatar', maxSize: 5242880 })\n * // Returns: { schema: { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } } }\n *\n * @example\n * // Array file upload\n * addUploadFields({ type: 'array', field: 'gallery', maxCount: 10 })\n *\n * @example\n * // Multiple fields upload\n * addUploadFields({ type: 'fields', fields: [{ name: 'avatar', maxCount: 1 }, { name: 'resume', maxCount: 1 }] })\n */\n addUploadFields(\n uploadConfig: UploadConfig,\n existingSchema: OpenAPIV3.SchemaObject = {}\n ): OpenAPIV3.SchemaObject {\n const uploadSchema: any = {\n type: \"object\",\n properties: {},\n required: [],\n };\n\n if (uploadConfig.type === \"single\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"string\",\n format: \"binary\",\n description: `Single file field${uploadConfig.maxSize ? `, max size: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"array\") {\n uploadSchema.properties[uploadConfig.field] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(uploadConfig.maxCount && { maxItems: uploadConfig.maxCount }),\n description: `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(uploadConfig.field);\n }\n } else if (uploadConfig.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n uploadSchema.properties[field.name] = {\n type: \"array\",\n items: {\n type: \"string\",\n format: \"binary\",\n },\n ...(field.maxCount && { maxItems: field.maxCount }),\n description: `Array file field${uploadConfig.maxSize ? `, max size per file: ${uploadConfig.maxSize} bytes` : \"\"}`,\n };\n if (uploadConfig.required !== false) {\n uploadSchema.required.push(field.name);\n }\n }\n }\n\n // Clean up empty required array\n if (uploadSchema.required.length === 0) delete uploadSchema.required;\n\n return deepmerge(existingSchema as any, uploadSchema);\n }\n\n /**\n * Validates that a user-defined multipart/form-data schema includes all required upload fields\n * with correct types, formats, and required flags.\n *\n * @param {any} userDefinedMultipartSchema - The schema object from openapi.requestBody.content['multipart/form-data'].schema\n * @param {UploadConfig} uploadConfig - The upload configuration from config.experimental.uploads\n * @param {string} routePath - The route path for error context\n * @throws {Error} If upload fields are missing or incorrectly defined\n *\n * @example\n * validateMultipartFormDocs(\n * { type: 'object', properties: { avatar: { type: 'string', format: 'binary' } } },\n * { type: 'single', field: 'avatar', required: true },\n * '/users/:id/avatar'\n * )\n */\n validateMultipartFormDocs(\n userDefinedMultipartSchema: any,\n routePath: string,\n uploadConfig?: UploadConfig\n ): void {\n const errors: string[] = [];\n const properties = userDefinedMultipartSchema?.properties || {};\n const requiredFields = userDefinedMultipartSchema?.required || [];\n\n const expectedFields: Array<{\n name: string;\n required: boolean;\n expectedType: \"single\" | \"array\";\n }> = [];\n\n if (uploadConfig?.type === \"single\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"single\",\n });\n } else if (uploadConfig?.type === \"array\") {\n expectedFields.push({\n name: uploadConfig.field,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n } else if (uploadConfig?.type === \"fields\") {\n for (const field of uploadConfig.fields) {\n expectedFields.push({\n name: field.name,\n required: uploadConfig.required !== false,\n expectedType: \"array\",\n });\n }\n }\n\n for (const { name, required, expectedType } of expectedFields) {\n const fieldSchema = properties[name];\n\n if (!fieldSchema) {\n errors.push(\n `Missing upload field '${name}' in multipart/form-data schema`\n );\n continue;\n }\n\n if (expectedType === \"single\") {\n if (fieldSchema.type !== \"string\")\n errors.push(\n `Upload field '${name}' must have type 'string', got '${fieldSchema.type}'`\n );\n\n if (fieldSchema.format !== \"binary\")\n errors.push(\n `Upload field '${name}' must have format 'binary', got '${fieldSchema.format || \"undefined\"}'`\n );\n } else if (expectedType === \"array\") {\n if (fieldSchema.type !== \"array\") {\n errors.push(\n `Upload field '${name}' must have type 'array', got '${fieldSchema.type}'`\n );\n } else if (\n !fieldSchema.items ||\n fieldSchema.items.type !== \"string\" ||\n fieldSchema.items.format !== \"binary\"\n )\n errors.push(\n `Upload field '${name}' must have items with type 'string' and format 'binary'`\n );\n }\n\n const isMarkedRequired = requiredFields.includes(name);\n if (required && !isMarkedRequired)\n errors.push(\n `Upload field '${name}' is required in config but not marked as required in schema`\n );\n\n if (!required && isMarkedRequired)\n errors.push(\n `Upload field '${name}' is not required in config but marked as required in schema`\n );\n }\n\n if (errors.length > 0) {\n throw new Error(\n `ValidationError: Invalid multipart/form-data schema for route '${routePath}':\\n${errors.map((e) => ` - ${e}`).join(\"\\n\")}`\n );\n }\n }\n}\n\nconst arkosRouterOpenApiManager = new ArkosRouterOpenAPIManager();\n\nexport default arkosRouterOpenApiManager;\n"]}
@@ -189,6 +189,9 @@ function generateOpenAPIFromApp(app) {
189
189
  delete convertedOpenAPI.parameters;
190
190
  const hasUploadFields = Object.keys(config?.experimental?.uploads || {}).length > 0;
191
191
  const multipartFormSchema = convertedOpenAPI?.requestBody?.content?.["multipart/form-data"];
192
+ const allUploadFieldsAreRequired = hasUploadFields
193
+ ? upload_manager_1.default.isAllFieldRequired(config?.experimental?.uploads)
194
+ : false;
192
195
  if (hasUploadFields && multipartFormSchema)
193
196
  arkos_router_openapi_manager_1.default.validateMultipartFormDocs(multipartFormSchema, path, config?.experimental?.uploads);
194
197
  paths[path][method.toLowerCase()] = {
@@ -211,9 +214,11 @@ function generateOpenAPIFromApp(app) {
211
214
  schema: openapi_schema_converter_1.default.flattenSchema(arkos_router_openapi_manager_1.default.addUploadFields(config.experimental?.uploads, schema)),
212
215
  },
213
216
  }),
214
- "application/json": {
215
- schema,
216
- },
217
+ ...(!allUploadFieldsAreRequired && {
218
+ "application/json": {
219
+ schema,
220
+ },
221
+ }),
217
222
  };
218
223
  })(),
219
224
  },
@@ -225,11 +230,17 @@ function generateOpenAPIFromApp(app) {
225
230
  content: (() => {
226
231
  const schema = convertedOpenAPI?.requestBody?.content?.["application/json"]
227
232
  ?.schema || {};
233
+ delete convertedOpenAPI?.requestBody?.content?.["application/json"];
228
234
  return {
229
235
  "multipart/form-data": {
230
236
  schema: openapi_schema_converter_1.default.flattenSchema(arkos_router_openapi_manager_1.default.addUploadFields(config?.experimental?.uploads || {}, schema)),
231
237
  },
232
238
  ...convertedOpenAPI?.requestBody?.content,
239
+ ...(!allUploadFieldsAreRequired && {
240
+ "application/json": {
241
+ schema,
242
+ },
243
+ }),
233
244
  };
234
245
  })(),
235
246
  },
@@ -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 {\n IArkosRouter,\n ArkosRouteConfig,\n ArkosAnyRequestHandler,\n PathParams,\n IArkosRoute,\n} from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport RouteConfigValidator from \"./route-config-validator\";\nimport RouteConfigRegistry from \"./route-config-registry\";\nimport {\n applyPrefix,\n extractArkosRoutes,\n extractPathParams,\n getMiddlewareStack,\n} from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\nimport { catchAsync } from \"../../exports/error-handler\";\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\";\nimport { getUserFileExtension } from \"../helpers/fs.helpers\";\nimport arkosRouterOpenApiManager from \"./arkos-router-openapi-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(\n options?: RouterOptions & {\n prefix?: string | RegExp | Array<string | RegExp>;\n }\n): IArkosRouter {\n const router = Router(options);\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 ] as const;\n\n if (prop === \"route\") {\n return function (path: PathParams) {\n const routeChain: any = {};\n\n httpMethods.forEach((method) => {\n routeChain[method] = function (\n config: ArkosAnyRequestHandler | Omit<ArkosRouteConfig, \"path\">,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n const fullConfig: ArkosRouteConfig = {\n ...config,\n path,\n };\n\n receiver[method](fullConfig, ...handlers);\n\n return routeChain as IArkosRoute;\n };\n });\n\n return routeChain;\n };\n }\n\n if (httpMethods.includes(prop as any)) {\n return function (\n config: ArkosRouteConfig,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n if (config.disabled) return;\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 path = applyPrefix(options?.prefix, config.path);\n\n config = { ...config, path };\n\n if ([null, undefined].includes(path as any))\n throw Error(\n \"Please pass valid value for path field to use in your route\"\n );\n\n const method = prop as string;\n const UndefinedHandlerError = (handler: any) =>\n Error(\n `Wrong value for handler in route ${method.toUpperCase()} ${path}, recevied ${handler}.`\n );\n\n if (handlers.length > 0) {\n const flattenHandlers = (arr: any[]): ArkosAnyRequestHandler[] => {\n return arr.reduce((flat, item) => {\n return flat.concat(\n Array.isArray(item) ? flattenHandlers(item) : item\n );\n }, []);\n };\n\n const flatHandlers = flattenHandlers(handlers);\n\n handlers = flatHandlers.map((handler: ArkosAnyRequestHandler) => {\n if (!handler) throw UndefinedHandlerError(handler);\n\n if (typeof handler !== \"function\") {\n throw UndefinedHandlerError(handler);\n }\n\n return catchAsync(handler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\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 (\n !validationConfig?.resolver &&\n Object.keys(config.validation || {}).length > 0\n )\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.config.${getUserFileExtension()}\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication-system.`\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\nconst hasDuplicatedPath = (path: string) => /^(\\/.+)\\1/.test(path);\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 || 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 tags: 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 };\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 {\n IArkosRouter,\n ArkosRouteConfig,\n ArkosAnyRequestHandler,\n PathParams,\n IArkosRoute,\n} from \"./types\";\nimport { OpenAPIV3 } from \"openapi-types\";\nimport RouteConfigValidator from \"./route-config-validator\";\nimport RouteConfigRegistry from \"./route-config-registry\";\nimport {\n applyPrefix,\n extractArkosRoutes,\n extractPathParams,\n getMiddlewareStack,\n} from \"./utils/helpers\";\nimport { getArkosConfig } from \"../../exports\";\nimport { catchAsync } from \"../../exports/error-handler\";\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\";\nimport { getUserFileExtension } from \"../helpers/fs.helpers\";\nimport arkosRouterOpenApiManager from \"./arkos-router-openapi-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(\n options?: RouterOptions & {\n prefix?: string | RegExp | Array<string | RegExp>;\n }\n): IArkosRouter {\n const router = Router(options);\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 ] as const;\n\n if (prop === \"route\") {\n return function (path: PathParams) {\n const routeChain: any = {};\n\n httpMethods.forEach((method) => {\n routeChain[method] = function (\n config: ArkosAnyRequestHandler | Omit<ArkosRouteConfig, \"path\">,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n const fullConfig: ArkosRouteConfig = {\n ...config,\n path,\n };\n\n receiver[method](fullConfig, ...handlers);\n\n return routeChain as IArkosRoute;\n };\n });\n\n return routeChain;\n };\n }\n\n if (httpMethods.includes(prop as any)) {\n return function (\n config: ArkosRouteConfig,\n ...handlers: ArkosAnyRequestHandler[]\n ) {\n if (config.disabled) return;\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 path = applyPrefix(options?.prefix, config.path);\n\n config = { ...config, path };\n\n if ([null, undefined].includes(path as any))\n throw Error(\n \"Please pass valid value for path field to use in your route\"\n );\n\n const method = prop as string;\n const UndefinedHandlerError = (handler: any) =>\n Error(\n `Wrong value for handler in route ${method.toUpperCase()} ${path}, recevied ${handler}.`\n );\n\n if (handlers.length > 0) {\n const flattenHandlers = (arr: any[]): ArkosAnyRequestHandler[] => {\n return arr.reduce((flat, item) => {\n return flat.concat(\n Array.isArray(item) ? flattenHandlers(item) : item\n );\n }, []);\n };\n\n const flatHandlers = flattenHandlers(handlers);\n\n handlers = flatHandlers.map((handler: ArkosAnyRequestHandler) => {\n if (!handler) throw UndefinedHandlerError(handler);\n\n if (typeof handler !== \"function\") {\n throw UndefinedHandlerError(handler);\n }\n\n return catchAsync(handler, {\n type: handler.length > 3 ? \"error\" : \"normal\",\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 (\n !validationConfig?.resolver &&\n Object.keys(config.validation || {}).length > 0\n )\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.config.${getUserFileExtension()}\n\nFor further help see https://www.arkosjs.com/docs/core-concepts/authentication-system.`\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\nconst hasDuplicatedPath = (path: string) => /^(\\/.+)\\1/.test(path);\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 || 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 tags: 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 };\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 { IRoute, IRouter, Locals } 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 { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../../types\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\nimport { BodyParserConfig } from \"./body-parser-config\";\nimport { Validator } from \"../../../types/validation/validator\";\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 ArkosAnyRequestHandler =\n | ArkosRequestHandler\n | ArkosErrorRequestHandler\n | Array<ArkosRequestHandler | ArkosErrorRequestHandler>;\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> = {\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> | PathParams,\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 | 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\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 | ArkosRequestHandler<\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\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\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\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = any,\n TBody extends\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = any,\n TParams extends\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = 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 { IRoute, IRouter, Locals } 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 { ArkosErrorRequestHandler, ArkosRequestHandler } from \"../../../types\";\nimport compression from \"compression\";\nimport { OpenApiConfig } from \"./openapi-config\";\nimport { UploadConfig } from \"./upload-config\";\nimport { BodyParserConfig } from \"./body-parser-config\";\nimport { Validator } from \"../../../types/validation/validator\";\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 ArkosAnyRequestHandler<\n P extends Record<string, any> = any,\n ResBody = any,\n ReqBody = any,\n ReqQuery extends Record<string, any> = any,\n Locals extends Record<string, any> = Record<string, any>,\n> =\n | ArkosRequestHandler<\n InferValidationType<P, Record<string, string>>,\n ResBody,\n InferValidationType<ReqBody, any>,\n InferValidationType<ReqQuery, qs.ParsedQs>,\n Locals\n >\n | ArkosErrorRequestHandler<\n InferValidationType<P, Record<string, string>>,\n ResBody,\n InferValidationType<ReqBody, any>,\n InferValidationType<ReqQuery, qs.ParsedQs>,\n Locals\n >\n | Array<\n | ArkosRequestHandler<\n InferValidationType<P, Record<string, string>>,\n ResBody,\n InferValidationType<ReqBody, any>,\n InferValidationType<ReqQuery, qs.ParsedQs>,\n Locals\n >\n | ArkosErrorRequestHandler<\n InferValidationType<P, Record<string, string>>,\n ResBody,\n InferValidationType<ReqBody, any>,\n InferValidationType<ReqQuery, qs.ParsedQs>,\n Locals\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> = {\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> | PathParams,\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 >\n >\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 | ArkosRequestHandler<\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\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\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\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = any,\n TBody extends\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = any,\n TParams extends\n | ZodSchema\n | (new (...args: any[]) => object)\n | false\n | null\n | undefined = 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;