vouchington-tooling 0.34.0 → 0.36.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/README.md +24 -221
- package/dist/agent-blackboard/feedback-audit-source.mjs +2 -2
- package/dist/agent-blackboard/feedback-canonical.mjs +1 -1
- package/dist/agent-blackboard/feedback-codec.mjs +3 -3
- package/dist/agent-blackboard/feedback-compose.mjs +5 -5
- package/dist/agent-blackboard/feedback-deadline.mjs +1 -1
- package/dist/agent-blackboard/feedback-delivery.mjs +6 -6
- package/dist/agent-blackboard/feedback-fields.mjs +1 -1
- package/dist/agent-blackboard/feedback-identity.mjs +3 -3
- package/dist/agent-blackboard/feedback-journal-audit.mjs +4 -4
- package/dist/agent-blackboard/feedback-journal-sandbox.mjs +1 -1
- package/dist/agent-blackboard/feedback-online-error.mjs +1 -1
- package/dist/agent-blackboard/feedback-online.mjs +7 -7
- package/dist/agent-blackboard/feedback-outbox-counts.mjs +2 -2
- package/dist/agent-blackboard/feedback-outbox.mjs +7 -7
- package/dist/agent-blackboard/index.mjs +13 -13
- package/dist/agent-blackboard/journal.mjs +3 -3
- package/dist/agent-blackboard/session-tools.mjs +4 -4
- package/dist/agent-blackboard/snapshot-cleanup-directory.mjs +3 -3
- package/dist/agent-blackboard/snapshot-cleanup-receipt.mjs +1 -1
- package/dist/agent-blackboard/snapshot-cleanup-resume.mjs +2 -2
- package/dist/agent-blackboard/snapshot-partition-cleanup.mjs +3 -3
- package/dist/agent-blackboard/snapshot-partition-format.mjs +3 -3
- package/dist/agent-blackboard/snapshot-partition-predicates.mjs +2 -2
- package/dist/agent-blackboard/snapshot-partition-read.mjs +2 -2
- package/dist/agent-blackboard/snapshot-partition-validate.mjs +2 -2
- package/dist/agent-blackboard/snapshot-partition-write.mjs +2 -2
- package/dist/agent-blackboard/snapshot-partitions.mjs +4 -4
- package/dist/agent-blackboard/snapshot.mjs +2 -2
- package/dist/agent-harness-identity/index.d.mts +1 -1
- package/dist/api-fixtures/fixture-contract-validation.mjs +1 -1
- package/dist/api-fixtures/index.mjs +3 -3
- package/dist/ast-grep-examples/companion-parity.mjs +1 -1
- package/dist/ast-grep-examples/index.mjs +1 -1
- package/dist/basic-auth-doc-sync/index.mjs +2 -2
- package/dist/basic-auth-doc-sync/runbook.mjs +4 -4
- package/dist/basic-auth-doc-sync/source.mjs +2 -2
- package/dist/browser-session-runner/attempt.mjs +5 -5
- package/dist/browser-session-runner/index.mjs +4 -4
- package/dist/browser-session-runner/output.mjs +1 -1
- package/dist/ci-local/index.mjs +2 -2
- package/dist/cli/commands/agent-blackboard-flags.mjs +1 -1
- package/dist/cli/commands/agent-blackboard.mjs +3 -3
- package/dist/cli/commands/ast-grep-examples.mjs +1 -1
- package/dist/cli/commands/ast-grep-pack.mjs +1 -1
- package/dist/cli/commands/gha-artifacts-cleanup.mjs +1 -1
- package/dist/cli/commands/gha-runtime-audit.mjs +1 -1
- package/dist/cli/commands/gha-workspace-policy.mjs +2 -2
- package/dist/cli/commands/http-origin.mjs +1 -1
- package/dist/cli/commands/link-skill.mjs +1 -1
- package/dist/cli/commands/mcp.mjs +2 -2
- package/dist/cli/commands/nuget-central-version.mjs +1 -1
- package/dist/cli/commands/pnpm-install.mjs +1 -1
- package/dist/cli/commands/prepare-vitest-reports.mjs +1 -1
- package/dist/cli/commands/require-up-to-date.mjs +1 -1
- package/dist/cli/commands/retrospective-facts.mjs +1 -1
- package/dist/cli/commands/retrospective-transcript.mjs +1 -1
- package/dist/cli/commands/runner-port-policy.mjs +1 -1
- package/dist/cli/commands/vitest-blob-manifest.mjs +1 -1
- package/dist/cli/commands/vitest-report-attempt.mjs +1 -1
- package/dist/cli/index.mjs +27 -27
- package/dist/cli/installed-version.mjs +1 -1
- package/dist/cli/parse-gha-runtime-audit.mjs +1 -1
- package/dist/cli/parse-options.mjs +2 -2
- package/dist/cli/parse.mjs +5 -5
- package/dist/compiler-build/index.mjs +3 -3
- package/dist/compiler-build/program.mjs +3 -3
- package/dist/config-inventory/collect.mjs +5 -5
- package/dist/config-inventory/dynamic-configs.mjs +1 -1
- package/dist/config-inventory/env-expression-readers.mjs +1 -1
- package/dist/config-inventory/env-prefix-readers.mjs +2 -2
- package/dist/config-inventory/env-var-accumulator.mjs +1 -1
- package/dist/config-inventory/env-vars.mjs +5 -5
- package/dist/config-inventory/index.mjs +2 -2
- package/dist/contract-schema/contract-schema-bounded-array.mjs +2 -2
- package/dist/contract-schema/contract-schema-extractor.mjs +3 -3
- package/dist/contract-schema/contract-schema-object-tuple.mjs +2 -2
- package/dist/contract-schema/contract-schema-type-extractor.mjs +5 -5
- package/dist/contract-schema/contract-schema-type-utils.mjs +2 -2
- package/dist/contract-schema/contract-schema-validator.mjs +1 -1
- package/dist/contract-schema/index.mjs +7 -7
- package/dist/contract-schema/type-query-call.mjs +3 -3
- package/dist/contract-schema/type-query.mjs +2 -2
- package/dist/contract-schema/virtual-program.mjs +1 -1
- package/dist/coverage-transport/control-v2-parse-object.mjs +2 -2
- package/dist/coverage-transport/control-v2.mjs +4 -4
- package/dist/coverage-transport/control.mjs +2 -2
- package/dist/coverage-transport/discovery.mjs +4 -4
- package/dist/coverage-transport/http.mjs +1 -1
- package/dist/coverage-transport/index.mjs +10 -10
- package/dist/coverage-transport/keys.mjs +1 -1
- package/dist/coverage-transport/lib.mjs +6 -6
- package/dist/coverage-transport/prefix-transfer.mjs +4 -4
- package/dist/coverage-transport/prefix.mjs +3 -3
- package/dist/coverage-transport/presign.mjs +1 -1
- package/dist/coverage-transport/vitest-blob-transport.mjs +2 -2
- package/dist/dependency-license-policy/collect.mjs +5 -5
- package/dist/dependency-license-policy/index.mjs +3 -3
- package/dist/dependency-license-policy/policy.mjs +1 -1
- package/dist/dependency-license-policy/workspace.mjs +1 -1
- package/dist/dockerfile-parse/index.mjs +2 -2
- package/dist/dockerfile-parse/prewarm-ports.mjs +1 -1
- package/dist/dockerfile-parse/runtime-cmd.mjs +2 -2
- package/dist/finite-enum-ripple/check.mjs +3 -3
- package/dist/finite-enum-ripple/compare.mjs +3 -5
- package/dist/finite-enum-ripple/component-paths.mjs +2 -2
- package/dist/finite-enum-ripple/configured-object-mutations.mjs +1 -1
- package/dist/finite-enum-ripple/create-page-jsx.mjs +1 -1
- package/dist/finite-enum-ripple/create-page-literals.mjs +4 -4
- package/dist/finite-enum-ripple/create-page-object-visitor.mjs +2 -2
- package/dist/finite-enum-ripple/create-page-properties.mjs +1 -1
- package/dist/finite-enum-ripple/index.mjs +1 -1
- package/dist/finite-enum-ripple/model.d.mts +4 -0
- package/dist/finite-enum-ripple/parser-support.mjs +16 -3
- package/dist/finite-enum-ripple/parsers.mjs +5 -3
- package/dist/finite-enum-ripple/structured-route-check.mjs +5 -5
- package/dist/finite-enum-ripple/types.mjs +3 -3
- package/dist/finite-enum-ripple/union-factory-check.mjs +2 -2
- package/dist/finite-enum-ripple/union-types.mjs +5 -5
- package/dist/gh-api-shell-quoting/index.mjs +2 -2
- package/dist/gh-api-shell-quoting/logical-line.mjs +1 -1
- package/dist/gh-api-shell-quoting/scan.mjs +1 -1
- package/dist/gh-api-shell-quoting/yaml.mjs +1 -1
- package/dist/gh-cli/index.mjs +4 -4
- package/dist/gha-artifacts-cleanup/commands.mjs +2 -2
- package/dist/gha-artifacts-cleanup/index.mjs +4 -4
- package/dist/gha-check-run/cli.mjs +2 -2
- package/dist/gha-check-run/index.mjs +2 -2
- package/dist/gha-claude-post-review/index.mjs +2 -2
- package/dist/gha-post-review/claude-token.d.mts +2 -2
- package/dist/gha-post-review/claude-token.mjs +1 -1
- package/dist/gha-post-review/cli.mjs +1 -1
- package/dist/gha-post-review/github.mjs +7 -7
- package/dist/gha-post-review/index.mjs +6 -6
- package/dist/gha-post-review/post.mjs +2 -2
- package/dist/gha-post-review/pull-io.mjs +1 -1
- package/dist/gha-post-review/token.mjs +1 -1
- package/dist/gha-pr-checkpoint/index.mjs +3 -3
- package/dist/gha-pr-checkpoint/resume.mjs +1 -1
- package/dist/gha-pr-checkpoint/update.mjs +1 -1
- package/dist/gha-review-payload/cli.mjs +2 -2
- package/dist/gha-review-payload/file.mjs +1 -1
- package/dist/gha-review-payload/index.mjs +4 -4
- package/dist/gha-review-payload/remap.mjs +1 -1
- package/dist/gha-runtime-audit/audit.mjs +4 -4
- package/dist/gha-runtime-audit/index.mjs +3 -3
- package/dist/gha-workspace-policy/docker-options.mjs +1 -1
- package/dist/gha-workspace-policy/docker-workspace-user.mjs +2 -2
- package/dist/gha-workspace-policy/index.mjs +3 -3
- package/dist/gha-workspace-policy/shell-tokens.mjs +1 -1
- package/dist/gha-workspace-policy/sparse-checkout.mjs +1 -1
- package/dist/github-projects/index.mjs +2 -2
- package/dist/github-projects/project-audit.mjs +1 -1
- package/dist/index.mjs +55 -55
- package/dist/markdown/content-facts.mjs +1 -1
- package/dist/markdown/document-sections.mjs +2 -2
- package/dist/markdown/html-blocks.mjs +1 -1
- package/dist/markdown/index.mjs +10 -10
- package/dist/markdown/sections.mjs +2 -2
- package/dist/markdown/tables.mjs +2 -2
- package/dist/markdown/tasks.mjs +1 -1
- package/dist/mcp-server/context.mjs +2 -2
- package/dist/mcp-server/dispatch.mjs +8 -8
- package/dist/mcp-server/git-fixture.test-helpers.mjs +1 -1
- package/dist/mcp-server/handlers-journal.mjs +4 -4
- package/dist/mcp-server/handlers-outbox.mjs +2 -2
- package/dist/mcp-server/handlers-session.mjs +3 -3
- package/dist/mcp-server/harness.test-helpers.mjs +4 -4
- package/dist/mcp-server/main.mjs +1 -1
- package/dist/mcp-server/run.mjs +3 -3
- package/dist/mcp-server/sdk.mjs +1 -1
- package/dist/mcp-server/server.mjs +2 -2
- package/dist/mcp-server/worktree.mjs +2 -2
- package/dist/nuget-central-version/cli.mjs +1 -1
- package/dist/openapi-document/build-openapi-catalog-sse.mjs +1 -1
- package/dist/openapi-document/build-openapi-document.mjs +8 -8
- package/dist/openapi-document/build-openapi-request.mjs +1 -1
- package/dist/openapi-document/build-openapi-response.mjs +3 -3
- package/dist/openapi-document/build-openapi-sse-events.mjs +1 -1
- package/dist/openapi-document/component-registry.mjs +1 -1
- package/dist/openapi-document/contract-schema-intersection-merge.mjs +1 -1
- package/dist/openapi-document/contract-schema-to-openapi.mjs +1 -1
- package/dist/openapi-document/index.mjs +12 -12
- package/dist/openapi-document/openapi-route-helpers.mjs +1 -1
- package/dist/pg-schema-snapshot/build-snapshot.mjs +3 -3
- package/dist/pg-schema-snapshot/catalog-objects.mjs +1 -1
- package/dist/pg-schema-snapshot/catalog-queries.mjs +4 -4
- package/dist/pg-schema-snapshot/catalog-table-constraints.mjs +1 -1
- package/dist/pg-schema-snapshot/catalog-table-indexes.mjs +1 -1
- package/dist/pg-schema-snapshot/catalog-tables.mjs +1 -1
- package/dist/pg-schema-snapshot/generate.mjs +5 -5
- package/dist/pg-schema-snapshot/index.mjs +6 -6
- package/dist/pg-schema-snapshot/markdown-files.mjs +1 -1
- package/dist/pg-schema-snapshot/render-markdown.mjs +1 -1
- package/dist/pg-schema-snapshot/table-snapshot-constraints.mjs +1 -1
- package/dist/pg-schema-snapshot/table-snapshot.mjs +3 -3
- package/dist/pnpm-deploy/index.mjs +3 -3
- package/dist/pnpm-deploy/restore.mjs +1 -1
- package/dist/pnpm-install/exec.mjs +1 -1
- package/dist/pnpm-install/index.mjs +8 -8
- package/dist/pnpm-install/install-operations.mjs +6 -6
- package/dist/pnpm-install/metadata-legacy.mjs +1 -1
- package/dist/pnpm-install/metadata.d.mts +1 -1
- package/dist/pnpm-install/metadata.mjs +2 -2
- package/dist/pnpm-install/native-health.mjs +2 -2
- package/dist/pnpm-install/pnpm-install-fixture.test-helpers.mjs +2 -2
- package/dist/pnpm-install/runner.mjs +7 -7
- package/dist/post-publication-inventory/index.d.mts +6 -0
- package/dist/post-publication-inventory/index.mjs +6 -2
- package/dist/post-publication-inventory/readers/compose-appends.d.mts +7 -0
- package/dist/post-publication-inventory/readers/compose-appends.mjs +38 -0
- package/dist/post-publication-inventory/readers/composes.d.mts +2 -0
- package/dist/post-publication-inventory/readers/composes.mjs +79 -0
- package/dist/post-publication-inventory/readers/composition.d.mts +2 -0
- package/dist/post-publication-inventory/readers/composition.mjs +62 -0
- package/dist/post-publication-inventory/readers/public-boundary-ast.d.mts +5 -0
- package/dist/post-publication-inventory/readers/public-boundary-ast.mjs +33 -0
- package/dist/post-publication-inventory/readers/public-boundary-consumed.d.mts +3 -0
- package/dist/post-publication-inventory/readers/public-boundary-consumed.mjs +39 -0
- package/dist/post-publication-inventory/readers/public-boundary-dataflow.d.mts +3 -0
- package/dist/post-publication-inventory/readers/public-boundary-dataflow.mjs +61 -0
- package/dist/post-publication-inventory/readers/public-boundary-then.d.mts +9 -0
- package/dist/post-publication-inventory/readers/public-boundary-then.mjs +31 -0
- package/dist/post-publication-inventory/readers/public-boundary.d.mts +3 -0
- package/dist/post-publication-inventory/readers/public-boundary.mjs +71 -0
- package/dist/post-publication-inventory/readers/public-view-ast.d.mts +6 -0
- package/dist/post-publication-inventory/readers/public-view-ast.mjs +67 -0
- package/dist/post-publication-inventory/readers/public-view-options.d.mts +8 -0
- package/dist/post-publication-inventory/readers/public-view-protection.d.mts +2 -0
- package/dist/post-publication-inventory/readers/public-view-protection.mjs +83 -0
- package/dist/post-publication-inventory/readers/public-view.d.mts +2 -0
- package/dist/post-publication-inventory/readers/public-view.mjs +117 -0
- package/dist/post-publication-inventory/readers/source-ast.d.mts +30 -0
- package/dist/post-publication-inventory/readers/source-ast.mjs +52 -0
- package/dist/post-publication-inventory/readers/source-executors.d.mts +4 -0
- package/dist/post-publication-inventory/readers/source-executors.mjs +38 -0
- package/dist/post-publication-inventory/readers/source-helpers.d.mts +16 -0
- package/dist/post-publication-inventory/readers/source-helpers.mjs +72 -0
- package/dist/post-publication-inventory/readers/source-options.d.mts +8 -0
- package/dist/post-publication-inventory/readers/source-sql.d.mts +3 -0
- package/dist/post-publication-inventory/readers/source-sql.mjs +17 -0
- package/dist/post-publication-inventory/readers/sql-executors.mjs +2 -2
- package/dist/post-publication-inventory/readers/sql-source.mjs +3 -3
- package/dist/post-publication-inventory/readers/sql-template.mjs +1 -1
- package/dist/post-publication-inventory/writers/source.mjs +1 -1
- package/dist/retrospective-facts/coverage.mjs +1 -1
- package/dist/retrospective-facts/foreign.mjs +3 -3
- package/dist/retrospective-facts/index.mjs +4 -4
- package/dist/retrospective-facts/local.mjs +4 -4
- package/dist/retrospective-transcript/claude-blocks.mjs +1 -1
- package/dist/retrospective-transcript/claude.mjs +2 -2
- package/dist/retrospective-transcript/codex-messages.mjs +1 -1
- package/dist/retrospective-transcript/codex-payload.mjs +2 -2
- package/dist/retrospective-transcript/codex-records.mjs +3 -3
- package/dist/retrospective-transcript/codex-segment.mjs +1 -1
- package/dist/retrospective-transcript/codex.mjs +2 -2
- package/dist/retrospective-transcript/index.mjs +9 -9
- package/dist/retrospective-transcript/resolve-transcript-file.mjs +2 -2
- package/dist/scc-complexity/baseline.mjs +2 -2
- package/dist/scc-complexity/index.mjs +8 -8
- package/dist/scc-complexity/parser.mjs +1 -1
- package/dist/scc-complexity/scope-config.mjs +1 -1
- package/dist/session-friction/audit-block.mjs +1 -1
- package/dist/session-friction/ci-failures.mjs +2 -2
- package/dist/session-friction/classify.mjs +2 -2
- package/dist/session-friction/coverage-ledger.mjs +1 -1
- package/dist/session-friction/index.mjs +5 -5
- package/dist/session-friction/log-file.mjs +2 -2
- package/dist/session-friction/log.mjs +7 -7
- package/dist/session-friction/normalize.mjs +1 -1
- package/dist/session-friction/report.mjs +5 -5
- package/dist/session-friction/sandbox.mjs +1 -1
- package/dist/session-friction/session-id.mjs +1 -1
- package/dist/shared-context/index.mjs +1 -1
- package/dist/skill-discovery/index.mjs +3 -3
- package/dist/sql-ast/add-column.mjs +1 -1
- package/dist/sql-ast/constraint-do-block.mjs +2 -2
- package/dist/sql-ast/constraint-shared.mjs +1 -1
- package/dist/sql-ast/constraint.mjs +4 -4
- package/dist/sql-ast/create-table.mjs +2 -2
- package/dist/sql-ast/drop-index.mjs +2 -2
- package/dist/sql-ast/implicit-indexes.mjs +1 -1
- package/dist/sql-ast/index-metadata.mjs +3 -3
- package/dist/sql-ast/index.mjs +8 -8
- package/dist/sql-scanner/comments.mjs +1 -1
- package/dist/sql-scanner/index.mjs +3 -3
- package/dist/sql-scanner/literals.mjs +1 -1
- package/dist/swift-semantic-equal/cli.mjs +1 -1
- package/dist/swift-semantic-equal/index.mjs +1 -1
- package/dist/transient-retry/index.mjs +2 -2
- package/dist/vitest-blob-manifest/cli.mjs +2 -2
- package/dist/vitest-blob-manifest/index.mjs +4 -4
- package/dist/vitest-blob-manifest/report-attempt-cli.mjs +2 -2
- package/dist/vitest-blob-manifest/report-attempt.mjs +1 -1
- package/dist/vitest-blob-manifest/reports-cli.mjs +3 -3
- package/dist/vitest-blob-manifest/reports-source.mjs +2 -2
- package/dist/vitest-blob-manifest/reports.mjs +2 -2
- package/dist/vitest-diagnostics/index.mjs +8 -8
- package/dist/vitest-diagnostics/vitest-fork-exit-records.mjs +1 -1
- package/dist/vitest-diagnostics/vitest-fork-exit-sentinel.mjs +2 -2
- package/dist/vitest-diagnostics/vitest-fork-leak-detection.mjs +2 -2
- package/dist/vitest-diagnostics/vitest-worker-exit-diagnostics-reporter.mjs +2 -2
- package/dist/workflow-policy/condition-entailment.mjs +1 -1
- package/dist/workflow-policy/index.d.mts +1 -3
- package/dist/workflow-policy/index.mjs +4 -6
- package/dist/workflow-policy/permission-inheritance.mjs +1 -1
- package/dist/workflow-policy/permission-mismatches.mjs +2 -2
- package/dist/workflow-policy/secret-readiness.mjs +2 -2
- package/dist/workflow-policy/types.d.mts +2 -28
- package/dist/workspace-gates/first-party-graph.mjs +2 -2
- package/dist/workspace-gates/index.mjs +1 -1
- package/dist/workspace-gates/manifest-version-assertions.mjs +2 -2
- package/dist/workspace-gates/manifest-version-parser.mjs +1 -1
- package/dist/workspace-gates/options.mjs +1 -1
- package/dist/workspace-gates/policy.mjs +7 -7
- package/dist/workspace-gates/test-helpers.d.mts +2 -2
- package/docs/workflow-and-compiler.md +7 -16
- package/package.json +3 -6
- package/dist/api-contract-discovery/header-contract-parser.d.mts +0 -3
- package/dist/api-contract-discovery/header-contract-parser.mjs +0 -93
- package/dist/api-contract-discovery/header-contract-registry.d.mts +0 -3
- package/dist/api-contract-discovery/header-contract-registry.mjs +0 -40
- package/dist/api-contract-discovery/header-contract-types.d.mts +0 -19
- package/dist/api-contract-discovery/index.d.mts +0 -34
- package/dist/api-contract-discovery/index.mjs +0 -27
- package/dist/api-contract-discovery/protocol-analysis-cache.d.mts +0 -21
- package/dist/api-contract-discovery/protocol-analysis-cache.mjs +0 -7
- package/dist/api-contract-discovery/protocol-body-status.d.mts +0 -2
- package/dist/api-contract-discovery/protocol-body-status.mjs +0 -4
- package/dist/api-contract-discovery/protocol-callback-argument-bindings.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-callback-argument-bindings.mjs +0 -33
- package/dist/api-contract-discovery/protocol-callback-invocation.d.mts +0 -6
- package/dist/api-contract-discovery/protocol-callback-invocation.mjs +0 -111
- package/dist/api-contract-discovery/protocol-callback-mutations.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-callback-mutations.mjs +0 -42
- package/dist/api-contract-discovery/protocol-callback-registration.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-callback-registration.mjs +0 -27
- package/dist/api-contract-discovery/protocol-callback-values.d.mts +0 -18
- package/dist/api-contract-discovery/protocol-callback-values.mjs +0 -114
- package/dist/api-contract-discovery/protocol-context-alias.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-context-alias.mjs +0 -20
- package/dist/api-contract-discovery/protocol-contract-extraction.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-contract-extraction.mjs +0 -87
- package/dist/api-contract-discovery/protocol-contract-keys.d.mts +0 -1
- package/dist/api-contract-discovery/protocol-contract-keys.mjs +0 -8
- package/dist/api-contract-discovery/protocol-contract-registry.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-contract-registry.mjs +0 -133
- package/dist/api-contract-discovery/protocol-executable-path.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-executable-path.mjs +0 -64
- package/dist/api-contract-discovery/protocol-execution-path.d.mts +0 -4
- package/dist/api-contract-discovery/protocol-execution-path.mjs +0 -16
- package/dist/api-contract-discovery/protocol-http-association.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-http-association.mjs +0 -108
- package/dist/api-contract-discovery/protocol-http-body-kinds.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-http-body-kinds.mjs +0 -19
- package/dist/api-contract-discovery/protocol-http-context-callers.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-http-context-callers.mjs +0 -40
- package/dist/api-contract-discovery/protocol-http-context-escapes.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-http-context-escapes.mjs +0 -95
- package/dist/api-contract-discovery/protocol-http-context.d.mts +0 -8
- package/dist/api-contract-discovery/protocol-http-context.mjs +0 -85
- package/dist/api-contract-discovery/protocol-http-emission.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-http-emission.mjs +0 -76
- package/dist/api-contract-discovery/protocol-http-implicit-taint.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-http-implicit-taint.mjs +0 -26
- package/dist/api-contract-discovery/protocol-http-method-access.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-http-method-access.mjs +0 -34
- package/dist/api-contract-discovery/protocol-http-method-mutations.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-http-method-mutations.mjs +0 -31
- package/dist/api-contract-discovery/protocol-http-reflect.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-http-reflect.mjs +0 -45
- package/dist/api-contract-discovery/protocol-http-registration.d.mts +0 -12
- package/dist/api-contract-discovery/protocol-http-registration.mjs +0 -53
- package/dist/api-contract-discovery/protocol-http-response-mutations.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-http-response-mutations.mjs +0 -31
- package/dist/api-contract-discovery/protocol-marker-analysis.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-marker-analysis.mjs +0 -50
- package/dist/api-contract-discovery/protocol-opaque-callback.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-opaque-callback.mjs +0 -107
- package/dist/api-contract-discovery/protocol-platform-callbacks.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-platform-callbacks.mjs +0 -76
- package/dist/api-contract-discovery/protocol-platform-mutation-targets.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-platform-mutation-targets.mjs +0 -89
- package/dist/api-contract-discovery/protocol-platform-writes.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-platform-writes.mjs +0 -92
- package/dist/api-contract-discovery/protocol-requested-keys.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-requested-keys.mjs +0 -45
- package/dist/api-contract-discovery/protocol-sse-callers.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-sse-callers.mjs +0 -67
- package/dist/api-contract-discovery/protocol-sse-emission.d.mts +0 -11
- package/dist/api-contract-discovery/protocol-sse-emission.mjs +0 -61
- package/dist/api-contract-discovery/protocol-sse-feasible-status.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-sse-feasible-status.mjs +0 -24
- package/dist/api-contract-discovery/protocol-sse-raw-writes.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-sse-raw-writes.mjs +0 -99
- package/dist/api-contract-discovery/protocol-sse-status.d.mts +0 -3
- package/dist/api-contract-discovery/protocol-sse-status.mjs +0 -84
- package/dist/api-contract-discovery/protocol-sse-write-access.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-sse-write-access.mjs +0 -42
- package/dist/api-contract-discovery/protocol-sse-write-helpers.d.mts +0 -7
- package/dist/api-contract-discovery/protocol-sse-write-helpers.mjs +0 -82
- package/dist/api-contract-discovery/protocol-sse-write-mutations.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-sse-write-mutations.mjs +0 -42
- package/dist/api-contract-discovery/protocol-sse-write-resolution.d.mts +0 -14
- package/dist/api-contract-discovery/protocol-sse-write-resolution.mjs +0 -79
- package/dist/api-contract-discovery/protocol-status-dominance.d.mts +0 -5
- package/dist/api-contract-discovery/protocol-status-dominance.mjs +0 -35
- package/dist/api-contract-discovery/protocol-write-receiver.d.mts +0 -9
- package/dist/api-contract-discovery/protocol-write-receiver.mjs +0 -79
- package/dist/api-contract-discovery/query-contract-extraction.d.mts +0 -3
- package/dist/api-contract-discovery/query-contract-extraction.mjs +0 -82
- package/dist/api-contract-discovery/query-contract-literals.d.mts +0 -13
- package/dist/api-contract-discovery/query-contract-literals.mjs +0 -83
- package/dist/api-contract-discovery/query-contract-registry.d.mts +0 -3
- package/dist/api-contract-discovery/query-contract-registry.mjs +0 -70
- package/dist/api-contract-discovery/query-contract-types.d.mts +0 -8
- package/dist/api-contract-discovery/registered-route-binding-writes.d.mts +0 -4
- package/dist/api-contract-discovery/registered-route-binding-writes.mjs +0 -47
- package/dist/api-contract-discovery/registered-route-catalog.d.mts +0 -10
- package/dist/api-contract-discovery/registered-route-catalog.mjs +0 -85
- package/dist/api-contract-discovery/registered-route-factory-returns.d.mts +0 -3
- package/dist/api-contract-discovery/registered-route-factory-returns.mjs +0 -29
- package/dist/api-contract-discovery/registered-route-handler-analysis.d.mts +0 -12
- package/dist/api-contract-discovery/registered-route-handler-analysis.mjs +0 -119
- package/dist/api-contract-discovery/registered-route-handler-helpers.d.mts +0 -3
- package/dist/api-contract-discovery/registered-route-handler-helpers.mjs +0 -16
- package/dist/api-contract-discovery/registered-route-runtime-parameters.d.mts +0 -3
- package/dist/api-contract-discovery/registered-route-runtime-parameters.mjs +0 -5
- package/dist/api-contract-discovery/registered-route-terminal-error.d.mts +0 -3
- package/dist/api-contract-discovery/registered-route-terminal-error.mjs +0 -98
- package/dist/api-contract-discovery/request-contract-implicit.d.mts +0 -17
- package/dist/api-contract-discovery/request-contract-implicit.mjs +0 -73
- package/dist/api-contract-discovery/request-contract-lenient.d.mts +0 -28
- package/dist/api-contract-discovery/request-contract-lenient.mjs +0 -59
- package/dist/api-contract-discovery/request-contract-registry.d.mts +0 -14
- package/dist/api-contract-discovery/request-contract-registry.mjs +0 -63
- package/dist/api-contract-discovery/request-contract-route-analysis.d.mts +0 -25
- package/dist/api-contract-discovery/request-contract-route-analysis.mjs +0 -68
- package/dist/api-contract-discovery/request-contract-types.d.mts +0 -12
- package/dist/api-contract-discovery/request-contract-types.mjs +0 -1
- package/dist/api-contract-discovery/request-validation-callbacks.d.mts +0 -9
- package/dist/api-contract-discovery/request-validation-callbacks.mjs +0 -27
- package/dist/api-contract-discovery/request-validation-checker.d.mts +0 -7
- package/dist/api-contract-discovery/request-validation-checker.mjs +0 -25
- package/dist/api-contract-discovery/request-validation-conditional.d.mts +0 -6
- package/dist/api-contract-discovery/request-validation-conditional.mjs +0 -31
- package/dist/api-contract-discovery/request-validation-factory-calls.d.mts +0 -11
- package/dist/api-contract-discovery/request-validation-factory-calls.mjs +0 -23
- package/dist/api-contract-discovery/request-validation-facts.d.mts +0 -16
- package/dist/api-contract-discovery/request-validation-facts.mjs +0 -64
- package/dist/api-contract-discovery/request-validation-follow.d.mts +0 -24
- package/dist/api-contract-discovery/request-validation-follow.mjs +0 -38
- package/dist/api-contract-discovery/request-validation-handler-state.d.mts +0 -8
- package/dist/api-contract-discovery/request-validation-handler-state.mjs +0 -35
- package/dist/api-contract-discovery/request-validation-input.d.mts +0 -12
- package/dist/api-contract-discovery/request-validation-input.mjs +0 -43
- package/dist/api-contract-discovery/request-validation-keys.d.mts +0 -25
- package/dist/api-contract-discovery/request-validation-keys.mjs +0 -119
- package/dist/api-contract-discovery/request-validation-match.d.mts +0 -11
- package/dist/api-contract-discovery/request-validation-match.mjs +0 -47
- package/dist/api-contract-discovery/request-validation-mutation.d.mts +0 -7
- package/dist/api-contract-discovery/request-validation-mutation.mjs +0 -80
- package/dist/api-contract-discovery/request-validation-origin.d.mts +0 -20
- package/dist/api-contract-discovery/request-validation-origin.mjs +0 -71
- package/dist/api-contract-discovery/request-validation-reads.d.mts +0 -13
- package/dist/api-contract-discovery/request-validation-reads.mjs +0 -88
- package/dist/api-contract-discovery/request-validation-registration.d.mts +0 -9
- package/dist/api-contract-discovery/request-validation-registration.mjs +0 -32
- package/dist/api-contract-discovery/request-validation-report.d.mts +0 -3
- package/dist/api-contract-discovery/request-validation-report.mjs +0 -21
- package/dist/api-contract-discovery/request-validation-request-origin.d.mts +0 -5
- package/dist/api-contract-discovery/request-validation-request-origin.mjs +0 -13
- package/dist/api-contract-discovery/request-validation-select.d.mts +0 -9
- package/dist/api-contract-discovery/request-validation-select.mjs +0 -36
- package/dist/api-contract-discovery/request-validation-sites.d.mts +0 -9
- package/dist/api-contract-discovery/request-validation-sites.mjs +0 -77
- package/dist/api-contract-discovery/request-validation-state-key.d.mts +0 -13
- package/dist/api-contract-discovery/request-validation-state-key.mjs +0 -30
- package/dist/api-contract-discovery/request-validation-trace-helpers.d.mts +0 -14
- package/dist/api-contract-discovery/request-validation-trace-helpers.mjs +0 -80
- package/dist/api-contract-discovery/request-validation-trace-select.d.mts +0 -23
- package/dist/api-contract-discovery/request-validation-trace-select.mjs +0 -45
- package/dist/api-contract-discovery/request-validation-trace.d.mts +0 -8
- package/dist/api-contract-discovery/request-validation-trace.mjs +0 -130
- package/dist/api-contract-discovery/request-validation-types.d.mts +0 -84
- package/dist/api-contract-discovery/request-validation-types.mjs +0 -1
- package/dist/api-contract-discovery/request-validation-walker.d.mts +0 -26
- package/dist/api-contract-discovery/request-validation-walker.mjs +0 -143
- package/dist/api-contract-discovery/request-validation.test-helpers.d.mts +0 -39
- package/dist/api-contract-discovery/request-validation.test-helpers.mjs +0 -108
- package/dist/api-contract-discovery/response-contract-attribution-facts.d.mts +0 -2
- package/dist/api-contract-discovery/response-contract-attribution-facts.mjs +0 -18
- package/dist/api-contract-discovery/response-contract-attribution.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-attribution.mjs +0 -23
- package/dist/api-contract-discovery/response-contract-call-classification.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-call-classification.mjs +0 -37
- package/dist/api-contract-discovery/response-contract-ctx-analysis.d.mts +0 -7
- package/dist/api-contract-discovery/response-contract-ctx-analysis.mjs +0 -28
- package/dist/api-contract-discovery/response-contract-error-branch.d.mts +0 -15
- package/dist/api-contract-discovery/response-contract-error-branch.mjs +0 -150
- package/dist/api-contract-discovery/response-contract-handler-bindings.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-handler-bindings.mjs +0 -126
- package/dist/api-contract-discovery/response-contract-handler-calls.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-handler-calls.mjs +0 -81
- package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.d.mts +0 -145
- package/dist/api-contract-discovery/response-contract-implicit-sources.test-helpers.mjs +0 -145
- package/dist/api-contract-discovery/response-contract-implicit-variants.d.mts +0 -2
- package/dist/api-contract-discovery/response-contract-implicit-variants.mjs +0 -6
- package/dist/api-contract-discovery/response-contract-implicit.d.mts +0 -6
- package/dist/api-contract-discovery/response-contract-implicit.mjs +0 -120
- package/dist/api-contract-discovery/response-contract-lenient.d.mts +0 -41
- package/dist/api-contract-discovery/response-contract-lenient.mjs +0 -52
- package/dist/api-contract-discovery/response-contract-media.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-media.mjs +0 -46
- package/dist/api-contract-discovery/response-contract-object-symbols.d.mts +0 -3
- package/dist/api-contract-discovery/response-contract-object-symbols.mjs +0 -80
- package/dist/api-contract-discovery/response-contract-property-mutations.d.mts +0 -5
- package/dist/api-contract-discovery/response-contract-property-mutations.mjs +0 -84
- package/dist/api-contract-discovery/response-contract-registration.d.mts +0 -11
- package/dist/api-contract-discovery/response-contract-registration.mjs +0 -65
- package/dist/api-contract-discovery/response-contract-registry.d.mts +0 -7
- package/dist/api-contract-discovery/response-contract-registry.mjs +0 -124
- package/dist/api-contract-discovery/response-contract-route-analysis.d.mts +0 -12
- package/dist/api-contract-discovery/response-contract-route-analysis.mjs +0 -65
- package/dist/api-contract-discovery/response-contract-route-syntax.d.mts +0 -7
- package/dist/api-contract-discovery/response-contract-route-syntax.mjs +0 -41
- package/dist/api-contract-discovery/response-contract-status.d.mts +0 -27
- package/dist/api-contract-discovery/response-contract-status.mjs +0 -82
- package/dist/api-contract-discovery/response-contract-symbols.d.mts +0 -5
- package/dist/api-contract-discovery/response-contract-symbols.mjs +0 -82
- package/dist/api-contract-discovery/response-contract-types.d.mts +0 -23
- package/dist/api-contract-discovery/response-contract-types.mjs +0 -1
- package/dist/api-contract-discovery/test-setup.test-helpers.d.mts +0 -3
- package/dist/api-contract-discovery/test-setup.test-helpers.mjs +0 -2
- package/dist/workflow-policy/concurrency-scope.d.mts +0 -4
- package/dist/workflow-policy/concurrency-scope.mjs +0 -66
- package/dist/workflow-policy/concurrency.d.mts +0 -10
- package/dist/workflow-policy/concurrency.mjs +0 -77
- package/dist/workflow-policy/graph.d.mts +0 -2
- package/dist/workflow-policy/graph.mjs +0 -138
- /package/dist/{api-contract-discovery/header-contract-types.mjs → post-publication-inventory/readers/public-view-options.mjs} +0 -0
- /package/dist/{api-contract-discovery/query-contract-types.mjs → post-publication-inventory/readers/source-options.mjs} +0 -0
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { registerPlatformCompilerLibraries } from './protocol-platform-callbacks.mjs';
|
|
3
|
-
import { extractQueryParameterDescriptor } from './query-contract-extraction.mjs';
|
|
4
|
-
import { contractError } from './response-contract-registration.mjs';
|
|
5
|
-
import { collectHandlerBindings, enclosingRouteBinding, visit, } from './response-contract-route-analysis.mjs';
|
|
6
|
-
export function discoverApiQueryContracts(program, sourceFiles, knownResponseRoutes) {
|
|
7
|
-
registerPlatformCompilerLibraries(program);
|
|
8
|
-
const checker = program.getTypeChecker();
|
|
9
|
-
const handlerBindings = collectHandlerBindings(sourceFiles, checker);
|
|
10
|
-
const contracts = new Map();
|
|
11
|
-
const knownOperations = new Set([...knownResponseRoutes].map((key) => key.split('#')[0]));
|
|
12
|
-
for (const sourceFile of sourceFiles) {
|
|
13
|
-
visit(sourceFile, (node) => {
|
|
14
|
-
if (!ts.isCallExpression(node) || !isApiQueryMarker(node.expression))
|
|
15
|
-
return;
|
|
16
|
-
const keyNode = node.arguments[0];
|
|
17
|
-
if (!keyNode || !ts.isStringLiteral(keyNode)) {
|
|
18
|
-
throw contractError(sourceFile, node, 'apiQuery requires a literal operation key');
|
|
19
|
-
}
|
|
20
|
-
const binding = enclosingRouteBinding(node, checker, handlerBindings);
|
|
21
|
-
if (!binding)
|
|
22
|
-
throw contractError(sourceFile, node, 'apiQuery must be inside an app.route handler');
|
|
23
|
-
const expectedKey = `${binding.method}:${binding.routeTemplate}`;
|
|
24
|
-
if (keyNode.text !== expectedKey) {
|
|
25
|
-
throw contractError(sourceFile, keyNode, `Query operation key "${keyNode.text}" does not match enclosing route ${expectedKey}`);
|
|
26
|
-
}
|
|
27
|
-
if (!knownOperations.has(expectedKey)) {
|
|
28
|
-
throw contractError(sourceFile, keyNode, `apiQuery references unknown response route ${expectedKey}`);
|
|
29
|
-
}
|
|
30
|
-
if (contracts.has(expectedKey)) {
|
|
31
|
-
throw contractError(sourceFile, keyNode, `Duplicate apiQuery marker for ${expectedKey}`);
|
|
32
|
-
}
|
|
33
|
-
if (node.arguments.length < 2) {
|
|
34
|
-
throw contractError(sourceFile, node, 'apiQuery requires at least one query contract carrier');
|
|
35
|
-
}
|
|
36
|
-
const parameters = Object.create(null);
|
|
37
|
-
for (const carrier of node.arguments.slice(1)) {
|
|
38
|
-
const carrierType = checker.getTypeAtLocation(carrier);
|
|
39
|
-
const queryContractSymbol = carrierType.getProperty('queryContract');
|
|
40
|
-
if (!queryContractSymbol || queryContractSymbol.flags & ts.SymbolFlags.Optional) {
|
|
41
|
-
throw contractError(sourceFile, carrier, 'apiQuery carrier requires a queryContract property');
|
|
42
|
-
}
|
|
43
|
-
const queryContractType = checker.getTypeOfSymbolAtLocation(queryContractSymbol, carrier);
|
|
44
|
-
if (queryContractType.getStringIndexType()) {
|
|
45
|
-
throw contractError(sourceFile, carrier, 'apiQuery queryContract keys must be literal names');
|
|
46
|
-
}
|
|
47
|
-
const properties = queryContractType.getProperties();
|
|
48
|
-
if (properties.length === 0) {
|
|
49
|
-
throw contractError(sourceFile, carrier, 'apiQuery queryContract must define parameters');
|
|
50
|
-
}
|
|
51
|
-
for (const property of properties) {
|
|
52
|
-
const name = property.getName();
|
|
53
|
-
if (property.flags & ts.SymbolFlags.Optional) {
|
|
54
|
-
throw contractError(sourceFile, carrier, `Query parameter "${name}" must not be optional`);
|
|
55
|
-
}
|
|
56
|
-
if (Object.hasOwn(parameters, name)) {
|
|
57
|
-
throw contractError(sourceFile, carrier, `Duplicate query parameter contract: ${name}`);
|
|
58
|
-
}
|
|
59
|
-
const descriptorType = checker.getTypeOfSymbolAtLocation(property, carrier);
|
|
60
|
-
parameters[name] = extractQueryParameterDescriptor(descriptorType, checker, sourceFile, carrier, name);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
contracts.set(expectedKey, { ...binding, parameters });
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return Object.fromEntries([...contracts.entries()].toSorted(([left], [right]) => left.localeCompare(right)));
|
|
67
|
-
}
|
|
68
|
-
function isApiQueryMarker(expression) {
|
|
69
|
-
return ts.isIdentifier(expression) && expression.text === 'apiQuery';
|
|
70
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { OpenApiQueryContract, OpenApiQueryParameter } from '../openapi-document/index.mts';
|
|
2
|
-
export type QueryParameterContract = OpenApiQueryParameter;
|
|
3
|
-
export type BackendQueryContract = {
|
|
4
|
-
method: string;
|
|
5
|
-
routeTemplate: string;
|
|
6
|
-
parameters: OpenApiQueryContract;
|
|
7
|
-
};
|
|
8
|
-
export type BackendQueryContractRegistry = Readonly<Record<string, BackendQueryContract>>;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
-
import type { ProtocolCache } from './protocol-analysis-cache.mts';
|
|
3
|
-
/** Helper and factory parameter bindings must remain unchanged in their declaring source. */
|
|
4
|
-
export declare function hasBindingWrite(declaration: ts.FunctionDeclaration | ts.ParameterDeclaration, checker: ts.TypeChecker, cache?: ProtocolCache): boolean;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
/** Every symbol assigned, updated, or looped over in the source file, found in one scan. */
|
|
3
|
-
function writtenSymbols(sourceFile, checker) {
|
|
4
|
-
const written = new Set();
|
|
5
|
-
const referencesBinding = (node) => {
|
|
6
|
-
// Index expressions and computed property names read their keys, not write them.
|
|
7
|
-
// inspect still visits these expressions separately to detect nested side-effect writes.
|
|
8
|
-
if (ts.isComputedPropertyName(node))
|
|
9
|
-
return;
|
|
10
|
-
if (ts.isElementAccessExpression(node)) {
|
|
11
|
-
referencesBinding(node.expression);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
if (ts.isIdentifier(node))
|
|
15
|
-
written.add(checker.getSymbolAtLocation(node));
|
|
16
|
-
node.forEachChild(referencesBinding);
|
|
17
|
-
};
|
|
18
|
-
const inspect = (node) => {
|
|
19
|
-
if (ts.isBinaryExpression(node) &&
|
|
20
|
-
node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
21
|
-
node.operatorToken.kind <= ts.SyntaxKind.LastAssignment)
|
|
22
|
-
referencesBinding(node.left);
|
|
23
|
-
if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) &&
|
|
24
|
-
(node.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
25
|
-
node.operator === ts.SyntaxKind.MinusMinusToken))
|
|
26
|
-
referencesBinding(node.operand);
|
|
27
|
-
if (ts.isForOfStatement(node) || ts.isForInStatement(node))
|
|
28
|
-
referencesBinding(node.initializer);
|
|
29
|
-
node.forEachChild(inspect);
|
|
30
|
-
};
|
|
31
|
-
inspect(sourceFile);
|
|
32
|
-
return written;
|
|
33
|
-
}
|
|
34
|
-
/** Helper and factory parameter bindings must remain unchanged in their declaring source. */
|
|
35
|
-
export function hasBindingWrite(declaration, checker, cache) {
|
|
36
|
-
if (!declaration.name)
|
|
37
|
-
return false;
|
|
38
|
-
if (!ts.isIdentifier(declaration.name))
|
|
39
|
-
return true;
|
|
40
|
-
const sourceFile = declaration.getSourceFile();
|
|
41
|
-
let written = cache?.writtenSymbols.get(sourceFile);
|
|
42
|
-
if (!written) {
|
|
43
|
-
written = writtenSymbols(sourceFile, checker);
|
|
44
|
-
cache?.writtenSymbols.set(sourceFile, written);
|
|
45
|
-
}
|
|
46
|
-
return written.has(checker.getSymbolAtLocation(declaration.name));
|
|
47
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
-
export type RegisteredRoute = {
|
|
3
|
-
method: string;
|
|
4
|
-
routeTemplate: string;
|
|
5
|
-
kind: 'ordinary' | 'sse' | 'error-only' | 'fixed-no-content';
|
|
6
|
-
fixedStatus?: number;
|
|
7
|
-
source: string;
|
|
8
|
-
};
|
|
9
|
-
export declare const routeShape: (routeTemplate: string) => string;
|
|
10
|
-
export declare function discoverRegisteredRoutes(program: ts.Program, sourceFiles: readonly ts.SourceFile[]): RegisteredRoute[];
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { handlerNodes } from './registered-route-handler-analysis.mjs';
|
|
3
|
-
import { isTerminal405Handler } from './registered-route-terminal-error.mjs';
|
|
4
|
-
import { propertyName, routeTemplateFromExpression, visit, } from './response-contract-route-analysis.mjs';
|
|
5
|
-
export const routeShape = (routeTemplate) => routeTemplate.replace(/:[^/]+/g, ':');
|
|
6
|
-
export function discoverRegisteredRoutes(program, sourceFiles) {
|
|
7
|
-
const checker = program.getTypeChecker();
|
|
8
|
-
const routes = [];
|
|
9
|
-
const registrations = new Map();
|
|
10
|
-
sourceFiles.forEach((sourceFile) => {
|
|
11
|
-
visit(sourceFile, (node) => {
|
|
12
|
-
if (!ts.isCallExpression(node))
|
|
13
|
-
return;
|
|
14
|
-
const method = propertyName(node.expression)?.toUpperCase();
|
|
15
|
-
if (!method || !['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(method))
|
|
16
|
-
return;
|
|
17
|
-
const routeTemplate = routeTemplateFromExpression(node.expression);
|
|
18
|
-
if (!routeTemplate)
|
|
19
|
-
return;
|
|
20
|
-
const key = `${method}:${routeShape(routeTemplate)}`;
|
|
21
|
-
const source = `${sourceFile.fileName}:${sourceFile.getLineAndCharacterOfPosition(node.getStart()).line + 1}`;
|
|
22
|
-
const classification = classifyHandler(node, checker, method, routeTemplate);
|
|
23
|
-
const route = {
|
|
24
|
-
method,
|
|
25
|
-
routeTemplate,
|
|
26
|
-
...classification,
|
|
27
|
-
source,
|
|
28
|
-
};
|
|
29
|
-
const existing = registrations.get(key);
|
|
30
|
-
if (existing)
|
|
31
|
-
throw new Error(`Duplicate registered API route ${key} at ${existing.source} and ${source}`);
|
|
32
|
-
registrations.set(key, route);
|
|
33
|
-
routes.push(route);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
return routes.toSorted((left, right) => `${left.method}:${left.routeTemplate}`.localeCompare(`${right.method}:${right.routeTemplate}`));
|
|
37
|
-
}
|
|
38
|
-
function classifyHandler(call, checker, method, routeTemplate) {
|
|
39
|
-
const nodes = call.arguments.flatMap((argument) => handlerNodes(argument, checker));
|
|
40
|
-
if (nodes.length === 0)
|
|
41
|
-
throw new Error(`Cannot inspect registered route handler ${method}:${routeTemplate}`);
|
|
42
|
-
let sse = false;
|
|
43
|
-
const proofGroups = call.arguments
|
|
44
|
-
.filter((argument) => !ts.isStringLiteral(argument))
|
|
45
|
-
.map((argument) => {
|
|
46
|
-
const proofs = [];
|
|
47
|
-
const nodes = handlerNodes(argument, checker, new Map(), new Set(), true, proofs);
|
|
48
|
-
return nodes.some(ts.isFunctionLike) ? proofs : [];
|
|
49
|
-
});
|
|
50
|
-
const error405 = proofGroups.length > 0 &&
|
|
51
|
-
proofGroups.every((handlers) => handlers.length > 0 &&
|
|
52
|
-
handlers.every((proof) => isTerminal405Handler(proof.node, checker, proof.bindings)));
|
|
53
|
-
let fixedStatus;
|
|
54
|
-
nodes.forEach((node) => {
|
|
55
|
-
visit(node, (child) => {
|
|
56
|
-
if (!ts.isCallExpression(child))
|
|
57
|
-
return;
|
|
58
|
-
if (ts.isIdentifier(child.expression) && child.expression.text === 'apiOpenApiNoContent') {
|
|
59
|
-
const [key, status] = child.arguments;
|
|
60
|
-
if (!key || !ts.isStringLiteral(key) || key.text !== `${method}:${routeTemplate}`)
|
|
61
|
-
throw new Error(`apiOpenApiNoContent key must match registered route ${method}:${routeTemplate}`);
|
|
62
|
-
if (!status || !ts.isNumericLiteral(status))
|
|
63
|
-
throw new Error('apiOpenApiNoContent status requires a numeric literal');
|
|
64
|
-
const value = Number(status.text);
|
|
65
|
-
if (fixedStatus !== undefined && fixedStatus !== value)
|
|
66
|
-
throw new Error(`Conflicting apiOpenApiNoContent statuses for ${method}:${routeTemplate}`);
|
|
67
|
-
fixedStatus = value;
|
|
68
|
-
}
|
|
69
|
-
if (ts.isIdentifier(child.expression) && child.expression.text === 'startSSE')
|
|
70
|
-
sse = true;
|
|
71
|
-
if (ts.isPropertyAccessExpression(child.expression) &&
|
|
72
|
-
child.expression.name.text === 'setType' &&
|
|
73
|
-
child.arguments[0] &&
|
|
74
|
-
ts.isStringLiteral(child.arguments[0]) &&
|
|
75
|
-
child.arguments[0].text.toLowerCase() === 'text/event-stream')
|
|
76
|
-
sse = true;
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
if (fixedStatus !== undefined) {
|
|
80
|
-
if (sse)
|
|
81
|
-
throw new Error(`apiOpenApiNoContent conflicts with SSE response handling for ${method}:${routeTemplate}`);
|
|
82
|
-
return { kind: 'fixed-no-content', fixedStatus };
|
|
83
|
-
}
|
|
84
|
-
return { kind: sse ? 'sse' : error405 ? 'error-only' : 'ordinary' };
|
|
85
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
export function returnedExpressions(declaration) {
|
|
3
|
-
const body = declaration.body;
|
|
4
|
-
if (!ts.isBlock(body))
|
|
5
|
-
return [body];
|
|
6
|
-
const returned = [];
|
|
7
|
-
const collect = (node) => {
|
|
8
|
-
if (node !== declaration && ts.isFunctionLike(node))
|
|
9
|
-
return;
|
|
10
|
-
if (ts.isReturnStatement(node)) {
|
|
11
|
-
returned.push(node.expression);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
node.forEachChild(collect);
|
|
15
|
-
};
|
|
16
|
-
body.forEachChild(collect);
|
|
17
|
-
return returned;
|
|
18
|
-
}
|
|
19
|
-
export function returnsOnEveryPath(node) {
|
|
20
|
-
if (ts.isBlock(node))
|
|
21
|
-
return node.statements.some(returnsOnEveryPath);
|
|
22
|
-
if (ts.isReturnStatement(node))
|
|
23
|
-
return true;
|
|
24
|
-
if (ts.isIfStatement(node))
|
|
25
|
-
return (!!node.elseStatement &&
|
|
26
|
-
returnsOnEveryPath(node.thenStatement) &&
|
|
27
|
-
returnsOnEveryPath(node.elseStatement));
|
|
28
|
-
return !ts.isStatement(node);
|
|
29
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
-
export type HandlerProof = {
|
|
3
|
-
node: ts.FunctionLikeDeclaration;
|
|
4
|
-
bindings: Map<ts.Symbol, ts.Expression>;
|
|
5
|
-
/** Set under `executableReturns` when a runtime branch selects the handler. */
|
|
6
|
-
conditional?: boolean;
|
|
7
|
-
};
|
|
8
|
-
export declare function handlerNodes(argument: ts.Expression, checker: ts.TypeChecker, parameterBindings?: Map<ts.Symbol, ts.Expression>, active?: Set<ts.Node>, staticProof?: boolean, proofs?: HandlerProof[],
|
|
9
|
-
/** Ignore `let`, `var` and reassigned bindings; always on under `staticProof`. */
|
|
10
|
-
stableBindings?: boolean,
|
|
11
|
-
/** Ignore returned values on statically dead paths, and mark runtime-branch ones conditional. */
|
|
12
|
-
executableReturns?: boolean): ts.Node[];
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { returnedExpressions, returnsOnEveryPath } from './registered-route-factory-returns.mjs';
|
|
3
|
-
import { runtimeParameters } from './registered-route-runtime-parameters.mjs';
|
|
4
|
-
import { potentiallyExecuted } from './protocol-executable-path.mjs';
|
|
5
|
-
import { hasBindingWrite } from './registered-route-binding-writes.mjs';
|
|
6
|
-
import { hasStableBinding, unwrapHandlerExpression } from './registered-route-handler-helpers.mjs';
|
|
7
|
-
import { isConditionalPosition } from './request-validation-conditional.mjs';
|
|
8
|
-
export function handlerNodes(argument, checker, parameterBindings = new Map(), active = new Set(), staticProof = false, proofs,
|
|
9
|
-
/** Ignore `let`, `var` and reassigned bindings; always on under `staticProof`. */
|
|
10
|
-
stableBindings = staticProof,
|
|
11
|
-
/** Ignore returned values on statically dead paths, and mark runtime-branch ones conditional. */
|
|
12
|
-
executableReturns = false) {
|
|
13
|
-
const again = (node, bindings = parameterBindings, seen = active, sink = proofs) => handlerNodes(node, checker, bindings, seen, staticProof, sink, stableBindings, executableReturns);
|
|
14
|
-
const unwrapped = unwrapHandlerExpression(argument);
|
|
15
|
-
if (unwrapped !== argument)
|
|
16
|
-
return again(unwrapped);
|
|
17
|
-
let bound = argument;
|
|
18
|
-
const boundIdentifiers = new Set();
|
|
19
|
-
while (ts.isIdentifier(bound)) {
|
|
20
|
-
const symbol = checker.getSymbolAtLocation(bound);
|
|
21
|
-
const nextArgument = symbol && parameterBindings.get(symbol);
|
|
22
|
-
if (!nextArgument)
|
|
23
|
-
break;
|
|
24
|
-
if (boundIdentifiers.has(bound))
|
|
25
|
-
return [];
|
|
26
|
-
boundIdentifiers.add(bound);
|
|
27
|
-
bound = nextArgument;
|
|
28
|
-
}
|
|
29
|
-
if (bound !== argument)
|
|
30
|
-
return again(bound);
|
|
31
|
-
if (active.has(argument))
|
|
32
|
-
return [];
|
|
33
|
-
const next = new Set(active).add(argument);
|
|
34
|
-
if (ts.isArrowFunction(argument) || ts.isFunctionExpression(argument)) {
|
|
35
|
-
proofs?.push({ node: argument, bindings: parameterBindings });
|
|
36
|
-
return [argument];
|
|
37
|
-
}
|
|
38
|
-
if (ts.isCallExpression(argument)) {
|
|
39
|
-
const resolvedProofs = [];
|
|
40
|
-
const groups = callableImplementations(argument.expression, checker, staticProof, stableBindings).map((implementation) => {
|
|
41
|
-
if (staticProof &&
|
|
42
|
-
(implementation.asteriskToken ||
|
|
43
|
-
implementation.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) ||
|
|
44
|
-
runtimeParameters(implementation).some((parameter) => hasBindingWrite(parameter, checker))))
|
|
45
|
-
return [];
|
|
46
|
-
const bindings = new Map(parameterBindings);
|
|
47
|
-
runtimeParameters(implementation).forEach((parameter, index) => {
|
|
48
|
-
const callArgument = argument.arguments[index];
|
|
49
|
-
const symbol = checker.getSymbolAtLocation(parameter.name);
|
|
50
|
-
if (callArgument && symbol)
|
|
51
|
-
bindings.set(symbol, callArgument);
|
|
52
|
-
});
|
|
53
|
-
const returned = returnedExpressions(implementation).filter((value) => !executableReturns || !value || potentiallyExecuted(value));
|
|
54
|
-
if (staticProof &&
|
|
55
|
-
(!returnsOnEveryPath(implementation.body) || returned.some((value) => !value)))
|
|
56
|
-
return [];
|
|
57
|
-
const results = returned.map((value) => {
|
|
58
|
-
const selected = [];
|
|
59
|
-
const found = value ? again(value, bindings, next, selected) : [];
|
|
60
|
-
if (executableReturns && value && isConditionalPosition(value))
|
|
61
|
-
selected.forEach((proof) => (proof.conditional = true));
|
|
62
|
-
resolvedProofs.push(...selected);
|
|
63
|
-
return found;
|
|
64
|
-
});
|
|
65
|
-
return staticProof && results.some((result) => !result.some(ts.isFunctionLike))
|
|
66
|
-
? []
|
|
67
|
-
: results.flat();
|
|
68
|
-
});
|
|
69
|
-
if (staticProof && groups.some((group) => group.length === 0))
|
|
70
|
-
return [];
|
|
71
|
-
proofs?.push(...resolvedProofs);
|
|
72
|
-
return groups.flat();
|
|
73
|
-
}
|
|
74
|
-
return declarationImplementations(argument, checker, next, staticProof, parameterBindings, proofs, stableBindings, executableReturns);
|
|
75
|
-
}
|
|
76
|
-
function callableImplementations(node, checker, staticProof = false, stableBindings = staticProof) {
|
|
77
|
-
const symbol = checker.getSymbolAtLocation(node);
|
|
78
|
-
if (!symbol)
|
|
79
|
-
return [];
|
|
80
|
-
const resolved = symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
81
|
-
const implementations = [];
|
|
82
|
-
for (const declaration of resolved.declarations ?? []) {
|
|
83
|
-
if (stableBindings && !hasStableBinding(declaration, checker))
|
|
84
|
-
continue;
|
|
85
|
-
if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
86
|
-
const initializer = unwrapHandlerExpression(declaration.initializer);
|
|
87
|
-
if (ts.isArrowFunction(initializer) || ts.isFunctionExpression(initializer))
|
|
88
|
-
implementations.push(initializer);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if ((ts.isFunctionDeclaration(declaration) ||
|
|
92
|
-
(!staticProof && ts.isMethodDeclaration(declaration))) &&
|
|
93
|
-
declaration.body)
|
|
94
|
-
implementations.push(declaration);
|
|
95
|
-
}
|
|
96
|
-
return implementations;
|
|
97
|
-
}
|
|
98
|
-
function declarationImplementations(node, checker, active, staticProof, parameterBindings, proofs, stableBindings = staticProof, executableReturns = false) {
|
|
99
|
-
const symbol = checker.getSymbolAtLocation(node);
|
|
100
|
-
if (!symbol)
|
|
101
|
-
return [];
|
|
102
|
-
const resolved = symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
103
|
-
return (resolved.declarations ?? []).flatMap((declaration) => {
|
|
104
|
-
if (stableBindings && !hasStableBinding(declaration, checker))
|
|
105
|
-
return [];
|
|
106
|
-
if (ts.isFunctionDeclaration(declaration) ||
|
|
107
|
-
(!staticProof && ts.isMethodDeclaration(declaration))) {
|
|
108
|
-
if (declaration.body)
|
|
109
|
-
proofs?.push({ node: declaration, bindings: parameterBindings });
|
|
110
|
-
return declaration.body ? [declaration] : [];
|
|
111
|
-
}
|
|
112
|
-
if (ts.isVariableDeclaration(declaration) && declaration.initializer)
|
|
113
|
-
return [
|
|
114
|
-
declaration,
|
|
115
|
-
...handlerNodes(declaration.initializer, checker, parameterBindings, active, staticProof, proofs, stableBindings, executableReturns),
|
|
116
|
-
];
|
|
117
|
-
return [];
|
|
118
|
-
});
|
|
119
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { hasBindingWrite } from './registered-route-binding-writes.mjs';
|
|
3
|
-
export function hasStableBinding(declaration, checker) {
|
|
4
|
-
if (ts.isVariableDeclaration(declaration))
|
|
5
|
-
return (ts.isVariableDeclarationList(declaration.parent) &&
|
|
6
|
-
!!(declaration.parent.flags & ts.NodeFlags.Const));
|
|
7
|
-
return !ts.isFunctionDeclaration(declaration) || !hasBindingWrite(declaration, checker);
|
|
8
|
-
}
|
|
9
|
-
export function unwrapHandlerExpression(node) {
|
|
10
|
-
while (ts.isParenthesizedExpression(node) ||
|
|
11
|
-
ts.isAsExpression(node) ||
|
|
12
|
-
ts.isTypeAssertionExpression(node) ||
|
|
13
|
-
ts.isSatisfiesExpression(node))
|
|
14
|
-
node = node.expression;
|
|
15
|
-
return node;
|
|
16
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
/** TypeScript's explicit this parameter is erased and consumes no runtime argument. */
|
|
3
|
-
export function runtimeParameters(node) {
|
|
4
|
-
return node.parameters.filter((parameter) => !ts.isIdentifier(parameter.name) || parameter.name.text !== 'this');
|
|
5
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
-
/** Proves a terminal 405 on the handler's own context, rather than finding a nested throw. */
|
|
3
|
-
export declare function isTerminal405Handler(node: ts.Node, checker: ts.TypeChecker, bindings?: Map<ts.Symbol, ts.Expression>): boolean;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { runtimeParameters } from './registered-route-runtime-parameters.mjs';
|
|
3
|
-
import { handlerNodes } from './registered-route-handler-analysis.mjs';
|
|
4
|
-
/** Proves a terminal 405 on the handler's own context, rather than finding a nested throw. */
|
|
5
|
-
export function isTerminal405Handler(node, checker, bindings = new Map()) {
|
|
6
|
-
if (!(ts.isArrowFunction(node) ||
|
|
7
|
-
ts.isFunctionExpression(node) ||
|
|
8
|
-
ts.isFunctionDeclaration(node) ||
|
|
9
|
-
ts.isMethodDeclaration(node)) ||
|
|
10
|
-
!node.body)
|
|
11
|
-
return false;
|
|
12
|
-
const context = runtimeParameters(node)[0]?.name;
|
|
13
|
-
const symbol = context && ts.isIdentifier(context) ? checker.getSymbolAtLocation(context) : undefined;
|
|
14
|
-
return !!symbol && terminalBody(node, symbol, checker, new Set(), true, bindings);
|
|
15
|
-
}
|
|
16
|
-
function terminalBody(node, context, checker, active, returned = true, bindings = new Map()) {
|
|
17
|
-
if (!node.body || node.asteriskToken || active.has(node))
|
|
18
|
-
return false;
|
|
19
|
-
if (node.parameters.some((parameter) => !ts.isIdentifier(parameter.name) ||
|
|
20
|
-
parameter.dotDotDotToken ||
|
|
21
|
-
(parameter.initializer && !ts.isLiteralExpression(parameter.initializer))))
|
|
22
|
-
return false;
|
|
23
|
-
const next = new Set(active).add(node);
|
|
24
|
-
if (!ts.isBlock(node.body))
|
|
25
|
-
return terminalCall(node.body, context, checker, next, returned, bindings);
|
|
26
|
-
const statements = node.body.statements;
|
|
27
|
-
const terminal = statements.at(-1);
|
|
28
|
-
if (!terminal ||
|
|
29
|
-
!statements.slice(0, -1).every((statement) => isInertStatement(statement, context, checker)))
|
|
30
|
-
return false;
|
|
31
|
-
if (ts.isExpressionStatement(terminal))
|
|
32
|
-
return terminalCall(terminal.expression, context, checker, next, false, bindings);
|
|
33
|
-
return (ts.isReturnStatement(terminal) &&
|
|
34
|
-
!!terminal.expression &&
|
|
35
|
-
terminalCall(terminal.expression, context, checker, next, returned, bindings));
|
|
36
|
-
}
|
|
37
|
-
function terminalCall(expression, context, checker, active, returned, bindings) {
|
|
38
|
-
if (ts.isAwaitExpression(expression))
|
|
39
|
-
return terminalCall(expression.expression, context, checker, active, true, bindings);
|
|
40
|
-
if (ts.isParenthesizedExpression(expression))
|
|
41
|
-
return terminalCall(expression.expression, context, checker, active, returned, bindings);
|
|
42
|
-
if (!ts.isCallExpression(expression) || expression.questionDotToken)
|
|
43
|
-
return false;
|
|
44
|
-
if (expression.arguments.some((argument) => !ts.isIdentifier(argument) && !ts.isLiteralExpression(argument)))
|
|
45
|
-
return false;
|
|
46
|
-
const callee = expression.expression;
|
|
47
|
-
if (ts.isPropertyAccessExpression(callee) && callee.name.text === 'throw') {
|
|
48
|
-
const status = expression.arguments[0];
|
|
49
|
-
return (!callee.questionDotToken &&
|
|
50
|
-
ts.isIdentifier(callee.expression) &&
|
|
51
|
-
checker.getSymbolAtLocation(callee.expression) === context &&
|
|
52
|
-
!!status &&
|
|
53
|
-
ts.isNumericLiteral(status) &&
|
|
54
|
-
Number(status.text) === 405);
|
|
55
|
-
}
|
|
56
|
-
if (!ts.isIdentifier(callee))
|
|
57
|
-
return false;
|
|
58
|
-
const implementations = [];
|
|
59
|
-
handlerNodes(callee, checker, bindings, new Set(), true, implementations);
|
|
60
|
-
if (!returned && checker.getPropertyOfType(checker.getTypeAtLocation(expression), 'then'))
|
|
61
|
-
return false;
|
|
62
|
-
return (implementations.length > 0 &&
|
|
63
|
-
implementations.every(({ node: implementation, bindings: captured }) => {
|
|
64
|
-
if (!returned &&
|
|
65
|
-
implementation.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword))
|
|
66
|
-
return false;
|
|
67
|
-
const index = expression.arguments.findIndex((argument) => ts.isIdentifier(argument) && checker.getSymbolAtLocation(argument) === context);
|
|
68
|
-
const parameter = runtimeParameters(implementation)[index]?.name;
|
|
69
|
-
const symbol = parameter && ts.isIdentifier(parameter) ? checker.getSymbolAtLocation(parameter) : undefined;
|
|
70
|
-
return !!symbol && terminalBody(implementation, symbol, checker, active, returned, captured);
|
|
71
|
-
}));
|
|
72
|
-
}
|
|
73
|
-
function isInertStatement(statement, context, checker) {
|
|
74
|
-
if (ts.isEmptyStatement(statement))
|
|
75
|
-
return true;
|
|
76
|
-
if (ts.isExpressionStatement(statement)) {
|
|
77
|
-
const expression = statement.expression;
|
|
78
|
-
if (ts.isStringLiteral(expression))
|
|
79
|
-
return true;
|
|
80
|
-
if (!ts.isCallExpression(expression) || expression.arguments.length !== 2)
|
|
81
|
-
return false;
|
|
82
|
-
const callee = expression.expression;
|
|
83
|
-
const [header, value] = expression.arguments;
|
|
84
|
-
return (ts.isPropertyAccessExpression(callee) &&
|
|
85
|
-
callee.name.text === 'set' &&
|
|
86
|
-
ts.isIdentifier(callee.expression) &&
|
|
87
|
-
checker.getSymbolAtLocation(callee.expression) === context &&
|
|
88
|
-
ts.isStringLiteral(header) &&
|
|
89
|
-
header.text.toLowerCase() === 'allow' &&
|
|
90
|
-
ts.isStringLiteral(value) &&
|
|
91
|
-
/^[A-Z]+(?:, *[A-Z]+)*$/.test(value.text));
|
|
92
|
-
}
|
|
93
|
-
if (!ts.isVariableStatement(statement))
|
|
94
|
-
return false;
|
|
95
|
-
return statement.declarationList.declarations.every((declaration) => ts.isIdentifier(declaration.name) &&
|
|
96
|
-
checker.getSymbolAtLocation(declaration.name) !== context &&
|
|
97
|
-
(!declaration.initializer || ts.isLiteralExpression(declaration.initializer)));
|
|
98
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
-
import { type DiscoverApiRequestContractsOptions } from './request-contract-lenient.mts';
|
|
3
|
-
import { type HandlerBindings } from './response-contract-route-analysis.mts';
|
|
4
|
-
import type { BackendRequestContract } from './request-contract-types.mts';
|
|
5
|
-
/**
|
|
6
|
-
* Phase 2 (implicit harvest) dispatch for one call expression. Requests have no `#variant` escape
|
|
7
|
-
* hatch, so precedence is stricter than the response side's: an explicit `apiRequest`/
|
|
8
|
-
* `apiNoRequestBody` marker registered in Phase 1 (`markerKeys`) always wins outright — a harvest
|
|
9
|
-
* never even attempts to register over one. A second implicit body-read for a route an earlier
|
|
10
|
-
* implicit call already covered attempts registration but swallows any failure (extraction error
|
|
11
|
-
* or hash mismatch), keeping the first-registered contract untouched — mirrors
|
|
12
|
-
* `response-contract-implicit.mts`'s secondary-variant handling, minus the variant key (requests
|
|
13
|
-
* get at most one contract per route). A `ctx.request.buffer(...)` read always overrides,
|
|
14
|
-
* regardless of visit order or what's already registered, mirroring the response side's own
|
|
15
|
-
* buffer-detection override.
|
|
16
|
-
*/
|
|
17
|
-
export declare function discoverImplicitRequestContract(call: ts.CallExpression, checker: ts.TypeChecker, sourceFile: ts.SourceFile, contracts: Map<string, BackendRequestContract>, markerKeys: ReadonlySet<string>, handlerBindings: HandlerBindings, requestedKeys: ReadonlySet<string> | undefined, options: DiscoverApiRequestContractsOptions | undefined): void;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
-
import { extractContractSchema } from '../contract-schema/index.mjs';
|
|
3
|
-
import { markBufferedRequestRouteUnavailable, registerRequestContract, registerRequestRouteContract, } from './request-contract-lenient.mjs';
|
|
4
|
-
import { enclosingRequestBodyCast, isContextRequestBufferCall, isContextRequestJsonCall, } from './request-contract-route-analysis.mjs';
|
|
5
|
-
import { sourceLocation } from './response-contract-registration.mjs';
|
|
6
|
-
import { enclosingRouteBinding, requestedKeyForBinding, } from './response-contract-route-analysis.mjs';
|
|
7
|
-
/**
|
|
8
|
-
* Resolves the effective static type of a body-read call, or `undefined` when `call` isn't a
|
|
9
|
-
* body-read pattern this harvester recognizes at all (most call expressions in a route file
|
|
10
|
-
* aren't). `parseJsonBody<T>(ctx)`'s own call-expression type is `Promise<T>` (or `Promise<unknown>`
|
|
11
|
-
* with no type argument) — `extractContractSchema` auto-unwraps the `Promise` either way, so no
|
|
12
|
-
* special-casing is needed. `ctx.request.json(...)` has no such generic in practice; its effective
|
|
13
|
-
* type comes from the enclosing `as T` cast, when one exists (`enclosingRequestBodyCast`) — absent
|
|
14
|
-
* one, the call's own type is `Promise<unknown>`, which resolves to an honest `{type:'unknown'}`
|
|
15
|
-
* rather than a failure (see `enclosingRequestBodyCast`'s docstring).
|
|
16
|
-
*/
|
|
17
|
-
function resolveRequestBodyType(call, checker) {
|
|
18
|
-
if (ts.isIdentifier(call.expression) && call.expression.text === 'parseJsonBody') {
|
|
19
|
-
return checker.getTypeAtLocation(call);
|
|
20
|
-
}
|
|
21
|
-
if (!isContextRequestJsonCall(call.expression))
|
|
22
|
-
return undefined;
|
|
23
|
-
const cast = enclosingRequestBodyCast(call);
|
|
24
|
-
return checker.getTypeAtLocation(cast ?? call);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Phase 2 (implicit harvest) dispatch for one call expression. Requests have no `#variant` escape
|
|
28
|
-
* hatch, so precedence is stricter than the response side's: an explicit `apiRequest`/
|
|
29
|
-
* `apiNoRequestBody` marker registered in Phase 1 (`markerKeys`) always wins outright — a harvest
|
|
30
|
-
* never even attempts to register over one. A second implicit body-read for a route an earlier
|
|
31
|
-
* implicit call already covered attempts registration but swallows any failure (extraction error
|
|
32
|
-
* or hash mismatch), keeping the first-registered contract untouched — mirrors
|
|
33
|
-
* `response-contract-implicit.mts`'s secondary-variant handling, minus the variant key (requests
|
|
34
|
-
* get at most one contract per route). A `ctx.request.buffer(...)` read always overrides,
|
|
35
|
-
* regardless of visit order or what's already registered, mirroring the response side's own
|
|
36
|
-
* buffer-detection override.
|
|
37
|
-
*/
|
|
38
|
-
export function discoverImplicitRequestContract(call, checker, sourceFile, contracts, markerKeys, handlerBindings, requestedKeys, options) {
|
|
39
|
-
const binding = enclosingRouteBinding(call, checker, handlerBindings);
|
|
40
|
-
if (!binding)
|
|
41
|
-
return;
|
|
42
|
-
const key = requestedKeyForBinding(binding, requestedKeys);
|
|
43
|
-
if (!key)
|
|
44
|
-
return;
|
|
45
|
-
if (isContextRequestBufferCall(call.expression)) {
|
|
46
|
-
markBufferedRequestRouteUnavailable(contracts, key, binding, sourceLocation(sourceFile, call));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (markerKeys.has(key))
|
|
50
|
-
return; // An explicit Phase 1 marker always wins; never harvest over it.
|
|
51
|
-
const bodyType = resolveRequestBodyType(call, checker);
|
|
52
|
-
if (!bodyType)
|
|
53
|
-
return;
|
|
54
|
-
const location = sourceLocation(sourceFile, call);
|
|
55
|
-
const extract = () => extractContractSchema(bodyType, checker, location, options);
|
|
56
|
-
if (!contracts.has(key)) {
|
|
57
|
-
registerRequestRouteContract(contracts, key, binding, location, extract, options);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
// A second body-read call for a route an earlier implicit harvest already covered — attempt
|
|
61
|
-
// registration but silently drop it on a hash-mismatch collision, keeping the
|
|
62
|
-
// first-registered contract. Anything else (a type-checker crash, an AST invariant
|
|
63
|
-
// violation) is unexpected and worth surfacing rather than swallowing.
|
|
64
|
-
try {
|
|
65
|
-
const extracted = extract();
|
|
66
|
-
registerRequestContract(contracts, key, { ...extracted, ...binding });
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
if (error instanceof Error && !error.message.includes('resolves to multiple')) {
|
|
70
|
-
console.warn(`Second body-read extraction for "${key}" failed:`, error);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|