arkos 2.0.0-next.16 → 2.0.0-next.18
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.
- package/README.md +33 -31
- package/cli.js +1 -8
- package/dist/esm/app.js +5 -12
- package/dist/esm/app.js.map +1 -1
- package/dist/esm/components/arkos-gateway/arkos-gateway.js +337 -0
- package/dist/esm/components/arkos-gateway/arkos-gateway.js.map +1 -0
- package/dist/esm/components/arkos-gateway/socket-extensions.js +161 -0
- package/dist/esm/components/arkos-gateway/socket-extensions.js.map +1 -0
- package/dist/esm/components/arkos-gateway/types.js +3 -0
- package/dist/esm/components/arkos-gateway/types.js.map +1 -0
- package/dist/esm/components/arkos-gateway/utils/helpers.js +105 -0
- package/dist/esm/components/arkos-gateway/utils/helpers.js.map +1 -0
- package/dist/esm/components/arkos-gateway/utils/memory-gateway-store.js +47 -0
- package/dist/esm/components/arkos-gateway/utils/memory-gateway-store.js.map +1 -0
- package/dist/esm/components/arkos-gateway/utils/multi-tier-arkos-gateway-store.js +39 -0
- package/dist/esm/components/arkos-gateway/utils/multi-tier-arkos-gateway-store.js.map +1 -0
- package/dist/esm/components/arkos-gateway/utils/rate-limiter.js +13 -0
- package/dist/esm/components/arkos-gateway/utils/rate-limiter.js.map +1 -0
- package/dist/esm/components/arkos-policy/index.js.map +1 -1
- package/dist/esm/components/arkos-route-hook/index.js +2 -1
- package/dist/esm/components/arkos-route-hook/index.js.map +1 -1
- package/dist/esm/components/arkos-route-hook/reader.js.map +1 -1
- package/dist/esm/components/arkos-route-hook/types.js.map +1 -1
- package/dist/esm/exports/index.js +2 -2
- package/dist/esm/exports/index.js.map +1 -1
- package/dist/esm/exports/services/index.js +2 -2
- package/dist/esm/exports/services/index.js.map +1 -1
- package/dist/esm/exports/websockets.js +5 -0
- package/dist/esm/exports/websockets.js.map +1 -0
- package/dist/esm/generated.js.map +1 -1
- package/dist/esm/modules/auth/auth.controller.js +2 -2
- package/dist/esm/modules/auth/auth.controller.js.map +1 -1
- package/dist/esm/modules/auth/auth.service.js +83 -204
- package/dist/esm/modules/auth/auth.service.js.map +1 -1
- package/dist/esm/modules/auth/utils/auth-error-objects.js +2 -2
- package/dist/esm/modules/auth/utils/auth-error-objects.js.map +1 -1
- package/dist/esm/modules/auth/utils/auth-hooks-manager.js +148 -0
- package/dist/esm/modules/auth/utils/auth-hooks-manager.js.map +1 -0
- package/dist/esm/modules/auth/utils/docs-links.js +6 -0
- package/dist/esm/modules/auth/utils/docs-links.js.map +1 -0
- package/dist/esm/modules/auth/utils/services/auth-action.service.js +6 -4
- package/dist/esm/modules/auth/utils/services/auth-action.service.js.map +1 -1
- package/dist/esm/modules/base/base.controller.js +11 -5
- package/dist/esm/modules/base/base.controller.js.map +1 -1
- package/dist/esm/modules/base/base.middlewares.js +12 -21
- package/dist/esm/modules/base/base.middlewares.js.map +1 -1
- package/dist/esm/modules/base/base.service.js +16 -128
- package/dist/esm/modules/base/base.service.js.map +1 -1
- package/dist/esm/modules/base/types/base.service.types.js.map +1 -1
- package/dist/esm/modules/email/email.service.js +14 -7
- package/dist/esm/modules/email/email.service.js.map +1 -1
- package/dist/esm/modules/error-handler/error-handler.controller.js +6 -66
- package/dist/esm/modules/error-handler/error-handler.controller.js.map +1 -1
- package/dist/esm/modules/error-handler/utils/catch-async.js.map +1 -1
- package/dist/esm/modules/error-handler/utils/get-handled-error.js +68 -0
- package/dist/esm/modules/error-handler/utils/get-handled-error.js.map +1 -0
- package/dist/esm/modules/file-upload/file-upload.router.js +9 -2
- package/dist/esm/modules/file-upload/file-upload.router.js.map +1 -1
- package/dist/esm/modules/file-upload/file-upload.service.js +1 -1
- package/dist/esm/modules/file-upload/file-upload.service.js.map +1 -1
- package/dist/esm/modules/swagger/swagger.router.js +11 -10
- package/dist/esm/modules/swagger/swagger.router.js.map +1 -1
- package/dist/esm/modules/swagger/utils/get-open-api-login-html.js +3 -1
- package/dist/esm/modules/swagger/utils/get-open-api-login-html.js.map +1 -1
- package/dist/esm/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +1 -1
- package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js +4 -2
- package/dist/esm/modules/swagger/utils/helpers/openapi-schema-converter.js.map +1 -1
- package/dist/esm/server.js +1 -1
- package/dist/esm/server.js.map +1 -1
- package/dist/esm/types/arkos.js.map +1 -1
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/new-arkos-config.js.map +1 -1
- package/dist/esm/types/upload.js +2 -0
- package/dist/esm/types/upload.js.map +1 -0
- package/dist/esm/types/validation/validation-manager.js +50 -0
- package/dist/esm/types/validation/validation-manager.js.map +1 -0
- package/dist/esm/types/validation/validator.js +2 -0
- package/dist/esm/types/validation/validator.js.map +1 -0
- package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js +9 -33
- package/dist/esm/utils/arkos-router/arkos-router-openapi-manager.js.map +1 -1
- package/dist/esm/utils/arkos-router/index.js +15 -3
- package/dist/esm/utils/arkos-router/index.js.map +1 -1
- package/dist/esm/utils/arkos-router/types/index.js.map +1 -1
- package/dist/esm/utils/arkos-router/types/upload-config.js.map +1 -1
- package/dist/esm/utils/arkos-router/utils/helpers/apply-arkos-router-proxy.js +45 -9
- package/dist/esm/utils/arkos-router/utils/helpers/apply-arkos-router-proxy.js.map +1 -1
- package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js +26 -6
- package/dist/esm/utils/arkos-router/utils/helpers/upload-manager.js.map +1 -1
- package/dist/esm/utils/cli/build.js +11 -2
- package/dist/esm/utils/cli/build.js.map +1 -1
- package/dist/esm/utils/cli/dev.js +4 -6
- package/dist/esm/utils/cli/dev.js.map +1 -1
- package/dist/esm/utils/cli/generate.js +0 -90
- package/dist/esm/utils/cli/generate.js.map +1 -1
- package/dist/esm/utils/cli/index.js +10 -74
- package/dist/esm/utils/cli/index.js.map +1 -1
- package/dist/esm/utils/cli/start.js +20 -11
- package/dist/esm/utils/cli/start.js.map +1 -1
- package/dist/esm/utils/cli/utils/cli.helpers.js +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +53 -17
- package/dist/esm/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/generate-multiple-components.js +3 -54
- package/dist/esm/utils/cli/utils/template-generator/templates/generate-multiple-components.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js +11 -4
- package/dist/esm/utils/cli/utils/template-generator/templates/router-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js +2 -2
- package/dist/esm/utils/cli/utils/template-generator/templates/service-template.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js +18 -18
- package/dist/esm/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +1 -1
- package/dist/esm/utils/cli/utils/template-generators.js +27 -24
- package/dist/esm/utils/cli/utils/template-generators.js.map +1 -1
- package/dist/esm/utils/docs-links.js +2 -0
- package/dist/esm/utils/docs-links.js.map +1 -0
- package/dist/esm/utils/features/api.features.js.map +1 -1
- package/dist/esm/utils/helpers/arkos-config.helpers.js.map +1 -1
- package/dist/esm/utils/helpers/exit-error.js +1 -1
- package/dist/esm/utils/helpers/exit-error.js.map +1 -1
- package/dist/esm/utils/initialize-app.js +3 -3
- package/dist/esm/utils/initialize-app.js.map +1 -1
- package/dist/esm/utils/prisma/prisma-json-schema-generator.js +19 -18
- package/dist/esm/utils/prisma/prisma-json-schema-generator.js.map +1 -1
- package/dist/esm/utils/remove-dir.js +1 -1
- package/dist/esm/utils/remove-dir.js.map +1 -1
- package/dist/esm/utils/setup-app.js.map +1 -1
- package/dist/types/app.d.ts +4 -0
- package/dist/types/components/arkos-gateway/arkos-gateway.d.ts +121 -0
- package/dist/types/components/arkos-gateway/socket-extensions.d.ts +79 -0
- package/dist/types/components/arkos-gateway/types.d.ts +364 -0
- package/dist/types/components/arkos-gateway/utils/helpers.d.ts +9 -0
- package/dist/types/components/arkos-gateway/utils/memory-gateway-store.d.ts +14 -0
- package/dist/types/components/arkos-gateway/utils/multi-tier-arkos-gateway-store.d.ts +20 -0
- package/dist/types/components/arkos-gateway/utils/rate-limiter.d.ts +11 -0
- package/dist/types/components/arkos-route-hook/index.d.ts +11 -5
- package/dist/types/components/arkos-route-hook/reader.d.ts +2 -2
- package/dist/types/components/arkos-route-hook/types.d.ts +5 -1
- package/dist/types/exports/index.d.ts +3 -2
- package/dist/types/exports/services/index.d.ts +3 -3
- package/dist/types/exports/websockets.d.ts +5 -0
- package/dist/types/modules/auth/auth.service.d.ts +12 -36
- package/dist/types/modules/auth/utils/auth-hooks-manager.d.ts +63 -0
- package/dist/types/modules/auth/utils/docs-links.d.ts +3 -0
- package/dist/types/modules/auth/utils/services/auth-action.service.d.ts +2 -2
- package/dist/types/modules/base/base.controller.d.ts +2 -2
- package/dist/types/modules/base/base.service.d.ts +5 -15
- package/dist/types/modules/base/types/base.service.types.d.ts +11 -0
- package/dist/types/modules/error-handler/utils/catch-async.d.ts +2 -2
- package/dist/types/modules/error-handler/utils/get-handled-error.d.ts +1 -0
- package/dist/types/modules/swagger/utils/helpers/openapi-schema-converter.d.ts +6 -1
- package/dist/types/types/arkos.d.ts +2 -15
- package/dist/types/types/index.d.ts +6 -5
- package/dist/types/types/new-arkos-config.d.ts +1 -1
- package/dist/types/types/upload.d.ts +10 -0
- package/dist/types/types/validation/validation-manager.d.ts +27 -0
- package/dist/types/types/validation/validator.d.ts +2 -0
- package/dist/types/utils/arkos-router/index.d.ts +7 -0
- package/dist/types/utils/arkos-router/types/index.d.ts +35 -21
- package/dist/types/utils/arkos-router/types/upload-config.d.ts +2 -1
- package/dist/types/utils/arkos-router/utils/helpers/apply-arkos-router-proxy.d.ts +6 -7
- package/dist/types/utils/arkos-router/utils/helpers/upload-manager.d.ts +1 -0
- package/dist/types/utils/cli/build.d.ts +1 -1
- package/dist/types/utils/cli/generate.d.ts +11 -10
- package/dist/types/utils/cli/start.d.ts +2 -0
- package/dist/types/utils/cli/utils/template-generator/templates/class-validator-dto-generator.d.ts +7 -0
- package/dist/types/utils/docs-links.d.ts +1 -0
- package/dist/types/utils/features/api.features.d.ts +1 -2
- package/dist/types/utils/helpers/arkos-config.helpers.d.ts +5 -0
- package/package.json +61 -30
- package/dist/cjs/app.js +0 -121
- package/dist/cjs/app.js.map +0 -1
- package/dist/cjs/components/arkos-loadable-registry/index.js +0 -28
- package/dist/cjs/components/arkos-loadable-registry/index.js.map +0 -1
- package/dist/cjs/components/arkos-loadable-translator/index.js +0 -144
- package/dist/cjs/components/arkos-loadable-translator/index.js.map +0 -1
- package/dist/cjs/components/arkos-policy/index.js +0 -38
- package/dist/cjs/components/arkos-policy/index.js.map +0 -1
- package/dist/cjs/components/arkos-policy/types.js +0 -3
- package/dist/cjs/components/arkos-policy/types.js.map +0 -1
- package/dist/cjs/components/arkos-route-hook/index.js +0 -50
- package/dist/cjs/components/arkos-route-hook/index.js.map +0 -1
- package/dist/cjs/components/arkos-route-hook/reader.js +0 -47
- package/dist/cjs/components/arkos-route-hook/reader.js.map +0 -1
- package/dist/cjs/components/arkos-route-hook/types.js +0 -3
- package/dist/cjs/components/arkos-route-hook/types.js.map +0 -1
- package/dist/cjs/components/arkos-service-hook/index.js +0 -35
- package/dist/cjs/components/arkos-service-hook/index.js.map +0 -1
- package/dist/cjs/components/arkos-service-hook/reader.js +0 -30
- package/dist/cjs/components/arkos-service-hook/reader.js.map +0 -1
- package/dist/cjs/components/arkos-service-hook/types.js +0 -3
- package/dist/cjs/components/arkos-service-hook/types.js.map +0 -1
- package/dist/cjs/exports/auth/index.js +0 -6
- package/dist/cjs/exports/auth/index.js.map +0 -1
- package/dist/cjs/exports/config.js +0 -6
- package/dist/cjs/exports/config.js.map +0 -1
- package/dist/cjs/exports/controllers/index.js +0 -42
- package/dist/cjs/exports/controllers/index.js.map +0 -1
- package/dist/cjs/exports/error-handler/index.js +0 -26
- package/dist/cjs/exports/error-handler/index.js.map +0 -1
- package/dist/cjs/exports/index.js +0 -23
- package/dist/cjs/exports/index.js.map +0 -1
- package/dist/cjs/exports/middlewares/index.js +0 -7
- package/dist/cjs/exports/middlewares/index.js.map +0 -1
- package/dist/cjs/exports/prisma/index.js +0 -13
- package/dist/cjs/exports/prisma/index.js.map +0 -1
- package/dist/cjs/exports/services/index.js +0 -53
- package/dist/cjs/exports/services/index.js.map +0 -1
- package/dist/cjs/exports/utils/index.js +0 -26
- package/dist/cjs/exports/utils/index.js.map +0 -1
- package/dist/cjs/exports/validation/index.js +0 -11
- package/dist/cjs/exports/validation/index.js.map +0 -1
- package/dist/cjs/generated.js +0 -7
- package/dist/cjs/generated.js.map +0 -1
- package/dist/cjs/modules/auth/auth.controller.js +0 -254
- package/dist/cjs/modules/auth/auth.controller.js.map +0 -1
- package/dist/cjs/modules/auth/auth.router.js +0 -130
- package/dist/cjs/modules/auth/auth.router.js.map +0 -1
- package/dist/cjs/modules/auth/auth.service.js +0 -433
- package/dist/cjs/modules/auth/auth.service.js.map +0 -1
- package/dist/cjs/modules/auth/utils/auth-error-objects.js +0 -10
- package/dist/cjs/modules/auth/utils/auth-error-objects.js.map +0 -1
- package/dist/cjs/modules/auth/utils/auth-openapi-generator.js +0 -372
- package/dist/cjs/modules/auth/utils/auth-openapi-generator.js.map +0 -1
- package/dist/cjs/modules/auth/utils/auth-prisma-json-schema-generator.js +0 -101
- package/dist/cjs/modules/auth/utils/auth-prisma-json-schema-generator.js.map +0 -1
- package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js +0 -83
- package/dist/cjs/modules/auth/utils/helpers/auth.controller.helpers.js.map +0 -1
- package/dist/cjs/modules/auth/utils/services/auth-action.service.js +0 -154
- package/dist/cjs/modules/auth/utils/services/auth-action.service.js.map +0 -1
- package/dist/cjs/modules/base/base.controller.js +0 -287
- package/dist/cjs/modules/base/base.controller.js.map +0 -1
- package/dist/cjs/modules/base/base.middlewares.js +0 -238
- package/dist/cjs/modules/base/base.middlewares.js.map +0 -1
- package/dist/cjs/modules/base/base.router.js +0 -126
- package/dist/cjs/modules/base/base.router.js.map +0 -1
- package/dist/cjs/modules/base/base.service.js +0 -436
- package/dist/cjs/modules/base/base.service.js.map +0 -1
- package/dist/cjs/modules/base/types/base.service.types.js +0 -3
- package/dist/cjs/modules/base/types/base.service.types.js.map +0 -1
- package/dist/cjs/modules/base/utils/error-prettifier.js +0 -188
- package/dist/cjs/modules/base/utils/error-prettifier.js.map +0 -1
- package/dist/cjs/modules/base/utils/helpers/base.middlewares.helpers.js +0 -49
- package/dist/cjs/modules/base/utils/helpers/base.middlewares.helpers.js.map +0 -1
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js +0 -243
- package/dist/cjs/modules/base/utils/helpers/base.service.helpers.js.map +0 -1
- package/dist/cjs/modules/base/utils/model-openapi-generator.js +0 -443
- package/dist/cjs/modules/base/utils/model-openapi-generator.js.map +0 -1
- package/dist/cjs/modules/base/utils/router-validator.js +0 -13
- package/dist/cjs/modules/base/utils/router-validator.js.map +0 -1
- package/dist/cjs/modules/base/utils/service-hooks-manager.js +0 -19
- package/dist/cjs/modules/base/utils/service-hooks-manager.js.map +0 -1
- package/dist/cjs/modules/debugger/debugger.service.js +0 -59
- package/dist/cjs/modules/debugger/debugger.service.js.map +0 -1
- package/dist/cjs/modules/email/email.service.js +0 -106
- package/dist/cjs/modules/email/email.service.js.map +0 -1
- package/dist/cjs/modules/error-handler/error-handler.controller.js +0 -166
- package/dist/cjs/modules/error-handler/error-handler.controller.js.map +0 -1
- package/dist/cjs/modules/error-handler/utils/app-error.js +0 -27
- package/dist/cjs/modules/error-handler/utils/app-error.js.map +0 -1
- package/dist/cjs/modules/error-handler/utils/catch-async.js +0 -21
- package/dist/cjs/modules/error-handler/utils/catch-async.js.map +0 -1
- package/dist/cjs/modules/error-handler/utils/error-handler.helpers.js +0 -104
- package/dist/cjs/modules/error-handler/utils/error-handler.helpers.js.map +0 -1
- package/dist/cjs/modules/error-handler/utils/errors.js +0 -158
- package/dist/cjs/modules/error-handler/utils/errors.js.map +0 -1
- package/dist/cjs/modules/error-handler/utils/multer-error-handler.js +0 -39
- package/dist/cjs/modules/error-handler/utils/multer-error-handler.js.map +0 -1
- package/dist/cjs/modules/file-upload/file-upload.controller.js +0 -252
- package/dist/cjs/modules/file-upload/file-upload.controller.js.map +0 -1
- package/dist/cjs/modules/file-upload/file-upload.router.js +0 -96
- package/dist/cjs/modules/file-upload/file-upload.router.js.map +0 -1
- package/dist/cjs/modules/file-upload/file-upload.service.js +0 -343
- package/dist/cjs/modules/file-upload/file-upload.service.js.map +0 -1
- package/dist/cjs/modules/file-upload/utils/file-upload-json-schema-generator.js +0 -351
- package/dist/cjs/modules/file-upload/utils/file-upload-json-schema-generator.js.map +0 -1
- package/dist/cjs/modules/file-upload/utils/helpers/file-extensions.js +0 -134
- package/dist/cjs/modules/file-upload/utils/helpers/file-extensions.js.map +0 -1
- package/dist/cjs/modules/file-upload/utils/helpers/file-upload.helpers.js +0 -100
- package/dist/cjs/modules/file-upload/utils/helpers/file-upload.helpers.js.map +0 -1
- package/dist/cjs/modules/swagger/swagger.router.js +0 -81
- package/dist/cjs/modules/swagger/swagger.router.js.map +0 -1
- package/dist/cjs/modules/swagger/utils/get-open-api-login-html.js +0 -306
- package/dist/cjs/modules/swagger/utils/get-open-api-login-html.js.map +0 -1
- package/dist/cjs/modules/swagger/utils/helpers/class-validator-to-json-schema.js +0 -53
- package/dist/cjs/modules/swagger/utils/helpers/class-validator-to-json-schema.js.map +0 -1
- package/dist/cjs/modules/swagger/utils/helpers/get-swagger-default-configs.js +0 -72
- package/dist/cjs/modules/swagger/utils/helpers/get-swagger-default-configs.js.map +0 -1
- package/dist/cjs/modules/swagger/utils/helpers/openapi-schema-converter.js +0 -331
- package/dist/cjs/modules/swagger/utils/helpers/openapi-schema-converter.js.map +0 -1
- package/dist/cjs/package.json +0 -3
- package/dist/cjs/server.js +0 -60
- package/dist/cjs/server.js.map +0 -1
- package/dist/cjs/types/arkos-config/utils.js +0 -3
- package/dist/cjs/types/arkos-config/utils.js.map +0 -1
- package/dist/cjs/types/arkos-prisma-input.js +0 -3
- package/dist/cjs/types/arkos-prisma-input.js.map +0 -1
- package/dist/cjs/types/arkos.js +0 -3
- package/dist/cjs/types/arkos.js.map +0 -1
- package/dist/cjs/types/auth.js +0 -3
- package/dist/cjs/types/auth.js.map +0 -1
- package/dist/cjs/types/index.js +0 -3
- package/dist/cjs/types/index.js.map +0 -1
- package/dist/cjs/types/new-arkos-config.js +0 -3
- package/dist/cjs/types/new-arkos-config.js.map +0 -1
- package/dist/cjs/types/router-config.js +0 -3
- package/dist/cjs/types/router-config.js.map +0 -1
- package/dist/cjs/utils/arkos-env.js +0 -9
- package/dist/cjs/utils/arkos-env.js.map +0 -1
- package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js +0 -184
- package/dist/cjs/utils/arkos-router/arkos-router-openapi-manager.js.map +0 -1
- package/dist/cjs/utils/arkos-router/index.js +0 -153
- package/dist/cjs/utils/arkos-router/index.js.map +0 -1
- package/dist/cjs/utils/arkos-router/route-config-registry.js +0 -16
- package/dist/cjs/utils/arkos-router/route-config-registry.js.map +0 -1
- package/dist/cjs/utils/arkos-router/route-config-validator.js +0 -56
- package/dist/cjs/utils/arkos-router/route-config-validator.js.map +0 -1
- package/dist/cjs/utils/arkos-router/types/body-parser-config.js +0 -3
- package/dist/cjs/utils/arkos-router/types/body-parser-config.js.map +0 -1
- package/dist/cjs/utils/arkos-router/types/index.js +0 -3
- package/dist/cjs/utils/arkos-router/types/index.js.map +0 -1
- package/dist/cjs/utils/arkos-router/types/openapi-config.js +0 -3
- package/dist/cjs/utils/arkos-router/types/openapi-config.js.map +0 -1
- package/dist/cjs/utils/arkos-router/types/upload-config.js +0 -3
- package/dist/cjs/utils/arkos-router/types/upload-config.js.map +0 -1
- package/dist/cjs/utils/arkos-router/utils/helpers/apply-arkos-router-proxy.js +0 -158
- package/dist/cjs/utils/arkos-router/utils/helpers/apply-arkos-router-proxy.js.map +0 -1
- package/dist/cjs/utils/arkos-router/utils/helpers/index.js +0 -179
- package/dist/cjs/utils/arkos-router/utils/helpers/index.js.map +0 -1
- package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js +0 -540
- package/dist/cjs/utils/arkos-router/utils/helpers/upload-manager.js.map +0 -1
- package/dist/cjs/utils/bundler.js +0 -163
- package/dist/cjs/utils/bundler.js.map +0 -1
- package/dist/cjs/utils/cli/build.js +0 -199
- package/dist/cjs/utils/cli/build.js.map +0 -1
- package/dist/cjs/utils/cli/dev.js +0 -133
- package/dist/cjs/utils/cli/dev.js.map +0 -1
- package/dist/cjs/utils/cli/export-auth-action.js +0 -80
- package/dist/cjs/utils/cli/export-auth-action.js.map +0 -1
- package/dist/cjs/utils/cli/generate.js +0 -333
- package/dist/cjs/utils/cli/generate.js.map +0 -1
- package/dist/cjs/utils/cli/index.js +0 -259
- package/dist/cjs/utils/cli/index.js.map +0 -1
- package/dist/cjs/utils/cli/prisma-generate.js +0 -112
- package/dist/cjs/utils/cli/prisma-generate.js.map +0 -1
- package/dist/cjs/utils/cli/start.js +0 -74
- package/dist/cjs/utils/cli/start.js.map +0 -1
- package/dist/cjs/utils/cli/utils/cli.helpers.js +0 -24
- package/dist/cjs/utils/cli/utils/cli.helpers.js.map +0 -1
- package/dist/cjs/utils/cli/utils/runtime-cli-commander.js +0 -118
- package/dist/cjs/utils/cli/utils/runtime-cli-commander.js.map +0 -1
- package/dist/cjs/utils/cli/utils/smart-fs-watcher.js +0 -73
- package/dist/cjs/utils/cli/utils/smart-fs-watcher.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js +0 -810
- package/dist/cjs/utils/cli/utils/template-generator/templates/class-validator-dto-generator.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-controller-template.js +0 -64
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-controller-template.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-multiple-components.js +0 -242
- package/dist/cjs/utils/cli/utils/template-generator/templates/generate-multiple-components.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/policy-template.js +0 -51
- package/dist/cjs/utils/cli/utils/template-generator/templates/policy-template.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js +0 -23
- package/dist/cjs/utils/cli/utils/template-generator/templates/router-template.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js +0 -50
- package/dist/cjs/utils/cli/utils/template-generator/templates/service-template.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js +0 -545
- package/dist/cjs/utils/cli/utils/template-generator/templates/zod-schema-generator.js.map +0 -1
- package/dist/cjs/utils/cli/utils/template-generators.js +0 -62
- package/dist/cjs/utils/cli/utils/template-generators.js.map +0 -1
- package/dist/cjs/utils/cli/utils/watermark-stamper.js +0 -26
- package/dist/cjs/utils/cli/utils/watermark-stamper.js.map +0 -1
- package/dist/cjs/utils/define-config.js +0 -60
- package/dist/cjs/utils/define-config.js.map +0 -1
- package/dist/cjs/utils/dotenv.helpers.js +0 -46
- package/dist/cjs/utils/dotenv.helpers.js.map +0 -1
- package/dist/cjs/utils/dynamic-loader.js +0 -22
- package/dist/cjs/utils/dynamic-loader.js.map +0 -1
- package/dist/cjs/utils/expand-env.js +0 -72
- package/dist/cjs/utils/expand-env.js.map +0 -1
- package/dist/cjs/utils/features/api.features.js +0 -216
- package/dist/cjs/utils/features/api.features.js.map +0 -1
- package/dist/cjs/utils/features/port-and-host-allocator.js +0 -129
- package/dist/cjs/utils/features/port-and-host-allocator.js.map +0 -1
- package/dist/cjs/utils/helpers/api.features.helpers.js +0 -347
- package/dist/cjs/utils/helpers/api.features.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/arkos-config.helpers.js +0 -106
- package/dist/cjs/utils/helpers/arkos-config.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/change-case.helpers.js +0 -177
- package/dist/cjs/utils/helpers/change-case.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/deepmerge.helper.js +0 -115
- package/dist/cjs/utils/helpers/deepmerge.helper.js.map +0 -1
- package/dist/cjs/utils/helpers/exit-error.js +0 -13
- package/dist/cjs/utils/helpers/exit-error.js.map +0 -1
- package/dist/cjs/utils/helpers/fs.helpers.js +0 -52
- package/dist/cjs/utils/helpers/fs.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/global.helpers.js +0 -106
- package/dist/cjs/utils/helpers/global.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/prisma.helpers.js +0 -56
- package/dist/cjs/utils/helpers/prisma.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/query-parser.helpers.js +0 -69
- package/dist/cjs/utils/helpers/query-parser.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/routers.helpers.js +0 -36
- package/dist/cjs/utils/helpers/routers.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/text.helpers.js +0 -28
- package/dist/cjs/utils/helpers/text.helpers.js.map +0 -1
- package/dist/cjs/utils/helpers/url-helpers.js +0 -14
- package/dist/cjs/utils/helpers/url-helpers.js.map +0 -1
- package/dist/cjs/utils/initialize-app.js +0 -80
- package/dist/cjs/utils/initialize-app.js.map +0 -1
- package/dist/cjs/utils/prisma/prisma-json-schema-generator.js +0 -366
- package/dist/cjs/utils/prisma/prisma-json-schema-generator.js.map +0 -1
- package/dist/cjs/utils/prisma/prisma-schema-parser.js +0 -380
- package/dist/cjs/utils/prisma/prisma-schema-parser.js.map +0 -1
- package/dist/cjs/utils/prisma/types.js +0 -3
- package/dist/cjs/utils/prisma/types.js.map +0 -1
- package/dist/cjs/utils/remove-dir.js +0 -14
- package/dist/cjs/utils/remove-dir.js.map +0 -1
- package/dist/cjs/utils/setup-app.js +0 -136
- package/dist/cjs/utils/setup-app.js.map +0 -1
- package/dist/cjs/utils/sheu.js +0 -131
- package/dist/cjs/utils/sheu.js.map +0 -1
- package/dist/cjs/utils/validate-dto.js +0 -19
- package/dist/cjs/utils/validate-dto.js.map +0 -1
- package/dist/cjs/utils/validate-schema.js +0 -75
- package/dist/cjs/utils/validate-schema.js.map +0 -1
- package/dist/esm/components/arkos-service-hook/index.js +0 -32
- package/dist/esm/components/arkos-service-hook/index.js.map +0 -1
- package/dist/esm/components/arkos-service-hook/reader.js +0 -24
- package/dist/esm/components/arkos-service-hook/reader.js.map +0 -1
- package/dist/esm/components/arkos-service-hook/types.js +0 -2
- package/dist/esm/components/arkos-service-hook/types.js.map +0 -1
- package/dist/esm/modules/base/utils/service-hooks-manager.js +0 -17
- package/dist/esm/modules/base/utils/service-hooks-manager.js.map +0 -1
- package/dist/types/components/arkos-service-hook/index.d.ts +0 -41
- package/dist/types/components/arkos-service-hook/reader.d.ts +0 -35
- package/dist/types/components/arkos-service-hook/types.d.ts +0 -240
- package/dist/types/modules/base/utils/service-hooks-manager.d.ts +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload.router.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.router.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,0BAA0B,CAAC;AAC5D,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,SAAS,MAAM,sCAAsC,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;
|
|
1
|
+
{"version":3,"file":"file-upload.router.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.router.ts"],"names":[],"mappings":"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","sourcesContent":["import fileUploadController from \"./file-upload.controller\";\nimport express from \"express\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { sendResponse } from \"../base/base.middlewares\";\nimport { processMiddleware } from \"../../utils/helpers/routers.helpers\";\nimport { adjustRequestUrl } from \"./utils/helpers/file-upload.helpers\";\nimport { ArkosNextFunction, ArkosRequest, ArkosResponse } from \"../../exports\";\nimport path from \"path\";\nimport ArkosRouter from \"../../utils/arkos-router\";\nimport loadableRegistry from \"../../components/arkos-loadable-registry\";\nimport {\n OperationByModule,\n routeHookReader,\n} from \"../../components/arkos-route-hook/reader\";\nimport { getArkosConfig } from \"../../server\";\nimport fileUploadJsonSchemaGenerator from \"./utils/file-upload-json-schema-generator\";\nimport AppError from \"../error-handler/utils/app-error\";\n\nexport function getFileUploadRouter() {\n const router = ArkosRouter();\n const { fileUpload } = getArkosConfig();\n if (!fileUpload?.enabled === false) return router;\n\n const routeHook = loadableRegistry.getItem(\"ArkosRouteHook\", \"file-upload\");\n\n const op = (operation: OperationByModule<\"file-upload\">) => {\n let components = routeHook\n ? routeHookReader.forOperation(\"file-upload\", operation)\n : {\n before: [],\n after: [],\n onError: [],\n routeConfig: {},\n };\n\n let endpointConfig = components.routeConfig || {};\n if (endpointConfig?.experimental?.openapi !== false)\n endpointConfig = {\n ...(endpointConfig || {}),\n experimental: {\n ...(endpointConfig?.experimental || {}),\n openapi: fileUploadJsonSchemaGenerator.getOpenApiConfig(\n endpointConfig,\n operation\n ),\n },\n };\n\n components.routeConfig = endpointConfig;\n return components;\n };\n\n let basePathname = fileUpload?.baseRoute || \"/api/uploads/\";\n if (!basePathname.startsWith(\"/\")) basePathname = \"/\" + basePathname;\n if (!basePathname.endsWith(\"/\")) basePathname = basePathname + \"/\";\n\n // FIND FILE\n {\n const { before, onError, routeConfig } = op(\"findFile\");\n const baseUploadDirFullPath = path.resolve(\n path\n .join(process.cwd(), fileUpload?.baseUploadDir || \"uploads\")\n .replaceAll(\"//\", \"/\")\n );\n router.get(\n {\n authentication: { action: \"View\", resource: \"file-upload\" },\n ...routeConfig,\n path: `${basePathname}*`,\n },\n ...processMiddleware(before),\n adjustRequestUrl,\n express.static(\n baseUploadDirFullPath,\n deepmerge(\n {\n maxAge: \"1y\",\n etag: true,\n lastModified: true,\n dotfiles: \"ignore\",\n fallthrough: false,\n index: false,\n cacheControl: true,\n },\n fileUpload?.expressStatic || {}\n )\n ),\n (\n err: any,\n req: ArkosRequest,\n _res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (err.code === \"ENOENT\") {\n const filepath = req.path.replace(\n `/api/${fileUpload?.baseRoute}`.replace(\"//\", \"/\"),\n \"\"\n );\n throw new AppError(\n `File ${filepath} was not found`,\n 404,\n \"FileNotFound\",\n { filepath }\n );\n }\n\n next(err);\n },\n ...processMiddleware(onError, { type: \"error\" })\n );\n }\n\n // UPLOAD FILE\n {\n const { before, after, onError, routeConfig } = op(\"uploadFile\");\n router.post(\n {\n authentication: { action: \"Create\", resource: \"file-upload\" },\n ...routeConfig,\n path: `${basePathname}:fileType`,\n },\n ...processMiddleware(before),\n fileUploadController.uploadFile,\n ...processMiddleware(after),\n sendResponse,\n ...processMiddleware(onError, { type: \"error\" })\n );\n }\n\n // UPDATE FILE\n {\n const { before, after, onError, routeConfig } = op(\"updateFile\");\n router.patch(\n {\n authentication: { action: \"Update\", resource: \"file-upload\" },\n ...routeConfig,\n path: `${basePathname}:fileType/:fileName`,\n },\n ...processMiddleware(before),\n fileUploadController.updateFile,\n ...processMiddleware(after),\n sendResponse,\n ...processMiddleware(onError, { type: \"error\" })\n );\n }\n\n // DELETE FILE\n {\n const { before, after, onError, routeConfig } = op(\"deleteFile\");\n router.delete(\n {\n authentication: { action: \"Delete\", resource: \"file-upload\" },\n ...routeConfig,\n path: `${basePathname}:fileType/:fileName`,\n },\n ...processMiddleware(before),\n fileUploadController.deleteFile,\n ...processMiddleware(after),\n sendResponse,\n ...processMiddleware(onError, { type: \"error\" })\n );\n }\n\n return router;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload.service.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.service.ts"],"names":[],"mappings":"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","sourcesContent":["import multer, { MulterError, StorageEngine } from \"multer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { NextFunction } from \"express\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport {\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { processFile, processImage } from \"./utils/helpers/file-upload.helpers\";\nimport { removeBothSlashes } from \"../../utils/helpers/text.helpers\";\nimport { pascalCase } from \"../../exports/utils\";\n\n/**\n * Service to handle file uploads, including single and multiple file uploads,\n * file validation (type, size), and file deletion.\n */\nexport class FileUploadService {\n public readonly uploadDir: string;\n private fileSizeLimit: number;\n private allowedFileTypes: RegExp;\n private storage: StorageEngine;\n private maxCount: number;\n\n private handleUploadError(err: any, next: ArkosNextFunction) {\n if (err instanceof MulterError)\n return next(\n new AppError(\n err.message,\n 400,\n pascalCase(err.code || \"FileUploadError\")\n )\n );\n else return next(err);\n }\n\n /**\n * Constructor to initialize the file uploader service.\n * @param {string} uploadDir - The directory where files will be uploaded.\n * @param {number} fileSizeLimit - The maximum allowed file size.\n * @param {RegExp} allowedFileTypes - The regular expression for allowed file types.\n */\n constructor(\n uploadDir: string,\n fileSizeLimit: number = 1024 * 1024 * 5,\n allowedFileTypes: RegExp = /.*/,\n maxCount: number = 30\n ) {\n uploadDir = uploadDir.startsWith(\"/\") ? uploadDir.substring(1) : uploadDir;\n uploadDir = uploadDir.endsWith(\"/\") ? uploadDir.slice(0, -1) : uploadDir;\n\n this.uploadDir = path.resolve(process.cwd(), `${uploadDir}/`);\n this.fileSizeLimit = fileSizeLimit;\n this.allowedFileTypes = allowedFileTypes;\n this.maxCount = maxCount;\n\n if (!fs.existsSync(this.uploadDir))\n fs.mkdirSync(this.uploadDir, { recursive: true });\n\n this.storage = multer.diskStorage({\n destination: (_, _1, cb) => {\n cb(null, this.uploadDir);\n },\n filename: (_, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n const ext = path.extname(file.originalname);\n cb(null, `${file.originalname.replace(ext, \"\")}-${uniqueSuffix}${ext}`);\n },\n });\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (_: any, file: any, cb: any) => {\n const extName = this.allowedFileTypes.test(\n path.extname(file.originalname).toLowerCase()\n );\n\n if (extName) cb(null, true);\n else\n cb(\n new AppError(\n `File type not allowed, allowed files are ${String(this.allowedFileTypes).replaceAll(\"/\", \"\").split(\"|\").join(\", \")}`,\n 400,\n \"FileTypeNotAllowed\",\n { filename: file.originalname }\n )\n );\n };\n\n /**\n * Returns the multer upload configuration.\n * @returns {multer.Multer} The multer instance configured for file uploads.\n */\n public getUpload(): multer.Multer {\n return multer({\n storage: this.storage,\n fileFilter: this.fileFilter,\n limits: { fileSize: this.fileSizeLimit },\n });\n }\n\n /**\n * Middleware to handle single file upload.\n * @param {string} [oldFilePath] - The path to the file to delete before uploading.\n * @returns {Function} Middleware function for handling file upload.\n */\n public handleSingleUpload(oldFilePath?: string): ArkosRequestHandler {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUpload().single(this.getFieldName());\n upload(req, res, async (err) => {\n if (err) return this.handleUploadError(err, next);\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n console.error(err);\n }\n }\n\n next();\n });\n };\n }\n\n /**\n * Middleware to handle multiple file uploads.\n * @returns {Function} Middleware function for handling multiple file uploads.\n */\n public handleMultipleUpload(): ArkosRequestHandler {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUpload().array(this.getFieldName(), this.maxCount);\n upload(req, res, next);\n };\n }\n\n /**\n * Middleware to handle deletion of a single file from the filesystem.\n * @param {string} oldFilePath - The path to the file to be deleted.\n * @returns {Function} Middleware function for handling file deletion.\n */\n public handleDeleteSingleFile(oldFilePath: string): ArkosRequestHandler {\n return async (_: ArkosRequest, _1: ArkosResponse, next: NextFunction) => {\n const filePath = path.join(oldFilePath);\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) {\n await promisify(fs.unlink)(filePath);\n }\n } catch (err) {\n console.error(err);\n }\n\n next();\n };\n }\n\n /**\n * Deletes a file based on its URL by identifying the appropriate uploader service\n * @param {string} fileUrl - The URL of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByUrl(fileUrl: string): Promise<boolean> {\n try {\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n let urlPath: string;\n if (fileUrl.startsWith(\"http\")) {\n const url = new URL(fileUrl);\n urlPath = url.pathname;\n } else urlPath = fileUrl;\n\n const baseRouteIndex = urlPath.indexOf(baseRoute);\n if (baseRouteIndex === -1)\n throw new AppError(\n \"Invalid file URL: base route not found\",\n 400,\n \"InvalidFileUrl\"\n );\n\n const pathAfterBaseRoute = urlPath.substring(\n baseRouteIndex + baseRoute.length\n );\n const cleanPath = pathAfterBaseRoute.startsWith(\"/\")\n ? pathAfterBaseRoute.substring(1)\n : pathAfterBaseRoute;\n\n const fileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n let fileType: string | null = null;\n let fileName: string | null = null;\n\n for (const type of fileTypes) {\n const typeIndex = cleanPath.indexOf(type + \"/\");\n if (typeIndex !== -1) {\n fileType = type;\n fileName = cleanPath.substring(typeIndex + type.length + 1);\n break;\n }\n }\n\n if (!fileType || !fileName) {\n throw new AppError(\n \"Unable to determine file type or file name from URL\",\n 400,\n \"UnableToProcessFileURL\"\n );\n }\n\n // Get the appropriate uploader service based on file type\n const {\n documentUploadService,\n fileUploadService,\n imageUploadService,\n videoUploadService,\n } = getFileUploadServices();\n\n let filePath: string;\n switch (fileType) {\n case \"images\":\n filePath = path.join(imageUploadService.uploadDir, fileName);\n break;\n case \"videos\":\n filePath = path.join(videoUploadService.uploadDir, fileName);\n break;\n case \"documents\":\n filePath = path.join(documentUploadService.uploadDir, fileName);\n break;\n case \"files\":\n filePath = path.join(fileUploadService.uploadDir, fileName);\n break;\n default:\n throw new AppError(\n `Unsupported file type: ${fileType}`,\n 400,\n \"UnsupportedFileType\"\n );\n }\n\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\")\n throw new AppError(\"File not found\", 404, \"FileNotFound\");\n\n throw new AppError(\n `Failed to delete file: ${error.message}`,\n 500,\n \"UnableToDeleteFile\"\n );\n }\n }\n\n private getFieldName() {\n let fieldName = \"files\";\n if (this.uploadDir.endsWith(\"images\") || this.uploadDir.endsWith(\"images/\"))\n fieldName = \"images\";\n if (this.uploadDir.endsWith(\"videos\") || this.uploadDir.endsWith(\"videos/\"))\n fieldName = \"videos\";\n if (\n this.uploadDir.endsWith(\"documents\") ||\n this.uploadDir.endsWith(\"documents/\")\n )\n fieldName = \"documents\";\n if (this.uploadDir.endsWith(\"files\") || this.uploadDir.endsWith(\"files/\"))\n fieldName = \"files\";\n return fieldName;\n }\n\n /**\n * Handles the upload process and returns the full URLs of uploaded files\n * @param {ArkosRequest} req - Arkos request object containing the files\n * @param {ArkosResponse} res - Arkos response object\n * @param {object} options - Optional parameters for image processing\n * @returns {Promise<string|string[]>} URL or array of URLs to the uploaded files\n */\n public async upload(\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction,\n options: {\n format?: string;\n width?: number;\n height?: number;\n resizeTo?: number;\n } = {}\n ): Promise<string | string[] | null> {\n const { fileUpload } = getArkosConfig();\n fileUpload?.baseRoute || \"/api/uploads\";\n\n return new Promise((resolve, reject) => {\n const isMultiple = Array.isArray(req.query.multiple)\n ? req.query.multiple[0] == \"true\"\n : req.query.multiple == \"true\";\n\n const uploadHandler = isMultiple\n ? this.getUpload().array(this.getFieldName(), this.maxCount)\n : this.getUpload().single(this.getFieldName());\n\n uploadHandler(req, res, async (err) => {\n if (err && err instanceof MulterError)\n return reject(\n new AppError(\n err.message,\n 400,\n pascalCase(err.code || \"FileUploadError\")\n )\n );\n else if (err) reject(err);\n\n try {\n const dirParts = this.uploadDir.split(\"/\");\n (this.uploadDir.endsWith(\"/\")\n ? dirParts[dirParts.length - 2]\n : dirParts[dirParts.length - 1]) || \"files\";\n\n let data;\n if (req.files && Array.isArray(req.files) && req.files.length > 0) {\n const isImageUpload = this.uploadDir?.includes?.(\"/images\");\n if (isImageUpload) {\n data = await Promise.all(\n req.files.map((file) =>\n processImage(req, next, file.path, options)\n )\n );\n } else {\n data = await Promise.all(\n req.files.map((file) => processFile(req, file.path))\n );\n }\n\n data = data.filter((url) => url !== null);\n } else if (req.file) {\n const isImageUpload = this.uploadDir?.includes?.(\"/images\");\n if (isImageUpload) {\n data = await processImage(req, next, req.file.path, options);\n } else {\n data = await processFile(req, req.file.path);\n }\n } else {\n return reject(\n new AppError(\n `No file or files were attached on field ${req.params.fileType} on the request body as form data.`,\n 400,\n \"NoFileOrFilesAttached\"\n )\n );\n }\n\n resolve(data);\n } catch (error) {\n reject(error);\n }\n });\n });\n }\n\n /**\n * Deletes a file based on filename and file type from request parameters\n * @param {string} fileName - The name of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByName(\n fileName: string,\n fileType: \"images\" | \"videos\" | \"documents\" | \"files\"\n ): Promise<boolean> {\n try {\n if (!fileType)\n throw new AppError(\n \"File type parameter is required\",\n 400,\n \"MissingFileType\"\n );\n\n const validFileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n if (!validFileTypes.includes(fileType)) {\n throw new AppError(\n `Invalid file type: ${fileType}. Must be one of: ${validFileTypes.join(\n \", \"\n )}`,\n 400\n );\n }\n\n const {\n documentUploadService,\n fileUploadService,\n imageUploadService,\n videoUploadService,\n } = getFileUploadServices();\n\n let targetService: FileUploadService;\n switch (fileType) {\n case \"images\":\n targetService = imageUploadService;\n break;\n case \"videos\":\n targetService = videoUploadService;\n break;\n case \"documents\":\n targetService = documentUploadService;\n break;\n case \"files\":\n targetService = fileUploadService;\n break;\n default:\n throw new AppError(`Unsupported file type: ${fileType}`, 400);\n }\n\n // Construct the full file path\n const filePath = path.join(targetService.uploadDir, fileName);\n\n // Check if file exists and delete it\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\")\n throw new AppError(\"File not found\", 404, \"FileNotFound\");\n\n throw new AppError(\n `Failed to delete file: ${error.message}`,\n 500,\n \"UnableToDeleteFile\"\n );\n }\n }\n}\n\n/**\n * Creates and returns all file uploader services based on config\n * @returns Object containing all specialized file uploader services\n */\nexport const getFileUploadServices = () => {\n const { fileUpload } = getArkosConfig();\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n const restrictions = fileUpload?.restrictions\n ? deepmerge(fileUploadDefaultRestrictions, fileUpload.restrictions)\n : fileUploadDefaultRestrictions;\n\n /**\n * Specialized file uploader service for handling image uploads.\n */\n const imageUploadService = new FileUploadService(\n `${baseUploadDir}/images`,\n restrictions.images.maxSize,\n restrictions.images.supportedFilesRegex,\n restrictions.images.maxCount\n );\n\n /**\n * Specialized file uploader service for handling video uploads.\n */\n const videoUploadService = new FileUploadService(\n `${baseUploadDir}/videos`,\n restrictions.videos.maxSize,\n restrictions.videos.supportedFilesRegex,\n restrictions.videos.maxCount\n );\n\n /**\n * Specialized file uploader service for handling document uploads.\n */\n const documentUploadService = new FileUploadService(\n `${baseUploadDir}/documents`,\n restrictions.documents.maxSize,\n restrictions.documents.supportedFilesRegex,\n restrictions.documents.maxCount\n );\n\n /**\n * Generic file uploader service for handling all file uploads.\n */\n const fileUploadService = new FileUploadService(\n `${baseUploadDir}/files`,\n restrictions.files.maxSize,\n restrictions.files.supportedFilesRegex,\n restrictions.files.maxCount\n );\n\n return {\n imageUploadService,\n videoUploadService,\n documentUploadService,\n fileUploadService,\n };\n};\n\nexport const fileUploadDefaultRestrictions = {\n images: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 15, // 15 MB\n supportedFilesRegex:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n },\n videos: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n },\n documents: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 50, // 50 MB\n supportedFilesRegex:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n },\n files: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex: /.*/,\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"file-upload.service.js","sourceRoot":"","sources":["../../../../src/modules/file-upload/file-upload.service.ts"],"names":[],"mappings":"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","sourcesContent":["import multer, { MulterError, StorageEngine } from \"multer\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { NextFunction } from \"express\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport { promisify } from \"util\";\nimport { getArkosConfig } from \"../../server\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport {\n ArkosNextFunction,\n ArkosRequest,\n ArkosRequestHandler,\n ArkosResponse,\n} from \"../../types\";\nimport { processFile, processImage } from \"./utils/helpers/file-upload.helpers\";\nimport { removeBothSlashes } from \"../../utils/helpers/text.helpers\";\nimport { pascalCase } from \"../../exports/utils\";\n\n/**\n * Service to handle file uploads, including single and multiple file uploads,\n * file validation (type, size), and file deletion.\n */\nexport class FileUploadService {\n public readonly uploadDir: string;\n private fileSizeLimit: number;\n private allowedFileTypes: RegExp;\n private storage: StorageEngine;\n private maxCount: number;\n\n private handleUploadError(err: any, next: ArkosNextFunction) {\n if (err instanceof MulterError)\n return next(\n new AppError(\n err.message,\n 400,\n pascalCase(err.code || \"FileUploadError\")\n )\n );\n else return next(err);\n }\n\n /**\n * Constructor to initialize the file uploader service.\n * @param {string} uploadDir - The directory where files will be uploaded.\n * @param {number} fileSizeLimit - The maximum allowed file size.\n * @param {RegExp} allowedFileTypes - The regular expression for allowed file types.\n */\n constructor(\n uploadDir: string,\n fileSizeLimit: number = 1024 * 1024 * 5,\n allowedFileTypes: RegExp = /.*/,\n maxCount: number = 30\n ) {\n uploadDir = uploadDir.startsWith(\"/\") ? uploadDir.substring(1) : uploadDir;\n uploadDir = uploadDir.endsWith(\"/\") ? uploadDir.slice(0, -1) : uploadDir;\n\n this.uploadDir = path.resolve(process.cwd(), `${uploadDir}/`);\n this.fileSizeLimit = fileSizeLimit;\n this.allowedFileTypes = allowedFileTypes;\n this.maxCount = maxCount;\n\n if (!fs.existsSync(this.uploadDir))\n fs.mkdirSync(this.uploadDir, { recursive: true });\n\n this.storage = multer.diskStorage({\n destination: (_, _1, cb) => {\n cb(null, this.uploadDir);\n },\n filename: (_, file, cb) => {\n const uniqueSuffix = Date.now() + \"-\" + Math.round(Math.random() * 1e9);\n const ext = path.extname(file.originalname);\n cb(null, `${file.originalname.replace(ext, \"\")}-${uniqueSuffix}${ext}`);\n },\n });\n }\n\n /**\n * Validates the file's type and MIME type.\n * @param {Express.Multer.File} file - The uploaded file.\n * @param {Function} cb - The callback function to indicate if file is valid.\n */\n private fileFilter = (_: any, file: any, cb: any) => {\n const extName = this.allowedFileTypes.test(\n path.extname(file.originalname).toLowerCase()\n );\n\n if (extName) cb(null, true);\n else\n cb(\n new AppError(\n `File type not allowed, allowed files are ${String(this.allowedFileTypes).replaceAll(\"/\", \"\").split(\"|\").join(\", \")}`,\n 400,\n \"FileTypeNotAllowed\",\n { filename: file.originalname }\n )\n );\n };\n\n /**\n * Returns the multer upload configuration.\n * @returns {multer.Multer} The multer instance configured for file uploads.\n */\n public getUpload(): multer.Multer {\n return multer({\n storage: this.storage,\n fileFilter: this.fileFilter,\n limits: { fileSize: this.fileSizeLimit },\n });\n }\n\n /**\n * Middleware to handle single file upload.\n * @param {string} [oldFilePath] - The path to the file to delete before uploading.\n * @returns {Function} Middleware function for handling file upload.\n */\n public handleSingleUpload(oldFilePath?: string): ArkosRequestHandler {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUpload().single(this.getFieldName());\n upload(req, res, async (err) => {\n if (err) return this.handleUploadError(err, next);\n\n if (oldFilePath) {\n const { fileUpload: configs } = getArkosConfig();\n\n const filePath = path.resolve(\n process.cwd(),\n removeBothSlashes(configs?.baseUploadDir!),\n removeBothSlashes(oldFilePath)\n );\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) await promisify(fs.unlink)(filePath);\n } catch (err) {\n console.error(err);\n }\n }\n\n next();\n });\n };\n }\n\n /**\n * Middleware to handle multiple file uploads.\n * @returns {Function} Middleware function for handling multiple file uploads.\n */\n public handleMultipleUpload(): ArkosRequestHandler {\n return (req: ArkosRequest, res: ArkosResponse, next: NextFunction) => {\n const upload = this.getUpload().array(this.getFieldName(), this.maxCount);\n upload(req, res, next);\n };\n }\n\n /**\n * Middleware to handle deletion of a single file from the filesystem.\n * @param {string} oldFilePath - The path to the file to be deleted.\n * @returns {Function} Middleware function for handling file deletion.\n */\n public handleDeleteSingleFile(oldFilePath: string): ArkosRequestHandler {\n return async (_: ArkosRequest, _1: ArkosResponse, next: NextFunction) => {\n const filePath = path.join(oldFilePath);\n try {\n const stats = await promisify(fs.stat)(filePath);\n if (stats) {\n await promisify(fs.unlink)(filePath);\n }\n } catch (err) {\n console.error(err);\n }\n\n next();\n };\n }\n\n /**\n * Deletes a file based on its URL by identifying the appropriate uploader service\n * @param {string} fileUrl - The URL of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByUrl(fileUrl: string): Promise<boolean> {\n try {\n const { fileUpload } = getArkosConfig();\n const baseRoute = fileUpload?.baseRoute || \"/api/uploads\";\n\n let urlPath: string;\n if (fileUrl.startsWith(\"http\")) {\n const url = new URL(fileUrl);\n urlPath = url.pathname;\n } else urlPath = fileUrl;\n\n const baseRouteIndex = urlPath.indexOf(baseRoute);\n if (baseRouteIndex === -1)\n throw new AppError(\n \"Invalid file URL: base route not found\",\n 400,\n \"InvalidFileUrl\"\n );\n\n const pathAfterBaseRoute = urlPath.substring(\n baseRouteIndex + baseRoute.length\n );\n const cleanPath = pathAfterBaseRoute.startsWith(\"/\")\n ? pathAfterBaseRoute.substring(1)\n : pathAfterBaseRoute;\n\n const fileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n let fileType: string | null = null;\n let fileName: string | null = null;\n\n for (const type of fileTypes) {\n const typeIndex = cleanPath.indexOf(type + \"/\");\n if (typeIndex !== -1) {\n fileType = type;\n fileName = cleanPath.substring(typeIndex + type.length + 1);\n break;\n }\n }\n\n if (!fileType || !fileName) {\n throw new AppError(\n \"Unable to determine file type or file name from URL\",\n 400,\n \"UnableToProcessFileURL\"\n );\n }\n\n // Get the appropriate uploader service based on file type\n const {\n documentUploadService,\n fileUploadService,\n imageUploadService,\n videoUploadService,\n } = getFileUploadServices();\n\n let filePath: string;\n switch (fileType) {\n case \"images\":\n filePath = path.join(imageUploadService.uploadDir, fileName);\n break;\n case \"videos\":\n filePath = path.join(videoUploadService.uploadDir, fileName);\n break;\n case \"documents\":\n filePath = path.join(documentUploadService.uploadDir, fileName);\n break;\n case \"files\":\n filePath = path.join(fileUploadService.uploadDir, fileName);\n break;\n default:\n throw new AppError(\n `Unsupported file type: ${fileType}`,\n 400,\n \"UnsupportedFileType\"\n );\n }\n\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\")\n throw new AppError(\"File not found\", 404, \"FileNotFound\");\n\n throw new AppError(\n `Failed to delete file: ${error.message}`,\n 500,\n \"UnableToDeleteFile\"\n );\n }\n }\n\n private getFieldName() {\n let fieldName = \"files\";\n if (this.uploadDir.endsWith(\"images\") || this.uploadDir.endsWith(\"images/\"))\n fieldName = \"images\";\n if (this.uploadDir.endsWith(\"videos\") || this.uploadDir.endsWith(\"videos/\"))\n fieldName = \"videos\";\n if (\n this.uploadDir.endsWith(\"documents\") ||\n this.uploadDir.endsWith(\"documents/\")\n )\n fieldName = \"documents\";\n if (this.uploadDir.endsWith(\"files\") || this.uploadDir.endsWith(\"files/\"))\n fieldName = \"files\";\n return fieldName;\n }\n\n /**\n * Handles the upload process and returns the full URLs of uploaded files\n * @param {ArkosRequest} req - Arkos request object containing the files\n * @param {ArkosResponse} res - Arkos response object\n * @param {object} options - Optional parameters for image processing\n * @returns {Promise<string|string[]>} URL or array of URLs to the uploaded files\n */\n public async upload(\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction,\n options: {\n format?: string;\n width?: number;\n height?: number;\n resizeTo?: number;\n } = {}\n ): Promise<string | string[] | null> {\n const { fileUpload } = getArkosConfig();\n fileUpload?.baseRoute || \"/api/uploads\";\n\n return new Promise((resolve, reject) => {\n const isMultiple = Array.isArray(req.query.multiple)\n ? req.query.multiple[0] == \"true\"\n : req.query.multiple == \"true\";\n\n const uploadHandler = isMultiple\n ? this.getUpload().array(this.getFieldName(), this.maxCount)\n : this.getUpload().single(this.getFieldName());\n\n uploadHandler(req, res, async (err) => {\n if (err && err instanceof MulterError)\n return reject(\n new AppError(\n err.message,\n 400,\n pascalCase(err.code || \"FileUploadError\")\n )\n );\n else if (err) reject(err);\n\n try {\n const dirParts = this.uploadDir.split(\"/\");\n (this.uploadDir.endsWith(\"/\")\n ? dirParts[dirParts.length - 2]\n : dirParts[dirParts.length - 1]) || \"files\";\n\n let data;\n if (req.files && Array.isArray(req.files) && req.files.length > 0) {\n const isImageUpload = this.uploadDir?.includes?.(\"/images\");\n if (isImageUpload) {\n data = await Promise.all(\n req.files.map((file) =>\n processImage(req, next, file.path, options)\n )\n );\n } else {\n data = await Promise.all(\n req.files.map((file) => processFile(req, file.path))\n );\n }\n\n data = data.filter((url) => url !== null);\n } else if (req.file) {\n const isImageUpload = this.uploadDir?.includes?.(\"/images\");\n if (isImageUpload) {\n data = await processImage(req, next, req.file.path, options);\n } else {\n data = processFile(req, req.file.path);\n }\n } else {\n return reject(\n new AppError(\n `No file or files were attached on field ${req.params.fileType} on the request body as form data.`,\n 400,\n \"NoFileOrFilesAttached\"\n )\n );\n }\n\n resolve(data);\n } catch (error) {\n reject(error);\n }\n });\n });\n }\n\n /**\n * Deletes a file based on filename and file type from request parameters\n * @param {string} fileName - The name of the file to delete\n * @returns {Promise<boolean>} - True if deletion successful, false otherwise\n */\n public async deleteFileByName(\n fileName: string,\n fileType: \"images\" | \"videos\" | \"documents\" | \"files\"\n ): Promise<boolean> {\n try {\n if (!fileType)\n throw new AppError(\n \"File type parameter is required\",\n 400,\n \"MissingFileType\"\n );\n\n const validFileTypes = [\"images\", \"videos\", \"documents\", \"files\"];\n if (!validFileTypes.includes(fileType)) {\n throw new AppError(\n `Invalid file type: ${fileType}. Must be one of: ${validFileTypes.join(\n \", \"\n )}`,\n 400\n );\n }\n\n const {\n documentUploadService,\n fileUploadService,\n imageUploadService,\n videoUploadService,\n } = getFileUploadServices();\n\n let targetService: FileUploadService;\n switch (fileType) {\n case \"images\":\n targetService = imageUploadService;\n break;\n case \"videos\":\n targetService = videoUploadService;\n break;\n case \"documents\":\n targetService = documentUploadService;\n break;\n case \"files\":\n targetService = fileUploadService;\n break;\n default:\n throw new AppError(`Unsupported file type: ${fileType}`, 400);\n }\n\n // Construct the full file path\n const filePath = path.join(targetService.uploadDir, fileName);\n\n // Check if file exists and delete it\n await promisify(fs.stat)(filePath);\n await promisify(fs.unlink)(filePath);\n\n return true;\n } catch (error: any) {\n if (error instanceof AppError) {\n throw error;\n }\n\n if (error.code === \"ENOENT\")\n throw new AppError(\"File not found\", 404, \"FileNotFound\");\n\n throw new AppError(\n `Failed to delete file: ${error.message}`,\n 500,\n \"UnableToDeleteFile\"\n );\n }\n }\n}\n\n/**\n * Creates and returns all file uploader services based on config\n * @returns Object containing all specialized file uploader services\n */\nexport const getFileUploadServices = () => {\n const { fileUpload } = getArkosConfig();\n const baseUploadDir = fileUpload?.baseUploadDir || \"/uploads\";\n\n const restrictions = fileUpload?.restrictions\n ? deepmerge(fileUploadDefaultRestrictions, fileUpload.restrictions)\n : fileUploadDefaultRestrictions;\n\n /**\n * Specialized file uploader service for handling image uploads.\n */\n const imageUploadService = new FileUploadService(\n `${baseUploadDir}/images`,\n restrictions.images.maxSize,\n restrictions.images.supportedFilesRegex,\n restrictions.images.maxCount\n );\n\n /**\n * Specialized file uploader service for handling video uploads.\n */\n const videoUploadService = new FileUploadService(\n `${baseUploadDir}/videos`,\n restrictions.videos.maxSize,\n restrictions.videos.supportedFilesRegex,\n restrictions.videos.maxCount\n );\n\n /**\n * Specialized file uploader service for handling document uploads.\n */\n const documentUploadService = new FileUploadService(\n `${baseUploadDir}/documents`,\n restrictions.documents.maxSize,\n restrictions.documents.supportedFilesRegex,\n restrictions.documents.maxCount\n );\n\n /**\n * Generic file uploader service for handling all file uploads.\n */\n const fileUploadService = new FileUploadService(\n `${baseUploadDir}/files`,\n restrictions.files.maxSize,\n restrictions.files.supportedFilesRegex,\n restrictions.files.maxCount\n );\n\n return {\n imageUploadService,\n videoUploadService,\n documentUploadService,\n fileUploadService,\n };\n};\n\nexport const fileUploadDefaultRestrictions = {\n images: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 15, // 15 MB\n supportedFilesRegex:\n /jpeg|jpg|png|gif|webp|svg|bmp|tiff|heif|heic|ico|jfif|raw|cr2|nef|orf|sr2|arw|dng|pef|raf|rw2|psd|ai|eps|xcf|jxr|wdp|hdp|jp2|j2k|jpf|jpx|jpm|mj2|avif/,\n },\n videos: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex:\n /mp4|avi|mov|mkv|flv|wmv|webm|mpg|mpeg|3gp|m4v|ts|rm|rmvb|vob|ogv|dv|qt|asf|m2ts|mts|divx|f4v|swf|mxf|roq|nsv|mvb|svi|mpe|m2v|mp2|mpv|h264|h265|hevc/,\n },\n documents: {\n maxCount: 30,\n maxSize: 1024 * 1024 * 50, // 50 MB\n supportedFilesRegex:\n /pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odg|odp|txt|rtf|csv|epub|md|tex|pages|numbers|key|xml|json|yaml|yml|ini|cfg|conf|log|html|htm|xhtml|djvu|mobi|azw|azw3|fb2|lit|ps|wpd|wps|dot|dotx|xlt|xltx|pot|potx|oft|one|onetoc2|opf|oxps|hwp/,\n },\n files: {\n maxCount: 10,\n maxSize: 1024 * 1024 * 5096, // 5 GB\n supportedFilesRegex: /.*/,\n },\n};\n"]}
|
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
1
|
import swaggerJsdoc from "swagger-jsdoc";
|
|
3
2
|
import getSwaggerDefaultConfig from "./utils/helpers/get-swagger-default-configs.js";
|
|
4
3
|
import { importEsmPreventingTsTransformation } from "../../utils/helpers/global.helpers.js";
|
|
5
|
-
import { generateOpenAPIFromApp } from "../../utils/arkos-router/index.js";
|
|
4
|
+
import ArkosRouter, { generateOpenAPIFromApp } from "../../utils/arkos-router/index.js";
|
|
6
5
|
import deepmerge from "../../utils/helpers/deepmerge.helper.js";
|
|
7
|
-
import authService from "../auth/auth.service.js";
|
|
8
6
|
import AppError from "../error-handler/utils/app-error.js";
|
|
9
7
|
import getOpenApiLoginHtml from "./utils/get-open-api-login-html.js";
|
|
10
|
-
|
|
8
|
+
import { isProduction } from "../../utils/helpers/arkos-config.helpers.js";
|
|
9
|
+
const swaggerRouter = ArkosRouter();
|
|
11
10
|
export function getSwaggerRouter(arkosConfig, app) {
|
|
12
11
|
const pathsFromCustomArkosRouters = generateOpenAPIFromApp(app);
|
|
13
12
|
const defaultSwaggerConfig = getSwaggerDefaultConfig({
|
|
14
13
|
...pathsFromCustomArkosRouters,
|
|
15
14
|
});
|
|
16
15
|
const swaggerConfigs = deepmerge(defaultSwaggerConfig, arkosConfig.swagger || {});
|
|
17
|
-
if (arkosConfig.swagger?.options?.definition?.servers &&
|
|
16
|
+
if (arkosConfig.swagger?.options?.definition?.servers &&
|
|
17
|
+
swaggerConfigs &&
|
|
18
|
+
isProduction()) {
|
|
18
19
|
swaggerConfigs.options.definition.servers =
|
|
19
20
|
arkosConfig.swagger.options.definition.servers;
|
|
20
21
|
swaggerConfigs.options.definition.servers.push(defaultSwaggerConfig.options.definition.servers[0]);
|
|
@@ -28,12 +29,12 @@ export function getSwaggerRouter(arkosConfig, app) {
|
|
|
28
29
|
const swaggerAuth = arkosConfig?.swagger;
|
|
29
30
|
const authenticate = swaggerAuth?.authenticate !== false;
|
|
30
31
|
if (authenticate) {
|
|
31
|
-
swaggerRouter.use(endpoint, (req, _, next) => {
|
|
32
|
+
swaggerRouter.use({ path: endpoint }, (req, _, next) => {
|
|
32
33
|
if (req.path.includes("/auth"))
|
|
33
34
|
return next();
|
|
34
35
|
next("route");
|
|
35
36
|
});
|
|
36
|
-
swaggerRouter.use(
|
|
37
|
+
swaggerRouter.use({ authentication: true, path: endpoint }, (req, _, next) => {
|
|
37
38
|
if (!req.user?.isSuperUser)
|
|
38
39
|
return next(new AppError("Only super users can access API documentation in production.", 403, "SuperUserRequired"));
|
|
39
40
|
next();
|
|
@@ -44,14 +45,14 @@ export function getSwaggerRouter(arkosConfig, app) {
|
|
|
44
45
|
return res.redirect(`${arkosConfig.globalPrefix}${endpoint}/auth/login?error-message=${message}`);
|
|
45
46
|
});
|
|
46
47
|
}
|
|
47
|
-
swaggerRouter.get(`${endpoint}/auth/login
|
|
48
|
+
swaggerRouter.get({ path: `${endpoint}/auth/login` }, (_, res) => {
|
|
48
49
|
res.send(getOpenApiLoginHtml());
|
|
49
50
|
});
|
|
50
|
-
swaggerRouter.get(`${endpoint}/openapi.json
|
|
51
|
+
swaggerRouter.get({ path: `${endpoint}/openapi.json` }, (_, res) => {
|
|
51
52
|
res.json(swaggerSpecification);
|
|
52
53
|
});
|
|
53
54
|
let scalarHandler = null;
|
|
54
|
-
swaggerRouter.use(endpoint, scalarMiddleware(scalarHandler, swaggerSpecification, swaggerConfigs));
|
|
55
|
+
swaggerRouter.use({ path: endpoint }, scalarMiddleware(scalarHandler, swaggerSpecification, swaggerConfigs));
|
|
55
56
|
return swaggerRouter;
|
|
56
57
|
}
|
|
57
58
|
export function scalarMiddleware(scalarHandler, swaggerSpecification, swaggerConfigs) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swagger.router.js","sourceRoot":"","sources":["../../../../src/modules/swagger/swagger.router.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"swagger.router.js","sourceRoot":"","sources":["../../../../src/modules/swagger/swagger.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { Router } from \"express\";\nimport swaggerJsdoc from \"swagger-jsdoc\";\nimport getSwaggerDefaultConfig from \"./utils/helpers/get-swagger-default-configs\";\nimport { importEsmPreventingTsTransformation } from \"../../utils/helpers/global.helpers\";\nimport ArkosRouter, { generateOpenAPIFromApp } from \"../../utils/arkos-router\";\nimport {\n ArkosConfig,\n ArkosNextFunction,\n ArkosRequest,\n ArkosResponse,\n} from \"../../exports\";\nimport deepmerge from \"../../utils/helpers/deepmerge.helper\";\nimport { Arkos } from \"../../types/arkos\";\nimport { UserArkosConfig } from \"../../utils/define-config\";\nimport AppError from \"../error-handler/utils/app-error\";\nimport getOpenApiLoginHtml from \"./utils/get-open-api-login-html\";\nimport { isProduction } from \"../../utils/helpers/arkos-config.helpers\";\n\nconst swaggerRouter = ArkosRouter();\n\nexport function getSwaggerRouter(\n arkosConfig: UserArkosConfig,\n app: Arkos\n): Router {\n const pathsFromCustomArkosRouters = generateOpenAPIFromApp(app);\n const defaultSwaggerConfig = getSwaggerDefaultConfig({\n ...pathsFromCustomArkosRouters,\n })!;\n\n const swaggerConfigs = deepmerge(\n defaultSwaggerConfig,\n arkosConfig.swagger || {}\n ) as ArkosConfig[\"swagger\"];\n\n if (\n arkosConfig.swagger?.options?.definition?.servers &&\n swaggerConfigs &&\n isProduction()\n ) {\n swaggerConfigs!.options!.definition!.servers =\n arkosConfig.swagger.options.definition.servers;\n\n swaggerConfigs!.options!.definition!.servers.push(\n defaultSwaggerConfig.options.definition.servers[0]\n );\n }\n\n const { definition, ...options } = swaggerConfigs?.options!;\n const swaggerSpecification = swaggerJsdoc({\n definition: definition as swaggerJsdoc.SwaggerDefinition,\n ...options,\n });\n\n const endpoint = swaggerConfigs!.endpoint!;\n\n const swaggerAuth = arkosConfig?.swagger;\n const authenticate = swaggerAuth?.authenticate !== false;\n\n if (authenticate) {\n swaggerRouter.use(\n { path: endpoint },\n (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (req.path.includes(\"/auth\")) return next();\n next(\"route\"); // skip to auth chain below\n }\n );\n\n swaggerRouter.use(\n { authentication: true, path: endpoint },\n (req: ArkosRequest, _: ArkosResponse, next: ArkosNextFunction) => {\n if (!req.user?.isSuperUser)\n return next(\n new AppError(\n \"Only super users can access API documentation in production.\",\n 403,\n \"SuperUserRequired\"\n )\n );\n next();\n },\n (\n err: AppError,\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (req.path.includes(\"/auth\")) return next();\n const message = encodeURIComponent(\n err?.message || \"Authentication required.\"\n );\n return res.redirect(\n `${arkosConfig.globalPrefix}${endpoint}/auth/login?error-message=${message}`\n );\n }\n );\n }\n\n swaggerRouter.get(\n { path: `${endpoint}/auth/login` },\n (_: ArkosRequest, res: ArkosResponse) => {\n res.send(getOpenApiLoginHtml());\n }\n );\n\n swaggerRouter.get(\n { path: `${endpoint}/openapi.json` },\n (_: ArkosRequest, res: ArkosResponse) => {\n res.json(swaggerSpecification);\n }\n );\n\n let scalarHandler: any = null;\n\n swaggerRouter.use(\n { path: endpoint },\n scalarMiddleware(scalarHandler, swaggerSpecification, swaggerConfigs)\n );\n\n return swaggerRouter;\n}\n\nexport function scalarMiddleware(\n scalarHandler: any,\n swaggerSpecification: object,\n swaggerConfigs: any\n) {\n let scalarLoading: Promise<void> | null = null;\n\n return async (\n req: ArkosRequest,\n res: ArkosResponse,\n next: ArkosNextFunction\n ) => {\n if (!scalarHandler) {\n if (!scalarLoading) {\n scalarLoading = importEsmPreventingTsTransformation(\n \"@scalar/express-api-reference\"\n ).then((scalar) => {\n scalarHandler = scalar.apiReference({\n content: swaggerSpecification,\n ...swaggerConfigs?.scalarApiReferenceConfiguration,\n });\n });\n }\n await scalarLoading;\n }\n return scalarHandler(req, res, next);\n };\n}\n"]}
|
|
@@ -241,13 +241,15 @@ export default function getOpenApiLoginHtml() {
|
|
|
241
241
|
.trim();
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
${allowedUsernames.length > 1 &&
|
|
245
|
+
`if (usernameSelect) {
|
|
245
246
|
usernameSelect.addEventListener('change', () => {
|
|
246
247
|
const label = formatFieldLabel(usernameSelect.value);
|
|
247
248
|
usernameLabel.textContent = label;
|
|
248
249
|
usernameField.placeholder = \`Enter your \${label.toLowerCase()}\`;
|
|
249
250
|
});
|
|
250
251
|
}
|
|
252
|
+
`}
|
|
251
253
|
|
|
252
254
|
const params = new URLSearchParams(window.location.search);
|
|
253
255
|
const urlErrorMessage = params.get('error-message');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-open-api-login-html.js","sourceRoot":"","sources":["../../../../../src/modules/swagger/utils/get-open-api-login-html.ts"],"names":[],"mappings":"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","sourcesContent":["import { getArkosConfig } from \"../../../server\";\n\nfunction formatFieldLabel(field: string): string {\n const last = field.split(\".\").pop()!;\n return last\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (c) => c.toUpperCase())\n .trim();\n}\n\nexport default function getOpenApiLoginHtml() {\n const arkosConfig = getArkosConfig();\n\n const theme =\n arkosConfig?.swagger?.scalarApiReferenceConfiguration?.theme || \"default\";\n\n const allowedUsernames = arkosConfig?.authentication?.login?.allowedUsernames\n ?.length\n ? arkosConfig.authentication.login.allowedUsernames\n : [\"username\"];\n\n const themeColors: Record<\n string,\n { bg: string; surface: string; border: string }\n > = {\n default: { bg: \"#0f0f0f\", surface: \"#1a1a1a\", border: \"#2e2e2e\" },\n moon: { bg: \"#0f1117\", surface: \"#1c1e26\", border: \"#2e3040\" },\n purple: { bg: \"#0d0d14\", surface: \"#1a1a2e\", border: \"#2e2e4a\" },\n solarized: { bg: \"#002b36\", surface: \"#073642\", border: \"#124652\" },\n bluePlanet: { bg: \"#070b14\", surface: \"#0d1424\", border: \"#1a2540\" },\n saturn: { bg: \"#0a0a0f\", surface: \"#16161f\", border: \"#28283a\" },\n kepler: { bg: \"#0a0f0a\", surface: \"#141f14\", border: \"#253525\" },\n mars: { bg: \"#0f0a08\", surface: \"#1f1410\", border: \"#352520\" },\n deepSpace: { bg: \"#0a0a0a\", surface: \"#121212\", border: \"#3a3a3a\" },\n };\n\n const colors = themeColors[theme] ?? themeColors[\"default\"];\n\n const firstLabel = formatFieldLabel(allowedUsernames[0]);\n const showSelect = allowedUsernames.length > 1;\n const title =\n arkosConfig?.swagger?.options?.definition?.info?.title ||\n \"Arkos.js OpenAPI Documentation\";\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title}</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: ${colors.bg};\n padding: 8px;\n }\n\n .login-container {\n background-color: ${colors.surface};\n padding: 40px;\n border: 1px solid ${colors.border};\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n }\n\n h1 {\n color: #ffffff;\n text-align: center;\n margin-bottom: 30px;\n font-size: 24px;\n font-weight: 600;\n }\n\n h2 {\n color: #ffffff;\n text-align: center;\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 500;\n }\n\n .form-group {\n margin-bottom: 20px;\n }\n\n label {\n display: block;\n color: #ffffff;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n }\n\n input[type=\"text\"],\n input[type=\"password\"] {\n width: 100%;\n padding: 12px 16px;\n background-color: ${colors.bg};\n border: 1px solid ${colors.border};\n border-radius: 4px;\n color: #ffffff;\n font-size: 14px;\n transition: border-color 0.3s;\n }\n\n select {\n width: 100%;\n padding: 12px 16px;\n background-color: ${colors.bg};\n border: 1px solid ${colors.border};\n border-radius: 4px;\n color: #ffffff;\n font-size: 14px;\n transition: border-color 0.3s;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n cursor: pointer;\n /* custom arrow */\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 16px center;\n }\n\n input[type=\"text\"]:focus,\n input[type=\"password\"]:focus,\n select:focus {\n outline: none;\n border-color: #ffffff;\n }\n\n input[type=\"text\"]::placeholder,\n input[type=\"password\"]::placeholder {\n color: #666666;\n }\n\n select option {\n background-color: ${colors.surface};\n color: #ffffff;\n }\n\n .login-button {\n width: 100%;\n padding: 12px;\n background-color: #ffffff;\n color: #1a1a1a;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.3s;\n }\n\n .login-button:hover { background-color: #e0e0e0; }\n .login-button:active { transform: translateY(1px); }\n .login-button:disabled { background-color: #666666; cursor: not-allowed; }\n\n .error-message {\n color: #ff6b6b;\n font-size: 14px;\n margin-top: 10px;\n text-align: center;\n display: none;\n }\n\n .error-message.show { display: block; }\n\n .page-footer {\n position: fixed;\n bottom: 16px;\n width: 100%;\n text-align: center;\n font-size: 14px;\n color: #999999;\n }\n\n .page-footer a {\n color: #999999;\n text-decoration: underline;\n }\n </style>\n</head>\n<body>\n <div class=\"login-container\">\n <h1>${title}</h1>\n <h2>Login</h2>\n <form id=\"loginForm\">\n\n ${\n showSelect\n ? `\n <div class=\"form-group\">\n <label for=\"usernameSelect\">Login With</label>\n <select id=\"usernameSelect\">\n ${allowedUsernames\n .map(\n (f) => `\n <option value=\"${f}\">${formatFieldLabel(f)}</option>\n `\n )\n .join(\"\")}\n </select>\n </div>\n `\n : \"\"\n }\n\n <div class=\"form-group\">\n <label id=\"usernameLabel\" for=\"usernameField\">${firstLabel}</label>\n <input\n type=\"text\"\n id=\"usernameField\"\n placeholder=\"Enter your ${firstLabel.toLowerCase()}\"\n required\n >\n </div>\n\n <div class=\"form-group\">\n <label for=\"password\">Password</label>\n <input\n type=\"password\"\n id=\"password\"\n placeholder=\"Enter your password\"\n required\n >\n </div>\n\n <button type=\"submit\" class=\"login-button\" id=\"loginButton\">Login</button>\n <div class=\"error-message\" id=\"errorMessage\"></div>\n\n </form>\n </div>\n\n <footer class=\"page-footer\">\n Powered by <a href=\"https://www.arkosjs.com\" target=\"_blank\" rel=\"noopener noreferrer\">Arkos.js</a>\n </footer>\n\n <script>\n const usernameLabel = document.getElementById('usernameLabel');\n const usernameField = document.getElementById('usernameField');\n const usernameSelect = document.getElementById('usernameSelect');\n const loginButton = document.getElementById('loginButton');\n const errorMessage = document.getElementById('errorMessage');\n\n function formatFieldLabel(field) {\n const last = field.split('.').pop();\n return last\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, c => c.toUpperCase())\n .trim();\n }\n\n if (usernameSelect) {\n usernameSelect.addEventListener('change', () => {\n const label = formatFieldLabel(usernameSelect.value);\n usernameLabel.textContent = label;\n usernameField.placeholder = \\`Enter your \\${label.toLowerCase()}\\`;\n });\n }\n\n const params = new URLSearchParams(window.location.search);\n const urlErrorMessage = params.get('error-message');\n if (urlErrorMessage) {\n errorMessage.textContent = decodeURIComponent(urlErrorMessage);\n errorMessage.classList.add('show');\n }\n\n document.getElementById('loginForm').addEventListener('submit', async (e) => {\n e.preventDefault();\n\n const selectedField = usernameSelect ? usernameSelect.value : '${allowedUsernames[0]}';\n const password = document.getElementById('password').value;\n\n errorMessage.classList.remove('show');\n errorMessage.textContent = '';\n loginButton.disabled = true;\n loginButton.textContent = '...';\n\n try {\n const selectedField = usernameSelect ? usernameSelect.value : '${allowedUsernames[0]}';\n const fieldKey = selectedField.split('.').pop(); // last segment only as body key\n\n const response = await fetch(\\`/api/auth/login?usernameField=\\${selectedField}\\`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n [fieldKey]: usernameField.value,\n password,\n }),\n });\n\n const data = await response.json();\n\n if (response.ok) {\n window.location.href = '/api/docs';\n } else {\n errorMessage.textContent = data.message || 'Login failed';\n errorMessage.classList.add('show');\n }\n } catch {\n errorMessage.textContent = 'An error occurred. Please try again.';\n errorMessage.classList.add('show');\n } finally {\n loginButton.disabled = false;\n loginButton.textContent = 'Login';\n }\n });\n </script>\n</body>\n</html>`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"get-open-api-login-html.js","sourceRoot":"","sources":["../../../../../src/modules/swagger/utils/get-open-api-login-html.ts"],"names":[],"mappings":"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","sourcesContent":["import { getArkosConfig } from \"../../../server\";\n\nfunction formatFieldLabel(field: string): string {\n const last = field.split(\".\").pop()!;\n return last\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (c) => c.toUpperCase())\n .trim();\n}\n\nexport default function getOpenApiLoginHtml() {\n const arkosConfig = getArkosConfig();\n\n const theme =\n arkosConfig?.swagger?.scalarApiReferenceConfiguration?.theme || \"default\";\n\n const allowedUsernames = arkosConfig?.authentication?.login?.allowedUsernames\n ?.length\n ? arkosConfig.authentication.login.allowedUsernames\n : [\"username\"];\n\n const themeColors: Record<\n string,\n { bg: string; surface: string; border: string }\n > = {\n default: { bg: \"#0f0f0f\", surface: \"#1a1a1a\", border: \"#2e2e2e\" },\n moon: { bg: \"#0f1117\", surface: \"#1c1e26\", border: \"#2e3040\" },\n purple: { bg: \"#0d0d14\", surface: \"#1a1a2e\", border: \"#2e2e4a\" },\n solarized: { bg: \"#002b36\", surface: \"#073642\", border: \"#124652\" },\n bluePlanet: { bg: \"#070b14\", surface: \"#0d1424\", border: \"#1a2540\" },\n saturn: { bg: \"#0a0a0f\", surface: \"#16161f\", border: \"#28283a\" },\n kepler: { bg: \"#0a0f0a\", surface: \"#141f14\", border: \"#253525\" },\n mars: { bg: \"#0f0a08\", surface: \"#1f1410\", border: \"#352520\" },\n deepSpace: { bg: \"#0a0a0a\", surface: \"#121212\", border: \"#3a3a3a\" },\n };\n\n const colors = themeColors[theme] ?? themeColors[\"default\"];\n\n const firstLabel = formatFieldLabel(allowedUsernames[0]);\n const showSelect = allowedUsernames.length > 1;\n const title =\n arkosConfig?.swagger?.options?.definition?.info?.title ||\n \"Arkos.js OpenAPI Documentation\";\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${title}</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n min-height: 100vh;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: ${colors.bg};\n padding: 8px;\n }\n\n .login-container {\n background-color: ${colors.surface};\n padding: 40px;\n border: 1px solid ${colors.border};\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n }\n\n h1 {\n color: #ffffff;\n text-align: center;\n margin-bottom: 30px;\n font-size: 24px;\n font-weight: 600;\n }\n\n h2 {\n color: #ffffff;\n text-align: center;\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 500;\n }\n\n .form-group {\n margin-bottom: 20px;\n }\n\n label {\n display: block;\n color: #ffffff;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n }\n\n input[type=\"text\"],\n input[type=\"password\"] {\n width: 100%;\n padding: 12px 16px;\n background-color: ${colors.bg};\n border: 1px solid ${colors.border};\n border-radius: 4px;\n color: #ffffff;\n font-size: 14px;\n transition: border-color 0.3s;\n }\n\n select {\n width: 100%;\n padding: 12px 16px;\n background-color: ${colors.bg};\n border: 1px solid ${colors.border};\n border-radius: 4px;\n color: #ffffff;\n font-size: 14px;\n transition: border-color 0.3s;\n appearance: none;\n -webkit-appearance: none;\n -moz-appearance: none;\n cursor: pointer;\n /* custom arrow */\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23ffffff' d='M6 8L1 3h10z'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 16px center;\n }\n\n input[type=\"text\"]:focus,\n input[type=\"password\"]:focus,\n select:focus {\n outline: none;\n border-color: #ffffff;\n }\n\n input[type=\"text\"]::placeholder,\n input[type=\"password\"]::placeholder {\n color: #666666;\n }\n\n select option {\n background-color: ${colors.surface};\n color: #ffffff;\n }\n\n .login-button {\n width: 100%;\n padding: 12px;\n background-color: #ffffff;\n color: #1a1a1a;\n border: none;\n border-radius: 4px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.3s;\n }\n\n .login-button:hover { background-color: #e0e0e0; }\n .login-button:active { transform: translateY(1px); }\n .login-button:disabled { background-color: #666666; cursor: not-allowed; }\n\n .error-message {\n color: #ff6b6b;\n font-size: 14px;\n margin-top: 10px;\n text-align: center;\n display: none;\n }\n\n .error-message.show { display: block; }\n\n .page-footer {\n position: fixed;\n bottom: 16px;\n width: 100%;\n text-align: center;\n font-size: 14px;\n color: #999999;\n }\n\n .page-footer a {\n color: #999999;\n text-decoration: underline;\n }\n </style>\n</head>\n<body>\n <div class=\"login-container\">\n <h1>${title}</h1>\n <h2>Login</h2>\n <form id=\"loginForm\">\n\n ${\n showSelect\n ? `\n <div class=\"form-group\">\n <label for=\"usernameSelect\">Login With</label>\n <select id=\"usernameSelect\">\n ${allowedUsernames\n .map(\n (f) => `\n <option value=\"${f}\">${formatFieldLabel(f)}</option>\n `\n )\n .join(\"\")}\n </select>\n </div>\n `\n : \"\"\n }\n\n <div class=\"form-group\">\n <label id=\"usernameLabel\" for=\"usernameField\">${firstLabel}</label>\n <input\n type=\"text\"\n id=\"usernameField\"\n placeholder=\"Enter your ${firstLabel.toLowerCase()}\"\n required\n >\n </div>\n\n <div class=\"form-group\">\n <label for=\"password\">Password</label>\n <input\n type=\"password\"\n id=\"password\"\n placeholder=\"Enter your password\"\n required\n >\n </div>\n\n <button type=\"submit\" class=\"login-button\" id=\"loginButton\">Login</button>\n <div class=\"error-message\" id=\"errorMessage\"></div>\n\n </form>\n </div>\n\n <footer class=\"page-footer\">\n Powered by <a href=\"https://www.arkosjs.com\" target=\"_blank\" rel=\"noopener noreferrer\">Arkos.js</a>\n </footer>\n\n <script>\n const usernameLabel = document.getElementById('usernameLabel');\n const usernameField = document.getElementById('usernameField');\n const usernameSelect = document.getElementById('usernameSelect');\n const loginButton = document.getElementById('loginButton');\n const errorMessage = document.getElementById('errorMessage');\n\n function formatFieldLabel(field) {\n const last = field.split('.').pop();\n return last\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, c => c.toUpperCase())\n .trim();\n }\n\n${\n allowedUsernames.length > 1 &&\n `if (usernameSelect) {\n usernameSelect.addEventListener('change', () => {\n const label = formatFieldLabel(usernameSelect.value);\n usernameLabel.textContent = label;\n usernameField.placeholder = \\`Enter your \\${label.toLowerCase()}\\`;\n });\n }\n`\n}\n\n const params = new URLSearchParams(window.location.search);\n const urlErrorMessage = params.get('error-message');\n if (urlErrorMessage) {\n errorMessage.textContent = decodeURIComponent(urlErrorMessage);\n errorMessage.classList.add('show');\n }\n\n document.getElementById('loginForm').addEventListener('submit', async (e) => {\n e.preventDefault();\n\n const selectedField = usernameSelect ? usernameSelect.value : '${allowedUsernames[0]}';\n const password = document.getElementById('password').value;\n\n errorMessage.classList.remove('show');\n errorMessage.textContent = '';\n loginButton.disabled = true;\n loginButton.textContent = '...';\n\n try {\n const selectedField = usernameSelect ? usernameSelect.value : '${allowedUsernames[0]}';\n const fieldKey = selectedField.split('.').pop(); // last segment only as body key\n\n const response = await fetch(\\`/api/auth/login?usernameField=\\${selectedField}\\`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n [fieldKey]: usernameField.value,\n password,\n }),\n });\n\n const data = await response.json();\n\n if (response.ok) {\n window.location.href = '/api/docs';\n } else {\n errorMessage.textContent = data.message || 'Login failed';\n errorMessage.classList.add('show');\n }\n } catch {\n errorMessage.textContent = 'An error occurred. Please try again.';\n errorMessage.classList.add('show');\n } finally {\n loginButton.disabled = false;\n loginButton.textContent = 'Login';\n }\n });\n </script>\n</body>\n</html>`;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class-validator-to-json-schema.js","sourceRoot":"","sources":["../../../../../../src/modules/swagger/utils/helpers/class-validator-to-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE1E,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,cAA8C;IAE9C,MAAM,WAAW,GAAG,4BAA4B,CAAC;QAC/C,6BAA6B,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"class-validator-to-json-schema.js","sourceRoot":"","sources":["../../../../../../src/modules/swagger/utils/helpers/class-validator-to-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAE1E,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,cAA8C;IAE9C,MAAM,WAAW,GAAG,4BAA4B,CAAC;QAC/C,6BAA6B,EAAE,kBAAkB,EAAS;QAC1D,+BAA+B,EAAE,sBAAsB;QACvD,gBAAgB,EAAE,uBAAuB;KAC1C,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IAEtD,IAAI,CAAC,YAAY;QAAE,OAAO,IAAI,CAAC;IAE/B,OAAO,iBAAiB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAW,EACX,UAA+B,EAC/B,UAAU,IAAI,GAAG,EAAU;IAE3B,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAEzD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE/C,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACtB,OAAO;gBACL,YAAY,EAAE,OAAO;gBACrB,WAAW,EAAE,yBAAyB,OAAO,EAAE;aAChD,CAAC;QAEJ,MAAM,gBAAgB,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,gBAAgB,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAC1E,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAExB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;YACjC,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC;QAClC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC","sourcesContent":["import { getMetadataStorage } from \"class-validator\";\nimport { defaultMetadataStorage } from \"class-transformer/cjs/storage.js\";\nimport { validationMetadatasToSchemas } from \"class-validator-jsonschema\";\n\nexport default function classValidatorToJsonSchema(\n decoratedClass: new (...args: any[]) => object\n): any {\n const jsonSchemas = validationMetadatasToSchemas({\n classValidatorMetadataStorage: getMetadataStorage() as any, // FIXME: dummy typing because of updates\n classTransformerMetadataStorage: defaultMetadataStorage,\n refPointerPrefix: \"#/components/schemas/\",\n });\n\n const targetSchema = jsonSchemas[decoratedClass.name];\n\n if (!targetSchema) return null;\n\n return resolveReferences(targetSchema, jsonSchemas);\n}\n\nexport function resolveReferences(\n schema: any,\n allSchemas: Record<string, any>,\n visited = new Set<string>()\n): any {\n if (!schema || typeof schema !== \"object\") return schema;\n\n if (schema.$ref) {\n const refName = extractSchemaName(schema.$ref);\n\n if (visited.has(refName))\n return {\n $resolvedRef: refName,\n description: `Circular reference to ${refName}`,\n };\n\n const referencedSchema = allSchemas[refName];\n if (referencedSchema) {\n visited.add(refName);\n const resolved = resolveReferences(referencedSchema, allSchemas, visited);\n visited.delete(refName);\n\n const { $ref, ...rest } = schema;\n return { ...resolved, ...rest };\n }\n\n return schema;\n }\n\n if (Array.isArray(schema)) {\n return schema.map((item) => resolveReferences(item, allSchemas, visited));\n }\n\n const result: any = {};\n for (const [key, value] of Object.entries(schema)) {\n result[key] = resolveReferences(value, allSchemas, visited);\n }\n\n return result;\n}\n\nexport function extractSchemaName(ref: string): string {\n const parts = ref.split(\"/\");\n return parts[parts.length - 1];\n}\n"]}
|
|
@@ -66,7 +66,7 @@ class OpenAPIchemaConverter {
|
|
|
66
66
|
return flattened;
|
|
67
67
|
}
|
|
68
68
|
if (schema.type === "array" && schema.items) {
|
|
69
|
-
const arrayPrefix = prefix ? `${prefix}[0]
|
|
69
|
+
const arrayPrefix = prefix && schema.items?.format === "binary" ? prefix : `${prefix}[0]`;
|
|
70
70
|
if (schema.items.type === "array") {
|
|
71
71
|
flattened.push(...this.flattenSchemaCore(schema.items, arrayPrefix, visitedRefs));
|
|
72
72
|
}
|
|
@@ -101,7 +101,9 @@ class OpenAPIchemaConverter {
|
|
|
101
101
|
visitedRefs.delete(refPath);
|
|
102
102
|
}
|
|
103
103
|
else if (value.type === "array" && value.items) {
|
|
104
|
-
const arrayPrefix =
|
|
104
|
+
const arrayPrefix = paramName && value.items?.format == "binary"
|
|
105
|
+
? paramName
|
|
106
|
+
: `${paramName}[0]`;
|
|
105
107
|
if (value.items.type === "array") {
|
|
106
108
|
flattened.push(...this.flattenSchemaCore(value.items, arrayPrefix, visitedRefs));
|
|
107
109
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi-schema-converter.js","sourceRoot":"","sources":["../../../../../../src/modules/swagger/utils/helpers/openapi-schema-converter.ts"],"names":[],"mappings":"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","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport { isClass, isZodSchema } from \"../../../../utils/dynamic-loader\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport classValidatorToJsonSchema from \"./class-validator-to-json-schema\";\nimport { getArkosConfig } from \"../../../../server\";\n\n/**\n * Singleton class responsible for converting various schema formats (Zod, Class DTOs, JSON Schema)\n * into OpenAPI-compliant schema objects. Handles shorthand syntax for responses, request bodies,\n * and parameters.\n */\nclass OpenAPIchemaConverter {\n private validatorToJsonSchema: (schema: any) => any;\n\n constructor() {\n this.validatorToJsonSchema = (schema: any) => {\n const validationResolver = getArkosConfig()?.validation?.resolver;\n const fn =\n validationResolver === \"zod\"\n ? zodToJsonSchema\n : classValidatorToJsonSchema;\n\n return fn(schema);\n };\n }\n\n /**\n * Checks if a value is a schema-like object (Zod, Class, or JSON Schema).\n *\n * @param value - The value to check\n * @returns True if the value is a schema-like object\n */\n private isSchemaLike(value: any): boolean {\n if (!value) return false;\n\n if (isZodSchema(value)) return true;\n\n if (isClass(value)) return true;\n\n if (this.isPlainObject(value) && value.type) return true;\n\n return false;\n }\n\n /**\n * Checks if a value is a plain JavaScript object.\n *\n * @param value - The value to check\n * @returns True if the value is a plain object\n */\n private isPlainObject(value: any): boolean {\n return Object.prototype.toString.call(value) === \"[object Object]\";\n }\n\n /**\n * Converts a schema-like object (Zod, Class, or JSON Schema) into a JSON Schema object.\n *\n * @param schema - The schema to convert\n * @returns The JSON Schema representation, or undefined if schema is null/undefined\n */\n private convertToJsonSchema(schema: any): any {\n if (this.isPlainObject(schema) && schema?.type) return schema;\n\n if (isZodSchema(schema) || isClass(schema))\n return this.validatorToJsonSchema(schema);\n\n throw new Error(\n `Unsupported schema type. Expected Zod schema, class constructor, or JSON Schema object.`\n );\n }\n\n /**\n * Gets the default description for an HTTP status code.\n *\n * @param statusCode - The HTTP status code\n * @returns A human-readable default description\n */\n private getDefaultDescription(statusCode: string): string {\n const defaults: Record<string, string> = {\n \"200\": \"Success\",\n \"201\": \"Created\",\n \"202\": \"Accepted\",\n \"204\": \"No Content\",\n \"400\": \"Bad Request\",\n \"401\": \"Unauthorized\",\n \"403\": \"Forbidden\",\n \"404\": \"Not Found\",\n \"409\": \"Conflict\",\n \"422\": \"Unprocessable Entity\",\n \"500\": \"Internal Server Error\",\n \"502\": \"Bad Gateway\",\n \"503\": \"Service Unavailable\",\n };\n\n return defaults[statusCode] || \"Response\";\n }\n\n /**\n * Core flattening logic that converts a JSON schema into bracket notation.\n * Handles nested objects, arrays, and circular references.\n *\n * @param schema - The JSON schema to flatten\n * @param prefix - Optional prefix for nested properties\n * @param visitedRefs - Set to track circular references\n * @returns Array of flattened field descriptors\n */\n flattenSchemaCore(\n schema: any,\n prefix = \"\",\n visitedRefs = new Set<string>()\n ): Array<{ name: string; schema: any; required: boolean }> {\n const flattened: Array<{ name: string; schema: any; required: boolean }> =\n [];\n\n if (schema.$ref) {\n const refPath = schema.$ref;\n if (visitedRefs.has(refPath)) return flattened;\n\n visitedRefs.add(refPath);\n const resolvedSchema = this.resolveRef(schema, refPath);\n if (resolvedSchema) {\n flattened.push(\n ...this.flattenSchemaCore(resolvedSchema, prefix, visitedRefs)\n );\n }\n visitedRefs.delete(refPath);\n return flattened;\n }\n\n if (schema.type === \"array\" && schema.items) {\n const arrayPrefix = prefix ? `${prefix}[0]` : \"[0]\";\n\n // Check if items is an array FIRST, before checking for object\n if (schema.items.type === \"array\") {\n flattened.push(\n ...this.flattenSchemaCore(schema.items, arrayPrefix, visitedRefs)\n );\n } else if (schema.items.properties || schema.items.type === \"object\") {\n flattened.push(\n ...this.flattenSchemaCore(schema.items, arrayPrefix, visitedRefs)\n );\n } else if (schema.items.type || schema.items.$ref) {\n flattened.push({\n name: arrayPrefix,\n schema: {\n type: schema.items.type,\n ...(schema.items.enum && { enum: schema.items.enum }),\n ...(schema.items.format && { format: schema.items.format }),\n },\n required: false,\n });\n }\n\n return flattened;\n }\n\n if ((schema.type === \"object\" || !schema.type) && schema.properties) {\n for (const [key, value] of Object.entries(schema.properties) as any) {\n const paramName = prefix ? `${prefix}[${key}]` : key;\n\n if (value.$ref) {\n const refPath = value.$ref;\n if (visitedRefs.has(refPath)) continue;\n\n visitedRefs.add(refPath);\n const resolvedSchema = this.resolveRef(schema, refPath);\n\n if (resolvedSchema) {\n flattened.push(\n ...this.flattenSchemaCore(resolvedSchema, paramName, visitedRefs)\n );\n }\n visitedRefs.delete(refPath);\n } else if (value.type === \"array\" && value.items) {\n const arrayPrefix = `${paramName}[0]`;\n if (value.items.type === \"array\") {\n flattened.push(\n ...this.flattenSchemaCore(value.items, arrayPrefix, visitedRefs)\n );\n } else if (value.items.type === \"object\" || value.items.properties) {\n flattened.push(\n ...this.flattenSchemaCore(value.items, arrayPrefix, visitedRefs)\n );\n } else {\n flattened.push({\n name: arrayPrefix,\n schema: {\n type: value.items.type,\n ...(value.items.enum && { enum: value.items.enum }),\n ...(value.items.format && { format: value.items.format }),\n },\n required: false,\n });\n }\n } else if (value.type === \"object\" && value.properties) {\n flattened.push(\n ...this.flattenSchemaCore(value, paramName, visitedRefs)\n );\n } else {\n flattened.push({\n name: paramName,\n schema: {\n type: value.type,\n ...(value.enum && { enum: value.enum }),\n ...(value.format && { format: value.format }),\n },\n required: schema.required?.includes(key) || false,\n });\n }\n }\n return flattened;\n }\n\n // Handle primitive types with prefix\n if (schema.type && prefix) {\n flattened.push({\n name: prefix,\n schema: {\n type: schema.type,\n ...(schema.enum && { enum: schema.enum }),\n ...(schema.format && { format: schema.format }),\n },\n required: false,\n });\n }\n\n return flattened;\n }\n\n /**\n * Flattens a JSON schema while preserving the schema structure.\n * Converts nested objects and arrays into bracket notation properties.\n * Used for multipart/form-data schema representation.\n *\n * @param schema - The JSON schema to flatten\n * @returns A flattened schema object with bracket notation properties\n */\n flattenSchema(schema: any): any {\n const flattened = this.flattenSchemaCore(schema);\n\n // Convert the flattened array into a schema object\n const flattenedSchema: any = {\n ...schema,\n properties: {},\n required: [],\n };\n\n for (const item of flattened) {\n flattenedSchema.properties[item.name] = item.schema;\n if (item.required) {\n flattenedSchema.required.push(item.name);\n }\n }\n\n // Remove empty required array if no required fields\n if (flattenedSchema.required.length === 0) {\n delete flattenedSchema.required;\n }\n\n return flattenedSchema;\n }\n\n /**\n * Converts a response definition (shorthand, medium, or full format) into a standard\n * OpenAPI ResponseObject.\n *\n * Supports three formats:\n * 1. Shorthand: ProfileDto → assumes application/json + default description\n * 2. Medium: { content: ProfileDto, description: \"...\" } → custom description\n * 3. Full: { content: { \"application/json\": { schema: ProfileDto } } } → full control\n *\n * @param statusCode - The HTTP status code for this response\n * @param definition - The response definition to convert\n * @returns A standard OpenAPI ResponseObject\n */\n convertResponseDefinition(\n statusCode: string,\n definition: any\n ): OpenAPIV3.ResponseObject {\n if (!definition.content && this.isSchemaLike(definition)) {\n return {\n description: this.getDefaultDescription(statusCode),\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition),\n },\n },\n };\n }\n\n if (definition.content && this.isSchemaLike(definition.content)) {\n return {\n description:\n definition.description || this.getDefaultDescription(statusCode),\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition.content),\n },\n },\n ...(definition.headers && { headers: definition.headers }),\n ...(definition.links && { links: definition.links }),\n };\n }\n\n if (definition.content) {\n const converted: OpenAPIV3.ResponseObject = {\n description:\n definition.description || this.getDefaultDescription(statusCode),\n content: {},\n };\n\n for (const [mediaType, mediaObj] of Object.entries(\n definition.content\n ) as any[]) {\n converted.content![mediaType] = {\n ...mediaObj,\n schema: this.convertToJsonSchema(mediaObj.schema),\n };\n }\n\n if (definition.headers) converted.headers = definition.headers;\n if (definition.links) converted.links = definition.links;\n\n return converted;\n }\n\n return definition;\n }\n\n /**\n * Converts a request body definition (shorthand, medium, or full format) into a standard\n * OpenAPI RequestBodyObject.\n *\n * Supports three formats:\n * 1. Shorthand: CreateUserDto → assumes application/json + required: true\n * 2. Medium: { content: CreateUserDto, required?: boolean } → custom config\n * 3. Full: { content: { \"application/json\": { schema: CreateUserDto } } } → full control\n *\n * For multipart/form-data, automatically converts the schema into an array of parameters.\n *\n * @param definition - The request body definition to convert\n * @returns A standard OpenAPI RequestBodyObject, or undefined if no definition provided\n */\n convertRequestBodyDefinition(\n definition: any\n ): OpenAPIV3.RequestBodyObject | undefined {\n if (!definition) return undefined;\n\n if (!definition.content && this.isSchemaLike(definition)) {\n return {\n required: true,\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition),\n },\n },\n };\n }\n\n if (definition.content && this.isSchemaLike(definition.content)) {\n return {\n required: definition.required === false ? false : true,\n description: definition.description,\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition.content),\n },\n },\n };\n }\n\n if (definition.content) {\n const converted: OpenAPIV3.RequestBodyObject = {\n required: definition.required ?? true,\n content: {},\n };\n\n if (definition.description)\n converted.description = definition.description;\n\n for (const [mediaType, mediaObj] of Object.entries(\n definition.content\n ) as any[]) {\n const jsonSchema = this.convertToJsonSchema(mediaObj.schema);\n\n // For multipart/form-data, flatten the schema into bracket notation\n if (mediaType === \"multipart/form-data\") {\n converted.content[mediaType] = {\n ...mediaObj,\n schema: this.flattenSchema(jsonSchema),\n };\n } else {\n // For other media types (like application/json), keep the full schema\n converted.content[mediaType] = {\n ...mediaObj,\n schema: jsonSchema,\n };\n }\n }\n\n return converted;\n }\n\n return definition;\n }\n\n /**\n * Converts an array of parameter definitions, transforming any Zod/Class schemas\n * into JSON Schema objects.\n *\n * @param parameters - Array of parameter definitions to convert\n * @returns Array of standard OpenAPI ParameterObjects, or undefined if no parameters provided\n */\n convertParameters(\n parameters: any[] | undefined\n ): (OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject)[] | undefined {\n if (!parameters) return undefined;\n\n return parameters.map((param) => {\n if (param.$ref) return param;\n\n if (param.schema)\n return {\n ...param,\n schema: this.convertToJsonSchema(param.schema),\n };\n\n return param;\n });\n }\n\n /**\n * Converts all responses in a responses object, handling shorthand, medium, and full formats.\n *\n * @param responses - Object containing response definitions keyed by status code\n * @returns Object with converted OpenAPI ResponseObjects\n */\n convertResponses(\n responses: Record<string, any> | undefined\n ): Record<string, OpenAPIV3.ResponseObject> | undefined {\n if (!responses) return undefined;\n\n const converted: Record<string, OpenAPIV3.ResponseObject> = {};\n\n for (const [statusCode, definition] of Object.entries(responses)) {\n converted[statusCode] = this.convertResponseDefinition(\n statusCode,\n definition\n );\n }\n\n return converted;\n }\n\n /**\n * Converts a complete OpenAPI operation configuration, processing responses, requestBody,\n * and parameters to handle shorthand syntax and schema conversions.\n *\n * @param config - The OpenAPI operation configuration to convert\n * @returns The converted configuration with all schemas transformed to JSON Schema\n */\n convertOpenAPIConfig(config: any): any {\n if (!config || config === false) return config;\n\n const converted = { ...config };\n\n if (config.responses)\n converted.responses = this.convertResponses(config.responses);\n\n if (config.requestBody)\n converted.requestBody = this.convertRequestBodyDefinition(\n config.requestBody\n );\n\n if (config.parameters)\n converted.parameters = this.convertParameters(config.parameters);\n\n return converted;\n }\n\n /**\n * Converts a JSON schema to OpenAPI parameter objects with flattened paths.\n * This is used for query/path/header parameters.\n *\n * @param paramType - The parameter location (query, path, header, cookie)\n * @param schema - The JSON schema to convert\n * @param prefix - Optional prefix for nested properties\n * @param visitedRefs - Set to track circular references\n * @returns Array of OpenAPI parameter objects\n */\n jsonSchemaToOpenApiParameters(\n paramType: string,\n schema: any,\n prefix = \"\",\n visitedRefs = new Set<string>()\n ): any[] {\n const flattened = this.flattenSchemaCore(schema, prefix, visitedRefs);\n\n return flattened.map(({ name, schema, required }) => ({\n in: paramType,\n name,\n required,\n schema,\n }));\n }\n\n resolveRef(rootSchema: any, refPath: string): any {\n if (!refPath.startsWith(\"#/properties/\")) {\n return null;\n }\n\n const path = refPath.substring(2).split(\"/\");\n let current = rootSchema;\n\n for (const part of path) {\n if (current && current[part] !== undefined) {\n current = current[part];\n } else {\n return null;\n }\n }\n\n return current;\n }\n}\n\nconst openApiSchemaConverter = new OpenAPIchemaConverter();\n\nexport default openApiSchemaConverter;\n"]}
|
|
1
|
+
{"version":3,"file":"openapi-schema-converter.js","sourceRoot":"","sources":["../../../../../../src/modules/swagger/utils/helpers/openapi-schema-converter.ts"],"names":[],"mappings":"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","sourcesContent":["import { OpenAPIV3 } from \"openapi-types\";\nimport { isClass, isZodSchema } from \"../../../../utils/dynamic-loader\";\nimport zodToJsonSchema from \"zod-to-json-schema\";\nimport classValidatorToJsonSchema from \"./class-validator-to-json-schema\";\nimport { getArkosConfig } from \"../../../../server\";\n\n/**\n * Singleton class responsible for converting various schema formats (Zod, Class DTOs, JSON Schema)\n * into OpenAPI-compliant schema objects. Handles shorthand syntax for responses, request bodies,\n * and parameters.\n */\nclass OpenAPIchemaConverter {\n private validatorToJsonSchema: (schema: any) => any;\n\n constructor() {\n this.validatorToJsonSchema = (schema: any) => {\n const validationResolver = getArkosConfig()?.validation?.resolver;\n const fn =\n validationResolver === \"zod\"\n ? zodToJsonSchema\n : classValidatorToJsonSchema;\n\n return fn(schema);\n };\n }\n\n /**\n * Checks if a value is a schema-like object (Zod, Class, or JSON Schema).\n *\n * @param value - The value to check\n * @returns True if the value is a schema-like object\n */\n private isSchemaLike(value: any): boolean {\n if (!value) return false;\n\n if (isZodSchema(value)) return true;\n\n if (isClass(value)) return true;\n\n if (this.isPlainObject(value) && value.type) return true;\n\n return false;\n }\n\n /**\n * Checks if a value is a plain JavaScript object.\n *\n * @param value - The value to check\n * @returns True if the value is a plain object\n */\n private isPlainObject(value: any): boolean {\n return Object.prototype.toString.call(value) === \"[object Object]\";\n }\n\n /**\n * Converts a schema-like object (Zod, Class, or JSON Schema) into a JSON Schema object.\n *\n * @param schema - The schema to convert\n * @returns The JSON Schema representation, or undefined if schema is null/undefined\n */\n private convertToJsonSchema(schema: any): any {\n if (this.isPlainObject(schema) && schema?.type) return schema;\n\n if (isZodSchema(schema) || isClass(schema))\n return this.validatorToJsonSchema(schema);\n\n throw new Error(\n `Unsupported schema type. Expected Zod schema, class constructor, or JSON Schema object.`\n );\n }\n\n /**\n * Gets the default description for an HTTP status code.\n *\n * @param statusCode - The HTTP status code\n * @returns A human-readable default description\n */\n private getDefaultDescription(statusCode: string): string {\n const defaults: Record<string, string> = {\n \"200\": \"Success\",\n \"201\": \"Created\",\n \"202\": \"Accepted\",\n \"204\": \"No Content\",\n \"400\": \"Bad Request\",\n \"401\": \"Unauthorized\",\n \"403\": \"Forbidden\",\n \"404\": \"Not Found\",\n \"409\": \"Conflict\",\n \"422\": \"Unprocessable Entity\",\n \"500\": \"Internal Server Error\",\n \"502\": \"Bad Gateway\",\n \"503\": \"Service Unavailable\",\n };\n\n return defaults[statusCode] || \"Response\";\n }\n\n /**\n * Core flattening logic that converts a JSON schema into bracket notation.\n * Handles nested objects, arrays, and circular references.\n *\n * @param schema - The JSON schema to flatten\n * @param prefix - Optional prefix for nested properties\n * @param visitedRefs - Set to track circular references\n * @returns Array of flattened field descriptors\n */\n flattenSchemaCore(\n schema: any,\n prefix = \"\",\n visitedRefs = new Set<string>()\n ): Array<{ name: string; schema: any; required: boolean }> {\n const flattened: Array<{ name: string; schema: any; required: boolean }> =\n [];\n\n if (schema.$ref) {\n const refPath = schema.$ref;\n if (visitedRefs.has(refPath)) return flattened;\n\n visitedRefs.add(refPath);\n const resolvedSchema = this.resolveRef(schema, refPath);\n if (resolvedSchema) {\n flattened.push(\n ...this.flattenSchemaCore(resolvedSchema, prefix, visitedRefs)\n );\n }\n visitedRefs.delete(refPath);\n return flattened;\n }\n\n if (schema.type === \"array\" && schema.items) {\n const arrayPrefix =\n prefix && schema.items?.format === \"binary\" ? prefix : `${prefix}[0]`;\n\n // Check if items is an array FIRST, before checking for object\n if (schema.items.type === \"array\") {\n flattened.push(\n ...this.flattenSchemaCore(schema.items, arrayPrefix, visitedRefs)\n );\n } else if (schema.items.properties || schema.items.type === \"object\") {\n flattened.push(\n ...this.flattenSchemaCore(schema.items, arrayPrefix, visitedRefs)\n );\n } else if (schema.items.type || schema.items.$ref) {\n flattened.push({\n name: arrayPrefix,\n schema: {\n type: schema.items.type,\n ...(schema.items.enum && { enum: schema.items.enum }),\n ...(schema.items.format && { format: schema.items.format }),\n },\n required: false,\n });\n }\n\n return flattened;\n }\n\n if ((schema.type === \"object\" || !schema.type) && schema.properties) {\n for (const [key, value] of Object.entries(schema.properties) as any) {\n const paramName = prefix ? `${prefix}[${key}]` : key;\n\n if (value.$ref) {\n const refPath = value.$ref;\n if (visitedRefs.has(refPath)) continue;\n\n visitedRefs.add(refPath);\n const resolvedSchema = this.resolveRef(schema, refPath);\n\n if (resolvedSchema) {\n flattened.push(\n ...this.flattenSchemaCore(resolvedSchema, paramName, visitedRefs)\n );\n }\n visitedRefs.delete(refPath);\n } else if (value.type === \"array\" && value.items) {\n const arrayPrefix =\n paramName && value.items?.format == \"binary\"\n ? paramName\n : `${paramName}[0]`;\n\n if (value.items.type === \"array\") {\n flattened.push(\n ...this.flattenSchemaCore(value.items, arrayPrefix, visitedRefs)\n );\n } else if (value.items.type === \"object\" || value.items.properties) {\n flattened.push(\n ...this.flattenSchemaCore(value.items, arrayPrefix, visitedRefs)\n );\n } else {\n flattened.push({\n name: arrayPrefix,\n schema: {\n type: value.items.type,\n ...(value.items.enum && { enum: value.items.enum }),\n ...(value.items.format && { format: value.items.format }),\n },\n required: false,\n });\n }\n } else if (value.type === \"object\" && value.properties) {\n flattened.push(\n ...this.flattenSchemaCore(value, paramName, visitedRefs)\n );\n } else {\n flattened.push({\n name: paramName,\n schema: {\n type: value.type,\n ...(value.enum && { enum: value.enum }),\n ...(value.format && { format: value.format }),\n },\n required: schema.required?.includes(key) || false,\n });\n }\n }\n return flattened;\n }\n\n // Handle primitive types with prefix\n if (schema.type && prefix) {\n flattened.push({\n name: prefix,\n schema: {\n type: schema.type,\n ...(schema.enum && { enum: schema.enum }),\n ...(schema.format && { format: schema.format }),\n },\n required: false,\n });\n }\n\n return flattened;\n }\n\n /**\n * Flattens a JSON schema while preserving the schema structure.\n * Converts nested objects and arrays into bracket notation properties.\n * Used for multipart/form-data schema representation.\n *\n * @param schema - The JSON schema to flatten\n * @returns A flattened schema object with bracket notation properties\n */\n flattenSchema(schema: any): any {\n const flattened = this.flattenSchemaCore(schema);\n\n // Convert the flattened array into a schema object\n const flattenedSchema: any = {\n ...schema,\n properties: {},\n required: [],\n };\n\n for (const item of flattened) {\n flattenedSchema.properties[item.name] = item.schema;\n if (item.required) {\n flattenedSchema.required.push(item.name);\n }\n }\n\n // Remove empty required array if no required fields\n if (flattenedSchema.required.length === 0) {\n delete flattenedSchema.required;\n }\n\n return flattenedSchema;\n }\n\n /**\n * Converts a response definition (shorthand, medium, or full format) into a standard\n * OpenAPI ResponseObject.\n *\n * Supports three formats:\n * 1. Shorthand: ProfileDto → assumes application/json + default description\n * 2. Medium: { content: ProfileDto, description: \"...\" } → custom description\n * 3. Full: { content: { \"application/json\": { schema: ProfileDto } } } → full control\n *\n * @param statusCode - The HTTP status code for this response\n * @param definition - The response definition to convert\n * @returns A standard OpenAPI ResponseObject\n */\n convertResponseDefinition(\n statusCode: string,\n definition: any\n ): OpenAPIV3.ResponseObject {\n if (!definition.content && this.isSchemaLike(definition)) {\n return {\n description: this.getDefaultDescription(statusCode),\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition),\n },\n },\n };\n }\n\n if (definition.content && this.isSchemaLike(definition.content)) {\n return {\n description:\n definition.description || this.getDefaultDescription(statusCode),\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition.content),\n },\n },\n ...(definition.headers && { headers: definition.headers }),\n ...(definition.links && { links: definition.links }),\n };\n }\n\n if (definition.content) {\n const converted: OpenAPIV3.ResponseObject = {\n description:\n definition.description || this.getDefaultDescription(statusCode),\n content: {},\n };\n\n for (const [mediaType, mediaObj] of Object.entries(\n definition.content\n ) as any[]) {\n converted.content![mediaType] = {\n ...mediaObj,\n schema: this.convertToJsonSchema(mediaObj.schema),\n };\n }\n\n if (definition.headers) converted.headers = definition.headers;\n if (definition.links) converted.links = definition.links;\n\n return converted;\n }\n\n return definition;\n }\n\n /**\n * Converts a request body definition (shorthand, medium, or full format) into a standard\n * OpenAPI RequestBodyObject.\n *\n * Supports three formats:\n * 1. Shorthand: CreateUserDto → assumes application/json + required: true\n * 2. Medium: { content: CreateUserDto, required?: boolean } → custom config\n * 3. Full: { content: { \"application/json\": { schema: CreateUserDto } } } → full control\n *\n * For multipart/form-data, automatically converts the schema into an array of parameters.\n *\n * @param definition - The request body definition to convert\n * @returns A standard OpenAPI RequestBodyObject, or undefined if no definition provided\n */\n convertRequestBodyDefinition(\n definition: any\n ): OpenAPIV3.RequestBodyObject | undefined {\n if (!definition) return undefined;\n\n if (!definition.content && this.isSchemaLike(definition)) {\n return {\n required: true,\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition),\n },\n },\n };\n }\n\n if (definition.content && this.isSchemaLike(definition.content)) {\n return {\n required: definition.required === false ? false : true,\n description: definition.description,\n content: {\n \"application/json\": {\n schema: this.convertToJsonSchema(definition.content),\n },\n },\n };\n }\n\n if (definition.content) {\n const converted: OpenAPIV3.RequestBodyObject = {\n required: definition.required ?? true,\n content: {},\n };\n\n if (definition.description)\n converted.description = definition.description;\n\n for (const [mediaType, mediaObj] of Object.entries(\n definition.content\n ) as any[]) {\n const jsonSchema = this.convertToJsonSchema(mediaObj.schema);\n\n // For multipart/form-data, flatten the schema into bracket notation\n if (mediaType === \"multipart/form-data\") {\n converted.content[mediaType] = {\n ...mediaObj,\n schema: this.flattenSchema(jsonSchema),\n };\n } else {\n // For other media types (like application/json), keep the full schema\n converted.content[mediaType] = {\n ...mediaObj,\n schema: jsonSchema,\n };\n }\n }\n\n return converted;\n }\n\n return definition;\n }\n\n /**\n * Converts an array of parameter definitions, transforming any Zod/Class schemas\n * into JSON Schema objects.\n *\n * @param parameters - Array of parameter definitions to convert\n * @returns Array of standard OpenAPI ParameterObjects, or undefined if no parameters provided\n */\n convertParameters(\n parameters: any[] | undefined\n ): (OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject)[] | undefined {\n if (!parameters) return undefined;\n\n return parameters.map((param) => {\n if (param.$ref) return param;\n\n if (param.schema)\n return {\n ...param,\n schema: this.convertToJsonSchema(param.schema),\n };\n\n return param;\n });\n }\n\n /**\n * Converts all responses in a responses object, handling shorthand, medium, and full formats.\n *\n * @param responses - Object containing response definitions keyed by status code\n * @returns Object with converted OpenAPI ResponseObjects\n */\n convertResponses(\n responses: Record<string, any> | undefined\n ): Record<string, OpenAPIV3.ResponseObject> | undefined {\n if (!responses) return undefined;\n\n const converted: Record<string, OpenAPIV3.ResponseObject> = {};\n\n for (const [statusCode, definition] of Object.entries(responses)) {\n converted[statusCode] = this.convertResponseDefinition(\n statusCode,\n definition\n );\n }\n\n return converted;\n }\n\n /**\n * Converts a complete OpenAPI operation configuration, processing responses, requestBody,\n * and parameters to handle shorthand syntax and schema conversions.\n *\n * @param config - The OpenAPI operation configuration to convert\n * @returns The converted configuration with all schemas transformed to JSON Schema\n */\n convertOpenAPIConfig(config: any): any {\n if (!config || config === false) return config;\n\n const converted = { ...config };\n\n if (config.responses)\n converted.responses = this.convertResponses(config.responses);\n\n if (config.requestBody)\n converted.requestBody = this.convertRequestBodyDefinition(\n config.requestBody\n );\n\n if (config.parameters)\n converted.parameters = this.convertParameters(config.parameters);\n\n return converted;\n }\n\n /**\n * Converts a JSON schema to OpenAPI parameter objects with flattened paths.\n * This is used for query/path/header parameters.\n *\n * @param paramType - The parameter location (query, path, header, cookie)\n * @param schema - The JSON schema to convert\n * @param prefix - Optional prefix for nested properties\n * @param visitedRefs - Set to track circular references\n * @returns Array of OpenAPI parameter objects\n */\n jsonSchemaToOpenApiParameters(\n paramType: string,\n schema: any,\n prefix = \"\",\n visitedRefs = new Set<string>()\n ) {\n const flattened = this.flattenSchemaCore(schema, prefix, visitedRefs);\n\n return flattened.map(({ name, schema, required }) => ({\n in: paramType,\n name,\n required,\n schema,\n }));\n }\n\n resolveRef(rootSchema: any, refPath: string): any {\n if (!refPath.startsWith(\"#/properties/\")) {\n return null;\n }\n\n const path = refPath.substring(2).split(\"/\");\n let current = rootSchema;\n\n for (const part of path) {\n if (current && current[part] !== undefined) {\n current = current[part];\n } else {\n return null;\n }\n }\n\n return current;\n }\n}\n\nconst openApiSchemaConverter = new OpenAPIchemaConverter();\n\nexport default openApiSchemaConverter;\n"]}
|
package/dist/esm/server.js
CHANGED
|
@@ -19,7 +19,7 @@ process.on("uncaughtException", (err) => {
|
|
|
19
19
|
}, 0);
|
|
20
20
|
});
|
|
21
21
|
process.on("unhandledRejection", (err) => {
|
|
22
|
-
if (process.env.NO_CLI === "true")
|
|
22
|
+
if (process.env.NO_CLI === "true" && process.env.__SKIP_LISTEN !== "true")
|
|
23
23
|
sheu.error("UNHANDLED REJECTION! SHUTTING DOWN...\n", {
|
|
24
24
|
timestamp: true,
|
|
25
25
|
bold: true,
|