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