@routar/core 1.5.0 → 1.7.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/dist/index.d.cts CHANGED
@@ -1,3 +1,83 @@
1
+ /**
2
+ * The Standard Schema interface (v1), vendored to keep `@routar/core`
3
+ * dependency-free. Standard Schema is the common validation interface adopted
4
+ * by Zod 3.24+, Valibot, ArkType, and others — exposed via the `~standard`
5
+ * property. The spec is type-only (no runtime), and the authors explicitly
6
+ * permit copying the interface rather than depending on `@standard-schema/spec`.
7
+ *
8
+ * @see https://standardschema.dev
9
+ */
10
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
11
+ /** The Standard Schema properties. */
12
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
13
+ }
14
+ declare namespace StandardSchemaV1 {
15
+ /** The Standard Schema properties interface. */
16
+ interface Props<Input = unknown, Output = Input> {
17
+ /** The version number of the standard. */
18
+ readonly version: 1;
19
+ /** The vendor name of the schema library. */
20
+ readonly vendor: string;
21
+ /** Validates unknown input values. */
22
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
23
+ /** Inferred types associated with the schema. */
24
+ readonly types?: Types<Input, Output> | undefined;
25
+ }
26
+ /** The result interface of the validate function. */
27
+ type Result<Output> = SuccessResult<Output> | FailureResult;
28
+ /** The result interface if validation succeeds. */
29
+ interface SuccessResult<Output> {
30
+ /** The typed output value. */
31
+ readonly value: Output;
32
+ /** The non-existent issues. */
33
+ readonly issues?: undefined;
34
+ }
35
+ /** The result interface if validation fails. */
36
+ interface FailureResult {
37
+ /** The issues of failed validation. */
38
+ readonly issues: ReadonlyArray<Issue>;
39
+ }
40
+ /** The issue interface of the failure output. */
41
+ interface Issue {
42
+ /** The error message of the issue. */
43
+ readonly message: string;
44
+ /** The path of the issue, if any. */
45
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
46
+ }
47
+ /** The path segment interface of the issue. */
48
+ interface PathSegment {
49
+ /** The key representing a path segment. */
50
+ readonly key: PropertyKey;
51
+ }
52
+ /** The Standard Schema types interface. */
53
+ interface Types<Input = unknown, Output = Input> {
54
+ /** The input type of the schema. */
55
+ readonly input: Input;
56
+ /** The output type of the schema. */
57
+ readonly output: Output;
58
+ }
59
+ /** Infers the input type of a Standard Schema. */
60
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
61
+ /** Infers the output type of a Standard Schema. */
62
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
63
+ }
64
+
65
+ declare class ValidationError extends Error {
66
+ readonly cause?: unknown;
67
+ constructor(message: string, cause?: unknown);
68
+ }
69
+ /**
70
+ * Thrown internally when a Standard Schema validator (`~standard.validate`)
71
+ * reports issues. It is wrapped as the `cause` of a {@link ValidationError} by
72
+ * the API client, mirroring how a thrown `.parse()` error becomes the cause —
73
+ * so callers branch on `ValidationError` regardless of the validator library.
74
+ * The structured `issues` array is preserved for drift reporting.
75
+ */
76
+ declare class StandardSchemaError extends Error {
77
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
78
+ constructor(issues: ReadonlyArray<StandardSchemaV1.Issue>);
79
+ }
80
+
1
81
  type HttpMethod = "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
2
82
  /** Options passed to {@link Executor.execute} on every HTTP call. */
