@spoosh/core 0.9.1 → 0.9.3

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.mts CHANGED
@@ -28,40 +28,32 @@ type QueryField<TQuery> = [TQuery] extends [never] ? object : {
28
28
  type BodyField<TBody> = [TBody] extends [never] ? object : {
29
29
  body: TBody;
30
30
  };
31
- type FormDataField<TFormData> = [TFormData] extends [never] ? object : {
32
- formData: TFormData;
33
- };
34
- type UrlEncodedField<TUrlEncoded> = [TUrlEncoded] extends [never] ? object : {
35
- urlEncoded: TUrlEncoded;
36
- };
37
31
  type ParamsField<TParamNames extends string> = [TParamNames] extends [never] ? object : {
38
32
  params: Record<TParamNames, string | number>;
39
33
  };
40
- type InputFields<TQuery, TBody, TFormData, TUrlEncoded, TParamNames extends string> = QueryField<TQuery> & BodyField<TBody> & FormDataField<TFormData> & UrlEncodedField<TUrlEncoded> & ParamsField<TParamNames>;
41
- type InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames extends string> = [TQuery, TBody, TFormData, TUrlEncoded, TParamNames] extends [
42
- never,
43
- never,
44
- never,
45
- never,
46
- never
47
- ] ? object : {
48
- input: InputFields<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>;
34
+ type InputFields<TQuery, TBody, TParamNames extends string> = QueryField<TQuery> & BodyField<TBody> & ParamsField<TParamNames>;
35
+ type InputFieldWrapper<TQuery, TBody, TParamNames extends string> = [
36
+ TQuery,
37
+ TBody,
38
+ TParamNames
39
+ ] extends [never, never, never] ? object : {
40
+ input: InputFields<TQuery, TBody, TParamNames>;
49
41
  };
50
- type SpooshResponse<TData, TError, TRequestOptions = unknown, TQuery = never, TBody = never, TFormData = never, TUrlEncoded = never, TParamNames extends string = never> = ({
42
+ type SpooshResponse<TData, TError, TRequestOptions = unknown, TQuery = never, TBody = never, TParamNames extends string = never> = ({
51
43
  status: number;
52
44
  data: TData;
53
45
  headers?: Headers;
54
46
  error?: undefined;
55
47
  aborted?: false;
56
48
  readonly __requestOptions?: TRequestOptions;
57
- } & InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>) | ({
49
+ } & InputFieldWrapper<TQuery, TBody, TParamNames>) | ({
58
50
  status: number;
59
51
  data?: undefined;
60
52
  headers?: Headers;
61
53
  error: TError;
62
54
  aborted?: boolean;
63
55
  readonly __requestOptions?: TRequestOptions;
64
- } & InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>);
56
+ } & InputFieldWrapper<TQuery, TBody, TParamNames>);
65
57
  type SpooshOptionsExtra<TData = unknown, TError = unknown> = {
66
58
  middlewares?: SpooshMiddleware<TData, TError>[];
67
59
  };
@@ -124,7 +116,7 @@ type MethodOptionsMap<TQueryOptions = object, TMutationOptions = object> = {
124
116
  DELETE: TMutationOptions;
125
117
  };
126
118
  type ExtractMethodOptions<TOptionsMap, TMethod extends HttpMethod> = TOptionsMap extends MethodOptionsMap<infer TQuery, infer TMutation> ? TMethod extends "GET" ? TQuery : TMutation : TOptionsMap;
127
- type FetchExecutor<TOptions = SpooshOptions, TRequestOptions = AnyRequestOptions> = <TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: TOptions, requestOptions?: TRequestOptions, nextTags?: boolean, tagPath?: string[]) => Promise<SpooshResponse<TData, TError>>;
119
+ type FetchExecutor<TOptions = SpooshOptions, TRequestOptions = AnyRequestOptions> = <TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: TOptions, requestOptions?: TRequestOptions, nextTags?: boolean) => Promise<SpooshResponse<TData, TError>>;
128
120
  type TypedParamsOption<TParamNames extends string> = [TParamNames] extends [
129
121
  never
130
122
  ] ? object : {
@@ -149,6 +141,7 @@ type EventCallback<T = unknown> = (payload: T) => void;
149
141
  interface BuiltInEvents {
150
142
  refetch: RefetchEvent;
151
143
  invalidate: string[];
144
+ refetchAll: void;
152
145
  }
153
146
  /**
154
147
  * Resolves event payload type. Built-in events get their specific type,
@@ -251,11 +244,6 @@ type PluginContext<TData = unknown, TError = unknown> = {
251
244
  readonly requestTimestamp: number;
252
245
  /** Unique identifier for the hook instance. Persists across queryKey changes within the same hook. */
253
246
  readonly hookId?: string;
254
- /**
255
- * Prefix to strip from tags. Configured at the Spoosh instance level.
256
- * Plugins can use this to normalize tags before emitting events.
257
- */
258
- readonly stripTagPrefix?: string;
259
247
  requestOptions: AnyRequestOptions;
260
248
  state: OperationState<TData, TError>;
261
249
  response?: SpooshResponse<TData, TError>;
@@ -563,13 +551,14 @@ type PluginAccessor = {
563
551
  get<K extends keyof PluginExportsRegistry>(name: K): PluginExportsRegistry[K] | undefined;
564
552
  get(name: string): unknown;
565
553
  };
554
+ type RefetchEventReason = "focus" | "reconnect" | "polling" | "invalidate";
566
555
  /**
567
556
  * Event emitted by plugins to request a refetch.
568
557
  * Hooks subscribe to this event and trigger controller.execute().
569
558
  */
570
559
  type RefetchEvent = {
571
560
  queryKey: string;
572
- reason: "focus" | "reconnect" | "polling" | "invalidate";
561
+ reason: RefetchEventReason | Omit<string, RefetchEventReason>;
573
562
  };
574
563
  /**
575
564
  * Minimal PluginExecutor interface for InstanceApiContext.
@@ -601,10 +590,7 @@ type PluginExecutor = {
601
590
  /** Creates a full PluginContext with plugins accessor injected */
602
591
  createContext: <TData, TError>(input: PluginContextInput<TData, TError>) => PluginContext<TData, TError>;
603
592
  };
604
- type PluginExecutorOptions = {
605
- stripTagPrefix?: string;
606
- };
607
- declare function createPluginExecutor(initialPlugins?: SpooshPlugin[], options?: PluginExecutorOptions): PluginExecutor;
593
+ declare function createPluginExecutor(initialPlugins?: SpooshPlugin[]): PluginExecutor;
608
594
 
609
595
  /**
610
596
  * Resolves plugin option types based on the full context.
@@ -794,16 +780,7 @@ type ExtractError<T, TDefault = unknown> = T extends {
794
780
  * const api = createClient<ApiSchema>({ baseUrl: "/api" });
795
781
  * ```
796
782
  */
797
- type SpooshSchema<T extends {
798
- [path: string]: {
799
- [M in HttpMethod]?: {
800
- data: unknown;
801
- body?: unknown;
802
- query?: unknown;
803
- error?: unknown;
804
- };
805
- };
806
- }> = T;
783
+ type SpooshSchema<T extends ApiSchema> = T;
807
784
  /**
808
785
  * Convert a route pattern like "posts/:id" to a path matcher pattern like `posts/${string}`.
809
786
  * This enables TypeScript to match actual paths like "posts/123" to their schema definitions.
@@ -815,7 +792,7 @@ type SpooshSchema<T extends {
815
792
  * type C = RouteToPath<"posts">; // "posts"
816
793
  * ```
817
794
  */
818
- type RouteToPath<T extends string> = T extends `${infer Start}/:${string}/${infer Rest}` ? `${Start}/${string}/${RouteToPath<Rest>}` : T extends `${infer Start}/:${string}` ? `${Start}/${string}` : T;
795
+ type RouteToPath<T extends string> = T extends `/${infer Rest}` ? `/${RouteToPath<Rest>}` : T extends `${infer Segment}/${infer Rest}` ? Segment extends `:${string}` ? `${string}/${RouteToPath<Rest>}` : `${Segment}/${RouteToPath<Rest>}` : T extends `:${string}` ? string : T;
819
796
  /**
820
797
  * Find which schema key matches a given path.
821
798
  * First checks for exact match, then checks pattern matches.
@@ -883,12 +860,12 @@ type StripPrefixFromPath<TPath extends string, TPrefix extends string> = TPath e
883
860
  * "api": { GET: { data: string } };
884
861
  * "api/users": { GET: { data: User[] } };
885
862
  * "api/posts/:id": { GET: { data: Post } };
886
- * "health": { GET: { data: { status: string } } };
863
+ * "api/health": { GET: { data: { status: string } } };
887
864
  * };
888
865
  *
889
866
  * type ApiSchema = StripPrefix<FullSchema, "api">;
890
867
  * // {
891
- * // "": { GET: { data: string } };
868
+ * // "/": { GET: { data: string } };
892
869
  * // "users": { GET: { data: User[] } };
893
870
  * // "posts/:id": { GET: { data: Post } };
894
871
  * // "health": { GET: { data: { status: string } } };
@@ -1019,7 +996,7 @@ type IsOptionsRequired<TMethodConfig, TUserPath extends string> = IsBodyRequired
1019
996
  /**
1020
997
  * Build response type for a method call.
1021
998
  */
