@warlock.js/core 5.30.0 → 5.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +142 -36
- package/README.md +28 -23
- package/bin/source-load-hook.mjs +63 -0
- package/bin/warlock.js +102 -42
- package/esm/cli/commands/add.command.mjs +4 -2
- package/esm/cli/commands/add.command.mjs.map +1 -1
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs +69 -0
- package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -0
- package/esm/cli/commands/agents-md.command.mjs +38 -0
- package/esm/cli/commands/agents-md.command.mjs.map +1 -0
- package/esm/cli/commands/board/board-command.action.mjs +279 -0
- package/esm/cli/commands/board/board-command.action.mjs.map +1 -0
- package/esm/cli/commands/board.command.mjs +78 -0
- package/esm/cli/commands/board.command.mjs.map +1 -0
- package/esm/cli/commands/build.command.mjs +6 -1
- package/esm/cli/commands/build.command.mjs.map +1 -1
- package/esm/cli/commands/check/check-command.action.mjs +57 -0
- package/esm/cli/commands/check/check-command.action.mjs.map +1 -0
- package/esm/cli/commands/check/child-typecheck.mjs +66 -0
- package/esm/cli/commands/check/child-typecheck.mjs.map +1 -0
- package/esm/cli/commands/check/format-problems.mjs +43 -0
- package/esm/cli/commands/check/format-problems.mjs.map +1 -0
- package/esm/cli/commands/check/typecheck-command.action.mjs +61 -0
- package/esm/cli/commands/check/typecheck-command.action.mjs.map +1 -0
- package/esm/cli/commands/check.command.mjs +50 -0
- package/esm/cli/commands/check.command.mjs.map +1 -0
- package/esm/cli/commands/dev-server.command.mjs +9 -1
- package/esm/cli/commands/dev-server.command.mjs.map +1 -1
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +8 -3
- package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
- package/esm/cli/commands/doctor/check.types.d.mts +76 -0
- package/esm/cli/commands/doctor/check.types.d.mts.map +1 -0
- package/esm/cli/commands/doctor/checks/config.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/connectors.check.mjs +2 -0
- package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/health.check.mjs +3 -0
- package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -0
- package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +4 -0
- package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/checks/routes.check.mjs +3 -0
- package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
- package/esm/cli/commands/doctor/doctor-command.action.mjs +14 -6
- package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
- package/esm/cli/commands/doctor/format-report.mjs +30 -2
- package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
- package/esm/cli/commands/doctor.command.mjs +4 -0
- package/esm/cli/commands/doctor.command.mjs.map +1 -1
- package/esm/cli/commands/explain/explain-command.action.mjs +64 -0
- package/esm/cli/commands/explain/explain-command.action.mjs.map +1 -0
- package/esm/cli/commands/explain.command.mjs +23 -0
- package/esm/cli/commands/explain.command.mjs.map +1 -0
- package/esm/cli/commands/generate/generate.command.mjs +124 -124
- package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs +311 -0
- package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -0
- package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +341 -0
- package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -0
- package/esm/cli/commands/generate/templates/stubs.mjs +19 -6
- package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs +137 -0
- package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -0
- package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
- package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
- package/esm/cli/commands/generate/utils/writer.mjs +38 -13
- package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
- package/esm/cli/commands/inspect/inspect-command.action.mjs +72 -0
- package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -0
- package/esm/cli/commands/inspect.command.mjs +39 -0
- package/esm/cli/commands/inspect.command.mjs.map +1 -0
- package/esm/cli/commands/mcp/mcp-command.action.mjs +103 -0
- package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -0
- package/esm/cli/commands/mcp.command.mjs +76 -0
- package/esm/cli/commands/mcp.command.mjs.map +1 -0
- package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
- package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
- package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
- package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
- package/esm/cli/commands/test.command.mjs +131 -0
- package/esm/cli/commands/test.command.mjs.map +1 -0
- package/esm/cli/commands/trace/trace-command.action.mjs +145 -0
- package/esm/cli/commands/trace/trace-command.action.mjs.map +1 -0
- package/esm/cli/commands/trace.command.mjs +60 -0
- package/esm/cli/commands/trace.command.mjs.map +1 -0
- package/esm/cli/commands/typecheck.command.mjs +40 -0
- package/esm/cli/commands/typecheck.command.mjs.map +1 -0
- package/esm/cli/commands/upgrade.command.mjs +46 -0
- package/esm/cli/commands/upgrade.command.mjs.map +1 -0
- package/esm/cli/flush-and-exit.mjs +34 -0
- package/esm/cli/flush-and-exit.mjs.map +1 -0
- package/esm/cli/framework-cli-commands.mjs +23 -1
- package/esm/cli/framework-cli-commands.mjs.map +1 -1
- package/esm/cli/parse-cli-args.mjs +1 -0
- package/esm/cli/parse-cli-args.mjs.map +1 -1
- package/esm/config/config-loader.d.mts.map +1 -1
- package/esm/config/config-loader.mjs +34 -13
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-schema.d.mts +67 -0
- package/esm/config/config-schema.d.mts.map +1 -0
- package/esm/config/config-schema.mjs +77 -0
- package/esm/config/config-schema.mjs.map +1 -0
- package/esm/config/index.d.mts +6 -0
- package/esm/config/index.mjs +1 -0
- package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs +2 -1
- package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
- package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
- package/esm/connectors/assert-unique-connector-names.mjs +26 -2
- package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +3 -2
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/single-server-warnings.mjs.map +1 -1
- package/esm/connectors/socket-connector.d.mts.map +1 -1
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/container/index.d.mts.map +1 -1
- package/esm/container/index.mjs.map +1 -1
- package/esm/database/migrate-action.mjs.map +1 -1
- package/esm/database/models/database-log/database-log.d.mts +0 -28
- package/esm/database/models/database-log/database-log.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.d.mts +4 -0
- package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
- package/esm/database/seeds/seeder.errors.mjs +2 -0
- package/esm/database/seeds/seeder.errors.mjs.map +1 -1
- package/esm/dev-server/boot-precondition-error.mjs +1 -0
- package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
- package/esm/dev-server/create-worker.mjs +15 -9
- package/esm/dev-server/create-worker.mjs.map +1 -1
- package/esm/dev-server/dev-agent-tooling.mjs +135 -0
- package/esm/dev-server/dev-agent-tooling.mjs.map +1 -0
- package/esm/dev-server/dev-logger.mjs.map +1 -1
- package/esm/dev-server/development-server.mjs +8 -0
- package/esm/dev-server/development-server.mjs.map +1 -1
- package/esm/dev-server/files-orchestrator.mjs +4 -5
- package/esm/dev-server/files-orchestrator.mjs.map +1 -1
- package/esm/dev-server/files-watcher.mjs +1 -1
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +2 -3
- package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
- package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +33 -0
- package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs.map +1 -0
- package/esm/dev-server/health-checker/default-health-checkers.mjs +31 -0
- package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -0
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +9 -3
- package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs +15 -4
- package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
- package/esm/dev-server/health-checker/oxlint-runner.mjs +302 -0
- package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs +42 -0
- package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs.map +1 -0
- package/esm/dev-server/loader/loader-port-acks.mjs +1 -1
- package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -1
- package/esm/dev-server/loader/register-loader.mjs +1 -1
- package/esm/dev-server/loader/register-loader.mjs.map +1 -1
- package/esm/dev-server/loader/resolve-hook.mjs +1 -1
- package/esm/dev-server/loader/transpile-cache.mjs +1 -1
- package/esm/dev-server/model-resource-typings.mjs.map +1 -1
- package/esm/dev-server/module-loader.mjs +1 -0
- package/esm/dev-server/module-loader.mjs.map +1 -1
- package/esm/dev-server/parse-imports.mjs +1 -1
- package/esm/dev-server/parse-imports.mjs.map +1 -1
- package/esm/dev-server/route-types-publisher.mjs +1 -1
- package/esm/dev-server/start-development-server.mjs.map +1 -1
- package/esm/dev-server/translation-keys-sources.mjs +1 -1
- package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
- package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
- package/esm/dev-server/type-generator.mjs +3 -3
- package/esm/dev-server/type-generator.mjs.map +1 -1
- package/esm/dev-server/types.d.mts.map +1 -1
- package/esm/errors/container-key-missing-error.mjs +1 -0
- package/esm/errors/container-key-missing-error.mjs.map +1 -1
- package/esm/errors/error-codes.d.mts +653 -0
- package/esm/errors/error-codes.d.mts.map +1 -0
- package/esm/errors/error-codes.mjs +634 -0
- package/esm/errors/error-codes.mjs.map +1 -0
- package/esm/errors/esbuild-binary-missing-error.mjs +1 -0
- package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
- package/esm/errors/index.d.mts +3 -1
- package/esm/errors/index.mjs +3 -1
- package/esm/errors/unknown-locale-error.mjs +1 -0
- package/esm/errors/unknown-locale-error.mjs.map +1 -1
- package/esm/errors/warlock-error.d.mts +23 -0
- package/esm/errors/warlock-error.d.mts.map +1 -0
- package/esm/errors/warlock-error.mjs +22 -0
- package/esm/errors/warlock-error.mjs.map +1 -0
- package/esm/generations/add-command.action.mjs +19 -3
- package/esm/generations/add-command.action.mjs.map +1 -1
- package/esm/generations/features/access.feature.mjs +1 -1
- package/esm/generations/features/access.feature.mjs.map +1 -1
- package/esm/generations/features/bull-board.feature.mjs +1 -1
- package/esm/generations/features/bull-board.feature.mjs.map +1 -1
- package/esm/generations/features/mysql.feature.mjs.map +1 -1
- package/esm/generations/features/notifications.feature.mjs +5 -2
- package/esm/generations/features/notifications.feature.mjs.map +1 -1
- package/esm/generations/features/queue.feature.mjs +1 -1
- package/esm/generations/features/queue.feature.mjs.map +1 -1
- package/esm/generations/features/react-email.feature.mjs +1 -1
- package/esm/generations/features/react-email.feature.mjs.map +1 -1
- package/esm/generations/features/shadcn.feature.mjs +1 -1
- package/esm/generations/features/shadcn.feature.mjs.map +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
- package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
- package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
- package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
- package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
- package/esm/generations/features/sitemap.feature.mjs +1 -1
- package/esm/generations/features/sitemap.feature.mjs.map +1 -1
- package/esm/generations/features/tailwind.feature.mjs +1 -1
- package/esm/generations/features/tailwind.feature.mjs.map +1 -1
- package/esm/generations/features/test.feature.mjs +11 -6
- package/esm/generations/features/test.feature.mjs.map +1 -1
- package/esm/generations/features/web.feature.mjs +1 -1
- package/esm/generations/features/web.feature.mjs.map +1 -1
- package/esm/generations/generation-fs.mjs +73 -0
- package/esm/generations/generation-fs.mjs.map +1 -0
- package/esm/generations/generation-run.mjs +185 -0
- package/esm/generations/generation-run.mjs.map +1 -0
- package/esm/generations/stubs.mjs +155 -13
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/bounded-stream-queue.d.mts +10 -0
- package/esm/http/bounded-stream-queue.d.mts.map +1 -0
- package/esm/http/bounded-stream-queue.mjs +97 -0
- package/esm/http/bounded-stream-queue.mjs.map +1 -0
- package/esm/http/build-rate-limit-options.d.mts +13 -0
- package/esm/http/build-rate-limit-options.d.mts.map +1 -1
- package/esm/http/build-rate-limit-options.mjs.map +1 -1
- package/esm/http/conditional-request.d.mts +86 -0
- package/esm/http/conditional-request.d.mts.map +1 -0
- package/esm/http/conditional-request.mjs +121 -0
- package/esm/http/conditional-request.mjs.map +1 -0
- package/esm/http/csp.d.mts +2 -0
- package/esm/http/csp.d.mts.map +1 -1
- package/esm/http/csp.mjs +1 -0
- package/esm/http/csp.mjs.map +1 -1
- package/esm/http/csrf-origin-policy.mjs.map +1 -1
- package/esm/http/database/RequestLog.d.mts +24 -84
- package/esm/http/database/RequestLog.d.mts.map +1 -1
- package/esm/http/errors/errors.d.mts +2 -0
- package/esm/http/errors/errors.d.mts.map +1 -1
- package/esm/http/errors/errors.mjs +1 -0
- package/esm/http/errors/errors.mjs.map +1 -1
- package/esm/http/escape-header-value.d.mts +18 -0
- package/esm/http/escape-header-value.d.mts.map +1 -0
- package/esm/http/escape-header-value.mjs +27 -0
- package/esm/http/escape-header-value.mjs.map +1 -0
- package/esm/http/flush-pending-cookies.mjs.map +1 -1
- package/esm/http/index.d.mts +5 -2
- package/esm/http/index.mjs +4 -1
- package/esm/http/lazy-static.mjs +194 -0
- package/esm/http/lazy-static.mjs.map +1 -0
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/plugins.d.mts.map +1 -1
- package/esm/http/plugins.mjs +7 -4
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/rate-limit-cache-store.mjs +2 -1
- package/esm/http/rate-limit-cache-store.mjs.map +1 -1
- package/esm/http/request-log-snapshot.d.mts +12 -5
- package/esm/http/request-log-snapshot.d.mts.map +1 -1
- package/esm/http/request-log-snapshot.mjs +83 -4
- package/esm/http/request-log-snapshot.mjs.map +1 -1
- package/esm/http/request.d.mts +2 -2
- package/esm/http/request.d.mts.map +1 -1
- package/esm/http/request.mjs +5 -4
- package/esm/http/request.mjs.map +1 -1
- package/esm/http/response.d.mts +11 -1
- package/esm/http/response.d.mts.map +1 -1
- package/esm/http/response.mjs +164 -76
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/safe-redirect.d.mts +51 -0
- package/esm/http/safe-redirect.d.mts.map +1 -0
- package/esm/http/safe-redirect.mjs +80 -0
- package/esm/http/safe-redirect.mjs.map +1 -0
- package/esm/http/serialized.d.mts.map +1 -1
- package/esm/http/server.d.mts +3 -1
- package/esm/http/server.d.mts.map +1 -1
- package/esm/http/server.mjs +14 -4
- package/esm/http/server.mjs.map +1 -1
- package/esm/http/stream-transport.mjs +4 -2
- package/esm/http/stream-transport.mjs.map +1 -1
- package/esm/http/types.d.mts +44 -11
- package/esm/http/types.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variant.mjs +1 -1
- package/esm/http/uploads/generate-image-variants.d.mts +10 -7
- package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/generate-image-variants.mjs +61 -24
- package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
- package/esm/http/uploads/image-variant-cache-entries.mjs +78 -0
- package/esm/http/uploads/image-variant-cache-entries.mjs.map +1 -0
- package/esm/http/uploads/image-variant-cache.mjs +72 -30
- package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
- package/esm/http/uploads/image-variant-types.d.mts +2 -0
- package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.d.mts +3 -1
- package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
- package/esm/http/uploads/image-variants-config-error.mjs +3 -2
- package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
- package/esm/http/uploads/load-variant-source.mjs +1 -1
- package/esm/http/uploads/load-variant-source.mjs.map +1 -1
- package/esm/http/uploads/purge-image-variants.d.mts +7 -2
- package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
- package/esm/http/uploads/purge-image-variants.mjs +16 -16
- package/esm/http/uploads/purge-image-variants.mjs.map +1 -1
- package/esm/http/uploads/remote-variant-source.mjs +115 -0
- package/esm/http/uploads/remote-variant-source.mjs.map +1 -0
- package/esm/http/uploads/resolve-image-variant.d.mts +3 -4
- package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
- package/esm/http/uploads/resolve-image-variant.mjs +10 -18
- package/esm/http/uploads/resolve-image-variant.mjs.map +1 -1
- package/esm/http/uploads/resolve-image-variants-config.mjs +5 -3
- package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
- package/esm/http/uploads/resolve-remote-image-variant.mjs +89 -0
- package/esm/http/uploads/resolve-remote-image-variant.mjs.map +1 -0
- package/esm/http/uploads/trim-image-variant-cache.mjs +193 -0
- package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -0
- package/esm/http/uploads/uploaded-file.controller.d.mts +5 -3
- package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
- package/esm/http/uploads/uploaded-file.controller.mjs +16 -8
- package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
- package/esm/http/uploads/variant-cache-key.mjs +1 -1
- package/esm/http/uploads-types.d.mts +6 -2
- package/esm/http/uploads-types.d.mts.map +1 -1
- package/esm/index.d.mts +17 -6
- package/esm/index.mjs +14 -3
- package/esm/localization/parse-locale-dictionary.d.mts +2 -0
- package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
- package/esm/localization/parse-locale-dictionary.mjs +1 -0
- package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
- package/esm/mail/config.d.mts +12 -1
- package/esm/mail/config.d.mts.map +1 -1
- package/esm/mail/config.mjs +16 -1
- package/esm/mail/config.mjs.map +1 -1
- package/esm/mail/index.d.mts +1 -1
- package/esm/mail/index.mjs +1 -1
- package/esm/net/index.d.mts +2 -0
- package/esm/net/index.mjs +3 -0
- package/esm/openapi/build-openapi-document.d.mts.map +1 -1
- package/esm/openapi/build-openapi-document.mjs +8 -5
- package/esm/openapi/build-openapi-document.mjs.map +1 -1
- package/esm/openapi/error-responses.mjs +28 -2
- package/esm/openapi/error-responses.mjs.map +1 -1
- package/esm/openapi/postman/build-request-body.mjs.map +1 -1
- package/esm/openapi/postman/build-request-url.mjs.map +1 -1
- package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
- package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
- package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
- package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
- package/esm/openapi/postman/schema-refs.mjs.map +1 -1
- package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
- package/esm/openapi/request-schemas.mjs.map +1 -1
- package/esm/openapi/response-schemas.mjs.map +1 -1
- package/esm/openapi/schema-registry.d.mts +1 -0
- package/esm/openapi/schema-registry.mjs.map +1 -1
- package/esm/openapi/security.mjs.map +1 -1
- package/esm/openapi/types.d.mts +3 -2
- package/esm/openapi/types.d.mts.map +1 -1
- package/esm/production/assert-generated-imports.mjs +1 -0
- package/esm/production/assert-generated-imports.mjs.map +1 -1
- package/esm/production/production-builder.mjs +12 -4
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/resolve-build-config.mjs +1 -0
- package/esm/production/resolve-build-config.mjs.map +1 -1
- package/esm/production/route-registration-child.mjs.map +1 -1
- package/esm/production/route-registration-snapshot.mjs.map +1 -1
- package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
- package/esm/repositories/contracts/types.d.mts.map +1 -1
- package/esm/repositories/repository.manager.mjs.map +1 -1
- package/esm/resource/resource.d.mts.map +1 -1
- package/esm/resource/resource.mjs.map +1 -1
- package/esm/resource/types.d.mts.map +1 -1
- package/esm/restful/restful.d.mts +5 -5
- package/esm/restful/restful.d.mts.map +1 -1
- package/esm/restful/restful.mjs.map +1 -1
- package/esm/router/build-route-rate-limit.mjs.map +1 -1
- package/esm/router/dev-dispatch.mjs +31 -12
- package/esm/router/dev-dispatch.mjs.map +1 -1
- package/esm/router/index.d.mts +4 -2
- package/esm/router/index.mjs +2 -0
- package/esm/router/log-request-lifecycle.mjs.map +1 -1
- package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
- package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
- package/esm/router/resolve-route-rate-limit.mjs +47 -0
- package/esm/router/resolve-route-rate-limit.mjs.map +1 -0
- package/esm/router/resolve-route-validation.mjs +19 -0
- package/esm/router/resolve-route-validation.mjs.map +1 -0
- package/esm/router/route-guard-names.mjs +30 -0
- package/esm/router/route-guard-names.mjs.map +1 -0
- package/esm/router/route-name-taken-error.d.mts +14 -0
- package/esm/router/route-name-taken-error.d.mts.map +1 -0
- package/esm/router/route-name-taken-error.mjs +18 -0
- package/esm/router/route-name-taken-error.mjs.map +1 -0
- package/esm/router/router.d.mts +32 -13
- package/esm/router/router.d.mts.map +1 -1
- package/esm/router/router.mjs +71 -38
- package/esm/router/router.mjs.map +1 -1
- package/esm/router/types.d.mts +137 -17
- package/esm/router/types.d.mts.map +1 -1
- package/esm/router/unguarded-route-diagnostics.d.mts +40 -0
- package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -0
- package/esm/router/unguarded-route-diagnostics.mjs +95 -0
- package/esm/router/unguarded-route-diagnostics.mjs.map +1 -0
- package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
- package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
- package/esm/storage/drivers/local-driver.d.mts.map +1 -1
- package/esm/storage/drivers/local-driver.mjs.map +1 -1
- package/esm/storage/local-disk-roots.mjs +24 -0
- package/esm/storage/local-disk-roots.mjs.map +1 -0
- package/esm/storage/storage.d.mts +14 -0
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/storage.mjs +22 -0
- package/esm/storage/storage.mjs.map +1 -1
- package/esm/storage/types.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.d.mts +2 -0
- package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
- package/esm/storage/utils/storage-not-initialized-error.mjs +1 -0
- package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
- package/esm/tests/authenticated-test-client.d.mts +32 -0
- package/esm/tests/authenticated-test-client.d.mts.map +1 -0
- package/esm/tests/authenticated-test-client.mjs +40 -0
- package/esm/tests/authenticated-test-client.mjs.map +1 -0
- package/esm/tests/factories.d.mts +59 -0
- package/esm/tests/factories.d.mts.map +1 -0
- package/esm/tests/factories.mjs +105 -0
- package/esm/tests/factories.mjs.map +1 -0
- package/esm/tests/fakes/cache-fake.d.mts +29 -0
- package/esm/tests/fakes/cache-fake.d.mts.map +1 -0
- package/esm/tests/fakes/cache-fake.mjs +79 -0
- package/esm/tests/fakes/cache-fake.mjs.map +1 -0
- package/esm/tests/fakes/clock-fake.d.mts +32 -0
- package/esm/tests/fakes/clock-fake.d.mts.map +1 -0
- package/esm/tests/fakes/clock-fake.mjs +69 -0
- package/esm/tests/fakes/clock-fake.mjs.map +1 -0
- package/esm/tests/fakes/fake-assertion-error.d.mts +13 -0
- package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -0
- package/esm/tests/fakes/fake-assertion-error.mjs +20 -0
- package/esm/tests/fakes/fake-assertion-error.mjs.map +1 -0
- package/esm/tests/fakes/ids-fake.d.mts +22 -0
- package/esm/tests/fakes/ids-fake.d.mts.map +1 -0
- package/esm/tests/fakes/ids-fake.mjs +57 -0
- package/esm/tests/fakes/ids-fake.mjs.map +1 -0
- package/esm/tests/fakes/index.d.mts +8 -0
- package/esm/tests/fakes/index.mjs +10 -0
- package/esm/tests/fakes/mail-fake.d.mts +41 -0
- package/esm/tests/fakes/mail-fake.d.mts.map +1 -0
- package/esm/tests/fakes/mail-fake.mjs +111 -0
- package/esm/tests/fakes/mail-fake.mjs.map +1 -0
- package/esm/tests/fakes/queue-fake.d.mts +48 -0
- package/esm/tests/fakes/queue-fake.d.mts.map +1 -0
- package/esm/tests/fakes/queue-fake.mjs +134 -0
- package/esm/tests/fakes/queue-fake.mjs.map +1 -0
- package/esm/tests/fakes/storage-fake.d.mts +31 -0
- package/esm/tests/fakes/storage-fake.d.mts.map +1 -0
- package/esm/tests/fakes/storage-fake.mjs +122 -0
- package/esm/tests/fakes/storage-fake.mjs.map +1 -0
- package/esm/tests/fakes/test-fakes.d.mts +39 -0
- package/esm/tests/fakes/test-fakes.d.mts.map +1 -0
- package/esm/tests/fakes/test-fakes.mjs +90 -0
- package/esm/tests/fakes/test-fakes.mjs.map +1 -0
- package/esm/tests/index.d.mts +14 -2
- package/esm/tests/index.mjs +15 -2
- package/esm/tests/snapshot-response.d.mts +34 -0
- package/esm/tests/snapshot-response.d.mts.map +1 -0
- package/esm/tests/snapshot-response.mjs +42 -0
- package/esm/tests/snapshot-response.mjs.map +1 -0
- package/esm/tests/start-http-development-server.d.mts +22 -0
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +36 -3
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-helpers.d.mts +20 -1
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-helpers.mjs +40 -27
- package/esm/tests/test-helpers.mjs.map +1 -1
- package/esm/tests/test-http-server.d.mts +62 -0
- package/esm/tests/test-http-server.d.mts.map +1 -0
- package/esm/tests/test-http-server.mjs +119 -0
- package/esm/tests/test-http-server.mjs.map +1 -0
- package/esm/tests/vitest-setup.d.mts +11 -0
- package/esm/tests/vitest-setup.d.mts.map +1 -1
- package/esm/tests/vitest-setup.mjs +12 -4
- package/esm/tests/vitest-setup.mjs.map +1 -1
- package/esm/tooling/agents-md/agents-md-markers.d.mts +27 -0
- package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -0
- package/esm/tooling/agents-md/agents-md-markers.mjs +59 -0
- package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -0
- package/esm/tooling/agents-md/agents-md-refresher.d.mts +36 -0
- package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -0
- package/esm/tooling/agents-md/agents-md-refresher.mjs +72 -0
- package/esm/tooling/agents-md/agents-md-refresher.mjs.map +1 -0
- package/esm/tooling/agents-md/index.mjs +7 -0
- package/esm/tooling/agents-md/installed-skills.d.mts +30 -0
- package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -0
- package/esm/tooling/agents-md/installed-skills.mjs +74 -0
- package/esm/tooling/agents-md/installed-skills.mjs.map +1 -0
- package/esm/tooling/agents-md/render-agents-md.d.mts +33 -0
- package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -0
- package/esm/tooling/agents-md/render-agents-md.mjs +195 -0
- package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -0
- package/esm/tooling/agents-md/write-agents-md.d.mts +33 -0
- package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -0
- package/esm/tooling/agents-md/write-agents-md.mjs +49 -0
- package/esm/tooling/agents-md/write-agents-md.mjs.map +1 -0
- package/esm/tooling/board/board-message.d.mts +31 -0
- package/esm/tooling/board/board-message.d.mts.map +1 -0
- package/esm/tooling/board/board-message.mjs +86 -0
- package/esm/tooling/board/board-message.mjs.map +1 -0
- package/esm/tooling/board/board.d.mts +109 -0
- package/esm/tooling/board/board.d.mts.map +1 -0
- package/esm/tooling/board/board.mjs +406 -0
- package/esm/tooling/board/board.mjs.map +1 -0
- package/esm/tooling/board/board.types.d.mts +72 -0
- package/esm/tooling/board/board.types.d.mts.map +1 -0
- package/esm/tooling/board/board.types.mjs +54 -0
- package/esm/tooling/board/board.types.mjs.map +1 -0
- package/esm/tooling/check/changed-files.d.mts +33 -0
- package/esm/tooling/check/changed-files.d.mts.map +1 -0
- package/esm/tooling/check/changed-files.mjs +73 -0
- package/esm/tooling/check/changed-files.mjs.map +1 -0
- package/esm/tooling/check/check-report.types.d.mts +62 -0
- package/esm/tooling/check/check-report.types.d.mts.map +1 -0
- package/esm/tooling/check/check-report.types.mjs +37 -0
- package/esm/tooling/check/check-report.types.mjs.map +1 -0
- package/esm/tooling/check/code-style-conventions.mjs +106 -0
- package/esm/tooling/check/code-style-conventions.mjs.map +1 -0
- package/esm/tooling/check/conventions-step.d.mts +34 -0
- package/esm/tooling/check/conventions-step.d.mts.map +1 -0
- package/esm/tooling/check/conventions-step.mjs +184 -0
- package/esm/tooling/check/conventions-step.mjs.map +1 -0
- package/esm/tooling/check/environment-step.d.mts +18 -0
- package/esm/tooling/check/environment-step.d.mts.map +1 -0
- package/esm/tooling/check/environment-step.mjs +78 -0
- package/esm/tooling/check/environment-step.mjs.map +1 -0
- package/esm/tooling/check/index.d.mts +8 -0
- package/esm/tooling/check/index.mjs +10 -0
- package/esm/tooling/check/lint-step.d.mts +19 -0
- package/esm/tooling/check/lint-step.d.mts.map +1 -0
- package/esm/tooling/check/lint-step.mjs +111 -0
- package/esm/tooling/check/lint-step.mjs.map +1 -0
- package/esm/tooling/check/request-input.mjs +132 -0
- package/esm/tooling/check/request-input.mjs.map +1 -0
- package/esm/tooling/check/run-check.d.mts +35 -0
- package/esm/tooling/check/run-check.d.mts.map +1 -0
- package/esm/tooling/check/run-check.mjs +192 -0
- package/esm/tooling/check/run-check.mjs.map +1 -0
- package/esm/tooling/check/run-tests.d.mts +48 -0
- package/esm/tooling/check/run-tests.d.mts.map +1 -0
- package/esm/tooling/check/run-tests.mjs +93 -0
- package/esm/tooling/check/run-tests.mjs.map +1 -0
- package/esm/tooling/check/security-conventions.mjs +648 -0
- package/esm/tooling/check/security-conventions.mjs.map +1 -0
- package/esm/tooling/check/source-ast.mjs +195 -0
- package/esm/tooling/check/source-ast.mjs.map +1 -0
- package/esm/tooling/check/source-files.mjs +27 -0
- package/esm/tooling/check/source-files.mjs.map +1 -0
- package/esm/tooling/check/tests-step.d.mts +34 -0
- package/esm/tooling/check/tests-step.d.mts.map +1 -0
- package/esm/tooling/check/tests-step.mjs +177 -0
- package/esm/tooling/check/tests-step.mjs.map +1 -0
- package/esm/tooling/dev-state/dev-server-state.d.mts +39 -0
- package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -0
- package/esm/tooling/dev-state/dev-server-state.mjs +67 -0
- package/esm/tooling/dev-state/dev-server-state.mjs.map +1 -0
- package/esm/tooling/devtools/devtools-client.d.mts +91 -0
- package/esm/tooling/devtools/devtools-client.d.mts.map +1 -0
- package/esm/tooling/devtools/devtools-client.mjs +155 -0
- package/esm/tooling/devtools/devtools-client.mjs.map +1 -0
- package/esm/tooling/generate/generation.d.mts +78 -0
- package/esm/tooling/generate/generation.d.mts.map +1 -0
- package/esm/tooling/generate/generation.mjs +123 -0
- package/esm/tooling/generate/generation.mjs.map +1 -0
- package/esm/tooling/generate/generator-spec.d.mts +57 -0
- package/esm/tooling/generate/generator-spec.d.mts.map +1 -0
- package/esm/tooling/generate/generator-spec.mjs +102 -0
- package/esm/tooling/generate/generator-spec.mjs.map +1 -0
- package/esm/tooling/generate/index.mjs +6 -0
- package/esm/tooling/generate/project-files.mjs +121 -0
- package/esm/tooling/generate/project-files.mjs.map +1 -0
- package/esm/tooling/generate/run-cli.d.mts +40 -0
- package/esm/tooling/generate/run-cli.d.mts.map +1 -0
- package/esm/tooling/generate/run-cli.mjs +93 -0
- package/esm/tooling/generate/run-cli.mjs.map +1 -0
- package/esm/tooling/generate/unified-diff.d.mts +37 -0
- package/esm/tooling/generate/unified-diff.d.mts.map +1 -0
- package/esm/tooling/generate/unified-diff.mjs +161 -0
- package/esm/tooling/generate/unified-diff.mjs.map +1 -0
- package/esm/tooling/index.d.mts +41 -0
- package/esm/tooling/index.mjs +45 -0
- package/esm/tooling/inspect/boot-for-inspect.d.mts +23 -0
- package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -0
- package/esm/tooling/inspect/boot-for-inspect.mjs +63 -0
- package/esm/tooling/inspect/boot-for-inspect.mjs.map +1 -0
- package/esm/tooling/inspect/collect-config.mjs +77 -0
- package/esm/tooling/inspect/collect-config.mjs.map +1 -0
- package/esm/tooling/inspect/collect-models.d.mts +9 -0
- package/esm/tooling/inspect/collect-models.d.mts.map +1 -0
- package/esm/tooling/inspect/collect-models.mjs +154 -0
- package/esm/tooling/inspect/collect-models.mjs.map +1 -0
- package/esm/tooling/inspect/collect-packages.d.mts +10 -0
- package/esm/tooling/inspect/collect-packages.d.mts.map +1 -0
- package/esm/tooling/inspect/collect-packages.mjs +157 -0
- package/esm/tooling/inspect/collect-packages.mjs.map +1 -0
- package/esm/tooling/inspect/collect-pages.mjs +108 -0
- package/esm/tooling/inspect/collect-pages.mjs.map +1 -0
- package/esm/tooling/inspect/collect-routes.mjs +168 -0
- package/esm/tooling/inspect/collect-routes.mjs.map +1 -0
- package/esm/tooling/inspect/event-recorder.d.mts +37 -0
- package/esm/tooling/inspect/event-recorder.d.mts.map +1 -0
- package/esm/tooling/inspect/event-recorder.mjs +91 -0
- package/esm/tooling/inspect/event-recorder.mjs.map +1 -0
- package/esm/tooling/inspect/index.d.mts +7 -0
- package/esm/tooling/inspect/index.mjs +7 -0
- package/esm/tooling/inspect/inspect-app.d.mts +53 -0
- package/esm/tooling/inspect/inspect-app.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-app.mjs +92 -0
- package/esm/tooling/inspect/inspect-app.mjs.map +1 -0
- package/esm/tooling/inspect/inspect-report.schema.d.mts +15 -0
- package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-report.schema.mjs +463 -0
- package/esm/tooling/inspect/inspect-report.schema.mjs.map +1 -0
- package/esm/tooling/inspect/inspect-report.types.d.mts +196 -0
- package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -0
- package/esm/tooling/inspect/inspect-report.types.mjs +33 -0
- package/esm/tooling/inspect/inspect-report.types.mjs.map +1 -0
- package/esm/tooling/mcp/create-mcp-context.d.mts +26 -0
- package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -0
- package/esm/tooling/mcp/create-mcp-context.mjs +75 -0
- package/esm/tooling/mcp/create-mcp-context.mjs.map +1 -0
- package/esm/tooling/mcp/db-schema.d.mts +49 -0
- package/esm/tooling/mcp/db-schema.d.mts.map +1 -0
- package/esm/tooling/mcp/db-schema.mjs +56 -0
- package/esm/tooling/mcp/db-schema.mjs.map +1 -0
- package/esm/tooling/mcp/docs-search.d.mts +72 -0
- package/esm/tooling/mcp/docs-search.d.mts.map +1 -0
- package/esm/tooling/mcp/docs-search.mjs +178 -0
- package/esm/tooling/mcp/docs-search.mjs.map +1 -0
- package/esm/tooling/mcp/index.mjs +9 -0
- package/esm/tooling/mcp/load-ai-tools.d.mts +62 -0
- package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -0
- package/esm/tooling/mcp/load-ai-tools.mjs +44 -0
- package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -0
- package/esm/tooling/mcp/mcp-tools.d.mts +60 -0
- package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -0
- package/esm/tooling/mcp/mcp-tools.mjs +513 -0
- package/esm/tooling/mcp/mcp-tools.mjs.map +1 -0
- package/esm/tooling/mcp/start-mcp-server.d.mts +56 -0
- package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -0
- package/esm/tooling/mcp/start-mcp-server.mjs +126 -0
- package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -0
- package/esm/tooling/mcp/tool-input.d.mts +75 -0
- package/esm/tooling/mcp/tool-input.d.mts.map +1 -0
- package/esm/tooling/mcp/tool-input.mjs +72 -0
- package/esm/tooling/mcp/tool-input.mjs.map +1 -0
- package/esm/tooling/problem.d.mts +45 -0
- package/esm/tooling/problem.d.mts.map +1 -0
- package/esm/tooling/problem.mjs +28 -0
- package/esm/tooling/problem.mjs.map +1 -0
- package/esm/tooling/trace/trace-report.types.d.mts +71 -0
- package/esm/tooling/trace/trace-report.types.d.mts.map +1 -0
- package/esm/tooling/trace/trace-report.types.mjs +7 -0
- package/esm/tooling/trace/trace-report.types.mjs.map +1 -0
- package/esm/tooling/trace/trace-request.d.mts +83 -0
- package/esm/tooling/trace/trace-request.d.mts.map +1 -0
- package/esm/tooling/trace/trace-request.mjs +241 -0
- package/esm/tooling/trace/trace-request.mjs.map +1 -0
- package/esm/tooling/typecheck/index.d.mts +1 -0
- package/esm/tooling/typecheck/index.mjs +3 -0
- package/esm/tooling/typecheck/run-typecheck.d.mts +59 -0
- package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -0
- package/esm/tooling/typecheck/run-typecheck.mjs +153 -0
- package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -0
- package/esm/upgrade/codemods/head-viewport.mjs +46 -0
- package/esm/upgrade/codemods/head-viewport.mjs.map +1 -0
- package/esm/upgrade/codemods/helpers.mjs +81 -0
- package/esm/upgrade/codemods/helpers.mjs.map +1 -0
- package/esm/upgrade/codemods/index.mjs +34 -0
- package/esm/upgrade/codemods/index.mjs.map +1 -0
- package/esm/upgrade/codemods/logger-sync-calls.mjs +57 -0
- package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -0
- package/esm/upgrade/codemods/package-json.mjs +122 -0
- package/esm/upgrade/codemods/package-json.mjs.map +1 -0
- package/esm/upgrade/codemods/request-log-snapshot.mjs +82 -0
- package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -0
- package/esm/upgrade/codemods/review-sites.mjs +262 -0
- package/esm/upgrade/codemods/review-sites.mjs.map +1 -0
- package/esm/upgrade/diff.mjs +119 -0
- package/esm/upgrade/diff.mjs.map +1 -0
- package/esm/upgrade/format-upgrade-report.mjs +32 -0
- package/esm/upgrade/format-upgrade-report.mjs.map +1 -0
- package/esm/upgrade/load-ts-morph.mjs +48 -0
- package/esm/upgrade/load-ts-morph.mjs.map +1 -0
- package/esm/upgrade/notes.mjs +16 -0
- package/esm/upgrade/notes.mjs.map +1 -0
- package/esm/upgrade/run-upgrade.mjs +246 -0
- package/esm/upgrade/run-upgrade.mjs.map +1 -0
- package/esm/upgrade/upgrade-command.action.mjs +37 -0
- package/esm/upgrade/upgrade-command.action.mjs.map +1 -0
- package/esm/upgrade/version.mjs +39 -0
- package/esm/upgrade/version.mjs.map +1 -0
- package/esm/use-cases/use-cases-registry.mjs.map +1 -1
- package/esm/utils/clock.d.mts +33 -0
- package/esm/utils/clock.d.mts.map +1 -0
- package/esm/utils/clock.mjs +27 -0
- package/esm/utils/clock.mjs.map +1 -0
- package/esm/utils/framework-vesion.mjs +1 -1
- package/esm/utils/framework-vesion.mjs.map +1 -1
- package/esm/utils/ids.d.mts +32 -0
- package/esm/utils/ids.d.mts.map +1 -0
- package/esm/utils/ids.mjs +33 -0
- package/esm/utils/ids.mjs.map +1 -0
- package/esm/utils/index.d.mts +3 -0
- package/esm/utils/index.mjs +3 -0
- package/esm/utils/runtime.d.mts +59 -0
- package/esm/utils/runtime.d.mts.map +1 -0
- package/esm/utils/runtime.mjs +85 -0
- package/esm/utils/runtime.mjs.map +1 -0
- package/esm/validation/index.d.mts +1 -1
- package/esm/validation/types.d.mts +57 -2
- package/esm/validation/types.d.mts.map +1 -1
- package/esm/validation/validateAll.mjs +19 -2
- package/esm/validation/validateAll.mjs.map +1 -1
- package/esm/validation/validation-failure-status.mjs +15 -0
- package/esm/validation/validation-failure-status.mjs.map +1 -0
- package/esm/validation/validators/file-validator.d.mts +0 -16
- package/esm/validation/validators/file-validator.d.mts.map +1 -1
- package/esm/warlock-config/bundle-config.mjs +1 -1
- package/esm/warlock-config/types.d.mts +27 -3
- package/esm/warlock-config/types.d.mts.map +1 -1
- package/llms-full.txt +3166 -736
- package/llms.txt +16 -6
- package/package.json +43 -13
- package/schemas/inspect-report.schema.json +554 -0
- package/skills/README.md +9 -0
- package/skills/add-connector/SKILL.md +26 -38
- package/skills/benchmark-code/SKILL.md +30 -24
- package/skills/build-restful/SKILL.md +14 -14
- package/skills/build-url/SKILL.md +18 -18
- package/skills/configure-app/SKILL.md +107 -14
- package/skills/create-controller/SKILL.md +25 -12
- package/skills/create-module/SKILL.md +3 -3
- package/skills/define-resource/SKILL.md +32 -29
- package/skills/encrypt-data/SKILL.md +21 -19
- package/skills/generate-openapi/SKILL.md +50 -24
- package/skills/hash-password/SKILL.md +2 -2
- package/skills/health-checks/SKILL.md +24 -7
- package/skills/index.md +9 -4
- package/skills/lower-stage3-decorators/SKILL.md +4 -4
- package/skills/make-endpoint/SKILL.md +110 -0
- package/skills/model-factories/SKILL.md +92 -0
- package/skills/process-image/SKILL.md +32 -30
- package/skills/register-route/SKILL.md +109 -10
- package/skills/request-memo/SKILL.md +1 -1
- package/skills/request-tracing/SKILL.md +4 -1
- package/skills/resolve-path/SKILL.md +45 -44
- package/skills/retry-operation/SKILL.md +20 -11
- package/skills/run-app/SKILL.md +106 -22
- package/skills/send-response/SKILL.md +179 -14
- package/skills/store-file/SKILL.md +93 -53
- package/skills/test-fakes/SKILL.md +123 -0
- package/skills/test-http/SKILL.md +125 -21
- package/skills/test-service/SKILL.md +41 -1
- package/skills/update-packages/SKILL.md +29 -18
- package/skills/upgrade-from-5-29/SKILL.md +413 -0
- package/skills/upload-file/SKILL.md +31 -33
- package/skills/use-app-context/SKILL.md +38 -31
- package/skills/use-middleware/SKILL.md +45 -25
- package/skills/use-model-transformers/SKILL.md +37 -28
- package/skills/use-repository/SKILL.md +2 -2
- package/skills/validate-input/SKILL.md +72 -28
- package/skills/warlock-agents-md/SKILL.md +96 -0
- package/skills/warlock-board/SKILL.md +123 -0
- package/skills/warlock-check/SKILL.md +132 -0
- package/skills/warlock-conventions/SKILL.md +115 -0
- package/skills/warlock-doctor/SKILL.md +55 -22
- package/skills/warlock-inspect/SKILL.md +134 -0
- package/skills/warlock-mcp/SKILL.md +120 -0
- package/skills/warlock-routes/SKILL.md +18 -11
- package/skills/warlock-trace/SKILL.md +81 -0
- package/skills/wire-socket/SKILL.md +8 -8
- package/skills/write-seeder/SKILL.md +46 -32
- package/skills/write-use-case/SKILL.md +40 -27
- package/esm/http/uploads/matches-if-none-match.mjs +0 -13
- package/esm/http/uploads/matches-if-none-match.mjs.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region ../../packages/core/src/tooling/dev-state/dev-server-state.d.ts
|
|
2
|
+
/** Where `warlock dev` records the address of the running server, under the project root. */
|
|
3
|
+
declare const DEV_SERVER_STATE_FILE = ".warlock/dev-server.json";
|
|
4
|
+
/**
|
|
5
|
+
* What a running `warlock dev` worker records about itself, so `warlock trace`
|
|
6
|
+
* and `warlock mcp` can find it without guessing a port.
|
|
7
|
+
*
|
|
8
|
+
* Written once the server is ready, rewritten when `--mcp` starts, and removed
|
|
9
|
+
* when the worker shuts down. A crashed worker can leave a stale file behind,
|
|
10
|
+
* so readers confirm the server answers before trusting it.
|
|
11
|
+
*/
|
|
12
|
+
type DevServerState = {
|
|
13
|
+
schemaVersion: 1; /** The worker process id (informational: readers never signal it). */
|
|
14
|
+
pid: number; /** The address to send requests to, e.g. `http://localhost:2030`. */
|
|
15
|
+
url: string; /** ISO time the worker became ready. */
|
|
16
|
+
startedAt: string; /** The devtools mount, when `@warlock.js/devtools` was registered. */
|
|
17
|
+
devtools: {
|
|
18
|
+
path: string;
|
|
19
|
+
} | null; /** The MCP endpoint `warlock dev --mcp` serves, when it is on. */
|
|
20
|
+
mcp: {
|
|
21
|
+
url: string;
|
|
22
|
+
} | null;
|
|
23
|
+
};
|
|
24
|
+
/** Narrow parsed JSON to a {@link DevServerState}; `undefined` for anything else. */
|
|
25
|
+
declare function parseDevServerState(value: unknown): DevServerState | undefined;
|
|
26
|
+
/** The recorded state, or `undefined` when no dev server recorded one. */
|
|
27
|
+
declare function readDevServerState(cwd?: string): DevServerState | undefined;
|
|
28
|
+
/** Record the state atomically (temp file + rename), creating `.warlock/` when needed. */
|
|
29
|
+
declare function writeDevServerState(state: DevServerState, cwd?: string): void;
|
|
30
|
+
/** Merge fields into the recorded state; a no-op when there is none. */
|
|
31
|
+
declare function updateDevServerState(patch: Partial<Omit<DevServerState, "schemaVersion">>, cwd?: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Remove the state file — only when it still belongs to `pid`, so a worker
|
|
34
|
+
* that shuts down late never deletes the record of the worker that replaced it.
|
|
35
|
+
*/
|
|
36
|
+
declare function removeDevServerState(pid?: number, cwd?: string): void;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { DEV_SERVER_STATE_FILE, DevServerState, parseDevServerState, readDevServerState, removeDevServerState, updateDevServerState, writeDevServerState };
|
|
39
|
+
//# sourceMappingURL=dev-server-state.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server-state.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/dev-state/dev-server-state.ts"],"mappings":";;cAIa,qBAAA;;;;AAAqB;AAUlC;;;;KAAY,cAAA;EACV,aAAA,KAIA;EAFA,GAAA,UAMA;EAJA,GAAA,UAMA;EAJA,SAAA,UAIU;EAFV,QAAA;IAAY,IAAA;EAAA;EAEZ,GAAA;IAAO,GAAA;EAAA;AAAA;;iBAYO,mBAAA,CAAoB,KAAA,YAAiB,cAAc;AAsBI;AAAA,iBAAvD,kBAAA,CAAmB,GAAA,YAAsB,cAAc;;iBAavD,mBAAA,CAAoB,KAAA,EAAO,cAAc,EAAE,GAAA;;iBAU3C,oBAAA,CACd,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,cAAA,qBACpB,GAAA;;;;AAZ4E;iBAyB9D,oBAAA,CAAqB,GAAA,WAAmB,GAAmB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
|
|
4
|
+
//#region ../../packages/core/src/tooling/dev-state/dev-server-state.ts
|
|
5
|
+
/** Where `warlock dev` records the address of the running server, under the project root. */
|
|
6
|
+
const DEV_SERVER_STATE_FILE = ".warlock/dev-server.json";
|
|
7
|
+
function isRecord(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
|
+
}
|
|
10
|
+
function statePath(cwd) {
|
|
11
|
+
return path.join(cwd, DEV_SERVER_STATE_FILE);
|
|
12
|
+
}
|
|
13
|
+
/** Narrow parsed JSON to a {@link DevServerState}; `undefined` for anything else. */
|
|
14
|
+
function parseDevServerState(value) {
|
|
15
|
+
if (!isRecord(value) || value.schemaVersion !== 1) return void 0;
|
|
16
|
+
if (typeof value.url !== "string" || typeof value.pid !== "number") return void 0;
|
|
17
|
+
const devtools = isRecord(value.devtools) && typeof value.devtools.path === "string" ? { path: value.devtools.path } : null;
|
|
18
|
+
const mcp = isRecord(value.mcp) && typeof value.mcp.url === "string" ? { url: value.mcp.url } : null;
|
|
19
|
+
return {
|
|
20
|
+
schemaVersion: 1,
|
|
21
|
+
pid: value.pid,
|
|
22
|
+
url: value.url,
|
|
23
|
+
startedAt: typeof value.startedAt === "string" ? value.startedAt : "",
|
|
24
|
+
devtools,
|
|
25
|
+
mcp
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** The recorded state, or `undefined` when no dev server recorded one. */
|
|
29
|
+
function readDevServerState(cwd = process.cwd()) {
|
|
30
|
+
const file = statePath(cwd);
|
|
31
|
+
if (!existsSync(file)) return void 0;
|
|
32
|
+
try {
|
|
33
|
+
return parseDevServerState(JSON.parse(readFileSync(file, "utf8")));
|
|
34
|
+
} catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Record the state atomically (temp file + rename), creating `.warlock/` when needed. */
|
|
39
|
+
function writeDevServerState(state, cwd = process.cwd()) {
|
|
40
|
+
const file = statePath(cwd);
|
|
41
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
42
|
+
mkdirSync(path.dirname(file), { recursive: true });
|
|
43
|
+
writeFileSync(temporary, `${JSON.stringify(state, null, 2)}\n`, "utf8");
|
|
44
|
+
renameSync(temporary, file);
|
|
45
|
+
}
|
|
46
|
+
/** Merge fields into the recorded state; a no-op when there is none. */
|
|
47
|
+
function updateDevServerState(patch, cwd = process.cwd()) {
|
|
48
|
+
const current = readDevServerState(cwd);
|
|
49
|
+
if (!current) return;
|
|
50
|
+
writeDevServerState({
|
|
51
|
+
...current,
|
|
52
|
+
...patch
|
|
53
|
+
}, cwd);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Remove the state file — only when it still belongs to `pid`, so a worker
|
|
57
|
+
* that shuts down late never deletes the record of the worker that replaced it.
|
|
58
|
+
*/
|
|
59
|
+
function removeDevServerState(pid = process.pid, cwd = process.cwd()) {
|
|
60
|
+
const current = readDevServerState(cwd);
|
|
61
|
+
if (current && current.pid !== pid) return;
|
|
62
|
+
rmSync(statePath(cwd), { force: true });
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
export { DEV_SERVER_STATE_FILE, parseDevServerState, readDevServerState, removeDevServerState, updateDevServerState, writeDevServerState };
|
|
67
|
+
//# sourceMappingURL=dev-server-state.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server-state.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/dev-state/dev-server-state.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\n/** Where `warlock dev` records the address of the running server, under the project root. */\nexport const DEV_SERVER_STATE_FILE = \".warlock/dev-server.json\";\n\n/**\n * What a running `warlock dev` worker records about itself, so `warlock trace`\n * and `warlock mcp` can find it without guessing a port.\n *\n * Written once the server is ready, rewritten when `--mcp` starts, and removed\n * when the worker shuts down. A crashed worker can leave a stale file behind,\n * so readers confirm the server answers before trusting it.\n */\nexport type DevServerState = {\n schemaVersion: 1;\n /** The worker process id (informational: readers never signal it). */\n pid: number;\n /** The address to send requests to, e.g. `http://localhost:2030`. */\n url: string;\n /** ISO time the worker became ready. */\n startedAt: string;\n /** The devtools mount, when `@warlock.js/devtools` was registered. */\n devtools: { path: string } | null;\n /** The MCP endpoint `warlock dev --mcp` serves, when it is on. */\n mcp: { url: string } | null;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction statePath(cwd: string): string {\n return path.join(cwd, DEV_SERVER_STATE_FILE);\n}\n\n/** Narrow parsed JSON to a {@link DevServerState}; `undefined` for anything else. */\nexport function parseDevServerState(value: unknown): DevServerState | undefined {\n if (!isRecord(value) || value.schemaVersion !== 1) return undefined;\n if (typeof value.url !== \"string\" || typeof value.pid !== \"number\") return undefined;\n\n const devtools =\n isRecord(value.devtools) && typeof value.devtools.path === \"string\"\n ? { path: value.devtools.path }\n : null;\n const mcp =\n isRecord(value.mcp) && typeof value.mcp.url === \"string\" ? { url: value.mcp.url } : null;\n\n return {\n schemaVersion: 1,\n pid: value.pid,\n url: value.url,\n startedAt: typeof value.startedAt === \"string\" ? value.startedAt : \"\",\n devtools,\n mcp,\n };\n}\n\n/** The recorded state, or `undefined` when no dev server recorded one. */\nexport function readDevServerState(cwd = process.cwd()): DevServerState | undefined {\n const file = statePath(cwd);\n\n if (!existsSync(file)) return undefined;\n\n try {\n return parseDevServerState(JSON.parse(readFileSync(file, \"utf8\")));\n } catch {\n return undefined;\n }\n}\n\n/** Record the state atomically (temp file + rename), creating `.warlock/` when needed. */\nexport function writeDevServerState(state: DevServerState, cwd = process.cwd()): void {\n const file = statePath(cwd);\n const temporary = `${file}.${process.pid}.tmp`;\n\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(temporary, `${JSON.stringify(state, null, 2)}\\n`, \"utf8\");\n renameSync(temporary, file);\n}\n\n/** Merge fields into the recorded state; a no-op when there is none. */\nexport function updateDevServerState(\n patch: Partial<Omit<DevServerState, \"schemaVersion\">>,\n cwd = process.cwd(),\n): void {\n const current = readDevServerState(cwd);\n\n if (!current) return;\n\n writeDevServerState({ ...current, ...patch }, cwd);\n}\n\n/**\n * Remove the state file — only when it still belongs to `pid`, so a worker\n * that shuts down late never deletes the record of the worker that replaced it.\n */\nexport function removeDevServerState(pid = process.pid, cwd = process.cwd()): void {\n const current = readDevServerState(cwd);\n\n if (current && current.pid !== pid) return;\n\n rmSync(statePath(cwd), { force: true });\n}\n"],"mappings":";;;;;AAIA,MAAa,wBAAwB;AAwBrC,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UAAU,KAAqB;CACtC,OAAO,KAAK,KAAK,KAAK,qBAAqB;AAC7C;;AAGA,SAAgB,oBAAoB,OAA4C;CAC9E,IAAI,CAAC,SAAS,KAAK,KAAK,MAAM,kBAAkB,GAAG,OAAO;CAC1D,IAAI,OAAO,MAAM,QAAQ,YAAY,OAAO,MAAM,QAAQ,UAAU,OAAO;CAE3E,MAAM,WACJ,SAAS,MAAM,QAAQ,KAAK,OAAO,MAAM,SAAS,SAAS,WACvD,EAAE,MAAM,MAAM,SAAS,KAAK,IAC5B;CACN,MAAM,MACJ,SAAS,MAAM,GAAG,KAAK,OAAO,MAAM,IAAI,QAAQ,WAAW,EAAE,KAAK,MAAM,IAAI,IAAI,IAAI;CAEtF,OAAO;EACL,eAAe;EACf,KAAK,MAAM;EACX,KAAK,MAAM;EACX,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;EACnE;EACA;CACF;AACF;;AAGA,SAAgB,mBAAmB,MAAM,QAAQ,IAAI,GAA+B;CAClF,MAAM,OAAO,UAAU,GAAG;CAE1B,IAAI,CAAC,WAAW,IAAI,GAAG,OAAO;CAE9B,IAAI;EACF,OAAO,oBAAoB,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC,CAAC;CACnE,QAAQ;EACN;CACF;AACF;;AAGA,SAAgB,oBAAoB,OAAuB,MAAM,QAAQ,IAAI,GAAS;CACpF,MAAM,OAAO,UAAU,GAAG;CAC1B,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,IAAI;CAEzC,UAAU,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;CACjD,cAAc,WAAW,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,EAAE,KAAK,MAAM;CACtE,WAAW,WAAW,IAAI;AAC5B;;AAGA,SAAgB,qBACd,OACA,MAAM,QAAQ,IAAI,GACZ;CACN,MAAM,UAAU,mBAAmB,GAAG;CAEtC,IAAI,CAAC,SAAS;CAEd,oBAAoB;EAAE,GAAG;EAAS,GAAG;CAAM,GAAG,GAAG;AACnD;;;;;AAMA,SAAgB,qBAAqB,MAAM,QAAQ,KAAK,MAAM,QAAQ,IAAI,GAAS;CACjF,MAAM,UAAU,mBAAmB,GAAG;CAEtC,IAAI,WAAW,QAAQ,QAAQ,KAAK;CAEpC,OAAO,UAAU,GAAG,GAAG,EAAE,OAAO,KAAK,CAAC;AACxC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//#region ../../packages/core/src/tooling/devtools/devtools-client.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* A client for the JSON API `@warlock.js/devtools` mounts on the running dev
|
|
4
|
+
* server (`GET <path>/api/requests`, `GET <path>/api/requests/:id`).
|
|
5
|
+
*
|
|
6
|
+
* Shapes are mirrored structurally rather than imported: devtools is an
|
|
7
|
+
* optional dev dependency, and this module must load without it.
|
|
8
|
+
*/
|
|
9
|
+
/** The devtools mount every app uses unless it wired devtools by hand. */
|
|
10
|
+
declare const DEFAULT_DEVTOOLS_PATH = "/__warlock";
|
|
11
|
+
/** The `fetch` this client calls; injectable for tests. */
|
|
12
|
+
type DevtoolsFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
13
|
+
/** One timed phase: `route.match`, `middleware` (with `attrs.name`), `validation`, `handler`. */
|
|
14
|
+
type DevtoolsPhaseRecord = {
|
|
15
|
+
name: string;
|
|
16
|
+
startedAt: number;
|
|
17
|
+
durationMs: number;
|
|
18
|
+
attrs?: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
/** The row `GET <path>/api/requests` returns. */
|
|
21
|
+
type DevtoolsRequestSummaryRecord = {
|
|
22
|
+
id: string;
|
|
23
|
+
method: string;
|
|
24
|
+
path: string;
|
|
25
|
+
route?: string;
|
|
26
|
+
status?: number;
|
|
27
|
+
startedAt: number;
|
|
28
|
+
durationMs?: number;
|
|
29
|
+
queryCount: number;
|
|
30
|
+
warningCount: number;
|
|
31
|
+
};
|
|
32
|
+
/** Everything devtools recorded for one request (`GET <path>/api/requests/:id`). */
|
|
33
|
+
type DevtoolsRequestRecord = {
|
|
34
|
+
id: string;
|
|
35
|
+
method: string;
|
|
36
|
+
path: string;
|
|
37
|
+
route?: string;
|
|
38
|
+
status?: number;
|
|
39
|
+
startedAt: number; /** Absent while the request is still in flight. */
|
|
40
|
+
durationMs?: number;
|
|
41
|
+
error?: string;
|
|
42
|
+
phases: DevtoolsPhaseRecord[]; /** Queries: `sql`/`collection`, `durationMs`, `shape`, `caller`, `error`. */
|
|
43
|
+
queries: Record<string, unknown>[];
|
|
44
|
+
cache: Record<string, unknown>[];
|
|
45
|
+
logs: Record<string, unknown>[];
|
|
46
|
+
mails: string[]; /** `{ type: "n+1", message, shape, count, caller }` entries. */
|
|
47
|
+
warnings: Record<string, unknown>[];
|
|
48
|
+
};
|
|
49
|
+
/** Where the dev server and its devtools API live. */
|
|
50
|
+
type DevtoolsEndpoint = {
|
|
51
|
+
/** The dev server origin, e.g. `http://localhost:2030`. */url: string; /** The devtools mount, e.g. `/__warlock`. */
|
|
52
|
+
devtoolsPath: string;
|
|
53
|
+
};
|
|
54
|
+
/** Options of {@link connectDevtools}. */
|
|
55
|
+
type ConnectDevtoolsOptions = {
|
|
56
|
+
/** Project root, where `.warlock/dev-server.json` is read. Default: `process.cwd()`. */cwd?: string; /** The dev server address; overrides the recorded one. */
|
|
57
|
+
url?: string; /** The devtools mount; overrides the recorded one. */
|
|
58
|
+
devtoolsPath?: string;
|
|
59
|
+
fetch?: DevtoolsFetch;
|
|
60
|
+
};
|
|
61
|
+
/** A connected devtools API. */
|
|
62
|
+
type DevtoolsClient = DevtoolsEndpoint & {
|
|
63
|
+
/** The summaries devtools holds, newest last (the order the collector keeps). */listRequests(): Promise<DevtoolsRequestSummaryRecord[]>; /** One request's full record, or `undefined` when devtools does not hold it. */
|
|
64
|
+
getRequest(id: string): Promise<DevtoolsRequestRecord | undefined>;
|
|
65
|
+
/**
|
|
66
|
+
* Poll until the request is recorded AND settled (`durationMs` set), or the
|
|
67
|
+
* timeout passes. On timeout, resolves the last record seen (still without
|
|
68
|
+
* `durationMs`), or `undefined` when devtools never recorded the request.
|
|
69
|
+
*/
|
|
70
|
+
waitForRequest(id: string, options?: {
|
|
71
|
+
timeoutMs?: number;
|
|
72
|
+
intervalMs?: number;
|
|
73
|
+
}): Promise<DevtoolsRequestRecord | undefined>;
|
|
74
|
+
};
|
|
75
|
+
/** Narrow one summary row; `undefined` when it is not one. */
|
|
76
|
+
declare function parseRequestSummary(value: unknown): DevtoolsRequestSummaryRecord | undefined;
|
|
77
|
+
/** Narrow a full request record; `undefined` when it is not one. */
|
|
78
|
+
declare function parseRequestRecord(value: unknown): DevtoolsRequestRecord | undefined;
|
|
79
|
+
/** Where the dev server is: the explicit option, else `.warlock/dev-server.json`. Throws `WL8008`. */
|
|
80
|
+
declare function resolveDevServerEndpoint(options?: ConnectDevtoolsOptions): DevtoolsEndpoint;
|
|
81
|
+
/**
|
|
82
|
+
* Connect to the devtools API of the running dev server.
|
|
83
|
+
*
|
|
84
|
+
* Throws `WL8008` when no dev server is recorded or it does not answer, and
|
|
85
|
+
* `WL8009` when it answers but devtools is not mounted (404, or anything that
|
|
86
|
+
* is not the devtools JSON).
|
|
87
|
+
*/
|
|
88
|
+
declare function connectDevtools(options?: ConnectDevtoolsOptions): Promise<DevtoolsClient>;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { ConnectDevtoolsOptions, DEFAULT_DEVTOOLS_PATH, DevtoolsClient, DevtoolsEndpoint, DevtoolsFetch, DevtoolsPhaseRecord, DevtoolsRequestRecord, DevtoolsRequestSummaryRecord, connectDevtools, parseRequestRecord, parseRequestSummary, resolveDevServerEndpoint };
|
|
91
|
+
//# sourceMappingURL=devtools-client.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devtools-client.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/devtools/devtools-client.ts"],"mappings":";;AAYA;;;;AAAkC;AAGlC;;cAHa,qBAAA;;KAGD,aAAA,IAAiB,KAAA,UAAe,IAAA,GAAO,WAAA,KAAgB,OAAA,CAAQ,QAAA;;KAG/D,mBAAA;EACV,IAAA;EACA,SAAA;EACA,UAAA;EACA,KAAA,GAAQ,MAAM;AAAA;;KAIJ,4BAAA;EACV,EAAA;EACA,MAAA;EACA,IAAA;EACA,KAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,UAAA;EACA,YAAA;AAAA;;KAIU,qBAAA;EACV,EAAA;EACA,MAAA;EACA,IAAA;EACA,KAAA;EACA,MAAA;EACA,SAAA,UAhBA;EAkBA,UAAA;EACA,KAAA;EACA,MAAA,EAAQ,mBAAA,IAhBR;EAkBA,OAAA,EAAS,MAAA;EACT,KAAA,EAAO,MAAA;EACP,IAAA,EAAM,MAAA;EACN,KAAA,YAfU;EAiBV,QAAA,EAAU,MAAA;AAAA;;KAIA,gBAAA;EARH,2DAUP,GAAA,UANU;EAQV,YAAY;AAAA;;KAIF,sBAAA;EA1BV,wFA4BA,GAAA,WA1BA;EA4BA,GAAA,WAzBA;EA2BA,YAAA;EACA,KAAA,GAAQ,aAAa;AAAA;;KAIX,cAAA,GAAiB,gBAAA;EA3B3B,iFA6BA,YAAA,IAAgB,OAAA,CAAQ,4BAAA,KA5BxB;EA8BA,UAAA,CAAW,EAAA,WAAa,OAAA,CAAQ,qBAAA;EA7BhC;;;;AAEgB;EAiChB,cAAA,CACE,EAAA,UACA,OAAA;IAAY,SAAA;IAAoB,UAAA;EAAA,IAC/B,OAAA,CAAQ,qBAAA;AAAA;AAxBb;AAAA,iBA4CgB,mBAAA,CAAoB,KAAA,YAAiB,4BAA4B;;iBAmBjE,kBAAA,CAAmB,KAAA,YAAiB,qBAAqB;;iBAsDzD,wBAAA,CAAyB,OAAA,GAAS,sBAAA,GAA8B,gBAAgB;;;;;AA9GzE;AAIvB;;iBAmIsB,eAAA,CACpB,OAAA,GAAS,sBAAA,GACR,OAAA,CAAQ,cAAA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { WarlockError } from "../../errors/warlock-error.mjs";
|
|
2
|
+
import { DEV_SERVER_STATE_FILE, readDevServerState } from "../dev-state/dev-server-state.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../../packages/core/src/tooling/devtools/devtools-client.ts
|
|
5
|
+
/**
|
|
6
|
+
* A client for the JSON API `@warlock.js/devtools` mounts on the running dev
|
|
7
|
+
* server (`GET <path>/api/requests`, `GET <path>/api/requests/:id`).
|
|
8
|
+
*
|
|
9
|
+
* Shapes are mirrored structurally rather than imported: devtools is an
|
|
10
|
+
* optional dev dependency, and this module must load without it.
|
|
11
|
+
*/
|
|
12
|
+
/** The devtools mount every app uses unless it wired devtools by hand. */
|
|
13
|
+
const DEFAULT_DEVTOOLS_PATH = "/__warlock";
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
function records(value) {
|
|
18
|
+
return Array.isArray(value) ? value.filter(isRecord) : [];
|
|
19
|
+
}
|
|
20
|
+
function optionalNumber(value) {
|
|
21
|
+
return typeof value === "number" ? value : void 0;
|
|
22
|
+
}
|
|
23
|
+
function optionalString(value) {
|
|
24
|
+
return typeof value === "string" ? value : void 0;
|
|
25
|
+
}
|
|
26
|
+
/** Narrow one summary row; `undefined` when it is not one. */
|
|
27
|
+
function parseRequestSummary(value) {
|
|
28
|
+
if (!isRecord(value)) return void 0;
|
|
29
|
+
if (typeof value.id !== "string" || typeof value.method !== "string") return void 0;
|
|
30
|
+
if (typeof value.path !== "string") return void 0;
|
|
31
|
+
return {
|
|
32
|
+
id: value.id,
|
|
33
|
+
method: value.method,
|
|
34
|
+
path: value.path,
|
|
35
|
+
route: optionalString(value.route),
|
|
36
|
+
status: optionalNumber(value.status),
|
|
37
|
+
startedAt: optionalNumber(value.startedAt) ?? 0,
|
|
38
|
+
durationMs: optionalNumber(value.durationMs),
|
|
39
|
+
queryCount: optionalNumber(value.queryCount) ?? 0,
|
|
40
|
+
warningCount: optionalNumber(value.warningCount) ?? 0
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Narrow a full request record; `undefined` when it is not one. */
|
|
44
|
+
function parseRequestRecord(value) {
|
|
45
|
+
if (!isRecord(value)) return void 0;
|
|
46
|
+
if (typeof value.id !== "string" || typeof value.method !== "string") return void 0;
|
|
47
|
+
if (typeof value.path !== "string") return void 0;
|
|
48
|
+
const phases = records(value.phases).flatMap((phase) => typeof phase.name === "string" ? [{
|
|
49
|
+
name: phase.name,
|
|
50
|
+
startedAt: optionalNumber(phase.startedAt) ?? 0,
|
|
51
|
+
durationMs: optionalNumber(phase.durationMs) ?? 0,
|
|
52
|
+
...isRecord(phase.attrs) ? { attrs: phase.attrs } : {}
|
|
53
|
+
}] : []);
|
|
54
|
+
return {
|
|
55
|
+
id: value.id,
|
|
56
|
+
method: value.method,
|
|
57
|
+
path: value.path,
|
|
58
|
+
route: optionalString(value.route),
|
|
59
|
+
status: optionalNumber(value.status),
|
|
60
|
+
startedAt: optionalNumber(value.startedAt) ?? 0,
|
|
61
|
+
durationMs: optionalNumber(value.durationMs),
|
|
62
|
+
error: optionalString(value.error),
|
|
63
|
+
phases,
|
|
64
|
+
queries: records(value.queries),
|
|
65
|
+
cache: records(value.cache),
|
|
66
|
+
logs: records(value.logs),
|
|
67
|
+
mails: Array.isArray(value.mails) ? value.mails.filter((mail) => typeof mail === "string") : [],
|
|
68
|
+
warnings: records(value.warnings)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function errorMessage(error) {
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
const cause = error.cause;
|
|
74
|
+
const code = isRecord(cause) && typeof cause.code === "string" ? ` (${cause.code})` : "";
|
|
75
|
+
return `${error.message}${code}`;
|
|
76
|
+
}
|
|
77
|
+
return String(error);
|
|
78
|
+
}
|
|
79
|
+
function trimSlash(value) {
|
|
80
|
+
return value.replace(/\/+$/, "");
|
|
81
|
+
}
|
|
82
|
+
/** Where the dev server is: the explicit option, else `.warlock/dev-server.json`. Throws `WL8008`. */
|
|
83
|
+
function resolveDevServerEndpoint(options = {}) {
|
|
84
|
+
const state = options.url === void 0 ? readDevServerState(options.cwd) : void 0;
|
|
85
|
+
const url = options.url ?? state?.url;
|
|
86
|
+
if (!url) throw new WarlockError("WL8008", `No running dev server is recorded in ${DEV_SERVER_STATE_FILE}. Start \`warlock dev\` in this project, or pass --url.`);
|
|
87
|
+
const devtoolsPath = trimSlash(options.devtoolsPath ?? state?.devtools?.path ?? "/__warlock");
|
|
88
|
+
return {
|
|
89
|
+
url: trimSlash(url),
|
|
90
|
+
devtoolsPath
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Connect to the devtools API of the running dev server.
|
|
95
|
+
*
|
|
96
|
+
* Throws `WL8008` when no dev server is recorded or it does not answer, and
|
|
97
|
+
* `WL8009` when it answers but devtools is not mounted (404, or anything that
|
|
98
|
+
* is not the devtools JSON).
|
|
99
|
+
*/
|
|
100
|
+
async function connectDevtools(options = {}) {
|
|
101
|
+
const endpoint = resolveDevServerEndpoint(options);
|
|
102
|
+
const fetcher = options.fetch ?? ((input, init) => fetch(input, init));
|
|
103
|
+
const api = `${endpoint.url}${endpoint.devtoolsPath}/api`;
|
|
104
|
+
const getJson = async (url) => {
|
|
105
|
+
let response;
|
|
106
|
+
try {
|
|
107
|
+
response = await fetcher(url, { headers: { accept: "application/json" } });
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw new WarlockError("WL8008", `The dev server at ${endpoint.url} is not reachable: ${errorMessage(error)}. Start \`warlock dev\`, or pass --url.`, { cause: error });
|
|
110
|
+
}
|
|
111
|
+
const text = await response.text();
|
|
112
|
+
let body;
|
|
113
|
+
try {
|
|
114
|
+
body = text.length > 0 ? JSON.parse(text) : void 0;
|
|
115
|
+
} catch {
|
|
116
|
+
body = void 0;
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
status: response.status,
|
|
120
|
+
body
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
const probe = await getJson(`${api}/requests`);
|
|
124
|
+
if (probe.status !== 200 || !Array.isArray(probe.body)) throw new WarlockError("WL8009", `The dev server at ${endpoint.url} answered ${probe.status} on ${endpoint.devtoolsPath}/api/requests: devtools is not running there. Install it with \`warlock add devtools\` and restart \`warlock dev\`.`);
|
|
125
|
+
const client = {
|
|
126
|
+
...endpoint,
|
|
127
|
+
async listRequests() {
|
|
128
|
+
const { body } = await getJson(`${api}/requests`);
|
|
129
|
+
return Array.isArray(body) ? body.flatMap((row) => {
|
|
130
|
+
const summary = parseRequestSummary(row);
|
|
131
|
+
return summary ? [summary] : [];
|
|
132
|
+
}) : [];
|
|
133
|
+
},
|
|
134
|
+
async getRequest(id) {
|
|
135
|
+
const { status, body } = await getJson(`${api}/requests/${encodeURIComponent(id)}`);
|
|
136
|
+
return status === 200 ? parseRequestRecord(body) : void 0;
|
|
137
|
+
},
|
|
138
|
+
async waitForRequest(id, waitOptions = {}) {
|
|
139
|
+
const timeoutMs = waitOptions.timeoutMs ?? 5e3;
|
|
140
|
+
const intervalMs = waitOptions.intervalMs ?? 50;
|
|
141
|
+
const deadline = Date.now() + timeoutMs;
|
|
142
|
+
for (;;) {
|
|
143
|
+
const record = await client.getRequest(id);
|
|
144
|
+
if (record && record.durationMs !== void 0) return record;
|
|
145
|
+
if (Date.now() >= deadline) return record;
|
|
146
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
return client;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//#endregion
|
|
154
|
+
export { DEFAULT_DEVTOOLS_PATH, connectDevtools, parseRequestRecord, parseRequestSummary, resolveDevServerEndpoint };
|
|
155
|
+
//# sourceMappingURL=devtools-client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devtools-client.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/devtools/devtools-client.ts"],"sourcesContent":["import { WarlockError } from \"../../errors/warlock-error\";\nimport { DEV_SERVER_STATE_FILE, readDevServerState } from \"../dev-state/dev-server-state\";\n\n/**\n * A client for the JSON API `@warlock.js/devtools` mounts on the running dev\n * server (`GET <path>/api/requests`, `GET <path>/api/requests/:id`).\n *\n * Shapes are mirrored structurally rather than imported: devtools is an\n * optional dev dependency, and this module must load without it.\n */\n\n/** The devtools mount every app uses unless it wired devtools by hand. */\nexport const DEFAULT_DEVTOOLS_PATH = \"/__warlock\";\n\n/** The `fetch` this client calls; injectable for tests. */\nexport type DevtoolsFetch = (input: string, init?: RequestInit) => Promise<Response>;\n\n/** One timed phase: `route.match`, `middleware` (with `attrs.name`), `validation`, `handler`. */\nexport type DevtoolsPhaseRecord = {\n name: string;\n startedAt: number;\n durationMs: number;\n attrs?: Record<string, unknown>;\n};\n\n/** The row `GET <path>/api/requests` returns. */\nexport type DevtoolsRequestSummaryRecord = {\n id: string;\n method: string;\n path: string;\n route?: string;\n status?: number;\n startedAt: number;\n durationMs?: number;\n queryCount: number;\n warningCount: number;\n};\n\n/** Everything devtools recorded for one request (`GET <path>/api/requests/:id`). */\nexport type DevtoolsRequestRecord = {\n id: string;\n method: string;\n path: string;\n route?: string;\n status?: number;\n startedAt: number;\n /** Absent while the request is still in flight. */\n durationMs?: number;\n error?: string;\n phases: DevtoolsPhaseRecord[];\n /** Queries: `sql`/`collection`, `durationMs`, `shape`, `caller`, `error`. */\n queries: Record<string, unknown>[];\n cache: Record<string, unknown>[];\n logs: Record<string, unknown>[];\n mails: string[];\n /** `{ type: \"n+1\", message, shape, count, caller }` entries. */\n warnings: Record<string, unknown>[];\n};\n\n/** Where the dev server and its devtools API live. */\nexport type DevtoolsEndpoint = {\n /** The dev server origin, e.g. `http://localhost:2030`. */\n url: string;\n /** The devtools mount, e.g. `/__warlock`. */\n devtoolsPath: string;\n};\n\n/** Options of {@link connectDevtools}. */\nexport type ConnectDevtoolsOptions = {\n /** Project root, where `.warlock/dev-server.json` is read. Default: `process.cwd()`. */\n cwd?: string;\n /** The dev server address; overrides the recorded one. */\n url?: string;\n /** The devtools mount; overrides the recorded one. */\n devtoolsPath?: string;\n fetch?: DevtoolsFetch;\n};\n\n/** A connected devtools API. */\nexport type DevtoolsClient = DevtoolsEndpoint & {\n /** The summaries devtools holds, newest last (the order the collector keeps). */\n listRequests(): Promise<DevtoolsRequestSummaryRecord[]>;\n /** One request's full record, or `undefined` when devtools does not hold it. */\n getRequest(id: string): Promise<DevtoolsRequestRecord | undefined>;\n /**\n * Poll until the request is recorded AND settled (`durationMs` set), or the\n * timeout passes. On timeout, resolves the last record seen (still without\n * `durationMs`), or `undefined` when devtools never recorded the request.\n */\n waitForRequest(\n id: string,\n options?: { timeoutMs?: number; intervalMs?: number },\n ): Promise<DevtoolsRequestRecord | undefined>;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction records(value: unknown): Record<string, unknown>[] {\n return Array.isArray(value) ? value.filter(isRecord) : [];\n}\n\nfunction optionalNumber(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\n/** Narrow one summary row; `undefined` when it is not one. */\nexport function parseRequestSummary(value: unknown): DevtoolsRequestSummaryRecord | undefined {\n if (!isRecord(value)) return undefined;\n if (typeof value.id !== \"string\" || typeof value.method !== \"string\") return undefined;\n if (typeof value.path !== \"string\") return undefined;\n\n return {\n id: value.id,\n method: value.method,\n path: value.path,\n route: optionalString(value.route),\n status: optionalNumber(value.status),\n startedAt: optionalNumber(value.startedAt) ?? 0,\n durationMs: optionalNumber(value.durationMs),\n queryCount: optionalNumber(value.queryCount) ?? 0,\n warningCount: optionalNumber(value.warningCount) ?? 0,\n };\n}\n\n/** Narrow a full request record; `undefined` when it is not one. */\nexport function parseRequestRecord(value: unknown): DevtoolsRequestRecord | undefined {\n if (!isRecord(value)) return undefined;\n if (typeof value.id !== \"string\" || typeof value.method !== \"string\") return undefined;\n if (typeof value.path !== \"string\") return undefined;\n\n const phases: DevtoolsPhaseRecord[] = records(value.phases).flatMap((phase) =>\n typeof phase.name === \"string\"\n ? [\n {\n name: phase.name,\n startedAt: optionalNumber(phase.startedAt) ?? 0,\n durationMs: optionalNumber(phase.durationMs) ?? 0,\n ...(isRecord(phase.attrs) ? { attrs: phase.attrs } : {}),\n },\n ]\n : [],\n );\n\n return {\n id: value.id,\n method: value.method,\n path: value.path,\n route: optionalString(value.route),\n status: optionalNumber(value.status),\n startedAt: optionalNumber(value.startedAt) ?? 0,\n durationMs: optionalNumber(value.durationMs),\n error: optionalString(value.error),\n phases,\n queries: records(value.queries),\n cache: records(value.cache),\n logs: records(value.logs),\n mails: Array.isArray(value.mails)\n ? value.mails.filter((mail): mail is string => typeof mail === \"string\")\n : [],\n warnings: records(value.warnings),\n };\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n const cause = error.cause;\n const code = isRecord(cause) && typeof cause.code === \"string\" ? ` (${cause.code})` : \"\";\n\n return `${error.message}${code}`;\n }\n\n return String(error);\n}\n\nfunction trimSlash(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\n/** Where the dev server is: the explicit option, else `.warlock/dev-server.json`. Throws `WL8008`. */\nexport function resolveDevServerEndpoint(options: ConnectDevtoolsOptions = {}): DevtoolsEndpoint {\n const state = options.url === undefined ? readDevServerState(options.cwd) : undefined;\n const url = options.url ?? state?.url;\n\n if (!url) {\n throw new WarlockError(\n \"WL8008\",\n `No running dev server is recorded in ${DEV_SERVER_STATE_FILE}. Start \\`warlock dev\\` in this project, or pass --url.`,\n );\n }\n\n const devtoolsPath = trimSlash(\n options.devtoolsPath ?? state?.devtools?.path ?? DEFAULT_DEVTOOLS_PATH,\n );\n\n return { url: trimSlash(url), devtoolsPath };\n}\n\n/**\n * Connect to the devtools API of the running dev server.\n *\n * Throws `WL8008` when no dev server is recorded or it does not answer, and\n * `WL8009` when it answers but devtools is not mounted (404, or anything that\n * is not the devtools JSON).\n */\nexport async function connectDevtools(\n options: ConnectDevtoolsOptions = {},\n): Promise<DevtoolsClient> {\n const endpoint = resolveDevServerEndpoint(options);\n const fetcher: DevtoolsFetch = options.fetch ?? ((input, init) => fetch(input, init));\n const api = `${endpoint.url}${endpoint.devtoolsPath}/api`;\n\n const getJson = async (url: string): Promise<{ status: number; body: unknown }> => {\n let response: Response;\n\n try {\n response = await fetcher(url, { headers: { accept: \"application/json\" } });\n } catch (error) {\n throw new WarlockError(\n \"WL8008\",\n `The dev server at ${endpoint.url} is not reachable: ${errorMessage(error)}. Start \\`warlock dev\\`, or pass --url.`,\n { cause: error },\n );\n }\n\n const text = await response.text();\n let body: unknown;\n\n try {\n body = text.length > 0 ? JSON.parse(text) : undefined;\n } catch {\n body = undefined;\n }\n\n return { status: response.status, body };\n };\n\n const probe = await getJson(`${api}/requests`);\n\n if (probe.status !== 200 || !Array.isArray(probe.body)) {\n throw new WarlockError(\n \"WL8009\",\n `The dev server at ${endpoint.url} answered ${probe.status} on ${endpoint.devtoolsPath}/api/requests: devtools is not running there. Install it with \\`warlock add devtools\\` and restart \\`warlock dev\\`.`,\n );\n }\n\n const client: DevtoolsClient = {\n ...endpoint,\n async listRequests() {\n const { body } = await getJson(`${api}/requests`);\n\n return Array.isArray(body)\n ? body.flatMap((row) => {\n const summary = parseRequestSummary(row);\n return summary ? [summary] : [];\n })\n : [];\n },\n async getRequest(id) {\n const { status, body } = await getJson(`${api}/requests/${encodeURIComponent(id)}`);\n\n return status === 200 ? parseRequestRecord(body) : undefined;\n },\n async waitForRequest(id, waitOptions = {}) {\n const timeoutMs = waitOptions.timeoutMs ?? 5_000;\n const intervalMs = waitOptions.intervalMs ?? 50;\n const deadline = Date.now() + timeoutMs;\n\n for (;;) {\n const record = await client.getRequest(id);\n\n if (record && record.durationMs !== undefined) return record;\n if (Date.now() >= deadline) return record;\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n },\n };\n\n return client;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { GeneratorSpec } from "./generator-spec.mjs";
|
|
2
|
+
import { CliRunner } from "./run-cli.mjs";
|
|
3
|
+
|
|
4
|
+
//#region ../../packages/core/src/tooling/generate/generation.d.ts
|
|
5
|
+
/** The largest diff kept per file; a longer one is cut with a note. */
|
|
6
|
+
declare const MAX_FILE_DIFF_BYTES: number;
|
|
7
|
+
/** One file a generation creates, changes or removes. */
|
|
8
|
+
type GeneratedFile = {
|
|
9
|
+
/** Project-relative POSIX path. */path: string;
|
|
10
|
+
status: "created" | "modified" | "deleted"; /** Unified diff against the project's current content (`""` for a binary file). */
|
|
11
|
+
diff: string; /** Set when the file is binary; `diff` is then empty. */
|
|
12
|
+
binary?: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** What a generation would do (or did). */
|
|
15
|
+
type GenerationPlan = {
|
|
16
|
+
spec: GeneratorSpec; /** The argv that ran, starting with `warlock`. */
|
|
17
|
+
command: string[]; /** Whether the command exited 0. A failed run usually lists no files. */
|
|
18
|
+
ok: boolean;
|
|
19
|
+
exitCode: number | null;
|
|
20
|
+
files: GeneratedFile[]; /** The command's stdout and stderr, ANSI stripped and capped. */
|
|
21
|
+
output: string;
|
|
22
|
+
};
|
|
23
|
+
/** Options every backend accepts. */
|
|
24
|
+
type GenerationPlanOptions = {
|
|
25
|
+
/** Project root. Default: `process.cwd()`. */cwd?: string; /** Default {@link DEFAULT_GENERATION_TIMEOUT_MS}. */
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Computes what a generation would change without touching the project.
|
|
30
|
+
*
|
|
31
|
+
* The seam a native `warlock generate.* --dry-run --json` can implement later;
|
|
32
|
+
* {@link sandboxBackend} implements it by generating into a throwaway copy.
|
|
33
|
+
*/
|
|
34
|
+
type GenerationBackend = {
|
|
35
|
+
plan(spec: GeneratorSpec, options?: GenerationPlanOptions): Promise<GenerationPlan>;
|
|
36
|
+
};
|
|
37
|
+
/** Options of {@link sandboxBackend}. */
|
|
38
|
+
type SandboxBackendOptions = {
|
|
39
|
+
/** The `warlock` bin to run. Default: {@link resolveCliEntry}. */cliEntry?: string; /** How the CLI runs. Default: {@link spawnCli}. */
|
|
40
|
+
runner?: CliRunner; /** Where sandboxes are created. Default: `os.tmpdir()`. */
|
|
41
|
+
tempDirectory?: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* The sandbox {@link GenerationBackend}: copies the project's root files and
|
|
45
|
+
* `src/` tree (never `.env` files) into a temporary directory, links the
|
|
46
|
+
* project's `node_modules` into it, runs the real `warlock` command there,
|
|
47
|
+
* and reports every file that changed as a unified diff against the project.
|
|
48
|
+
* The project is never written; the sandbox is always removed.
|
|
49
|
+
*
|
|
50
|
+
* `add` runs with `--no-install`: package.json shows the dependencies it
|
|
51
|
+
* would record, and nothing is downloaded.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* const plan = await sandboxBackend().plan(
|
|
55
|
+
* { type: "make", generator: "service", name: "users/send-welcome" },
|
|
56
|
+
* { cwd: projectRoot },
|
|
57
|
+
* );
|
|
58
|
+
* plan.files.map((file) => `${file.status} ${file.path}`);
|
|
59
|
+
*/
|
|
60
|
+
declare function sandboxBackend(options?: SandboxBackendOptions): GenerationBackend;
|
|
61
|
+
/** Options of {@link applyGeneration}. */
|
|
62
|
+
type ApplyGenerationOptions = GenerationPlanOptions & {
|
|
63
|
+
/** The `warlock` bin to run. Default: {@link resolveCliEntry}. */cliEntry?: string; /** How the CLI runs. Default: {@link spawnCli}. */
|
|
64
|
+
runner?: CliRunner; /** For `add`: install the packages it records. Default `true`. */
|
|
65
|
+
install?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Run a generation in the real project and report what it changed, as a
|
|
69
|
+
* {@link GenerationPlan} whose diffs compare the files before and after.
|
|
70
|
+
*
|
|
71
|
+
* Only the generation scope (root files and `src/`, never `.env` files) is
|
|
72
|
+
* compared. This WRITES the project: `warlock mcp` exposes it only with
|
|
73
|
+
* `--allow-writes`.
|
|
74
|
+
*/
|
|
75
|
+
declare function applyGeneration(spec: GeneratorSpec, options?: ApplyGenerationOptions): Promise<GenerationPlan>;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { ApplyGenerationOptions, GeneratedFile, GenerationBackend, GenerationPlan, GenerationPlanOptions, MAX_FILE_DIFF_BYTES, SandboxBackendOptions, applyGeneration, sandboxBackend };
|
|
78
|
+
//# sourceMappingURL=generation.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/generate/generation.ts"],"mappings":";;;;;cAwBa,mBAAA;AAAb;AAAA,KAGY,aAAA;qCAEV,IAAA;EACA,MAAA,sCAHU;EAKV,IAAA;EAEA,MAAA;AAAA;;KAIU,cAAA;EACV,IAAA,EAAM,aAAA,EALA;EAON,OAAA,YAHU;EAKV,EAAA;EACA,QAAA;EACA,KAAA,EAAO,aAAa,IANpB;EAQA,MAAA;AAAA;;KAIU,qBAAA;EANV,8CAQA,GAAA,WANA;EAQA,SAAS;AAAA;AAJX;;;;AAIW;AASX;AAbA,KAaY,iBAAA;EACV,IAAA,CAAK,IAAA,EAAM,aAAA,EAAe,OAAA,GAAU,qBAAA,GAAwB,OAAA,CAAQ,cAAA;AAAA;;KAI1D,qBAAA;EAJkD,kEAM5D,QAAA,WANmE;EAQnE,MAAA,GAAS,SAAS,EARP;EAUX,aAAA;AAAA;;;;;AAVkF;AAIpF;;;;;;;;;AAMe;AA6Ef;;iBAAgB,cAAA,CAAe,OAAA,GAAS,qBAAA,GAA6B,iBAAiB;;KA2C1E,sBAAA,GAAyB,qBAAA;EA3CN,kEA6C7B,QAAA,WA7CoF;EA+CpF,MAAA,GAAS,SAAS,EAJR;EAMV,OAAA;AAAA;;;;;;;;AAAO;iBAWa,eAAA,CACpB,IAAA,EAAM,aAAA,EACN,OAAA,GAAS,sBAAA,GACR,OAAA,CAAQ,cAAA"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { buildGeneratorArgs } from "./generator-spec.mjs";
|
|
2
|
+
import { compareSnapshots, copyProjectScope, forEachSandboxFile, forEachScopedFile, isBinary, snapshotFiles } from "./project-files.mjs";
|
|
3
|
+
import { DEFAULT_GENERATION_TIMEOUT_MS, describeRun, resolveCliEntry, spawnCli } from "./run-cli.mjs";
|
|
4
|
+
import { unifiedDiff } from "./unified-diff.mjs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
|
|
9
|
+
//#region ../../packages/core/src/tooling/generate/generation.ts
|
|
10
|
+
/** The largest diff kept per file; a longer one is cut with a note. */
|
|
11
|
+
const MAX_FILE_DIFF_BYTES = 200 * 1024;
|
|
12
|
+
function readOrNull(file) {
|
|
13
|
+
return existsSync(file) ? readFileSync(file) : null;
|
|
14
|
+
}
|
|
15
|
+
function capDiff(diff) {
|
|
16
|
+
return diff.length > 204800 ? `${diff.slice(0, MAX_FILE_DIFF_BYTES)}\n… (diff truncated)\n` : diff;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Build the {@link GeneratedFile} for one change from the two contents, or
|
|
20
|
+
* `undefined` when they are byte-identical (a file rewritten unchanged).
|
|
21
|
+
*/
|
|
22
|
+
function describeChange(change, before, after) {
|
|
23
|
+
if (before !== null && after !== null && before.equals(after)) return void 0;
|
|
24
|
+
const status = before === null ? "created" : after === null ? "deleted" : "modified";
|
|
25
|
+
if (before && isBinary(before) || after && isBinary(after)) return {
|
|
26
|
+
path: change.path,
|
|
27
|
+
status,
|
|
28
|
+
diff: "",
|
|
29
|
+
binary: true
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
path: change.path,
|
|
33
|
+
status,
|
|
34
|
+
diff: capDiff(unifiedDiff({
|
|
35
|
+
path: change.path,
|
|
36
|
+
before: before === null ? null : before.toString("utf8"),
|
|
37
|
+
after: after === null ? null : after.toString("utf8")
|
|
38
|
+
}))
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function planFrom(spec, args, run, files) {
|
|
42
|
+
return {
|
|
43
|
+
spec,
|
|
44
|
+
command: ["warlock", ...args],
|
|
45
|
+
ok: run.exitCode === 0 && !run.timedOut,
|
|
46
|
+
exitCode: run.exitCode,
|
|
47
|
+
files,
|
|
48
|
+
output: describeRun(run)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The sandbox {@link GenerationBackend}: copies the project's root files and
|
|
53
|
+
* `src/` tree (never `.env` files) into a temporary directory, links the
|
|
54
|
+
* project's `node_modules` into it, runs the real `warlock` command there,
|
|
55
|
+
* and reports every file that changed as a unified diff against the project.
|
|
56
|
+
* The project is never written; the sandbox is always removed.
|
|
57
|
+
*
|
|
58
|
+
* `add` runs with `--no-install`: package.json shows the dependencies it
|
|
59
|
+
* would record, and nothing is downloaded.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const plan = await sandboxBackend().plan(
|
|
63
|
+
* { type: "make", generator: "service", name: "users/send-welcome" },
|
|
64
|
+
* { cwd: projectRoot },
|
|
65
|
+
* );
|
|
66
|
+
* plan.files.map((file) => `${file.status} ${file.path}`);
|
|
67
|
+
*/
|
|
68
|
+
function sandboxBackend(options = {}) {
|
|
69
|
+
const runner = options.runner ?? spawnCli;
|
|
70
|
+
return { async plan(spec, planOptions = {}) {
|
|
71
|
+
const cwd = path.resolve(planOptions.cwd ?? process.cwd());
|
|
72
|
+
const args = buildGeneratorArgs(spec, { install: false });
|
|
73
|
+
const sandbox = mkdtempSync(path.join(options.tempDirectory ?? os.tmpdir(), "warlock-generate-"));
|
|
74
|
+
try {
|
|
75
|
+
copyProjectScope(cwd, sandbox);
|
|
76
|
+
const before = snapshotFiles(sandbox, forEachSandboxFile);
|
|
77
|
+
return planFrom(spec, args, await runner({
|
|
78
|
+
entry: options.cliEntry ?? resolveCliEntry(),
|
|
79
|
+
args,
|
|
80
|
+
cwd: sandbox,
|
|
81
|
+
timeoutMs: planOptions.timeoutMs ?? 12e4
|
|
82
|
+
}), compareSnapshots(before, snapshotFiles(sandbox, forEachSandboxFile)).flatMap((change) => {
|
|
83
|
+
const file = describeChange(change, readOrNull(path.join(cwd, change.path)), change.status === "deleted" ? null : readOrNull(path.join(sandbox, change.path)));
|
|
84
|
+
return file ? [file] : [];
|
|
85
|
+
}));
|
|
86
|
+
} finally {
|
|
87
|
+
rmSync(sandbox, {
|
|
88
|
+
recursive: true,
|
|
89
|
+
force: true
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
} };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Run a generation in the real project and report what it changed, as a
|
|
96
|
+
* {@link GenerationPlan} whose diffs compare the files before and after.
|
|
97
|
+
*
|
|
98
|
+
* Only the generation scope (root files and `src/`, never `.env` files) is
|
|
99
|
+
* compared. This WRITES the project: `warlock mcp` exposes it only with
|
|
100
|
+
* `--allow-writes`.
|
|
101
|
+
*/
|
|
102
|
+
async function applyGeneration(spec, options = {}) {
|
|
103
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
104
|
+
const args = buildGeneratorArgs(spec, { install: options.install ?? true });
|
|
105
|
+
const contents = /* @__PURE__ */ new Map();
|
|
106
|
+
forEachScopedFile(cwd, (absolute, relative) => {
|
|
107
|
+
contents.set(relative, readFileSync(absolute));
|
|
108
|
+
});
|
|
109
|
+
const before = snapshotFiles(cwd, forEachScopedFile);
|
|
110
|
+
return planFrom(spec, args, await (options.runner ?? spawnCli)({
|
|
111
|
+
entry: options.cliEntry ?? resolveCliEntry(),
|
|
112
|
+
args,
|
|
113
|
+
cwd,
|
|
114
|
+
timeoutMs: options.timeoutMs ?? 12e4
|
|
115
|
+
}), compareSnapshots(before, snapshotFiles(cwd, forEachScopedFile)).flatMap((change) => {
|
|
116
|
+
const file = describeChange(change, contents.get(change.path) ?? null, change.status === "deleted" ? null : readOrNull(path.join(cwd, change.path)));
|
|
117
|
+
return file ? [file] : [];
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
export { MAX_FILE_DIFF_BYTES, applyGeneration, sandboxBackend };
|
|
123
|
+
//# sourceMappingURL=generation.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/tooling/generate/generation.ts"],"sourcesContent":["import { existsSync, mkdtempSync, readFileSync, rmSync } from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { buildGeneratorArgs, type GeneratorSpec } from \"./generator-spec\";\nimport {\n compareSnapshots,\n copyProjectScope,\n forEachSandboxFile,\n forEachScopedFile,\n isBinary,\n type SnapshotChange,\n snapshotFiles,\n} from \"./project-files\";\nimport {\n type CliRun,\n type CliRunner,\n DEFAULT_GENERATION_TIMEOUT_MS,\n describeRun,\n resolveCliEntry,\n spawnCli,\n} from \"./run-cli\";\nimport { unifiedDiff } from \"./unified-diff\";\n\n/** The largest diff kept per file; a longer one is cut with a note. */\nexport const MAX_FILE_DIFF_BYTES = 200 * 1024;\n\n/** One file a generation creates, changes or removes. */\nexport type GeneratedFile = {\n /** Project-relative POSIX path. */\n path: string;\n status: \"created\" | \"modified\" | \"deleted\";\n /** Unified diff against the project's current content (`\"\"` for a binary file). */\n diff: string;\n /** Set when the file is binary; `diff` is then empty. */\n binary?: boolean;\n};\n\n/** What a generation would do (or did). */\nexport type GenerationPlan = {\n spec: GeneratorSpec;\n /** The argv that ran, starting with `warlock`. */\n command: string[];\n /** Whether the command exited 0. A failed run usually lists no files. */\n ok: boolean;\n exitCode: number | null;\n files: GeneratedFile[];\n /** The command's stdout and stderr, ANSI stripped and capped. */\n output: string;\n};\n\n/** Options every backend accepts. */\nexport type GenerationPlanOptions = {\n /** Project root. Default: `process.cwd()`. */\n cwd?: string;\n /** Default {@link DEFAULT_GENERATION_TIMEOUT_MS}. */\n timeoutMs?: number;\n};\n\n/**\n * Computes what a generation would change without touching the project.\n *\n * The seam a native `warlock generate.* --dry-run --json` can implement later;\n * {@link sandboxBackend} implements it by generating into a throwaway copy.\n */\nexport type GenerationBackend = {\n plan(spec: GeneratorSpec, options?: GenerationPlanOptions): Promise<GenerationPlan>;\n};\n\n/** Options of {@link sandboxBackend}. */\nexport type SandboxBackendOptions = {\n /** The `warlock` bin to run. Default: {@link resolveCliEntry}. */\n cliEntry?: string;\n /** How the CLI runs. Default: {@link spawnCli}. */\n runner?: CliRunner;\n /** Where sandboxes are created. Default: `os.tmpdir()`. */\n tempDirectory?: string;\n};\n\nfunction readOrNull(file: string): Buffer | null {\n return existsSync(file) ? readFileSync(file) : null;\n}\n\nfunction capDiff(diff: string): string {\n return diff.length > MAX_FILE_DIFF_BYTES\n ? `${diff.slice(0, MAX_FILE_DIFF_BYTES)}\\n… (diff truncated)\\n`\n : diff;\n}\n\n/**\n * Build the {@link GeneratedFile} for one change from the two contents, or\n * `undefined` when they are byte-identical (a file rewritten unchanged).\n */\nfunction describeChange(\n change: SnapshotChange,\n before: Buffer | null,\n after: Buffer | null,\n): GeneratedFile | undefined {\n if (before !== null && after !== null && before.equals(after)) return undefined;\n\n const status: GeneratedFile[\"status\"] =\n before === null ? \"created\" : after === null ? \"deleted\" : \"modified\";\n\n if ((before && isBinary(before)) || (after && isBinary(after))) {\n return { path: change.path, status, diff: \"\", binary: true };\n }\n\n return {\n path: change.path,\n status,\n diff: capDiff(\n unifiedDiff({\n path: change.path,\n before: before === null ? null : before.toString(\"utf8\"),\n after: after === null ? null : after.toString(\"utf8\"),\n }),\n ),\n };\n}\n\nfunction planFrom(\n spec: GeneratorSpec,\n args: string[],\n run: CliRun,\n files: GeneratedFile[],\n): GenerationPlan {\n return {\n spec,\n command: [\"warlock\", ...args],\n ok: run.exitCode === 0 && !run.timedOut,\n exitCode: run.exitCode,\n files,\n output: describeRun(run),\n };\n}\n\n/**\n * The sandbox {@link GenerationBackend}: copies the project's root files and\n * `src/` tree (never `.env` files) into a temporary directory, links the\n * project's `node_modules` into it, runs the real `warlock` command there,\n * and reports every file that changed as a unified diff against the project.\n * The project is never written; the sandbox is always removed.\n *\n * `add` runs with `--no-install`: package.json shows the dependencies it\n * would record, and nothing is downloaded.\n *\n * @example\n * const plan = await sandboxBackend().plan(\n * { type: \"make\", generator: \"service\", name: \"users/send-welcome\" },\n * { cwd: projectRoot },\n * );\n * plan.files.map((file) => `${file.status} ${file.path}`);\n */\nexport function sandboxBackend(options: SandboxBackendOptions = {}): GenerationBackend {\n const runner = options.runner ?? spawnCli;\n\n return {\n async plan(spec, planOptions = {}) {\n const cwd = path.resolve(planOptions.cwd ?? process.cwd());\n const args = buildGeneratorArgs(spec, { install: false });\n const sandbox = mkdtempSync(\n path.join(options.tempDirectory ?? os.tmpdir(), \"warlock-generate-\"),\n );\n\n try {\n copyProjectScope(cwd, sandbox);\n\n const before = snapshotFiles(sandbox, forEachSandboxFile);\n const run = await runner({\n entry: options.cliEntry ?? resolveCliEntry(),\n args,\n cwd: sandbox,\n timeoutMs: planOptions.timeoutMs ?? DEFAULT_GENERATION_TIMEOUT_MS,\n });\n const after = snapshotFiles(sandbox, forEachSandboxFile);\n const files = compareSnapshots(before, after).flatMap((change) => {\n // Compared with the PROJECT, not the sandbox copy: a file outside the\n // copied scope that the project already has is a change, not a creation.\n const file = describeChange(\n change,\n readOrNull(path.join(cwd, change.path)),\n change.status === \"deleted\" ? null : readOrNull(path.join(sandbox, change.path)),\n );\n\n return file ? [file] : [];\n });\n\n return planFrom(spec, args, run, files);\n } finally {\n rmSync(sandbox, { recursive: true, force: true });\n }\n },\n };\n}\n\n/** Options of {@link applyGeneration}. */\nexport type ApplyGenerationOptions = GenerationPlanOptions & {\n /** The `warlock` bin to run. Default: {@link resolveCliEntry}. */\n cliEntry?: string;\n /** How the CLI runs. Default: {@link spawnCli}. */\n runner?: CliRunner;\n /** For `add`: install the packages it records. Default `true`. */\n install?: boolean;\n};\n\n/**\n * Run a generation in the real project and report what it changed, as a\n * {@link GenerationPlan} whose diffs compare the files before and after.\n *\n * Only the generation scope (root files and `src/`, never `.env` files) is\n * compared. This WRITES the project: `warlock mcp` exposes it only with\n * `--allow-writes`.\n */\nexport async function applyGeneration(\n spec: GeneratorSpec,\n options: ApplyGenerationOptions = {},\n): Promise<GenerationPlan> {\n const cwd = path.resolve(options.cwd ?? process.cwd());\n const args = buildGeneratorArgs(spec, { install: options.install ?? true });\n const contents = new Map<string, Buffer>();\n\n forEachScopedFile(cwd, (absolute, relative) => {\n contents.set(relative, readFileSync(absolute));\n });\n\n const before = snapshotFiles(cwd, forEachScopedFile);\n const run = await (options.runner ?? spawnCli)({\n entry: options.cliEntry ?? resolveCliEntry(),\n args,\n cwd,\n timeoutMs: options.timeoutMs ?? DEFAULT_GENERATION_TIMEOUT_MS,\n });\n const after = snapshotFiles(cwd, forEachScopedFile);\n const files = compareSnapshots(before, after).flatMap((change) => {\n const file = describeChange(\n change,\n contents.get(change.path) ?? null,\n change.status === \"deleted\" ? null : readOrNull(path.join(cwd, change.path)),\n );\n\n return file ? [file] : [];\n });\n\n return planFrom(spec, args, run, files);\n}\n"],"mappings":"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"}
|