3
83
  interface ExecuteOptions {
@@ -13,6 +93,39 @@ interface ExecuteOptions {
13
93
  headers?: Record<string, string>;
14
94
  signal?: AbortSignal;
15
95
  }
96
+ /**
97
+ * Per-call transport options, passed as the optional second argument to any
98
+ * generated endpoint function: `api.create(params, { signal, headers, timeout })`.
99
+ *
100
+ * Passing a bare {@link AbortSignal} as the second argument is still supported
101
+ * (backward compatible) — it is treated as `{ signal }`.
102
+ *
103
+ * @example
104
+ * ```ts
105
+ * await api.create({ body }, {
106
+ * signal: controller.signal,
107
+ * headers: { 'Idempotency-Key': key },
108
+ * timeout: 30_000,
109
+ * });
110
+ * ```
111
+ */
112
+ interface EndpointCallOptions {
113
+ /** Aborts the request when the signal fires. */
114
+ signal?: AbortSignal;
115
+ /**
116
+ * Per-call headers. Seeded onto the request before plugin `onRequest` hooks
117
+ * run, and merged over the executor's default headers — so per-call headers
118
+ * win over defaults. A plugin that sets the same header key still wins on
119
+ * collision (plugins are cross-cutting policy such as auth).
120
+ */
121
+ headers?: Record<string, string>;
122
+ /**
123
+ * Per-call timeout in milliseconds. Aborts the request with a `TimeoutError`
124
+ * when exceeded. Applied by the core client (transport-agnostic) and composes
125
+ * with any executor-level timeout (whichever fires first wins).
126
+ */
127
+ timeout?: number;
128
+ }
16
129
  /**
17
130
  * Transport abstraction. Implement this to support any HTTP client.
18
131
  *
@@ -50,7 +163,17 @@ interface ExecutorPlugin {
50
163
  onRequest?: (opts: ExecuteOptions) => ExecuteOptions | Promise<ExecuteOptions>;
51
164
  /** Runs after a successful response. Return a modified value to transform the response. */
52
165
  onResponse?: (response: unknown, opts: ExecuteOptions) => unknown | Promise<unknown>;
53
- /** Runs when the request throws. Must re-throw (or throw a different error). */
166
+ /**
167
+ * Runs when the request throws.
168
+ *
169
+ * The return value is ignored — this hook MUST always throw. To transform
170
+ * the error, throw a new error from within the hook (the original error is
171
+ * not automatically re-thrown for you).
172
+ *
173
+ * Transport errors reaching this hook are normalized to `HttpError` across
174
+ * all executors (fetch, Axios, ky), so you can branch on `instanceof
175
+ * HttpError` without depending on the underlying client.
176
+ */
54
177
  onError?: (error: unknown, opts: ExecuteOptions) => never | Promise<never>;
55
178
  }
56
179
  /**
@@ -66,6 +189,21 @@ interface ExecutorPlugin {
66
189
  interface CreateExecutorOptions {
67
190
  /** Plugins applied in declaration order (first plugin is outermost). */
68
191
  plugins?: ExecutorPlugin[];
192
+ /**
193
+ * Transforms the raw response immediately after the transport returns,
194
+ * before any plugin `onResponse` hooks and before schema validation in
195
+ * `createApi`. Use to unwrap envelope shapes like `{ data: T }`.
196
+ *
197
+ * Equivalent to an innermost `onResponse` plugin, but declarative.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * const executor = createExecutor(transport, {
202
+ * unwrap: (raw) => (raw as { data: unknown })?.data ?? raw,
203
+ * });
204
+ * ```
205
+ */
206
+ unwrap?: (raw: unknown) => unknown;
69
207
  }
70
208
  /**
71
209
  * Any object with a `parse` method — compatible with Zod, Valibot, Yup, etc.
@@ -75,8 +213,24 @@ interface CreateExecutorOptions {
75
213
  interface Validator<TOutput> {
76
214
  parse(data: unknown): TOutput;
77
215
  }
78
- /** Extracts the output type of a {@link Validator}. */
79
- type ValidatorOutput<T extends Validator<unknown>> = T extends Validator<infer O> ? O : never;
216
+ /**
217
+ * A validator accepted by routar: either the `.parse()` duck-typed
218
+ * {@link Validator} (Zod, Valibot, Yup, or any object with `.parse()`) **or** a
219
+ * [Standard Schema](https://standardschema.dev) (`~standard` — Zod 3.24+,
220
+ * Valibot, ArkType, …). Both forms are validated at runtime; the `.parse()` path
221
+ * is preferred when present (synchronous), otherwise `~standard.validate` is
222
+ * used (sync or async).
223
+ *
224
+ * @template TOutput Parsed/validated output type.
225
+ */
226
+ type AnyValidator<TOutput = unknown> = Validator<TOutput> | StandardSchemaV1<unknown, TOutput>;
227
+ /**
228
+ * Extracts the output type of an {@link AnyValidator} — the `.parse()` return
229
+ * type for a {@link Validator}, or the Standard Schema output type. The
230
+ * `Validator` branch is checked first so a schema satisfying both (e.g. Zod)
231
+ * resolves through its `.parse()` signature.
232
+ */
233
+ type ValidatorOutput<T> = T extends Validator<infer O> ? O : T extends StandardSchemaV1<unknown, infer O> ? O : never;
80
234
  /**
81
235
  * Shape of an endpoint's request parameters.
82
236
  *
@@ -98,11 +252,11 @@ interface RequestShape {
98
252
  * @template TResponse Validator for the raw response.
99
253
  * @template TAdapter Optional adapter function type.
100
254
  */
