Skip to content

feat(openapi-resource-gen): add callOptions for per-call request options - #83

Merged
constantant merged 3 commits into
masterfrom
feat/call-options
Oct 2, 2026
Merged

constantant merged 3 commits into
masterfrom
feat/call-options

Conversation

@constantant

Copy link
Copy Markdown
Owner

Summary

Opt-in --callOptions adds a trailing optional options argument to every generated token function: HttpContext, headers, withCredentials and the other request fields Angular supports, plus (httpResource tokens) defaultValue, equal, injector, debugName.

  • A defaultValue narrows the resource's value() to non-undefined (generic XxxFn type).
  • Types derive from Angular's own HttpResourceRequest/HttpResourceOptions, so they follow the installed version (compiles on Angular 20.0.0).
  • Caller headers are merged over generated ones. URL, method, body, params, reportProgress and parse cannot be overridden (types + runtime), so validateResponses keeps working.
  • Shared request-options.ts, exported from the root barrel and covered by stale-file cleanup.
  • Off by default: github/youtube/weather regenerate byte-identically.

Mocks and DevTools

  • MockResourceMeta.args names the function arguments; mocks honour defaultValue.
  • The bus names uncloneable arguments (HttpContext, Injector, functions) instead of dropping the whole event.
  • DevTools history labels arguments by name.

Demo

Petstore lib regenerated with --callOptions; the Pets list uses defaultValue. New wire-level spec proves the options reach HttpClient; the compat matrix now runs every generated-*.spec.ts.

Test plan

  • gen 205, mocks 153, panel 17, app 31 unit tests; build and lint
  • mock e2e 52/52
  • integration spec with @ts-expect-error probes and negative controls
  • CI incl. Compat matrix (Angular 20.0.0–22, Nx 20–23)

🤖 Generated with Claude Code

constantant and others added 3 commits October 2, 2026 17:55
… headers and httpResource options

Spec-driven requests can't carry an HttpContext for interceptors, extra headers,
withCredentials, or a defaultValue. The opt-in `callOptions` option adds a
trailing, optional `options` argument to every token function.

httpResource tokens get a generic `XxxFn` type so a `defaultValue` narrows the
returned resource's `value()` from `T | undefined` to `T`; httpClient tokens take
`CallOptions` (request options and headers only). A shared `request-options.ts`
(exported from the barrel) holds the types and a small `splitCallOptions` helper.

The types are derived from Angular's own HttpResourceRequest / HttpResourceOptions
rather than listing fields, so they follow the installed version (debugName
exists only from Angular 22), and the runtime routes fields by a key list, never
naming a version-specific field in code; this compiles on Angular 20.0.0. The
caller's headers are merged over the generated ones and win on a clash. The URL,
method, body, query params and reportProgress are refused by the types and also
dropped at runtime, so a cast can't turn a GET into a DELETE; `parse` can't be
replaced either, so validateResponses keeps working.

With includeMocks, a mock's `_meta` records the argument names (`args`) so the
mock and DevTools can find the options argument. Off by default: output is
byte-identical (github, youtube and weather regenerate with no diff).

Tests: unit tests for the emitted code and the stale-file cleanup, and an
integration test that runs the real generator and parser and compiles the output
with `@ts-expect-error` probes (defaultValue narrows; unknown options and
spec-controlled fields are rejected; httpClient accepts request options only).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…rguments, add MockResourceMeta.args

Support for the generator's per-call options (`callOptions`):

- MockResourceMeta gains `args`, the names of the token function's arguments. The
  mock uses it to find the `options` argument (by name, so a body with a
  `defaultValue` field is never mistaken for it) and honours `defaultValue` like
  the real httpResource: value() returns it until something resolves, and again
  after reset(). Without this a mock-mode app would see `undefined` where the real
  resource returns the default.
- The bus names values that can't be structured-cloned (an HttpContext, an
  Injector, an equality function) with a placeholder instead of letting one of
  them null the whole DOM event, which would hide the request from DevTools. The
  raw arguments stay in getHistory().
- The DevTools history labels each argument by name (Body, Query, Options, or the
  argument's own name) when `args` is present, instead of guessing "Body [0]",
  "Body [1]".

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…hem on the wire

Regenerate petstore-data-access with --callOptions. The Pets list passes
`defaultValue: []` (so its value is never undefined) and a `debugName`.

New wire-level spec (generated-call-options.spec.ts): a real HttpClient with a
recording interceptor and a fake backend checks that an HttpContext reaches the
interceptor, withCredentials and caller headers reach the request (a caller
header beats the generated one), defaultValue is the value while loading, an
injector allows calling outside an injection context, undefined options are
ignored, spec-controlled fields and the validate hook cannot be overridden, and
the httpClient and event-yielding tokens behave the same.

The compat matrix now runs every generated-*.spec.ts, so this spec also runs on
Angular 20.0.0, 21 and 22.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@constantant
constantant merged commit f32ddfc into master Oct 2, 2026
9 checks passed
@constantant
constantant deleted the feat/call-options branch October 2, 2026 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant