@insforge/sdk 1.2.4 → 1.2.5
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 +100 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +100 -56
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -755,19 +755,13 @@ interface FunctionInvokeOptions {
|
|
|
755
755
|
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
756
756
|
}
|
|
757
757
|
/**
|
|
758
|
-
* Edge Functions client for invoking serverless functions
|
|
758
|
+
* Edge Functions client for invoking serverless functions.
|
|
759
759
|
*
|
|
760
760
|
* @example
|
|
761
761
|
* ```typescript
|
|
762
|
-
* // Invoke a function with JSON body
|
|
763
762
|
* const { data, error } = await client.functions.invoke('hello-world', {
|
|
764
763
|
* body: { name: 'World' }
|
|
765
764
|
* });
|
|
766
|
-
*
|
|
767
|
-
* // GET request
|
|
768
|
-
* const { data, error } = await client.functions.invoke('get-data', {
|
|
769
|
-
* method: 'GET'
|
|
770
|
-
* });
|
|
771
765
|
* ```
|
|
772
766
|
*/
|
|
773
767
|
declare class Functions {
|
|
@@ -782,10 +776,19 @@ declare class Functions {
|
|
|
782
776
|
*/
|
|
783
777
|
private static deriveSubhostingUrl;
|
|
784
778
|
/**
|
|
785
|
-
*
|
|
779
|
+
* Build a Request for in-process dispatch. The host is a non-routable
|
|
780
|
+
* placeholder; the router only reads pathname.
|
|
781
|
+
*/
|
|
782
|
+
private buildInProcessRequest;
|
|
783
|
+
/**
|
|
784
|
+
* Invoke an Edge Function.
|
|
786
785
|
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
786
|
+
* Dispatch order:
|
|
787
|
+
* 1. If `globalThis.__insforge_dispatch__` is present, call it in-process.
|
|
788
|
+
* This avoids Deno Subhosting's 508 Loop Detected when one bundled
|
|
789
|
+
* function invokes another inside the same deployment.
|
|
790
|
+
* 2. Otherwise, try the configured subhosting URL.
|
|
791
|
+
* 3. On 404 from subhosting, fall back to the proxy path.
|
|
789
792
|
*
|
|
790
793
|
* @param slug The function slug to invoke
|
|
791
794
|
* @param options Request options
|
package/dist/index.d.ts
CHANGED
|
@@ -755,19 +755,13 @@ interface FunctionInvokeOptions {
|
|
|
755
755
|
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
756
756
|
}
|
|
757
757
|
/**
|
|
758
|
-
* Edge Functions client for invoking serverless functions
|
|
758
|
+
* Edge Functions client for invoking serverless functions.
|
|
759
759
|
*
|
|
760
760
|
* @example
|
|
761
761
|
* ```typescript
|
|
762
|
-
* // Invoke a function with JSON body
|
|
763
762
|
* const { data, error } = await client.functions.invoke('hello-world', {
|
|
764
763
|
* body: { name: 'World' }
|
|
765
764
|
* });
|
|
766
|
-
*
|
|
767
|
-
* // GET request
|
|
768
|
-
* const { data, error } = await client.functions.invoke('get-data', {
|
|
769
|
-
* method: 'GET'
|
|
770
|
-
* });
|
|
771
765
|
* ```
|
|
772
766
|
*/
|
|
773
767
|
declare class Functions {
|
|
@@ -782,10 +776,19 @@ declare class Functions {
|
|
|
782
776
|
*/
|
|
783
777
|
private static deriveSubhostingUrl;
|
|
784
778
|
/**
|
|
785
|
-
*
|
|
779
|
+
* Build a Request for in-process dispatch. The host is a non-routable
|
|
780
|
+
* placeholder; the router only reads pathname.
|
|
781
|
+
*/
|
|
782
|
+
private buildInProcessRequest;
|
|
783
|
+
/**
|
|
784
|
+
* Invoke an Edge Function.
|
|
786
785
|
*
|
|
787
|
-
*
|
|
788
|
-
*
|
|
786
|
+
* Dispatch order:
|
|
787
|
+
* 1. If `globalThis.__insforge_dispatch__` is present, call it in-process.
|
|
788
|
+
* This avoids Deno Subhosting's 508 Loop Detected when one bundled
|
|
789
|
+
* function invokes another inside the same deployment.
|
|
790
|
+
* 2. Otherwise, try the configured subhosting URL.
|
|
791
|
+
* 3. On 404 from subhosting, fall back to the proxy path.
|
|
789
792
|
*
|
|
790
793
|
* @param slug The function slug to invoke
|
|
791
794
|
* @param options Request options
|
package/dist/index.js
CHANGED
|
@@ -324,6 +324,51 @@ var TokenManager = class {
|
|
|
324
324
|
// src/lib/http-client.ts
|
|
325
325
|
var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([500, 502, 503, 504]);
|
|
326
326
|
var IDEMPOTENT_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
327
|
+
function serializeBody(method, body, headers) {
|
|
328
|
+
if (body === void 0) return void 0;
|
|
329
|
+
if (method === "GET" || method === "HEAD") return void 0;
|
|
330
|
+
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
331
|
+
return body;
|
|
332
|
+
}
|
|
333
|
+
headers["Content-Type"] = "application/json;charset=UTF-8";
|
|
334
|
+
return JSON.stringify(body);
|
|
335
|
+
}
|
|
336
|
+
async function parseResponse(response) {
|
|
337
|
+
if (response.status === 204) return void 0;
|
|
338
|
+
let data;
|
|
339
|
+
const contentType = response.headers.get("content-type");
|
|
340
|
+
try {
|
|
341
|
+
if (contentType?.includes("json")) {
|
|
342
|
+
data = await response.json();
|
|
343
|
+
} else {
|
|
344
|
+
data = await response.text();
|
|
345
|
+
}
|
|
346
|
+
} catch (parseErr) {
|
|
347
|
+
throw new InsForgeError(
|
|
348
|
+
`Failed to parse response body: ${parseErr?.message || "Unknown error"}`,
|
|
349
|
+
response.status,
|
|
350
|
+
response.ok ? "PARSE_ERROR" : "REQUEST_FAILED"
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
if (!response.ok) {
|
|
354
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
355
|
+
data.statusCode ?? (data.statusCode = data.status ?? response.status);
|
|
356
|
+
const error = InsForgeError.fromApiError(data);
|
|
357
|
+
Object.keys(data).forEach((key) => {
|
|
358
|
+
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
359
|
+
error[key] = data[key];
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
364
|
+
throw new InsForgeError(
|
|
365
|
+
`Request failed: ${response.statusText}`,
|
|
366
|
+
response.status,
|
|
367
|
+
"REQUEST_FAILED"
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
return data;
|
|
371
|
+
}
|
|
327
372
|
var HttpClient = class {
|
|
328
373
|
/**
|
|
329
374
|
* Creates a new HttpClient instance.
|
|
@@ -417,17 +462,7 @@ var HttpClient = class {
|
|
|
417
462
|
if (authToken) {
|
|
418
463
|
requestHeaders["Authorization"] = `Bearer ${authToken}`;
|
|
419
464
|
}
|
|
420
|
-
|
|
421
|
-
if (body !== void 0) {
|
|
422
|
-
if (typeof FormData !== "undefined" && body instanceof FormData) {
|
|
423
|
-
processedBody = body;
|
|
424
|
-
} else {
|
|
425
|
-
if (method !== "GET") {
|
|
426
|
-
requestHeaders["Content-Type"] = "application/json;charset=UTF-8";
|
|
427
|
-
}
|
|
428
|
-
processedBody = JSON.stringify(body);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
465
|
+
const processedBody = serializeBody(method, body, requestHeaders);
|
|
431
466
|
if (headers instanceof Headers) {
|
|
432
467
|
headers.forEach((value, key) => {
|
|
433
468
|
requestHeaders[key] = value;
|
|
@@ -506,53 +541,23 @@ var HttpClient = class {
|
|
|
506
541
|
);
|
|
507
542
|
continue;
|
|
508
543
|
}
|
|
509
|
-
if (response.status === 204) {
|
|
510
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
511
|
-
return void 0;
|
|
512
|
-
}
|
|
513
544
|
let data;
|
|
514
|
-
const contentType = response.headers.get("content-type");
|
|
515
545
|
try {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
} else {
|
|
519
|
-
data = await response.text();
|
|
520
|
-
}
|
|
521
|
-
} catch (parseErr) {
|
|
546
|
+
data = await parseResponse(response);
|
|
547
|
+
} catch (err) {
|
|
522
548
|
if (timer !== void 0) clearTimeout(timer);
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
this.logger.logResponse(
|
|
532
|
-
method,
|
|
533
|
-
url,
|
|
534
|
-
response.status,
|
|
535
|
-
Date.now() - startTime,
|
|
536
|
-
data
|
|
537
|
-
);
|
|
538
|
-
if (data && typeof data === "object" && "error" in data) {
|
|
539
|
-
if (!data.statusCode && !data.status) {
|
|
540
|
-
data.statusCode = response.status;
|
|
541
|
-
}
|
|
542
|
-
const error = InsForgeError.fromApiError(data);
|
|
543
|
-
Object.keys(data).forEach((key) => {
|
|
544
|
-
if (key !== "error" && key !== "message" && key !== "statusCode") {
|
|
545
|
-
error[key] = data[key];
|
|
546
|
-
}
|
|
547
|
-
});
|
|
548
|
-
throw error;
|
|
549
|
+
if (err instanceof InsForgeError) {
|
|
550
|
+
this.logger.logResponse(
|
|
551
|
+
method,
|
|
552
|
+
url,
|
|
553
|
+
err.statusCode || response.status,
|
|
554
|
+
Date.now() - startTime,
|
|
555
|
+
err
|
|
556
|
+
);
|
|
549
557
|
}
|
|
550
|
-
throw
|
|
551
|
-
`Request failed: ${response.statusText}`,
|
|
552
|
-
response.status,
|
|
553
|
-
"REQUEST_FAILED"
|
|
554
|
-
);
|
|
558
|
+
throw err;
|
|
555
559
|
}
|
|
560
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
556
561
|
this.logger.logResponse(
|
|
557
562
|
method,
|
|
558
563
|
url,
|
|
@@ -1918,16 +1923,55 @@ var Functions = class _Functions {
|
|
|
1918
1923
|
}
|
|
1919
1924
|
}
|
|
1920
1925
|
/**
|
|
1921
|
-
*
|
|
1926
|
+
* Build a Request for in-process dispatch. The host is a non-routable
|
|
1927
|
+
* placeholder; the router only reads pathname.
|
|
1928
|
+
*/
|
|
1929
|
+
buildInProcessRequest(slug, method, body, callerHeaders) {
|
|
1930
|
+
const url = new URL("/" + slug, "http://insforge.local").toString();
|
|
1931
|
+
const headers = { ...this.http.getHeaders() };
|
|
1932
|
+
const reqBody = serializeBody(method, body, headers);
|
|
1933
|
+
Object.assign(headers, callerHeaders);
|
|
1934
|
+
return new Request(url, {
|
|
1935
|
+
method,
|
|
1936
|
+
headers,
|
|
1937
|
+
body: reqBody
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Invoke an Edge Function.
|
|
1922
1942
|
*
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1943
|
+
* Dispatch order:
|
|
1944
|
+
* 1. If `globalThis.__insforge_dispatch__` is present, call it in-process.
|
|
1945
|
+
* This avoids Deno Subhosting's 508 Loop Detected when one bundled
|
|
1946
|
+
* function invokes another inside the same deployment.
|
|
1947
|
+
* 2. Otherwise, try the configured subhosting URL.
|
|
1948
|
+
* 3. On 404 from subhosting, fall back to the proxy path.
|
|
1925
1949
|
*
|
|
1926
1950
|
* @param slug The function slug to invoke
|
|
1927
1951
|
* @param options Request options
|
|
1928
1952
|
*/
|
|
1929
1953
|
async invoke(slug, options = {}) {
|
|
1930
1954
|
const { method = "POST", body, headers = {} } = options;
|
|
1955
|
+
const dispatch = globalThis.__insforge_dispatch__;
|
|
1956
|
+
const localFunctionsUrl = _Functions.deriveSubhostingUrl(this.http.baseUrl);
|
|
1957
|
+
if (typeof dispatch === "function" && !!localFunctionsUrl && this.functionsUrl === localFunctionsUrl) {
|
|
1958
|
+
try {
|
|
1959
|
+
const req = this.buildInProcessRequest(slug, method, body, headers);
|
|
1960
|
+
const res = await dispatch(req);
|
|
1961
|
+
const data = await parseResponse(res);
|
|
1962
|
+
return { data, error: null };
|
|
1963
|
+
} catch (error) {
|
|
1964
|
+
if (error instanceof Error && error.name === "AbortError") throw error;
|
|
1965
|
+
return {
|
|
1966
|
+
data: null,
|
|
1967
|
+
error: error instanceof InsForgeError ? error : new InsForgeError(
|
|
1968
|
+
error instanceof Error ? error.message : "Function invocation failed",
|
|
1969
|
+
500,
|
|
1970
|
+
"FUNCTION_ERROR"
|
|
1971
|
+
)
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1931
1975
|
if (this.functionsUrl) {
|
|
1932
1976
|
try {
|
|
1933
1977
|
const data = await this.http.request(method, `${this.functionsUrl}/${slug}`, {
|