101
- interface EndpointSpec<TRequest extends RequestShape = RequestShape, TResponse extends Validator<unknown> = Validator<unknown>, TAdapter extends ((raw: ValidatorOutput<TResponse>) => unknown) | undefined = undefined> {
255
+ interface EndpointSpec<TRequest extends RequestShape = RequestShape, TResponse extends AnyValidator = AnyValidator, TAdapter extends ((raw: ValidatorOutput<TResponse>) => unknown) | undefined = undefined> {
102
256
  method: HttpMethod;
103
257
  path: string;
104
258
  /** Validates and narrows request parameters before the HTTP call. */
105
- request?: Validator<TRequest>;
259
+ request?: AnyValidator<TRequest>;
106
260
  /** Validates the raw server response. */
107
261
  response: TResponse;
108
262
  /**
@@ -151,6 +305,31 @@ type ApiTypes<TApi> = {
151
305
  response: R;
152
306
  } : TApi[K] extends object ? ApiTypes<TApi[K]> : never;
153
307
  };
308
+ /**
309
+ * Per-kind validation mode.
310
+ *
311
+ * - `true` (default) — validate and throw {@link ValidationError} on failure.
312
+ * - `false` — skip validation; raw data passes through untouched.
313
+ * - `'warn'` — attempt validation but, on failure, pass the raw data through
314
+ * and report the error via {@link CreateApiOptions.onValidationError} instead
315
+ * of throwing. The drift-observation mode: surface schema drift without
316
+ * turning it into an outage.
317
+ */
318
+ type ValidationMode = boolean | "warn";
319
+ /**
320
+ * Context passed to {@link CreateApiOptions.onValidationError} describing which
321
+ * call and which phase produced the validation failure.
322
+ */
323
+ interface ValidationErrorContext {
324
+ /** Which phase failed — request params or the server response. */
325
+ kind: "request" | "response";
326
+ /** The endpoint's HTTP method. */
327
+ method: HttpMethod;
328
+ /** The resolved request URL (path is already substituted). */
329
+ url: string;
330
+ /** The raw data that failed validation (raw params or raw response). */
331
+ data: unknown;
332
+ }
154
333
  /**
155
334
  * Options for {@link createApi}.
156
335
  *
@@ -161,6 +340,12 @@ type ApiTypes<TApi> = {
161
340
  *
162
341
  * // Keep request validation (catch call-site bugs), skip response in prod
163
342
  * createApi(executor, router, { validate: { request: true, response: false } });
343
+ *
344
+ * // Observe response drift without breaking production
345
+ * createApi(executor, router, {
346
+ * validate: { request: true, response: 'warn' },
347
+ * onValidationError: (err, ctx) => Sentry.captureException(err, { extra: ctx }),
348
+ * });
164
349
  * ```
165
350
  */
166
351
  interface CreateApiOptions {
@@ -169,18 +354,25 @@ interface CreateApiOptions {
169
354
  *
170
355
  * - `true` (default) — validate both request and response.
171
356
  * - `false` — skip both; raw params and raw response pass through.
172
- * - `{ request?, response? }` enable/disable each independently.
357
+ * - `'warn'` validate both, but pass raw data through and report via
358
+ * {@link CreateApiOptions.onValidationError} instead of throwing.
359
+ * - `{ request?, response? }` — set each independently (each a
360
+ * {@link ValidationMode}).
173
361
  */
174
- validate?: boolean | {
175
- request?: boolean;
176
- response?: boolean;
362
+ validate?: ValidationMode | {
363
+ request?: ValidationMode;
364
+ response?: ValidationMode;
177
365
  };
366
+ /**
367
+ * Called when validation fails under `'warn'` mode (instead of throwing).
368
+ * Use it to report schema drift to your observability stack. Never called
369
+ * when `validate` is `true` (which throws) or `false` (which skips).
370
+ */
371
+ onValidationError?: (error: ValidationError, context: ValidationErrorContext) => void;
178
372
  }
179
373
 
180
374
  /** Callable type for a single endpoint on the generated API client. */
181
- type EndpointFn<TSpec extends EndpointSpec<any, any, any>> = TSpec["request"] extends {
182
- parse: (data: unknown) => infer R;
183
- } ? (params: R, signal?: AbortSignal) => Promise<InferResponse<TSpec>> : (params?: RequestShape, signal?: AbortSignal) => Promise<InferResponse<TSpec>>;
375
+ type EndpointFn<TSpec extends EndpointSpec<any, any, any>> = TSpec["request"] extends Validator<infer R> ? (params: R, options?: AbortSignal | EndpointCallOptions) => Promise<InferResponse<TSpec>> : TSpec["request"] extends StandardSchemaV1<unknown, infer O> ? (params: O, options?: AbortSignal | EndpointCallOptions) => Promise<InferResponse<TSpec>> : (params?: RequestShape, options?: AbortSignal | EndpointCallOptions) => Promise<InferResponse<TSpec>>;
184
376
  /**
185
377
  * Fully-typed API client produced by {@link createApi}.
186
378
  * Nested {@link RouterDef} entries become nested sub-client objects.
@@ -283,6 +475,13 @@ declare function createApi<TEndpoints extends RouterEndpoints>(executor: Executo
283
475
  * plugins: [authPlugin, logger()],
284
476
  * });
285
477
  * ```
478
+ *
479
+ * @example Unwrap an envelope response
480
+ * ```ts
481
+ * const executor = createExecutor(transport, {
482
+ * unwrap: (raw) => (raw as { data: unknown })?.data ?? raw,
483
+ * });
484
+ * ```
286
485
  */
287
486
  declare function createExecutor(execute: (options: ExecuteOptions) => Promise<unknown>, options?: CreateExecutorOptions): Executor;
288
487
  /**
@@ -320,6 +519,8 @@ interface FetchExecutorOptions extends CreateExecutorOptions {
320
519
  * - Non-2xx responses throw an {@link HttpError}.
321
520
  *
322
521
  * @param baseURL - Absolute base URL prepended to every endpoint path.
522
+ * Accepts a static string or a sync/async factory called on every request —
523
+ * useful when the origin depends on runtime environment (e.g. SSR vs CSR).
323
524
  * @param options.defaultHeaders - Async factory called on every request to
324
525
  * produce headers (e.g. reading cookies in a Next.js server component).
325
526
  * @param options.plugins - Plugins applied around the fetch call. Each retry
@@ -335,6 +536,13 @@ interface FetchExecutorOptions extends CreateExecutorOptions {
335
536
  * const executor = createFetchExecutor('https://api.example.com');
336
537
  * ```
337
538
  *
539
+ * @example Dynamic base URL for SSR/CSR
540
+ * ```ts
541
+ * const executor = createFetchExecutor(
542
+ * () => typeof window === 'undefined' ? 'http://localhost:3000/api' : '/api',
543
+ * );
544
+ * ```
545
+ *
338
546
  * @example SSR with bearer token
339
547
  * ```ts
340
548
  * const executor = createFetchExecutor('https://api.example.com', {
@@ -353,10 +561,14 @@ interface FetchExecutorOptions extends CreateExecutorOptions {
353
561
  * });
354
562
  * ```
355
563
  */
356
- declare function createFetchExecutor(baseURL: string, options?: FetchExecutorOptions): Executor;
564
+ declare function createFetchExecutor(baseURL: string | (() => string | Promise<string>), options?: FetchExecutorOptions): Executor;
357
565
  /**
358
566
  * Thrown by {@link createFetchExecutor} when the server returns a non-2xx
359
- * status code.
567
+ * status code. The Axios and ky executors also normalize their transport
568
+ * errors to `HttpError`, so `onError` plugins and callers can branch on a
569
+ * single error type regardless of the underlying transport. The original
570
+ * transport error (e.g. an `AxiosError` or ky `HTTPError`) is preserved on
571
+ * the `cause` property.
360
572
  *
361
573
  * @example
362
574
  * ```ts
@@ -373,7 +585,13 @@ declare class HttpError extends Error {
373
585
  readonly status: number;
374
586
  readonly statusText: string;
375
587
  readonly body: unknown;
376
- constructor(status: number, statusText: string, body?: unknown);
588
+ readonly url?: string;
589
+ readonly method?: string;
590
+ constructor(status: number, statusText: string, body?: unknown, options?: {
591
+ url?: string;
592
+ method?: string;
593
+ cause?: unknown;
594
+ });
377
595
  }
378
596
 
379
597
  /**
@@ -393,6 +611,33 @@ type PathParams<TPath extends string> = TPath extends `${string}:${infer Param}/
393
611
  type PathConstraint<TPath extends string> = [PathParams<TPath>] extends [never] ? {} : {
394
612
  path: Record<PathParams<TPath>, unknown>;
395
613
  };
614
+ /**
615
+ * Builds the envelope request output type from the SE-12 separated bucket
616
+ * validators. Each bucket contributes its key only when supplied — the tuple
617
+ * wrapping (`[T] extends [never]`) prevents the `never` default from
618
+ * distributing and collapsing the whole intersection.
619
+ */
620
+ type BucketRequestOutput<TPathParams, TQuery, TBody> = ([
621
+ TPathParams
622
+ ] extends [never] ? {} : {
623
+ path: ValidatorOutput<TPathParams>;
624
+ }) & ([TQuery] extends [never] ? {} : {
625
+ query: ValidatorOutput<TQuery>;
626
+ }) & ([TBody] extends [never] ? {} : {
627
+ body: ValidatorOutput<TBody>;
628
+ });
629
+ /**
630
+ * The `pathParams` field of the separated form: required when `TPath` has
631
+ * dynamic segments, optional otherwise. The validator type is further
632
+ * constrained (at the generic level) to cover every `:param` name.
633
+ */
634
+ type BucketPathField<TPath extends string, TPathParams> = [
635
+ PathParams<TPath>
636
+ ] extends [never] ? {
637
+ pathParams?: TPathParams;
638
+ } : {
639
+ pathParams: TPathParams;
640
+ };
396
641
  /**
397
642
  * Type-safe endpoint definition helper.
398
643
  *
@@ -465,31 +710,31 @@ type PathConstraint<TPath extends string> = [PathParams<TPath>] extends [never]
465
710
  * });
466
711
  * ```
467
712
  */
468
- declare function endpoint<TMethod extends HttpMethod, TPath extends string, TRequest extends RequestShape & PathConstraint<TPath>, TResponse extends Validator<unknown>, TOut>(spec: {
713
+ declare function endpoint<TMethod extends HttpMethod, TPath extends string, TReq extends AnyValidator<RequestShape & PathConstraint<TPath>>, TResponse extends AnyValidator, TOut>(spec: {
469
714
  method: TMethod;
470
715
  path: TPath;
471
- request: Validator<TRequest>;
716
+ request: TReq;
472
717
  response: TResponse;
473
718
  adapter: (raw: ValidatorOutput<TResponse>) => TOut;
474
719
  }): {
475
720
  method: TMethod;
476
721
  path: string;
477
- request: Validator<TRequest>;
722
+ request: TReq;
478
723
  response: TResponse;
479
724
  adapter: (raw: ValidatorOutput<TResponse>) => TOut;
480
725
  };
481
- declare function endpoint<TMethod extends HttpMethod, TPath extends string, TRequest extends RequestShape & PathConstraint<TPath>, TResponse extends Validator<unknown>>(spec: {
726
+ declare function endpoint<TMethod extends HttpMethod, TPath extends string, TReq extends AnyValidator<RequestShape & PathConstraint<TPath>>, TResponse extends AnyValidator>(spec: {
482
727
  method: TMethod;
483
728
  path: TPath;
484
- request: Validator<TRequest>;
729
+ request: TReq;
485
730
  response: TResponse;
486
731
  }): {
487
732
  method: TMethod;
488
733
  path: string;
489
- request: Validator<TRequest>;
734
+ request: TReq;
490
735
  response: TResponse;
491
736
  };
492
- declare function endpoint<TMethod extends HttpMethod, TResponse extends Validator<unknown>, TOut>(spec: {
737
+ declare function endpoint<TMethod extends HttpMethod, TResponse extends AnyValidator, TOut>(spec: {
493
738
  method: TMethod;
494
739
  path: string;
495
740
  response: TResponse;
@@ -500,7 +745,7 @@ declare function endpoint<TMethod extends HttpMethod, TResponse extends Validato
500
745
  response: TResponse;
501
746
  adapter: (raw: ValidatorOutput<TResponse>) => TOut;
502
747
  };
503
- declare function endpoint<TMethod extends HttpMethod, TResponse extends Validator<unknown>>(spec: {
748
+ declare function endpoint<TMethod extends HttpMethod, TResponse extends AnyValidator>(spec: {
504
749
  method: TMethod;
505
750
  path: string;
506
751
  response: TResponse;
@@ -509,6 +754,32 @@ declare function endpoint<TMethod extends HttpMethod, TResponse extends Validato
509
754
  path: string;
510
755
  response: TResponse;
511
756
  };
757
+ declare function endpoint<TMethod extends HttpMethod, TPath extends string, TResponse extends AnyValidator, TOut, TPathParams extends AnyValidator<Record<PathParams<TPath>, unknown>> = never, TQuery extends AnyValidator = never, TBody extends AnyValidator = never>(spec: {
758
+ method: TMethod;
759
+ path: TPath;
760
+ query?: TQuery;
761
+ body?: TBody;
762
+ response: TResponse;
763
+ adapter: (raw: ValidatorOutput<TResponse>) => TOut;
764
+ } & BucketPathField<TPath, TPathParams>): {
765
+ method: TMethod;
766
+ path: string;
767
+ request: Validator<BucketRequestOutput<TPathParams, TQuery, TBody>>;
768
+ response: TResponse;
769
+ adapter: (raw: ValidatorOutput<TResponse>) => TOut;
770
+ };
771
+ declare function endpoint<TMethod extends HttpMethod, TPath extends string, TResponse extends AnyValidator, TPathParams extends AnyValidator<Record<PathParams<TPath>, unknown>> = never, TQuery extends AnyValidator = never, TBody extends AnyValidator = never>(spec: {
772
+ method: TMethod;
773
+ path: TPath;
774
+ query?: TQuery;
775
+ body?: TBody;
776
+ response: TResponse;
777
+ } & BucketPathField<TPath, TPathParams>): {
778
+ method: TMethod;
779
+ path: string;
780
+ request: Validator<BucketRequestOutput<TPathParams, TQuery, TBody>>;
781
+ response: TResponse;
782
+ };
512
783
 
513
784
  /**
514
785
  * Groups a set of endpoint specs (and optional nested routers) under a shared
@@ -596,9 +867,17 @@ declare function serializeParams(params: Record<string, unknown>): URLSearchPara
596
867
  declare function joinPaths(...segments: string[]): string;
597
868
  declare function resolvePath(pathTemplate: string, params?: Record<string, unknown>): string;
598
869
 
599
- declare class ValidationError extends Error {
600
- readonly cause?: unknown;
601
- constructor(message: string, cause?: unknown);
602
- }
870
+ /**
871
+ * Validates `data` with an {@link AnyValidator}, returning the parsed value.
872
+ *
873
+ * Prefers the synchronous `.parse()` path when present (Zod, Valibot, Yup, or
874
+ * any object with `.parse()`); a thrown parse error propagates unchanged.
875
+ * Otherwise uses the Standard Schema `~standard.validate` path (sync or async);
876
+ * reported issues are thrown as a {@link StandardSchemaError}.
877
+ *
878
+ * Exported for executor / mock-handler authors who need routar's exact
879
+ * validate-or-throw semantics for both validator styles.
880
+ */
881
+ declare function runValidator(validator: AnyValidator, data: unknown): Promise<unknown>;
603
882
 
604
- export { type ApiClient, type ApiClientWithRouter, type ApiTypes, type CreateApiOptions, type CreateExecutorOptions, type EndpointSpec, type ExecuteOptions, type Executor, type ExecutorPlugin, type FetchExecutorOptions, type FetchRetryOption, HttpError, type HttpMethod, type InferResponse, type PathParams, type RequestShape, type RouterDef, type RouterEndpoints, type RouterEntry, TimeoutError, ValidationError, type Validator, type ValidatorOutput, createApi, createExecutor, createFetchExecutor, definePlugin, defineRouter, dispatchExecutor, endpoint, isRouterDef, joinPaths, logger, resolvePath, serializeParams };
883
+ export { type AnyValidator, type ApiClient, type ApiClientWithRouter, type ApiTypes, type CreateApiOptions, type CreateExecutorOptions, type EndpointCallOptions, type EndpointSpec, type ExecuteOptions, type Executor, type ExecutorPlugin, type FetchExecutorOptions, type FetchRetryOption, HttpError, type HttpMethod, type InferResponse, type PathParams, type RequestShape, type RouterDef, type RouterEndpoints, type RouterEntry, StandardSchemaError, StandardSchemaV1, TimeoutError, ValidationError, type ValidationErrorContext, type ValidationMode, type Validator, type ValidatorOutput, createApi, createExecutor, createFetchExecutor, definePlugin, defineRouter, dispatchExecutor, endpoint, isRouterDef, joinPaths, logger, resolvePath, runValidator, serializeParams };