@warlock.js/core 5.28.0 → 5.30.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/CHANGELOG.md +71 -0
- package/esm/application/app.d.mts +1 -1
- package/esm/application/app.d.mts.map +1 -1
- package/esm/application/app.mjs +1 -1
- package/esm/application/app.mjs.map +1 -1
- package/esm/application/application-config-types.d.mts +1 -1
- package/esm/application/application-config-types.d.mts.map +1 -1
- package/esm/application/application.d.mts +1 -1
- package/esm/application/application.d.mts.map +1 -1
- package/esm/application/application.mjs +1 -1
- package/esm/application/application.mjs.map +1 -1
- package/esm/application/boot-signal.d.mts +1 -1
- package/esm/application/boot-signal.d.mts.map +1 -1
- package/esm/application/boot-signal.mjs +1 -1
- package/esm/application/boot-signal.mjs.map +1 -1
- package/esm/application/public-url.d.mts +1 -1
- package/esm/application/public-url.d.mts.map +1 -1
- package/esm/application/public-url.mjs +1 -1
- package/esm/application/public-url.mjs.map +1 -1
- package/esm/application/roles.d.mts +1 -1
- package/esm/application/roles.d.mts.map +1 -1
- package/esm/application/roles.mjs +1 -1
- package/esm/application/roles.mjs.map +1 -1
- package/esm/benchmark/benchmark-snapshots.d.mts +1 -1
- package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
- package/esm/benchmark/benchmark-snapshots.mjs +1 -1
- package/esm/benchmark/benchmark-snapshots.mjs.map +1 -1
- package/esm/benchmark/benchmark.d.mts +1 -1
- package/esm/benchmark/benchmark.d.mts.map +1 -1
- package/esm/benchmark/benchmark.mjs +1 -1
- package/esm/benchmark/benchmark.mjs.map +1 -1
- package/esm/benchmark/channels/console.channel.d.mts +1 -1
- package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
- package/esm/benchmark/channels/console.channel.mjs +1 -1
- package/esm/benchmark/channels/console.channel.mjs.map +1 -1
- package/esm/benchmark/channels/noop.channel.d.mts +1 -1
- package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
- package/esm/benchmark/channels/noop.channel.mjs +1 -1
- package/esm/benchmark/channels/noop.channel.mjs.map +1 -1
- package/esm/benchmark/profiler.d.mts +1 -1
- package/esm/benchmark/profiler.d.mts.map +1 -1
- package/esm/benchmark/profiler.mjs +1 -1
- package/esm/benchmark/profiler.mjs.map +1 -1
- package/esm/benchmark/types.d.mts +1 -1
- package/esm/benchmark/types.d.mts.map +1 -1
- package/esm/bootstrap/setup.d.mts +1 -1
- package/esm/bootstrap/setup.d.mts.map +1 -1
- package/esm/bootstrap/setup.mjs +1 -1
- package/esm/bootstrap/setup.mjs.map +1 -1
- package/esm/bootstrap.d.mts +1 -1
- package/esm/bootstrap.d.mts.map +1 -1
- package/esm/bootstrap.mjs +1 -1
- package/esm/bootstrap.mjs.map +1 -1
- package/esm/cache/database-cache-driver.d.mts +1 -1
- package/esm/cache/database-cache-driver.d.mts.map +1 -1
- package/esm/cache/database-cache-driver.mjs +1 -1
- package/esm/cache/database-cache-driver.mjs.map +1 -1
- package/esm/cache/index.mjs +1 -1
- package/esm/cache/index.mjs.map +1 -1
- package/esm/cli/cli-commands.manager.mjs +1 -1
- package/esm/cli/cli-commands.manager.mjs.map +1 -1
- package/esm/cli/cli-commands.utils.mjs +1 -1
- package/esm/cli/cli-commands.utils.mjs.map +1 -1
- package/esm/cli/commands/add.command.mjs +1 -1
- package/esm/cli/commands/add.command.mjs.map +1 -1
- package/esm/cli/commands/build.command.mjs +1 -1
- package/esm/cli/commands/build.command.mjs.map +1 -1
- package/esm/cli/commands/create-database.command.mjs +1 -1
- package/esm/cli/commands/create-database.command.mjs.map +1 -1
- package/esm/cli/commands/dev-server.command.mjs +1 -1
- package/esm/cli/commands/dev-server.command.mjs.map +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/config.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/index.mjs +1 -1
- package/esm/cli/commands/doctor/checks/index.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
- package/esm/cli/commands/doctor/format-report.mjs +1 -1
- package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
- package/esm/cli/commands/doctor/run-checks.mjs +1 -1
- package/esm/cli/commands/doctor/run-checks.mjs.map +1 -1
- package/esm/cli/commands/doctor.command.mjs +1 -1
- package/esm/cli/commands/doctor.command.mjs.map +1 -1
- package/esm/cli/commands/drop-tables.command.mjs +1 -1
- package/esm/cli/commands/drop-tables.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generate.command.mjs +1 -1
- package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/column-dsl-parser.mjs +1 -1
- package/esm/cli/commands/generate/generators/column-dsl-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/controller.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/use-case.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/use-case.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/templates/stubs.mjs +1 -1
- package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
- package/esm/cli/commands/generate/utils/path-resolver.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
- package/esm/cli/commands/migrate.command.mjs +1 -1
- package/esm/cli/commands/migrate.command.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.action.mjs +1 -1
- package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.action.mjs +1 -1
- package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.command.mjs +1 -1
- package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
- package/esm/cli/commands/routes/diff-page-routes.mjs +1 -1
- package/esm/cli/commands/routes/diff-page-routes.mjs.map +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs.map +1 -1
- package/esm/cli/commands/routes/route-row.mjs +1 -1
- package/esm/cli/commands/routes/route-row.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-command.action.mjs +1 -1
- package/esm/cli/commands/routes/routes-command.action.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs.map +1 -1
- package/esm/cli/commands/routes/with-console-on-stderr.mjs +1 -1
- package/esm/cli/commands/routes/with-console-on-stderr.mjs.map +1 -1
- package/esm/cli/commands/routes.command.mjs +1 -1
- package/esm/cli/commands/routes.command.mjs.map +1 -1
- package/esm/cli/commands/seed.command.mjs +1 -1
- package/esm/cli/commands/seed.command.mjs.map +1 -1
- package/esm/cli/commands/start-production.command.mjs +1 -1
- package/esm/cli/commands/start-production.command.mjs.map +1 -1
- package/esm/cli/commands/storage-put.action.mjs +1 -1
- package/esm/cli/commands/storage-put.action.mjs.map +1 -1
- package/esm/cli/commands/storage-put.command.mjs +1 -1
- package/esm/cli/commands/storage-put.command.mjs.map +1 -1
- package/esm/cli/commands/typings-generator.command.mjs +1 -1
- package/esm/cli/commands/typings-generator.command.mjs.map +1 -1
- package/esm/cli/commands/update.command.mjs +1 -1
- package/esm/cli/commands/update.command.mjs.map +1 -1
- package/esm/cli/commands-loader.mjs +1 -1
- package/esm/cli/commands-loader.mjs.map +1 -1
- package/esm/cli/framework-cli-commands.mjs +1 -1
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/cli/parse-cli-args.mjs +1 -1
- package/esm/cli/parse-cli-args.mjs.map +1 -1
- package/esm/cli/start.mjs +1 -1
- package/esm/cli/start.mjs.map +1 -1
- package/esm/cli/string-similarity.mjs +1 -1
- package/esm/cli/string-similarity.mjs.map +1 -1
- package/esm/commands/cli-command.d.mts +1 -1
- package/esm/commands/cli-command.d.mts.map +1 -1
- package/esm/commands/cli-command.mjs +1 -1
- package/esm/commands/cli-command.mjs.map +1 -1
- package/esm/commands/types.d.mts +1 -1
- package/esm/commands/types.d.mts.map +1 -1
- package/esm/config/config-getter.d.mts +1 -1
- package/esm/config/config-getter.d.mts.map +1 -1
- package/esm/config/config-getter.mjs +1 -1
- package/esm/config/config-getter.mjs.map +1 -1
- package/esm/config/config-handlers.d.mts +1 -1
- package/esm/config/config-handlers.d.mts.map +1 -1
- package/esm/config/config-handlers.mjs +1 -1
- package/esm/config/config-handlers.mjs.map +1 -1
- package/esm/config/config-key-from-path.mjs +1 -1
- package/esm/config/config-key-from-path.mjs.map +1 -1
- package/esm/config/config-loader.d.mts +1 -1
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +1 -1
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-manager.mjs +1 -1
- package/esm/config/config-manager.mjs.map +1 -1
- package/esm/config/config-setter.d.mts +1 -1
- package/esm/config/config-setter.d.mts.map +1 -1
- package/esm/config/config-setter.mjs +1 -1
- package/esm/config/config-setter.mjs.map +1 -1
- package/esm/config/config-special-handlers.d.mts +1 -1
- package/esm/config/config-special-handlers.d.mts.map +1 -1
- package/esm/config/config-special-handlers.mjs +1 -1
- package/esm/config/config-special-handlers.mjs.map +1 -1
- package/esm/config/load-config-files.mjs +1 -1
- package/esm/config/load-config-files.mjs.map +1 -1
- package/esm/config/locale-configuration.mjs +1 -1
- package/esm/config/locale-configuration.mjs.map +1 -1
- package/esm/config/types.d.mts +1 -1
- package/esm/config/types.d.mts.map +1 -1
- package/esm/connectors/access-connector.d.mts +1 -1
- package/esm/connectors/access-connector.d.mts.map +1 -1
- package/esm/connectors/access-connector.mjs +1 -1
- package/esm/connectors/access-connector.mjs.map +1 -1
- package/esm/connectors/ai-connector.d.mts +1 -1
- package/esm/connectors/ai-connector.d.mts.map +1 -1
- package/esm/connectors/ai-connector.mjs +1 -1
- package/esm/connectors/ai-connector.mjs.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.d.mts +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
- package/esm/connectors/base-connector.d.mts +1 -1
- package/esm/connectors/base-connector.d.mts.map +1 -1
- package/esm/connectors/base-connector.mjs +1 -1
- package/esm/connectors/base-connector.mjs.map +1 -1
- package/esm/connectors/cache-connector.d.mts +1 -1
- package/esm/connectors/cache-connector.d.mts.map +1 -1
- package/esm/connectors/cache-connector.mjs +1 -1
- package/esm/connectors/cache-connector.mjs.map +1 -1
- package/esm/connectors/connectors-manager.d.mts +1 -1
- package/esm/connectors/connectors-manager.d.mts.map +1 -1
- package/esm/connectors/connectors-manager.mjs +2 -2
- package/esm/connectors/connectors-manager.mjs.map +1 -1
- package/esm/connectors/database-connector.d.mts +1 -1
- package/esm/connectors/database-connector.d.mts.map +1 -1
- package/esm/connectors/database-connector.mjs +1 -1
- package/esm/connectors/database-connector.mjs.map +1 -1
- package/esm/connectors/describe-server-address.mjs +1 -1
- package/esm/connectors/describe-server-address.mjs.map +1 -1
- package/esm/connectors/herald-connector.d.mts +1 -1
- package/esm/connectors/herald-connector.d.mts.map +1 -1
- package/esm/connectors/herald-connector.mjs +1 -1
- package/esm/connectors/herald-connector.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +1 -1
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/logger-connector.d.mts +1 -1
- package/esm/connectors/logger-connector.d.mts.map +1 -1
- package/esm/connectors/logger-connector.mjs +1 -1
- package/esm/connectors/logger-connector.mjs.map +1 -1
- package/esm/connectors/mail-connector.d.mts +1 -1
- package/esm/connectors/mail-connector.d.mts.map +1 -1
- package/esm/connectors/mail-connector.mjs +1 -1
- package/esm/connectors/mail-connector.mjs.map +1 -1
- package/esm/connectors/notifications-connector.d.mts +1 -1
- package/esm/connectors/notifications-connector.d.mts.map +1 -1
- package/esm/connectors/notifications-connector.mjs +1 -1
- package/esm/connectors/notifications-connector.mjs.map +1 -1
- package/esm/connectors/read-bound-port.mjs +1 -1
- package/esm/connectors/read-bound-port.mjs.map +1 -1
- package/esm/connectors/register-configured-connectors.d.mts +1 -1
- package/esm/connectors/register-configured-connectors.d.mts.map +1 -1
- package/esm/connectors/register-configured-connectors.mjs +1 -1
- package/esm/connectors/register-configured-connectors.mjs.map +1 -1
- package/esm/connectors/single-server-warnings.mjs +1 -1
- package/esm/connectors/single-server-warnings.mjs.map +1 -1
- package/esm/connectors/socket-connector.d.mts +1 -1
- package/esm/connectors/socket-connector.d.mts.map +1 -1
- package/esm/connectors/socket-connector.mjs +1 -1
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/connectors/storage.connector.d.mts +1 -1
- package/esm/connectors/storage.connector.d.mts.map +1 -1
- package/esm/connectors/storage.connector.mjs +1 -1
- package/esm/connectors/storage.connector.mjs.map +1 -1
- package/esm/connectors/types.d.mts +1 -1
- package/esm/connectors/types.d.mts.map +1 -1
- package/esm/connectors/types.mjs +1 -1
- package/esm/connectors/types.mjs.map +1 -1
- package/esm/container/container-instance-registry.mjs +1 -1
- package/esm/container/container-instance-registry.mjs.map +1 -1
- package/esm/container/development-app-modules.d.mts +31 -0
- package/esm/container/development-app-modules.d.mts.map +1 -0
- package/esm/container/development-model-modules.d.mts +1 -1
- package/esm/container/development-model-modules.d.mts.map +1 -1
- package/esm/container/index.d.mts +3 -1
- package/esm/container/index.d.mts.map +1 -1
- package/esm/container/index.mjs +1 -1
- package/esm/container/index.mjs.map +1 -1
- package/esm/database/create-database-action.mjs +1 -1
- package/esm/database/create-database-action.mjs.map +1 -1
- package/esm/database/drop-tables-action.mjs +1 -1
- package/esm/database/drop-tables-action.mjs.map +1 -1
- package/esm/database/migrate-action.mjs +1 -1
- package/esm/database/migrate-action.mjs.map +1 -1
- package/esm/database/models/database-log/database-log.d.mts +31 -39
- package/esm/database/models/database-log/database-log.d.mts.map +1 -1
- package/esm/database/models/database-log/database-log.mjs +1 -1
- package/esm/database/models/database-log/database-log.mjs.map +1 -1
- package/esm/database/pending-exit-code.mjs +1 -1
- package/esm/database/pending-exit-code.mjs.map +1 -1
- package/esm/database/resolve-pending-migrations.mjs +1 -1
- package/esm/database/resolve-pending-migrations.mjs.map +1 -1
- package/esm/database/seed-command-action.mjs +1 -1
- package/esm/database/seed-command-action.mjs.map +1 -1
- package/esm/database/seeds/seed-records-table-migration.mjs +1 -1
- package/esm/database/seeds/seed-records-table-migration.mjs.map +1 -1
- package/esm/database/seeds/seeder.d.mts +1 -1
- package/esm/database/seeds/seeder.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +1 -1
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.mjs +1 -1
- package/esm/database/seeds/seeder.errors.mjs.map +1 -1
- package/esm/database/seeds/seeder.mjs +1 -1
- package/esm/database/seeds/seeder.mjs.map +1 -1
- package/esm/database/seeds/seeders.manager.mjs +1 -1
- package/esm/database/seeds/seeders.manager.mjs.map +1 -1
- package/esm/database/seeds/seeds-table-migration.mjs +1 -1
- package/esm/database/seeds/seeds-table-migration.mjs.map +1 -1
- package/esm/database/seeds/types.d.mts +1 -1
- package/esm/database/seeds/types.d.mts.map +1 -1
- package/esm/database/seeds/utils.mjs +1 -1
- package/esm/database/seeds/utils.mjs.map +1 -1
- package/esm/database/utils.d.mts +1 -1
- package/esm/database/utils.d.mts.map +1 -1
- package/esm/database/utils.mjs +1 -1
- package/esm/database/utils.mjs.map +1 -1
- package/esm/dev-server/app-module-registry.mjs +52 -0
- package/esm/dev-server/app-module-registry.mjs.map +1 -0
- package/esm/dev-server/boot-precondition-error.mjs +1 -1
- package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
- package/esm/dev-server/build-development-openapi-document.mjs +1 -1
- package/esm/dev-server/build-development-openapi-document.mjs.map +1 -1
- package/esm/dev-server/check-for-updates.mjs +1 -1
- package/esm/dev-server/check-for-updates.mjs.map +1 -1
- package/esm/dev-server/collect-development-api-routes.mjs +1 -1
- package/esm/dev-server/collect-development-api-routes.mjs.map +1 -1
- package/esm/dev-server/create-worker.mjs +1 -1
- package/esm/dev-server/create-worker.mjs.map +1 -1
- package/esm/dev-server/dependency-graph.d.mts +1 -1
- package/esm/dev-server/dependency-graph.d.mts.map +1 -1
- package/esm/dev-server/dependency-graph.mjs +1 -1
- package/esm/dev-server/dependency-graph.mjs.map +1 -1
- package/esm/dev-server/dev-logger.mjs +1 -1
- package/esm/dev-server/dev-logger.mjs.map +1 -1
- package/esm/dev-server/development-server.mjs +1 -1
- package/esm/dev-server/development-server.mjs.map +1 -1
- package/esm/dev-server/events.mjs +1 -1
- package/esm/dev-server/events.mjs.map +1 -1
- package/esm/dev-server/extract-translation-keys.mjs +1 -1
- package/esm/dev-server/extract-translation-keys.mjs.map +1 -1
- package/esm/dev-server/file-event-handler.mjs +1 -1
- package/esm/dev-server/file-event-handler.mjs.map +1 -1
- package/esm/dev-server/file-manager.d.mts +1 -1
- package/esm/dev-server/file-manager.d.mts.map +1 -1
- package/esm/dev-server/file-manager.mjs +1 -1
- package/esm/dev-server/file-manager.mjs.map +1 -1
- package/esm/dev-server/file-operations.d.mts +1 -1
- package/esm/dev-server/file-operations.d.mts.map +1 -1
- package/esm/dev-server/file-operations.mjs +1 -1
- package/esm/dev-server/file-operations.mjs.map +1 -1
- package/esm/dev-server/files-orchestrator.mjs +28 -14
- package/esm/dev-server/files-orchestrator.mjs.map +1 -1
- package/esm/dev-server/files-watcher.mjs +1 -1
- package/esm/dev-server/files-watcher.mjs.map +1 -1
- package/esm/dev-server/flags.mjs +1 -1
- package/esm/dev-server/flags.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/base-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/base-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +1 -1
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
- package/esm/dev-server/health-checker/file-health-result.d.mts +1 -1
- package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
- package/esm/dev-server/health-checker/file-health-result.mjs +1 -1
- package/esm/dev-server/health-checker/file-health-result.mjs.map +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs +1 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.mjs.map +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
- package/esm/dev-server/layer-executor.mjs +1 -1
- package/esm/dev-server/layer-executor.mjs.map +1 -1
- package/esm/dev-server/legacy-locales-warning.mjs +1 -1
- package/esm/dev-server/legacy-locales-warning.mjs.map +1 -1
- package/esm/dev-server/loader/build-transpile-init.mjs +1 -1
- package/esm/dev-server/loader/build-transpile-init.mjs.map +1 -1
- package/esm/dev-server/loader/hook-thread.d.mts +1 -1
- package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
- package/esm/dev-server/loader/hook-thread.mjs +1 -1
- package/esm/dev-server/loader/hook-thread.mjs.map +1 -1
- package/esm/dev-server/loader/load-hook.d.mts +1 -1
- package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/load-hook.mjs +1 -1
- package/esm/dev-server/loader/load-hook.mjs.map +1 -1
- package/esm/dev-server/loader/loader-port-acks.mjs +34 -0
- package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -0
- package/esm/dev-server/loader/own-resolver.mjs +1 -1
- package/esm/dev-server/loader/own-resolver.mjs.map +1 -1
- package/esm/dev-server/loader/register-loader.mjs +1 -1
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-capture.mjs +1 -1
- package/esm/dev-server/loader/resolve-capture.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-hook.d.mts +1 -1
- package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/resolve-hook.mjs +2 -2
- package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
- package/esm/dev-server/loader/source-slug.mjs +1 -1
- package/esm/dev-server/loader/source-slug.mjs.map +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
- package/esm/dev-server/loader/version-registry.mjs +1 -1
- package/esm/dev-server/loader/version-registry.mjs.map +1 -1
- package/esm/dev-server/manifest-manager.d.mts +1 -1
- package/esm/dev-server/manifest-manager.d.mts.map +1 -1
- package/esm/dev-server/manifest-manager.mjs +1 -1
- package/esm/dev-server/manifest-manager.mjs.map +1 -1
- package/esm/dev-server/model-module-registry.mjs +1 -1
- package/esm/dev-server/model-module-registry.mjs.map +1 -1
- package/esm/dev-server/model-resource-typings.mjs +1 -1
- package/esm/dev-server/model-resource-typings.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +1 -1
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/package-json-manager.mjs +1 -1
- package/esm/dev-server/package-json-manager.mjs.map +1 -1
- package/esm/dev-server/parse-imports.mjs +73 -6
- package/esm/dev-server/parse-imports.mjs.map +1 -1
- package/esm/dev-server/read-config-ast.mjs +1 -1
- package/esm/dev-server/read-config-ast.mjs.map +1 -1
- package/esm/dev-server/ready-block.mjs +1 -1
- package/esm/dev-server/ready-block.mjs.map +1 -1
- package/esm/dev-server/register-dev-shortcuts.mjs +1 -1
- package/esm/dev-server/register-dev-shortcuts.mjs.map +1 -1
- package/esm/dev-server/register-installed-devtools.mjs +1 -1
- package/esm/dev-server/register-installed-devtools.mjs.map +1 -1
- package/esm/dev-server/restart-dev-server.mjs +1 -1
- package/esm/dev-server/restart-dev-server.mjs.map +1 -1
- package/esm/dev-server/route-types-publisher.mjs +1 -1
- package/esm/dev-server/route-types-publisher.mjs.map +1 -1
- package/esm/dev-server/run-connector-typings.mjs +1 -1
- package/esm/dev-server/run-connector-typings.mjs.map +1 -1
- package/esm/dev-server/run-typings-generation.mjs +1 -1
- package/esm/dev-server/run-typings-generation.mjs.map +1 -1
- package/esm/dev-server/shortcuts.mjs +1 -1
- package/esm/dev-server/shortcuts.mjs.map +1 -1
- package/esm/dev-server/special-file-patterns.mjs +1 -1
- package/esm/dev-server/special-file-patterns.mjs.map +1 -1
- package/esm/dev-server/special-files-collector.d.mts +1 -1
- package/esm/dev-server/special-files-collector.d.mts.map +1 -1
- package/esm/dev-server/special-files-collector.mjs +1 -1
- package/esm/dev-server/special-files-collector.mjs.map +1 -1
- package/esm/dev-server/start-development-server.mjs +1 -1
- package/esm/dev-server/start-development-server.mjs.map +1 -1
- package/esm/dev-server/supervisor.mjs +1 -1
- package/esm/dev-server/supervisor.mjs.map +1 -1
- package/esm/dev-server/translation-keys-sources.mjs +1 -1
- package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
- package/esm/dev-server/tsconfig-manager.mjs +1 -1
- package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
- package/esm/dev-server/type-generator.mjs +32 -11
- package/esm/dev-server/type-generator.mjs.map +1 -1
- package/esm/dev-server/types.d.mts +1 -1
- package/esm/dev-server/types.d.mts.map +1 -1
- package/esm/dev-server/update-check-cache.mjs +1 -1
- package/esm/dev-server/update-check-cache.mjs.map +1 -1
- package/esm/dev-server/utils.mjs +1 -1
- package/esm/dev-server/utils.mjs.map +1 -1
- package/esm/encryption/encrypt.d.mts +1 -1
- package/esm/encryption/encrypt.d.mts.map +1 -1
- package/esm/encryption/encrypt.mjs +1 -1
- package/esm/encryption/encrypt.mjs.map +1 -1
- package/esm/encryption/hash.d.mts +1 -1
- package/esm/encryption/hash.d.mts.map +1 -1
- package/esm/encryption/hash.mjs +1 -1
- package/esm/encryption/hash.mjs.map +1 -1
- package/esm/encryption/password.d.mts +1 -1
- package/esm/encryption/password.d.mts.map +1 -1
- package/esm/encryption/password.mjs +1 -1
- package/esm/encryption/password.mjs.map +1 -1
- package/esm/encryption/types.d.mts +1 -1
- package/esm/encryption/types.d.mts.map +1 -1
- package/esm/errors/container-key-missing-error.mjs +1 -1
- package/esm/errors/container-key-missing-error.mjs.map +1 -1
- package/esm/errors/esbuild-binary-missing-error.mjs +1 -1
- package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
- package/esm/errors/index.d.mts +2 -0
- package/esm/errors/index.mjs +3 -0
- package/esm/errors/unknown-locale-error.mjs +1 -1
- package/esm/errors/unknown-locale-error.mjs.map +1 -1
- package/esm/generations/add-command.action.mjs +29 -6
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/features/access.feature.mjs +1 -1
- package/esm/generations/features/access.feature.mjs.map +1 -1
- package/esm/generations/features/ai-anthropic.feature.mjs +1 -1
- package/esm/generations/features/ai-anthropic.feature.mjs.map +1 -1
- package/esm/generations/features/ai-bedrock.feature.mjs +1 -1
- package/esm/generations/features/ai-bedrock.feature.mjs.map +1 -1
- package/esm/generations/features/ai-google.feature.mjs +1 -1
- package/esm/generations/features/ai-google.feature.mjs.map +1 -1
- package/esm/generations/features/ai-ollama.feature.mjs +1 -1
- package/esm/generations/features/ai-ollama.feature.mjs.map +1 -1
- package/esm/generations/features/ai-openai.feature.mjs +1 -1
- package/esm/generations/features/ai-openai.feature.mjs.map +1 -1
- package/esm/generations/features/ai-panoptic.feature.mjs +1 -1
- package/esm/generations/features/ai-panoptic.feature.mjs.map +1 -1
- package/esm/generations/features/ai-tools.feature.mjs +1 -1
- package/esm/generations/features/ai-tools.feature.mjs.map +1 -1
- package/esm/generations/features/ai-workspace.feature.mjs +1 -1
- package/esm/generations/features/ai-workspace.feature.mjs.map +1 -1
- package/esm/generations/features/ai.feature.mjs +1 -1
- package/esm/generations/features/ai.feature.mjs.map +1 -1
- package/esm/generations/features/auth-google.feature.mjs +1 -1
- package/esm/generations/features/auth-google.feature.mjs.map +1 -1
- package/esm/generations/features/auth-passkeys.feature.mjs +1 -1
- package/esm/generations/features/auth-passkeys.feature.mjs.map +1 -1
- package/esm/generations/features/bull-board.feature.mjs +1 -1
- package/esm/generations/features/bull-board.feature.mjs.map +1 -1
- package/esm/generations/features/devtools.feature.mjs +1 -1
- package/esm/generations/features/devtools.feature.mjs.map +1 -1
- package/esm/generations/features/herald.feature.mjs +1 -1
- package/esm/generations/features/herald.feature.mjs.map +1 -1
- package/esm/generations/features/image.feature.mjs +1 -1
- package/esm/generations/features/image.feature.mjs.map +1 -1
- package/esm/generations/features/index.mjs +1 -1
- package/esm/generations/features/index.mjs.map +1 -1
- package/esm/generations/features/mail.feature.mjs +1 -1
- package/esm/generations/features/mail.feature.mjs.map +1 -1
- package/esm/generations/features/mongodb.feature.mjs +1 -1
- package/esm/generations/features/mongodb.feature.mjs.map +1 -1
- package/esm/generations/features/mysql.feature.mjs +1 -1
- package/esm/generations/features/mysql.feature.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +121 -17
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/postgres.feature.mjs +1 -1
- package/esm/generations/features/postgres.feature.mjs.map +1 -1
- package/esm/generations/features/queue.feature.mjs +1 -1
- package/esm/generations/features/queue.feature.mjs.map +1 -1
- package/esm/generations/features/react-email.feature.mjs +1 -1
- package/esm/generations/features/react-email.feature.mjs.map +1 -1
- package/esm/generations/features/react.feature.mjs +1 -1
- package/esm/generations/features/react.feature.mjs.map +1 -1
- package/esm/generations/features/redis.feature.mjs +1 -1
- package/esm/generations/features/redis.feature.mjs.map +1 -1
- package/esm/generations/features/s3.feature.mjs +1 -1
- package/esm/generations/features/s3.feature.mjs.map +1 -1
- package/esm/generations/features/scheduler.feature.mjs +1 -1
- package/esm/generations/features/scheduler.feature.mjs.map +1 -1
- package/esm/generations/features/ses.feature.mjs +1 -1
- package/esm/generations/features/ses.feature.mjs.map +1 -1
- package/esm/generations/features/shadcn.feature.mjs +1 -1
- package/esm/generations/features/shadcn.feature.mjs.map +1 -1
- package/esm/generations/features/shared/insert-connector-entry.mjs +1 -1
- package/esm/generations/features/shared/insert-connector-entry.mjs.map +1 -1
- package/esm/generations/features/shared/insert-queue-dashboard-block.mjs +1 -1
- package/esm/generations/features/shared/insert-queue-dashboard-block.mjs.map +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
- package/esm/generations/features/shared/migration-timestamp.mjs +1 -1
- package/esm/generations/features/shared/migration-timestamp.mjs.map +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
- package/esm/generations/features/shared/resolve-contact-scaffold.mjs +1 -1
- package/esm/generations/features/shared/resolve-contact-scaffold.mjs.map +1 -1
- package/esm/generations/features/sitemap.feature.mjs +1 -1
- package/esm/generations/features/sitemap.feature.mjs.map +1 -1
- package/esm/generations/features/socket.feature.mjs +1 -1
- package/esm/generations/features/socket.feature.mjs.map +1 -1
- package/esm/generations/features/tailwind.feature.mjs +1 -1
- package/esm/generations/features/tailwind.feature.mjs.map +1 -1
- package/esm/generations/features/test.feature.mjs +1 -1
- package/esm/generations/features/test.feature.mjs.map +1 -1
- package/esm/generations/features/types.mjs +1 -1
- package/esm/generations/features/types.mjs.map +1 -1
- package/esm/generations/features/web.feature.mjs +1 -1
- package/esm/generations/features/web.feature.mjs.map +1 -1
- package/esm/generations/pnpm-build-approvals.mjs +89 -3
- package/esm/generations/pnpm-build-approvals.mjs.map +1 -1
- package/esm/generations/stubs.mjs +184 -78
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/boot-port-preflight.d.mts +1 -1
- package/esm/http/boot-port-preflight.d.mts.map +1 -1
- package/esm/http/boot-port-preflight.mjs +1 -1
- package/esm/http/boot-port-preflight.mjs.map +1 -1
- package/esm/http/build-cors-options.mjs +1 -1
- package/esm/http/build-cors-options.mjs.map +1 -1
- package/esm/http/build-rate-limit-options.d.mts +22 -1
- package/esm/http/build-rate-limit-options.d.mts.map +1 -1
- package/esm/http/build-rate-limit-options.mjs +7 -1
- package/esm/http/build-rate-limit-options.mjs.map +1 -1
- package/esm/http/config.d.mts +1 -1
- package/esm/http/config.d.mts.map +1 -1
- package/esm/http/config.mjs +1 -1
- package/esm/http/config.mjs.map +1 -1
- package/esm/http/context/request-context.d.mts +1 -1
- package/esm/http/context/request-context.d.mts.map +1 -1
- package/esm/http/context/request-context.mjs +1 -1
- package/esm/http/context/request-context.mjs.map +1 -1
- package/esm/http/context/request-memo.d.mts +1 -1
- package/esm/http/context/request-memo.d.mts.map +1 -1
- package/esm/http/context/request-memo.mjs +1 -1
- package/esm/http/context/request-memo.mjs.map +1 -1
- package/esm/http/createHttpApplication.d.mts +1 -1
- package/esm/http/createHttpApplication.d.mts.map +1 -1
- package/esm/http/createHttpApplication.mjs +1 -1
- package/esm/http/createHttpApplication.mjs.map +1 -1
- package/esm/http/csp.d.mts +1 -1
- package/esm/http/csp.d.mts.map +1 -1
- package/esm/http/csp.mjs +1 -1
- package/esm/http/csp.mjs.map +1 -1
- package/esm/http/csrf-default-guard.d.mts +1 -1
- package/esm/http/csrf-default-guard.d.mts.map +1 -1
- package/esm/http/csrf-default-guard.mjs +1 -1
- package/esm/http/csrf-default-guard.mjs.map +1 -1
- package/esm/http/csrf-origin-policy.d.mts +1 -1
- package/esm/http/csrf-origin-policy.d.mts.map +1 -1
- package/esm/http/csrf-origin-policy.mjs +1 -1
- package/esm/http/csrf-origin-policy.mjs.map +1 -1
- package/esm/http/database/RequestLog.d.mts +63 -111
- package/esm/http/database/RequestLog.d.mts.map +1 -1
- package/esm/http/database/RequestLog.mjs +1 -1
- package/esm/http/database/RequestLog.mjs.map +1 -1
- package/esm/http/error-codes.d.mts +1 -1
- package/esm/http/error-codes.d.mts.map +1 -1
- package/esm/http/error-codes.mjs +1 -1
- package/esm/http/error-codes.mjs.map +1 -1
- package/esm/http/error-mapper.d.mts +48 -0
- package/esm/http/error-mapper.d.mts.map +1 -0
- package/esm/http/error-mapper.mjs +48 -0
- package/esm/http/error-mapper.mjs.map +1 -0
- package/esm/http/errors/errors.d.mts +1 -1
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/errors/errors.mjs +1 -1
- package/esm/http/errors/errors.mjs.map +1 -1
- package/esm/http/events.d.mts +1 -1
- package/esm/http/events.d.mts.map +1 -1
- package/esm/http/events.mjs +1 -1
- package/esm/http/events.mjs.map +1 -1
- package/esm/http/flush-pending-cookies.mjs +1 -1
- package/esm/http/flush-pending-cookies.mjs.map +1 -1
- package/esm/http/health.d.mts +1 -1
- package/esm/http/health.d.mts.map +1 -1
- package/esm/http/health.mjs +1 -1
- package/esm/http/health.mjs.map +1 -1
- package/esm/http/index.d.mts +10 -6
- package/esm/http/index.mjs +8 -5
- package/esm/http/middleware/cache-response-middleware.d.mts +1 -1
- package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
- package/esm/http/middleware/cache-response-middleware.mjs +1 -1
- package/esm/http/middleware/cache-response-middleware.mjs.map +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.d.mts +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.mjs +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.mjs.map +1 -1
- package/esm/http/middleware/idempotency.middleware.d.mts +1 -1
- package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/middleware/inject-request-context.d.mts +1 -1
- package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +4 -2
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/middleware/ip-filter.middleware.d.mts +1 -1
- package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
- package/esm/http/middleware/ip-filter.middleware.mjs +1 -1
- package/esm/http/middleware/ip-filter.middleware.mjs.map +1 -1
- package/esm/http/middleware/maintenance.middleware.d.mts +1 -1
- package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
- package/esm/http/middleware/max-body-size.middleware.d.mts +1 -1
- package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
- package/esm/http/middleware/max-body-size.middleware.mjs +1 -1
- package/esm/http/middleware/max-body-size.middleware.mjs.map +1 -1
- package/esm/http/middleware/middleware-list.d.mts +1 -1
- package/esm/http/middleware/middleware-list.d.mts.map +1 -1
- package/esm/http/middleware/middleware-list.mjs +1 -1
- package/esm/http/middleware/middleware-list.mjs.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.d.mts +20 -5
- package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.mjs +34 -12
- package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
- package/esm/http/middleware/utils/cidr-match.d.mts +1 -1
- package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
- package/esm/http/middleware/utils/cidr-match.mjs +1 -1
- package/esm/http/middleware/utils/cidr-match.mjs.map +1 -1
- package/esm/http/middleware/utils/idempotency-key.d.mts +1 -1
- package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
- package/esm/http/middleware/utils/idempotency-key.mjs +1 -1
- package/esm/http/middleware/utils/idempotency-key.mjs.map +1 -1
- package/esm/http/middleware/utils/parse-size.d.mts +1 -1
- package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
- package/esm/http/middleware/utils/parse-size.mjs +1 -1
- package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
- package/esm/http/parse-urlencoded-body.mjs +1 -1
- package/esm/http/parse-urlencoded-body.mjs.map +1 -1
- package/esm/http/plugins.d.mts +9 -2
- package/esm/http/plugins.d.mts.map +1 -1
- package/esm/http/plugins.mjs +18 -4
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/port-preflight.d.mts +1 -1
- package/esm/http/port-preflight.d.mts.map +1 -1
- package/esm/http/port-preflight.mjs +1 -1
- package/esm/http/port-preflight.mjs.map +1 -1
- package/esm/http/rate-limit-cache-store.mjs +155 -0
- package/esm/http/rate-limit-cache-store.mjs.map +1 -0
- package/esm/http/ready-report.d.mts +1 -1
- package/esm/http/ready-report.d.mts.map +1 -1
- package/esm/http/ready-report.mjs +1 -1
- package/esm/http/ready-report.mjs.map +1 -1
- package/esm/http/request-controller.d.mts +1 -1
- package/esm/http/request-controller.d.mts.map +1 -1
- package/esm/http/request-controller.mjs +1 -1
- package/esm/http/request-controller.mjs.map +1 -1
- package/esm/http/request-log-snapshot.d.mts +123 -0
- package/esm/http/request-log-snapshot.d.mts.map +1 -0
- package/esm/http/request-log-snapshot.mjs +141 -0
- package/esm/http/request-log-snapshot.mjs.map +1 -0
- package/esm/http/request.d.mts +41 -2
- package/esm/http/request.d.mts.map +1 -1
- package/esm/http/request.mjs +65 -2
- package/esm/http/request.mjs.map +1 -1
- package/esm/http/resolve-bind-port.mjs +1 -1
- package/esm/http/resolve-bind-port.mjs.map +1 -1
- package/esm/http/response.d.mts +40 -8
- package/esm/http/response.d.mts.map +1 -1
- package/esm/http/response.mjs +173 -61
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/serialized.d.mts +1 -1
- package/esm/http/serialized.d.mts.map +1 -1
- package/esm/http/server-rebuilt.d.mts +1 -1
- package/esm/http/server-rebuilt.d.mts.map +1 -1
- package/esm/http/server-rebuilt.mjs +1 -1
- package/esm/http/server-rebuilt.mjs.map +1 -1
- package/esm/http/server.d.mts +34 -6
- package/esm/http/server.d.mts.map +1 -1
- package/esm/http/server.mjs +70 -5
- package/esm/http/server.mjs.map +1 -1
- package/esm/http/stream-react-response.d.mts +1 -1
- package/esm/http/stream-react-response.d.mts.map +1 -1
- package/esm/http/stream-react-response.mjs +1 -1
- package/esm/http/stream-react-response.mjs.map +1 -1
- package/esm/http/stream-transport.mjs +75 -0
- package/esm/http/stream-transport.mjs.map +1 -0
- package/esm/http/tracing/trace-id.d.mts +1 -1
- package/esm/http/tracing/trace-id.d.mts.map +1 -1
- package/esm/http/tracing/trace-id.mjs +1 -1
- package/esm/http/tracing/trace-id.mjs.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.d.mts +1 -1
- package/esm/http/tracing/tracing-dispatcher.d.mts.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.mjs +1 -1
- package/esm/http/tracing/tracing-dispatcher.mjs.map +1 -1
- package/esm/http/tracing/tracing.type.d.mts +1 -1
- package/esm/http/tracing/tracing.type.d.mts.map +1 -1
- package/esm/http/types.d.mts +131 -6
- package/esm/http/types.d.mts.map +1 -1
- package/esm/http/uploaded-file.d.mts +2 -2
- package/esm/http/uploaded-file.d.mts.map +1 -1
- package/esm/http/uploaded-file.mjs +2 -2
- package/esm/http/uploaded-file.mjs.map +1 -1
- package/esm/http/uploads/detect-image-format.mjs +1 -1
- package/esm/http/uploads/detect-image-format.mjs.map +1 -1
- package/esm/http/uploads/generate-image-variant.mjs +1 -1
- package/esm/http/uploads/generate-image-variant.mjs.map +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.mjs +15 -7
- package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
- package/esm/http/uploads/image-variant-cache.mjs +143 -0
- package/esm/http/uploads/image-variant-cache.mjs.map +1 -0
- package/esm/http/uploads/image-variant-types.d.mts +1 -1
- package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
- package/esm/http/uploads/index.d.mts +3 -1
- package/esm/http/uploads/index.mjs +3 -1
- package/esm/http/uploads/is-path-inside.mjs +1 -1
- package/esm/http/uploads/is-path-inside.mjs.map +1 -1
- package/esm/http/uploads/load-variant-source.mjs +1 -1
- package/esm/http/uploads/load-variant-source.mjs.map +1 -1
- package/esm/http/uploads/local-disk-root.mjs +24 -0
- package/esm/http/uploads/local-disk-root.mjs.map +1 -0
- package/esm/http/uploads/matches-if-none-match.mjs +1 -1
- package/esm/http/uploads/matches-if-none-match.mjs.map +1 -1
- package/esm/http/uploads/parse-uploaded-file-query.mjs +1 -1
- package/esm/http/uploads/parse-uploaded-file-query.mjs.map +1 -1
- package/esm/http/uploads/purge-image-variants.d.mts +32 -0
- package/esm/http/uploads/purge-image-variants.d.mts.map +1 -0
- package/esm/http/uploads/purge-image-variants.mjs +46 -0
- package/esm/http/uploads/purge-image-variants.mjs.map +1 -0
- package/esm/http/uploads/read-file-head.mjs +1 -1
- package/esm/http/uploads/read-file-head.mjs.map +1 -1
- package/esm/http/uploads/resolve-image-variant.d.mts +73 -0
- package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -0
- package/esm/http/uploads/resolve-image-variant.mjs +107 -0
- package/esm/http/uploads/resolve-image-variant.mjs.map +1 -0
- package/esm/http/uploads/resolve-image-variants-config.mjs +1 -1
- package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
- package/esm/http/uploads/resolve-inline-image-content-type.mjs +1 -1
- package/esm/http/uploads/resolve-inline-image-content-type.mjs.map +1 -1
- package/esm/http/uploads/resolve-original-content-type.mjs +1 -1
- package/esm/http/uploads/resolve-original-content-type.mjs.map +1 -1
- package/esm/http/uploads/resolve-upload-path.mjs +3 -2
- package/esm/http/uploads/resolve-upload-path.mjs.map +1 -1
- package/esm/http/uploads/resolve-variant-candidate.mjs +1 -1
- package/esm/http/uploads/resolve-variant-candidate.mjs.map +1 -1
- package/esm/http/uploads/single-flight.mjs +1 -1
- package/esm/http/uploads/single-flight.mjs.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.d.mts +24 -6
- package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.mjs +63 -91
- package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
- package/esm/http/uploads/variant-cache-key.mjs +30 -5
- package/esm/http/uploads/variant-cache-key.mjs.map +1 -1
- package/esm/http/uploads/variant-generations.mjs +1 -1
- package/esm/http/uploads/variant-generations.mjs.map +1 -1
- package/esm/http/uploads-config.d.mts +1 -1
- package/esm/http/uploads-config.d.mts.map +1 -1
- package/esm/http/uploads-config.mjs +1 -1
- package/esm/http/uploads-config.mjs.map +1 -1
- package/esm/http/uploads-types.d.mts +1 -1
- package/esm/http/uploads-types.d.mts.map +1 -1
- package/esm/http/xmlable.d.mts +1 -1
- package/esm/http/xmlable.d.mts.map +1 -1
- package/esm/image/image.d.mts +1 -1
- package/esm/image/image.d.mts.map +1 -1
- package/esm/image/image.mjs +1 -1
- package/esm/image/image.mjs.map +1 -1
- package/esm/index.d.mts +15 -9
- package/esm/index.mjs +11 -7
- package/esm/loader/app-module-importer.d.mts +1 -1
- package/esm/loader/app-module-importer.d.mts.map +1 -1
- package/esm/loader/app-module-importer.mjs +1 -1
- package/esm/loader/app-module-importer.mjs.map +1 -1
- package/esm/localization/parse-locale-dictionary.d.mts +7 -2
- package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/parse-locale-dictionary.mjs +6 -2
- package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
- package/esm/localization/register-locale-dictionary.d.mts +1 -1
- package/esm/localization/register-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/register-locale-dictionary.mjs +1 -1
- package/esm/localization/register-locale-dictionary.mjs.map +1 -1
- package/esm/logger/fatal-visibility.d.mts +1 -1
- package/esm/logger/fatal-visibility.d.mts.map +1 -1
- package/esm/logger/fatal-visibility.mjs +1 -1
- package/esm/logger/fatal-visibility.mjs.map +1 -1
- package/esm/logger/logger.d.mts +1 -1
- package/esm/logger/logger.d.mts.map +1 -1
- package/esm/logger/logger.mjs +1 -1
- package/esm/logger/logger.mjs.map +1 -1
- package/esm/logger/types.d.mts +1 -1
- package/esm/logger/types.d.mts.map +1 -1
- package/esm/mail/config.d.mts +1 -1
- package/esm/mail/config.d.mts.map +1 -1
- package/esm/mail/config.mjs +1 -1
- package/esm/mail/config.mjs.map +1 -1
- package/esm/mail/events.d.mts +1 -1
- package/esm/mail/events.d.mts.map +1 -1
- package/esm/mail/events.mjs +1 -1
- package/esm/mail/events.mjs.map +1 -1
- package/esm/mail/mail.d.mts +1 -1
- package/esm/mail/mail.d.mts.map +1 -1
- package/esm/mail/mail.mjs +1 -1
- package/esm/mail/mail.mjs.map +1 -1
- package/esm/mail/mailer-pool.d.mts +1 -1
- package/esm/mail/mailer-pool.d.mts.map +1 -1
- package/esm/mail/mailer-pool.mjs +1 -1
- package/esm/mail/mailer-pool.mjs.map +1 -1
- package/esm/mail/react-mail.d.mts +1 -1
- package/esm/mail/react-mail.d.mts.map +1 -1
- package/esm/mail/react-mail.mjs +1 -1
- package/esm/mail/react-mail.mjs.map +1 -1
- package/esm/mail/send-mail.d.mts +1 -1
- package/esm/mail/send-mail.d.mts.map +1 -1
- package/esm/mail/send-mail.mjs +7 -7
- package/esm/mail/send-mail.mjs.map +1 -1
- package/esm/mail/test-mailbox.d.mts +1 -1
- package/esm/mail/test-mailbox.d.mts.map +1 -1
- package/esm/mail/test-mailbox.mjs +1 -1
- package/esm/mail/test-mailbox.mjs.map +1 -1
- package/esm/mail/types.d.mts +1 -1
- package/esm/mail/types.d.mts.map +1 -1
- package/esm/mail/types.mjs +1 -1
- package/esm/mail/types.mjs.map +1 -1
- package/esm/manifest/manifest-manager.mjs +1 -1
- package/esm/manifest/manifest-manager.mjs.map +1 -1
- package/esm/openapi/build-openapi-document.d.mts +1 -1
- package/esm/openapi/build-openapi-document.d.mts.map +1 -1
- package/esm/openapi/build-openapi-document.mjs +1 -1
- package/esm/openapi/build-openapi-document.mjs.map +1 -1
- package/esm/openapi/cast-schema.mjs +1 -1
- package/esm/openapi/cast-schema.mjs.map +1 -1
- package/esm/openapi/collect-openapi-document.mjs +1 -1
- package/esm/openapi/collect-openapi-document.mjs.map +1 -1
- package/esm/openapi/development-openapi-provider.d.mts +1 -1
- package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
- package/esm/openapi/development-openapi-provider.mjs +1 -1
- package/esm/openapi/development-openapi-provider.mjs.map +1 -1
- package/esm/openapi/error-responses.mjs +1 -1
- package/esm/openapi/error-responses.mjs.map +1 -1
- package/esm/openapi/openapi-child-output.mjs +1 -1
- package/esm/openapi/openapi-child-output.mjs.map +1 -1
- package/esm/openapi/openapi-protocol.mjs +1 -1
- package/esm/openapi/openapi-protocol.mjs.map +1 -1
- package/esm/openapi/paths.mjs +1 -1
- package/esm/openapi/paths.mjs.map +1 -1
- package/esm/openapi/postman/build-request-body.mjs +1 -1
- package/esm/openapi/postman/build-request-body.mjs.map +1 -1
- package/esm/openapi/postman/build-request-url.mjs +1 -1
- package/esm/openapi/postman/build-request-url.mjs.map +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
- package/esm/openapi/postman/example-from-schema.mjs +1 -1
- package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
- package/esm/openapi/postman/http-status-text.mjs +1 -1
- package/esm/openapi/postman/http-status-text.mjs.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
- package/esm/openapi/postman/postman-types.d.mts +1 -1
- package/esm/openapi/postman/postman-types.d.mts.map +1 -1
- package/esm/openapi/postman/resolve-operation-auth.mjs +1 -1
- package/esm/openapi/postman/resolve-operation-auth.mjs.map +1 -1
- package/esm/openapi/postman/schema-refs.d.mts +1 -1
- package/esm/openapi/postman/schema-refs.d.mts.map +1 -1
- package/esm/openapi/postman/schema-refs.mjs +1 -1
- package/esm/openapi/postman/schema-refs.mjs.map +1 -1
- package/esm/openapi/postman/uuid-v5.mjs +1 -1
- package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
- package/esm/openapi/request-schemas.mjs +1 -1
- package/esm/openapi/request-schemas.mjs.map +1 -1
- package/esm/openapi/response-schemas.mjs +5 -2
- package/esm/openapi/response-schemas.mjs.map +1 -1
- package/esm/openapi/schema-registry.mjs +7 -1
- package/esm/openapi/schema-registry.mjs.map +1 -1
- package/esm/openapi/security.mjs +1 -1
- package/esm/openapi/security.mjs.map +1 -1
- package/esm/openapi/types.d.mts +1 -1
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/assert-dist-ready-to-start.mjs +1 -1
- package/esm/production/assert-dist-ready-to-start.mjs.map +1 -1
- package/esm/production/assert-generated-imports.mjs +1 -1
- package/esm/production/assert-generated-imports.mjs.map +1 -1
- package/esm/production/build-app-production.mjs +1 -1
- package/esm/production/build-app-production.mjs.map +1 -1
- package/esm/production/build-contributions.mjs +1 -1
- package/esm/production/build-contributions.mjs.map +1 -1
- package/esm/production/bundle-framework-dependencies.mjs +1 -1
- package/esm/production/bundle-framework-dependencies.mjs.map +1 -1
- package/esm/production/dist-build-manifest.mjs +1 -1
- package/esm/production/dist-build-manifest.mjs.map +1 -1
- package/esm/production/esbuild-plugins.mjs +1 -1
- package/esm/production/esbuild-plugins.mjs.map +1 -1
- package/esm/production/esbuild-preflight.mjs +1 -1
- package/esm/production/esbuild-preflight.mjs.map +1 -1
- package/esm/production/production-builder.mjs +1 -1
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/production-supervisor.mjs +1 -1
- package/esm/production/production-supervisor.mjs.map +1 -1
- package/esm/production/promote-dist.mjs +1 -1
- package/esm/production/promote-dist.mjs.map +1 -1
- package/esm/production/registration-child-runner.mjs +1 -1
- package/esm/production/registration-child-runner.mjs.map +1 -1
- package/esm/production/resolve-build-config.d.mts +1 -1
- package/esm/production/resolve-build-config.d.mts.map +1 -1
- package/esm/production/resolve-build-config.mjs +1 -1
- package/esm/production/resolve-build-config.mjs.map +1 -1
- package/esm/production/route-registration-child.mjs +1 -1
- package/esm/production/route-registration-child.mjs.map +1 -1
- package/esm/production/route-registration-snapshot.mjs +1 -1
- package/esm/production/route-registration-snapshot.mjs.map +1 -1
- package/esm/production/tsconfig-path-aliases.mjs +1 -1
- package/esm/production/tsconfig-path-aliases.mjs.map +1 -1
- package/esm/react/index.d.mts +1 -1
- package/esm/react/index.d.mts.map +1 -1
- package/esm/react/index.mjs +1 -1
- package/esm/react/index.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.mjs +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/filter-applicator.mjs +1 -1
- package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -1
- package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/types.d.mts +1 -1
- package/esm/repositories/contracts/types.d.mts.map +1 -1
- package/esm/repositories/repository.manager.d.mts +1 -1
- package/esm/repositories/repository.manager.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs +1 -1
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/resource/define-resource.d.mts +1 -1
- package/esm/resource/define-resource.d.mts.map +1 -1
- package/esm/resource/define-resource.mjs +1 -1
- package/esm/resource/define-resource.mjs.map +1 -1
- package/esm/resource/index.d.mts +1 -0
- package/esm/resource/index.mjs +1 -0
- package/esm/resource/nullable-resource.d.mts +44 -0
- package/esm/resource/nullable-resource.d.mts.map +1 -0
- package/esm/resource/nullable-resource.mjs +38 -0
- package/esm/resource/nullable-resource.mjs.map +1 -0
- package/esm/resource/register-resource.d.mts +1 -1
- package/esm/resource/register-resource.d.mts.map +1 -1
- package/esm/resource/register-resource.mjs +1 -1
- package/esm/resource/register-resource.mjs.map +1 -1
- package/esm/resource/resource-field-builder.d.mts +1 -1
- package/esm/resource/resource-field-builder.d.mts.map +1 -1
- package/esm/resource/resource-field-builder.mjs +1 -1
- package/esm/resource/resource-field-builder.mjs.map +1 -1
- package/esm/resource/resource.d.mts +1 -1
- package/esm/resource/resource.d.mts.map +1 -1
- package/esm/resource/resource.mjs +23 -4
- package/esm/resource/resource.mjs.map +1 -1
- package/esm/resource/types.d.mts +11 -6
- package/esm/resource/types.d.mts.map +1 -1
- package/esm/restful/restful.d.mts +1 -1
- package/esm/restful/restful.d.mts.map +1 -1
- package/esm/restful/restful.mjs +1 -1
- package/esm/restful/restful.mjs.map +1 -1
- package/esm/router/build-route-rate-limit.mjs +1 -1
- package/esm/router/build-route-rate-limit.mjs.map +1 -1
- package/esm/router/describe-route-for-log.mjs +1 -1
- package/esm/router/describe-route-for-log.mjs.map +1 -1
- package/esm/router/dev-dispatch.mjs +1 -1
- package/esm/router/dev-dispatch.mjs.map +1 -1
- package/esm/router/log-request-lifecycle.mjs +1 -1
- package/esm/router/log-request-lifecycle.mjs.map +1 -1
- package/esm/router/named-api-routes-with-responses.mjs +1 -1
- package/esm/router/named-api-routes-with-responses.mjs.map +1 -1
- package/esm/router/normalize-request-path.d.mts +1 -1
- package/esm/router/normalize-request-path.d.mts.map +1 -1
- package/esm/router/normalize-request-path.mjs +1 -1
- package/esm/router/normalize-request-path.mjs.map +1 -1
- package/esm/router/normalize-route-path.d.mts +1 -1
- package/esm/router/normalize-route-path.d.mts.map +1 -1
- package/esm/router/normalize-route-path.mjs +1 -1
- package/esm/router/normalize-route-path.mjs.map +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
- package/esm/router/positional-handler-diagnostics.mjs +1 -1
- package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
- package/esm/router/response-schema-types.mjs +3 -1
- package/esm/router/response-schema-types.mjs.map +1 -1
- package/esm/router/route-builder.d.mts +1 -1
- package/esm/router/route-builder.d.mts.map +1 -1
- package/esm/router/route-builder.mjs +1 -1
- package/esm/router/route-builder.mjs.map +1 -1
- package/esm/router/route-name-method-suffix.d.mts +1 -1
- package/esm/router/route-name-method-suffix.d.mts.map +1 -1
- package/esm/router/route-name-method-suffix.mjs +1 -1
- package/esm/router/route-name-method-suffix.mjs.map +1 -1
- package/esm/router/route-registry.d.mts +1 -1
- package/esm/router/route-registry.d.mts.map +1 -1
- package/esm/router/route-registry.mjs +1 -1
- package/esm/router/route-registry.mjs.map +1 -1
- package/esm/router/router.d.mts +8 -1
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +20 -15
- package/esm/router/router.mjs.map +1 -1
- package/esm/router/types.d.mts +13 -1
- package/esm/router/types.d.mts.map +1 -1
- package/esm/socket/types.d.mts +1 -1
- package/esm/socket/types.d.mts.map +1 -1
- package/esm/socket/utils.d.mts +1 -1
- package/esm/socket/utils.d.mts.map +1 -1
- package/esm/socket/utils.mjs +1 -1
- package/esm/socket/utils.mjs.map +1 -1
- package/esm/storage/config.d.mts +1 -1
- package/esm/storage/config.d.mts.map +1 -1
- package/esm/storage/config.mjs +1 -1
- package/esm/storage/config.mjs.map +1 -1
- package/esm/storage/context/storage-driver-context.d.mts +1 -1
- package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
- package/esm/storage/context/storage-driver-context.mjs +1 -1
- package/esm/storage/context/storage-driver-context.mjs.map +1 -1
- package/esm/storage/drivers/cloud-driver.d.mts +1 -1
- package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
- package/esm/storage/drivers/cloud-driver.mjs +1 -1
- package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
- package/esm/storage/drivers/do-spaces-driver.d.mts +1 -1
- package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
- package/esm/storage/drivers/do-spaces-driver.mjs +1 -1
- package/esm/storage/drivers/do-spaces-driver.mjs.map +1 -1
- package/esm/storage/drivers/local-driver.d.mts +12 -1
- package/esm/storage/drivers/local-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.mjs +33 -1
- package/esm/storage/drivers/local-driver.mjs.map +1 -1
- package/esm/storage/drivers/r2-driver.d.mts +1 -1
- package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
- package/esm/storage/drivers/r2-driver.mjs +1 -1
- package/esm/storage/drivers/r2-driver.mjs.map +1 -1
- package/esm/storage/drivers/s3-driver.d.mts +1 -1
- package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
- package/esm/storage/drivers/s3-driver.mjs +1 -1
- package/esm/storage/drivers/s3-driver.mjs.map +1 -1
- package/esm/storage/index.d.mts +1 -1
- package/esm/storage/scoped-storage.d.mts +1 -1
- package/esm/storage/scoped-storage.d.mts.map +1 -1
- package/esm/storage/scoped-storage.mjs +1 -1
- package/esm/storage/scoped-storage.mjs.map +1 -1
- package/esm/storage/storage-file.d.mts +1 -1
- package/esm/storage/storage-file.d.mts.map +1 -1
- package/esm/storage/storage-file.mjs +1 -1
- package/esm/storage/storage-file.mjs.map +1 -1
- package/esm/storage/storage.d.mts +3 -3
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/storage.mjs +1 -1
- package/esm/storage/storage.mjs.map +1 -1
- package/esm/storage/types.d.mts +3 -2
- package/esm/storage/types.d.mts.map +1 -1
- package/esm/storage/utils/classify-ip-address.d.mts +1 -1
- package/esm/storage/utils/classify-ip-address.d.mts.map +1 -1
- package/esm/storage/utils/classify-ip-address.mjs +1 -1
- package/esm/storage/utils/classify-ip-address.mjs.map +1 -1
- package/esm/storage/utils/contain-path.d.mts +1 -1
- package/esm/storage/utils/contain-path.d.mts.map +1 -1
- package/esm/storage/utils/contain-path.mjs +1 -1
- package/esm/storage/utils/contain-path.mjs.map +1 -1
- package/esm/storage/utils/mime.d.mts +1 -1
- package/esm/storage/utils/mime.d.mts.map +1 -1
- package/esm/storage/utils/mime.mjs +1 -1
- package/esm/storage/utils/mime.mjs.map +1 -1
- package/esm/storage/utils/safe-fetch.d.mts +1 -1
- package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
- package/esm/storage/utils/safe-fetch.mjs +1 -1
- package/esm/storage/utils/safe-fetch.mjs.map +1 -1
- package/esm/storage/utils/storage-capability-error.d.mts +1 -1
- package/esm/storage/utils/storage-capability-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-capability-error.mjs +1 -1
- package/esm/storage/utils/storage-capability-error.mjs.map +1 -1
- package/esm/storage/utils/storage-error.d.mts +1 -1
- package/esm/storage/utils/storage-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-error.mjs +1 -1
- package/esm/storage/utils/storage-error.mjs.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
- package/esm/tests/start-http-development-server.d.mts +1 -1
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +1 -1
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-connectors-selection.d.mts +1 -1
- package/esm/tests/test-connectors-selection.d.mts.map +1 -1
- package/esm/tests/test-connectors-selection.mjs +1 -1
- package/esm/tests/test-connectors-selection.mjs.map +1 -1
- package/esm/tests/test-helpers.d.mts +1 -1
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-helpers.mjs +1 -1
- package/esm/tests/test-helpers.mjs.map +1 -1
- package/esm/tests/test-lifecycle-state.mjs +1 -1
- package/esm/tests/test-lifecycle-state.mjs.map +1 -1
- package/esm/tests/test-server-port-channel.mjs +1 -1
- package/esm/tests/test-server-port-channel.mjs.map +1 -1
- package/esm/tests/test-setup-timeout.mjs +1 -1
- package/esm/tests/test-setup-timeout.mjs.map +1 -1
- package/esm/tests/vitest-setup.d.mts +1 -1
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tests/vitest-setup.mjs +1 -1
- package/esm/tests/vitest-setup.mjs.map +1 -1
- package/esm/updater/package-manager.mjs +1 -1
- package/esm/updater/package-manager.mjs.map +1 -1
- package/esm/updater/update-warlock-packages.mjs +1 -1
- package/esm/updater/update-warlock-packages.mjs.map +1 -1
- package/esm/use-cases/types.d.mts +1 -1
- package/esm/use-cases/types.d.mts.map +1 -1
- package/esm/use-cases/use-case-broadcast.d.mts +1 -1
- package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
- package/esm/use-cases/use-case-broadcast.mjs +1 -1
- package/esm/use-cases/use-case-broadcast.mjs.map +1 -1
- package/esm/use-cases/use-case-events.d.mts +1 -1
- package/esm/use-cases/use-case-events.d.mts.map +1 -1
- package/esm/use-cases/use-case-events.mjs +1 -1
- package/esm/use-cases/use-case-events.mjs.map +1 -1
- package/esm/use-cases/use-case-pipeline.d.mts +1 -1
- package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
- package/esm/use-cases/use-case-pipeline.mjs +1 -1
- package/esm/use-cases/use-case-pipeline.mjs.map +1 -1
- package/esm/use-cases/use-case.d.mts +1 -1
- package/esm/use-cases/use-case.d.mts.map +1 -1
- package/esm/use-cases/use-case.errors.d.mts +1 -1
- package/esm/use-cases/use-case.errors.d.mts.map +1 -1
- package/esm/use-cases/use-case.errors.mjs +1 -1
- package/esm/use-cases/use-case.errors.mjs.map +1 -1
- package/esm/use-cases/use-case.mjs +1 -1
- package/esm/use-cases/use-case.mjs.map +1 -1
- package/esm/use-cases/use-cases-registry.d.mts +1 -1
- package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
- package/esm/use-cases/use-cases-registry.mjs +1 -1
- package/esm/use-cases/use-cases-registry.mjs.map +1 -1
- package/esm/utils/app-log.d.mts +6 -6
- package/esm/utils/app-log.d.mts.map +1 -1
- package/esm/utils/app-log.mjs +1 -1
- package/esm/utils/app-log.mjs.map +1 -1
- package/esm/utils/database-log.d.mts +1 -1
- package/esm/utils/database-log.d.mts.map +1 -1
- package/esm/utils/database-log.mjs +1 -1
- package/esm/utils/database-log.mjs.map +1 -1
- package/esm/utils/detect-environment-overrides.mjs +1 -1
- package/esm/utils/detect-environment-overrides.mjs.map +1 -1
- package/esm/utils/environment.d.mts +1 -1
- package/esm/utils/environment.d.mts.map +1 -1
- package/esm/utils/environment.mjs +1 -1
- package/esm/utils/environment.mjs.map +1 -1
- package/esm/utils/framework-vesion.mjs +1 -1
- package/esm/utils/framework-vesion.mjs.map +1 -1
- package/esm/utils/get-localized.d.mts +1 -1
- package/esm/utils/get-localized.d.mts.map +1 -1
- package/esm/utils/get-localized.mjs +1 -1
- package/esm/utils/get-localized.mjs.map +1 -1
- package/esm/utils/is-test-file.mjs +1 -1
- package/esm/utils/is-test-file.mjs.map +1 -1
- package/esm/utils/load-environment.mjs +1 -1
- package/esm/utils/load-environment.mjs.map +1 -1
- package/esm/utils/normalized-path.d.mts +1 -1
- package/esm/utils/normalized-path.d.mts.map +1 -1
- package/esm/utils/normalized-path.mjs +1 -1
- package/esm/utils/normalized-path.mjs.map +1 -1
- package/esm/utils/npm-registry.d.mts +1 -1
- package/esm/utils/npm-registry.d.mts.map +1 -1
- package/esm/utils/npm-registry.mjs +1 -1
- package/esm/utils/npm-registry.mjs.map +1 -1
- package/esm/utils/paths.d.mts +1 -1
- package/esm/utils/paths.d.mts.map +1 -1
- package/esm/utils/paths.mjs +1 -1
- package/esm/utils/paths.mjs.map +1 -1
- package/esm/utils/promise-all-object.d.mts +1 -1
- package/esm/utils/promise-all-object.d.mts.map +1 -1
- package/esm/utils/promise-all-object.mjs +1 -1
- package/esm/utils/promise-all-object.mjs.map +1 -1
- package/esm/utils/queue.d.mts +1 -1
- package/esm/utils/queue.d.mts.map +1 -1
- package/esm/utils/queue.mjs +1 -1
- package/esm/utils/queue.mjs.map +1 -1
- package/esm/utils/recorded-environment-overrides.mjs +1 -1
- package/esm/utils/recorded-environment-overrides.mjs.map +1 -1
- package/esm/utils/report-environment-overrides.mjs +1 -1
- package/esm/utils/report-environment-overrides.mjs.map +1 -1
- package/esm/utils/sleep.d.mts +1 -1
- package/esm/utils/sleep.d.mts.map +1 -1
- package/esm/utils/sleep.mjs +1 -1
- package/esm/utils/sleep.mjs.map +1 -1
- package/esm/utils/sluggable.d.mts +1 -1
- package/esm/utils/sluggable.d.mts.map +1 -1
- package/esm/utils/sluggable.mjs +1 -1
- package/esm/utils/sluggable.mjs.map +1 -1
- package/esm/utils/to-json.d.mts +1 -1
- package/esm/utils/to-json.d.mts.map +1 -1
- package/esm/utils/to-json.mjs +1 -1
- package/esm/utils/to-json.mjs.map +1 -1
- package/esm/utils/types.d.mts +1 -1
- package/esm/utils/types.d.mts.map +1 -1
- package/esm/utils/urls.d.mts +1 -1
- package/esm/utils/urls.d.mts.map +1 -1
- package/esm/utils/urls.mjs +1 -1
- package/esm/utils/urls.mjs.map +1 -1
- package/esm/utils/version-compare.d.mts +1 -1
- package/esm/utils/version-compare.d.mts.map +1 -1
- package/esm/utils/version-compare.mjs +1 -1
- package/esm/utils/version-compare.mjs.map +1 -1
- package/esm/validation/database/exists-except-current-id.d.mts +1 -1
- package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-id.mjs +1 -1
- package/esm/validation/database/exists-except-current-id.mjs.map +1 -1
- package/esm/validation/database/exists-except-current-user.d.mts +1 -1
- package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-user.mjs +1 -1
- package/esm/validation/database/exists-except-current-user.mjs.map +1 -1
- package/esm/validation/database/types.d.mts +1 -1
- package/esm/validation/database/types.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-id.d.mts +1 -1
- package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-id.mjs +1 -1
- package/esm/validation/database/unique-except-current-id.mjs.map +1 -1
- package/esm/validation/database/unique-except-current-user.d.mts +1 -1
- package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-user.mjs +1 -1
- package/esm/validation/database/unique-except-current-user.mjs.map +1 -1
- package/esm/validation/file/file.d.mts +1 -1
- package/esm/validation/file/file.d.mts.map +1 -1
- package/esm/validation/file/file.mjs +1 -1
- package/esm/validation/file/file.mjs.map +1 -1
- package/esm/validation/init.mjs +1 -1
- package/esm/validation/init.mjs.map +1 -1
- package/esm/validation/plugins/database-plugin.mjs +1 -1
- package/esm/validation/plugins/database-plugin.mjs.map +1 -1
- package/esm/validation/plugins/file-plugin.mjs +1 -1
- package/esm/validation/plugins/file-plugin.mjs.map +1 -1
- package/esm/validation/plugins/localized-plugin.mjs +1 -1
- package/esm/validation/plugins/localized-plugin.mjs.map +1 -1
- package/esm/validation/types.d.mts +1 -1
- package/esm/validation/types.d.mts.map +1 -1
- package/esm/validation/validateAll.mjs +1 -1
- package/esm/validation/validateAll.mjs.map +1 -1
- package/esm/validation/validators/file-validator.d.mts +44 -41
- package/esm/validation/validators/file-validator.d.mts.map +1 -1
- package/esm/validation/validators/file-validator.mjs +4 -1
- package/esm/validation/validators/file-validator.mjs.map +1 -1
- package/esm/vite/lower-stage3-decorators.d.mts +1 -1
- package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
- package/esm/vite/lower-stage3-decorators.mjs +1 -1
- package/esm/vite/lower-stage3-decorators.mjs.map +1 -1
- package/esm/warlock-config/bundle-config.mjs +148 -0
- package/esm/warlock-config/bundle-config.mjs.map +1 -0
- package/esm/warlock-config/default-configurations.mjs +1 -1
- package/esm/warlock-config/default-configurations.mjs.map +1 -1
- package/esm/warlock-config/define-config.d.mts +1 -1
- package/esm/warlock-config/define-config.d.mts.map +1 -1
- package/esm/warlock-config/define-config.mjs +1 -1
- package/esm/warlock-config/define-config.mjs.map +1 -1
- package/esm/warlock-config/index.d.mts +1 -1
- package/esm/warlock-config/index.mjs +1 -1
- package/esm/warlock-config/normalize-build-config.mjs +1 -1
- package/esm/warlock-config/normalize-build-config.mjs.map +1 -1
- package/esm/warlock-config/types.d.mts +1 -1
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.d.mts +32 -7
- package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.mjs +94 -18
- package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
- package/esm/warlock-config/warn-deprecated-config.mjs +1 -1
- package/esm/warlock-config/warn-deprecated-config.mjs.map +1 -1
- package/llms-full.txt +306 -249
- package/llms.txt +42 -42
- package/package.json +20 -13
- package/skills/README.md +39 -39
- package/skills/add-connector/SKILL.md +4 -4
- package/skills/benchmark-code/SKILL.md +3 -3
- package/skills/build-restful/SKILL.md +5 -5
- package/skills/build-url/SKILL.md +7 -7
- package/skills/configure-app/SKILL.md +30 -8
- package/skills/create-controller/SKILL.md +12 -8
- package/skills/create-module/SKILL.md +9 -9
- package/skills/define-resource/SKILL.md +4 -4
- package/skills/encrypt-data/SKILL.md +7 -7
- package/skills/generate-openapi/SKILL.md +5 -5
- package/skills/hash-password/SKILL.md +8 -8
- package/skills/health-checks/SKILL.md +8 -6
- package/skills/lower-stage3-decorators/SKILL.md +4 -4
- package/skills/process-image/SKILL.md +5 -5
- package/skills/register-route/SKILL.md +16 -6
- package/skills/request-memo/SKILL.md +4 -4
- package/skills/request-tracing/SKILL.md +6 -6
- package/skills/resolve-path/SKILL.md +6 -6
- package/skills/retry-operation/SKILL.md +4 -4
- package/skills/run-app/SKILL.md +20 -13
- package/skills/send-mail/SKILL.md +3 -3
- package/skills/send-response/SKILL.md +16 -8
- package/skills/store-file/SKILL.md +9 -5
- package/skills/test-http/SKILL.md +5 -5
- package/skills/test-service/SKILL.md +5 -5
- package/skills/update-packages/SKILL.md +6 -6
- package/skills/upload-file/SKILL.md +7 -7
- package/skills/use-app-context/SKILL.md +7 -7
- package/skills/use-localization/SKILL.md +6 -6
- package/skills/use-middleware/SKILL.md +8 -8
- package/skills/use-model-transformers/SKILL.md +6 -6
- package/skills/use-repository/SKILL.md +7 -7
- package/skills/use-request-locals/SKILL.md +4 -4
- package/skills/validate-input/SKILL.md +7 -7
- package/skills/warlock-conventions/SKILL.md +6 -6
- package/skills/warlock-doctor/SKILL.md +5 -5
- package/skills/warlock-routes/SKILL.md +6 -6
- package/skills/wire-socket/SKILL.md +4 -4
- package/skills/write-cli-command/SKILL.md +6 -6
- package/skills/write-middleware/SKILL.md +8 -8
- package/skills/write-seeder/SKILL.md +5 -5
- package/skills/write-use-case/SKILL.md +3 -3
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { HttpErrorCodes } from "../error-codes.mjs";
|
|
2
2
|
import { t } from "./inject-request-context.mjs";
|
|
3
|
+
import { incrementSharedRateLimit, logSharedRateLimitError } from "../rate-limit-cache-store.mjs";
|
|
4
|
+
import config from "@mongez/config";
|
|
3
5
|
import { normalizeIP } from "@fastify/rate-limit";
|
|
4
6
|
|
|
5
|
-
//#region
|
|
7
|
+
//#region ../../packages/core/src/http/middleware/rate-limit.middleware.ts
|
|
6
8
|
const buckets = /* @__PURE__ */ new Map();
|
|
7
9
|
const defaultIpv6Subnet = 64;
|
|
8
10
|
/**
|
|
@@ -21,16 +23,23 @@ let lastPruneAt = 0;
|
|
|
21
23
|
function pruneExpired(now) {
|
|
22
24
|
for (const [key, bucket] of buckets) if (bucket.resetAt <= now) buckets.delete(key);
|
|
23
25
|
}
|
|
26
|
+
function resolveStore(options) {
|
|
27
|
+
if (options.store) return options.store;
|
|
28
|
+
return config.get("http.rateLimit.store") === "cache" ? "cache" : "memory";
|
|
29
|
+
}
|
|
24
30
|
/**
|
|
25
31
|
* Per-route / per-group rate limit. Layers on top of `@fastify/rate-limit`'s
|
|
26
32
|
* global cap (configured via `http.rateLimit`) — both run, and either can
|
|
27
33
|
* 429. Use this for endpoints that need a tighter cap than the global default:
|
|
28
34
|
* login, OTP request, password reset, expensive search, AI completions.
|
|
29
35
|
*
|
|
30
|
-
* The counter
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
36
|
+
* The counter lives in-process by default, so with `N` replicas the
|
|
37
|
+
* effective cap is `N × max`. Set `store: "cache"` (or `http.rateLimit.store:
|
|
38
|
+
* "cache"`, which this follows) to count in `@warlock.js/cache` instead, so
|
|
39
|
+
* every process sharing the cache driver counts together. A cache outage
|
|
40
|
+
* fails open: the request is let through and the error is logged (at most
|
|
41
|
+
* once a minute). The `null` and `file` cache drivers are refused the same
|
|
42
|
+
* way: they cannot count, so the limiter lets requests through and logs why.
|
|
34
43
|
*
|
|
35
44
|
* Sets `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on
|
|
36
45
|
* every response; adds `Retry-After` (seconds) on a 429.
|
|
@@ -43,7 +52,7 @@ function pruneExpired(now) {
|
|
|
43
52
|
*/
|
|
44
53
|
function rateLimitMiddleware(options) {
|
|
45
54
|
const limiterId = nextLimiterId++;
|
|
46
|
-
return ({ request, response }) => {
|
|
55
|
+
return async ({ request, response }) => {
|
|
47
56
|
const now = Date.now();
|
|
48
57
|
if (now - lastPruneAt > 6e4) {
|
|
49
58
|
pruneExpired(now);
|
|
@@ -59,15 +68,28 @@ function rateLimitMiddleware(options) {
|
|
|
59
68
|
const ipKey = ip ? normalizeIP(ip, defaultIpv6Subnet) : "unknown";
|
|
60
69
|
const groupKey = options.keyGenerator?.(request) || userKey || ipKey;
|
|
61
70
|
const cacheKey = `${limiterId}:${request.route.path}:${groupKey}`;
|
|
62
|
-
let bucket
|
|
63
|
-
if (
|
|
71
|
+
let bucket;
|
|
72
|
+
if (resolveStore(options) === "cache") try {
|
|
73
|
+
const shared = await incrementSharedRateLimit(`route.${options.name ?? limiterId}.${request.route.path}`, groupKey, options.duration, now);
|
|
64
74
|
bucket = {
|
|
65
|
-
count:
|
|
66
|
-
resetAt:
|
|
75
|
+
count: shared.current,
|
|
76
|
+
resetAt: shared.resetAt
|
|
67
77
|
};
|
|
68
|
-
|
|
78
|
+
} catch (error) {
|
|
79
|
+
logSharedRateLimitError(error);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
bucket = buckets.get(cacheKey);
|
|
84
|
+
if (!bucket || bucket.resetAt <= now) {
|
|
85
|
+
bucket = {
|
|
86
|
+
count: 0,
|
|
87
|
+
resetAt: now + options.duration
|
|
88
|
+
};
|
|
89
|
+
buckets.set(cacheKey, bucket);
|
|
90
|
+
}
|
|
91
|
+
bucket.count++;
|
|
69
92
|
}
|
|
70
|
-
bucket.count++;
|
|
71
93
|
const remaining = Math.max(0, options.max - bucket.count);
|
|
72
94
|
const retryAfter = Math.max(1, Math.ceil((bucket.resetAt - now) / 1e3));
|
|
73
95
|
response.header("X-RateLimit-Limit", options.max);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limit.middleware.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"rate-limit.middleware.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/http/middleware/rate-limit.middleware.ts"],"sourcesContent":["import { normalizeIP } from \"@fastify/rate-limit\";\nimport config from \"@mongez/config\";\nimport type { Middleware } from \"../../router\";\nimport { HttpErrorCodes } from \"../error-codes\";\nimport { incrementSharedRateLimit, logSharedRateLimitError } from \"../rate-limit-cache-store\";\nimport type { Request } from \"../request\";\nimport { t } from \"./inject-request-context\";\n\n/**\n * Options for the per-route rate limit middleware.\n */\nexport type RateLimitOptions = {\n /**\n * Max requests allowed within the time window.\n */\n max: number;\n /**\n * Time window in milliseconds.\n */\n duration: number;\n /**\n * Group key generator. Defaults to the client IP. Override to scope per-user,\n * per-organization, per-tenant, etc.\n *\n * @example\n * keyGenerator: (request) => request.locals.user?.id ?? request.ip,\n */\n keyGenerator?: (request: Request) => string;\n /**\n * Key the bucket to the signed-in user (`request.locals.user.id`). Works on\n * routes and page actions alike. `keyGenerator` wins when both are set.\n */\n key?: \"user\";\n /**\n * With `key: \"user\"`, what to do for unauthenticated requests: bucket them\n * by IP (default) or skip limiting entirely.\n */\n guests?: \"ip\" | \"skip\";\n /**\n * Override the default error message. Pass a function to build it per\n * request, e.g. to translate it into the visitor's locale.\n */\n errorMessage?: string | ((request: Request) => string);\n /**\n * Where this limiter counts: `\"memory\"` (this process) or `\"cache\"`\n * (`@warlock.js/cache`, shared by every process using the same driver).\n * Defaults to `http.rateLimit.store` when that is `\"cache\"`, else `\"memory\"`.\n */\n store?: \"memory\" | \"cache\";\n /**\n * Stable name for this limiter's shared counters. Without it, limiters are\n * told apart by the order they were created, which matches across processes\n * running the same code; set a name when limiters are created conditionally.\n */\n name?: string;\n};\n\ntype Bucket = {\n count: number;\n resetAt: number;\n};\n\nconst buckets = new Map<string, Bucket>();\nconst defaultIpv6Subnet = 64;\n\n/**\n * Each `rateLimitMiddleware()` call is its own limiter. Page actions share one\n * route, so without this two limits on the same page (say `like` and\n * `comment`) would count into one bucket.\n */\nlet nextLimiterId = 0;\n\n/**\n * Sweep expired buckets so the Map doesn't grow unbounded with one-shot keys\n * (rare per-user keys, dynamic path parameters in `keyGenerator`, etc.).\n * Called opportunistically, at most once per minute, not on a timer — keeps\n * the module side-effect-free for testing.\n */\nlet lastPruneAt = 0;\n\nfunction pruneExpired(now: number) {\n for (const [key, bucket] of buckets) {\n if (bucket.resetAt <= now) {\n buckets.delete(key);\n }\n }\n}\n\nfunction resolveStore(options: RateLimitOptions): \"memory\" | \"cache\" {\n if (options.store) return options.store;\n\n return config.get(\"http.rateLimit.store\") === \"cache\" ? \"cache\" : \"memory\";\n}\n\n/**\n * Per-route / per-group rate limit. Layers on top of `@fastify/rate-limit`'s\n * global cap (configured via `http.rateLimit`) — both run, and either can\n * 429. Use this for endpoints that need a tighter cap than the global default:\n * login, OTP request, password reset, expensive search, AI completions.\n *\n * The counter lives in-process by default, so with `N` replicas the\n * effective cap is `N × max`. Set `store: \"cache\"` (or `http.rateLimit.store:\n * \"cache\"`, which this follows) to count in `@warlock.js/cache` instead, so\n * every process sharing the cache driver counts together. A cache outage\n * fails open: the request is let through and the error is logged (at most\n * once a minute). The `null` and `file` cache drivers are refused the same\n * way: they cannot count, so the limiter lets requests through and logs why.\n *\n * Sets `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on\n * every response; adds `Retry-After` (seconds) on a 429.\n *\n * @example\n * import { middleware } from \"@warlock.js/core\";\n * router.post(\"/auth/login\", loginController, {\n * middleware: [middleware.rateLimit({ max: 5, duration: 60_000 })],\n * });\n */\nexport function rateLimitMiddleware(options: RateLimitOptions): Middleware {\n const limiterId = nextLimiterId++;\n\n return async ({ request, response }) => {\n const now = Date.now();\n\n if (now - lastPruneAt > 60_000) {\n pruneExpired(now);\n lastPruneAt = now;\n }\n\n let userKey: string | undefined;\n\n if (options.key === \"user\" && !options.keyGenerator) {\n const id = (request.locals as { user?: { id?: unknown } } | undefined)?.user?.id;\n\n if (id !== undefined && id !== null && id !== \"\") {\n userKey = `user:${String(id)}`;\n } else if (options.guests === \"skip\") {\n return undefined;\n }\n }\n\n const ip = request.detectIp();\n const ipKey = ip ? normalizeIP(ip, defaultIpv6Subnet) : \"unknown\";\n const groupKey = options.keyGenerator?.(request) || userKey || ipKey;\n const cacheKey = `${limiterId}:${request.route.path}:${groupKey}`;\n\n let bucket: Bucket | undefined;\n\n if (resolveStore(options) === \"cache\") {\n try {\n const shared = await incrementSharedRateLimit(\n `route.${options.name ?? limiterId}.${request.route.path}`,\n groupKey,\n options.duration,\n now,\n );\n\n bucket = { count: shared.current, resetAt: shared.resetAt };\n } catch (error) {\n // Fail open, and report the outage at most once a minute rather\n // than once per request.\n logSharedRateLimitError(error);\n\n return undefined;\n }\n } else {\n bucket = buckets.get(cacheKey);\n\n if (!bucket || bucket.resetAt <= now) {\n bucket = { count: 0, resetAt: now + options.duration };\n buckets.set(cacheKey, bucket);\n }\n\n bucket.count++;\n }\n\n const remaining = Math.max(0, options.max - bucket.count);\n const retryAfter = Math.max(1, Math.ceil((bucket.resetAt - now) / 1000));\n\n response.header(\"X-RateLimit-Limit\", options.max);\n response.header(\"X-RateLimit-Remaining\", remaining);\n response.header(\"X-RateLimit-Reset\", Math.ceil(bucket.resetAt / 1000));\n\n if (bucket.count > options.max) {\n response.header(\"Retry-After\", retryAfter);\n\n return response.tooManyRequests({\n error:\n (typeof options.errorMessage === \"function\"\n ? options.errorMessage(request)\n : options.errorMessage) || t(\"http.rateLimitExceeded\"),\n errorCode: HttpErrorCodes.RateLimitExceeded,\n });\n }\n\n return undefined;\n };\n}\n"],"mappings":";;;;;;;AA8DA,MAAM,0BAAU,IAAI,IAAoB;AACxC,MAAM,oBAAoB;;;;;;AAO1B,IAAI,gBAAgB;;;;;;;AAQpB,IAAI,cAAc;AAElB,SAAS,aAAa,KAAa;CACjC,KAAK,MAAM,CAAC,KAAK,WAAW,SAC1B,IAAI,OAAO,WAAW,KACpB,QAAQ,OAAO,GAAG;AAGxB;AAEA,SAAS,aAAa,SAA+C;CACnE,IAAI,QAAQ,OAAO,OAAO,QAAQ;CAElC,OAAO,OAAO,IAAI,sBAAsB,MAAM,UAAU,UAAU;AACpE;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,oBAAoB,SAAuC;CACzE,MAAM,YAAY;CAElB,OAAO,OAAO,EAAE,SAAS,eAAe;EACtC,MAAM,MAAM,KAAK,IAAI;EAErB,IAAI,MAAM,cAAc,KAAQ;GAC9B,aAAa,GAAG;GAChB,cAAc;EAChB;EAEA,IAAI;EAEJ,IAAI,QAAQ,QAAQ,UAAU,CAAC,QAAQ,cAAc;GACnD,MAAM,KAAM,QAAQ,QAAoD,MAAM;GAE9E,IAAI,OAAO,UAAa,OAAO,QAAQ,OAAO,IAC5C,UAAU,QAAQ,OAAO,EAAE;QACtB,IAAI,QAAQ,WAAW,QAC5B;EAEJ;EAEA,MAAM,KAAK,QAAQ,SAAS;EAC5B,MAAM,QAAQ,KAAK,YAAY,IAAI,iBAAiB,IAAI;EACxD,MAAM,WAAW,QAAQ,eAAe,OAAO,KAAK,WAAW;EAC/D,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,MAAM,KAAK,GAAG;EAEvD,IAAI;EAEJ,IAAI,aAAa,OAAO,MAAM,SAC5B,IAAI;GACF,MAAM,SAAS,MAAM,yBACnB,SAAS,QAAQ,QAAQ,UAAU,GAAG,QAAQ,MAAM,QACpD,UACA,QAAQ,UACR,GACF;GAEA,SAAS;IAAE,OAAO,OAAO;IAAS,SAAS,OAAO;GAAQ;EAC5D,SAAS,OAAO;GAGd,wBAAwB,KAAK;GAE7B;EACF;OACK;GACL,SAAS,QAAQ,IAAI,QAAQ;GAE7B,IAAI,CAAC,UAAU,OAAO,WAAW,KAAK;IACpC,SAAS;KAAE,OAAO;KAAG,SAAS,MAAM,QAAQ;IAAS;IACrD,QAAQ,IAAI,UAAU,MAAM;GAC9B;GAEA,OAAO;EACT;EAEA,MAAM,YAAY,KAAK,IAAI,GAAG,QAAQ,MAAM,OAAO,KAAK;EACxD,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,UAAU,OAAO,GAAI,CAAC;EAEvE,SAAS,OAAO,qBAAqB,QAAQ,GAAG;EAChD,SAAS,OAAO,yBAAyB,SAAS;EAClD,SAAS,OAAO,qBAAqB,KAAK,KAAK,OAAO,UAAU,GAAI,CAAC;EAErE,IAAI,OAAO,QAAQ,QAAQ,KAAK;GAC9B,SAAS,OAAO,eAAe,UAAU;GAEzC,OAAO,SAAS,gBAAgB;IAC9B,QACG,OAAO,QAAQ,iBAAiB,aAC7B,QAAQ,aAAa,OAAO,IAC5B,QAAQ,iBAAiB,EAAE,wBAAwB;IACzD;GACF,CAAC;EACH;CAGF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cidr-match.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"cidr-match.d.mts","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/cidr-match.ts"],"mappings":";iBA2CgB,SAAA,CAAU,KAAA,UAAe,UAAkB;AAA3D;;;;AAA2D;AAkD3D;AAlDA,iBAkDgB,QAAA,CAAS,EAAA,UAAY,QAAkB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cidr-match.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"cidr-match.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/cidr-match.ts"],"sourcesContent":["/**\n * Match an IPv4 address against an exact IP or a CIDR block.\n *\n * IPv6 patterns are matched as exact-string only — full IPv6 CIDR support is\n * out of scope; ACLs in production almost always use IPv4 ranges. Add IPv6 CIDR\n * later if a real use-case appears.\n *\n * @example\n * ipMatches(\"10.0.0.5\", \"10.0.0.0/8\"); // true\n * ipMatches(\"10.0.0.5\", \"10.0.0.5\"); // true\n * ipMatches(\"192.168.1.1\", \"10.0.0.0/8\"); // false\n */\nfunction ipv4ToInt(ip: string): number | null {\n const parts = ip.split(\".\");\n\n if (parts.length !== 4) {\n return null;\n }\n\n let result = 0;\n\n for (const part of parts) {\n const num = Number(part);\n\n if (!Number.isInteger(num) || num < 0 || num > 255) {\n return null;\n }\n\n result = (result << 8) + num;\n }\n\n return result >>> 0;\n}\n\nconst IPV4_MAPPED_PREFIX = /^::ffff:(?=\\d+\\.\\d+\\.\\d+\\.\\d+$)/i;\n\n/**\n * Normalize IPv4-mapped IPv6 (`::ffff:1.2.3.4`) to plain IPv4.\n */\nfunction normalizeIp(value: string): string {\n return value.replace(IPV4_MAPPED_PREFIX, \"\");\n}\n\nexport function ipMatches(rawIp: string, rawPattern: string): boolean {\n if (!rawIp || !rawPattern) {\n return false;\n }\n\n const ip = normalizeIp(rawIp);\n const pattern = normalizeIp(rawPattern);\n\n if (pattern === ip) {\n return true;\n }\n\n if (!pattern.includes(\"/\")) {\n return false;\n }\n\n const [base, bitsRaw] = pattern.split(\"/\");\n\n if (base === undefined || bitsRaw === undefined) {\n return false;\n }\n\n const bits = Number(bitsRaw);\n\n if (!Number.isInteger(bits) || bits < 0 || bits > 32) {\n return false;\n }\n\n const ipInt = ipv4ToInt(ip);\n const baseInt = ipv4ToInt(base);\n\n if (ipInt === null || baseInt === null) {\n return false;\n }\n\n if (bits === 0) {\n return true;\n }\n\n const mask = (~0 << (32 - bits)) >>> 0;\n\n return (ipInt & mask) === (baseInt & mask);\n}\n\n/**\n * Returns true if `ip` matches any pattern in the list.\n *\n * @example\n * anyMatch(\"10.0.0.5\", [\"192.168.0.0/16\", \"10.0.0.0/8\"]); // true\n */\nexport function anyMatch(ip: string, patterns: string[]): boolean {\n return patterns.some((pattern) => ipMatches(ip, pattern));\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAS,UAAU,IAA2B;CAC5C,MAAM,QAAQ,GAAG,MAAM,GAAG;CAE1B,IAAI,MAAM,WAAW,GACnB,OAAO;CAGT,IAAI,SAAS;CAEb,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,MAAM,OAAO,IAAI;EAEvB,IAAI,CAAC,OAAO,UAAU,GAAG,KAAK,MAAM,KAAK,MAAM,KAC7C,OAAO;EAGT,UAAU,UAAU,KAAK;CAC3B;CAEA,OAAO,WAAW;AACpB;AAEA,MAAM,qBAAqB;;;;AAK3B,SAAS,YAAY,OAAuB;CAC1C,OAAO,MAAM,QAAQ,oBAAoB,EAAE;AAC7C;AAEA,SAAgB,UAAU,OAAe,YAA6B;CACpE,IAAI,CAAC,SAAS,CAAC,YACb,OAAO;CAGT,MAAM,KAAK,YAAY,KAAK;CAC5B,MAAM,UAAU,YAAY,UAAU;CAEtC,IAAI,YAAY,IACd,OAAO;CAGT,IAAI,CAAC,QAAQ,SAAS,GAAG,GACvB,OAAO;CAGT,MAAM,CAAC,MAAM,WAAW,QAAQ,MAAM,GAAG;CAEzC,IAAI,SAAS,UAAa,YAAY,QACpC,OAAO;CAGT,MAAM,OAAO,OAAO,OAAO;CAE3B,IAAI,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,IAChD,OAAO;CAGT,MAAM,QAAQ,UAAU,EAAE;CAC1B,MAAM,UAAU,UAAU,IAAI;CAE9B,IAAI,UAAU,QAAQ,YAAY,MAChC,OAAO;CAGT,IAAI,SAAS,GACX,OAAO;CAGT,MAAM,OAAQ,MAAO,KAAK,SAAW;CAErC,QAAQ,QAAQ,WAAW,UAAU;AACvC;;;;;;;AAQA,SAAgB,SAAS,IAAY,UAA6B;CAChE,OAAO,SAAS,MAAM,YAAY,UAAU,IAAI,OAAO,CAAC;AAC1D"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Request } from "../../request.mjs";
|
|
2
2
|
|
|
3
|
-
//#region
|
|
3
|
+
//#region ../../packages/core/src/http/middleware/utils/idempotency-key.d.ts
|
|
4
4
|
declare function isValidIdempotencyKey(value: unknown): value is string;
|
|
5
5
|
/**
|
|
6
6
|
* Hash a request body to a stable hex digest.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idempotency-key.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"idempotency-key.d.mts","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/idempotency-key.ts"],"mappings":";;;iBAcgB,qBAAA,CAAsB,KAAA,YAAiB,KAAK;;AAA5D;;;;AAA4D;AAmB5D;;;;iBAAgB,QAAA,CAAS,IAAa;AAAA,iBAuCtB,wBAAA,CAAyB,OAAA,EAAS,OAAO,EAAE,cAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idempotency-key.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"idempotency-key.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/idempotency-key.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport type { Request } from \"../../request\";\n\n/**\n * Idempotency-key validation rules.\n *\n * RFC draft-ietf-httpapi-idempotency-key suggests UUIDs or ULIDs but doesn't\n * mandate a format. We accept any printable ASCII string up to 255 chars —\n * tight enough to reject log-injection (no control characters / newlines),\n * loose enough to accept whatever ID scheme the client picks.\n */\nconst MAX_KEY_LENGTH = 255;\nconst PRINTABLE_ASCII = /^[\\x21-\\x7e]+$/;\n\nexport function isValidIdempotencyKey(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n value.length <= MAX_KEY_LENGTH &&\n PRINTABLE_ASCII.test(value)\n );\n}\n\n/**\n * Hash a request body to a stable hex digest.\n *\n * Used to detect \"same key, different body\" — that's a client bug, not a retry.\n * sha256 is overkill for collision resistance here, but it's the dependency-free\n * choice and avoids importing a faster hasher.\n *\n * @example\n * hashBody({ amount: 100, currency: \"USD\" }); // \"a1b2c3...\"\n */\nexport function hashBody(body: unknown): string {\n const serialized = typeof body === \"string\" ? body : JSON.stringify(body ?? {});\n\n return createHash(\"sha256\").update(serialized).digest(\"hex\");\n}\n\n/**\n * Build the cache key for an idempotency record.\n *\n * Scope is `userType:userId` when authenticated, falling back to the client IP\n * when anonymous. This prevents user A from replaying user B's key — even if\n * user B used a guessable value — while still letting the primitive work on\n * public endpoints.\n *\n * Idempotency middleware must run **after** `authMiddleware` so\n * `request.locals.user` (written by `@warlock.js/auth`) and\n * `request.decodedAccessToken` are populated.\n *\n * @example\n * buildIdempotencyCacheKey(request, \"01J9XZQ-ABC\"); // \"idem:client:user_123:01J9XZQ-ABC\"\n */\n/**\n * Read `id` off `request.locals.user` without assuming any app's\n * `RequestUser` augmentation (declared by `@warlock.js/auth`, which core\n * cannot import) declares it, and without assuming `@warlock.js/auth` is\n * even installed — hence the untyped `unknown` read here rather than a\n * typed `RequestLocals[\"user\"]` access.\n *\n * A local, narrow runtime read survives any augmentation shape — no\n * `as any`.\n */\nfunction readUserId(user: unknown): string | number | undefined {\n if (!user || typeof user !== \"object\" || !(\"id\" in user)) return undefined;\n\n const id = (user as { id?: unknown }).id;\n\n return typeof id === \"string\" || typeof id === \"number\" ? id : undefined;\n}\n\nexport function buildIdempotencyCacheKey(request: Request, idempotencyKey: string): string {\n const userType = request.decodedAccessToken?.userType || \"anonymous\";\n const locals = request.locals as Record<string, unknown>;\n const userId = readUserId(locals.user) || request.detectIp() || \"unknown\";\n\n // scope by endpoint so one key reused on another route/method never replays\n // that other endpoint's response\n const method = (request.route?.method || request.method || \"\").toUpperCase();\n const routePath = request.route?.path || \"\";\n\n return `idem:${userType}:${userId}:${method}:${routePath}:${idempotencyKey}`;\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAM,iBAAiB;AACvB,MAAM,kBAAkB;AAExB,SAAgB,sBAAsB,OAAiC;CACrE,OACE,OAAO,UAAU,YACjB,MAAM,SAAS,KACf,MAAM,UAAU,kBAChB,gBAAgB,KAAK,KAAK;AAE9B;;;;;;;;;;;AAYA,SAAgB,SAAS,MAAuB;CAC9C,MAAM,aAAa,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,QAAQ,CAAC,CAAC;CAE9E,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,OAAO,KAAK;AAC7D;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAS,WAAW,MAA4C;CAC9D,IAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,EAAE,QAAQ,OAAO,OAAO;CAEjE,MAAM,KAAM,KAA0B;CAEtC,OAAO,OAAO,OAAO,YAAY,OAAO,OAAO,WAAW,KAAK;AACjE;AAEA,SAAgB,yBAAyB,SAAkB,gBAAgC;CACzF,MAAM,WAAW,QAAQ,oBAAoB,YAAY;CACzD,MAAM,SAAS,QAAQ;CAQvB,OAAO,QAAQ,SAAS,GAPT,WAAW,OAAO,IAAI,KAAK,QAAQ,SAAS,KAAK,UAO9B,IAHlB,QAAQ,OAAO,UAAU,QAAQ,UAAU,GAAE,CAAE,YAGrB,EAAE,GAF1B,QAAQ,OAAO,QAAQ,GAEgB,GAAG;AAC9D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-size.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"parse-size.d.mts","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/parse-size.ts"],"mappings":";iBAkBgB,SAAA,CAAU,KAAsB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-size.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"parse-size.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/http/middleware/utils/parse-size.ts"],"sourcesContent":["/**\n * Parse a human-readable size string into bytes.\n *\n * Accepts `\"2mb\"`, `\"500kb\"`, `\"1.5gb\"`, `\"1024\"`, `\"1024b\"`, etc. Case-insensitive.\n * Numeric input is returned untouched (already bytes).\n *\n * @example\n * parseSize(\"2mb\"); // 2_097_152\n * parseSize(\"500kb\"); // 512_000\n * parseSize(4096); // 4096\n */\nconst UNITS: Record<string, number> = {\n b: 1,\n kb: 1024,\n mb: 1024 * 1024,\n gb: 1024 * 1024 * 1024,\n};\n\nexport function parseSize(value: string | number): number {\n if (typeof value === \"number\") {\n return value;\n }\n\n const match = /^(\\d+(?:\\.\\d+)?)\\s*(b|kb|mb|gb)?$/i.exec(value.trim());\n\n if (!match) {\n throw new Error(`Invalid size value: ${value}`);\n }\n\n const [, amount, rawUnit = \"b\"] = match;\n const unit = rawUnit.toLowerCase();\n const multiplier = UNITS[unit];\n\n if (!multiplier) {\n throw new Error(`Unknown size unit: ${unit}`);\n }\n\n return Math.floor(Number(amount) * multiplier);\n}\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,QAAgC;CACpC,GAAG;CACH,IAAI;CACJ,IAAI,OAAO;CACX,IAAI,OAAO,OAAO;AACpB;AAEA,SAAgB,UAAU,OAAgC;CACxD,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,MAAM,QAAQ,qCAAqC,KAAK,MAAM,KAAK,CAAC;CAEpE,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,uBAAuB,OAAO;CAGhD,MAAM,GAAG,QAAQ,UAAU,OAAO;CAClC,MAAM,OAAO,QAAQ,YAAY;CACjC,MAAM,aAAa,MAAM;CAEzB,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,sBAAsB,MAAM;CAG9C,OAAO,KAAK,MAAM,OAAO,MAAM,IAAI,UAAU;AAC/C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region
|
|
1
|
+
//#region ../../packages/core/src/http/parse-urlencoded-body.ts
|
|
2
2
|
/**
|
|
3
3
|
* Decode an `application/x-www-form-urlencoded` request body into a plain
|
|
4
4
|
* object, the shape `request.ts`'s `parseBody` already expects from JSON and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-urlencoded-body.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"parse-urlencoded-body.mjs","names":[],"sources":["../../../../../../../../packages/core/src/http/parse-urlencoded-body.ts"],"sourcesContent":["/**\n * Decode an `application/x-www-form-urlencoded` request body into a plain\n * object, the shape `request.ts`'s `parseBody` already expects from JSON and\n * multipart bodies.\n *\n * Repeated keys become arrays (`code=a&code=b` -> `{ code: [\"a\", \"b\"] }`);\n * every other key stays a single string. Bracket-notation keys (`a[b]=1`) are\n * NOT expanded here — they are handed through as literal keys and, like any\n * JSON or query-string key of that shape, are expanded later by the shared\n * `parseBody` nesting logic in `request.ts`. This function's only job is the\n * urlencoded -> flat-object step; it does not duplicate that logic.\n */\nexport function parseUrlencodedBody(raw: string): Record<string, string | string[]> {\n const params = new URLSearchParams(raw);\n const body: Record<string, string | string[]> = {};\n\n for (const key of params.keys()) {\n if (Object.prototype.hasOwnProperty.call(body, key)) continue;\n\n const values = params.getAll(key);\n\n body[key] = values.length > 1 ? values : (values[0] ?? \"\");\n }\n\n return body;\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,oBAAoB,KAAgD;CAClF,MAAM,SAAS,IAAI,gBAAgB,GAAG;CACtC,MAAM,OAA0C,CAAC;CAEjD,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG;EAC/B,IAAI,OAAO,UAAU,eAAe,KAAK,MAAM,GAAG,GAAG;EAErD,MAAM,SAAS,OAAO,OAAO,GAAG;EAEhC,KAAK,OAAO,OAAO,SAAS,IAAI,SAAU,OAAO,MAAM;CACzD;CAEA,OAAO;AACT"}
|
package/esm/http/plugins.d.mts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { FastifyInstance } from "./server.mjs";
|
|
2
2
|
|
|
3
|
-
//#region
|
|
3
|
+
//#region ../../packages/core/src/http/plugins.d.ts
|
|
4
4
|
declare function registerHttpPlugins(server: FastifyInstance): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* The public folder(s) worth handing to `@fastify/static`, or `undefined`
|
|
7
|
+
* when there is nothing to serve: `false`, or a single path that does not
|
|
8
|
+
* exist. An array is passed through unchanged; `@fastify/static` validates
|
|
9
|
+
* each entry itself.
|
|
10
|
+
*/
|
|
11
|
+
declare function resolvePublicRoot(publicRoot: unknown): string | string[] | undefined;
|
|
5
12
|
//#endregion
|
|
6
|
-
export { registerHttpPlugins };
|
|
13
|
+
export { registerHttpPlugins, resolvePublicRoot };
|
|
7
14
|
//# sourceMappingURL=plugins.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"plugins.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/plugins.ts"],"mappings":";;;iBAYsB,mBAAA,CAAoB,MAAA,EAAQ,eAAA,GAAe,OAAA;;AAAjE;;;;;iBA+EgB,iBAAA,CAAkB,UAAmB"}
|
package/esm/http/plugins.mjs
CHANGED
|
@@ -8,8 +8,9 @@ import { parseUrlencodedBody } from "./parse-urlencoded-body.mjs";
|
|
|
8
8
|
import config from "@mongez/config";
|
|
9
9
|
import { log } from "@warlock.js/logger";
|
|
10
10
|
import fastifyMultipart from "@fastify/multipart";
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
11
12
|
|
|
12
|
-
//#region
|
|
13
|
+
//#region ../../packages/core/src/http/plugins.ts
|
|
13
14
|
async function registerHttpPlugins(server) {
|
|
14
15
|
const rateLimitOptions = buildRateLimitOptions(config.get("http.rateLimit"));
|
|
15
16
|
if (rateLimitOptions) server.register(import("@fastify/rate-limit"), rateLimitOptions);
|
|
@@ -31,8 +32,9 @@ async function registerHttpPlugins(server) {
|
|
|
31
32
|
done(error, void 0);
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
const publicRoot = resolvePublicRoot(config.get("storage.publicRoot", rootPath("public")));
|
|
36
|
+
if (publicRoot !== void 0) server.register(import("@fastify/static"), {
|
|
37
|
+
root: publicRoot,
|
|
36
38
|
prefix: config.get("storage.publicPrefix", "/public/")
|
|
37
39
|
});
|
|
38
40
|
server.register(import("@fastify/cookie"), {
|
|
@@ -40,7 +42,19 @@ async function registerHttpPlugins(server) {
|
|
|
40
42
|
parseOptions: config.get("http.cookies.options", {})
|
|
41
43
|
});
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The public folder(s) worth handing to `@fastify/static`, or `undefined`
|
|
47
|
+
* when there is nothing to serve: `false`, or a single path that does not
|
|
48
|
+
* exist. An array is passed through unchanged; `@fastify/static` validates
|
|
49
|
+
* each entry itself.
|
|
50
|
+
*/
|
|
51
|
+
function resolvePublicRoot(publicRoot) {
|
|
52
|
+
if (publicRoot === false || publicRoot === null || publicRoot === void 0) return;
|
|
53
|
+
if (Array.isArray(publicRoot)) return publicRoot.length > 0 ? publicRoot : void 0;
|
|
54
|
+
if (typeof publicRoot === "string") return existsSync(publicRoot) ? publicRoot : void 0;
|
|
55
|
+
return publicRoot;
|
|
56
|
+
}
|
|
43
57
|
|
|
44
58
|
//#endregion
|
|
45
|
-
export { registerHttpPlugins };
|
|
59
|
+
export { registerHttpPlugins, resolvePublicRoot };
|
|
46
60
|
//# sourceMappingURL=plugins.mjs.map
|
package/esm/http/plugins.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"plugins.mjs","names":[],"sources":["../../../../../../../../packages/core/src/http/plugins.ts"],"sourcesContent":["import fastifyMultipart from \"@fastify/multipart\";\nimport config from \"@mongez/config\";\nimport { existsSync } from \"node:fs\";\nimport type { FastifyRequest } from \"fastify\";\nimport { log } from \"@warlock.js/logger\";\nimport { router } from \"../router\";\nimport { rootPath } from \"../utils\";\nimport { buildCorsOptions } from \"./build-cors-options\";\nimport { buildRateLimitOptions } from \"./build-rate-limit-options\";\nimport { parseUrlencodedBody } from \"./parse-urlencoded-body\";\nimport type { FastifyInstance } from \"./server\";\n\nexport async function registerHttpPlugins(server: FastifyInstance) {\n // 👇🏻 register rate-limit plugin\n const rateLimitOptions = buildRateLimitOptions(config.get(\"http.rateLimit\"));\n\n if (rateLimitOptions) {\n server.register(import(\"@fastify/rate-limit\"), rateLimitOptions);\n } else if (router.list().some((route) => route.rateLimit)) {\n log.warn(\n \"http\",\n \"rateLimit\",\n \"Routes declare `rateLimit`, but `http.rateLimit.enabled` is false so the rate-limit plugin is not registered: route rate limits (and their errorMessage) are inactive.\",\n );\n }\n\n // 👇🏻 register cors plugin\n server.register(import(\"@fastify/cors\"), buildCorsOptions());\n\n // 👇🏻 import multipart plugin\n server.register(fastifyMultipart, {\n attachFieldsToBody: true,\n limits: {\n // file size could be up to 10MB\n fileSize: config.get(\"http.fileUploadLimit\", 10 * 1024 * 1024),\n // every file part is buffered in memory (`attachFieldsToBody`), so cap the counts too;\n // hitting any limit makes @fastify/multipart throw an error with statusCode 413\n files: config.get(\"http.multipart.files\", 10),\n fields: config.get(\"http.multipart.fields\", 100),\n fieldSize: config.get(\"http.multipart.fieldSize\", 1024 * 1024),\n },\n });\n\n // 👇🏻 parse application/x-www-form-urlencoded bodies (Apple's OAuth\n // `form_post` callback, plain HTML forms). Fastify only parses JSON and\n // text natively, so without this every urlencoded POST is rejected with\n // FST_ERR_CTP_INVALID_MEDIA_TYPE before it reaches a route.\n //\n // No `bodyLimit` option here: Fastify falls back to the server's own\n // `bodyLimit` (`server.ts`, from `http.bodyLimit`) whenever a content-type\n // parser doesn't set one — the exact limit JSON bodies are already held to.\n // Reading `http.bodyLimit` again here would duplicate that lookup and risk\n // the two silently drifting.\n server.addContentTypeParser(\n \"application/x-www-form-urlencoded\",\n { parseAs: \"string\" },\n (_request: FastifyRequest, body: string, done: (err: Error | null, body?: any) => void) => {\n try {\n done(null, parseUrlencodedBody(body));\n } catch (error) {\n done(error as Error, undefined);\n }\n },\n );\n\n // 👇🏻 serve the public folder. Importing `@fastify/static` is not free (its\n // directory-listing module calls `os.cpus()` at load), so it is only loaded\n // when there is a folder to serve: `storage.publicRoot: false` turns public\n // serving off, and a missing folder skips it (WR-027).\n const publicRoot = resolvePublicRoot(config.get(\"storage.publicRoot\", rootPath(\"public\")));\n\n if (publicRoot !== undefined) {\n server.register(import(\"@fastify/static\"), {\n root: publicRoot,\n prefix: config.get(\"storage.publicPrefix\", \"/public/\"),\n });\n }\n\n // 👇🏻 register cookie plugin\n server.register(import(\"@fastify/cookie\"), {\n secret: config.get(\"http.cookies.secret\"), // Optional: allow signed cookies\n parseOptions: config.get(\"http.cookies.options\", {}),\n });\n}\n\n/**\n * The public folder(s) worth handing to `@fastify/static`, or `undefined`\n * when there is nothing to serve: `false`, or a single path that does not\n * exist. An array is passed through unchanged; `@fastify/static` validates\n * each entry itself.\n */\nexport function resolvePublicRoot(publicRoot: unknown): string | string[] | undefined {\n if (publicRoot === false || publicRoot === null || publicRoot === undefined) {\n return undefined;\n }\n\n if (Array.isArray(publicRoot)) {\n return publicRoot.length > 0 ? publicRoot : undefined;\n }\n\n if (typeof publicRoot === \"string\") {\n return existsSync(publicRoot) ? publicRoot : undefined;\n }\n\n return publicRoot as string;\n}\n"],"mappings":";;;;;;;;;;;;;AAYA,eAAsB,oBAAoB,QAAyB;CAEjE,MAAM,mBAAmB,sBAAsB,OAAO,IAAI,gBAAgB,CAAC;CAE3E,IAAI,kBACF,OAAO,SAAS,OAAO,wBAAwB,gBAAgB;MAC1D,IAAI,OAAO,KAAK,CAAC,CAAC,MAAM,UAAU,MAAM,SAAS,GACtD,IAAI,KACF,QACA,aACA,wKACF;CAIF,OAAO,SAAS,OAAO,kBAAkB,iBAAiB,CAAC;CAG3D,OAAO,SAAS,kBAAkB;EAChC,oBAAoB;EACpB,QAAQ;GAEN,UAAU,OAAO,IAAI,wBAAwB,KAAK,OAAO,IAAI;GAG7D,OAAO,OAAO,IAAI,wBAAwB,EAAE;GAC5C,QAAQ,OAAO,IAAI,yBAAyB,GAAG;GAC/C,WAAW,OAAO,IAAI,4BAA4B,OAAO,IAAI;EAC/D;CACF,CAAC;CAYD,OAAO,qBACL,qCACA,EAAE,SAAS,SAAS,IACnB,UAA0B,MAAc,SAAkD;EACzF,IAAI;GACF,KAAK,MAAM,oBAAoB,IAAI,CAAC;EACtC,SAAS,OAAO;GACd,KAAK,OAAgB,MAAS;EAChC;CACF,CACF;CAMA,MAAM,aAAa,kBAAkB,OAAO,IAAI,sBAAsB,SAAS,QAAQ,CAAC,CAAC;CAEzF,IAAI,eAAe,QACjB,OAAO,SAAS,OAAO,oBAAoB;EACzC,MAAM;EACN,QAAQ,OAAO,IAAI,wBAAwB,UAAU;CACvD,CAAC;CAIH,OAAO,SAAS,OAAO,oBAAoB;EACzC,QAAQ,OAAO,IAAI,qBAAqB;EACxC,cAAc,OAAO,IAAI,wBAAwB,CAAC,CAAC;CACrD,CAAC;AACH;;;;;;;AAQA,SAAgB,kBAAkB,YAAoD;CACpF,IAAI,eAAe,SAAS,eAAe,QAAQ,eAAe,QAChE;CAGF,IAAI,MAAM,QAAQ,UAAU,GAC1B,OAAO,WAAW,SAAS,IAAI,aAAa;CAG9C,IAAI,OAAO,eAAe,UACxB,OAAO,WAAW,UAAU,IAAI,aAAa;CAG/C,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-preflight.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"port-preflight.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/port-preflight.ts"],"mappings":";;AAoBA;;;;;;;;;;;;cAAa,cAAA,SAAuB,KAAK;EAAA,SAKrB,IAAA;EAAA,SACA,IAAA;;WAJF,IAAA;cAGE,IAAA,UACA,IAAA;AAAA;;;AAiBqE;AAmCzF;;;;iBAnCgB,eAAA,CAAgB,IAAA,UAAc,IAAA,YAAoC,OAAO;;;;AAsC/E;;;;;;iBAHY,qBAAA,CACpB,IAAA,UACA,IAAA,YACC,OAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-preflight.mjs","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"port-preflight.mjs","names":[],"sources":["../../../../../../../../packages/core/src/http/port-preflight.ts"],"sourcesContent":["import { createServer } from \"node:net\";\n\n/**\n * Host used when the caller has no configured bind host.\n */\nconst DEFAULT_PROBE_HOST = \"localhost\";\n\n/**\n * Raised when a port the framework is about to bind is already taken.\n *\n * Carries the port and host so a caller can report them without parsing the\n * message, and its message is the developer-facing instruction — the whole\n * point of preflighting is that nobody has to decode a raw `EADDRINUSE`.\n *\n * The message leads with `EADDRINUSE` on purpose: it is the string a\n * developer greps their terminal for, and the one every other Node tool\n * already trained them to recognize as \"something else is on this port\".\n * `code` mirrors it as a property so a caller can branch on it without\n * parsing text, the same way `NodeJS.ErrnoException.code` works.\n */\nexport class PortInUseError extends Error {\n /** Mirrors Node's own `ErrnoException.code` for this failure. */\n public readonly code = \"EADDRINUSE\";\n\n public constructor(\n public readonly port: number,\n public readonly host: string,\n ) {\n super(\n `EADDRINUSE: Port ${port} is already in use on ${host}. Stop the dev server (or whatever else is listening on port ${port}) and run again, or start on a free port — e.g. startHttpTestServer({ port: ${port + 1} }).`,\n );\n\n this.name = \"PortInUseError\";\n }\n}\n\n/**\n * Probe a TCP port by attempting a bind and immediately releasing it.\n *\n * @returns `true` when the port is free, `false` when it is taken or the\n * process is not allowed to bind it. Any other bind failure is re-thrown —\n * an unreadable network error must not be reported as \"port in use\".\n */\nexport function isPortAvailable(port: number, host: string = DEFAULT_PROBE_HOST): Promise<boolean> {\n return new Promise((resolve, reject) => {\n const probe = createServer();\n\n probe.unref();\n\n probe.once(\"error\", (error: NodeJS.ErrnoException) => {\n if (error.code === \"EADDRINUSE\" || error.code === \"EACCES\") {\n resolve(false);\n\n return;\n }\n\n reject(error);\n });\n\n probe.once(\"listening\", () => {\n probe.close(() => resolve(true));\n });\n\n // `exclusive` refuses a shared bind, which is what makes the probe honest:\n // with load balancing enabled a second bind on a served port can succeed.\n probe.listen({ port, host, exclusive: true });\n });\n}\n\n/**\n * Assert a port is free before something binds it.\n *\n * Run this ahead of the actual `listen()` so a collision surfaces as an\n * instruction the developer can act on, instead of a raw `EADDRINUSE` thrown\n * from deep inside the HTTP stack.\n *\n * @throws {PortInUseError} when the port is taken.\n */\nexport async function assertPortIsAvailable(\n port: number,\n host: string = DEFAULT_PROBE_HOST,\n): Promise<void> {\n const available = await isPortAvailable(port, host);\n\n if (!available) {\n throw new PortInUseError(port, host);\n }\n}\n"],"mappings":";;;;;;AAKA,MAAM,qBAAqB;;;;;;;;;;;;;;AAe3B,IAAa,iBAAb,cAAoC,MAAM;CAIxC,AAAO,YACL,AAAgB,MAChB,AAAgB,MAChB;EACA,MACE,oBAAoB,KAAK,wBAAwB,KAAK,+DAA+D,KAAK,8EAA8E,OAAO,EAAE,KACnN;EALgB;EACA;cAJK;EAUrB,KAAK,OAAO;CACd;AACF;;;;;;;;AASA,SAAgB,gBAAgB,MAAc,OAAe,oBAAsC;CACjG,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,aAAa;EAE3B,MAAM,MAAM;EAEZ,MAAM,KAAK,UAAU,UAAiC;GACpD,IAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,UAAU;IAC1D,QAAQ,KAAK;IAEb;GACF;GAEA,OAAO,KAAK;EACd,CAAC;EAED,MAAM,KAAK,mBAAmB;GAC5B,MAAM,YAAY,QAAQ,IAAI,CAAC;EACjC,CAAC;EAID,MAAM,OAAO;GAAE;GAAM;GAAM,WAAW;EAAK,CAAC;CAC9C,CAAC;AACH;;;;;;;;;;AAWA,eAAsB,sBACpB,MACA,OAAe,oBACA;CAGf,IAAI,CAAC,MAFmB,gBAAgB,MAAM,IAAI,GAGhD,MAAM,IAAI,eAAe,MAAM,IAAI;AAEvC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { log } from "@warlock.js/logger";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { cache } from "@warlock.js/cache";
|
|
4
|
+
|
|
5
|
+
//#region ../../packages/core/src/http/rate-limit-cache-store.ts
|
|
6
|
+
/**
|
|
7
|
+
* Rate-limit counting shared through `@warlock.js/cache`, so every process
|
|
8
|
+
* that uses the same cache driver (Redis, Postgres) counts into the same
|
|
9
|
+
* buckets. With a memory driver (`memory`, `lru`, `memoryExtended`) the
|
|
10
|
+
* counts stay in the process, like the in-memory limiter.
|
|
11
|
+
*
|
|
12
|
+
* Windows are fixed and aligned to the clock: a 60 s window resets on the
|
|
13
|
+
* minute, whichever process saw the first request. Each window has its own
|
|
14
|
+
* key, created atomically with a TTL of two windows and incremented with the
|
|
15
|
+
* driver's atomic increment, so a key cannot expire while its window counts.
|
|
16
|
+
*
|
|
17
|
+
* Two drivers are refused, with {@link UnsupportedRateLimitDriverError}:
|
|
18
|
+
*
|
|
19
|
+
* - `null` stores nothing, so every request would count as the first and the
|
|
20
|
+
* limit would never trip.
|
|
21
|
+
* - `file` has no expiry sweeper, so every past window would stay on disk
|
|
22
|
+
* forever, and its increment is only serialized within one process, so
|
|
23
|
+
* workers sharing the directory would lose counts.
|
|
24
|
+
*/
|
|
25
|
+
const KEY_PREFIX = "rate-limit";
|
|
26
|
+
/**
|
|
27
|
+
* Cache drivers that cannot back a shared limiter (see the module comment).
|
|
28
|
+
*/
|
|
29
|
+
const UNSUPPORTED_DRIVERS = new Set(["null", "file"]);
|
|
30
|
+
/**
|
|
31
|
+
* Thrown when `store: "cache"` runs on a cache driver that cannot count.
|
|
32
|
+
*/
|
|
33
|
+
var UnsupportedRateLimitDriverError = class extends Error {
|
|
34
|
+
constructor(driverName) {
|
|
35
|
+
super(`Rate limiting with store: "cache" cannot use the "${driverName}" cache driver: ` + (driverName === "null" ? "it stores nothing, so the limit would never trip. " : "it never removes expired windows and its increment is not shared between processes. ") + "Use redis or pg (or a memory driver for a single process), or set store: \"memory\".");
|
|
36
|
+
this.name = "UnsupportedRateLimitDriverError";
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function assertSupportedDriver() {
|
|
40
|
+
const driverName = cache.currentDriver?.name;
|
|
41
|
+
if (driverName && UNSUPPORTED_DRIVERS.has(driverName)) throw new UnsupportedRateLimitDriverError(driverName);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Hash used for group keys and route namespaces before they reach the cache.
|
|
45
|
+
*/
|
|
46
|
+
function shortHash(value) {
|
|
47
|
+
return createHash("sha256").update(value).digest("hex").slice(0, 32);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The group key (an IP, a user id, whatever `keyGenerator` returned) is
|
|
51
|
+
* hashed before it reaches the cache: cache drivers log their keys, and a raw
|
|
52
|
+
* IP or email in a key is personal data in a log line.
|
|
53
|
+
*
|
|
54
|
+
* The namespace (it carries a route path) is hashed as well: flattening
|
|
55
|
+
* `/users/:id` and `/users/id` to one safe string merged their counters, and
|
|
56
|
+
* the file driver would turn `/` into directories. A readable, flattened
|
|
57
|
+
* prefix stays in front of the hash for debugging.
|
|
58
|
+
*/
|
|
59
|
+
function windowKey(namespace, group, windowIndex) {
|
|
60
|
+
return `${KEY_PREFIX}.${namespace.replace(/[^A-Za-z0-9_-]+/g, "_").slice(0, 40)}-${shortHash(namespace).slice(0, 16)}.${shortHash(group)}.${windowIndex}`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Count one request for `group` in the current window.
|
|
64
|
+
*
|
|
65
|
+
* @returns the count so far in this window and when the window resets (epoch ms)
|
|
66
|
+
* @throws {UnsupportedRateLimitDriverError} on the `null` or `file` driver
|
|
67
|
+
*/
|
|
68
|
+
async function incrementSharedRateLimit(namespace, group, windowMs, now = Date.now()) {
|
|
69
|
+
assertSupportedDriver();
|
|
70
|
+
const windowIndex = Math.floor(now / windowMs);
|
|
71
|
+
const key = windowKey(namespace, group, windowIndex);
|
|
72
|
+
const ttlSeconds = Math.max(1, Math.ceil(2 * windowMs / 1e3));
|
|
73
|
+
await cache.set(key, 0, {
|
|
74
|
+
ttl: ttlSeconds,
|
|
75
|
+
onConflict: "create"
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
current: await cache.increment(key),
|
|
79
|
+
resetAt: (windowIndex + 1) * windowMs
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Read the count for `group` in the current window without counting a request
|
|
84
|
+
*/
|
|
85
|
+
async function readSharedRateLimit(namespace, group, windowMs, now = Date.now()) {
|
|
86
|
+
assertSupportedDriver();
|
|
87
|
+
const windowIndex = Math.floor(now / windowMs);
|
|
88
|
+
const value = await cache.get(windowKey(namespace, group, windowIndex));
|
|
89
|
+
return {
|
|
90
|
+
current: typeof value === "number" ? value : 0,
|
|
91
|
+
resetAt: (windowIndex + 1) * windowMs
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* How often a failing shared store is reported. A cache outage fails every
|
|
96
|
+
* request, so logging each one would flood the log.
|
|
97
|
+
*/
|
|
98
|
+
const ERROR_LOG_INTERVAL_MS = 6e4;
|
|
99
|
+
let lastErrorLogAt = 0;
|
|
100
|
+
/**
|
|
101
|
+
* Log a shared rate-limit store failure, at most once per minute.
|
|
102
|
+
*/
|
|
103
|
+
function logSharedRateLimitError(error, now = Date.now()) {
|
|
104
|
+
if (now - lastErrorLogAt < ERROR_LOG_INTERVAL_MS) return;
|
|
105
|
+
lastErrorLogAt = now;
|
|
106
|
+
log.error("http", "rate-limit", error);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* `fastify.rateLimit()` hooks have no route; told apart by creation order,
|
|
110
|
+
* which matches across processes running the same code.
|
|
111
|
+
*/
|
|
112
|
+
let nextHookNamespace = 0;
|
|
113
|
+
/**
|
|
114
|
+
* `@fastify/rate-limit` store backed by `@warlock.js/cache`. Selected with
|
|
115
|
+
* `http.rateLimit.store: "cache"`; each route with its own `rateLimit` gets
|
|
116
|
+
* its own namespace through `child()`.
|
|
117
|
+
*
|
|
118
|
+
* A failure (cache outage, unsupported driver) is logged at most once a
|
|
119
|
+
* minute and passed to the plugin, which lets the request through because
|
|
120
|
+
* Warlock registers it with `skipOnError: true` for this store.
|
|
121
|
+
*/
|
|
122
|
+
var CacheRateLimitStore = class CacheRateLimitStore {
|
|
123
|
+
constructor(_options, namespace = "global") {
|
|
124
|
+
this.namespace = namespace;
|
|
125
|
+
}
|
|
126
|
+
incr(key, callback, timeWindow) {
|
|
127
|
+
incrementSharedRateLimit(this.namespace, key, timeWindow).then(({ current, resetAt }) => callback(null, {
|
|
128
|
+
current,
|
|
129
|
+
ttl: Math.max(0, resetAt - Date.now())
|
|
130
|
+
}), (error) => {
|
|
131
|
+
logSharedRateLimitError(error);
|
|
132
|
+
callback(error instanceof Error ? error : new Error(String(error)));
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
read(key, callback, timeWindow) {
|
|
136
|
+
readSharedRateLimit(this.namespace, key, timeWindow).then(({ current, resetAt }) => callback(null, {
|
|
137
|
+
current,
|
|
138
|
+
ttl: current === 0 ? 0 : Math.max(0, resetAt - Date.now())
|
|
139
|
+
}), (error) => {
|
|
140
|
+
logSharedRateLimitError(error);
|
|
141
|
+
callback(error instanceof Error ? error : new Error(String(error)));
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
child(routeOptions) {
|
|
145
|
+
const routeInfo = routeOptions.routeInfo ?? {};
|
|
146
|
+
const method = Array.isArray(routeInfo.method) ? routeInfo.method.join(",") : String(routeInfo.method ?? "");
|
|
147
|
+
const url = routeInfo.url ?? routeInfo.path ?? "";
|
|
148
|
+
if (!method && !url) return new CacheRateLimitStore(void 0, `hook.${nextHookNamespace++}`);
|
|
149
|
+
return new CacheRateLimitStore(void 0, `route.${method} ${url}`);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
export { CacheRateLimitStore, incrementSharedRateLimit, logSharedRateLimitError };
|
|
155
|
+
//# sourceMappingURL=rate-limit-cache-store.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit-cache-store.mjs","names":[],"sources":["../../../../../../../../packages/core/src/http/rate-limit-cache-store.ts"],"sourcesContent":["import type { FastifyRateLimitOptions, FastifyRateLimitStore } from \"@fastify/rate-limit\";\nimport { cache } from \"@warlock.js/cache\";\nimport { log } from \"@warlock.js/logger\";\nimport { createHash } from \"node:crypto\";\n\n/**\n * Rate-limit counting shared through `@warlock.js/cache`, so every process\n * that uses the same cache driver (Redis, Postgres) counts into the same\n * buckets. With a memory driver (`memory`, `lru`, `memoryExtended`) the\n * counts stay in the process, like the in-memory limiter.\n *\n * Windows are fixed and aligned to the clock: a 60 s window resets on the\n * minute, whichever process saw the first request. Each window has its own\n * key, created atomically with a TTL of two windows and incremented with the\n * driver's atomic increment, so a key cannot expire while its window counts.\n *\n * Two drivers are refused, with {@link UnsupportedRateLimitDriverError}:\n *\n * - `null` stores nothing, so every request would count as the first and the\n * limit would never trip.\n * - `file` has no expiry sweeper, so every past window would stay on disk\n * forever, and its increment is only serialized within one process, so\n * workers sharing the directory would lose counts.\n */\n\nconst KEY_PREFIX = \"rate-limit\";\n\n/**\n * Cache drivers that cannot back a shared limiter (see the module comment).\n */\nconst UNSUPPORTED_DRIVERS = new Set([\"null\", \"file\"]);\n\n/**\n * Thrown when `store: \"cache\"` runs on a cache driver that cannot count.\n */\nexport class UnsupportedRateLimitDriverError extends Error {\n public constructor(driverName: string) {\n super(\n `Rate limiting with store: \"cache\" cannot use the \"${driverName}\" cache driver: ` +\n (driverName === \"null\"\n ? \"it stores nothing, so the limit would never trip. \"\n : \"it never removes expired windows and its increment is not shared between processes. \") +\n 'Use redis or pg (or a memory driver for a single process), or set store: \"memory\".',\n );\n\n this.name = \"UnsupportedRateLimitDriverError\";\n }\n}\n\nfunction assertSupportedDriver(): void {\n const driverName = cache.currentDriver?.name;\n\n if (driverName && UNSUPPORTED_DRIVERS.has(driverName)) {\n throw new UnsupportedRateLimitDriverError(driverName);\n }\n}\n\n/**\n * Hash used for group keys and route namespaces before they reach the cache.\n */\nfunction shortHash(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 32);\n}\n\n/**\n * The group key (an IP, a user id, whatever `keyGenerator` returned) is\n * hashed before it reaches the cache: cache drivers log their keys, and a raw\n * IP or email in a key is personal data in a log line.\n *\n * The namespace (it carries a route path) is hashed as well: flattening\n * `/users/:id` and `/users/id` to one safe string merged their counters, and\n * the file driver would turn `/` into directories. A readable, flattened\n * prefix stays in front of the hash for debugging.\n */\nfunction windowKey(namespace: string, group: string, windowIndex: number): string {\n const readable = namespace.replace(/[^A-Za-z0-9_-]+/g, \"_\").slice(0, 40);\n\n return `${KEY_PREFIX}.${readable}-${shortHash(namespace).slice(0, 16)}.${shortHash(group)}.${windowIndex}`;\n}\n\n/**\n * Count one request for `group` in the current window.\n *\n * @returns the count so far in this window and when the window resets (epoch ms)\n * @throws {UnsupportedRateLimitDriverError} on the `null` or `file` driver\n */\nexport async function incrementSharedRateLimit(\n namespace: string,\n group: string,\n windowMs: number,\n now: number = Date.now(),\n): Promise<{ current: number; resetAt: number }> {\n assertSupportedDriver();\n\n const windowIndex = Math.floor(now / windowMs);\n const key = windowKey(namespace, group, windowIndex);\n const ttlSeconds = Math.max(1, Math.ceil((2 * windowMs) / 1000));\n\n await cache.set(key, 0, { ttl: ttlSeconds, onConflict: \"create\" });\n\n const current = await cache.increment(key);\n\n return { current, resetAt: (windowIndex + 1) * windowMs };\n}\n\n/**\n * Read the count for `group` in the current window without counting a request\n */\nexport async function readSharedRateLimit(\n namespace: string,\n group: string,\n windowMs: number,\n now: number = Date.now(),\n): Promise<{ current: number; resetAt: number }> {\n assertSupportedDriver();\n\n const windowIndex = Math.floor(now / windowMs);\n const value = await cache.get(windowKey(namespace, group, windowIndex));\n\n return {\n current: typeof value === \"number\" ? value : 0,\n resetAt: (windowIndex + 1) * windowMs,\n };\n}\n\n/**\n * How often a failing shared store is reported. A cache outage fails every\n * request, so logging each one would flood the log.\n */\nconst ERROR_LOG_INTERVAL_MS = 60_000;\n\nlet lastErrorLogAt = 0;\n\n/**\n * Log a shared rate-limit store failure, at most once per minute.\n */\nexport function logSharedRateLimitError(error: unknown, now: number = Date.now()): void {\n if (now - lastErrorLogAt < ERROR_LOG_INTERVAL_MS) return;\n\n lastErrorLogAt = now;\n log.error(\"http\", \"rate-limit\", error);\n}\n\n/**\n * Forget when the last store error was logged (tests).\n */\nexport function resetSharedRateLimitErrorLog(): void {\n lastErrorLogAt = 0;\n}\n\n/**\n * Route data `@fastify/rate-limit` passes to `child()`: the route's options\n * under `routeInfo` (`fastify.rateLimit()` hooks pass an empty one).\n */\ntype ChildRouteOptions = {\n routeInfo?: { method?: unknown; url?: string; path?: string };\n};\n\n/**\n * `fastify.rateLimit()` hooks have no route; told apart by creation order,\n * which matches across processes running the same code.\n */\nlet nextHookNamespace = 0;\n\n/**\n * `@fastify/rate-limit` store backed by `@warlock.js/cache`. Selected with\n * `http.rateLimit.store: \"cache\"`; each route with its own `rateLimit` gets\n * its own namespace through `child()`.\n *\n * A failure (cache outage, unsupported driver) is logged at most once a\n * minute and passed to the plugin, which lets the request through because\n * Warlock registers it with `skipOnError: true` for this store.\n */\nexport class CacheRateLimitStore implements FastifyRateLimitStore {\n public constructor(\n _options?: FastifyRateLimitOptions,\n protected readonly namespace: string = \"global\",\n ) {}\n\n public incr(\n key: string,\n callback: (error: Error | null, result?: { current: number; ttl: number }) => void,\n timeWindow: number,\n ): void {\n incrementSharedRateLimit(this.namespace, key, timeWindow).then(\n ({ current, resetAt }) => callback(null, { current, ttl: Math.max(0, resetAt - Date.now()) }),\n (error: unknown) => {\n logSharedRateLimitError(error);\n callback(error instanceof Error ? error : new Error(String(error)));\n },\n );\n }\n\n public read(\n key: string,\n callback: (error: Error | null, result?: { current: number; ttl: number }) => void,\n timeWindow: number,\n ): void {\n readSharedRateLimit(this.namespace, key, timeWindow).then(\n ({ current, resetAt }) =>\n callback(null, { current, ttl: current === 0 ? 0 : Math.max(0, resetAt - Date.now()) }),\n (error: unknown) => {\n logSharedRateLimitError(error);\n callback(error instanceof Error ? error : new Error(String(error)));\n },\n );\n }\n\n public child(routeOptions: Parameters<FastifyRateLimitStore[\"child\"]>[0]): FastifyRateLimitStore {\n // The plugin's declared type names the route options directly, but at\n // runtime (11.x) it passes them merged under `routeInfo`.\n const routeInfo = (routeOptions as unknown as ChildRouteOptions).routeInfo ?? {};\n const method = Array.isArray(routeInfo.method)\n ? routeInfo.method.join(\",\")\n : String(routeInfo.method ?? \"\");\n const url = routeInfo.url ?? routeInfo.path ?? \"\";\n\n if (!method && !url) {\n return new CacheRateLimitStore(undefined, `hook.${nextHookNamespace++}`);\n }\n\n return new CacheRateLimitStore(undefined, `route.${method} ${url}`);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,aAAa;;;;AAKnB,MAAM,sBAAsB,IAAI,IAAI,CAAC,QAAQ,MAAM,CAAC;;;;AAKpD,IAAa,kCAAb,cAAqD,MAAM;CACzD,AAAO,YAAY,YAAoB;EACrC,MACE,qDAAqD,WAAW,qBAC7D,eAAe,SACZ,uDACA,0FACJ,sFACJ;EAEA,KAAK,OAAO;CACd;AACF;AAEA,SAAS,wBAA8B;CACrC,MAAM,aAAa,MAAM,eAAe;CAExC,IAAI,cAAc,oBAAoB,IAAI,UAAU,GAClD,MAAM,IAAI,gCAAgC,UAAU;AAExD;;;;AAKA,SAAS,UAAU,OAAuB;CACxC,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE;AACrE;;;;;;;;;;;AAYA,SAAS,UAAU,WAAmB,OAAe,aAA6B;CAGhF,OAAO,GAAG,WAAW,GAFJ,UAAU,QAAQ,oBAAoB,GAAG,CAAC,CAAC,MAAM,GAAG,EAEtC,EAAE,GAAG,UAAU,SAAS,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,GAAG,UAAU,KAAK,EAAE,GAAG;AAC/F;;;;;;;AAQA,eAAsB,yBACpB,WACA,OACA,UACA,MAAc,KAAK,IAAI,GACwB;CAC/C,sBAAsB;CAEtB,MAAM,cAAc,KAAK,MAAM,MAAM,QAAQ;CAC7C,MAAM,MAAM,UAAU,WAAW,OAAO,WAAW;CACnD,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,KAAM,IAAI,WAAY,GAAI,CAAC;CAE/D,MAAM,MAAM,IAAI,KAAK,GAAG;EAAE,KAAK;EAAY,YAAY;CAAS,CAAC;CAIjE,OAAO;EAAE,eAFa,MAAM,UAAU,GAAG;EAEvB,UAAU,cAAc,KAAK;CAAS;AAC1D;;;;AAKA,eAAsB,oBACpB,WACA,OACA,UACA,MAAc,KAAK,IAAI,GACwB;CAC/C,sBAAsB;CAEtB,MAAM,cAAc,KAAK,MAAM,MAAM,QAAQ;CAC7C,MAAM,QAAQ,MAAM,MAAM,IAAI,UAAU,WAAW,OAAO,WAAW,CAAC;CAEtE,OAAO;EACL,SAAS,OAAO,UAAU,WAAW,QAAQ;EAC7C,UAAU,cAAc,KAAK;CAC/B;AACF;;;;;AAMA,MAAM,wBAAwB;AAE9B,IAAI,iBAAiB;;;;AAKrB,SAAgB,wBAAwB,OAAgB,MAAc,KAAK,IAAI,GAAS;CACtF,IAAI,MAAM,iBAAiB,uBAAuB;CAElD,iBAAiB;CACjB,IAAI,MAAM,QAAQ,cAAc,KAAK;AACvC;;;;;AAqBA,IAAI,oBAAoB;;;;;;;;;;AAWxB,IAAa,sBAAb,MAAa,oBAAqD;CAChE,AAAO,YACL,UACA,AAAmB,YAAoB,UACvC;EADmB;CAClB;CAEH,AAAO,KACL,KACA,UACA,YACM;EACN,yBAAyB,KAAK,WAAW,KAAK,UAAU,CAAC,CAAC,MACvD,EAAE,SAAS,cAAc,SAAS,MAAM;GAAE;GAAS,KAAK,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,CAAC;EAAE,CAAC,IAC3F,UAAmB;GAClB,wBAAwB,KAAK;GAC7B,SAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EACpE,CACF;CACF;CAEA,AAAO,KACL,KACA,UACA,YACM;EACN,oBAAoB,KAAK,WAAW,KAAK,UAAU,CAAC,CAAC,MAClD,EAAE,SAAS,cACV,SAAS,MAAM;GAAE;GAAS,KAAK,YAAY,IAAI,IAAI,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,CAAC;EAAE,CAAC,IACvF,UAAmB;GAClB,wBAAwB,KAAK;GAC7B,SAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EACpE,CACF;CACF;CAEA,AAAO,MAAM,cAAoF;EAG/F,MAAM,YAAa,aAA8C,aAAa,CAAC;EAC/E,MAAM,SAAS,MAAM,QAAQ,UAAU,MAAM,IACzC,UAAU,OAAO,KAAK,GAAG,IACzB,OAAO,UAAU,UAAU,EAAE;EACjC,MAAM,MAAM,UAAU,OAAO,UAAU,QAAQ;EAE/C,IAAI,CAAC,UAAU,CAAC,KACd,OAAO,IAAI,oBAAoB,QAAW,QAAQ,qBAAqB;EAGzE,OAAO,IAAI,oBAAoB,QAAW,SAAS,OAAO,GAAG,KAAK;CACpE;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ready-report.d.mts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"ready-report.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/ready-report.ts"],"mappings":";;AAiCA;;;;;;;;;;;AAYW;AAQX;;;;AAAwD;AASxD;;;;AAAqD;AAKrD;;;;AAAoC;;;;;KAlCxB,eAAA;2EAEV,YAAA;EAEA,GAAA;EAEA,YAAA;EAEA,IAAA;EAEA,UAAA;EAEA,SAAA;AAAA;;;;iBAQc,kBAAA,CAAmB,IAAqB,EAAf,eAAe;;;;;;iBASxC,kBAAA,IAAsB,eAAe;;iBAKrC,oBAAA"}
|