@warlock.js/core 5.30.0 → 5.31.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 +142 -36
- package/README.md +28 -23
- package/bin/source-load-hook.mjs +63 -0
- package/bin/warlock.js +102 -42
- package/esm/cli/commands/add.command.mjs +4 -2
- package/esm/cli/commands/add.command.mjs.map +1 -1
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs +69 -0
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -0
- package/esm/cli/commands/agents-md.command.mjs +38 -0
- package/esm/cli/commands/agents-md.command.mjs.map +1 -0
- package/esm/cli/commands/board/board-command.action.mjs +279 -0
- package/esm/cli/commands/board/board-command.action.mjs.map +1 -0
- package/esm/cli/commands/board.command.mjs +78 -0
- package/esm/cli/commands/board.command.mjs.map +1 -0
- package/esm/cli/commands/build.command.mjs +6 -1
- package/esm/cli/commands/build.command.mjs.map +1 -1
- package/esm/cli/commands/check/check-command.action.mjs +57 -0
- package/esm/cli/commands/check/check-command.action.mjs.map +1 -0
- package/esm/cli/commands/check/child-typecheck.mjs +66 -0
- package/esm/cli/commands/check/child-typecheck.mjs.map +1 -0
- package/esm/cli/commands/check/format-problems.mjs +43 -0
- package/esm/cli/commands/check/format-problems.mjs.map +1 -0
- package/esm/cli/commands/check/typecheck-command.action.mjs +61 -0
- package/esm/cli/commands/check/typecheck-command.action.mjs.map +1 -0
- package/esm/cli/commands/check.command.mjs +50 -0
- package/esm/cli/commands/check.command.mjs.map +1 -0
- package/esm/cli/commands/dev-server.command.mjs +9 -1
- package/esm/cli/commands/dev-server.command.mjs.map +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +8 -3
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
- package/esm/cli/commands/doctor/check.types.d.mts +76 -0
- package/esm/cli/commands/doctor/check.types.d.mts.map +1 -0
- package/esm/cli/commands/doctor/checks/config.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs +2 -0
- package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs +3 -0
- package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +4 -0
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs +3 -0
- package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs +14 -6
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
- package/esm/cli/commands/doctor/format-report.mjs +30 -2
- package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
- package/esm/cli/commands/doctor.command.mjs +4 -0
- package/esm/cli/commands/doctor.command.mjs.map +1 -1
- package/esm/cli/commands/explain/explain-command.action.mjs +64 -0
- package/esm/cli/commands/explain/explain-command.action.mjs.map +1 -0
- package/esm/cli/commands/explain.command.mjs +23 -0
- package/esm/cli/commands/explain.command.mjs.map +1 -0
- package/esm/cli/commands/generate/generate.command.mjs +124 -124
- package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs +311 -0
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -0
- package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +341 -0
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -0
- package/esm/cli/commands/generate/templates/stubs.mjs +19 -6
- package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs +137 -0
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -0
- package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs +38 -13
- package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
- package/esm/cli/commands/inspect/inspect-command.action.mjs +72 -0
- package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -0
- package/esm/cli/commands/inspect.command.mjs +39 -0
- package/esm/cli/commands/inspect.command.mjs.map +1 -0
- package/esm/cli/commands/mcp/mcp-command.action.mjs +103 -0
- package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -0
- package/esm/cli/commands/mcp.command.mjs +76 -0
- package/esm/cli/commands/mcp.command.mjs.map +1 -0
- package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
- package/esm/cli/commands/test.command.mjs +131 -0
- package/esm/cli/commands/test.command.mjs.map +1 -0
- package/esm/cli/commands/trace/trace-command.action.mjs +145 -0
- package/esm/cli/commands/trace/trace-command.action.mjs.map +1 -0
- package/esm/cli/commands/trace.command.mjs +60 -0
- package/esm/cli/commands/trace.command.mjs.map +1 -0
- package/esm/cli/commands/typecheck.command.mjs +40 -0
- package/esm/cli/commands/typecheck.command.mjs.map +1 -0
- package/esm/cli/commands/upgrade.command.mjs +46 -0
- package/esm/cli/commands/upgrade.command.mjs.map +1 -0
- package/esm/cli/flush-and-exit.mjs +34 -0
- package/esm/cli/flush-and-exit.mjs.map +1 -0
- package/esm/cli/framework-cli-commands.mjs +23 -1
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/cli/parse-cli-args.mjs +1 -0
- package/esm/cli/parse-cli-args.mjs.map +1 -1
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +34 -13
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-schema.d.mts +67 -0
- package/esm/config/config-schema.d.mts.map +1 -0
- package/esm/config/config-schema.mjs +77 -0
- package/esm/config/config-schema.mjs.map +1 -0
- package/esm/config/index.d.mts +6 -0
- package/esm/config/index.mjs +1 -0
- package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs +2 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs +26 -2
- package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +3 -2
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/single-server-warnings.mjs.map +1 -1
- package/esm/connectors/socket-connector.d.mts.map +1 -1
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/container/index.d.mts.map +1 -1
- package/esm/container/index.mjs.map +1 -1
- package/esm/database/migrate-action.mjs.map +1 -1
- package/esm/database/models/database-log/database-log.d.mts +0 -28
- package/esm/database/models/database-log/database-log.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +4 -0
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.mjs +2 -0
- package/esm/database/seeds/seeder.errors.mjs.map +1 -1
- package/esm/dev-server/boot-precondition-error.mjs +1 -0
- package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
- package/esm/dev-server/create-worker.mjs +15 -9
- package/esm/dev-server/create-worker.mjs.map +1 -1
- package/esm/dev-server/dev-agent-tooling.mjs +135 -0
- package/esm/dev-server/dev-agent-tooling.mjs.map +1 -0
- package/esm/dev-server/dev-logger.mjs.map +1 -1
- package/esm/dev-server/development-server.mjs +8 -0
- package/esm/dev-server/development-server.mjs.map +1 -1
- package/esm/dev-server/files-orchestrator.mjs +4 -5
- package/esm/dev-server/files-orchestrator.mjs.map +1 -1
- package/esm/dev-server/files-watcher.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +2 -3
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +33 -0
- package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs.map +1 -0
- package/esm/dev-server/health-checker/default-health-checkers.mjs +31 -0
- package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -0
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +9 -3
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs +15 -4
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
- package/esm/dev-server/health-checker/oxlint-runner.mjs +302 -0
- package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs +42 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs.map +1 -0
- package/esm/dev-server/loader/loader-port-acks.mjs +1 -1
- package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -1
- package/esm/dev-server/loader/register-loader.mjs +1 -1
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-hook.mjs +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs +1 -1
- package/esm/dev-server/model-resource-typings.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +1 -0
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/parse-imports.mjs +1 -1
- package/esm/dev-server/parse-imports.mjs.map +1 -1
- package/esm/dev-server/route-types-publisher.mjs +1 -1
- package/esm/dev-server/start-development-server.mjs.map +1 -1
- package/esm/dev-server/translation-keys-sources.mjs +1 -1
- package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
- package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
- package/esm/dev-server/type-generator.mjs +3 -3
- package/esm/dev-server/type-generator.mjs.map +1 -1
- package/esm/dev-server/types.d.mts.map +1 -1
- package/esm/errors/container-key-missing-error.mjs +1 -0
- package/esm/errors/container-key-missing-error.mjs.map +1 -1
- package/esm/errors/error-codes.d.mts +653 -0
- package/esm/errors/error-codes.d.mts.map +1 -0
- package/esm/errors/error-codes.mjs +634 -0
- package/esm/errors/error-codes.mjs.map +1 -0
- package/esm/errors/esbuild-binary-missing-error.mjs +1 -0
- package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
- package/esm/errors/index.d.mts +3 -1
- package/esm/errors/index.mjs +3 -1
- package/esm/errors/unknown-locale-error.mjs +1 -0
- package/esm/errors/unknown-locale-error.mjs.map +1 -1
- package/esm/errors/warlock-error.d.mts +23 -0
- package/esm/errors/warlock-error.d.mts.map +1 -0
- package/esm/errors/warlock-error.mjs +22 -0
- package/esm/errors/warlock-error.mjs.map +1 -0
- package/esm/generations/add-command.action.mjs +19 -3
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/features/access.feature.mjs +1 -1
- package/esm/generations/features/access.feature.mjs.map +1 -1
- package/esm/generations/features/bull-board.feature.mjs +1 -1
- package/esm/generations/features/bull-board.feature.mjs.map +1 -1
- package/esm/generations/features/mysql.feature.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +5 -2
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/queue.feature.mjs +1 -1
- package/esm/generations/features/queue.feature.mjs.map +1 -1
- package/esm/generations/features/react-email.feature.mjs +1 -1
- package/esm/generations/features/react-email.feature.mjs.map +1 -1
- package/esm/generations/features/shadcn.feature.mjs +1 -1
- package/esm/generations/features/shadcn.feature.mjs.map +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
- package/esm/generations/features/sitemap.feature.mjs +1 -1
- package/esm/generations/features/sitemap.feature.mjs.map +1 -1
- package/esm/generations/features/tailwind.feature.mjs +1 -1
- package/esm/generations/features/tailwind.feature.mjs.map +1 -1
- package/esm/generations/features/test.feature.mjs +11 -6
- package/esm/generations/features/test.feature.mjs.map +1 -1
- package/esm/generations/features/web.feature.mjs +1 -1
- package/esm/generations/features/web.feature.mjs.map +1 -1
- package/esm/generations/generation-fs.mjs +73 -0
- package/esm/generations/generation-fs.mjs.map +1 -0
- package/esm/generations/generation-run.mjs +185 -0
- package/esm/generations/generation-run.mjs.map +1 -0
- package/esm/generations/stubs.mjs +155 -13
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/bounded-stream-queue.d.mts +10 -0
- package/esm/http/bounded-stream-queue.d.mts.map +1 -0
- package/esm/http/bounded-stream-queue.mjs +97 -0
- package/esm/http/bounded-stream-queue.mjs.map +1 -0
- package/esm/http/build-rate-limit-options.d.mts +13 -0
- package/esm/http/build-rate-limit-options.d.mts.map +1 -1
- package/esm/http/build-rate-limit-options.mjs.map +1 -1
- package/esm/http/conditional-request.d.mts +86 -0
- package/esm/http/conditional-request.d.mts.map +1 -0
- package/esm/http/conditional-request.mjs +121 -0
- package/esm/http/conditional-request.mjs.map +1 -0
- package/esm/http/csp.d.mts +2 -0
- package/esm/http/csp.d.mts.map +1 -1
- package/esm/http/csp.mjs +1 -0
- package/esm/http/csp.mjs.map +1 -1
- package/esm/http/csrf-origin-policy.mjs.map +1 -1
- package/esm/http/database/RequestLog.d.mts +24 -84
- package/esm/http/database/RequestLog.d.mts.map +1 -1
- package/esm/http/errors/errors.d.mts +2 -0
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/errors/errors.mjs +1 -0
- package/esm/http/errors/errors.mjs.map +1 -1
- package/esm/http/escape-header-value.d.mts +18 -0
- package/esm/http/escape-header-value.d.mts.map +1 -0
- package/esm/http/escape-header-value.mjs +27 -0
- package/esm/http/escape-header-value.mjs.map +1 -0
- package/esm/http/flush-pending-cookies.mjs.map +1 -1
- package/esm/http/index.d.mts +5 -2
- package/esm/http/index.mjs +4 -1
- package/esm/http/lazy-static.mjs +194 -0
- package/esm/http/lazy-static.mjs.map +1 -0
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/plugins.d.mts.map +1 -1
- package/esm/http/plugins.mjs +7 -4
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/rate-limit-cache-store.mjs +2 -1
- package/esm/http/rate-limit-cache-store.mjs.map +1 -1
- package/esm/http/request-log-snapshot.d.mts +12 -5
- package/esm/http/request-log-snapshot.d.mts.map +1 -1
- package/esm/http/request-log-snapshot.mjs +83 -4
- package/esm/http/request-log-snapshot.mjs.map +1 -1
- package/esm/http/request.d.mts +2 -2
- package/esm/http/request.d.mts.map +1 -1
- package/esm/http/request.mjs +5 -4
- package/esm/http/request.mjs.map +1 -1
- package/esm/http/response.d.mts +11 -1
- package/esm/http/response.d.mts.map +1 -1
- package/esm/http/response.mjs +164 -76
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/safe-redirect.d.mts +51 -0
- package/esm/http/safe-redirect.d.mts.map +1 -0
- package/esm/http/safe-redirect.mjs +80 -0
- package/esm/http/safe-redirect.mjs.map +1 -0
- package/esm/http/serialized.d.mts.map +1 -1
- package/esm/http/server.d.mts +3 -1
- package/esm/http/server.d.mts.map +1 -1
- package/esm/http/server.mjs +14 -4
- package/esm/http/server.mjs.map +1 -1
- package/esm/http/stream-transport.mjs +4 -2
- package/esm/http/stream-transport.mjs.map +1 -1
- package/esm/http/types.d.mts +44 -11
- package/esm/http/types.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variant.mjs +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts +10 -7
- package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.mjs +61 -24
- package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
- package/esm/http/uploads/image-variant-cache-entries.mjs +78 -0
- package/esm/http/uploads/image-variant-cache-entries.mjs.map +1 -0
- package/esm/http/uploads/image-variant-cache.mjs +72 -30
- package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
- package/esm/http/uploads/image-variant-types.d.mts +2 -0
- package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts +3 -1
- package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs +3 -2
- package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
- package/esm/http/uploads/load-variant-source.mjs +1 -1
- package/esm/http/uploads/load-variant-source.mjs.map +1 -1
- package/esm/http/uploads/purge-image-variants.d.mts +7 -2
- package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/purge-image-variants.mjs +16 -16
- package/esm/http/uploads/purge-image-variants.mjs.map +1 -1
- package/esm/http/uploads/remote-variant-source.mjs +115 -0
- package/esm/http/uploads/remote-variant-source.mjs.map +1 -0
- package/esm/http/uploads/resolve-image-variant.d.mts +3 -4
- package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
- package/esm/http/uploads/resolve-image-variant.mjs +10 -18
- package/esm/http/uploads/resolve-image-variant.mjs.map +1 -1
- package/esm/http/uploads/resolve-image-variants-config.mjs +5 -3
- package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
- package/esm/http/uploads/resolve-remote-image-variant.mjs +89 -0
- package/esm/http/uploads/resolve-remote-image-variant.mjs.map +1 -0
- package/esm/http/uploads/trim-image-variant-cache.mjs +193 -0
- package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -0
- package/esm/http/uploads/uploaded-file.controller.d.mts +5 -3
- package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.mjs +16 -8
- 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-types.d.mts +6 -2
- package/esm/http/uploads-types.d.mts.map +1 -1
- package/esm/index.d.mts +17 -6
- package/esm/index.mjs +14 -3
- package/esm/localization/parse-locale-dictionary.d.mts +2 -0
- package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/parse-locale-dictionary.mjs +1 -0
- package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
- package/esm/mail/config.d.mts +12 -1
- package/esm/mail/config.d.mts.map +1 -1
- package/esm/mail/config.mjs +16 -1
- package/esm/mail/config.mjs.map +1 -1
- package/esm/mail/index.d.mts +1 -1
- package/esm/mail/index.mjs +1 -1
- package/esm/net/index.d.mts +2 -0
- package/esm/net/index.mjs +3 -0
- package/esm/openapi/build-openapi-document.d.mts.map +1 -1
- package/esm/openapi/build-openapi-document.mjs +8 -5
- package/esm/openapi/build-openapi-document.mjs.map +1 -1
- package/esm/openapi/error-responses.mjs +28 -2
- package/esm/openapi/error-responses.mjs.map +1 -1
- package/esm/openapi/postman/build-request-body.mjs.map +1 -1
- package/esm/openapi/postman/build-request-url.mjs.map +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
- package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
- package/esm/openapi/postman/schema-refs.mjs.map +1 -1
- package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
- package/esm/openapi/request-schemas.mjs.map +1 -1
- package/esm/openapi/response-schemas.mjs.map +1 -1
- package/esm/openapi/schema-registry.d.mts +1 -0
- package/esm/openapi/schema-registry.mjs.map +1 -1
- package/esm/openapi/security.mjs.map +1 -1
- package/esm/openapi/types.d.mts +3 -2
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/assert-generated-imports.mjs +1 -0
- package/esm/production/assert-generated-imports.mjs.map +1 -1
- package/esm/production/production-builder.mjs +12 -4
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/resolve-build-config.mjs +1 -0
- package/esm/production/resolve-build-config.mjs.map +1 -1
- package/esm/production/route-registration-child.mjs.map +1 -1
- package/esm/production/route-registration-snapshot.mjs.map +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/types.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/resource/resource.d.mts.map +1 -1
- package/esm/resource/resource.mjs.map +1 -1
- package/esm/resource/types.d.mts.map +1 -1
- package/esm/restful/restful.d.mts +5 -5
- package/esm/restful/restful.d.mts.map +1 -1
- package/esm/restful/restful.mjs.map +1 -1
- package/esm/router/build-route-rate-limit.mjs.map +1 -1
- package/esm/router/dev-dispatch.mjs +31 -12
- package/esm/router/dev-dispatch.mjs.map +1 -1
- package/esm/router/index.d.mts +4 -2
- package/esm/router/index.mjs +2 -0
- package/esm/router/log-request-lifecycle.mjs.map +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
- package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
- package/esm/router/resolve-route-rate-limit.mjs +47 -0
- package/esm/router/resolve-route-rate-limit.mjs.map +1 -0
- package/esm/router/resolve-route-validation.mjs +19 -0
- package/esm/router/resolve-route-validation.mjs.map +1 -0
- package/esm/router/route-guard-names.mjs +30 -0
- package/esm/router/route-guard-names.mjs.map +1 -0
- package/esm/router/route-name-taken-error.d.mts +14 -0
- package/esm/router/route-name-taken-error.d.mts.map +1 -0
- package/esm/router/route-name-taken-error.mjs +18 -0
- package/esm/router/route-name-taken-error.mjs.map +1 -0
- package/esm/router/router.d.mts +32 -13
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +71 -38
- package/esm/router/router.mjs.map +1 -1
- package/esm/router/types.d.mts +137 -17
- package/esm/router/types.d.mts.map +1 -1
- package/esm/router/unguarded-route-diagnostics.d.mts +40 -0
- package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -0
- package/esm/router/unguarded-route-diagnostics.mjs +95 -0
- package/esm/router/unguarded-route-diagnostics.mjs.map +1 -0
- 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/local-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.mjs.map +1 -1
- package/esm/storage/local-disk-roots.mjs +24 -0
- package/esm/storage/local-disk-roots.mjs.map +1 -0
- package/esm/storage/storage.d.mts +14 -0
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/storage.mjs +22 -0
- package/esm/storage/storage.mjs.map +1 -1
- package/esm/storage/types.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts +2 -0
- package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs +1 -0
- package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
- package/esm/tests/authenticated-test-client.d.mts +32 -0
- package/esm/tests/authenticated-test-client.d.mts.map +1 -0
- package/esm/tests/authenticated-test-client.mjs +40 -0
- package/esm/tests/authenticated-test-client.mjs.map +1 -0
- package/esm/tests/factories.d.mts +59 -0
- package/esm/tests/factories.d.mts.map +1 -0
- package/esm/tests/factories.mjs +105 -0
- package/esm/tests/factories.mjs.map +1 -0
- package/esm/tests/fakes/cache-fake.d.mts +29 -0
- package/esm/tests/fakes/cache-fake.d.mts.map +1 -0
- package/esm/tests/fakes/cache-fake.mjs +79 -0
- package/esm/tests/fakes/cache-fake.mjs.map +1 -0
- package/esm/tests/fakes/clock-fake.d.mts +32 -0
- package/esm/tests/fakes/clock-fake.d.mts.map +1 -0
- package/esm/tests/fakes/clock-fake.mjs +69 -0
- package/esm/tests/fakes/clock-fake.mjs.map +1 -0
- package/esm/tests/fakes/fake-assertion-error.d.mts +13 -0
- package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -0
- package/esm/tests/fakes/fake-assertion-error.mjs +20 -0
- package/esm/tests/fakes/fake-assertion-error.mjs.map +1 -0
- package/esm/tests/fakes/ids-fake.d.mts +22 -0
- package/esm/tests/fakes/ids-fake.d.mts.map +1 -0
- package/esm/tests/fakes/ids-fake.mjs +57 -0
- package/esm/tests/fakes/ids-fake.mjs.map +1 -0
- package/esm/tests/fakes/index.d.mts +8 -0
- package/esm/tests/fakes/index.mjs +10 -0
- package/esm/tests/fakes/mail-fake.d.mts +41 -0
- package/esm/tests/fakes/mail-fake.d.mts.map +1 -0
- package/esm/tests/fakes/mail-fake.mjs +111 -0
- package/esm/tests/fakes/mail-fake.mjs.map +1 -0
- package/esm/tests/fakes/queue-fake.d.mts +48 -0
- package/esm/tests/fakes/queue-fake.d.mts.map +1 -0
- package/esm/tests/fakes/queue-fake.mjs +134 -0
- package/esm/tests/fakes/queue-fake.mjs.map +1 -0
- package/esm/tests/fakes/storage-fake.d.mts +31 -0
- package/esm/tests/fakes/storage-fake.d.mts.map +1 -0
- package/esm/tests/fakes/storage-fake.mjs +122 -0
- package/esm/tests/fakes/storage-fake.mjs.map +1 -0
- package/esm/tests/fakes/test-fakes.d.mts +39 -0
- package/esm/tests/fakes/test-fakes.d.mts.map +1 -0
- package/esm/tests/fakes/test-fakes.mjs +90 -0
- package/esm/tests/fakes/test-fakes.mjs.map +1 -0
- package/esm/tests/index.d.mts +14 -2
- package/esm/tests/index.mjs +15 -2
- package/esm/tests/snapshot-response.d.mts +34 -0
- package/esm/tests/snapshot-response.d.mts.map +1 -0
- package/esm/tests/snapshot-response.mjs +42 -0
- package/esm/tests/snapshot-response.mjs.map +1 -0
- package/esm/tests/start-http-development-server.d.mts +22 -0
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +36 -3
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-helpers.d.mts +20 -1
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-helpers.mjs +40 -27
- package/esm/tests/test-helpers.mjs.map +1 -1
- package/esm/tests/test-http-server.d.mts +62 -0
- package/esm/tests/test-http-server.d.mts.map +1 -0
- package/esm/tests/test-http-server.mjs +119 -0
- package/esm/tests/test-http-server.mjs.map +1 -0
- package/esm/tests/vitest-setup.d.mts +11 -0
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tests/vitest-setup.mjs +12 -4
- package/esm/tests/vitest-setup.mjs.map +1 -1
- package/esm/tooling/agents-md/agents-md-markers.d.mts +27 -0
- package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -0
- package/esm/tooling/agents-md/agents-md-markers.mjs +59 -0
- package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -0
- package/esm/tooling/agents-md/agents-md-refresher.d.mts +36 -0
- package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -0
- package/esm/tooling/agents-md/agents-md-refresher.mjs +72 -0
- package/esm/tooling/agents-md/agents-md-refresher.mjs.map +1 -0
- package/esm/tooling/agents-md/index.mjs +7 -0
- package/esm/tooling/agents-md/installed-skills.d.mts +30 -0
- package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -0
- package/esm/tooling/agents-md/installed-skills.mjs +74 -0
- package/esm/tooling/agents-md/installed-skills.mjs.map +1 -0
- package/esm/tooling/agents-md/render-agents-md.d.mts +33 -0
- package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -0
- package/esm/tooling/agents-md/render-agents-md.mjs +195 -0
- package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -0
- package/esm/tooling/agents-md/write-agents-md.d.mts +33 -0
- package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -0
- package/esm/tooling/agents-md/write-agents-md.mjs +49 -0
- package/esm/tooling/agents-md/write-agents-md.mjs.map +1 -0
- package/esm/tooling/board/board-message.d.mts +31 -0
- package/esm/tooling/board/board-message.d.mts.map +1 -0
- package/esm/tooling/board/board-message.mjs +86 -0
- package/esm/tooling/board/board-message.mjs.map +1 -0
- package/esm/tooling/board/board.d.mts +109 -0
- package/esm/tooling/board/board.d.mts.map +1 -0
- package/esm/tooling/board/board.mjs +406 -0
- package/esm/tooling/board/board.mjs.map +1 -0
- package/esm/tooling/board/board.types.d.mts +72 -0
- package/esm/tooling/board/board.types.d.mts.map +1 -0
- package/esm/tooling/board/board.types.mjs +54 -0
- package/esm/tooling/board/board.types.mjs.map +1 -0
- package/esm/tooling/check/changed-files.d.mts +33 -0
- package/esm/tooling/check/changed-files.d.mts.map +1 -0
- package/esm/tooling/check/changed-files.mjs +73 -0
- package/esm/tooling/check/changed-files.mjs.map +1 -0
- package/esm/tooling/check/check-report.types.d.mts +62 -0
- package/esm/tooling/check/check-report.types.d.mts.map +1 -0
- package/esm/tooling/check/check-report.types.mjs +37 -0
- package/esm/tooling/check/check-report.types.mjs.map +1 -0
- package/esm/tooling/check/code-style-conventions.mjs +106 -0
- package/esm/tooling/check/code-style-conventions.mjs.map +1 -0
- package/esm/tooling/check/conventions-step.d.mts +34 -0
- package/esm/tooling/check/conventions-step.d.mts.map +1 -0
- package/esm/tooling/check/conventions-step.mjs +184 -0
- package/esm/tooling/check/conventions-step.mjs.map +1 -0
- package/esm/tooling/check/environment-step.d.mts +18 -0
- package/esm/tooling/check/environment-step.d.mts.map +1 -0
- package/esm/tooling/check/environment-step.mjs +78 -0
- package/esm/tooling/check/environment-step.mjs.map +1 -0
- package/esm/tooling/check/index.d.mts +8 -0
- package/esm/tooling/check/index.mjs +10 -0
- package/esm/tooling/check/lint-step.d.mts +19 -0
- package/esm/tooling/check/lint-step.d.mts.map +1 -0
- package/esm/tooling/check/lint-step.mjs +111 -0
- package/esm/tooling/check/lint-step.mjs.map +1 -0
- package/esm/tooling/check/request-input.mjs +132 -0
- package/esm/tooling/check/request-input.mjs.map +1 -0
- package/esm/tooling/check/run-check.d.mts +35 -0
- package/esm/tooling/check/run-check.d.mts.map +1 -0
- package/esm/tooling/check/run-check.mjs +192 -0
- package/esm/tooling/check/run-check.mjs.map +1 -0
- package/esm/tooling/check/run-tests.d.mts +48 -0
- package/esm/tooling/check/run-tests.d.mts.map +1 -0
- package/esm/tooling/check/run-tests.mjs +93 -0
- package/esm/tooling/check/run-tests.mjs.map +1 -0
- package/esm/tooling/check/security-conventions.mjs +648 -0
- package/esm/tooling/check/security-conventions.mjs.map +1 -0
- package/esm/tooling/check/source-ast.mjs +195 -0
- package/esm/tooling/check/source-ast.mjs.map +1 -0
- package/esm/tooling/check/source-files.mjs +27 -0
- package/esm/tooling/check/source-files.mjs.map +1 -0
- package/esm/tooling/check/tests-step.d.mts +34 -0
- package/esm/tooling/check/tests-step.d.mts.map +1 -0
- package/esm/tooling/check/tests-step.mjs +177 -0
- package/esm/tooling/check/tests-step.mjs.map +1 -0
- package/esm/tooling/dev-state/dev-server-state.d.mts +39 -0
- package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -0
- package/esm/tooling/dev-state/dev-server-state.mjs +67 -0
- package/esm/tooling/dev-state/dev-server-state.mjs.map +1 -0
- package/esm/tooling/devtools/devtools-client.d.mts +91 -0
- package/esm/tooling/devtools/devtools-client.d.mts.map +1 -0
- package/esm/tooling/devtools/devtools-client.mjs +155 -0
- package/esm/tooling/devtools/devtools-client.mjs.map +1 -0
- package/esm/tooling/generate/generation.d.mts +78 -0
- package/esm/tooling/generate/generation.d.mts.map +1 -0
- package/esm/tooling/generate/generation.mjs +123 -0
- package/esm/tooling/generate/generation.mjs.map +1 -0
- package/esm/tooling/generate/generator-spec.d.mts +57 -0
- package/esm/tooling/generate/generator-spec.d.mts.map +1 -0
- package/esm/tooling/generate/generator-spec.mjs +102 -0
- package/esm/tooling/generate/generator-spec.mjs.map +1 -0
- package/esm/tooling/generate/index.mjs +6 -0
- package/esm/tooling/generate/project-files.mjs +121 -0
- package/esm/tooling/generate/project-files.mjs.map +1 -0
- package/esm/tooling/generate/run-cli.d.mts +40 -0
- package/esm/tooling/generate/run-cli.d.mts.map +1 -0
- package/esm/tooling/generate/run-cli.mjs +93 -0
- package/esm/tooling/generate/run-cli.mjs.map +1 -0
- package/esm/tooling/generate/unified-diff.d.mts +37 -0
- package/esm/tooling/generate/unified-diff.d.mts.map +1 -0
- package/esm/tooling/generate/unified-diff.mjs +161 -0
- package/esm/tooling/generate/unified-diff.mjs.map +1 -0
- package/esm/tooling/index.d.mts +41 -0
- package/esm/tooling/index.mjs +45 -0
- package/esm/tooling/inspect/boot-for-inspect.d.mts +23 -0
- package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -0
- package/esm/tooling/inspect/boot-for-inspect.mjs +63 -0
- package/esm/tooling/inspect/boot-for-inspect.mjs.map +1 -0
- package/esm/tooling/inspect/collect-config.mjs +77 -0
- package/esm/tooling/inspect/collect-config.mjs.map +1 -0
- package/esm/tooling/inspect/collect-models.d.mts +9 -0
- package/esm/tooling/inspect/collect-models.d.mts.map +1 -0
- package/esm/tooling/inspect/collect-models.mjs +154 -0
- package/esm/tooling/inspect/collect-models.mjs.map +1 -0
- package/esm/tooling/inspect/collect-packages.d.mts +10 -0
- package/esm/tooling/inspect/collect-packages.d.mts.map +1 -0
- package/esm/tooling/inspect/collect-packages.mjs +157 -0
- package/esm/tooling/inspect/collect-packages.mjs.map +1 -0
- package/esm/tooling/inspect/collect-pages.mjs +108 -0
- package/esm/tooling/inspect/collect-pages.mjs.map +1 -0
- package/esm/tooling/inspect/collect-routes.mjs +168 -0
- package/esm/tooling/inspect/collect-routes.mjs.map +1 -0
- package/esm/tooling/inspect/event-recorder.d.mts +37 -0
- package/esm/tooling/inspect/event-recorder.d.mts.map +1 -0
- package/esm/tooling/inspect/event-recorder.mjs +91 -0
- package/esm/tooling/inspect/event-recorder.mjs.map +1 -0
- package/esm/tooling/inspect/index.d.mts +7 -0
- package/esm/tooling/inspect/index.mjs +7 -0
- package/esm/tooling/inspect/inspect-app.d.mts +53 -0
- package/esm/tooling/inspect/inspect-app.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-app.mjs +92 -0
- package/esm/tooling/inspect/inspect-app.mjs.map +1 -0
- package/esm/tooling/inspect/inspect-report.schema.d.mts +15 -0
- package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-report.schema.mjs +463 -0
- package/esm/tooling/inspect/inspect-report.schema.mjs.map +1 -0
- package/esm/tooling/inspect/inspect-report.types.d.mts +196 -0
- package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-report.types.mjs +33 -0
- package/esm/tooling/inspect/inspect-report.types.mjs.map +1 -0
- package/esm/tooling/mcp/create-mcp-context.d.mts +26 -0
- package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -0
- package/esm/tooling/mcp/create-mcp-context.mjs +75 -0
- package/esm/tooling/mcp/create-mcp-context.mjs.map +1 -0
- package/esm/tooling/mcp/db-schema.d.mts +49 -0
- package/esm/tooling/mcp/db-schema.d.mts.map +1 -0
- package/esm/tooling/mcp/db-schema.mjs +56 -0
- package/esm/tooling/mcp/db-schema.mjs.map +1 -0
- package/esm/tooling/mcp/docs-search.d.mts +72 -0
- package/esm/tooling/mcp/docs-search.d.mts.map +1 -0
- package/esm/tooling/mcp/docs-search.mjs +178 -0
- package/esm/tooling/mcp/docs-search.mjs.map +1 -0
- package/esm/tooling/mcp/index.mjs +9 -0
- package/esm/tooling/mcp/load-ai-tools.d.mts +62 -0
- package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -0
- package/esm/tooling/mcp/load-ai-tools.mjs +44 -0
- package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -0
- package/esm/tooling/mcp/mcp-tools.d.mts +60 -0
- package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -0
- package/esm/tooling/mcp/mcp-tools.mjs +513 -0
- package/esm/tooling/mcp/mcp-tools.mjs.map +1 -0
- package/esm/tooling/mcp/start-mcp-server.d.mts +56 -0
- package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -0
- package/esm/tooling/mcp/start-mcp-server.mjs +126 -0
- package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -0
- package/esm/tooling/mcp/tool-input.d.mts +75 -0
- package/esm/tooling/mcp/tool-input.d.mts.map +1 -0
- package/esm/tooling/mcp/tool-input.mjs +72 -0
- package/esm/tooling/mcp/tool-input.mjs.map +1 -0
- package/esm/tooling/problem.d.mts +45 -0
- package/esm/tooling/problem.d.mts.map +1 -0
- package/esm/tooling/problem.mjs +28 -0
- package/esm/tooling/problem.mjs.map +1 -0
- package/esm/tooling/trace/trace-report.types.d.mts +71 -0
- package/esm/tooling/trace/trace-report.types.d.mts.map +1 -0
- package/esm/tooling/trace/trace-report.types.mjs +7 -0
- package/esm/tooling/trace/trace-report.types.mjs.map +1 -0
- package/esm/tooling/trace/trace-request.d.mts +83 -0
- package/esm/tooling/trace/trace-request.d.mts.map +1 -0
- package/esm/tooling/trace/trace-request.mjs +241 -0
- package/esm/tooling/trace/trace-request.mjs.map +1 -0
- package/esm/tooling/typecheck/index.d.mts +1 -0
- package/esm/tooling/typecheck/index.mjs +3 -0
- package/esm/tooling/typecheck/run-typecheck.d.mts +59 -0
- package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -0
- package/esm/tooling/typecheck/run-typecheck.mjs +153 -0
- package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -0
- package/esm/upgrade/codemods/head-viewport.mjs +46 -0
- package/esm/upgrade/codemods/head-viewport.mjs.map +1 -0
- package/esm/upgrade/codemods/helpers.mjs +81 -0
- package/esm/upgrade/codemods/helpers.mjs.map +1 -0
- package/esm/upgrade/codemods/index.mjs +34 -0
- package/esm/upgrade/codemods/index.mjs.map +1 -0
- package/esm/upgrade/codemods/logger-sync-calls.mjs +57 -0
- package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -0
- package/esm/upgrade/codemods/package-json.mjs +122 -0
- package/esm/upgrade/codemods/package-json.mjs.map +1 -0
- package/esm/upgrade/codemods/request-log-snapshot.mjs +82 -0
- package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -0
- package/esm/upgrade/codemods/review-sites.mjs +262 -0
- package/esm/upgrade/codemods/review-sites.mjs.map +1 -0
- package/esm/upgrade/diff.mjs +119 -0
- package/esm/upgrade/diff.mjs.map +1 -0
- package/esm/upgrade/format-upgrade-report.mjs +32 -0
- package/esm/upgrade/format-upgrade-report.mjs.map +1 -0
- package/esm/upgrade/load-ts-morph.mjs +48 -0
- package/esm/upgrade/load-ts-morph.mjs.map +1 -0
- package/esm/upgrade/notes.mjs +16 -0
- package/esm/upgrade/notes.mjs.map +1 -0
- package/esm/upgrade/run-upgrade.mjs +246 -0
- package/esm/upgrade/run-upgrade.mjs.map +1 -0
- package/esm/upgrade/upgrade-command.action.mjs +37 -0
- package/esm/upgrade/upgrade-command.action.mjs.map +1 -0
- package/esm/upgrade/version.mjs +39 -0
- package/esm/upgrade/version.mjs.map +1 -0
- package/esm/use-cases/use-cases-registry.mjs.map +1 -1
- package/esm/utils/clock.d.mts +33 -0
- package/esm/utils/clock.d.mts.map +1 -0
- package/esm/utils/clock.mjs +27 -0
- package/esm/utils/clock.mjs.map +1 -0
- package/esm/utils/framework-vesion.mjs +1 -1
- package/esm/utils/framework-vesion.mjs.map +1 -1
- package/esm/utils/ids.d.mts +32 -0
- package/esm/utils/ids.d.mts.map +1 -0
- package/esm/utils/ids.mjs +33 -0
- package/esm/utils/ids.mjs.map +1 -0
- package/esm/utils/index.d.mts +3 -0
- package/esm/utils/index.mjs +3 -0
- package/esm/utils/runtime.d.mts +59 -0
- package/esm/utils/runtime.d.mts.map +1 -0
- package/esm/utils/runtime.mjs +85 -0
- package/esm/utils/runtime.mjs.map +1 -0
- package/esm/validation/index.d.mts +1 -1
- package/esm/validation/types.d.mts +57 -2
- package/esm/validation/types.d.mts.map +1 -1
- package/esm/validation/validateAll.mjs +19 -2
- package/esm/validation/validateAll.mjs.map +1 -1
- package/esm/validation/validation-failure-status.mjs +15 -0
- package/esm/validation/validation-failure-status.mjs.map +1 -0
- package/esm/validation/validators/file-validator.d.mts +0 -16
- package/esm/validation/validators/file-validator.d.mts.map +1 -1
- package/esm/warlock-config/bundle-config.mjs +1 -1
- package/esm/warlock-config/types.d.mts +27 -3
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/llms-full.txt +3166 -736
- package/llms.txt +16 -6
- package/package.json +43 -13
- package/schemas/inspect-report.schema.json +554 -0
- package/skills/README.md +9 -0
- package/skills/add-connector/SKILL.md +26 -38
- package/skills/benchmark-code/SKILL.md +30 -24
- package/skills/build-restful/SKILL.md +14 -14
- package/skills/build-url/SKILL.md +18 -18
- package/skills/configure-app/SKILL.md +107 -14
- package/skills/create-controller/SKILL.md +25 -12
- package/skills/create-module/SKILL.md +3 -3
- package/skills/define-resource/SKILL.md +32 -29
- package/skills/encrypt-data/SKILL.md +21 -19
- package/skills/generate-openapi/SKILL.md +50 -24
- package/skills/hash-password/SKILL.md +2 -2
- package/skills/health-checks/SKILL.md +24 -7
- package/skills/index.md +9 -4
- package/skills/lower-stage3-decorators/SKILL.md +4 -4
- package/skills/make-endpoint/SKILL.md +110 -0
- package/skills/model-factories/SKILL.md +92 -0
- package/skills/process-image/SKILL.md +32 -30
- package/skills/register-route/SKILL.md +109 -10
- package/skills/request-memo/SKILL.md +1 -1
- package/skills/request-tracing/SKILL.md +4 -1
- package/skills/resolve-path/SKILL.md +45 -44
- package/skills/retry-operation/SKILL.md +20 -11
- package/skills/run-app/SKILL.md +106 -22
- package/skills/send-response/SKILL.md +179 -14
- package/skills/store-file/SKILL.md +93 -53
- package/skills/test-fakes/SKILL.md +123 -0
- package/skills/test-http/SKILL.md +125 -21
- package/skills/test-service/SKILL.md +41 -1
- package/skills/update-packages/SKILL.md +29 -18
- package/skills/upgrade-from-5-29/SKILL.md +413 -0
- package/skills/upload-file/SKILL.md +31 -33
- package/skills/use-app-context/SKILL.md +38 -31
- package/skills/use-middleware/SKILL.md +45 -25
- package/skills/use-model-transformers/SKILL.md +37 -28
- package/skills/use-repository/SKILL.md +2 -2
- package/skills/validate-input/SKILL.md +72 -28
- package/skills/warlock-agents-md/SKILL.md +96 -0
- package/skills/warlock-board/SKILL.md +123 -0
- package/skills/warlock-check/SKILL.md +132 -0
- package/skills/warlock-conventions/SKILL.md +115 -0
- package/skills/warlock-doctor/SKILL.md +55 -22
- package/skills/warlock-inspect/SKILL.md +134 -0
- package/skills/warlock-mcp/SKILL.md +120 -0
- package/skills/warlock-routes/SKILL.md +18 -11
- package/skills/warlock-trace/SKILL.md +81 -0
- package/skills/wire-socket/SKILL.md +8 -8
- package/skills/write-seeder/SKILL.md +46 -32
- package/skills/write-use-case/SKILL.md +40 -27
- package/esm/http/uploads/matches-if-none-match.mjs +0 -13
- package/esm/http/uploads/matches-if-none-match.mjs.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region ../../packages/core/src/tests/fakes/test-fakes.d.ts
|
|
2
|
+
/** The fakes the test kit installs. */
|
|
3
|
+
declare const TEST_FAKE_NAMES: readonly ["mail", "queue", "cache", "storage", "clock", "ids"];
|
|
4
|
+
type TestFakeName = (typeof TEST_FAKE_NAMES)[number];
|
|
5
|
+
/**
|
|
6
|
+
* Which fakes to install.
|
|
7
|
+
*
|
|
8
|
+
* - `true` (the default) — all of them.
|
|
9
|
+
* - `false` — none: real drivers, real clock, real ids.
|
|
10
|
+
* - an object — all of them except the ones set to `false`, e.g.
|
|
11
|
+
* `{ cache: false }` keeps the configured cache driver.
|
|
12
|
+
*/
|
|
13
|
+
type TestFakesSelection = boolean | Partial<Record<TestFakeName, boolean>>;
|
|
14
|
+
/** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */
|
|
15
|
+
declare function readConfiguredFakes(): TestFakesSelection | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The fakes to install. Precedence: an explicit selection (the `fakes`
|
|
18
|
+
* option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in
|
|
19
|
+
* `src/config/tests.ts` > all on.
|
|
20
|
+
*/
|
|
21
|
+
declare function resolveTestFakes(explicit?: TestFakesSelection): TestFakeName[];
|
|
22
|
+
/**
|
|
23
|
+
* Install the selected fakes. Called by `setupTest()` and
|
|
24
|
+
* `startHttpTestServer()` once their connectors are up; call it yourself only
|
|
25
|
+
* when you bootstrap the framework without them.
|
|
26
|
+
*
|
|
27
|
+
* @returns the fakes that are now installed.
|
|
28
|
+
*/
|
|
29
|
+
declare function installTestFakes(explicit?: TestFakesSelection): Promise<TestFakeName[]>;
|
|
30
|
+
/**
|
|
31
|
+
* Restore every installed fake, in reverse order. Every fake is restored even
|
|
32
|
+
* when one fails; the failures are rethrown together afterwards.
|
|
33
|
+
*/
|
|
34
|
+
declare function restoreTestFakes(): Promise<void>;
|
|
35
|
+
/** The fakes installed right now. */
|
|
36
|
+
declare function installedTestFakes(): TestFakeName[];
|
|
37
|
+
//#endregion
|
|
38
|
+
export { TEST_FAKE_NAMES, TestFakeName, TestFakesSelection, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes };
|
|
39
|
+
//# sourceMappingURL=test-fakes.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-fakes.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tests/fakes/test-fakes.ts"],"mappings":";;cAUa,eAAA;AAAA,KAED,YAAA,WAAuB,eAAe;;;AAF2C;AAE7F;;;;AAAkD;KAUtC,kBAAA,aAA+B,OAAA,CAAQ,MAAA,CAAO,YAAA;;iBAiB1C,mBAAA,IAAuB,kBAAkB;;;;;;iBA0CzC,gBAAA,CAAiB,QAAA,GAAW,kBAAA,GAAqB,YAAY;;;;AA3DP;AAiBtE;;;iBA2DsB,gBAAA,CAAiB,QAAA,GAAW,kBAAA,GAAqB,OAAA,CAAQ,YAAA;AA3DtB;AA0CzD;;;AA1CyD,iBA2EnC,gBAAA,IAAoB,OAAO;;iBAiBjC,kBAAA,IAAsB,YAAY"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { config } from "../../config/config-getter.mjs";
|
|
2
|
+
import "../../config/index.mjs";
|
|
3
|
+
import { cacheFake } from "./cache-fake.mjs";
|
|
4
|
+
import { clockFake } from "./clock-fake.mjs";
|
|
5
|
+
import { idsFake } from "./ids-fake.mjs";
|
|
6
|
+
import { mailFake } from "./mail-fake.mjs";
|
|
7
|
+
import { queueFake } from "./queue-fake.mjs";
|
|
8
|
+
import { storageFake } from "./storage-fake.mjs";
|
|
9
|
+
|
|
10
|
+
//#region ../../packages/core/src/tests/fakes/test-fakes.ts
|
|
11
|
+
/** The fakes the test kit installs. */
|
|
12
|
+
const TEST_FAKE_NAMES = [
|
|
13
|
+
"mail",
|
|
14
|
+
"queue",
|
|
15
|
+
"cache",
|
|
16
|
+
"storage",
|
|
17
|
+
"clock",
|
|
18
|
+
"ids"
|
|
19
|
+
];
|
|
20
|
+
const fakes = {
|
|
21
|
+
mail: mailFake,
|
|
22
|
+
queue: queueFake,
|
|
23
|
+
cache: cacheFake,
|
|
24
|
+
storage: storageFake,
|
|
25
|
+
clock: clockFake,
|
|
26
|
+
ids: idsFake
|
|
27
|
+
};
|
|
28
|
+
let active = [];
|
|
29
|
+
/** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */
|
|
30
|
+
function readConfiguredFakes() {
|
|
31
|
+
return validateSelection((config.get("tests", {}) ?? {}).fakes, "tests.fakes");
|
|
32
|
+
}
|
|
33
|
+
function validateSelection(value, source) {
|
|
34
|
+
if (value === void 0 || typeof value === "boolean") return value;
|
|
35
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${source} must be true, false, or an object such as { cache: false }; got ${JSON.stringify(value)}.`);
|
|
36
|
+
const selection = {};
|
|
37
|
+
for (const [key, flag] of Object.entries(value)) {
|
|
38
|
+
const name = TEST_FAKE_NAMES.find((candidate) => candidate === key);
|
|
39
|
+
if (!name) throw new Error(`${source} has an unknown fake "${key}". Known fakes: ${TEST_FAKE_NAMES.join(", ")}.`);
|
|
40
|
+
if (typeof flag !== "boolean") throw new Error(`${source}.${key} must be true or false; got ${JSON.stringify(flag)}.`);
|
|
41
|
+
selection[name] = flag;
|
|
42
|
+
}
|
|
43
|
+
return selection;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The fakes to install. Precedence: an explicit selection (the `fakes`
|
|
47
|
+
* option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in
|
|
48
|
+
* `src/config/tests.ts` > all on.
|
|
49
|
+
*/
|
|
50
|
+
function resolveTestFakes(explicit) {
|
|
51
|
+
const selection = explicit !== void 0 ? validateSelection(explicit, "fakes") : readConfiguredFakes();
|
|
52
|
+
if (selection === void 0 || selection === true) return [...TEST_FAKE_NAMES];
|
|
53
|
+
if (selection === false) return [];
|
|
54
|
+
return TEST_FAKE_NAMES.filter((name) => selection[name] !== false);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Install the selected fakes. Called by `setupTest()` and
|
|
58
|
+
* `startHttpTestServer()` once their connectors are up; call it yourself only
|
|
59
|
+
* when you bootstrap the framework without them.
|
|
60
|
+
*
|
|
61
|
+
* @returns the fakes that are now installed.
|
|
62
|
+
*/
|
|
63
|
+
async function installTestFakes(explicit) {
|
|
64
|
+
const selected = resolveTestFakes(explicit);
|
|
65
|
+
for (const name of selected) await fakes[name].install();
|
|
66
|
+
active = [...new Set([...active, ...selected])];
|
|
67
|
+
return selected;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Restore every installed fake, in reverse order. Every fake is restored even
|
|
71
|
+
* when one fails; the failures are rethrown together afterwards.
|
|
72
|
+
*/
|
|
73
|
+
async function restoreTestFakes() {
|
|
74
|
+
const errors = [];
|
|
75
|
+
for (const name of [...active].reverse()) try {
|
|
76
|
+
await fakes[name].restore();
|
|
77
|
+
} catch (error) {
|
|
78
|
+
errors.push(error);
|
|
79
|
+
}
|
|
80
|
+
active = [];
|
|
81
|
+
if (errors.length > 0) throw new AggregateError(errors, "Restoring the test fakes failed.");
|
|
82
|
+
}
|
|
83
|
+
/** The fakes installed right now. */
|
|
84
|
+
function installedTestFakes() {
|
|
85
|
+
return [...active];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { TEST_FAKE_NAMES, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes };
|
|
90
|
+
//# sourceMappingURL=test-fakes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-fakes.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tests/fakes/test-fakes.ts"],"sourcesContent":["import type { GenericObject } from \"@mongez/reinforcements\";\nimport { config } from \"../../config\";\nimport { cacheFake } from \"./cache-fake\";\nimport { clockFake } from \"./clock-fake\";\nimport { idsFake } from \"./ids-fake\";\nimport { mailFake } from \"./mail-fake\";\nimport { queueFake } from \"./queue-fake\";\nimport { storageFake } from \"./storage-fake\";\n\n/** The fakes the test kit installs. */\nexport const TEST_FAKE_NAMES = [\"mail\", \"queue\", \"cache\", \"storage\", \"clock\", \"ids\"] as const;\n\nexport type TestFakeName = (typeof TEST_FAKE_NAMES)[number];\n\n/**\n * Which fakes to install.\n *\n * - `true` (the default) — all of them.\n * - `false` — none: real drivers, real clock, real ids.\n * - an object — all of them except the ones set to `false`, e.g.\n * `{ cache: false }` keeps the configured cache driver.\n */\nexport type TestFakesSelection = boolean | Partial<Record<TestFakeName, boolean>>;\n\nconst fakes: Record<\n TestFakeName,\n { install(): void | Promise<void>; restore(): void | Promise<void> }\n> = {\n mail: mailFake,\n queue: queueFake,\n cache: cacheFake,\n storage: storageFake,\n clock: clockFake,\n ids: idsFake,\n};\n\nlet active: TestFakeName[] = [];\n\n/** Read `tests.fakes` from `src/config/tests.ts`, or `undefined` when unset. */\nexport function readConfiguredFakes(): TestFakesSelection | undefined {\n // `config.get` resolves an absent key to `null`, not to its default's shape.\n const testsConfig = config.get<GenericObject>(\"tests\", {}) ?? {};\n\n return validateSelection(testsConfig.fakes as unknown, \"tests.fakes\");\n}\n\nfunction validateSelection(value: unknown, source: string): TestFakesSelection | undefined {\n if (value === undefined || typeof value === \"boolean\") return value;\n\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(\n `${source} must be true, false, or an object such as { cache: false }; got ${JSON.stringify(value)}.`,\n );\n }\n\n const selection: Partial<Record<TestFakeName, boolean>> = {};\n\n for (const [key, flag] of Object.entries(value)) {\n const name = TEST_FAKE_NAMES.find((candidate) => candidate === key);\n\n if (!name) {\n throw new Error(\n `${source} has an unknown fake \"${key}\". Known fakes: ${TEST_FAKE_NAMES.join(\", \")}.`,\n );\n }\n\n if (typeof flag !== \"boolean\") {\n throw new Error(`${source}.${key} must be true or false; got ${JSON.stringify(flag)}.`);\n }\n\n selection[name] = flag;\n }\n\n return selection;\n}\n\n/**\n * The fakes to install. Precedence: an explicit selection (the `fakes`\n * option of `setupTest()` / `startHttpTestServer()`) > `tests.fakes` in\n * `src/config/tests.ts` > all on.\n */\nexport function resolveTestFakes(explicit?: TestFakesSelection): TestFakeName[] {\n const selection =\n explicit !== undefined ? validateSelection(explicit, \"fakes\") : readConfiguredFakes();\n\n if (selection === undefined || selection === true) return [...TEST_FAKE_NAMES];\n if (selection === false) return [];\n\n return TEST_FAKE_NAMES.filter((name) => selection[name] !== false);\n}\n\n/**\n * Install the selected fakes. Called by `setupTest()` and\n * `startHttpTestServer()` once their connectors are up; call it yourself only\n * when you bootstrap the framework without them.\n *\n * @returns the fakes that are now installed.\n */\nexport async function installTestFakes(explicit?: TestFakesSelection): Promise<TestFakeName[]> {\n const selected = resolveTestFakes(explicit);\n\n for (const name of selected) {\n await fakes[name].install();\n }\n\n active = [...new Set([...active, ...selected])];\n\n return selected;\n}\n\n/**\n * Restore every installed fake, in reverse order. Every fake is restored even\n * when one fails; the failures are rethrown together afterwards.\n */\nexport async function restoreTestFakes(): Promise<void> {\n const errors: unknown[] = [];\n\n for (const name of [...active].reverse()) {\n try {\n await fakes[name].restore();\n } catch (error) {\n errors.push(error);\n }\n }\n\n active = [];\n\n if (errors.length > 0) throw new AggregateError(errors, \"Restoring the test fakes failed.\");\n}\n\n/** The fakes installed right now. */\nexport function installedTestFakes(): TestFakeName[] {\n return [...active];\n}\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,kBAAkB;CAAC;CAAQ;CAAS;CAAS;CAAW;CAAS;AAAK;AAcnF,MAAM,QAGF;CACF,MAAM;CACN,OAAO;CACP,OAAO;CACP,SAAS;CACT,OAAO;CACP,KAAK;AACP;AAEA,IAAI,SAAyB,CAAC;;AAG9B,SAAgB,sBAAsD;CAIpE,OAAO,mBAFa,OAAO,IAAmB,SAAS,CAAC,CAAC,KAAK,CAAC,EAE3B,CAAC,OAAkB,aAAa;AACtE;AAEA,SAAS,kBAAkB,OAAgB,QAAgD;CACzF,IAAI,UAAU,UAAa,OAAO,UAAU,WAAW,OAAO;CAE9D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,IAAI,MACR,GAAG,OAAO,mEAAmE,KAAK,UAAU,KAAK,EAAE,EACrG;CAGF,MAAM,YAAoD,CAAC;CAE3D,KAAK,MAAM,CAAC,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;EAC/C,MAAM,OAAO,gBAAgB,MAAM,cAAc,cAAc,GAAG;EAElE,IAAI,CAAC,MACH,MAAM,IAAI,MACR,GAAG,OAAO,wBAAwB,IAAI,kBAAkB,gBAAgB,KAAK,IAAI,EAAE,EACrF;EAGF,IAAI,OAAO,SAAS,WAClB,MAAM,IAAI,MAAM,GAAG,OAAO,GAAG,IAAI,8BAA8B,KAAK,UAAU,IAAI,EAAE,EAAE;EAGxF,UAAU,QAAQ;CACpB;CAEA,OAAO;AACT;;;;;;AAOA,SAAgB,iBAAiB,UAA+C;CAC9E,MAAM,YACJ,aAAa,SAAY,kBAAkB,UAAU,OAAO,IAAI,oBAAoB;CAEtF,IAAI,cAAc,UAAa,cAAc,MAAM,OAAO,CAAC,GAAG,eAAe;CAC7E,IAAI,cAAc,OAAO,OAAO,CAAC;CAEjC,OAAO,gBAAgB,QAAQ,SAAS,UAAU,UAAU,KAAK;AACnE;;;;;;;;AASA,eAAsB,iBAAiB,UAAwD;CAC7F,MAAM,WAAW,iBAAiB,QAAQ;CAE1C,KAAK,MAAM,QAAQ,UACjB,MAAM,MAAM,KAAK,CAAC,QAAQ;CAG5B,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;CAE9C,OAAO;AACT;;;;;AAMA,eAAsB,mBAAkC;CACtD,MAAM,SAAoB,CAAC;CAE3B,KAAK,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,GACrC,IAAI;EACF,MAAM,MAAM,KAAK,CAAC,QAAQ;CAC5B,SAAS,OAAO;EACd,OAAO,KAAK,KAAK;CACnB;CAGF,SAAS,CAAC;CAEV,IAAI,OAAO,SAAS,GAAG,MAAM,IAAI,eAAe,QAAQ,kCAAkC;AAC5F;;AAGA,SAAgB,qBAAqC;CACnD,OAAO,CAAC,GAAG,MAAM;AACnB"}
|
package/esm/tests/index.d.mts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { assertPortIsAvailable, isPortAvailable } from "../http/port-preflight.mjs";
|
|
2
|
+
import { TEST_FAKE_NAMES, TestFakeName, TestFakesSelection, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
|
|
2
3
|
import { StartHttpTestServerOptions, isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./start-http-development-server.mjs";
|
|
3
|
-
import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
|
|
4
|
+
import { TestRequestClient, createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
|
|
5
|
+
import { AuthenticatedTestClient, TestAuthenticableUser, actingAs } from "./authenticated-test-client.mjs";
|
|
4
6
|
import { TestConnectorsSelection } from "./test-connectors-selection.mjs";
|
|
5
7
|
import { TestLifecycleError, TestSetupOptions, setupTest, teardownTest, warnMissingImportModule } from "./vitest-setup.mjs";
|
|
6
|
-
|
|
8
|
+
import { cacheFake } from "./fakes/cache-fake.mjs";
|
|
9
|
+
import { DEFAULT_FAKE_NOW, clockFake } from "./fakes/clock-fake.mjs";
|
|
10
|
+
import { FakeAssertionError, describeRecorded } from "./fakes/fake-assertion-error.mjs";
|
|
11
|
+
import { idsFake } from "./fakes/ids-fake.mjs";
|
|
12
|
+
import { MailMatcher, mailFake } from "./fakes/mail-fake.mjs";
|
|
13
|
+
import { JobReference, PushedJob, PushedJobMatcher, queueFake } from "./fakes/queue-fake.mjs";
|
|
14
|
+
import { storageFake } from "./fakes/storage-fake.mjs";
|
|
15
|
+
import { Factory, FactoryAttributes, FactoryOverrides, FactorySeed, FactoryState, defineFactory, resetFactorySequences } from "./factories.mjs";
|
|
16
|
+
import { CreateTestHttpServerOptions, TestHttpServer, createTestHttpServer } from "./test-http-server.mjs";
|
|
17
|
+
import { REDACTED, ResponseSnapshot, SnapshotResponseOptions, snapshotResponse } from "./snapshot-response.mjs";
|
|
18
|
+
export { AuthenticatedTestClient, CreateTestHttpServerOptions, DEFAULT_FAKE_NOW, Factory, FactoryAttributes, FactoryOverrides, FactorySeed, FactoryState, FakeAssertionError, JobReference, MailMatcher, PushedJob, PushedJobMatcher, REDACTED, ResponseSnapshot, SnapshotResponseOptions, StartHttpTestServerOptions, TEST_FAKE_NAMES, TestAuthenticableUser, type TestConnectorsSelection, TestFakeName, TestFakesSelection, TestHttpServer, TestLifecycleError, TestRequestClient, TestSetupOptions, actingAs, assertPortIsAvailable, cacheFake, clockFake, createTestHttpServer, createTestRequestClient, defineFactory, describeRecorded, expectJson, getTestServerUrl, idsFake, installTestFakes, installedTestFakes, isPortAvailable, isTestServerRunning, mailFake, parseJsonResponse, queueFake, readConfiguredFakes, resetFactorySequences, resolveTestFakes, restoreTestFakes, setupTest, snapshotResponse, startHttpTestServer, stopHttpTestServer, storageFake, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
|
package/esm/tests/index.mjs
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { assertPortIsAvailable, isPortAvailable } from "../http/port-preflight.mjs";
|
|
2
|
+
import { FakeAssertionError, describeRecorded } from "./fakes/fake-assertion-error.mjs";
|
|
3
|
+
import { cacheFake } from "./fakes/cache-fake.mjs";
|
|
4
|
+
import { DEFAULT_FAKE_NOW, clockFake } from "./fakes/clock-fake.mjs";
|
|
5
|
+
import { idsFake } from "./fakes/ids-fake.mjs";
|
|
6
|
+
import { mailFake } from "./fakes/mail-fake.mjs";
|
|
7
|
+
import { queueFake } from "./fakes/queue-fake.mjs";
|
|
8
|
+
import { storageFake } from "./fakes/storage-fake.mjs";
|
|
9
|
+
import { TEST_FAKE_NAMES, installTestFakes, installedTestFakes, readConfiguredFakes, resolveTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
|
|
2
10
|
import { isTestServerRunning, startHttpTestServer, stopHttpTestServer } from "./start-http-development-server.mjs";
|
|
3
|
-
import { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
|
|
11
|
+
import { createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest } from "./test-helpers.mjs";
|
|
12
|
+
import { actingAs } from "./authenticated-test-client.mjs";
|
|
4
13
|
import { TestLifecycleError, setupTest, teardownTest, warnMissingImportModule } from "./vitest-setup.mjs";
|
|
14
|
+
import "./fakes/index.mjs";
|
|
15
|
+
import { defineFactory, resetFactorySequences } from "./factories.mjs";
|
|
16
|
+
import { createTestHttpServer } from "./test-http-server.mjs";
|
|
17
|
+
import { REDACTED, snapshotResponse } from "./snapshot-response.mjs";
|
|
5
18
|
|
|
6
|
-
export { TestLifecycleError, assertPortIsAvailable, expectJson, getTestServerUrl, isPortAvailable, isTestServerRunning, parseJsonResponse, setupTest, startHttpTestServer, stopHttpTestServer, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
|
|
19
|
+
export { DEFAULT_FAKE_NOW, FakeAssertionError, REDACTED, TEST_FAKE_NAMES, TestLifecycleError, actingAs, assertPortIsAvailable, cacheFake, clockFake, createTestHttpServer, createTestRequestClient, defineFactory, describeRecorded, expectJson, getTestServerUrl, idsFake, installTestFakes, installedTestFakes, isPortAvailable, isTestServerRunning, mailFake, parseJsonResponse, queueFake, readConfiguredFakes, resetFactorySequences, resolveTestFakes, restoreTestFakes, setupTest, snapshotResponse, startHttpTestServer, stopHttpTestServer, storageFake, teardownTest, testDelete, testGet, testPatch, testPost, testPut, testRequest, warnMissingImportModule };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region ../../packages/core/src/tests/snapshot-response.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A response reduced to what a snapshot should pin: the status, the content
|
|
4
|
+
* type and the body — with the values that differ on every run (ids, tokens,
|
|
5
|
+
* timestamps) replaced, so the snapshot fails only when the shape or a stable
|
|
6
|
+
* value changes.
|
|
7
|
+
*/
|
|
8
|
+
type ResponseSnapshot = {
|
|
9
|
+
status: number;
|
|
10
|
+
contentType: string | null;
|
|
11
|
+
body: unknown;
|
|
12
|
+
};
|
|
13
|
+
type SnapshotResponseOptions = {
|
|
14
|
+
/**
|
|
15
|
+
* Dot paths whose values are replaced by `"[redacted]"`. `*` matches any
|
|
16
|
+
* key or array index: `"post.id"`, `"posts.*.createdAt"`, `"*.token"`.
|
|
17
|
+
*/
|
|
18
|
+
redact?: string[];
|
|
19
|
+
};
|
|
20
|
+
declare const REDACTED = "[redacted]";
|
|
21
|
+
/**
|
|
22
|
+
* Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.
|
|
23
|
+
* Consumes the body: call it instead of `response.json()`, not after.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const response = await testPost("/posts", { title: "Hello" });
|
|
27
|
+
*
|
|
28
|
+
* expect(await snapshotResponse(response, { redact: ["post.id", "post.createdAt"] }))
|
|
29
|
+
* .toMatchSnapshot();
|
|
30
|
+
*/
|
|
31
|
+
declare function snapshotResponse(response: Response, options?: SnapshotResponseOptions): Promise<ResponseSnapshot>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { REDACTED, ResponseSnapshot, SnapshotResponseOptions, snapshotResponse };
|
|
34
|
+
//# sourceMappingURL=snapshot-response.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-response.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/snapshot-response.ts"],"mappings":";;AAMA;;;;;KAAY,gBAAA;EACV,MAAA;EACA,WAAA;EACA,IAAA;AAAA;AAAA,KAGU,uBAAA;;;AAKJ;AAGR;EAHE,MAAM;AAAA;AAAA,cAGK,QAAA;AAAQ;AAkCrB;;;;;;;;;AAlCqB,iBAkCC,gBAAA,CACpB,QAAA,EAAU,QAAA,EACV,OAAA,GAAS,uBAAA,GACR,OAAA,CAAQ,gBAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
//#region ../../packages/core/src/tests/snapshot-response.ts
|
|
2
|
+
const REDACTED = "[redacted]";
|
|
3
|
+
function redactPath(value, segments) {
|
|
4
|
+
if (segments.length === 0) return REDACTED;
|
|
5
|
+
if (typeof value !== "object" || value === null) return value;
|
|
6
|
+
const [head, ...rest] = segments;
|
|
7
|
+
if (Array.isArray(value)) return value.map((item, index) => head === "*" || head === String(index) ? redactPath(item, rest) : item);
|
|
8
|
+
const record = value;
|
|
9
|
+
const copy = { ...record };
|
|
10
|
+
for (const key of Object.keys(record)) if (head === "*" || head === key) copy[key] = redactPath(record[key], rest);
|
|
11
|
+
return copy;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.
|
|
15
|
+
* Consumes the body: call it instead of `response.json()`, not after.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const response = await testPost("/posts", { title: "Hello" });
|
|
19
|
+
*
|
|
20
|
+
* expect(await snapshotResponse(response, { redact: ["post.id", "post.createdAt"] }))
|
|
21
|
+
* .toMatchSnapshot();
|
|
22
|
+
*/
|
|
23
|
+
async function snapshotResponse(response, options = {}) {
|
|
24
|
+
const contentType = response.headers.get("content-type");
|
|
25
|
+
const text = await response.text();
|
|
26
|
+
let body = text;
|
|
27
|
+
if (contentType?.includes("json") && text !== "") try {
|
|
28
|
+
body = JSON.parse(text);
|
|
29
|
+
} catch {
|
|
30
|
+
body = text;
|
|
31
|
+
}
|
|
32
|
+
for (const path of options.redact ?? []) body = redactPath(body, path.split("."));
|
|
33
|
+
return {
|
|
34
|
+
status: response.status,
|
|
35
|
+
contentType,
|
|
36
|
+
body
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { REDACTED, snapshotResponse };
|
|
42
|
+
//# sourceMappingURL=snapshot-response.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-response.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/snapshot-response.ts"],"sourcesContent":["/**\n * A response reduced to what a snapshot should pin: the status, the content\n * type and the body — with the values that differ on every run (ids, tokens,\n * timestamps) replaced, so the snapshot fails only when the shape or a stable\n * value changes.\n */\nexport type ResponseSnapshot = {\n status: number;\n contentType: string | null;\n body: unknown;\n};\n\nexport type SnapshotResponseOptions = {\n /**\n * Dot paths whose values are replaced by `\"[redacted]\"`. `*` matches any\n * key or array index: `\"post.id\"`, `\"posts.*.createdAt\"`, `\"*.token\"`.\n */\n redact?: string[];\n};\n\nexport const REDACTED = \"[redacted]\";\n\nfunction redactPath(value: unknown, segments: readonly string[]): unknown {\n if (segments.length === 0) return REDACTED;\n if (typeof value !== \"object\" || value === null) return value;\n\n const [head, ...rest] = segments;\n\n if (Array.isArray(value)) {\n return value.map((item, index) =>\n head === \"*\" || head === String(index) ? redactPath(item, rest) : item,\n );\n }\n\n const record = value as Record<string, unknown>;\n const copy: Record<string, unknown> = { ...record };\n\n for (const key of Object.keys(record)) {\n if (head === \"*\" || head === key) copy[key] = redactPath(record[key], rest);\n }\n\n return copy;\n}\n\n/**\n * Read a response into a {@link ResponseSnapshot} for `toMatchSnapshot()`.\n * Consumes the body: call it instead of `response.json()`, not after.\n *\n * @example\n * const response = await testPost(\"/posts\", { title: \"Hello\" });\n *\n * expect(await snapshotResponse(response, { redact: [\"post.id\", \"post.createdAt\"] }))\n * .toMatchSnapshot();\n */\nexport async function snapshotResponse(\n response: Response,\n options: SnapshotResponseOptions = {},\n): Promise<ResponseSnapshot> {\n const contentType = response.headers.get(\"content-type\");\n const text = await response.text();\n let body: unknown = text;\n\n if (contentType?.includes(\"json\") && text !== \"\") {\n try {\n body = JSON.parse(text) as unknown;\n } catch {\n body = text;\n }\n }\n\n for (const path of options.redact ?? []) {\n body = redactPath(body, path.split(\".\"));\n }\n\n return { status: response.status, contentType, body };\n}\n"],"mappings":";AAoBA,MAAa,WAAW;AAExB,SAAS,WAAW,OAAgB,UAAsC;CACxE,IAAI,SAAS,WAAW,GAAG,OAAO;CAClC,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CAExD,MAAM,CAAC,MAAM,GAAG,QAAQ;CAExB,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,KAAK,MAAM,UACtB,SAAS,OAAO,SAAS,OAAO,KAAK,IAAI,WAAW,MAAM,IAAI,IAAI,IACpE;CAGF,MAAM,SAAS;CACf,MAAM,OAAgC,EAAE,GAAG,OAAO;CAElD,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,IAAI,SAAS,OAAO,SAAS,KAAK,KAAK,OAAO,WAAW,OAAO,MAAM,IAAI;CAG5E,OAAO;AACT;;;;;;;;;;;AAYA,eAAsB,iBACpB,UACA,UAAmC,CAAC,GACT;CAC3B,MAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;CACvD,MAAM,OAAO,MAAM,SAAS,KAAK;CACjC,IAAI,OAAgB;CAEpB,IAAI,aAAa,SAAS,MAAM,KAAK,SAAS,IAC5C,IAAI;EACF,OAAO,KAAK,MAAM,IAAI;CACxB,QAAQ;EACN,OAAO;CACT;CAGF,KAAK,MAAM,QAAQ,QAAQ,UAAU,CAAC,GACpC,OAAO,WAAW,MAAM,KAAK,MAAM,GAAG,CAAC;CAGzC,OAAO;EAAE,QAAQ,SAAS;EAAQ;EAAa;CAAK;AACtD"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { TestFakesSelection } from "./fakes/test-fakes.mjs";
|
|
2
|
+
|
|
1
3
|
//#region ../../packages/core/src/tests/start-http-development-server.d.ts
|
|
2
4
|
type StartHttpTestServerOptions = {
|
|
3
5
|
/**
|
|
@@ -5,6 +7,10 @@ type StartHttpTestServerOptions = {
|
|
|
5
7
|
*
|
|
6
8
|
* Needed because the server cannot be moved from outside: this function
|
|
7
9
|
* bootstraps the app itself, and that bootstrap re-reads `.env`.
|
|
10
|
+
*
|
|
11
|
+
* `0` asks the OS for a free port. The port actually bound is published to
|
|
12
|
+
* the test workers, so `testGet()`, `actingAs()` and friends follow it, and
|
|
13
|
+
* a suite never collides with `warlock dev` or another suite.
|
|
8
14
|
*/
|
|
9
15
|
port?: number;
|
|
10
16
|
/**
|
|
@@ -17,6 +23,18 @@ type StartHttpTestServerOptions = {
|
|
|
17
23
|
* @default true
|
|
18
24
|
*/
|
|
19
25
|
web?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Which test fakes the server process installs (mail, queue, cache,
|
|
28
|
+
* storage, clock, ids). Same values and precedence as `setupTest({ fakes })`:
|
|
29
|
+
* this option > `tests.fakes` config > all on.
|
|
30
|
+
*
|
|
31
|
+
* A fake records what happens in ITS process: mail sent while this server
|
|
32
|
+
* handles a request is captured here, not in the test worker that sent the
|
|
33
|
+
* request. To assert on what an HTTP request did, serve it in the worker
|
|
34
|
+
* with `createTestHttpServer()`. The storage fake is the exception: its
|
|
35
|
+
* temp root is shared with the workers.
|
|
36
|
+
*/
|
|
37
|
+
fakes?: TestFakesSelection;
|
|
20
38
|
};
|
|
21
39
|
/**
|
|
22
40
|
* Start the HTTP test server (minimal - no file watching)
|
|
@@ -25,6 +43,10 @@ type StartHttpTestServerOptions = {
|
|
|
25
43
|
* @example
|
|
26
44
|
* // run this suite on its own port, whatever `.env` says
|
|
27
45
|
* await startHttpTestServer({ port: 3999 });
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* // let the OS pick a free port; the request helpers follow it
|
|
49
|
+
* await startHttpTestServer({ port: 0 });
|
|
28
50
|
*/
|
|
29
51
|
declare function startHttpTestServer(options?: StartHttpTestServerOptions): Promise<void>;
|
|
30
52
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-http-development-server.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"start-http-development-server.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"mappings":";;;KA4BY,0BAAA;;AAAZ;;;;;;;;;EAWE,IAAA;EAqJoB;;;;;;;;AAAsE;EA1I1F,GAAA;EAqQsC;;;AAAW;AAmCnD;;;;AAAmC;;;EA3RjC,KAAA,GAAQ,kBAAkB;AAAA;;;;;;;;;;;;;iBA6HN,mBAAA,CAAoB,OAAA,GAAS,0BAAA,GAAkC,OAAO;;;;;iBA2HtE,kBAAA,IAAsB,OAAO;;;;iBAmCnC,mBAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Application } from "../application/application.mjs";
|
|
2
2
|
import "../application/index.mjs";
|
|
3
3
|
import { assertPortIsAvailable } from "../http/port-preflight.mjs";
|
|
4
|
+
import { getHttpReadyReport } from "../http/ready-report.mjs";
|
|
4
5
|
import { loadEnvironmentFiles } from "../utils/load-environment.mjs";
|
|
5
6
|
import { bootstrap } from "../bootstrap.mjs";
|
|
6
7
|
import { ConnectorLifecyclePhase } from "../connectors/types.mjs";
|
|
@@ -8,6 +9,7 @@ import { connectorsManager } from "../connectors/connectors-manager.mjs";
|
|
|
8
9
|
import { warlockConfigManager } from "../warlock-config/warlock-config.manager.mjs";
|
|
9
10
|
import { filesOrchestrator } from "../dev-server/files-orchestrator.mjs";
|
|
10
11
|
import { loadConfigFiles } from "../config/load-config-files.mjs";
|
|
12
|
+
import { installTestFakes, restoreTestFakes } from "./fakes/test-fakes.mjs";
|
|
11
13
|
import { publishTestServerPort, withdrawTestServerPort } from "./test-server-port-channel.mjs";
|
|
12
14
|
import config from "@mongez/config";
|
|
13
15
|
|
|
@@ -50,14 +52,28 @@ async function startTestServerPhase(phase) {
|
|
|
50
52
|
async function applyTestServerPort(port) {
|
|
51
53
|
if (!config.get("http")) {
|
|
52
54
|
if (port !== void 0) throw new Error(`startHttpTestServer({ port: ${port} }) was given a port, but this app has no \`http\` config, so no HTTP server is started. Add \`src/config/http.ts\` first.`);
|
|
53
|
-
return;
|
|
55
|
+
return "none";
|
|
54
56
|
}
|
|
55
57
|
if (port !== void 0) config.set("http.port", port);
|
|
56
58
|
const resolvedPort = config.get("http.port");
|
|
57
59
|
if (typeof resolvedPort !== "number") throw new Error(`startHttpTestServer() cannot use \`http.port\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \`String(Number(v)) === v\`, so "03999", "+3999", "1e3", and values with stray whitespace stay strings). Fix \`HTTP_PORT\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`);
|
|
58
|
-
if (resolvedPort
|
|
60
|
+
if (resolvedPort === 0) return "ephemeral";
|
|
61
|
+
if (resolvedPort < 0) throw new Error(`startHttpTestServer() cannot run on port ${resolvedPort}. Pass a port number, or 0 to let the OS pick a free one — e.g. startHttpTestServer({ port: 0 }).`);
|
|
59
62
|
await assertPortIsAvailable(resolvedPort, config.get("http.host") || "localhost");
|
|
60
63
|
publishTestServerPort(resolvedPort);
|
|
64
|
+
return "published";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Publish the port an ephemeral (`port: 0`) bind actually took.
|
|
68
|
+
*
|
|
69
|
+
* `before` is the ready report from before the late phase: the report is a
|
|
70
|
+
* module-level record, so an unchanged one means THIS boot bound nothing and an
|
|
71
|
+
* older report must not be mistaken for it.
|
|
72
|
+
*/
|
|
73
|
+
function publishEphemeralPort(before) {
|
|
74
|
+
const report = getHttpReadyReport();
|
|
75
|
+
if (!report || report === before || report.port <= 0) throw new Error("startHttpTestServer({ port: 0 }) booted, but the HTTP connector did not bind a port, so there is no address to give the test workers. Check that `src/config/http.ts` exists and that this process serves HTTP (its role is not worker-only).");
|
|
76
|
+
publishTestServerPort(report.port);
|
|
61
77
|
}
|
|
62
78
|
/**
|
|
63
79
|
* Start the HTTP test server (minimal - no file watching)
|
|
@@ -66,6 +82,10 @@ async function applyTestServerPort(port) {
|
|
|
66
82
|
* @example
|
|
67
83
|
* // run this suite on its own port, whatever `.env` says
|
|
68
84
|
* await startHttpTestServer({ port: 3999 });
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // let the OS pick a free port; the request helpers follow it
|
|
88
|
+
* await startHttpTestServer({ port: 0 });
|
|
69
89
|
*/
|
|
70
90
|
async function startHttpTestServer(options = {}) {
|
|
71
91
|
const nodeEnvironment = process.env.NODE_ENV;
|
|
@@ -87,11 +107,14 @@ async function startHttpTestServer(options = {}) {
|
|
|
87
107
|
await loadConfigFiles(true);
|
|
88
108
|
if (options.web === false) await startTestServerPhase("early");
|
|
89
109
|
else await connectorsManager.startPhase("early");
|
|
110
|
+
await installTestFakes(options.fakes);
|
|
90
111
|
await filesOrchestrator.moduleLoader.loadAll();
|
|
91
|
-
await applyTestServerPort(options.port);
|
|
112
|
+
const portMode = await applyTestServerPort(options.port);
|
|
113
|
+
const readyReportBefore = getHttpReadyReport();
|
|
92
114
|
await Application.runStartupValidators();
|
|
93
115
|
if (options.web === false) await startTestServerPhase("late");
|
|
94
116
|
else await connectorsManager.startPhase("late");
|
|
117
|
+
if (portMode === "ephemeral") publishEphemeralPort(readyReportBefore);
|
|
95
118
|
isServerRunning = true;
|
|
96
119
|
} catch (error) {
|
|
97
120
|
await unwindPartialStartup();
|
|
@@ -106,6 +129,11 @@ async function startHttpTestServer(options = {}) {
|
|
|
106
129
|
* already in flight, and the caller is about to rethrow it.
|
|
107
130
|
*/
|
|
108
131
|
async function unwindPartialStartup() {
|
|
132
|
+
try {
|
|
133
|
+
await restoreTestFakes();
|
|
134
|
+
} catch (fakesError) {
|
|
135
|
+
console.error("[test-server] Restoring the test fakes after a failed start did not complete:", fakesError);
|
|
136
|
+
}
|
|
109
137
|
try {
|
|
110
138
|
await connectorsManager.shutdown();
|
|
111
139
|
} catch (shutdownError) {
|
|
@@ -124,6 +152,11 @@ async function stopHttpTestServer() {
|
|
|
124
152
|
return;
|
|
125
153
|
}
|
|
126
154
|
try {
|
|
155
|
+
try {
|
|
156
|
+
await restoreTestFakes();
|
|
157
|
+
} catch (fakesError) {
|
|
158
|
+
console.error("[test-server] Restoring the test fakes did not complete:", fakesError);
|
|
159
|
+
}
|
|
127
160
|
await connectorsManager.shutdown();
|
|
128
161
|
console.log("[test-server] HTTP test server stopped");
|
|
129
162
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-http-development-server.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"sourcesContent":["/**\n * HTTP Test Server\n *\n * Starts a minimal HTTP server for testing.\n * Unlike the full DevelopmentServer, this:\n * - Does NOT watch files\n * - Does NOT do HMR\n * - Only starts connectors needed for HTTP requests\n *\n * Used in Vitest's globalSetup to start server once for all test workers.\n */\nimport config from \"@mongez/config\";\nimport { Application } from \"../application\";\nimport { bootstrap } from \"../bootstrap\";\nimport { loadConfigFiles } from \"../config/load-config-files\";\nimport { connectorsManager } from \"../connectors/connectors-manager\";\nimport { ConnectorLifecyclePhase } from \"../connectors/types\";\nimport { filesOrchestrator } from \"../dev-server/files-orchestrator\";\nimport { assertPortIsAvailable } from \"../http/port-preflight\";\nimport { loadEnvironmentFiles } from \"../utils/load-environment\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\nimport { publishTestServerPort, withdrawTestServerPort } from \"./test-server-port-channel\";\n\nlet isServerRunning = false;\n\nexport type StartHttpTestServerOptions = {\n /**\n * Port the test server binds to, overriding `http.port`.\n *\n * Needed because the server cannot be moved from outside: this function\n * bootstraps the app itself, and that bootstrap re-reads `.env`.\n */\n port?: number;\n\n /**\n * Whether to boot the optional web connector.\n *\n * Defaults to `true` to preserve the full-stack test server. Pass `false`\n * for API-only suites: the web connector's lazy delegate is skipped before\n * `boot()`, so it never constructs its Vite-backed implementation.\n *\n * @default true\n */\n web?: boolean;\n};\n\n/**\n * Start one lifecycle phase while omitting the web connector.\n *\n * Kept here rather than changing the manager's public API: this is a\n * test-server-only selection, and retaining the manager's boot-all / start-all\n * ordering is essential for HTTP and socket connector wiring.\n */\nasync function startTestServerPhase(phase: ConnectorLifecyclePhase): Promise<void> {\n const connectors = connectorsManager\n .list()\n .filter((connector) => connector.lifecyclePhase === phase)\n .filter((connector) => connector.name !== \"web\");\n\n for (const connector of connectors) {\n await connector.boot();\n }\n\n for (const connector of connectors) {\n await connector.start();\n }\n}\n\n/**\n * Apply the caller's port and preflight the bind.\n *\n * Called at the last moment before the HTTP connector binds, and that timing is\n * the fix: `bootstrap()` re-reads `.env` through `loadEnv()` (dotenv overrides\n * by default), and `src/config/http.ts` then resolves its port from that store,\n * so anything the caller set earlier is gone by the time the port is read.\n * Writing into `config` here is also the only channel that works — assigning\n * `process.env.HTTP_PORT` has no effect, since `env()` reads dotenv's own store\n * and never falls back to `process.env`.\n */\nasync function applyTestServerPort(port?: number): Promise<void> {\n const httpConfig = config.get(\"http\");\n\n if (!httpConfig) {\n if (port !== undefined) {\n throw new Error(\n `startHttpTestServer({ port: ${port} }) was given a port, but this app has no \\`http\\` config, so no HTTP server is started. Add \\`src/config/http.ts\\` first.`,\n );\n }\n\n return;\n }\n\n if (port !== undefined) {\n config.set(\"http.port\", port);\n }\n\n const resolvedPort = config.get(\"http.port\");\n\n // No configured port at all is fine: Fastify falls back to its own default and\n // the workers resolve the same one from their own config, so both ends agree\n // without the channel.\n //\n // A non-numeric port is NOT fine, and must fail loudly rather than skip the\n // preflight silently. `env()` coerces a value only when it round-trips exactly\n // (`String(Number(v)) === v`), so `HTTP_PORT=3999` and `HTTP_PORT=0` arrive as\n // numbers, but `03999`, `+3999`, `1e3` and anything with stray whitespace stay\n // strings. Letting those through used to reach `HttpConnector.start()`'s\n // `listen({ port })` unchanged — no preflight, no published port, and every\n // test worker resolving a URL from a channel nothing ever wrote to.\n if (typeof resolvedPort !== \"number\") {\n throw new Error(\n `startHttpTestServer() cannot use \\`http.port\\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \\`String(Number(v)) === v\\`, so \"03999\", \"+3999\", \"1e3\", and values with stray whitespace stay strings). Fix \\`HTTP_PORT\\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`,\n );\n }\n\n // `0` is the OS's \"pick a free one for me\" idiom, and the test server cannot\n // support it. Preflighting 0 would bind some unrelated ephemeral port and pass\n // without proving anything, and there is nothing meaningful to publish: the\n // port Fastify ends up binding is never recorded — `HttpConnector.start()`\n // stores the port it ASKED for, not the one it got. Accepting 0 silently is\n // what left `getTestServerUrl()` resolving to `http://host:0` through its own\n // config fallback, so every worker request went to a port nothing listens on.\n if (resolvedPort <= 0) {\n throw new Error(\n `startHttpTestServer() cannot run on port ${resolvedPort}. Pass an explicit port — e.g. startHttpTestServer({ port: 3999 }) — or set \\`http.port\\` in your config. Test workers are separate processes that resolve the server's URL from the port published at startup, and an OS-assigned port is not knowable to them.`,\n );\n }\n\n await assertPortIsAvailable(resolvedPort, config.get(\"http.host\") || \"localhost\");\n\n publishTestServerPort(resolvedPort);\n}\n\n/**\n * Start the HTTP test server (minimal - no file watching)\n * Call this in Vitest's globalSetup\n *\n * @example\n * // run this suite on its own port, whatever `.env` says\n * await startHttpTestServer({ port: 3999 });\n */\nexport async function startHttpTestServer(options: StartHttpTestServerOptions = {}): Promise<void> {\n const nodeEnvironment = process.env.NODE_ENV;\n\n if (nodeEnvironment === undefined) {\n process.env.NODE_ENV = \"test\";\n } else if (nodeEnvironment !== \"test\") {\n throw new Error(\n `startHttpTestServer() requires NODE_ENV=\"test\", but received NODE_ENV=${JSON.stringify(nodeEnvironment)}. Set NODE_ENV=test before starting the test server.`,\n );\n }\n\n if (isServerRunning) {\n console.log(\"[test-server] Server already running, skipping start\");\n return;\n }\n\n console.log(\"[test-server] Starting HTTP test server...\");\n\n try {\n // `globalSetup` runs in Vitest's main process, where Vitest's worker env\n // setup has not run. Load `.env.test` here, before any config is read.\n await loadEnvironmentFiles();\n\n // Set environment\n Application.setRuntimeStrategy(\"development\");\n Application.setEnvironment(\"test\");\n\n // Bootstrap (env, etc.)\n await warlockConfigManager.load();\n await bootstrap();\n\n // Initialize file orchestrator (but don't watch)\n await filesOrchestrator.init();\n await filesOrchestrator.initializeAll();\n\n // Load config files\n await loadConfigFiles(true);\n\n // Early-phase connectors (database, cache, logger, storage, mailer,\n // herald) must start BEFORE app modules load: a module's `main.ts` boot\n // side-effect can query the DB at import time, so the data source has to\n // be registered first. This mirrors the dev/prod boot order (see\n // `cli-commands.manager`, `production-builder`, and `DevelopmentServer`).\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Early);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\n }\n\n // Load application modules (their boot side-effects now see a live DB).\n await filesOrchestrator.moduleLoader.loadAll();\n\n await applyTestServerPort(options.port);\n\n // A rejecting validator (Application.onValidateBoot) must abort boot\n // before late-phase connectors bind a port — same slot as\n // `DevelopmentServer.start()` and the generated production `app.ts`.\n await Application.runStartupValidators();\n\n // Late-phase connectors (http, socket) bind after app code has\n // registered its routes and listeners.\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Late);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\n }\n\n isServerRunning = true;\n } catch (error) {\n // This function owns the connectors it starts, so a failure part-way\n // through has to leave nothing behind. Without this, `isServerRunning` was\n // still `false` — it is only set on the last line — so `globalTeardown`'s\n // `stopHttpTestServer()` reported \"No server to stop\" and walked away from\n // live early-phase connectors and a published port that outlived them.\n await unwindPartialStartup();\n\n // Rethrown unchanged: the startup failure is the one the caller needs to\n // read. A cleanup failure that replaced it would hide the actual cause.\n throw error;\n }\n}\n\n/**\n * Best-effort teardown of whatever a failed {@link startHttpTestServer} managed\n * to start.\n *\n * Every step is independent and none may throw: this runs while an error is\n * already in flight, and the caller is about to rethrow it.\n */\nasync function unwindPartialStartup(): Promise<void> {\n try {\n await connectorsManager.shutdown();\n } catch (shutdownError) {\n // Reported, not thrown — it is secondary to the startup error being\n // rethrown, and losing that one to this would be the worse outcome.\n console.error(\"[test-server] Cleanup after a failed start did not complete:\", shutdownError);\n }\n\n withdrawTestServerPort();\n isServerRunning = false;\n}\n\n/**\n * Stop the HTTP test server\n * Call this in Vitest's globalTeardown\n */\nexport async function stopHttpTestServer(): Promise<void> {\n if (!isServerRunning) {\n console.log(\"[test-server] No server to stop\");\n return;\n }\n\n try {\n await connectorsManager.shutdown();\n\n console.log(\"[test-server] HTTP test server stopped\");\n } catch (error) {\n // Surfaced, never swallowed — cleaning up is not the same as the shutdown\n // having succeeded, and a suite whose teardown failed should say so.\n console.error(\"[test-server] Error stopping HTTP server:\", error);\n\n throw error;\n } finally {\n // In a `finally` rather than after the `await`: when `shutdown()` threw,\n // the published port survived the server it pointed at, so the next run in\n // the same process inherited a stale one and sent every request to it.\n withdrawTestServerPort();\n\n isServerRunning = false;\n }\n}\n\n/**\n * Check if test server is running\n */\nexport function isTestServerRunning(): boolean {\n return isServerRunning;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,IAAI,kBAAkB;;;;;;;;AA8BtB,eAAe,qBAAqB,OAA+C;CACjF,MAAM,aAAa,kBAChB,KAAK,CAAC,CACN,QAAQ,cAAc,UAAU,mBAAmB,KAAK,CAAC,CACzD,QAAQ,cAAc,UAAU,SAAS,KAAK;CAEjD,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,KAAK;CAGvB,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,MAAM;AAE1B;;;;;;;;;;;;AAaA,eAAe,oBAAoB,MAA8B;CAG/D,IAAI,CAFe,OAAO,IAAI,MAEhB,GAAG;EACf,IAAI,SAAS,QACX,MAAM,IAAI,MACR,+BAA+B,KAAK,2HACtC;EAGF;CACF;CAEA,IAAI,SAAS,QACX,OAAO,IAAI,aAAa,IAAI;CAG9B,MAAM,eAAe,OAAO,IAAI,WAAW;CAa3C,IAAI,OAAO,iBAAiB,UAC1B,MAAM,IAAI,MACR,wDAAwD,KAAK,UAAU,YAAY,EAAE,sRACvF;CAUF,IAAI,gBAAgB,GAClB,MAAM,IAAI,MACR,4CAA4C,aAAa,iQAC3D;CAGF,MAAM,sBAAsB,cAAc,OAAO,IAAI,WAAW,KAAK,WAAW;CAEhF,sBAAsB,YAAY;AACpC;;;;;;;;;AAUA,eAAsB,oBAAoB,UAAsC,CAAC,GAAkB;CACjG,MAAM,kBAAkB,QAAQ,IAAI;CAEpC,IAAI,oBAAoB,QACtB,QAAQ,IAAI,WAAW;MAClB,IAAI,oBAAoB,QAC7B,MAAM,IAAI,MACR,yEAAyE,KAAK,UAAU,eAAe,EAAE,qDAC3G;CAGF,IAAI,iBAAiB;EACnB,QAAQ,IAAI,sDAAsD;EAClE;CACF;CAEA,QAAQ,IAAI,4CAA4C;CAExD,IAAI;EAGF,MAAM,qBAAqB;EAG3B,YAAY,mBAAmB,aAAa;EAC5C,YAAY,eAAe,MAAM;EAGjC,MAAM,qBAAqB,KAAK;EAChC,MAAM,UAAU;EAGhB,MAAM,kBAAkB,KAAK;EAC7B,MAAM,kBAAkB,cAAc;EAGtC,MAAM,gBAAgB,IAAI;EAO1B,IAAI,QAAQ,QAAQ,OAClB,MAAM,4BAAkD;OAExD,MAAM,kBAAkB,kBAAwC;EAIlE,MAAM,kBAAkB,aAAa,QAAQ;EAE7C,MAAM,oBAAoB,QAAQ,IAAI;EAKtC,MAAM,YAAY,qBAAqB;EAIvC,IAAI,QAAQ,QAAQ,OAClB,MAAM,2BAAiD;OAEvD,MAAM,kBAAkB,iBAAuC;EAGjE,kBAAkB;CACpB,SAAS,OAAO;EAMd,MAAM,qBAAqB;EAI3B,MAAM;CACR;AACF;;;;;;;;AASA,eAAe,uBAAsC;CACnD,IAAI;EACF,MAAM,kBAAkB,SAAS;CACnC,SAAS,eAAe;EAGtB,QAAQ,MAAM,gEAAgE,aAAa;CAC7F;CAEA,uBAAuB;CACvB,kBAAkB;AACpB;;;;;AAMA,eAAsB,qBAAoC;CACxD,IAAI,CAAC,iBAAiB;EACpB,QAAQ,IAAI,iCAAiC;EAC7C;CACF;CAEA,IAAI;EACF,MAAM,kBAAkB,SAAS;EAEjC,QAAQ,IAAI,wCAAwC;CACtD,SAAS,OAAO;EAGd,QAAQ,MAAM,6CAA6C,KAAK;EAEhE,MAAM;CACR,UAAU;EAIR,uBAAuB;EAEvB,kBAAkB;CACpB;AACF;;;;AAKA,SAAgB,sBAA+B;CAC7C,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"start-http-development-server.mjs","names":[],"sources":["../../../../../../../../packages/core/src/tests/start-http-development-server.ts"],"sourcesContent":["/**\n * HTTP Test Server\n *\n * Starts a minimal HTTP server for testing.\n * Unlike the full DevelopmentServer, this:\n * - Does NOT watch files\n * - Does NOT do HMR\n * - Only starts connectors needed for HTTP requests\n *\n * Used in Vitest's globalSetup to start server once for all test workers.\n */\nimport config from \"@mongez/config\";\nimport { Application } from \"../application\";\nimport { bootstrap } from \"../bootstrap\";\nimport { loadConfigFiles } from \"../config/load-config-files\";\nimport { connectorsManager } from \"../connectors/connectors-manager\";\nimport { ConnectorLifecyclePhase } from \"../connectors/types\";\nimport { filesOrchestrator } from \"../dev-server/files-orchestrator\";\nimport { assertPortIsAvailable } from \"../http/port-preflight\";\nimport { getHttpReadyReport } from \"../http/ready-report\";\nimport { loadEnvironmentFiles } from \"../utils/load-environment\";\nimport { warlockConfigManager } from \"../warlock-config/warlock-config.manager\";\nimport { installTestFakes, restoreTestFakes } from \"./fakes/test-fakes\";\nimport type { TestFakesSelection } from \"./fakes/test-fakes\";\nimport { publishTestServerPort, withdrawTestServerPort } from \"./test-server-port-channel\";\n\nlet isServerRunning = false;\n\nexport type StartHttpTestServerOptions = {\n /**\n * Port the test server binds to, overriding `http.port`.\n *\n * Needed because the server cannot be moved from outside: this function\n * bootstraps the app itself, and that bootstrap re-reads `.env`.\n *\n * `0` asks the OS for a free port. The port actually bound is published to\n * the test workers, so `testGet()`, `actingAs()` and friends follow it, and\n * a suite never collides with `warlock dev` or another suite.\n */\n port?: number;\n\n /**\n * Whether to boot the optional web connector.\n *\n * Defaults to `true` to preserve the full-stack test server. Pass `false`\n * for API-only suites: the web connector's lazy delegate is skipped before\n * `boot()`, so it never constructs its Vite-backed implementation.\n *\n * @default true\n */\n web?: boolean;\n\n /**\n * Which test fakes the server process installs (mail, queue, cache,\n * storage, clock, ids). Same values and precedence as `setupTest({ fakes })`:\n * this option > `tests.fakes` config > all on.\n *\n * A fake records what happens in ITS process: mail sent while this server\n * handles a request is captured here, not in the test worker that sent the\n * request. To assert on what an HTTP request did, serve it in the worker\n * with `createTestHttpServer()`. The storage fake is the exception: its\n * temp root is shared with the workers.\n */\n fakes?: TestFakesSelection;\n};\n\n/**\n * Start one lifecycle phase while omitting the web connector.\n *\n * Kept here rather than changing the manager's public API: this is a\n * test-server-only selection, and retaining the manager's boot-all / start-all\n * ordering is essential for HTTP and socket connector wiring.\n */\nasync function startTestServerPhase(phase: ConnectorLifecyclePhase): Promise<void> {\n const connectors = connectorsManager\n .list()\n .filter((connector) => connector.lifecyclePhase === phase)\n .filter((connector) => connector.name !== \"web\");\n\n for (const connector of connectors) {\n await connector.boot();\n }\n\n for (const connector of connectors) {\n await connector.start();\n }\n}\n\n/**\n * Apply the caller's port and preflight the bind.\n *\n * Called at the last moment before the HTTP connector binds, and that timing is\n * the fix: `bootstrap()` re-reads `.env` through `loadEnv()` (dotenv overrides\n * by default), and `src/config/http.ts` then resolves its port from that store,\n * so anything the caller set earlier is gone by the time the port is read.\n * Writing into `config` here is also the only channel that works — assigning\n * `process.env.HTTP_PORT` has no effect, since `env()` reads dotenv's own store\n * and never falls back to `process.env`.\n */\nasync function applyTestServerPort(port?: number): Promise<\"published\" | \"ephemeral\" | \"none\"> {\n const httpConfig = config.get(\"http\");\n\n if (!httpConfig) {\n if (port !== undefined) {\n throw new Error(\n `startHttpTestServer({ port: ${port} }) was given a port, but this app has no \\`http\\` config, so no HTTP server is started. Add \\`src/config/http.ts\\` first.`,\n );\n }\n\n return \"none\";\n }\n\n if (port !== undefined) {\n config.set(\"http.port\", port);\n }\n\n const resolvedPort = config.get(\"http.port\");\n\n // No configured port at all is fine: Fastify falls back to its own default and\n // the workers resolve the same one from their own config, so both ends agree\n // without the channel.\n //\n // A non-numeric port is NOT fine, and must fail loudly rather than skip the\n // preflight silently. `env()` coerces a value only when it round-trips exactly\n // (`String(Number(v)) === v`), so `HTTP_PORT=3999` and `HTTP_PORT=0` arrive as\n // numbers, but `03999`, `+3999`, `1e3` and anything with stray whitespace stay\n // strings. Letting those through used to reach `HttpConnector.start()`'s\n // `listen({ port })` unchanged — no preflight, no published port, and every\n // test worker resolving a URL from a channel nothing ever wrote to.\n if (typeof resolvedPort !== \"number\") {\n throw new Error(\n `startHttpTestServer() cannot use \\`http.port\\` value ${JSON.stringify(resolvedPort)} — it did not round-trip through Number() (env() only coerces a value when \\`String(Number(v)) === v\\`, so \"03999\", \"+3999\", \"1e3\", and values with stray whitespace stay strings). Fix \\`HTTP_PORT\\` in .env, or pass an explicit numeric port: startHttpTestServer({ port: 3999 }).`,\n );\n }\n\n // `0` is the OS's \"pick a free one for me\". There is nothing to preflight —\n // probing 0 would bind some unrelated port and prove nothing — and nothing to\n // publish yet: the port is only known once the HTTP connector has bound, and\n // `HttpConnector.start()` records the port `listen()` actually returned (see\n // `ready-report.ts`). It is published right after the late phase instead.\n if (resolvedPort === 0) {\n return \"ephemeral\";\n }\n\n if (resolvedPort < 0) {\n throw new Error(\n `startHttpTestServer() cannot run on port ${resolvedPort}. Pass a port number, or 0 to let the OS pick a free one — e.g. startHttpTestServer({ port: 0 }).`,\n );\n }\n\n await assertPortIsAvailable(resolvedPort, config.get(\"http.host\") || \"localhost\");\n\n publishTestServerPort(resolvedPort);\n\n return \"published\";\n}\n\n/**\n * Publish the port an ephemeral (`port: 0`) bind actually took.\n *\n * `before` is the ready report from before the late phase: the report is a\n * module-level record, so an unchanged one means THIS boot bound nothing and an\n * older report must not be mistaken for it.\n */\nfunction publishEphemeralPort(before: ReturnType<typeof getHttpReadyReport>): void {\n const report = getHttpReadyReport();\n\n if (!report || report === before || report.port <= 0) {\n throw new Error(\n \"startHttpTestServer({ port: 0 }) booted, but the HTTP connector did not bind a port, so there is no address to give the test workers. Check that `src/config/http.ts` exists and that this process serves HTTP (its role is not worker-only).\",\n );\n }\n\n publishTestServerPort(report.port);\n}\n\n/**\n * Start the HTTP test server (minimal - no file watching)\n * Call this in Vitest's globalSetup\n *\n * @example\n * // run this suite on its own port, whatever `.env` says\n * await startHttpTestServer({ port: 3999 });\n *\n * @example\n * // let the OS pick a free port; the request helpers follow it\n * await startHttpTestServer({ port: 0 });\n */\nexport async function startHttpTestServer(options: StartHttpTestServerOptions = {}): Promise<void> {\n const nodeEnvironment = process.env.NODE_ENV;\n\n if (nodeEnvironment === undefined) {\n process.env.NODE_ENV = \"test\";\n } else if (nodeEnvironment !== \"test\") {\n throw new Error(\n `startHttpTestServer() requires NODE_ENV=\"test\", but received NODE_ENV=${JSON.stringify(nodeEnvironment)}. Set NODE_ENV=test before starting the test server.`,\n );\n }\n\n if (isServerRunning) {\n console.log(\"[test-server] Server already running, skipping start\");\n return;\n }\n\n console.log(\"[test-server] Starting HTTP test server...\");\n\n try {\n // `globalSetup` runs in Vitest's main process, where Vitest's worker env\n // setup has not run. Load `.env.test` here, before any config is read.\n await loadEnvironmentFiles();\n\n // Set environment\n Application.setRuntimeStrategy(\"development\");\n Application.setEnvironment(\"test\");\n\n // Bootstrap (env, etc.)\n await warlockConfigManager.load();\n await bootstrap();\n\n // Initialize file orchestrator (but don't watch)\n await filesOrchestrator.init();\n await filesOrchestrator.initializeAll();\n\n // Load config files\n await loadConfigFiles(true);\n\n // Early-phase connectors (database, cache, logger, storage, mailer,\n // herald) must start BEFORE app modules load: a module's `main.ts` boot\n // side-effect can query the DB at import time, so the data source has to\n // be registered first. This mirrors the dev/prod boot order (see\n // `cli-commands.manager`, `production-builder`, and `DevelopmentServer`).\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Early);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Early);\n }\n\n // Fakes before app modules load, so module boot code already sees them.\n await installTestFakes(options.fakes);\n\n // Load application modules (their boot side-effects now see a live DB).\n await filesOrchestrator.moduleLoader.loadAll();\n\n const portMode = await applyTestServerPort(options.port);\n const readyReportBefore = getHttpReadyReport();\n\n // A rejecting validator (Application.onValidateBoot) must abort boot\n // before late-phase connectors bind a port — same slot as\n // `DevelopmentServer.start()` and the generated production `app.ts`.\n await Application.runStartupValidators();\n\n // Late-phase connectors (http, socket) bind after app code has\n // registered its routes and listeners.\n if (options.web === false) {\n await startTestServerPhase(ConnectorLifecyclePhase.Late);\n } else {\n await connectorsManager.startPhase(ConnectorLifecyclePhase.Late);\n }\n\n if (portMode === \"ephemeral\") {\n publishEphemeralPort(readyReportBefore);\n }\n\n isServerRunning = true;\n } catch (error) {\n // This function owns the connectors it starts, so a failure part-way\n // through has to leave nothing behind. Without this, `isServerRunning` was\n // still `false` — it is only set on the last line — so `globalTeardown`'s\n // `stopHttpTestServer()` reported \"No server to stop\" and walked away from\n // live early-phase connectors and a published port that outlived them.\n await unwindPartialStartup();\n\n // Rethrown unchanged: the startup failure is the one the caller needs to\n // read. A cleanup failure that replaced it would hide the actual cause.\n throw error;\n }\n}\n\n/**\n * Best-effort teardown of whatever a failed {@link startHttpTestServer} managed\n * to start.\n *\n * Every step is independent and none may throw: this runs while an error is\n * already in flight, and the caller is about to rethrow it.\n */\nasync function unwindPartialStartup(): Promise<void> {\n try {\n await restoreTestFakes();\n } catch (fakesError) {\n console.error(\n \"[test-server] Restoring the test fakes after a failed start did not complete:\",\n fakesError,\n );\n }\n\n try {\n await connectorsManager.shutdown();\n } catch (shutdownError) {\n // Reported, not thrown — it is secondary to the startup error being\n // rethrown, and losing that one to this would be the worse outcome.\n console.error(\"[test-server] Cleanup after a failed start did not complete:\", shutdownError);\n }\n\n withdrawTestServerPort();\n isServerRunning = false;\n}\n\n/**\n * Stop the HTTP test server\n * Call this in Vitest's globalTeardown\n */\nexport async function stopHttpTestServer(): Promise<void> {\n if (!isServerRunning) {\n console.log(\"[test-server] No server to stop\");\n return;\n }\n\n try {\n try {\n await restoreTestFakes();\n } catch (fakesError) {\n console.error(\"[test-server] Restoring the test fakes did not complete:\", fakesError);\n }\n\n await connectorsManager.shutdown();\n\n console.log(\"[test-server] HTTP test server stopped\");\n } catch (error) {\n // Surfaced, never swallowed — cleaning up is not the same as the shutdown\n // having succeeded, and a suite whose teardown failed should say so.\n console.error(\"[test-server] Error stopping HTTP server:\", error);\n\n throw error;\n } finally {\n // In a `finally` rather than after the `await`: when `shutdown()` threw,\n // the published port survived the server it pointed at, so the next run in\n // the same process inherited a stale one and sent every request to it.\n withdrawTestServerPort();\n\n isServerRunning = false;\n }\n}\n\n/**\n * Check if test server is running\n */\nexport function isTestServerRunning(): boolean {\n return isServerRunning;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAI,kBAAkB;;;;;;;;AA+CtB,eAAe,qBAAqB,OAA+C;CACjF,MAAM,aAAa,kBAChB,KAAK,CAAC,CACN,QAAQ,cAAc,UAAU,mBAAmB,KAAK,CAAC,CACzD,QAAQ,cAAc,UAAU,SAAS,KAAK;CAEjD,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,KAAK;CAGvB,KAAK,MAAM,aAAa,YACtB,MAAM,UAAU,MAAM;AAE1B;;;;;;;;;;;;AAaA,eAAe,oBAAoB,MAA4D;CAG7F,IAAI,CAFe,OAAO,IAAI,MAEhB,GAAG;EACf,IAAI,SAAS,QACX,MAAM,IAAI,MACR,+BAA+B,KAAK,2HACtC;EAGF,OAAO;CACT;CAEA,IAAI,SAAS,QACX,OAAO,IAAI,aAAa,IAAI;CAG9B,MAAM,eAAe,OAAO,IAAI,WAAW;CAa3C,IAAI,OAAO,iBAAiB,UAC1B,MAAM,IAAI,MACR,wDAAwD,KAAK,UAAU,YAAY,EAAE,sRACvF;CAQF,IAAI,iBAAiB,GACnB,OAAO;CAGT,IAAI,eAAe,GACjB,MAAM,IAAI,MACR,4CAA4C,aAAa,kGAC3D;CAGF,MAAM,sBAAsB,cAAc,OAAO,IAAI,WAAW,KAAK,WAAW;CAEhF,sBAAsB,YAAY;CAElC,OAAO;AACT;;;;;;;;AASA,SAAS,qBAAqB,QAAqD;CACjF,MAAM,SAAS,mBAAmB;CAElC,IAAI,CAAC,UAAU,WAAW,UAAU,OAAO,QAAQ,GACjD,MAAM,IAAI,MACR,+OACF;CAGF,sBAAsB,OAAO,IAAI;AACnC;;;;;;;;;;;;;AAcA,eAAsB,oBAAoB,UAAsC,CAAC,GAAkB;CACjG,MAAM,kBAAkB,QAAQ,IAAI;CAEpC,IAAI,oBAAoB,QACtB,QAAQ,IAAI,WAAW;MAClB,IAAI,oBAAoB,QAC7B,MAAM,IAAI,MACR,yEAAyE,KAAK,UAAU,eAAe,EAAE,qDAC3G;CAGF,IAAI,iBAAiB;EACnB,QAAQ,IAAI,sDAAsD;EAClE;CACF;CAEA,QAAQ,IAAI,4CAA4C;CAExD,IAAI;EAGF,MAAM,qBAAqB;EAG3B,YAAY,mBAAmB,aAAa;EAC5C,YAAY,eAAe,MAAM;EAGjC,MAAM,qBAAqB,KAAK;EAChC,MAAM,UAAU;EAGhB,MAAM,kBAAkB,KAAK;EAC7B,MAAM,kBAAkB,cAAc;EAGtC,MAAM,gBAAgB,IAAI;EAO1B,IAAI,QAAQ,QAAQ,OAClB,MAAM,4BAAkD;OAExD,MAAM,kBAAkB,kBAAwC;EAIlE,MAAM,iBAAiB,QAAQ,KAAK;EAGpC,MAAM,kBAAkB,aAAa,QAAQ;EAE7C,MAAM,WAAW,MAAM,oBAAoB,QAAQ,IAAI;EACvD,MAAM,oBAAoB,mBAAmB;EAK7C,MAAM,YAAY,qBAAqB;EAIvC,IAAI,QAAQ,QAAQ,OAClB,MAAM,2BAAiD;OAEvD,MAAM,kBAAkB,iBAAuC;EAGjE,IAAI,aAAa,aACf,qBAAqB,iBAAiB;EAGxC,kBAAkB;CACpB,SAAS,OAAO;EAMd,MAAM,qBAAqB;EAI3B,MAAM;CACR;AACF;;;;;;;;AASA,eAAe,uBAAsC;CACnD,IAAI;EACF,MAAM,iBAAiB;CACzB,SAAS,YAAY;EACnB,QAAQ,MACN,iFACA,UACF;CACF;CAEA,IAAI;EACF,MAAM,kBAAkB,SAAS;CACnC,SAAS,eAAe;EAGtB,QAAQ,MAAM,gEAAgE,aAAa;CAC7F;CAEA,uBAAuB;CACvB,kBAAkB;AACpB;;;;;AAMA,eAAsB,qBAAoC;CACxD,IAAI,CAAC,iBAAiB;EACpB,QAAQ,IAAI,iCAAiC;EAC7C;CACF;CAEA,IAAI;EACF,IAAI;GACF,MAAM,iBAAiB;EACzB,SAAS,YAAY;GACnB,QAAQ,MAAM,4DAA4D,UAAU;EACtF;EAEA,MAAM,kBAAkB,SAAS;EAEjC,QAAQ,IAAI,wCAAwC;CACtD,SAAS,OAAO;EAGd,QAAQ,MAAM,6CAA6C,KAAK;EAEhE,MAAM;CACR,UAAU;EAIR,uBAAuB;EAEvB,kBAAkB;CACpB;AACF;;;;AAKA,SAAgB,sBAA+B;CAC7C,OAAO;AACT"}
|
|
@@ -13,6 +13,25 @@ declare function getTestServerUrl(): string;
|
|
|
13
13
|
* Uses native fetch - lightweight, no extra dependencies
|
|
14
14
|
*/
|
|
15
15
|
declare function testRequest(path: string, options?: RequestInit): Promise<Response>;
|
|
16
|
+
/** The request helpers, bound to one server. */
|
|
17
|
+
type TestRequestClient = {
|
|
18
|
+
request(path: string, options?: RequestInit): Promise<Response>;
|
|
19
|
+
get(path: string, options?: RequestInit): Promise<Response>;
|
|
20
|
+
post(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
|
|
21
|
+
put(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
|
|
22
|
+
patch(path: string, body?: unknown, options?: RequestInit): Promise<Response>;
|
|
23
|
+
delete(path: string, options?: RequestInit): Promise<Response>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Request helpers bound to `baseUrl` (a string, or a function read on every
|
|
27
|
+
* request). `testGet()` and friends are this, bound to the shared test server;
|
|
28
|
+
* `createTestHttpServer()` returns one bound to its own port.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const client = createTestRequestClient("http://127.0.0.1:4100");
|
|
32
|
+
* await client.post("/posts", { title: "Hello" });
|
|
33
|
+
*/
|
|
34
|
+
declare function createTestRequestClient(baseUrl: string | (() => string)): TestRequestClient;
|
|
16
35
|
/**
|
|
17
36
|
* GET request helper
|
|
18
37
|
*/
|
|
@@ -42,5 +61,5 @@ declare function parseJsonResponse<T>(response: Response): Promise<T>;
|
|
|
42
61
|
*/
|
|
43
62
|
declare function expectJson<T>(response: Response, expectedStatus?: number): Promise<T>;
|
|
44
63
|
//#endregion
|
|
45
|
-
export { expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest };
|
|
64
|
+
export { TestRequestClient, createTestRequestClient, expectJson, getTestServerUrl, parseJsonResponse, testDelete, testGet, testPatch, testPost, testPut, testRequest };
|
|
46
65
|
//# sourceMappingURL=test-helpers.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-helpers.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/test-helpers.ts"],"mappings":";;AAaA;;;;AAAgC;AA6BhC;;AA7BgC,iBAAhB,gBAAA;;;;;iBA6BM,WAAA,CAAY,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;
|
|
1
|
+
{"version":3,"file":"test-helpers.d.mts","names":[],"sources":["../../../../../../../../packages/core/src/tests/test-helpers.ts"],"mappings":";;AAaA;;;;AAAgC;AA6BhC;;AA7BgC,iBAAhB,gBAAA;;;;;iBA6BM,WAAA,CAAY,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;KA8CxE,iBAAA;EACV,OAAA,CAAQ,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACtD,GAAA,CAAI,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EAClD,IAAA,CAAK,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACnE,GAAA,CAAI,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EAClE,KAAA,CAAM,IAAA,UAAc,IAAA,YAAgB,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;EACpE,MAAA,CAAO,IAAA,UAAc,OAAA,GAAU,WAAA,GAAc,OAAA,CAAQ,QAAA;AAAA;;;;;;;;;;iBAYvC,uBAAA,CAAwB,OAAA,4BAAmC,iBAAiB;;;;iBAqBtE,OAAA,CAAQ,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAO1D,QAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,OAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,UAAA,CAAW,IAAA,UAAc,OAAA,GAAS,WAAA,GAAmB,OAAA,CAAQ,QAAA;;;;iBAO7D,SAAA,CACpB,IAAA,UACA,IAAA,YACA,OAAA,GAAS,WAAA,GACR,OAAA,CAAQ,QAAA;;;;iBAOW,iBAAA,IAAqB,QAAA,EAAU,QAAA,GAAW,OAAA,CAAQ,CAAA;;;;iBAOlD,UAAA,IAAc,QAAA,EAAU,QAAA,EAAU,cAAA,YAAuB,OAAA,CAAQ,CAAA"}
|