@kollors/react-codegen 2.0.0-alpha.4 → 2.0.0-alpha.6

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.
Files changed (89) hide show
  1. package/README.md +193 -49
  2. package/README.ru.md +193 -49
  3. package/dist/{cli.js → cli/index.js} +6 -11
  4. package/dist/cli/index.js.map +1 -0
  5. package/dist/core/auth.d.ts +7 -0
  6. package/dist/core/auth.js +2 -0
  7. package/dist/core/auth.js.map +1 -0
  8. package/dist/core/config.d.ts +2 -0
  9. package/dist/core/config.js +67 -0
  10. package/dist/core/config.js.map +1 -0
  11. package/dist/{generate.d.ts → core/generate.d.ts} +0 -1
  12. package/dist/core/generate.js +47 -0
  13. package/dist/core/generate.js.map +1 -0
  14. package/dist/core/names.d.ts +5 -0
  15. package/dist/core/names.js +16 -0
  16. package/dist/core/names.js.map +1 -0
  17. package/dist/core/output.d.ts +5 -0
  18. package/dist/core/output.js +39 -0
  19. package/dist/core/output.js.map +1 -0
  20. package/dist/core/paths.d.ts +4 -0
  21. package/dist/core/paths.js +12 -0
  22. package/dist/core/paths.js.map +1 -0
  23. package/dist/{types.d.ts → core/types.d.ts} +2 -2
  24. package/dist/core/types.js.map +1 -0
  25. package/dist/graphql/document.d.ts +8 -0
  26. package/dist/graphql/document.js +118 -0
  27. package/dist/graphql/document.js.map +1 -0
  28. package/dist/graphql/fetcher.d.ts +5 -0
  29. package/dist/graphql/fetcher.js +4 -0
  30. package/dist/graphql/fetcher.js.map +1 -0
  31. package/dist/graphql/generate.d.ts +3 -0
  32. package/dist/graphql/generate.js +59 -0
  33. package/dist/graphql/generate.js.map +1 -0
  34. package/dist/graphql/operations.d.ts +13 -0
  35. package/dist/graphql/operations.js +139 -0
  36. package/dist/graphql/operations.js.map +1 -0
  37. package/dist/{graphql-fetcher.d.ts → graphql/runtime.d.ts} +4 -3
  38. package/dist/{graphql-fetcher.js → graphql/runtime.js} +12 -6
  39. package/dist/graphql/runtime.js.map +1 -0
  40. package/dist/graphql/runtime.source +140 -0
  41. package/dist/graphql/selections.d.ts +12 -0
  42. package/dist/graphql/selections.js +120 -0
  43. package/dist/graphql/selections.js.map +1 -0
  44. package/dist/graphql/types.d.ts +15 -0
  45. package/dist/graphql/types.js +110 -0
  46. package/dist/graphql/types.js.map +1 -0
  47. package/dist/index.d.ts +6 -6
  48. package/dist/index.js +3 -3
  49. package/dist/index.js.map +1 -1
  50. package/dist/openapi/fetcher.d.ts +3 -0
  51. package/dist/openapi/fetcher.js +4 -0
  52. package/dist/openapi/fetcher.js.map +1 -0
  53. package/dist/openapi/generate.d.ts +1 -1
  54. package/dist/openapi/generate.js +2 -1
  55. package/dist/openapi/generate.js.map +1 -1
  56. package/dist/openapi/names.d.ts +1 -5
  57. package/dist/openapi/names.js +1 -15
  58. package/dist/openapi/names.js.map +1 -1
  59. package/dist/openapi/operations.d.ts +0 -1
  60. package/dist/openapi/operations.js +35 -45
  61. package/dist/openapi/operations.js.map +1 -1
  62. package/dist/{openapi-runtime.d.ts → openapi/runtime.d.ts} +5 -7
  63. package/dist/{openapi-runtime.js → openapi/runtime.js} +38 -25
  64. package/dist/openapi/runtime.js.map +1 -0
  65. package/dist/{openapi-runtime.source → openapi/runtime.source} +43 -21
  66. package/dist/openapi/schema.d.ts +4 -0
  67. package/dist/openapi/schema.js +83 -77
  68. package/dist/openapi/schema.js.map +1 -1
  69. package/dist/openapi/type-expression.d.ts +38 -0
  70. package/dist/openapi/type-expression.js +166 -0
  71. package/dist/openapi/type-expression.js.map +1 -0
  72. package/docs/migration.md +21 -0
  73. package/docs/migration.ru.md +21 -0
  74. package/package.json +10 -15
  75. package/dist/cli.js.map +0 -1
  76. package/dist/generate.js +0 -197
  77. package/dist/generate.js.map +0 -1
  78. package/dist/graphql-fetcher.js.map +0 -1
  79. package/dist/openapi-fetcher.d.ts +0 -3
  80. package/dist/openapi-fetcher.js +0 -4
  81. package/dist/openapi-fetcher.js.map +0 -1
  82. package/dist/openapi-runtime.js.map +0 -1
  83. package/dist/path-utils.d.ts +0 -2
  84. package/dist/path-utils.js +0 -5
  85. package/dist/path-utils.js.map +0 -1
  86. package/dist/types.js.map +0 -1
  87. package/templates/graphql.template +0 -23
  88. /package/dist/{cli.d.ts → cli/index.d.ts} +0 -0
  89. /package/dist/{types.js → core/types.js} +0 -0
