zibri 2.4.1 → 2.5.0
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/dist/cjs/application-options.model.d.ts +2 -2
- package/dist/cjs/application-options.model.d.ts.map +1 -1
- package/dist/cjs/application.d.ts.map +1 -1
- package/dist/cjs/application.js +0 -1
- package/dist/cjs/application.js.map +1 -1
- package/dist/cjs/assets/asset.service.d.ts.map +1 -1
- package/dist/cjs/assets/asset.service.js +3 -1
- package/dist/cjs/assets/asset.service.js.map +1 -1
- package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.d.ts +1 -1
- package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.d.ts.map +1 -1
- package/dist/cjs/auth/2fa/methods/otp/otp-credentials.model.js.map +1 -1
- package/dist/cjs/auth/2fa/methods/otp/otp.two-factor-method.js +1 -1
- package/dist/cjs/auth/2fa/methods/otp/otp.two-factor-method.js.map +1 -1
- package/dist/cjs/auth/strategies/cookie/cookie-auth.controller.js +1 -1
- package/dist/cjs/auth/strategies/cookie/cookie-auth.controller.js.map +1 -1
- package/dist/cjs/auth/strategies/jwt/jwt-auth.controller.js +1 -1
- package/dist/cjs/auth/strategies/jwt/jwt-auth.controller.js.map +1 -1
- package/dist/cjs/auth/strategies/jwt/jwt.auth-strategy.js +1 -1
- package/dist/cjs/auth/strategies/jwt/jwt.auth-strategy.js.map +1 -1
- package/dist/cjs/backup/backup-resource-entity.model.d.ts +1 -1
- package/dist/cjs/backup/backup-resource-entity.model.d.ts.map +1 -1
- package/dist/cjs/backup/backup-resource-entity.model.js.map +1 -1
- package/dist/cjs/change-sets/models/change-set.model.d.ts +1 -1
- package/dist/cjs/change-sets/models/change-set.model.d.ts.map +1 -1
- package/dist/cjs/change-sets/models/change-set.model.js +1 -1
- package/dist/cjs/change-sets/models/change-set.model.js.map +1 -1
- package/dist/cjs/change-sets/models/change.model.d.ts +2 -2
- package/dist/cjs/change-sets/models/change.model.d.ts.map +1 -1
- package/dist/cjs/change-sets/models/change.model.js.map +1 -1
- package/dist/cjs/context/cache/cache.context.d.ts +2 -2
- package/dist/cjs/context/cache/cache.context.d.ts.map +1 -1
- package/dist/cjs/context/cache/cache.context.js +2 -2
- package/dist/cjs/context/cache/cache.context.js.map +1 -1
- package/dist/cjs/context/request/request-context-token.model.js +1 -1
- package/dist/cjs/context/request/request-context-token.model.js.map +1 -1
- package/dist/cjs/cron/cron-job-entity.model.d.ts +2 -2
- package/dist/cjs/cron/cron-job-entity.model.d.ts.map +1 -1
- package/dist/cjs/cron/cron-job-entity.model.js.map +1 -1
- package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.d.ts +1 -0
- package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.d.ts.map +1 -1
- package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.js +9 -0
- package/dist/cjs/data-source/data-sources/postgres-typeorm-data-source.model.js.map +1 -1
- package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.d.ts.map +1 -1
- package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.js +3 -3
- package/dist/cjs/data-source/data-sources/typeorm-base-data-source.model.js.map +1 -1
- package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.d.ts +2 -1
- package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.d.ts.map +1 -1
- package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js +20 -0
- package/dist/cjs/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js.map +1 -1
- package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.d.ts +4 -0
- package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.d.ts.map +1 -1
- package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.js +3 -1
- package/dist/cjs/data-source/data-sources/where-converter/typeorm-where-filter.converter.js.map +1 -1
- package/dist/cjs/data-source/migration/migration-entity.model.d.ts +2 -2
- package/dist/cjs/data-source/migration/migration-entity.model.d.ts.map +1 -1
- package/dist/cjs/data-source/migration/migration-entity.model.js.map +1 -1
- package/dist/cjs/data-source/migration/migration.model.d.ts +2 -2
- package/dist/cjs/data-source/migration/migration.model.d.ts.map +1 -1
- package/dist/cjs/data-source/models/where/date-where-filter.model.d.ts +10 -2
- package/dist/cjs/data-source/models/where/date-where-filter.model.d.ts.map +1 -1
- package/dist/cjs/data-source/models/where/string-where-filter.model.d.ts +17 -0
- package/dist/cjs/data-source/models/where/string-where-filter.model.d.ts.map +1 -1
- package/dist/cjs/data-source/models/where/where-filter-keys.model.d.ts.map +1 -1
- package/dist/cjs/data-source/models/where/where-filter-keys.model.js +3 -0
- package/dist/cjs/data-source/models/where/where-filter-keys.model.js.map +1 -1
- package/dist/cjs/di/default/zibri-di-providers.default.d.ts.map +1 -1
- package/dist/cjs/di/default/zibri-di-providers.default.js +4 -0
- package/dist/cjs/di/default/zibri-di-providers.default.js.map +1 -1
- package/dist/cjs/di/default/zibri-di-tokens.default.d.ts +3 -0
- package/dist/cjs/di/default/zibri-di-tokens.default.d.ts.map +1 -1
- package/dist/cjs/di/default/zibri-di-tokens.default.js +2 -0
- package/dist/cjs/di/default/zibri-di-tokens.default.js.map +1 -1
- package/dist/cjs/email/email.service.d.ts +1 -1
- package/dist/cjs/email/email.service.d.ts.map +1 -1
- package/dist/cjs/email/email.service.js +4 -4
- package/dist/cjs/email/email.service.js.map +1 -1
- package/dist/cjs/email/models/email.model.d.ts +4 -4
- package/dist/cjs/email/models/email.model.d.ts.map +1 -1
- package/dist/cjs/email/models/email.model.js +4 -4
- package/dist/cjs/email/models/email.model.js.map +1 -1
- package/dist/cjs/entity/generation/generate-entity-file.function.js +1 -1
- package/dist/cjs/entity/generation/generate-entity-file.function.js.map +1 -1
- package/dist/cjs/event/event-subscriber-run.model.d.ts +1 -1
- package/dist/cjs/event/event-subscriber-run.model.d.ts.map +1 -1
- package/dist/cjs/event/event-subscriber-run.model.js +1 -1
- package/dist/cjs/event/event-subscriber-run.model.js.map +1 -1
- package/dist/cjs/global/global-registry.d.ts +2 -2
- package/dist/cjs/global/global-registry.d.ts.map +1 -1
- package/dist/cjs/http/http-request.model.d.ts +2 -2
- package/dist/cjs/http/http-request.model.d.ts.map +1 -1
- package/dist/cjs/http/known-header.enum.d.ts +1 -0
- package/dist/cjs/http/known-header.enum.d.ts.map +1 -1
- package/dist/cjs/http/known-header.enum.js +1 -0
- package/dist/cjs/http/known-header.enum.js.map +1 -1
- package/dist/cjs/http-client/http-client.d.ts.map +1 -1
- package/dist/cjs/http-client/http-client.js.map +1 -1
- package/dist/cjs/index.d.ts +7 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/localization/formatting/format-price.function.d.ts.map +1 -1
- package/dist/cjs/localization/formatting/format-price.function.js.map +1 -1
- package/dist/cjs/logging/log-context.model.d.ts +6 -6
- package/dist/cjs/logging/log-context.model.d.ts.map +1 -1
- package/dist/cjs/logging/log-context.model.js +6 -6
- package/dist/cjs/logging/log-context.model.js.map +1 -1
- package/dist/cjs/logging/logger.js +1 -1
- package/dist/cjs/logging/logger.js.map +1 -1
- package/dist/cjs/multithreading/models/thread-job-entity.model.d.ts +5 -5
- package/dist/cjs/multithreading/models/thread-job-entity.model.d.ts.map +1 -1
- package/dist/cjs/multithreading/models/thread-job-entity.model.js +4 -4
- package/dist/cjs/multithreading/models/thread-job-entity.model.js.map +1 -1
- package/dist/cjs/multithreading/services/thread-job.d.ts +4 -4
- package/dist/cjs/multithreading/services/thread-job.d.ts.map +1 -1
- package/dist/cjs/multithreading/services/thread-job.js.map +1 -1
- package/dist/cjs/open-api/open-api-service.interface.d.ts +2 -1
- package/dist/cjs/open-api/open-api-service.interface.d.ts.map +1 -1
- package/dist/cjs/open-api/open-api.service.d.ts +5 -2
- package/dist/cjs/open-api/open-api.service.d.ts.map +1 -1
- package/dist/cjs/open-api/open-api.service.js +256 -139
- package/dist/cjs/open-api/open-api.service.js.map +1 -1
- package/dist/cjs/parsing/html/csp-options.model.d.ts +1 -1
- package/dist/cjs/parsing/html/csp-options.model.d.ts.map +1 -1
- package/dist/cjs/parsing/html/csp-options.model.js.map +1 -1
- package/dist/cjs/parsing/parser.js +3 -3
- package/dist/cjs/parsing/parser.js.map +1 -1
- package/dist/cjs/plugin/invoicing/models/invoice-address.model.d.ts +2 -2
- package/dist/cjs/plugin/invoicing/models/invoice-address.model.d.ts.map +1 -1
- package/dist/cjs/plugin/invoicing/models/invoice-address.model.js +2 -2
- package/dist/cjs/plugin/invoicing/models/invoice-address.model.js.map +1 -1
- package/dist/cjs/plugin/invoicing/models/vat.model.d.ts +1 -1
- package/dist/cjs/plugin/invoicing/models/vat.model.d.ts.map +1 -1
- package/dist/cjs/plugin/invoicing/models/vat.model.js +1 -1
- package/dist/cjs/plugin/invoicing/models/vat.model.js.map +1 -1
- package/dist/cjs/plugin/mailing-list/mailing-list.controller.js +1 -1
- package/dist/cjs/plugin/mailing-list/mailing-list.controller.js.map +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.d.ts +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.d.ts.map +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.js +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscriber.model.js.map +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.d.ts +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.d.ts.map +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js +1 -1
- package/dist/cjs/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js.map +1 -1
- package/dist/cjs/plugin/payment/models/payment.model.d.ts +2 -2
- package/dist/cjs/plugin/payment/models/payment.model.d.ts.map +1 -1
- package/dist/cjs/plugin/payment/models/payment.model.js +1 -1
- package/dist/cjs/plugin/payment/models/payment.model.js.map +1 -1
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.d.ts +17 -17
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.d.ts.map +1 -1
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.js +17 -17
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal-client.js.map +1 -1
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js +1 -1
- package/dist/cjs/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js.map +1 -1
- package/dist/cjs/preact/preact.utilities.js +1 -1
- package/dist/cjs/preact/preact.utilities.js.map +1 -1
- package/dist/cjs/preact/validate-email-templates.function.js +1 -1
- package/dist/cjs/preact/validate-email-templates.function.js.map +1 -1
- package/dist/cjs/rate-limiting/rate-limiter.d.ts +10 -5
- package/dist/cjs/rate-limiting/rate-limiter.d.ts.map +1 -1
- package/dist/cjs/rate-limiting/rate-limiter.js +22 -12
- package/dist/cjs/rate-limiting/rate-limiter.js.map +1 -1
- package/dist/cjs/routing/controller-route-configuration.model.d.ts +5 -0
- package/dist/cjs/routing/controller-route-configuration.model.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/controller.decorator.d.ts +5 -0
- package/dist/cjs/routing/decorators/controller.decorator.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/controller.decorator.js +3 -2
- package/dist/cjs/routing/decorators/controller.decorator.js.map +1 -1
- package/dist/cjs/routing/decorators/create-http-decorator.function.d.ts +2 -1
- package/dist/cjs/routing/decorators/create-http-decorator.function.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/create-http-decorator.function.js +2 -2
- package/dist/cjs/routing/decorators/create-http-decorator.function.js.map +1 -1
- package/dist/cjs/routing/decorators/delete.decorator.d.ts +3 -1
- package/dist/cjs/routing/decorators/delete.decorator.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/delete.decorator.js +3 -2
- package/dist/cjs/routing/decorators/delete.decorator.js.map +1 -1
- package/dist/cjs/routing/decorators/get.decorator.d.ts +3 -1
- package/dist/cjs/routing/decorators/get.decorator.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/get.decorator.js +3 -2
- package/dist/cjs/routing/decorators/get.decorator.js.map +1 -1
- package/dist/cjs/routing/decorators/http-decorator-option-input.model.d.ts +11 -0
- package/dist/cjs/routing/decorators/http-decorator-option-input.model.d.ts.map +1 -0
- package/dist/cjs/routing/decorators/http-decorator-option-input.model.js +3 -0
- package/dist/cjs/routing/decorators/http-decorator-option-input.model.js.map +1 -0
- package/dist/cjs/routing/decorators/patch.decorator.d.ts +3 -1
- package/dist/cjs/routing/decorators/patch.decorator.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/patch.decorator.js +3 -2
- package/dist/cjs/routing/decorators/patch.decorator.js.map +1 -1
- package/dist/cjs/routing/decorators/post.decorator.d.ts +3 -1
- package/dist/cjs/routing/decorators/post.decorator.d.ts.map +1 -1
- package/dist/cjs/routing/decorators/post.decorator.js +3 -2
- package/dist/cjs/routing/decorators/post.decorator.js.map +1 -1
- package/dist/cjs/routing/resolve-route-params.function.js +1 -0
- package/dist/cjs/routing/resolve-route-params.function.js.map +1 -1
- package/dist/cjs/routing/route-configuration.model.d.ts +11 -1
- package/dist/cjs/routing/route-configuration.model.d.ts.map +1 -1
- package/dist/cjs/routing/router.d.ts +6 -2
- package/dist/cjs/routing/router.d.ts.map +1 -1
- package/dist/cjs/routing/router.js +173 -88
- package/dist/cjs/routing/router.js.map +1 -1
- package/dist/cjs/utilities/fs.utilities.d.ts +1 -1
- package/dist/cjs/utilities/fs.utilities.js +1 -1
- package/dist/cjs/utilities/sem-ver.utilities.d.ts +46 -0
- package/dist/cjs/utilities/sem-ver.utilities.d.ts.map +1 -0
- package/dist/cjs/utilities/sem-ver.utilities.js +204 -0
- package/dist/cjs/utilities/sem-ver.utilities.js.map +1 -0
- package/dist/cjs/utilities/uuid.utilities.js +2 -2
- package/dist/cjs/utilities/uuid.utilities.js.map +1 -1
- package/dist/cjs/versioning/route-with-version-data.model.d.ts +15 -0
- package/dist/cjs/versioning/route-with-version-data.model.d.ts.map +1 -0
- package/dist/cjs/versioning/route-with-version-data.model.js +3 -0
- package/dist/cjs/versioning/route-with-version-data.model.js.map +1 -0
- package/dist/cjs/versioning/supported-versions-options.model.d.ts +17 -0
- package/dist/cjs/versioning/supported-versions-options.model.d.ts.map +1 -0
- package/dist/cjs/versioning/supported-versions-options.model.js +3 -0
- package/dist/cjs/versioning/supported-versions-options.model.js.map +1 -0
- package/dist/cjs/versioning/version.model.d.ts +29 -0
- package/dist/cjs/versioning/version.model.d.ts.map +1 -0
- package/dist/{esm/types/version.type.js → cjs/versioning/version.model.js} +1 -1
- package/dist/cjs/versioning/version.model.js.map +1 -0
- package/dist/cjs/versioning/versioning-service.interface.d.ts +31 -0
- package/dist/cjs/versioning/versioning-service.interface.d.ts.map +1 -0
- package/dist/cjs/versioning/versioning-service.interface.js +3 -0
- package/dist/cjs/versioning/versioning-service.interface.js.map +1 -0
- package/dist/cjs/versioning/versioning.service.d.ts +41 -0
- package/dist/cjs/versioning/versioning.service.d.ts.map +1 -0
- package/dist/cjs/versioning/versioning.service.js +366 -0
- package/dist/cjs/versioning/versioning.service.js.map +1 -0
- package/dist/cjs/websocket/decorators/websocket-controller.decorator.d.ts +10 -0
- package/dist/cjs/websocket/decorators/websocket-controller.decorator.d.ts.map +1 -1
- package/dist/cjs/websocket/decorators/websocket-controller.decorator.js +2 -2
- package/dist/cjs/websocket/decorators/websocket-controller.decorator.js.map +1 -1
- package/dist/cjs/websocket/decorators/websocket-route.decorator.d.ts +13 -1
- package/dist/cjs/websocket/decorators/websocket-route.decorator.d.ts.map +1 -1
- package/dist/cjs/websocket/decorators/websocket-route.decorator.js +3 -2
- package/dist/cjs/websocket/decorators/websocket-route.decorator.js.map +1 -1
- package/dist/cjs/websocket/models/connection/base-websocket-connection.model.d.ts +5 -0
- package/dist/cjs/websocket/models/connection/base-websocket-connection.model.d.ts.map +1 -1
- package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.d.ts +3 -1
- package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.d.ts.map +1 -1
- package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.js +3 -1
- package/dist/cjs/websocket/models/connection/socket-io-websocket-connection.model.js.map +1 -1
- package/dist/cjs/websocket/models/websocket-controller-route-configuration.model.d.ts +6 -0
- package/dist/cjs/websocket/models/websocket-controller-route-configuration.model.d.ts.map +1 -1
- package/dist/cjs/websocket/models/websocket-message.model.d.ts +2 -2
- package/dist/cjs/websocket/models/websocket-message.model.d.ts.map +1 -1
- package/dist/cjs/websocket/models/websocket-message.model.js.map +1 -1
- package/dist/cjs/websocket/models/websocket-request.model.d.ts +3 -3
- package/dist/cjs/websocket/models/websocket-request.model.d.ts.map +1 -1
- package/dist/cjs/websocket/models/websocket-request.model.js +1 -1
- package/dist/cjs/websocket/models/websocket-request.model.js.map +1 -1
- package/dist/cjs/websocket/services/websocket.service.d.ts +6 -4
- package/dist/cjs/websocket/services/websocket.service.d.ts.map +1 -1
- package/dist/cjs/websocket/services/websocket.service.js +121 -33
- package/dist/cjs/websocket/services/websocket.service.js.map +1 -1
- package/dist/esm/application.js +0 -1
- package/dist/esm/application.js.map +1 -1
- package/dist/esm/assets/asset.service.js +3 -1
- package/dist/esm/assets/asset.service.js.map +1 -1
- package/dist/esm/auth/2fa/methods/otp/otp-credentials.model.js.map +1 -1
- package/dist/esm/auth/2fa/methods/otp/otp.two-factor-method.js +1 -1
- package/dist/esm/auth/2fa/methods/otp/otp.two-factor-method.js.map +1 -1
- package/dist/esm/auth/strategies/cookie/cookie-auth.controller.js +1 -1
- package/dist/esm/auth/strategies/cookie/cookie-auth.controller.js.map +1 -1
- package/dist/esm/auth/strategies/jwt/jwt-auth.controller.js +1 -1
- package/dist/esm/auth/strategies/jwt/jwt-auth.controller.js.map +1 -1
- package/dist/esm/auth/strategies/jwt/jwt.auth-strategy.js +1 -1
- package/dist/esm/auth/strategies/jwt/jwt.auth-strategy.js.map +1 -1
- package/dist/esm/backup/backup-resource-entity.model.js.map +1 -1
- package/dist/esm/change-sets/models/change-set.model.js +1 -1
- package/dist/esm/change-sets/models/change-set.model.js.map +1 -1
- package/dist/esm/change-sets/models/change.model.js.map +1 -1
- package/dist/esm/context/cache/cache.context.js +2 -2
- package/dist/esm/context/cache/cache.context.js.map +1 -1
- package/dist/esm/context/request/request-context-token.model.js +1 -1
- package/dist/esm/context/request/request-context-token.model.js.map +1 -1
- package/dist/esm/cron/cron-job-entity.model.js.map +1 -1
- package/dist/esm/data-source/data-sources/postgres-typeorm-data-source.model.js +9 -0
- package/dist/esm/data-source/data-sources/postgres-typeorm-data-source.model.js.map +1 -1
- package/dist/esm/data-source/data-sources/typeorm-base-data-source.model.js +3 -3
- package/dist/esm/data-source/data-sources/typeorm-base-data-source.model.js.map +1 -1
- package/dist/esm/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js +20 -0
- package/dist/esm/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.js.map +1 -1
- package/dist/esm/data-source/data-sources/where-converter/typeorm-where-filter.converter.js +3 -1
- package/dist/esm/data-source/data-sources/where-converter/typeorm-where-filter.converter.js.map +1 -1
- package/dist/esm/data-source/migration/migration-entity.model.js.map +1 -1
- package/dist/esm/data-source/models/where/where-filter-keys.model.js +3 -0
- package/dist/esm/data-source/models/where/where-filter-keys.model.js.map +1 -1
- package/dist/esm/di/default/zibri-di-providers.default.js +4 -0
- package/dist/esm/di/default/zibri-di-providers.default.js.map +1 -1
- package/dist/esm/di/default/zibri-di-tokens.default.js +2 -0
- package/dist/esm/di/default/zibri-di-tokens.default.js.map +1 -1
- package/dist/esm/email/email.service.js +4 -4
- package/dist/esm/email/email.service.js.map +1 -1
- package/dist/esm/email/models/email.model.js +4 -4
- package/dist/esm/email/models/email.model.js.map +1 -1
- package/dist/esm/entity/generation/generate-entity-file.function.js +1 -1
- package/dist/esm/entity/generation/generate-entity-file.function.js.map +1 -1
- package/dist/esm/event/event-subscriber-run.model.js +1 -1
- package/dist/esm/event/event-subscriber-run.model.js.map +1 -1
- package/dist/esm/http/known-header.enum.js +1 -0
- package/dist/esm/http/known-header.enum.js.map +1 -1
- package/dist/esm/http-client/http-client.js.map +1 -1
- package/dist/esm/index.js +8 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/localization/formatting/format-price.function.js.map +1 -1
- package/dist/esm/logging/log-context.model.js +6 -6
- package/dist/esm/logging/log-context.model.js.map +1 -1
- package/dist/esm/logging/logger.js +1 -1
- package/dist/esm/logging/logger.js.map +1 -1
- package/dist/esm/multithreading/models/thread-job-entity.model.js +4 -4
- package/dist/esm/multithreading/models/thread-job-entity.model.js.map +1 -1
- package/dist/esm/multithreading/services/thread-job.js.map +1 -1
- package/dist/esm/open-api/open-api.service.js +256 -139
- package/dist/esm/open-api/open-api.service.js.map +1 -1
- package/dist/esm/parsing/html/csp-options.model.js.map +1 -1
- package/dist/esm/parsing/parser.js +3 -3
- package/dist/esm/parsing/parser.js.map +1 -1
- package/dist/esm/plugin/invoicing/models/invoice-address.model.js +2 -2
- package/dist/esm/plugin/invoicing/models/invoice-address.model.js.map +1 -1
- package/dist/esm/plugin/invoicing/models/vat.model.js +1 -1
- package/dist/esm/plugin/invoicing/models/vat.model.js.map +1 -1
- package/dist/esm/plugin/mailing-list/mailing-list.controller.js +1 -1
- package/dist/esm/plugin/mailing-list/mailing-list.controller.js.map +1 -1
- package/dist/esm/plugin/mailing-list/models/mailing-list-subscriber.model.js +1 -1
- package/dist/esm/plugin/mailing-list/models/mailing-list-subscriber.model.js.map +1 -1
- package/dist/esm/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js +1 -1
- package/dist/esm/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.js.map +1 -1
- package/dist/esm/plugin/payment/models/payment.model.js +1 -1
- package/dist/esm/plugin/payment/models/payment.model.js.map +1 -1
- package/dist/esm/plugin/payment/providers/pay-pal/pay-pal-client.js +17 -17
- package/dist/esm/plugin/payment/providers/pay-pal/pay-pal-client.js.map +1 -1
- package/dist/esm/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js +1 -1
- package/dist/esm/plugin/payment/providers/pay-pal/pay-pal.payment-provider.js.map +1 -1
- package/dist/esm/preact/preact.utilities.js +1 -1
- package/dist/esm/preact/preact.utilities.js.map +1 -1
- package/dist/esm/preact/validate-email-templates.function.js +1 -1
- package/dist/esm/preact/validate-email-templates.function.js.map +1 -1
- package/dist/esm/rate-limiting/rate-limiter.js +22 -12
- package/dist/esm/rate-limiting/rate-limiter.js.map +1 -1
- package/dist/esm/routing/decorators/controller.decorator.js +3 -2
- package/dist/esm/routing/decorators/controller.decorator.js.map +1 -1
- package/dist/esm/routing/decorators/create-http-decorator.function.js +2 -2
- package/dist/esm/routing/decorators/create-http-decorator.function.js.map +1 -1
- package/dist/esm/routing/decorators/delete.decorator.js +3 -2
- package/dist/esm/routing/decorators/delete.decorator.js.map +1 -1
- package/dist/esm/routing/decorators/get.decorator.js +3 -2
- package/dist/esm/routing/decorators/get.decorator.js.map +1 -1
- package/dist/esm/routing/decorators/http-decorator-option-input.model.js +3 -0
- package/dist/esm/routing/decorators/http-decorator-option-input.model.js.map +1 -0
- package/dist/esm/routing/decorators/patch.decorator.js +3 -2
- package/dist/esm/routing/decorators/patch.decorator.js.map +1 -1
- package/dist/esm/routing/decorators/post.decorator.js +3 -2
- package/dist/esm/routing/decorators/post.decorator.js.map +1 -1
- package/dist/esm/routing/resolve-route-params.function.js +1 -0
- package/dist/esm/routing/resolve-route-params.function.js.map +1 -1
- package/dist/esm/routing/router.js +173 -88
- package/dist/esm/routing/router.js.map +1 -1
- package/dist/esm/utilities/fs.utilities.js +1 -1
- package/dist/esm/utilities/sem-ver.utilities.js +204 -0
- package/dist/esm/utilities/sem-ver.utilities.js.map +1 -0
- package/dist/esm/utilities/uuid.utilities.js +2 -2
- package/dist/esm/utilities/uuid.utilities.js.map +1 -1
- package/dist/esm/versioning/route-with-version-data.model.js +3 -0
- package/dist/esm/versioning/route-with-version-data.model.js.map +1 -0
- package/dist/esm/versioning/supported-versions-options.model.js +3 -0
- package/dist/esm/versioning/supported-versions-options.model.js.map +1 -0
- package/dist/{cjs/types/version.type.js → esm/versioning/version.model.js} +1 -1
- package/dist/esm/versioning/version.model.js.map +1 -0
- package/dist/esm/versioning/versioning-service.interface.js +3 -0
- package/dist/esm/versioning/versioning-service.interface.js.map +1 -0
- package/dist/esm/versioning/versioning.service.js +366 -0
- package/dist/esm/versioning/versioning.service.js.map +1 -0
- package/dist/esm/websocket/decorators/websocket-controller.decorator.js +2 -2
- package/dist/esm/websocket/decorators/websocket-controller.decorator.js.map +1 -1
- package/dist/esm/websocket/decorators/websocket-route.decorator.js +3 -2
- package/dist/esm/websocket/decorators/websocket-route.decorator.js.map +1 -1
- package/dist/esm/websocket/models/connection/socket-io-websocket-connection.model.js +3 -1
- package/dist/esm/websocket/models/connection/socket-io-websocket-connection.model.js.map +1 -1
- package/dist/esm/websocket/models/websocket-message.model.js.map +1 -1
- package/dist/esm/websocket/models/websocket-request.model.js +1 -1
- package/dist/esm/websocket/models/websocket-request.model.js.map +1 -1
- package/dist/esm/websocket/services/websocket.service.js +121 -33
- package/dist/esm/websocket/services/websocket.service.js.map +1 -1
- package/package.json +17 -19
- package/src/__testing__/test-server/providers.ts +25 -1
- package/src/__testing__/test-server/start-test-server.function.ts +76 -8
- package/src/application-options.model.ts +2 -2
- package/src/application.ts +0 -1
- package/src/assets/asset.service.ts +3 -1
- package/src/auth/2fa/methods/otp/otp-credentials.model.ts +1 -1
- package/src/auth/2fa/methods/otp/otp.two-factor-method.ts +1 -1
- package/src/auth/strategies/cookie/cookie-auth.controller.ts +1 -1
- package/src/auth/strategies/jwt/jwt-auth.controller.ts +1 -1
- package/src/auth/strategies/jwt/jwt.auth-strategy.ts +1 -1
- package/src/backup/backup-resource-entity.model.ts +1 -1
- package/src/backup/backup-service.test.ts +2 -1
- package/src/change-sets/models/change-set.model.ts +1 -1
- package/src/change-sets/models/change.model.ts +2 -2
- package/src/context/cache/cache.context.ts +2 -2
- package/src/context/request/request-context-token.model.ts +1 -1
- package/src/cron/cron-job-entity.model.ts +2 -2
- package/src/data-source/data-sources/postgres-typeorm-data-source.model.ts +10 -0
- package/src/data-source/data-sources/typeorm-base-data-source.model.ts +4 -5
- package/src/data-source/data-sources/where-converter/postgres-typeorm-where-filter.converter.ts +35 -2
- package/src/data-source/data-sources/where-converter/typeorm-where-filter.converter.ts +14 -1
- package/src/data-source/hooks/hooks.test.ts +1 -1
- package/src/data-source/migration/migration-entity.model.ts +2 -2
- package/src/data-source/migration/migration.model.ts +2 -2
- package/src/data-source/migration/migration.test.ts +2 -2
- package/src/data-source/models/where/date-where-filter.model.ts +11 -3
- package/src/data-source/models/where/string-where-filter.model.ts +18 -1
- package/src/data-source/models/where/where-filter-keys.model.ts +3 -0
- package/src/data-source/nested-where-filter.test.ts +8 -3
- package/src/data-source/repository.test.ts +2 -2
- package/src/data-source/where-filter.test.ts +17 -7
- package/src/di/default/zibri-di-providers.default.ts +4 -0
- package/src/di/default/zibri-di-tokens.default.ts +3 -0
- package/src/email/email.service.ts +5 -5
- package/src/email/models/email.model.ts +4 -4
- package/src/entity/generation/generate-entity-file.function.ts +1 -1
- package/src/event/event-subscriber-run.model.ts +1 -1
- package/src/global/global-registry.ts +2 -2
- package/src/http/http-request.model.ts +2 -2
- package/src/http/known-header.enum.ts +1 -0
- package/src/http-client/http-client.ts +0 -1
- package/src/index.ts +9 -3
- package/src/localization/formatting/format-price.function.ts +2 -3
- package/src/logging/log-context.model.ts +6 -6
- package/src/logging/logger.ts +1 -1
- package/src/multithreading/models/thread-job-entity.model.ts +5 -5
- package/src/multithreading/services/thread-job.ts +4 -4
- package/src/open-api/open-api-service.interface.ts +2 -1
- package/src/open-api/open-api.service.ts +263 -141
- package/src/parsing/html/csp-options.model.ts +3 -0
- package/src/parsing/parser.ts +3 -3
- package/src/plugin/invoicing/models/invoice-address.model.ts +2 -2
- package/src/plugin/invoicing/models/vat.model.ts +1 -1
- package/src/plugin/mailing-list/mailing-list.controller.ts +1 -1
- package/src/plugin/mailing-list/models/mailing-list-subscriber.model.ts +1 -1
- package/src/plugin/mailing-list/models/mailing-list-subscription-confirmation-token.model.ts +1 -1
- package/src/plugin/payment/models/payment.model.ts +2 -2
- package/src/plugin/payment/providers/pay-pal/pay-pal-client.ts +17 -17
- package/src/plugin/payment/providers/pay-pal/pay-pal.payment-provider.test.ts +1 -1
- package/src/plugin/payment/providers/pay-pal/pay-pal.payment-provider.ts +1 -1
- package/src/preact/preact.utilities.ts +1 -1
- package/src/preact/validate-email-templates.function.ts +1 -1
- package/src/rate-limiting/rate-limiter.ts +23 -12
- package/src/routing/controller-route-configuration.model.ts +6 -1
- package/src/routing/decorators/controller.decorator.ts +8 -2
- package/src/routing/decorators/create-http-decorator.function.ts +3 -2
- package/src/routing/decorators/delete.decorator.ts +4 -2
- package/src/routing/decorators/get.decorator.ts +4 -2
- package/src/routing/decorators/http-decorator-option-input.model.ts +11 -0
- package/src/routing/decorators/patch.decorator.ts +4 -2
- package/src/routing/decorators/post.decorator.ts +4 -2
- package/src/routing/resolve-route-params.function.ts +1 -0
- package/src/routing/route-configuration.model.ts +13 -3
- package/src/routing/router.ts +265 -134
- package/src/utilities/fs.utilities.ts +1 -1
- package/src/utilities/sem-ver.utilities.ts +270 -0
- package/src/utilities/uuid.utilities.ts +2 -2
- package/src/versioning/route-with-version-data.model.ts +15 -0
- package/src/versioning/supported-versions-options.model.ts +25 -0
- package/src/versioning/version.model.ts +30 -0
- package/src/versioning/versioning-service.interface.ts +39 -0
- package/src/versioning/versioning-websocket.test.ts +351 -0
- package/src/versioning/versioning.service.test.ts +582 -0
- package/src/versioning/versioning.service.ts +496 -0
- package/src/websocket/decorators/websocket-controller.decorator.ts +13 -3
- package/src/websocket/decorators/websocket-route.decorator.ts +15 -2
- package/src/websocket/models/connection/base-websocket-connection.model.ts +6 -0
- package/src/websocket/models/connection/socket-io-websocket-connection.model.ts +8 -1
- package/src/websocket/models/websocket-controller-route-configuration.model.ts +8 -1
- package/src/websocket/models/websocket-message.model.ts +2 -2
- package/src/websocket/models/websocket-request.model.ts +4 -3
- package/src/websocket/services/websocket.service.ts +143 -38
- package/dist/cjs/types/version.type.d.ts +0 -5
- package/dist/cjs/types/version.type.d.ts.map +0 -1
- package/dist/cjs/types/version.type.js.map +0 -1
- package/dist/cjs/utilities/compare-versions.function.d.ts +0 -9
- package/dist/cjs/utilities/compare-versions.function.d.ts.map +0 -1
- package/dist/cjs/utilities/compare-versions.function.js +0 -33
- package/dist/cjs/utilities/compare-versions.function.js.map +0 -1
- package/dist/cjs/utilities/is-version.function.d.ts +0 -7
- package/dist/cjs/utilities/is-version.function.d.ts.map +0 -1
- package/dist/cjs/utilities/is-version.function.js +0 -18
- package/dist/cjs/utilities/is-version.function.js.map +0 -1
- package/dist/esm/types/version.type.js.map +0 -1
- package/dist/esm/utilities/compare-versions.function.js +0 -33
- package/dist/esm/utilities/compare-versions.function.js.map +0 -1
- package/dist/esm/utilities/is-version.function.js +0 -18
- package/dist/esm/utilities/is-version.function.js.map +0 -1
- package/src/types/version.type.ts +0 -4
- package/src/utilities/compare-versions.function.ts +0 -33
- package/src/utilities/is-version.function.ts +0 -16
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { Dirent } from 'node:fs';
|
|
3
|
+
|
|
4
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it } from '@jest/globals';
|
|
5
|
+
|
|
6
|
+
import { RouteWithVersionData } from './route-with-version-data.model';
|
|
7
|
+
import { Version, VersionFile } from './version.model';
|
|
8
|
+
import { type VersioningServiceInterface } from './versioning-service.interface';
|
|
9
|
+
import { VersioningService } from './versioning.service';
|
|
10
|
+
import { testFileFolder } from '../__testing__/constants';
|
|
11
|
+
import { defaultTestServerProviders } from '../__testing__/test-server/providers';
|
|
12
|
+
import { startTestServer, StartedTestServer } from '../__testing__/test-server/start-test-server.function';
|
|
13
|
+
import { HttpRequestContext } from '../context/request/http-request.context';
|
|
14
|
+
import { WebsocketRequestContext } from '../context/request/websocket-request.context';
|
|
15
|
+
import { Inject } from '../di/decorators/inject.decorator';
|
|
16
|
+
import { ZIBRI_DI_TOKENS } from '../di/default/zibri-di-tokens.default';
|
|
17
|
+
import { inject } from '../di/inject.function';
|
|
18
|
+
import { type Header } from '../http/header.type';
|
|
19
|
+
import { Controller } from '../routing/decorators/controller.decorator';
|
|
20
|
+
import { Get } from '../routing/decorators/get.decorator';
|
|
21
|
+
import { type RouterInterface } from '../routing/router.interface';
|
|
22
|
+
import { Newable } from '../types/newable.type';
|
|
23
|
+
import { FsPath, FsUtilities } from '../utilities/fs.utilities';
|
|
24
|
+
import { JsonUtilities } from '../utilities/json.utilities';
|
|
25
|
+
import { SemVerVersion } from '../utilities/sem-ver.utilities';
|
|
26
|
+
|
|
27
|
+
const testVersionsDir: FsPath = FsUtilities.getPath(testFileFolder, 'versions');
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------
|
|
30
|
+
// Custom versioning service that writes to a temporary directory
|
|
31
|
+
// ---------------------------------------------------------------
|
|
32
|
+
class TestVersioningService extends VersioningService {
|
|
33
|
+
constructor(
|
|
34
|
+
@Inject(ZIBRI_DI_TOKENS.VERSION_HEADER)
|
|
35
|
+
versionHeader: Header,
|
|
36
|
+
@Inject(ZIBRI_DI_TOKENS.ROUTER)
|
|
37
|
+
router: RouterInterface
|
|
38
|
+
) {
|
|
39
|
+
super(versionHeader, router);
|
|
40
|
+
// eslint-disable-next-line typescript/no-unsafe-member-access, typescript/no-explicit-any
|
|
41
|
+
(this as any).versionsPath = testVersionsDir;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ---------------------------------------------------------------
|
|
46
|
+
// Test controller that exposes the versioning service via HTTP
|
|
47
|
+
// ---------------------------------------------------------------
|
|
48
|
+
@Controller('/version-test', { allowOrphan: true, versions: 'all' })
|
|
49
|
+
class VersionTestController {
|
|
50
|
+
constructor(
|
|
51
|
+
@Inject(ZIBRI_DI_TOKENS.VERSIONING_SERVICE)
|
|
52
|
+
private readonly versioningService: VersioningServiceInterface
|
|
53
|
+
) {}
|
|
54
|
+
|
|
55
|
+
@Get('/resolve')
|
|
56
|
+
async resolveVersion(): Promise<Version> {
|
|
57
|
+
const context: HttpRequestContext | WebsocketRequestContext | undefined = inject(ZIBRI_DI_TOKENS.CURRENT_REQUEST_CONTEXT);
|
|
58
|
+
if (!context) {
|
|
59
|
+
throw new Error('context missing');
|
|
60
|
+
}
|
|
61
|
+
return await this.versioningService.resolveVersion(context);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------
|
|
66
|
+
// Test controller with versioned routes for validation tests
|
|
67
|
+
// ---------------------------------------------------------------
|
|
68
|
+
@Controller('/validated', { versions: ['1.0.0'], allowOrphan: true })
|
|
69
|
+
class ValidatedController {
|
|
70
|
+
@Get('/endpoint')
|
|
71
|
+
getEndpoint(): { ok: boolean } {
|
|
72
|
+
return { ok: true };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Controller with a route that only uses 'latest', not '1.0.0'
|
|
77
|
+
@Controller('/latest-test', { versions: ['latest'], allowOrphan: true })
|
|
78
|
+
class LatestOnlyController {
|
|
79
|
+
@Get('/endpoint')
|
|
80
|
+
get(): {} {
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Controller('/bad', { versions: ['2.0.0'], allowOrphan: true })
|
|
86
|
+
class BadController {
|
|
87
|
+
@Get('/endpoint')
|
|
88
|
+
get(): {} {
|
|
89
|
+
return {};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let server: StartedTestServer;
|
|
94
|
+
let baseUrl: string;
|
|
95
|
+
|
|
96
|
+
// Helper to write a version file into the temp dir
|
|
97
|
+
async function writeVersionFile(file: VersionFile): Promise<void> {
|
|
98
|
+
const filePath: FsPath = FsUtilities.getPath(testVersionsDir, `${file.value}.json`);
|
|
99
|
+
await FsUtilities.mkdir(testVersionsDir);
|
|
100
|
+
await FsUtilities.upsertFile(filePath, JsonUtilities.stringify(file));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Helper to read a version file
|
|
104
|
+
async function readVersionFile(version: string): Promise<VersionFile> {
|
|
105
|
+
const filePath: FsPath = FsUtilities.getPath(testVersionsDir, `${version}.json`);
|
|
106
|
+
const raw: string = await FsUtilities.readFile(filePath);
|
|
107
|
+
return JsonUtilities.parse(raw);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Reset state before each test: clear temp dir and stop/restart?
|
|
111
|
+
// Since version files are read only during afterAppInit, which runs once at startup,
|
|
112
|
+
// we need to restart the server for each test scenario. We'll use a helper.
|
|
113
|
+
async function restartServer(options: { version?: SemVerVersion, controllers?: Newable<unknown>[] } = {}): Promise<void> {
|
|
114
|
+
await server.reInit(options);
|
|
115
|
+
baseUrl = await server.start();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
beforeAll(async () => {
|
|
119
|
+
await FsUtilities.rm(testVersionsDir);
|
|
120
|
+
// Start the server with our custom versioning service and a test controller
|
|
121
|
+
server = await startTestServer({
|
|
122
|
+
version: '1.0.0', // default version, we'll change per test
|
|
123
|
+
providers: [
|
|
124
|
+
...defaultTestServerProviders,
|
|
125
|
+
{ token: ZIBRI_DI_TOKENS.VERSIONING_SERVICE, useClass: TestVersioningService }
|
|
126
|
+
],
|
|
127
|
+
controllers: [VersionTestController, ValidatedController]
|
|
128
|
+
});
|
|
129
|
+
baseUrl = await server.start();
|
|
130
|
+
}, 15000);
|
|
131
|
+
|
|
132
|
+
afterAll(async () => {
|
|
133
|
+
await server.shutdown();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('VersioningService integration', () => {
|
|
137
|
+
describe('First startup', () => {
|
|
138
|
+
it('creates the initial version file with routes', async () => {
|
|
139
|
+
const file: VersionFile = await readVersionFile('1.0.0');
|
|
140
|
+
expect(file.value).toBe('1.0.0');
|
|
141
|
+
expect(file.endsAt).toBeUndefined();
|
|
142
|
+
expect(file.routes.length).toBeGreaterThan(0);
|
|
143
|
+
|
|
144
|
+
const validatedRoute: RouteWithVersionData | undefined = file.routes.find(r => r.key === 'GET /validated/endpoint');
|
|
145
|
+
expect(validatedRoute).toBeDefined();
|
|
146
|
+
expect(validatedRoute?.versions).toEqual(['1.0.0']);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe('Already at latest version (no-op)', () => {
|
|
151
|
+
it('does not modify the version file', async () => {
|
|
152
|
+
await restartServer({ version: '1.0.0' });
|
|
153
|
+
const file: VersionFile = await readVersionFile('1.0.0');
|
|
154
|
+
expect(file.endsAt).toBeUndefined();
|
|
155
|
+
// No new files created
|
|
156
|
+
const files: Dirent[] = await FsUtilities.readdir(testVersionsDir);
|
|
157
|
+
expect(files.map(f => f.name)).toEqual(['1.0.0.json']);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('Normal version bump', () => {
|
|
162
|
+
const oldVersion: SemVerVersion = '1.0.0';
|
|
163
|
+
const newVersion: SemVerVersion = '2.0.0';
|
|
164
|
+
|
|
165
|
+
beforeEach(async () => {
|
|
166
|
+
await FsUtilities.rm(testVersionsDir);
|
|
167
|
+
await restartServer({
|
|
168
|
+
version: oldVersion,
|
|
169
|
+
controllers: [ValidatedController]
|
|
170
|
+
});
|
|
171
|
+
await restartServer({
|
|
172
|
+
version: newVersion,
|
|
173
|
+
controllers: [ValidatedController]
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('deprecates the old version and creates the new one', async () => {
|
|
178
|
+
const oldFile: VersionFile = await readVersionFile(oldVersion);
|
|
179
|
+
assert(oldFile.endsAt);
|
|
180
|
+
const transitionTime: Date = new Date(oldFile.endsAt);
|
|
181
|
+
|
|
182
|
+
const newFile: VersionFile = await readVersionFile(newVersion);
|
|
183
|
+
expect(newFile.value).toBe(newVersion);
|
|
184
|
+
expect(newFile.endsAt).toBeUndefined();
|
|
185
|
+
expect(new Date(newFile.startsAt).getTime()).toBe(transitionTime.getTime());
|
|
186
|
+
// Routes in new file reflect current in-code routes (e.g., still include the validated endpoint)
|
|
187
|
+
expect(newFile.routes).toEqual(expect.arrayContaining([expect.objectContaining({ key: 'GET /validated/endpoint' })]));
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe('Crash recovery: zero active versions', () => {
|
|
192
|
+
const oldVersion: SemVerVersion = '1.0.0';
|
|
193
|
+
const newVersion: SemVerVersion = '2.0.0';
|
|
194
|
+
|
|
195
|
+
beforeEach(async () => {
|
|
196
|
+
// Old version already deprecated (crash scenario)
|
|
197
|
+
await writeVersionFile({
|
|
198
|
+
value: oldVersion,
|
|
199
|
+
startsAt: new Date('2024-01-01'),
|
|
200
|
+
endsAt: new Date('2024-02-01'),
|
|
201
|
+
routes: [{ key: 'GET /validated/endpoint', versions: [oldVersion] }]
|
|
202
|
+
});
|
|
203
|
+
// New version does NOT exist
|
|
204
|
+
await restartServer({ version: newVersion });
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('leaves the old file untouched and creates the new one with a fresh startsAt', async () => {
|
|
208
|
+
const oldFile: VersionFile = await readVersionFile(oldVersion);
|
|
209
|
+
expect(oldFile.endsAt).toBe('2024-02-01T00:00:00.000Z');
|
|
210
|
+
|
|
211
|
+
const newFile: VersionFile = await readVersionFile(newVersion);
|
|
212
|
+
expect(newFile.value).toBe(newVersion);
|
|
213
|
+
expect(newFile.endsAt).toBeUndefined();
|
|
214
|
+
assert(oldFile.endsAt);
|
|
215
|
+
expect(new Date(newFile.startsAt).getTime()).toBeGreaterThan(new Date(oldFile.endsAt).getTime());
|
|
216
|
+
// Validation still passed: the route GET /validated/endpoint still exists, so no error.
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe('Crash recovery: multiple active versions (incomplete bump)', () => {
|
|
221
|
+
const v1: SemVerVersion = '1.0.0';
|
|
222
|
+
const v2: SemVerVersion = '2.0.0'; // new app version, file already created prematurely
|
|
223
|
+
|
|
224
|
+
beforeEach(async () => {
|
|
225
|
+
await writeVersionFile({
|
|
226
|
+
value: v1,
|
|
227
|
+
startsAt: new Date('2024-01-01'),
|
|
228
|
+
routes: [{ key: 'GET /validated/endpoint', versions: [v1] }]
|
|
229
|
+
});
|
|
230
|
+
// Prematurely created new version file with stale routes
|
|
231
|
+
await writeVersionFile({
|
|
232
|
+
value: v2,
|
|
233
|
+
startsAt: new Date('2024-02-01'),
|
|
234
|
+
routes: [] // will be updated
|
|
235
|
+
});
|
|
236
|
+
await restartServer({ version: v2, controllers: [ValidatedController] });
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('chains endsAt of old versions and updates new file routes', async () => {
|
|
240
|
+
const oldFile: VersionFile = await readVersionFile(v1);
|
|
241
|
+
expect(oldFile.endsAt).toBe('2024-02-01T00:00:00.000Z');
|
|
242
|
+
|
|
243
|
+
const newFile: VersionFile = await readVersionFile(v2);
|
|
244
|
+
expect(newFile.endsAt).toBeUndefined();
|
|
245
|
+
expect(newFile.routes).toEqual(expect.arrayContaining([expect.objectContaining({ key: 'GET /validated/endpoint' })]));
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe('Validation: route removed', () => {
|
|
250
|
+
it('throws if a previously supported route is missing in the new version', async () => {
|
|
251
|
+
// Prepare old active version with an extra route
|
|
252
|
+
await writeVersionFile({
|
|
253
|
+
value: '1.0.0',
|
|
254
|
+
startsAt: new Date(),
|
|
255
|
+
routes: [
|
|
256
|
+
{ key: 'GET /validated/endpoint', versions: ['1.0.0'] },
|
|
257
|
+
{ key: 'POST /delete-me', versions: ['1.0.0'] }
|
|
258
|
+
]
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
// Start with version 2.0.0 and a controller that does NOT define POST /delete-me
|
|
262
|
+
// The ValidatedController only has GET /validated/endpoint, so POST /delete-me is missing.
|
|
263
|
+
await expect(
|
|
264
|
+
restartServer({ version: '2.0.0', controllers: [VersionTestController, ValidatedController] })
|
|
265
|
+
).rejects.toThrow(/Route "POST \/delete-me" no longer exists in code/);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
describe('Validation: unknown version in stored route (file-level first)', () => {
|
|
270
|
+
// Controller that supports the version referenced in the old snapshot
|
|
271
|
+
@Controller('/validated', { versions: ['2.0.0'], allowOrphan: true })
|
|
272
|
+
class ValidatedForV2Controller {
|
|
273
|
+
@Get('/endpoint')
|
|
274
|
+
getEndpoint(): { ok: boolean } {
|
|
275
|
+
return { ok: true };
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
it('throws file-level error before checking in-code routes', async () => {
|
|
280
|
+
await FsUtilities.rm(testVersionsDir);
|
|
281
|
+
// Create a version file with a stored route referencing a version that doesn't exist
|
|
282
|
+
await writeVersionFile({
|
|
283
|
+
value: '1.0.0',
|
|
284
|
+
startsAt: new Date(),
|
|
285
|
+
routes: [{ key: 'GET /validated/endpoint', versions: ['2.0.0'] }]
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
await expect(
|
|
289
|
+
restartServer({ version: '3.0.0', controllers: [ValidatedForV2Controller] })
|
|
290
|
+
).rejects.toThrow(
|
|
291
|
+
'Route version mismatch detected:\n- Unknown version "2.0.0" in version file "1.0.0.json" on route "GET /validated/endpoint"'
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
describe('Validation: unknown version in in-code route', () => {
|
|
297
|
+
it('throws after file-level checks pass if in-code route references unknown version', async () => {
|
|
298
|
+
await FsUtilities.rm(testVersionsDir);
|
|
299
|
+
await writeVersionFile({
|
|
300
|
+
value: '1.0.0',
|
|
301
|
+
startsAt: new Date(),
|
|
302
|
+
routes: [{ key: 'GET /validated/endpoint', versions: ['1.0.0'] }]
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
await expect(
|
|
306
|
+
restartServer({ version: '1.0.1', controllers: [ValidatedController, BadController] })
|
|
307
|
+
).rejects.toThrow(/Unknown version "2.0.0" on route "GET \/bad\/endpoint"/);
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('does NOT throw after file-level checks pass if in-code route references new version', async () => {
|
|
311
|
+
await writeVersionFile({
|
|
312
|
+
value: '1.0.0',
|
|
313
|
+
startsAt: new Date(),
|
|
314
|
+
routes: [{ key: 'GET /validated/endpoint', versions: ['1.0.0'] }]
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
await expect(
|
|
318
|
+
restartServer({ version: '2.0.0', controllers: [ValidatedController, BadController] })
|
|
319
|
+
).resolves.not.toThrow();
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe('Validation: latest route must support previous version', () => {
|
|
324
|
+
it('throws if route uses "latest" but does not explicitly support the previous version', async () => {
|
|
325
|
+
await writeVersionFile({
|
|
326
|
+
value: '1.0.0',
|
|
327
|
+
startsAt: new Date(),
|
|
328
|
+
routes: [] // empty snapshot
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
await expect(
|
|
332
|
+
restartServer({ version: '2.0.0', controllers: [VersionTestController, LatestOnlyController] })
|
|
333
|
+
).rejects.toThrow(
|
|
334
|
+
/There are routes that have been used under the previous version "1.0.0"/
|
|
335
|
+
);
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
describe('resolveVersion via HTTP', () => {
|
|
340
|
+
beforeEach(async () => {
|
|
341
|
+
// Ensure we have version files for 1.0.0 and 2.0.0 active
|
|
342
|
+
await writeVersionFile({
|
|
343
|
+
value: '1.0.0',
|
|
344
|
+
startsAt: new Date('2024-01-01'),
|
|
345
|
+
endsAt: new Date('2024-02-01'),
|
|
346
|
+
routes: []
|
|
347
|
+
});
|
|
348
|
+
await writeVersionFile({
|
|
349
|
+
value: '2.0.0',
|
|
350
|
+
startsAt: new Date('2024-02-01'),
|
|
351
|
+
routes: []
|
|
352
|
+
});
|
|
353
|
+
await restartServer({ version: '2.0.0' });
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('returns latest version when no header provided', async () => {
|
|
357
|
+
const res: Response = await fetch(`${baseUrl}/version-test/resolve`);
|
|
358
|
+
const body: Version = await res.json() as Version;
|
|
359
|
+
expect(res.status).toBe(200);
|
|
360
|
+
expect(body.value).toBe('2.0.0');
|
|
361
|
+
expect(body.endsAt).toBeUndefined();
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
it('returns specific version by string', async () => {
|
|
365
|
+
const res: Response = await fetch(`${baseUrl}/version-test/resolve`, {
|
|
366
|
+
headers: { 'x-version': '1.0.0' }
|
|
367
|
+
});
|
|
368
|
+
const body: Version = await res.json() as Version;
|
|
369
|
+
expect(res.status).toBe(200);
|
|
370
|
+
expect(body.value).toBe('1.0.0');
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
it('resolves version by date (boundary case)', async () => {
|
|
374
|
+
const res: Response = await fetch(`${baseUrl}/version-test/resolve`, {
|
|
375
|
+
headers: { 'x-version': '2024-02-01T00:00:00.000Z' }
|
|
376
|
+
});
|
|
377
|
+
const body: Version = await res.json() as Version;
|
|
378
|
+
expect(res.status).toBe(200);
|
|
379
|
+
expect(body.value).toBe('2.0.0'); // half-open: startsAt <= date and endsAt > date or null
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('returns 400 for unknown version string', async () => {
|
|
383
|
+
const res: Response = await fetch(`${baseUrl}/version-test/resolve`, {
|
|
384
|
+
headers: { 'x-version': '9.9.9' }
|
|
385
|
+
});
|
|
386
|
+
expect(res.status).toBe(400);
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it('returns 400 for date with no active version', async () => {
|
|
390
|
+
const res: Response = await fetch(`${baseUrl}/version-test/resolve`, {
|
|
391
|
+
headers: { 'x-version': '2023-12-31T00:00:00.000Z' }
|
|
392
|
+
});
|
|
393
|
+
expect(res.status).toBe(400);
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
describe('Version-based routing', () => {
|
|
398
|
+
@Controller('/routing-test', { allowOrphan: true })
|
|
399
|
+
class VersionedRouteController {
|
|
400
|
+
@Get('/multi', { versions: ['1.0.0'] })
|
|
401
|
+
multiV1(): object {
|
|
402
|
+
return { handler: 'v1' };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
@Get('/multi', { versions: ['2.0.0'] })
|
|
406
|
+
multiV2(): object {
|
|
407
|
+
return { handler: 'v2' };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
@Get('/missing-v2', { versions: ['1.0.0'] })
|
|
411
|
+
missingV2Handler(): object {
|
|
412
|
+
return { handler: 'v1' };
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
@Get('/only-latest', { versions: ['latest'] })
|
|
416
|
+
onlyLatest(): object {
|
|
417
|
+
return { handler: 'latest' };
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
@Get('/only-all', { versions: 'all' })
|
|
421
|
+
onlyAll(): object {
|
|
422
|
+
return { handler: 'all' };
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
beforeEach(async () => {
|
|
427
|
+
await writeVersionFile({
|
|
428
|
+
value: '1.0.0',
|
|
429
|
+
startsAt: new Date('2024-01-01'),
|
|
430
|
+
endsAt: new Date('2024-02-01'),
|
|
431
|
+
routes: []
|
|
432
|
+
});
|
|
433
|
+
await writeVersionFile({
|
|
434
|
+
value: '2.0.0',
|
|
435
|
+
startsAt: new Date('2024-02-01'),
|
|
436
|
+
routes: []
|
|
437
|
+
});
|
|
438
|
+
await writeVersionFile({
|
|
439
|
+
value: '3.0.0',
|
|
440
|
+
startsAt: new Date('2024-01-01'),
|
|
441
|
+
endsAt: new Date('2024-01-15'),
|
|
442
|
+
routes: []
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
await restartServer({
|
|
446
|
+
version: '2.0.0',
|
|
447
|
+
controllers: [VersionedRouteController]
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// --- /multi ---
|
|
452
|
+
it('uses v2 handler when no header (active version)', async () => {
|
|
453
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/multi`);
|
|
454
|
+
expect(res.status).toBe(200);
|
|
455
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
456
|
+
const body: { handler: string } = await res.json();
|
|
457
|
+
expect(body.handler).toBe('v2');
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it('uses v1 handler when requesting 1.0.0 explicitly', async () => {
|
|
461
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/multi`, {
|
|
462
|
+
headers: { 'x-version': '1.0.0' }
|
|
463
|
+
});
|
|
464
|
+
expect(res.status).toBe(200);
|
|
465
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
466
|
+
const body: { handler: string } = await res.json();
|
|
467
|
+
expect(body.handler).toBe('v1');
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
it('uses v2 handler when requesting 2.0.0 explicitly', async () => {
|
|
471
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/multi`, {
|
|
472
|
+
headers: { 'x-version': '2.0.0' }
|
|
473
|
+
});
|
|
474
|
+
expect(res.status).toBe(200);
|
|
475
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
476
|
+
const body: { handler: string } = await res.json();
|
|
477
|
+
expect(body.handler).toBe('v2');
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('falls back to "all" handler for known version 3.0.0 without specific handler', async () => {
|
|
481
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/multi`, {
|
|
482
|
+
headers: { 'x-version': '3.0.0' }
|
|
483
|
+
});
|
|
484
|
+
expect(res.status).toBe(404);
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it('returns 400 for unknown version', async () => {
|
|
488
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/multi`, {
|
|
489
|
+
headers: { 'x-version': '4.0.0' }
|
|
490
|
+
});
|
|
491
|
+
expect(res.status).toBe(400);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// --- /missing-v2 ---
|
|
495
|
+
it('returns 404 when active version has no handler', async () => {
|
|
496
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/missing-v2`);
|
|
497
|
+
expect(res.status).toBe(404);
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it('serves v1 handler when requesting 1.0.0 even if no 2.0.0 handler exists', async () => {
|
|
501
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/missing-v2`, {
|
|
502
|
+
headers: { 'x-version': '1.0.0' }
|
|
503
|
+
});
|
|
504
|
+
expect(res.status).toBe(200);
|
|
505
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
506
|
+
const body: { handler: string } = await res.json();
|
|
507
|
+
expect(body.handler).toBe('v1');
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('returns 404 when explicit 2.0.0 has no handler', async () => {
|
|
511
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/missing-v2`, {
|
|
512
|
+
headers: { 'x-version': '2.0.0' }
|
|
513
|
+
});
|
|
514
|
+
expect(res.status).toBe(404);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// --- /only-latest ---
|
|
518
|
+
it('uses latest handler for active version (no header)', async () => {
|
|
519
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/only-latest`);
|
|
520
|
+
expect(res.status).toBe(200);
|
|
521
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
522
|
+
const body: { handler: string } = await res.json();
|
|
523
|
+
expect(body.handler).toBe('latest');
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
it('uses latest handler when explicitly requesting active version 2.0.0', async () => {
|
|
527
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/only-latest`, {
|
|
528
|
+
headers: { 'x-version': '2.0.0' }
|
|
529
|
+
});
|
|
530
|
+
expect(res.status).toBe(200);
|
|
531
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
532
|
+
const body: { handler: string } = await res.json();
|
|
533
|
+
expect(body.handler).toBe('latest');
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
it('returns 404 when requesting older version on a latest‑only route', async () => {
|
|
537
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/only-latest`, {
|
|
538
|
+
headers: { 'x-version': '1.0.0' }
|
|
539
|
+
});
|
|
540
|
+
expect(res.status).toBe(404);
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
// --- /only-all ---
|
|
544
|
+
it('uses all handler for any valid version (1.0.0)', async () => {
|
|
545
|
+
const res: Response = await fetch(`${baseUrl}/routing-test/only-all`, {
|
|
546
|
+
headers: { 'x-version': '1.0.0' }
|
|
547
|
+
});
|
|
548
|
+
expect(res.status).toBe(200);
|
|
549
|
+
// eslint-disable-next-line typescript/no-unsafe-assignment
|
|
550
|
+
const body: { handler: string } = await res.json();
|
|
551
|
+
expect(body.handler).toBe('all');
|
|
552
|
+
});
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
describe('Validation: overlap between latest and active version', () => {
|
|
556
|
+
@Controller('/overlap', { allowOrphan: true })
|
|
557
|
+
class OverlapController {
|
|
558
|
+
@Get('/endpoint', { versions: ['latest'] })
|
|
559
|
+
latest(): { handler: string } {
|
|
560
|
+
return { handler: 'latest' };
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
@Get('/endpoint', { versions: ['2.0.0'] })
|
|
564
|
+
v2(): { handler: string } {
|
|
565
|
+
return { handler: 'v2' };
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
it('throws if latest overlaps with the current active version', async () => {
|
|
570
|
+
await FsUtilities.rm(testVersionsDir);
|
|
571
|
+
await writeVersionFile({
|
|
572
|
+
value: '2.0.0',
|
|
573
|
+
startsAt: new Date('2024-02-01'),
|
|
574
|
+
routes: []
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
await expect(
|
|
578
|
+
restartServer({ version: '2.0.0', controllers: [OverlapController] })
|
|
579
|
+
).rejects.toThrow(/defined more than once/);
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
});
|