@izak0s/spacebring-api 1.0.0 → 1.2.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/index.js CHANGED
@@ -13,24 +13,27 @@ function createClient(clientOptions) {
13
13
  fetch: baseFetch = globalThis.fetch,
14
14
  querySerializer: globalQuerySerializer,
15
15
  bodySerializer: globalBodySerializer,
16
+ pathSerializer: globalPathSerializer,
16
17
  headers: baseHeaders,
17
18
  requestInitExt = void 0,
18
19
  ...baseOptions
19
20
  } = { ...clientOptions };
20
21
  requestInitExt = supportsRequestInitExt() ? requestInitExt : void 0;
21
22
  baseUrl = removeTrailingSlash(baseUrl);
22
- const middlewares = [];
23
+ const globalMiddlewares = [];
23
24
  async function coreFetch(schemaPath, fetchOptions) {
24
25
  const {
25
26
  baseUrl: localBaseUrl,
26
27
  fetch = baseFetch,
27
- Request = CustomRequest,
28
+ Request: Request2 = CustomRequest,
28
29
  headers,
29
30
  params = {},
30
31
  parseAs = "json",
31
32
  querySerializer: requestQuerySerializer,
32
33
  bodySerializer = globalBodySerializer ?? defaultBodySerializer,
34
+ pathSerializer: requestPathSerializer,
33
35
  body,
36
+ middleware: requestMiddlewares = [],
34
37
  ...init
35
38
  } = fetchOptions || {};
36
39
  let finalBaseUrl = baseUrl;
@@ -44,6 +47,7 @@ function createClient(clientOptions) {
44
47
  ...requestQuerySerializer
45
48
  });
46
49
  }
50
+ const pathSerializer = requestPathSerializer || globalPathSerializer || defaultPathSerializer;
47
51
  const serializedBody = body === void 0 ? void 0 : bodySerializer(
48
52
  body,
49
53
  // Note: we declare mergeHeaders() both here and below because it’s a bit of a chicken-or-egg situation:
@@ -63,6 +67,7 @@ function createClient(clientOptions) {
63
67
  headers,
64
68
  params.header
65
69
  );
70
+ const finalMiddlewares = [...globalMiddlewares, ...requestMiddlewares];
66
71
  const requestInit = {
67
72
  redirect: "follow",
68
73
  ...baseOptions,
@@ -72,8 +77,8 @@ function createClient(clientOptions) {
72
77
  };
73
78
  let id;
74
79
  let options;
75
- let request = new Request(
76
- createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer }),
80
+ let request = new Request2(
81
+ createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer, pathSerializer }),
77
82
  requestInit
78
83
  );
79
84
  let response;
@@ -82,16 +87,17 @@ function createClient(clientOptions) {
82
87
  request[key] = init[key];
83
88
  }
84
89
  }