1022
- type MethodResponse<TMethodConfig, TDefaultError, TUserPath extends string> = SpooshResponse<ExtractData<TMethodConfig>, ExtractError<TMethodConfig, TDefaultError>, RequestOptions<TMethodConfig, TUserPath>, ExtractQuery<TMethodConfig>, ExtractBody<TMethodConfig>, never, never, ExtractParamNames<TUserPath>>;
999
+ type MethodResponse<TMethodConfig, TDefaultError, TUserPath extends string> = SpooshResponse<ExtractData<TMethodConfig>, ExtractError<TMethodConfig, TDefaultError>, RequestOptions<TMethodConfig, TUserPath>, ExtractQuery<TMethodConfig>, ExtractBody<TMethodConfig>, ExtractParamNames<TUserPath>>;
1023
1000
  /**
1024
1001
  * Create a method function type.
1025
1002
  * Direct lookup: Schema[Path][Method] → method config → build function type
@@ -1091,33 +1068,6 @@ type WritePathMethods<TSchema, TPath extends string, TDefaultError> = FindMatchi
1091
1068
  type WriteClient<TSchema, TDefaultError = unknown> = <TPath extends WritePaths<TSchema> | (string & {})>(path: TPath) => HasWriteMethod<TSchema, TPath> extends true ? WritePathMethods<TSchema, TPath, TDefaultError> : never;
1092
1069
 
1093
1070
  type PluginArray = readonly SpooshPlugin<PluginTypeConfig>[];
1094
- /**
1095
- * Configuration options for Spoosh runtime behavior.
1096
- */
1097
- type SpooshConfigOptions = {
1098
- /**
1099
- * Prefix to strip from tag generation.
1100
- *
1101
- * URL prefix stripping always auto-detects from baseUrl.
1102
- * This option only affects tag generation for cache invalidation.
1103
- *
1104
- * - `undefined`: Auto-detect from baseUrl (default)
1105
- * - `string`: Explicit prefix to strip from tags
1106
- *
1107
- * @example
1108
- * ```ts
1109
- * // Default: auto-detect from baseUrl
1110
- * // baseUrl="/api", schema="api/posts" → tags: ["posts"]
1111
- * new Spoosh<Schema>('https://localhost:3000/api')
1112
- *
1113
- * // Explicit prefix (when baseUrl doesn't have it)
1114
- * // baseUrl="/", schema="api/v1/posts" → tags: ["posts"]
1115
- * new Spoosh<Schema>('http://localhost:3000')
1116
- * .configure({ stripTagPrefix: "api/v1" })
1117
- * ```
1118
- */
1119
- stripTagPrefix?: string;
1120
- };
1121
1071
  interface SpooshConfig<TPlugins extends PluginArray = PluginArray> {
1122
1072
  baseUrl: string;
1123
1073
  defaultOptions?: SpooshOptions;
@@ -1131,8 +1081,6 @@ type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends
1131
1081
  config: {
1132
1082
  baseUrl: string;
1133
1083
  defaultOptions: SpooshOptions;
1134
- /** Resolved prefix to strip from tags (used for cache invalidation matching) */
1135
- stripTagPrefix?: string;
1136
1084
  };
1137
1085
  _types: {
1138
1086
  schema: TSchema;
@@ -1184,14 +1132,12 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1184
1132
  private baseUrl;
1185
1133
  private defaultOptions;
1186
1134
  private _plugins;
1187
- private _config;
1188
1135
  /**
1189
1136
  * Creates a new Spoosh instance.
1190
1137
  *
1191
1138
  * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
1192
1139
  * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
1193
1140
  * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
1194
- * @param configOptions - Internal parameter used by the `.config()` method. Do not pass directly.
1195
1141
  *
1196
1142
  * @example
1197
1143
  * ```ts
@@ -1204,7 +1150,7 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1204
1150
  * });
1205
1151
  * ```
1206
1152
  */
1207
- constructor(baseUrl: string, defaultOptions?: SpooshOptions, plugins?: TPlugins, configOptions?: SpooshConfigOptions);
1153
+ constructor(baseUrl: string, defaultOptions?: SpooshOptions, plugins?: TPlugins);
1208
1154
  /**
1209
1155
  * Adds plugins to the Spoosh instance.
1210
1156
  *
@@ -1240,34 +1186,6 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1240
1186
  * ```
1241
1187
  */
1242
1188
  use<const TNewPlugins extends PluginArray>(plugins: TNewPlugins): Spoosh<TSchema, TError, TNewPlugins>;
1243
- /**
1244
- * Configures runtime options for the Spoosh instance.
1245
- *
1246
- * Returns a **new** Spoosh instance with the updated configuration (immutable pattern).
1247
- * Configuration is preserved across `.use()` calls.
1248
- *
1249
- * URL prefix stripping always auto-detects from baseUrl.
1250
- * Tag prefix stripping defaults to URL prefix but can be overridden.
1251
- *
1252
- * @param options - Configuration options
1253
- * @returns A new Spoosh instance with the specified configuration
1254
- *
1255
- * @example Default behavior (auto-detect from baseUrl for both URL and tags)
1256
- * ```ts
1257
- * // baseUrl="/api", schema="api/posts"
1258
- * // URL: /api/posts, Tags: ["posts"]
1259
- * const client = new Spoosh<Schema, Error>('https://localhost:3000/api');
1260
- * ```
1261
- *
1262
- * @example Override tag prefix (when baseUrl doesn't have the prefix you want to strip from tags)
1263
- * ```ts
1264
- * // baseUrl="/", schema="api/v1/posts"
1265
- * // URL: /api/v1/posts, Tags: ["posts"] (strips "api/v1" from tags only)
1266
- * const client = new Spoosh<Schema, Error>('http://localhost:3000')
1267
- * .configure({ stripTagPrefix: "api/v1" });
1268
- * ```
1269
- */
1270
- configure(options: SpooshConfigOptions): Spoosh<TSchema, TError, TPlugins>;
1271
1189
  /**
1272
1190
  * Cached instance of the underlying SpooshInstance.
1273
1191
  * Created lazily on first property access.
@@ -1367,7 +1285,6 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1367
1285
  get config(): {
1368
1286
  baseUrl: string;
1369
1287
  defaultOptions: SpooshOptions;
1370
- stripTagPrefix?: string;
1371
1288
  };
1372
1289
  /**
1373
1290
  * Type information carrier for generic type inference.
@@ -1386,16 +1303,6 @@ type SpooshClientConfig = {
1386
1303
  baseUrl: string;
1387
1304
  defaultOptions?: SpooshOptions;
1388
1305
  middlewares?: SpooshMiddleware[];
1389
- /**
1390
- * Prefix to strip from tag generation.
1391
- *
1392
- * URL prefix stripping always auto-detects from baseUrl.
1393
- * This option only affects tag generation for cache invalidation.
1394
- *
1395
- * - `undefined`: Auto-detect from baseUrl (default, same as URL prefix)
1396
- * - `string`: Explicit prefix to strip from tags
1397
- */
1398
- stripTagPrefix?: string;
1399
1306
  };
1400
1307
  /**
1401
1308
  * Creates a lightweight type-safe API client for vanilla JavaScript/TypeScript usage.
@@ -1489,61 +1396,11 @@ type TagOptions = {
1489
1396
  declare function resolveTags(options: TagOptions | undefined, resolvedPath: string[]): string[];
1490
1397
  declare function resolvePath(path: string[], params: Record<string, string | number> | undefined): string[];
1491
1398
 
1492
- /**
1493
- * Extracts the path prefix from a base URL.
1494
- *
1495
- * @param baseUrl - The base URL (absolute or relative)
1496
- * @returns The path portion without leading/trailing slashes
1497
- *
1498
- * @example
1499
- * ```ts
1500
- * extractPrefixFromBaseUrl("https://localhost:3000/api"); // "api"
1501
- * extractPrefixFromBaseUrl("/api/v1"); // "api/v1"
1502
- * extractPrefixFromBaseUrl("api"); // "api"
1503
- * ```
1504
- */
1505
- declare function extractPrefixFromBaseUrl(baseUrl: string): string;
1506
- /**
1507
- * Strips a prefix from path segments if the path starts with that prefix.
1508
- *
1509
- * @param pathSegments - Array of path segments
1510
- * @param prefix - Prefix to strip (e.g., "api" or "api/v1")
1511
- * @returns Path segments with prefix removed
1512
- *
1513
- * @example
1514
- * ```ts
1515
- * stripPrefixFromPath(["api", "posts"], "api"); // ["posts"]
1516
- * stripPrefixFromPath(["api", "v1", "users"], "api/v1"); // ["users"]
1517
- * stripPrefixFromPath(["posts"], "api"); // ["posts"] (no match, unchanged)
1518
- * ```
1519
- */
1520
- declare function stripPrefixFromPath(pathSegments: string[], prefix: string): string[];
1521
- /**
1522
- * Resolves the strip prefix value based on configuration.
1523
- *
1524
- * @param stripPathPrefix - Configuration value (boolean, string, or undefined)
1525
- * @param baseUrl - The base URL to extract prefix from when true
1526
- * @returns The resolved prefix string to strip
1527
- *
1528
- * @example
1529
- * ```ts
1530
- * resolveStripPrefix(true, "https://localhost:3000/api"); // "api"
1531
- * resolveStripPrefix("api/v1", "https://localhost:3000/api"); // "api/v1"
1532
- * resolveStripPrefix(false, "https://localhost:3000/api"); // ""
1533
- * resolveStripPrefix(undefined, "https://localhost:3000/api"); // ""
1534
- * ```
1535
- */
1536
- declare function resolveStripPrefix(stripPathPrefix: boolean | string | undefined, baseUrl: string): string;
1537
-
1538
1399
  type ProxyHandlerConfig<TOptions = SpooshOptions> = {
1539
1400
  baseUrl: string;
1540
1401
  defaultOptions: TOptions;
1541
1402
  fetchExecutor?: FetchExecutor<TOptions, AnyRequestOptions>;
1542
1403
  nextTags?: boolean;
1543
- /** Prefix to strip from URL path (auto-detected from baseUrl, always applied) */
1544
- urlPrefix?: string;
1545
- /** Prefix to strip from tag generation (defaults to urlPrefix) */
1546
- tagPrefix?: string;
1547
1404
  };
1548
1405
  /**
1549
1406
  * Creates an API client proxy that uses path strings instead of chained property access.
@@ -1670,7 +1527,7 @@ declare function extractPathFromSelector(fn: unknown): string;
1670
1527
  */
1671
1528
  declare function extractMethodFromSelector(fn: unknown): string | undefined;
1672
1529
 
1673
- declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions & SpooshOptionsExtra, requestOptions?: AnyRequestOptions, nextTags?: boolean, tagPath?: string[]): Promise<SpooshResponse<TData, TError>>;
1530
+ declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions & SpooshOptionsExtra, requestOptions?: AnyRequestOptions, nextTags?: boolean): Promise<SpooshResponse<TData, TError>>;
1674
1531
 
