@gemigo/app-sdk 0.2.7 → 0.2.8
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/gemigo-app-sdk.es.js +287 -277
- package/dist/gemigo-app-sdk.umd.js +1 -1
- package/dist/types/cloud.d.ts +3 -12
- package/package.json +1 -1
|
@@ -2,81 +2,81 @@ import { i as tryGetHost, n as createRPCProxy, t as callHost } from "./connectio
|
|
|
2
2
|
function createEventBus() {
|
|
3
3
|
let f = /* @__PURE__ */ new Map();
|
|
4
4
|
return {
|
|
5
|
-
on(
|
|
6
|
-
return f.has(
|
|
5
|
+
on(V, H) {
|
|
6
|
+
return f.has(V) || f.set(V, /* @__PURE__ */ new Set()), f.get(V).add(H), () => f.get(V)?.delete(H);
|
|
7
7
|
},
|
|
8
|
-
emit(
|
|
9
|
-
f.get(
|
|
8
|
+
emit(V, ...H) {
|
|
9
|
+
f.get(V)?.forEach((f) => f(...H));
|
|
10
10
|
},
|
|
11
|
-
off(
|
|
12
|
-
|
|
11
|
+
off(V) {
|
|
12
|
+
V ? f.delete(V) : f.clear();
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
const sdkEventBus = createEventBus();
|
|
17
|
-
function createUnifiedAPI(
|
|
18
|
-
let
|
|
19
|
-
if (
|
|
20
|
-
let f = createRPCProxy(
|
|
21
|
-
mapping:
|
|
22
|
-
fallbacks:
|
|
17
|
+
function createUnifiedAPI(H) {
|
|
18
|
+
let U = tryGetHost, G = {}, K = {};
|
|
19
|
+
if (H.rpc) {
|
|
20
|
+
let f = createRPCProxy(H.rpc.methods, {
|
|
21
|
+
mapping: H.rpc.mapping,
|
|
22
|
+
fallbacks: H.rpc.fallbacks
|
|
23
23
|
});
|
|
24
|
-
Object.assign(
|
|
24
|
+
Object.assign(G, f);
|
|
25
25
|
}
|
|
26
|
-
if (
|
|
27
|
-
let
|
|
28
|
-
|
|
29
|
-
sdkEventBus.emit(
|
|
26
|
+
if (H.events) if (Array.isArray(H.events)) for (let f of H.events) {
|
|
27
|
+
let V = f;
|
|
28
|
+
G[f] = (f) => (U?.(), sdkEventBus.on(V, f)), K[f] = (...f) => {
|
|
29
|
+
sdkEventBus.emit(V, ...f);
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
else for (let [f,
|
|
33
|
-
if (!
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
sdkEventBus.emit(
|
|
32
|
+
else for (let [f, V] of Object.entries(H.events)) {
|
|
33
|
+
if (!V) continue;
|
|
34
|
+
let H = V, q = typeof H == "string" ? H : H.event, J = typeof H == "object" && "childMethod" in H && H.childMethod ? H.childMethod : f;
|
|
35
|
+
G[f] = (f) => (U?.(), sdkEventBus.on(q, f)), K[J] = (...f) => {
|
|
36
|
+
sdkEventBus.emit(q, ...f);
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
return {
|
|
40
|
-
api:
|
|
41
|
-
childMethods:
|
|
40
|
+
api: G,
|
|
41
|
+
childMethods: K
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
-
function createRPCAction(f,
|
|
45
|
-
return async (...
|
|
44
|
+
function createRPCAction(f, V) {
|
|
45
|
+
return async (...U) => {
|
|
46
46
|
try {
|
|
47
|
-
let
|
|
48
|
-
return
|
|
47
|
+
let W = await callHost(f, V.transform ? V.transform(...U) : U);
|
|
48
|
+
return V.onSuccess ? V.onSuccess(W) : W;
|
|
49
49
|
} catch {
|
|
50
|
-
return
|
|
50
|
+
return V.fallback(...U);
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
function createSDK(f) {
|
|
55
|
-
let
|
|
56
|
-
if (f.modules) for (let [
|
|
57
|
-
let { api: f, childMethods:
|
|
58
|
-
|
|
55
|
+
let V = f.statics ? { ...f.statics } : {}, H = {};
|
|
56
|
+
if (f.modules) for (let [U, W] of Object.entries(f.modules)) {
|
|
57
|
+
let { api: f, childMethods: K } = createUnifiedAPI(W);
|
|
58
|
+
V[U] = f, Object.assign(H, K);
|
|
59
59
|
}
|
|
60
|
-
if (f.actions) for (let [
|
|
61
|
-
let f =
|
|
62
|
-
|
|
60
|
+
if (f.actions) for (let [H, U] of Object.entries(f.actions)) {
|
|
61
|
+
let f = U;
|
|
62
|
+
V[H] = createRPCAction(f.method, f);
|
|
63
63
|
}
|
|
64
|
-
if (f.getters) for (let [
|
|
65
|
-
get:
|
|
64
|
+
if (f.getters) for (let [H, U] of Object.entries(f.getters)) Object.defineProperty(V, H, {
|
|
65
|
+
get: U,
|
|
66
66
|
enumerable: !0,
|
|
67
67
|
configurable: !0
|
|
68
68
|
});
|
|
69
69
|
return {
|
|
70
|
-
sdk:
|
|
71
|
-
childMethods:
|
|
70
|
+
sdk: V,
|
|
71
|
+
childMethods: H
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
-
async function bootstrapSDK(
|
|
75
|
-
let { initConnection:
|
|
76
|
-
|
|
77
|
-
let
|
|
78
|
-
if (
|
|
79
|
-
return await
|
|
74
|
+
async function bootstrapSDK(V, H = {}) {
|
|
75
|
+
let { initConnection: U } = await import("./connection-C-IGR2wz.js");
|
|
76
|
+
U(V, H);
|
|
77
|
+
let W = await tryGetHost();
|
|
78
|
+
if (W && typeof W.getProtocolInfo == "function") try {
|
|
79
|
+
return await W.getProtocolInfo();
|
|
80
80
|
} catch {
|
|
81
81
|
return null;
|
|
82
82
|
}
|
|
@@ -86,16 +86,16 @@ var localStoragePrefix = () => `gemigo:${typeof window > "u" ? "unknown" : windo
|
|
|
86
86
|
const fallbackStorage = {
|
|
87
87
|
get: async (f) => {
|
|
88
88
|
if (typeof window > "u" || !window.localStorage) return null;
|
|
89
|
-
let
|
|
90
|
-
if (!
|
|
89
|
+
let V = window.localStorage.getItem(`${localStoragePrefix()}${f}`);
|
|
90
|
+
if (!V) return null;
|
|
91
91
|
try {
|
|
92
|
-
return JSON.parse(
|
|
92
|
+
return JSON.parse(V);
|
|
93
93
|
} catch {
|
|
94
94
|
return null;
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
|
-
set: async (f,
|
|
98
|
-
typeof window > "u" || !window.localStorage || window.localStorage.setItem(`${localStoragePrefix()}${f}`, JSON.stringify(
|
|
97
|
+
set: async (f, V) => {
|
|
98
|
+
typeof window > "u" || !window.localStorage || window.localStorage.setItem(`${localStoragePrefix()}${f}`, JSON.stringify(V));
|
|
99
99
|
},
|
|
100
100
|
delete: async (f) => {
|
|
101
101
|
typeof window > "u" || !window.localStorage || window.localStorage.removeItem(`${localStoragePrefix()}${f}`);
|
|
@@ -103,9 +103,9 @@ const fallbackStorage = {
|
|
|
103
103
|
clear: async () => {
|
|
104
104
|
if (typeof window > "u" || !window.localStorage) return;
|
|
105
105
|
let f = localStoragePrefix();
|
|
106
|
-
for (let
|
|
107
|
-
let
|
|
108
|
-
|
|
106
|
+
for (let V = window.localStorage.length - 1; V >= 0; --V) {
|
|
107
|
+
let H = window.localStorage.key(V);
|
|
108
|
+
H && H.startsWith(f) && window.localStorage.removeItem(H);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}, fallbackNotify = async (f) => {
|
|
@@ -128,39 +128,39 @@ const fallbackStorage = {
|
|
|
128
128
|
reason: "failed_to_notify"
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
|
-
}, fallbackNetwork = { request: async (f,
|
|
132
|
-
let { method:
|
|
133
|
-
method:
|
|
134
|
-
headers:
|
|
135
|
-
body:
|
|
136
|
-
}),
|
|
137
|
-
|
|
138
|
-
let
|
|
131
|
+
}, fallbackNetwork = { request: async (f, V) => {
|
|
132
|
+
let { method: H = "GET", headers: U, body: W, responseType: G } = V ?? {}, K = await fetch(f, {
|
|
133
|
+
method: H,
|
|
134
|
+
headers: U,
|
|
135
|
+
body: W ? typeof W == "string" ? W : JSON.stringify(W) : void 0
|
|
136
|
+
}), q = {};
|
|
137
|
+
K.headers.forEach((f, V) => q[V] = f);
|
|
138
|
+
let J = G === "text" ? await K.text() : G === "arraybuffer" ? await K.arrayBuffer() : await K.json();
|
|
139
139
|
return {
|
|
140
|
-
status:
|
|
141
|
-
data:
|
|
142
|
-
headers:
|
|
140
|
+
status: K.status,
|
|
141
|
+
data: J,
|
|
142
|
+
headers: q
|
|
143
143
|
};
|
|
144
144
|
} };
|
|
145
145
|
var SDKError = class f extends Error {
|
|
146
|
-
constructor(
|
|
147
|
-
super(
|
|
146
|
+
constructor(V, H) {
|
|
147
|
+
super(H), this.code = V, this.name = "SDKError", Object.setPrototypeOf(this, f.prototype);
|
|
148
148
|
}
|
|
149
149
|
}, currentToken = null, currentApiBaseUrl = null;
|
|
150
150
|
function base64UrlEncode(f) {
|
|
151
|
-
let
|
|
152
|
-
for (let
|
|
153
|
-
let
|
|
154
|
-
if (!
|
|
155
|
-
return V
|
|
151
|
+
let V = "";
|
|
152
|
+
for (let H of f) V += String.fromCharCode(H);
|
|
153
|
+
let H = globalThis.btoa;
|
|
154
|
+
if (!H) throw Error("base64 encoder not available");
|
|
155
|
+
return H(V).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
156
156
|
}
|
|
157
157
|
function randomString(f = 32) {
|
|
158
|
-
let
|
|
159
|
-
return crypto.getRandomValues(
|
|
158
|
+
let V = new Uint8Array(f);
|
|
159
|
+
return crypto.getRandomValues(V), base64UrlEncode(V);
|
|
160
160
|
}
|
|
161
161
|
async function sha256Base64Url(f) {
|
|
162
|
-
let
|
|
163
|
-
return base64UrlEncode(new Uint8Array(
|
|
162
|
+
let V = new TextEncoder().encode(f), H = await crypto.subtle.digest("SHA-256", V);
|
|
163
|
+
return base64UrlEncode(new Uint8Array(H));
|
|
164
164
|
}
|
|
165
165
|
function deriveDefaultAppId() {
|
|
166
166
|
if (typeof window > "u") return "unknown";
|
|
@@ -168,27 +168,27 @@ function deriveDefaultAppId() {
|
|
|
168
168
|
return f.endsWith(".gemigo.app") ? f.replace(/\.gemigo\.app$/, "") : f;
|
|
169
169
|
}
|
|
170
170
|
function normalizeScopes(f) {
|
|
171
|
-
let
|
|
172
|
-
return
|
|
171
|
+
let V = (f ?? ["identity:basic"]).map((f) => String(f).trim()).filter(Boolean);
|
|
172
|
+
return V.length > 0 ? V : ["identity:basic"];
|
|
173
173
|
}
|
|
174
174
|
function buildBrokerUrl(f) {
|
|
175
|
-
let
|
|
176
|
-
return
|
|
175
|
+
let V = new URL("/sdk/broker", f.platformOrigin);
|
|
176
|
+
return V.searchParams.set("app_id", f.appId), V.searchParams.set("scope", f.scopes.join(" ")), V.searchParams.set("state", f.state), V.searchParams.set("code_challenge", f.codeChallenge), V.searchParams.set("code_challenge_method", "S256"), V.searchParams.set("origin", f.openerOrigin), V.toString();
|
|
177
177
|
}
|
|
178
|
-
async function exchangeCode(f,
|
|
179
|
-
let
|
|
178
|
+
async function exchangeCode(f, V, H) {
|
|
179
|
+
let U = await fetch(`${f.replace(/\/+$/, "")}/sdk/token`, {
|
|
180
180
|
method: "POST",
|
|
181
181
|
headers: { "Content-Type": "application/json" },
|
|
182
182
|
body: JSON.stringify({
|
|
183
|
-
code:
|
|
184
|
-
codeVerifier:
|
|
183
|
+
code: V,
|
|
184
|
+
codeVerifier: H
|
|
185
185
|
})
|
|
186
186
|
});
|
|
187
|
-
if (!
|
|
188
|
-
let f = await
|
|
187
|
+
if (!U.ok) {
|
|
188
|
+
let f = await U.json().catch(() => ({}));
|
|
189
189
|
throw Error(f.error || "Failed to exchange code");
|
|
190
190
|
}
|
|
191
|
-
return await
|
|
191
|
+
return await U.json();
|
|
192
192
|
}
|
|
193
193
|
function getWebApiBaseUrl() {
|
|
194
194
|
return currentApiBaseUrl || "https://gemigo.io/api/v1";
|
|
@@ -196,46 +196,46 @@ function getWebApiBaseUrl() {
|
|
|
196
196
|
const webAuth = {
|
|
197
197
|
async login(f = {}) {
|
|
198
198
|
if (typeof window > "u") throw new SDKError("NOT_SUPPORTED", "auth.login is only supported in browser environments.");
|
|
199
|
-
let
|
|
200
|
-
if (!
|
|
199
|
+
let V = f.platformOrigin?.trim() || "https://gemigo.io", H = f.apiBaseUrl?.trim() || `${V.replace(/\/+$/, "")}/api/v1`, U = f.appId?.trim() || deriveDefaultAppId(), W = normalizeScopes(f.scopes), G = typeof f.timeoutMs == "number" ? f.timeoutMs : 120 * 1e3, K = randomString(16), q = randomString(48), J = window.location.origin, Y = Math.max(0, (window.screen.width - 520) / 2), X = Math.max(0, (window.screen.height - 720) / 2), Z = window.open("about:blank", "gemigo_sdk_auth", `popup=yes,width=520,height=720,left=${Y},top=${X}`);
|
|
200
|
+
if (!Z) throw Error("Popup blocked. Please allow popups and retry.");
|
|
201
201
|
try {
|
|
202
|
-
|
|
202
|
+
Z.document.title = "GemiGo Auth", Z.document.body.innerHTML = "<div style=\"font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;padding:24px;\">Loading…</div>";
|
|
203
203
|
} catch {}
|
|
204
|
-
let
|
|
205
|
-
platformOrigin:
|
|
206
|
-
appId:
|
|
207
|
-
scopes:
|
|
208
|
-
state:
|
|
209
|
-
codeChallenge: await sha256Base64Url(
|
|
210
|
-
openerOrigin:
|
|
204
|
+
let Q = buildBrokerUrl({
|
|
205
|
+
platformOrigin: V,
|
|
206
|
+
appId: U,
|
|
207
|
+
scopes: W,
|
|
208
|
+
state: K,
|
|
209
|
+
codeChallenge: await sha256Base64Url(q),
|
|
210
|
+
openerOrigin: J
|
|
211
211
|
});
|
|
212
212
|
try {
|
|
213
|
-
|
|
213
|
+
Z.location.href = Q;
|
|
214
214
|
} catch {
|
|
215
|
-
if (!window.open(
|
|
215
|
+
if (!window.open(Q, "gemigo_sdk_auth")) throw Error("Popup navigation failed. Please allow popups and retry.");
|
|
216
216
|
}
|
|
217
|
-
let
|
|
218
|
-
let
|
|
219
|
-
|
|
220
|
-
},
|
|
221
|
-
window.clearTimeout(
|
|
217
|
+
let $ = await exchangeCode(H, (await new Promise((f, H) => {
|
|
218
|
+
let U = window.setTimeout(() => {
|
|
219
|
+
W(), H(/* @__PURE__ */ Error("Login timeout."));
|
|
220
|
+
}, G), W = () => {
|
|
221
|
+
window.clearTimeout(U), window.removeEventListener("message", q);
|
|
222
222
|
try {
|
|
223
|
-
|
|
223
|
+
Z.close();
|
|
224
224
|
} catch {}
|
|
225
|
-
},
|
|
226
|
-
if (
|
|
227
|
-
let
|
|
228
|
-
if (!(!
|
|
229
|
-
if (
|
|
230
|
-
|
|
225
|
+
}, q = (U) => {
|
|
226
|
+
if (U.origin !== new URL(V).origin) return;
|
|
227
|
+
let G = U.data;
|
|
228
|
+
if (!(!G || typeof G != "object") && G.state === K) {
|
|
229
|
+
if (G.type === "gemigo:sdk-auth-error") {
|
|
230
|
+
W(), H(Error(String(G.error || "auth_error")));
|
|
231
231
|
return;
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
G.type === "gemigo:sdk-auth-code" && typeof G.code == "string" && (W(), f({ code: G.code }));
|
|
234
234
|
}
|
|
235
235
|
};
|
|
236
|
-
window.addEventListener("message",
|
|
237
|
-
})).code,
|
|
238
|
-
return currentToken =
|
|
236
|
+
window.addEventListener("message", q);
|
|
237
|
+
})).code, q);
|
|
238
|
+
return currentToken = $, currentApiBaseUrl = H, $;
|
|
239
239
|
},
|
|
240
240
|
getAccessToken() {
|
|
241
241
|
return currentToken?.accessToken ?? null;
|
|
@@ -249,92 +249,92 @@ function requireAccessToken() {
|
|
|
249
249
|
if (!f) throw new SDKError("PERMISSION_DENIED", "Login required. Call gemigo.auth.login() first.");
|
|
250
250
|
return f;
|
|
251
251
|
}
|
|
252
|
-
async function fetchJson(f,
|
|
253
|
-
let
|
|
254
|
-
...
|
|
252
|
+
async function fetchJson(f, V = {}) {
|
|
253
|
+
let H = requireAccessToken(), U = getWebApiBaseUrl().replace(/\/+$/, ""), W = await fetch(`${U}${f}`, {
|
|
254
|
+
...V,
|
|
255
255
|
headers: {
|
|
256
|
-
...
|
|
257
|
-
Authorization: `Bearer ${
|
|
256
|
+
...V.headers ?? {},
|
|
257
|
+
Authorization: `Bearer ${H}`
|
|
258
258
|
}
|
|
259
259
|
});
|
|
260
|
-
if (!
|
|
261
|
-
let f = (await
|
|
262
|
-
throw
|
|
260
|
+
if (!W.ok) {
|
|
261
|
+
let f = (await W.json().catch(() => ({}))).error || `Request failed: ${W.status}`;
|
|
262
|
+
throw W.status === 401 || W.status === 403 ? new SDKError("PERMISSION_DENIED", f) : new SDKError("INTERNAL_ERROR", f);
|
|
263
263
|
}
|
|
264
|
-
return await
|
|
264
|
+
return await W.json();
|
|
265
265
|
}
|
|
266
266
|
var WebCloudKv = class {
|
|
267
267
|
async get(f) {
|
|
268
268
|
return fetchJson(`/cloud/kv/get?key=${encodeURIComponent(f)}`);
|
|
269
269
|
}
|
|
270
|
-
async set(f,
|
|
270
|
+
async set(f, V, H) {
|
|
271
271
|
return fetchJson("/cloud/kv/set", {
|
|
272
272
|
method: "POST",
|
|
273
273
|
headers: { "Content-Type": "application/json" },
|
|
274
274
|
body: JSON.stringify({
|
|
275
275
|
key: f,
|
|
276
|
-
value:
|
|
277
|
-
ifMatch:
|
|
276
|
+
value: V,
|
|
277
|
+
ifMatch: H?.ifMatch
|
|
278
278
|
})
|
|
279
279
|
});
|
|
280
280
|
}
|
|
281
|
-
async delete(f,
|
|
281
|
+
async delete(f, V) {
|
|
282
282
|
await fetchJson("/cloud/kv/delete", {
|
|
283
283
|
method: "POST",
|
|
284
284
|
headers: { "Content-Type": "application/json" },
|
|
285
285
|
body: JSON.stringify({
|
|
286
286
|
key: f,
|
|
287
|
-
ifMatch:
|
|
287
|
+
ifMatch: V?.ifMatch
|
|
288
288
|
})
|
|
289
289
|
});
|
|
290
290
|
}
|
|
291
291
|
async list(f) {
|
|
292
|
-
let
|
|
293
|
-
f?.prefix &&
|
|
294
|
-
let
|
|
295
|
-
return fetchJson(`/cloud/kv/list${
|
|
292
|
+
let V = new URLSearchParams();
|
|
293
|
+
f?.prefix && V.set("prefix", f.prefix), typeof f?.limit == "number" && V.set("limit", String(f.limit)), f?.cursor && V.set("cursor", f.cursor);
|
|
294
|
+
let H = V.toString();
|
|
295
|
+
return fetchJson(`/cloud/kv/list${H ? `?${H}` : ""}`);
|
|
296
296
|
}
|
|
297
297
|
}, WebCloudDbQueryBuilder = class f {
|
|
298
|
-
constructor(f,
|
|
298
|
+
constructor(f, V) {
|
|
299
299
|
this.collectionName = f, this.state = {
|
|
300
|
-
where:
|
|
301
|
-
orderBy:
|
|
300
|
+
where: V?.where ?? [],
|
|
301
|
+
orderBy: V?.orderBy ?? {
|
|
302
302
|
field: "createdAt",
|
|
303
303
|
direction: "desc"
|
|
304
304
|
},
|
|
305
|
-
limit:
|
|
306
|
-
cursor:
|
|
305
|
+
limit: V?.limit ?? 20,
|
|
306
|
+
cursor: V?.cursor ?? null
|
|
307
307
|
};
|
|
308
308
|
}
|
|
309
|
-
where(
|
|
309
|
+
where(V, H, U) {
|
|
310
310
|
return new f(this.collectionName, {
|
|
311
311
|
...this.state,
|
|
312
312
|
where: [...this.state.where, {
|
|
313
|
-
field:
|
|
314
|
-
op:
|
|
315
|
-
value:
|
|
313
|
+
field: V,
|
|
314
|
+
op: H,
|
|
315
|
+
value: U
|
|
316
316
|
}]
|
|
317
317
|
});
|
|
318
318
|
}
|
|
319
|
-
orderBy(
|
|
319
|
+
orderBy(V, H = "desc") {
|
|
320
320
|
return new f(this.collectionName, {
|
|
321
321
|
...this.state,
|
|
322
322
|
orderBy: {
|
|
323
|
-
field:
|
|
324
|
-
direction:
|
|
323
|
+
field: V,
|
|
324
|
+
direction: H
|
|
325
325
|
}
|
|
326
326
|
});
|
|
327
327
|
}
|
|
328
|
-
limit(
|
|
328
|
+
limit(V) {
|
|
329
329
|
return new f(this.collectionName, {
|
|
330
330
|
...this.state,
|
|
331
|
-
limit:
|
|
331
|
+
limit: V
|
|
332
332
|
});
|
|
333
333
|
}
|
|
334
|
-
startAfter(
|
|
334
|
+
startAfter(V) {
|
|
335
335
|
return new f(this.collectionName, {
|
|
336
336
|
...this.state,
|
|
337
|
-
cursor:
|
|
337
|
+
cursor: V
|
|
338
338
|
});
|
|
339
339
|
}
|
|
340
340
|
async get() {
|
|
@@ -353,43 +353,37 @@ var WebCloudKv = class {
|
|
|
353
353
|
constructor(f) {
|
|
354
354
|
this.name = f;
|
|
355
355
|
}
|
|
356
|
-
async add(f,
|
|
356
|
+
async add(f, V) {
|
|
357
357
|
return fetchJson(`/cloud/db/collections/${encodeURIComponent(this.name)}/docs`, {
|
|
358
358
|
method: "POST",
|
|
359
359
|
headers: { "Content-Type": "application/json" },
|
|
360
360
|
body: JSON.stringify({
|
|
361
|
-
id:
|
|
362
|
-
visibility: B?.visibility,
|
|
363
|
-
refType: B?.refType,
|
|
364
|
-
refId: B?.refId,
|
|
361
|
+
id: V?.id,
|
|
365
362
|
data: f
|
|
366
363
|
})
|
|
367
364
|
});
|
|
368
365
|
}
|
|
369
366
|
doc(f) {
|
|
370
|
-
let
|
|
367
|
+
let V = this.name;
|
|
371
368
|
return {
|
|
372
|
-
get: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(
|
|
373
|
-
set: async (
|
|
369
|
+
get: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(V)}/docs/${encodeURIComponent(f)}`),
|
|
370
|
+
set: async (H, U) => fetchJson(`/cloud/db/collections/${encodeURIComponent(V)}/docs/${encodeURIComponent(f)}`, {
|
|
374
371
|
method: "PUT",
|
|
375
372
|
headers: { "Content-Type": "application/json" },
|
|
376
373
|
body: JSON.stringify({
|
|
377
|
-
data:
|
|
378
|
-
ifMatch:
|
|
379
|
-
visibility: H?.visibility,
|
|
380
|
-
refType: H?.refType,
|
|
381
|
-
refId: H?.refId
|
|
374
|
+
data: H,
|
|
375
|
+
ifMatch: U?.ifMatch
|
|
382
376
|
})
|
|
383
377
|
}),
|
|
384
|
-
update: async (
|
|
378
|
+
update: async (H, U) => fetchJson(`/cloud/db/collections/${encodeURIComponent(V)}/docs/${encodeURIComponent(f)}`, {
|
|
385
379
|
method: "PATCH",
|
|
386
380
|
headers: { "Content-Type": "application/json" },
|
|
387
381
|
body: JSON.stringify({
|
|
388
|
-
patch:
|
|
389
|
-
ifMatch:
|
|
382
|
+
patch: H,
|
|
383
|
+
ifMatch: U?.ifMatch
|
|
390
384
|
})
|
|
391
385
|
}),
|
|
392
|
-
delete: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(
|
|
386
|
+
delete: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(V)}/docs/${encodeURIComponent(f)}`, { method: "DELETE" }).then(() => void 0)
|
|
393
387
|
};
|
|
394
388
|
}
|
|
395
389
|
query() {
|
|
@@ -403,6 +397,24 @@ function toWxDoc(f) {
|
|
|
403
397
|
_openid: f.ownerId
|
|
404
398
|
};
|
|
405
399
|
}
|
|
400
|
+
function isWxInternalSentinel(f) {
|
|
401
|
+
if (!f || typeof f != "object" || Array.isArray(f)) return !1;
|
|
402
|
+
let V = f;
|
|
403
|
+
return typeof V.__gemigoWxCmd == "string" || V.__gemigoWxType === "serverDate";
|
|
404
|
+
}
|
|
405
|
+
function assertNoWxSystemFields(f, V) {
|
|
406
|
+
if (!f || typeof f != "object") return;
|
|
407
|
+
if (Array.isArray(f)) {
|
|
408
|
+
for (let H of f) assertNoWxSystemFields(H, V);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (isWxInternalSentinel(f)) return;
|
|
412
|
+
let H = f;
|
|
413
|
+
for (let [f, U] of Object.entries(H)) {
|
|
414
|
+
if (f.startsWith("_") && !(V.allowId && f === "_id")) throw new SDKError("PERMISSION_DENIED", `Cannot write system field ${f}`);
|
|
415
|
+
assertNoWxSystemFields(U, V);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
406
418
|
function createWxCommand() {
|
|
407
419
|
return {
|
|
408
420
|
eq: (f) => ({
|
|
@@ -449,94 +461,94 @@ function createWxCommand() {
|
|
|
449
461
|
};
|
|
450
462
|
}
|
|
451
463
|
function createWxServerDate(f) {
|
|
452
|
-
let
|
|
453
|
-
return
|
|
464
|
+
let V = typeof f?.offset == "number" && Number.isFinite(f.offset) ? f.offset : void 0;
|
|
465
|
+
return V === void 0 ? { __gemigoWxType: "serverDate" } : {
|
|
454
466
|
__gemigoWxType: "serverDate",
|
|
455
|
-
offset:
|
|
467
|
+
offset: V
|
|
456
468
|
};
|
|
457
469
|
}
|
|
458
470
|
function normalizeWxDirection(f) {
|
|
459
471
|
return f === "asc" ? "asc" : "desc";
|
|
460
472
|
}
|
|
461
|
-
async function wxQueryPage(f,
|
|
473
|
+
async function wxQueryPage(f, V, H, U) {
|
|
462
474
|
return fetchJson(`/cloud/db/collections/${encodeURIComponent(f)}/query`, {
|
|
463
475
|
method: "POST",
|
|
464
476
|
headers: { "Content-Type": "application/json" },
|
|
465
477
|
body: JSON.stringify({
|
|
466
|
-
where:
|
|
467
|
-
orderBy:
|
|
468
|
-
limit:
|
|
469
|
-
cursor:
|
|
478
|
+
where: V.where,
|
|
479
|
+
orderBy: V.orderBy,
|
|
480
|
+
limit: U,
|
|
481
|
+
cursor: H
|
|
470
482
|
})
|
|
471
483
|
});
|
|
472
484
|
}
|
|
473
|
-
function createWxQuery(f,
|
|
474
|
-
let
|
|
475
|
-
where:
|
|
476
|
-
orderBy:
|
|
485
|
+
function createWxQuery(f, V, H) {
|
|
486
|
+
let U = {
|
|
487
|
+
where: H?.where ?? {},
|
|
488
|
+
orderBy: H?.orderBy ?? {
|
|
477
489
|
field: "createdAt",
|
|
478
490
|
direction: "desc"
|
|
479
491
|
},
|
|
480
|
-
limit:
|
|
481
|
-
skip:
|
|
482
|
-
cursor:
|
|
492
|
+
limit: H?.limit ?? 20,
|
|
493
|
+
skip: H?.skip ?? 0,
|
|
494
|
+
cursor: H?.cursor ?? null
|
|
483
495
|
};
|
|
484
496
|
return {
|
|
485
|
-
where(
|
|
486
|
-
return createWxQuery(f,
|
|
487
|
-
...
|
|
497
|
+
where(H) {
|
|
498
|
+
return createWxQuery(f, V, {
|
|
499
|
+
...U,
|
|
488
500
|
where: {
|
|
489
|
-
...
|
|
490
|
-
...
|
|
501
|
+
...U.where,
|
|
502
|
+
...H ?? {}
|
|
491
503
|
}
|
|
492
504
|
});
|
|
493
505
|
},
|
|
494
|
-
orderBy(
|
|
495
|
-
return createWxQuery(f,
|
|
496
|
-
...
|
|
506
|
+
orderBy(H, W) {
|
|
507
|
+
return createWxQuery(f, V, {
|
|
508
|
+
...U,
|
|
497
509
|
orderBy: {
|
|
498
|
-
field: String(
|
|
499
|
-
direction: normalizeWxDirection(
|
|
510
|
+
field: String(H),
|
|
511
|
+
direction: normalizeWxDirection(W)
|
|
500
512
|
}
|
|
501
513
|
});
|
|
502
514
|
},
|
|
503
|
-
limit(
|
|
504
|
-
return createWxQuery(f,
|
|
505
|
-
...
|
|
506
|
-
limit: Math.max(1, Math.floor(Number(
|
|
515
|
+
limit(H) {
|
|
516
|
+
return createWxQuery(f, V, {
|
|
517
|
+
...U,
|
|
518
|
+
limit: Math.max(1, Math.floor(Number(H) || 0))
|
|
507
519
|
});
|
|
508
520
|
},
|
|
509
|
-
skip(
|
|
510
|
-
return createWxQuery(f,
|
|
511
|
-
...
|
|
512
|
-
skip: Math.max(0, Math.floor(Number(
|
|
521
|
+
skip(H) {
|
|
522
|
+
return createWxQuery(f, V, {
|
|
523
|
+
...U,
|
|
524
|
+
skip: Math.max(0, Math.floor(Number(H) || 0))
|
|
513
525
|
});
|
|
514
526
|
},
|
|
515
|
-
startAfter(
|
|
516
|
-
let
|
|
517
|
-
if (!
|
|
518
|
-
return createWxQuery(f,
|
|
519
|
-
...
|
|
520
|
-
cursor:
|
|
527
|
+
startAfter(H) {
|
|
528
|
+
let W = String(H ?? "").trim();
|
|
529
|
+
if (!W) throw new SDKError("INTERNAL_ERROR", "startAfter(cursor) requires a non-empty cursor");
|
|
530
|
+
return createWxQuery(f, V, {
|
|
531
|
+
...U,
|
|
532
|
+
cursor: W
|
|
521
533
|
});
|
|
522
534
|
},
|
|
523
535
|
async count() {
|
|
524
536
|
return fetchJson(`/cloud/db/collections/${encodeURIComponent(f)}/count`, {
|
|
525
537
|
method: "POST",
|
|
526
538
|
headers: { "Content-Type": "application/json" },
|
|
527
|
-
body: JSON.stringify({ where:
|
|
539
|
+
body: JSON.stringify({ where: U.where })
|
|
528
540
|
});
|
|
529
541
|
},
|
|
530
|
-
async update(
|
|
531
|
-
let
|
|
532
|
-
if (!
|
|
533
|
-
if ("_openid" in
|
|
542
|
+
async update(V) {
|
|
543
|
+
let H = V?.data;
|
|
544
|
+
if (!H || typeof H != "object" || Array.isArray(H)) throw new SDKError("INTERNAL_ERROR", "update({data}) must be an object");
|
|
545
|
+
if ("_openid" in H) throw new SDKError("PERMISSION_DENIED", "Cannot write system field _openid");
|
|
534
546
|
return fetchJson(`/cloud/db/collections/${encodeURIComponent(f)}/update`, {
|
|
535
547
|
method: "POST",
|
|
536
548
|
headers: { "Content-Type": "application/json" },
|
|
537
549
|
body: JSON.stringify({
|
|
538
|
-
where:
|
|
539
|
-
data:
|
|
550
|
+
where: U.where,
|
|
551
|
+
data: H
|
|
540
552
|
})
|
|
541
553
|
});
|
|
542
554
|
},
|
|
@@ -544,31 +556,31 @@ function createWxQuery(f, B, V) {
|
|
|
544
556
|
return fetchJson(`/cloud/db/collections/${encodeURIComponent(f)}/remove`, {
|
|
545
557
|
method: "POST",
|
|
546
558
|
headers: { "Content-Type": "application/json" },
|
|
547
|
-
body: JSON.stringify({ where:
|
|
559
|
+
body: JSON.stringify({ where: U.where })
|
|
548
560
|
});
|
|
549
561
|
},
|
|
550
562
|
async get() {
|
|
551
|
-
let
|
|
552
|
-
if (
|
|
553
|
-
let
|
|
554
|
-
for (; (
|
|
555
|
-
let
|
|
556
|
-
if (
|
|
557
|
-
if (
|
|
558
|
-
let f = Math.min(
|
|
559
|
-
|
|
560
|
-
let
|
|
561
|
-
if (
|
|
562
|
-
let f = Math.min(
|
|
563
|
-
|
|
563
|
+
let V = Math.min(U.limit, 100), H = U.skip;
|
|
564
|
+
if (H > 1e3) throw new SDKError("NOT_SUPPORTED", "skip(n) is capped at 1000; use cursor pagination instead.");
|
|
565
|
+
let W = U.cursor ?? null, G = H, K = V, q = [], J = 0;
|
|
566
|
+
for (; (G > 0 || K > 0) && J < 30;) {
|
|
567
|
+
let V = await wxQueryPage(f, U, W, Math.min(100, G > 0 ? G : K));
|
|
568
|
+
if (J += 1, V.items.length === 0) break;
|
|
569
|
+
if (G > 0) {
|
|
570
|
+
let f = Math.min(G, V.items.length);
|
|
571
|
+
G -= f;
|
|
572
|
+
let H = V.items.slice(f);
|
|
573
|
+
if (G === 0 && K > 0 && H.length > 0) {
|
|
574
|
+
let f = Math.min(K, H.length);
|
|
575
|
+
q.push(...H.slice(0, f).map(toWxDoc)), K -= f;
|
|
564
576
|
}
|
|
565
|
-
} else
|
|
566
|
-
if (
|
|
577
|
+
} else q.push(...V.items.slice(0, K).map(toWxDoc)), K = Math.max(0, K - V.items.length);
|
|
578
|
+
if (W = V.nextCursor, !W) break;
|
|
567
579
|
}
|
|
568
|
-
if (
|
|
580
|
+
if (J >= 30) throw new SDKError("NOT_SUPPORTED", "skip/limit query requires too many requests; narrow your query.");
|
|
569
581
|
return {
|
|
570
|
-
data:
|
|
571
|
-
_meta: { nextCursor:
|
|
582
|
+
data: q,
|
|
583
|
+
_meta: { nextCursor: W }
|
|
572
584
|
};
|
|
573
585
|
}
|
|
574
586
|
};
|
|
@@ -578,37 +590,35 @@ function createWxDatabase() {
|
|
|
578
590
|
return {
|
|
579
591
|
command: f,
|
|
580
592
|
serverDate: (f) => createWxServerDate(f),
|
|
581
|
-
collection(
|
|
582
|
-
let
|
|
583
|
-
if (!
|
|
584
|
-
let
|
|
593
|
+
collection(V) {
|
|
594
|
+
let H = String(V).trim();
|
|
595
|
+
if (!H) throw new SDKError("INTERNAL_ERROR", "collection name is required");
|
|
596
|
+
let U = createWxQuery(H, f);
|
|
585
597
|
return {
|
|
586
|
-
...
|
|
598
|
+
...U,
|
|
587
599
|
add: async (f) => {
|
|
588
|
-
let
|
|
589
|
-
|
|
590
|
-
let
|
|
591
|
-
return
|
|
600
|
+
let V = f?.data;
|
|
601
|
+
assertNoWxSystemFields(V, { allowId: !0 });
|
|
602
|
+
let U = V && typeof V == "object" && !Array.isArray(V) ? V._id : void 0, W = V && typeof V == "object" && !Array.isArray(V) ? { ...V } : V;
|
|
603
|
+
return W && typeof W == "object" && !Array.isArray(W) && delete W._id, { _id: (await webCloud.db.collection(H).add(W, { id: U ? String(U) : void 0 })).id };
|
|
592
604
|
},
|
|
593
605
|
doc: (f) => {
|
|
594
|
-
let
|
|
606
|
+
let V = webCloud.db.collection(H).doc(String(f));
|
|
595
607
|
return {
|
|
596
|
-
get: async () => ({ data: toWxDoc(await
|
|
608
|
+
get: async () => ({ data: toWxDoc(await V.get()) }),
|
|
597
609
|
set: async (f) => {
|
|
598
|
-
let
|
|
599
|
-
|
|
600
|
-
await B.set(f?.data);
|
|
610
|
+
let H = f?.data;
|
|
611
|
+
assertNoWxSystemFields(H, { allowId: !1 }), await V.set(f?.data);
|
|
601
612
|
},
|
|
602
613
|
update: async (f) => {
|
|
603
|
-
let
|
|
604
|
-
if (!
|
|
605
|
-
|
|
606
|
-
await B.update(V);
|
|
614
|
+
let H = f?.data ?? {};
|
|
615
|
+
if (!H || typeof H != "object" || Array.isArray(H)) throw new SDKError("INTERNAL_ERROR", "update({data}) must be an object");
|
|
616
|
+
assertNoWxSystemFields(H, { allowId: !1 }), await V.update(H);
|
|
607
617
|
},
|
|
608
|
-
remove: async () => (await
|
|
618
|
+
remove: async () => (await V.delete(), { stats: { removed: 1 } })
|
|
609
619
|
};
|
|
610
620
|
},
|
|
611
|
-
get: async () =>
|
|
621
|
+
get: async () => U.get()
|
|
612
622
|
};
|
|
613
623
|
}
|
|
614
624
|
};
|
|
@@ -616,9 +626,9 @@ function createWxDatabase() {
|
|
|
616
626
|
const webCloud = {
|
|
617
627
|
kv: new WebCloudKv(),
|
|
618
628
|
db: { collection(f) {
|
|
619
|
-
let
|
|
620
|
-
if (!
|
|
621
|
-
return new WebCloudDbCollection(
|
|
629
|
+
let V = String(f).trim();
|
|
630
|
+
if (!V) throw new SDKError("INTERNAL_ERROR", "collection name is required");
|
|
631
|
+
return new WebCloudDbCollection(V);
|
|
622
632
|
} },
|
|
623
633
|
blob: {
|
|
624
634
|
async createUploadUrl(f) {
|
|
@@ -644,13 +654,13 @@ const webCloud = {
|
|
|
644
654
|
});
|
|
645
655
|
}
|
|
646
656
|
},
|
|
647
|
-
functions: { async call(f,
|
|
657
|
+
functions: { async call(f, V) {
|
|
648
658
|
return (await fetchJson("/cloud/functions/call", {
|
|
649
659
|
method: "POST",
|
|
650
660
|
headers: { "Content-Type": "application/json" },
|
|
651
661
|
body: JSON.stringify({
|
|
652
662
|
name: f,
|
|
653
|
-
data:
|
|
663
|
+
data: V ?? null
|
|
654
664
|
})
|
|
655
665
|
})).data;
|
|
656
666
|
} },
|
|
@@ -659,46 +669,46 @@ const webCloud = {
|
|
|
659
669
|
return createWxDatabase();
|
|
660
670
|
},
|
|
661
671
|
async callFunction(f) {
|
|
662
|
-
let
|
|
663
|
-
if (!
|
|
664
|
-
return { result: await webCloud.functions.call(
|
|
672
|
+
let V = String(f?.name ?? "").trim();
|
|
673
|
+
if (!V) throw new SDKError("INTERNAL_ERROR", "callFunction name is required");
|
|
674
|
+
return { result: await webCloud.functions.call(V, f?.data) };
|
|
665
675
|
},
|
|
666
676
|
async uploadFile(f) {
|
|
667
|
-
let
|
|
668
|
-
if (!
|
|
669
|
-
let
|
|
670
|
-
if (!
|
|
671
|
-
let
|
|
672
|
-
path:
|
|
677
|
+
let V = String(f?.cloudPath ?? "").trim().replace(/^\/+/, "");
|
|
678
|
+
if (!V) throw new SDKError("INTERNAL_ERROR", "cloudPath is required");
|
|
679
|
+
let H = f?.filePath;
|
|
680
|
+
if (!H) throw new SDKError("INTERNAL_ERROR", "filePath is required");
|
|
681
|
+
let U = H.type ? String(H.type) : void 0, { fileId: W, uploadUrl: G } = await webCloud.blob.createUploadUrl({
|
|
682
|
+
path: V,
|
|
673
683
|
visibility: "private",
|
|
674
|
-
contentType:
|
|
684
|
+
contentType: U
|
|
675
685
|
});
|
|
676
|
-
return await fetch(
|
|
686
|
+
return await fetch(G, {
|
|
677
687
|
method: "PUT",
|
|
678
|
-
headers:
|
|
679
|
-
body:
|
|
680
|
-
}), { fileID:
|
|
688
|
+
headers: U ? { "Content-Type": U } : void 0,
|
|
689
|
+
body: H
|
|
690
|
+
}), { fileID: W };
|
|
681
691
|
},
|
|
682
692
|
async getTempFileURL(f) {
|
|
683
|
-
let
|
|
684
|
-
return { fileList: await Promise.all(
|
|
685
|
-
let
|
|
686
|
-
if (!
|
|
693
|
+
let V = Array.isArray(f?.fileList) ? f.fileList : [];
|
|
694
|
+
return { fileList: await Promise.all(V.map(async (f) => {
|
|
695
|
+
let V = typeof f == "string" ? f : String(f?.fileID ?? "");
|
|
696
|
+
if (!V) return {
|
|
687
697
|
fileID: "",
|
|
688
698
|
tempFileURL: "",
|
|
689
699
|
status: 400,
|
|
690
700
|
errMsg: "fileID is required"
|
|
691
701
|
};
|
|
692
702
|
try {
|
|
693
|
-
let { url: f } = await webCloud.blob.getDownloadUrl({ fileId:
|
|
703
|
+
let { url: f } = await webCloud.blob.getDownloadUrl({ fileId: V });
|
|
694
704
|
return {
|
|
695
|
-
fileID:
|
|
705
|
+
fileID: V,
|
|
696
706
|
tempFileURL: f,
|
|
697
707
|
status: 0
|
|
698
708
|
};
|
|
699
709
|
} catch (f) {
|
|
700
710
|
return {
|
|
701
|
-
fileID:
|
|
711
|
+
fileID: V,
|
|
702
712
|
tempFileURL: "",
|
|
703
713
|
status: 500,
|
|
704
714
|
errMsg: f instanceof Error ? f.message : String(f)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.gemigo=t())})(this,function(){var e=Object.defineProperty,t=(e,t)=>()=>(e&&(t=e(e=0)),t),n=t=>{let n={};for(var r in t)e(n,r,{get:t[r],enumerable:!0});return n},r,i,a,o,s,c=t((()=>{(function(e){e.Call=`call`,e.Reply=`reply`,e.Syn=`syn`,e.SynAck=`synAck`,e.Ack=`ack`})(r||={}),(function(e){e.Fulfilled=`fulfilled`,e.Rejected=`rejected`})(i||={}),(function(e){e.ConnectionDestroyed=`ConnectionDestroyed`,e.ConnectionTimeout=`ConnectionTimeout`,e.NoIframeSrc=`NoIframeSrc`})(a||={}),(function(e){e.DataCloneError=`DataCloneError`})(o||={}),(function(e){e.Message=`message`})(s||={})})),l,u=t((()=>{l=(e,t)=>{let n=[],r=!1;return{destroy(i){r||(r=!0,t(`${e}: Destroying connection`),n.forEach(e=>{e(i)}))},onDestroy(e){r?e():n.push(e)}}}})),d,f=t((()=>{d=e=>(...t)=>{e&&console.log(`[Penpal]`,...t)}})),p,m,h=t((()=>{p=({name:e,message:t,stack:n})=>({name:e,message:t,stack:n}),m=e=>{let t=Error();return Object.keys(e).forEach(n=>t[n]=e[n]),t}})),g,_=t((()=>{h(),c(),g=(e,t,n)=>{let{localName:a,local:c,remote:l,originForSending:u,originForReceiving:d}=e,f=!1,m=e=>{if(e.source!==l||e.data.penpal!==r.Call)return;if(d!==`*`&&e.origin!==d){n(`${a} received message from origin ${e.origin} which did not match expected origin ${d}`);return}let{methodName:s,args:c,id:m}=e.data;n(`${a}: Received ${s}() call`);let h=e=>t=>{if(n(`${a}: Sending ${s}() reply`),f){n(`${a}: Unable to send ${s}() reply due to destroyed connection`);return}let c={penpal:r.Reply,id:m,resolution:e,returnValue:t};e===i.Rejected&&t instanceof Error&&(c.returnValue=p(t),c.returnValueIsError=!0);try{l.postMessage(c,u)}catch(e){if(e.name===o.DataCloneError){let t={penpal:r.Reply,id:m,resolution:i.Rejected,returnValue:p(e),returnValueIsError:!0};l.postMessage(t,u)}throw e}};new Promise(e=>e(t[s].apply(t,c))).then(h(i.Fulfilled),h(i.Rejected))};return c.addEventListener(s.Message,m),()=>{f=!0,c.removeEventListener(s.Message,m)}}})),ee,te,ne=t((()=>{ee=0,te=()=>++ee})),v,y,b,x,S,C,w,T=t((()=>{v=`.`,y=e=>e?e.split(v):[],b=e=>e.join(v),x=(e,t)=>{let n=y(t||``);return n.push(e),b(n)},S=(e,t,n)=>{let r=y(t);return r.reduce((e,t,i)=>(e[t]===void 0&&(e[t]={}),i===r.length-1&&(e[t]=n),e[t]),e),e},C=(e,t)=>{let n={};return Object.keys(e).forEach(r=>{let i=e[r],a=x(r,t);typeof i==`object`&&Object.assign(n,C(i,a)),typeof i==`function`&&(n[a]=i)}),n},w=e=>{let t={};for(let n in e)S(t,n,e[n]);return t}})),E,D=t((()=>{ne(),h(),T(),c(),E=(e,t,n,o,c)=>{let{localName:l,local:u,remote:d,originForSending:f,originForReceiving:p}=t,h=!1;c(`${l}: Connecting call sender`);let g=e=>(...t)=>{c(`${l}: Sending ${e}() call`);let n;try{d.closed&&(n=!0)}catch{n=!0}if(n&&o(),h){let t=Error(`Unable to send ${e}() call due to destroyed connection`);throw t.code=a.ConnectionDestroyed,t}return new Promise((n,a)=>{let o=te(),h=t=>{if(t.source!==d||t.data.penpal!==r.Reply||t.data.id!==o)return;if(p!==`*`&&t.origin!==p){c(`${l} received message from origin ${t.origin} which did not match expected origin ${p}`);return}let f=t.data;c(`${l}: Received ${e}() reply`),u.removeEventListener(s.Message,h);let g=f.returnValue;f.returnValueIsError&&(g=m(g)),(f.resolution===i.Fulfilled?n:a)(g)};u.addEventListener(s.Message,h);let g={penpal:r.Call,id:o,methodName:e,args:t};d.postMessage(g,f)})},_=n.reduce((e,t)=>(e[t]=g(t),e),{});return Object.assign(e,w(_)),()=>{h=!0}}})),re=t((()=>{_(),D()})),ie=t((()=>{c()})),ae,O=t((()=>{c(),ae=(e,t)=>{let n;return e!==void 0&&(n=window.setTimeout(()=>{let n=Error(`Connection timed out after ${e}ms`);n.code=a.ConnectionTimeout,t(n)},e)),()=>{clearTimeout(n)}}})),oe=t((()=>{c()})),se=t((()=>{c(),re(),ie(),O(),oe()})),k,ce=t((()=>{c(),_(),D(),k=(e,t,n,i)=>{let{destroy:a,onDestroy:o}=n;return n=>{if(!(e instanceof RegExp?e.test(n.origin):e===`*`||e===n.origin)){i(`Child: Handshake - Received SYN-ACK from origin ${n.origin} which did not match expected origin ${e}`);return}i(`Child: Handshake - Received SYN-ACK, responding with ACK`);let s=n.origin===`null`?`*`:n.origin,c={penpal:r.Ack,methodNames:Object.keys(t)};window.parent.postMessage(c,s);let l={localName:`Child`,local:window,remote:window.parent,originForSending:s,originForReceiving:n.origin};o(g(l,t,i));let u={};return o(E(u,l,n.data.methodNames,a,i)),u}}})),A,j,le=t((()=>{u(),f(),c(),ce(),T(),O(),A=()=>{try{clearTimeout()}catch{return!1}return!0},j=(e={})=>{let{parentOrigin:t=`*`,methods:n={},timeout:i,debug:a=!1}=e,o=d(a),c=l(`Child`,o),{destroy:u,onDestroy:f}=c,p=k(t,C(n),c,o),m=()=>{o(`Child: Handshake - Sending SYN`);let e={penpal:r.Syn},n=t instanceof RegExp?`*`:t;window.parent.postMessage(e,n)};return{promise:new Promise((e,t)=>{let n=ae(i,u),a=t=>{if(A()&&!(t.source!==parent||!t.data)&&t.data.penpal===r.SynAck){let r=p(t);r&&(window.removeEventListener(s.Message,a),n(),e(r))}};window.addEventListener(s.Message,a),m(),f(e=>{window.removeEventListener(s.Message,a),e&&t(e)})}),destroy(){u()}}}})),ue=t((()=>{se(),le(),c()})),de=n({callHost:()=>N,createRPCProxy:()=>P,getHost:()=>pe,hasConnectionFailed:()=>he,initConnection:()=>ge,isConnected:()=>me,tryGetHost:()=>M,withFallback:()=>_e});function fe(){try{return window.self!==window.top}catch{return!0}}async function M(e,t){if(I)return I;if(L)return null;if(!fe())return L=!0,null;if(!F){let n={},r=e??R;r&&Object.assign(n,r),F=j({methods:n,timeout:t?.timeoutMs??z}).promise.then(e=>(I=e,e)).catch(e=>(console.error(`[GemiGo Connection] Promise failed:`,e),L=!0,F=null,null))}return F}async function pe(){let e=await M();if(!e)throw Error(`Not connected to host. SDK may be running outside of a supported environment.`);return e}function me(){return I!==null}function he(){return L}function ge(e,t){R=e,M(e,t)}async function N(e,t=[],n){let r=await M();if(r&&typeof r[e]==`function`){let i=await r[e](...t);if(i?.success!==!1)return i?.data===void 0?i?.value===void 0?i:i.value:i.data;if(n)return n(...t);throw Error(i?.error||`Host method ${String(e)} failed`)}if(n)return n(...t);throw Error(`Method ${String(e)} not supported in this environment`)}function P(e,t={}){let n={};for(let r of e){let e=t.mapping?.[r]||r,i=t.fallbacks?.[r];n[r]=(...t)=>N(e,t,i)}return n}function _e(e,t){return async(...n)=>{try{return await e(...n)}catch{return t(...n)}}}var F,I,L,R,z,B=t((()=>{ue(),F=null,I=null,L=!1,z=1500}));B();function ve(){let e=new Map;return{on(t,n){return e.has(t)||e.set(t,new Set),e.get(t).add(n),()=>e.get(t)?.delete(n)},emit(t,...n){e.get(t)?.forEach(e=>e(...n))},off(t){t?e.delete(t):e.clear()}}}let V=ve();function ye(e){let t=M,n={},r={};if(e.rpc){let t=P(e.rpc.methods,{mapping:e.rpc.mapping,fallbacks:e.rpc.fallbacks});Object.assign(n,t)}if(e.events)if(Array.isArray(e.events))for(let i of e.events){let e=i;n[i]=n=>(t?.(),V.on(e,n)),r[i]=(...t)=>{V.emit(e,...t)}}else for(let[i,a]of Object.entries(e.events)){if(!a)continue;let e=a,o=typeof e==`string`?e:e.event,s=typeof e==`object`&&`childMethod`in e&&e.childMethod?e.childMethod:i;n[i]=e=>(t?.(),V.on(o,e)),r[s]=(...e)=>{V.emit(o,...e)}}return{api:n,childMethods:r}}function be(e,t){return async(...n)=>{try{let r=await N(e,t.transform?t.transform(...n):n);return t.onSuccess?t.onSuccess(r):r}catch{return t.fallback(...n)}}}function xe(e){let t=e.statics?{...e.statics}:{},n={};if(e.modules)for(let[r,i]of Object.entries(e.modules)){let{api:e,childMethods:a}=ye(i);t[r]=e,Object.assign(n,a)}if(e.actions)for(let[n,r]of Object.entries(e.actions)){let e=r;t[n]=be(e.method,e)}if(e.getters)for(let[n,r]of Object.entries(e.getters))Object.defineProperty(t,n,{get:r,enumerable:!0,configurable:!0});return{sdk:t,childMethods:n}}async function Se(e,t={}){let{initConnection:n}=await Promise.resolve().then(()=>(B(),de));n(e,t);let r=await M();if(r&&typeof r.getProtocolInfo==`function`)try{return await r.getProtocolInfo()}catch{return null}return null}B();var H=()=>`gemigo:${typeof window>`u`?`unknown`:window.location.origin.replace(/[:/]/g,`_`)}:`;let U={get:async e=>{if(typeof window>`u`||!window.localStorage)return null;let t=window.localStorage.getItem(`${H()}${e}`);if(!t)return null;try{return JSON.parse(t)}catch{return null}},set:async(e,t)=>{typeof window>`u`||!window.localStorage||window.localStorage.setItem(`${H()}${e}`,JSON.stringify(t))},delete:async e=>{typeof window>`u`||!window.localStorage||window.localStorage.removeItem(`${H()}${e}`)},clear:async()=>{if(typeof window>`u`||!window.localStorage)return;let e=H();for(let t=window.localStorage.length-1;t>=0;--t){let n=window.localStorage.key(t);n&&n.startsWith(e)&&window.localStorage.removeItem(n)}}},Ce=async e=>{if(typeof window>`u`||typeof Notification>`u`)return{success:!1,reason:`not_supported`};if(Notification.permission!==`granted`)return{success:!1,reason:`permission_not_granted`};try{return new Notification(e.title,{body:e.message,icon:e.icon}),{success:!0}}catch{return{success:!1,reason:`failed_to_notify`}}},we={request:async(e,t)=>{let{method:n=`GET`,headers:r,body:i,responseType:a}=t??{},o=await fetch(e,{method:n,headers:r,body:i?typeof i==`string`?i:JSON.stringify(i):void 0}),s={};o.headers.forEach((e,t)=>s[t]=e);let c=a===`text`?await o.text():a===`arraybuffer`?await o.arrayBuffer():await o.json();return{status:o.status,data:c,headers:s}}};var W=class e extends Error{constructor(t,n){super(n),this.code=t,this.name=`SDKError`,Object.setPrototypeOf(this,e.prototype)}},G=null,K=null;function Te(e){let t=``;for(let n of e)t+=String.fromCharCode(n);let n=globalThis.btoa;if(!n)throw Error(`base64 encoder not available`);return n(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function Ee(e=32){let t=new Uint8Array(e);return crypto.getRandomValues(t),Te(t)}async function De(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest(`SHA-256`,t);return Te(new Uint8Array(n))}function Oe(){if(typeof window>`u`)return`unknown`;let e=window.location.hostname.toLowerCase();return e.endsWith(`.gemigo.app`)?e.replace(/\.gemigo\.app$/,``):e}function ke(e){let t=(e??[`identity:basic`]).map(e=>String(e).trim()).filter(Boolean);return t.length>0?t:[`identity:basic`]}function Ae(e){let t=new URL(`/sdk/broker`,e.platformOrigin);return t.searchParams.set(`app_id`,e.appId),t.searchParams.set(`scope`,e.scopes.join(` `)),t.searchParams.set(`state`,e.state),t.searchParams.set(`code_challenge`,e.codeChallenge),t.searchParams.set(`code_challenge_method`,`S256`),t.searchParams.set(`origin`,e.openerOrigin),t.toString()}async function je(e,t,n){let r=await fetch(`${e.replace(/\/+$/,``)}/sdk/token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:t,codeVerifier:n})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to exchange code`)}return await r.json()}function Me(){return K||`https://gemigo.io/api/v1`}let Ne={async login(e={}){if(typeof window>`u`)throw new W(`NOT_SUPPORTED`,`auth.login is only supported in browser environments.`);let t=e.platformOrigin?.trim()||`https://gemigo.io`,n=e.apiBaseUrl?.trim()||`${t.replace(/\/+$/,``)}/api/v1`,r=e.appId?.trim()||Oe(),i=ke(e.scopes),a=typeof e.timeoutMs==`number`?e.timeoutMs:120*1e3,o=Ee(16),s=Ee(48),c=window.location.origin,l=Math.max(0,(window.screen.width-520)/2),u=Math.max(0,(window.screen.height-720)/2),d=window.open(`about:blank`,`gemigo_sdk_auth`,`popup=yes,width=520,height=720,left=${l},top=${u}`);if(!d)throw Error(`Popup blocked. Please allow popups and retry.`);try{d.document.title=`GemiGo Auth`,d.document.body.innerHTML=`<div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;padding:24px;">Loading…</div>`}catch{}let f=Ae({platformOrigin:t,appId:r,scopes:i,state:o,codeChallenge:await De(s),openerOrigin:c});try{d.location.href=f}catch{if(!window.open(f,`gemigo_sdk_auth`))throw Error(`Popup navigation failed. Please allow popups and retry.`)}let p=await je(n,(await new Promise((e,n)=>{let r=window.setTimeout(()=>{i(),n(Error(`Login timeout.`))},a),i=()=>{window.clearTimeout(r),window.removeEventListener(`message`,s);try{d.close()}catch{}},s=r=>{if(r.origin!==new URL(t).origin)return;let a=r.data;if(!(!a||typeof a!=`object`)&&a.state===o){if(a.type===`gemigo:sdk-auth-error`){i(),n(Error(String(a.error||`auth_error`)));return}a.type===`gemigo:sdk-auth-code`&&typeof a.code==`string`&&(i(),e({code:a.code}))}};window.addEventListener(`message`,s)})).code,s);return G=p,K=n,p},getAccessToken(){return G?.accessToken??null},logout(){G=null}};function Pe(){let e=Ne.getAccessToken();if(!e)throw new W(`PERMISSION_DENIED`,`Login required. Call gemigo.auth.login() first.`);return e}async function q(e,t={}){let n=Pe(),r=Me().replace(/\/+$/,``),i=await fetch(`${r}${e}`,{...t,headers:{...t.headers??{},Authorization:`Bearer ${n}`}});if(!i.ok){let e=(await i.json().catch(()=>({}))).error||`Request failed: ${i.status}`;throw i.status===401||i.status===403?new W(`PERMISSION_DENIED`,e):new W(`INTERNAL_ERROR`,e)}return await i.json()}var Fe=class{async get(e){return q(`/cloud/kv/get?key=${encodeURIComponent(e)}`)}async set(e,t,n){return q(`/cloud/kv/set`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e,value:t,ifMatch:n?.ifMatch})})}async delete(e,t){await q(`/cloud/kv/delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e,ifMatch:t?.ifMatch})})}async list(e){let t=new URLSearchParams;e?.prefix&&t.set(`prefix`,e.prefix),typeof e?.limit==`number`&&t.set(`limit`,String(e.limit)),e?.cursor&&t.set(`cursor`,e.cursor);let n=t.toString();return q(`/cloud/kv/list${n?`?${n}`:``}`)}},Ie=class e{constructor(e,t){this.collectionName=e,this.state={where:t?.where??[],orderBy:t?.orderBy??{field:`createdAt`,direction:`desc`},limit:t?.limit??20,cursor:t?.cursor??null}}where(t,n,r){return new e(this.collectionName,{...this.state,where:[...this.state.where,{field:t,op:n,value:r}]})}orderBy(t,n=`desc`){return new e(this.collectionName,{...this.state,orderBy:{field:t,direction:n}})}limit(t){return new e(this.collectionName,{...this.state,limit:t})}startAfter(t){return new e(this.collectionName,{...this.state,cursor:t})}async get(){return q(`/cloud/db/collections/${encodeURIComponent(this.collectionName)}/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:this.state.where,orderBy:this.state.orderBy,limit:this.state.limit,cursor:this.state.cursor})})}},Le=class{constructor(e){this.name=e}async add(e,t){return q(`/cloud/db/collections/${encodeURIComponent(this.name)}/docs`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:t?.id,visibility:t?.visibility,refType:t?.refType,refId:t?.refId,data:e})})}doc(e){let t=this.name;return{get:async()=>q(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`),set:async(n,r)=>q(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({data:n,ifMatch:r?.ifMatch,visibility:r?.visibility,refType:r?.refType,refId:r?.refId})}),update:async(n,r)=>q(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({patch:n,ifMatch:r?.ifMatch})}),delete:async()=>q(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`DELETE`}).then(()=>void 0)}}query(){return new Ie(this.name)}};function J(e){return{...e.data&&typeof e.data==`object`&&!Array.isArray(e.data)?e.data:{},_id:e.id,_openid:e.ownerId}}function Re(){return{eq:e=>({__gemigoWxCmd:`eq`,value:e}),neq:e=>({__gemigoWxCmd:`neq`,value:e}),gt:e=>({__gemigoWxCmd:`gt`,value:e}),gte:e=>({__gemigoWxCmd:`gte`,value:e}),lt:e=>({__gemigoWxCmd:`lt`,value:e}),lte:e=>({__gemigoWxCmd:`lte`,value:e}),in:e=>({__gemigoWxCmd:`in`,value:Array.isArray(e)?e:[]}),nin:e=>({__gemigoWxCmd:`nin`,value:Array.isArray(e)?e:[]}),inc:e=>({__gemigoWxCmd:`inc`,value:e}),set:e=>({__gemigoWxCmd:`set`,value:e}),remove:()=>({__gemigoWxCmd:`remove`})}}function ze(e){let t=typeof e?.offset==`number`&&Number.isFinite(e.offset)?e.offset:void 0;return t===void 0?{__gemigoWxType:`serverDate`}:{__gemigoWxType:`serverDate`,offset:t}}function Be(e){return e===`asc`?`asc`:`desc`}async function Ve(e,t,n,r){return q(`/cloud/db/collections/${encodeURIComponent(e)}/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:t.where,orderBy:t.orderBy,limit:r,cursor:n})})}function Y(e,t,n){let r={where:n?.where??{},orderBy:n?.orderBy??{field:`createdAt`,direction:`desc`},limit:n?.limit??20,skip:n?.skip??0,cursor:n?.cursor??null};return{where(n){return Y(e,t,{...r,where:{...r.where,...n??{}}})},orderBy(n,i){return Y(e,t,{...r,orderBy:{field:String(n),direction:Be(i)}})},limit(n){return Y(e,t,{...r,limit:Math.max(1,Math.floor(Number(n)||0))})},skip(n){return Y(e,t,{...r,skip:Math.max(0,Math.floor(Number(n)||0))})},startAfter(n){let i=String(n??``).trim();if(!i)throw new W(`INTERNAL_ERROR`,`startAfter(cursor) requires a non-empty cursor`);return Y(e,t,{...r,cursor:i})},async count(){return q(`/cloud/db/collections/${encodeURIComponent(e)}/count`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where})})},async update(t){let n=t?.data;if(!n||typeof n!=`object`||Array.isArray(n))throw new W(`INTERNAL_ERROR`,`update({data}) must be an object`);if(`_openid`in n)throw new W(`PERMISSION_DENIED`,`Cannot write system field _openid`);return q(`/cloud/db/collections/${encodeURIComponent(e)}/update`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where,data:n})})},async remove(){return q(`/cloud/db/collections/${encodeURIComponent(e)}/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where})})},async get(){let t=Math.min(r.limit,100),n=r.skip;if(n>1e3)throw new W(`NOT_SUPPORTED`,`skip(n) is capped at 1000; use cursor pagination instead.`);let i=r.cursor??null,a=n,o=t,s=[],c=0;for(;(a>0||o>0)&&c<30;){let t=await Ve(e,r,i,Math.min(100,a>0?a:o));if(c+=1,t.items.length===0)break;if(a>0){let e=Math.min(a,t.items.length);a-=e;let n=t.items.slice(e);if(a===0&&o>0&&n.length>0){let e=Math.min(o,n.length);s.push(...n.slice(0,e).map(J)),o-=e}}else s.push(...t.items.slice(0,o).map(J)),o=Math.max(0,o-t.items.length);if(i=t.nextCursor,!i)break}if(c>=30)throw new W(`NOT_SUPPORTED`,`skip/limit query requires too many requests; narrow your query.`);return{data:s,_meta:{nextCursor:i}}}}}function He(){let e=Re();return{command:e,serverDate:e=>ze(e),collection(t){let n=String(t).trim();if(!n)throw new W(`INTERNAL_ERROR`,`collection name is required`);let r=Y(n,e);return{...r,add:async e=>{let t=e?.data;if(t&&typeof t==`object`&&!Array.isArray(t)&&`_openid`in t)throw new W(`PERMISSION_DENIED`,`Cannot write system field _openid`);let r=t&&typeof t==`object`&&!Array.isArray(t)?t._id:void 0,i=t&&typeof t==`object`&&!Array.isArray(t)?{...t}:t;return i&&typeof i==`object`&&!Array.isArray(i)&&delete i._id,{_id:(await X.db.collection(n).add(i,{id:r?String(r):void 0})).id}},doc:e=>{let t=X.db.collection(n).doc(String(e));return{get:async()=>({data:J(await t.get())}),set:async e=>{let n=e?.data;if(n&&typeof n==`object`&&!Array.isArray(n)&&`_openid`in n)throw new W(`PERMISSION_DENIED`,`Cannot write system field _openid`);await t.set(e?.data)},update:async e=>{let n=e?.data??{};if(!n||typeof n!=`object`||Array.isArray(n))throw new W(`INTERNAL_ERROR`,`update({data}) must be an object`);if(`_openid`in n)throw new W(`PERMISSION_DENIED`,`Cannot write system field _openid`);await t.update(n)},remove:async()=>(await t.delete(),{stats:{removed:1}})}},get:async()=>r.get()}}}}let X={kv:new Fe,db:{collection(e){let t=String(e).trim();if(!t)throw new W(`INTERNAL_ERROR`,`collection name is required`);return new Le(t)}},blob:{async createUploadUrl(e){return q(`/cloud/blob/upload-url`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e.path,visibility:e.visibility,contentType:e.contentType,expiresIn:e.expiresIn})})},async getDownloadUrl(e){return q(`/cloud/blob/download-url`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({fileId:e.fileId,expiresIn:e.expiresIn})})}},functions:{async call(e,t){return(await q(`/cloud/functions/call`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:e,data:t??null})})).data}},init(e){},database(){return He()},async callFunction(e){let t=String(e?.name??``).trim();if(!t)throw new W(`INTERNAL_ERROR`,`callFunction name is required`);return{result:await X.functions.call(t,e?.data)}},async uploadFile(e){let t=String(e?.cloudPath??``).trim().replace(/^\/+/,``);if(!t)throw new W(`INTERNAL_ERROR`,`cloudPath is required`);let n=e?.filePath;if(!n)throw new W(`INTERNAL_ERROR`,`filePath is required`);let r=n.type?String(n.type):void 0,{fileId:i,uploadUrl:a}=await X.blob.createUploadUrl({path:t,visibility:`private`,contentType:r});return await fetch(a,{method:`PUT`,headers:r?{"Content-Type":r}:void 0,body:n}),{fileID:i}},async getTempFileURL(e){let t=Array.isArray(e?.fileList)?e.fileList:[];return{fileList:await Promise.all(t.map(async e=>{let t=typeof e==`string`?e:String(e?.fileID??``);if(!t)return{fileID:``,tempFileURL:``,status:400,errMsg:`fileID is required`};try{let{url:e}=await X.blob.getDownloadUrl({fileId:t});return{fileID:t,tempFileURL:e,status:0}}catch(e){return{fileID:t,tempFileURL:``,status:500,errMsg:e instanceof Error?e.message:String(e)}}}))}}};var Z=null,Ue={storage:!0,network:!1,scheduler:!1,fileWatch:!1,fileWrite:!1,notification:!0,clipboard:!1,ai:!1,shell:!1,extension:{read:!1,events:!1,modify:!1,capture:!1}};let We=e=>{Z=e};var Ge=e=>{throw new W(`NOT_SUPPORTED`,`${e} is not supported in this environment.`)},Q=e=>async()=>Ge(e),$=e=>()=>Ge(e),Ke={chat:Q(`ai.chat`),summarize:Q(`ai.summarize`),translate:Q(`ai.translate`)},qe={readText:Q(`clipboard.readText`),writeText:Q(`clipboard.writeText`),readImage:Q(`clipboard.readImage`),writeImage:Q(`clipboard.writeImage`),onChange:$(`clipboard.onChange`)},Je={openFile:Q(`dialog.openFile`),openDirectory:Q(`dialog.openDirectory`),saveFile:Q(`dialog.saveFile`),message:Q(`dialog.message`)},Ye={readText:Q(`file.readText`),readBinary:Q(`file.readBinary`),write:Q(`file.write`),append:Q(`file.append`),exists:Q(`file.exists`),stat:Q(`file.stat`),copy:Q(`file.copy`),move:Q(`file.move`),remove:Q(`file.remove`),list:Q(`file.list`),mkdir:Q(`file.mkdir`),persistPermission:Q(`file.persistPermission`)},Xe=$(`onNotificationAction`),Ze=$(`onFileDrop`);let{sdk:Qe,childMethods:$e}=xe({getters:{platform:()=>Z?.platform??`web`,capabilities:()=>Z?.capabilities??Ue},modules:{storage:{rpc:{methods:[`get`,`set`,`delete`,`clear`],mapping:{get:`storageGet`,set:`storageSet`,delete:`storageDelete`,clear:`storageClear`},fallbacks:{get:U.get,set:U.set,delete:U.delete,clear:U.clear}}},network:{rpc:{methods:[`request`],mapping:{request:`networkRequest`},fallbacks:{request:we.request}}},extension:{rpc:{methods:[`getPageInfo`,`getPageHTML`,`getPageText`,`getSelection`,`extractArticle`,`extractLinks`,`extractImages`,`queryElement`,`highlight`,`removeHighlight`,`insertWidget`,`updateWidget`,`removeWidget`,`injectCSS`,`removeCSS`,`captureVisible`,`getContextMenuEvent`]},events:[`onContextMenu`,`onSelectionChange`]}},actions:{notify:{method:`notify`,fallback:Ce}},statics:{SDKError:W,auth:Ne,cloud:X,ai:Ke,clipboard:qe,dialog:Je,file:Ye,onNotificationAction:Xe,onFileDrop:Ze}});return Se($e,{timeoutMs:1500}).then(e=>{e&&We(e)}),Qe.SDKError=W,Qe});
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?module.exports=t():typeof define==`function`&&define.amd?define([],t):(e=typeof globalThis<`u`?globalThis:e||self,e.gemigo=t())})(this,function(){var e=Object.defineProperty,t=(e,t)=>()=>(e&&(t=e(e=0)),t),n=t=>{let n={};for(var r in t)e(n,r,{get:t[r],enumerable:!0});return n},r,i,a,o,s,c=t((()=>{(function(e){e.Call=`call`,e.Reply=`reply`,e.Syn=`syn`,e.SynAck=`synAck`,e.Ack=`ack`})(r||={}),(function(e){e.Fulfilled=`fulfilled`,e.Rejected=`rejected`})(i||={}),(function(e){e.ConnectionDestroyed=`ConnectionDestroyed`,e.ConnectionTimeout=`ConnectionTimeout`,e.NoIframeSrc=`NoIframeSrc`})(a||={}),(function(e){e.DataCloneError=`DataCloneError`})(o||={}),(function(e){e.Message=`message`})(s||={})})),l,u=t((()=>{l=(e,t)=>{let n=[],r=!1;return{destroy(i){r||(r=!0,t(`${e}: Destroying connection`),n.forEach(e=>{e(i)}))},onDestroy(e){r?e():n.push(e)}}}})),d,f=t((()=>{d=e=>(...t)=>{e&&console.log(`[Penpal]`,...t)}})),p,m,h=t((()=>{p=({name:e,message:t,stack:n})=>({name:e,message:t,stack:n}),m=e=>{let t=Error();return Object.keys(e).forEach(n=>t[n]=e[n]),t}})),g,_=t((()=>{h(),c(),g=(e,t,n)=>{let{localName:a,local:c,remote:l,originForSending:u,originForReceiving:d}=e,f=!1,m=e=>{if(e.source!==l||e.data.penpal!==r.Call)return;if(d!==`*`&&e.origin!==d){n(`${a} received message from origin ${e.origin} which did not match expected origin ${d}`);return}let{methodName:s,args:c,id:m}=e.data;n(`${a}: Received ${s}() call`);let h=e=>t=>{if(n(`${a}: Sending ${s}() reply`),f){n(`${a}: Unable to send ${s}() reply due to destroyed connection`);return}let c={penpal:r.Reply,id:m,resolution:e,returnValue:t};e===i.Rejected&&t instanceof Error&&(c.returnValue=p(t),c.returnValueIsError=!0);try{l.postMessage(c,u)}catch(e){if(e.name===o.DataCloneError){let t={penpal:r.Reply,id:m,resolution:i.Rejected,returnValue:p(e),returnValueIsError:!0};l.postMessage(t,u)}throw e}};new Promise(e=>e(t[s].apply(t,c))).then(h(i.Fulfilled),h(i.Rejected))};return c.addEventListener(s.Message,m),()=>{f=!0,c.removeEventListener(s.Message,m)}}})),ee,te,ne=t((()=>{ee=0,te=()=>++ee})),v,y,re,ie,ae,b,x,S=t((()=>{v=`.`,y=e=>e?e.split(v):[],re=e=>e.join(v),ie=(e,t)=>{let n=y(t||``);return n.push(e),re(n)},ae=(e,t,n)=>{let r=y(t);return r.reduce((e,t,i)=>(e[t]===void 0&&(e[t]={}),i===r.length-1&&(e[t]=n),e[t]),e),e},b=(e,t)=>{let n={};return Object.keys(e).forEach(r=>{let i=e[r],a=ie(r,t);typeof i==`object`&&Object.assign(n,b(i,a)),typeof i==`function`&&(n[a]=i)}),n},x=e=>{let t={};for(let n in e)ae(t,n,e[n]);return t}})),C,w=t((()=>{ne(),h(),S(),c(),C=(e,t,n,o,c)=>{let{localName:l,local:u,remote:d,originForSending:f,originForReceiving:p}=t,h=!1;c(`${l}: Connecting call sender`);let g=e=>(...t)=>{c(`${l}: Sending ${e}() call`);let n;try{d.closed&&(n=!0)}catch{n=!0}if(n&&o(),h){let t=Error(`Unable to send ${e}() call due to destroyed connection`);throw t.code=a.ConnectionDestroyed,t}return new Promise((n,a)=>{let o=te(),h=t=>{if(t.source!==d||t.data.penpal!==r.Reply||t.data.id!==o)return;if(p!==`*`&&t.origin!==p){c(`${l} received message from origin ${t.origin} which did not match expected origin ${p}`);return}let f=t.data;c(`${l}: Received ${e}() reply`),u.removeEventListener(s.Message,h);let g=f.returnValue;f.returnValueIsError&&(g=m(g)),(f.resolution===i.Fulfilled?n:a)(g)};u.addEventListener(s.Message,h);let g={penpal:r.Call,id:o,methodName:e,args:t};d.postMessage(g,f)})},_=n.reduce((e,t)=>(e[t]=g(t),e),{});return Object.assign(e,x(_)),()=>{h=!0}}})),oe=t((()=>{_(),w()})),se=t((()=>{c()})),T,E=t((()=>{c(),T=(e,t)=>{let n;return e!==void 0&&(n=window.setTimeout(()=>{let n=Error(`Connection timed out after ${e}ms`);n.code=a.ConnectionTimeout,t(n)},e)),()=>{clearTimeout(n)}}})),ce=t((()=>{c()})),le=t((()=>{c(),oe(),se(),E(),ce()})),D,ue=t((()=>{c(),_(),w(),D=(e,t,n,i)=>{let{destroy:a,onDestroy:o}=n;return n=>{if(!(e instanceof RegExp?e.test(n.origin):e===`*`||e===n.origin)){i(`Child: Handshake - Received SYN-ACK from origin ${n.origin} which did not match expected origin ${e}`);return}i(`Child: Handshake - Received SYN-ACK, responding with ACK`);let s=n.origin===`null`?`*`:n.origin,c={penpal:r.Ack,methodNames:Object.keys(t)};window.parent.postMessage(c,s);let l={localName:`Child`,local:window,remote:window.parent,originForSending:s,originForReceiving:n.origin};o(g(l,t,i));let u={};return o(C(u,l,n.data.methodNames,a,i)),u}}})),O,k,de=t((()=>{u(),f(),c(),ue(),S(),E(),O=()=>{try{clearTimeout()}catch{return!1}return!0},k=(e={})=>{let{parentOrigin:t=`*`,methods:n={},timeout:i,debug:a=!1}=e,o=d(a),c=l(`Child`,o),{destroy:u,onDestroy:f}=c,p=D(t,b(n),c,o),m=()=>{o(`Child: Handshake - Sending SYN`);let e={penpal:r.Syn},n=t instanceof RegExp?`*`:t;window.parent.postMessage(e,n)};return{promise:new Promise((e,t)=>{let n=T(i,u),a=t=>{if(O()&&!(t.source!==parent||!t.data)&&t.data.penpal===r.SynAck){let r=p(t);r&&(window.removeEventListener(s.Message,a),n(),e(r))}};window.addEventListener(s.Message,a),m(),f(e=>{window.removeEventListener(s.Message,a),e&&t(e)})}),destroy(){u()}}}})),fe=t((()=>{le(),de(),c()})),pe=n({callHost:()=>j,createRPCProxy:()=>ye,getHost:()=>he,hasConnectionFailed:()=>_e,initConnection:()=>ve,isConnected:()=>ge,tryGetHost:()=>A,withFallback:()=>be});function me(){try{return window.self!==window.top}catch{return!0}}async function A(e,t){if(N)return N;if(P)return null;if(!me())return P=!0,null;if(!M){let n={},r=e??xe;r&&Object.assign(n,r),M=k({methods:n,timeout:t?.timeoutMs??F}).promise.then(e=>(N=e,e)).catch(e=>(console.error(`[GemiGo Connection] Promise failed:`,e),P=!0,M=null,null))}return M}async function he(){let e=await A();if(!e)throw Error(`Not connected to host. SDK may be running outside of a supported environment.`);return e}function ge(){return N!==null}function _e(){return P}function ve(e,t){xe=e,A(e,t)}async function j(e,t=[],n){let r=await A();if(r&&typeof r[e]==`function`){let i=await r[e](...t);if(i?.success!==!1)return i?.data===void 0?i?.value===void 0?i:i.value:i.data;if(n)return n(...t);throw Error(i?.error||`Host method ${String(e)} failed`)}if(n)return n(...t);throw Error(`Method ${String(e)} not supported in this environment`)}function ye(e,t={}){let n={};for(let r of e){let e=t.mapping?.[r]||r,i=t.fallbacks?.[r];n[r]=(...t)=>j(e,t,i)}return n}function be(e,t){return async(...n)=>{try{return await e(...n)}catch{return t(...n)}}}var M,N,P,xe,F,I=t((()=>{fe(),M=null,N=null,P=!1,F=1500}));I();function Se(){let e=new Map;return{on(t,n){return e.has(t)||e.set(t,new Set),e.get(t).add(n),()=>e.get(t)?.delete(n)},emit(t,...n){e.get(t)?.forEach(e=>e(...n))},off(t){t?e.delete(t):e.clear()}}}let L=Se();function Ce(e){let t=A,n={},r={};if(e.rpc){let t=ye(e.rpc.methods,{mapping:e.rpc.mapping,fallbacks:e.rpc.fallbacks});Object.assign(n,t)}if(e.events)if(Array.isArray(e.events))for(let i of e.events){let e=i;n[i]=n=>(t?.(),L.on(e,n)),r[i]=(...t)=>{L.emit(e,...t)}}else for(let[i,a]of Object.entries(e.events)){if(!a)continue;let e=a,o=typeof e==`string`?e:e.event,s=typeof e==`object`&&`childMethod`in e&&e.childMethod?e.childMethod:i;n[i]=e=>(t?.(),L.on(o,e)),r[s]=(...e)=>{L.emit(o,...e)}}return{api:n,childMethods:r}}function we(e,t){return async(...n)=>{try{let r=await j(e,t.transform?t.transform(...n):n);return t.onSuccess?t.onSuccess(r):r}catch{return t.fallback(...n)}}}function Te(e){let t=e.statics?{...e.statics}:{},n={};if(e.modules)for(let[r,i]of Object.entries(e.modules)){let{api:e,childMethods:a}=Ce(i);t[r]=e,Object.assign(n,a)}if(e.actions)for(let[n,r]of Object.entries(e.actions)){let e=r;t[n]=we(e.method,e)}if(e.getters)for(let[n,r]of Object.entries(e.getters))Object.defineProperty(t,n,{get:r,enumerable:!0,configurable:!0});return{sdk:t,childMethods:n}}async function Ee(e,t={}){let{initConnection:n}=await Promise.resolve().then(()=>(I(),pe));n(e,t);let r=await A();if(r&&typeof r.getProtocolInfo==`function`)try{return await r.getProtocolInfo()}catch{return null}return null}I();var R=()=>`gemigo:${typeof window>`u`?`unknown`:window.location.origin.replace(/[:/]/g,`_`)}:`;let z={get:async e=>{if(typeof window>`u`||!window.localStorage)return null;let t=window.localStorage.getItem(`${R()}${e}`);if(!t)return null;try{return JSON.parse(t)}catch{return null}},set:async(e,t)=>{typeof window>`u`||!window.localStorage||window.localStorage.setItem(`${R()}${e}`,JSON.stringify(t))},delete:async e=>{typeof window>`u`||!window.localStorage||window.localStorage.removeItem(`${R()}${e}`)},clear:async()=>{if(typeof window>`u`||!window.localStorage)return;let e=R();for(let t=window.localStorage.length-1;t>=0;--t){let n=window.localStorage.key(t);n&&n.startsWith(e)&&window.localStorage.removeItem(n)}}},De=async e=>{if(typeof window>`u`||typeof Notification>`u`)return{success:!1,reason:`not_supported`};if(Notification.permission!==`granted`)return{success:!1,reason:`permission_not_granted`};try{return new Notification(e.title,{body:e.message,icon:e.icon}),{success:!0}}catch{return{success:!1,reason:`failed_to_notify`}}},Oe={request:async(e,t)=>{let{method:n=`GET`,headers:r,body:i,responseType:a}=t??{},o=await fetch(e,{method:n,headers:r,body:i?typeof i==`string`?i:JSON.stringify(i):void 0}),s={};o.headers.forEach((e,t)=>s[t]=e);let c=a===`text`?await o.text():a===`arraybuffer`?await o.arrayBuffer():await o.json();return{status:o.status,data:c,headers:s}}};var B=class e extends Error{constructor(t,n){super(n),this.code=t,this.name=`SDKError`,Object.setPrototypeOf(this,e.prototype)}},V=null,H=null;function U(e){let t=``;for(let n of e)t+=String.fromCharCode(n);let n=globalThis.btoa;if(!n)throw Error(`base64 encoder not available`);return n(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/g,``)}function W(e=32){let t=new Uint8Array(e);return crypto.getRandomValues(t),U(t)}async function ke(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest(`SHA-256`,t);return U(new Uint8Array(n))}function Ae(){if(typeof window>`u`)return`unknown`;let e=window.location.hostname.toLowerCase();return e.endsWith(`.gemigo.app`)?e.replace(/\.gemigo\.app$/,``):e}function je(e){let t=(e??[`identity:basic`]).map(e=>String(e).trim()).filter(Boolean);return t.length>0?t:[`identity:basic`]}function Me(e){let t=new URL(`/sdk/broker`,e.platformOrigin);return t.searchParams.set(`app_id`,e.appId),t.searchParams.set(`scope`,e.scopes.join(` `)),t.searchParams.set(`state`,e.state),t.searchParams.set(`code_challenge`,e.codeChallenge),t.searchParams.set(`code_challenge_method`,`S256`),t.searchParams.set(`origin`,e.openerOrigin),t.toString()}async function Ne(e,t,n){let r=await fetch(`${e.replace(/\/+$/,``)}/sdk/token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:t,codeVerifier:n})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to exchange code`)}return await r.json()}function Pe(){return H||`https://gemigo.io/api/v1`}let G={async login(e={}){if(typeof window>`u`)throw new B(`NOT_SUPPORTED`,`auth.login is only supported in browser environments.`);let t=e.platformOrigin?.trim()||`https://gemigo.io`,n=e.apiBaseUrl?.trim()||`${t.replace(/\/+$/,``)}/api/v1`,r=e.appId?.trim()||Ae(),i=je(e.scopes),a=typeof e.timeoutMs==`number`?e.timeoutMs:120*1e3,o=W(16),s=W(48),c=window.location.origin,l=Math.max(0,(window.screen.width-520)/2),u=Math.max(0,(window.screen.height-720)/2),d=window.open(`about:blank`,`gemigo_sdk_auth`,`popup=yes,width=520,height=720,left=${l},top=${u}`);if(!d)throw Error(`Popup blocked. Please allow popups and retry.`);try{d.document.title=`GemiGo Auth`,d.document.body.innerHTML=`<div style="font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;padding:24px;">Loading…</div>`}catch{}let f=Me({platformOrigin:t,appId:r,scopes:i,state:o,codeChallenge:await ke(s),openerOrigin:c});try{d.location.href=f}catch{if(!window.open(f,`gemigo_sdk_auth`))throw Error(`Popup navigation failed. Please allow popups and retry.`)}let p=await Ne(n,(await new Promise((e,n)=>{let r=window.setTimeout(()=>{i(),n(Error(`Login timeout.`))},a),i=()=>{window.clearTimeout(r),window.removeEventListener(`message`,s);try{d.close()}catch{}},s=r=>{if(r.origin!==new URL(t).origin)return;let a=r.data;if(!(!a||typeof a!=`object`)&&a.state===o){if(a.type===`gemigo:sdk-auth-error`){i(),n(Error(String(a.error||`auth_error`)));return}a.type===`gemigo:sdk-auth-code`&&typeof a.code==`string`&&(i(),e({code:a.code}))}};window.addEventListener(`message`,s)})).code,s);return V=p,H=n,p},getAccessToken(){return V?.accessToken??null},logout(){V=null}};function Fe(){let e=G.getAccessToken();if(!e)throw new B(`PERMISSION_DENIED`,`Login required. Call gemigo.auth.login() first.`);return e}async function K(e,t={}){let n=Fe(),r=Pe().replace(/\/+$/,``),i=await fetch(`${r}${e}`,{...t,headers:{...t.headers??{},Authorization:`Bearer ${n}`}});if(!i.ok){let e=(await i.json().catch(()=>({}))).error||`Request failed: ${i.status}`;throw i.status===401||i.status===403?new B(`PERMISSION_DENIED`,e):new B(`INTERNAL_ERROR`,e)}return await i.json()}var Ie=class{async get(e){return K(`/cloud/kv/get?key=${encodeURIComponent(e)}`)}async set(e,t,n){return K(`/cloud/kv/set`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e,value:t,ifMatch:n?.ifMatch})})}async delete(e,t){await K(`/cloud/kv/delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({key:e,ifMatch:t?.ifMatch})})}async list(e){let t=new URLSearchParams;e?.prefix&&t.set(`prefix`,e.prefix),typeof e?.limit==`number`&&t.set(`limit`,String(e.limit)),e?.cursor&&t.set(`cursor`,e.cursor);let n=t.toString();return K(`/cloud/kv/list${n?`?${n}`:``}`)}},Le=class e{constructor(e,t){this.collectionName=e,this.state={where:t?.where??[],orderBy:t?.orderBy??{field:`createdAt`,direction:`desc`},limit:t?.limit??20,cursor:t?.cursor??null}}where(t,n,r){return new e(this.collectionName,{...this.state,where:[...this.state.where,{field:t,op:n,value:r}]})}orderBy(t,n=`desc`){return new e(this.collectionName,{...this.state,orderBy:{field:t,direction:n}})}limit(t){return new e(this.collectionName,{...this.state,limit:t})}startAfter(t){return new e(this.collectionName,{...this.state,cursor:t})}async get(){return K(`/cloud/db/collections/${encodeURIComponent(this.collectionName)}/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:this.state.where,orderBy:this.state.orderBy,limit:this.state.limit,cursor:this.state.cursor})})}},Re=class{constructor(e){this.name=e}async add(e,t){return K(`/cloud/db/collections/${encodeURIComponent(this.name)}/docs`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:t?.id,data:e})})}doc(e){let t=this.name;return{get:async()=>K(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`),set:async(n,r)=>K(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({data:n,ifMatch:r?.ifMatch})}),update:async(n,r)=>K(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({patch:n,ifMatch:r?.ifMatch})}),delete:async()=>K(`/cloud/db/collections/${encodeURIComponent(t)}/docs/${encodeURIComponent(e)}`,{method:`DELETE`}).then(()=>void 0)}}query(){return new Le(this.name)}};function q(e){return{...e.data&&typeof e.data==`object`&&!Array.isArray(e.data)?e.data:{},_id:e.id,_openid:e.ownerId}}function ze(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.__gemigoWxCmd==`string`||t.__gemigoWxType===`serverDate`}function J(e,t){if(!e||typeof e!=`object`)return;if(Array.isArray(e)){for(let n of e)J(n,t);return}if(ze(e))return;let n=e;for(let[e,r]of Object.entries(n)){if(e.startsWith(`_`)&&!(t.allowId&&e===`_id`))throw new B(`PERMISSION_DENIED`,`Cannot write system field ${e}`);J(r,t)}}function Be(){return{eq:e=>({__gemigoWxCmd:`eq`,value:e}),neq:e=>({__gemigoWxCmd:`neq`,value:e}),gt:e=>({__gemigoWxCmd:`gt`,value:e}),gte:e=>({__gemigoWxCmd:`gte`,value:e}),lt:e=>({__gemigoWxCmd:`lt`,value:e}),lte:e=>({__gemigoWxCmd:`lte`,value:e}),in:e=>({__gemigoWxCmd:`in`,value:Array.isArray(e)?e:[]}),nin:e=>({__gemigoWxCmd:`nin`,value:Array.isArray(e)?e:[]}),inc:e=>({__gemigoWxCmd:`inc`,value:e}),set:e=>({__gemigoWxCmd:`set`,value:e}),remove:()=>({__gemigoWxCmd:`remove`})}}function Ve(e){let t=typeof e?.offset==`number`&&Number.isFinite(e.offset)?e.offset:void 0;return t===void 0?{__gemigoWxType:`serverDate`}:{__gemigoWxType:`serverDate`,offset:t}}function He(e){return e===`asc`?`asc`:`desc`}async function Ue(e,t,n,r){return K(`/cloud/db/collections/${encodeURIComponent(e)}/query`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:t.where,orderBy:t.orderBy,limit:r,cursor:n})})}function Y(e,t,n){let r={where:n?.where??{},orderBy:n?.orderBy??{field:`createdAt`,direction:`desc`},limit:n?.limit??20,skip:n?.skip??0,cursor:n?.cursor??null};return{where(n){return Y(e,t,{...r,where:{...r.where,...n??{}}})},orderBy(n,i){return Y(e,t,{...r,orderBy:{field:String(n),direction:He(i)}})},limit(n){return Y(e,t,{...r,limit:Math.max(1,Math.floor(Number(n)||0))})},skip(n){return Y(e,t,{...r,skip:Math.max(0,Math.floor(Number(n)||0))})},startAfter(n){let i=String(n??``).trim();if(!i)throw new B(`INTERNAL_ERROR`,`startAfter(cursor) requires a non-empty cursor`);return Y(e,t,{...r,cursor:i})},async count(){return K(`/cloud/db/collections/${encodeURIComponent(e)}/count`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where})})},async update(t){let n=t?.data;if(!n||typeof n!=`object`||Array.isArray(n))throw new B(`INTERNAL_ERROR`,`update({data}) must be an object`);if(`_openid`in n)throw new B(`PERMISSION_DENIED`,`Cannot write system field _openid`);return K(`/cloud/db/collections/${encodeURIComponent(e)}/update`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where,data:n})})},async remove(){return K(`/cloud/db/collections/${encodeURIComponent(e)}/remove`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({where:r.where})})},async get(){let t=Math.min(r.limit,100),n=r.skip;if(n>1e3)throw new B(`NOT_SUPPORTED`,`skip(n) is capped at 1000; use cursor pagination instead.`);let i=r.cursor??null,a=n,o=t,s=[],c=0;for(;(a>0||o>0)&&c<30;){let t=await Ue(e,r,i,Math.min(100,a>0?a:o));if(c+=1,t.items.length===0)break;if(a>0){let e=Math.min(a,t.items.length);a-=e;let n=t.items.slice(e);if(a===0&&o>0&&n.length>0){let e=Math.min(o,n.length);s.push(...n.slice(0,e).map(q)),o-=e}}else s.push(...t.items.slice(0,o).map(q)),o=Math.max(0,o-t.items.length);if(i=t.nextCursor,!i)break}if(c>=30)throw new B(`NOT_SUPPORTED`,`skip/limit query requires too many requests; narrow your query.`);return{data:s,_meta:{nextCursor:i}}}}}function We(){let e=Be();return{command:e,serverDate:e=>Ve(e),collection(t){let n=String(t).trim();if(!n)throw new B(`INTERNAL_ERROR`,`collection name is required`);let r=Y(n,e);return{...r,add:async e=>{let t=e?.data;J(t,{allowId:!0});let r=t&&typeof t==`object`&&!Array.isArray(t)?t._id:void 0,i=t&&typeof t==`object`&&!Array.isArray(t)?{...t}:t;return i&&typeof i==`object`&&!Array.isArray(i)&&delete i._id,{_id:(await X.db.collection(n).add(i,{id:r?String(r):void 0})).id}},doc:e=>{let t=X.db.collection(n).doc(String(e));return{get:async()=>({data:q(await t.get())}),set:async e=>{let n=e?.data;J(n,{allowId:!1}),await t.set(e?.data)},update:async e=>{let n=e?.data??{};if(!n||typeof n!=`object`||Array.isArray(n))throw new B(`INTERNAL_ERROR`,`update({data}) must be an object`);J(n,{allowId:!1}),await t.update(n)},remove:async()=>(await t.delete(),{stats:{removed:1}})}},get:async()=>r.get()}}}}let X={kv:new Ie,db:{collection(e){let t=String(e).trim();if(!t)throw new B(`INTERNAL_ERROR`,`collection name is required`);return new Re(t)}},blob:{async createUploadUrl(e){return K(`/cloud/blob/upload-url`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:e.path,visibility:e.visibility,contentType:e.contentType,expiresIn:e.expiresIn})})},async getDownloadUrl(e){return K(`/cloud/blob/download-url`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({fileId:e.fileId,expiresIn:e.expiresIn})})}},functions:{async call(e,t){return(await K(`/cloud/functions/call`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:e,data:t??null})})).data}},init(e){},database(){return We()},async callFunction(e){let t=String(e?.name??``).trim();if(!t)throw new B(`INTERNAL_ERROR`,`callFunction name is required`);return{result:await X.functions.call(t,e?.data)}},async uploadFile(e){let t=String(e?.cloudPath??``).trim().replace(/^\/+/,``);if(!t)throw new B(`INTERNAL_ERROR`,`cloudPath is required`);let n=e?.filePath;if(!n)throw new B(`INTERNAL_ERROR`,`filePath is required`);let r=n.type?String(n.type):void 0,{fileId:i,uploadUrl:a}=await X.blob.createUploadUrl({path:t,visibility:`private`,contentType:r});return await fetch(a,{method:`PUT`,headers:r?{"Content-Type":r}:void 0,body:n}),{fileID:i}},async getTempFileURL(e){let t=Array.isArray(e?.fileList)?e.fileList:[];return{fileList:await Promise.all(t.map(async e=>{let t=typeof e==`string`?e:String(e?.fileID??``);if(!t)return{fileID:``,tempFileURL:``,status:400,errMsg:`fileID is required`};try{let{url:e}=await X.blob.getDownloadUrl({fileId:t});return{fileID:t,tempFileURL:e,status:0}}catch(e){return{fileID:t,tempFileURL:``,status:500,errMsg:e instanceof Error?e.message:String(e)}}}))}}};var Z=null,Ge={storage:!0,network:!1,scheduler:!1,fileWatch:!1,fileWrite:!1,notification:!0,clipboard:!1,ai:!1,shell:!1,extension:{read:!1,events:!1,modify:!1,capture:!1}};let Ke=e=>{Z=e};var qe=e=>{throw new B(`NOT_SUPPORTED`,`${e} is not supported in this environment.`)},Q=e=>async()=>qe(e),$=e=>()=>qe(e),Je={chat:Q(`ai.chat`),summarize:Q(`ai.summarize`),translate:Q(`ai.translate`)},Ye={readText:Q(`clipboard.readText`),writeText:Q(`clipboard.writeText`),readImage:Q(`clipboard.readImage`),writeImage:Q(`clipboard.writeImage`),onChange:$(`clipboard.onChange`)},Xe={openFile:Q(`dialog.openFile`),openDirectory:Q(`dialog.openDirectory`),saveFile:Q(`dialog.saveFile`),message:Q(`dialog.message`)},Ze={readText:Q(`file.readText`),readBinary:Q(`file.readBinary`),write:Q(`file.write`),append:Q(`file.append`),exists:Q(`file.exists`),stat:Q(`file.stat`),copy:Q(`file.copy`),move:Q(`file.move`),remove:Q(`file.remove`),list:Q(`file.list`),mkdir:Q(`file.mkdir`),persistPermission:Q(`file.persistPermission`)},Qe=$(`onNotificationAction`),$e=$(`onFileDrop`);let{sdk:et,childMethods:tt}=Te({getters:{platform:()=>Z?.platform??`web`,capabilities:()=>Z?.capabilities??Ge},modules:{storage:{rpc:{methods:[`get`,`set`,`delete`,`clear`],mapping:{get:`storageGet`,set:`storageSet`,delete:`storageDelete`,clear:`storageClear`},fallbacks:{get:z.get,set:z.set,delete:z.delete,clear:z.clear}}},network:{rpc:{methods:[`request`],mapping:{request:`networkRequest`},fallbacks:{request:Oe.request}}},extension:{rpc:{methods:[`getPageInfo`,`getPageHTML`,`getPageText`,`getSelection`,`extractArticle`,`extractLinks`,`extractImages`,`queryElement`,`highlight`,`removeHighlight`,`insertWidget`,`updateWidget`,`removeWidget`,`injectCSS`,`removeCSS`,`captureVisible`,`getContextMenuEvent`]},events:[`onContextMenu`,`onSelectionChange`]}},actions:{notify:{method:`notify`,fallback:De}},statics:{SDKError:B,auth:G,cloud:X,ai:Je,clipboard:Ye,dialog:Xe,file:Ze,onNotificationAction:Qe,onFileDrop:$e}});return Ee(tt,{timeoutMs:1500}).then(e=>{e&&Ke(e)}),et.SDKError=B,et});
|
package/dist/types/cloud.d.ts
CHANGED
|
@@ -35,9 +35,6 @@ export interface CloudKvAPI {
|
|
|
35
35
|
export interface CloudDbDoc<T = unknown> {
|
|
36
36
|
id: string;
|
|
37
37
|
ownerId: string;
|
|
38
|
-
visibility: CloudVisibility;
|
|
39
|
-
refType: string | null;
|
|
40
|
-
refId: string | null;
|
|
41
38
|
data: T;
|
|
42
39
|
createdAt: number;
|
|
43
40
|
updatedAt: number;
|
|
@@ -45,9 +42,9 @@ export interface CloudDbDoc<T = unknown> {
|
|
|
45
42
|
}
|
|
46
43
|
export type CloudDbWhereOp = '==';
|
|
47
44
|
export interface CloudDbWhere {
|
|
48
|
-
field:
|
|
45
|
+
field: string;
|
|
49
46
|
op: CloudDbWhereOp;
|
|
50
|
-
value:
|
|
47
|
+
value: unknown;
|
|
51
48
|
}
|
|
52
49
|
export interface CloudDbQueryInput {
|
|
53
50
|
where?: CloudDbWhere[];
|
|
@@ -66,9 +63,6 @@ export interface CloudDbDocumentRef<T = unknown> {
|
|
|
66
63
|
get(): Promise<CloudDbDoc<T>>;
|
|
67
64
|
set(data: T, options?: {
|
|
68
65
|
ifMatch?: string;
|
|
69
|
-
visibility?: CloudVisibility;
|
|
70
|
-
refType?: string;
|
|
71
|
-
refId?: string;
|
|
72
66
|
}): Promise<CloudDbDoc<T>>;
|
|
73
67
|
update(patch: Partial<T>, options?: {
|
|
74
68
|
ifMatch?: string;
|
|
@@ -76,7 +70,7 @@ export interface CloudDbDocumentRef<T = unknown> {
|
|
|
76
70
|
delete(): Promise<void>;
|
|
77
71
|
}
|
|
78
72
|
export interface CloudDbQueryBuilder<T = unknown> {
|
|
79
|
-
where(field:
|
|
73
|
+
where(field: string, op: CloudDbWhereOp, value: unknown): CloudDbQueryBuilder<T>;
|
|
80
74
|
orderBy(field: 'createdAt' | 'updatedAt', direction?: 'asc' | 'desc'): CloudDbQueryBuilder<T>;
|
|
81
75
|
limit(n: number): CloudDbQueryBuilder<T>;
|
|
82
76
|
startAfter(cursor: string): CloudDbQueryBuilder<T>;
|
|
@@ -85,9 +79,6 @@ export interface CloudDbQueryBuilder<T = unknown> {
|
|
|
85
79
|
export interface CloudDbCollection<T = unknown> {
|
|
86
80
|
add(data: T, options?: {
|
|
87
81
|
id?: string;
|
|
88
|
-
visibility?: CloudVisibility;
|
|
89
|
-
refType?: string;
|
|
90
|
-
refId?: string;
|
|
91
82
|
}): Promise<CloudDbDoc<T>>;
|
|
92
83
|
doc(id: string): CloudDbDocumentRef<T>;
|
|
93
84
|
query(): CloudDbQueryBuilder<T>;
|