@neon/sdk 1.4.1 → 2.0.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 +257 -30
- package/dist/client/client/client.gen.js +1 -3
- package/dist/client/client/client.gen.js.map +1 -1
- package/dist/client/client/utils.gen.js +1 -3
- package/dist/client/client/utils.gen.js.map +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +2 -2
- package/dist/client/raw.gen.d.ts +146 -16
- package/dist/client/raw.gen.d.ts.map +1 -1
- package/dist/client/raw.gen.js +8 -3
- package/dist/client/raw.gen.js.map +1 -1
- package/dist/client/sdk.gen.d.ts +137 -78
- package/dist/client/sdk.gen.d.ts.map +1 -1
- package/dist/client/sdk.gen.js +258 -96
- package/dist/client/sdk.gen.js.map +1 -1
- package/dist/client/types.gen.d.ts +1397 -315
- package/dist/client/types.gen.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +2 -2
- package/dist/neon/client.d.ts +2 -0
- package/dist/neon/client.d.ts.map +1 -1
- package/dist/neon/client.js +2 -0
- package/dist/neon/client.js.map +1 -1
- package/dist/neon/config.d.ts +13 -0
- package/dist/neon/config.d.ts.map +1 -1
- package/dist/neon/config.js +2 -0
- package/dist/neon/config.js.map +1 -1
- package/dist/neon/context.d.ts +26 -6
- package/dist/neon/context.d.ts.map +1 -1
- package/dist/neon/context.js +60 -10
- package/dist/neon/context.js.map +1 -1
- package/dist/neon/coverage.d.ts.map +1 -1
- package/dist/neon/coverage.js +12 -2
- package/dist/neon/coverage.js.map +1 -1
- package/dist/neon/deadline.d.ts +81 -0
- package/dist/neon/deadline.d.ts.map +1 -0
- package/dist/neon/deadline.js +143 -0
- package/dist/neon/deadline.js.map +1 -0
- package/dist/neon/errors.d.ts +22 -3
- package/dist/neon/errors.d.ts.map +1 -1
- package/dist/neon/errors.js +22 -2
- package/dist/neon/errors.js.map +1 -1
- package/dist/neon/paginate.d.ts +6 -1
- package/dist/neon/paginate.d.ts.map +1 -1
- package/dist/neon/paginate.js +63 -25
- package/dist/neon/paginate.js.map +1 -1
- package/dist/neon/raw-wrap.d.ts.map +1 -1
- package/dist/neon/raw-wrap.js +17 -2
- package/dist/neon/raw-wrap.js.map +1 -1
- package/dist/neon/resources/account.d.ts.map +1 -1
- package/dist/neon/resources/account.js +18 -12
- package/dist/neon/resources/account.js.map +1 -1
- package/dist/neon/resources/ai-gateway.js +3 -2
- package/dist/neon/resources/ai-gateway.js.map +1 -1
- package/dist/neon/resources/auth.d.ts.map +1 -1
- package/dist/neon/resources/auth.js +42 -28
- package/dist/neon/resources/auth.js.map +1 -1
- package/dist/neon/resources/branches.d.ts +1 -8
- package/dist/neon/resources/branches.d.ts.map +1 -1
- package/dist/neon/resources/branches.js +32 -32
- package/dist/neon/resources/branches.js.map +1 -1
- package/dist/neon/resources/bucket-objects.d.ts.map +1 -1
- package/dist/neon/resources/bucket-objects.js +15 -10
- package/dist/neon/resources/bucket-objects.js.map +1 -1
- package/dist/neon/resources/buckets.d.ts.map +1 -1
- package/dist/neon/resources/buckets.js +9 -6
- package/dist/neon/resources/buckets.js.map +1 -1
- package/dist/neon/resources/consumption.d.ts +4 -4
- package/dist/neon/resources/consumption.d.ts.map +1 -1
- package/dist/neon/resources/consumption.js +6 -6
- package/dist/neon/resources/consumption.js.map +1 -1
- package/dist/neon/resources/credentials.d.ts.map +1 -1
- package/dist/neon/resources/credentials.js +9 -6
- package/dist/neon/resources/credentials.js.map +1 -1
- package/dist/neon/resources/dataapi.d.ts.map +1 -1
- package/dist/neon/resources/dataapi.js +12 -8
- package/dist/neon/resources/dataapi.js.map +1 -1
- package/dist/neon/resources/databases.d.ts.map +1 -1
- package/dist/neon/resources/databases.js +15 -10
- package/dist/neon/resources/databases.js.map +1 -1
- package/dist/neon/resources/endpoints.d.ts.map +1 -1
- package/dist/neon/resources/endpoints.js +27 -18
- package/dist/neon/resources/endpoints.js.map +1 -1
- package/dist/neon/resources/functions.d.ts +1 -1
- package/dist/neon/resources/functions.d.ts.map +1 -1
- package/dist/neon/resources/functions.js +14 -10
- package/dist/neon/resources/functions.js.map +1 -1
- package/dist/neon/resources/logs.d.ts +76 -0
- package/dist/neon/resources/logs.d.ts.map +1 -0
- package/dist/neon/resources/logs.js +90 -0
- package/dist/neon/resources/logs.js.map +1 -0
- package/dist/neon/resources/operations.d.ts +12 -3
- package/dist/neon/resources/operations.d.ts.map +1 -1
- package/dist/neon/resources/operations.js +5 -4
- package/dist/neon/resources/operations.js.map +1 -1
- package/dist/neon/resources/postgres.d.ts.map +1 -1
- package/dist/neon/resources/postgres.js +10 -1
- package/dist/neon/resources/postgres.js.map +1 -1
- package/dist/neon/resources/projects.d.ts +62 -5
- package/dist/neon/resources/projects.d.ts.map +1 -1
- package/dist/neon/resources/projects.js +106 -29
- package/dist/neon/resources/projects.js.map +1 -1
- package/dist/neon/resources/roles.d.ts.map +1 -1
- package/dist/neon/resources/roles.js +18 -12
- package/dist/neon/resources/roles.js.map +1 -1
- package/dist/neon/resources/snapshots.d.ts +10 -1
- package/dist/neon/resources/snapshots.d.ts.map +1 -1
- package/dist/neon/resources/snapshots.js +37 -19
- package/dist/neon/resources/snapshots.js.map +1 -1
- package/dist/neon/resources/storage.js +3 -2
- package/dist/neon/resources/storage.js.map +1 -1
- package/dist/neon/retry.d.ts +30 -8
- package/dist/neon/retry.d.ts.map +1 -1
- package/dist/neon/retry.js +59 -20
- package/dist/neon/retry.js.map +1 -1
- package/dist/neon/wait.d.ts +7 -1
- package/dist/neon/wait.d.ts.map +1 -1
- package/dist/neon/wait.js +53 -34
- package/dist/neon/wait.js.map +1 -1
- package/dist/raw.d.ts +3 -3
- package/dist/raw.js +8 -3
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -43,11 +43,12 @@ const { project, connectionString } = data;
|
|
|
43
43
|
| `waitForReadiness` | `boolean` | `false` | When `true`, mutations block until their provisioning `operations` finish, so the returned resource is ready to use. |
|
|
44
44
|
| `wait` | `{ pollIntervalMs?: number; timeoutMs?: number }` | `1000` / `300000` | Tuning for the readiness poller. |
|
|
45
45
|
| `retries` | `number` | `2` | Automatic retries on always-safe statuses (`423`, `429`, `503`) with backoff. |
|
|
46
|
+
| `requestTimeoutMs` | `number` | — (unbounded) | Deadline for a request **and** its retries. Aborts the request and resolves with a `NeonTimeoutError`. Pass `Infinity` per call to opt out of a client-wide value. Separate from `wait.timeoutMs`. |
|
|
46
47
|
| `orgId` | `string` | — | Default organization, applied to project create/list and as the transfer source org. Overridable per call. |
|
|
47
48
|
| `baseUrl` | `string` | `https://console.neon.tech/api/v2` | Override the API base URL. |
|
|
48
49
|
| `fetch` | `typeof fetch` | global `fetch` | Custom fetch implementation (proxies, tests, non-global runtimes). |
|
|
49
50
|
|
|
50
|
-
Every option except `apiKey` is also accepted **per call** via the last `options` argument (`{ throwOnError?, waitForReadiness?, signal? }`), overriding the client default.
|
|
51
|
+
Every option except `apiKey` is also accepted **per call** via the last `options` argument (`{ throwOnError?, waitForReadiness?, requestTimeoutMs?, signal? }`), overriding the client default. Paginated methods take it too, after their query.
|
|
51
52
|
|
|
52
53
|
## The result model
|
|
53
54
|
|
|
@@ -82,7 +83,8 @@ The `error` channel carries a typed hierarchy (all `Error` subclasses with a `ki
|
|
|
82
83
|
| `NeonAuthError` | `"auth"` | (401/403) |
|
|
83
84
|
| `NeonRateLimitError` | `"rate_limit"` | (429, after retries) |
|
|
84
85
|
| `NeonOperationError` | `"operation"` | `operationId`, `status` — an awaited operation failed |
|
|
85
|
-
| `NeonTimeoutError` | `"timeout"` | readiness/wait
|
|
86
|
+
| `NeonTimeoutError` | `"timeout"` | a deadline was exceeded — `requestTimeoutMs`, or the readiness/wait budget |
|
|
87
|
+
| `NeonAbortError` | `"aborted"` | the caller's `signal` fired |
|
|
86
88
|
| `NeonNetworkError` | `"network"` | `reason` — transport failure (no response) |
|
|
87
89
|
| `NeonError` | `"client"` | SDK-side errors (e.g. ambiguous connection-string selection) |
|
|
88
90
|
|
|
@@ -94,14 +96,20 @@ if (error?.kind === "not_found") { /* … */ }
|
|
|
94
96
|
Branch on `kind` rather than `name` or `message`. `name` is a stable string literal on every
|
|
95
97
|
class, so it survives bundling, but `message` is not a contract.
|
|
96
98
|
|
|
99
|
+
`kind` tells you what happened. To reach a subclass's **own** fields — `NeonNetworkError.reason`,
|
|
100
|
+
`NeonApiError.body` — narrow with `instanceof`: the result envelope types `error` as the base
|
|
101
|
+
`NeonError`, so a `kind` check alone does not make those properties visible.
|
|
102
|
+
|
|
97
103
|
`NeonNetworkError.reason` carries the most specific reason the platform gave — an `errno`
|
|
98
104
|
code such as `ECONNRESET` when one is available, otherwise the innermost non-empty message.
|
|
99
105
|
It is also interpolated into `message`, so transport faults are distinguishable in logs and
|
|
100
106
|
error trackers instead of collapsing onto one string:
|
|
101
107
|
|
|
102
108
|
```ts
|
|
109
|
+
import { NeonNetworkError } from "@neon/sdk";
|
|
110
|
+
|
|
103
111
|
const { error } = await neon.projects.get(id);
|
|
104
|
-
if (error
|
|
112
|
+
if (error instanceof NeonNetworkError) {
|
|
105
113
|
error.reason; // "ECONNRESET"
|
|
106
114
|
error.message; // 'Network error: no response received from the Neon API (ECONNRESET).'
|
|
107
115
|
}
|
|
@@ -112,6 +120,54 @@ responsibility. An empty path parameter builds a URL with an empty segment, whic
|
|
|
112
120
|
API answers with a redirect rather than a `400`; that can surface as a `"network"` error
|
|
113
121
|
rather than anything that names the argument.
|
|
114
122
|
|
|
123
|
+
## Cancellation & deadlines
|
|
124
|
+
|
|
125
|
+
Pass a `signal` to cancel a call, or `requestTimeoutMs` to bound it. Both arrive on the
|
|
126
|
+
`error` channel as typed errors — a cancelled call never rejects with a raw `DOMException`,
|
|
127
|
+
and a `throwOnError` client throws the same `NeonError` subclass it would have returned:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const controller = new AbortController();
|
|
131
|
+
const { error } = await neon.projects.list().all();
|
|
132
|
+
|
|
133
|
+
// cancel in-flight work (a user navigating away, a request handler aborting)
|
|
134
|
+
const result = await neon.projects.get(id, { signal: controller.signal });
|
|
135
|
+
if (result.error?.kind === "aborted") { /* the caller stopped it */ }
|
|
136
|
+
|
|
137
|
+
// bound a call, on the client or per call
|
|
138
|
+
const neon = createNeonClient({ apiKey, requestTimeoutMs: 30_000 });
|
|
139
|
+
const slow = await neon.projects.get(id, { requestTimeoutMs: 5_000 });
|
|
140
|
+
if (slow.error?.kind === "timeout") { /* the deadline was exceeded */ }
|
|
141
|
+
|
|
142
|
+
// opt a single call back out of a client-wide deadline
|
|
143
|
+
await neon.storage.objects.get(projectId, branchId, "bucket", "big.tar", {
|
|
144
|
+
requestTimeoutMs: Number.POSITIVE_INFINITY,
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`"aborted"` and `"timeout"` are deliberately distinct: a timeout is worth retrying, a
|
|
149
|
+
cancellation is not.
|
|
150
|
+
|
|
151
|
+
`requestTimeoutMs` must be a positive number of milliseconds up to `2147483647`, or
|
|
152
|
+
`Infinity`. Anything else — `0`, a negative, `NaN`, or a value past that range — is
|
|
153
|
+
rejected with a `client`-kind error when the client is created or the call is made, rather
|
|
154
|
+
than silently becoming an instant timeout or no timeout at all.
|
|
155
|
+
|
|
156
|
+
Cancellation reaches everything the SDK controls: the request and its retries, readiness
|
|
157
|
+
polling, each page of a paginated walk, and the multi-request `postgres.connectionString`
|
|
158
|
+
resolver. The one thing it cannot interrupt is your own code — a `snapshots.restore`
|
|
159
|
+
`preview` callback receives the signal as its second argument so it can cooperate, and the
|
|
160
|
+
restore is left un-finalized if the call is cancelled around it.
|
|
161
|
+
|
|
162
|
+
**Calls are unbounded unless you set `requestTimeoutMs`**, which is what they have always
|
|
163
|
+
been. `requestTimeoutMs` covers one request and all of its retries; readiness polling keeps
|
|
164
|
+
its own budget in `wait.timeoutMs`, so setting one does not silently cap the other.
|
|
165
|
+
|
|
166
|
+
`retries` interacts with it: a `Retry-After` is never shortened, because retrying earlier
|
|
167
|
+
than the server asked is worse than not retrying. If honouring it would take longer than
|
|
168
|
+
10s or than the remaining deadline, the SDK stops retrying and hands you the real
|
|
169
|
+
`423`/`429`/`503` instead of waiting or reporting a timeout that hides the status.
|
|
170
|
+
|
|
115
171
|
## Pagination
|
|
116
172
|
|
|
117
173
|
Cursor-paginated `list()` methods return a lazy `Paginated<T>`:
|
|
@@ -120,8 +176,17 @@ Cursor-paginated `list()` methods return a lazy `Paginated<T>`:
|
|
|
120
176
|
const { data: all } = await neon.projects.list().all(); // every page → { data, error }
|
|
121
177
|
const { data: page } = await neon.projects.list().page(); // one page
|
|
122
178
|
for await (const project of neon.projects.list()) { … } // stream; throws on a page error
|
|
179
|
+
|
|
180
|
+
// per-call options come after the query
|
|
181
|
+
const { data } = await neon.projects
|
|
182
|
+
.list({ search: "prod" }, { signal, requestTimeoutMs: 10_000 })
|
|
183
|
+
.all();
|
|
123
184
|
```
|
|
124
185
|
|
|
186
|
+
A deadline covers **one consumption** — a whole `all()`, or a whole iteration — rather than
|
|
187
|
+
each page, since that is the unit a caller waits on. A `Paginated` is lazy and reusable, so
|
|
188
|
+
consuming it twice gets a fresh deadline each time.
|
|
189
|
+
|
|
125
190
|
## Readiness & workflows
|
|
126
191
|
|
|
127
192
|
Neon mutations are asynchronous (they return `operations`). `waitForReadiness` blocks until they settle; the **workflow** methods (`createAndConnect`, `createWithCompute`) default it on and hand back a connection string in one call. The primitive is `neon.operations.waitFor(operations)`.
|
|
@@ -173,9 +238,22 @@ await neon.projects.transfer({
|
|
|
173
238
|
| `createWithCompute(projectId, input, { pooled? })` | **[W]** `{ branch, endpoint, connectionString }` | `input`: `{ name?, parentId?, compute?: { minCu?, maxCu?, suspendTimeoutSeconds? } }` |
|
|
174
239
|
| `getDefault(projectId)` | `Branch` | resolves the default branch by the `default` flag |
|
|
175
240
|
| `setDefault(projectId, branchId)` | `Branch` | |
|
|
176
|
-
| `recover(projectId, branchId)` | `Branch` | beta — recover a soft-deleted branch within the 7-day window |
|
|
177
241
|
| `finalizeRestore(projectId, branchId, { name? }?)` | **→void** | commits a restore previewed with `snapshots.restore({ finalize: false })` |
|
|
178
242
|
|
|
243
|
+
**There is no `recover`.** Neon stopped publishing `POST /projects/{project_id}/branches/{branch_id}/recover` in its OpenAPI spec, so the wrapper is gone until it returns. The endpoint still answers, so a soft-deleted branch can still be recovered through the low-level client — note that this envelope carries the API's own error body rather than a `NeonError`:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import type { BranchRecoverResponse } from "@neon/sdk";
|
|
247
|
+
|
|
248
|
+
const { data } = await neon.client.post<{ 200: BranchRecoverResponse }>({
|
|
249
|
+
url: "/projects/{project_id}/branches/{branch_id}/recover",
|
|
250
|
+
path: { project_id: projectId, branch_id: branchId },
|
|
251
|
+
});
|
|
252
|
+
const branch = data?.branch;
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
`neon.projects.recover` is a different endpoint — it recovers a deleted **project**, not a branch.
|
|
256
|
+
|
|
179
257
|
```ts
|
|
180
258
|
// Resolve the project's default ("production") branch
|
|
181
259
|
const { data: prod } = await neon.branches.getDefault(projectId);
|
|
@@ -333,6 +411,110 @@ Branch-scoped AI Gateway endpoint metadata (beta).
|
|
|
333
411
|
| --- | --- | --- |
|
|
334
412
|
| `get(projectId, branchId)` | `BranchAiGateway` | 404 when AI Gateway is not enabled on the branch |
|
|
335
413
|
|
|
414
|
+
### `neon.logs`
|
|
415
|
+
|
|
416
|
+
Branch-scoped logs from the services running on a branch — Neon Functions, object
|
|
417
|
+
storage, and Postgres computes (private beta).
|
|
418
|
+
|
|
419
|
+
Being private beta shows, and all three calls behave the same way on a given branch:
|
|
420
|
+
|
|
421
|
+
| Branch state | Response |
|
|
422
|
+
| --- | --- |
|
|
423
|
+
| Telemetry not available in the branch's region | `404`, `reason: "telemetry_not_enabled"` |
|
|
424
|
+
| Project or branch missing, or no access to it | `404`, `reason: "branch_not_found"` |
|
|
425
|
+
| Telemetry available, nothing recorded in the window | `200` with an empty `logs` / `values` array |
|
|
426
|
+
| Telemetry available, backend down | `503`, which the client retries on by default |
|
|
427
|
+
|
|
428
|
+
**The two 404s need different handling, and only `reason` tells them apart.** Telemetry is
|
|
429
|
+
region-gated and the region is fixed at project creation, so `telemetry_not_enabled` is a
|
|
430
|
+
permanent property of the branch and an ordinary outcome to design around.
|
|
431
|
+
`branch_not_found` is a real error — a wrong id or a key without access — and should not
|
|
432
|
+
be absorbed into the same path. Both arrive as `NeonNotFoundError`, and `reason` is not
|
|
433
|
+
lifted onto the error, so it has to be read off the API's body, which the SDK keeps as
|
|
434
|
+
`unknown`:
|
|
435
|
+
|
|
436
|
+
```ts
|
|
437
|
+
import { NeonNotFoundError } from "@neon/sdk";
|
|
438
|
+
|
|
439
|
+
function logsUnavailableReason(error: unknown): string | undefined {
|
|
440
|
+
if (!(error instanceof NeonNotFoundError)) return undefined;
|
|
441
|
+
const body = error.body;
|
|
442
|
+
if (typeof body !== "object" || body === null || !("reason" in body)) return undefined;
|
|
443
|
+
return typeof body.reason === "string" ? body.reason : undefined;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const { error } = await neon.logs.fields(projectId, branchId);
|
|
447
|
+
if (error) {
|
|
448
|
+
if (logsUnavailableReason(error) === "telemetry_not_enabled") {
|
|
449
|
+
// no logs on this branch, ever — carry on
|
|
450
|
+
} else throw error;
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
Two more limits worth knowing, because the spec is wider than the backend. `source` is a
|
|
455
|
+
three-value enum, but only `function` and `storage` were observed emitting; no branch
|
|
456
|
+
produced a `pg_endpoint` record. And `minimum_severity` can be rejected outright with a
|
|
457
|
+
`400` (`NeonApiError`, `kind: "api"`) reading
|
|
458
|
+
`"minimum_severity is not supported by this branch's log backend"` — so filter on
|
|
459
|
+
`severity_text` if you need it to work everywhere.
|
|
460
|
+
|
|
461
|
+
| Method | Returns | Notes |
|
|
462
|
+
| --- | --- | --- |
|
|
463
|
+
| `query(projectId, branchId, input?)` | **[P]** `ProjectBranchLogRecord` | `input`: `{ since?, start_time?, end_time?, limit?, sort_order?, source?, service_name?, scope_name?, minimum_severity?, severity_text?, body_contains?, trace_id?, logql? }` — filters combine with `AND` |
|
|
464
|
+
| `fields(projectId, branchId)` | `string[]` | field names this branch has emitted, usable as `fieldName` below |
|
|
465
|
+
| `fieldValues(projectId, branchId, fieldName, query?)` | `ProjectBranchLogFieldValuesResponse` | `query`: `{ since?, start_time?, end_time?, source?, limit? }` — check `is_truncated` |
|
|
466
|
+
|
|
467
|
+
Give the window as **either** `since` (`"30m"`, `"6h"`, `"7d"`) **or** `start_time`;
|
|
468
|
+
supplying both is rejected with `conflicting_time_range`. `logql` replaces the seven
|
|
469
|
+
content filters rather than adding to them — combining them is rejected with
|
|
470
|
+
`conflicting_filters` — while `limit`, `sort_order`, and the time window still apply
|
|
471
|
+
alongside it. Seven days is the widest range served. **The default window differs
|
|
472
|
+
between the two calls:** `query` covers the last hour, `fieldValues` the last six, so a
|
|
473
|
+
value discovered by one is not guaranteed to appear in the other.
|
|
474
|
+
|
|
475
|
+
`query` pages for you, replaying the filters unchanged as the endpoint requires. If a
|
|
476
|
+
page reports more records than it returned but no cursor to reach them, the walk fails
|
|
477
|
+
with a `client`-kind `NeonError` rather than handing back a partial result as if it
|
|
478
|
+
were complete.
|
|
479
|
+
|
|
480
|
+
```ts
|
|
481
|
+
// Errors from a function over the last 6 hours, newest first
|
|
482
|
+
const { data: errors } = await neon.logs
|
|
483
|
+
.query(projectId, branchId, {
|
|
484
|
+
since: "6h",
|
|
485
|
+
source: "function",
|
|
486
|
+
// some branches' log backends reject minimum_severity; severity_text always works
|
|
487
|
+
minimum_severity: "error",
|
|
488
|
+
})
|
|
489
|
+
.all();
|
|
490
|
+
|
|
491
|
+
// Paging replays the filters for you — the endpoint returns wrong results otherwise
|
|
492
|
+
for await (const line of neon.logs.query(projectId, branchId, { since: "1h" })) {
|
|
493
|
+
console.log(line.timestamp, line.message);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Discover what you can enumerate, then read one field's values
|
|
497
|
+
const { data: fields } = await neon.logs.fields(projectId, branchId);
|
|
498
|
+
// e.g. ["service_name", "severity_text", "scope_name", "entity_type"]
|
|
499
|
+
|
|
500
|
+
const { data: services } = await neon.logs.fieldValues(
|
|
501
|
+
projectId, branchId, "service_name", { since: "24h" },
|
|
502
|
+
);
|
|
503
|
+
console.log(services?.values);
|
|
504
|
+
if (services?.is_truncated) {
|
|
505
|
+
// an arbitrary subset — narrow `since` or `source` before filtering on it
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**`fieldName` must be a name `fields` returned.** The enumerable set and the filterable
|
|
510
|
+
set overlap rather than nest: `source` is a filter — on `query` and on `fieldValues`' own
|
|
511
|
+
query — but is not enumerable, so `fieldValues(…, "source")` answers `400` with
|
|
512
|
+
`reason: "unknown_field"`; `entity_type` is enumerable but is not a filter on `query`.
|
|
513
|
+
|
|
514
|
+
`fields` returns a bare `string[]` because its response carries nothing else.
|
|
515
|
+
`fieldValues` returns the whole response, because `is_truncated` is what decides whether
|
|
516
|
+
the values can be trusted and unwrapping would hide it.
|
|
517
|
+
|
|
336
518
|
### `neon.snapshots`
|
|
337
519
|
|
|
338
520
|
| Method | Returns | Notes |
|
|
@@ -362,7 +544,9 @@ const { data: snapshot } = await neon.snapshots.create(projectId, branchId, {
|
|
|
362
544
|
```ts
|
|
363
545
|
await neon.snapshots.restore(projectId, snapshotId, {
|
|
364
546
|
targetBranchId,
|
|
365
|
-
|
|
547
|
+
// second argument carries the call's signal; the SDK cannot interrupt your callback
|
|
548
|
+
preview: async (branch, { signal }) =>
|
|
549
|
+
(await checks(branch, { signal })) === "ok", // true → commit · false → abort
|
|
366
550
|
});
|
|
367
551
|
```
|
|
368
552
|
|
|
@@ -422,6 +606,74 @@ for await (const project of neon.consumption.perProject({
|
|
|
422
606
|
| `user.me()` | `CurrentUserInfoResponse` |
|
|
423
607
|
| `user.organizations()` | `Organization[]` |
|
|
424
608
|
|
|
609
|
+
### `neon.auth`
|
|
610
|
+
|
|
611
|
+
Branch-scoped Neon Auth (the legacy project-scoped endpoints are deprecated and stay raw-only).
|
|
612
|
+
|
|
613
|
+
| Method | Returns | Notes |
|
|
614
|
+
| --- | --- | --- |
|
|
615
|
+
| `get(projectId, branchId)` | `NeonAuthIntegration` | |
|
|
616
|
+
| `create(projectId, branchId, input)` | `NeonAuthCreateIntegrationResponse` | enable the integration |
|
|
617
|
+
| `disable(projectId, branchId, { deleteData? }?)` | **→void** | |
|
|
618
|
+
| `updateConfig(projectId, branchId, input)` | `NeonAuthConfigResponse` | |
|
|
619
|
+
| `oauthProviders.list / add / update / delete` | `NeonAuthOauthProvider`(`[]`) / **→void** | |
|
|
620
|
+
| `trustedDomains.list / add / delete` | `NeonAuthRedirectUriWhitelistDomain[]` / **→void** | redirect-URI whitelist |
|
|
621
|
+
| `users.create / delete / updateRole` | `NeonAuthCreateNewUserResponse` / **→void** / role | |
|
|
622
|
+
|
|
623
|
+
### `neon.projects.permissions`
|
|
624
|
+
|
|
625
|
+
| Method | Returns |
|
|
626
|
+
| --- | --- |
|
|
627
|
+
| `list(projectId)` | `ProjectPermission[]` |
|
|
628
|
+
| `grant(projectId, email)` | `ProjectPermission` |
|
|
629
|
+
| `revoke(projectId, permissionId)` | `ProjectPermission` |
|
|
630
|
+
|
|
631
|
+
For an **org-owned** project, roles for existing organization members live on
|
|
632
|
+
`neon.projects.members` below instead.
|
|
633
|
+
|
|
634
|
+
### `neon.projects.members`
|
|
635
|
+
|
|
636
|
+
Per-project roles for members of the **owning organization**. Distinct from
|
|
637
|
+
`neon.projects.permissions`, which shares a project with an individual by email: these
|
|
638
|
+
act on existing org members by member id, and clearing a grant leaves the member's
|
|
639
|
+
organization-role default in force rather than removing their access. Org-owned projects
|
|
640
|
+
only — a personal project answers 404.
|
|
641
|
+
|
|
642
|
+
| Method | Returns | Notes |
|
|
643
|
+
| --- | --- | --- |
|
|
644
|
+
| `list(projectId, query?)` | **[P]** `ProjectMember` | `query`: `{ limit? }` |
|
|
645
|
+
| `setRole(projectId, memberId, role, { confirmSelfDemotion? }?)` | `ProjectMemberRoleResponse` | `role`: `"viewer" \| "editor" \| "admin"`; idempotent |
|
|
646
|
+
| `removeRole(projectId, memberId, { confirmSelfLockout? }?)` | `ProjectMemberRoleResponse` | clears the explicit grant; idempotent |
|
|
647
|
+
|
|
648
|
+
A `ProjectMember` carries several role-ish fields, and they are not interchangeable.
|
|
649
|
+
**Read `effective_project_permission`** for "what can this member actually do" — `VIEWER`
|
|
650
|
+
/ `EDITOR` / `ADMIN`, uppercase. `org_default_project_permission` and
|
|
651
|
+
`explicit_project_permission` are the two inputs it was resolved from, and `grant_source`
|
|
652
|
+
says which one won (`explicit`, `org_role_default`, `org_admin_override`, `unassigned`).
|
|
653
|
+
|
|
654
|
+
The two lowercase fields are a different axis: `project_role` is the explicit grant you
|
|
655
|
+
set with `setRole` and shares its `"viewer" | "editor" | "admin"` type, and `org_role` is
|
|
656
|
+
the member's organization role. Reading back `project_role` after a `setRole` tells you
|
|
657
|
+
the grant landed — it does **not** tell you the member's effective access, which the
|
|
658
|
+
org-role default can still exceed.
|
|
659
|
+
|
|
660
|
+
The two confirmations are **off by default** so a call cannot silently cost you access to
|
|
661
|
+
your own project. Pass one only when you mean to lower your own role
|
|
662
|
+
(`confirmSelfDemotion`) or to drop your own grant when that removes your management
|
|
663
|
+
access (`confirmSelfLockout`); without it the API rejects the call.
|
|
664
|
+
|
|
665
|
+
```ts
|
|
666
|
+
const { data: grant } = await neon.projects.members.setRole(
|
|
667
|
+
projectId, memberId, "editor",
|
|
668
|
+
);
|
|
669
|
+
// A downgrade can leave credentials the member still holds
|
|
670
|
+
if (grant?.credential_rotation_recommended) { /* rotate database credentials */ }
|
|
671
|
+
if (grant?.org_api_key_rotation_recommended) { /* rotate project-scoped org keys */ }
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
Also on `neon.projects`: `recover(id)` (beta — recover a soft-deleted project), and on
|
|
675
|
+
`neon.postgres.endpoints`: `listByBranch(projectId, branchId)` → `Endpoint[]`.
|
|
676
|
+
|
|
425
677
|
---
|
|
426
678
|
|
|
427
679
|
## Raw layer (every endpoint, 1:1)
|
|
@@ -458,31 +710,6 @@ underlying configured Fetch client; `raw.*` are the wrapped generated functions,
|
|
|
458
710
|
request/response/error **types** are re-exported flat from `@neon/sdk` for
|
|
459
711
|
`import type { Project, Branch, … }`.
|
|
460
712
|
|
|
461
|
-
### `neon.auth`
|
|
462
|
-
|
|
463
|
-
Branch-scoped Neon Auth (the legacy project-scoped endpoints are deprecated and stay raw-only).
|
|
464
|
-
|
|
465
|
-
| Method | Returns | Notes |
|
|
466
|
-
| --- | --- | --- |
|
|
467
|
-
| `get(projectId, branchId)` | `NeonAuthIntegration` | |
|
|
468
|
-
| `create(projectId, branchId, input)` | `NeonAuthCreateIntegrationResponse` | enable the integration |
|
|
469
|
-
| `disable(projectId, branchId, { deleteData? }?)` | **→void** | |
|
|
470
|
-
| `updateConfig(projectId, branchId, input)` | `NeonAuthConfigResponse` | |
|
|
471
|
-
| `oauthProviders.list / add / update / delete` | `NeonAuthOauthProvider`(`[]`) / **→void** | |
|
|
472
|
-
| `trustedDomains.list / add / delete` | `NeonAuthRedirectUriWhitelistDomain[]` / **→void** | redirect-URI whitelist |
|
|
473
|
-
| `users.create / delete / updateRole` | `NeonAuthCreateNewUserResponse` / **→void** / role | |
|
|
474
|
-
|
|
475
|
-
### `neon.projects.permissions`
|
|
476
|
-
|
|
477
|
-
| Method | Returns |
|
|
478
|
-
| --- | --- |
|
|
479
|
-
| `list(projectId)` | `ProjectPermission[]` |
|
|
480
|
-
| `grant(projectId, email)` | `ProjectPermission` |
|
|
481
|
-
| `revoke(projectId, permissionId)` | `ProjectPermission` |
|
|
482
|
-
|
|
483
|
-
Also on `neon.projects`: `recover(id)` (beta — recover a soft-deleted project), and on
|
|
484
|
-
`neon.postgres.endpoints`: `listByBranch(projectId, branchId)` → `Endpoint[]`.
|
|
485
|
-
|
|
486
713
|
## Regenerating the client
|
|
487
714
|
|
|
488
715
|
The client is generated from a vendored, pinned copy of the spec in [`spec/neon-openapi.json`](./spec/neon-openapi.json) using [`@hey-api/openapi-ts`](https://heyapi.dev).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.gen.js","names":[],"sources":["../../../src/client/client/client.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport { createSseClient } from '../core/serverSentEvents.gen.js';\nimport type { HttpMethod } from '../core/types.gen.js';\nimport { getValidRequestBody } from '../core/utils.gen.js';\nimport type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen.js';\nimport {\n buildUrl,\n createConfig,\n createInterceptors,\n getParseAs,\n mergeConfigs,\n mergeHeaders,\n setAuthParams,\n} from './utils.gen.js';\n\ntype ReqInit = Omit<RequestInit, 'body' | 'headers'> & {\n body?: any;\n headers: ReturnType<typeof mergeHeaders>;\n};\n\nexport const createClient = (config: Config = {}): Client => {\n let _config = mergeConfigs(createConfig(), config);\n\n const getConfig = (): Config => ({ ..._config });\n\n const setConfig = (config: Config): Config => {\n _config = mergeConfigs(_config, config);\n return getConfig();\n };\n\n const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();\n\n const beforeRequest = async <\n TData = unknown,\n TResponseStyle extends 'data' | 'fields' = 'fields',\n ThrowOnError extends boolean = boolean,\n Url extends string = string,\n >(\n options: RequestOptions<TData, TResponseStyle, ThrowOnError, Url>,\n ) => {\n const opts = {\n ..._config,\n ...options,\n fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,\n headers: mergeHeaders(_config.headers, options.headers),\n serializedBody: undefined as string | undefined,\n };\n\n if (opts.security) {\n await setAuthParams(opts);\n }\n\n if (opts.requestValidator) {\n await opts.requestValidator(opts);\n }\n\n if (opts.body !== undefined && opts.bodySerializer) {\n opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;\n }\n\n // remove Content-Type header if body is empty to avoid sending invalid requests\n if (opts.body === undefined || opts.serializedBody === '') {\n opts.headers.delete('Content-Type');\n }\n\n const resolvedOpts = opts as typeof opts &\n ResolvedRequestOptions<TResponseStyle, ThrowOnError, Url>;\n const url = buildUrl(resolvedOpts);\n\n return { opts: resolvedOpts, url };\n };\n\n const request: Client['request'] = async (options) => {\n const throwOnError = options.throwOnError ?? _config.throwOnError;\n const responseStyle = options.responseStyle ?? _config.responseStyle;\n\n let request: Request | undefined;\n let response: Response | undefined;\n\n try {\n const { opts, url } = await beforeRequest(options);\n const requestInit: ReqInit = {\n redirect: 'follow',\n ...opts,\n body: getValidRequestBody(opts),\n };\n\n request = new Request(url, requestInit);\n\n for (const fn of interceptors.request.fns) {\n if (fn) {\n request = await fn(request, opts);\n }\n }\n\n // fetch must be assigned here, otherwise it would throw the error:\n // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation\n const _fetch = opts.fetch!;\n\n response = await _fetch(request);\n\n for (const fn of interceptors.response.fns) {\n if (fn) {\n response = await fn(response, request, opts);\n }\n }\n\n const result = {\n request,\n response,\n };\n\n if (response.ok) {\n const parseAs =\n (opts.parseAs === 'auto'\n ? getParseAs(response.headers.get('Content-Type'))\n : opts.parseAs) ?? 'json';\n\n if (response.status === 204 || response.headers.get('Content-Length') === '0') {\n let emptyData: any;\n switch (parseAs) {\n case 'arrayBuffer':\n case 'blob':\n case 'text':\n emptyData = await response[parseAs]();\n break;\n case 'formData':\n emptyData = new FormData();\n break;\n case 'stream':\n emptyData = response.body;\n break;\n case 'json':\n default:\n emptyData = {};\n break;\n }\n return opts.responseStyle === 'data'\n ? emptyData\n : {\n data: emptyData,\n ...result,\n };\n }\n\n let data: any;\n switch (parseAs) {\n case 'arrayBuffer':\n case 'blob':\n case 'formData':\n case 'text':\n data = await response[parseAs]();\n break;\n case 'json': {\n // Some servers return 200 with no Content-Length and empty body.\n // response.json() would throw; read as text and parse if non-empty.\n const text = await response.text();\n data = text ? JSON.parse(text) : {};\n break;\n }\n case 'stream':\n return opts.responseStyle === 'data'\n ? response.body\n : {\n data: response.body,\n ...result,\n };\n }\n\n if (parseAs === 'json') {\n if (opts.responseValidator) {\n await opts.responseValidator(data);\n }\n\n if (opts.responseTransformer) {\n data = await opts.responseTransformer(data);\n }\n }\n\n return opts.responseStyle === 'data'\n ? data\n : {\n data,\n ...result,\n };\n }\n\n const textError = await response.text();\n let jsonError: unknown;\n\n try {\n jsonError = JSON.parse(textError);\n } catch {\n // noop\n }\n\n throw jsonError ?? textError;\n } catch (error) {\n let finalError = error;\n\n for (const fn of interceptors.error.fns) {\n if (fn) {\n finalError = await fn(finalError, response, request, options as ResolvedRequestOptions);\n }\n }\n\n finalError = finalError || {};\n\n if (throwOnError) {\n throw finalError;\n }\n\n // TODO: we probably want to return error and improve types\n return responseStyle === 'data'\n ? undefined\n : {\n error: finalError,\n request,\n response,\n };\n }\n };\n\n const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>\n request({ ...options, method });\n\n const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {\n const { opts, url } = await beforeRequest(options);\n return createSseClient({\n ...opts,\n body: opts.body as BodyInit | null | undefined,\n method,\n onRequest: async (url, init) => {\n let request = new Request(url, init);\n for (const fn of interceptors.request.fns) {\n if (fn) {\n request = await fn(request, opts);\n }\n }\n return request;\n },\n serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,\n url,\n });\n };\n\n const _buildUrl: Client['buildUrl'] = (options) => buildUrl({ ..._config, ...options });\n\n return {\n buildUrl: _buildUrl,\n connect: makeMethodFn('CONNECT'),\n delete: makeMethodFn('DELETE'),\n get: makeMethodFn('GET'),\n getConfig,\n head: makeMethodFn('HEAD'),\n interceptors,\n options: makeMethodFn('OPTIONS'),\n patch: makeMethodFn('PATCH'),\n post: makeMethodFn('POST'),\n put: makeMethodFn('PUT'),\n request,\n setConfig,\n sse: {\n connect: makeSseFn('CONNECT'),\n delete: makeSseFn('DELETE'),\n get: makeSseFn('GET'),\n head: makeSseFn('HEAD'),\n options: makeSseFn('OPTIONS'),\n patch: makeSseFn('PATCH'),\n post: makeSseFn('POST'),\n put: makeSseFn('PUT'),\n trace: makeSseFn('TRACE'),\n },\n trace: makeMethodFn('TRACE'),\n } as Client;\n};\n"],"mappings":";;;;AAqBA,MAAa,gBAAgB,SAAiB,CAAC,MAAc;CAC3D,IAAI,UAAU,aAAa,aAAa,GAAG,MAAM;CAEjD,MAAM,mBAA2B,EAAE,GAAG,QAAQ;CAE9C,MAAM,aAAa,WAA2B;EAC5C,UAAU,aAAa,SAAS,MAAM;EACtC,OAAO,UAAU;CACnB;CAEA,MAAM,eAAe,mBAAuE;CAE5F,MAAM,gBAAgB,OAMpB,YACG;EACH,MAAM,OAAO;GACX,GAAG;GACH,GAAG;GACH,OAAO,QAAQ,SAAS,QAAQ,SAAS,WAAW;GACpD,SAAS,aAAa,QAAQ,SAAS,QAAQ,OAAO;GACtD,gBAAgB,KAAA;EAClB;EAEA,IAAI,KAAK,UACP,MAAM,cAAc,IAAI;EAG1B,IAAI,KAAK,kBACP,MAAM,KAAK,iBAAiB,IAAI;EAGlC,IAAI,KAAK,SAAS,KAAA,KAAa,KAAK,gBAClC,KAAK,iBAAiB,KAAK,eAAe,KAAK,IAAI;EAIrD,IAAI,KAAK,SAAS,KAAA,KAAa,KAAK,mBAAmB,IACrD,KAAK,QAAQ,OAAO,cAAc;EAGpC,MAAM,eAAe;EAIrB,OAAO;GAAE,MAAM;GAAc,KAFjB,SAAS,YAEU;EAAE;CACnC;CAEA,MAAM,UAA6B,OAAO,YAAY;EACpD,MAAM,eAAe,QAAQ,gBAAgB,QAAQ;EACrD,MAAM,gBAAgB,QAAQ,iBAAiB,QAAQ;EAEvD,IAAI;EACJ,IAAI;EAEJ,IAAI;GACF,MAAM,EAAE,MAAM,QAAQ,MAAM,cAAc,OAAO;GACjD,MAAM,cAAuB;IAC3B,UAAU;IACV,GAAG;IACH,MAAM,oBAAoB,IAAI;GAChC;GAEA,UAAU,IAAI,QAAQ,KAAK,WAAW;GAEtC,KAAK,MAAM,MAAM,aAAa,QAAQ,KACpC,IAAI,IACF,UAAU,MAAM,GAAG,SAAS,IAAI;GAMpC,MAAM,SAAS,KAAK;GAEpB,WAAW,MAAM,OAAO,OAAO;GAE/B,KAAK,MAAM,MAAM,aAAa,SAAS,KACrC,IAAI,IACF,WAAW,MAAM,GAAG,UAAU,SAAS,IAAI;GAI/C,MAAM,SAAS;IACb;IACA;GACF;GAEA,IAAI,SAAS,IAAI;IACf,MAAM,WACH,KAAK,YAAY,SACd,WAAW,SAAS,QAAQ,IAAI,cAAc,CAAC,IAC/C,KAAK,YAAY;IAEvB,IAAI,SAAS,WAAW,OAAO,SAAS,QAAQ,IAAI,gBAAgB,MAAM,KAAK;KAC7E,IAAI;KACJ,QAAQ,SAAR;MACE,KAAK;MACL,KAAK;MACL,KAAK;OACH,YAAY,MAAM,SAAS,QAAQ,CAAC;OACpC;MACF,KAAK;OACH,YAAY,IAAI,SAAS;OACzB;MACF,KAAK;OACH,YAAY,SAAS;OACrB;MAEF;OACE,YAAY,CAAC;OACb;KACJ;KACA,OAAO,KAAK,kBAAkB,SAC1B,YACA;MACE,MAAM;MACN,GAAG;KACL;IACN;IAEA,IAAI;IACJ,QAAQ,SAAR;KACE,KAAK;KACL,KAAK;KACL,KAAK;KACL,KAAK;MACH,OAAO,MAAM,SAAS,QAAQ,CAAC;MAC/B;KACF,KAAK,QAAQ;MAGX,MAAM,OAAO,MAAM,SAAS,KAAK;MACjC,OAAO,OAAO,KAAK,MAAM,IAAI,IAAI,CAAC;MAClC;KACF;KACA,KAAK,UACH,OAAO,KAAK,kBAAkB,SAC1B,SAAS,OACT;MACE,MAAM,SAAS;MACf,GAAG;KACL;IACR;IAEA,IAAI,YAAY,QAAQ;KACtB,IAAI,KAAK,mBACP,MAAM,KAAK,kBAAkB,IAAI;KAGnC,IAAI,KAAK,qBACP,OAAO,MAAM,KAAK,oBAAoB,IAAI;IAE9C;IAEA,OAAO,KAAK,kBAAkB,SAC1B,OACA;KACE;KACA,GAAG;IACL;GACN;GAEA,MAAM,YAAY,MAAM,SAAS,KAAK;GACtC,IAAI;GAEJ,IAAI;IACF,YAAY,KAAK,MAAM,SAAS;GAClC,QAAQ,CAER;GAEA,MAAM,aAAa;EACrB,SAAS,OAAO;GACd,IAAI,aAAa;GAEjB,KAAK,MAAM,MAAM,aAAa,MAAM,KAClC,IAAI,IACF,aAAa,MAAM,GAAG,YAAY,UAAU,SAAS,OAAiC;GAI1F,aAAa,cAAc,CAAC;GAE5B,IAAI,cACF,MAAM;GAIR,OAAO,kBAAkB,SACrB,KAAA,IACA;IACE,OAAO;IACP;IACA;GACF;EACN;CACF;CAEA,MAAM,gBAAgB,YAAmC,YACvD,QAAQ;EAAE,GAAG;EAAS;CAAO,CAAC;CAEhC,MAAM,aAAa,WAAkC,OAAO,YAA4B;EACtF,MAAM,EAAE,MAAM,QAAQ,MAAM,cAAc,OAAO;EACjD,OAAO,gBAAgB;GACrB,GAAG;GACH,MAAM,KAAK;GACX;GACA,WAAW,OAAO,KAAK,SAAS;IAC9B,IAAI,UAAU,IAAI,QAAQ,KAAK,IAAI;IACnC,KAAK,MAAM,MAAM,aAAa,QAAQ,KACpC,IAAI,IACF,UAAU,MAAM,GAAG,SAAS,IAAI;IAGpC,OAAO;GACT;GACA,gBAAgB,oBAAoB,IAAI;GACxC;EACF,CAAC;CACH;CAEA,MAAM,aAAiC,YAAY,SAAS;EAAE,GAAG;EAAS,GAAG;CAAQ,CAAC;CAEtF,OAAO;EACL,UAAU;EACV,SAAS,aAAa,SAAS;EAC/B,QAAQ,aAAa,QAAQ;EAC7B,KAAK,aAAa,KAAK;EACvB;EACA,MAAM,aAAa,MAAM;EACzB;EACA,SAAS,aAAa,SAAS;EAC/B,OAAO,aAAa,OAAO;EAC3B,MAAM,aAAa,MAAM;EACzB,KAAK,aAAa,KAAK;EACvB;EACA;EACA,KAAK;GACH,SAAS,UAAU,SAAS;GAC5B,QAAQ,UAAU,QAAQ;GAC1B,KAAK,UAAU,KAAK;GACpB,MAAM,UAAU,MAAM;GACtB,SAAS,UAAU,SAAS;GAC5B,OAAO,UAAU,OAAO;GACxB,MAAM,UAAU,MAAM;GACtB,KAAK,UAAU,KAAK;GACpB,OAAO,UAAU,OAAO;EAC1B;EACA,OAAO,aAAa,OAAO;CAC7B;AACF"}
|
|
1
|
+
{"version":3,"file":"client.gen.js","names":[],"sources":["../../../src/client/client/client.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport { createSseClient } from '../core/serverSentEvents.gen.js';\nimport type { HttpMethod } from '../core/types.gen.js';\nimport { getValidRequestBody } from '../core/utils.gen.js';\nimport type { Client, Config, RequestOptions, ResolvedRequestOptions } from './types.gen.js';\nimport {\n buildUrl,\n createConfig,\n createInterceptors,\n getParseAs,\n mergeConfigs,\n mergeHeaders,\n setAuthParams,\n} from './utils.gen.js';\n\ntype ReqInit = Omit<RequestInit, 'body' | 'headers'> & {\n body?: any;\n headers: ReturnType<typeof mergeHeaders>;\n};\n\nexport const createClient = (config: Config = {}): Client => {\n let _config = mergeConfigs(createConfig(), config);\n\n const getConfig = (): Config => ({ ..._config });\n\n const setConfig = (config: Config): Config => {\n _config = mergeConfigs(_config, config);\n return getConfig();\n };\n\n const interceptors = createInterceptors<Request, Response, unknown, ResolvedRequestOptions>();\n\n const beforeRequest = async <\n TData = unknown,\n TResponseStyle extends 'data' | 'fields' = 'fields',\n ThrowOnError extends boolean = boolean,\n Url extends string = string,\n >(\n options: RequestOptions<TData, TResponseStyle, ThrowOnError, Url>,\n ) => {\n const opts = {\n ..._config,\n ...options,\n fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,\n headers: mergeHeaders(_config.headers, options.headers),\n serializedBody: undefined as string | undefined,\n };\n\n if (opts.security) {\n await setAuthParams(opts);\n }\n\n if (opts.requestValidator) {\n await opts.requestValidator(opts);\n }\n\n if (opts.body !== undefined && opts.bodySerializer) {\n opts.serializedBody = opts.bodySerializer(opts.body) as string | undefined;\n }\n\n // remove Content-Type header if body is empty to avoid sending invalid requests\n if (opts.body === undefined || opts.serializedBody === '') {\n opts.headers.delete('Content-Type');\n }\n\n const resolvedOpts = opts as typeof opts &\n ResolvedRequestOptions<TResponseStyle, ThrowOnError, Url>;\n const url = buildUrl(resolvedOpts);\n\n return { opts: resolvedOpts, url };\n };\n\n const request: Client['request'] = async (options) => {\n const throwOnError = options.throwOnError ?? _config.throwOnError;\n const responseStyle = options.responseStyle ?? _config.responseStyle;\n\n let request: Request | undefined;\n let response: Response | undefined;\n\n try {\n const { opts, url } = await beforeRequest(options);\n const requestInit: ReqInit = {\n redirect: 'follow',\n ...opts,\n body: getValidRequestBody(opts),\n };\n\n request = new Request(url, requestInit);\n\n for (const fn of interceptors.request.fns) {\n if (fn) {\n request = await fn(request, opts);\n }\n }\n\n // fetch must be assigned here, otherwise it would throw the error:\n // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation\n const _fetch = opts.fetch!;\n\n response = await _fetch(request);\n\n for (const fn of interceptors.response.fns) {\n if (fn) {\n response = await fn(response, request, opts);\n }\n }\n\n const result = {\n request,\n response,\n };\n\n if (response.ok) {\n const parseAs =\n (opts.parseAs === 'auto'\n ? getParseAs(response.headers.get('Content-Type'))\n : opts.parseAs) ?? 'json';\n\n if (response.status === 204 || response.headers.get('Content-Length') === '0') {\n let emptyData: any;\n switch (parseAs) {\n case 'arrayBuffer':\n case 'blob':\n case 'text':\n emptyData = await response[parseAs]();\n break;\n case 'formData':\n emptyData = new FormData();\n break;\n case 'stream':\n emptyData = response.body;\n break;\n case 'json':\n default:\n emptyData = {};\n break;\n }\n return opts.responseStyle === 'data'\n ? emptyData\n : {\n data: emptyData,\n ...result,\n };\n }\n\n let data: any;\n switch (parseAs) {\n case 'arrayBuffer':\n case 'blob':\n case 'formData':\n case 'text':\n data = await response[parseAs]();\n break;\n case 'json': {\n // Some servers return 200 with no Content-Length and empty body.\n // response.json() would throw; read as text and parse if non-empty.\n const text = await response.text();\n data = text ? JSON.parse(text) : {};\n break;\n }\n case 'stream':\n return opts.responseStyle === 'data'\n ? response.body\n : {\n data: response.body,\n ...result,\n };\n }\n\n if (parseAs === 'json') {\n if (opts.responseValidator) {\n await opts.responseValidator(data);\n }\n\n if (opts.responseTransformer) {\n data = await opts.responseTransformer(data);\n }\n }\n\n return opts.responseStyle === 'data'\n ? data\n : {\n data,\n ...result,\n };\n }\n\n const textError = await response.text();\n let jsonError: unknown;\n\n try {\n jsonError = JSON.parse(textError);\n } catch {\n // noop\n }\n\n throw jsonError ?? textError;\n } catch (error) {\n let finalError = error;\n\n for (const fn of interceptors.error.fns) {\n if (fn) {\n finalError = await fn(finalError, response, request, options as ResolvedRequestOptions);\n }\n }\n\n finalError = finalError || {};\n\n if (throwOnError) {\n throw finalError;\n }\n\n // TODO: we probably want to return error and improve types\n return responseStyle === 'data'\n ? undefined\n : {\n error: finalError,\n request,\n response,\n };\n }\n };\n\n const makeMethodFn = (method: Uppercase<HttpMethod>) => (options: RequestOptions) =>\n request({ ...options, method });\n\n const makeSseFn = (method: Uppercase<HttpMethod>) => async (options: RequestOptions) => {\n const { opts, url } = await beforeRequest(options);\n return createSseClient({\n ...opts,\n body: opts.body as BodyInit | null | undefined,\n method,\n onRequest: async (url, init) => {\n let request = new Request(url, init);\n for (const fn of interceptors.request.fns) {\n if (fn) {\n request = await fn(request, opts);\n }\n }\n return request;\n },\n serializedBody: getValidRequestBody(opts) as BodyInit | null | undefined,\n url,\n });\n };\n\n const _buildUrl: Client['buildUrl'] = (options) => buildUrl({ ..._config, ...options });\n\n return {\n buildUrl: _buildUrl,\n connect: makeMethodFn('CONNECT'),\n delete: makeMethodFn('DELETE'),\n get: makeMethodFn('GET'),\n getConfig,\n head: makeMethodFn('HEAD'),\n interceptors,\n options: makeMethodFn('OPTIONS'),\n patch: makeMethodFn('PATCH'),\n post: makeMethodFn('POST'),\n put: makeMethodFn('PUT'),\n request,\n setConfig,\n sse: {\n connect: makeSseFn('CONNECT'),\n delete: makeSseFn('DELETE'),\n get: makeSseFn('GET'),\n head: makeSseFn('HEAD'),\n options: makeSseFn('OPTIONS'),\n patch: makeSseFn('PATCH'),\n post: makeSseFn('POST'),\n put: makeSseFn('PUT'),\n trace: makeSseFn('TRACE'),\n },\n trace: makeMethodFn('TRACE'),\n } as Client;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.gen.js","names":[],"sources":["../../../src/client/client/utils.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport { getAuthToken } from '../core/auth.gen.js';\nimport type { QuerySerializerOptions } from '../core/bodySerializer.gen.js';\nimport { jsonBodySerializer } from '../core/bodySerializer.gen.js';\nimport {\n serializeArrayParam,\n serializeObjectParam,\n serializePrimitiveParam,\n} from '../core/pathSerializer.gen.js';\nimport { getUrl } from '../core/utils.gen.js';\nimport type { Client, ClientOptions, Config, RequestOptions } from './types.gen.js';\n\nexport const createQuerySerializer = <T = unknown>({\n parameters = {},\n ...args\n}: QuerySerializerOptions = {}): ((queryParams: T) => string) => {\n const querySerializer = (queryParams: T): string => {\n const search: string[] = [];\n if (queryParams && typeof queryParams === 'object') {\n for (const name in queryParams) {\n const value = queryParams[name];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const options = parameters[name] || args;\n\n if (Array.isArray(value)) {\n const serializedArray = serializeArrayParam({\n allowReserved: options.allowReserved,\n explode: true,\n name,\n style: 'form',\n value,\n ...options.array,\n });\n if (serializedArray) search.push(serializedArray);\n } else if (typeof value === 'object') {\n const serializedObject = serializeObjectParam({\n allowReserved: options.allowReserved,\n explode: true,\n name,\n style: 'deepObject',\n value: value as Record<string, unknown>,\n ...options.object,\n });\n if (serializedObject) search.push(serializedObject);\n } else {\n const serializedPrimitive = serializePrimitiveParam({\n allowReserved: options.allowReserved,\n name,\n value: value as string,\n });\n if (serializedPrimitive) search.push(serializedPrimitive);\n }\n }\n }\n return search.join('&');\n };\n return querySerializer;\n};\n\n/**\n * Infers parseAs value from provided Content-Type header.\n */\nexport const getParseAs = (contentType: string | null): Exclude<Config['parseAs'], 'auto'> => {\n if (!contentType) {\n // If no Content-Type header is provided, the best we can do is return the raw response body,\n // which is effectively the same as the 'stream' option.\n return 'stream';\n }\n\n const cleanContent = contentType.split(';')[0]?.trim();\n\n if (!cleanContent) {\n return;\n }\n\n if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) {\n return 'json';\n }\n\n if (cleanContent === 'multipart/form-data') {\n return 'formData';\n }\n\n if (\n ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type))\n ) {\n return 'blob';\n }\n\n if (cleanContent.startsWith('text/')) {\n return 'text';\n }\n\n return;\n};\n\nconst checkForExistence = (\n options: Pick<RequestOptions, 'auth' | 'query'> & {\n headers: Headers;\n },\n name?: string,\n): boolean => {\n if (!name) {\n return false;\n }\n if (\n options.headers.has(name) ||\n options.query?.[name] ||\n options.headers.get('Cookie')?.includes(`${name}=`)\n ) {\n return true;\n }\n return false;\n};\n\nexport async function setAuthParams(\n options: Pick<RequestOptions, 'auth' | 'query' | 'security'> & {\n headers: Headers;\n },\n): Promise<void> {\n for (const auth of options.security ?? []) {\n if (checkForExistence(options, auth.name)) {\n continue;\n }\n\n const token = await getAuthToken(auth, options.auth);\n\n if (!token) {\n continue;\n }\n\n const name = auth.name ?? 'Authorization';\n\n switch (auth.in) {\n case 'query':\n if (!options.query) {\n options.query = {};\n }\n options.query[name] = token;\n break;\n case 'cookie':\n options.headers.append('Cookie', `${name}=${token}`);\n break;\n case 'header':\n default:\n options.headers.set(name, token);\n break;\n }\n }\n}\n\nexport const buildUrl: Client['buildUrl'] = (options) =>\n getUrl({\n baseUrl: options.baseUrl as string,\n path: options.path,\n query: options.query,\n querySerializer:\n typeof options.querySerializer === 'function'\n ? options.querySerializer\n : createQuerySerializer(options.querySerializer),\n url: options.url,\n });\n\nexport const mergeConfigs = (a: Config, b: Config): Config => {\n const config = { ...a, ...b };\n if (config.baseUrl?.endsWith('/')) {\n config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);\n }\n config.headers = mergeHeaders(a.headers, b.headers);\n return config;\n};\n\nconst headersEntries = (headers: Headers): Array<[string, string]> => {\n const entries: Array<[string, string]> = [];\n headers.forEach((value, key) => {\n entries.push([key, value]);\n });\n return entries;\n};\n\nexport const mergeHeaders = (\n ...headers: Array<Required<Config>['headers'] | undefined>\n): Headers => {\n const mergedHeaders = new Headers();\n for (const header of headers) {\n if (!header) {\n continue;\n }\n\n const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);\n\n for (const [key, value] of iterator) {\n if (value === null) {\n mergedHeaders.delete(key);\n } else if (Array.isArray(value)) {\n for (const v of value) {\n mergedHeaders.append(key, v as string);\n }\n } else if (value !== undefined) {\n // assume object headers are meant to be JSON stringified, i.e., their\n // content value in OpenAPI specification is 'application/json'\n mergedHeaders.set(\n key,\n typeof value === 'object' ? JSON.stringify(value) : (value as string),\n );\n }\n }\n }\n return mergedHeaders;\n};\n\ntype ErrInterceptor<Err, Res, Req, Options> = (\n error: Err,\n /** response may be undefined due to a network error where no response object is produced */\n response: Res | undefined,\n /** request may be undefined, because error may be from building the request object itself */\n request: Req | undefined,\n options: Options,\n) => Err | Promise<Err>;\n\ntype ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;\n\ntype ResInterceptor<Res, Req, Options> = (\n response: Res,\n request: Req,\n options: Options,\n) => Res | Promise<Res>;\n\nclass Interceptors<Interceptor> {\n fns: Array<Interceptor | null> = [];\n\n clear(): void {\n this.fns = [];\n }\n\n eject(id: number | Interceptor): void {\n const index = this.getInterceptorIndex(id);\n if (this.fns[index]) {\n this.fns[index] = null;\n }\n }\n\n exists(id: number | Interceptor): boolean {\n const index = this.getInterceptorIndex(id);\n return Boolean(this.fns[index]);\n }\n\n getInterceptorIndex(id: number | Interceptor): number {\n if (typeof id === 'number') {\n return this.fns[id] ? id : -1;\n }\n return this.fns.indexOf(id);\n }\n\n update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false {\n const index = this.getInterceptorIndex(id);\n if (this.fns[index]) {\n this.fns[index] = fn;\n return id;\n }\n return false;\n }\n\n use(fn: Interceptor): number {\n this.fns.push(fn);\n return this.fns.length - 1;\n }\n}\n\nexport interface Middleware<Req, Res, Err, Options> {\n error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;\n request: Interceptors<ReqInterceptor<Req, Options>>;\n response: Interceptors<ResInterceptor<Res, Req, Options>>;\n}\n\nexport const createInterceptors = <Req, Res, Err, Options>(): Middleware<\n Req,\n Res,\n Err,\n Options\n> => ({\n error: new Interceptors<ErrInterceptor<Err, Res, Req, Options>>(),\n request: new Interceptors<ReqInterceptor<Req, Options>>(),\n response: new Interceptors<ResInterceptor<Res, Req, Options>>(),\n});\n\nconst defaultQuerySerializer = createQuerySerializer({\n allowReserved: false,\n array: {\n explode: true,\n style: 'form',\n },\n object: {\n explode: true,\n style: 'deepObject',\n },\n});\n\nconst defaultHeaders = {\n 'Content-Type': 'application/json',\n};\n\nexport const createConfig = <T extends ClientOptions = ClientOptions>(\n override: Config<Omit<ClientOptions, keyof T> & T> = {},\n): Config<Omit<ClientOptions, keyof T> & T> => ({\n ...jsonBodySerializer,\n headers: defaultHeaders,\n parseAs: 'auto',\n querySerializer: defaultQuerySerializer,\n ...override,\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.gen.js","names":[],"sources":["../../../src/client/client/utils.gen.ts"],"sourcesContent":["// This file is auto-generated by @hey-api/openapi-ts\n\nimport { getAuthToken } from '../core/auth.gen.js';\nimport type { QuerySerializerOptions } from '../core/bodySerializer.gen.js';\nimport { jsonBodySerializer } from '../core/bodySerializer.gen.js';\nimport {\n serializeArrayParam,\n serializeObjectParam,\n serializePrimitiveParam,\n} from '../core/pathSerializer.gen.js';\nimport { getUrl } from '../core/utils.gen.js';\nimport type { Client, ClientOptions, Config, RequestOptions } from './types.gen.js';\n\nexport const createQuerySerializer = <T = unknown>({\n parameters = {},\n ...args\n}: QuerySerializerOptions = {}): ((queryParams: T) => string) => {\n const querySerializer = (queryParams: T): string => {\n const search: string[] = [];\n if (queryParams && typeof queryParams === 'object') {\n for (const name in queryParams) {\n const value = queryParams[name];\n\n if (value === undefined || value === null) {\n continue;\n }\n\n const options = parameters[name] || args;\n\n if (Array.isArray(value)) {\n const serializedArray = serializeArrayParam({\n allowReserved: options.allowReserved,\n explode: true,\n name,\n style: 'form',\n value,\n ...options.array,\n });\n if (serializedArray) search.push(serializedArray);\n } else if (typeof value === 'object') {\n const serializedObject = serializeObjectParam({\n allowReserved: options.allowReserved,\n explode: true,\n name,\n style: 'deepObject',\n value: value as Record<string, unknown>,\n ...options.object,\n });\n if (serializedObject) search.push(serializedObject);\n } else {\n const serializedPrimitive = serializePrimitiveParam({\n allowReserved: options.allowReserved,\n name,\n value: value as string,\n });\n if (serializedPrimitive) search.push(serializedPrimitive);\n }\n }\n }\n return search.join('&');\n };\n return querySerializer;\n};\n\n/**\n * Infers parseAs value from provided Content-Type header.\n */\nexport const getParseAs = (contentType: string | null): Exclude<Config['parseAs'], 'auto'> => {\n if (!contentType) {\n // If no Content-Type header is provided, the best we can do is return the raw response body,\n // which is effectively the same as the 'stream' option.\n return 'stream';\n }\n\n const cleanContent = contentType.split(';')[0]?.trim();\n\n if (!cleanContent) {\n return;\n }\n\n if (cleanContent.startsWith('application/json') || cleanContent.endsWith('+json')) {\n return 'json';\n }\n\n if (cleanContent === 'multipart/form-data') {\n return 'formData';\n }\n\n if (\n ['application/', 'audio/', 'image/', 'video/'].some((type) => cleanContent.startsWith(type))\n ) {\n return 'blob';\n }\n\n if (cleanContent.startsWith('text/')) {\n return 'text';\n }\n\n return;\n};\n\nconst checkForExistence = (\n options: Pick<RequestOptions, 'auth' | 'query'> & {\n headers: Headers;\n },\n name?: string,\n): boolean => {\n if (!name) {\n return false;\n }\n if (\n options.headers.has(name) ||\n options.query?.[name] ||\n options.headers.get('Cookie')?.includes(`${name}=`)\n ) {\n return true;\n }\n return false;\n};\n\nexport async function setAuthParams(\n options: Pick<RequestOptions, 'auth' | 'query' | 'security'> & {\n headers: Headers;\n },\n): Promise<void> {\n for (const auth of options.security ?? []) {\n if (checkForExistence(options, auth.name)) {\n continue;\n }\n\n const token = await getAuthToken(auth, options.auth);\n\n if (!token) {\n continue;\n }\n\n const name = auth.name ?? 'Authorization';\n\n switch (auth.in) {\n case 'query':\n if (!options.query) {\n options.query = {};\n }\n options.query[name] = token;\n break;\n case 'cookie':\n options.headers.append('Cookie', `${name}=${token}`);\n break;\n case 'header':\n default:\n options.headers.set(name, token);\n break;\n }\n }\n}\n\nexport const buildUrl: Client['buildUrl'] = (options) =>\n getUrl({\n baseUrl: options.baseUrl as string,\n path: options.path,\n query: options.query,\n querySerializer:\n typeof options.querySerializer === 'function'\n ? options.querySerializer\n : createQuerySerializer(options.querySerializer),\n url: options.url,\n });\n\nexport const mergeConfigs = (a: Config, b: Config): Config => {\n const config = { ...a, ...b };\n if (config.baseUrl?.endsWith('/')) {\n config.baseUrl = config.baseUrl.substring(0, config.baseUrl.length - 1);\n }\n config.headers = mergeHeaders(a.headers, b.headers);\n return config;\n};\n\nconst headersEntries = (headers: Headers): Array<[string, string]> => {\n const entries: Array<[string, string]> = [];\n headers.forEach((value, key) => {\n entries.push([key, value]);\n });\n return entries;\n};\n\nexport const mergeHeaders = (\n ...headers: Array<Required<Config>['headers'] | undefined>\n): Headers => {\n const mergedHeaders = new Headers();\n for (const header of headers) {\n if (!header) {\n continue;\n }\n\n const iterator = header instanceof Headers ? headersEntries(header) : Object.entries(header);\n\n for (const [key, value] of iterator) {\n if (value === null) {\n mergedHeaders.delete(key);\n } else if (Array.isArray(value)) {\n for (const v of value) {\n mergedHeaders.append(key, v as string);\n }\n } else if (value !== undefined) {\n // assume object headers are meant to be JSON stringified, i.e., their\n // content value in OpenAPI specification is 'application/json'\n mergedHeaders.set(\n key,\n typeof value === 'object' ? JSON.stringify(value) : (value as string),\n );\n }\n }\n }\n return mergedHeaders;\n};\n\ntype ErrInterceptor<Err, Res, Req, Options> = (\n error: Err,\n /** response may be undefined due to a network error where no response object is produced */\n response: Res | undefined,\n /** request may be undefined, because error may be from building the request object itself */\n request: Req | undefined,\n options: Options,\n) => Err | Promise<Err>;\n\ntype ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;\n\ntype ResInterceptor<Res, Req, Options> = (\n response: Res,\n request: Req,\n options: Options,\n) => Res | Promise<Res>;\n\nclass Interceptors<Interceptor> {\n fns: Array<Interceptor | null> = [];\n\n clear(): void {\n this.fns = [];\n }\n\n eject(id: number | Interceptor): void {\n const index = this.getInterceptorIndex(id);\n if (this.fns[index]) {\n this.fns[index] = null;\n }\n }\n\n exists(id: number | Interceptor): boolean {\n const index = this.getInterceptorIndex(id);\n return Boolean(this.fns[index]);\n }\n\n getInterceptorIndex(id: number | Interceptor): number {\n if (typeof id === 'number') {\n return this.fns[id] ? id : -1;\n }\n return this.fns.indexOf(id);\n }\n\n update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false {\n const index = this.getInterceptorIndex(id);\n if (this.fns[index]) {\n this.fns[index] = fn;\n return id;\n }\n return false;\n }\n\n use(fn: Interceptor): number {\n this.fns.push(fn);\n return this.fns.length - 1;\n }\n}\n\nexport interface Middleware<Req, Res, Err, Options> {\n error: Interceptors<ErrInterceptor<Err, Res, Req, Options>>;\n request: Interceptors<ReqInterceptor<Req, Options>>;\n response: Interceptors<ResInterceptor<Res, Req, Options>>;\n}\n\nexport const createInterceptors = <Req, Res, Err, Options>(): Middleware<\n Req,\n Res,\n Err,\n Options\n> => ({\n error: new Interceptors<ErrInterceptor<Err, Res, Req, Options>>(),\n request: new Interceptors<ReqInterceptor<Req, Options>>(),\n response: new Interceptors<ResInterceptor<Res, Req, Options>>(),\n});\n\nconst defaultQuerySerializer = createQuerySerializer({\n allowReserved: false,\n array: {\n explode: true,\n style: 'form',\n },\n object: {\n explode: true,\n style: 'deepObject',\n },\n});\n\nconst defaultHeaders = {\n 'Content-Type': 'application/json',\n};\n\nexport const createConfig = <T extends ClientOptions = ClientOptions>(\n override: Config<Omit<ClientOptions, keyof T> & T> = {},\n): Config<Omit<ClientOptions, keyof T> & T> => ({\n ...jsonBodySerializer,\n headers: defaultHeaders,\n parseAs: 'auto',\n querySerializer: defaultQuerySerializer,\n ...override,\n});\n"],"mappings":"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"}
|