1675
1532
  declare function createMiddleware<TData = unknown, TError = unknown>(name: string, phase: MiddlewarePhase, handler: SpooshMiddleware<TData, TError>["handler"]): SpooshMiddleware<TData, TError>;
1676
1533
  declare function applyMiddlewares<TData = unknown, TError = unknown>(context: MiddlewareContext<TData, TError>, middlewares: SpooshMiddleware<TData, TError>[], phase: MiddlewarePhase): Promise<MiddlewareContext<TData, TError>>;
@@ -1764,4 +1621,4 @@ type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
1764
1621
  };
1765
1622
  declare function createInfiniteReadController<TData, TItem, TError, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions>(options: CreateInfiniteReadOptions<TData, TItem, TError, TRequest>): InfiniteReadController<TData, TItem, TError>;
1766
1623
 
1767
- export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type EventEmitter, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExecutorOptions, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestOptions$1 as RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type RouteToPath, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshConfigOptions, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, applyMiddlewares, buildUrl, composeMiddlewares, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, extractPrefixFromBaseUrl, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveStripPrefix, resolveTags, setHeaders, sortObjectKeys, stripPrefixFromPath, urlencoded };
1624
+ export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type EventEmitter, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestOptions$1 as RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, applyMiddlewares, buildUrl, composeMiddlewares, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveTags, setHeaders, sortObjectKeys, urlencoded };
package/dist/index.d.ts CHANGED
@@ -28,40 +28,32 @@ type QueryField<TQuery> = [TQuery] extends [never] ? object : {
28
28
  type BodyField<TBody> = [TBody] extends [never] ? object : {
29
29
  body: TBody;
30
30
  };
31
- type FormDataField<TFormData> = [TFormData] extends [never] ? object : {
32
- formData: TFormData;
33
- };
34
- type UrlEncodedField<TUrlEncoded> = [TUrlEncoded] extends [never] ? object : {
35
- urlEncoded: TUrlEncoded;
36
- };
37
31
  type ParamsField<TParamNames extends string> = [TParamNames] extends [never] ? object : {
38
32
  params: Record<TParamNames, string | number>;
39
33
  };
40
- type InputFields<TQuery, TBody, TFormData, TUrlEncoded, TParamNames extends string> = QueryField<TQuery> & BodyField<TBody> & FormDataField<TFormData> & UrlEncodedField<TUrlEncoded> & ParamsField<TParamNames>;
41
- type InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames extends string> = [TQuery, TBody, TFormData, TUrlEncoded, TParamNames] extends [
42
- never,
43
- never,
44
- never,
45
- never,
46
- never
47
- ] ? object : {
48
- input: InputFields<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>;
34
+ type InputFields<TQuery, TBody, TParamNames extends string> = QueryField<TQuery> & BodyField<TBody> & ParamsField<TParamNames>;
35
+ type InputFieldWrapper<TQuery, TBody, TParamNames extends string> = [
36
+ TQuery,
37
+ TBody,
38
+ TParamNames
39
+ ] extends [never, never, never] ? object : {
40
+ input: InputFields<TQuery, TBody, TParamNames>;
49
41
  };
50
- type SpooshResponse<TData, TError, TRequestOptions = unknown, TQuery = never, TBody = never, TFormData = never, TUrlEncoded = never, TParamNames extends string = never> = ({
42
+ type SpooshResponse<TData, TError, TRequestOptions = unknown, TQuery = never, TBody = never, TParamNames extends string = never> = ({
51
43
  status: number;
52
44
  data: TData;
53
45
  headers?: Headers;
54
46
  error?: undefined;
55
47
  aborted?: false;
56
48
  readonly __requestOptions?: TRequestOptions;
57
- } & InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>) | ({
49
+ } & InputFieldWrapper<TQuery, TBody, TParamNames>) | ({
58
50
  status: number;
59
51
  data?: undefined;
60
52
  headers?: Headers;
61
53
  error: TError;
62
54
  aborted?: boolean;
63
55
  readonly __requestOptions?: TRequestOptions;
64
- } & InputFieldWrapper<TQuery, TBody, TFormData, TUrlEncoded, TParamNames>);
56
+ } & InputFieldWrapper<TQuery, TBody, TParamNames>);
65
57
  type SpooshOptionsExtra<TData = unknown, TError = unknown> = {
66
58
  middlewares?: SpooshMiddleware<TData, TError>[];
67
59
  };
@@ -124,7 +116,7 @@ type MethodOptionsMap<TQueryOptions = object, TMutationOptions = object> = {
124
116
  DELETE: TMutationOptions;
125
117
  };
126
118
  type ExtractMethodOptions<TOptionsMap, TMethod extends HttpMethod> = TOptionsMap extends MethodOptionsMap<infer TQuery, infer TMutation> ? TMethod extends "GET" ? TQuery : TMutation : TOptionsMap;
127
- type FetchExecutor<TOptions = SpooshOptions, TRequestOptions = AnyRequestOptions> = <TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: TOptions, requestOptions?: TRequestOptions, nextTags?: boolean, tagPath?: string[]) => Promise<SpooshResponse<TData, TError>>;
119
+ type FetchExecutor<TOptions = SpooshOptions, TRequestOptions = AnyRequestOptions> = <TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: TOptions, requestOptions?: TRequestOptions, nextTags?: boolean) => Promise<SpooshResponse<TData, TError>>;
128
120
  type TypedParamsOption<TParamNames extends string> = [TParamNames] extends [
129
121
  never
130
122
  ] ? object : {
@@ -149,6 +141,7 @@ type EventCallback<T = unknown> = (payload: T) => void;
149
141
  interface BuiltInEvents {
150
142
  refetch: RefetchEvent;
151
143
  invalidate: string[];
144
+ refetchAll: void;
152
145
  }
153
146
  /**
154
147
  * Resolves event payload type. Built-in events get their specific type,
@@ -251,11 +244,6 @@ type PluginContext<TData = unknown, TError = unknown> = {
251
244
  readonly requestTimestamp: number;
252
245
  /** Unique identifier for the hook instance. Persists across queryKey changes within the same hook. */
253
246
  readonly hookId?: string;
254
- /**
255
- * Prefix to strip from tags. Configured at the Spoosh instance level.
256
- * Plugins can use this to normalize tags before emitting events.
257
- */
258
- readonly stripTagPrefix?: string;
259
247
  requestOptions: AnyRequestOptions;
260
248
  state: OperationState<TData, TError>;
261
249
  response?: SpooshResponse<TData, TError>;
@@ -563,13 +551,14 @@ type PluginAccessor = {
563
551
  get<K extends keyof PluginExportsRegistry>(name: K): PluginExportsRegistry[K] | undefined;
564
552
  get(name: string): unknown;
565
553
  };
554
+ type RefetchEventReason = "focus" | "reconnect" | "polling" | "invalidate";
566
555
  /**
567
556
  * Event emitted by plugins to request a refetch.
568
557
  * Hooks subscribe to this event and trigger controller.execute().
569
558
  */
570
559
  type RefetchEvent = {
571
560
  queryKey: string;
572
- reason: "focus" | "reconnect" | "polling" | "invalidate";
561
+ reason: RefetchEventReason | Omit<string, RefetchEventReason>;
573
562
  };
574
563
  /**
575
564
  * Minimal PluginExecutor interface for InstanceApiContext.
@@ -601,10 +590,7 @@ type PluginExecutor = {
601
590
  /** Creates a full PluginContext with plugins accessor injected */
602
591
  createContext: <TData, TError>(input: PluginContextInput<TData, TError>) => PluginContext<TData, TError>;
603
592
  };
