@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 @@
|
|
|
1
|
+
{"version":3,"file":"trace-report.types.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/trace/trace-report.types.ts"],"sourcesContent":["import type { DevtoolsPhaseRecord } from \"../devtools/devtools-client\";\n\n/** The `schemaVersion` of {@link TraceReport}. Fields are only added within a version. */\nexport const TRACE_SCHEMA_VERSION = 1;\n\n/** One middleware run, in the order it ran. */\nexport type TraceMiddleware = {\n name: string | null;\n index: number | null;\n durationMs: number;\n};\n\n/** What the route's validation did. */\nexport type TraceValidation = {\n /** Whether a validation phase ran (the route declares a schema or a `validate` function). */\n ran: boolean;\n durationMs: number | null;\n /**\n * `true` when validation ran and the handler ran after it (or the response\n * succeeded); `false` when it ran, the handler did not, and the response is\n * an error; `null` when validation did not run.\n */\n passed: boolean | null;\n /** The response body's `errors` (or the whole body) when validation failed; otherwise `null`. */\n errors: unknown;\n};\n\n/** One recorded query, with its N+1 flag. */\nexport type TraceQuery = Record<string, unknown> & {\n /** `true` when the query's shape is one devtools reported as an N+1. */\n nPlusOne: boolean;\n};\n\n/** What `warlock trace --json` prints and `traceRequest()` returns. */\nexport type TraceReport = {\n schemaVersion: typeof TRACE_SCHEMA_VERSION;\n /** The request id the server used (the `x-request-id` it echoed). */\n requestId: string;\n /** The dev server origin the request went to. */\n server: string;\n request: {\n method: string;\n url: string;\n /** Sent headers; `authorization`, `cookie` and `proxy-authorization` values read `[redacted]`. */\n headers: Record<string, string>;\n body: unknown;\n };\n response: {\n status: number;\n headers: Record<string, string>;\n /** Parsed JSON when the content type is JSON, else text; `null` for an empty body. */\n body: unknown;\n /** Whether `body` was cut to the first 64 KiB. */\n truncated: boolean;\n };\n /** The matched route pattern, e.g. `/posts/:id`, or `null`. */\n route: string | null;\n /** The error devtools recorded for the request, or `null`. */\n error: string | null;\n timeline: {\n /** Every recorded phase in the order it was recorded. */\n phases: DevtoolsPhaseRecord[];\n routeMatch: { durationMs: number } | null;\n middleware: TraceMiddleware[];\n validation: TraceValidation;\n handler: { durationMs: number } | null;\n };\n queries: TraceQuery[];\n /** Devtools warnings for the request (`{ type: \"n+1\", message, shape, count, caller }`). */\n warnings: Record<string, unknown>[];\n logs: Record<string, unknown>[];\n cache: Record<string, unknown>[];\n /** Ids of mails captured during the request. */\n mails: string[];\n timings: {\n /** The server-side duration devtools measured, or `null` while unsettled. */\n totalMs: number | null;\n /** The round trip measured by the client. */\n clientMs: number;\n /** Total time per phase name. */\n phasesMs: Record<string, number>;\n };\n};\n"],"mappings":";;AAGA,MAAa,uBAAuB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { DevtoolsFetch, DevtoolsRequestRecord } from "../devtools/devtools-client.mjs";
|
|
2
|
+
import { TraceReport } from "./trace-report.types.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../../packages/core/src/tooling/trace/trace-request.d.ts
|
|
5
|
+
/** The correlation header core reads and echoes by default (`http.requestId.header`). */
|
|
6
|
+
declare const TRACE_REQUEST_ID_HEADER = "x-request-id";
|
|
7
|
+
/** Response bodies longer than this are cut in the report. */
|
|
8
|
+
declare const TRACE_BODY_LIMIT: number;
|
|
9
|
+
/** Inputs of {@link traceRequest}. */
|
|
10
|
+
type TraceRequestOptions = {
|
|
11
|
+
/** HTTP method, any case. */method: string; /** A path on the dev server (`/posts?page=2`) or an absolute URL. */
|
|
12
|
+
url: string;
|
|
13
|
+
/**
|
|
14
|
+
* The request body. A string is sent as-is; anything else is sent as JSON
|
|
15
|
+
* with `content-type: application/json` unless `headers` sets a content type.
|
|
16
|
+
*/
|
|
17
|
+
body?: unknown; /** Extra request headers. */
|
|
18
|
+
headers?: Record<string, string>; /** Project root, where `.warlock/dev-server.json` is read. Default: `process.cwd()`. */
|
|
19
|
+
cwd?: string; /** The dev server origin; overrides the recorded one. */
|
|
20
|
+
serverUrl?: string; /** The devtools mount; overrides the recorded one (default `/__warlock`). */
|
|
21
|
+
devtoolsPath?: string;
|
|
22
|
+
fetch?: DevtoolsFetch; /** How long to wait for devtools to settle the request record. Default 5000 ms. */
|
|
23
|
+
timeoutMs?: number; /** Poll interval while waiting for the record. Default 50 ms. */
|
|
24
|
+
intervalMs?: number;
|
|
25
|
+
/**
|
|
26
|
+
* The correlation header the app reads and echoes (`http.requestId.header`).
|
|
27
|
+
* Default `x-request-id`.
|
|
28
|
+
*/
|
|
29
|
+
requestIdHeader?: string;
|
|
30
|
+
};
|
|
31
|
+
/** The HTTP response as the report needs it. */
|
|
32
|
+
type TracedResponse = {
|
|
33
|
+
status: number;
|
|
34
|
+
headers: Record<string, string>; /** The raw response text. */
|
|
35
|
+
text: string;
|
|
36
|
+
};
|
|
37
|
+
/** Inputs of {@link buildTraceReport}. */
|
|
38
|
+
type BuildTraceReportInput = {
|
|
39
|
+
requestId: string;
|
|
40
|
+
server: string;
|
|
41
|
+
request: {
|
|
42
|
+
method: string;
|
|
43
|
+
url: string;
|
|
44
|
+
headers: Record<string, string>;
|
|
45
|
+
body: unknown;
|
|
46
|
+
};
|
|
47
|
+
response: TracedResponse;
|
|
48
|
+
record: DevtoolsRequestRecord;
|
|
49
|
+
clientMs: number;
|
|
50
|
+
};
|
|
51
|
+
/** Headers with credential values replaced by `[redacted]`. */
|
|
52
|
+
declare function redactHeaders(headers: Record<string, string>): Record<string, string>;
|
|
53
|
+
/** The response body as the report prints it: parsed JSON, else text, cut at the limit. */
|
|
54
|
+
declare function readResponseBody(text: string, contentType: string | undefined): {
|
|
55
|
+
body: unknown;
|
|
56
|
+
truncated: boolean;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Assemble a {@link TraceReport} from the HTTP response and the devtools
|
|
60
|
+
* record of the same request. Pure: no I/O, so it is testable on its own.
|
|
61
|
+
*/
|
|
62
|
+
declare function buildTraceReport(input: BuildTraceReportInput): TraceReport;
|
|
63
|
+
/** The absolute URL a trace sends to: `url` as-is when absolute, else joined to the server origin. */
|
|
64
|
+
declare function resolveTraceUrl(server: string, url: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Send one request to the running dev server and return its devtools
|
|
67
|
+
* timeline: middleware, validation result, handler, queries (with N+1 flags),
|
|
68
|
+
* logs, cache operations, captured mails, the response and the timings.
|
|
69
|
+
*
|
|
70
|
+
* Devtools is reached first, so a missing dev server (`WL8008`) or devtools
|
|
71
|
+
* (`WL8009`) fails before anything is sent. The request carries an
|
|
72
|
+
* `x-request-id` (unless the caller set one), which core adopts as
|
|
73
|
+
* `request.id` and echoes back; that id is how the devtools record is found.
|
|
74
|
+
* Throws `WL5004` when devtools never recorded the request.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* const report = await traceRequest({ method: "POST", url: "/posts", body: { title: "Hi" } });
|
|
78
|
+
* report.timeline.validation.passed; // false when the body was refused
|
|
79
|
+
*/
|
|
80
|
+
declare function traceRequest(options: TraceRequestOptions): Promise<TraceReport>;
|
|
81
|
+
//#endregion
|
|
82
|
+
export { BuildTraceReportInput, TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, TraceRequestOptions, TracedResponse, buildTraceReport, readResponseBody, redactHeaders, resolveTraceUrl, traceRequest };
|
|
83
|
+
//# sourceMappingURL=trace-request.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-request.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/trace/trace-request.ts"],"mappings":";;;;;cAgBa,uBAAA;AAAb;AAAA,cAGa,gBAAA;;KAMD,mBAAA;EATwB,6BAWlC,MAAA,UARuC;EAUvC,GAAA;EAVuC;AAAA;AAMzC;;EASE,IAAA,YASqB;EAPrB,OAAA,GAAU,MAAA,kBAPV;EASA,GAAA,WAFA;EAIA,SAAA,WAFA;EAIA,YAAA;EACA,KAAA,GAAQ,aAAa,EAArB;EAEA,SAAA;EAEA,UAAA;EAKA;;AAAe;AAIjB;EAJE,eAAA;AAAA;;KAIU,cAAA;EACV,MAAA;EACA,OAAA,EAAS,MAAM,kBAEf;EAAA,IAAA;AAAA;AAIF;AAAA,KAAY,qBAAA;EACV,SAAA;EACA,MAAA;EACA,OAAA;IAAW,MAAA;IAAgB,GAAA;IAAa,OAAA,EAAS,MAAA;IAAwB,IAAA;EAAA;EACzE,QAAA,EAAU,cAAA;EACV,MAAA,EAAQ,qBAAA;EACR,QAAA;AAAA;;iBAkBc,aAAA,CAAc,OAAA,EAAS,MAAA,mBAAyB,MAAM;;iBAWtD,gBAAA,CACd,IAAA,UACA,WAAA;EACG,IAAA;EAAe,SAAA;AAAA;;AAhCV;AAkBV;;iBA2EgB,gBAAA,CAAiB,KAAA,EAAO,qBAAA,GAAwB,WAAW;;iBAoE3D,eAAA,CAAgB,MAAA,UAAgB,GAAW;;;;AA/IW;AAWtE;;;;;;;;;AAG6B;AA6D7B;iBA+GsB,YAAA,CAAa,OAAA,EAAS,mBAAA,GAAsB,OAAA,CAAQ,WAAA"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { WarlockError } from "../../errors/warlock-error.mjs";
|
|
2
|
+
import { connectDevtools } from "../devtools/devtools-client.mjs";
|
|
3
|
+
import { TRACE_SCHEMA_VERSION } from "./trace-report.types.mjs";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
|
|
6
|
+
//#region ../../packages/core/src/tooling/trace/trace-request.ts
|
|
7
|
+
/** The correlation header core reads and echoes by default (`http.requestId.header`). */
|
|
8
|
+
const TRACE_REQUEST_ID_HEADER = "x-request-id";
|
|
9
|
+
/** Response bodies longer than this are cut in the report. */
|
|
10
|
+
const TRACE_BODY_LIMIT = 64 * 1024;
|
|
11
|
+
/** Header values never printed in a report. */
|
|
12
|
+
const REDACTED_HEADERS = new Set([
|
|
13
|
+
"authorization",
|
|
14
|
+
"cookie",
|
|
15
|
+
"proxy-authorization"
|
|
16
|
+
]);
|
|
17
|
+
function isRecord(value) {
|
|
18
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
function lowerCaseKeys(headers) {
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const [key, value] of Object.entries(headers)) result[key.toLowerCase()] = value;
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
/** Headers with credential values replaced by `[redacted]`. */
|
|
26
|
+
function redactHeaders(headers) {
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const [key, value] of Object.entries(headers)) result[key] = REDACTED_HEADERS.has(key.toLowerCase()) ? "[redacted]" : value;
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/** The response body as the report prints it: parsed JSON, else text, cut at the limit. */
|
|
32
|
+
function readResponseBody(text, contentType) {
|
|
33
|
+
if (text.length === 0) return {
|
|
34
|
+
body: null,
|
|
35
|
+
truncated: false
|
|
36
|
+
};
|
|
37
|
+
const truncated = text.length > TRACE_BODY_LIMIT;
|
|
38
|
+
if (!truncated && contentType !== void 0 && /\bjson\b/i.test(contentType)) try {
|
|
39
|
+
return {
|
|
40
|
+
body: JSON.parse(text),
|
|
41
|
+
truncated: false
|
|
42
|
+
};
|
|
43
|
+
} catch {}
|
|
44
|
+
return {
|
|
45
|
+
body: truncated ? text.slice(0, TRACE_BODY_LIMIT) : text,
|
|
46
|
+
truncated
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function attrNumber(attrs, key) {
|
|
50
|
+
const value = attrs?.[key];
|
|
51
|
+
return typeof value === "number" ? value : null;
|
|
52
|
+
}
|
|
53
|
+
function attrString(attrs, key) {
|
|
54
|
+
const value = attrs?.[key];
|
|
55
|
+
return typeof value === "string" ? value : null;
|
|
56
|
+
}
|
|
57
|
+
function validationOf(record, status, body) {
|
|
58
|
+
const phases = record.phases.filter((phase) => phase.name === "validation");
|
|
59
|
+
if (phases.length === 0) return {
|
|
60
|
+
ran: false,
|
|
61
|
+
durationMs: null,
|
|
62
|
+
passed: null,
|
|
63
|
+
errors: null
|
|
64
|
+
};
|
|
65
|
+
const durationMs = phases.reduce((total, phase) => total + phase.durationMs, 0);
|
|
66
|
+
const passed = record.phases.some((phase) => phase.name === "handler") || status < 400;
|
|
67
|
+
return {
|
|
68
|
+
ran: true,
|
|
69
|
+
durationMs,
|
|
70
|
+
passed,
|
|
71
|
+
errors: passed ? null : isRecord(body) && "errors" in body ? body.errors : body
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function sumPhase(record, name) {
|
|
75
|
+
const phases = record.phases.filter((phase) => phase.name === name);
|
|
76
|
+
if (phases.length === 0) return null;
|
|
77
|
+
return { durationMs: phases.reduce((total, phase) => total + phase.durationMs, 0) };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Assemble a {@link TraceReport} from the HTTP response and the devtools
|
|
81
|
+
* record of the same request. Pure: no I/O, so it is testable on its own.
|
|
82
|
+
*/
|
|
83
|
+
function buildTraceReport(input) {
|
|
84
|
+
const { record, response } = input;
|
|
85
|
+
const responseHeaders = lowerCaseKeys(response.headers);
|
|
86
|
+
const { body, truncated } = readResponseBody(response.text, responseHeaders["content-type"]);
|
|
87
|
+
const middleware = record.phases.filter((phase) => phase.name === "middleware").map((phase) => ({
|
|
88
|
+
name: attrString(phase.attrs, "name"),
|
|
89
|
+
index: attrNumber(phase.attrs, "index"),
|
|
90
|
+
durationMs: phase.durationMs
|
|
91
|
+
}));
|
|
92
|
+
const nPlusOneShapes = new Set(record.warnings.flatMap((warning) => warning.type === "n+1" && typeof warning.shape === "string" ? [warning.shape] : []));
|
|
93
|
+
const queries = record.queries.map((query) => ({
|
|
94
|
+
...query,
|
|
95
|
+
nPlusOne: typeof query.shape === "string" && nPlusOneShapes.has(query.shape)
|
|
96
|
+
}));
|
|
97
|
+
const phasesMs = {};
|
|
98
|
+
for (const phase of record.phases) phasesMs[phase.name] = (phasesMs[phase.name] ?? 0) + phase.durationMs;
|
|
99
|
+
return {
|
|
100
|
+
schemaVersion: 1,
|
|
101
|
+
requestId: input.requestId,
|
|
102
|
+
server: input.server,
|
|
103
|
+
request: {
|
|
104
|
+
method: input.request.method,
|
|
105
|
+
url: input.request.url,
|
|
106
|
+
headers: redactHeaders(input.request.headers),
|
|
107
|
+
body: input.request.body
|
|
108
|
+
},
|
|
109
|
+
response: {
|
|
110
|
+
status: response.status,
|
|
111
|
+
headers: redactHeaders(responseHeaders),
|
|
112
|
+
body,
|
|
113
|
+
truncated
|
|
114
|
+
},
|
|
115
|
+
route: record.route ?? null,
|
|
116
|
+
error: record.error ?? null,
|
|
117
|
+
timeline: {
|
|
118
|
+
phases: record.phases,
|
|
119
|
+
routeMatch: sumPhase(record, "route.match"),
|
|
120
|
+
middleware,
|
|
121
|
+
validation: validationOf(record, response.status, body),
|
|
122
|
+
handler: sumPhase(record, "handler")
|
|
123
|
+
},
|
|
124
|
+
queries,
|
|
125
|
+
warnings: record.warnings,
|
|
126
|
+
logs: record.logs,
|
|
127
|
+
cache: record.cache,
|
|
128
|
+
mails: record.mails,
|
|
129
|
+
timings: {
|
|
130
|
+
totalMs: record.durationMs ?? null,
|
|
131
|
+
clientMs: input.clientMs,
|
|
132
|
+
phasesMs
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** The absolute URL a trace sends to: `url` as-is when absolute, else joined to the server origin. */
|
|
137
|
+
function resolveTraceUrl(server, url) {
|
|
138
|
+
if (/^https?:\/\//i.test(url)) return url;
|
|
139
|
+
return `${server}${url.startsWith("/") ? url : `/${url}`}`;
|
|
140
|
+
}
|
|
141
|
+
/** The body and headers to send for a {@link TraceRequestOptions.body}. */
|
|
142
|
+
function encodeBody(body, headers) {
|
|
143
|
+
if (body === void 0) return {
|
|
144
|
+
payload: void 0,
|
|
145
|
+
headers
|
|
146
|
+
};
|
|
147
|
+
if (typeof body === "string") return {
|
|
148
|
+
payload: body,
|
|
149
|
+
headers
|
|
150
|
+
};
|
|
151
|
+
const hasContentType = Object.keys(headers).some((key) => key.toLowerCase() === "content-type");
|
|
152
|
+
return {
|
|
153
|
+
payload: JSON.stringify(body),
|
|
154
|
+
headers: hasContentType ? headers : {
|
|
155
|
+
...headers,
|
|
156
|
+
"content-type": "application/json"
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function headerValue(headers, name) {
|
|
161
|
+
const key = Object.keys(headers).find((candidate) => candidate.toLowerCase() === name);
|
|
162
|
+
return key === void 0 ? void 0 : headers[key];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Send one request to the running dev server and return its devtools
|
|
166
|
+
* timeline: middleware, validation result, handler, queries (with N+1 flags),
|
|
167
|
+
* logs, cache operations, captured mails, the response and the timings.
|
|
168
|
+
*
|
|
169
|
+
* Devtools is reached first, so a missing dev server (`WL8008`) or devtools
|
|
170
|
+
* (`WL8009`) fails before anything is sent. The request carries an
|
|
171
|
+
* `x-request-id` (unless the caller set one), which core adopts as
|
|
172
|
+
* `request.id` and echoes back; that id is how the devtools record is found.
|
|
173
|
+
* Throws `WL5004` when devtools never recorded the request.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* const report = await traceRequest({ method: "POST", url: "/posts", body: { title: "Hi" } });
|
|
177
|
+
* report.timeline.validation.passed; // false when the body was refused
|
|
178
|
+
*/
|
|
179
|
+
async function traceRequest(options) {
|
|
180
|
+
const fetcher = options.fetch ?? ((input, init) => fetch(input, init));
|
|
181
|
+
const devtools = await connectDevtools({
|
|
182
|
+
cwd: options.cwd,
|
|
183
|
+
url: options.serverUrl,
|
|
184
|
+
devtoolsPath: options.devtoolsPath,
|
|
185
|
+
fetch: fetcher
|
|
186
|
+
});
|
|
187
|
+
const method = options.method.toUpperCase();
|
|
188
|
+
const url = resolveTraceUrl(devtools.url, options.url);
|
|
189
|
+
const idHeader = (options.requestIdHeader ?? "x-request-id").toLowerCase();
|
|
190
|
+
const ownId = headerValue(options.headers ?? {}, idHeader);
|
|
191
|
+
const sentId = ownId ?? randomUUID();
|
|
192
|
+
const base = ownId === void 0 ? {
|
|
193
|
+
...options.headers,
|
|
194
|
+
[idHeader]: sentId
|
|
195
|
+
} : { ...options.headers };
|
|
196
|
+
const { payload, headers } = encodeBody(options.body, base);
|
|
197
|
+
const startedAt = performance.now();
|
|
198
|
+
let response;
|
|
199
|
+
try {
|
|
200
|
+
response = await fetcher(url, {
|
|
201
|
+
method,
|
|
202
|
+
headers,
|
|
203
|
+
body: payload
|
|
204
|
+
});
|
|
205
|
+
} catch (error) {
|
|
206
|
+
throw new WarlockError("WL8008", `The dev server at ${devtools.url} did not answer ${method} ${url}: ${error instanceof Error ? error.message : String(error)}.`, { cause: error });
|
|
207
|
+
}
|
|
208
|
+
const text = await response.text();
|
|
209
|
+
const clientMs = performance.now() - startedAt;
|
|
210
|
+
const responseHeaders = {};
|
|
211
|
+
response.headers.forEach((value, key) => {
|
|
212
|
+
responseHeaders[key] = value;
|
|
213
|
+
});
|
|
214
|
+
const requestId = responseHeaders[idHeader] ?? sentId;
|
|
215
|
+
const record = await devtools.waitForRequest(requestId, {
|
|
216
|
+
timeoutMs: options.timeoutMs,
|
|
217
|
+
intervalMs: options.intervalMs
|
|
218
|
+
});
|
|
219
|
+
if (!record) throw new WarlockError("WL5004", `Devtools holds no record of request ${requestId} (${method} ${url} answered ${response.status}). Keep http.requestId enabled so the id is echoed; paths under ${devtools.devtoolsPath} are never recorded.`);
|
|
220
|
+
return buildTraceReport({
|
|
221
|
+
requestId,
|
|
222
|
+
server: devtools.url,
|
|
223
|
+
request: {
|
|
224
|
+
method,
|
|
225
|
+
url,
|
|
226
|
+
headers,
|
|
227
|
+
body: options.body ?? null
|
|
228
|
+
},
|
|
229
|
+
response: {
|
|
230
|
+
status: response.status,
|
|
231
|
+
headers: responseHeaders,
|
|
232
|
+
text
|
|
233
|
+
},
|
|
234
|
+
record,
|
|
235
|
+
clientMs
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//#endregion
|
|
240
|
+
export { TRACE_BODY_LIMIT, TRACE_REQUEST_ID_HEADER, buildTraceReport, readResponseBody, redactHeaders, resolveTraceUrl, traceRequest };
|
|
241
|
+
//# sourceMappingURL=trace-request.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-request.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/trace/trace-request.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { WarlockError } from \"../../errors/warlock-error\";\nimport {\n connectDevtools,\n type DevtoolsFetch,\n type DevtoolsRequestRecord,\n} from \"../devtools/devtools-client\";\nimport {\n TRACE_SCHEMA_VERSION,\n type TraceMiddleware,\n type TraceQuery,\n type TraceReport,\n type TraceValidation,\n} from \"./trace-report.types\";\n\n/** The correlation header core reads and echoes by default (`http.requestId.header`). */\nexport const TRACE_REQUEST_ID_HEADER = \"x-request-id\";\n\n/** Response bodies longer than this are cut in the report. */\nexport const TRACE_BODY_LIMIT = 64 * 1024;\n\n/** Header values never printed in a report. */\nconst REDACTED_HEADERS = new Set([\"authorization\", \"cookie\", \"proxy-authorization\"]);\n\n/** Inputs of {@link traceRequest}. */\nexport type TraceRequestOptions = {\n /** HTTP method, any case. */\n method: string;\n /** A path on the dev server (`/posts?page=2`) or an absolute URL. */\n url: string;\n /**\n * The request body. A string is sent as-is; anything else is sent as JSON\n * with `content-type: application/json` unless `headers` sets a content type.\n */\n body?: unknown;\n /** Extra request headers. */\n headers?: Record<string, string>;\n /** Project root, where `.warlock/dev-server.json` is read. Default: `process.cwd()`. */\n cwd?: string;\n /** The dev server origin; overrides the recorded one. */\n serverUrl?: string;\n /** The devtools mount; overrides the recorded one (default `/__warlock`). */\n devtoolsPath?: string;\n fetch?: DevtoolsFetch;\n /** How long to wait for devtools to settle the request record. Default 5000 ms. */\n timeoutMs?: number;\n /** Poll interval while waiting for the record. Default 50 ms. */\n intervalMs?: number;\n /**\n * The correlation header the app reads and echoes (`http.requestId.header`).\n * Default `x-request-id`.\n */\n requestIdHeader?: string;\n};\n\n/** The HTTP response as the report needs it. */\nexport type TracedResponse = {\n status: number;\n headers: Record<string, string>;\n /** The raw response text. */\n text: string;\n};\n\n/** Inputs of {@link buildTraceReport}. */\nexport type BuildTraceReportInput = {\n requestId: string;\n server: string;\n request: { method: string; url: string; headers: Record<string, string>; body: unknown };\n response: TracedResponse;\n record: DevtoolsRequestRecord;\n clientMs: number;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction lowerCaseKeys(headers: Record<string, string>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n result[key.toLowerCase()] = value;\n }\n\n return result;\n}\n\n/** Headers with credential values replaced by `[redacted]`. */\nexport function redactHeaders(headers: Record<string, string>): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n result[key] = REDACTED_HEADERS.has(key.toLowerCase()) ? \"[redacted]\" : value;\n }\n\n return result;\n}\n\n/** The response body as the report prints it: parsed JSON, else text, cut at the limit. */\nexport function readResponseBody(\n text: string,\n contentType: string | undefined,\n): { body: unknown; truncated: boolean } {\n if (text.length === 0) return { body: null, truncated: false };\n\n const truncated = text.length > TRACE_BODY_LIMIT;\n\n if (!truncated && contentType !== undefined && /\\bjson\\b/i.test(contentType)) {\n try {\n return { body: JSON.parse(text), truncated: false };\n } catch {\n // Fall through to text: a body that claims JSON and is not is worth seeing as-is.\n }\n }\n\n return { body: truncated ? text.slice(0, TRACE_BODY_LIMIT) : text, truncated };\n}\n\nfunction attrNumber(attrs: Record<string, unknown> | undefined, key: string): number | null {\n const value = attrs?.[key];\n\n return typeof value === \"number\" ? value : null;\n}\n\nfunction attrString(attrs: Record<string, unknown> | undefined, key: string): string | null {\n const value = attrs?.[key];\n\n return typeof value === \"string\" ? value : null;\n}\n\nfunction validationOf(\n record: DevtoolsRequestRecord,\n status: number,\n body: unknown,\n): TraceValidation {\n const phases = record.phases.filter((phase) => phase.name === \"validation\");\n\n if (phases.length === 0) {\n return { ran: false, durationMs: null, passed: null, errors: null };\n }\n\n const durationMs = phases.reduce((total, phase) => total + phase.durationMs, 0);\n const handlerRan = record.phases.some((phase) => phase.name === \"handler\");\n // A validation failure answers before the handler runs, with the configured\n // failure status (422 by default, `validation.response.status`).\n const passed = handlerRan || status < 400;\n const errors = passed ? null : isRecord(body) && \"errors\" in body ? body.errors : body;\n\n return { ran: true, durationMs, passed, errors };\n}\n\nfunction sumPhase(record: DevtoolsRequestRecord, name: string): { durationMs: number } | null {\n const phases = record.phases.filter((phase) => phase.name === name);\n\n if (phases.length === 0) return null;\n\n return { durationMs: phases.reduce((total, phase) => total + phase.durationMs, 0) };\n}\n\n/**\n * Assemble a {@link TraceReport} from the HTTP response and the devtools\n * record of the same request. Pure: no I/O, so it is testable on its own.\n */\nexport function buildTraceReport(input: BuildTraceReportInput): TraceReport {\n const { record, response } = input;\n const responseHeaders = lowerCaseKeys(response.headers);\n const { body, truncated } = readResponseBody(response.text, responseHeaders[\"content-type\"]);\n\n const middleware: TraceMiddleware[] = record.phases\n .filter((phase) => phase.name === \"middleware\")\n .map((phase) => ({\n name: attrString(phase.attrs, \"name\"),\n index: attrNumber(phase.attrs, \"index\"),\n durationMs: phase.durationMs,\n }));\n\n const nPlusOneShapes = new Set(\n record.warnings.flatMap((warning) =>\n warning.type === \"n+1\" && typeof warning.shape === \"string\" ? [warning.shape] : [],\n ),\n );\n const queries: TraceQuery[] = record.queries.map((query) => ({\n ...query,\n nPlusOne: typeof query.shape === \"string\" && nPlusOneShapes.has(query.shape),\n }));\n\n const phasesMs: Record<string, number> = {};\n\n for (const phase of record.phases) {\n phasesMs[phase.name] = (phasesMs[phase.name] ?? 0) + phase.durationMs;\n }\n\n return {\n schemaVersion: TRACE_SCHEMA_VERSION,\n requestId: input.requestId,\n server: input.server,\n request: {\n method: input.request.method,\n url: input.request.url,\n headers: redactHeaders(input.request.headers),\n body: input.request.body,\n },\n response: {\n status: response.status,\n headers: redactHeaders(responseHeaders),\n body,\n truncated,\n },\n route: record.route ?? null,\n error: record.error ?? null,\n timeline: {\n phases: record.phases,\n routeMatch: sumPhase(record, \"route.match\"),\n middleware,\n validation: validationOf(record, response.status, body),\n handler: sumPhase(record, \"handler\"),\n },\n queries,\n warnings: record.warnings,\n logs: record.logs,\n cache: record.cache,\n mails: record.mails,\n timings: {\n totalMs: record.durationMs ?? null,\n clientMs: input.clientMs,\n phasesMs,\n },\n };\n}\n\n/** The absolute URL a trace sends to: `url` as-is when absolute, else joined to the server origin. */\nexport function resolveTraceUrl(server: string, url: string): string {\n if (/^https?:\\/\\//i.test(url)) return url;\n\n return `${server}${url.startsWith(\"/\") ? url : `/${url}`}`;\n}\n\n/** The body and headers to send for a {@link TraceRequestOptions.body}. */\nfunction encodeBody(\n body: unknown,\n headers: Record<string, string>,\n): { payload: string | undefined; headers: Record<string, string> } {\n if (body === undefined) return { payload: undefined, headers };\n if (typeof body === \"string\") return { payload: body, headers };\n\n const hasContentType = Object.keys(headers).some((key) => key.toLowerCase() === \"content-type\");\n\n return {\n payload: JSON.stringify(body),\n headers: hasContentType ? headers : { ...headers, \"content-type\": \"application/json\" },\n };\n}\n\nfunction headerValue(headers: Record<string, string>, name: string): string | undefined {\n const key = Object.keys(headers).find((candidate) => candidate.toLowerCase() === name);\n\n return key === undefined ? undefined : headers[key];\n}\n\n/**\n * Send one request to the running dev server and return its devtools\n * timeline: middleware, validation result, handler, queries (with N+1 flags),\n * logs, cache operations, captured mails, the response and the timings.\n *\n * Devtools is reached first, so a missing dev server (`WL8008`) or devtools\n * (`WL8009`) fails before anything is sent. The request carries an\n * `x-request-id` (unless the caller set one), which core adopts as\n * `request.id` and echoes back; that id is how the devtools record is found.\n * Throws `WL5004` when devtools never recorded the request.\n *\n * @example\n * const report = await traceRequest({ method: \"POST\", url: \"/posts\", body: { title: \"Hi\" } });\n * report.timeline.validation.passed; // false when the body was refused\n */\nexport async function traceRequest(options: TraceRequestOptions): Promise<TraceReport> {\n const fetcher: DevtoolsFetch = options.fetch ?? ((input, init) => fetch(input, init));\n const devtools = await connectDevtools({\n cwd: options.cwd,\n url: options.serverUrl,\n devtoolsPath: options.devtoolsPath,\n fetch: fetcher,\n });\n\n const method = options.method.toUpperCase();\n const url = resolveTraceUrl(devtools.url, options.url);\n const idHeader = (options.requestIdHeader ?? TRACE_REQUEST_ID_HEADER).toLowerCase();\n const ownId = headerValue(options.headers ?? {}, idHeader);\n const sentId = ownId ?? randomUUID();\n const base =\n ownId === undefined ? { ...options.headers, [idHeader]: sentId } : { ...options.headers };\n const { payload, headers } = encodeBody(options.body, base);\n\n const startedAt = performance.now();\n let response: Response;\n\n try {\n response = await fetcher(url, { method, headers, body: payload });\n } catch (error) {\n throw new WarlockError(\n \"WL8008\",\n `The dev server at ${devtools.url} did not answer ${method} ${url}: ${error instanceof Error ? error.message : String(error)}.`,\n { cause: error },\n );\n }\n\n const text = await response.text();\n const clientMs = performance.now() - startedAt;\n const responseHeaders: Record<string, string> = {};\n\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n\n const requestId = responseHeaders[idHeader] ?? sentId;\n const record = await devtools.waitForRequest(requestId, {\n timeoutMs: options.timeoutMs,\n intervalMs: options.intervalMs,\n });\n\n if (!record) {\n throw new WarlockError(\n \"WL5004\",\n `Devtools holds no record of request ${requestId} (${method} ${url} answered ${response.status}). Keep http.requestId enabled so the id is echoed; paths under ${devtools.devtoolsPath} are never recorded.`,\n );\n }\n\n return buildTraceReport({\n requestId,\n server: devtools.url,\n request: { method, url, headers, body: options.body ?? null },\n response: { status: response.status, headers: responseHeaders, text },\n record,\n clientMs,\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { DEFAULT_TYPECHECK_BUILD_INFO, TypecheckOptions, TypecheckResult, diagnosticToProblem, directImporters, runTypecheck } from "./run-typecheck.mjs";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ToolingProblem } from "../problem.mjs";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
|
|
4
|
+
//#region ../../packages/core/src/tooling/typecheck/run-typecheck.d.ts
|
|
5
|
+
/** Inputs of {@link runTypecheck}. */
|
|
6
|
+
type TypecheckOptions = {
|
|
7
|
+
/** Project root. Default: `process.cwd()`. */cwd?: string; /** tsconfig path, relative to `cwd`. Default: `tsconfig.json`. */
|
|
8
|
+
project?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Limit diagnostics to these files (relative to `cwd` or absolute) and the
|
|
11
|
+
* project files that import them directly. Omit for the whole program.
|
|
12
|
+
*/
|
|
13
|
+
files?: readonly string[]; /** Where the incremental state is kept. Default: `.warlock/cache/typecheck.tsbuildinfo`. */
|
|
14
|
+
buildInfoFile?: string;
|
|
15
|
+
};
|
|
16
|
+
/** The outcome of {@link runTypecheck}. */
|
|
17
|
+
type TypecheckResult = {
|
|
18
|
+
/** `true` when no error-severity problem was found. */ok: boolean; /** `program` = every file; `files` = the given files and their direct importers. */
|
|
19
|
+
mode: "program" | "files"; /** Project-relative files whose diagnostics were collected in `files` mode, else `null`. */
|
|
20
|
+
files: string[] | null; /** Number of source files checked. */
|
|
21
|
+
checkedFiles: number;
|
|
22
|
+
problems: ToolingProblem[];
|
|
23
|
+
durationMs: number; /** Absolute path of the incremental state file, or `null` when nothing was written. */
|
|
24
|
+
buildInfoFile: string | null;
|
|
25
|
+
};
|
|
26
|
+
/** Default location of the incremental state, under the framework's own folder. */
|
|
27
|
+
declare const DEFAULT_TYPECHECK_BUILD_INFO: string;
|
|
28
|
+
/** Map one TypeScript diagnostic to a problem (`WL7101`, `rule: "TS<code>"`). */
|
|
29
|
+
declare function diagnosticToProblem(diagnostic: ts.Diagnostic, cwd: string, code?: "WL7101" | "WL7102"): ToolingProblem | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The project files that import any of `targets` directly.
|
|
32
|
+
*
|
|
33
|
+
* Read from each file's import list (`ts.preProcessFile`) resolved with the
|
|
34
|
+
* program's own options and a shared resolution cache, rather than through the
|
|
35
|
+
* builder's transitive dependency graph: a change to a widely used file would
|
|
36
|
+
* otherwise pull in nearly the whole project, and `--changed` exists to keep
|
|
37
|
+
* the loop small. A full `warlock typecheck` (incremental, so cheap after the
|
|
38
|
+
* first run) still checks everything.
|
|
39
|
+
*/
|
|
40
|
+
declare function directImporters(program: ts.Program, targets: ReadonlySet<string>, root: string): Set<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Typecheck the project with the TypeScript compiler API, incrementally.
|
|
43
|
+
*
|
|
44
|
+
* The program is built with `incremental` and `noEmit`, and its state is kept
|
|
45
|
+
* in {@link DEFAULT_TYPECHECK_BUILD_INFO}, so a second run re-checks only what
|
|
46
|
+
* changed. With `files`, diagnostics are collected only for those files and
|
|
47
|
+
* their direct importers — the checker is lazy, so files nobody asks about are
|
|
48
|
+
* parsed and bound but not checked, which is most of the memory a full check
|
|
49
|
+
* costs.
|
|
50
|
+
*
|
|
51
|
+
* Never throws for a project problem: a missing or invalid tsconfig is a
|
|
52
|
+
* `WL7102` problem, a type error a `WL7101` problem. A compiler crash is
|
|
53
|
+
* re-thrown for the caller to classify (`warlock check` reports it as
|
|
54
|
+
* `WL8007`).
|
|
55
|
+
*/
|
|
56
|
+
declare function runTypecheck(options?: TypecheckOptions): TypecheckResult;
|
|
57
|
+
//#endregion
|
|
58
|
+
export { DEFAULT_TYPECHECK_BUILD_INFO, TypecheckOptions, TypecheckResult, diagnosticToProblem, directImporters, runTypecheck };
|
|
59
|
+
//# sourceMappingURL=run-typecheck.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-typecheck.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/typecheck/run-typecheck.ts"],"mappings":";;;;;KAMY,gBAAA;EAAA,8CAEV,GAAA;EAEA,OAAA;EAFA;;;;EAOA,KAAA,sBAEa;EAAb,aAAA;AAAA;;KAIU,eAAA;EAEV,uDAAA,EAAA,WAIA;EAFA,IAAA,uBAKA;EAHA,KAAA,mBAIA;EAFA,YAAA;EACA,QAAA,EAAU,cAAc;EACxB,UAAA,UAMW;EAJX,aAAA;AAAA;;cAIW,4BAAA;AAkBb;AAAA,iBAAgB,mBAAA,CACd,UAAA,EAAY,EAAA,CAAG,UAAA,EACf,GAAA,UACA,IAAA,yBACC,cAAc;;;;;;;;;;AAAA;iBAuDD,eAAA,CACd,OAAA,EAAS,EAAA,CAAG,OAAA,EACZ,OAAA,EAAS,WAAA,UACT,IAAA,WACC,GAAA;;;;;;;;;;;;;;;;iBAyCa,YAAA,CAAa,OAAA,GAAS,gBAAA,GAAwB,eAAe"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { createProblem } from "../problem.mjs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
|
|
6
|
+
//#region ../../packages/core/src/tooling/typecheck/run-typecheck.ts
|
|
7
|
+
/** Default location of the incremental state, under the framework's own folder. */
|
|
8
|
+
const DEFAULT_TYPECHECK_BUILD_INFO = path.join(".warlock", "cache", "typecheck.tsbuildinfo");
|
|
9
|
+
function toPosix(file) {
|
|
10
|
+
return file.split(path.sep).join("/");
|
|
11
|
+
}
|
|
12
|
+
/** Whether a program file belongs to the project (under the root, outside node_modules). */
|
|
13
|
+
function isProjectFile(fileName, root, declarations = true) {
|
|
14
|
+
const normalized = path.resolve(fileName);
|
|
15
|
+
return normalized.startsWith(root + path.sep) && !normalized.split(path.sep).includes("node_modules") && (declarations || !normalized.endsWith(".d.ts"));
|
|
16
|
+
}
|
|
17
|
+
/** Map one TypeScript diagnostic to a problem (`WL7101`, `rule: "TS<code>"`). */
|
|
18
|
+
function diagnosticToProblem(diagnostic, cwd, code = "WL7101") {
|
|
19
|
+
if (diagnostic.category !== ts.DiagnosticCategory.Error && diagnostic.category !== ts.DiagnosticCategory.Warning) return;
|
|
20
|
+
let file = null;
|
|
21
|
+
let line = null;
|
|
22
|
+
let column = null;
|
|
23
|
+
if (diagnostic.file) {
|
|
24
|
+
file = toPosix(path.relative(cwd, diagnostic.file.fileName));
|
|
25
|
+
if (diagnostic.start !== void 0) {
|
|
26
|
+
const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
27
|
+
line = position.line + 1;
|
|
28
|
+
column = position.character + 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return createProblem({
|
|
32
|
+
code,
|
|
33
|
+
source: "typescript",
|
|
34
|
+
severity: diagnostic.category === ts.DiagnosticCategory.Error ? "error" : "warning",
|
|
35
|
+
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"),
|
|
36
|
+
file,
|
|
37
|
+
line,
|
|
38
|
+
column,
|
|
39
|
+
rule: `TS${diagnostic.code}`
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function collect(diagnostics, cwd, code) {
|
|
43
|
+
return diagnostics.map((diagnostic) => diagnosticToProblem(diagnostic, cwd, code)).filter((problem) => problem !== void 0);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The project files that import any of `targets` directly.
|
|
47
|
+
*
|
|
48
|
+
* Read from each file's import list (`ts.preProcessFile`) resolved with the
|
|
49
|
+
* program's own options and a shared resolution cache, rather than through the
|
|
50
|
+
* builder's transitive dependency graph: a change to a widely used file would
|
|
51
|
+
* otherwise pull in nearly the whole project, and `--changed` exists to keep
|
|
52
|
+
* the loop small. A full `warlock typecheck` (incremental, so cheap after the
|
|
53
|
+
* first run) still checks everything.
|
|
54
|
+
*/
|
|
55
|
+
function directImporters(program, targets, root) {
|
|
56
|
+
const options = program.getCompilerOptions();
|
|
57
|
+
const cache = ts.createModuleResolutionCache(root, (name) => name, options);
|
|
58
|
+
const importers = /* @__PURE__ */ new Set();
|
|
59
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
60
|
+
const fileName = path.resolve(sourceFile.fileName);
|
|
61
|
+
if (!isProjectFile(fileName, root, false) || targets.has(fileName)) continue;
|
|
62
|
+
const { importedFiles } = ts.preProcessFile(sourceFile.text, true, true);
|
|
63
|
+
for (const imported of importedFiles) {
|
|
64
|
+
const resolved = ts.resolveModuleName(imported.fileName, fileName, options, ts.sys, cache).resolvedModule?.resolvedFileName;
|
|
65
|
+
if (resolved && targets.has(path.resolve(resolved))) {
|
|
66
|
+
importers.add(fileName);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return importers;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Typecheck the project with the TypeScript compiler API, incrementally.
|
|
75
|
+
*
|
|
76
|
+
* The program is built with `incremental` and `noEmit`, and its state is kept
|
|
77
|
+
* in {@link DEFAULT_TYPECHECK_BUILD_INFO}, so a second run re-checks only what
|
|
78
|
+
* changed. With `files`, diagnostics are collected only for those files and
|
|
79
|
+
* their direct importers — the checker is lazy, so files nobody asks about are
|
|
80
|
+
* parsed and bound but not checked, which is most of the memory a full check
|
|
81
|
+
* costs.
|
|
82
|
+
*
|
|
83
|
+
* Never throws for a project problem: a missing or invalid tsconfig is a
|
|
84
|
+
* `WL7102` problem, a type error a `WL7101` problem. A compiler crash is
|
|
85
|
+
* re-thrown for the caller to classify (`warlock check` reports it as
|
|
86
|
+
* `WL8007`).
|
|
87
|
+
*/
|
|
88
|
+
function runTypecheck(options = {}) {
|
|
89
|
+
const startedAt = Date.now();
|
|
90
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
91
|
+
const configPath = path.resolve(cwd, options.project ?? "tsconfig.json");
|
|
92
|
+
const result = (problems, rest = {}) => ({
|
|
93
|
+
ok: !problems.some((problem) => problem.severity === "error"),
|
|
94
|
+
mode: options.files ? "files" : "program",
|
|
95
|
+
files: null,
|
|
96
|
+
checkedFiles: 0,
|
|
97
|
+
problems,
|
|
98
|
+
durationMs: Date.now() - startedAt,
|
|
99
|
+
buildInfoFile: null,
|
|
100
|
+
...rest
|
|
101
|
+
});
|
|
102
|
+
if (!existsSync(configPath)) return result([createProblem({
|
|
103
|
+
code: "WL7102",
|
|
104
|
+
source: "typescript",
|
|
105
|
+
message: `No TypeScript config at ${toPosix(path.relative(cwd, configPath)) || configPath}.`,
|
|
106
|
+
file: toPosix(path.relative(cwd, configPath))
|
|
107
|
+
})]);
|
|
108
|
+
const read = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
109
|
+
if (read.error) return result(collect([read.error], cwd, "WL7102"));
|
|
110
|
+
const parsed = ts.parseJsonConfigFileContent(read.config, ts.sys, path.dirname(configPath), void 0, configPath);
|
|
111
|
+
const buildInfoFile = path.resolve(cwd, options.buildInfoFile ?? DEFAULT_TYPECHECK_BUILD_INFO);
|
|
112
|
+
mkdirSync(path.dirname(buildInfoFile), { recursive: true });
|
|
113
|
+
const compilerOptions = {
|
|
114
|
+
...parsed.options,
|
|
115
|
+
noEmit: true,
|
|
116
|
+
incremental: true,
|
|
117
|
+
tsBuildInfoFile: buildInfoFile,
|
|
118
|
+
composite: false,
|
|
119
|
+
emitDeclarationOnly: false
|
|
120
|
+
};
|
|
121
|
+
const builder = ts.createIncrementalProgram({
|
|
122
|
+
rootNames: parsed.fileNames,
|
|
123
|
+
options: compilerOptions,
|
|
124
|
+
projectReferences: parsed.projectReferences,
|
|
125
|
+
configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(parsed),
|
|
126
|
+
host: ts.createIncrementalCompilerHost(compilerOptions)
|
|
127
|
+
});
|
|
128
|
+
const problems = [
|
|
129
|
+
...collect(builder.getConfigFileParsingDiagnostics(), cwd, "WL7102"),
|
|
130
|
+
...collect(builder.getOptionsDiagnostics(), cwd, "WL7102"),
|
|
131
|
+
...collect(builder.getGlobalDiagnostics(), cwd, "WL7101")
|
|
132
|
+
];
|
|
133
|
+
let checked;
|
|
134
|
+
let files = null;
|
|
135
|
+
if (options.files) {
|
|
136
|
+
const targets = new Set(options.files.map((file) => path.resolve(cwd, file)));
|
|
137
|
+
const program = builder.getProgram();
|
|
138
|
+
const wanted = new Set([...targets, ...directImporters(program, targets, cwd)]);
|
|
139
|
+
checked = builder.getSourceFiles().filter((sourceFile) => wanted.has(path.resolve(sourceFile.fileName)));
|
|
140
|
+
files = checked.map((sourceFile) => toPosix(path.relative(cwd, sourceFile.fileName))).sort();
|
|
141
|
+
} else checked = builder.getSourceFiles().filter((sourceFile) => isProjectFile(sourceFile.fileName, cwd));
|
|
142
|
+
for (const sourceFile of checked) problems.push(...collect(builder.getSyntacticDiagnostics(sourceFile), cwd, "WL7101"), ...collect(builder.getSemanticDiagnostics(sourceFile), cwd, "WL7101"));
|
|
143
|
+
builder.emit();
|
|
144
|
+
return result(problems, {
|
|
145
|
+
files,
|
|
146
|
+
checkedFiles: checked.length,
|
|
147
|
+
buildInfoFile: existsSync(buildInfoFile) ? buildInfoFile : null
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
//#endregion
|
|
152
|
+
export { DEFAULT_TYPECHECK_BUILD_INFO, diagnosticToProblem, directImporters, runTypecheck };
|
|
153
|
+
//# sourceMappingURL=run-typecheck.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-typecheck.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/typecheck/run-typecheck.ts"],"sourcesContent":["import { existsSync, mkdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport ts from \"typescript\";\nimport { createProblem, type ToolingProblem } from \"../problem\";\n\n/** Inputs of {@link runTypecheck}. */\nexport type TypecheckOptions = {\n /** Project root. Default: `process.cwd()`. */\n cwd?: string;\n /** tsconfig path, relative to `cwd`. Default: `tsconfig.json`. */\n project?: string;\n /**\n * Limit diagnostics to these files (relative to `cwd` or absolute) and the\n * project files that import them directly. Omit for the whole program.\n */\n files?: readonly string[];\n /** Where the incremental state is kept. Default: `.warlock/cache/typecheck.tsbuildinfo`. */\n buildInfoFile?: string;\n};\n\n/** The outcome of {@link runTypecheck}. */\nexport type TypecheckResult = {\n /** `true` when no error-severity problem was found. */\n ok: boolean;\n /** `program` = every file; `files` = the given files and their direct importers. */\n mode: \"program\" | \"files\";\n /** Project-relative files whose diagnostics were collected in `files` mode, else `null`. */\n files: string[] | null;\n /** Number of source files checked. */\n checkedFiles: number;\n problems: ToolingProblem[];\n durationMs: number;\n /** Absolute path of the incremental state file, or `null` when nothing was written. */\n buildInfoFile: string | null;\n};\n\n/** Default location of the incremental state, under the framework's own folder. */\nexport const DEFAULT_TYPECHECK_BUILD_INFO = path.join(\".warlock\", \"cache\", \"typecheck.tsbuildinfo\");\n\nfunction toPosix(file: string): string {\n return file.split(path.sep).join(\"/\");\n}\n\n/** Whether a program file belongs to the project (under the root, outside node_modules). */\nfunction isProjectFile(fileName: string, root: string, declarations = true): boolean {\n const normalized = path.resolve(fileName);\n\n return (\n normalized.startsWith(root + path.sep) &&\n !normalized.split(path.sep).includes(\"node_modules\") &&\n (declarations || !normalized.endsWith(\".d.ts\"))\n );\n}\n\n/** Map one TypeScript diagnostic to a problem (`WL7101`, `rule: \"TS<code>\"`). */\nexport function diagnosticToProblem(\n diagnostic: ts.Diagnostic,\n cwd: string,\n code: \"WL7101\" | \"WL7102\" = \"WL7101\",\n): ToolingProblem | undefined {\n if (\n diagnostic.category !== ts.DiagnosticCategory.Error &&\n diagnostic.category !== ts.DiagnosticCategory.Warning\n ) {\n return undefined;\n }\n\n let file: string | null = null;\n let line: number | null = null;\n let column: number | null = null;\n\n if (diagnostic.file) {\n file = toPosix(path.relative(cwd, diagnostic.file.fileName));\n\n if (diagnostic.start !== undefined) {\n const position = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n\n line = position.line + 1;\n column = position.character + 1;\n }\n }\n\n return createProblem({\n code,\n source: \"typescript\",\n severity: diagnostic.category === ts.DiagnosticCategory.Error ? \"error\" : \"warning\",\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\"),\n file,\n line,\n column,\n rule: `TS${diagnostic.code}`,\n });\n}\n\nfunction collect(\n diagnostics: readonly ts.Diagnostic[],\n cwd: string,\n code: \"WL7101\" | \"WL7102\",\n): ToolingProblem[] {\n return diagnostics\n .map((diagnostic) => diagnosticToProblem(diagnostic, cwd, code))\n .filter((problem): problem is ToolingProblem => problem !== undefined);\n}\n\n/**\n * The project files that import any of `targets` directly.\n *\n * Read from each file's import list (`ts.preProcessFile`) resolved with the\n * program's own options and a shared resolution cache, rather than through the\n * builder's transitive dependency graph: a change to a widely used file would\n * otherwise pull in nearly the whole project, and `--changed` exists to keep\n * the loop small. A full `warlock typecheck` (incremental, so cheap after the\n * first run) still checks everything.\n */\nexport function directImporters(\n program: ts.Program,\n targets: ReadonlySet<string>,\n root: string,\n): Set<string> {\n const options = program.getCompilerOptions();\n const cache = ts.createModuleResolutionCache(root, (name) => name, options);\n const importers = new Set<string>();\n\n for (const sourceFile of program.getSourceFiles()) {\n const fileName = path.resolve(sourceFile.fileName);\n\n if (!isProjectFile(fileName, root, false) || targets.has(fileName)) continue;\n\n const { importedFiles } = ts.preProcessFile(sourceFile.text, true, true);\n\n for (const imported of importedFiles) {\n const resolved = ts.resolveModuleName(imported.fileName, fileName, options, ts.sys, cache)\n .resolvedModule?.resolvedFileName;\n\n if (resolved && targets.has(path.resolve(resolved))) {\n importers.add(fileName);\n break;\n }\n }\n }\n\n return importers;\n}\n\n/**\n * Typecheck the project with the TypeScript compiler API, incrementally.\n *\n * The program is built with `incremental` and `noEmit`, and its state is kept\n * in {@link DEFAULT_TYPECHECK_BUILD_INFO}, so a second run re-checks only what\n * changed. With `files`, diagnostics are collected only for those files and\n * their direct importers — the checker is lazy, so files nobody asks about are\n * parsed and bound but not checked, which is most of the memory a full check\n * costs.\n *\n * Never throws for a project problem: a missing or invalid tsconfig is a\n * `WL7102` problem, a type error a `WL7101` problem. A compiler crash is\n * re-thrown for the caller to classify (`warlock check` reports it as\n * `WL8007`).\n */\nexport function runTypecheck(options: TypecheckOptions = {}): TypecheckResult {\n const startedAt = Date.now();\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const configPath = path.resolve(cwd, options.project ?? \"tsconfig.json\");\n const result = (\n problems: ToolingProblem[],\n rest: Partial<TypecheckResult> = {},\n ): TypecheckResult => ({\n ok: !problems.some((problem) => problem.severity === \"error\"),\n mode: options.files ? \"files\" : \"program\",\n files: null,\n checkedFiles: 0,\n problems,\n durationMs: Date.now() - startedAt,\n buildInfoFile: null,\n ...rest,\n });\n\n if (!existsSync(configPath)) {\n return result([\n createProblem({\n code: \"WL7102\",\n source: \"typescript\",\n message: `No TypeScript config at ${toPosix(path.relative(cwd, configPath)) || configPath}.`,\n file: toPosix(path.relative(cwd, configPath)),\n }),\n ]);\n }\n\n const read = ts.readConfigFile(configPath, ts.sys.readFile);\n\n if (read.error) {\n return result(collect([read.error], cwd, \"WL7102\"));\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n read.config,\n ts.sys,\n path.dirname(configPath),\n undefined,\n configPath,\n );\n const buildInfoFile = path.resolve(cwd, options.buildInfoFile ?? DEFAULT_TYPECHECK_BUILD_INFO);\n\n mkdirSync(path.dirname(buildInfoFile), { recursive: true });\n\n const compilerOptions: ts.CompilerOptions = {\n ...parsed.options,\n noEmit: true,\n incremental: true,\n tsBuildInfoFile: buildInfoFile,\n // Both require emitting and are refused alongside noEmit.\n composite: false,\n emitDeclarationOnly: false,\n };\n const builder = ts.createIncrementalProgram({\n rootNames: parsed.fileNames,\n options: compilerOptions,\n projectReferences: parsed.projectReferences,\n configFileParsingDiagnostics: ts.getConfigFileParsingDiagnostics(parsed),\n host: ts.createIncrementalCompilerHost(compilerOptions),\n });\n const problems: ToolingProblem[] = [\n ...collect(builder.getConfigFileParsingDiagnostics(), cwd, \"WL7102\"),\n ...collect(builder.getOptionsDiagnostics(), cwd, \"WL7102\"),\n ...collect(builder.getGlobalDiagnostics(), cwd, \"WL7101\"),\n ];\n\n let checked: ts.SourceFile[];\n let files: string[] | null = null;\n\n if (options.files) {\n const targets = new Set(options.files.map((file) => path.resolve(cwd, file)));\n const program = builder.getProgram();\n const wanted = new Set([...targets, ...directImporters(program, targets, cwd)]);\n\n checked = builder\n .getSourceFiles()\n .filter((sourceFile) => wanted.has(path.resolve(sourceFile.fileName)));\n files = checked.map((sourceFile) => toPosix(path.relative(cwd, sourceFile.fileName))).sort();\n } else {\n checked = builder\n .getSourceFiles()\n .filter((sourceFile) => isProjectFile(sourceFile.fileName, cwd));\n }\n\n for (const sourceFile of checked) {\n problems.push(\n ...collect(builder.getSyntacticDiagnostics(sourceFile), cwd, \"WL7101\"),\n ...collect(builder.getSemanticDiagnostics(sourceFile), cwd, \"WL7101\"),\n );\n }\n\n // With noEmit + incremental, emit writes only the .tsbuildinfo state.\n builder.emit();\n\n return result(problems, {\n files,\n checkedFiles: checked.length,\n buildInfoFile: existsSync(buildInfoFile) ? buildInfoFile : null,\n });\n}\n"],"mappings":";;;;;;;AAqCA,MAAa,+BAA+B,KAAK,KAAK,YAAY,SAAS,uBAAuB;AAElG,SAAS,QAAQ,MAAsB;CACrC,OAAO,KAAK,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,GAAG;AACtC;;AAGA,SAAS,cAAc,UAAkB,MAAc,eAAe,MAAe;CACnF,MAAM,aAAa,KAAK,QAAQ,QAAQ;CAExC,OACE,WAAW,WAAW,OAAO,KAAK,GAAG,KACrC,CAAC,WAAW,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,cAAc,MAClD,gBAAgB,CAAC,WAAW,SAAS,OAAO;AAEjD;;AAGA,SAAgB,oBACd,YACA,KACA,OAA4B,UACA;CAC5B,IACE,WAAW,aAAa,GAAG,mBAAmB,SAC9C,WAAW,aAAa,GAAG,mBAAmB,SAE9C;CAGF,IAAI,OAAsB;CAC1B,IAAI,OAAsB;CAC1B,IAAI,SAAwB;CAE5B,IAAI,WAAW,MAAM;EACnB,OAAO,QAAQ,KAAK,SAAS,KAAK,WAAW,KAAK,QAAQ,CAAC;EAE3D,IAAI,WAAW,UAAU,QAAW;GAClC,MAAM,WAAW,WAAW,KAAK,8BAA8B,WAAW,KAAK;GAE/E,OAAO,SAAS,OAAO;GACvB,SAAS,SAAS,YAAY;EAChC;CACF;CAEA,OAAO,cAAc;EACnB;EACA,QAAQ;EACR,UAAU,WAAW,aAAa,GAAG,mBAAmB,QAAQ,UAAU;EAC1E,SAAS,GAAG,6BAA6B,WAAW,aAAa,IAAI;EACrE;EACA;EACA;EACA,MAAM,KAAK,WAAW;CACxB,CAAC;AACH;AAEA,SAAS,QACP,aACA,KACA,MACkB;CAClB,OAAO,YACJ,KAAK,eAAe,oBAAoB,YAAY,KAAK,IAAI,CAAC,CAAC,CAC/D,QAAQ,YAAuC,YAAY,MAAS;AACzE;;;;;;;;;;;AAYA,SAAgB,gBACd,SACA,SACA,MACa;CACb,MAAM,UAAU,QAAQ,mBAAmB;CAC3C,MAAM,QAAQ,GAAG,4BAA4B,OAAO,SAAS,MAAM,OAAO;CAC1E,MAAM,4BAAY,IAAI,IAAY;CAElC,KAAK,MAAM,cAAc,QAAQ,eAAe,GAAG;EACjD,MAAM,WAAW,KAAK,QAAQ,WAAW,QAAQ;EAEjD,IAAI,CAAC,cAAc,UAAU,MAAM,KAAK,KAAK,QAAQ,IAAI,QAAQ,GAAG;EAEpE,MAAM,EAAE,kBAAkB,GAAG,eAAe,WAAW,MAAM,MAAM,IAAI;EAEvE,KAAK,MAAM,YAAY,eAAe;GACpC,MAAM,WAAW,GAAG,kBAAkB,SAAS,UAAU,UAAU,SAAS,GAAG,KAAK,KAAK,CAAC,CACvF,gBAAgB;GAEnB,IAAI,YAAY,QAAQ,IAAI,KAAK,QAAQ,QAAQ,CAAC,GAAG;IACnD,UAAU,IAAI,QAAQ;IACtB;GACF;EACF;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;AAiBA,SAAgB,aAAa,UAA4B,CAAC,GAAoB;CAC5E,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,MAAM,KAAK,QAAQ,QAAQ,OAAO,QAAQ,IAAI,CAAC;CACrD,MAAM,aAAa,KAAK,QAAQ,KAAK,QAAQ,WAAW,eAAe;CACvE,MAAM,UACJ,UACA,OAAiC,CAAC,OACb;EACrB,IAAI,CAAC,SAAS,MAAM,YAAY,QAAQ,aAAa,OAAO;EAC5D,MAAM,QAAQ,QAAQ,UAAU;EAChC,OAAO;EACP,cAAc;EACd;EACA,YAAY,KAAK,IAAI,IAAI;EACzB,eAAe;EACf,GAAG;CACL;CAEA,IAAI,CAAC,WAAW,UAAU,GACxB,OAAO,OAAO,CACZ,cAAc;EACZ,MAAM;EACN,QAAQ;EACR,SAAS,2BAA2B,QAAQ,KAAK,SAAS,KAAK,UAAU,CAAC,KAAK,WAAW;EAC1F,MAAM,QAAQ,KAAK,SAAS,KAAK,UAAU,CAAC;CAC9C,CAAC,CACH,CAAC;CAGH,MAAM,OAAO,GAAG,eAAe,YAAY,GAAG,IAAI,QAAQ;CAE1D,IAAI,KAAK,OACP,OAAO,OAAO,QAAQ,CAAC,KAAK,KAAK,GAAG,KAAK,QAAQ,CAAC;CAGpD,MAAM,SAAS,GAAG,2BAChB,KAAK,QACL,GAAG,KACH,KAAK,QAAQ,UAAU,GACvB,QACA,UACF;CACA,MAAM,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,iBAAiB,4BAA4B;CAE7F,UAAU,KAAK,QAAQ,aAAa,GAAG,EAAE,WAAW,KAAK,CAAC;CAE1D,MAAM,kBAAsC;EAC1C,GAAG,OAAO;EACV,QAAQ;EACR,aAAa;EACb,iBAAiB;EAEjB,WAAW;EACX,qBAAqB;CACvB;CACA,MAAM,UAAU,GAAG,yBAAyB;EAC1C,WAAW,OAAO;EAClB,SAAS;EACT,mBAAmB,OAAO;EAC1B,8BAA8B,GAAG,gCAAgC,MAAM;EACvE,MAAM,GAAG,8BAA8B,eAAe;CACxD,CAAC;CACD,MAAM,WAA6B;EACjC,GAAG,QAAQ,QAAQ,gCAAgC,GAAG,KAAK,QAAQ;EACnE,GAAG,QAAQ,QAAQ,sBAAsB,GAAG,KAAK,QAAQ;EACzD,GAAG,QAAQ,QAAQ,qBAAqB,GAAG,KAAK,QAAQ;CAC1D;CAEA,IAAI;CACJ,IAAI,QAAyB;CAE7B,IAAI,QAAQ,OAAO;EACjB,MAAM,UAAU,IAAI,IAAI,QAAQ,MAAM,KAAK,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC,CAAC;EAC5E,MAAM,UAAU,QAAQ,WAAW;EACnC,MAAM,SAAS,IAAI,IAAI,CAAC,GAAG,SAAS,GAAG,gBAAgB,SAAS,SAAS,GAAG,CAAC,CAAC;EAE9E,UAAU,QACP,eAAe,CAAC,CAChB,QAAQ,eAAe,OAAO,IAAI,KAAK,QAAQ,WAAW,QAAQ,CAAC,CAAC;EACvE,QAAQ,QAAQ,KAAK,eAAe,QAAQ,KAAK,SAAS,KAAK,WAAW,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK;CAC7F,OACE,UAAU,QACP,eAAe,CAAC,CAChB,QAAQ,eAAe,cAAc,WAAW,UAAU,GAAG,CAAC;CAGnE,KAAK,MAAM,cAAc,SACvB,SAAS,KACP,GAAG,QAAQ,QAAQ,wBAAwB,UAAU,GAAG,KAAK,QAAQ,GACrE,GAAG,QAAQ,QAAQ,uBAAuB,UAAU,GAAG,KAAK,QAAQ,CACtE;CAIF,QAAQ,KAAK;CAEb,OAAO,OAAO,UAAU;EACtB;EACA,cAAc,QAAQ;EACtB,eAAe,WAAW,aAAa,IAAI,gBAAgB;CAC7D,CAAC;AACH"}
|