@conduit-client/service-fetch-network 3.20.5 → 3.21.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.
@@ -1,7 +1,32 @@
1
1
  import { type NamedService, type ServiceDescriptor } from '@conduit-client/utils';
2
2
  import type { RetryService } from '@conduit-client/service-retry/v1';
3
3
  export type FetchParameters = Parameters<typeof fetch>;
4
- export type FetchService = (...args: FetchParameters) => PromiseLike<Response>;
4
+ /**
5
+ * The first argument to `fetch` (a `RequestInfo | URL` in lib.dom). Pulled
6
+ * via index access so we don't depend on the DOM `RequestInfo` name being
7
+ * directly resolvable in every consuming tsconfig.
8
+ */
9
+ export type FetchInput = FetchParameters[0];
10
+ /**
11
+ * Optional per-call data passed by callers (typically `FetchNetworkCommand`
12
+ * subclasses) and merged into the per-request interceptor context inside
13
+ * `buildServiceDescriptor`. Carried on the `init` argument under the
14
+ * `__contextSeed` key (see `ExtendedRequestInit`) so that detection is a
15
+ * named-property lookup rather than positional arity sniffing — runtime
16
+ * type checks beat length checks for distinguishing a seed from a vanilla
17
+ * `RequestInit`. The seed is stripped from `init` before the underlying
18
+ * `fetch` call, so it never reaches the network.
19
+ */
20
+ export type FetchContextSeed = Record<string, unknown>;
21
+ /**
22
+ * `RequestInit` plus an optional `__contextSeed` slot. Every existing
23
+ * `RequestInit` value is assignable to this type, so today's callers
24
+ * continue to compile and behave identically.
25
+ */
26
+ export type ExtendedRequestInit = RequestInit & {
27
+ __contextSeed?: FetchContextSeed;
28
+ };
29
+ export type FetchService = (input: FetchInput, init?: ExtendedRequestInit) => PromiseLike<Response>;
5
30
  export type IFetchService = FetchService;
6
31
  export type FetchServiceDescriptor = ServiceDescriptor<IFetchService, 'fetch', '1.0'>;
7
32
  export type NamedFetchService<Name extends string = 'fetch'> = NamedService<Name, IFetchService>;
