@spfn/core 0.3.0-beta.2 → 0.3.0-beta.21

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 (94) hide show
  1. package/README.md +343 -16
  2. package/dist/app-config/index.d.ts +134 -0
  3. package/dist/app-config/index.js +58 -0
  4. package/dist/app-config/index.js.map +1 -0
  5. package/dist/authz/index.js +1 -381
  6. package/dist/authz/index.js.map +1 -1
  7. package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
  8. package/dist/codegen/index.d.ts +93 -15
  9. package/dist/codegen/index.js +626 -165
  10. package/dist/codegen/index.js.map +1 -1
  11. package/dist/config/index.d.ts +0 -63
  12. package/dist/config/index.js +15 -15
  13. package/dist/config/index.js.map +1 -1
  14. package/dist/contract/index.d.ts +40 -17
  15. package/dist/contract/index.js +147 -23
  16. package/dist/contract/index.js.map +1 -1
  17. package/dist/db/index.d.ts +201 -34
  18. package/dist/db/index.js +294 -158
  19. package/dist/db/index.js.map +1 -1
  20. package/dist/{define-middleware-DfDP39Nq.d.ts → define-middleware-CVKgqo8S.d.ts} +1 -1
  21. package/dist/env/index.d.ts +6 -442
  22. package/dist/env/index.js +13 -16
  23. package/dist/env/index.js.map +1 -1
  24. package/dist/env/loader.js +24 -1
  25. package/dist/env/loader.js.map +1 -1
  26. package/dist/error-TsUIjp_x.d.ts +157 -0
  27. package/dist/errors/index.js +1 -381
  28. package/dist/errors/index.js.map +1 -1
  29. package/dist/event/index.d.ts +5 -5
  30. package/dist/event/index.js +32 -1
  31. package/dist/event/index.js.map +1 -1
  32. package/dist/event/sse/client.d.ts +18 -4
  33. package/dist/event/sse/client.js +38 -2
  34. package/dist/event/sse/client.js.map +1 -1
  35. package/dist/event/sse/index.d.ts +5 -4
  36. package/dist/event/ws/client.d.ts +3 -2
  37. package/dist/event/ws/index.d.ts +4 -3
  38. package/dist/job/index.d.ts +48 -3
  39. package/dist/job/index.js +131 -52
  40. package/dist/job/index.js.map +1 -1
  41. package/dist/logger/index.js +0 -12
  42. package/dist/logger/index.js.map +1 -1
  43. package/dist/middleware/index.d.ts +6 -2
  44. package/dist/middleware/index.js +7 -388
  45. package/dist/middleware/index.js.map +1 -1
  46. package/dist/nextjs/index.d.ts +88 -8
  47. package/dist/nextjs/index.js +138 -62
  48. package/dist/nextjs/index.js.map +1 -1
  49. package/dist/nextjs/server.d.ts +45 -7
  50. package/dist/nextjs/server.js +14 -0
  51. package/dist/nextjs/server.js.map +1 -1
  52. package/dist/ops/index.d.ts +62 -43
  53. package/dist/ops/index.js +638 -97
  54. package/dist/ops/index.js.map +1 -1
  55. package/dist/registry-C2KQCh0m.d.ts +473 -0
  56. package/dist/route/index.d.ts +6 -3
  57. package/dist/route/index.js +97 -28
  58. package/dist/route/index.js.map +1 -1
  59. package/dist/route/types.d.ts +7 -1
  60. package/dist/{router-Qbssr11H.d.ts → route-builder-DRW-MSCJ.d.ts} +52 -127
  61. package/dist/router-4YoIy5fN.d.ts +172 -0
  62. package/dist/{token-manager-BT5EnUAR.d.ts → router-CysBmgv3.d.ts} +81 -127
  63. package/dist/server/index.d.ts +185 -14
  64. package/dist/server/index.js +883 -78
  65. package/dist/server/index.js.map +1 -1
  66. package/dist/surface/index.d.ts +115 -0
  67. package/dist/surface/index.js +1003 -0
  68. package/dist/surface/index.js.map +1 -0
  69. package/dist/token-manager-Ckjt2-qq.d.ts +122 -0
  70. package/dist/{types-D1c57Ko-.d.ts → types-5Rl11_Nb.d.ts} +43 -4
  71. package/dist/{types-ZQODsBft.d.ts → types-B8zAxFsE.d.ts} +2 -1
  72. package/dist/types-CxhPH4s_.d.ts +375 -0
  73. package/dist/{types-2AbaW4Ie.d.ts → types-W4u_S0lF.d.ts} +4 -3
  74. package/docs/file-upload.md +195 -333
  75. package/package.json +20 -9
  76. package/src/cache/README.md +330 -0
  77. package/src/codegen/README.md +634 -0
  78. package/src/config/README.md +333 -0
  79. package/src/contract/README.md +440 -0
  80. package/src/db/README.md +589 -0
  81. package/src/db/manager/README.md +500 -0
  82. package/src/db/schema/README.md +354 -0
  83. package/src/db/transaction/README.md +822 -0
  84. package/src/env/README.md +787 -0
  85. package/src/errors/README.md +429 -0
  86. package/src/event/README.md +789 -0
  87. package/src/job/README.md +613 -0
  88. package/src/logger/README.md +321 -0
  89. package/src/middleware/README.md +634 -0
  90. package/src/nextjs/README.md +688 -0
  91. package/src/route/README.md +763 -0
  92. package/src/security/README.md +100 -0
  93. package/src/server/README.md +704 -0
  94. package/dist/types-9oszaJqp.d.ts +0 -250