package/README.md CHANGED
@@ -2,27 +2,29 @@
2
2
 
3
3
  [Русский](README.ru.md)
4
4
 
5
- Generate one self-contained TypeScript client file from an OpenAPI schema, GraphQL schema and operations, or both.
6
-
7
- Requires Node.js 22 or newer and TanStack Query 5 in the consuming application.
5
+ Generate TypeScript types, request functions, and React hooks for TanStack Query from OpenAPI and GraphQL. Each configured schema produces a separate `.ts` file.
8
6
 
9
7
  ## Install
10
8
 
9
+ Requires Node.js 22 or newer. The application using the generated hooks must have TanStack Query 5 installed and a `QueryClientProvider` configured.
10
+
11
11
  ```sh
12
12
  npm install -D @kollors/react-codegen@alpha
13
13
  ```
14
14
 
15
- ## Configuration
15
+ The generated files include the code that sends requests. They use TanStack Query and do not require React Codegen in the application at runtime.
16
+
17
+ ## Configuration and generation
16
18
 
17
19
  Create `codegen.config.js`:
18
20
 
19
21
  ```js
20
22
  export default {
21
23
  auth: {
22
- storage: 'localStorage', // 'localStorage' | 'sessionStorage' | 'cookie' | 'none'
24
+ storage: 'localStorage',
23
25
  key: 'accessToken',
24
- scheme: 'Bearer', // false sends the token without a scheme
25
- credentials: 'same-origin', // 'omit' | 'same-origin' | 'include'
26
+ scheme: 'Bearer',
27
+ credentials: 'same-origin',
26
28
  },
27
29
  openapi: {
28
30
  schema: './openapi.yaml',
@@ -38,53 +40,168 @@ export default {
38
40
  };
39
41
  ```
40
42
 
41
- Run both configured generators with:
43
+ Run:
42
44
 
43
45
  ```sh
44
46
  npx react-codegen codegen.config.js
45
47
  ```
46
48
 