604
- type PluginExecutorOptions = {
605
- stripTagPrefix?: string;
606
- };
607
- declare function createPluginExecutor(initialPlugins?: SpooshPlugin[], options?: PluginExecutorOptions): PluginExecutor;
593
+ declare function createPluginExecutor(initialPlugins?: SpooshPlugin[]): PluginExecutor;
608
594
 
609
595
  /**
610
596
  * Resolves plugin option types based on the full context.
@@ -794,16 +780,7 @@ type ExtractError<T, TDefault = unknown> = T extends {
794
780
  * const api = createClient<ApiSchema>({ baseUrl: "/api" });
795
781
  * ```
796
782
  */
797
- type SpooshSchema<T extends {
798
- [path: string]: {
799
- [M in HttpMethod]?: {
800
- data: unknown;
801
- body?: unknown;
802
- query?: unknown;
803
- error?: unknown;
804
- };
805
- };
806
- }> = T;
783
+ type SpooshSchema<T extends ApiSchema> = T;
807
784
  /**
808
785
  * Convert a route pattern like "posts/:id" to a path matcher pattern like `posts/${string}`.
809
786
  * This enables TypeScript to match actual paths like "posts/123" to their schema definitions.
@@ -815,7 +792,7 @@ type SpooshSchema<T extends {
815
792
  * type C = RouteToPath<"posts">; // "posts"
816
793
  * ```
817
794
  */
818
- type RouteToPath<T extends string> = T extends `${infer Start}/:${string}/${infer Rest}` ? `${Start}/${string}/${RouteToPath<Rest>}` : T extends `${infer Start}/:${string}` ? `${Start}/${string}` : T;
795
+ type RouteToPath<T extends string> = T extends `/${infer Rest}` ? `/${RouteToPath<Rest>}` : T extends `${infer Segment}/${infer Rest}` ? Segment extends `:${string}` ? `${string}/${RouteToPath<Rest>}` : `${Segment}/${RouteToPath<Rest>}` : T extends `:${string}` ? string : T;
819
796
  /**
820
797
  * Find which schema key matches a given path.
821
798
  * First checks for exact match, then checks pattern matches.
@@ -883,12 +860,12 @@ type StripPrefixFromPath<TPath extends string, TPrefix extends string> = TPath e
883
860
  * "api": { GET: { data: string } };
884
861
  * "api/users": { GET: { data: User[] } };
885
862
  * "api/posts/:id": { GET: { data: Post } };
886
- * "health": { GET: { data: { status: string } } };
863
+ * "api/health": { GET: { data: { status: string } } };
887
864
  * };
888
865
  *
889
866
  * type ApiSchema = StripPrefix<FullSchema, "api">;
890
867
  * // {
891
- * // "": { GET: { data: string } };
868
+ * // "/": { GET: { data: string } };
892
869
  * // "users": { GET: { data: User[] } };
893
870
  * // "posts/:id": { GET: { data: Post } };
894
871
  * // "health": { GET: { data: { status: string } } };
@@ -1019,7 +996,7 @@ type IsOptionsRequired<TMethodConfig, TUserPath extends string> = IsBodyRequired
1019
996
  /**
1020
997
  * Build response type for a method call.
1021
998
  */