@@ -1,6 +1,6 @@
1
1
  import { Router, RouteDef } from '@spfn/core/route';
2
- import { R as RequestInterceptor, a as ResponseInterceptor, I as InferRouteInput, b as InferRouteOutput, A as ApiConfig } from '../types-9oszaJqp.js';
3
- export { C as CallOptions, c as CookieOptions, d as RouterInput, e as RouterOutput, S as SetCookie, f as StructuredInput } from '../types-9oszaJqp.js';
2
+ import { R as RequestInterceptor, a as ResponseInterceptor, I as InferRouteInput, b as InferRouteOutput, E as ExtractRoutes, A as ApiConfig } from '../types-CxhPH4s_.js';
3
+ export { C as CallOptions, c as CookieOptions, d as RouterInput, e as RouterOutput, S as SetCookie, f as StructuredInput } from '../types-CxhPH4s_.js';
4
4
  import '@sinclair/typebox';
5
5
  import '@spfn/core/errors';
6
6
 
@@ -57,6 +57,11 @@ type RouteClient<TRoute extends RouteDef<any, any>> = {
57
57
  tags?: string[];
58
58
  };
59
59
  }): RouteClient<TRoute>;
60
+ /**
61
+ * Set this call's timeout in milliseconds, overriding the client-wide one.
62
+ * Throws a `TypeError` unless `ms` is finite, `> 0` and `<= 2147483647`.
63
+ */
64
+ timeout(ms: number): RouteClient<TRoute>;
60
65
  /**
61
66
  * Set request interceptor
62
67
  */
@@ -80,11 +85,42 @@ type RouteClient<TRoute extends RouteDef<any, any>> = {
80
85
  call: HasAnyRequiredFields<InferRouteInput<TRoute>> extends true ? (input: CleanStructuredInput<InferRouteInput<TRoute>>) => Promise<InferRouteOutput<TRoute>> : (input?: CleanStructuredInput<InferRouteInput<TRoute>>) => Promise<InferRouteOutput<TRoute>>;
81
86
  };
82
87
  /**
83
- * Typed client for entire router
88
+ * One property per route in a flattened route record.
89
+ *
90
+ * A slot the flattening could not resolve to a route definition is `never`, as it was
91
+ * before nesting was flattened — a record whose values are neither routes nor routers
92
+ * names nothing callable.
84
93
  */
