@warlock.js/core 5.31.0 → 5.32.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 +23 -0
- package/esm/application/app.d.mts +3 -3
- package/esm/application/app.d.mts.map +1 -1
- package/esm/application/application-config-types.d.mts +1 -2
- package/esm/application/application-config-types.d.mts.map +1 -1
- package/esm/application/application.d.mts +5 -7
- package/esm/application/application.d.mts.map +1 -1
- package/esm/application/application.mjs +3 -1
- package/esm/application/application.mjs.map +1 -1
- package/esm/application/boot-signal.d.mts +14 -12
- package/esm/application/boot-signal.d.mts.map +1 -1
- package/esm/application/index.d.mts +2 -1
- package/esm/application/index.mjs +1 -1
- package/esm/application/public-url.d.mts +1 -2
- package/esm/application/public-url.d.mts.map +1 -1
- package/esm/application/roles.d.mts +10 -11
- package/esm/application/roles.d.mts.map +1 -1
- package/esm/benchmark/benchmark-snapshots.d.mts +1 -3
- package/esm/benchmark/benchmark-snapshots.d.mts.map +1 -1
- package/esm/benchmark/benchmark.d.mts +1 -3
- package/esm/benchmark/benchmark.d.mts.map +1 -1
- package/esm/benchmark/channels/console.channel.d.mts +1 -3
- package/esm/benchmark/channels/console.channel.d.mts.map +1 -1
- package/esm/benchmark/channels/noop.channel.d.mts +1 -3
- package/esm/benchmark/channels/noop.channel.d.mts.map +1 -1
- package/esm/benchmark/index.mjs +1 -1
- package/esm/benchmark/profiler.d.mts +1 -3
- package/esm/benchmark/profiler.d.mts.map +1 -1
- package/esm/benchmark/profiler.mjs +2 -1
- package/esm/benchmark/profiler.mjs.map +1 -1
- package/esm/benchmark/types.d.mts +22 -17
- package/esm/benchmark/types.d.mts.map +1 -1
- package/esm/bootstrap/setup.d.mts +1 -2
- package/esm/bootstrap/setup.d.mts.map +1 -1
- package/esm/bootstrap.d.mts +1 -2
- package/esm/bootstrap.d.mts.map +1 -1
- package/esm/cache/database-cache-driver.d.mts +3 -5
- package/esm/cache/database-cache-driver.d.mts.map +1 -1
- package/esm/cache/database-cache-driver.mjs +1 -1
- package/esm/cache/index.d.mts +2 -1
- package/esm/cache/index.mjs +1 -1
- package/esm/cli/cli-commands.manager.mjs +6 -3
- package/esm/cli/cli-commands.manager.mjs.map +1 -1
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs +3 -2
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -1
- package/esm/cli/commands/board/board-command.action.mjs +1 -1
- package/esm/cli/commands/check/check-command.action.mjs +1 -1
- package/esm/cli/commands/check/child-typecheck.mjs +1 -1
- package/esm/cli/commands/check/child-typecheck.mjs.map +1 -1
- package/esm/cli/commands/check/format-problems.mjs +1 -1
- package/esm/cli/commands/dev-server.command.mjs +3 -2
- package/esm/cli/commands/dev-server.command.mjs.map +1 -1
- package/esm/cli/commands/doctor/check.types.d.mts +29 -16
- package/esm/cli/commands/doctor/check.types.d.mts.map +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +22 -27
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs +2 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
- package/esm/cli/commands/explain/explain-command.action.mjs +1 -1
- package/esm/cli/commands/generate/generators/controller.generator.mjs +5 -2
- package/esm/cli/commands/generate/generators/controller.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs +5 -3
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs +3 -2
- package/esm/cli/commands/generate/generators/model.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs +3 -1
- package/esm/cli/commands/generate/generators/repository.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs +3 -1
- package/esm/cli/commands/generate/generators/resource.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs +3 -1
- package/esm/cli/commands/generate/generators/service.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +2 -2
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs +1 -2
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
- package/esm/cli/commands/generate/utils/path-resolver.mjs +1 -1
- package/esm/cli/commands/inspect/inspect-command.action.mjs +3 -2
- package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -1
- package/esm/cli/commands/issue/collect-environment.mjs +187 -0
- package/esm/cli/commands/issue/collect-environment.mjs.map +1 -0
- package/esm/cli/commands/issue/issue-command.action.mjs +70 -0
- package/esm/cli/commands/issue/issue-command.action.mjs.map +1 -0
- package/esm/cli/commands/issue.command.mjs +31 -0
- package/esm/cli/commands/issue.command.mjs.map +1 -0
- package/esm/cli/commands/mcp/mcp-command.action.mjs +15 -14
- package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.action.mjs +1 -1
- package/esm/cli/commands/postman-generator.action.mjs +1 -1
- package/esm/cli/commands/routes/format-routes-table.mjs +1 -1
- package/esm/cli/commands/routes/route-row.mjs +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs +2 -2
- package/esm/cli/commands/routes/routes-diff.action.mjs.map +1 -1
- package/esm/cli/commands/test.command.mjs +1 -1
- package/esm/cli/commands/trace/trace-command.action.mjs +1 -1
- package/esm/cli/commands-loader.mjs +1 -1
- package/esm/cli/framework-cli-commands.mjs +2 -0
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/cli/parse-cli-args.mjs +2 -2
- package/esm/cli/parse-cli-args.mjs.map +1 -1
- package/esm/cli/start.d.mts +1 -1
- package/esm/cli/string-similarity.mjs +1 -1
- package/esm/commands/cli-command.d.mts +2 -4
- package/esm/commands/cli-command.d.mts.map +1 -1
- package/esm/commands/index.d.mts +2 -1
- package/esm/commands/index.mjs +1 -1
- package/esm/commands/types.d.mts +8 -8
- package/esm/commands/types.d.mts.map +1 -1
- package/esm/config/config-getter.d.mts +2 -3
- package/esm/config/config-getter.d.mts.map +1 -1
- package/esm/config/config-getter.mjs +5 -5
- package/esm/config/config-getter.mjs.map +1 -1
- package/esm/config/config-handlers.d.mts +1 -3
- package/esm/config/config-handlers.d.mts.map +1 -1
- package/esm/config/config-loader.d.mts +1 -2
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +3 -3
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-manager.mjs +1 -1
- package/esm/config/config-schema.d.mts +19 -16
- package/esm/config/config-schema.d.mts.map +1 -1
- package/esm/config/config-setter.d.mts +2 -4
- package/esm/config/config-setter.d.mts.map +1 -1
- package/esm/config/config-setter.mjs +2 -2
- package/esm/config/config-setter.mjs.map +1 -1
- package/esm/config/config-special-handlers.d.mts +2 -4
- package/esm/config/config-special-handlers.d.mts.map +1 -1
- package/esm/config/index.d.mts +2 -1
- package/esm/config/index.mjs +1 -1
- package/esm/config/types.d.mts +4 -5
- package/esm/config/types.d.mts.map +1 -1
- package/esm/connectors/access-connector.d.mts +1 -3
- package/esm/connectors/access-connector.d.mts.map +1 -1
- package/esm/connectors/access-connector.mjs +2 -2
- package/esm/connectors/access-connector.mjs.map +1 -1
- package/esm/connectors/ai-connector.d.mts +1 -3
- package/esm/connectors/ai-connector.d.mts.map +1 -1
- package/esm/connectors/ai-connector.mjs +2 -2
- package/esm/connectors/ai-connector.mjs.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.d.mts +1 -3
- package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts +1 -3
- package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs +2 -1
- package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
- package/esm/connectors/base-connector.d.mts +1 -3
- package/esm/connectors/base-connector.d.mts.map +1 -1
- package/esm/connectors/cache-connector.d.mts +1 -3
- package/esm/connectors/cache-connector.d.mts.map +1 -1
- package/esm/connectors/cache-connector.mjs +3 -3
- package/esm/connectors/cache-connector.mjs.map +1 -1
- package/esm/connectors/connectors-manager.d.mts +2 -4
- 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 -3
- package/esm/connectors/database-connector.d.mts.map +1 -1
- package/esm/connectors/database-connector.mjs +2 -2
- package/esm/connectors/database-connector.mjs.map +1 -1
- package/esm/connectors/describe-server-address.mjs +4 -4
- package/esm/connectors/describe-server-address.mjs.map +1 -1
- package/esm/connectors/herald-connector.d.mts +1 -3
- package/esm/connectors/herald-connector.d.mts.map +1 -1
- package/esm/connectors/herald-connector.mjs +2 -2
- package/esm/connectors/herald-connector.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts +1 -3
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +8 -7
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/index.d.mts +2 -1
- package/esm/connectors/index.mjs +1 -1
- package/esm/connectors/logger-connector.d.mts +1 -3
- package/esm/connectors/logger-connector.d.mts.map +1 -1
- package/esm/connectors/logger-connector.mjs +2 -2
- package/esm/connectors/logger-connector.mjs.map +1 -1
- package/esm/connectors/mail-connector.d.mts +1 -3
- package/esm/connectors/mail-connector.d.mts.map +1 -1
- package/esm/connectors/mail-connector.mjs +2 -2
- package/esm/connectors/mail-connector.mjs.map +1 -1
- package/esm/connectors/notifications-connector.d.mts +1 -3
- package/esm/connectors/notifications-connector.d.mts.map +1 -1
- package/esm/connectors/notifications-connector.mjs +2 -2
- package/esm/connectors/notifications-connector.mjs.map +1 -1
- package/esm/connectors/register-configured-connectors.d.mts +2 -4
- package/esm/connectors/register-configured-connectors.d.mts.map +1 -1
- package/esm/connectors/socket-connector.d.mts +1 -3
- package/esm/connectors/socket-connector.d.mts.map +1 -1
- package/esm/connectors/socket-connector.mjs +12 -10
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/connectors/storage.connector.d.mts +1 -3
- package/esm/connectors/storage.connector.d.mts.map +1 -1
- package/esm/connectors/storage.connector.mjs +2 -2
- package/esm/connectors/storage.connector.mjs.map +1 -1
- package/esm/connectors/types.d.mts +17 -14
- package/esm/connectors/types.d.mts.map +1 -1
- package/esm/container/container-instance-registry.mjs.map +1 -1
- package/esm/container/development-app-modules.d.mts +7 -5
- package/esm/container/development-app-modules.d.mts.map +1 -1
- package/esm/container/development-model-modules.d.mts +6 -5
- package/esm/container/development-model-modules.d.mts.map +1 -1
- package/esm/container/index.d.mts +4 -4
- package/esm/container/index.d.mts.map +1 -1
- package/esm/database/index.d.mts +3 -1
- package/esm/database/index.mjs +1 -1
- package/esm/database/migrate-action.mjs +1 -1
- package/esm/database/models/database-log/database-log.d.mts +2 -3
- package/esm/database/models/database-log/database-log.d.mts.map +1 -1
- package/esm/database/models/database-log/index.d.mts +2 -1
- package/esm/database/models/database-log/index.mjs +1 -1
- package/esm/database/seed-command-action.mjs +1 -1
- package/esm/database/seeds/seeder.d.mts +2 -4
- package/esm/database/seeds/seeder.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +2 -3
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
- package/esm/database/seeds/seeders.manager.mjs +2 -1
- package/esm/database/seeds/seeders.manager.mjs.map +1 -1
- package/esm/database/seeds/types.d.mts +7 -8
- package/esm/database/seeds/types.d.mts.map +1 -1
- package/esm/database/utils.d.mts +4 -5
- package/esm/database/utils.d.mts.map +1 -1
- package/esm/dev-server/app-module-registry.mjs +1 -1
- package/esm/dev-server/create-worker.mjs +5 -3
- package/esm/dev-server/create-worker.mjs.map +1 -1
- package/esm/dev-server/dependency-graph.d.mts +1 -3
- 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/extract-translation-keys.mjs +16 -17
- package/esm/dev-server/extract-translation-keys.mjs.map +1 -1
- package/esm/dev-server/file-manager.d.mts +3 -7
- package/esm/dev-server/file-manager.d.mts.map +1 -1
- package/esm/dev-server/file-operations.d.mts +1 -3
- package/esm/dev-server/file-operations.d.mts.map +1 -1
- package/esm/dev-server/files-watcher.mjs +12 -11
- package/esm/dev-server/files-watcher.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/typescript-health-checker.mjs +36 -115
- 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 +5 -5
- 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 +2 -2
- package/esm/dev-server/health-checker/file-health-result.d.mts.map +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs +1 -0
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
- package/esm/dev-server/health-checker/oxlint-runner.mjs +6 -5
- package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -1
- package/esm/dev-server/health-checker/workers/eslint-health.worker.d.mts +1 -1
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.d.mts +1 -1
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs +40 -174
- package/esm/dev-server/health-checker/workers/ts-health.worker.mjs.map +1 -1
- package/esm/dev-server/loader/hook-thread.d.mts +4 -8
- package/esm/dev-server/loader/hook-thread.d.mts.map +1 -1
- package/esm/dev-server/loader/load-hook.d.mts +10 -6
- package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/load-hook.mjs +4 -3
- package/esm/dev-server/loader/load-hook.mjs.map +1 -1
- package/esm/dev-server/loader/own-resolver.mjs +1 -1
- package/esm/dev-server/loader/register-loader.mjs +3 -2
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-hook.d.mts +2 -2
- package/esm/dev-server/loader/resolve-hook.d.mts.map +1 -1
- package/esm/dev-server/loader/resolve-hook.mjs +2 -1
- package/esm/dev-server/loader/resolve-hook.mjs.map +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs +2 -1
- package/esm/dev-server/loader/transpile-cache.mjs.map +1 -1
- package/esm/dev-server/manifest-manager.d.mts +1 -3
- package/esm/dev-server/manifest-manager.d.mts.map +1 -1
- package/esm/dev-server/model-module-registry.mjs +3 -3
- package/esm/dev-server/model-module-registry.mjs.map +1 -1
- package/esm/dev-server/model-resource-typings.mjs +40 -47
- package/esm/dev-server/model-resource-typings.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +2 -2
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/package-json-manager.mjs +1 -1
- package/esm/dev-server/parse-imports.mjs +6 -38
- package/esm/dev-server/parse-imports.mjs.map +1 -1
- package/esm/dev-server/read-config-ast.mjs +3 -33
- package/esm/dev-server/read-config-ast.mjs.map +1 -1
- package/esm/dev-server/ready-block.mjs +1 -1
- package/esm/dev-server/shortcuts.mjs +1 -1
- package/esm/dev-server/special-files-collector.d.mts +2 -4
- package/esm/dev-server/special-files-collector.d.mts.map +1 -1
- package/esm/dev-server/supervisor.mjs +1 -1
- package/esm/dev-server/tsconfig-manager.mjs +3 -3
- package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
- package/esm/dev-server/type-generator.mjs +28 -35
- package/esm/dev-server/type-generator.mjs.map +1 -1
- package/esm/dev-server/types.d.mts +3 -4
- package/esm/dev-server/types.d.mts.map +1 -1
- package/esm/dev-server/update-check-cache.mjs +2 -2
- package/esm/dev-server/update-check-cache.mjs.map +1 -1
- package/esm/encryption/encrypt.d.mts +2 -3
- package/esm/encryption/encrypt.d.mts.map +1 -1
- package/esm/encryption/hash.d.mts +1 -2
- package/esm/encryption/hash.d.mts.map +1 -1
- package/esm/encryption/index.mjs +1 -1
- package/esm/encryption/password.d.mts +2 -3
- package/esm/encryption/password.d.mts.map +1 -1
- package/esm/encryption/types.d.mts +2 -3
- package/esm/encryption/types.d.mts.map +1 -1
- package/esm/errors/error-codes.d.mts +29 -22
- package/esm/errors/error-codes.d.mts.map +1 -1
- package/esm/errors/warlock-error.d.mts +1 -3
- package/esm/errors/warlock-error.d.mts.map +1 -1
- package/esm/generations/add-command.action.mjs +3 -2
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/features/bull-board.feature.mjs +2 -1
- package/esm/generations/features/bull-board.feature.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +2 -1
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs +16 -23
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
- package/esm/generations/features/sitemap.feature.mjs +2 -1
- package/esm/generations/features/sitemap.feature.mjs.map +1 -1
- package/esm/generations/generation-fs.mjs +1 -1
- package/esm/generations/generation-run.mjs +1 -1
- package/esm/generations/stubs.mjs +1 -1
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/boot-port-preflight.d.mts +4 -5
- package/esm/http/boot-port-preflight.d.mts.map +1 -1
- package/esm/http/boot-port-preflight.mjs +2 -2
- package/esm/http/boot-port-preflight.mjs.map +1 -1
- package/esm/http/bounded-stream-queue.d.mts +4 -4
- package/esm/http/bounded-stream-queue.d.mts.map +1 -1
- package/esm/http/bounded-stream-queue.mjs +1 -1
- package/esm/http/bounded-stream-queue.mjs.map +1 -1
- package/esm/http/build-cors-options.mjs +2 -2
- package/esm/http/build-cors-options.mjs.map +1 -1
- package/esm/http/build-rate-limit-options.d.mts +2 -3
- package/esm/http/build-rate-limit-options.d.mts.map +1 -1
- package/esm/http/build-rate-limit-options.mjs +1 -1
- package/esm/http/build-rate-limit-options.mjs.map +1 -1
- package/esm/http/conditional-request.d.mts +14 -13
- package/esm/http/conditional-request.d.mts.map +1 -1
- package/esm/http/config.d.mts +2 -4
- package/esm/http/config.d.mts.map +1 -1
- package/esm/http/config.mjs +2 -2
- package/esm/http/config.mjs.map +1 -1
- package/esm/http/context/request-context.d.mts +6 -7
- package/esm/http/context/request-context.d.mts.map +1 -1
- package/esm/http/context/request-memo.d.mts +1 -2
- package/esm/http/context/request-memo.d.mts.map +1 -1
- package/esm/http/createHttpApplication.d.mts +2 -3
- package/esm/http/createHttpApplication.d.mts.map +1 -1
- package/esm/http/createHttpApplication.mjs +2 -2
- package/esm/http/createHttpApplication.mjs.map +1 -1
- package/esm/http/csp.d.mts +10 -12
- package/esm/http/csp.d.mts.map +1 -1
- package/esm/http/csp.mjs +2 -2
- package/esm/http/csp.mjs.map +1 -1
- package/esm/http/csrf-default-guard.d.mts +2 -4
- 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 +7 -9
- package/esm/http/csrf-origin-policy.d.mts.map +1 -1
- package/esm/http/csrf-origin-policy.mjs +2 -2
- package/esm/http/csrf-origin-policy.mjs.map +1 -1
- package/esm/http/database/RequestLog.d.mts +2 -3
- package/esm/http/database/RequestLog.d.mts.map +1 -1
- package/esm/http/error-codes.d.mts +1 -2
- package/esm/http/error-codes.d.mts.map +1 -1
- package/esm/http/error-mapper.d.mts +2 -4
- package/esm/http/error-mapper.d.mts.map +1 -1
- package/esm/http/error-mapper.mjs +2 -2
- package/esm/http/error-mapper.mjs.map +1 -1
- package/esm/http/errors/errors.d.mts +28 -29
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/escape-header-value.d.mts +1 -2
- package/esm/http/escape-header-value.d.mts.map +1 -1
- package/esm/http/events.d.mts +2 -4
- package/esm/http/events.d.mts.map +1 -1
- package/esm/http/health.d.mts +4 -4
- package/esm/http/health.d.mts.map +1 -1
- package/esm/http/index.d.mts +4 -1
- package/esm/http/index.mjs +1 -1
- package/esm/http/middleware/cache-response-middleware.d.mts +2 -4
- package/esm/http/middleware/cache-response-middleware.d.mts.map +1 -1
- package/esm/http/middleware/concurrency-limit.middleware.d.mts +3 -3
- package/esm/http/middleware/concurrency-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/idempotency.middleware.d.mts +3 -3
- package/esm/http/middleware/idempotency.middleware.d.mts.map +1 -1
- package/esm/http/middleware/idempotency.middleware.mjs +6 -6
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/middleware/index.d.mts +3 -1
- package/esm/http/middleware/index.mjs +1 -1
- package/esm/http/middleware/inject-request-context.d.mts +2 -4
- package/esm/http/middleware/inject-request-context.d.mts.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +3 -3
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/middleware/ip-filter.middleware.d.mts +3 -3
- package/esm/http/middleware/ip-filter.middleware.d.mts.map +1 -1
- package/esm/http/middleware/maintenance.middleware.d.mts +3 -3
- package/esm/http/middleware/maintenance.middleware.d.mts.map +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs +4 -4
- package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
- package/esm/http/middleware/max-body-size.middleware.d.mts +2 -2
- package/esm/http/middleware/max-body-size.middleware.d.mts.map +1 -1
- package/esm/http/middleware/middleware-list.d.mts +1 -3
- package/esm/http/middleware/middleware-list.d.mts.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.d.mts +3 -3
- package/esm/http/middleware/rate-limit.middleware.d.mts.map +1 -1
- package/esm/http/middleware/rate-limit.middleware.mjs +2 -2
- package/esm/http/middleware/rate-limit.middleware.mjs.map +1 -1
- package/esm/http/middleware/utils/cidr-match.d.mts +2 -3
- package/esm/http/middleware/utils/cidr-match.d.mts.map +1 -1
- package/esm/http/middleware/utils/idempotency-key.d.mts +3 -5
- package/esm/http/middleware/utils/idempotency-key.d.mts.map +1 -1
- package/esm/http/middleware/utils/index.d.mts +2 -1
- package/esm/http/middleware/utils/parse-size.d.mts +1 -2
- package/esm/http/middleware/utils/parse-size.d.mts.map +1 -1
- package/esm/http/middleware/utils/parse-size.mjs +2 -2
- package/esm/http/middleware/utils/parse-size.mjs.map +1 -1
- package/esm/http/plugins.d.mts +2 -4
- package/esm/http/plugins.d.mts.map +1 -1
- package/esm/http/plugins.mjs +10 -10
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/port-preflight.d.mts +3 -4
- package/esm/http/port-preflight.d.mts.map +1 -1
- package/esm/http/rate-limit-cache-store.mjs +4 -3
- package/esm/http/rate-limit-cache-store.mjs.map +1 -1
- package/esm/http/ready-report.d.mts +15 -10
- package/esm/http/ready-report.d.mts.map +1 -1
- package/esm/http/request-controller.d.mts +1 -3
- package/esm/http/request-controller.d.mts.map +1 -1
- package/esm/http/request-log-snapshot.d.mts +20 -16
- package/esm/http/request-log-snapshot.d.mts.map +1 -1
- package/esm/http/request-log-snapshot.mjs +3 -3
- package/esm/http/request-log-snapshot.mjs.map +1 -1
- package/esm/http/request.d.mts +8 -7
- package/esm/http/request.d.mts.map +1 -1
- package/esm/http/request.mjs +8 -7
- package/esm/http/request.mjs.map +1 -1
- package/esm/http/response.d.mts +12 -11
- package/esm/http/response.d.mts.map +1 -1
- package/esm/http/response.mjs +7 -7
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/safe-redirect.d.mts +3 -4
- package/esm/http/safe-redirect.d.mts.map +1 -1
- package/esm/http/serialized.d.mts +12 -13
- package/esm/http/serialized.d.mts.map +1 -1
- package/esm/http/server-rebuilt.d.mts +3 -5
- package/esm/http/server-rebuilt.d.mts.map +1 -1
- package/esm/http/server.d.mts +9 -9
- package/esm/http/server.d.mts.map +1 -1
- package/esm/http/server.mjs +4 -4
- package/esm/http/server.mjs.map +1 -1
- package/esm/http/stream-react-response.d.mts +7 -7
- package/esm/http/stream-react-response.d.mts.map +1 -1
- package/esm/http/tracing/index.mjs +1 -1
- package/esm/http/tracing/trace-id.d.mts +2 -3
- package/esm/http/tracing/trace-id.d.mts.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.d.mts +10 -11
- package/esm/http/tracing/tracing-dispatcher.d.mts.map +1 -1
- package/esm/http/tracing/tracing-dispatcher.mjs +2 -2
- package/esm/http/tracing/tracing-dispatcher.mjs.map +1 -1
- package/esm/http/tracing/tracing.type.d.mts +11 -9
- package/esm/http/tracing/tracing.type.d.mts.map +1 -1
- package/esm/http/types.d.mts +49 -43
- package/esm/http/types.d.mts.map +1 -1
- package/esm/http/uploaded-file.d.mts +6 -5
- package/esm/http/uploaded-file.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts +6 -6
- package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.mjs +1 -1
- package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
- package/esm/http/uploads/image-variant-cache-entries.mjs +1 -1
- package/esm/http/uploads/image-variant-cache.mjs +8 -8
- package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
- package/esm/http/uploads/image-variant-types.d.mts +7 -9
- package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts +1 -2
- package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
- package/esm/http/uploads/index.d.mts +2 -1
- package/esm/http/uploads/index.mjs +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 +2 -4
- package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/resolve-image-variant.d.mts +3 -5
- package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
- package/esm/http/uploads/resolve-image-variants-config.mjs +4 -4
- package/esm/http/uploads/resolve-image-variants-config.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/trim-image-variant-cache.mjs +3 -3
- package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.d.mts +6 -5
- package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.mjs +2 -1
- package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
- package/esm/http/uploads/variant-cache-key.mjs +1 -1
- package/esm/http/uploads-config.d.mts +2 -4
- package/esm/http/uploads-config.d.mts.map +1 -1
- package/esm/http/uploads-types.d.mts +19 -17
- package/esm/http/uploads-types.d.mts.map +1 -1
- package/esm/http/xmlable.d.mts +1 -2
- package/esm/http/xmlable.d.mts.map +1 -1
- package/esm/image/image.d.mts +6 -7
- package/esm/image/image.d.mts.map +1 -1
- package/esm/image/image.mjs.map +1 -1
- package/esm/image/index.d.mts +2 -1
- package/esm/image/index.mjs +1 -1
- package/esm/index.d.mts +21 -0
- package/esm/loader/app-module-importer.d.mts +1 -2
- package/esm/loader/app-module-importer.d.mts.map +1 -1
- package/esm/localization/index.mjs +1 -1
- package/esm/localization/parse-locale-dictionary.d.mts +4 -5
- package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/parse-locale-dictionary.mjs +1 -1
- package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
- package/esm/localization/register-locale-dictionary.d.mts +3 -4
- package/esm/localization/register-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/register-locale-dictionary.mjs +2 -2
- package/esm/localization/register-locale-dictionary.mjs.map +1 -1
- package/esm/logger/fatal-visibility.d.mts +1 -2
- package/esm/logger/fatal-visibility.d.mts.map +1 -1
- package/esm/logger/index.d.mts +2 -1
- package/esm/logger/index.mjs +1 -1
- package/esm/logger/logger.d.mts +1 -3
- package/esm/logger/logger.d.mts.map +1 -1
- package/esm/logger/types.d.mts +2 -3
- package/esm/logger/types.d.mts.map +1 -1
- package/esm/mail/config.d.mts +12 -14
- package/esm/mail/config.d.mts.map +1 -1
- package/esm/mail/events.d.mts +4 -6
- package/esm/mail/events.d.mts.map +1 -1
- package/esm/mail/index.d.mts +2 -1
- package/esm/mail/index.mjs +1 -1
- package/esm/mail/mail.d.mts +1 -3
- package/esm/mail/mail.d.mts.map +1 -1
- package/esm/mail/mailer-pool.d.mts +5 -7
- package/esm/mail/mailer-pool.d.mts.map +1 -1
- package/esm/mail/react-mail.d.mts +1 -3
- package/esm/mail/react-mail.d.mts.map +1 -1
- package/esm/mail/send-mail.d.mts +1 -3
- package/esm/mail/send-mail.d.mts.map +1 -1
- package/esm/mail/send-mail.mjs +2 -1
- package/esm/mail/send-mail.mjs.map +1 -1
- package/esm/mail/test-mailbox.d.mts +11 -13
- package/esm/mail/test-mailbox.d.mts.map +1 -1
- package/esm/mail/types.d.mts +17 -18
- package/esm/mail/types.d.mts.map +1 -1
- package/esm/manifest/manifest-manager.mjs +1 -1
- package/esm/openapi/build-openapi-document.d.mts +2 -4
- package/esm/openapi/build-openapi-document.d.mts.map +1 -1
- package/esm/openapi/cast-schema.mjs +1 -1
- package/esm/openapi/development-openapi-provider.d.mts +5 -6
- package/esm/openapi/development-openapi-provider.d.mts.map +1 -1
- package/esm/openapi/index.d.mts +3 -1
- package/esm/openapi/index.mjs +1 -1
- package/esm/openapi/openapi-child-output.mjs +2 -2
- package/esm/openapi/openapi-child-output.mjs.map +1 -1
- package/esm/openapi/postman/build-request-url.mjs +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts +1 -3
- package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
- package/esm/openapi/postman/index.d.mts +2 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts +3 -5
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
- package/esm/openapi/postman/postman-types.d.mts +19 -18
- package/esm/openapi/postman/postman-types.d.mts.map +1 -1
- package/esm/openapi/postman/schema-refs.d.mts +1 -3
- package/esm/openapi/postman/schema-refs.d.mts.map +1 -1
- package/esm/openapi/postman/uuid-v5.mjs +1 -1
- package/esm/openapi/schema-registry.d.mts +1 -1
- package/esm/openapi/security.mjs +1 -1
- package/esm/openapi/types.d.mts +23 -21
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/assert-generated-imports.mjs +1 -1
- package/esm/production/build-contributions.mjs +1 -1
- package/esm/production/bundle-framework-dependencies.mjs +1 -1
- package/esm/production/dist-build-manifest.mjs +1 -1
- package/esm/production/esbuild-plugins.mjs.map +1 -1
- package/esm/production/esbuild-preflight.mjs +1 -1
- package/esm/production/production-builder.mjs +2 -1
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/production-supervisor.mjs +1 -1
- package/esm/production/registration-child-runner.mjs +4 -3
- package/esm/production/registration-child-runner.mjs.map +1 -1
- package/esm/production/resolve-build-config.d.mts +4 -4
- package/esm/production/resolve-build-config.d.mts.map +1 -1
- package/esm/production/resolve-build-config.mjs +1 -1
- package/esm/production/route-registration-child.d.mts +1 -1
- package/esm/production/route-registration-child.mjs +8 -7
- package/esm/production/route-registration-child.mjs.map +1 -1
- package/esm/production/tsconfig-path-aliases.mjs +1 -1
- package/esm/react/index.d.mts +1 -3
- package/esm/react/index.d.mts.map +1 -1
- package/esm/react/index.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts +3 -4
- package/esm/repositories/adapters/cascade/cascade-adapter.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts +2 -3
- package/esm/repositories/adapters/cascade/cascade-query-builder.d.mts.map +1 -1
- package/esm/repositories/adapters/cascade/filter-applicator.mjs +10 -9
- package/esm/repositories/adapters/cascade/filter-applicator.mjs.map +1 -1
- package/esm/repositories/adapters/cascade/index.d.mts +2 -1
- package/esm/repositories/adapters/cascade/index.mjs +1 -1
- package/esm/repositories/contracts/index.d.mts +2 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts +4 -6
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/repository-adapter.contract.d.mts +1 -3
- package/esm/repositories/contracts/repository-adapter.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/types.d.mts +23 -25
- package/esm/repositories/contracts/types.d.mts.map +1 -1
- package/esm/repositories/index.d.mts +4 -1
- package/esm/repositories/index.mjs +1 -1
- package/esm/repositories/repository.manager.d.mts +2 -3
- package/esm/repositories/repository.manager.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs +2 -2
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/resource/define-resource.d.mts +3 -5
- package/esm/resource/define-resource.d.mts.map +1 -1
- package/esm/resource/index.d.mts +2 -1
- package/esm/resource/index.mjs +1 -1
- package/esm/resource/nullable-resource.d.mts +5 -7
- package/esm/resource/nullable-resource.d.mts.map +1 -1
- package/esm/resource/register-resource.d.mts +1 -3
- package/esm/resource/register-resource.d.mts.map +1 -1
- package/esm/resource/resource-field-builder.d.mts +1 -3
- package/esm/resource/resource-field-builder.d.mts.map +1 -1
- package/esm/resource/resource.d.mts +3 -5
- package/esm/resource/resource.d.mts.map +1 -1
- package/esm/resource/resource.mjs +4 -2
- package/esm/resource/resource.mjs.map +1 -1
- package/esm/resource/types.d.mts +21 -21
- package/esm/resource/types.d.mts.map +1 -1
- package/esm/restful/index.d.mts +2 -1
- package/esm/restful/index.mjs +1 -1
- package/esm/restful/restful.d.mts +12 -32
- package/esm/restful/restful.d.mts.map +1 -1
- package/esm/router/index.d.mts +2 -1
- package/esm/router/index.mjs +1 -1
- package/esm/router/named-api-routes-with-responses.mjs +2 -1
- package/esm/router/named-api-routes-with-responses.mjs.map +1 -1
- package/esm/router/normalize-request-path.d.mts +1 -2
- package/esm/router/normalize-request-path.d.mts.map +1 -1
- package/esm/router/normalize-route-path.d.mts +1 -2
- package/esm/router/normalize-route-path.d.mts.map +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts +15 -13
- package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
- package/esm/router/resolve-route-rate-limit.mjs +3 -3
- package/esm/router/resolve-route-rate-limit.mjs.map +1 -1
- package/esm/router/route-builder.d.mts +1 -3
- package/esm/router/route-builder.d.mts.map +1 -1
- package/esm/router/route-guard-names.mjs +1 -1
- package/esm/router/route-guard-names.mjs.map +1 -1
- package/esm/router/route-name-method-suffix.d.mts +2 -3
- package/esm/router/route-name-method-suffix.d.mts.map +1 -1
- package/esm/router/route-name-taken-error.d.mts +1 -3
- package/esm/router/route-name-taken-error.d.mts.map +1 -1
- package/esm/router/route-registry.d.mts +1 -3
- package/esm/router/route-registry.d.mts.map +1 -1
- package/esm/router/router.d.mts +2 -4
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +8 -6
- package/esm/router/router.mjs.map +1 -1
- package/esm/router/types.d.mts +25 -26
- package/esm/router/types.d.mts.map +1 -1
- package/esm/router/unguarded-route-diagnostics.d.mts +6 -8
- package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -1
- package/esm/socket/index.d.mts +2 -1
- package/esm/socket/index.mjs +1 -1
- package/esm/socket/types.d.mts +2 -4
- package/esm/socket/types.d.mts.map +1 -1
- package/esm/socket/utils.d.mts +1 -3
- package/esm/socket/utils.d.mts.map +1 -1
- package/esm/storage/config.d.mts +4 -6
- package/esm/storage/config.d.mts.map +1 -1
- package/esm/storage/context/storage-driver-context.d.mts +3 -4
- package/esm/storage/context/storage-driver-context.d.mts.map +1 -1
- package/esm/storage/drivers/cloud-driver.d.mts +2 -4
- package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
- package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
- package/esm/storage/drivers/do-spaces-driver.d.mts +1 -3
- package/esm/storage/drivers/do-spaces-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.d.mts +2 -3
- package/esm/storage/drivers/local-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.mjs +8 -3
- package/esm/storage/drivers/local-driver.mjs.map +1 -1
- package/esm/storage/drivers/r2-driver.d.mts +1 -3
- package/esm/storage/drivers/r2-driver.d.mts.map +1 -1
- package/esm/storage/drivers/s3-driver.d.mts +1 -3
- package/esm/storage/drivers/s3-driver.d.mts.map +1 -1
- package/esm/storage/index.d.mts +2 -1
- package/esm/storage/index.mjs +1 -1
- package/esm/storage/local-disk-roots.mjs +2 -2
- package/esm/storage/local-disk-roots.mjs.map +1 -1
- package/esm/storage/scoped-storage.d.mts +2 -3
- package/esm/storage/scoped-storage.d.mts.map +1 -1
- package/esm/storage/storage-file.d.mts +1 -3
- package/esm/storage/storage-file.d.mts.map +1 -1
- package/esm/storage/storage.d.mts +3 -4
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/types.d.mts +36 -36
- package/esm/storage/types.d.mts.map +1 -1
- package/esm/storage/utils/classify-ip-address.d.mts +1 -2
- package/esm/storage/utils/classify-ip-address.d.mts.map +1 -1
- package/esm/storage/utils/contain-path.d.mts +1 -2
- package/esm/storage/utils/contain-path.d.mts.map +1 -1
- package/esm/storage/utils/mime.d.mts +2 -3
- package/esm/storage/utils/mime.d.mts.map +1 -1
- package/esm/storage/utils/safe-fetch.d.mts +6 -6
- package/esm/storage/utils/safe-fetch.d.mts.map +1 -1
- package/esm/storage/utils/safe-fetch.mjs +3 -3
- package/esm/storage/utils/safe-fetch.mjs.map +1 -1
- package/esm/storage/utils/storage-capability-error.d.mts +1 -3
- package/esm/storage/utils/storage-capability-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-error.d.mts +2 -3
- package/esm/storage/utils/storage-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts +1 -2
- package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
- package/esm/tests/authenticated-test-client.d.mts +5 -6
- package/esm/tests/authenticated-test-client.d.mts.map +1 -1
- package/esm/tests/factories.d.mts +38 -23
- package/esm/tests/factories.d.mts.map +1 -1
- package/esm/tests/fakes/cache-fake.d.mts +14 -9
- package/esm/tests/fakes/cache-fake.d.mts.map +1 -1
- package/esm/tests/fakes/clock-fake.d.mts +13 -8
- package/esm/tests/fakes/clock-fake.d.mts.map +1 -1
- package/esm/tests/fakes/fake-assertion-error.d.mts +2 -3
- package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -1
- package/esm/tests/fakes/ids-fake.d.mts +5 -4
- package/esm/tests/fakes/ids-fake.d.mts.map +1 -1
- package/esm/tests/fakes/index.d.mts +2 -1
- package/esm/tests/fakes/index.mjs +1 -1
- package/esm/tests/fakes/mail-fake.d.mts +21 -13
- package/esm/tests/fakes/mail-fake.d.mts.map +1 -1
- package/esm/tests/fakes/queue-fake.d.mts +21 -13
- package/esm/tests/fakes/queue-fake.d.mts.map +1 -1
- package/esm/tests/fakes/storage-fake.d.mts +12 -8
- package/esm/tests/fakes/storage-fake.d.mts.map +1 -1
- package/esm/tests/fakes/storage-fake.mjs +1 -1
- package/esm/tests/fakes/test-fakes.d.mts +8 -9
- package/esm/tests/fakes/test-fakes.d.mts.map +1 -1
- package/esm/tests/fakes/test-fakes.mjs +1 -1
- package/esm/tests/fakes/test-fakes.mjs.map +1 -1
- package/esm/tests/index.d.mts +1 -0
- package/esm/tests/snapshot-response.d.mts +4 -5
- package/esm/tests/snapshot-response.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.d.mts +4 -6
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +5 -5
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-connectors-selection.d.mts +2 -2
- package/esm/tests/test-connectors-selection.d.mts.map +1 -1
- package/esm/tests/test-connectors-selection.mjs +1 -1
- package/esm/tests/test-helpers.d.mts +11 -12
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-http-server.d.mts +14 -10
- package/esm/tests/test-http-server.d.mts.map +1 -1
- package/esm/tests/test-lifecycle-state.mjs +1 -1
- package/esm/tests/vitest-setup.d.mts +6 -7
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tooling/agents-md/agents-md-markers.d.mts +4 -5
- package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -1
- package/esm/tooling/agents-md/agents-md-markers.mjs +2 -1
- package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -1
- package/esm/tooling/agents-md/agents-md-refresher.d.mts +19 -12
- package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -1
- package/esm/tooling/agents-md/installed-skills.d.mts +13 -9
- package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -1
- package/esm/tooling/agents-md/render-agents-md.d.mts +8 -7
- package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -1
- package/esm/tooling/agents-md/render-agents-md.mjs +2 -2
- package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -1
- package/esm/tooling/agents-md/write-agents-md.d.mts +17 -12
- package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -1
- package/esm/tooling/board/board-message.d.mts +4 -6
- package/esm/tooling/board/board-message.d.mts.map +1 -1
- package/esm/tooling/board/board.d.mts +50 -38
- package/esm/tooling/board/board.d.mts.map +1 -1
- package/esm/tooling/board/board.mjs +4 -3
- package/esm/tooling/board/board.mjs.map +1 -1
- package/esm/tooling/board/board.types.d.mts +32 -23
- package/esm/tooling/board/board.types.d.mts.map +1 -1
- package/esm/tooling/check/changed-files.d.mts +4 -6
- package/esm/tooling/check/changed-files.d.mts.map +1 -1
- package/esm/tooling/check/changed-files.mjs +2 -2
- package/esm/tooling/check/changed-files.mjs.map +1 -1
- package/esm/tooling/check/check-report.types.d.mts +22 -17
- package/esm/tooling/check/check-report.types.d.mts.map +1 -1
- package/esm/tooling/check/code-style-conventions.mjs +25 -25
- package/esm/tooling/check/code-style-conventions.mjs.map +1 -1
- package/esm/tooling/check/conventions-step.d.mts +4 -6
- package/esm/tooling/check/conventions-step.d.mts.map +1 -1
- package/esm/tooling/check/conventions-step.mjs +7 -18
- package/esm/tooling/check/conventions-step.mjs.map +1 -1
- package/esm/tooling/check/environment-step.d.mts +2 -4
- package/esm/tooling/check/environment-step.d.mts.map +1 -1
- package/esm/tooling/check/environment-step.mjs +1 -1
- package/esm/tooling/check/index.mjs +1 -1
- package/esm/tooling/check/lint-step.d.mts +4 -5
- package/esm/tooling/check/lint-step.d.mts.map +1 -1
- package/esm/tooling/check/lint-step.mjs +2 -1
- package/esm/tooling/check/lint-step.mjs.map +1 -1
- package/esm/tooling/check/request-input.mjs +15 -15
- package/esm/tooling/check/request-input.mjs.map +1 -1
- package/esm/tooling/check/run-check.d.mts +22 -14
- package/esm/tooling/check/run-check.d.mts.map +1 -1
- package/esm/tooling/check/run-tests.d.mts +22 -15
- package/esm/tooling/check/run-tests.d.mts.map +1 -1
- package/esm/tooling/check/security-conventions.mjs +133 -131
- package/esm/tooling/check/security-conventions.mjs.map +1 -1
- package/esm/tooling/check/source-ast.mjs +92 -132
- package/esm/tooling/check/source-ast.mjs.map +1 -1
- package/esm/tooling/check/tests-step.d.mts +7 -8
- package/esm/tooling/check/tests-step.d.mts.map +1 -1
- package/esm/tooling/check/tests-step.mjs +3 -3
- package/esm/tooling/check/tests-step.mjs.map +1 -1
- package/esm/tooling/dev-state/dev-server-state.d.mts +17 -13
- package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -1
- package/esm/tooling/devtools/devtools-client.d.mts +29 -20
- package/esm/tooling/devtools/devtools-client.d.mts.map +1 -1
- package/esm/tooling/generate/generation.d.mts +34 -22
- package/esm/tooling/generate/generation.d.mts.map +1 -1
- package/esm/tooling/generate/generation.mjs +9 -5
- package/esm/tooling/generate/generation.mjs.map +1 -1
- package/esm/tooling/generate/generator-spec.d.mts +9 -9
- package/esm/tooling/generate/generator-spec.d.mts.map +1 -1
- package/esm/tooling/generate/index.mjs +1 -1
- package/esm/tooling/generate/project-files.mjs +3 -3
- package/esm/tooling/generate/project-files.mjs.map +1 -1
- package/esm/tooling/generate/run-cli.d.mts +14 -11
- package/esm/tooling/generate/run-cli.d.mts.map +1 -1
- package/esm/tooling/generate/run-cli.mjs +2 -2
- package/esm/tooling/generate/run-cli.mjs.map +1 -1
- package/esm/tooling/generate/unified-diff.d.mts +10 -7
- package/esm/tooling/generate/unified-diff.d.mts.map +1 -1
- package/esm/tooling/index.d.mts +1 -0
- package/esm/tooling/inspect/boot-for-inspect.d.mts +7 -7
- package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -1
- package/esm/tooling/inspect/collect-config.mjs +3 -3
- package/esm/tooling/inspect/collect-config.mjs.map +1 -1
- package/esm/tooling/inspect/collect-models.d.mts +4 -3
- package/esm/tooling/inspect/collect-models.d.mts.map +1 -1
- package/esm/tooling/inspect/collect-models.mjs +1 -1
- package/esm/tooling/inspect/collect-packages.d.mts +1 -2
- package/esm/tooling/inspect/collect-packages.d.mts.map +1 -1
- package/esm/tooling/inspect/collect-pages.mjs +10 -10
- package/esm/tooling/inspect/collect-pages.mjs.map +1 -1
- package/esm/tooling/inspect/collect-routes.mjs +1 -1
- package/esm/tooling/inspect/event-recorder.d.mts +7 -7
- package/esm/tooling/inspect/event-recorder.d.mts.map +1 -1
- package/esm/tooling/inspect/index.d.mts +2 -1
- package/esm/tooling/inspect/index.mjs +1 -1
- package/esm/tooling/inspect/inspect-app.d.mts +25 -16
- package/esm/tooling/inspect/inspect-app.d.mts.map +1 -1
- package/esm/tooling/inspect/inspect-report.schema.d.mts +1 -2
- package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -1
- package/esm/tooling/inspect/inspect-report.types.d.mts +86 -54
- package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -1
- package/esm/tooling/mcp/create-mcp-context.d.mts +11 -8
- package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -1
- package/esm/tooling/mcp/db-schema.d.mts +10 -9
- package/esm/tooling/mcp/db-schema.d.mts.map +1 -1
- package/esm/tooling/mcp/docs-search.d.mts +20 -15
- package/esm/tooling/mcp/docs-search.d.mts.map +1 -1
- package/esm/tooling/mcp/index.mjs +1 -1
- package/esm/tooling/mcp/load-ai-tools.d.mts +7 -8
- package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -1
- package/esm/tooling/mcp/load-ai-tools.mjs +2 -1
- package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -1
- package/esm/tooling/mcp/mcp-tools.d.mts +29 -19
- package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -1
- package/esm/tooling/mcp/mcp-tools.mjs +3 -2
- package/esm/tooling/mcp/mcp-tools.mjs.map +1 -1
- package/esm/tooling/mcp/start-mcp-server.d.mts +24 -17
- package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -1
- package/esm/tooling/mcp/start-mcp-server.mjs +1 -1
- package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -1
- package/esm/tooling/mcp/tool-input.d.mts +7 -7
- package/esm/tooling/mcp/tool-input.d.mts.map +1 -1
- package/esm/tooling/problem.d.mts +27 -17
- package/esm/tooling/problem.d.mts.map +1 -1
- package/esm/tooling/syntax/ast.mjs +230 -0
- package/esm/tooling/syntax/ast.mjs.map +1 -0
- package/esm/tooling/syntax/imports.mjs +34 -0
- package/esm/tooling/syntax/imports.mjs.map +1 -0
- package/esm/tooling/trace/trace-report.types.d.mts +36 -22
- package/esm/tooling/trace/trace-report.types.d.mts.map +1 -1
- package/esm/tooling/trace/trace-request.d.mts +27 -20
- package/esm/tooling/trace/trace-request.d.mts.map +1 -1
- package/esm/tooling/trace/trace-request.mjs +2 -2
- package/esm/tooling/trace/trace-request.mjs.map +1 -1
- package/esm/tooling/typecheck/index.mjs +1 -1
- package/esm/tooling/typecheck/run-typecheck.d.mts +15 -48
- package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -1
- package/esm/tooling/typecheck/run-typecheck.mjs +42 -105
- package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -1
- package/esm/tooling/typescript/compiler.d.mts +31 -0
- package/esm/tooling/typescript/compiler.d.mts.map +1 -0
- package/esm/tooling/typescript/compiler.mjs +120 -0
- package/esm/tooling/typescript/compiler.mjs.map +1 -0
- package/esm/updater/update-warlock-packages.mjs +3 -2
- package/esm/updater/update-warlock-packages.mjs.map +1 -1
- package/esm/upgrade/codemods/index.mjs +1 -1
- package/esm/upgrade/codemods/logger-sync-calls.mjs +1 -1
- package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -1
- package/esm/upgrade/codemods/request-log-snapshot.mjs +1 -1
- package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -1
- package/esm/upgrade/diff.mjs +1 -1
- package/esm/upgrade/diff.mjs.map +1 -1
- package/esm/upgrade/load-ts-morph.mjs +3 -2
- package/esm/upgrade/load-ts-morph.mjs.map +1 -1
- package/esm/upgrade/run-upgrade.mjs +1 -1
- package/esm/use-cases/index.d.mts +2 -1
- package/esm/use-cases/index.mjs +1 -1
- package/esm/use-cases/types.d.mts +116 -63
- package/esm/use-cases/types.d.mts.map +1 -1
- package/esm/use-cases/use-case-broadcast.d.mts +1 -3
- package/esm/use-cases/use-case-broadcast.d.mts.map +1 -1
- package/esm/use-cases/use-case-events.d.mts +3 -5
- package/esm/use-cases/use-case-events.d.mts.map +1 -1
- package/esm/use-cases/use-case-pipeline.d.mts +6 -6
- package/esm/use-cases/use-case-pipeline.d.mts.map +1 -1
- package/esm/use-cases/use-case.d.mts +2 -4
- package/esm/use-cases/use-case.d.mts.map +1 -1
- package/esm/use-cases/use-case.errors.d.mts +1 -3
- package/esm/use-cases/use-case.errors.d.mts.map +1 -1
- package/esm/use-cases/use-cases-registry.d.mts +8 -10
- package/esm/use-cases/use-cases-registry.d.mts.map +1 -1
- package/esm/utils/app-log.d.mts +1 -2
- package/esm/utils/app-log.d.mts.map +1 -1
- package/esm/utils/clock.d.mts +8 -6
- package/esm/utils/clock.d.mts.map +1 -1
- package/esm/utils/database-log.d.mts +3 -4
- package/esm/utils/database-log.d.mts.map +1 -1
- package/esm/utils/environment.d.mts +4 -5
- package/esm/utils/environment.d.mts.map +1 -1
- package/esm/utils/framework-vesion.mjs.map +1 -1
- package/esm/utils/get-localized.d.mts +2 -3
- package/esm/utils/get-localized.d.mts.map +1 -1
- package/esm/utils/ids.d.mts +9 -6
- package/esm/utils/ids.d.mts.map +1 -1
- package/esm/utils/index.d.mts +2 -1
- package/esm/utils/index.mjs +1 -1
- package/esm/utils/normalized-path.d.mts +1 -2
- package/esm/utils/normalized-path.d.mts.map +1 -1
- package/esm/utils/npm-registry.d.mts +1 -2
- package/esm/utils/npm-registry.d.mts.map +1 -1
- package/esm/utils/paths.d.mts +13 -14
- package/esm/utils/paths.d.mts.map +1 -1
- package/esm/utils/paths.mjs +2 -2
- package/esm/utils/paths.mjs.map +1 -1
- package/esm/utils/promise-all-object.d.mts +1 -2
- package/esm/utils/promise-all-object.d.mts.map +1 -1
- package/esm/utils/queue.d.mts +1 -2
- package/esm/utils/queue.d.mts.map +1 -1
- package/esm/utils/runtime.d.mts +11 -10
- package/esm/utils/runtime.d.mts.map +1 -1
- package/esm/utils/sleep.d.mts +1 -2
- package/esm/utils/sleep.d.mts.map +1 -1
- package/esm/utils/sluggable.d.mts +1 -3
- package/esm/utils/sluggable.d.mts.map +1 -1
- package/esm/utils/to-json.d.mts +1 -2
- package/esm/utils/to-json.d.mts.map +1 -1
- package/esm/utils/types.d.mts +1 -2
- package/esm/utils/types.d.mts.map +1 -1
- package/esm/utils/urls.d.mts +5 -6
- package/esm/utils/urls.d.mts.map +1 -1
- package/esm/utils/version-compare.d.mts +1 -2
- package/esm/utils/version-compare.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-id.d.mts +2 -3
- package/esm/validation/database/exists-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/exists-except-current-user.d.mts +2 -3
- package/esm/validation/database/exists-except-current-user.d.mts.map +1 -1
- package/esm/validation/database/index.d.mts +2 -1
- package/esm/validation/database/index.mjs +1 -1
- package/esm/validation/database/types.d.mts +14 -10
- package/esm/validation/database/types.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-id.d.mts +2 -3
- package/esm/validation/database/unique-except-current-id.d.mts.map +1 -1
- package/esm/validation/database/unique-except-current-user.d.mts +2 -3
- package/esm/validation/database/unique-except-current-user.d.mts.map +1 -1
- package/esm/validation/file/file.d.mts +4 -6
- package/esm/validation/file/file.d.mts.map +1 -1
- package/esm/validation/file/index.d.mts +2 -1
- package/esm/validation/file/index.mjs +1 -1
- package/esm/validation/index.d.mts +5 -1
- package/esm/validation/index.mjs +1 -1
- package/esm/validation/plugins/index.mjs +1 -1
- package/esm/validation/types.d.mts +6 -4
- package/esm/validation/types.d.mts.map +1 -1
- package/esm/validation/validateAll.mjs +2 -2
- package/esm/validation/validateAll.mjs.map +1 -1
- package/esm/validation/validation-failure-status.mjs +2 -2
- package/esm/validation/validation-failure-status.mjs.map +1 -1
- package/esm/validation/validators/file-validator.d.mts +2 -4
- package/esm/validation/validators/file-validator.d.mts.map +1 -1
- package/esm/validation/validators/index.d.mts +2 -1
- package/esm/validation/validators/index.mjs +1 -1
- package/esm/vite/lower-stage3-decorators.d.mts +2 -3
- package/esm/vite/lower-stage3-decorators.d.mts.map +1 -1
- package/esm/warlock-config/define-config.d.mts +1 -3
- package/esm/warlock-config/define-config.d.mts.map +1 -1
- package/esm/warlock-config/define-config.mjs +3 -2
- package/esm/warlock-config/define-config.mjs.map +1 -1
- package/esm/warlock-config/index.d.mts +2 -1
- package/esm/warlock-config/index.mjs +1 -1
- package/esm/warlock-config/types.d.mts +6 -5
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.d.mts +5 -7
- package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
- package/esm/warlock-config/warlock-config.manager.mjs +2 -1
- package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
- package/esm/warlock-config/warn-deprecated-config.mjs +1 -1
- package/llms-full.txt +55 -5
- package/package.json +17 -15
- package/skills/create-module/SKILL.md +7 -0
- package/skills/index.md +2 -0
- package/skills/report-framework-issue.md +154 -0
- package/skills/run-app/SKILL.md +6 -5
- package/skills/upgrade-from-5-29/SKILL.md +41 -0
- package/skills/warlock-check/SKILL.md +1 -0
- package/esm/tooling/check/index.d.mts +0 -8
- package/esm/tooling/typecheck/index.d.mts +0 -1
package/esm/http/types.d.mts
CHANGED
|
@@ -6,15 +6,15 @@ import { CspConfig } from "./csp.mjs";
|
|
|
6
6
|
import { HttpErrorMapper } from "./error-mapper.mjs";
|
|
7
7
|
import { HttpTracingConfig } from "./tracing/tracing.type.mjs";
|
|
8
8
|
import { Middleware } from "../router/types.mjs";
|
|
9
|
+
import "../router/index.mjs";
|
|
9
10
|
import { FastifyHttpOptions } from "fastify";
|
|
10
11
|
import { CookieSerializeOptions } from "@fastify/cookie";
|
|
11
12
|
import { FastifyCorsOptions } from "@fastify/cors";
|
|
12
13
|
import { Server } from "node:http";
|
|
13
14
|
import { SecureServerOptions } from "node:http2";
|
|
14
15
|
import React from "react";
|
|
15
|
-
|
|
16
16
|
//#region ../../packages/core/src/http/types.d.ts
|
|
17
|
-
type RequestEvent = "executingMiddleware" | "executedMiddleware" | "executingAction" | "executedAction";
|
|
17
|
+
export type RequestEvent = "executingMiddleware" | "executedMiddleware" | "executingAction" | "executedAction";
|
|
18
18
|
/**
|
|
19
19
|
* Private, server-only, per-request data bag — `request.locals`.
|
|
20
20
|
*
|
|
@@ -38,7 +38,7 @@ type RequestEvent = "executingMiddleware" | "executedMiddleware" | "executingAct
|
|
|
38
38
|
* }
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
interface RequestLocals {
|
|
41
|
+
export interface RequestLocals {
|
|
42
42
|
/**
|
|
43
43
|
* Whether this request has, at any point, been assigned a
|
|
44
44
|
* `decodedAccessToken` — set by its accessor in `request.ts`, never by
|
|
@@ -66,105 +66,105 @@ interface RequestLocals {
|
|
|
66
66
|
* `interface`, because nothing in core augments it — auth's own richer
|
|
67
67
|
* shape is simply assignable here.
|
|
68
68
|
*/
|
|
69
|
-
type DecodedAccessToken = {
|
|
69
|
+
export type DecodedAccessToken = {
|
|
70
70
|
userType?: string;
|
|
71
71
|
};
|
|
72
72
|
/**
|
|
73
73
|
* Allowed response type
|
|
74
74
|
*/
|
|
75
|
-
type ReturnedResponse =
|
|
75
|
+
export type ReturnedResponse =
|
|
76
76
|
/**
|
|
77
77
|
* Can be a response object
|
|
78
78
|
*/
|
|
79
|
-
Response
|
|
79
|
+
Response |
|
|
80
80
|
/**
|
|
81
81
|
* Or a promise returning a response object
|
|
82
82
|
*/
|
|
83
|
-
|
|
83
|
+
Promise<Response> |
|
|
84
84
|
/**
|
|
85
85
|
* Or an object
|
|
86
86
|
*/
|
|
87
|
-
|
|
87
|
+
Record<string, any> |
|
|
88
88
|
/**
|
|
89
89
|
* Or a promise returning an object
|
|
90
90
|
*/
|
|
91
|
-
|
|
91
|
+
Promise<Record<string, any>> |
|
|
92
92
|
/**
|
|
93
93
|
* Or an array
|
|
94
94
|
*/
|
|
95
|
-
|
|
95
|
+
any[] |
|
|
96
96
|
/**
|
|
97
97
|
* Or a promise returning an array
|
|
98
98
|
*/
|
|
99
|
-
|
|
99
|
+
Promise<any[]>;
|
|
100
100
|
/**
|
|
101
101
|
* Response Event Types
|
|
102
102
|
*/
|
|
103
|
-
type ResponseEvent =
|
|
103
|
+
export type ResponseEvent =
|
|
104
104
|
/**
|
|
105
105
|
* Triggered before sending the response
|
|
106
106
|
*/
|
|
107
|
-
"sending"
|
|
107
|
+
"sending" |
|
|
108
108
|
/**
|
|
109
109
|
* Triggered before sending json response
|
|
110
110
|
*/
|
|
111
|
-
|
|
111
|
+
"sendingJson" |
|
|
112
112
|
/**
|
|
113
113
|
* Triggered after sending success json response
|
|
114
114
|
*/
|
|
115
|
-
|
|
115
|
+
"sendingSuccessJson" |
|
|
116
116
|
/**
|
|
117
117
|
* Triggered after sending bad request json response
|
|
118
118
|
*/
|
|
119
|
-
|
|
119
|
+
"sendingBadRequestJson" |
|
|
120
120
|
/**
|
|
121
121
|
* Triggered after sending the response regardless of the response status code
|
|
122
122
|
*/
|
|
123
|
-
|
|
123
|
+
"sent" |
|
|
124
124
|
/**
|
|
125
125
|
* Triggered after sending the response if the response status code is 2xx
|
|
126
126
|
*/
|
|
127
|
-
|
|
127
|
+
"success" |
|
|
128
128
|
/**
|
|
129
129
|
* Triggered after sending the response if the response status code is 201
|
|
130
130
|
*/
|
|
131
|
-
|
|
131
|
+
"successCreate" |
|
|
132
132
|
/**
|
|
133
133
|
* Triggered after sending the response if the response status code is 400
|
|
134
134
|
*/
|
|
135
|
-
|
|
135
|
+
"badRequest" |
|
|
136
136
|
/**
|
|
137
137
|
* Triggered after sending the response if the response status code is 401
|
|
138
138
|
*/
|
|
139
|
-
|
|
139
|
+
"unauthorized" |
|
|
140
140
|
/**
|
|
141
141
|
* Triggered after sending the response if the response status code is 403
|
|
142
142
|
*/
|
|
143
|
-
|
|
143
|
+
"forbidden" |
|
|
144
144
|
/**
|
|
145
145
|
* Triggered after sending the response if the response status code is 404
|
|
146
146
|
*/
|
|
147
|
-
|
|
147
|
+
"notFound" |
|
|
148
148
|
/**
|
|
149
149
|
* Triggered after sending the response if the response status code is 413
|
|
150
150
|
*/
|
|
151
|
-
|
|
151
|
+
"contentTooLarge" |
|
|
152
152
|
/**
|
|
153
153
|
* Triggered after sending the response if the response status code is 429
|
|
154
154
|
*/
|
|
155
|
-
|
|
155
|
+
"throttled" |
|
|
156
156
|
/**
|
|
157
157
|
* Triggered after sending the response if the response status code is 500
|
|
158
158
|
*/
|
|
159
|
-
|
|
159
|
+
"serverError" |
|
|
160
160
|
/**
|
|
161
161
|
* Triggered after sending the response if the response status code is 4xx or 5xx
|
|
162
162
|
*/
|
|
163
|
-
|
|
163
|
+
"error";
|
|
164
164
|
/**
|
|
165
165
|
* Partial Middleware
|
|
166
166
|
*/
|
|
167
|
-
interface PartialMiddleware {
|
|
167
|
+
export interface PartialMiddleware {
|
|
168
168
|
/**
|
|
169
169
|
* Routes list
|
|
170
170
|
* @example routes: ["/users", "/posts"]
|
|
@@ -190,15 +190,16 @@ interface PartialMiddleware {
|
|
|
190
190
|
* `gracefulShutdown.forceCloseConnections`) have their own `http.*` keys;
|
|
191
191
|
* setting them here as well overrides those keys.
|
|
192
192
|
*/
|
|
193
|
-
type HttpServerOptions = Omit<FastifyHttpOptions<Server>, "http2"> & {
|
|
194
|
-
/** Enable HTTP/2 while retaining the framework's HTTP-compatible reply API. */
|
|
193
|
+
export type HttpServerOptions = Omit<FastifyHttpOptions<Server>, "http2"> & {
|
|
194
|
+
/** Enable HTTP/2 while retaining the framework's HTTP-compatible reply API. */
|
|
195
|
+
http2?: boolean;
|
|
195
196
|
https?: SecureServerOptions;
|
|
196
197
|
http2SessionTimeout?: number;
|
|
197
198
|
};
|
|
198
199
|
/**
|
|
199
200
|
* Http Configurations list
|
|
200
201
|
*/
|
|
201
|
-
interface HttpConfigurations {
|
|
202
|
+
export interface HttpConfigurations {
|
|
202
203
|
/**
|
|
203
204
|
* Options for the underlying Fastify server, applied when it is created.
|
|
204
205
|
*
|
|
@@ -506,8 +507,9 @@ interface HttpConfigurations {
|
|
|
506
507
|
/**
|
|
507
508
|
* Options for `response.stream()`.
|
|
508
509
|
*/
|
|
509
|
-
type ResponseStreamOptions = StreamQueueOptions & {
|
|
510
|
-
/** Application/cache headers override defaults before flushing; framing and connection headers are ignored. */
|
|
510
|
+
export type ResponseStreamOptions = StreamQueueOptions & {
|
|
511
|
+
/** Application/cache headers override defaults before flushing; framing and connection headers are ignored. */
|
|
512
|
+
headers?: Record<string, string>;
|
|
511
513
|
/**
|
|
512
514
|
* How many of the most recent chunks (from `send()`, `write()` and
|
|
513
515
|
* `render()`) to keep on `response.body` after `end()`, for logging and
|
|
@@ -518,14 +520,15 @@ type ResponseStreamOptions = StreamQueueOptions & {
|
|
|
518
520
|
*/
|
|
519
521
|
retainChunks?: number;
|
|
520
522
|
};
|
|
521
|
-
type ResponseStreamController = {
|
|
523
|
+
export type ResponseStreamController = {
|
|
522
524
|
/**
|
|
523
525
|
* Send data to the client. Does not wait for the client; for long-lived or
|
|
524
526
|
* high-volume streams use `write()` (or `drain()`) so the producer slows
|
|
525
527
|
* down to the client's pace instead of buffering. A silent no-op after the
|
|
526
528
|
* client disconnected; throws after `end()`.
|
|
527
529
|
*/
|
|
528
|
-
send: (data: string | Uint8Array) => void;
|
|
530
|
+
send: (data: string | Uint8Array) => void;
|
|
531
|
+
/** Bounded synchronous write; false when closed or overflow rejects this chunk. */
|
|
529
532
|
enqueue: (data: string | Uint8Array) => boolean;
|
|
530
533
|
/**
|
|
531
534
|
* Send data and wait until the transport can take more. Resolves `true`
|
|
@@ -560,7 +563,8 @@ type ResponseStreamController = {
|
|
|
560
563
|
/**
|
|
561
564
|
* Whether the transport is currently holding more than its high-water mark.
|
|
562
565
|
*/
|
|
563
|
-
backpressured: boolean;
|
|
566
|
+
backpressured: boolean;
|
|
567
|
+
/** Chunks/events/comments rejected by onOverflow: "drop", including send/write/render paths. */
|
|
564
568
|
readonly dropped: number;
|
|
565
569
|
/**
|
|
566
570
|
* Detect whether stream is ended (by `end()` or a client disconnect)
|
|
@@ -570,8 +574,9 @@ type ResponseStreamController = {
|
|
|
570
574
|
/**
|
|
571
575
|
* Options for `response.sse()`.
|
|
572
576
|
*/
|
|
573
|
-
type ResponseSSEOptions = StreamQueueOptions & {
|
|
574
|
-
/** Application/cache headers override defaults before flushing; framing and connection headers are ignored. */
|
|
577
|
+
export type ResponseSSEOptions = StreamQueueOptions & {
|
|
578
|
+
/** Application/cache headers override defaults before flushing; framing and connection headers are ignored. */
|
|
579
|
+
headers?: Record<string, string>;
|
|
575
580
|
/**
|
|
576
581
|
* How many of the most recent events to keep on `response.body` after
|
|
577
582
|
* `end()`, for logging and debugging. Sent events are otherwise not kept,
|
|
@@ -582,10 +587,10 @@ type ResponseSSEOptions = StreamQueueOptions & {
|
|
|
582
587
|
retainEvents?: number;
|
|
583
588
|
};
|
|
584
589
|
/** Wire serialization for one SSE event. Raw strings are split into safe data lines. */
|
|
585
|
-
type ResponseSSEMessageOptions = {
|
|
590
|
+
export type ResponseSSEMessageOptions = {
|
|
586
591
|
raw?: boolean;
|
|
587
592
|
};
|
|
588
|
-
type ResponseSSEController = {
|
|
593
|
+
export type ResponseSSEController = {
|
|
589
594
|
/**
|
|
590
595
|
* Send an SSE event to the client. Does not wait for the client; for
|
|
591
596
|
* long-lived or high-volume streams use `write()` (or `drain()`) so the
|
|
@@ -594,7 +599,8 @@ type ResponseSSEController = {
|
|
|
594
599
|
* @param data - Event data (will be JSON stringified)
|
|
595
600
|
* @param id - Optional event ID for client-side Last-Event-ID tracking
|
|
596
601
|
*/
|
|
597
|
-
send: (event: string | undefined, data: any, id?: string, options?: ResponseSSEMessageOptions) => ResponseSSEController;
|
|
602
|
+
send: (event: string | undefined, data: any, id?: string, options?: ResponseSSEMessageOptions) => ResponseSSEController;
|
|
603
|
+
/** Bounded synchronous event; undefined event omits the event field. */
|
|
598
604
|
enqueue: (event: string | undefined, data: unknown, id?: string, options?: ResponseSSEMessageOptions) => boolean;
|
|
599
605
|
/**
|
|
600
606
|
* Send an SSE event and wait until the transport can take more.
|
|
@@ -617,7 +623,8 @@ type ResponseSSEController = {
|
|
|
617
623
|
/**
|
|
618
624
|
* Whether the transport is currently holding more than its high-water mark.
|
|
619
625
|
*/
|
|
620
|
-
backpressured: boolean;
|
|
626
|
+
backpressured: boolean;
|
|
627
|
+
/** Chunks/events/comments rejected by onOverflow: "drop", including send/write/render paths. */
|
|
621
628
|
readonly dropped: number;
|
|
622
629
|
/**
|
|
623
630
|
* Send a comment to keep the connection alive (invisible to client)
|
|
@@ -638,5 +645,4 @@ type ResponseSSEController = {
|
|
|
638
645
|
ended: boolean;
|
|
639
646
|
};
|
|
640
647
|
//#endregion
|
|
641
|
-
export { DecodedAccessToken, HttpConfigurations, HttpServerOptions, PartialMiddleware, RequestEvent, RequestLocals, ResponseEvent, ResponseSSEController, ResponseSSEMessageOptions, ResponseSSEOptions, ResponseStreamController, ResponseStreamOptions, ReturnedResponse };
|
|
642
648
|
//# sourceMappingURL=types.d.mts.map
|
package/esm/http/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/types.ts"],"mappings":";;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":["NodeHttpServer","Http2SecureOptions"],"sources":["../../../../../../../../packages/core/src/http/types.ts"],"mappings":";;;;;;;;;;;;;;;;YAeY;;;;;;;;;;;;;;;;;;;;;;;;iBA6BK;;;;;;;;;;;;;;EAcf;;;;;;;;;;;;;;YAeU;EACV;;;;;YAMU;;;;AAIR;;;;AAIA,QAAQ;;;;AAIR;;;;AAIA,QAAQ;;;;;;;;AAQR;;;;YAKQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiEK;;;;;EAKf;;;;;;EAMA;;;;EAIA,YAAY;;;;;;;;;;;YAYF,oBAAoB,KAAK,mBAAmBA;;EAEtD;EACA,QAAQC;EACR;;;;;iBAMe;;;;;;;;;;;;;;;;;;;EAmBf,gBAAgB;;;;;;;;;EAShB;;;;;;;EAOA,cAAc;;;;;;;;EAQd;;;;EAIA;;;;EAIA;;;;;;;EAOA,UAAU;;;;EAIV,OAAO;;;;;;EAMP;;;;;EAKA;;;;;;IAME;;;;;;IAMA;;;;;;IAMA;;;;;;;;;;;EAWF;;;;;;;;;;;;;;;;;;;;EAoBA,6CAA6C,iBAAiB;EAC9D;;;;IAIE;;;;IAIA,UAAU;;;;;;;;;;;EAWZ,MAAM;;;;EAIN,YAAY;;;;;;;;EAQZ;;;;;;IAME;;;;IAIA;;;;;;;IAOA;;;;;EAKF;;;;;;IAME;;;;;;IAMA;;;;;;;IAOA;;;;IAIA;;;;;EAKF;;;;;;;IAOE;;;;;;IAMA;;;;;;IAMA;;;;;EAKF;;;;;;;IAOE;;;;;;;;IAQA;;;;;EAKF;;;;;;IAME;;;;;;;IAOA;;;;;;;IAOA;;;;;;;IAOA;;;;;EAKF;;;;EAIA;;;;IAIE,MAAM;;;;IAIN,OAAO;;;;IAIP,SAAS;;;;;;;EAOX,UAAU;;;;;YAMA,wBAAwB;;EAElC,UAAU;;;;;;;;;EASV;;YAGU;;;;;;;EAOV,OAAO,eAAe;;EAEtB,UAAU,eAAe;;;;;;;EAOzB,QAAQ,eAAe,eAAe;;;;EAItC,SAAS,MAAM,MAAM;;;;;;EAMrB,aAAa;;;;EAIb;;;;EAIA,eAAe,wBAAwB;;;;;EAKvC,QAAQ;;;;EAIR;;WAES;;;;EAIT;;;;;YAMU,qBAAqB;;EAE/B,UAAU;;;;;;;;EAQV;;;YAIU;EAA8B;;YAE9B;;;;;;;;;EASV,OACE,2BACA,WACA,aACA,UAAU,8BACP;;EAEL,UACE,2BACA,eACA,aACA,UAAU;;;;;;;EAQZ,QACE,2BACA,WACA,aACA,UAAU,8BACP;;;;;;EAML,aAAa;;;;;EAKb,QAAQ;;;;EAIR;;WAES;;;;EAIT,UAAU,oBAAoB;;;;EAI9B,WAAW;;;;;EAKX,eAAe,wBAAwB;;;;EAIvC"}
|
|
@@ -2,10 +2,11 @@ import { StorageFile } from "../storage/storage-file.mjs";
|
|
|
2
2
|
import { ScopedStorage } from "../storage/scoped-storage.mjs";
|
|
3
3
|
import { StorageDriverName } from "../storage/types.mjs";
|
|
4
4
|
import { storage } from "../storage/storage.mjs";
|
|
5
|
+
import "../storage/index.mjs";
|
|
5
6
|
import { Image, ImageFormat, ImageTransformOptions } from "../image/image.mjs";
|
|
7
|
+
import "../image/index.mjs";
|
|
6
8
|
import { ImageTransformCallback, PrefixConfig, SaveAsOptions, SaveOptions, UploadedFileImageOptions } from "./uploads-types.mjs";
|
|
7
9
|
import { MultipartFile } from "@fastify/multipart";
|
|
8
|
-
|
|
9
10
|
//#region ../../packages/core/src/http/uploaded-file.d.ts
|
|
10
11
|
type UploadedFileMetadata = {
|
|
11
12
|
name: string;
|
|
@@ -23,7 +24,7 @@ type UploadedFileMetadata = {
|
|
|
23
24
|
* the one exception and it is optional for exactly that reason: present when
|
|
24
25
|
* the file has already been buffered, absent otherwise, never guessed.
|
|
25
26
|
*/
|
|
26
|
-
type UploadedFileJson = {
|
|
27
|
+
export type UploadedFileJson = {
|
|
27
28
|
name: string;
|
|
28
29
|
mimeType: string;
|
|
29
30
|
extension: string;
|
|
@@ -35,7 +36,7 @@ type UploadedFileJson = {
|
|
|
35
36
|
/**
|
|
36
37
|
* Options for validating file before saving
|
|
37
38
|
*/
|
|
38
|
-
type FileValidationOptions = {
|
|
39
|
+
export type FileValidationOptions = {
|
|
39
40
|
/**
|
|
40
41
|
* List of allowed MIME types
|
|
41
42
|
*
|
|
@@ -83,7 +84,7 @@ type FileValidationOptions = {
|
|
|
83
84
|
* const file = await uploadedFile.use("s3").save("avatars");
|
|
84
85
|
* ```
|
|
85
86
|
*/
|
|
86
|
-
declare class UploadedFile {
|
|
87
|
+
export declare class UploadedFile {
|
|
87
88
|
protected readonly fileData: MultipartFile;
|
|
88
89
|
/**
|
|
89
90
|
* File buffered content
|
|
@@ -492,5 +493,5 @@ declare class UploadedFile {
|
|
|
492
493
|
toBase64(): Promise<string>;
|
|
493
494
|
}
|
|
494
495
|
//#endregion
|
|
495
|
-
export {
|
|
496
|
+
export {};
|
|
496
497
|
//# sourceMappingURL=uploaded-file.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploaded-file.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/uploaded-file.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"uploaded-file.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/http/uploaded-file.ts"],"mappings":";;;;;;;;;;KAiBK;EACH;EACA;EACA;EACA;EACA;EACA;;;;;;;;;;YAWU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;;;;;YAMU;;;;;;EAMV;;;;;;EAOA;;;;;;EAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA+BW;qBA4C2B,UAAU;;;;;YAvCtC,sBAAsB;;;;;;EAOzB;;;;;YAMG,UAAU;;;;;YAMV,eAAe;;;;;YAMf,eAAe;;;;;YAMf,mBAAmB,wBAAwB;;;;;;;EAQrD,YAAsC,UAAU;;;;;;MAerC;;;;;;MASA;;;;;;MASA;;;;EAOE,YAAY,QAAQ;;;;;;EAsBpB,QAAQ;;;;;;EAUR,UAAU,QAAQ;;;;MAgBpB;;;;MAOA;;;;MAOA;;;;;;;;;;;;;;;;EAuBJ,IAAI,QAAQ;;;;;;;;;;;;;;;;EAwBZ,OAAO,eAAe;;;;;;;;;;;;;;;EAmBtB,QAAQ;;;;;;;;;;;;;;;EAsBR,OAAO,QAAQ;;;;;;;;;;;;EAgBf,OAAO;;;;;;;;;;;;EAgBP,KAAK;;;;;;;;;;;EAkBL;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCA,UAAU,QAAQ,wBAAwB;;;;;;;;;;;;;;;;;;EAsBpC,WAAW,QAAQ;;;;;;EAanB,cAAc;IAAU;IAAgB;;;;;;;;;;;;;;;;EA0BxC,SAAS,SAAS,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2D1C,KAAK,mBAAmB,UAAU,cAAc,QAAQ;;;;;;;;;;;;;;;;;EA8BxD,OAAO,kBAAkB,UAAU,gBAAgB,QAAQ;;;;;;MAc7D,eAAe;;;;;YAYV,eACd,kBACA,SAAS,oBACR,QAAQ;;;;;YA0BK,uBAAuB,QAAQ;;;;;YA4BrC,kBAAkB,KAAK,QAAQ;;;;;YAkC/B;;;;;YAQA,eAAe,SAAS,oBAAoB,uBAAuB;;;;;YAYnE,gBAAgB,UAAU;;;;;YAwB1B,cAAc,SAAS;;;;;YAiDvB,iBAAiB,gBAAgB;;;;;YASjC,WAAW;;;;;YAQX,cAAc,mBAAmB,gBAAgB;;;;;YAiBjD;;;;;YAiBA;;;;;YAgBA,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6C3B,UAAU;;;;;;;EAkBJ,YAAY"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { StorageDriverName } from "../../storage/types.mjs";
|
|
2
2
|
import { GeneratedImageDescriptor } from "./image-variant-types.mjs";
|
|
3
|
-
|
|
4
3
|
//#region ../../packages/core/src/http/uploads/generate-image-variants.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Options for `generateImageVariants`
|
|
7
6
|
*/
|
|
8
|
-
type GenerateImageVariantsOptions = {
|
|
7
|
+
export type GenerateImageVariantsOptions = {
|
|
9
8
|
/**
|
|
10
9
|
* Limit generation to these variant names, instead of every variant in
|
|
11
10
|
* `uploads.images.variants`.
|
|
12
11
|
*/
|
|
13
|
-
variants?: readonly string[];
|
|
14
|
-
|
|
12
|
+
variants?: readonly string[];
|
|
13
|
+
/** Disk holding the source; defaults to the active disk. */
|
|
14
|
+
disk?: StorageDriverName;
|
|
15
|
+
/** Route prefix serving variants of this disk (and originals for local disks). Default /uploads. */
|
|
15
16
|
urlPrefix?: string;
|
|
16
17
|
};
|
|
17
18
|
/**
|
|
@@ -46,7 +47,6 @@ type GenerateImageVariantsOptions = {
|
|
|
46
47
|
* `maxSourcePixels`
|
|
47
48
|
* @throws HttpError(415) when the source is not jpeg, png, webp or avif
|
|
48
49
|
*/
|
|
49
|
-
declare function generateImageVariants(relativePath: string, options?: GenerateImageVariantsOptions): Promise<GeneratedImageDescriptor>;
|
|
50
|
+
export declare function generateImageVariants(relativePath: string, options?: GenerateImageVariantsOptions): Promise<GeneratedImageDescriptor>;
|
|
50
51
|
//#endregion
|
|
51
|
-
export { GenerateImageVariantsOptions, generateImageVariants };
|
|
52
52
|
//# sourceMappingURL=generate-image-variants.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-image-variants.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/http/uploads/generate-image-variants.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"generate-image-variants.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/http/uploads/generate-image-variants.ts"],"mappings":";;;;;;YAqCY;;;;;EAKV;;EAGA,OAAO;;EAGP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAoEoB,sBACpB,sBACA,UAAS,+BACR,QAAQ"}
|
|
@@ -36,7 +36,7 @@ async function readDerivativeDimensions(target) {
|
|
|
36
36
|
* that is both the source format and an allowed format is generated once.
|
|
37
37
|
*/
|
|
38
38
|
function outputFormatsFor(sourceFormat, configuredFormats) {
|
|
39
|
-
return [
|
|
39
|
+
return [.../* @__PURE__ */ new Set([sourceFormat, ...configuredFormats])];
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
42
|
* Render every configured variant of one uploaded image, right after it is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-image-variants.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/http/uploads/generate-image-variants.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport { Image } from \"../../image\";\nimport type { StorageDriverName } from \"../../storage/types\";\nimport { localDiskRoot } from \"./local-disk-root\";\nimport { remoteVariantDisk, remoteVariantSource } from \"./remote-variant-source\";\nimport { renderRemoteImageVariant } from \"./resolve-remote-image-variant\";\nimport { HttpError } from \"../errors\";\nimport { uploadsConfig } from \"../uploads-config\";\nimport type { ImageVariantOutputFormat } from \"../uploads-types\";\nimport { generateImageVariant } from \"./generate-image-variant\";\nimport {\n pruneStaleVariantGenerationsIfCurrent,\n retryOnVanishedDirectory,\n warnIfVariantCacheIsPublic,\n} from \"./image-variant-cache\";\nimport { ImageVariantsConfigError } from \"./image-variants-config-error\";\nimport type {\n GeneratedImageDescriptor,\n GeneratedImageVariant,\n VariantOutputFormat,\n} from \"./image-variant-types\";\nimport { loadVariantSource } from \"./load-variant-source\";\nimport { resolveImageVariantsConfig } from \"./resolve-image-variants-config\";\nimport { resolveVariantCandidate } from \"./resolve-variant-candidate\";\nimport {\n variantCacheKey,\n variantCachePath,\n variantGenerationTag,\n variantSourceDirectory,\n variantSourceKey,\n} from \"./variant-cache-key\";\nimport { freshImageVariant, scheduleImageVariantCacheTrim } from \"./trim-image-variant-cache\";\nimport { variantGenerations } from \"./variant-generations\";\n\n/**\n * Options for `generateImageVariants`\n */\nexport type GenerateImageVariantsOptions = {\n /**\n * Limit generation to these variant names, instead of every variant in\n * `uploads.images.variants`.\n */\n variants?: readonly string[];\n\n /** Disk holding the source; defaults to the active disk. */\n disk?: StorageDriverName;\n\n /** Route prefix serving variants of this disk (and originals for local disks). Default /uploads. */\n urlPrefix?: string;\n};\n\nfunction encodeUploadsPath(relativePath: string): string {\n return relativePath.split(\"/\").map(encodeURIComponent).join(\"/\");\n}\n\nfunction variantUrl(src: string, name: string, format?: VariantOutputFormat): string {\n const query = format\n ? `variant=${encodeURIComponent(name)}&format=${format}`\n : `variant=${encodeURIComponent(name)}`;\n\n return `${src}?${query}`;\n}\n\nasync function readDerivativeDimensions(\n target: string,\n): Promise<{ width: number; height: number }> {\n const derivative = new Image(await fs.readFile(target));\n const { width, height } = await derivative.metadata();\n\n return { width: width ?? 0, height: height ?? 0 };\n}\n\n/**\n * Every distinct format a variant is rendered in: the source format plus\n * whatever `uploads.images.formats` adds, with duplicates dropped so a format\n * that is both the source format and an allowed format is generated once.\n */\nfunction outputFormatsFor(\n sourceFormat: VariantOutputFormat,\n configuredFormats: readonly ImageVariantOutputFormat[],\n): VariantOutputFormat[] {\n return [...new Set<VariantOutputFormat>([sourceFormat, ...configuredFormats])];\n}\n\n/**\n * Render every configured variant of one uploaded image, right after it is\n * saved.\n *\n * Uses the exact same normalized config (`uploads.images`), cache key and\n * derivative path as `uploadedFileController`, so a variant generated here is\n * already on disk the first time `GET /uploads/<path>?variant=<name>` is\n * requested — no second render. `variantGenerations` (the single-flight used\n * by the route) is reused, so a concurrent request for a variant this call is\n * still generating joins the same run instead of starting a second one.\n *\n * The returned descriptor is plain JSON, safe to store next to the record\n * that owns the image, or to carry through loader data. On local storage the\n * `url`/`urls` already point at `uploadedFileController`; an app serving\n * uploads from object storage use the driver URL for the original, and\n * `options.urlPrefix` for the route serving locally cached derivatives.\n * Ingest downloads a remote source once for all variants and formats.\n * On-demand cache hits use ETag metadata; sources without ETags are hashed.\n *\n * @param relativePath - path of the saved upload, relative to the storage root\n * @param options.variants - limit generation to these variant names\n * @throws ImageVariantsConfigError when `uploads.images` is not\n * configured — this is server misconfiguration, not\n * a bad request\n * @throws HttpError(400) when a name in `options.variants` is not declared in\n * `uploads.images.variants`\n * @throws HttpError(404) when `relativePath` does not resolve to a file\n * inside the storage root\n * @throws HttpError(413) when the source is over `maxSourceBytes` or\n * `maxSourcePixels`\n * @throws HttpError(415) when the source is not jpeg, png, webp or avif\n */\nexport async function generateImageVariants(\n relativePath: string,\n options: GenerateImageVariantsOptions = {},\n): Promise<GeneratedImageDescriptor> {\n const storageRoot = localDiskRoot(options.disk);\n\n if (!storageRoot) return generateRemoteImageVariants(relativePath, options);\n\n const images = resolveImageVariantsConfig(uploadsConfig(\"images\"), storageRoot);\n\n if (!images) {\n throw new ImageVariantsConfigError(\"uploads.images is not configured.\");\n }\n\n const names = options.variants ?? Object.keys(images.variants);\n\n for (const name of names) {\n if (!Object.prototype.hasOwnProperty.call(images.variants, name)) {\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n }\n\n const candidate = await resolveVariantCandidate(relativePath, storageRoot, images);\n\n if (!candidate) {\n throw new HttpError(404, \"File Not Found\");\n }\n\n const { source, stats, sourceFormat } = candidate;\n\n const image = await loadVariantSource(source.absolutePath, {\n maxSourceBytes: images.maxSourceBytes,\n maxSourcePixels: images.maxSourcePixels,\n expectedFormat: sourceFormat,\n });\n\n const { width: sourceWidth, height: sourceHeight } = await image.metadata();\n warnIfVariantCacheIsPublic(images.cacheDirectory);\n\n const src = `${(options.urlPrefix ?? \"/uploads\").replace(/\\/$/, \"\")}/${encodeUploadsPath(source.relativePath)}`;\n const variants: Record<string, GeneratedImageVariant> = {};\n\n for (const name of names) {\n const variant = images.variants[name];\n if (variant === undefined) {\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n const formats = outputFormatsFor(sourceFormat, images.formats);\n let dimensions: { width: number; height: number } | undefined;\n\n for (const format of formats) {\n const hash = variantCacheKey({\n relativePath: source.relativePath,\n sourceSize: stats.size,\n sourceMtimeMs: stats.mtimeMs,\n variant,\n format,\n });\n const sourceKey = variantSourceKey(source.root, source.relativePath);\n const generation = variantGenerationTag(stats.size, stats.mtimeMs);\n const target = variantCachePath(\n images.cacheDirectory,\n { sourceKey, generation },\n hash,\n format,\n );\n\n if (!(await freshImageVariant(target, images.maxCacheAge))) {\n // keyed on the target, which includes the disk root (see resolveImageVariant)\n await variantGenerations.run(target, async () => {\n if (await freshImageVariant(target, images.maxCacheAge)) return;\n\n await retryOnVanishedDirectory(() =>\n generateImageVariant({ image: image.clone(), variant, format, targetPath: target }),\n );\n scheduleImageVariantCacheTrim(images, target);\n await pruneStaleVariantGenerationsIfCurrent(\n source.absolutePath,\n variantSourceDirectory(images.cacheDirectory, sourceKey),\n generation,\n );\n });\n }\n\n if (dimensions === undefined) {\n dimensions = await readDerivativeDimensions(target);\n }\n }\n\n const urls: Partial<Record<ImageVariantOutputFormat, string>> = {};\n\n for (const format of images.formats) {\n urls[format] = variantUrl(src, name, format);\n }\n\n variants[name] = {\n width: dimensions?.width ?? variant.width,\n height:\n dimensions?.height ??\n variant.height ??\n Math.round(variant.width * ((sourceHeight ?? 1) / (sourceWidth ?? 1))),\n url: variantUrl(src, name),\n ...(Object.keys(urls).length > 0 ? { urls } : {}),\n };\n }\n\n return {\n src,\n width: sourceWidth ?? 0,\n height: sourceHeight ?? 0,\n variants,\n ...(images.formats.length > 0 ? { formats: images.formats } : {}),\n };\n}\n\nasync function generateRemoteImageVariants(\n relativePath: string,\n options: GenerateImageVariantsOptions,\n): Promise<GeneratedImageDescriptor> {\n const disk = remoteVariantDisk(options.disk);\n const images = resolveImageVariantsConfig(uploadsConfig(\"images\"), disk.cacheRoot);\n if (!images) throw new ImageVariantsConfigError(\"uploads.images is not configured.\");\n const names = options.variants ?? Object.keys(images.variants);\n for (const name of names) {\n if (!Object.prototype.hasOwnProperty.call(images.variants, name))\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n const source = await remoteVariantSource(relativePath, disk, images);\n if (!source) throw new HttpError(404, \"File Not Found\");\n try {\n const { image, sourceFormat } = await source.load();\n const { width, height } = await image.metadata();\n const variantSrc = `${(options.urlPrefix ?? \"/uploads\").replace(/\\/$/, \"\")}/${encodeUploadsPath(source.relativePath)}`;\n const variants: Record<string, GeneratedImageVariant> = {};\n for (const name of names) {\n let dimensions: { width: number; height: number } | undefined;\n for (const format of outputFormatsFor(sourceFormat, images.formats)) {\n const resolved = await renderRemoteImageVariant(\n {\n path: relativePath,\n variant: name,\n ...(format === sourceFormat ? {} : { format }),\n },\n disk,\n images,\n source,\n );\n if (!resolved) throw new HttpError(404, \"File Not Found\");\n dimensions ??= await readDerivativeDimensions(resolved.absolutePath);\n }\n variants[name] = {\n width: dimensions?.width ?? 0,\n height: dimensions?.height ?? 0,\n url: variantUrl(variantSrc, name),\n ...(images.formats.length\n ? {\n urls: Object.fromEntries(\n images.formats.map((format) => [format, variantUrl(variantSrc, name, format)]),\n ),\n }\n : {}),\n };\n }\n return {\n src: disk.driver.url(source.relativePath),\n width: width ?? 0,\n height: height ?? 0,\n variants,\n ...(images.formats.length ? { formats: images.formats } : {}),\n };\n } finally {\n source.release();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generate-image-variants.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/http/uploads/generate-image-variants.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport { Image } from \"../../image\";\nimport type { StorageDriverName } from \"../../storage/types\";\nimport { localDiskRoot } from \"./local-disk-root\";\nimport { remoteVariantDisk, remoteVariantSource } from \"./remote-variant-source\";\nimport { renderRemoteImageVariant } from \"./resolve-remote-image-variant\";\nimport { HttpError } from \"../errors\";\nimport { uploadsConfig } from \"../uploads-config\";\nimport type { ImageVariantOutputFormat } from \"../uploads-types\";\nimport { generateImageVariant } from \"./generate-image-variant\";\nimport {\n pruneStaleVariantGenerationsIfCurrent,\n retryOnVanishedDirectory,\n warnIfVariantCacheIsPublic,\n} from \"./image-variant-cache\";\nimport { ImageVariantsConfigError } from \"./image-variants-config-error\";\nimport type {\n GeneratedImageDescriptor,\n GeneratedImageVariant,\n VariantOutputFormat,\n} from \"./image-variant-types\";\nimport { loadVariantSource } from \"./load-variant-source\";\nimport { resolveImageVariantsConfig } from \"./resolve-image-variants-config\";\nimport { resolveVariantCandidate } from \"./resolve-variant-candidate\";\nimport {\n variantCacheKey,\n variantCachePath,\n variantGenerationTag,\n variantSourceDirectory,\n variantSourceKey,\n} from \"./variant-cache-key\";\nimport { freshImageVariant, scheduleImageVariantCacheTrim } from \"./trim-image-variant-cache\";\nimport { variantGenerations } from \"./variant-generations\";\n\n/**\n * Options for `generateImageVariants`\n */\nexport type GenerateImageVariantsOptions = {\n /**\n * Limit generation to these variant names, instead of every variant in\n * `uploads.images.variants`.\n */\n variants?: readonly string[];\n\n /** Disk holding the source; defaults to the active disk. */\n disk?: StorageDriverName;\n\n /** Route prefix serving variants of this disk (and originals for local disks). Default /uploads. */\n urlPrefix?: string;\n};\n\nfunction encodeUploadsPath(relativePath: string): string {\n return relativePath.split(\"/\").map(encodeURIComponent).join(\"/\");\n}\n\nfunction variantUrl(src: string, name: string, format?: VariantOutputFormat): string {\n const query = format\n ? `variant=${encodeURIComponent(name)}&format=${format}`\n : `variant=${encodeURIComponent(name)}`;\n\n return `${src}?${query}`;\n}\n\nasync function readDerivativeDimensions(\n target: string,\n): Promise<{ width: number; height: number }> {\n const derivative = new Image(await fs.readFile(target));\n const { width, height } = await derivative.metadata();\n\n return { width: width ?? 0, height: height ?? 0 };\n}\n\n/**\n * Every distinct format a variant is rendered in: the source format plus\n * whatever `uploads.images.formats` adds, with duplicates dropped so a format\n * that is both the source format and an allowed format is generated once.\n */\nfunction outputFormatsFor(\n sourceFormat: VariantOutputFormat,\n configuredFormats: readonly ImageVariantOutputFormat[],\n): VariantOutputFormat[] {\n return [...new Set<VariantOutputFormat>([sourceFormat, ...configuredFormats])];\n}\n\n/**\n * Render every configured variant of one uploaded image, right after it is\n * saved.\n *\n * Uses the exact same normalized config (`uploads.images`), cache key and\n * derivative path as `uploadedFileController`, so a variant generated here is\n * already on disk the first time `GET /uploads/<path>?variant=<name>` is\n * requested — no second render. `variantGenerations` (the single-flight used\n * by the route) is reused, so a concurrent request for a variant this call is\n * still generating joins the same run instead of starting a second one.\n *\n * The returned descriptor is plain JSON, safe to store next to the record\n * that owns the image, or to carry through loader data. On local storage the\n * `url`/`urls` already point at `uploadedFileController`; an app serving\n * uploads from object storage use the driver URL for the original, and\n * `options.urlPrefix` for the route serving locally cached derivatives.\n * Ingest downloads a remote source once for all variants and formats.\n * On-demand cache hits use ETag metadata; sources without ETags are hashed.\n *\n * @param relativePath - path of the saved upload, relative to the storage root\n * @param options.variants - limit generation to these variant names\n * @throws ImageVariantsConfigError when `uploads.images` is not\n * configured — this is server misconfiguration, not\n * a bad request\n * @throws HttpError(400) when a name in `options.variants` is not declared in\n * `uploads.images.variants`\n * @throws HttpError(404) when `relativePath` does not resolve to a file\n * inside the storage root\n * @throws HttpError(413) when the source is over `maxSourceBytes` or\n * `maxSourcePixels`\n * @throws HttpError(415) when the source is not jpeg, png, webp or avif\n */\nexport async function generateImageVariants(\n relativePath: string,\n options: GenerateImageVariantsOptions = {},\n): Promise<GeneratedImageDescriptor> {\n const storageRoot = localDiskRoot(options.disk);\n\n if (!storageRoot) return generateRemoteImageVariants(relativePath, options);\n\n const images = resolveImageVariantsConfig(uploadsConfig(\"images\"), storageRoot);\n\n if (!images) {\n throw new ImageVariantsConfigError(\"uploads.images is not configured.\");\n }\n\n const names = options.variants ?? Object.keys(images.variants);\n\n for (const name of names) {\n if (!Object.prototype.hasOwnProperty.call(images.variants, name)) {\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n }\n\n const candidate = await resolveVariantCandidate(relativePath, storageRoot, images);\n\n if (!candidate) {\n throw new HttpError(404, \"File Not Found\");\n }\n\n const { source, stats, sourceFormat } = candidate;\n\n const image = await loadVariantSource(source.absolutePath, {\n maxSourceBytes: images.maxSourceBytes,\n maxSourcePixels: images.maxSourcePixels,\n expectedFormat: sourceFormat,\n });\n\n const { width: sourceWidth, height: sourceHeight } = await image.metadata();\n warnIfVariantCacheIsPublic(images.cacheDirectory);\n\n const src = `${(options.urlPrefix ?? \"/uploads\").replace(/\\/$/, \"\")}/${encodeUploadsPath(source.relativePath)}`;\n const variants: Record<string, GeneratedImageVariant> = {};\n\n for (const name of names) {\n const variant = images.variants[name];\n if (variant === undefined) {\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n const formats = outputFormatsFor(sourceFormat, images.formats);\n let dimensions: { width: number; height: number } | undefined;\n\n for (const format of formats) {\n const hash = variantCacheKey({\n relativePath: source.relativePath,\n sourceSize: stats.size,\n sourceMtimeMs: stats.mtimeMs,\n variant,\n format,\n });\n const sourceKey = variantSourceKey(source.root, source.relativePath);\n const generation = variantGenerationTag(stats.size, stats.mtimeMs);\n const target = variantCachePath(\n images.cacheDirectory,\n { sourceKey, generation },\n hash,\n format,\n );\n\n if (!(await freshImageVariant(target, images.maxCacheAge))) {\n // keyed on the target, which includes the disk root (see resolveImageVariant)\n await variantGenerations.run(target, async () => {\n if (await freshImageVariant(target, images.maxCacheAge)) return;\n\n await retryOnVanishedDirectory(() =>\n generateImageVariant({ image: image.clone(), variant, format, targetPath: target }),\n );\n scheduleImageVariantCacheTrim(images, target);\n await pruneStaleVariantGenerationsIfCurrent(\n source.absolutePath,\n variantSourceDirectory(images.cacheDirectory, sourceKey),\n generation,\n );\n });\n }\n\n if (dimensions === undefined) {\n dimensions = await readDerivativeDimensions(target);\n }\n }\n\n const urls: Partial<Record<ImageVariantOutputFormat, string>> = {};\n\n for (const format of images.formats) {\n urls[format] = variantUrl(src, name, format);\n }\n\n variants[name] = {\n width: dimensions?.width ?? variant.width,\n height:\n dimensions?.height ??\n variant.height ??\n Math.round(variant.width * ((sourceHeight ?? 1) / (sourceWidth ?? 1))),\n url: variantUrl(src, name),\n ...(Object.keys(urls).length > 0 ? { urls } : {}),\n };\n }\n\n return {\n src,\n width: sourceWidth ?? 0,\n height: sourceHeight ?? 0,\n variants,\n ...(images.formats.length > 0 ? { formats: images.formats } : {}),\n };\n}\n\nasync function generateRemoteImageVariants(\n relativePath: string,\n options: GenerateImageVariantsOptions,\n): Promise<GeneratedImageDescriptor> {\n const disk = remoteVariantDisk(options.disk);\n const images = resolveImageVariantsConfig(uploadsConfig(\"images\"), disk.cacheRoot);\n if (!images) throw new ImageVariantsConfigError(\"uploads.images is not configured.\");\n const names = options.variants ?? Object.keys(images.variants);\n for (const name of names) {\n if (!Object.prototype.hasOwnProperty.call(images.variants, name))\n throw new HttpError(400, `Unknown variant \"${name}\".`);\n }\n const source = await remoteVariantSource(relativePath, disk, images);\n if (!source) throw new HttpError(404, \"File Not Found\");\n try {\n const { image, sourceFormat } = await source.load();\n const { width, height } = await image.metadata();\n const variantSrc = `${(options.urlPrefix ?? \"/uploads\").replace(/\\/$/, \"\")}/${encodeUploadsPath(source.relativePath)}`;\n const variants: Record<string, GeneratedImageVariant> = {};\n for (const name of names) {\n let dimensions: { width: number; height: number } | undefined;\n for (const format of outputFormatsFor(sourceFormat, images.formats)) {\n const resolved = await renderRemoteImageVariant(\n {\n path: relativePath,\n variant: name,\n ...(format === sourceFormat ? {} : { format }),\n },\n disk,\n images,\n source,\n );\n if (!resolved) throw new HttpError(404, \"File Not Found\");\n dimensions ??= await readDerivativeDimensions(resolved.absolutePath);\n }\n variants[name] = {\n width: dimensions?.width ?? 0,\n height: dimensions?.height ?? 0,\n url: variantUrl(variantSrc, name),\n ...(images.formats.length\n ? {\n urls: Object.fromEntries(\n images.formats.map((format) => [format, variantUrl(variantSrc, name, format)]),\n ),\n }\n : {}),\n };\n }\n return {\n src: disk.driver.url(source.relativePath),\n width: width ?? 0,\n height: height ?? 0,\n variants,\n ...(images.formats.length ? { formats: images.formats } : {}),\n };\n } finally {\n source.release();\n }\n}\n"],"mappings":"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"}
|
|
@@ -74,5 +74,5 @@ async function purgeVariantCacheEntries(entries) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
//#endregion
|
|
77
|
-
export { purgeVariantCacheEntries, variantCacheEntries, variantCacheGenerations, variantSourceCacheEntries };
|
|
77
|
+
export { purgeVariantCacheEntries, variantCacheEntries, variantCacheGenerations, variantSourceCacheEntries, variantSourceCacheGenerations };
|
|
78
78
|
//# sourceMappingURL=image-variant-cache-entries.mjs.map
|
|
@@ -5,16 +5,16 @@ import { purgeVariantCacheEntries, variantSourceCacheEntries } from "./image-var
|
|
|
5
5
|
import { uploadsConfig } from "../uploads-config.mjs";
|
|
6
6
|
import { isPathInside, isPathWithin } from "./is-path-inside.mjs";
|
|
7
7
|
import { variantGenerationTag, variantSourceDirectory, variantSourceKey } from "./variant-cache-key.mjs";
|
|
8
|
-
import
|
|
8
|
+
import baseConfig from "@mongez/config";
|
|
9
9
|
import { log } from "@warlock.js/logger";
|
|
10
10
|
import path from "node:path";
|
|
11
|
-
import
|
|
12
|
-
import fs
|
|
11
|
+
import fsSync from "node:fs";
|
|
12
|
+
import fs from "node:fs/promises";
|
|
13
13
|
|
|
14
14
|
//#region ../../packages/core/src/http/uploads/image-variant-cache.ts
|
|
15
15
|
async function realpathOrSelf(target) {
|
|
16
16
|
try {
|
|
17
|
-
return await fs
|
|
17
|
+
return await fs.realpath(target);
|
|
18
18
|
} catch {
|
|
19
19
|
return target;
|
|
20
20
|
}
|
|
@@ -22,7 +22,7 @@ async function realpathOrSelf(target) {
|
|
|
22
22
|
function canonicalDirectory(target) {
|
|
23
23
|
const resolved = path.resolve(target);
|
|
24
24
|
try {
|
|
25
|
-
return
|
|
25
|
+
return fsSync.realpathSync(resolved);
|
|
26
26
|
} catch (error) {
|
|
27
27
|
const code = error.code;
|
|
28
28
|
if (code !== "ENOENT") throw new ImageVariantsConfigError(`uploads.images.cacheDirectory (or a local disk root) could not be resolved: ${resolved} (${code ?? "unknown error"})`, { cause: error });
|
|
@@ -132,7 +132,7 @@ async function pruneStaleVariantGenerations(sourceDirectory, keep) {
|
|
|
132
132
|
async function pruneStaleVariantGenerationsIfCurrent(sourceAbsolutePath, sourceDirectory, keep) {
|
|
133
133
|
let current;
|
|
134
134
|
try {
|
|
135
|
-
const stats = await fs
|
|
135
|
+
const stats = await fs.stat(sourceAbsolutePath);
|
|
136
136
|
current = variantGenerationTag(stats.size, stats.mtimeMs);
|
|
137
137
|
} catch {
|
|
138
138
|
return;
|
|
@@ -172,7 +172,7 @@ let warnedPublicCache = false;
|
|
|
172
172
|
*/
|
|
173
173
|
function warnIfVariantCacheIsPublic(cacheDirectory) {
|
|
174
174
|
if (warnedPublicCache) return;
|
|
175
|
-
const configured =
|
|
175
|
+
const configured = baseConfig.get("storage.publicRoot", rootPath("public"));
|
|
176
176
|
const publicRoots = (Array.isArray(configured) ? configured : [configured]).filter((root) => typeof root === "string" && root.length > 0).map((root) => path.resolve(root));
|
|
177
177
|
const resolved = path.resolve(cacheDirectory);
|
|
178
178
|
if (!publicRoots.some((root) => resolved === root || isPathInside(resolved, root))) return;
|
|
@@ -181,5 +181,5 @@ function warnIfVariantCacheIsPublic(cacheDirectory) {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
//#endregion
|
|
184
|
-
export { isMissingFileError, pruneStaleVariantGenerationsIfCurrent, purgeImageVariantsOfFile, retryOnVanishedDirectory, variantCacheDirectoryFor, warnIfVariantCacheIsPublic };
|
|
184
|
+
export { isMissingFileError, pruneStaleVariantGenerations, pruneStaleVariantGenerationsIfCurrent, purgeImageVariantsOfFile, retryOnVanishedDirectory, variantCacheDirectoryFor, variantSourceDirectoryForFile, warnIfVariantCacheIsPublic };
|
|
185
185
|
//# sourceMappingURL=image-variant-cache.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-variant-cache.mjs","names":["fs","fsSync"],"sources":["../../../../../../../../../packages/core/src/http/uploads/image-variant-cache.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport { configuredLocalDiskRoots } from \"../../storage/local-disk-roots\";\nimport type { UploadsImagesConfigurations } from \"../uploads-types\";\nimport { ImageVariantsConfigError } from \"./image-variants-config-error\";\nimport { purgeVariantCacheEntries, variantSourceCacheEntries } from \"./image-variant-cache-entries\";\nimport path from \"node:path\";\nimport { rootPath } from \"../../utils/paths\";\nimport { uploadsConfig } from \"../uploads-config\";\nimport { isPathInside, isPathWithin } from \"./is-path-inside\";\nimport {\n variantGenerationTag,\n variantSourceDirectory,\n variantSourceKey,\n} from \"./variant-cache-key\";\n\n/*\n * Cache housekeeping for image derivatives. Deliberately free of any\n * import of the storage manager or drivers: the local driver calls into this module when it\n * deletes or moves a file, and storage must not import back into the HTTP\n * layer that already imports storage.\n */\n\nasync function realpathOrSelf(target: string): Promise<string> {\n try {\n return await fs.realpath(target);\n } catch {\n return target;\n }\n}\n\nfunction canonicalDirectory(target: string): string {\n const resolved = path.resolve(target);\n try {\n return fsSync.realpathSync(resolved);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n // ENOTDIR, EACCES, ELOOP, ...: a configuration problem, reported as one.\n throw new ImageVariantsConfigError(\n `uploads.images.cacheDirectory (or a local disk root) could not be resolved: ${resolved} (${code ?? \"unknown error\"})`,\n { cause: error },\n );\n }\n const parent = path.dirname(resolved);\n if (parent === resolved) throw error;\n // Resolve the nearest existing ancestor too, so a symlink followed by a\n // not-yet-created directory cannot hide an overlap with a future disk root.\n return path.join(canonicalDirectory(parent), path.basename(resolved));\n }\n}\n\n/** Most distinct cache/disk-root combinations whose overlap check is remembered. */\nconst OVERLAP_CHECKS_LIMIT = 64;\n\n/**\n * Overlap check outcomes, keyed by the cache directory, the disk root and\n * every configured local root. A disk registered later changes the key, so\n * it is checked again; the stored error is rethrown for a refused layout.\n */\nconst overlapChecks = new Map<string, ImageVariantsConfigError | undefined>();\n\nfunction checkCacheOverlap(directory: string, diskRoot: string): void {\n const roots = [diskRoot, ...configuredLocalDiskRoots()];\n const key = [directory, ...roots].join(\"\\0\");\n if (overlapChecks.has(key)) {\n const failure = overlapChecks.get(key);\n if (failure) throw failure;\n return;\n }\n let failure: ImageVariantsConfigError | undefined;\n try {\n const realCache = canonicalDirectory(directory);\n for (const root of roots) {\n if (isPathWithin(canonicalDirectory(root), realCache)) {\n failure = new ImageVariantsConfigError(\n \"uploads.images.cacheDirectory must not equal or contain the storage root of any local disk (including symlinks).\",\n );\n break;\n }\n }\n } catch (error) {\n // Only configuration errors are remembered; anything else is retried next time.\n if (!(error instanceof ImageVariantsConfigError)) throw error;\n failure = error;\n }\n if (overlapChecks.size >= OVERLAP_CHECKS_LIMIT) {\n const oldest = overlapChecks.keys().next();\n if (!oldest.done) overlapChecks.delete(oldest.value);\n }\n overlapChecks.set(key, failure);\n if (failure) throw failure;\n}\n\n/**\n * Forget remembered cache overlap checks, so the next check resolves every\n * path again (tests). Changes to the configured disks are detected without it;\n * a directory replaced by a symlink at runtime is not.\n */\nexport function resetVariantCacheOverlapChecks(): void {\n overlapChecks.clear();\n}\n\n/**\n * The derivative cache directory for a local disk: `uploads.images.cacheDirectory`\n * when the app sets one (shared by every disk; derivatives are keyed by the\n * disk's real root, so they never collide), otherwise\n * `<diskRoot>/.cache/image-variants`. The same rule as\n * `resolveImageVariantsConfig`. Refuses any cache that equals or contains\n * any configured local root, resolving symlinks before comparison. The\n * outcome is remembered per cache, disk root and configured local roots, so\n * repeated requests do not resolve the same paths again.\n *\n * @throws ImageVariantsConfigError when a cache overlaps a local disk root, or\n * when the cache or a root cannot be resolved (for example `ENOTDIR`, `EACCES`)\n */\nexport function variantCacheDirectoryFor(\n diskRoot: string,\n images: Pick<UploadsImagesConfigurations, \"cacheDirectory\"> | undefined = uploadsConfig(\"images\"),\n): string {\n const configured = images?.cacheDirectory;\n const directory = configured\n ? path.resolve(configured)\n : path.join(path.resolve(diskRoot), \".cache\", \"image-variants\");\n checkCacheOverlap(directory, diskRoot);\n return directory;\n}\n\n/**\n * The directory holding every derivative of one file on a local disk, or\n * `undefined` when the file is not inside the disk root. The file does not\n * need to exist any more: only its parent directory is resolved through\n * symlinks, exactly as `resolveUploadPath` resolved it when the derivative\n * was made.\n */\nexport async function variantSourceDirectoryForFile(\n diskRoot: string,\n absolutePath: string,\n): Promise<string | undefined> {\n const realRoot = await realpathOrSelf(path.resolve(diskRoot));\n const realParent = await realpathOrSelf(path.dirname(path.resolve(absolutePath)));\n const realPath = path.join(realParent, path.basename(absolutePath));\n\n if (!isPathInside(realPath, realRoot)) return undefined;\n\n const relativePath = path.relative(realRoot, realPath).split(path.sep).join(\"/\");\n\n return variantSourceDirectory(\n variantCacheDirectoryFor(diskRoot),\n variantSourceKey(realRoot, relativePath),\n );\n}\n\n/**\n * Remove every cached derivative of one file on a local disk.\n *\n * @returns `true` when recognized cache files were removed\n */\nexport async function purgeImageVariantsOfFile(\n diskRoot: string,\n absolutePath: string,\n): Promise<boolean> {\n const directory = await variantSourceDirectoryForFile(diskRoot, absolutePath);\n\n if (!directory) return false;\n\n return purgeVariantCacheEntries(variantSourceCacheEntries(directory));\n}\n\n/**\n * Remove derivatives made from older versions of a source (a different size\n * or mtime), keeping only the `keep` generation. Called after a derivative of\n * the current version has been written, so a source rewritten in place does\n * not leave its old derivatives behind. Only recognized cache files in\n * generation-shaped directories are removed; unrelated entries and all\n * directories and symlinks stay in place.\n */\nexport async function pruneStaleVariantGenerations(\n sourceDirectory: string,\n keep: string,\n): Promise<void> {\n await purgeVariantCacheEntries(variantSourceCacheEntries(sourceDirectory, keep));\n}\n\n/**\n * {@link pruneStaleVariantGenerations}, but only while `keep` is still the\n * source's current generation.\n *\n * A request that read the source before it was rewritten renders an old\n * generation; if it pruned afterwards it would delete the derivatives of the\n * newer version another request had just written. Re-reading the source's\n * size and mtime right before pruning keeps a stale request from doing that.\n */\nexport async function pruneStaleVariantGenerationsIfCurrent(\n sourceAbsolutePath: string,\n sourceDirectory: string,\n keep: string,\n): Promise<void> {\n let current: string;\n\n try {\n const stats = await fs.stat(sourceAbsolutePath);\n current = variantGenerationTag(stats.size, stats.mtimeMs);\n } catch {\n // the source is gone; its derivatives are purged by the delete itself\n return;\n }\n\n if (current !== keep) return;\n\n await pruneStaleVariantGenerations(sourceDirectory, keep);\n}\n\n/**\n * True for \"no such file or directory\"\n */\nexport function isMissingFileError(error: unknown): boolean {\n return (error as NodeJS.ErrnoException | undefined)?.code === \"ENOENT\";\n}\n\n/**\n * Run a derivative write, once more if it fails because its directory\n * vanished: a concurrent request for a newer version of the source may prune\n * the generation directory between `mkdir` and the atomic rename.\n */\nexport async function retryOnVanishedDirectory(write: () => Promise<void>): Promise<void> {\n try {\n await write();\n } catch (error) {\n if (!isMissingFileError(error)) throw error;\n\n await write();\n }\n}\n\nlet warnedPublicCache = false;\n\n/**\n * Warn once when the derivative cache sits inside the public folder.\n *\n * A configured `uploads.images.cacheDirectory` is shared by every local disk,\n * so derivatives of a private disk land beside public ones. Inside\n * `public/` (or `storage.publicRoot`) they are served to anyone, bypassing\n * whatever guards the private disk's own route. The paths are hashes, but\n * they are derived from the disk root and the file path, which are not\n * secret.\n */\nexport function warnIfVariantCacheIsPublic(cacheDirectory: string): void {\n if (warnedPublicCache) return;\n\n const configured = config.get(\"storage.publicRoot\", rootPath(\"public\")) as unknown;\n const publicRoots = (Array.isArray(configured) ? configured : [configured])\n .filter((root): root is string => typeof root === \"string\" && root.length > 0)\n .map((root) => path.resolve(root));\n const resolved = path.resolve(cacheDirectory);\n\n if (!publicRoots.some((root) => resolved === root || isPathInside(resolved, root))) return;\n\n warnedPublicCache = true;\n log.warn(\n \"uploads\",\n \"image-variants\",\n `The image variant cache (${resolved}) is inside the public folder, so every cached derivative, private disks included, is publicly served. Move uploads.images.cacheDirectory outside public/.`,\n );\n}\n\n/**\n * Forget that the public-cache warning was shown (tests).\n */\nexport function resetVariantCacheWarnings(): void {\n warnedPublicCache = false;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"image-variant-cache.mjs","names":["config"],"sources":["../../../../../../../../../packages/core/src/http/uploads/image-variant-cache.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport { configuredLocalDiskRoots } from \"../../storage/local-disk-roots\";\nimport type { UploadsImagesConfigurations } from \"../uploads-types\";\nimport { ImageVariantsConfigError } from \"./image-variants-config-error\";\nimport { purgeVariantCacheEntries, variantSourceCacheEntries } from \"./image-variant-cache-entries\";\nimport path from \"node:path\";\nimport { rootPath } from \"../../utils/paths\";\nimport { uploadsConfig } from \"../uploads-config\";\nimport { isPathInside, isPathWithin } from \"./is-path-inside\";\nimport {\n variantGenerationTag,\n variantSourceDirectory,\n variantSourceKey,\n} from \"./variant-cache-key\";\n\n/*\n * Cache housekeeping for image derivatives. Deliberately free of any\n * import of the storage manager or drivers: the local driver calls into this module when it\n * deletes or moves a file, and storage must not import back into the HTTP\n * layer that already imports storage.\n */\n\nasync function realpathOrSelf(target: string): Promise<string> {\n try {\n return await fs.realpath(target);\n } catch {\n return target;\n }\n}\n\nfunction canonicalDirectory(target: string): string {\n const resolved = path.resolve(target);\n try {\n return fsSync.realpathSync(resolved);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") {\n // ENOTDIR, EACCES, ELOOP, ...: a configuration problem, reported as one.\n throw new ImageVariantsConfigError(\n `uploads.images.cacheDirectory (or a local disk root) could not be resolved: ${resolved} (${code ?? \"unknown error\"})`,\n { cause: error },\n );\n }\n const parent = path.dirname(resolved);\n if (parent === resolved) throw error;\n // Resolve the nearest existing ancestor too, so a symlink followed by a\n // not-yet-created directory cannot hide an overlap with a future disk root.\n return path.join(canonicalDirectory(parent), path.basename(resolved));\n }\n}\n\n/** Most distinct cache/disk-root combinations whose overlap check is remembered. */\nconst OVERLAP_CHECKS_LIMIT = 64;\n\n/**\n * Overlap check outcomes, keyed by the cache directory, the disk root and\n * every configured local root. A disk registered later changes the key, so\n * it is checked again; the stored error is rethrown for a refused layout.\n */\nconst overlapChecks = new Map<string, ImageVariantsConfigError | undefined>();\n\nfunction checkCacheOverlap(directory: string, diskRoot: string): void {\n const roots = [diskRoot, ...configuredLocalDiskRoots()];\n const key = [directory, ...roots].join(\"\\0\");\n if (overlapChecks.has(key)) {\n const failure = overlapChecks.get(key);\n if (failure) throw failure;\n return;\n }\n let failure: ImageVariantsConfigError | undefined;\n try {\n const realCache = canonicalDirectory(directory);\n for (const root of roots) {\n if (isPathWithin(canonicalDirectory(root), realCache)) {\n failure = new ImageVariantsConfigError(\n \"uploads.images.cacheDirectory must not equal or contain the storage root of any local disk (including symlinks).\",\n );\n break;\n }\n }\n } catch (error) {\n // Only configuration errors are remembered; anything else is retried next time.\n if (!(error instanceof ImageVariantsConfigError)) throw error;\n failure = error;\n }\n if (overlapChecks.size >= OVERLAP_CHECKS_LIMIT) {\n const oldest = overlapChecks.keys().next();\n if (!oldest.done) overlapChecks.delete(oldest.value);\n }\n overlapChecks.set(key, failure);\n if (failure) throw failure;\n}\n\n/**\n * Forget remembered cache overlap checks, so the next check resolves every\n * path again (tests). Changes to the configured disks are detected without it;\n * a directory replaced by a symlink at runtime is not.\n */\nexport function resetVariantCacheOverlapChecks(): void {\n overlapChecks.clear();\n}\n\n/**\n * The derivative cache directory for a local disk: `uploads.images.cacheDirectory`\n * when the app sets one (shared by every disk; derivatives are keyed by the\n * disk's real root, so they never collide), otherwise\n * `<diskRoot>/.cache/image-variants`. The same rule as\n * `resolveImageVariantsConfig`. Refuses any cache that equals or contains\n * any configured local root, resolving symlinks before comparison. The\n * outcome is remembered per cache, disk root and configured local roots, so\n * repeated requests do not resolve the same paths again.\n *\n * @throws ImageVariantsConfigError when a cache overlaps a local disk root, or\n * when the cache or a root cannot be resolved (for example `ENOTDIR`, `EACCES`)\n */\nexport function variantCacheDirectoryFor(\n diskRoot: string,\n images: Pick<UploadsImagesConfigurations, \"cacheDirectory\"> | undefined = uploadsConfig(\"images\"),\n): string {\n const configured = images?.cacheDirectory;\n const directory = configured\n ? path.resolve(configured)\n : path.join(path.resolve(diskRoot), \".cache\", \"image-variants\");\n checkCacheOverlap(directory, diskRoot);\n return directory;\n}\n\n/**\n * The directory holding every derivative of one file on a local disk, or\n * `undefined` when the file is not inside the disk root. The file does not\n * need to exist any more: only its parent directory is resolved through\n * symlinks, exactly as `resolveUploadPath` resolved it when the derivative\n * was made.\n */\nexport async function variantSourceDirectoryForFile(\n diskRoot: string,\n absolutePath: string,\n): Promise<string | undefined> {\n const realRoot = await realpathOrSelf(path.resolve(diskRoot));\n const realParent = await realpathOrSelf(path.dirname(path.resolve(absolutePath)));\n const realPath = path.join(realParent, path.basename(absolutePath));\n\n if (!isPathInside(realPath, realRoot)) return undefined;\n\n const relativePath = path.relative(realRoot, realPath).split(path.sep).join(\"/\");\n\n return variantSourceDirectory(\n variantCacheDirectoryFor(diskRoot),\n variantSourceKey(realRoot, relativePath),\n );\n}\n\n/**\n * Remove every cached derivative of one file on a local disk.\n *\n * @returns `true` when recognized cache files were removed\n */\nexport async function purgeImageVariantsOfFile(\n diskRoot: string,\n absolutePath: string,\n): Promise<boolean> {\n const directory = await variantSourceDirectoryForFile(diskRoot, absolutePath);\n\n if (!directory) return false;\n\n return purgeVariantCacheEntries(variantSourceCacheEntries(directory));\n}\n\n/**\n * Remove derivatives made from older versions of a source (a different size\n * or mtime), keeping only the `keep` generation. Called after a derivative of\n * the current version has been written, so a source rewritten in place does\n * not leave its old derivatives behind. Only recognized cache files in\n * generation-shaped directories are removed; unrelated entries and all\n * directories and symlinks stay in place.\n */\nexport async function pruneStaleVariantGenerations(\n sourceDirectory: string,\n keep: string,\n): Promise<void> {\n await purgeVariantCacheEntries(variantSourceCacheEntries(sourceDirectory, keep));\n}\n\n/**\n * {@link pruneStaleVariantGenerations}, but only while `keep` is still the\n * source's current generation.\n *\n * A request that read the source before it was rewritten renders an old\n * generation; if it pruned afterwards it would delete the derivatives of the\n * newer version another request had just written. Re-reading the source's\n * size and mtime right before pruning keeps a stale request from doing that.\n */\nexport async function pruneStaleVariantGenerationsIfCurrent(\n sourceAbsolutePath: string,\n sourceDirectory: string,\n keep: string,\n): Promise<void> {\n let current: string;\n\n try {\n const stats = await fs.stat(sourceAbsolutePath);\n current = variantGenerationTag(stats.size, stats.mtimeMs);\n } catch {\n // the source is gone; its derivatives are purged by the delete itself\n return;\n }\n\n if (current !== keep) return;\n\n await pruneStaleVariantGenerations(sourceDirectory, keep);\n}\n\n/**\n * True for \"no such file or directory\"\n */\nexport function isMissingFileError(error: unknown): boolean {\n return (error as NodeJS.ErrnoException | undefined)?.code === \"ENOENT\";\n}\n\n/**\n * Run a derivative write, once more if it fails because its directory\n * vanished: a concurrent request for a newer version of the source may prune\n * the generation directory between `mkdir` and the atomic rename.\n */\nexport async function retryOnVanishedDirectory(write: () => Promise<void>): Promise<void> {\n try {\n await write();\n } catch (error) {\n if (!isMissingFileError(error)) throw error;\n\n await write();\n }\n}\n\nlet warnedPublicCache = false;\n\n/**\n * Warn once when the derivative cache sits inside the public folder.\n *\n * A configured `uploads.images.cacheDirectory` is shared by every local disk,\n * so derivatives of a private disk land beside public ones. Inside\n * `public/` (or `storage.publicRoot`) they are served to anyone, bypassing\n * whatever guards the private disk's own route. The paths are hashes, but\n * they are derived from the disk root and the file path, which are not\n * secret.\n */\nexport function warnIfVariantCacheIsPublic(cacheDirectory: string): void {\n if (warnedPublicCache) return;\n\n const configured = config.get(\"storage.publicRoot\", rootPath(\"public\")) as unknown;\n const publicRoots = (Array.isArray(configured) ? configured : [configured])\n .filter((root): root is string => typeof root === \"string\" && root.length > 0)\n .map((root) => path.resolve(root));\n const resolved = path.resolve(cacheDirectory);\n\n if (!publicRoots.some((root) => resolved === root || isPathInside(resolved, root))) return;\n\n warnedPublicCache = true;\n log.warn(\n \"uploads\",\n \"image-variants\",\n `The image variant cache (${resolved}) is inside the public folder, so every cached derivative, private disks included, is publicly served. Move uploads.images.cacheDirectory outside public/.`,\n );\n}\n\n/**\n * Forget that the public-cache warning was shown (tests).\n */\nexport function resetVariantCacheWarnings(): void {\n warnedPublicCache = false;\n}\n"],"mappings":"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"}
|