85
- if (middlewares.length) {
90
+ if (finalMiddlewares.length) {
86
91
  id = randomID();
87
92
  options = Object.freeze({
88
93
  baseUrl: finalBaseUrl,
89
94
  fetch,
90
95
  parseAs,
91
96
  querySerializer,
92
- bodySerializer
97
+ bodySerializer,
98
+ pathSerializer
93
99
  });
94
- for (const m of middlewares) {
100
+ for (const m of finalMiddlewares) {
95
101
  if (m && typeof m === "object" && typeof m.onRequest === "function") {
96
102
  const result = await m.onRequest({
97
103
  request,
@@ -101,7 +107,7 @@ function createClient(clientOptions) {
101
107
  id
102
108
  });
103
109
  if (result) {
104
- if (result instanceof Request) {
110
+ if (result instanceof Request2) {
105
111
  request = result;
106
112
  } else if (result instanceof Response) {
107
113
  response = result;
@@ -118,9 +124,9 @@ function createClient(clientOptions) {
118
124
  response = await fetch(request, requestInitExt);
119
125
  } catch (error2) {
120
126
  let errorAfterMiddleware = error2;
121
- if (middlewares.length) {
122
- for (let i = middlewares.length - 1; i >= 0; i--) {
123
- const m = middlewares[i];
127
+ if (finalMiddlewares.length) {
128
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
129
+ const m = finalMiddlewares[i];
124
130
  if (m && typeof m === "object" && typeof m.onError === "function") {
125
131
  const result = await m.onError({
126
132
  request,
@@ -149,9 +155,9 @@ function createClient(clientOptions) {
149
155
  throw errorAfterMiddleware;
150
156
  }
151
157
  }
152
- if (middlewares.length) {
153
- for (let i = middlewares.length - 1; i >= 0; i--) {
154
- const m = middlewares[i];
158
+ if (finalMiddlewares.length) {
159
+ for (let i = finalMiddlewares.length - 1; i >= 0; i--) {
160
+ const m = finalMiddlewares[i];
155
161
  if (m && typeof m === "object" && typeof m.onResponse === "function") {
156
162
  const result = await m.onResponse({
157
163
  request,
@@ -171,14 +177,22 @@ function createClient(clientOptions) {
171
177
  }
172
178
  }
173
179
  }
174
- if (response.status === 204 || request.method === "HEAD" || response.headers.get("Content-Length") === "0") {
180
+ const contentLength = response.headers.get("Content-Length");
181
+ if (response.status === 204 || request.method === "HEAD" || contentLength === "0" && !response.headers.get("Transfer-Encoding")?.includes("chunked")) {
175
182
  return response.ok ? { data: void 0, response } : { error: void 0, response };
176
183
  }
177
184
  if (response.ok) {
178
- if (parseAs === "stream") {
179
- return { data: response.body, response };
180
- }
181
- return { data: await response[parseAs](), response };
185
+ const getResponseData = async () => {
186
+ if (parseAs === "stream") {
187
+ return response.body;
188
+ }
189
+ if (parseAs === "json" && !contentLength) {
190
+ const raw = await response.text();
191
+ return raw ? JSON.parse(raw) : void 0;
192
+ }
193
+ return await response[parseAs]();
194
+ };
195
+ return { data: await getResponseData(), response };
182
196
  }
183
197
  let error = await response.text();
184
198
  try {
@@ -232,15 +246,15 @@ function createClient(clientOptions) {
232
246
  if (typeof m !== "object" || !("onRequest" in m || "onResponse" in m || "onError" in m)) {
233
247
  throw new Error("Middleware must be an object with one of `onRequest()`, `onResponse() or `onError()`");
234
248
  }
235
- middlewares.push(m);
249
+ globalMiddlewares.push(m);
236
250
  }
237
251
  },
238
252
  /** Unregister middleware */
239
253
  eject(...middleware) {
240
254
  for (const m of middleware) {
241
- const i = middlewares.indexOf(m);
255
+ const i = globalMiddlewares.indexOf(m);
242
256
  if (i !== -1) {
243
- middlewares.splice(i, 1);
257
+ globalMiddlewares.splice(i, 1);
244
258
  }
245
259
  }
246
260
  }
@@ -421,7 +435,7 @@ function defaultBodySerializer(body, headers) {
421
435
  function createFinalURL(pathname, options) {
422
436
  let finalURL = `${options.baseUrl}${pathname}`;
423
437
  if (options.params?.path) {
424
- finalURL = defaultPathSerializer(finalURL, options.params.path);
438
+ finalURL = options.pathSerializer(finalURL, options.params.path);
425
439
  }
426
440
  let search = options.querySerializer(options.params.query ?? {});
427
441
  if (search.startsWith("?")) {
@@ -1681,8 +1695,8 @@ function createSubscriptions(client, defaults) {
1681
1695
  *
1682
1696
  * Retrieve a certain subscription.
1683
1697
  */
1684
- async get(id) {
1685
- return unwrapProp(await client.GET("/subscriptions/v1/{id}", { params: { path: { id } } }), "subscription");
1698
+ async get(subscriptionId) {
1699
+ return unwrapProp(await client.GET("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } } }), "subscription");
1686
1700
  },
1687
1701
  /**
1688
1702
  * Create a subscription
@@ -1697,28 +1711,28 @@ function createSubscriptions(client, defaults) {
1697
1711
  *
1698
1712
  * Update a certain subscription.
1699
1713
  */
1700
- async update(id, body) {
1701
- return unwrap(await client.PATCH("/subscriptions/v1/{id}", { params: { path: { id } }, body }));
1714
+ async update(subscriptionId, body) {
1715
+ return unwrap(await client.PATCH("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } }, body }));
1702
1716
  },
1703
1717
  /**
1704
1718
  * Delete a subscription
1705
1719
  *
1706
1720
  * Delete a certain subscription.
1707
1721
  */
1708
- async delete(id) {
1709
- return unwrap(await client.DELETE("/subscriptions/v1/{id}", { params: { path: { id } } }));
1722
+ async delete(subscriptionId) {
1723
+ return unwrap(await client.DELETE("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } } }));
1710
1724
  },
1711
1725
  /** Create a subscription item */
1712
- async createItem(id, body) {
1713
- return unwrapProp(await client.POST("/subscriptions/v1/{id}/items", { params: { path: { id } }, body }), "subscription");
1726
+ async createItem(subscriptionId, body) {
1727
+ return unwrapProp(await client.POST("/subscriptions/v1/{subscriptionId}/items", { params: { path: { subscriptionId } }, body }), "subscription");
1714
1728
  },
1715
1729
  /** Delete a subscription item */
1716
- async deleteItem(id, itemId) {
1717
- return unwrap(await client.DELETE("/subscriptions/v1/{id}/items/{itemId}", { params: { path: { id, itemId } } }));
1730
+ async deleteItem(subscriptionId, itemId) {
1731
+ return unwrap(await client.DELETE("/subscriptions/v1/{subscriptionId}/items/{itemId}", { params: { path: { subscriptionId, itemId } } }));
1718
1732
  },
1719
1733
  /** Update a subscription item */
1720
- async updateItem(id, itemId, body) {
1721
- return unwrap(await client.PATCH("/subscriptions/v1/{id}/items/{itemId}", { params: { path: { id, itemId } }, body }));
1734
+ async updateItem(subscriptionId, itemId, body) {
1735
+ return unwrap(await client.PATCH("/subscriptions/v1/{subscriptionId}/items/{itemId}", { params: { path: { subscriptionId, itemId } }, body }));
1722
1736
  }
1723
1737
  };
1724
1738
  }
@@ -2048,11 +2062,25 @@ var Spacebring = class {
2048
2062
  this.raw = createClient({
2049
2063
  baseUrl: config.baseUrl ?? "https://api.spacebring.com",
2050
2064
  headers,
2051
- fetch: config.fetch
2065
+ fetch: withRetry(config.fetch ?? globalThis.fetch, config.maxRetries ?? 3)
2052
2066
  });
2053
2067
  Object.assign(this, createResources2(this.raw, { networkId: config.networkId }));
2054
2068
  }
2055
2069
  };
2070
+ function withRetry(fetchImpl, maxRetries) {
2071
+ if (maxRetries <= 0) return fetchImpl;
2072
+ return async (input, init) => {
2073
+ const request = input instanceof Request && init === void 0 ? input : new Request(input, init);
2074
+ for (let attempt = 0; ; attempt += 1) {
2075
+ const response = await fetchImpl(request.clone());
2076
+ if (response.status !== 429 || attempt >= maxRetries) return response;
2077
+ const retryAfterHeader = response.headers.get("retry-after");
2078
+ const retryAfter = retryAfterHeader === null ? Number.NaN : Number(retryAfterHeader);
2079
+ const delayMs = Number.isFinite(retryAfter) && retryAfter >= 0 ? Math.min(retryAfter * 1e3, 6e4) : Math.min(250 * 2 ** attempt + Math.random() * 100, 5e3);
2080
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
2081
+ }
2082
+ };
2083
+ }
2056
2084
  function toBase64(value) {
2057
2085
  if (typeof Buffer !== "undefined") {
2058
2086
  return Buffer.from(value, "utf8").toString("base64");