85
- type Client<TRouter extends Router<any>> = {
86
- [K in keyof TRouter['routes']]: TRouter['routes'][K] extends RouteDef<any, any, any> ? RouteClient<TRouter['routes'][K]> : TRouter['routes'][K] extends Router<any> ? Client<TRouter['routes'][K]> : never;
94
+ type RouteClients<TRoutes> = {
95
+ [K in keyof TRoutes]: TRoutes[K] extends RouteDef<any, any, any> ? RouteClient<TRoutes[K]> : never;
87
96
  };
97
+ /**
98
+ * Typed client for entire router
99
+ *
100
+ * One flat namespace, holding the same route names the server registers. A route
101
+ * declared inside a nested `defineRouter` is reached by its own key — `api.getThing`,
102
+ * never `api.group.getThing` — because that is the name `registerRoutes` mounts it
103
+ * under, the name the RPC proxy resolves, and the name `RouterOutput` takes. The group
104
+ * key is not a route and naming it is a compile error.
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const appRouter = defineRouter({
109
+ * getRoot,
110
+ * users: defineRouter({ getUser }),
111
+ * });
112
+ *
113
+ * const api = createApi<typeof appRouter>();
114
+ *
115
+ * await api.getUser.call({ params: { id: '1' } }); // not api.users.getUser
116
+ * ```
117
+ *
118
+ * A name two branches both declare is left out of the namespace rather than resolved to
119
+ * one of them — the same collision `RouterOutput` refuses. Routes mounted with
120
+ * `.packages()` are deliberately absent: a package publishes its own route map and its
121
+ * own client (`authApi`, `cmsApi`), and that is what calls them.
122
+ */
123
+ type Client<TRouter extends Router<any>> = RouteClients<ExtractRoutes<TRouter>>;
88
124
 
89
125
  /**
90
126
  * Create type-safe RPC client
@@ -106,15 +142,59 @@ type Client<TRouter extends Router<any>> = {
106
142
  */
107
143
  declare function createApi<TRouter extends Router<any>>(config?: ApiConfig): Client<TRouter>;
108
144
 
145
+ /**
146
+ * CSRF token transport for the RPC client
147
+ *
148
+ * The Next.js proxy sets a readable (non-HttpOnly) cookie carrying an HMAC of
149
+ * the session's key id; this module mirrors it into a request header. The proxy
150
+ * never compares cookie against header — it recomputes the value from the
151
+ * session — so the cookie is transport only and reading it here is not a trust
152
+ * decision. See the CSRF section of the @spfn/auth README.
153
+ */
154
+ /**
155
+ * Header the readable CSRF cookie is mirrored into.
156
+ *
157
+ * Must match CSRF_HEADER in @spfn/auth. It is duplicated rather than imported
158
+ * because @spfn/core cannot depend on @spfn/auth.
159
+ */
160
+ declare const CSRF_HEADER = "x-spfn-csrf";
161
+ /**
162
+ * Collect the CSRF token candidates from cookie entries.
163
+ *
164
+ * Takes entries rather than a map because a name can legitimately appear twice:
165
+ * a sibling subdomain that tosses `spfn_csrf` for the parent domain leaves the
166
+ * browser holding two cookies of that name, and folding them into a map would
167
+ * throw away whichever the tossed one displaced — locking the user out of every
168
+ * mutation. Sending both keeps the real one in play, and the tossed one is inert
169
+ * because the proxy recomputes what it expects.
170
+ *
171
+ * @returns Header value (comma-separated), or undefined when no cookie exists
172
+ */
173
+ declare function csrfHeaderValue(cookies: Iterable<[string, string]>): string | undefined;
174
+ /**
175
+ * Read the browser cookie jar as entries, duplicates preserved.
176
+ *
177
+ * Empty outside a browser (SSR reads the jar it forwards instead).
178
+ */
179
+ declare function documentCookieEntries(): Array<[string, string]>;
180
+
109
181
  /**
110
182
  * Typed client error
183
+ *
184
+ * `errorType` tells apart why a call failed:
185
+ * - `'http'`: the server answered with a non-2xx status
186
+ * - `'network'`: the fetch or the body read failed (status 0)
187
+ * - `'timeout'`: the call's timeout elapsed before response headers arrived (status 408)
188
+ * - `'aborted'`: the caller's own signal aborted the call (status 0); `cause` is the signal's reason
111
189
  */
112
190
  declare class ApiError extends Error {
113
191
  readonly status: number;
114
192
  readonly url: string;
115
193
  readonly response?: unknown | undefined;
116
- readonly errorType?: "http" | "network" | "timeout" | undefined;
117
- constructor(message: string, status: number, url: string, response?: unknown | undefined, errorType?: "http" | "network" | "timeout" | undefined);
194
+ readonly errorType?: "http" | "network" | "timeout" | "aborted" | undefined;
195
+ constructor(message: string, status: number, url: string, response?: unknown | undefined, errorType?: "http" | "network" | "timeout" | "aborted" | undefined, options?: {
196
+ cause?: unknown;
197
+ });
118
198
  }
119
199
 
120
- export { ApiConfig, ApiError, type Client, InferRouteInput, InferRouteOutput, RequestInterceptor, ResponseInterceptor, type RouteClient, createApi };
200
+ export { ApiConfig, ApiError, CSRF_HEADER, type Client, InferRouteInput, InferRouteOutput, RequestInterceptor, ResponseInterceptor, type RouteClient, createApi, csrfHeaderValue, documentCookieEntries };
@@ -69,8 +69,8 @@ function logThrowingDeserializedError(logger3, error) {
69
69
 
70
70
  // src/nextjs/client/errors.ts
71
71
  var ApiError = class extends Error {
72
- constructor(message, status, url, response, errorType) {
73
- super(message);
72
+ constructor(message, status, url, response, errorType, options) {
73
+ super(message, options);
74
74
  this.status = status;
75
75
  this.url = url;
76
76
  this.response = response;
@@ -123,19 +123,45 @@ async function autoDetectServerCookies() {
123
123
  return {};
124
124
  }
125
125
  }
126
- async function executeFetchWithTimeout(url, init, timeout, customFetch = fetch) {
126
+ function openAbortScope(callerSignal, timeout) {
127
127
  const controller = new AbortController();
128
- const timeoutId = setTimeout(() => controller.abort(), timeout);
128
+ let cause;
129
+ const abort = (source, reason) => {
130
+ cause ??= source;
131
+ controller.abort(reason);
132
+ };
133
+ const onCallerAbort = () => abort("caller", callerSignal?.reason);
134
+ const timeoutId = setTimeout(() => abort("timeout"), timeout);
135
+ callerSignal?.addEventListener("abort", onCallerAbort, { once: true });
136
+ return {
137
+ signal: controller.signal,
138
+ cause: () => cause,
139
+ stopTimer: () => clearTimeout(timeoutId),
140
+ close: () => {
141
+ clearTimeout(timeoutId);
142
+ callerSignal?.removeEventListener("abort", onCallerAbort);
143
+ }
144
+ };
145
+ }
146
+ async function fetchInAbortScope(url, init, timeout, customFetch = fetch) {
147
+ const callerSignal = init.signal ?? void 0;
148
+ if (callerSignal?.aborted) {
149
+ return { ok: false, error: callerSignal.reason, cause: "caller" };
150
+ }
151
+ const scope = openAbortScope(callerSignal, timeout);
129
152
  try {
130
- const response = await customFetch(url, {
131
- ...init,
132
- signal: controller.signal
133
- });
134
- clearTimeout(timeoutId);
135
- return response;
153
+ const response = await customFetch(url, { ...init, signal: scope.signal });
154
+ scope.stopTimer();
155
+ const body = await parseResponseBody(response);
156
+ if (scope.cause() === "caller") {
157
+ return { ok: false, error: callerSignal?.reason, cause: "caller" };
158
+ }
159
+ return { ok: true, response, body };
136
160
  } catch (error) {
137
- clearTimeout(timeoutId);
138
- throw error;
161
+ const cause = scope.cause();
162
+ return { ok: false, cause, error: cause === "caller" ? callerSignal?.reason : error };
163
+ } finally {
164
+ scope.close();
139
165
  }
140
166
  }
141
167
  async function handleErrorResponse(response, body, fullUrl, errorRegistry, debug, logger3) {
@@ -180,7 +206,40 @@ async function handleErrorResponse(response, body, fullUrl, errorRegistry, debug
180
206
  );
181
207
  }
182
208
 
209
+ // src/nextjs/client/csrf.ts
210
+ var CSRF_HEADER = "x-spfn-csrf";
211
+ var CSRF_COOKIE_PATTERN = /^spfn_csrf(_\d+)?$/;
212
+ var HEADER_SAFE_VALUE = /^[!-~]+$/;
213
+ var MAX_CANDIDATES = 32;
214
+ function selectCandidates(values) {
215
+ const unique = Array.from(new Set(values));
216
+ if (unique.length <= MAX_CANDIDATES) {
217
+ return unique;
218
+ }
219
+ const half = MAX_CANDIDATES / 2;
220
+ return [...unique.slice(0, half), ...unique.slice(-half)];
221
+ }
222
+ function csrfHeaderValue(cookies) {
223
+ const values = Array.from(cookies).filter(([name, value]) => CSRF_COOKIE_PATTERN.test(name) && HEADER_SAFE_VALUE.test(value) && !value.includes(",")).map(([, value]) => value);
224
+ const candidates = selectCandidates(values);
225
+ return candidates.length > 0 ? candidates.join(",") : void 0;
226
+ }
227
+ function documentCookieEntries() {
228
+ if (typeof document === "undefined" || !document.cookie) {
229
+ return [];
230
+ }
231
+ const entries = [];
232
+ for (const pair of document.cookie.split(";")) {
233
+ const separator = pair.indexOf("=");
234
+ if (separator > 0) {
235
+ entries.push([pair.slice(0, separator).trim(), pair.slice(separator + 1).trim()]);
236
+ }
237
+ }
238
+ return entries;
239
+ }
240
+
183
241
  // src/nextjs/client/builder.ts
242
+ var MAX_TIMEOUT_MS = 2147483647;
184
243
  var RouteCallBuilder = class _RouteCallBuilder {
185
244
  constructor(executor, routeName) {
186
245
  this.executor = executor;
@@ -189,6 +248,7 @@ var RouteCallBuilder = class _RouteCallBuilder {
189
248
  _headers;
190
249
  _cookies;
191
250
  _fetchOptions;
251
+ _timeout;
192
252
  _onRequest;
193
253
  _onResponse;
194
254
  /**
@@ -202,6 +262,7 @@ var RouteCallBuilder = class _RouteCallBuilder {
202
262
  builder._headers = this._headers;
203
263
  builder._cookies = this._cookies;
204
264
  builder._fetchOptions = this._fetchOptions;
265
+ builder._timeout = this._timeout;
205
266
  builder._onRequest = this._onRequest;
206
267
  builder._onResponse = this._onResponse;
207
268
  return builder;
@@ -230,6 +291,20 @@ var RouteCallBuilder = class _RouteCallBuilder {
230
291
  builder._fetchOptions = { ...this._fetchOptions, ...options };
231
292
  return builder;
232
293
  }
294
+ /**
295
+ * Set this call's timeout in milliseconds, overriding the client-wide one
296
+ *
297
+ * Throws a `TypeError`, before any request is made, unless `ms` is a finite number
298
+ * greater than 0 and at most 2147483647 (the largest delay `setTimeout` honours).
299
+ */
300
+ timeout(ms) {
301
+ if (!Number.isFinite(ms) || ms <= 0 || ms > MAX_TIMEOUT_MS) {
302
+ throw new TypeError(`timeout must be a finite number of milliseconds in (0, ${MAX_TIMEOUT_MS}], got ${String(ms)}`);
303
+ }
304
+ const builder = this.clone();
305
+ builder._timeout = ms;
306
+ return builder;
307
+ }
233
308
  /**
234
309
  * Set request interceptor
235
310
  */
@@ -265,6 +340,9 @@ var RouteCallBuilder = class _RouteCallBuilder {
265
340
  if (this._fetchOptions) {
266
341
  options.fetchOptions = this._fetchOptions;
267
342
  }
343
+ if (this._timeout !== void 0) {
344
+ options.timeout = this._timeout;
345
+ }
268
346
  if (this._onRequest) {
269
347
  options.onRequest = this._onRequest;
270
348
  }
@@ -277,6 +355,28 @@ var RouteCallBuilder = class _RouteCallBuilder {
277
355
 
278
356
  // src/nextjs/client/core.ts
279
357
  var apiLogger = logger.child("@spfn/core:api-client");
358
+ function transportError(failure, site, timeout) {
359
+ if (failure.cause === "timeout") {
360
+ apiLogger.error("Request timeout", { ...site, timeout });
361
+ return new ApiError(`Request timeout after ${timeout}ms`, 408, site.url, void 0, "timeout");
362
+ }
363
+ if (failure.cause === "caller") {
364
+ apiLogger.debug("Request aborted by caller", site);
365
+ return new ApiError("Request aborted", 0, site.url, void 0, "aborted", { cause: failure.error });
366
+ }
367
+ const { error } = failure;
368
+ if (error instanceof Error && error.name === "AbortError") {
369
+ apiLogger.error("Request timeout", { ...site, timeout });
370
+ return new ApiError(`Request timeout after ${timeout}ms`, 408, site.url, void 0, "timeout");
371
+ }
372
+ const errorMessage = error instanceof Error ? error.message : "Network error";
373
+ apiLogger.error("Network error", {
374
+ ...site,
375
+ error: errorMessage,
376
+ errorName: error instanceof Error ? error.name : "unknown"
377
+ });
378
+ return new ApiError(errorMessage, 0, site.url, void 0, "network");
379
+ }
280
380
  function createApi(config = {}) {
281
381
  const {
282
382
  baseUrl = "/api/rpc",
@@ -335,6 +435,13 @@ function createApi(config = {}) {
335
435
  if (Object.keys(cookiesToSend).length > 0) {
336
436
  headers["Cookie"] = buildCookieHeader(cookiesToSend);
337
437
  }
438
+ const csrfToken = csrfHeaderValue(
439
+ typeof window === "undefined" ? Object.entries(cookiesToSend) : documentCookieEntries()
440
+ );
441
+ const csrfSetByCaller = Object.keys(headers).some((name) => name.toLowerCase() === CSRF_HEADER);
442
+ if (csrfToken && !csrfSetByCaller) {
443
+ headers[CSRF_HEADER] = csrfToken;
444
+ }
338
445
  if (debug && Object.keys(autoDetectedCookies).length > 0) {
339
446
  const cookieArray = Object.entries(autoDetectedCookies).map(([name, value]) => ({ name, value }));
340
447
  logCookieAutoDetection(apiLogger, cookieArray);
@@ -385,55 +492,24 @@ function createApi(config = {}) {
385
492
  if (debug) {
386
493
  logRequest(apiLogger, routeName, method, fullUrl, !!init.body);
387
494
  }
388
- let response;
389
- let body;
390
- try {
391
- response = await executeFetchWithTimeout(fullUrl, init, timeout, customFetch);
392
- body = await parseResponseBody(response);
393
- if (globalOnResponse) {
394
- const result = await globalOnResponse(response, body);
395
- response = result.response;
396
- body = result.body;
397
- }
398
- if (options.onResponse) {
399
- const result = await options.onResponse(response, body);
400
- response = result.response;
401
- body = result.body;
402
- }
403
- if (debug) {
404
- logResponse(apiLogger, routeName, response.status, !!body);
405
- }
406
- } catch (error) {
407
- if (error instanceof Error && error.name === "AbortError") {
408
- apiLogger.error("Request timeout", {
409
- route: routeName,
410
- method,
411
- url: fullUrl,
412
- timeout
413
- });
414
- throw new ApiError(
415
- `Request timeout after ${timeout}ms`,
416
- 408,
417
- fullUrl,
418
- void 0,
419
- "timeout"
420
- );
421
- }
422
- const errorMessage = error instanceof Error ? error.message : "Network error";
423
- apiLogger.error("Network error", {
424
- route: routeName,
425
- method,
426
- url: fullUrl,
427
- error: errorMessage,
428
- errorName: error instanceof Error ? error.name : "unknown"
429
- });
430
- throw new ApiError(
431
- errorMessage,
432
- 0,
433
- fullUrl,
434
- void 0,
435
- "network"
436
- );
495
+ const appliedTimeout = options.timeout ?? timeout;
496
+ const fetched = await fetchInAbortScope(fullUrl, init, appliedTimeout, customFetch);
497
+ if (!fetched.ok) {
498
+ throw transportError(fetched, { route: routeName, method, url: fullUrl }, appliedTimeout);
499
+ }
500
+ let { response, body } = fetched;
501
+ if (globalOnResponse) {
502
+ const result = await globalOnResponse(response, body);
503
+ response = result.response;
504
+ body = result.body;
505
+ }
506
+ if (options.onResponse) {
507
+ const result = await options.onResponse(response, body);
508
+ response = result.response;
509
+ body = result.body;
510
+ }
511
+ if (debug) {
512
+ logResponse(apiLogger, routeName, response.status, !!body);
437
513
  }
438
514
  if (!response.ok) {
439
515
  await handleErrorResponse(response, body, fullUrl, errorRegistry$1, debug, apiLogger);
@@ -457,6 +533,6 @@ function createApi(config = {}) {
457
533
  return buildProxy();
458
534
  }
459
535
 
460
- export { ApiError, createApi };
536
+ export { ApiError, CSRF_HEADER, createApi, csrfHeaderValue, documentCookieEntries };
461
537
  //# sourceMappingURL=index.js.map
462
538
  //# sourceMappingURL=index.js.map