1022
- type MethodResponse<TMethodConfig, TDefaultError, TUserPath extends string> = SpooshResponse<ExtractData<TMethodConfig>, ExtractError<TMethodConfig, TDefaultError>, RequestOptions<TMethodConfig, TUserPath>, ExtractQuery<TMethodConfig>, ExtractBody<TMethodConfig>, never, never, ExtractParamNames<TUserPath>>;
999
+ type MethodResponse<TMethodConfig, TDefaultError, TUserPath extends string> = SpooshResponse<ExtractData<TMethodConfig>, ExtractError<TMethodConfig, TDefaultError>, RequestOptions<TMethodConfig, TUserPath>, ExtractQuery<TMethodConfig>, ExtractBody<TMethodConfig>, ExtractParamNames<TUserPath>>;
1023
1000
  /**
1024
1001
  * Create a method function type.
1025
1002
  * Direct lookup: Schema[Path][Method] → method config → build function type
@@ -1091,33 +1068,6 @@ type WritePathMethods<TSchema, TPath extends string, TDefaultError> = FindMatchi
1091
1068
  type WriteClient<TSchema, TDefaultError = unknown> = <TPath extends WritePaths<TSchema> | (string & {})>(path: TPath) => HasWriteMethod<TSchema, TPath> extends true ? WritePathMethods<TSchema, TPath, TDefaultError> : never;
1092
1069
 
1093
1070
  type PluginArray = readonly SpooshPlugin<PluginTypeConfig>[];
1094
- /**
1095
- * Configuration options for Spoosh runtime behavior.
1096
- */
1097
- type SpooshConfigOptions = {
1098
- /**
1099
- * Prefix to strip from tag generation.
1100
- *
1101
- * URL prefix stripping always auto-detects from baseUrl.
1102
- * This option only affects tag generation for cache invalidation.
1103
- *
1104
- * - `undefined`: Auto-detect from baseUrl (default)
1105
- * - `string`: Explicit prefix to strip from tags
1106
- *
1107
- * @example
1108
- * ```ts
1109
- * // Default: auto-detect from baseUrl
1110
- * // baseUrl="/api", schema="api/posts" → tags: ["posts"]
1111
- * new Spoosh<Schema>('https://localhost:3000/api')
1112
- *
1113
- * // Explicit prefix (when baseUrl doesn't have it)
1114
- * // baseUrl="/", schema="api/v1/posts" → tags: ["posts"]
1115
- * new Spoosh<Schema>('http://localhost:3000')
1116
- * .configure({ stripTagPrefix: "api/v1" })
1117
- * ```
1118
- */
1119
- stripTagPrefix?: string;
1120
- };
1121
1071
  interface SpooshConfig<TPlugins extends PluginArray = PluginArray> {
1122
1072
  baseUrl: string;
1123
1073
  defaultOptions?: SpooshOptions;
@@ -1131,8 +1081,6 @@ type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends
1131
1081
  config: {
1132
1082
  baseUrl: string;
1133
1083
  defaultOptions: SpooshOptions;
1134
- /** Resolved prefix to strip from tags (used for cache invalidation matching) */
1135
- stripTagPrefix?: string;
1136
1084
  };
1137
1085
  _types: {
1138
1086
  schema: TSchema;
@@ -1184,14 +1132,12 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1184
1132
  private baseUrl;
1185
1133
  private defaultOptions;
1186
1134
  private _plugins;
1187
- private _config;
1188
1135
  /**
1189
1136
  * Creates a new Spoosh instance.
1190
1137
  *
1191
1138
  * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
1192
1139
  * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
1193
1140
  * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
1194
- * @param configOptions - Internal parameter used by the `.config()` method. Do not pass directly.
1195
1141
  *
1196
1142
  * @example
1197
1143
  * ```ts
@@ -1204,7 +1150,7 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1204
1150
  * });
1205
1151
  * ```
1206
1152
  */
1207
- constructor(baseUrl: string, defaultOptions?: SpooshOptions, plugins?: TPlugins, configOptions?: SpooshConfigOptions);
1153
+ constructor(baseUrl: string, defaultOptions?: SpooshOptions, plugins?: TPlugins);
1208
1154
  /**
1209
1155
  * Adds plugins to the Spoosh instance.
1210
1156
  *
@@ -1240,34 +1186,6 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1240
1186
  * ```
1241
1187
  */
1242
1188
  use<const TNewPlugins extends PluginArray>(plugins: TNewPlugins): Spoosh<TSchema, TError, TNewPlugins>;
1243
- /**
1244
- * Configures runtime options for the Spoosh instance.
1245
- *
1246
- * Returns a **new** Spoosh instance with the updated configuration (immutable pattern).
1247
- * Configuration is preserved across `.use()` calls.
1248
- *
1249
- * URL prefix stripping always auto-detects from baseUrl.
1250
- * Tag prefix stripping defaults to URL prefix but can be overridden.
1251
- *
1252
- * @param options - Configuration options
1253
- * @returns A new Spoosh instance with the specified configuration
1254
- *
1255
- * @example Default behavior (auto-detect from baseUrl for both URL and tags)
1256
- * ```ts
1257
- * // baseUrl="/api", schema="api/posts"
1258
- * // URL: /api/posts, Tags: ["posts"]
1259
- * const client = new Spoosh<Schema, Error>('https://localhost:3000/api');
1260
- * ```
1261
- *
1262
- * @example Override tag prefix (when baseUrl doesn't have the prefix you want to strip from tags)
1263
- * ```ts
1264
- * // baseUrl="/", schema="api/v1/posts"
1265
- * // URL: /api/v1/posts, Tags: ["posts"] (strips "api/v1" from tags only)
1266
- * const client = new Spoosh<Schema, Error>('http://localhost:3000')
1267
- * .configure({ stripTagPrefix: "api/v1" });
1268
- * ```
1269
- */
1270
- configure(options: SpooshConfigOptions): Spoosh<TSchema, TError, TPlugins>;
1271
1189
  /**
1272
1190
  * Cached instance of the underlying SpooshInstance.
1273
1191
  * Created lazily on first property access.
@@ -1367,7 +1285,6 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1367
1285
  get config(): {
1368
1286
  baseUrl: string;
1369
1287
  defaultOptions: SpooshOptions;
1370
- stripTagPrefix?: string;
1371
1288
  };
1372
1289
  /**
1373
1290
  * Type information carrier for generic type inference.
@@ -1386,16 +1303,6 @@ type SpooshClientConfig = {
1386
1303
  baseUrl: string;
1387
1304
  defaultOptions?: SpooshOptions;
1388
1305
  middlewares?: SpooshMiddleware[];
1389
- /**
1390
- * Prefix to strip from tag generation.
1391
- *
1392
- * URL prefix stripping always auto-detects from baseUrl.
1393
- * This option only affects tag generation for cache invalidation.
1394
- *
1395
- * - `undefined`: Auto-detect from baseUrl (default, same as URL prefix)
1396
- * - `string`: Explicit prefix to strip from tags
1397
- */
1398
- stripTagPrefix?: string;
1399
1306
  };
1400
1307
  /**
1401
1308
  * Creates a lightweight type-safe API client for vanilla JavaScript/TypeScript usage.
@@ -1489,61 +1396,11 @@ type TagOptions = {
1489
1396
  declare function resolveTags(options: TagOptions | undefined, resolvedPath: string[]): string[];
1490
1397
  declare function resolvePath(path: string[], params: Record<string, string | number> | undefined): string[];
1491
1398
 
1492
- /**
1493
- * Extracts the path prefix from a base URL.
1494
- *
1495
- * @param baseUrl - The base URL (absolute or relative)
1496
- * @returns The path portion without leading/trailing slashes
1497
- *
1498
- * @example
1499
- * ```ts
1500
- * extractPrefixFromBaseUrl("https://localhost:3000/api"); // "api"
1501
- * extractPrefixFromBaseUrl("/api/v1"); // "api/v1"
1502
- * extractPrefixFromBaseUrl("api"); // "api"
1503
- * ```
1504
- */
1505
- declare function extractPrefixFromBaseUrl(baseUrl: string): string;
1506
- /**
1507
- * Strips a prefix from path segments if the path starts with that prefix.
1508
- *
1509
- * @param pathSegments - Array of path segments
1510
- * @param prefix - Prefix to strip (e.g., "api" or "api/v1")
1511
- * @returns Path segments with prefix removed
1512
- *
1513
- * @example
1514
- * ```ts
1515
- * stripPrefixFromPath(["api", "posts"], "api"); // ["posts"]
1516
- * stripPrefixFromPath(["api", "v1", "users"], "api/v1"); // ["users"]
1517
- * stripPrefixFromPath(["posts"], "api"); // ["posts"] (no match, unchanged)
1518
- * ```
1519
- */
1520
- declare function stripPrefixFromPath(pathSegments: string[], prefix: string): string[];
1521
- /**
1522
- * Resolves the strip prefix value based on configuration.
1523
- *
1524
- * @param stripPathPrefix - Configuration value (boolean, string, or undefined)
1525
- * @param baseUrl - The base URL to extract prefix from when true
1526
- * @returns The resolved prefix string to strip
1527
- *
1528
- * @example
1529
- * ```ts
1530
- * resolveStripPrefix(true, "https://localhost:3000/api"); // "api"
1531
- * resolveStripPrefix("api/v1", "https://localhost:3000/api"); // "api/v1"
1532
- * resolveStripPrefix(false, "https://localhost:3000/api"); // ""
1533
- * resolveStripPrefix(undefined, "https://localhost:3000/api"); // ""
1534
- * ```
1535
- */
1536
- declare function resolveStripPrefix(stripPathPrefix: boolean | string | undefined, baseUrl: string): string;
1537
-
1538
1399
  type ProxyHandlerConfig<TOptions = SpooshOptions> = {
1539
1400
  baseUrl: string;
1540
1401
  defaultOptions: TOptions;
1541
1402
  fetchExecutor?: FetchExecutor<TOptions, AnyRequestOptions>;
1542
1403
  nextTags?: boolean;
1543
- /** Prefix to strip from URL path (auto-detected from baseUrl, always applied) */
1544
- urlPrefix?: string;
1545
- /** Prefix to strip from tag generation (defaults to urlPrefix) */
1546
- tagPrefix?: string;
1547
1404
  };
1548
1405
  /**
1549
1406
  * Creates an API client proxy that uses path strings instead of chained property access.
@@ -1670,7 +1527,7 @@ declare function extractPathFromSelector(fn: unknown): string;
1670
1527
  */
1671
1528
  declare function extractMethodFromSelector(fn: unknown): string | undefined;
1672
1529
 
1673
- declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions & SpooshOptionsExtra, requestOptions?: AnyRequestOptions, nextTags?: boolean, tagPath?: string[]): Promise<SpooshResponse<TData, TError>>;
1530
+ declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions & SpooshOptionsExtra, requestOptions?: AnyRequestOptions, nextTags?: boolean): Promise<SpooshResponse<TData, TError>>;
1674
1531
 
1675
1532
  declare function createMiddleware<TData = unknown, TError = unknown>(name: string, phase: MiddlewarePhase, handler: SpooshMiddleware<TData, TError>["handler"]): SpooshMiddleware<TData, TError>;
