@api-wrappers/api-core 1.0.0 → 1.0.2
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/CHANGELOG.md +17 -0
- package/LICENSE +21 -0
- package/README.md +23 -9
- package/dist/index.cjs +90 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -49
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +59 -49
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +86 -24
- package/dist/index.mjs.map +1 -1
- package/docs/guides/error-handling.md +10 -10
- package/docs/guides/rest-requests.md +4 -0
- package/docs/reference/configuration.md +15 -4
- package/docs/reference/exports.md +8 -0
- package/package.json +22 -6
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
//#region src/types/common.d.ts
|
|
2
2
|
type MaybePromise<T> = T | Promise<T>;
|
|
3
|
+
type HeaderInput = HeadersInit;
|
|
3
4
|
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
4
5
|
type QueryPrimitive = string | number | boolean;
|
|
5
6
|
type QueryValue = QueryPrimitive | null | undefined | readonly (QueryPrimitive | null | undefined)[];
|
|
@@ -90,7 +91,7 @@ interface GraphQLRequestOptions<TVariables extends object = Record<string, unkno
|
|
|
90
91
|
* Additional headers merged on top of `ClientConfig.defaultHeaders` for
|
|
91
92
|
* this request only. `content-type: application/json` is always set.
|
|
92
93
|
*/
|
|
93
|
-
headers?:
|
|
94
|
+
headers?: HeaderInput;
|
|
94
95
|
/**
|
|
95
96
|
* Optional caller-provided abort signal. Composes with `timeoutMs`.
|
|
96
97
|
*/
|
|
@@ -175,6 +176,7 @@ interface ApiPlugin {
|
|
|
175
176
|
}
|
|
176
177
|
//#endregion
|
|
177
178
|
//#region src/transport/types.d.ts
|
|
179
|
+
type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
178
180
|
interface Transport {
|
|
179
181
|
execute(ctx: RequestContext): Promise<Response>;
|
|
180
182
|
}
|
|
@@ -226,7 +228,7 @@ interface ClientConfig {
|
|
|
226
228
|
* precedence. `content-type: application/json` is always present as the
|
|
227
229
|
* lowest-priority default.
|
|
228
230
|
*/
|
|
229
|
-
defaultHeaders?:
|
|
231
|
+
defaultHeaders?: HeaderInput;
|
|
230
232
|
/** Plugins registered for the lifetime of this client. */
|
|
231
233
|
plugins?: ApiPlugin[];
|
|
232
234
|
/**
|
|
@@ -241,7 +243,7 @@ interface ClientConfig {
|
|
|
241
243
|
* Ignored when a custom `transport` is provided.
|
|
242
244
|
* @example `import fetch from "node-fetch"; createClient({ fetch })`
|
|
243
245
|
*/
|
|
244
|
-
fetch?:
|
|
246
|
+
fetch?: FetchLike;
|
|
245
247
|
/**
|
|
246
248
|
* Default request timeout in ms. Overridable per-request via
|
|
247
249
|
* `RequestOptions.timeoutMs`. Throws {@link TimeoutError} when exceeded.
|
|
@@ -303,7 +305,7 @@ interface RequestOptions {
|
|
|
303
305
|
* These take precedence; `content-type: application/json` is always
|
|
304
306
|
* present and is the lowest-priority default.
|
|
305
307
|
*/
|
|
306
|
-
headers?:
|
|
308
|
+
headers?: HeaderInput;
|
|
307
309
|
/** Request body. Serialised to JSON by {@link fetchTransport}. Ignored for GET and HEAD. */
|
|
308
310
|
body?: unknown;
|
|
309
311
|
/**
|
|
@@ -480,6 +482,46 @@ declare class ApiError extends Error {
|
|
|
480
482
|
constructor(message: string, status: number, responseBody?: unknown, cause?: unknown);
|
|
481
483
|
}
|
|
482
484
|
//#endregion
|
|
485
|
+
//#region src/graphql/GraphQLRequestError.d.ts
|
|
486
|
+
/**
|
|
487
|
+
* Thrown when a GraphQL server returns a well-formed HTTP 200 response that
|
|
488
|
+
* contains a non-empty `errors` array.
|
|
489
|
+
*
|
|
490
|
+
* Extends {@link ApiError} so that code catching `ApiError` also catches
|
|
491
|
+
* GraphQL-level failures. Callers that need to inspect the individual error
|
|
492
|
+
* objects can narrow with `instanceof GraphQLRequestError` and read
|
|
493
|
+
* `graphqlErrors`.
|
|
494
|
+
*
|
|
495
|
+
* When the server returns both `data` and `errors` (partial result), the
|
|
496
|
+
* partial data is available on `partialData` but the error is still thrown —
|
|
497
|
+
* callers must explicitly opt in to consuming partial results.
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```ts
|
|
501
|
+
* import { GraphQLRequestError } from "@api-wrappers/api-core";
|
|
502
|
+
*
|
|
503
|
+
* try {
|
|
504
|
+
* const data = await client.graphql<MyQuery>("/graphql", { query: QUERY });
|
|
505
|
+
* } catch (err) {
|
|
506
|
+
* if (err instanceof GraphQLRequestError) {
|
|
507
|
+
* for (const e of err.graphqlErrors) {
|
|
508
|
+
* console.error(e.message, e.path);
|
|
509
|
+
* }
|
|
510
|
+
* }
|
|
511
|
+
* }
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
declare class GraphQLRequestError extends ApiError {
|
|
515
|
+
/** The errors array from the GraphQL response envelope. */
|
|
516
|
+
readonly graphqlErrors: readonly GraphQLErrorDetail[];
|
|
517
|
+
/**
|
|
518
|
+
* Partial `data` returned alongside `errors`, if any. `undefined` when
|
|
519
|
+
* the server returned no `data` field.
|
|
520
|
+
*/
|
|
521
|
+
readonly partialData: unknown;
|
|
522
|
+
constructor(errors: GraphQLErrorDetail[], partialData?: unknown, cause?: unknown);
|
|
523
|
+
}
|
|
524
|
+
//#endregion
|
|
483
525
|
//#region src/errors/RateLimitError.d.ts
|
|
484
526
|
declare class RateLimitError extends ApiError {
|
|
485
527
|
readonly retryAfterMs: number | undefined;
|
|
@@ -492,6 +534,14 @@ declare class TimeoutError extends Error {
|
|
|
492
534
|
constructor(message?: string, cause?: unknown);
|
|
493
535
|
}
|
|
494
536
|
//#endregion
|
|
537
|
+
//#region src/errors/guards.d.ts
|
|
538
|
+
type ApiCoreError = ApiError | RateLimitError | TimeoutError | GraphQLRequestError;
|
|
539
|
+
declare function isApiError(error: unknown): error is ApiError;
|
|
540
|
+
declare function isRateLimitError(error: unknown): error is RateLimitError;
|
|
541
|
+
declare function isTimeoutError(error: unknown): error is TimeoutError;
|
|
542
|
+
declare function isGraphQLRequestError(error: unknown): error is GraphQLRequestError;
|
|
543
|
+
declare function isApiCoreError(error: unknown): error is ApiCoreError;
|
|
544
|
+
//#endregion
|
|
495
545
|
//#region src/plugins/auth/types.d.ts
|
|
496
546
|
interface AuthPluginOptions {
|
|
497
547
|
/**
|
|
@@ -672,46 +722,6 @@ interface TimeoutPluginOptions {
|
|
|
672
722
|
*/
|
|
673
723
|
declare function createTimeoutPlugin(options: TimeoutPluginOptions): ApiPlugin;
|
|
674
724
|
//#endregion
|
|
675
|
-
//#region src/graphql/GraphQLRequestError.d.ts
|
|
676
|
-
/**
|
|
677
|
-
* Thrown when a GraphQL server returns a well-formed HTTP 200 response that
|
|
678
|
-
* contains a non-empty `errors` array.
|
|
679
|
-
*
|
|
680
|
-
* Extends {@link ApiError} so that code catching `ApiError` also catches
|
|
681
|
-
* GraphQL-level failures. Callers that need to inspect the individual error
|
|
682
|
-
* objects can narrow with `instanceof GraphQLRequestError` and read
|
|
683
|
-
* `graphqlErrors`.
|
|
684
|
-
*
|
|
685
|
-
* When the server returns both `data` and `errors` (partial result), the
|
|
686
|
-
* partial data is available on `partialData` but the error is still thrown —
|
|
687
|
-
* callers must explicitly opt in to consuming partial results.
|
|
688
|
-
*
|
|
689
|
-
* @example
|
|
690
|
-
* ```ts
|
|
691
|
-
* import { GraphQLRequestError } from "@api-wrappers/api-core";
|
|
692
|
-
*
|
|
693
|
-
* try {
|
|
694
|
-
* const data = await client.graphql<MyQuery>("/graphql", { query: QUERY });
|
|
695
|
-
* } catch (err) {
|
|
696
|
-
* if (err instanceof GraphQLRequestError) {
|
|
697
|
-
* for (const e of err.graphqlErrors) {
|
|
698
|
-
* console.error(e.message, e.path);
|
|
699
|
-
* }
|
|
700
|
-
* }
|
|
701
|
-
* }
|
|
702
|
-
* ```
|
|
703
|
-
*/
|
|
704
|
-
declare class GraphQLRequestError extends ApiError {
|
|
705
|
-
/** The errors array from the GraphQL response envelope. */
|
|
706
|
-
readonly graphqlErrors: readonly GraphQLErrorDetail[];
|
|
707
|
-
/**
|
|
708
|
-
* Partial `data` returned alongside `errors`, if any. `undefined` when
|
|
709
|
-
* the server returned no `data` field.
|
|
710
|
-
*/
|
|
711
|
-
readonly partialData: unknown;
|
|
712
|
-
constructor(errors: GraphQLErrorDetail[], partialData?: unknown, cause?: unknown);
|
|
713
|
-
}
|
|
714
|
-
//#endregion
|
|
715
725
|
//#region src/graphql/gql.d.ts
|
|
716
726
|
/**
|
|
717
727
|
* Lightweight GraphQL template tag.
|
|
@@ -728,12 +738,12 @@ declare function gql(chunks: TemplateStringsArray, ...values: unknown[]): string
|
|
|
728
738
|
*
|
|
729
739
|
* ```ts
|
|
730
740
|
* import nodeFetch from "node-fetch";
|
|
731
|
-
* createClient({ fetch: nodeFetch as
|
|
741
|
+
* createClient({ fetch: nodeFetch as FetchLike });
|
|
732
742
|
* // — or set it directly on the transport:
|
|
733
|
-
* const transport = createFetchTransport(nodeFetch as
|
|
743
|
+
* const transport = createFetchTransport(nodeFetch as FetchLike);
|
|
734
744
|
* ```
|
|
735
745
|
*/
|
|
736
|
-
declare function createFetchTransport(fetchFn?:
|
|
746
|
+
declare function createFetchTransport(fetchFn?: FetchLike): Transport;
|
|
737
747
|
/**
|
|
738
748
|
* Default {@link Transport} backed by the global `fetch` API.
|
|
739
749
|
*
|
|
@@ -763,7 +773,7 @@ declare function isPlainObject(value: unknown): value is Record<string, unknown>
|
|
|
763
773
|
* Merges header objects left to right. Keys are normalized to
|
|
764
774
|
* lowercase so merging is case-insensitive. Later sources win.
|
|
765
775
|
*/
|
|
766
|
-
declare function mergeHeaders(...sources: (
|
|
776
|
+
declare function mergeHeaders(...sources: (HeaderInput | undefined)[]): Record<string, string>;
|
|
767
777
|
//#endregion
|
|
768
778
|
//#region src/utils/resolveUrl.d.ts
|
|
769
779
|
/**
|
|
@@ -775,5 +785,5 @@ declare function resolveUrl(baseUrl: string, path: string): string;
|
|
|
775
785
|
//#region src/utils/sleep.d.ts
|
|
776
786
|
declare function sleep(ms: number): Promise<void>;
|
|
777
787
|
//#endregion
|
|
778
|
-
export { ApiError, type ApiPlugin, type ApiResponse, type AuthPluginOptions, BaseHttpClient, type CachePlugin, type CachePluginOptions, type CacheStore, type ClientConfig, type GraphQLErrorDetail, GraphQLRequestError, type GraphQLRequestOptions, type GraphQLResponse, type HttpMethod, type LoggerInterface, type LoggerPluginOptions, type MaybePromise, MemoryStore, PluginManager, type QueryParams, type QueryPrimitive, type QueryValue, RateLimitError, type RateLimitPluginOptions, type RequestContext, type RequestOptions, type ResponseContext, type ResponseType, type RetryConfig, type RetryPluginOptions, TimeoutError, type TimeoutPluginOptions, type Transport, buildUrl, createAuthPlugin, createCachePlugin, createClient, createFetchTransport, createLoggerPlugin, createRateLimitPlugin, createRetryPlugin, createTimeoutPlugin, fetchTransport, gql, isPlainObject, mergeHeaders, resolveUrl, sleep };
|
|
788
|
+
export { type ApiCoreError, ApiError, type ApiPlugin, type ApiResponse, type AuthPluginOptions, BaseHttpClient, type CachePlugin, type CachePluginOptions, type CacheStore, type ClientConfig, type FetchLike, type GraphQLErrorDetail, GraphQLRequestError, type GraphQLRequestOptions, type GraphQLResponse, type HeaderInput, type HttpMethod, type LoggerInterface, type LoggerPluginOptions, type MaybePromise, MemoryStore, PluginManager, type QueryParams, type QueryPrimitive, type QueryValue, RateLimitError, type RateLimitPluginOptions, type RequestContext, type RequestOptions, type ResponseContext, type ResponseType, type RetryConfig, type RetryPluginOptions, TimeoutError, type TimeoutPluginOptions, type Transport, buildUrl, createAuthPlugin, createCachePlugin, createClient, createFetchTransport, createLoggerPlugin, createRateLimitPlugin, createRetryPlugin, createTimeoutPlugin, fetchTransport, gql, isApiCoreError, isApiError, isGraphQLRequestError, isPlainObject, isRateLimitError, isTimeoutError, mergeHeaders, resolveUrl, sleep };
|
|
779
789
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/common.ts","../src/context/RequestContext.ts","../src/graphql/types.ts","../src/context/ResponseContext.ts","../src/plugin/types.ts","../src/transport/types.ts","../src/client/types.ts","../src/plugin/PluginManager.ts","../src/client/BaseHttpClient.ts","../src/client/createClient.ts","../src/errors/ApiError.ts","../src/errors/RateLimitError.ts","../src/errors/TimeoutError.ts","../src/plugins/auth/types.ts","../src/plugins/auth/authPlugin.ts","../src/plugins/cache/types.ts","../src/plugins/cache/cachePlugin.ts","../src/plugins/cache/memoryStore.ts","../src/plugins/logger/types.ts","../src/plugins/logger/loggerPlugin.ts","../src/plugins/rateLimit/types.ts","../src/plugins/rateLimit/rateLimitPlugin.ts","../src/plugins/retry/types.ts","../src/plugins/retry/retryPlugin.ts","../src/plugins/timeout/types.ts","../src/plugins/timeout/timeoutPlugin.ts","../src/graphql/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/common.ts","../src/context/RequestContext.ts","../src/graphql/types.ts","../src/context/ResponseContext.ts","../src/plugin/types.ts","../src/transport/types.ts","../src/client/types.ts","../src/plugin/PluginManager.ts","../src/client/BaseHttpClient.ts","../src/client/createClient.ts","../src/errors/ApiError.ts","../src/graphql/GraphQLRequestError.ts","../src/errors/RateLimitError.ts","../src/errors/TimeoutError.ts","../src/errors/guards.ts","../src/plugins/auth/types.ts","../src/plugins/auth/authPlugin.ts","../src/plugins/cache/types.ts","../src/plugins/cache/cachePlugin.ts","../src/plugins/cache/memoryStore.ts","../src/plugins/logger/types.ts","../src/plugins/logger/loggerPlugin.ts","../src/plugins/rateLimit/types.ts","../src/plugins/rateLimit/rateLimitPlugin.ts","../src/plugins/retry/types.ts","../src/plugins/retry/retryPlugin.ts","../src/plugins/timeout/types.ts","../src/plugins/timeout/timeoutPlugin.ts","../src/graphql/gql.ts","../src/transport/fetchTransport.ts","../src/utils/buildUrl.ts","../src/utils/isPlainObject.ts","../src/utils/mergeHeaders.ts","../src/utils/resolveUrl.ts","../src/utils/sleep.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -208,6 +208,12 @@ function buildUrl(base, query) {
|
|
|
208
208
|
return `${base}${base.includes("?") ? base.endsWith("?") || base.endsWith("&") ? "" : "&" : "?"}${qs}`;
|
|
209
209
|
}
|
|
210
210
|
//#endregion
|
|
211
|
+
//#region src/utils/isJsonContentType.ts
|
|
212
|
+
function isJsonContentType(contentType) {
|
|
213
|
+
const mediaType = contentType?.split(";", 1)[0]?.trim().toLowerCase();
|
|
214
|
+
return mediaType === "application/json" || mediaType?.endsWith("+json") === true;
|
|
215
|
+
}
|
|
216
|
+
//#endregion
|
|
211
217
|
//#region src/utils/isPlainObject.ts
|
|
212
218
|
function isPlainObject(value) {
|
|
213
219
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -225,9 +231,9 @@ const defaultFetch = (input, init) => {
|
|
|
225
231
|
*
|
|
226
232
|
* ```ts
|
|
227
233
|
* import nodeFetch from "node-fetch";
|
|
228
|
-
* createClient({ fetch: nodeFetch as
|
|
234
|
+
* createClient({ fetch: nodeFetch as FetchLike });
|
|
229
235
|
* // — or set it directly on the transport:
|
|
230
|
-
* const transport = createFetchTransport(nodeFetch as
|
|
236
|
+
* const transport = createFetchTransport(nodeFetch as FetchLike);
|
|
231
237
|
* ```
|
|
232
238
|
*/
|
|
233
239
|
function createFetchTransport(fetchFn = defaultFetch) {
|
|
@@ -279,8 +285,7 @@ function createFetchTransport(fetchFn = defaultFetch) {
|
|
|
279
285
|
const fetchTransport = createFetchTransport();
|
|
280
286
|
function serializeRequestBody(body, headers) {
|
|
281
287
|
if (isBodyInit(body)) return body;
|
|
282
|
-
|
|
283
|
-
if (isPlainObject(body) || Array.isArray(body) || contentType.includes("json")) return JSON.stringify(body);
|
|
288
|
+
if (isPlainObject(body) || Array.isArray(body) || isJsonContentType(headers["content-type"])) return JSON.stringify(body);
|
|
284
289
|
return String(body);
|
|
285
290
|
}
|
|
286
291
|
function isBodyInit(body) {
|
|
@@ -303,10 +308,29 @@ function mergeHeaders(...sources) {
|
|
|
303
308
|
const result = {};
|
|
304
309
|
for (const source of sources) {
|
|
305
310
|
if (!source) continue;
|
|
306
|
-
|
|
311
|
+
if (isHeaders(source)) {
|
|
312
|
+
source.forEach((value, key) => {
|
|
313
|
+
result[key.toLowerCase()] = value;
|
|
314
|
+
});
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (Array.isArray(source)) {
|
|
318
|
+
for (const [key, value] of source) result[key.toLowerCase()] = value;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
for (const [key, value] of Object.entries(source)) result[key.toLowerCase()] = String(value);
|
|
307
322
|
}
|
|
308
323
|
return result;
|
|
309
324
|
}
|
|
325
|
+
function isHeaders(source) {
|
|
326
|
+
return typeof Headers !== "undefined" && source instanceof Headers;
|
|
327
|
+
}
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region src/utils/normalizeRetryMaxAttempts.ts
|
|
330
|
+
function normalizeRetryMaxAttempts(value) {
|
|
331
|
+
if (value === void 0 || !Number.isFinite(value)) return 1;
|
|
332
|
+
return Math.max(1, Math.floor(value));
|
|
333
|
+
}
|
|
310
334
|
//#endregion
|
|
311
335
|
//#region src/utils/resolveUrl.ts
|
|
312
336
|
/**
|
|
@@ -415,7 +439,7 @@ var BaseHttpClient = class {
|
|
|
415
439
|
await this.init();
|
|
416
440
|
const transport = this.config.transport ?? (this.config.fetch ? createFetchTransport(this.config.fetch) : fetchTransport);
|
|
417
441
|
const retryCfg = this.config.retry;
|
|
418
|
-
let maxAttempts = retryCfg?.maxAttempts
|
|
442
|
+
let maxAttempts = normalizeRetryMaxAttempts(retryCfg?.maxAttempts);
|
|
419
443
|
let baseDelay = retryCfg?.delayMs ?? 500;
|
|
420
444
|
let jitter = retryCfg?.jitter ?? true;
|
|
421
445
|
let retriableCodes = retryCfg?.retriableStatusCodes ?? DEFAULT_RETRIABLE_STATUS_CODES;
|
|
@@ -442,10 +466,15 @@ var BaseHttpClient = class {
|
|
|
442
466
|
await this.pluginManager.onError(err, getPluginErrorContext(err) ?? baseCtx);
|
|
443
467
|
throw err;
|
|
444
468
|
}
|
|
445
|
-
if (ctx.meta["retry.maxAttempts"] !== void 0) maxAttempts = ctx.meta["retry.maxAttempts"];
|
|
469
|
+
if (ctx.meta["retry.maxAttempts"] !== void 0) maxAttempts = normalizeRetryMaxAttempts(ctx.meta["retry.maxAttempts"]);
|
|
446
470
|
if (ctx.meta["retry.delayMs"] !== void 0) baseDelay = ctx.meta["retry.delayMs"];
|
|
447
471
|
if (ctx.meta["retry.jitter"] !== void 0) jitter = ctx.meta["retry.jitter"];
|
|
448
472
|
if (ctx.meta["retry.retriableStatusCodes"] !== void 0) retriableCodes = ctx.meta["retry.retriableStatusCodes"];
|
|
473
|
+
const retryCount = maxAttempts - 1 - attempt;
|
|
474
|
+
if (ctx.retryCount !== retryCount) ctx = {
|
|
475
|
+
...ctx,
|
|
476
|
+
retryCount
|
|
477
|
+
};
|
|
449
478
|
let rawResponse;
|
|
450
479
|
if (ctx.syntheticResponse) rawResponse = ctx.syntheticResponse;
|
|
451
480
|
else try {
|
|
@@ -472,16 +501,17 @@ var BaseHttpClient = class {
|
|
|
472
501
|
await this.pluginManager.onError(err, ctx);
|
|
473
502
|
throw err;
|
|
474
503
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
504
|
+
const finalResponse = resCtx.response;
|
|
505
|
+
if (!finalResponse.ok) {
|
|
506
|
+
if (retriableCodes.includes(finalResponse.status) && attempt < maxAttempts - 1) {
|
|
507
|
+
if (finalResponse.status === 429) {
|
|
508
|
+
const wait = readRetryAfterMs(finalResponse);
|
|
479
509
|
await this.waitForRetry(attempt, wait ?? baseDelay, false);
|
|
480
510
|
} else await this.waitForRetry(attempt, baseDelay, jitter);
|
|
481
|
-
lastError = normalizeHttpError(
|
|
511
|
+
lastError = normalizeHttpError(finalResponse, resCtx.parsedBody);
|
|
482
512
|
continue;
|
|
483
513
|
}
|
|
484
|
-
const err = normalizeHttpError(
|
|
514
|
+
const err = normalizeHttpError(finalResponse, resCtx.parsedBody);
|
|
485
515
|
await this.pluginManager.onError(err, ctx);
|
|
486
516
|
throw err;
|
|
487
517
|
}
|
|
@@ -585,7 +615,7 @@ var BaseHttpClient = class {
|
|
|
585
615
|
...variables !== void 0 && { variables },
|
|
586
616
|
...operationName !== void 0 && { operationName }
|
|
587
617
|
},
|
|
588
|
-
headers,
|
|
618
|
+
headers: mergeHeaders(headers, { "content-type": "application/json" }),
|
|
589
619
|
signal,
|
|
590
620
|
timeoutMs,
|
|
591
621
|
cacheKey,
|
|
@@ -609,7 +639,7 @@ async function parseBody(response, responseType = "auto") {
|
|
|
609
639
|
if (responseType === "text") return text;
|
|
610
640
|
if (!text) return void 0;
|
|
611
641
|
if (responseType === "json") return JSON.parse(text);
|
|
612
|
-
if ((response.headers.get("content-type")
|
|
642
|
+
if (isJsonContentType(response.headers.get("content-type"))) return JSON.parse(text);
|
|
613
643
|
return text;
|
|
614
644
|
}
|
|
615
645
|
function normalizeHttpError(response, body) {
|
|
@@ -645,6 +675,23 @@ function createClient(config) {
|
|
|
645
675
|
return new BaseHttpClient(config);
|
|
646
676
|
}
|
|
647
677
|
//#endregion
|
|
678
|
+
//#region src/errors/guards.ts
|
|
679
|
+
function isApiError(error) {
|
|
680
|
+
return error instanceof ApiError;
|
|
681
|
+
}
|
|
682
|
+
function isRateLimitError(error) {
|
|
683
|
+
return error instanceof RateLimitError;
|
|
684
|
+
}
|
|
685
|
+
function isTimeoutError(error) {
|
|
686
|
+
return error instanceof TimeoutError;
|
|
687
|
+
}
|
|
688
|
+
function isGraphQLRequestError(error) {
|
|
689
|
+
return error instanceof GraphQLRequestError;
|
|
690
|
+
}
|
|
691
|
+
function isApiCoreError(error) {
|
|
692
|
+
return isApiError(error) || isTimeoutError(error);
|
|
693
|
+
}
|
|
694
|
+
//#endregion
|
|
648
695
|
//#region src/plugins/auth/authPlugin.ts
|
|
649
696
|
/**
|
|
650
697
|
* Adds an auth token header before each request. The token can be static or
|
|
@@ -722,7 +769,7 @@ function createCachePlugin(options = {}) {
|
|
|
722
769
|
const key = ctx.cacheKey ?? generateKey(ctx);
|
|
723
770
|
const cached = await store.get(key);
|
|
724
771
|
if (cached !== void 0) {
|
|
725
|
-
const syntheticResponse = new Response(
|
|
772
|
+
const syntheticResponse = new Response(serializeCachedBody(cached), {
|
|
726
773
|
status: 200,
|
|
727
774
|
headers: { "content-type": "application/json" }
|
|
728
775
|
});
|
|
@@ -783,8 +830,14 @@ function createCachePlugin(options = {}) {
|
|
|
783
830
|
};
|
|
784
831
|
}
|
|
785
832
|
function defaultCacheKey(ctx) {
|
|
786
|
-
|
|
787
|
-
|
|
833
|
+
return `${ctx.method}:${buildUrl(ctx.url, ctx.query)}`;
|
|
834
|
+
}
|
|
835
|
+
function serializeCachedBody(value) {
|
|
836
|
+
try {
|
|
837
|
+
return JSON.stringify(value) ?? null;
|
|
838
|
+
} catch {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
788
841
|
}
|
|
789
842
|
//#endregion
|
|
790
843
|
//#region src/plugins/logger/loggerPlugin.ts
|
|
@@ -932,11 +985,20 @@ function createRetryPlugin(options = {}) {
|
|
|
932
985
|
name: "retry",
|
|
933
986
|
priority: 5,
|
|
934
987
|
beforeRequest(ctx) {
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
if (options.
|
|
938
|
-
|
|
939
|
-
|
|
988
|
+
const meta = { ...ctx.meta };
|
|
989
|
+
let retryCount = ctx.retryCount;
|
|
990
|
+
if (options.maxAttempts !== void 0) {
|
|
991
|
+
meta["retry.maxAttempts"] = options.maxAttempts;
|
|
992
|
+
retryCount = normalizeRetryMaxAttempts(options.maxAttempts) - 1 - ctx.attempt;
|
|
993
|
+
}
|
|
994
|
+
if (options.delayMs !== void 0) meta["retry.delayMs"] = options.delayMs;
|
|
995
|
+
if (options.jitter !== void 0) meta["retry.jitter"] = options.jitter;
|
|
996
|
+
if (options.retriableStatusCodes !== void 0) meta["retry.retriableStatusCodes"] = options.retriableStatusCodes;
|
|
997
|
+
return {
|
|
998
|
+
...ctx,
|
|
999
|
+
meta,
|
|
1000
|
+
retryCount
|
|
1001
|
+
};
|
|
940
1002
|
}
|
|
941
1003
|
};
|
|
942
1004
|
}
|
|
@@ -1036,6 +1098,6 @@ function consumeTrailingWhitespace(source, index) {
|
|
|
1036
1098
|
return next;
|
|
1037
1099
|
}
|
|
1038
1100
|
//#endregion
|
|
1039
|
-
export { ApiError, BaseHttpClient, GraphQLRequestError, MemoryStore, PluginManager, RateLimitError, TimeoutError, buildUrl, createAuthPlugin, createCachePlugin, createClient, createFetchTransport, createLoggerPlugin, createRateLimitPlugin, createRetryPlugin, createTimeoutPlugin, fetchTransport, gql, isPlainObject, mergeHeaders, resolveUrl, sleep };
|
|
1101
|
+
export { ApiError, BaseHttpClient, GraphQLRequestError, MemoryStore, PluginManager, RateLimitError, TimeoutError, buildUrl, createAuthPlugin, createCachePlugin, createClient, createFetchTransport, createLoggerPlugin, createRateLimitPlugin, createRetryPlugin, createTimeoutPlugin, fetchTransport, gql, isApiCoreError, isApiError, isGraphQLRequestError, isPlainObject, isRateLimitError, isTimeoutError, mergeHeaders, resolveUrl, sleep };
|
|
1040
1102
|
|
|
1041
1103
|
//# sourceMappingURL=index.mjs.map
|