package/dist/v1/index.js CHANGED
@@ -8,8 +8,17 @@ function buildServiceDescriptor(interceptors = {
8
8
  return {
9
9
  type: "fetch",
10
10
  version: "1.0",
11
- service: function(...args) {
12
- const context = interceptors.createContext?.();
11
+ service: function(input, init) {
12
+ let contextSeed;
13
+ let cleanInit = init;
14
+ if (init !== void 0 && "__contextSeed" in init) {
15
+ const { __contextSeed, ...initWithoutSeed } = init;
16
+ contextSeed = __contextSeed;
17
+ cleanInit = Object.keys(initWithoutSeed).length === 0 ? void 0 : initWithoutSeed;
18
+ }
19
+ const fetchArgs = cleanInit === void 0 ? [input] : [input, cleanInit];
20
+ const baseContext = interceptors.createContext?.();
21
+ const context = contextSeed === void 0 ? baseContext : { ...baseContext, ...contextSeed };
13
22
  const {
14
23
  request: requestInterceptors = [],
15
24
  retry: retryInterceptor = void 0,
@@ -17,17 +26,17 @@ function buildServiceDescriptor(interceptors = {
17
26
  finally: finallyInterceptors = []
18
27
  } = interceptors;
19
28
  const pending = requestInterceptors.reduce(
20
- (previousPromise, interceptor) => previousPromise.then((args2) => interceptor(args2, context)),
21
- resolvedPromiseLike(args)
29
+ (previousPromise, interceptor) => previousPromise.then((args) => interceptor(args, context)),
30
+ resolvedPromiseLike(fetchArgs)
22
31
  );
23
- return Promise.resolve(pending).then((args2) => {
32
+ return Promise.resolve(pending).then((args) => {
24
33
  if (retryInterceptor) {
25
- return retryInterceptor(args2, retryService, context);
34
+ return retryInterceptor(args, retryService, context);
26
35
  } else {
27
36
  if (retryService) {
28
- return retryService.applyRetry(() => fetch(...args2));
37
+ return retryService.applyRetry(() => fetch(...args));
29
38
  }
30
- return fetch(...args2);
39
+ return fetch(...args);
31
40
  }
32
41
  }).then((response) => {
33
42
  return responseInterceptors.reduce(
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/v1/fetch.ts","../../src/v1/compression-interceptor.ts","../../src/v1/utils.ts","../../src/v1/jwt-interceptor.ts","../../src/v1/mock-fetch.ts"],"sourcesContent":["import {\n resolvedPromiseLike,\n type NamedService,\n type ServiceDescriptor,\n} from '@conduit-client/utils';\nimport type { RetryService } from '@conduit-client/service-retry/v1';\n\nexport type FetchParameters = Parameters<typeof fetch>;\nexport type FetchService = (...args: FetchParameters) => PromiseLike<Response>;\nexport type IFetchService = FetchService;\nexport type FetchServiceDescriptor = ServiceDescriptor<IFetchService, 'fetch', '1.0'>;\nexport type NamedFetchService<Name extends string = 'fetch'> = NamedService<Name, IFetchService>;\nexport type RequestInterceptor<Context = any> = (\n fetchArgs: FetchParameters,\n context?: Context\n) => PromiseLike<FetchParameters>;\nexport type RetryInterceptor<Context = any> = (\n fetchArgs: FetchParameters,\n retryService?: RetryService<Response>,\n context?: Context\n) => PromiseLike<Response>;\nexport type ResponseInterceptor<Context = any> = (\n response: Response,\n context?: Context\n) => PromiseLike<Response>;\nexport type FinallyInterceptor<Context = any> = (context?: Context) => PromiseLike<void> | void;\nexport type Interceptors<Context = any> = {\n createContext?: () => Context;\n request?: RequestInterceptor<Context>[];\n retry?: RetryInterceptor<Context>;\n response?: ResponseInterceptor<Context>[];\n finally?: FinallyInterceptor<Context>[];\n};\nexport function buildServiceDescriptor<Context = any>(\n interceptors: Interceptors<Context> = {\n request: [],\n retry: undefined,\n response: [],\n finally: [],\n },\n retryService?: RetryService<Response>\n): FetchServiceDescriptor {\n return {\n type: 'fetch',\n version: '1.0',\n service: function (...args: FetchParameters) {\n // Create context per request if factory is provided\n const context = interceptors.createContext?.();\n\n const {\n request: requestInterceptors = [],\n retry: retryInterceptor = undefined,\n response: responseInterceptors = [],\n finally: finallyInterceptors = [],\n } = interceptors;\n\n const pending = requestInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then((args) => interceptor(args, context)),\n resolvedPromiseLike(args)\n );\n\n return Promise.resolve(pending)\n .then((args) => {\n if (retryInterceptor) {\n return retryInterceptor(args, retryService, context);\n } else {\n // default retry logic\n if (retryService) {\n return retryService.applyRetry(() => fetch(...args));\n }\n return fetch(...args);\n }\n })\n .then((response) => {\n // Success path - run response interceptors\n return responseInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then((response) => interceptor(response, context)),\n resolvedPromiseLike(response)\n );\n })\n .finally(() => {\n // Always run finally interceptors for cleanup\n if (finallyInterceptors.length > 0) {\n // Run all finally interceptors sequentially\n return finallyInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then(() => interceptor(context)),\n Promise.resolve()\n );\n }\n });\n },\n };\n}\n","import { resolvedPromiseLike } from '@conduit-client/utils';\nimport type { FetchParameters, RequestInterceptor } from './fetch';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Lazily initializes and returns the TextEncoder instance.\n * This ensures the module can be imported even in environments without TextEncoder,\n * and only fails when compression is actually attempted.\n */\nfunction getTextEncoder(): TextEncoder {\n if (!textEncoder) {\n if (typeof TextEncoder === 'undefined') {\n throw new Error(\n 'TextEncoder is not available in this environment. ' +\n 'Request body compression requires TextEncoder support.'\n );\n }\n textEncoder = new TextEncoder();\n }\n return textEncoder;\n}\n\n/**\n * Configuration for the compression interceptor.\n */\nexport interface CompressionInterceptorConfig {\n /**\n * Compression algorithm. Currently only 'gzip' is supported.\n */\n algorithm: 'gzip';\n\n /**\n * Minimum body size in bytes to trigger compression.\n * Bodies smaller than this threshold are sent uncompressed.\n * @default 1024\n */\n threshold?: number;\n}\n\n/**\n * Builds a request interceptor that compresses string request bodies.\n *\n * The interceptor only compresses when all conditions are met:\n * - The request has a body\n * - The body is a string\n * - The body size exceeds the configured threshold\n * - The runtime supports CompressionStream\n * - Content-Encoding is not already set\n *\n * If compression fails for any reason, the request is sent uncompressed.\n *\n * IMPORTANT: This interceptor should run LAST in the request interceptor chain,\n * after any other interceptors that might modify the request body.\n *\n * @param config - Compression configuration\n * @returns A request interceptor that compresses eligible request bodies\n */\nexport function buildCompressionInterceptor(\n config: CompressionInterceptorConfig\n): RequestInterceptor {\n const threshold = config.threshold ?? 1024;\n\n return async (args: FetchParameters) => {\n const [resource, options = {}] = args;\n\n // Only compress string bodies\n if (!options.body || typeof options.body !== 'string') {\n return resolvedPromiseLike(args);\n }\n\n // Check if CompressionStream is available in this runtime\n if (typeof CompressionStream === 'undefined') {\n return resolvedPromiseLike(args);\n }\n\n // Normalize headers once — reuse for check and mutation\n const headers = new Headers(options.headers);\n\n // Skip if Content-Encoding is already set (don't double-encode)\n if (headers.has('Content-Encoding')) {\n return resolvedPromiseLike(args);\n }\n\n // Encode the body once and check threshold\n const encodedBody = getTextEncoder().encode(options.body);\n if (encodedBody.byteLength < threshold) {\n return resolvedPromiseLike(args);\n }\n\n try {\n // Compress the body using CompressionStream (reuse encoded bytes)\n const stream = new Blob([encodedBody])\n .stream()\n .pipeThrough(new CompressionStream(config.algorithm));\n\n const compressedBody = await new Response(stream).blob();\n\n // Set Content-Encoding and remove Content-Length (now invalid after compression)\n headers.set('Content-Encoding', config.algorithm);\n headers.delete('Content-Length');\n\n const compressedOptions: RequestInit = {\n ...options,\n body: compressedBody,\n headers,\n };\n\n return resolvedPromiseLike<FetchParameters>([resource, compressedOptions]);\n } catch {\n // If compression fails for any reason, fall back to uncompressed\n // This ensures requests are never broken by compression failures\n return resolvedPromiseLike(args);\n }\n };\n}\n","import type { FetchParameters } from './fetch';\n\n/**\n * Generic utility function to set any header value in fetch parameters\n * @param headerName - The name of the header to set\n * @param headerValue - The value to set for the header\n * @param fetchParams - The fetch parameters [resource, options]\n * @param options - Additional options\n * @param options.throwOnExisting - If true, throws an error when the header already exists\n * @param options.errorMessage - Custom error message to use when header exists\n * @returns Modified fetch parameters with the header set\n */\nexport function setHeader<T extends string = string>(\n headerName: T,\n headerValue: string,\n [resource, options = {}]: FetchParameters,\n {\n throwOnExisting = false,\n errorMessage = `Unexpected ${headerName} header encountered`,\n }: {\n throwOnExisting?: boolean;\n errorMessage?: string;\n } = {}\n): FetchParameters {\n let hasHeaderBeenSet = false;\n\n // Handle Request instance with Headers\n if (resource instanceof Request && !options?.headers) {\n if (throwOnExisting && resource.headers.has(headerName)) {\n throw new Error(errorMessage);\n }\n resource.headers.set(headerName, headerValue);\n hasHeaderBeenSet = true;\n }\n\n // Handle options with Headers instance\n if (options?.headers instanceof Headers) {\n if (throwOnExisting && options.headers.has(headerName)) {\n throw new Error(errorMessage);\n }\n options.headers.set(headerName, headerValue);\n } else {\n // Handle options with plain object headers\n if (\n throwOnExisting &&\n options?.headers &&\n Reflect.has(options.headers as any, headerName)\n ) {\n throw new Error(errorMessage);\n }\n // Add the header if it hasn't been set on Request\n if (!hasHeaderBeenSet) {\n options.headers = {\n ...options?.headers,\n [headerName]: headerValue,\n };\n }\n }\n\n return [resource, options];\n}\n","import { resolvedPromiseLike } from '@conduit-client/utils';\nimport { setHeader } from './utils';\nimport type { JwtManager, JwtToken } from '@conduit-client/jwt-manager';\nimport type { FetchParameters } from './fetch';\n\nconst UNEXPECTED_AUTHORIZATION_HEADER_MESSAGE =\n 'Unexpected Authorization header encountered. To specify a custom Authorization header, use a Fetch service that is not configured with JwtRequestHeaderInterceptor';\n\n/**\n * Sets the Authorization header with a JWT token using the generic setHeader utility\n * @param token - The JWT token to set in the Authorization header\n * @param fetchParams - The fetch parameters [resource, options]\n * @returns Modified fetch parameters with the Authorization header set\n */\nexport function setHeaderAuthorization<T, E>(\n { token }: JwtToken<T, E>,\n fetchParams: FetchParameters\n): FetchParameters {\n const authorizationValue = `Bearer ${token}`;\n\n return setHeader('Authorization', authorizationValue, fetchParams, {\n throwOnExisting: true,\n errorMessage: UNEXPECTED_AUTHORIZATION_HEADER_MESSAGE,\n });\n}\n\nexport type JwtRequestModifier = (extraInfo: any, fetchArgs: FetchParameters) => FetchParameters;\n\nexport function buildJwtRequestHeaderInterceptor<ExtraInfo>(\n jwtManager: JwtManager<unknown, ExtraInfo>,\n jwtRequestModifier: JwtRequestModifier = (_e, fetchArgs) => fetchArgs\n) {\n return (args: FetchParameters) => {\n return resolvedPromiseLike(jwtManager.getJwt()).then((token) => {\n const fetchArgsWithRequestHeaderAuthorization = setHeaderAuthorization(token, args);\n return token.extraInfo\n ? jwtRequestModifier(token.extraInfo, fetchArgsWithRequestHeaderAuthorization)\n : fetchArgsWithRequestHeaderAuthorization;\n });\n };\n}\n","import { type FetchService } from './fetch';\nimport type { ServiceDescriptor } from '@conduit-client/utils';\n\n// AbortError class that matches the standard AbortError\nclass AbortError extends Error {\n name = 'AbortError';\n constructor(message = 'This operation was aborted') {\n super(message);\n }\n}\n\nexport type MockResponse = {\n status?: number;\n statusText?: string;\n ok?: boolean;\n body?: any;\n delay?: number; // Delay in milliseconds to simulate network latency\n};\n\nexport type MockFetchService = {\n readonly requests: Array<Parameters<FetchService>>;\n readonly availableResponses: number;\n queueResponses: (...newResponses: Array<any>) => void;\n reset: () => void;\n readonly responsesUsed: number;\n} & ((...args: any[]) => Promise<any>);\n\nexport function buildMockFetchService(\n initialResponses: Array<any> = []\n): ServiceDescriptor<MockFetchService, 'fetch', '1.0'> {\n let responses: Array<any> = [...initialResponses];\n\n const networkAdapter = (...args: any[]) => {\n // Capture the full fetch parameters for more realistic testing\n const [_, fetchOptions = {}] = args;\n\n networkAdapter.requests.push(args);\n\n // Immediate abort detection - check if signal is already aborted\n if (fetchOptions.signal?.aborted) {\n return Promise.reject(new AbortError());\n }\n\n const result = responses.shift();\n if (result === undefined) {\n throw new Error('No more mock responses queued');\n }\n networkAdapter.availableResponses = responses.length;\n networkAdapter.responsesUsed++;\n\n if (result instanceof Error) {\n return Promise.reject(result);\n }\n\n // Simulate request delay if specified\n const delay = (result as MockResponse).delay || 0;\n\n // Create a promise that handles both delay simulation and runtime abort\n return new Promise((resolve, reject) => {\n let abortHandler: (() => void) | null = null;\n\n // Set up abort listener for runtime abort detection\n if (fetchOptions.signal) {\n abortHandler = () => {\n reject(new AbortError());\n };\n fetchOptions.signal.addEventListener('abort', abortHandler);\n }\n\n const completeRequest = () => {\n // Clean up abort listener\n if (abortHandler && fetchOptions.signal) {\n fetchOptions.signal.removeEventListener('abort', abortHandler);\n }\n\n // Check one more time if aborted during delay\n if (fetchOptions.signal?.aborted) {\n reject(new AbortError());\n return;\n }\n\n // Return successful response\n resolve({\n ok: result.ok !== undefined ? result.ok : true,\n statusText: result.statusText !== undefined ? result.statusText : 'ok',\n status: result.status !== undefined ? result.status : 200,\n json: () => Promise.resolve(result.body),\n } as Response);\n };\n\n if (delay > 0) {\n setTimeout(completeRequest, delay);\n } else {\n // Always use async behavior to maintain existing test expectations\n // Even without delay, tests expect async behavior for wire adapters\n setTimeout(completeRequest, 0);\n }\n });\n };\n\n networkAdapter.requests = [] as Array<any>;\n networkAdapter.availableResponses = responses.length;\n\n networkAdapter.queueResponses = (newResponses: Array<any>) => {\n responses = responses.concat(newResponses);\n networkAdapter.availableResponses = responses.length;\n };\n\n networkAdapter.fetch = (args: any) => networkAdapter(args);\n\n networkAdapter.reset = () => {\n networkAdapter.requests = [];\n responses = [];\n networkAdapter.availableResponses = 0;\n networkAdapter.responsesUsed = 0;\n };\n\n networkAdapter.responsesUsed = 0;\n return {\n type: 'fetch',\n version: '1.0',\n service: networkAdapter as MockFetchService,\n };\n}\n"],"names":["args","response"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/v1/fetch.ts","../../src/v1/compression-interceptor.ts","../../src/v1/utils.ts","../../src/v1/jwt-interceptor.ts","../../src/v1/mock-fetch.ts"],"sourcesContent":["import {\n resolvedPromiseLike,\n type NamedService,\n type ServiceDescriptor,\n} from '@conduit-client/utils';\nimport type { RetryService } from '@conduit-client/service-retry/v1';\n\nexport type FetchParameters = Parameters<typeof fetch>;\n/**\n * The first argument to `fetch` (a `RequestInfo | URL` in lib.dom). Pulled\n * via index access so we don't depend on the DOM `RequestInfo` name being\n * directly resolvable in every consuming tsconfig.\n */\nexport type FetchInput = FetchParameters[0];\n/**\n * Optional per-call data passed by callers (typically `FetchNetworkCommand`\n * subclasses) and merged into the per-request interceptor context inside\n * `buildServiceDescriptor`. Carried on the `init` argument under the\n * `__contextSeed` key (see `ExtendedRequestInit`) so that detection is a\n * named-property lookup rather than positional arity sniffing — runtime\n * type checks beat length checks for distinguishing a seed from a vanilla\n * `RequestInit`. The seed is stripped from `init` before the underlying\n * `fetch` call, so it never reaches the network.\n */\nexport type FetchContextSeed = Record<string, unknown>;\n/**\n * `RequestInit` plus an optional `__contextSeed` slot. Every existing\n * `RequestInit` value is assignable to this type, so today's callers\n * continue to compile and behave identically.\n */\nexport type ExtendedRequestInit = RequestInit & { __contextSeed?: FetchContextSeed };\nexport type FetchService = (input: FetchInput, init?: ExtendedRequestInit) => PromiseLike<Response>;\nexport type IFetchService = FetchService;\nexport type FetchServiceDescriptor = ServiceDescriptor<IFetchService, 'fetch', '1.0'>;\nexport type NamedFetchService<Name extends string = 'fetch'> = NamedService<Name, IFetchService>;\nexport type RequestInterceptor<Context = any> = (\n fetchArgs: FetchParameters,\n context?: Context\n) => PromiseLike<FetchParameters>;\nexport type RetryInterceptor<Context = any> = (\n fetchArgs: FetchParameters,\n retryService?: RetryService<Response>,\n context?: Context\n) => PromiseLike<Response>;\nexport type ResponseInterceptor<Context = any> = (\n response: Response,\n context?: Context\n) => PromiseLike<Response>;\nexport type FinallyInterceptor<Context = any> = (context?: Context) => PromiseLike<void> | void;\nexport type Interceptors<Context = any> = {\n createContext?: () => Context;\n request?: RequestInterceptor<Context>[];\n retry?: RetryInterceptor<Context>;\n response?: ResponseInterceptor<Context>[];\n finally?: FinallyInterceptor<Context>[];\n};\nexport function buildServiceDescriptor<Context = any>(\n interceptors: Interceptors<Context> = {\n request: [],\n retry: undefined,\n response: [],\n finally: [],\n },\n retryService?: RetryService<Response>\n): FetchServiceDescriptor {\n return {\n type: 'fetch',\n version: '1.0',\n service: function (input: FetchInput, init?: ExtendedRequestInit) {\n // Detect the optional context seed via a named property on init.\n // Strip it before forwarding so the underlying fetch call shape\n // matches today's exactly (no extra arg, no extra init key on\n // the wire).\n let contextSeed: FetchContextSeed | undefined;\n let cleanInit: RequestInit | undefined = init;\n if (init !== undefined && '__contextSeed' in init) {\n const { __contextSeed, ...initWithoutSeed } = init;\n contextSeed = __contextSeed;\n // Preserve today's call shape: if init only carried the seed,\n // pass `undefined` rather than `{}` so single-arg fetch calls\n // remain single-arg.\n cleanInit = Object.keys(initWithoutSeed).length === 0 ? undefined : initWithoutSeed;\n }\n const fetchArgs: FetchParameters =\n cleanInit === undefined ? [input] : [input, cleanInit];\n\n // Create context per request if factory is provided, then layer\n // the per-call seed on top so seeded keys win over factory defaults.\n const baseContext = interceptors.createContext?.();\n const context =\n contextSeed === undefined\n ? baseContext\n : ({ ...(baseContext as object), ...contextSeed } as Context);\n\n const {\n request: requestInterceptors = [],\n retry: retryInterceptor = undefined,\n response: responseInterceptors = [],\n finally: finallyInterceptors = [],\n } = interceptors;\n\n const pending = requestInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then((args) => interceptor(args, context)),\n resolvedPromiseLike(fetchArgs)\n );\n\n return Promise.resolve(pending)\n .then((args) => {\n if (retryInterceptor) {\n return retryInterceptor(args, retryService, context);\n } else {\n // default retry logic\n if (retryService) {\n return retryService.applyRetry(() => fetch(...args));\n }\n return fetch(...args);\n }\n })\n .then((response) => {\n // Success path - run response interceptors\n return responseInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then((response) => interceptor(response, context)),\n resolvedPromiseLike(response)\n );\n })\n .finally(() => {\n // Always run finally interceptors for cleanup\n if (finallyInterceptors.length > 0) {\n // Run all finally interceptors sequentially\n return finallyInterceptors.reduce(\n (previousPromise, interceptor) =>\n previousPromise.then(() => interceptor(context)),\n Promise.resolve()\n );\n }\n });\n },\n };\n}\n","import { resolvedPromiseLike } from '@conduit-client/utils';\nimport type { FetchParameters, RequestInterceptor } from './fetch';\n\nlet textEncoder: TextEncoder | undefined;\n\n/**\n * Lazily initializes and returns the TextEncoder instance.\n * This ensures the module can be imported even in environments without TextEncoder,\n * and only fails when compression is actually attempted.\n */\nfunction getTextEncoder(): TextEncoder {\n if (!textEncoder) {\n if (typeof TextEncoder === 'undefined') {\n throw new Error(\n 'TextEncoder is not available in this environment. ' +\n 'Request body compression requires TextEncoder support.'\n );\n }\n textEncoder = new TextEncoder();\n }\n return textEncoder;\n}\n\n/**\n * Configuration for the compression interceptor.\n */\nexport interface CompressionInterceptorConfig {\n /**\n * Compression algorithm. Currently only 'gzip' is supported.\n */\n algorithm: 'gzip';\n\n /**\n * Minimum body size in bytes to trigger compression.\n * Bodies smaller than this threshold are sent uncompressed.\n * @default 1024\n */\n threshold?: number;\n}\n\n/**\n * Builds a request interceptor that compresses string request bodies.\n *\n * The interceptor only compresses when all conditions are met:\n * - The request has a body\n * - The body is a string\n * - The body size exceeds the configured threshold\n * - The runtime supports CompressionStream\n * - Content-Encoding is not already set\n *\n * If compression fails for any reason, the request is sent uncompressed.\n *\n * IMPORTANT: This interceptor should run LAST in the request interceptor chain,\n * after any other interceptors that might modify the request body.\n *\n * @param config - Compression configuration\n * @returns A request interceptor that compresses eligible request bodies\n */\nexport function buildCompressionInterceptor(\n config: CompressionInterceptorConfig\n): RequestInterceptor {\n const threshold = config.threshold ?? 1024;\n\n return async (args: FetchParameters) => {\n const [resource, options = {}] = args;\n\n // Only compress string bodies\n if (!options.body || typeof options.body !== 'string') {\n return resolvedPromiseLike(args);\n }\n\n // Check if CompressionStream is available in this runtime\n if (typeof CompressionStream === 'undefined') {\n return resolvedPromiseLike(args);\n }\n\n // Normalize headers once — reuse for check and mutation\n const headers = new Headers(options.headers);\n\n // Skip if Content-Encoding is already set (don't double-encode)\n if (headers.has('Content-Encoding')) {\n return resolvedPromiseLike(args);\n }\n\n // Encode the body once and check threshold\n const encodedBody = getTextEncoder().encode(options.body);\n if (encodedBody.byteLength < threshold) {\n return resolvedPromiseLike(args);\n }\n\n try {\n // Compress the body using CompressionStream (reuse encoded bytes)\n const stream = new Blob([encodedBody])\n .stream()\n .pipeThrough(new CompressionStream(config.algorithm));\n\n const compressedBody = await new Response(stream).blob();\n\n // Set Content-Encoding and remove Content-Length (now invalid after compression)\n headers.set('Content-Encoding', config.algorithm);\n headers.delete('Content-Length');\n\n const compressedOptions: RequestInit = {\n ...options,\n body: compressedBody,\n headers,\n };\n\n return resolvedPromiseLike<FetchParameters>([resource, compressedOptions]);\n } catch {\n // If compression fails for any reason, fall back to uncompressed\n // This ensures requests are never broken by compression failures\n return resolvedPromiseLike(args);\n }\n };\n}\n","import type { FetchParameters } from './fetch';\n\n/**\n * Generic utility function to set any header value in fetch parameters\n * @param headerName - The name of the header to set\n * @param headerValue - The value to set for the header\n * @param fetchParams - The fetch parameters [resource, options]\n * @param options - Additional options\n * @param options.throwOnExisting - If true, throws an error when the header already exists\n * @param options.errorMessage - Custom error message to use when header exists\n * @returns Modified fetch parameters with the header set\n */\nexport function setHeader<T extends string = string>(\n headerName: T,\n headerValue: string,\n [resource, options = {}]: FetchParameters,\n {\n throwOnExisting = false,\n errorMessage = `Unexpected ${headerName} header encountered`,\n }: {\n throwOnExisting?: boolean;\n errorMessage?: string;\n } = {}\n): FetchParameters {\n let hasHeaderBeenSet = false;\n\n // Handle Request instance with Headers\n if (resource instanceof Request && !options?.headers) {\n if (throwOnExisting && resource.headers.has(headerName)) {\n throw new Error(errorMessage);\n }\n resource.headers.set(headerName, headerValue);\n hasHeaderBeenSet = true;\n }\n\n // Handle options with Headers instance\n if (options?.headers instanceof Headers) {\n if (throwOnExisting && options.headers.has(headerName)) {\n throw new Error(errorMessage);\n }\n options.headers.set(headerName, headerValue);\n } else {\n // Handle options with plain object headers\n if (\n throwOnExisting &&\n options?.headers &&\n Reflect.has(options.headers as any, headerName)\n ) {\n throw new Error(errorMessage);\n }\n // Add the header if it hasn't been set on Request\n if (!hasHeaderBeenSet) {\n options.headers = {\n ...options?.headers,\n [headerName]: headerValue,\n };\n }\n }\n\n return [resource, options];\n}\n","import { resolvedPromiseLike } from '@conduit-client/utils';\nimport { setHeader } from './utils';\nimport type { JwtManager, JwtToken } from '@conduit-client/jwt-manager';\nimport type { FetchParameters } from './fetch';\n\nconst UNEXPECTED_AUTHORIZATION_HEADER_MESSAGE =\n 'Unexpected Authorization header encountered. To specify a custom Authorization header, use a Fetch service that is not configured with JwtRequestHeaderInterceptor';\n\n/**\n * Sets the Authorization header with a JWT token using the generic setHeader utility\n * @param token - The JWT token to set in the Authorization header\n * @param fetchParams - The fetch parameters [resource, options]\n * @returns Modified fetch parameters with the Authorization header set\n */\nexport function setHeaderAuthorization<T, E>(\n { token }: JwtToken<T, E>,\n fetchParams: FetchParameters\n): FetchParameters {\n const authorizationValue = `Bearer ${token}`;\n\n return setHeader('Authorization', authorizationValue, fetchParams, {\n throwOnExisting: true,\n errorMessage: UNEXPECTED_AUTHORIZATION_HEADER_MESSAGE,\n });\n}\n\nexport type JwtRequestModifier = (extraInfo: any, fetchArgs: FetchParameters) => FetchParameters;\n\nexport function buildJwtRequestHeaderInterceptor<ExtraInfo>(\n jwtManager: JwtManager<unknown, ExtraInfo>,\n jwtRequestModifier: JwtRequestModifier = (_e, fetchArgs) => fetchArgs\n) {\n return (args: FetchParameters) => {\n return resolvedPromiseLike(jwtManager.getJwt()).then((token) => {\n const fetchArgsWithRequestHeaderAuthorization = setHeaderAuthorization(token, args);\n return token.extraInfo\n ? jwtRequestModifier(token.extraInfo, fetchArgsWithRequestHeaderAuthorization)\n : fetchArgsWithRequestHeaderAuthorization;\n });\n };\n}\n","import { type FetchService } from './fetch';\nimport type { ServiceDescriptor } from '@conduit-client/utils';\n\n// AbortError class that matches the standard AbortError\nclass AbortError extends Error {\n name = 'AbortError';\n constructor(message = 'This operation was aborted') {\n super(message);\n }\n}\n\nexport type MockResponse = {\n status?: number;\n statusText?: string;\n ok?: boolean;\n body?: any;\n delay?: number; // Delay in milliseconds to simulate network latency\n};\n\nexport type MockFetchService = {\n readonly requests: Array<Parameters<FetchService>>;\n readonly availableResponses: number;\n queueResponses: (...newResponses: Array<any>) => void;\n reset: () => void;\n readonly responsesUsed: number;\n} & ((...args: any[]) => Promise<any>);\n\nexport function buildMockFetchService(\n initialResponses: Array<any> = []\n): ServiceDescriptor<MockFetchService, 'fetch', '1.0'> {\n let responses: Array<any> = [...initialResponses];\n\n const networkAdapter = (...args: any[]) => {\n // Capture the full fetch parameters for more realistic testing\n const [_, fetchOptions = {}] = args;\n\n networkAdapter.requests.push(args);\n\n // Immediate abort detection - check if signal is already aborted\n if (fetchOptions.signal?.aborted) {\n return Promise.reject(new AbortError());\n }\n\n const result = responses.shift();\n if (result === undefined) {\n throw new Error('No more mock responses queued');\n }\n networkAdapter.availableResponses = responses.length;\n networkAdapter.responsesUsed++;\n\n if (result instanceof Error) {\n return Promise.reject(result);\n }\n\n // Simulate request delay if specified\n const delay = (result as MockResponse).delay || 0;\n\n // Create a promise that handles both delay simulation and runtime abort\n return new Promise((resolve, reject) => {\n let abortHandler: (() => void) | null = null;\n\n // Set up abort listener for runtime abort detection\n if (fetchOptions.signal) {\n abortHandler = () => {\n reject(new AbortError());\n };\n fetchOptions.signal.addEventListener('abort', abortHandler);\n }\n\n const completeRequest = () => {\n // Clean up abort listener\n if (abortHandler && fetchOptions.signal) {\n fetchOptions.signal.removeEventListener('abort', abortHandler);\n }\n\n // Check one more time if aborted during delay\n if (fetchOptions.signal?.aborted) {\n reject(new AbortError());\n return;\n }\n\n // Return successful response\n resolve({\n ok: result.ok !== undefined ? result.ok : true,\n statusText: result.statusText !== undefined ? result.statusText : 'ok',\n status: result.status !== undefined ? result.status : 200,\n json: () => Promise.resolve(result.body),\n } as Response);\n };\n\n if (delay > 0) {\n setTimeout(completeRequest, delay);\n } else {\n // Always use async behavior to maintain existing test expectations\n // Even without delay, tests expect async behavior for wire adapters\n setTimeout(completeRequest, 0);\n }\n });\n };\n\n networkAdapter.requests = [] as Array<any>;\n networkAdapter.availableResponses = responses.length;\n\n networkAdapter.queueResponses = (newResponses: Array<any>) => {\n responses = responses.concat(newResponses);\n networkAdapter.availableResponses = responses.length;\n };\n\n networkAdapter.fetch = (args: any) => networkAdapter(args);\n\n networkAdapter.reset = () => {\n networkAdapter.requests = [];\n responses = [];\n networkAdapter.availableResponses = 0;\n networkAdapter.responsesUsed = 0;\n };\n\n networkAdapter.responsesUsed = 0;\n return {\n type: 'fetch',\n version: '1.0',\n service: networkAdapter as MockFetchService,\n };\n}\n"],"names":["response"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@conduit-client/service-fetch-network",
3
- "version": "3.20.5",
3
+ "version": "3.21.0",
4
4
  "private": false,
5
5
  "description": "Luvio Network Service definition",
6
6
  "type": "module",
@@ -31,9 +31,9 @@
31
31
  "watch": "npm run build --watch"
32
32
  },
33
33
  "dependencies": {
34
- "@conduit-client/jwt-manager": "3.20.5",
35
- "@conduit-client/service-retry": "3.20.5",
36
- "@conduit-client/utils": "3.20.5"
34
+ "@conduit-client/jwt-manager": "3.21.0",
35
+ "@conduit-client/service-retry": "3.21.0",
36
+ "@conduit-client/utils": "3.21.0"
37
37
  },
38
38
  "volta": {
39
39
  "extends": "../../../../package.json"