@gauts/ft 0.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/retry.js ADDED
@@ -0,0 +1,55 @@
1
+ import { DEFAULTS } from "./config.js";
2
+ const assertNumber = (name, value) => {
3
+ if (!Number.isFinite(value) || value < 0) {
4
+ throw new TypeError(`${name} must be a non-negative number`);
5
+ }
6
+ };
7
+ export const resolveRetry = (retry) => {
8
+ if (retry === false || retry === undefined || retry === 0)
9
+ return null;
10
+ const input = typeof retry === "number" ? { limit: retry } : retry;
11
+ const config = {
12
+ baseDelay: input.baseDelay ?? DEFAULTS.retry.baseDelay,
13
+ jitter: input.jitter ?? DEFAULTS.retry.jitter,
14
+ limit: input.limit ?? DEFAULTS.retry.limit,
15
+ maxDelay: input.maxDelay ?? DEFAULTS.retry.maxDelay,
16
+ methods: input.methods ?? DEFAULTS.retry.methods,
17
+ statusCodes: input.statusCodes ?? DEFAULTS.retry.statusCodes,
18
+ };
19
+ assertNumber("retry.limit", config.limit);
20
+ assertNumber("retry.baseDelay", config.baseDelay);
21
+ assertNumber("retry.maxDelay", config.maxDelay);
22
+ return config;
23
+ };
24
+ export const canRetry = ({ attempt, config, method, replayable }) => Boolean(config && replayable && attempt <= config.limit && config.methods.includes(method));
25
+ const retryAfter = (response) => {
26
+ const value = response.headers.get("retry-after");
27
+ if (!value)
28
+ return null;
29
+ const seconds = Number(value);
30
+ if (Number.isFinite(seconds))
31
+ return Math.max(0, seconds * 1000);
32
+ const date = Date.parse(value);
33
+ return Number.isNaN(date) ? null : Math.max(0, date - Date.now());
34
+ };
35
+ export const getRetryDelay = ({ attempt, config, response }) => {
36
+ const headerDelay = response ? retryAfter(response) : null;
37
+ const backoff = config.baseDelay * 2 ** (attempt - 1);
38
+ const base = Math.min(headerDelay ?? backoff, config.maxDelay);
39
+ return config.jitter ? Math.round(Math.random() * base) : base;
40
+ };
41
+ export const sleep = (delay, signal) => new Promise((resolve, reject) => {
42
+ const getError = () => signal.reason instanceof Error
43
+ ? signal.reason
44
+ : new DOMException("The operation was aborted", "AbortError");
45
+ if (signal.aborted) {
46
+ reject(getError());
47
+ return;
48
+ }
49
+ const timer = setTimeout(resolve, delay);
50
+ signal.addEventListener("abort", () => {
51
+ clearTimeout(timer);
52
+ reject(getError());
53
+ }, { once: true });
54
+ });
55
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ export type HttpMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
2
+ export type RequestInput = Request | string | URL;
3
+ export type SearchValue = boolean | number | string | null | undefined;
4
+ export type SearchParams = URLSearchParams | Record<string, SearchValue | readonly SearchValue[]> | readonly (readonly [string, SearchValue])[];
5
+ export type RuntimeBaseUrl = {
6
+ client: string | URL;
7
+ server: string | URL;
8
+ };
9
+ export type ForwardHeaders = boolean | {
10
+ extra: readonly string[];
11
+ };
12
+ export type GetHeaders = () => HeadersInit | Promise<HeadersInit>;
13
+ export type Progress = {
14
+ percent: number | null;
15
+ total: number | null;
16
+ transferred: number;
17
+ };
18
+ export type RequestContext = {
19
+ attempt: number;
20
+ request: Request;
21
+ };
22
+ export type ResponseContext = RequestContext & {
23
+ response: Response;
24
+ };
25
+ export type RetryContext = RequestContext & {
26
+ delay: number;
27
+ error: Error;
28
+ response: Response | null;
29
+ };
30
+ export type ErrorContext = {
31
+ attempt: number;
32
+ error: Error;
33
+ request: Request | null;
34
+ };
35
+ export type BeforeRequest = (context: RequestContext) => unknown;
36
+ export type AfterResponse = (context: ResponseContext) => Promise<Response | void> | Response | void;
37
+ export type OnRetry = (context: RetryContext) => unknown;
38
+ export type OnError = (context: ErrorContext) => Promise<Error | void> | Error | void;
39
+ export type OnStatus = (context: ResponseContext) => unknown;
40
+ export type StatusHandlers = Partial<Record<number, OnStatus>>;
41
+ export type RetryConfig = {
42
+ baseDelay?: number;
43
+ jitter?: boolean;
44
+ limit?: number;
45
+ maxDelay?: number;
46
+ methods?: readonly HttpMethod[];
47
+ statusCodes?: readonly number[];
48
+ };
49
+ export type RetryOption = RetryConfig | number | false;
50
+ type Lifecycle = {
51
+ afterResponse?: AfterResponse;
52
+ beforeRequest?: BeforeRequest;
53
+ onError?: OnError;
54
+ onRetry?: OnRetry;
55
+ onStatus?: StatusHandlers;
56
+ };
57
+ type Reliability = {
58
+ retry?: RetryOption;
59
+ throwHttpErrors?: boolean;
60
+ timeout?: false | number;
61
+ };
62
+ export type FetcherConfig = Omit<RequestInit, "body" | "method" | "signal"> & Lifecycle & Reliability & {
63
+ baseUrl?: RuntimeBaseUrl | string | URL;
64
+ forwardHeaders?: ForwardHeaders;
65
+ getHeaders?: GetHeaders;
66
+ prefix?: string;
67
+ searchParams?: SearchParams;
68
+ };
69
+ export type RequestOptions = Omit<RequestInit, "method"> & Lifecycle & Reliability & {
70
+ json?: unknown;
71
+ onDownloadProgress?: (progress: Progress) => void;
72
+ onUploadProgress?: (progress: Progress) => void;
73
+ searchParams?: SearchParams;
74
+ };
75
+ export type FetchTask = PromiseLike<Response> & {
76
+ arrayBuffer: () => Promise<ArrayBuffer>;
77
+ blob: () => Promise<Blob>;
78
+ bytes: () => Promise<Uint8Array<ArrayBuffer>>;
79
+ catch: <TResult = never>(onRejected?: ((reason: unknown) => PromiseLike<TResult> | TResult) | null) => Promise<Response | TResult>;
80
+ finally: (onFinally?: (() => void) | null) => Promise<Response>;
81
+ formData: () => Promise<FormData>;
82
+ json: <T = unknown>() => Promise<T>;
83
+ response: () => Promise<Response>;
84
+ text: () => Promise<string>;
85
+ };
86
+ export type FetchMethod = (input?: RequestInput, options?: RequestOptions) => FetchTask;
87
+ export type Fetcher = {
88
+ delete: FetchMethod;
89
+ get: FetchMethod;
90
+ head: FetchMethod;
91
+ patch: FetchMethod;
92
+ post: FetchMethod;
93
+ put: FetchMethod;
94
+ };
95
+ export type Ft = Fetcher & {
96
+ create: (config?: FetcherConfig) => Fetcher;
97
+ };
98
+ export {};
99
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/dist/url.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { RequestInput, SearchParams } from "./types.js";
2
+ type ResolveUrlInput = {
3
+ baseUrl?: string | URL | undefined;
4
+ input: Exclude<RequestInput, Request>;
5
+ prefix?: string | undefined;
6
+ searchParams?: SearchParams | undefined;
7
+ requestSearchParams?: SearchParams | undefined;
8
+ };
9
+ export declare const resolveUrl: ({ baseUrl, input, prefix, requestSearchParams, searchParams, }: ResolveUrlInput) => string;
10
+ export {};
11
+ //# sourceMappingURL=url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAe,MAAM,YAAY,CAAC;AAqD1E,KAAK,eAAe,GAAG;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,mBAAmB,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CAClD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,gEAMxB,eAAe,KAAG,MAwBpB,CAAC"}
package/dist/url.js ADDED
@@ -0,0 +1,70 @@
1
+ const absolutePattern = /^[a-z][a-z\d+.-]*:/i;
2
+ const placeholder = "http://ft.local";
3
+ const trimStart = (value) => value.replace(/^\/+/, "");
4
+ const trimEnd = (value) => value.replace(/\/+$/, "");
5
+ const joinPath = (...values) => values
6
+ .filter((value) => Boolean(value))
7
+ .map((value, index) => (index === 0 ? trimEnd(value) : trimStart(trimEnd(value))))
8
+ .filter(Boolean)
9
+ .join("/");
10
+ const addValue = (params, key, value) => {
11
+ if (value !== null && value !== undefined) {
12
+ params.append(key, String(value));
13
+ }
14
+ };
15
+ const setSearchParams = (target, values) => {
16
+ if (!values)
17
+ return;
18
+ if (values instanceof URLSearchParams) {
19
+ const entries = Array.from(values.entries());
20
+ const keys = new Set(entries.map(([key]) => key));
21
+ for (const key of keys)
22
+ target.delete(key);
23
+ for (const [key, value] of entries)
24
+ addValue(target, key, value);
25
+ return;
26
+ }
27
+ if (Array.isArray(values)) {
28
+ const entries = values;
29
+ const keys = new Set(entries.map(([key]) => key));
30
+ for (const key of keys)
31
+ target.delete(key);
32
+ for (const [key, value] of entries)
33
+ addValue(target, key, value);
34
+ return;
35
+ }
36
+ for (const [key, value] of Object.entries(values)) {
37
+ target.delete(key);
38
+ if (Array.isArray(value)) {
39
+ for (const item of value)
40
+ addValue(target, key, item);
41
+ }
42
+ else {
43
+ addValue(target, key, value);
44
+ }
45
+ }
46
+ };
47
+ export const resolveUrl = ({ baseUrl, input, prefix, requestSearchParams, searchParams, }) => {
48
+ const inputValue = input.toString();
49
+ const isAbsolute = absolutePattern.test(inputValue);
50
+ const baseValue = baseUrl?.toString();
51
+ const isBaseAbsolute = Boolean(baseValue && absolutePattern.test(baseValue));
52
+ let value;
53
+ if (isAbsolute) {
54
+ value = inputValue;
55
+ }
56
+ else if (baseValue && isBaseAbsolute) {
57
+ const base = `${trimEnd(baseValue)}/`;
58
+ value = new URL(joinPath(prefix, inputValue), base).toString();
59
+ }
60
+ else {
61
+ value = joinPath(baseValue, prefix, inputValue);
62
+ }
63
+ const url = new URL(value || "", isAbsolute || isBaseAbsolute ? undefined : placeholder);
64
+ setSearchParams(url.searchParams, searchParams);
65
+ setSearchParams(url.searchParams, requestSearchParams);
66
+ if (isAbsolute || isBaseAbsolute)
67
+ return url.toString();
68
+ return `${url.pathname}${url.search}${url.hash}`;
69
+ };
70
+ //# sourceMappingURL=url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../src/url.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@gauts/ft",
3
+ "version": "0.1.0",
4
+ "description": "A small, typed HTTP client built on the native Fetch API.",
5
+ "license": "MIT",
6
+ "author": "GVALFER",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/GVALFER/GAUTS-FT.git"
10
+ },
11
+ "homepage": "https://github.com/GVALFER/GAUTS-FT#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/GVALFER/GAUTS-FT/issues"
14
+ },
15
+ "keywords": [
16
+ "fetch",
17
+ "fetcher",
18
+ "http",
19
+ "request",
20
+ "retry",
21
+ "typescript"
22
+ ],
23
+ "type": "module",
24
+ "packageManager": "npm@11.17.0",
25
+ "engines": {
26
+ "node": ">=22.0.0"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "LICENSE",
31
+ "README.md",
32
+ "SECURITY.md"
33
+ ],
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.js"
38
+ }
39
+ },
40
+ "scripts": {
41
+ "clean": "node --eval \"import { rmSync } from 'node:fs'; rmSync('dist', { force: true, recursive: true })\"",
42
+ "build": "npm run clean && tsc -p tsconfig.build.json",
43
+ "typecheck": "tsc --noEmit",
44
+ "lint": "eslint src tests examples",
45
+ "test": "node --import tsx --test tests/**/*.test.ts",
46
+ "check": "npm run build && npm run lint && npm run typecheck && npm test",
47
+ "prepack": "npm run check"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "devDependencies": {
53
+ "@eslint/js": "^9.39.5",
54
+ "@types/node": "^24.10.0",
55
+ "esbuild": "^0.25.12",
56
+ "eslint": "^9.39.5",
57
+ "globals": "^16.5.0",
58
+ "tsx": "^4.23.0",
59
+ "typescript": "^5.9.3",
60
+ "typescript-eslint": "^8.66.0"
61
+ }
62
+ }