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