47
- Paths are resolved relative to the config file. A configured `openapi` section enables OpenAPI generation; a configured `graphql` section enables GraphQL generation. Omit a section to skip it. At least one section is required. Each section writes one TypeScript file. `documents` is a directory; all `.graphql` files under it, including nested directories, are included. The built-in OpenAPI generator reads and generates in memory, without third-party generators, subprocesses or intermediate files. GraphQL still uses its existing generator and a temporary subdirectory inside the package's `.react-codegen-temp` directory, removed after generation. Each completed output is staged beside its destination and published with an atomic rename.
49
+ This example creates `src/api/openapi.ts` and `src/api/graphql.ts`. Include `openapi`, `graphql`, or both; at least one is required. Output directories are created automatically, and the two outputs must use different filenames.
50
+
51
+ File paths resolve relative to the config file. The config uses an ES module default export; in a CommonJS project, use `codegen.config.mjs` and pass that filename to the command.
52
+
53
+ | Setting | Required | Description or default |
54
+ | --- | --- | --- |
55
+ | `openapi.schema` | Yes | OpenAPI 3.0.x or 3.1.x in YAML/JSON: file path or HTTP URL |
56
+ | `openapi.output` | Yes | Path to the generated `.ts` file |
57
+ | `openapi.baseUrl` | No | URL prefix for requests; paths stay relative when omitted |
58
+ | `graphql.schema` | Yes | GraphQL SDL or introspection JSON: file path or HTTP URL |
59
+ | `graphql.documents` | Yes | Directory containing named queries, mutations, and fragments in `.graphql` files; subdirectories are included |
60
+ | `graphql.output` | Yes | Path to the generated `.ts` file |
61
+ | `graphql.endpoint` | No | Request endpoint; defaults to `/api/graphql` |
62
+ | `auth` | No | Shared [authentication settings](#authentication) |
63
+ | `openapi.auth`, `graphql.auth` | No | Replace shared authentication settings for that client |
64
+
65
+ GraphQL introspection JSON can contain `__schema` or `data.__schema`. A GraphQL HTTP endpoint can also be used as `schema`: the generator requests its schema through introspection.
66
+
67
+ ## Using the generated code
68
+
69
+ ### Queries
70
+
71
+ For an OpenAPI GET operation with `operationId: getPet`, use the hook inside a component or another hook:
72
+
73
+ ```ts
74
+ import { useGetPet } from './api/openapi';
75
+
76
+ export function usePetName(id: string) {
77
+ return useGetPet({ pathParams: { id } }, { select: pet => pet.name });
78
+ }
79
+ ```
80
+
81
+ For a GraphQL query named `MovieDetailsQuery` that selects `movie.title`:
82
+
83
+ ```ts
84
+ import { useMovieDetailsQuery } from './api/graphql';
85
+
86
+ export function useMovieTitle(id: string) {
87
+ return useMovieDetailsQuery({ id }, { select: data => data.movie?.title });
88
+ }
89
+ ```
90
+
91
+ Both generators provide the following helpers for queries:
92
+
93
+ | Purpose | OpenAPI `getPet` | GraphQL `MovieDetailsQuery` |
94
+ | --- | --- | --- |
95
+ | Query hook | `useGetPet` | `useMovieDetailsQuery` |
96
+ | Suspense hook | `useSuspenseGetPet` | `useSuspenseMovieDetailsQuery` |
97
+ | Options for `QueryClient` | `getPetQuery` | `movieDetailsQuery` |
98
+ | Cache key | `getPetQueryKey` | `movieDetailsQueryKey` |
99
+ | Direct request | `fetchGetPet` | `fetchMovieDetailsQuery` |
100
+
101
+ OpenAPI names come from `operationId`, or from the HTTP method and path when it is absent. GraphQL names come from the operation name. GraphQL also exports the selected result type, variable type, and document string, such as `MovieDetailsQuery`, `MovieDetailsQueryVariables`, and `MovieDetailsQueryDocument`.
102
+
103
+ ### Mutations
104
+
105
+ OpenAPI methods other than GET and GraphQL mutations generate mutation hooks. For an OpenAPI operation with `operationId: createPet`:
106
+
107
+ ```ts
108
+ import { useCreatePet, type CreatePetRequestBody } from './api/openapi';
109
+
110
+ export function useSavePet() {
111
+ const mutation = useCreatePet();
112
+ return (body: CreatePetRequestBody) => mutation.mutate({ body });
113
+ }
114
+ ```
115
+
116
+ OpenAPI arguments are grouped into `pathParams`, `queryParams`, `headers`, and `body`. GraphQL arguments are the operation's variables. Required arguments follow the schema; GraphQL variables marked `!` are required unless they have a default.
117
+
118
+ If no arguments are required, hooks and request functions can be called without them. Mutation hooks also allow `mutate()` and `mutateAsync()` in that case.
119
+
120
+ ### Skipping a query
121
+
122
+ Regular query hooks accept `skipToken`:
123
+
124
+ ```ts
125
+ import { skipToken } from '@tanstack/react-query';
126
+ import { useGetPet } from './api/openapi';
127
+
128
+ export function useOptionalPet(id?: string) {
129
+ return useGetPet(id ? { pathParams: { id } } : skipToken);
130
+ }
131
+ ```
132
+
133
+ Suspense hooks do not accept `skipToken`. Their arguments can be omitted when the operation has no required arguments.
134
+
135
+ ### Requests and cache keys
48
136
 
49
- Schema values may be local paths or URLs. `output` directories are created when needed.
137
+ Load data through TanStack Query:
138
+
139
+ ```ts
140
+ import { QueryClient } from '@tanstack/react-query';
141
+ import { getPetQuery } from './api/openapi';
50
142
 
51
- ## OpenAPI generator
143
+ const queryClient = new QueryClient();
144
+ const pet = await queryClient.fetchQuery(getPetQuery({ pathParams: { id: '42' } }));
145
+ ```
146
+
147
+ To refresh cached data in the application, use its `QueryClient`:
148
+
149
+ ```ts
150
+ import { useQueryClient } from '@tanstack/react-query';
151
+ import { getPetQueryKey } from './api/openapi';
52
152
 
53
- Only `schema` and `output` are required. One OpenAPI 3.0.x or 3.1.x document in YAML/JSON produces one `.ts` file with types, a fetcher, request functions and TanStack Query 5 hooks. Swagger 2.0 is rejected. The generated client does not import this package. `yaml` only parses input during generation.
153
+ export function useRefreshPet(id: string) {
154
+ const queryClient = useQueryClient();
155
+ return () => queryClient.invalidateQueries({ queryKey: getPetQueryKey({ pathParams: { id } }) });
156
+ }
157
+ ```
54
158
 
55
- For `operationId: getPet`, the output includes:
159
+ To send a request directly, without TanStack Query:
56
160
 
57
161
  ```ts
58
- import { useGetPet, getPetQuery, getPetQueryKey, fetchGetPet } from './api/openapi';
162
+ import { fetchGetPet } from './api/openapi';
59
163
 
60
- const variables = { pathParams: { id: '42' } };
61
- const query = useGetPet(variables, { select: pet => pet.name });
62
- await queryClient.fetchQuery(getPetQuery(variables));
63
- await queryClient.invalidateQueries({ queryKey: getPetQueryKey(variables) });
64
- await fetchGetPet(variables, abortController.signal);
164
+ const controller = new AbortController();
165
+ const pet = await fetchGetPet({ pathParams: { id: '42' } }, controller.signal);
65
166
  ```
66
167
 
67
- GET generates `useX`, `useSuspenseX`, `xQuery`, `xQueryKey` and `fetchX`. Other methods generate `useX` mutations and `fetchX`, e.g. `useCreatePet().mutate({ body: pet })`. Variables group `pathParams`, `queryParams`, `headers` and `body`; required groups follow the schema. Calls with no required variables can omit the argument. Regular queries accept TanStack's `skipToken`; suspense queries require variables. Names use `operationId`, falling back to method and path; collisions report both locations.
168
+ Calling `controller.abort()` cancels the direct request. Query hooks receive TanStack Query's cancellation signal automatically. The GraphQL request functions and helpers work the same way.
169
+
170
+ Use the generated key helpers for cache operations. Keys include the endpoint or base URL and request arguments; OpenAPI keys also include request headers. Tokens read from storage and browser cookies are excluded, so clear the relevant cache when the signed-in user changes.
171
+
172
+ ## Authentication
68
173
 
69
- Query keys include the configured base URL, HTTP method, path, operation name and variables. The generated `Accept` header and explicit request headers are normalized to their serialized names and values, so equivalent `Headers`, objects and tuple arrays share a cache entry while different header values stay separate. Tokens read from storage and browser cookies are not part of the key; clear the relevant query cache when the signed-in user changes.
174
+ Top-level `auth` applies to both clients. `openapi.auth` or `graphql.auth` replaces the whole shared section for that client.
70
175
 
71
- ### Supported features
176
+ Without `auth`, the generated client does not add an `Authorization` header.
72
177
 
73
- - Primitive types, arrays, objects, dictionaries, enums, internal `$ref`, recursive component types, `allOf` intersections, `oneOf`/`anyOf` unions. OpenAPI 3.1 also supports boolean schemas, `const` and type arrays.
74
- - `required` controls optional properties. `null` is included only when allowed by the schema. No blanket replacement of `null` with `undefined`. `readOnly`/`writeOnly` produce input/output variants when needed.
75
- - Path/header `simple` parameters; query `form`, flat `deepObject` with `explode: true`, array `spaceDelimited`/`pipeDelimited` with `explode: false`. Operation parameters override path-level parameters.
76
- - JSON/`+json`, text/XML as strings, binary bodies/responses as `Blob`, multipart and URL-encoded object bodies. Multiple request formats are selected in this order: JSON, `+json`, URL-encoded, multipart, other supported formats alphabetically. Responses use their actual Content-Type; successful response types form a union. `default` is a success fallback only when no explicit 2xx exists. Empty mutation responses return `undefined` with type `void`.
77
- - Descriptions become comments. Dates remain strings. Numeric bounds, patterns and lengths do not add runtime validation. `oneOf` becomes a TypeScript union without checking exclusivity. `discriminator` does not invent properties or values: describe the discriminator field in the schema.
178
+ | Option | Required | Behavior |
179
+ | --- | --- | --- |
180
+ | `storage` | When `auth` is configured | Where to read the token; see below |
181
+ | `key` | Unless `storage` is `none` | Name of the storage entry or cookie |
182
+ | `scheme` | No | Header prefix; defaults to `Bearer`. Set `false` to send the token unchanged |
183
+ | `credentials` | No | Browser cookie policy; defaults to `same-origin` |
78
184
 
79
- ### Current limits
185
+ | `storage` | Token source |
186
+ | --- | --- |
187
+ | `localStorage` | `localStorage.getItem(key)` |
188
+ | `sessionStorage` | `sessionStorage.getItem(key)` |
189
+ | `cookie` | Cookie named `key`, read through `document.cookie` |
190
+ | `none` | No token is read; no authorization header is added |
80
191
 
81
- Generation fails with a schema location before replacing output for unsupported constructs: external `$ref` (bundle first), callbacks/webhooks, cookie parameters, parameter `content`, nested parameter objects/arrays, `allowReserved`, path `label`/`matrix`, custom form encoding, unsupported media types, and advanced JSON Schema keywords such as conditionals, `not`, dynamic references, `prefixItems`, `patternProperties` and `unevaluatedProperties`. Typed `additionalProperties` alongside named properties are rejected because a TypeScript index signature would also constrain named properties; use a separate dictionary property. Recursive types must be components; circular aliases and cyclic YAML aliases are rejected.
192
+ | `credentials` | Browser cookies |
193
+ | --- | --- |
194
+ | `omit` | Do not send |
195
+ | `same-origin` | Allow for requests to the same origin |
196
+ | `include` | Also allow for requests to another origin |
82
197
 
83
- Fetch cannot send GET/HEAD bodies or TRACE requests. A GET response declared without a body is rejected because React Query cannot cache `undefined`; the generator does not replace it with `null`. Empty text responses remain empty strings. Path segments `.` and `..` are rejected before sending a request because Fetch would normalize them and change the route. Schema `servers` and `security` do not override configuration: use `baseUrl` and `auth`. Response headers are not returned separately. Generated types do not validate server responses at runtime.
198
+ If the token is missing or empty, no authorization header is added. For `HttpOnly` cookies, which JavaScript cannot read, let the browser send them:
84
199
 
85
- ### Migration
200
+ ```js
201
+ auth: { storage: 'none', credentials: 'include' }
202
+ ```
86
203
 
87
- Regenerate the client. Usual camelCase operation names and grouped variables remain, but full export compatibility is not guaranteed. Empty context, `deepMerge`, `QueryOperation`, shared `queryKeyFn` and `@ts-nocheck` are removed. Starting with `2.0.0-alpha.4`, query keys use `[baseUrl, method, path, operationName, normalizedVariables]` instead of `[operationName, variables]`: use `xQueryKey`, update manually constructed invalidation keys and clear persisted caches when upgrading. Type names use PascalCase; punctuation and underscores separate words. Errors use `OpenapiHttpError` or ordinary `Error` instead of `ErrorWrapper`. Stricter types may require call-site fixes.
204
+ Browser cookie and CORS rules still apply. When calling `createOpenapiFetcher` or `createGraphqlFetcher` directly, `getToken` can return the complete `Authorization` header value. This option belongs to the fetcher factories, not the codegen config.
88
205
 
89
206
  ## Programmatic API
90
207
 
@@ -92,33 +209,53 @@ Regenerate the client. Usual camelCase operation names and grouped variables rem
92
209
  import { generate, type CodegenConfig } from '@kollors/react-codegen';
93
210
 
94
211
  const config: CodegenConfig = {
95
- auth: {
96
- storage: 'localStorage',
97
- key: 'accessToken',
98
- },
99
- graphql: {
100
- schema: './schema.graphql',
101
- documents: './src/graphql',
102
- output: './src/api/graphql.ts',
103
- endpoint: '/graphql',
212
+ openapi: {
213
+ schema: './openapi.yaml',
214
+ output: './src/api/openapi.ts',
104
215
  },
105
216
  };
106
217
 
107
- const result = await generate(config);
108
- console.log(result.outputs);
218
+ const { outputs } = await generate(config);
219
+ console.log(outputs);
109
220
  ```
110
221
 
111
- Programmatic relative paths resolve from the current working directory. `generate` returns the generated output paths.
222
+ The settings are the same as in the CLI config. Relative paths resolve from the current working directory. `generate` returns the paths of the generated files.
223
+
224
+ ## Supported schemas and limits
225
+
226
+ Both generators create types from the schema. They do not validate server response data at runtime. A generation error leaves the existing output files in place.
112
227
 
113
- ## Authentication and errors
228
+ ### OpenAPI
114
229
 
115
- The top-level `auth` settings apply to both generated clients. Add `auth` inside `openapi` or `graphql` to replace them for that client. Supported `storage` values are `localStorage`, `sessionStorage`, `cookie`, and `none`. If `auth` is present, `storage` is required. `key` names the stored token and is required for `localStorage`, `sessionStorage`, and `cookie`; it is not used with `none`. `scheme` defaults to `Bearer`; set it to `false` to send the token unchanged. `credentials` is optional and uses the Fetch API's default `same-origin` behavior unless set to `omit` or `include`.
230
+ - Supports OpenAPI 3.0.x and 3.1.x; Swagger 2.0 is not supported.
231
+ - Supports objects, arrays, dictionaries, enums, internal `$ref`, recursive components, `allOf`, `oneOf`, and `anyOf`. OpenAPI 3.1 also supports `const`, boolean schemas, and type arrays.
232
+ - `required` controls required fields; `null` is included where the schema allows it. `readOnly` fields are excluded from request types, and `writeOnly` fields from response types. Dates remain strings.
233
+ - Supports JSON, `+json`, text/XML strings, binary data as `Blob`, multipart, and URL-encoded bodies. For multiple request formats, priority is JSON, `+json`, URL-encoded, multipart, then other supported formats alphabetically.
234
+ - Supports path/header `simple` and query `form` parameters, flat `deepObject` with `explode: true`, and `spaceDelimited`/`pipeDelimited` arrays with `explode: false`. Nested parameter objects and arrays are not supported.
116
235
 
117
- If no top-level or per-section `auth` is configured, generated clients do not add an `Authorization` header. JavaScript cannot read `HttpOnly` cookies; for those, use `auth: { storage: 'none', credentials: 'include' }` and let the browser send the cookie. `graphql.endpoint` defaults to `/api/graphql`. `openapi.baseUrl` defaults to an empty prefix, leaving generated paths relative.
236
+ External `$ref` must be bundled into one document before generation. Callbacks, webhooks, cookie parameters, parameter `content`, `allowReserved`, `label`/`matrix` path styles, and custom form encoding are not supported. Advanced JSON Schema constraints such as conditions, `not`, `dependentRequired`, `patternProperties`, and `unevaluatedProperties` cause an error with the schema location.
118
237
 
119
- When using the fetcher factories directly, `getToken` may provide a custom token getter; it should return the complete `Authorization` header value.
238
+ Typed `additionalProperties` combined with named properties are not supported; put the dictionary in a separate property. Numeric bounds, patterns, and lengths are not checked at runtime. `oneOf` becomes a TypeScript union without checking that exactly one branch matches; describe the discriminator field and its values in the schema.
120
239
 
121
- HTTP failures are reported as `GraphqlHttpError` or `OpenapiHttpError`, with status and response details. GraphQL execution errors are reported as `GraphqlResponseError` and include all messages returned by the server.
240
+ Use `baseUrl` and `auth` to configure requests; schema `servers` and `security` are not applied. GET responses must declare a body. Empty mutation responses return `undefined` with type `void`; a missing body where one is declared causes a request error. GET/HEAD request bodies, TRACE, and path segments `.` or `..` are rejected. Response headers are not returned separately.
241
+
242
+ ### GraphQL
243
+
244
+ Supports named queries and mutations, fragments, aliases, interfaces, and unions. Result types describe selected fields. Select `__typename` when you need to distinguish union members.
245
+
246
+ Nullable fields use `T | null`; conditional selections with `@skip` or `@include` can be optional. Lists preserve element nullability. Non-null input fields and variables with defaults can be omitted but cannot be `null`. `@oneOf` inputs require exactly one non-null field. Custom scalars use `unknown`.
247
+
248
+ Subscriptions and `@defer`/`@stream` are not supported. Schema downloads do not use `auth`; use a local schema export if the schema URL requires authentication.
249
+
250
+ ### Request errors
251
+
252
+ | Error | Details |
253
+ | --- | --- |
254
+ | `OpenapiHttpError` | HTTP status and response data in `data` |
255
+ | `GraphqlHttpError` | HTTP status and response body in `body` |
256
+ | `GraphqlResponseError` | GraphQL execution errors in `errors` and partial response data in `data` |
257
+
258
+ When updating existing generated clients, see the [migration guide](docs/migration.md).
122
259
 
123
260
  ## Development
124
261
 
@@ -127,6 +264,13 @@ npm ci
127
264
  npm run verify
128
265
  ```
129
266
 
267
+ | Directory | Contents |
268
+ | --- | --- |
269
+ | `src/cli/` | CLI command |
270
+ | `src/core/` | Configuration, generation entry point, file writing, and shared utilities |
271
+ | `src/openapi/` | OpenAPI generator and request code |
272
+ | `src/graphql/` | GraphQL generator and request code |
273
+
130
274
  ## License
131
275
 
132
276
  [MIT](LICENSE)