@stacks/network 6.17.0 → 7.0.0-next.70

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/src/fetch.ts DELETED
@@ -1,180 +0,0 @@
1
- import 'cross-fetch/polyfill';
2
-
3
- // Define a default request options and allow modification using getters, setters
4
- // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
5
- const defaultFetchOpts: RequestInit = {
6
- // By default referrer value will be client:origin: above reference link
7
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
8
- referrerPolicy: 'origin', // Use origin value for referrer policy
9
- headers: {
10
- 'x-hiro-product': 'stacksjs',
11
- },
12
- };
13
-
14
- /**
15
- * Get fetch options
16
- * @category Network
17
- */
18
- export const getFetchOptions = () => {
19
- return defaultFetchOpts;
20
- };
21
-
22
- /**
23
- * Sets global fetch options for stacks.js network calls.
24
- *
25
- * @example
26
- * Users can change the default referrer as well as other options when fetch is used internally by stacks.js:
27
- * ```
28
- * setFetchOptions({ referrer: 'no-referrer', referrerPolicy: 'no-referrer', ...otherRequestOptions });
29
- * ```
30
- * After calling {@link setFetchOptions} all subsequent network calls will use the specified options above.
31
- *
32
- * @see MDN Request: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
33
- * @returns global fetch options after merging with previous options (or defaults)
34
- * @category Network
35
- * @related {@link getFetchOptions}
36
- */
37
- export const setFetchOptions = (ops: RequestInit): RequestInit => {
38
- return Object.assign(defaultFetchOpts, ops);
39
- };
40
-
41
- /** @internal */
42
- export async function fetchWrapper(input: RequestInfo, init?: RequestInit): Promise<Response> {
43
- const fetchOpts = {};
44
- // Use the provided options in request options along with default or user provided values
45
- Object.assign(fetchOpts, defaultFetchOpts, init);
46
-
47
- const fetchResult = await fetch(input, fetchOpts);
48
- return fetchResult;
49
- }
50
-
51
- export type FetchFn = (url: string, init?: RequestInit) => Promise<Response>;
52
-
53
- export interface RequestContext {
54
- fetch: FetchFn;
55
- url: string;
56
- init: RequestInit;
57
- }
58
-
59
- export interface ResponseContext {
60
- fetch: FetchFn;
61
- url: string;
62
- init: RequestInit;
63
- response: Response;
64
- }
65
-
66
- export interface FetchParams {
67
- url: string;
68
- init: RequestInit;
69
- }
70
-
71
- export interface FetchMiddleware {
72
- pre?: (context: RequestContext) => PromiseLike<FetchParams | void> | FetchParams | void;
73
- post?: (context: ResponseContext) => Promise<Response | void> | Response | void;
74
- }
75
- export interface ApiKeyMiddlewareOpts {
76
- /** The middleware / API key header will only be added to requests matching this host. */
77
- host?: RegExp | string;
78
- /** The http header name used for specifying the API key value. */
79
- httpHeader?: string;
80
- /** The API key string to specify as an http header value. */
81
- apiKey: string;
82
- }
83
-
84
- /** @internal */
85
- export function hostMatches(host: string, pattern: string | RegExp) {
86
- if (typeof pattern === 'string') return pattern === host;
87
- return pattern.exec(host);
88
- }
89
-
90
- /**
91
- * Creates a new middleware from an API key.
92
- * @example
93
- * ```
94
- * const apiMiddleware = createApiKeyMiddleware("example_e8e044a3_41d8b0fe_3dd3988ef302");
95
- * const fetchFn = createFetchFn(apiMiddleware);
96
- * const network = new StacksMainnet({ fetchFn });
97
- * ```
98
- * @category Network
99
- * @related {@link createFetchFn}, {@link StacksNetwork}
100
- */
101
- export function createApiKeyMiddleware({
102
- apiKey,
103
- host = /(.*)api(.*)(\.stacks\.co|\.hiro\.so)$/i,
104
- httpHeader = 'x-api-key',
105
- }: ApiKeyMiddlewareOpts): FetchMiddleware {
106
- return {
107
- pre: context => {
108
- const reqUrl = new URL(context.url);
109
- if (!hostMatches(reqUrl.host, host)) return; // Skip middleware if host does not match pattern
110
-
111
- const headers =
112
- context.init.headers instanceof Headers
113
- ? context.init.headers
114
- : (context.init.headers = new Headers(context.init.headers));
115
- headers.set(httpHeader, apiKey);
116
- },
117
- };
118
- }
119
-
120
- function argsForCreateFetchFn(args: any[]): { fetchLib: FetchFn; middlewares: FetchMiddleware[] } {
121
- let fetchLib: FetchFn = fetchWrapper;
122
- let middlewares: FetchMiddleware[] = [];
123
- if (args.length > 0 && typeof args[0] === 'function') {
124
- fetchLib = args.shift();
125
- }
126
- if (args.length > 0) {
127
- middlewares = args; // remaining args
128
- }
129
- return { fetchLib, middlewares };
130
- }
131
-
132
- /**
133
- * Creates a new network fetching function, which combines an optional fetch-compatible library with optional middleware.
134
- * @example
135
- * ```
136
- * const customFetch = createFetchFn(someMiddleware)
137
- * const customFetch = createFetchFn(fetch, someMiddleware)
138
- * const customFetch = createFetchFn(fetch, middlewareA, middlewareB)
139
- * ```
140
- * @category Network
141
- */
142
- export function createFetchFn(fetchLib: FetchFn, ...middleware: FetchMiddleware[]): FetchFn;
143
- export function createFetchFn(...middleware: FetchMiddleware[]): FetchFn;
144
- export function createFetchFn(...args: any[]): FetchFn {
145
- const { fetchLib, middlewares } = argsForCreateFetchFn(args);
146
-
147
- const fetchFn = async (url: string, init?: RequestInit | undefined): Promise<Response> => {
148
- let fetchParams = { url, init: init ?? {} };
149
-
150
- for (const middleware of middlewares) {
151
- if (typeof middleware.pre === 'function') {
152
- const result = await Promise.resolve(
153
- middleware.pre({
154
- fetch: fetchLib,
155
- ...fetchParams,
156
- })
157
- );
158
- fetchParams = result ?? fetchParams;
159
- }
160
- }
161
-
162
- let response = await fetchLib(fetchParams.url, fetchParams.init);
163
-
164
- for (const middleware of middlewares) {
165
- if (typeof middleware.post === 'function') {
166
- const result = await Promise.resolve(
167
- middleware.post({
168
- fetch: fetchLib,
169
- url: fetchParams.url,
170
- init: fetchParams.init,
171
- response: response?.clone() ?? response,
172
- })
173
- );
174
- response = result ?? response;
175
- }
176
- }
177
- return response;
178
- };
179
- return fetchFn;
180
- }