@omnikit-ai/sdk 2.2.0 → 2.2.1
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 +247 -9
- package/dist/index.d.ts +247 -9
- package/dist/index.js +194 -59
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +194 -59
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -660,6 +660,20 @@ var APIClient = class {
|
|
|
660
660
|
description: "Create a signed URL for a private file",
|
|
661
661
|
method: "POST",
|
|
662
662
|
params: { file_uri: "string" }
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
name: "DownloadPrivateFile",
|
|
666
|
+
path: "/services/files/private/download",
|
|
667
|
+
description: "Download a private file via backend proxy (solves CORS issues)",
|
|
668
|
+
method: "POST",
|
|
669
|
+
params: { file_uri: "string" }
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
name: "DownloadFile",
|
|
673
|
+
path: "/services/files/{file_id}/download",
|
|
674
|
+
description: "Download a public file via backend proxy (like Supabase ?download)",
|
|
675
|
+
method: "GET",
|
|
676
|
+
params: { file_id: "string", download: "boolean", filename: "string" }
|
|
663
677
|
}
|
|
664
678
|
];
|
|
665
679
|
builtInServices.forEach((service) => {
|
|
@@ -869,6 +883,25 @@ var APIClient = class {
|
|
|
869
883
|
}
|
|
870
884
|
return this._connectors;
|
|
871
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* Resolve a return URL to an absolute URL.
|
|
888
|
+
* Handles relative paths like "/profile" by combining with current location.
|
|
889
|
+
* This fixes the OAuth redirect bug where relative URLs like "/profile" become
|
|
890
|
+
* "https://omnikit.ai/profile" instead of "https://omnikit.ai/app-builder/{id}/preview/profile"
|
|
891
|
+
*/
|
|
892
|
+
_resolveReturnUrl(returnUrl) {
|
|
893
|
+
if (typeof window === "undefined") return returnUrl || "/";
|
|
894
|
+
if (!returnUrl) return window.location.href;
|
|
895
|
+
if (returnUrl.startsWith("http://") || returnUrl.startsWith("https://")) {
|
|
896
|
+
return returnUrl;
|
|
897
|
+
}
|
|
898
|
+
if (returnUrl.startsWith("/")) {
|
|
899
|
+
const basePath = window.location.pathname.endsWith("/") ? window.location.pathname.slice(0, -1) : window.location.pathname;
|
|
900
|
+
return window.location.origin + basePath + returnUrl;
|
|
901
|
+
}
|
|
902
|
+
const base = window.location.origin + window.location.pathname;
|
|
903
|
+
return base.endsWith("/") ? base + returnUrl : base + "/" + returnUrl;
|
|
904
|
+
}
|
|
872
905
|
/**
|
|
873
906
|
* Create auth proxy that auto-initializes
|
|
874
907
|
*/
|
|
@@ -896,31 +929,42 @@ var APIClient = class {
|
|
|
896
929
|
client.emitUserChange(response);
|
|
897
930
|
return response;
|
|
898
931
|
},
|
|
899
|
-
login(returnUrl) {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
} else {
|
|
912
|
-
window.location.href = `/login?return_url=${encodedReturnUrl}`;
|
|
932
|
+
async login(returnUrl) {
|
|
933
|
+
if (typeof window === "undefined") return;
|
|
934
|
+
const fullReturnUrl = client._resolveReturnUrl(returnUrl);
|
|
935
|
+
const token = getAccessToken();
|
|
936
|
+
if (token) {
|
|
937
|
+
try {
|
|
938
|
+
const isAuth = await this.isAuthenticated();
|
|
939
|
+
if (isAuth && returnUrl) {
|
|
940
|
+
window.location.href = fullReturnUrl;
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
} catch {
|
|
913
944
|
}
|
|
914
945
|
}
|
|
946
|
+
if (window.__omnikit_openLoginModal) {
|
|
947
|
+
window.__omnikit_openLoginModal(fullReturnUrl);
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
const encodedReturnUrl = encodeURIComponent(fullReturnUrl);
|
|
951
|
+
const currentPath = window.location.pathname;
|
|
952
|
+
const apiSitesMatch = currentPath.match(/^\/api\/sites\/([^\/]+)/);
|
|
953
|
+
if (apiSitesMatch) {
|
|
954
|
+
window.location.href = `/api/sites/${client.appId}/login?return_url=${encodedReturnUrl}`;
|
|
955
|
+
} else {
|
|
956
|
+
window.location.href = `/login?return_url=${encodedReturnUrl}`;
|
|
957
|
+
}
|
|
915
958
|
},
|
|
916
959
|
/**
|
|
917
960
|
* Request a passwordless login code to email
|
|
918
961
|
*/
|
|
919
962
|
async requestLoginCode(email, returnUrl) {
|
|
963
|
+
const fullReturnUrl = returnUrl ? client._resolveReturnUrl(returnUrl) : void 0;
|
|
920
964
|
return await client.makeRequest(
|
|
921
965
|
`${client.baseUrl}/auth/email/request-code`,
|
|
922
966
|
"POST",
|
|
923
|
-
{ email, return_url:
|
|
967
|
+
{ email, return_url: fullReturnUrl }
|
|
924
968
|
);
|
|
925
969
|
},
|
|
926
970
|
/**
|
|
@@ -968,44 +1012,43 @@ var APIClient = class {
|
|
|
968
1012
|
* Redirects to the backend OAuth endpoint for the specified provider
|
|
969
1013
|
*/
|
|
970
1014
|
loginWithProvider(providerId, returnUrl) {
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1015
|
+
if (typeof window === "undefined") {
|
|
1016
|
+
throw new OmnikitError("loginWithProvider() can only be called in browser environment", 400, "NOT_BROWSER");
|
|
1017
|
+
}
|
|
1018
|
+
const fullReturnUrl = client._resolveReturnUrl(returnUrl);
|
|
1019
|
+
const redirectUrl = `${client.baseUrl}/auth/${providerId}?redirect_url=${encodeURIComponent(fullReturnUrl)}`;
|
|
1020
|
+
const inIframe = window.self !== window.top;
|
|
1021
|
+
if (inIframe) {
|
|
1022
|
+
const width = 600;
|
|
1023
|
+
const height = 700;
|
|
1024
|
+
const left = window.screen.width / 2 - width / 2;
|
|
1025
|
+
const top = window.screen.height / 2 - height / 2;
|
|
1026
|
+
const popup = window.open(
|
|
1027
|
+
redirectUrl,
|
|
1028
|
+
"oauth_popup",
|
|
1029
|
+
`width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes,status=yes`
|
|
1030
|
+
);
|
|
1031
|
+
if (popup) {
|
|
1032
|
+
const checkTimer = setInterval(() => {
|
|
1033
|
+
const token = getAccessToken();
|
|
1034
|
+
if (token) {
|
|
1035
|
+
clearInterval(checkTimer);
|
|
1036
|
+
popup.close();
|
|
1037
|
+
window.location.reload();
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (popup.closed) {
|
|
1041
|
+
clearInterval(checkTimer);
|
|
1042
|
+
const finalToken = getAccessToken();
|
|
1043
|
+
if (finalToken) {
|
|
991
1044
|
window.location.reload();
|
|
992
|
-
return;
|
|
993
1045
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
if (finalToken) {
|
|
998
|
-
window.location.reload();
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
}, 1e3);
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1046
|
+
}
|
|
1047
|
+
}, 1e3);
|
|
1048
|
+
return;
|
|
1004
1049
|
}
|
|
1005
|
-
window.location.href = redirectUrl;
|
|
1006
|
-
} else {
|
|
1007
|
-
throw new OmnikitError("loginWithProvider() can only be called in browser environment", 400, "NOT_BROWSER");
|
|
1008
1050
|
}
|
|
1051
|
+
window.location.href = redirectUrl;
|
|
1009
1052
|
},
|
|
1010
1053
|
/**
|
|
1011
1054
|
* Initiate Google OAuth Login
|
|
@@ -1217,7 +1260,8 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1217
1260
|
// Remove callback functions from request body
|
|
1218
1261
|
onToken: void 0,
|
|
1219
1262
|
onComplete: void 0,
|
|
1220
|
-
onError: void 0
|
|
1263
|
+
onError: void 0,
|
|
1264
|
+
onToolCall: void 0
|
|
1221
1265
|
};
|
|
1222
1266
|
Object.keys(requestBody).forEach((key) => {
|
|
1223
1267
|
if (requestBody[key] === void 0) {
|
|
@@ -1268,6 +1312,14 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1268
1312
|
if (event.type === "token" && event.content) {
|
|
1269
1313
|
fullResponse += event.content;
|
|
1270
1314
|
params.onToken?.(event.content);
|
|
1315
|
+
} else if (event.type === "tool_call") {
|
|
1316
|
+
if (params.onToolCall && event.id && event.name) {
|
|
1317
|
+
params.onToolCall({
|
|
1318
|
+
id: event.id,
|
|
1319
|
+
name: event.name,
|
|
1320
|
+
arguments: event.arguments || {}
|
|
1321
|
+
});
|
|
1322
|
+
}
|
|
1271
1323
|
} else if (event.type === "done") {
|
|
1272
1324
|
params.onComplete?.({
|
|
1273
1325
|
result: event.result || fullResponse,
|
|
@@ -1326,6 +1378,56 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1326
1378
|
);
|
|
1327
1379
|
};
|
|
1328
1380
|
}
|
|
1381
|
+
if (normalizedName === "DownloadFile") {
|
|
1382
|
+
return async function(params) {
|
|
1383
|
+
await client.ensureInitialized();
|
|
1384
|
+
if (!params?.file_id) {
|
|
1385
|
+
throw new OmnikitError(
|
|
1386
|
+
"file_id is required for DownloadFile",
|
|
1387
|
+
400,
|
|
1388
|
+
"MISSING_FILE_ID"
|
|
1389
|
+
);
|
|
1390
|
+
}
|
|
1391
|
+
const downloadUrl = new URL(`${client.baseUrl}/apps/${client.appId}/services/files/${params.file_id}/download`);
|
|
1392
|
+
if (params.download !== void 0) {
|
|
1393
|
+
downloadUrl.searchParams.set("download", String(params.download));
|
|
1394
|
+
}
|
|
1395
|
+
if (params.filename) {
|
|
1396
|
+
downloadUrl.searchParams.set("filename", params.filename);
|
|
1397
|
+
}
|
|
1398
|
+
const response = await fetch(downloadUrl.toString(), {
|
|
1399
|
+
method: "GET"
|
|
1400
|
+
});
|
|
1401
|
+
if (!response.ok) {
|
|
1402
|
+
const error = await response.json().catch(() => ({ detail: "Download failed" }));
|
|
1403
|
+
throw new OmnikitError(
|
|
1404
|
+
error.detail || "Download failed",
|
|
1405
|
+
response.status,
|
|
1406
|
+
"DOWNLOAD_FAILED"
|
|
1407
|
+
);
|
|
1408
|
+
}
|
|
1409
|
+
const blob = await response.blob();
|
|
1410
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
1411
|
+
let filename = params.filename;
|
|
1412
|
+
if (!filename) {
|
|
1413
|
+
const contentDisposition = response.headers.get("Content-Disposition");
|
|
1414
|
+
if (contentDisposition) {
|
|
1415
|
+
const match = contentDisposition.match(/filename="?([^"]+)"?/);
|
|
1416
|
+
if (match) filename = match[1];
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
if (!filename) {
|
|
1420
|
+
filename = `file-${params.file_id}`;
|
|
1421
|
+
}
|
|
1422
|
+
const link = document.createElement("a");
|
|
1423
|
+
link.href = blobUrl;
|
|
1424
|
+
link.download = filename;
|
|
1425
|
+
document.body.appendChild(link);
|
|
1426
|
+
link.click();
|
|
1427
|
+
document.body.removeChild(link);
|
|
1428
|
+
URL.revokeObjectURL(blobUrl);
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1329
1431
|
if (normalizedName === "DownloadPrivateFile") {
|
|
1330
1432
|
return async function(params) {
|
|
1331
1433
|
await client.ensureInitialized();
|
|
@@ -1336,16 +1438,47 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1336
1438
|
"MISSING_FILE_URI"
|
|
1337
1439
|
);
|
|
1338
1440
|
}
|
|
1339
|
-
const downloadUrl =
|
|
1340
|
-
downloadUrl.searchParams.set("file_uri", params.file_uri);
|
|
1341
|
-
if (params.filename) {
|
|
1342
|
-
downloadUrl.searchParams.set("filename", params.filename);
|
|
1343
|
-
}
|
|
1441
|
+
const downloadUrl = `${client.baseUrl}/apps/${client.appId}/services/files/private/download`;
|
|
1344
1442
|
const token = client.getAuthToken();
|
|
1345
|
-
|
|
1346
|
-
|
|
1443
|
+
const response = await fetch(downloadUrl, {
|
|
1444
|
+
method: "POST",
|
|
1445
|
+
headers: {
|
|
1446
|
+
"Content-Type": "application/json",
|
|
1447
|
+
...token ? { "Authorization": `Bearer ${token}` } : {}
|
|
1448
|
+
},
|
|
1449
|
+
body: JSON.stringify({ file_uri: params.file_uri })
|
|
1450
|
+
});
|
|
1451
|
+
if (!response.ok) {
|
|
1452
|
+
const error = await response.json().catch(() => ({ detail: "Download failed" }));
|
|
1453
|
+
throw new OmnikitError(
|
|
1454
|
+
error.detail || "Download failed",
|
|
1455
|
+
response.status,
|
|
1456
|
+
"DOWNLOAD_FAILED"
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
const blob = await response.blob();
|
|
1460
|
+
const blobUrl = URL.createObjectURL(blob);
|
|
1461
|
+
let filename = params.filename;
|
|
1462
|
+
if (!filename) {
|
|
1463
|
+
const contentDisposition = response.headers.get("Content-Disposition");
|
|
1464
|
+
if (contentDisposition) {
|
|
1465
|
+
const match = contentDisposition.match(/filename="?([^"]+)"?/);
|
|
1466
|
+
if (match) filename = match[1];
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
if (!filename) {
|
|
1470
|
+
const uriParts = params.file_uri.split("/");
|
|
1471
|
+
const lastPart = uriParts[uriParts.length - 1];
|
|
1472
|
+
const underscoreIdx = lastPart.indexOf("_");
|
|
1473
|
+
filename = underscoreIdx > 0 ? lastPart.slice(underscoreIdx + 1) : lastPart;
|
|
1347
1474
|
}
|
|
1348
|
-
|
|
1475
|
+
const link = document.createElement("a");
|
|
1476
|
+
link.href = blobUrl;
|
|
1477
|
+
link.download = filename;
|
|
1478
|
+
document.body.appendChild(link);
|
|
1479
|
+
link.click();
|
|
1480
|
+
document.body.removeChild(link);
|
|
1481
|
+
URL.revokeObjectURL(blobUrl);
|
|
1349
1482
|
};
|
|
1350
1483
|
}
|
|
1351
1484
|
return async function(params, asyncOptions) {
|
|
@@ -1364,7 +1497,7 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1364
1497
|
response = await method(params, useServiceToken);
|
|
1365
1498
|
} else {
|
|
1366
1499
|
throw new OmnikitError(
|
|
1367
|
-
`Service '${serviceName}' not found. Known services: SendEmail, InvokeLLM, GenerateImage, GenerateSpeech, GenerateVideo, ExtractData, SendSMS, UploadFile, UploadPrivateFile, CreateFileSignedUrl (camelCase also supported)`,
|
|
1500
|
+
`Service '${serviceName}' not found. Known services: SendEmail, InvokeLLM, GenerateImage, GenerateSpeech, GenerateVideo, ExtractData, SendSMS, UploadFile, UploadPrivateFile, CreateFileSignedUrl, DownloadFile, DownloadPrivateFile (camelCase also supported)`,
|
|
1368
1501
|
404,
|
|
1369
1502
|
"SERVICE_NOT_FOUND"
|
|
1370
1503
|
);
|
|
@@ -1880,6 +2013,8 @@ Example: await ${collectionName}.list({ limit: 100, sort: '-created_at' })`,
|
|
|
1880
2013
|
"files": "UploadFile",
|
|
1881
2014
|
"files/private": "UploadPrivateFile",
|
|
1882
2015
|
"files/signed-url": "CreateFileSignedUrl",
|
|
2016
|
+
"files/private/download": "DownloadPrivateFile",
|
|
2017
|
+
"files/download": "DownloadFile",
|
|
1883
2018
|
"images": "GenerateImage",
|
|
1884
2019
|
"speech": "GenerateSpeech",
|
|
1885
2020
|
"video": "GenerateVideo",
|