@classytic/arc-next 0.4.1 → 0.6.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 +272 -660
- package/dist/api.d.ts +115 -194
- package/dist/api.js +69 -116
- package/dist/cache.d.ts +125 -0
- package/dist/cache.js +211 -0
- package/dist/client.d.ts +295 -5
- package/dist/client.js +392 -12
- package/dist/hooks.d.ts +162 -22
- package/dist/hooks.js +249 -89
- package/dist/mutation.d.ts +18 -1
- package/dist/mutation.js +20 -1
- package/dist/prefetch.d.ts +36 -2
- package/dist/prefetch.js +47 -3
- package/dist/presets/bulk.d.ts +43 -0
- package/dist/presets/bulk.js +50 -0
- package/dist/presets/search.d.ts +56 -0
- package/dist/presets/search.js +60 -0
- package/dist/presets/slug.d.ts +28 -0
- package/dist/presets/slug.js +27 -0
- package/dist/presets/soft-delete.d.ts +34 -0
- package/dist/presets/soft-delete.js +45 -0
- package/dist/presets/tree.d.ts +32 -0
- package/dist/presets/tree.js +47 -0
- package/dist/query.d.ts +86 -69
- package/dist/query.js +59 -161
- package/dist/sse.d.ts +115 -36
- package/dist/sse.js +179 -103
- package/dist/upload.d.ts +181 -0
- package/dist/upload.js +346 -0
- package/dist/ws.d.ts +167 -0
- package/dist/ws.js +274 -0
- package/package.json +39 -1
package/dist/client.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ErrorDetail } from "@classytic/repo-core/errors";
|
|
2
|
+
|
|
1
3
|
//#region src/client.d.ts
|
|
2
4
|
interface ToastHandler {
|
|
3
5
|
success: (message: string) => void;
|
|
@@ -11,6 +13,34 @@ type UseRouterHook = () => {
|
|
|
11
13
|
scroll?: boolean;
|
|
12
14
|
}) => void;
|
|
13
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Canonical error codes arc and repo-core emit on `json.code`. Single
|
|
18
|
+
* top-level slot — arc 2.13's `createError` lifts business codes from
|
|
19
|
+
* `details` to top-level so `repo-core`'s `toErrorContract` round-trips
|
|
20
|
+
* them on the wire. There is no separate `detailsCode` slot; everything
|
|
21
|
+
* lives at `error.code`.
|
|
22
|
+
*
|
|
23
|
+
* Three families compose this list:
|
|
24
|
+
* 1. **repo-core canonical** (`validation_error`, `not_found`, ...) — RFC 7807
|
|
25
|
+
* / Stripe-shaped lowercase + snake_case. Cross-package universals.
|
|
26
|
+
* 2. **arc hierarchical** (`arc.forbidden`, `arc.validation_error`,
|
|
27
|
+
* `arc.org.access_denied`, ...) — what arc's `errorHandlerPlugin`
|
|
28
|
+
* emits for HTTP-status throws + arc-classified errors.
|
|
29
|
+
* 3. **arc business** (`ORG_CONTEXT_REQUIRED`, `ALL_FIELDS_STRIPPED`,
|
|
30
|
+
* `OWNERSHIP_DENIED`, ...) — emitted by mixins / org guards via
|
|
31
|
+
* `createError(status, msg, { code })`. The UPPER_SNAKE form is
|
|
32
|
+
* intentional: these are reason codes, not HTTP-status codes.
|
|
33
|
+
*
|
|
34
|
+
* `(string & {})` keeps the type open so domain packages and custom
|
|
35
|
+
* `errorMappers` codes still satisfy it.
|
|
36
|
+
*/
|
|
37
|
+
declare const KNOWN_ARC_ERROR_CODES: readonly ["validation_error", "not_found", "conflict", "unauthorized", "forbidden", "rate_limited", "idempotency_conflict", "precondition_failed", "internal_error", "service_unavailable", "timeout", "arc.bad_request", "arc.unauthorized", "arc.forbidden", "arc.not_found", "arc.conflict", "arc.unprocessable_entity", "arc.rate_limited", "arc.internal_error", "arc.bad_gateway", "arc.service_unavailable", "arc.gateway_timeout", "arc.validation_error", "arc.invalid_id", "arc.org.selection_required", "arc.org.access_denied", "ORG_CONTEXT_REQUIRED", "ORG_ROLE_REQUIRED", "OWNERSHIP_DENIED", "MIXED_UPDATE_SHAPE", "ALL_FIELDS_STRIPPED", "BEFORE_RESTORE_HOOK_ERROR", "duplicate_key"];
|
|
38
|
+
/**
|
|
39
|
+
* Canonical arc error code union. `(string & {})` keeps the type open so
|
|
40
|
+
* domain packages can extend hierarchically (`'order.cart.locked'`,
|
|
41
|
+
* `'payment.gateway.timeout'`) and still satisfy the type.
|
|
42
|
+
*/
|
|
43
|
+
type ArcErrorCode = (typeof KNOWN_ARC_ERROR_CODES)[number] | (string & {});
|
|
14
44
|
interface ArcApiErrorOptions {
|
|
15
45
|
status: number;
|
|
16
46
|
statusText: string;
|
|
@@ -39,13 +69,108 @@ declare class ArcApiError extends Error {
|
|
|
39
69
|
readonly endpoint: string;
|
|
40
70
|
readonly method: HttpMethod;
|
|
41
71
|
constructor(message: string, options: ArcApiErrorOptions);
|
|
42
|
-
/**
|
|
72
|
+
/**
|
|
73
|
+
* Canonical error code from arc's wire envelope (`json.code`).
|
|
74
|
+
*
|
|
75
|
+
* Arc 2.13 + `repo-core` 0.4 emit one canonical {@link ErrorContract}
|
|
76
|
+
* shape — `{ code, message, status, details? }` — with the business
|
|
77
|
+
* code at top-level. Hosts switch on `error.code` directly:
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* if (error.code === 'ORG_CONTEXT_REQUIRED') promptOrgSelector();
|
|
81
|
+
* if (error.code === 'arc.not_found') router.replace('/404');
|
|
82
|
+
* if (error.code === 'duplicate_key') showRetryAsAdmin();
|
|
83
|
+
*/
|
|
84
|
+
get code(): ArcErrorCode | null;
|
|
85
|
+
/**
|
|
86
|
+
* Canonical structured details — populated for validation failures
|
|
87
|
+
* (one entry per offending field) and duplicate-key conflicts (one entry
|
|
88
|
+
* per offending field). Shape matches `repo-core`'s {@link ErrorDetail}:
|
|
89
|
+
* `{ path?, code, message, meta? }`. Returns `null` for non-arc backends
|
|
90
|
+
* or responses without details.
|
|
91
|
+
*/
|
|
92
|
+
get details(): readonly ErrorDetail[] | null;
|
|
93
|
+
/**
|
|
94
|
+
* Extract field-level validation errors as `{ field: message }` map.
|
|
95
|
+
*
|
|
96
|
+
* Reads the canonical `ErrorContract.details: ErrorDetail[]` shape first
|
|
97
|
+
* (what arc 2.13 + repo-core emit), then falls back to legacy shapes for
|
|
98
|
+
* non-arc backends:
|
|
99
|
+
* 1. `details: [{ path, code, message }]` — canonical (arc / repo-core).
|
|
100
|
+
* 2. `errors: { email: 'invalid' }` — record form (legacy app handlers).
|
|
101
|
+
* 3. `details: { errors: [{ field|instancePath, message }] }` — pre-2.13 AJV.
|
|
102
|
+
* 4. `errors: [...]` at the top level — third-party frameworks.
|
|
103
|
+
*/
|
|
43
104
|
get fieldErrors(): Record<string, string> | null;
|
|
44
105
|
}
|
|
45
106
|
/**
|
|
46
107
|
* Type guard for ArcApiError.
|
|
47
108
|
*/
|
|
48
109
|
declare function isArcApiError(error: unknown): error is ArcApiError;
|
|
110
|
+
/**
|
|
111
|
+
* Detects request cancellation (AbortSignal triggered) regardless of runtime.
|
|
112
|
+
*
|
|
113
|
+
* Filtering out abort errors from real failures is a common need — without it,
|
|
114
|
+
* unmounting a React component mid-fetch produces noisy logs and bogus error
|
|
115
|
+
* toasts that look like API failures. Use this predicate to skip the catch
|
|
116
|
+
* branch when the request was deliberately cancelled.
|
|
117
|
+
*
|
|
118
|
+
* Handles the three AbortError shapes you'll see in the wild:
|
|
119
|
+
* 1. Browser `DOMException { name: 'AbortError' }`
|
|
120
|
+
* 2. Node 18+ / undici `Error { name: 'AbortError' }` (no DOMException)
|
|
121
|
+
* 3. Some polyfills / older runtimes where the error has `code: 'ERR_ABORTED'`
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* try {
|
|
125
|
+
* await api.getAll({ options: { signal } });
|
|
126
|
+
* } catch (err) {
|
|
127
|
+
* if (isAbortError(err)) return; // user navigated away — silence
|
|
128
|
+
* showToast('Failed to load: ' + err.message);
|
|
129
|
+
* }
|
|
130
|
+
*/
|
|
131
|
+
declare function isAbortError(error: unknown): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Generic check: is this an `ArcApiError` carrying a specific `code`?
|
|
134
|
+
* Single-slot — arc 2.13 + repo-core 0.4 emit one canonical `code` at
|
|
135
|
+
* top-level. Pass either the canonical lowercase form (`'arc.not_found'`,
|
|
136
|
+
* `'validation_error'`) or arc's UPPER_SNAKE business form
|
|
137
|
+
* (`'ORG_CONTEXT_REQUIRED'`).
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* if (isArcErrorCode(error, 'duplicate_key')) showRetryUI();
|
|
141
|
+
* if (isArcErrorCode(error, 'ORG_CONTEXT_REQUIRED')) promptOrgSelector();
|
|
142
|
+
*/
|
|
143
|
+
declare function isArcErrorCode(error: unknown, code: ArcErrorCode): error is ArcApiError;
|
|
144
|
+
/**
|
|
145
|
+
* Specific predicate for arc's bulk-preset + orgGuard safety code.
|
|
146
|
+
*
|
|
147
|
+
* Arc's bulk endpoints (`POST/PATCH/DELETE /:resource/bulk`) reject any call
|
|
148
|
+
* where `request.scope.organizationId` is missing — the wire signal is
|
|
149
|
+
* `403 { code: 'ORG_CONTEXT_REQUIRED', message, status: 403 }`. Hosts hitting
|
|
150
|
+
* this need to call `configureAuth({ getOrgId })` before retrying.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* try { await api.bulkCreate({ data: [...] }); }
|
|
154
|
+
* catch (e) {
|
|
155
|
+
* if (isOrgContextRequiredError(e)) {
|
|
156
|
+
* console.warn('Bulk requires org context. Configure: configureAuth({ getOrgId })');
|
|
157
|
+
* } else throw e;
|
|
158
|
+
* }
|
|
159
|
+
*/
|
|
160
|
+
declare function isOrgContextRequiredError(error: unknown): error is ArcApiError;
|
|
161
|
+
/**
|
|
162
|
+
* Specific predicate for validation failures (Fastify AJV + Mongoose
|
|
163
|
+
* ValidationError). When true, `error.fieldErrors` is populated with the
|
|
164
|
+
* `{ field: message }` map. Matches arc's `arc.validation_error` and the
|
|
165
|
+
* canonical `validation_error` from repo-core.
|
|
166
|
+
*/
|
|
167
|
+
declare function isValidationError(error: unknown): error is ArcApiError;
|
|
168
|
+
/**
|
|
169
|
+
* Specific predicate for unique-constraint violations. Arc's errorHandler
|
|
170
|
+
* classifies these uniformly across MongoDB E11000, Postgres 23505,
|
|
171
|
+
* Prisma P2002 → `arc.conflict` (with `details[].code === 'duplicate_key'`).
|
|
172
|
+
*/
|
|
173
|
+
declare function isDuplicateKeyError(error: unknown): error is ArcApiError;
|
|
49
174
|
interface ClientConfig {
|
|
50
175
|
baseUrl: string;
|
|
51
176
|
internalApiKey?: string;
|
|
@@ -79,7 +204,101 @@ interface ClientConfig {
|
|
|
79
204
|
* Default: false — opt-in per-request via `idempotencyKey` option.
|
|
80
205
|
*/
|
|
81
206
|
autoIdempotency?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Send `x-arc-scope: platform` on every request. Triggers arc's elevated-scope
|
|
209
|
+
* upgrade (member → elevated) when the caller has the appropriate permission.
|
|
210
|
+
* Use sparingly — typically only for internal admin tooling.
|
|
211
|
+
* Per-request override: set `elevated: true | false` on `RequestOptions`.
|
|
212
|
+
*/
|
|
213
|
+
elevated?: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Network-failure + 5xx retry policy. Off by default — TanStack Query already
|
|
216
|
+
* retries query reads (3× by default), but the SDK's mutation flow and any
|
|
217
|
+
* direct `handleApiRequest` call get nothing without this.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* configureClient({
|
|
221
|
+
* baseUrl,
|
|
222
|
+
* retry: { attempts: 3, backoff: 'exponential' },
|
|
223
|
+
* });
|
|
224
|
+
*/
|
|
225
|
+
retry?: RetryConfig;
|
|
226
|
+
/**
|
|
227
|
+
* Mutate the outgoing request before fetch. Runs once per attempt (so a retry
|
|
228
|
+
* re-runs the interceptor — useful for refreshed tokens or rotated trace IDs).
|
|
229
|
+
* Return the (possibly modified) context. Async is supported.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* configureClient({
|
|
233
|
+
* baseUrl,
|
|
234
|
+
* beforeRequest: (req) => ({
|
|
235
|
+
* ...req,
|
|
236
|
+
* headers: { ...req.headers, 'x-correlation-id': crypto.randomUUID() },
|
|
237
|
+
* }),
|
|
238
|
+
* });
|
|
239
|
+
*/
|
|
240
|
+
beforeRequest?: BeforeRequestInterceptor;
|
|
241
|
+
/**
|
|
242
|
+
* Inspect or transform the parsed response body. Receives the same shape the
|
|
243
|
+
* SDK is about to return; returning a new `body` replaces it. Errors are not
|
|
244
|
+
* forwarded here — they throw `ArcApiError` before this runs. Async is supported.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* configureClient({
|
|
248
|
+
* baseUrl,
|
|
249
|
+
* afterResponse: (res) => {
|
|
250
|
+
* console.log(`[arc] ${res.method} ${res.endpoint} ${res.status} ${res.durationMs}ms`);
|
|
251
|
+
* return res; // unchanged
|
|
252
|
+
* },
|
|
253
|
+
* });
|
|
254
|
+
*/
|
|
255
|
+
afterResponse?: AfterResponseInterceptor;
|
|
256
|
+
}
|
|
257
|
+
interface RetryConfig {
|
|
258
|
+
/** Total attempts including the first. `attempts: 3` means 1 try + 2 retries. Default: 0 (off). */
|
|
259
|
+
attempts?: number;
|
|
260
|
+
/**
|
|
261
|
+
* Backoff strategy.
|
|
262
|
+
* - `'exponential'` (default): `min(300 * 2^n, 10_000)` ms
|
|
263
|
+
* - `'linear'`: `300 * (n + 1)` ms
|
|
264
|
+
* - `(attempt) => number`: custom delay in ms; receives the 0-indexed retry attempt
|
|
265
|
+
*/
|
|
266
|
+
backoff?: 'exponential' | 'linear' | ((attempt: number) => number);
|
|
267
|
+
/**
|
|
268
|
+
* Whitelist of statuses to retry on, OR a predicate. Defaults to a function
|
|
269
|
+
* that returns true for: any non-`ArcApiError` (network failure / fetch
|
|
270
|
+
* TypeError) AND `ArcApiError.status >= 500 && < 600`. Never retries on
|
|
271
|
+
* AbortError or 4xx.
|
|
272
|
+
*/
|
|
273
|
+
retryOn?: number[] | ((error: unknown) => boolean);
|
|
274
|
+
}
|
|
275
|
+
/** Context handed to {@link ClientConfig.beforeRequest}. Mutate + return to override. */
|
|
276
|
+
interface BeforeRequestContext {
|
|
277
|
+
method: HttpMethod;
|
|
278
|
+
endpoint: string;
|
|
279
|
+
/** Headers about to be sent. Mutating this is the recommended way to inject auth/trace headers. */
|
|
280
|
+
headers: Record<string, string>;
|
|
281
|
+
/** Body as the SDK is about to send it (already JSON-stringified, FormData, or undefined). */
|
|
282
|
+
body: BodyInit | undefined;
|
|
283
|
+
/** AbortSignal forwarded to fetch, if any. */
|
|
284
|
+
signal?: AbortSignal;
|
|
285
|
+
/** 0 on first attempt, 1+ on retries — useful for trace stamping. */
|
|
286
|
+
attempt: number;
|
|
82
287
|
}
|
|
288
|
+
type BeforeRequestInterceptor = (ctx: BeforeRequestContext) => BeforeRequestContext | Promise<BeforeRequestContext>;
|
|
289
|
+
/** Context handed to {@link ClientConfig.afterResponse}. */
|
|
290
|
+
interface AfterResponseContext<T = unknown> {
|
|
291
|
+
method: HttpMethod;
|
|
292
|
+
endpoint: string;
|
|
293
|
+
status: number;
|
|
294
|
+
/** Parsed response body — JSON object, blob wrapper, or text wrapper depending on Content-Type. */
|
|
295
|
+
body: T;
|
|
296
|
+
/** Total elapsed milliseconds from `beforeRequest` invocation to response parse complete. */
|
|
297
|
+
durationMs: number;
|
|
298
|
+
/** Original Response — clone before reading body if you need raw access. */
|
|
299
|
+
response: Response;
|
|
300
|
+
}
|
|
301
|
+
type AfterResponseInterceptor = <T = unknown>(ctx: AfterResponseContext<T>) => AfterResponseContext<T> | Promise<AfterResponseContext<T>>;
|
|
83
302
|
/**
|
|
84
303
|
* Configure the API client. Call once at app init before any API requests.
|
|
85
304
|
*
|
|
@@ -104,6 +323,16 @@ declare function getBaseUrl(): string;
|
|
|
104
323
|
/** Whether auto-idempotency is enabled on the global client. */
|
|
105
324
|
declare function isAutoIdempotency(): boolean;
|
|
106
325
|
interface AuthConfig {
|
|
326
|
+
/**
|
|
327
|
+
* Returns the current bearer/API token, or `null` if not authenticated.
|
|
328
|
+
*
|
|
329
|
+
* **MUST resolve synchronously.** The signature is `() => string | null`, never
|
|
330
|
+
* `Promise<string | null>`. If your auth library exposes an async session getter
|
|
331
|
+
* (Better Auth, NextAuth, Clerk, OAuth flows), refresh the token out-of-band
|
|
332
|
+
* (timer, event listener, lazy 401 retry) and have `getToken` return the *cached*
|
|
333
|
+
* value. Returning a Promise will be detected and warned about in dev — but the
|
|
334
|
+
* underlying token will be silently treated as `null`, causing 401s.
|
|
335
|
+
*/
|
|
107
336
|
getToken?: () => string | null;
|
|
108
337
|
getOrgId?: () => string | null;
|
|
109
338
|
/** Custom auth header name. Used when authMode is 'header'. Default: 'x-api-key' */
|
|
@@ -115,11 +344,15 @@ interface AuthConfig {
|
|
|
115
344
|
*
|
|
116
345
|
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
117
346
|
*
|
|
347
|
+
* **Token resolution is synchronous.** `getToken` must return `string | null`
|
|
348
|
+
* synchronously — never a Promise. See {@link AuthConfig.getToken} for guidance
|
|
349
|
+
* on bridging async auth libraries via cached values.
|
|
350
|
+
*
|
|
118
351
|
* @example
|
|
119
352
|
* // Cookie auth (no token needed)
|
|
120
353
|
* configureAuth({ getOrgId: () => currentOrg.id });
|
|
121
354
|
*
|
|
122
|
-
* // Bearer auth
|
|
355
|
+
* // Bearer auth — token is cached synchronously by the auth library
|
|
123
356
|
* configureAuth({
|
|
124
357
|
* getToken: () => session?.accessToken ?? null,
|
|
125
358
|
* getOrgId: () => currentOrg?.id ?? null,
|
|
@@ -133,6 +366,23 @@ declare function getAuthContext(): {
|
|
|
133
366
|
token: string | null;
|
|
134
367
|
organizationId: string | null;
|
|
135
368
|
};
|
|
369
|
+
/** @internal — exposed for tests; resets the dev-warn dedup flag. */
|
|
370
|
+
declare function _resetAuthWarnings(): void;
|
|
371
|
+
/** Protocol family the URL should target. `http` keeps `getBaseUrl()` as-is; `ws` rewrites `http(s)://` → `ws(s)://`. */
|
|
372
|
+
type StreamUrlProtocol = 'http' | 'ws';
|
|
373
|
+
/**
|
|
374
|
+
* Build an auth-aware URL using the global client + auth singletons.
|
|
375
|
+
*
|
|
376
|
+
* Single source of truth for {@link import('./sse.js').buildSseUrl} (HTTP) and
|
|
377
|
+
* {@link import('./ws.js').buildWsUrl} (WebSocket). Both delegate here so the
|
|
378
|
+
* auth-injection rule (org always, token only when `authMode !== 'cookie'`)
|
|
379
|
+
* stays in one place and can't drift.
|
|
380
|
+
*
|
|
381
|
+
* @param path Path appended to the base URL (leading slash recommended).
|
|
382
|
+
* @param params Caller-supplied params; merged with auth params. Caller wins on key collision.
|
|
383
|
+
* @param protocol `'http'` (default) or `'ws'` — controls the protocol rewrite.
|
|
384
|
+
*/
|
|
385
|
+
declare function buildStreamUrl(path: string, params?: Record<string, string | number | boolean | null | undefined>, protocol?: StreamUrlProtocol): string;
|
|
136
386
|
type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
137
387
|
/** Returned by `handleApiRequest` for PDF, image, and CSV responses. */
|
|
138
388
|
interface BlobResponse {
|
|
@@ -155,6 +405,11 @@ interface ApiRequestOptions {
|
|
|
155
405
|
signal?: AbortSignal;
|
|
156
406
|
/** Explicit idempotency key for this request. Sent as `Idempotency-Key` header. */
|
|
157
407
|
idempotencyKey?: string;
|
|
408
|
+
/**
|
|
409
|
+
* Send `x-arc-scope: platform` for this request only — overrides `ClientConfig.elevated`.
|
|
410
|
+
* Pass `false` to suppress when client-level elevation is on.
|
|
411
|
+
*/
|
|
412
|
+
elevated?: boolean;
|
|
158
413
|
}
|
|
159
414
|
interface ArcClientConfig extends ClientConfig {
|
|
160
415
|
toast?: ToastHandler;
|
|
@@ -198,6 +453,41 @@ interface ArcClient {
|
|
|
198
453
|
* });
|
|
199
454
|
*/
|
|
200
455
|
declare function createClient(config: ArcClientConfig): ArcClient;
|
|
456
|
+
/**
|
|
457
|
+
* Create an `ArcClient` wired to the global `configureClient` + `configureAuth` setup.
|
|
458
|
+
*
|
|
459
|
+
* Removes the boilerplate every consumer SDK writes by hand (auth-injection adapter
|
|
460
|
+
* + `BaseApi` constructor with `client: { request: handleApiRequest, config: ... }`).
|
|
461
|
+
* The returned client reads `getToken` / `getOrgId` lazily on each request, so token
|
|
462
|
+
* rotation in the global auth layer takes effect immediately.
|
|
463
|
+
*
|
|
464
|
+
* Equivalent to `createClient(...)` with `getToken`/`getOrgId` pulled from
|
|
465
|
+
* `getAuthContext()`. Pass `overrides` to customize specific fields without
|
|
466
|
+
* rebuilding the whole transport.
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* // App init (somewhere in a "use client" provider)
|
|
470
|
+
* configureClient({ baseUrl: process.env.NEXT_PUBLIC_API_URL! });
|
|
471
|
+
* configureAuth({
|
|
472
|
+
* getToken: () => session?.accessToken ?? null,
|
|
473
|
+
* getOrgId: () => currentOrg?.id ?? null,
|
|
474
|
+
* });
|
|
475
|
+
*
|
|
476
|
+
* // SDK module
|
|
477
|
+
* import { createAuthAwareClient } from '@classytic/arc-next/client';
|
|
478
|
+
* import { createCrudApi } from '@classytic/arc-next/api';
|
|
479
|
+
*
|
|
480
|
+
* const client = createAuthAwareClient();
|
|
481
|
+
* export const productsApi = createCrudApi('products', { client });
|
|
482
|
+
*
|
|
483
|
+
* // With per-call overrides
|
|
484
|
+
* const analyticsClient = createAuthAwareClient({
|
|
485
|
+
* baseUrl: 'https://analytics.example.com',
|
|
486
|
+
* authMode: 'header',
|
|
487
|
+
* headerName: 'x-api-key',
|
|
488
|
+
* });
|
|
489
|
+
*/
|
|
490
|
+
declare function createAuthAwareClient(overrides?: Partial<ArcClientConfig>): ArcClient;
|
|
201
491
|
/**
|
|
202
492
|
* Get auth context for a specific client instance, falling back to global.
|
|
203
493
|
*/
|
|
@@ -210,8 +500,8 @@ declare function getClientAuthContext(client?: ArcClient): {
|
|
|
210
500
|
* Handles JSON, binary (PDF, images), CSV, and text responses.
|
|
211
501
|
*
|
|
212
502
|
* @example
|
|
213
|
-
* const
|
|
214
|
-
* const response = await handleApiRequest<
|
|
503
|
+
* const user = await handleApiRequest<User>('GET', '/users/me');
|
|
504
|
+
* const response = await handleApiRequest<PaginatedResult<Product>>('GET', '/products?page=1');
|
|
215
505
|
*/
|
|
216
506
|
declare function handleApiRequest<T = unknown>(method: HttpMethod, endpoint: string, options?: ApiRequestOptions): Promise<T>;
|
|
217
507
|
/**
|
|
@@ -232,4 +522,4 @@ declare function handleApiRequest<T = unknown>(method: HttpMethod, endpoint: str
|
|
|
232
522
|
*/
|
|
233
523
|
declare function createQueryString<T extends Record<string, unknown>>(params?: T): string;
|
|
234
524
|
//#endregion
|
|
235
|
-
export { ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, AuthConfig, BlobResponse, ClientConfig, HttpMethod, TextResponse, ToastHandler, UseRouterHook, configureAuth, configureClient, createClient, createQueryString, getAuthContext, getAuthMode, getBaseUrl, getClientAuthContext, handleApiRequest, isArcApiError, isAutoIdempotency };
|
|
525
|
+
export { AfterResponseContext, AfterResponseInterceptor, ApiRequestOptions, ArcApiError, ArcApiErrorOptions, ArcClient, ArcClientConfig, ArcErrorCode, AuthConfig, BeforeRequestContext, BeforeRequestInterceptor, BlobResponse, ClientConfig, HttpMethod, KNOWN_ARC_ERROR_CODES, RetryConfig, StreamUrlProtocol, TextResponse, ToastHandler, UseRouterHook, _resetAuthWarnings, buildStreamUrl, configureAuth, configureClient, createAuthAwareClient, createClient, createQueryString, getAuthContext, getAuthMode, getBaseUrl, getClientAuthContext, handleApiRequest, isAbortError, isArcApiError, isArcErrorCode, isAutoIdempotency, isDuplicateKeyError, isOrgContextRequiredError, isValidationError };
|