1676
1533
  declare function applyMiddlewares<TData = unknown, TError = unknown>(context: MiddlewareContext<TData, TError>, middlewares: SpooshMiddleware<TData, TError>[], phase: MiddlewarePhase): Promise<MiddlewareContext<TData, TError>>;
@@ -1764,4 +1621,4 @@ type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
1764
1621
  };
1765
1622
  declare function createInfiniteReadController<TData, TItem, TError, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions>(options: CreateInfiniteReadOptions<TData, TItem, TError, TRequest>): InfiniteReadController<TData, TItem, TError>;
1766
1623
 
1767
- export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type EventEmitter, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExecutorOptions, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestOptions$1 as RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type RouteToPath, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshConfigOptions, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, applyMiddlewares, buildUrl, composeMiddlewares, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, extractPrefixFromBaseUrl, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveStripPrefix, resolveTags, setHeaders, sortObjectKeys, stripPrefixFromPath, urlencoded };
1624
+ export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type EventEmitter, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestOptions$1 as RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type RetryConfig, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, applyMiddlewares, buildUrl, composeMiddlewares, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveTags, setHeaders, sortObjectKeys, urlencoded };
package/dist/index.js CHANGED
@@ -41,7 +41,6 @@ __export(src_exports, {
41
41
  executeFetch: () => executeFetch,
42
42
  extractMethodFromSelector: () => extractMethodFromSelector,
43
43
  extractPathFromSelector: () => extractPathFromSelector,
44
- extractPrefixFromBaseUrl: () => extractPrefixFromBaseUrl,
45
44
  form: () => form,
46
45
  generateTags: () => generateTags,
47
46
  getContentType: () => getContentType,
@@ -54,11 +53,9 @@ __export(src_exports, {
54
53
  resolveHeadersToRecord: () => resolveHeadersToRecord,
55
54
  resolvePath: () => resolvePath,
56
55
  resolveRequestBody: () => resolveRequestBody,
57
- resolveStripPrefix: () => resolveStripPrefix,
58
56
  resolveTags: () => resolveTags,
59
57
  setHeaders: () => setHeaders,
60
58
  sortObjectKeys: () => sortObjectKeys,
61
- stripPrefixFromPath: () => stripPrefixFromPath,
62
59
  urlencoded: () => urlencoded
63
60
  });
64
61
  module.exports = __toCommonJS(src_exports);
@@ -371,41 +368,11 @@ function resolvePath(path, params) {
371
368
  });
372
369
  }
373
370
 
374
- // src/utils/stripPathPrefix.ts
375
- function extractPrefixFromBaseUrl(baseUrl) {
376
- const isAbsolute = /^https?:\/\//.test(baseUrl);
377
- if (isAbsolute) {
378
- try {
379
- const url = new URL(baseUrl);
380
- return url.pathname.replace(/^\/|\/$/g, "");
381
- } catch {
382
- return "";
383
- }
384
- }
385
- return baseUrl.replace(/^\/|\/$/g, "");
386
- }
387
- function stripPrefixFromPath(pathSegments, prefix) {
388
- if (!prefix) return pathSegments;
389
- const prefixSegments = prefix.split("/").filter(Boolean);
390
- if (prefixSegments.length === 0) return pathSegments;
391
- const startsWithPrefix = prefixSegments.every(
392
- (seg, i) => pathSegments[i] === seg
393
- );
394
- return startsWithPrefix ? pathSegments.slice(prefixSegments.length) : pathSegments;
395
- }
396
- function resolveStripPrefix(stripPathPrefix, baseUrl) {
397
- if (!stripPathPrefix) return "";
398
- if (stripPathPrefix === true) {
399
- return extractPrefixFromBaseUrl(baseUrl);
400
- }
401
- return stripPathPrefix.replace(/^\/|\/$/g, "");
402
- }
403
-
404
371
  // src/fetch.ts
405
372
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
406
373
  var isNetworkError = (err) => err instanceof TypeError;
407
374
  var isAbortError = (err) => err instanceof DOMException && err.name === "AbortError";
