@vielzeug/courier 2.0.0 → 2.1.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/courier.cjs +3 -3
- package/dist/courier.cjs.map +1 -1
- package/dist/courier.d.ts +8 -7
- package/dist/courier.d.ts.map +1 -1
- package/dist/courier.iife.js +3 -3
- package/dist/courier.iife.js.map +1 -1
- package/dist/courier.js +3 -3
- package/dist/courier.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/query.cjs +1 -1
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +1 -1
- package/dist/query.js.map +1 -1
- package/dist/stream.cjs.map +1 -1
- package/dist/stream.d.ts +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/url.cjs.map +1 -1
- package/dist/url.d.ts.map +1 -1
- package/dist/url.js.map +1 -1
- package/package.json +17 -24
- package/dist/api.cjs +0 -2
- package/dist/api.cjs.map +0 -1
- package/dist/api.d.ts +0 -40
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -2
- package/dist/api.js.map +0 -1
- package/dist/devtools.cjs +0 -2
- package/dist/devtools.cjs.map +0 -1
- package/dist/devtools.d.ts +0 -3
- package/dist/devtools.d.ts.map +0 -1
- package/dist/devtools.js +0 -2
- package/dist/devtools.js.map +0 -1
package/dist/stream.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","names":[],"sources":["../src/stream.ts"],"sourcesContent":["import type { Params } from './url';\n\nimport { classifyRequestError, CourierDisposedError, CourierHttpError, CourierParseError } from './errors';\nimport { buildRequestInit } from './serialize';\nimport { anySignal, buildTimeoutSignal, type TransportCore } from './transport';\nimport { buildUrl } from './url';\n\nexport type StreamOptions<P extends string = string> = {\n body?: unknown;\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n headers?: Record<string, string>;\n method?: string;\n params?: P extends string ? Record<string, string | number | boolean> : never;\n query?: Params;\n signal?: AbortSignal;\n timeout?: number;\n};\n\nexport type StreamEvent<T = unknown> = { readonly data: T; readonly event: string };\n\nfunction abortable<T>(create: (signal: AbortSignal) => AsyncGenerator<T>): AsyncIterableIterator<T> {\n const controller = new AbortController();\n const iterator = create(controller.signal);\n\n return {\n next: (value?: undefined) => iterator.next(value),\n return: (value?: T) => {\n controller.abort();\n\n return iterator.return(value as T);\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n throw: (error?: unknown) => {\n controller.abort();\n\n return iterator.throw(error);\n },\n };\n}\n\nasync function open(\n transport: TransportCore,\n url: string,\n config: StreamOptions,\n): Promise<{ controller: AbortController; response: Response; untrack: () => void }> {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n const untrack = transport.track(controller);\n const method = (config.method ?? (config.body === undefined ? 'GET' : 'POST')).toUpperCase();\n const signal = buildTimeoutSignal(\n config.timeout ?? Number.POSITIVE_INFINITY,\n anySignal(config.signal, controller.signal),\n );\n let fullUrl = url;\n\n try {\n fullUrl = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n\n const headers = transport.mergeHeaders(config.headers);\n const { headers: requestHeaders, ...init } = buildRequestInit(\n method,\n headers,\n config.body,\n signal,\n config.fetchInit ?? {},\n );\n const response = await transport.dispatch({\n headers: requestHeaders as Record<string, string>,\n init,\n url: fullUrl,\n });\n\n if (!response.ok)\n throw CourierHttpError.fromResponse(response, await response.text().catch(() => ''), method, fullUrl);\n\n if (!response.body) throw new CourierParseError('Response has no body');\n\n return { controller, response, untrack };\n } catch (error) {\n untrack();\n\n if (error instanceof CourierHttpError || error instanceof CourierParseError) throw error;\n\n throw classifyRequestError(error, method, fullUrl, signal);\n }\n}\n\n/** Platform-shaped streaming primitives: async iteration owns cancellation and backpressure. */\nexport function createStreams(transport: TransportCore) {\n async function* events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P>,\n ): AsyncGenerator<StreamEvent<T>> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let event = 'message';\n let data = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) break;\n\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n?/g, '\\n');\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline);\n\n buffer = buffer.slice(newline + 1);\n\n if (line === '') {\n if (data !== '') {\n let parsed: unknown = data.endsWith('\\n') ? data.slice(0, -1) : data;\n\n try {\n parsed = JSON.parse(parsed as string);\n } catch {\n // SSE text payloads are valid raw values.\n }\n\n yield { data: parsed as T, event };\n }\n\n data = '';\n event = 'message';\n continue;\n }\n\n if (line.startsWith(':')) continue;\n\n const separator = line.indexOf(':');\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = (separator === -1 ? '' : line.slice(separator + 1)).replace(/^ /, '');\n\n if (field === 'data') data += `${value}\\n`;\n else if (field === 'event') event = value;\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n async function* read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' },\n ): AsyncGenerator<T> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) {\n if (config.parse === 'ndjson' && buffer.trim()) {\n try {\n yield JSON.parse(buffer) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${buffer.slice(0, 200)}`);\n }\n }\n\n break;\n }\n\n const text = decoder.decode(chunk.value, { stream: true });\n\n if (config.parse !== 'ndjson') {\n yield text as T;\n continue;\n }\n\n buffer += text;\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n\n buffer = buffer.slice(newline + 1);\n\n if (!line) continue;\n\n try {\n yield JSON.parse(line) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${line.slice(0, 200)}`);\n }\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n return {\n events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P> = {},\n ): AsyncIterableIterator<StreamEvent<T>> {\n return abortable((signal) =>\n events<T, P>(url, {\n ...config,\n headers: { accept: 'text/event-stream', 'cache-control': 'no-cache', ...config.headers },\n signal: anySignal(config.signal, signal),\n }),\n );\n },\n read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' } = {},\n ): AsyncIterableIterator<T> {\n return abortable((signal) => read<T, P>(url, { ...config, signal: anySignal(config.signal, signal) }));\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.js","names":[],"sources":["../src/stream.ts"],"sourcesContent":["import { CourierDisposedError, CourierHttpError, CourierParseError, classifyRequestError } from './errors';\nimport { buildRequestInit } from './serialize';\nimport { anySignal, buildTimeoutSignal, type TransportCore } from './transport';\nimport type { Params } from './url';\nimport { buildUrl } from './url';\n\nexport type StreamOptions<P extends string = string> = {\n body?: unknown;\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n headers?: Record<string, string>;\n method?: string;\n params?: P extends string ? Record<string, string | number | boolean> : never;\n query?: Params;\n signal?: AbortSignal;\n timeout?: number;\n};\n\nexport type StreamEvent<T = unknown> = { readonly data: T; readonly event: string };\n\nfunction abortable<T>(create: (signal: AbortSignal) => AsyncGenerator<T>): AsyncIterableIterator<T> {\n const controller = new AbortController();\n const iterator = create(controller.signal);\n\n return {\n next: (value?: undefined) => iterator.next(value),\n return: (value?: T) => {\n controller.abort();\n\n return iterator.return(value as T);\n },\n [Symbol.asyncIterator]() {\n return this;\n },\n throw: (error?: unknown) => {\n controller.abort();\n\n return iterator.throw(error);\n },\n };\n}\n\nasync function open(\n transport: TransportCore,\n url: string,\n config: StreamOptions,\n): Promise<{ controller: AbortController; response: Response; untrack: () => void }> {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const controller = new AbortController();\n const untrack = transport.track(controller);\n const method = (config.method ?? (config.body === undefined ? 'GET' : 'POST')).toUpperCase();\n const signal = buildTimeoutSignal(\n config.timeout ?? Number.POSITIVE_INFINITY,\n anySignal(config.signal, controller.signal),\n );\n let fullUrl = url;\n\n try {\n fullUrl = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n\n const headers = transport.mergeHeaders(config.headers);\n const { headers: requestHeaders, ...init } = buildRequestInit(\n method,\n headers,\n config.body,\n signal,\n config.fetchInit ?? {},\n );\n const response = await transport.dispatch({\n headers: requestHeaders as Record<string, string>,\n init,\n url: fullUrl,\n });\n\n if (!response.ok)\n throw CourierHttpError.fromResponse(response, await response.text().catch(() => ''), method, fullUrl);\n\n if (!response.body) throw new CourierParseError('Response has no body');\n\n return { controller, response, untrack };\n } catch (error) {\n untrack();\n\n if (error instanceof CourierHttpError || error instanceof CourierParseError) throw error;\n\n throw classifyRequestError(error, method, fullUrl, signal);\n }\n}\n\n/** Platform-shaped streaming primitives: async iteration owns cancellation and backpressure. */\nexport function createStreams(transport: TransportCore) {\n async function* events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P>,\n ): AsyncGenerator<StreamEvent<T>> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let event = 'message';\n let data = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) break;\n\n buffer += decoder.decode(chunk.value, { stream: true }).replace(/\\r\\n?/g, '\\n');\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline);\n\n buffer = buffer.slice(newline + 1);\n\n if (line === '') {\n if (data !== '') {\n let parsed: unknown = data.endsWith('\\n') ? data.slice(0, -1) : data;\n\n try {\n parsed = JSON.parse(parsed as string);\n } catch {\n // SSE text payloads are valid raw values.\n }\n\n yield { data: parsed as T, event };\n }\n\n data = '';\n event = 'message';\n continue;\n }\n\n if (line.startsWith(':')) continue;\n\n const separator = line.indexOf(':');\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = (separator === -1 ? '' : line.slice(separator + 1)).replace(/^ /, '');\n\n if (field === 'data') data += `${value}\\n`;\n else if (field === 'event') event = value;\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n async function* read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' },\n ): AsyncGenerator<T> {\n const { controller, response, untrack } = await open(transport, url, config);\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n const chunk = await reader.read();\n\n if (chunk.done) {\n if (config.parse === 'ndjson' && buffer.trim()) {\n try {\n yield JSON.parse(buffer) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${buffer.slice(0, 200)}`);\n }\n }\n\n break;\n }\n\n const text = decoder.decode(chunk.value, { stream: true });\n\n if (config.parse !== 'ndjson') {\n yield text as T;\n continue;\n }\n\n buffer += text;\n\n let newline: number;\n\n while ((newline = buffer.indexOf('\\n')) !== -1) {\n const line = buffer.slice(0, newline).trim();\n\n buffer = buffer.slice(newline + 1);\n\n if (!line) continue;\n\n try {\n yield JSON.parse(line) as T;\n } catch {\n throw new CourierParseError(`NDJSON: failed to parse line: ${line.slice(0, 200)}`);\n }\n }\n }\n } finally {\n reader.releaseLock();\n controller.abort();\n untrack();\n }\n }\n\n return {\n events<T = unknown, P extends string = string>(\n url: P,\n config: StreamOptions<P> = {},\n ): AsyncIterableIterator<StreamEvent<T>> {\n return abortable((signal) =>\n events<T, P>(url, {\n ...config,\n headers: { accept: 'text/event-stream', 'cache-control': 'no-cache', ...config.headers },\n signal: anySignal(config.signal, signal),\n }),\n );\n },\n read<T = string, P extends string = string>(\n url: P,\n config: StreamOptions<P> & { parse?: 'ndjson' | 'text' } = {},\n ): AsyncIterableIterator<T> {\n return abortable((signal) => read<T, P>(url, { ...config, signal: anySignal(config.signal, signal) }));\n },\n };\n}\n"],"mappings":"mRAmBA,SAAS,EAAa,EAA8E,CAClG,IAAM,EAAa,IAAI,gBACjB,EAAW,EAAO,EAAW,MAAM,EAEzC,MAAO,CACL,KAAO,GAAsB,EAAS,KAAK,CAAK,EAChD,OAAS,IACP,EAAW,MAAM,EAEV,EAAS,OAAO,CAAU,GAEnC,CAAC,OAAO,gBAAiB,CACvB,OAAO,IACT,EACA,MAAQ,IACN,EAAW,MAAM,EAEV,EAAS,MAAM,CAAK,EAE/B,CACF,CAEA,eAAe,EACb,EACA,EACA,EACmF,CACnF,GAAI,EAAU,SAAU,MAAM,IAAI,EAAqB,SAAS,EAEhE,IAAM,EAAa,IAAI,gBACjB,EAAU,EAAU,MAAM,CAAU,EACpC,GAAU,EAAO,SAAW,EAAO,OAAS,IAAA,GAAY,MAAQ,QAAA,CAAS,YAAY,EACrF,EAAS,EACb,EAAO,SAAW,IAClB,EAAU,EAAO,OAAQ,EAAW,MAAM,CAC5C,EACI,EAAU,EAEd,GAAI,CACF,EAAU,EAAS,EAAU,QAAS,EAAK,EAAO,OAA8B,EAAO,KAAK,EAE5F,IAAM,EAAU,EAAU,aAAa,EAAO,OAAO,EAC/C,CAAE,QAAS,EAAgB,GAAG,GAAS,EAC3C,EACA,EACA,EAAO,KACP,EACA,EAAO,WAAa,CAAC,CACvB,EACM,EAAW,MAAM,EAAU,SAAS,CACxC,QAAS,EACT,OACA,IAAK,CACP,CAAC,EAED,GAAI,CAAC,EAAS,GACZ,MAAM,EAAiB,aAAa,EAAU,MAAM,EAAS,KAAK,CAAC,CAAC,UAAY,EAAE,EAAG,EAAQ,CAAO,EAEtG,GAAI,CAAC,EAAS,KAAM,MAAM,IAAI,EAAkB,sBAAsB,EAEtE,MAAO,CAAE,aAAY,WAAU,SAAQ,CACzC,OAAS,EAAO,CAKd,MAJA,EAAQ,EAEJ,aAAiB,GAAoB,aAAiB,EAAyB,EAE7E,EAAqB,EAAO,EAAQ,EAAS,CAAM,CAC3D,CACF,CAGA,SAAgB,EAAc,EAA0B,CACtD,eAAgB,EACd,EACA,EACgC,CAChC,GAAM,CAAE,aAAY,WAAU,WAAY,MAAM,EAAK,EAAW,EAAK,CAAM,EACrE,EAAS,EAAS,KAAM,UAAU,EAClC,EAAU,IAAI,YAChB,EAAS,GACT,EAAQ,UACR,EAAO,GAEX,GAAI,CACF,OAAa,CACX,IAAM,EAAQ,MAAM,EAAO,KAAK,EAEhC,GAAI,EAAM,KAAM,MAEhB,GAAU,EAAQ,OAAO,EAAM,MAAO,CAAE,OAAQ,EAAK,CAAC,CAAC,CAAC,QAAQ,SAAU;CAAI,EAE9E,IAAI,EAEJ,MAAQ,EAAU,EAAO,QAAQ;CAAI,KAAO,IAAI,CAC9C,IAAM,EAAO,EAAO,MAAM,EAAG,CAAO,EAIpC,GAFA,EAAS,EAAO,MAAM,EAAU,CAAC,EAE7B,IAAS,GAAI,CACf,GAAI,IAAS,GAAI,CACf,IAAI,EAAkB,EAAK,SAAS;CAAI,EAAI,EAAK,MAAM,EAAG,EAAE,EAAI,EAEhE,GAAI,CACF,EAAS,KAAK,MAAM,CAAgB,CACtC,MAAQ,CAER,CAEA,KAAM,CAAE,KAAM,EAAa,OAAM,CACnC,CAEA,EAAO,GACP,EAAQ,UACR,QACF,CAEA,GAAI,EAAK,WAAW,GAAG,EAAG,SAE1B,IAAM,EAAY,EAAK,QAAQ,GAAG,EAC5B,EAAQ,IAAc,GAAK,EAAO,EAAK,MAAM,EAAG,CAAS,EACzD,GAAS,IAAc,GAAK,GAAK,EAAK,MAAM,EAAY,CAAC,EAAA,CAAG,QAAQ,KAAM,EAAE,EAE9E,IAAU,OAAQ,GAAQ,GAAG,EAAM,IAC9B,IAAU,UAAS,EAAQ,EACtC,CACF,CACF,QAAU,CACR,EAAO,YAAY,EACnB,EAAW,MAAM,EACjB,EAAQ,CACV,CACF,CAEA,eAAgB,EACd,EACA,EACmB,CACnB,GAAM,CAAE,aAAY,WAAU,WAAY,MAAM,EAAK,EAAW,EAAK,CAAM,EACrE,EAAS,EAAS,KAAM,UAAU,EAClC,EAAU,IAAI,YAChB,EAAS,GAEb,GAAI,CACF,OAAa,CACX,IAAM,EAAQ,MAAM,EAAO,KAAK,EAEhC,GAAI,EAAM,KAAM,CACd,GAAI,EAAO,QAAU,UAAY,EAAO,KAAK,EAC3C,GAAI,CACF,MAAM,KAAK,MAAM,CAAM,CACzB,MAAQ,CACN,MAAM,IAAI,EAAkB,iCAAiC,EAAO,MAAM,EAAG,GAAG,GAAG,CACrF,CAGF,KACF,CAEA,IAAM,EAAO,EAAQ,OAAO,EAAM,MAAO,CAAE,OAAQ,EAAK,CAAC,EAEzD,GAAI,EAAO,QAAU,SAAU,CAC7B,MAAM,EACN,QACF,CAEA,GAAU,EAEV,IAAI,EAEJ,MAAQ,EAAU,EAAO,QAAQ;CAAI,KAAO,IAAI,CAC9C,IAAM,EAAO,EAAO,MAAM,EAAG,CAAO,CAAC,CAAC,KAAK,EAE3C,KAAS,EAAO,MAAM,EAAU,CAAC,EAE5B,EAEL,GAAI,CACF,MAAM,KAAK,MAAM,CAAI,CACvB,MAAQ,CACN,MAAM,IAAI,EAAkB,iCAAiC,EAAK,MAAM,EAAG,GAAG,GAAG,CACnF,CACF,CACF,CACF,QAAU,CACR,EAAO,YAAY,EACnB,EAAW,MAAM,EACjB,EAAQ,CACV,CACF,CAEA,MAAO,CACL,OACE,EACA,EAA2B,CAAC,EACW,CACvC,OAAO,EAAW,GAChB,EAAa,EAAK,CAChB,GAAG,EACH,QAAS,CAAE,OAAQ,oBAAqB,gBAAiB,WAAY,GAAG,EAAO,OAAQ,EACvF,OAAQ,EAAU,EAAO,OAAQ,CAAM,CACzC,CAAC,CACH,CACF,EACA,KACE,EACA,EAA2D,CAAC,EAClC,CAC1B,OAAO,EAAW,GAAW,EAAW,EAAK,CAAE,GAAG,EAAQ,OAAQ,EAAU,EAAO,OAAQ,CAAM,CAAE,CAAC,CAAC,CACvG,CACF,CACF"}
|
package/dist/types.d.ts
CHANGED
|
@@ -38,7 +38,8 @@ export type QueryCache = {
|
|
|
38
38
|
}): Promise<T>;
|
|
39
39
|
get<T>(key: QueryKey): T | undefined;
|
|
40
40
|
getSnapshot<T>(key: QueryKey): AsyncState<T> | null;
|
|
41
|
-
|
|
41
|
+
/** Invalidate all entries whose key starts with `prefix`. An empty prefix invalidates every entry. */
|
|
42
|
+
invalidate(prefix: readonly unknown[]): void;
|
|
42
43
|
keys(): QueryKey[];
|
|
43
44
|
refetchStale(): void;
|
|
44
45
|
set<T>(key: QueryKey, data: T, options?: {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/url.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.cjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"url.cjs","names":[],"sources":["../src/url.ts"],"sourcesContent":["import { CourierParseError } from './errors';\nimport type { ResponseType } from './response';\n\ntype QueryScalar = string | number | boolean | null;\n\nexport type ParamValue = QueryScalar | readonly QueryScalar[] | undefined;\nexport type Params = Record<string, ParamValue>;\n\n// Type-safe path params: extracts {param} placeholders from a path string\ntype ExtractPathParams<P extends string> = P extends `${string}{${infer K}}${infer R}`\n ? K | ExtractPathParams<R>\n : never;\n\nexport type PathConfig<P extends string> = [ExtractPathParams<P>] extends [never]\n ? { params?: never }\n : { params: Record<ExtractPathParams<P>, string | number | boolean> };\n\nexport type CourierRequestConfig<P extends string = string, T = unknown> = PathConfig<P> & {\n /** Request body. Plain objects → JSON. BodyInit values passed as-is. */\n body?: unknown;\n /** Query string parameters. */\n query?: Params;\n /** Response parsing strategy. */\n responseType?: ResponseType;\n /**\n * Optional schema for response validation. Any object with a `parse(data)` method\n * works — e.g. a `@vielzeug/spell` schema or a plain validator function wrapper.\n * Called after the response body is parsed; throws if validation fails.\n * The schema's return type must be assignable to `T`.\n */\n schema?: { parse(data: unknown): T };\n /** Request timeout in ms. Overrides client default. */\n timeout?: number;\n};\n\nexport type HttpRequestConfig<P extends string = string, T = unknown> = CourierRequestConfig<P, T> & {\n /** Raw fetch options for advanced use (credentials, cache, mode, referrer, etc.). */\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n /** Per-request headers merged with (and overriding) global client headers. */\n headers?: Record<string, string>;\n /** External abort signal merged with internal cancellation. */\n signal?: AbortSignal;\n};\n\nexport function buildUrl(base: string, path: string, params?: Params, query?: Params): string {\n const baseClean = base.replace(/\\/+$/, '');\n let pathClean = path.replace(/^\\/+/, '');\n\n pathClean = pathClean.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const val = params?.[key];\n\n if (val === undefined || val === null) throw new CourierParseError(`unresolved path param {${key}} in '${path}'`);\n\n return encodeURIComponent(String(val));\n });\n\n const url = baseClean && pathClean ? `${baseClean}/${pathClean}` : baseClean || pathClean;\n\n if (!query) return url;\n\n const qs = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined) {\n qs.append(key, entry === null ? '' : String(entry));\n }\n }\n\n continue;\n }\n\n qs.append(key, value === null ? '' : String(value));\n }\n\n const queryString = qs.toString();\n\n return queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url;\n}\n"],"mappings":"gCA4CA,SAAgB,EAAS,EAAc,EAAc,EAAiB,EAAwB,CAC5F,IAAM,EAAY,EAAK,QAAQ,OAAQ,EAAE,EACrC,EAAY,EAAK,QAAQ,OAAQ,EAAE,EAEvC,EAAY,EAAU,QAAQ,gBAAiB,EAAG,IAAgB,CAChE,IAAM,EAAM,IAAS,GAErB,GAAI,GAA6B,KAAM,MAAM,IAAI,EAAA,kBAAkB,0BAA0B,EAAI,QAAQ,EAAK,EAAE,EAEhH,OAAO,mBAAmB,OAAO,CAAG,CAAC,CACvC,CAAC,EAED,IAAM,EAAM,GAAa,EAAY,GAAG,EAAU,GAAG,IAAc,GAAa,EAEhF,GAAI,CAAC,EAAO,OAAO,EAEnB,IAAM,EAAK,IAAI,gBAEf,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EACzC,OAAU,IAAA,GAId,IAAI,MAAM,QAAQ,CAAK,EAAG,CACxB,IAAK,IAAM,KAAS,EACd,IAAU,IAAA,IACZ,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,EAItD,QACF,CAEA,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,CAFlD,CAKF,IAAM,EAAc,EAAG,SAAS,EAEhC,OAAO,EAAc,GAAG,IAAM,EAAI,SAAS,GAAG,EAAI,IAAM,MAAM,IAAgB,CAChF"}
|
package/dist/url.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;AAC1E,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAGhD,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,GAClF,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,GACxB,KAAK,CAAC;AAEV,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC7E;IAAE,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;CAAE,CAAC;AAExE,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,GAAG;IACzF,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,OAAO,GAAG,CAAC,CAAA;KAAE,CAAC;IACrC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,IAAI,oBAAoB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IACnG,qFAAqF;IACrF,SAAS,CAAC,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACxE,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAuC5F"}
|
package/dist/url.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["import { CourierParseError } from './errors';\nimport type { ResponseType } from './response';\n\ntype QueryScalar = string | number | boolean | null;\n\nexport type ParamValue = QueryScalar | readonly QueryScalar[] | undefined;\nexport type Params = Record<string, ParamValue>;\n\n// Type-safe path params: extracts {param} placeholders from a path string\ntype ExtractPathParams<P extends string> = P extends `${string}{${infer K}}${infer R}`\n ? K | ExtractPathParams<R>\n : never;\n\nexport type PathConfig<P extends string> = [ExtractPathParams<P>] extends [never]\n ? { params?: never }\n : { params: Record<ExtractPathParams<P>, string | number | boolean> };\n\nexport type CourierRequestConfig<P extends string = string, T = unknown> = PathConfig<P> & {\n /** Request body. Plain objects → JSON. BodyInit values passed as-is. */\n body?: unknown;\n /** Query string parameters. */\n query?: Params;\n /** Response parsing strategy. */\n responseType?: ResponseType;\n /**\n * Optional schema for response validation. Any object with a `parse(data)` method\n * works — e.g. a `@vielzeug/spell` schema or a plain validator function wrapper.\n * Called after the response body is parsed; throws if validation fails.\n * The schema's return type must be assignable to `T`.\n */\n schema?: { parse(data: unknown): T };\n /** Request timeout in ms. Overrides client default. */\n timeout?: number;\n};\n\nexport type HttpRequestConfig<P extends string = string, T = unknown> = CourierRequestConfig<P, T> & {\n /** Raw fetch options for advanced use (credentials, cache, mode, referrer, etc.). */\n fetchInit?: Omit<RequestInit, 'body' | 'headers' | 'method' | 'signal'>;\n /** Per-request headers merged with (and overriding) global client headers. */\n headers?: Record<string, string>;\n /** External abort signal merged with internal cancellation. */\n signal?: AbortSignal;\n};\n\nexport function buildUrl(base: string, path: string, params?: Params, query?: Params): string {\n const baseClean = base.replace(/\\/+$/, '');\n let pathClean = path.replace(/^\\/+/, '');\n\n pathClean = pathClean.replace(/\\{([^}]+)\\}/g, (_, key: string) => {\n const val = params?.[key];\n\n if (val === undefined || val === null) throw new CourierParseError(`unresolved path param {${key}} in '${path}'`);\n\n return encodeURIComponent(String(val));\n });\n\n const url = baseClean && pathClean ? `${baseClean}/${pathClean}` : baseClean || pathClean;\n\n if (!query) return url;\n\n const qs = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const entry of value) {\n if (entry !== undefined) {\n qs.append(key, entry === null ? '' : String(entry));\n }\n }\n\n continue;\n }\n\n qs.append(key, value === null ? '' : String(value));\n }\n\n const queryString = qs.toString();\n\n return queryString ? `${url}${url.includes('?') ? '&' : '?'}${queryString}` : url;\n}\n"],"mappings":"gDA4CA,SAAgB,EAAS,EAAc,EAAc,EAAiB,EAAwB,CAC5F,IAAM,EAAY,EAAK,QAAQ,OAAQ,EAAE,EACrC,EAAY,EAAK,QAAQ,OAAQ,EAAE,EAEvC,EAAY,EAAU,QAAQ,gBAAiB,EAAG,IAAgB,CAChE,IAAM,EAAM,IAAS,GAErB,GAAI,GAA6B,KAAM,MAAM,IAAI,EAAkB,0BAA0B,EAAI,QAAQ,EAAK,EAAE,EAEhH,OAAO,mBAAmB,OAAO,CAAG,CAAC,CACvC,CAAC,EAED,IAAM,EAAM,GAAa,EAAY,GAAG,EAAU,GAAG,IAAc,GAAa,EAEhF,GAAI,CAAC,EAAO,OAAO,EAEnB,IAAM,EAAK,IAAI,gBAEf,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAK,EACzC,OAAU,IAAA,GAId,IAAI,MAAM,QAAQ,CAAK,EAAG,CACxB,IAAK,IAAM,KAAS,EACd,IAAU,IAAA,IACZ,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,EAItD,QACF,CAEA,EAAG,OAAO,EAAK,IAAU,KAAO,GAAK,OAAO,CAAK,CAAC,CAFlD,CAKF,IAAM,EAAc,EAAG,SAAS,EAEhC,OAAO,EAAc,GAAG,IAAM,EAAI,SAAS,GAAG,EAAI,IAAM,MAAM,IAAgB,CAChF"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vielzeug/courier",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "HTTP client with caching, request deduplication, typed mutations, SSE streaming, and interceptors",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
6
9
|
"files": [
|
|
7
10
|
"dist"
|
|
8
11
|
],
|
|
@@ -10,43 +13,33 @@
|
|
|
10
13
|
"module": "./dist/index.js",
|
|
11
14
|
"types": "dist/index.d.ts",
|
|
12
15
|
"exports": {
|
|
13
|
-
"./devtools": {
|
|
14
|
-
"source": "./src/devtools.ts",
|
|
15
|
-
"types": "./dist/devtools.d.ts",
|
|
16
|
-
"import": "./dist/devtools.js",
|
|
17
|
-
"require": "./dist/devtools.cjs"
|
|
18
|
-
},
|
|
19
16
|
".": {
|
|
20
|
-
"source": "./src/index.ts",
|
|
21
|
-
"types": "./dist/index.d.ts",
|
|
22
17
|
"import": "./dist/index.js",
|
|
23
|
-
"require": "./dist/index.cjs"
|
|
18
|
+
"require": "./dist/index.cjs",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
24
20
|
}
|
|
25
21
|
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"registry": "https://registry.npmjs.org/"
|
|
25
|
+
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "vite build && pnpm run build:bundle && pnpm run build:types",
|
|
28
|
+
"build:bundle": "vite build --config vite.bundle.config.ts",
|
|
28
29
|
"build:types": "tsc -p tsconfig.declarations.json",
|
|
29
|
-
"fix": "
|
|
30
|
-
"lint": "
|
|
30
|
+
"fix": "biome check --write src",
|
|
31
|
+
"lint": "biome ci src",
|
|
31
32
|
"prepublishOnly": "pnpm run build",
|
|
32
33
|
"preview": "vite preview",
|
|
33
|
-
"test": "vitest"
|
|
34
|
-
"build:bundle": "vite build --config vite.bundle.config.ts"
|
|
35
|
-
},
|
|
36
|
-
"publishConfig": {
|
|
37
|
-
"access": "public",
|
|
38
|
-
"registry": "https://registry.npmjs.org/"
|
|
39
|
-
},
|
|
40
|
-
"engines": {
|
|
41
|
-
"node": ">=22"
|
|
34
|
+
"test": "vitest"
|
|
42
35
|
},
|
|
43
36
|
"dependencies": {
|
|
44
|
-
"@vielzeug/arsenal": "2.0.
|
|
37
|
+
"@vielzeug/arsenal": "2.0.1"
|
|
45
38
|
},
|
|
46
39
|
"devDependencies": {
|
|
47
|
-
"@types/node": "^26.
|
|
40
|
+
"@types/node": "^26.2.0",
|
|
48
41
|
"typescript": "^6.0.3",
|
|
49
|
-
"vite": "^8.2.
|
|
42
|
+
"vite": "^8.2.1",
|
|
50
43
|
"vitest": "^4.1.10"
|
|
51
44
|
}
|
|
52
45
|
}
|
package/dist/api.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const e=require("./errors.cjs"),t=require("./response.cjs"),n=require("./serialize.cjs"),r=require("./transport.cjs"),i=require("./url.cjs");function a(a){let{transport:o,...s}=a??{},c=o??r.createTransportCore(s),l=!o;async function u(n,r,i,a,o,s){let l=r.signal,u;try{u=await c.dispatch({headers:n,init:r,url:i})}catch(t){throw e.classifyRequestError(t,a,i,l)}if(!u.ok){let n=u.headers.get(`content-type`)?.includes(`json`)??!1,r;if(typeof u.text==`function`){let e=await u.text().catch(()=>``);if(r=e,e&&n)try{r=JSON.parse(e)}catch{}}else r=await t.parseResponse(u,n?`json`:`auto`).catch(()=>``);throw e.CourierHttpError.fromResponse(u,r,a,i)}let d;try{d=await t.parseResponse(u,o??`auto`)}catch(t){throw e.classifyRequestError(t,a,i,l)}if(s)try{return s.parse(d)}catch(t){throw new e.CourierSchemaValidationError(t,d)}return d}async function d(t,a,o={}){if(c.disposed)throw new e.CourierDisposedError(`Courier`);let s=t.toUpperCase(),l;try{l=i.buildUrl(c.baseUrl,a,o.params,o.query)}catch(t){throw e.classifyRequestError(t,s,a)}let{body:d,fetchInit:f,headers:p,responseType:m,schema:h,signal:g,timeout:_}=o;_!==void 0&&r.validateTimeout(_);let v=new AbortController,y=c.track(v),b=r.buildTimeoutSignal(_??c.getTimeout(),r.anySignal(g,v.signal)),{headers:x,...S}=n.buildRequestInit(s,c.mergeHeaders(p),d,b,f??{});try{return await u(x,S,l,s,m,h)}finally{y()}}return{cancelAll:c.cancelAll,delete:(e,t)=>d(`DELETE`,e,t),get disposalSignal(){return c.disposalSignal},dispose(){l&&c.dispose()},get disposed(){return c.disposed},get:(e,t)=>d(`GET`,e,t),getHeaders:c.getHeaders,headers:c.headers,patch:(e,t)=>d(`PATCH`,e,t),post:(e,t)=>d(`POST`,e,t),put:(e,t)=>d(`PUT`,e,t),request:d,[Symbol.dispose](){this.dispose()},use:c.use}}exports.createApi=a;
|
|
2
|
-
//# sourceMappingURL=api.cjs.map
|
package/dist/api.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.cjs","names":[],"sources":["../src/api.ts"],"sourcesContent":["import type { HttpRequestConfig, Params } from './url';\n\nimport { classifyRequestError, CourierDisposedError, CourierHttpError, CourierSchemaValidationError } from './errors';\nimport { parseResponse } from './response';\nimport { buildRequestInit } from './serialize';\nimport {\n anySignal,\n buildTimeoutSignal,\n createTransportCore,\n type TransportCore,\n type TransportOptions,\n validateTimeout,\n} from './transport';\nimport { buildUrl } from './url';\n\nexport type { FetchContext, Interceptor } from './transport';\n\n/**\n * Creates a typed REST client — `get`/`post`/`put`/`patch`/`delete`/`request`, all backed by a\n * shared interceptor pipeline, header management, and `AbortController` lifecycle.\n *\n * @example\n * ```ts\n * const api = createApi({ baseUrl: 'https://api.example.com', timeout: 10_000 });\n *\n * const user = await api.get<User>('/users/{id}', { params: { id: '1' } });\n * const created = await api.post<User>('/users', { body: { name: 'Ada' } });\n *\n * api.use(async (ctx, next) => next(ctx.withHeaders({ authorization: `Bearer ${token}` })));\n *\n * // later:\n * api.dispose();\n * ```\n */\nexport function createApi(opts?: TransportOptions & { transport?: TransportCore }) {\n const { transport: sharedTransport, ...transportOpts } = opts ?? {};\n const transport = sharedTransport ?? createTransportCore(transportOpts);\n const ownTransport = !sharedTransport;\n\n async function execute<T>(\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n full: string,\n m: string,\n responseType: HttpRequestConfig['responseType'],\n schema?: { parse(data: unknown): T },\n ): Promise<T> {\n const signal = init.signal as AbortSignal | undefined;\n let res: Response;\n\n try {\n res = await transport.dispatch({ headers, init, url: full });\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (!res.ok) {\n // Error bodies are read once as text, then JSON-parsed if the content-type\n // says so — a binary success config (`responseType: 'blob'`) must not trap\n // the server's error message in an unreadable wrapper, and a failed\n // parseResponse-then-fallback double-read loses the body entirely.\n // `res.text` is missing on minimal custom-fetch fakes — fall back to\n // parseResponse there.\n const isJson = res.headers.get('content-type')?.includes('json') ?? false;\n let body: unknown;\n\n if (typeof res.text === 'function') {\n const text = await res.text().catch(() => '');\n\n body = text;\n\n if (text && isJson) {\n try {\n body = JSON.parse(text);\n } catch {\n // Malformed JSON error body — keep the raw text, not ''.\n }\n }\n } else {\n body = await parseResponse(res, isJson ? 'json' : 'auto').catch(() => '');\n }\n\n throw CourierHttpError.fromResponse(res, body, m, full);\n }\n\n let raw: unknown;\n\n try {\n raw = await parseResponse(res, responseType ?? 'auto');\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (schema) {\n try {\n return schema.parse(raw);\n } catch (err) {\n throw new CourierSchemaValidationError(err, raw);\n }\n }\n\n return raw as T;\n }\n\n async function request<T, P extends string = string>(\n method: string,\n url: P,\n config: HttpRequestConfig<P> = {} as HttpRequestConfig<P>,\n ) {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const m = method.toUpperCase();\n\n let full: string;\n\n try {\n full = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n } catch (err) {\n throw classifyRequestError(err, m, url);\n }\n\n const {\n body,\n fetchInit,\n headers,\n responseType,\n schema,\n signal: extSignal,\n timeout: cfgTimeout,\n } = config as HttpRequestConfig;\n\n if (cfgTimeout !== undefined) validateTimeout(cfgTimeout);\n\n const requestAc = new AbortController();\n const untrack = transport.track(requestAc);\n const signal = buildTimeoutSignal(cfgTimeout ?? transport.getTimeout(), anySignal(extSignal, requestAc.signal));\n const { headers: initHeaders, ...restInit } = buildRequestInit(\n m,\n transport.mergeHeaders(headers),\n body,\n signal,\n fetchInit ?? {},\n );\n\n try {\n return await execute<T>(\n initHeaders as Record<string, string>,\n restInit,\n full,\n m,\n responseType,\n schema as { parse(data: unknown): T } | undefined,\n );\n } finally {\n untrack();\n }\n }\n\n return {\n cancelAll: transport.cancelAll,\n delete: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('DELETE', url, cfg),\n get disposalSignal() {\n return transport.disposalSignal;\n },\n dispose(): void {\n if (ownTransport) transport.dispose();\n },\n get disposed() {\n return transport.disposed;\n },\n get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('GET', url, cfg),\n getHeaders: transport.getHeaders,\n headers: transport.headers,\n patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PATCH', url, cfg),\n post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('POST', url, cfg),\n put: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PUT', url, cfg),\n request,\n [Symbol.dispose](): void {\n this.dispose();\n },\n use: transport.use,\n };\n}\n\nexport type ApiClient = ReturnType<typeof createApi>;\n"],"mappings":"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"}
|
package/dist/api.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { HttpRequestConfig } from './url';
|
|
2
|
-
import { type TransportCore, type TransportOptions } from './transport';
|
|
3
|
-
export type { FetchContext, Interceptor } from './transport';
|
|
4
|
-
/**
|
|
5
|
-
* Creates a typed REST client — `get`/`post`/`put`/`patch`/`delete`/`request`, all backed by a
|
|
6
|
-
* shared interceptor pipeline, header management, and `AbortController` lifecycle.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* const api = createApi({ baseUrl: 'https://api.example.com', timeout: 10_000 });
|
|
11
|
-
*
|
|
12
|
-
* const user = await api.get<User>('/users/{id}', { params: { id: '1' } });
|
|
13
|
-
* const created = await api.post<User>('/users', { body: { name: 'Ada' } });
|
|
14
|
-
*
|
|
15
|
-
* api.use(async (ctx, next) => next(ctx.withHeaders({ authorization: `Bearer ${token}` })));
|
|
16
|
-
*
|
|
17
|
-
* // later:
|
|
18
|
-
* api.dispose();
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export declare function createApi(opts?: TransportOptions & {
|
|
22
|
-
transport?: TransportCore;
|
|
23
|
-
}): {
|
|
24
|
-
cancelAll: () => void;
|
|
25
|
-
delete: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
|
|
26
|
-
readonly disposalSignal: AbortSignal;
|
|
27
|
-
dispose(): void;
|
|
28
|
-
readonly disposed: boolean;
|
|
29
|
-
get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
|
|
30
|
-
getHeaders: () => Readonly<Record<string, string>>;
|
|
31
|
-
headers: (updates: Record<string, string | undefined>) => void;
|
|
32
|
-
patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
|
|
33
|
-
post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
|
|
34
|
-
put: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => Promise<T>;
|
|
35
|
-
request: <T, P extends string = string>(method: string, url: P, config?: HttpRequestConfig<P>) => Promise<T>;
|
|
36
|
-
[Symbol.dispose](): void;
|
|
37
|
-
use: (interceptor: import("./transport").Interceptor) => () => void;
|
|
38
|
-
};
|
|
39
|
-
export type ApiClient = ReturnType<typeof createApi>;
|
|
40
|
-
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAU,MAAM,OAAO,CAAC;AAKvD,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EAEtB,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG;IAAE,SAAS,CAAC,EAAE,aAAa,CAAA;CAAE;;aA8HpE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;eAI9D,IAAI;;UAMT,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;;;YAG9D,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;WACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;UACjE,CAAC,EAAE,CAAC,SAAS,MAAM,gBAAgB,CAAC,QAAQ,iBAAiB,CAAC,CAAC,CAAC;cAvEjD,CAAC,EAAE,CAAC,SAAS,MAAM,mBAChC,MAAM,OACT,CAAC,WACE,iBAAiB,CAAC,CAAC,CAAC;wBAsER,IAAI;;EAK3B;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
|
package/dist/api.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{CourierDisposedError as e,CourierHttpError as t,CourierSchemaValidationError as n,classifyRequestError as r}from"./errors.js";import{parseResponse as i}from"./response.js";import{buildRequestInit as a}from"./serialize.js";import{anySignal as o,buildTimeoutSignal as s,createTransportCore as c,validateTimeout as l}from"./transport.js";import{buildUrl as u}from"./url.js";function d(d){let{transport:f,...p}=d??{},m=f??c(p),h=!f;async function g(e,a,o,s,c,l){let u=a.signal,d;try{d=await m.dispatch({headers:e,init:a,url:o})}catch(e){throw r(e,s,o,u)}if(!d.ok){let e=d.headers.get(`content-type`)?.includes(`json`)??!1,n;if(typeof d.text==`function`){let t=await d.text().catch(()=>``);if(n=t,t&&e)try{n=JSON.parse(t)}catch{}}else n=await i(d,e?`json`:`auto`).catch(()=>``);throw t.fromResponse(d,n,s,o)}let f;try{f=await i(d,c??`auto`)}catch(e){throw r(e,s,o,u)}if(l)try{return l.parse(f)}catch(e){throw new n(e,f)}return f}async function _(t,n,i={}){if(m.disposed)throw new e(`Courier`);let c=t.toUpperCase(),d;try{d=u(m.baseUrl,n,i.params,i.query)}catch(e){throw r(e,c,n)}let{body:f,fetchInit:p,headers:h,responseType:_,schema:v,signal:y,timeout:b}=i;b!==void 0&&l(b);let x=new AbortController,S=m.track(x),C=s(b??m.getTimeout(),o(y,x.signal)),{headers:w,...T}=a(c,m.mergeHeaders(h),f,C,p??{});try{return await g(w,T,d,c,_,v)}finally{S()}}return{cancelAll:m.cancelAll,delete:(e,t)=>_(`DELETE`,e,t),get disposalSignal(){return m.disposalSignal},dispose(){h&&m.dispose()},get disposed(){return m.disposed},get:(e,t)=>_(`GET`,e,t),getHeaders:m.getHeaders,headers:m.headers,patch:(e,t)=>_(`PATCH`,e,t),post:(e,t)=>_(`POST`,e,t),put:(e,t)=>_(`PUT`,e,t),request:_,[Symbol.dispose](){this.dispose()},use:m.use}}export{d as createApi};
|
|
2
|
-
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":[],"sources":["../src/api.ts"],"sourcesContent":["import type { HttpRequestConfig, Params } from './url';\n\nimport { classifyRequestError, CourierDisposedError, CourierHttpError, CourierSchemaValidationError } from './errors';\nimport { parseResponse } from './response';\nimport { buildRequestInit } from './serialize';\nimport {\n anySignal,\n buildTimeoutSignal,\n createTransportCore,\n type TransportCore,\n type TransportOptions,\n validateTimeout,\n} from './transport';\nimport { buildUrl } from './url';\n\nexport type { FetchContext, Interceptor } from './transport';\n\n/**\n * Creates a typed REST client — `get`/`post`/`put`/`patch`/`delete`/`request`, all backed by a\n * shared interceptor pipeline, header management, and `AbortController` lifecycle.\n *\n * @example\n * ```ts\n * const api = createApi({ baseUrl: 'https://api.example.com', timeout: 10_000 });\n *\n * const user = await api.get<User>('/users/{id}', { params: { id: '1' } });\n * const created = await api.post<User>('/users', { body: { name: 'Ada' } });\n *\n * api.use(async (ctx, next) => next(ctx.withHeaders({ authorization: `Bearer ${token}` })));\n *\n * // later:\n * api.dispose();\n * ```\n */\nexport function createApi(opts?: TransportOptions & { transport?: TransportCore }) {\n const { transport: sharedTransport, ...transportOpts } = opts ?? {};\n const transport = sharedTransport ?? createTransportCore(transportOpts);\n const ownTransport = !sharedTransport;\n\n async function execute<T>(\n headers: Record<string, string>,\n init: Omit<RequestInit, 'headers'>,\n full: string,\n m: string,\n responseType: HttpRequestConfig['responseType'],\n schema?: { parse(data: unknown): T },\n ): Promise<T> {\n const signal = init.signal as AbortSignal | undefined;\n let res: Response;\n\n try {\n res = await transport.dispatch({ headers, init, url: full });\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (!res.ok) {\n // Error bodies are read once as text, then JSON-parsed if the content-type\n // says so — a binary success config (`responseType: 'blob'`) must not trap\n // the server's error message in an unreadable wrapper, and a failed\n // parseResponse-then-fallback double-read loses the body entirely.\n // `res.text` is missing on minimal custom-fetch fakes — fall back to\n // parseResponse there.\n const isJson = res.headers.get('content-type')?.includes('json') ?? false;\n let body: unknown;\n\n if (typeof res.text === 'function') {\n const text = await res.text().catch(() => '');\n\n body = text;\n\n if (text && isJson) {\n try {\n body = JSON.parse(text);\n } catch {\n // Malformed JSON error body — keep the raw text, not ''.\n }\n }\n } else {\n body = await parseResponse(res, isJson ? 'json' : 'auto').catch(() => '');\n }\n\n throw CourierHttpError.fromResponse(res, body, m, full);\n }\n\n let raw: unknown;\n\n try {\n raw = await parseResponse(res, responseType ?? 'auto');\n } catch (err) {\n throw classifyRequestError(err, m, full, signal);\n }\n\n if (schema) {\n try {\n return schema.parse(raw);\n } catch (err) {\n throw new CourierSchemaValidationError(err, raw);\n }\n }\n\n return raw as T;\n }\n\n async function request<T, P extends string = string>(\n method: string,\n url: P,\n config: HttpRequestConfig<P> = {} as HttpRequestConfig<P>,\n ) {\n if (transport.disposed) throw new CourierDisposedError('Courier');\n\n const m = method.toUpperCase();\n\n let full: string;\n\n try {\n full = buildUrl(transport.baseUrl, url, config.params as Params | undefined, config.query);\n } catch (err) {\n throw classifyRequestError(err, m, url);\n }\n\n const {\n body,\n fetchInit,\n headers,\n responseType,\n schema,\n signal: extSignal,\n timeout: cfgTimeout,\n } = config as HttpRequestConfig;\n\n if (cfgTimeout !== undefined) validateTimeout(cfgTimeout);\n\n const requestAc = new AbortController();\n const untrack = transport.track(requestAc);\n const signal = buildTimeoutSignal(cfgTimeout ?? transport.getTimeout(), anySignal(extSignal, requestAc.signal));\n const { headers: initHeaders, ...restInit } = buildRequestInit(\n m,\n transport.mergeHeaders(headers),\n body,\n signal,\n fetchInit ?? {},\n );\n\n try {\n return await execute<T>(\n initHeaders as Record<string, string>,\n restInit,\n full,\n m,\n responseType,\n schema as { parse(data: unknown): T } | undefined,\n );\n } finally {\n untrack();\n }\n }\n\n return {\n cancelAll: transport.cancelAll,\n delete: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('DELETE', url, cfg),\n get disposalSignal() {\n return transport.disposalSignal;\n },\n dispose(): void {\n if (ownTransport) transport.dispose();\n },\n get disposed() {\n return transport.disposed;\n },\n get: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('GET', url, cfg),\n getHeaders: transport.getHeaders,\n headers: transport.headers,\n patch: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PATCH', url, cfg),\n post: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('POST', url, cfg),\n put: <T, P extends string = string>(url: P, cfg?: HttpRequestConfig<P>) => request<T, P>('PUT', url, cfg),\n request,\n [Symbol.dispose](): void {\n this.dispose();\n },\n use: transport.use,\n };\n}\n\nexport type ApiClient = ReturnType<typeof createApi>;\n"],"mappings":"0XAkCA,SAAgB,EAAU,EAAyD,CACjF,GAAM,CAAE,UAAW,EAAiB,GAAG,GAAkB,GAAQ,CAAC,EAC5D,EAAY,GAAmB,EAAoB,CAAa,EAChE,EAAe,CAAC,EAEtB,eAAe,EACb,EACA,EACA,EACA,EACA,EACA,EACY,CACZ,IAAM,EAAS,EAAK,OAChB,EAEJ,GAAI,CACF,EAAM,MAAM,EAAU,SAAS,CAAE,UAAS,OAAM,IAAK,CAAK,CAAC,CAC7D,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,EAAM,CAAM,CACjD,CAEA,GAAI,CAAC,EAAI,GAAI,CAOX,IAAM,EAAS,EAAI,QAAQ,IAAI,cAAc,CAAC,EAAE,SAAS,MAAM,GAAK,GAChE,EAEJ,GAAI,OAAO,EAAI,MAAS,WAAY,CAClC,IAAM,EAAO,MAAM,EAAI,KAAK,CAAC,CAAC,UAAY,EAAE,EAI5C,GAFA,EAAO,EAEH,GAAQ,EACV,GAAI,CACF,EAAO,KAAK,MAAM,CAAI,CACxB,MAAQ,CAER,CAEJ,KACE,GAAO,MAAM,EAAc,EAAK,EAAS,OAAS,MAAM,CAAC,CAAC,UAAY,EAAE,EAG1E,MAAM,EAAiB,aAAa,EAAK,EAAM,EAAG,CAAI,CACxD,CAEA,IAAI,EAEJ,GAAI,CACF,EAAM,MAAM,EAAc,EAAK,GAAgB,MAAM,CACvD,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,EAAM,CAAM,CACjD,CAEA,GAAI,EACF,GAAI,CACF,OAAO,EAAO,MAAM,CAAG,CACzB,OAAS,EAAK,CACZ,MAAM,IAAI,EAA6B,EAAK,CAAG,CACjD,CAGF,OAAO,CACT,CAEA,eAAe,EACb,EACA,EACA,EAA+B,CAAC,EAChC,CACA,GAAI,EAAU,SAAU,MAAM,IAAI,EAAqB,SAAS,EAEhE,IAAM,EAAI,EAAO,YAAY,EAEzB,EAEJ,GAAI,CACF,EAAO,EAAS,EAAU,QAAS,EAAK,EAAO,OAA8B,EAAO,KAAK,CAC3F,OAAS,EAAK,CACZ,MAAM,EAAqB,EAAK,EAAG,CAAG,CACxC,CAEA,GAAM,CACJ,OACA,YACA,UACA,eACA,SACA,OAAQ,EACR,QAAS,GACP,EAEA,IAAe,IAAA,IAAW,EAAgB,CAAU,EAExD,IAAM,EAAY,IAAI,gBAChB,EAAU,EAAU,MAAM,CAAS,EACnC,EAAS,EAAmB,GAAc,EAAU,WAAW,EAAG,EAAU,EAAW,EAAU,MAAM,CAAC,EACxG,CAAE,QAAS,EAAa,GAAG,GAAa,EAC5C,EACA,EAAU,aAAa,CAAO,EAC9B,EACA,EACA,GAAa,CAAC,CAChB,EAEA,GAAI,CACF,OAAO,MAAM,EACX,EACA,EACA,EACA,EACA,EACA,CACF,CACF,QAAU,CACR,EAAQ,CACV,CACF,CAEA,MAAO,CACL,UAAW,EAAU,UACrB,QAAuC,EAAQ,IAA+B,EAAc,SAAU,EAAK,CAAG,EAC9G,IAAI,gBAAiB,CACnB,OAAO,EAAU,cACnB,EACA,SAAgB,CACV,GAAc,EAAU,QAAQ,CACtC,EACA,IAAI,UAAW,CACb,OAAO,EAAU,QACnB,EACA,KAAoC,EAAQ,IAA+B,EAAc,MAAO,EAAK,CAAG,EACxG,WAAY,EAAU,WACtB,QAAS,EAAU,QACnB,OAAsC,EAAQ,IAA+B,EAAc,QAAS,EAAK,CAAG,EAC5G,MAAqC,EAAQ,IAA+B,EAAc,OAAQ,EAAK,CAAG,EAC1G,KAAoC,EAAQ,IAA+B,EAAc,MAAO,EAAK,CAAG,EACxG,UACA,CAAC,OAAO,UAAiB,CACvB,KAAK,QAAQ,CACf,EACA,IAAK,EAAU,GACjB,CACF"}
|
package/dist/devtools.cjs
DELETED
package/dist/devtools.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.cjs","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["import type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"oIAKA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAA,cAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAA,YAAY,CAAC,EAEjB,CACT"}
|
package/dist/devtools.d.ts
DELETED
package/dist/devtools.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.d.ts","sourceRoot":"","sources":["../src/devtools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAKzD,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAM9D"}
|
package/dist/devtools.js
DELETED
package/dist/devtools.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.js","names":[],"sources":["../src/devtools.ts"],"sourcesContent":["import type { Courier, CourierOptions } from './courier';\n\nimport { createCourier } from './courier';\nimport { withLogging } from './interceptors';\n\nexport function debugCourier(options?: CourierOptions): Courier {\n const client = createCourier(options);\n\n client.use(withLogging());\n\n return client;\n}\n"],"mappings":"6FAKA,SAAgB,EAAa,EAAmC,CAC9D,IAAM,EAAS,EAAc,CAAO,EAIpC,OAFA,EAAO,IAAI,EAAY,CAAC,EAEjB,CACT"}
|