@izak0s/spacebring-api 1.1.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/README.md +6 -0
- package/dist/index.cjs +30 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1538 -467
- package/dist/index.d.ts +1538 -467
- package/dist/index.js +30 -16
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -85,6 +85,8 @@ Values are passed through exactly as the API sends them — no runtime conversio
|
|
|
85
85
|
|
|
86
86
|
HTTP Basic with your **Client ID** and **Client Secret** from **Spacebring → [Network] → Network Settings → Developers**. The client builds the `Authorization: Basic …` header for you. The API's OAuth2 flow is not currently supported.
|
|
87
87
|
|
|
88
|
+
For development without touching live data, Spacebring offers a [test environment](https://www.spacebring.com/docs/administration/test-environment) (Network settings → Billing add-on) with free sandbox API credentials that work with this client unchanged.
|
|
89
|
+
|
|
88
90
|
---
|
|
89
91
|
|
|
90
92
|
## Error handling
|
|
@@ -105,6 +107,10 @@ try {
|
|
|
105
107
|
|
|
106
108
|
Malformed successes are covered too: a 2xx with an empty or incomplete body throws a `SpacebringError` (never a bare `TypeError`), and `iterate()` throws instead of looping forever if the API repeats a page token.
|
|
107
109
|
|
|
110
|
+
### Rate limits
|
|
111
|
+
|
|
112
|
+
The API allows **10 requests per second**. Rate-limited requests (429) are retried automatically — up to 3 times, honoring `Retry-After` or backing off exponentially — so `iterate()` survives the limit out of the box. Tune or disable via `maxRetries` in the config (`maxRetries: 0` turns it off); a 429 that persists past the retries is thrown as a normal `SpacebringError`.
|
|
113
|
+
|
|
108
114
|
---
|
|
109
115
|
|
|
110
116
|
## Escape hatch
|
package/dist/index.cjs
CHANGED
|
@@ -52,7 +52,7 @@ function createClient(clientOptions) {
|
|
|
52
52
|
const {
|
|
53
53
|
baseUrl: localBaseUrl,
|
|
54
54
|
fetch = baseFetch,
|
|
55
|
-
Request = CustomRequest,
|
|
55
|
+
Request: Request2 = CustomRequest,
|
|
56
56
|
headers,
|
|
57
57
|
params = {},
|
|
58
58
|
parseAs = "json",
|
|
@@ -104,7 +104,7 @@ function createClient(clientOptions) {
|
|
|
104
104
|
};
|
|
105
105
|
let id;
|
|
106
106
|
let options;
|
|
107
|
-
let request = new
|
|
107
|
+
let request = new Request2(
|
|
108
108
|
createFinalURL(schemaPath, { baseUrl: finalBaseUrl, params, querySerializer, pathSerializer }),
|
|
109
109
|
requestInit
|
|
110
110
|
);
|
|
@@ -134,7 +134,7 @@ function createClient(clientOptions) {
|
|
|
134
134
|
id
|
|
135
135
|
});
|
|
136
136
|
if (result) {
|
|
137
|
-
if (result instanceof
|
|
137
|
+
if (result instanceof Request2) {
|
|
138
138
|
request = result;
|
|
139
139
|
} else if (result instanceof Response) {
|
|
140
140
|
response = result;
|
|
@@ -1722,8 +1722,8 @@ function createSubscriptions(client, defaults) {
|
|
|
1722
1722
|
*
|
|
1723
1723
|
* Retrieve a certain subscription.
|
|
1724
1724
|
*/
|
|
1725
|
-
async get(
|
|
1726
|
-
return unwrapProp(await client.GET("/subscriptions/v1/{
|
|
1725
|
+
async get(subscriptionId) {
|
|
1726
|
+
return unwrapProp(await client.GET("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } } }), "subscription");
|
|
1727
1727
|
},
|
|
1728
1728
|
/**
|
|
1729
1729
|
* Create a subscription
|
|
@@ -1738,28 +1738,28 @@ function createSubscriptions(client, defaults) {
|
|
|
1738
1738
|
*
|
|
1739
1739
|
* Update a certain subscription.
|
|
1740
1740
|
*/
|
|
1741
|
-
async update(
|
|
1742
|
-
return unwrap(await client.PATCH("/subscriptions/v1/{
|
|
1741
|
+
async update(subscriptionId, body) {
|
|
1742
|
+
return unwrap(await client.PATCH("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } }, body }));
|
|
1743
1743
|
},
|
|
1744
1744
|
/**
|
|
1745
1745
|
* Delete a subscription
|
|
1746
1746
|
*
|
|
1747
1747
|
* Delete a certain subscription.
|
|
1748
1748
|
*/
|
|
1749
|
-
async delete(
|
|
1750
|
-
return unwrap(await client.DELETE("/subscriptions/v1/{
|
|
1749
|
+
async delete(subscriptionId) {
|
|
1750
|
+
return unwrap(await client.DELETE("/subscriptions/v1/{subscriptionId}", { params: { path: { subscriptionId } } }));
|
|
1751
1751
|
},
|
|
1752
1752
|
/** Create a subscription item */
|
|
1753
|
-
async createItem(
|
|
1754
|
-
return unwrapProp(await client.POST("/subscriptions/v1/{
|
|
1753
|
+
async createItem(subscriptionId, body) {
|
|
1754
|
+
return unwrapProp(await client.POST("/subscriptions/v1/{subscriptionId}/items", { params: { path: { subscriptionId } }, body }), "subscription");
|
|
1755
1755
|
},
|
|
1756
1756
|
/** Delete a subscription item */
|
|
1757
|
-
async deleteItem(
|
|
1758
|
-
return unwrap(await client.DELETE("/subscriptions/v1/{
|
|
1757
|
+
async deleteItem(subscriptionId, itemId) {
|
|
1758
|
+
return unwrap(await client.DELETE("/subscriptions/v1/{subscriptionId}/items/{itemId}", { params: { path: { subscriptionId, itemId } } }));
|
|
1759
1759
|
},
|
|
1760
1760
|
/** Update a subscription item */
|
|
1761
|
-
async updateItem(
|
|
1762
|
-
return unwrap(await client.PATCH("/subscriptions/v1/{
|
|
1761
|
+
async updateItem(subscriptionId, itemId, body) {
|
|
1762
|
+
return unwrap(await client.PATCH("/subscriptions/v1/{subscriptionId}/items/{itemId}", { params: { path: { subscriptionId, itemId } }, body }));
|
|
1763
1763
|
}
|
|
1764
1764
|
};
|
|
1765
1765
|
}
|
|
@@ -2089,11 +2089,25 @@ var Spacebring = class {
|
|
|
2089
2089
|
this.raw = createClient({
|
|
2090
2090
|
baseUrl: config.baseUrl ?? "https://api.spacebring.com",
|
|
2091
2091
|
headers,
|
|
2092
|
-
fetch: config.fetch
|
|
2092
|
+
fetch: withRetry(config.fetch ?? globalThis.fetch, config.maxRetries ?? 3)
|
|
2093
2093
|
});
|
|
2094
2094
|
Object.assign(this, createResources2(this.raw, { networkId: config.networkId }));
|
|
2095
2095
|
}
|
|
2096
2096
|
};
|
|
2097
|
+
function withRetry(fetchImpl, maxRetries) {
|
|
2098
|
+
if (maxRetries <= 0) return fetchImpl;
|
|
2099
|
+
return async (input, init) => {
|
|
2100
|
+
const request = input instanceof Request && init === void 0 ? input : new Request(input, init);
|
|
2101
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
2102
|
+
const response = await fetchImpl(request.clone());
|
|
2103
|
+
if (response.status !== 429 || attempt >= maxRetries) return response;
|
|
2104
|
+
const retryAfterHeader = response.headers.get("retry-after");
|
|
2105
|
+
const retryAfter = retryAfterHeader === null ? Number.NaN : Number(retryAfterHeader);
|
|
2106
|
+
const delayMs = Number.isFinite(retryAfter) && retryAfter >= 0 ? Math.min(retryAfter * 1e3, 6e4) : Math.min(250 * 2 ** attempt + Math.random() * 100, 5e3);
|
|
2107
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
}
|
|
2097
2111
|
function toBase64(value) {
|
|
2098
2112
|
if (typeof Buffer !== "undefined") {
|
|
2099
2113
|
return Buffer.from(value, "utf8").toString("base64");
|