408
- async function executeFetch(baseUrl, path, method, defaultOptions, requestOptions, nextTags, tagPath) {
375
+ async function executeFetch(baseUrl, path, method, defaultOptions, requestOptions, nextTags) {
409
376
  const middlewares = defaultOptions.middlewares ?? [];
410
377
  let context = {
411
378
  baseUrl,
@@ -425,8 +392,7 @@ async function executeFetch(baseUrl, path, method, defaultOptions, requestOption
425
392
  defaultOptions: context.defaultOptions,
426
393
  requestOptions: context.requestOptions,
427
394
  middlewareFetchInit: context.fetchInit,
428
- nextTags,
429
- tagPath
395
+ nextTags
430
396
  });
431
397
  context.response = response;
432
398
  if (middlewares.length > 0) {
@@ -458,8 +424,7 @@ async function executeCoreFetch(config) {
458
424
  defaultOptions,
459
425
  requestOptions,
460
426
  middlewareFetchInit,
461
- nextTags,
462
- tagPath
427
+ nextTags
463
428
  } = config;
464
429
  const {
465
430
  middlewares: _,
@@ -484,7 +449,7 @@ async function executeCoreFetch(config) {
484
449
  }
485
450
  fetchInit.cache = requestOptions?.cache ?? fetchDefaults?.cache;
486
451
  if (nextTags) {
487
- const autoTags = generateTags(tagPath ?? path);
452
+ const autoTags = generateTags(path);
488
453
  const userNext = requestOptions?.next;
489
454
  fetchInit.next = {
490
455
  tags: userNext?.tags ?? autoTags,
@@ -575,11 +540,8 @@ function createProxyHandler(config) {
575
540
  baseUrl,
576
541
  defaultOptions,
577
542
  fetchExecutor = executeFetch,
578
- nextTags,
579
- urlPrefix,
580
- tagPrefix
543
+ nextTags
581
544
  } = config;
582
- const effectiveTagPrefix = tagPrefix ?? urlPrefix;
583
545
  return ((path) => {
584
546
  return new Proxy(
585
547
  {},
@@ -592,16 +554,13 @@ function createProxyHandler(config) {
592
554
  }
593
555
  return (options) => {
594
556
  const resolvedPath = resolvePath2(path, options?.params);
595
- const urlPath = urlPrefix ? stripPrefixFromPath(resolvedPath, urlPrefix) : resolvedPath;
596
- const tagPath = effectiveTagPrefix ? stripPrefixFromPath(resolvedPath, effectiveTagPrefix) : resolvedPath;
597
557
  return fetchExecutor(
598
558
  baseUrl,
599
- urlPath,
559
+ resolvedPath,
600
560
  method,
601
561
  defaultOptions,
602
562
  options,
603
- nextTags,
604
- tagPath
563
+ nextTags
605
564
  );
606
565
  };
607
566
  }
@@ -884,8 +843,7 @@ function sortByDependencies(plugins) {
884
843
  }
885
844
  return sorted;
886
845
  }
887
- function createPluginExecutor(initialPlugins = [], options = {}) {
888
- const { stripTagPrefix } = options;
846
+ function createPluginExecutor(initialPlugins = []) {
889
847
  validateDependencies(initialPlugins);
890
848
  const plugins = sortByDependencies(initialPlugins);
891
849
  const frozenPlugins = Object.freeze([...plugins]);
@@ -969,9 +927,6 @@ function createPluginExecutor(initialPlugins = [], options = {}) {
969
927
  ctx.headers = { ...ctx.headers, ...newHeaders };
970
928
  ctx.requestOptions.headers = ctx.headers;
971
929
  };
972
- if (stripTagPrefix) {
973
- ctx.stripTagPrefix = stripTagPrefix;
974
- }
975
930
  return ctx;
976
931
  }
977
932
  };
@@ -990,14 +945,12 @@ var Spoosh = class _Spoosh {
990
945
  baseUrl;
991
946
  defaultOptions;
992
947
  _plugins;
993
- _config;
994
948
  /**
995
949
  * Creates a new Spoosh instance.
996
950
  *
997
951
  * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
998
952
  * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
999
953
  * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
1000
- * @param configOptions - Internal parameter used by the `.config()` method. Do not pass directly.
1001
954
  *
1002
955
  * @example
1003
956
  * ```ts
@@ -1010,11 +963,10 @@ var Spoosh = class _Spoosh {
1010
963
  * });
1011
964
  * ```
1012
965
  */
1013
- constructor(baseUrl, defaultOptions, plugins, configOptions) {
966
+ constructor(baseUrl, defaultOptions, plugins) {
1014
967
  this.baseUrl = baseUrl;
1015
968
  this.defaultOptions = defaultOptions || {};
1016
969
  this._plugins = plugins || [];
1017
- this._config = configOptions || {};
1018
970
  }
1019
971
  /**
1020
972
  * Adds plugins to the Spoosh instance.
@@ -1054,43 +1006,7 @@ var Spoosh = class _Spoosh {
1054
1006
  return new _Spoosh(
1055
1007
  this.baseUrl,
1056
1008
  this.defaultOptions,
1057
- plugins,
1058
- this._config
1059
- );
1060
- }
1061
- /**
1062
- * Configures runtime options for the Spoosh instance.
1063
- *
1064
- * Returns a **new** Spoosh instance with the updated configuration (immutable pattern).
1065
- * Configuration is preserved across `.use()` calls.
1066
- *
1067
- * URL prefix stripping always auto-detects from baseUrl.
1068
- * Tag prefix stripping defaults to URL prefix but can be overridden.
1069
- *
1070
- * @param options - Configuration options
1071
- * @returns A new Spoosh instance with the specified configuration
1072
- *
1073
- * @example Default behavior (auto-detect from baseUrl for both URL and tags)
1074
- * ```ts
1075
- * // baseUrl="/api", schema="api/posts"
1076
- * // URL: /api/posts, Tags: ["posts"]
1077
- * const client = new Spoosh<Schema, Error>('https://localhost:3000/api');
1078
- * ```
1079
- *
1080
- * @example Override tag prefix (when baseUrl doesn't have the prefix you want to strip from tags)
1081
- * ```ts
1082
- * // baseUrl="/", schema="api/v1/posts"
1083
- * // URL: /api/v1/posts, Tags: ["posts"] (strips "api/v1" from tags only)
1084
- * const client = new Spoosh<Schema, Error>('http://localhost:3000')
1085
- * .configure({ stripTagPrefix: "api/v1" });
1086
- * ```
1087
- */
1088
- configure(options) {
1089
- return new _Spoosh(
1090
- this.baseUrl,
1091
- this.defaultOptions,
1092
- this._plugins,
1093
- { ...this._config, ...options }
1009
+ plugins
1094
1010
  );
1095
1011
  }
1096
1012
  /**
@@ -1106,19 +1022,13 @@ var Spoosh = class _Spoosh {
1106
1022
  */
1107
1023
  getInstance() {
1108
1024
  if (!this._instance) {
1109
- const urlPrefix = extractPrefixFromBaseUrl(this.baseUrl) || void 0;
1110
- const tagPrefix = this._config.stripTagPrefix ?? urlPrefix;
1111
1025
  const api = createProxyHandler({
1112
1026
  baseUrl: this.baseUrl,
1113
- defaultOptions: this.defaultOptions,
1114
- urlPrefix,
1115
- tagPrefix
1027
+ defaultOptions: this.defaultOptions
1116
1028
  });
1117
1029
  const stateManager = createStateManager();
1118
1030
  const eventEmitter = createEventEmitter();
1119
- const pluginExecutor = createPluginExecutor([...this._plugins], {
1120
- stripTagPrefix: tagPrefix
1121
- });
1031
+ const pluginExecutor = createPluginExecutor([...this._plugins]);
1122
1032
  this._instance = {
1123
1033
  api,
1124
1034
  stateManager,
@@ -1126,8 +1036,7 @@ var Spoosh = class _Spoosh {
1126
1036
  pluginExecutor,
1127
1037
  config: {
1128
1038
  baseUrl: this.baseUrl,
1129
- defaultOptions: this.defaultOptions,
1130
- stripTagPrefix: tagPrefix
1039
+ defaultOptions: this.defaultOptions
1131
1040
  },
1132
1041
  _types: {
1133
1042
  schema: void 0,
@@ -1246,21 +1155,12 @@ var Spoosh = class _Spoosh {
1246
1155
 
1247
1156
  // src/createClient.ts
1248
1157
  function createClient(config) {
1249
- const {
1250
- baseUrl,
1251
- defaultOptions = {},
1252
- middlewares = [],
1253
- stripTagPrefix
1254
- } = config;
1158
+ const { baseUrl, defaultOptions = {}, middlewares = [] } = config;
1255
1159
  const optionsWithMiddlewares = { ...defaultOptions, middlewares };
1256
- const urlPrefix = extractPrefixFromBaseUrl(baseUrl) || void 0;
1257
- const tagPrefix = stripTagPrefix ?? urlPrefix;
1258
1160
  return createProxyHandler({
1259
1161
  baseUrl,
1260
1162
  defaultOptions: optionsWithMiddlewares,
1261
- nextTags: true,
1262
- urlPrefix,
1263
- tagPrefix
1163
+ nextTags: true
1264
1164
  });
1265
1165
  }
1266
1166
 
package/dist/index.mjs CHANGED
@@ -306,41 +306,11 @@ function resolvePath(path, params) {
306
306
  });
307
307
  }
308
308
 
309
- // src/utils/stripPathPrefix.ts
310
- function extractPrefixFromBaseUrl(baseUrl) {
311
- const isAbsolute = /^https?:\/\//.test(baseUrl);
312
- if (isAbsolute) {
313
- try {
314
- const url = new URL(baseUrl);
315
- return url.pathname.replace(/^\/|\/$/g, "");
316
- } catch {
317
- return "";
318
- }
319
- }
320
- return baseUrl.replace(/^\/|\/$/g, "");
321
- }
322
- function stripPrefixFromPath(pathSegments, prefix) {
323
- if (!prefix) return pathSegments;
324
- const prefixSegments = prefix.split("/").filter(Boolean);
325
- if (prefixSegments.length === 0) return pathSegments;
326
- const startsWithPrefix = prefixSegments.every(
327
- (seg, i) => pathSegments[i] === seg
328
- );
329
- return startsWithPrefix ? pathSegments.slice(prefixSegments.length) : pathSegments;
330
- }
331
- function resolveStripPrefix(stripPathPrefix, baseUrl) {
332
- if (!stripPathPrefix) return "";
333
- if (stripPathPrefix === true) {
334
- return extractPrefixFromBaseUrl(baseUrl);
335
- }
336
- return stripPathPrefix.replace(/^\/|\/$/g, "");
337
- }
338
-
339
309
  // src/fetch.ts
340
310
  var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
341
311
  var isNetworkError = (err) => err instanceof TypeError;
342
312
  var isAbortError = (err) => err instanceof DOMException && err.name === "AbortError";
343
- async function executeFetch(baseUrl, path, method, defaultOptions, requestOptions, nextTags, tagPath) {
313
+ async function executeFetch(baseUrl, path, method, defaultOptions, requestOptions, nextTags) {
344
314
  const middlewares = defaultOptions.middlewares ?? [];
345
315
  let context = {
346
316
  baseUrl,
@@ -360,8 +330,7 @@ async function executeFetch(baseUrl, path, method, defaultOptions, requestOption
360
330
  defaultOptions: context.defaultOptions,
361
331
  requestOptions: context.requestOptions,
362
332
  middlewareFetchInit: context.fetchInit,
363
- nextTags,
364
- tagPath
333
+ nextTags
365
334
  });
366
335
  context.response = response;
367
336
  if (middlewares.length > 0) {
@@ -393,8 +362,7 @@ async function executeCoreFetch(config) {
393
362
  defaultOptions,
394
363
  requestOptions,
395
364
  middlewareFetchInit,
396
- nextTags,
397
- tagPath
365
+ nextTags
398
366
  } = config;
399
367
  const {
400
368
  middlewares: _,
@@ -419,7 +387,7 @@ async function executeCoreFetch(config) {
419
387
  }
420
388
  fetchInit.cache = requestOptions?.cache ?? fetchDefaults?.cache;
421
389
  if (nextTags) {
422
- const autoTags = generateTags(tagPath ?? path);
390
+ const autoTags = generateTags(path);
423
391
  const userNext = requestOptions?.next;
424
392
  fetchInit.next = {
425
393
  tags: userNext?.tags ?? autoTags,
@@ -510,11 +478,8 @@ function createProxyHandler(config) {
510
478
  baseUrl,
511
479
  defaultOptions,
512
480
  fetchExecutor = executeFetch,
513
- nextTags,
514
- urlPrefix,
515
- tagPrefix
481
+ nextTags
516
482
  } = config;
517
- const effectiveTagPrefix = tagPrefix ?? urlPrefix;
518
483
  return ((path) => {
519
484
  return new Proxy(
520
485
  {},
@@ -527,16 +492,13 @@ function createProxyHandler(config) {
527
492
  }
528
493
  return (options) => {
529
494
  const resolvedPath = resolvePath2(path, options?.params);
530
- const urlPath = urlPrefix ? stripPrefixFromPath(resolvedPath, urlPrefix) : resolvedPath;
531
- const tagPath = effectiveTagPrefix ? stripPrefixFromPath(resolvedPath, effectiveTagPrefix) : resolvedPath;
532
495
  return fetchExecutor(
533
496
  baseUrl,
534
- urlPath,
497
+ resolvedPath,
535
498
  method,
536
499
  defaultOptions,
537
500
  options,
538
- nextTags,
539
- tagPath
501
+ nextTags
540
502
  );
541
503
  };
542
504
  }
@@ -819,8 +781,7 @@ function sortByDependencies(plugins) {
819
781
  }
820
782
  return sorted;
821
783
  }
822
- function createPluginExecutor(initialPlugins = [], options = {}) {
823
- const { stripTagPrefix } = options;
784
+ function createPluginExecutor(initialPlugins = []) {
824
785
  validateDependencies(initialPlugins);
825
786
  const plugins = sortByDependencies(initialPlugins);
826
787
  const frozenPlugins = Object.freeze([...plugins]);
@@ -904,9 +865,6 @@ function createPluginExecutor(initialPlugins = [], options = {}) {
904
865
  ctx.headers = { ...ctx.headers, ...newHeaders };
905
866
  ctx.requestOptions.headers = ctx.headers;
906
867
  };
907
- if (stripTagPrefix) {
908
- ctx.stripTagPrefix = stripTagPrefix;
909
- }
910
868
  return ctx;
911
869
  }
912
870
  };
@@ -925,14 +883,12 @@ var Spoosh = class _Spoosh {
925
883
  baseUrl;
926
884
  defaultOptions;
927
885
  _plugins;
928
- _config;
929
886
  /**
930
887
  * Creates a new Spoosh instance.
931
888
  *
932
889
  * @param baseUrl - The base URL for all API requests (e.g., '/api' or 'https://api.example.com')
933
890
  * @param defaultOptions - Optional default options applied to all requests (headers, credentials, etc.)
934
891
  * @param plugins - Internal parameter used by the `.use()` method. Do not pass directly.
935
- * @param configOptions - Internal parameter used by the `.config()` method. Do not pass directly.
936
892
  *
937
893
  * @example
938
894
  * ```ts
@@ -945,11 +901,10 @@ var Spoosh = class _Spoosh {
945
901
  * });
946
902
  * ```
947
903
  */
948
- constructor(baseUrl, defaultOptions, plugins, configOptions) {
904
+ constructor(baseUrl, defaultOptions, plugins) {
949
905
  this.baseUrl = baseUrl;
950
906
  this.defaultOptions = defaultOptions || {};
951
907
  this._plugins = plugins || [];
952
- this._config = configOptions || {};
953
908
  }
954
909
  /**
955
910
  * Adds plugins to the Spoosh instance.
@@ -989,43 +944,7 @@ var Spoosh = class _Spoosh {
989
944
  return new _Spoosh(
990
945
  this.baseUrl,
991
946
  this.defaultOptions,
992
- plugins,
993
- this._config
994
- );
995
- }
996
- /**
997
- * Configures runtime options for the Spoosh instance.
998
- *
999
- * Returns a **new** Spoosh instance with the updated configuration (immutable pattern).
1000
- * Configuration is preserved across `.use()` calls.
1001
- *
1002
- * URL prefix stripping always auto-detects from baseUrl.
1003
- * Tag prefix stripping defaults to URL prefix but can be overridden.
1004
- *
1005
- * @param options - Configuration options
1006
- * @returns A new Spoosh instance with the specified configuration
1007
- *
1008
- * @example Default behavior (auto-detect from baseUrl for both URL and tags)
1009
- * ```ts
1010
- * // baseUrl="/api", schema="api/posts"
1011
- * // URL: /api/posts, Tags: ["posts"]
1012
- * const client = new Spoosh<Schema, Error>('https://localhost:3000/api');
1013
- * ```
1014
- *
1015
- * @example Override tag prefix (when baseUrl doesn't have the prefix you want to strip from tags)
1016
- * ```ts
1017
- * // baseUrl="/", schema="api/v1/posts"
1018
- * // URL: /api/v1/posts, Tags: ["posts"] (strips "api/v1" from tags only)
1019
- * const client = new Spoosh<Schema, Error>('http://localhost:3000')
1020
- * .configure({ stripTagPrefix: "api/v1" });
1021
- * ```
1022
- */
1023
- configure(options) {
1024
- return new _Spoosh(
1025
- this.baseUrl,
1026
- this.defaultOptions,
1027
- this._plugins,
1028
- { ...this._config, ...options }
947
+ plugins
1029
948
  );
1030
949
  }
1031
950
  /**
@@ -1041,19 +960,13 @@ var Spoosh = class _Spoosh {
1041
960
  */
1042
961
  getInstance() {
1043
962
  if (!this._instance) {
1044
- const urlPrefix = extractPrefixFromBaseUrl(this.baseUrl) || void 0;
1045
- const tagPrefix = this._config.stripTagPrefix ?? urlPrefix;
1046
963
  const api = createProxyHandler({
1047
964
  baseUrl: this.baseUrl,
1048
- defaultOptions: this.defaultOptions,
1049
- urlPrefix,
1050
- tagPrefix
965
+ defaultOptions: this.defaultOptions
1051
966
  });
1052
967
  const stateManager = createStateManager();
1053
968
  const eventEmitter = createEventEmitter();
1054
- const pluginExecutor = createPluginExecutor([...this._plugins], {
1055
- stripTagPrefix: tagPrefix
1056
- });
969
+ const pluginExecutor = createPluginExecutor([...this._plugins]);
1057
970
  this._instance = {
1058
971
  api,
1059
972
  stateManager,
@@ -1061,8 +974,7 @@ var Spoosh = class _Spoosh {
1061
974
  pluginExecutor,
1062
975
  config: {
1063
976
  baseUrl: this.baseUrl,
1064
- defaultOptions: this.defaultOptions,
1065
- stripTagPrefix: tagPrefix
977
+ defaultOptions: this.defaultOptions
1066
978
  },
1067
979
  _types: {
1068
980
  schema: void 0,
@@ -1181,21 +1093,12 @@ var Spoosh = class _Spoosh {
1181
1093
 
1182
1094
  // src/createClient.ts
1183
1095
  function createClient(config) {
1184
- const {
1185
- baseUrl,
1186
- defaultOptions = {},
1187
- middlewares = [],
1188
- stripTagPrefix
1189
- } = config;
1096
+ const { baseUrl, defaultOptions = {}, middlewares = [] } = config;
1190
1097
  const optionsWithMiddlewares = { ...defaultOptions, middlewares };
1191
- const urlPrefix = extractPrefixFromBaseUrl(baseUrl) || void 0;
1192
- const tagPrefix = stripTagPrefix ?? urlPrefix;
1193
1098
  return createProxyHandler({
1194
1099
  baseUrl,
1195
1100
  defaultOptions: optionsWithMiddlewares,
1196
- nextTags: true,
1197
- urlPrefix,
1198
- tagPrefix
1101
+ nextTags: true
1199
1102
  });
1200
1103
  }
1201
1104
 
@@ -1778,7 +1681,6 @@ export {
1778
1681
  executeFetch,
1779
1682
  extractMethodFromSelector,
1780
1683
  extractPathFromSelector,
1781
- extractPrefixFromBaseUrl,
1782
1684
  form,
1783
1685
  generateTags,
1784
1686
  getContentType,
@@ -1791,10 +1693,8 @@ export {
1791
1693
  resolveHeadersToRecord,
1792
1694
  resolvePath,
1793
1695
  resolveRequestBody,
1794
- resolveStripPrefix,
1795
1696
  resolveTags,
1796
1697
  setHeaders,
1797
1698
  sortObjectKeys,
1798
- stripPrefixFromPath,
1799
1699
  urlencoded
1800
1700
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spoosh/core",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "license": "MIT",
5
5
  "description": "Type-safe API client with plugin middleware system",
6
6
  "keywords": [