@insforge/sdk 1.2.4 → 1.2.5-dev.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.d.mts +13 -10
- package/dist/index.d.ts +13 -10
- package/dist/index.js +101 -57
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -57
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -284,6 +284,51 @@ var TokenManager = class {
|
|
|
284
284
|
// src/lib/http-client.ts
|
|
285
285
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
286
286
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
287
|
+
function serializeBody(method, body, headers) {
|
|
288
|
+
if (body === void 0) return void 0;
|
|
289
|
+
if (method === "GET" || method === "HEAD") return void 0;
|
|
290
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
291
|
+
return body;
|
|
292
|
+
}
|
|
293
|
+
headers["Content-Type"] = "application/json;charset=UTF-8";
|
|
294
|
+
return JSON.stringify(body);
|
|
295
|
+
}
|
|
296
|
+
async function parseResponse(response) {
|
|
297
|
+
if (response.status === 204) return void 0;
|
|
298
|
+
let data;
|
|
299
|
+
const contentType = response.headers.get("content-type");
|
|
300
|
+
try {
|
|
301
|
+
if (contentType?.includes("json")) {
|
|
302
|
+
data = await response.json();
|
|
303
|
+
} else {
|
|
304
|
+
data = await response.text();
|
|
305
|
+
}
|
|
306
|
+
} catch (parseErr) {
|
|
307
|
+
throw new InsForgeError(
|
|
308
|
+
`Failed to parse response body: ${parseErr?.message || "Unknown error"}`,
|
|
309
|
+
response.status,
|
|
310
|
+
response.ok ? "PARSE_ERROR" : "REQUEST_FAILED"
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
if (!response.ok) {
|
|
314
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
315
|
+
data.statusCode ?? (data.statusCode = data.status ?? response.status);
|
|
316
|
+
const error = InsForgeError.fromApiError(data);
|
|
317
|
+
Object.keys(data).forEach((key) => {
|
|
318
|
+
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
319
|
+
error[key] = data[key];
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
throw error;
|
|
323
|
+
}
|
|
324
|
+
throw new InsForgeError(
|
|
325
|
+
`Request failed: ${response.statusText}`,
|
|
326
|
+
response.status,
|
|
327
|
+
"REQUEST_FAILED"
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
return data;
|
|
331
|
+
}
|
|
287
332
|
var HttpClient = class {
|
|
288
333
|
/**
|
|
289
334
|
* Creates a new HttpClient instance.
|
|
@@ -377,17 +422,7 @@ var HttpClient = class {
|
|
|
377
422
|
if (authToken) {
|
|
378
423
|
requestHeaders["Authorization"] = `Bearer ${authToken}`;
|
|
379
424
|
}
|
|
380
|
-
|
|
381
|
-
if (body !== void 0) {
|
|
382
|
-
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
383
|
-
processedBody = body;
|
|
384
|
-
} else {
|
|
385
|
-
if (method !== "GET") {
|
|
386
|
-
requestHeaders["Content-Type"] = "application/json;charset=UTF-8";
|
|
387
|
-
}
|
|
388
|
-
processedBody = JSON.stringify(body);
|
|
389
|
-
}
|
|
390
|
-
}
|
|
425
|
+
const processedBody = serializeBody(method, body, requestHeaders);
|
|
391
426
|
if (headers instanceof Headers) {
|
|
392
427
|
headers.forEach((value, key) => {
|
|
393
428
|
requestHeaders[key] = value;
|
|
@@ -466,53 +501,23 @@ var HttpClient = class {
|
|
|
466
501
|
);
|
|
467
502
|
continue;
|
|
468
503
|
}
|
|
469
|
-
if (response.status === 204) {
|
|
470
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
471
|
-
return void 0;
|
|
472
|
-
}
|
|
473
504
|
let data;
|
|
474
|
-
const contentType = response.headers.get("content-type");
|
|
475
505
|
try {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
} else {
|
|
479
|
-
data = await response.text();
|
|
480
|
-
}
|
|
481
|
-
} catch (parseErr) {
|
|
506
|
+
data = await parseResponse(response);
|
|
507
|
+
} catch (err) {
|
|
482
508
|
if (timer !== void 0) clearTimeout(timer);
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
this.logger.logResponse(
|
|
492
|
-
method,
|
|
493
|
-
url,
|
|
494
|
-
response.status,
|
|
495
|
-
Date.now() - startTime,
|
|
496
|
-
data
|
|
497
|
-
);
|
|
498
|
-
if (data && typeof data === "object" && "error" in data) {
|
|
499
|
-
if (!data.statusCode && !data.status) {
|
|
500
|
-
data.statusCode = response.status;
|
|
501
|
-
}
|
|
502
|
-
const error = InsForgeError.fromApiError(data);
|
|
503
|
-
Object.keys(data).forEach((key) => {
|
|
504
|
-
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
505
|
-
error[key] = data[key];
|
|
506
|
-
}
|
|
507
|
-
});
|
|
508
|
-
throw error;
|
|
509
|
+
if (err instanceof InsForgeError) {
|
|
510
|
+
this.logger.logResponse(
|
|
511
|
+
method,
|
|
512
|
+
url,
|
|
513
|
+
err.statusCode || response.status,
|
|
514
|
+
Date.now() - startTime,
|
|
515
|
+
err
|
|
516
|
+
);
|
|
509
517
|
}
|
|
510
|
-
throw
|
|
511
|
-
`Request failed: ${response.statusText}`,
|
|
512
|
-
response.status,
|
|
513
|
-
"REQUEST_FAILED"
|
|
514
|
-
);
|
|
518
|
+
throw err;
|
|
515
519
|
}
|
|
520
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
516
521
|
this.logger.logResponse(
|
|
517
522
|
method,
|
|
518
523
|
url,
|
|
@@ -1878,16 +1883,55 @@ var Functions = class _Functions {
|
|
|
1878
1883
|
}
|
|
1879
1884
|
}
|
|
1880
1885
|
/**
|
|
1881
|
-
*
|
|
1886
|
+
* Build a Request for in-process dispatch. The host is a non-routable
|
|
1887
|
+
* placeholder; the router only reads pathname.
|
|
1888
|
+
*/
|
|
1889
|
+
buildInProcessRequest(slug, method, body, callerHeaders) {
|
|
1890
|
+
const url = new URL("/" + slug, "http://insforge.local").toString();
|
|
1891
|
+
const headers = { ...this.http.getHeaders() };
|
|
1892
|
+
const reqBody = serializeBody(method, body, headers);
|
|
1893
|
+
Object.assign(headers, callerHeaders);
|
|
1894
|
+
return new Request(url, {
|
|
1895
|
+
method,
|
|
1896
|
+
headers,
|
|
1897
|
+
body: reqBody
|
|
1898
|
+
});
|
|
1899
|
+
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Invoke an Edge Function.
|
|
1882
1902
|
*
|
|
1883
|
-
*
|
|
1884
|
-
*
|
|
1903
|
+
* Dispatch order:
|
|
1904
|
+
* 1. If `globalThis.__insforge_dispatch__` is present, call it in-process.
|
|
1905
|
+
* This avoids Deno Subhosting's 508 Loop Detected when one bundled
|
|
1906
|
+
* function invokes another inside the same deployment.
|
|
1907
|
+
* 2. Otherwise, try the configured subhosting URL.
|
|
1908
|
+
* 3. On 404 from subhosting, fall back to the proxy path.
|
|
1885
1909
|
*
|
|
1886
1910
|
* @param slug The function slug to invoke
|
|
1887
1911
|
* @param options Request options
|
|
1888
1912
|
*/
|
|
1889
1913
|
async invoke(slug, options = {}) {
|
|
1890
1914
|
const { method = "POST", body, headers = {} } = options;
|
|
1915
|
+
const dispatch = globalThis.__insforge_dispatch__;
|
|
1916
|
+
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
1917
|
+
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
1918
|
+
try {
|
|
1919
|
+
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
1920
|
+
const res = await dispatch(req);
|
|
1921
|
+
const data = await parseResponse(res);
|
|
1922
|
+
return { data, error: null };
|
|
1923
|
+
} catch (error) {
|
|
1924
|
+
if (error instanceof Error && error.name === "AbortError") throw error;
|
|
1925
|
+
return {
|
|
1926
|
+
data: null,
|
|
1927
|
+
error: error instanceof InsForgeError ? error : new InsForgeError(
|
|
1928
|
+
error instanceof Error ? error.message : "Function invocation failed",
|
|
1929
|
+
500,
|
|
1930
|
+
"FUNCTION_ERROR"
|
|
1931
|
+
)
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1891
1935
|
if (this.functionsUrl) {
|
|
1892
1936
|
try {
|
|
1893
1937
|
const data = await this.http.request(method, `${this.functionsUrl}/${slug}`, {
|
|
@@ -2218,7 +2262,7 @@ var InsForgeClient = class {
|
|
|
2218
2262
|
this.tokenManager.setAccessToken(config.edgeFunctionToken);
|
|
2219
2263
|
}
|
|
2220
2264
|
this.auth = new Auth(this.http, this.tokenManager, {
|
|
2221
|
-
isServerMode: config.isServerMode ??
|
|
2265
|
+
isServerMode: config.isServerMode ?? false
|
|
2222
2266
|
});
|
|
2223
2267
|
this.database = new Database(this.http, this.tokenManager);
|
|
2224
2268
|
this.storage = new Storage(this.http);
|