@blinkdotnew/dev-sdk 0.0.2 → 2.1.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 +163 -9
- package/dist/index.d.ts +163 -9
- package/dist/index.js +304 -137
- package/dist/index.mjs +302 -138
- package/package.json +5 -3
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,33 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
5
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
+
// ../core/src/platform.ts
|
|
9
|
+
function detectPlatform() {
|
|
10
|
+
if (typeof Deno !== "undefined") {
|
|
11
|
+
return "deno";
|
|
12
|
+
}
|
|
13
|
+
if (typeof process !== "undefined" && process.versions?.node) {
|
|
14
|
+
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
15
|
+
return "react-native";
|
|
16
|
+
}
|
|
17
|
+
return "node";
|
|
18
|
+
}
|
|
19
|
+
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
20
|
+
return "react-native";
|
|
21
|
+
}
|
|
22
|
+
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
23
|
+
return "web";
|
|
24
|
+
}
|
|
25
|
+
return "node";
|
|
26
|
+
}
|
|
27
|
+
var platform = detectPlatform();
|
|
28
|
+
var isWeb = platform === "web";
|
|
29
|
+
var isReactNative = platform === "react-native";
|
|
30
|
+
var isNode = platform === "node";
|
|
31
|
+
var isDeno = platform === "deno";
|
|
32
|
+
var isBrowser = isWeb || isReactNative;
|
|
33
|
+
var isServer = isNode || isDeno;
|
|
34
|
+
|
|
8
35
|
// ../core/src/storage-adapter.ts
|
|
9
36
|
var WebStorageAdapter = class {
|
|
10
37
|
getItem(key) {
|
|
@@ -90,6 +117,9 @@ var NoOpStorageAdapter = class {
|
|
|
90
117
|
}
|
|
91
118
|
};
|
|
92
119
|
function getDefaultStorageAdapter() {
|
|
120
|
+
if (isDeno) {
|
|
121
|
+
return new NoOpStorageAdapter();
|
|
122
|
+
}
|
|
93
123
|
if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
|
|
94
124
|
try {
|
|
95
125
|
localStorage.setItem("__test__", "test");
|
|
@@ -101,28 +131,6 @@ function getDefaultStorageAdapter() {
|
|
|
101
131
|
return new NoOpStorageAdapter();
|
|
102
132
|
}
|
|
103
133
|
|
|
104
|
-
// ../core/src/platform.ts
|
|
105
|
-
function detectPlatform() {
|
|
106
|
-
if (typeof process !== "undefined" && process.versions?.node) {
|
|
107
|
-
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
108
|
-
return "react-native";
|
|
109
|
-
}
|
|
110
|
-
return "node";
|
|
111
|
-
}
|
|
112
|
-
if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
|
|
113
|
-
return "react-native";
|
|
114
|
-
}
|
|
115
|
-
if (typeof window !== "undefined" && typeof document !== "undefined") {
|
|
116
|
-
return "web";
|
|
117
|
-
}
|
|
118
|
-
return "node";
|
|
119
|
-
}
|
|
120
|
-
var platform = detectPlatform();
|
|
121
|
-
var isWeb = platform === "web";
|
|
122
|
-
var isReactNative = platform === "react-native";
|
|
123
|
-
var isNode = platform === "node";
|
|
124
|
-
var isBrowser = isWeb || isReactNative;
|
|
125
|
-
|
|
126
134
|
// ../core/src/types.ts
|
|
127
135
|
var BlinkError = class extends Error {
|
|
128
136
|
constructor(message, code, status, details) {
|
|
@@ -386,17 +394,44 @@ function convertKeysToCamelCase(obj) {
|
|
|
386
394
|
return converted;
|
|
387
395
|
}
|
|
388
396
|
var HttpClient = class {
|
|
389
|
-
authUrl;
|
|
390
|
-
coreUrl;
|
|
397
|
+
authUrl = "https://blink.new";
|
|
398
|
+
coreUrl = "https://core.blink.new";
|
|
391
399
|
projectId;
|
|
400
|
+
publishableKey;
|
|
401
|
+
secretKey;
|
|
402
|
+
// Permanent, non-expiring key (like Stripe's sk_live_...)
|
|
392
403
|
getToken;
|
|
393
404
|
getValidToken;
|
|
394
405
|
constructor(config, getToken, getValidToken) {
|
|
395
406
|
this.projectId = config.projectId;
|
|
407
|
+
this.publishableKey = config.publishableKey;
|
|
408
|
+
this.secretKey = config.secretKey || config.serviceToken;
|
|
396
409
|
this.getToken = getToken;
|
|
397
410
|
this.getValidToken = getValidToken;
|
|
398
|
-
|
|
399
|
-
|
|
411
|
+
}
|
|
412
|
+
shouldAttachPublishableKey(path, method) {
|
|
413
|
+
if (method !== "GET" && method !== "POST") return false;
|
|
414
|
+
if (path.includes("/api/analytics/")) return true;
|
|
415
|
+
if (path.includes("/api/storage/")) return true;
|
|
416
|
+
if (path.includes("/api/db/") && path.includes("/rest/v1/")) return method === "GET";
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
shouldSkipSecretKey(url) {
|
|
420
|
+
try {
|
|
421
|
+
const parsed = new URL(url);
|
|
422
|
+
return parsed.hostname.endsWith(".functions.blink.new");
|
|
423
|
+
} catch {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
getAuthorizationHeader(url, token) {
|
|
428
|
+
if (this.secretKey && !this.shouldSkipSecretKey(url)) {
|
|
429
|
+
return `Bearer ${this.secretKey}`;
|
|
430
|
+
}
|
|
431
|
+
if (token) {
|
|
432
|
+
return `Bearer ${token}`;
|
|
433
|
+
}
|
|
434
|
+
return null;
|
|
400
435
|
}
|
|
401
436
|
/**
|
|
402
437
|
* Make an authenticated request to the Blink API
|
|
@@ -404,19 +439,23 @@ var HttpClient = class {
|
|
|
404
439
|
async request(path, options = {}) {
|
|
405
440
|
const url = this.buildUrl(path, options.searchParams);
|
|
406
441
|
const token = this.getValidToken ? await this.getValidToken() : this.getToken();
|
|
442
|
+
const method = options.method || "GET";
|
|
407
443
|
const headers = {
|
|
408
444
|
"Content-Type": "application/json",
|
|
409
445
|
...options.headers
|
|
410
446
|
};
|
|
411
|
-
|
|
412
|
-
|
|
447
|
+
const auth = this.getAuthorizationHeader(url, token);
|
|
448
|
+
if (auth) {
|
|
449
|
+
headers.Authorization = auth;
|
|
450
|
+
} else if (this.publishableKey && !headers["x-blink-publishable-key"] && this.shouldAttachPublishableKey(path, method)) {
|
|
451
|
+
headers["x-blink-publishable-key"] = this.publishableKey;
|
|
413
452
|
}
|
|
414
453
|
const requestInit = {
|
|
415
|
-
method
|
|
454
|
+
method,
|
|
416
455
|
headers,
|
|
417
456
|
signal: options.signal
|
|
418
457
|
};
|
|
419
|
-
if (options.body &&
|
|
458
|
+
if (options.body && method !== "GET") {
|
|
420
459
|
requestInit.body = typeof options.body === "string" ? options.body : JSON.stringify(options.body);
|
|
421
460
|
}
|
|
422
461
|
try {
|
|
@@ -570,12 +609,12 @@ var HttpClient = class {
|
|
|
570
609
|
throw new BlinkValidationError("Unsupported file type");
|
|
571
610
|
}
|
|
572
611
|
formData.append("path", filePath);
|
|
573
|
-
if (options.upsert !== void 0) {
|
|
574
|
-
formData.append("options", JSON.stringify({ upsert: options.upsert }));
|
|
575
|
-
}
|
|
576
612
|
const headers = {};
|
|
577
|
-
|
|
578
|
-
|
|
613
|
+
const auth = this.getAuthorizationHeader(url, token);
|
|
614
|
+
if (auth) {
|
|
615
|
+
headers.Authorization = auth;
|
|
616
|
+
} else if (this.publishableKey && path.includes("/api/storage/") && !headers["x-blink-publishable-key"]) {
|
|
617
|
+
headers["x-blink-publishable-key"] = this.publishableKey;
|
|
579
618
|
}
|
|
580
619
|
try {
|
|
581
620
|
if (typeof XMLHttpRequest !== "undefined" && options.onProgress) {
|
|
@@ -676,7 +715,7 @@ var HttpClient = class {
|
|
|
676
715
|
});
|
|
677
716
|
}
|
|
678
717
|
/**
|
|
679
|
-
* Stream AI text generation
|
|
718
|
+
* Stream AI text generation - uses Vercel AI SDK's pipeUIMessageStreamToResponse (Data Stream Protocol)
|
|
680
719
|
*/
|
|
681
720
|
async streamAiText(prompt, options = {}, onChunk) {
|
|
682
721
|
const url = this.buildUrl(`/api/ai/${this.projectId}/text`);
|
|
@@ -684,9 +723,8 @@ var HttpClient = class {
|
|
|
684
723
|
const headers = {
|
|
685
724
|
"Content-Type": "application/json"
|
|
686
725
|
};
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
726
|
+
const auth = this.getAuthorizationHeader(url, token);
|
|
727
|
+
if (auth) headers.Authorization = auth;
|
|
690
728
|
const body = {
|
|
691
729
|
prompt,
|
|
692
730
|
stream: true,
|
|
@@ -706,7 +744,7 @@ var HttpClient = class {
|
|
|
706
744
|
if (!response.body) {
|
|
707
745
|
throw new BlinkNetworkError("No response body for streaming");
|
|
708
746
|
}
|
|
709
|
-
return this.
|
|
747
|
+
return this.parseDataStreamProtocol(response.body, onChunk);
|
|
710
748
|
} catch (error) {
|
|
711
749
|
if (error instanceof BlinkError) {
|
|
712
750
|
throw error;
|
|
@@ -731,7 +769,7 @@ var HttpClient = class {
|
|
|
731
769
|
});
|
|
732
770
|
}
|
|
733
771
|
/**
|
|
734
|
-
* Stream AI object generation
|
|
772
|
+
* Stream AI object generation - uses Vercel AI SDK's pipeTextStreamToResponse
|
|
735
773
|
*/
|
|
736
774
|
async streamAiObject(prompt, options = {}, onPartial) {
|
|
737
775
|
const url = this.buildUrl(`/api/ai/${this.projectId}/object`);
|
|
@@ -739,9 +777,8 @@ var HttpClient = class {
|
|
|
739
777
|
const headers = {
|
|
740
778
|
"Content-Type": "application/json"
|
|
741
779
|
};
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
}
|
|
780
|
+
const auth = this.getAuthorizationHeader(url, token);
|
|
781
|
+
if (auth) headers.Authorization = auth;
|
|
745
782
|
const body = {
|
|
746
783
|
prompt,
|
|
747
784
|
stream: true,
|
|
@@ -761,7 +798,35 @@ var HttpClient = class {
|
|
|
761
798
|
if (!response.body) {
|
|
762
799
|
throw new BlinkNetworkError("No response body for streaming");
|
|
763
800
|
}
|
|
764
|
-
|
|
801
|
+
const reader = response.body.getReader();
|
|
802
|
+
const decoder = new TextDecoder();
|
|
803
|
+
let buffer = "";
|
|
804
|
+
let latestObject = {};
|
|
805
|
+
try {
|
|
806
|
+
while (true) {
|
|
807
|
+
const { done, value } = await reader.read();
|
|
808
|
+
if (done) break;
|
|
809
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
810
|
+
buffer += chunk;
|
|
811
|
+
try {
|
|
812
|
+
const parsed = JSON.parse(buffer);
|
|
813
|
+
latestObject = parsed;
|
|
814
|
+
if (onPartial) {
|
|
815
|
+
onPartial(parsed);
|
|
816
|
+
}
|
|
817
|
+
} catch {
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
if (buffer) {
|
|
821
|
+
try {
|
|
822
|
+
latestObject = JSON.parse(buffer);
|
|
823
|
+
} catch {
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
return { object: latestObject };
|
|
827
|
+
} finally {
|
|
828
|
+
reader.releaseLock();
|
|
829
|
+
}
|
|
765
830
|
} catch (error) {
|
|
766
831
|
if (error instanceof BlinkError) {
|
|
767
832
|
throw error;
|
|
@@ -859,6 +924,38 @@ var HttpClient = class {
|
|
|
859
924
|
async dataSearch(projectId, request) {
|
|
860
925
|
return this.post(`/api/data/${projectId}/search`, request);
|
|
861
926
|
}
|
|
927
|
+
/**
|
|
928
|
+
* Connector requests
|
|
929
|
+
*/
|
|
930
|
+
formatProviderForPath(provider) {
|
|
931
|
+
return provider.replace("_", "-");
|
|
932
|
+
}
|
|
933
|
+
async connectorStatus(provider) {
|
|
934
|
+
return this.request(`/api/connectors/${this.formatProviderForPath(provider)}/${this.projectId}/status`, {
|
|
935
|
+
method: "GET"
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
async connectorExecute(provider, request) {
|
|
939
|
+
const path = request.method.startsWith("/") ? request.method : `/${request.method}`;
|
|
940
|
+
const url = `/api/connectors/${this.formatProviderForPath(provider)}/${this.projectId}${path}`;
|
|
941
|
+
const method = (request.http_method || "GET").toUpperCase();
|
|
942
|
+
if (method === "GET") {
|
|
943
|
+
return this.request(url, {
|
|
944
|
+
method: "GET",
|
|
945
|
+
searchParams: request.params
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
return this.request(url, {
|
|
949
|
+
method,
|
|
950
|
+
body: request.params || {}
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
async connectorSaveApiKey(provider, request) {
|
|
954
|
+
return this.request(`/api/connectors/${this.formatProviderForPath(provider)}/${this.projectId}/api-key`, {
|
|
955
|
+
method: "POST",
|
|
956
|
+
body: request
|
|
957
|
+
});
|
|
958
|
+
}
|
|
862
959
|
/**
|
|
863
960
|
* Realtime-specific requests
|
|
864
961
|
*/
|
|
@@ -924,93 +1021,94 @@ var HttpClient = class {
|
|
|
924
1021
|
}
|
|
925
1022
|
}
|
|
926
1023
|
/**
|
|
927
|
-
* Parse Vercel AI SDK
|
|
928
|
-
*
|
|
1024
|
+
* Parse Vercel AI SDK v5 Data Stream Protocol (Server-Sent Events)
|
|
1025
|
+
* Supports all event types from the UI Message Stream protocol
|
|
929
1026
|
*/
|
|
930
|
-
async
|
|
1027
|
+
async parseDataStreamProtocol(body, onChunk) {
|
|
931
1028
|
const reader = body.getReader();
|
|
932
1029
|
const decoder = new TextDecoder();
|
|
1030
|
+
const finalResult = {
|
|
1031
|
+
text: "",
|
|
1032
|
+
toolCalls: [],
|
|
1033
|
+
toolResults: [],
|
|
1034
|
+
sources: [],
|
|
1035
|
+
files: [],
|
|
1036
|
+
reasoning: []
|
|
1037
|
+
};
|
|
933
1038
|
let buffer = "";
|
|
934
|
-
let finalResult = {};
|
|
935
1039
|
try {
|
|
936
1040
|
while (true) {
|
|
937
1041
|
const { done, value } = await reader.read();
|
|
938
1042
|
if (done) break;
|
|
939
1043
|
buffer += decoder.decode(value, { stream: true });
|
|
940
|
-
const lines = buffer.split(
|
|
1044
|
+
const lines = buffer.split("\n");
|
|
941
1045
|
buffer = lines.pop() || "";
|
|
942
1046
|
for (const line of lines) {
|
|
943
1047
|
if (!line.trim()) continue;
|
|
1048
|
+
if (line === "[DONE]") {
|
|
1049
|
+
continue;
|
|
1050
|
+
}
|
|
1051
|
+
if (!line.startsWith("data: ")) continue;
|
|
944
1052
|
try {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
} else if (line.startsWith("2:")) {
|
|
955
|
-
const data = JSON.parse(line.slice(2));
|
|
956
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
957
|
-
const item = data[0];
|
|
958
|
-
if (typeof item === "string") {
|
|
959
|
-
finalResult.status = item;
|
|
960
|
-
} else if (typeof item === "object") {
|
|
961
|
-
if (onPartial) {
|
|
962
|
-
onPartial(item);
|
|
963
|
-
}
|
|
964
|
-
finalResult.object = item;
|
|
1053
|
+
const jsonStr = line.slice(6);
|
|
1054
|
+
const part = JSON.parse(jsonStr);
|
|
1055
|
+
switch (part.type) {
|
|
1056
|
+
case "text-start":
|
|
1057
|
+
break;
|
|
1058
|
+
case "text-delta":
|
|
1059
|
+
if (part.delta) {
|
|
1060
|
+
finalResult.text += part.delta;
|
|
1061
|
+
if (onChunk) onChunk(part.delta);
|
|
965
1062
|
}
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
if (metadata.usage) {
|
|
970
|
-
finalResult.usage = metadata.usage;
|
|
971
|
-
}
|
|
972
|
-
if (metadata.finishReason) {
|
|
973
|
-
finalResult.finishReason = metadata.finishReason;
|
|
974
|
-
}
|
|
975
|
-
} else if (line.startsWith("e:")) {
|
|
976
|
-
const errorData = JSON.parse(line.slice(2));
|
|
977
|
-
finalResult.error = errorData;
|
|
978
|
-
}
|
|
979
|
-
} catch (error) {
|
|
980
|
-
console.warn("Failed to parse stream line:", line, error);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
if (buffer.trim()) {
|
|
985
|
-
try {
|
|
986
|
-
if (buffer.startsWith("0:")) {
|
|
987
|
-
const textChunk = JSON.parse(buffer.slice(2));
|
|
988
|
-
if (onChunk) {
|
|
989
|
-
onChunk(textChunk);
|
|
990
|
-
}
|
|
991
|
-
finalResult.text = (finalResult.text || "") + textChunk;
|
|
992
|
-
} else if (buffer.startsWith("2:")) {
|
|
993
|
-
const data = JSON.parse(buffer.slice(2));
|
|
994
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
995
|
-
const item = data[0];
|
|
996
|
-
if (typeof item === "object") {
|
|
997
|
-
if (onPartial) {
|
|
998
|
-
onPartial(item);
|
|
1063
|
+
if (part.textDelta) {
|
|
1064
|
+
finalResult.text += part.textDelta;
|
|
1065
|
+
if (onChunk) onChunk(part.textDelta);
|
|
999
1066
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1067
|
+
break;
|
|
1068
|
+
case "text-end":
|
|
1069
|
+
break;
|
|
1070
|
+
case "tool-call":
|
|
1071
|
+
finalResult.toolCalls.push({
|
|
1072
|
+
toolCallId: part.toolCallId,
|
|
1073
|
+
toolName: part.toolName,
|
|
1074
|
+
args: part.args
|
|
1075
|
+
});
|
|
1076
|
+
break;
|
|
1077
|
+
case "tool-result":
|
|
1078
|
+
finalResult.toolResults.push({
|
|
1079
|
+
toolCallId: part.toolCallId,
|
|
1080
|
+
toolName: part.toolName,
|
|
1081
|
+
result: part.result
|
|
1082
|
+
});
|
|
1083
|
+
break;
|
|
1084
|
+
case "source-url":
|
|
1085
|
+
finalResult.sources.push({
|
|
1086
|
+
id: part.id,
|
|
1087
|
+
url: part.url,
|
|
1088
|
+
title: part.title
|
|
1089
|
+
});
|
|
1090
|
+
break;
|
|
1091
|
+
case "file":
|
|
1092
|
+
finalResult.files.push(part.file);
|
|
1093
|
+
break;
|
|
1094
|
+
case "reasoning":
|
|
1095
|
+
finalResult.reasoning.push(part.content);
|
|
1096
|
+
break;
|
|
1097
|
+
case "finish":
|
|
1098
|
+
finalResult.finishReason = part.finishReason;
|
|
1099
|
+
finalResult.usage = part.usage;
|
|
1100
|
+
if (part.response) finalResult.response = part.response;
|
|
1101
|
+
break;
|
|
1102
|
+
case "error":
|
|
1103
|
+
finalResult.error = part.error;
|
|
1104
|
+
throw new Error(part.error);
|
|
1105
|
+
case "data":
|
|
1106
|
+
if (!finalResult.customData) finalResult.customData = [];
|
|
1107
|
+
finalResult.customData.push(part.value);
|
|
1108
|
+
break;
|
|
1010
1109
|
}
|
|
1110
|
+
} catch (e) {
|
|
1011
1111
|
}
|
|
1012
|
-
} catch (error) {
|
|
1013
|
-
console.warn("Failed to parse final buffer:", buffer, error);
|
|
1014
1112
|
}
|
|
1015
1113
|
}
|
|
1016
1114
|
return finalResult;
|
|
@@ -2937,6 +3035,11 @@ var BlinkAuth = class {
|
|
|
2937
3035
|
};
|
|
2938
3036
|
|
|
2939
3037
|
// src/database.ts
|
|
3038
|
+
function assertServerOnly(methodName) {
|
|
3039
|
+
if (typeof window !== "undefined") {
|
|
3040
|
+
throw new Error(`${methodName} is server-only. Use Blink CRUD methods (blink.db.<table>.*) instead.`);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
2940
3043
|
function camelToSnake3(str) {
|
|
2941
3044
|
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
2942
3045
|
}
|
|
@@ -3155,6 +3258,7 @@ var BlinkTable = class {
|
|
|
3155
3258
|
* Raw SQL query on this table (for advanced use cases)
|
|
3156
3259
|
*/
|
|
3157
3260
|
async sql(query, params) {
|
|
3261
|
+
assertServerOnly("blink.db.<table>.sql");
|
|
3158
3262
|
const response = await this.httpClient.dbSql(query, params);
|
|
3159
3263
|
return response.data;
|
|
3160
3264
|
}
|
|
@@ -3203,6 +3307,7 @@ var BlinkDatabase = class {
|
|
|
3203
3307
|
* Execute raw SQL query
|
|
3204
3308
|
*/
|
|
3205
3309
|
async sql(query, params) {
|
|
3310
|
+
assertServerOnly("blink.db.sql");
|
|
3206
3311
|
const response = await this.httpClient.dbSql(query, params);
|
|
3207
3312
|
return response.data;
|
|
3208
3313
|
}
|
|
@@ -3210,6 +3315,7 @@ var BlinkDatabase = class {
|
|
|
3210
3315
|
* Execute batch SQL operations
|
|
3211
3316
|
*/
|
|
3212
3317
|
async batch(statements, mode = "write") {
|
|
3318
|
+
assertServerOnly("blink.db.batch");
|
|
3213
3319
|
const response = await this.httpClient.dbBatch(statements, mode);
|
|
3214
3320
|
return response.data;
|
|
3215
3321
|
}
|
|
@@ -3272,7 +3378,6 @@ var BlinkStorageImpl = class {
|
|
|
3272
3378
|
correctedPath,
|
|
3273
3379
|
// Use corrected path with proper extension
|
|
3274
3380
|
{
|
|
3275
|
-
upsert: options.upsert,
|
|
3276
3381
|
onProgress: options.onProgress,
|
|
3277
3382
|
contentType: detectedContentType
|
|
3278
3383
|
// Pass detected content type
|
|
@@ -3292,7 +3397,7 @@ var BlinkStorageImpl = class {
|
|
|
3292
3397
|
if (error instanceof Error && "status" in error) {
|
|
3293
3398
|
const status = error.status;
|
|
3294
3399
|
if (status === 409) {
|
|
3295
|
-
throw new BlinkStorageError("File already exists.
|
|
3400
|
+
throw new BlinkStorageError("File already exists.", 409);
|
|
3296
3401
|
}
|
|
3297
3402
|
if (status === 400) {
|
|
3298
3403
|
throw new BlinkStorageError("Invalid request parameters", 400);
|
|
@@ -3337,7 +3442,6 @@ var BlinkStorageImpl = class {
|
|
|
3337
3442
|
detectedContentType
|
|
3338
3443
|
};
|
|
3339
3444
|
} catch (error) {
|
|
3340
|
-
console.warn("File type detection failed, using original path:", error);
|
|
3341
3445
|
return {
|
|
3342
3446
|
correctedPath: originalPath,
|
|
3343
3447
|
detectedContentType: "application/octet-stream"
|
|
@@ -3727,13 +3831,7 @@ var BlinkAIImpl = class {
|
|
|
3727
3831
|
options.prompt || "",
|
|
3728
3832
|
requestBody
|
|
3729
3833
|
);
|
|
3730
|
-
|
|
3731
|
-
return response.data.result;
|
|
3732
|
-
} else if (response.data?.text) {
|
|
3733
|
-
return response.data;
|
|
3734
|
-
} else {
|
|
3735
|
-
throw new BlinkAIError("Invalid response format: missing text");
|
|
3736
|
-
}
|
|
3834
|
+
return response.data;
|
|
3737
3835
|
} catch (error) {
|
|
3738
3836
|
if (error instanceof BlinkAIError) {
|
|
3739
3837
|
throw error;
|
|
@@ -3802,9 +3900,14 @@ var BlinkAIImpl = class {
|
|
|
3802
3900
|
);
|
|
3803
3901
|
return {
|
|
3804
3902
|
text: result.text || "",
|
|
3805
|
-
finishReason: "stop",
|
|
3903
|
+
finishReason: result.finishReason || "stop",
|
|
3806
3904
|
usage: result.usage,
|
|
3807
|
-
|
|
3905
|
+
toolCalls: result.toolCalls,
|
|
3906
|
+
toolResults: result.toolResults,
|
|
3907
|
+
sources: result.sources,
|
|
3908
|
+
files: result.files,
|
|
3909
|
+
reasoningDetails: result.reasoning,
|
|
3910
|
+
response: result.response
|
|
3808
3911
|
};
|
|
3809
3912
|
} catch (error) {
|
|
3810
3913
|
if (error instanceof BlinkAIError) {
|
|
@@ -3883,13 +3986,7 @@ var BlinkAIImpl = class {
|
|
|
3883
3986
|
signal: options.signal
|
|
3884
3987
|
}
|
|
3885
3988
|
);
|
|
3886
|
-
|
|
3887
|
-
return response.data.result;
|
|
3888
|
-
} else if (response.data?.object) {
|
|
3889
|
-
return response.data;
|
|
3890
|
-
} else {
|
|
3891
|
-
throw new BlinkAIError("Invalid response format: missing object");
|
|
3892
|
-
}
|
|
3989
|
+
return response.data;
|
|
3893
3990
|
} catch (error) {
|
|
3894
3991
|
if (error instanceof BlinkAIError) {
|
|
3895
3992
|
throw error;
|
|
@@ -3951,8 +4048,7 @@ var BlinkAIImpl = class {
|
|
|
3951
4048
|
return {
|
|
3952
4049
|
object: result.object || {},
|
|
3953
4050
|
finishReason: "stop",
|
|
3954
|
-
usage: result.usage
|
|
3955
|
-
...result
|
|
4051
|
+
usage: result.usage
|
|
3956
4052
|
};
|
|
3957
4053
|
} catch (error) {
|
|
3958
4054
|
if (error instanceof BlinkAIError) {
|
|
@@ -5271,7 +5367,6 @@ var BlinkAnalyticsImpl = class {
|
|
|
5271
5367
|
} catch (error) {
|
|
5272
5368
|
this.queue = [...events, ...this.queue];
|
|
5273
5369
|
this.persistQueue();
|
|
5274
|
-
console.error("Failed to send analytics events:", error);
|
|
5275
5370
|
}
|
|
5276
5371
|
if (this.queue.length > 0) {
|
|
5277
5372
|
this.timer = setTimeout(() => this.flush(), BATCH_TIMEOUT);
|
|
@@ -5462,6 +5557,64 @@ var BlinkAnalyticsImpl = class {
|
|
|
5462
5557
|
}
|
|
5463
5558
|
};
|
|
5464
5559
|
|
|
5560
|
+
// src/connectors.ts
|
|
5561
|
+
var BlinkConnectorsImpl = class {
|
|
5562
|
+
constructor(httpClient) {
|
|
5563
|
+
this.httpClient = httpClient;
|
|
5564
|
+
}
|
|
5565
|
+
async status(provider, options) {
|
|
5566
|
+
const response = await this.httpClient.connectorStatus(provider);
|
|
5567
|
+
return response.data;
|
|
5568
|
+
}
|
|
5569
|
+
async execute(provider, request) {
|
|
5570
|
+
const response = await this.httpClient.connectorExecute(provider, request);
|
|
5571
|
+
return response.data;
|
|
5572
|
+
}
|
|
5573
|
+
async saveApiKey(provider, request) {
|
|
5574
|
+
const response = await this.httpClient.connectorSaveApiKey(provider, request);
|
|
5575
|
+
return response.data;
|
|
5576
|
+
}
|
|
5577
|
+
};
|
|
5578
|
+
|
|
5579
|
+
// src/functions.ts
|
|
5580
|
+
var BlinkFunctionsImpl = class {
|
|
5581
|
+
httpClient;
|
|
5582
|
+
projectId;
|
|
5583
|
+
constructor(httpClient, projectId, _getToken) {
|
|
5584
|
+
this.httpClient = httpClient;
|
|
5585
|
+
this.projectId = projectId;
|
|
5586
|
+
}
|
|
5587
|
+
/**
|
|
5588
|
+
* Get the project suffix from the full project ID.
|
|
5589
|
+
* Project IDs are formatted as: prj_xxxxx
|
|
5590
|
+
* The suffix is the last 8 characters used in function URLs.
|
|
5591
|
+
*/
|
|
5592
|
+
getProjectSuffix() {
|
|
5593
|
+
return this.projectId.slice(-8);
|
|
5594
|
+
}
|
|
5595
|
+
/**
|
|
5596
|
+
* Build the full function URL
|
|
5597
|
+
*/
|
|
5598
|
+
buildFunctionUrl(functionSlug, searchParams) {
|
|
5599
|
+
const suffix = this.getProjectSuffix();
|
|
5600
|
+
const baseUrl = `https://${suffix}--${functionSlug}.functions.blink.new`;
|
|
5601
|
+
if (!searchParams || Object.keys(searchParams).length === 0) {
|
|
5602
|
+
return baseUrl;
|
|
5603
|
+
}
|
|
5604
|
+
const url = new URL(baseUrl);
|
|
5605
|
+
Object.entries(searchParams).forEach(([key, value]) => {
|
|
5606
|
+
url.searchParams.set(key, value);
|
|
5607
|
+
});
|
|
5608
|
+
return url.toString();
|
|
5609
|
+
}
|
|
5610
|
+
async invoke(functionSlug, options = {}) {
|
|
5611
|
+
const { method = "POST", body, headers = {}, searchParams } = options;
|
|
5612
|
+
const url = this.buildFunctionUrl(functionSlug, searchParams);
|
|
5613
|
+
const res = await this.httpClient.request(url, { method, body, headers });
|
|
5614
|
+
return { data: res.data, status: res.status, headers: res.headers };
|
|
5615
|
+
}
|
|
5616
|
+
};
|
|
5617
|
+
|
|
5465
5618
|
// src/client.ts
|
|
5466
5619
|
var BlinkClientImpl = class {
|
|
5467
5620
|
auth;
|
|
@@ -5472,8 +5625,13 @@ var BlinkClientImpl = class {
|
|
|
5472
5625
|
realtime;
|
|
5473
5626
|
notifications;
|
|
5474
5627
|
analytics;
|
|
5628
|
+
connectors;
|
|
5629
|
+
functions;
|
|
5475
5630
|
httpClient;
|
|
5476
5631
|
constructor(config) {
|
|
5632
|
+
if ((config.secretKey || config.serviceToken) && isBrowser) {
|
|
5633
|
+
throw new Error("secretKey/serviceToken is server-only. Do not provide it in browser/React Native clients.");
|
|
5634
|
+
}
|
|
5477
5635
|
this.auth = new BlinkAuth(config);
|
|
5478
5636
|
this.httpClient = new HttpClient(
|
|
5479
5637
|
config,
|
|
@@ -5487,6 +5645,12 @@ var BlinkClientImpl = class {
|
|
|
5487
5645
|
this.realtime = new BlinkRealtimeImpl(this.httpClient, config.projectId);
|
|
5488
5646
|
this.notifications = new BlinkNotificationsImpl(this.httpClient);
|
|
5489
5647
|
this.analytics = new BlinkAnalyticsImpl(this.httpClient, config.projectId);
|
|
5648
|
+
this.connectors = new BlinkConnectorsImpl(this.httpClient);
|
|
5649
|
+
this.functions = new BlinkFunctionsImpl(
|
|
5650
|
+
this.httpClient,
|
|
5651
|
+
config.projectId,
|
|
5652
|
+
() => this.auth.getValidToken()
|
|
5653
|
+
);
|
|
5490
5654
|
this.auth.onAuthStateChanged((state) => {
|
|
5491
5655
|
if (state.isAuthenticated && state.user) {
|
|
5492
5656
|
this.analytics.setUserId(state.user.id);
|
|
@@ -5505,6 +5669,6 @@ function createClient(config) {
|
|
|
5505
5669
|
return new BlinkClientImpl(config);
|
|
5506
5670
|
}
|
|
5507
5671
|
|
|
5508
|
-
export { AsyncStorageAdapter, BlinkAIImpl, BlinkAnalyticsImpl, BlinkDataImpl, BlinkDatabase, BlinkRealtimeChannel, BlinkRealtimeImpl, BlinkStorageImpl, BlinkTable, NoOpStorageAdapter, WebStorageAdapter, createClient, getDefaultStorageAdapter, isBrowser, isNode, isReactNative, isWeb, platform };
|
|
5672
|
+
export { AsyncStorageAdapter, BlinkAIImpl, BlinkAnalyticsImpl, BlinkConnectorsImpl, BlinkDataImpl, BlinkDatabase, BlinkRealtimeChannel, BlinkRealtimeImpl, BlinkStorageImpl, BlinkTable, NoOpStorageAdapter, WebStorageAdapter, createClient, getDefaultStorageAdapter, isBrowser, isDeno, isNode, isReactNative, isServer, isWeb, platform };
|
|
5509
5673
|
//# sourceMappingURL=index.mjs.map
|
|
5510
5674
|
//# sourceMappingURL=index.mjs.map
|