@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.
@@ -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(B, V) {
6
- return f.has(B) || f.set(B, /* @__PURE__ */ new Set()), f.get(B).add(V), () => f.get(B)?.delete(V);
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(B, ...V) {
9
- f.get(B)?.forEach((f) => f(...V));
8
+ emit(V, ...H) {
9
+ f.get(V)?.forEach((f) => f(...H));
10
10
  },
11
- off(B) {
12
- B ? f.delete(B) : f.clear();
11
+ off(V) {
12
+ V ? f.delete(V) : f.clear();
13
13
  }
14
14
  };
15
15
  }
16
16
  const sdkEventBus = createEventBus();
17
- function createUnifiedAPI(V) {
18
- let H = tryGetHost, W = {}, G = {};
19
- if (V.rpc) {
20
- let f = createRPCProxy(V.rpc.methods, {
21
- mapping: V.rpc.mapping,
22
- fallbacks: V.rpc.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(W, f);
24
+ Object.assign(G, f);
25
25
  }
26
- if (V.events) if (Array.isArray(V.events)) for (let f of V.events) {
27
- let B = f;
28
- W[f] = (f) => (H?.(), sdkEventBus.on(B, f)), G[f] = (...f) => {
29
- sdkEventBus.emit(B, ...f);
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, B] of Object.entries(V.events)) {
33
- if (!B) continue;
34
- let V = B, K = typeof V == "string" ? V : V.event, q = typeof V == "object" && "childMethod" in V && V.childMethod ? V.childMethod : f;
35
- W[f] = (f) => (H?.(), sdkEventBus.on(K, f)), G[q] = (...f) => {
36
- sdkEventBus.emit(K, ...f);
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: W,
41
- childMethods: G
40
+ api: G,
41
+ childMethods: K
42
42
  };
43
43
  }
44
- function createRPCAction(f, B) {
45
- return async (...H) => {
44
+ function createRPCAction(f, V) {
45
+ return async (...U) => {
46
46
  try {
47
- let U = await callHost(f, B.transform ? B.transform(...H) : H);
48
- return B.onSuccess ? B.onSuccess(U) : U;
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 B.fallback(...H);
50
+ return V.fallback(...U);
51
51
  }
52
52
  };
53
53
  }
54
54
  function createSDK(f) {
55
- let B = f.statics ? { ...f.statics } : {}, V = {};
56
- if (f.modules) for (let [H, U] of Object.entries(f.modules)) {
57
- let { api: f, childMethods: G } = createUnifiedAPI(U);
58
- B[H] = f, Object.assign(V, G);
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 [V, H] of Object.entries(f.actions)) {
61
- let f = H;
62
- B[V] = createRPCAction(f.method, f);
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 [V, H] of Object.entries(f.getters)) Object.defineProperty(B, V, {
65
- get: H,
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: B,
71
- childMethods: V
70
+ sdk: V,
71
+ childMethods: H
72
72
  };
73
73
  }
74
- async function bootstrapSDK(B, V = {}) {
75
- let { initConnection: H } = await import("./connection-C-IGR2wz.js");
76
- H(B, V);
77
- let U = await tryGetHost();
78
- if (U && typeof U.getProtocolInfo == "function") try {
79
- return await U.getProtocolInfo();
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 B = window.localStorage.getItem(`${localStoragePrefix()}${f}`);
90
- if (!B) return null;
89
+ let V = window.localStorage.getItem(`${localStoragePrefix()}${f}`);
90
+ if (!V) return null;
91
91
  try {
92
- return JSON.parse(B);
92
+ return JSON.parse(V);
93
93
  } catch {
94
94
  return null;
95
95
  }
96
96
  },
97
- set: async (f, B) => {
98
- typeof window > "u" || !window.localStorage || window.localStorage.setItem(`${localStoragePrefix()}${f}`, JSON.stringify(B));
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 B = window.localStorage.length - 1; B >= 0; --B) {
107
- let V = window.localStorage.key(B);
108
- V && V.startsWith(f) && window.localStorage.removeItem(V);
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, B) => {
132
- let { method: V = "GET", headers: H, body: U, responseType: W } = B ?? {}, G = await fetch(f, {
133
- method: V,
134
- headers: H,
135
- body: U ? typeof U == "string" ? U : JSON.stringify(U) : void 0
136
- }), K = {};
137
- G.headers.forEach((f, B) => K[B] = f);
138
- let q = W === "text" ? await G.text() : W === "arraybuffer" ? await G.arrayBuffer() : await G.json();
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: G.status,
141
- data: q,
142
- headers: K
140
+ status: K.status,
141
+ data: J,
142
+ headers: q
143
143
  };
144
144
  } };
145
145
  var SDKError = class f extends Error {
146
- constructor(B, V) {
147
- super(V), this.code = B, this.name = "SDKError", Object.setPrototypeOf(this, f.prototype);
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 B = "";
152
- for (let V of f) B += String.fromCharCode(V);
153
- let V = globalThis.btoa;
154
- if (!V) throw Error("base64 encoder not available");
155
- return V(B).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
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 B = new Uint8Array(f);
159
- return crypto.getRandomValues(B), base64UrlEncode(B);
158
+ let V = new Uint8Array(f);
159
+ return crypto.getRandomValues(V), base64UrlEncode(V);
160
160
  }
161
161
  async function sha256Base64Url(f) {
162
- let B = new TextEncoder().encode(f), V = await crypto.subtle.digest("SHA-256", B);
163
- return base64UrlEncode(new Uint8Array(V));
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 B = (f ?? ["identity:basic"]).map((f) => String(f).trim()).filter(Boolean);
172
- return B.length > 0 ? B : ["identity:basic"];
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 B = new URL("/sdk/broker", f.platformOrigin);
176
- return B.searchParams.set("app_id", f.appId), B.searchParams.set("scope", f.scopes.join(" ")), B.searchParams.set("state", f.state), B.searchParams.set("code_challenge", f.codeChallenge), B.searchParams.set("code_challenge_method", "S256"), B.searchParams.set("origin", f.openerOrigin), B.toString();
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, B, V) {
179
- let H = await fetch(`${f.replace(/\/+$/, "")}/sdk/token`, {
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: B,
184
- codeVerifier: V
183
+ code: V,
184
+ codeVerifier: H
185
185
  })
186
186
  });
187
- if (!H.ok) {
188
- let f = await H.json().catch(() => ({}));
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 H.json();
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 B = f.platformOrigin?.trim() || "https://gemigo.io", V = f.apiBaseUrl?.trim() || `${B.replace(/\/+$/, "")}/api/v1`, H = f.appId?.trim() || deriveDefaultAppId(), U = normalizeScopes(f.scopes), W = typeof f.timeoutMs == "number" ? f.timeoutMs : 120 * 1e3, G = randomString(16), K = randomString(48), q = window.location.origin, J = Math.max(0, (window.screen.width - 520) / 2), Y = Math.max(0, (window.screen.height - 720) / 2), X = window.open("about:blank", "gemigo_sdk_auth", `popup=yes,width=520,height=720,left=${J},top=${Y}`);
200
- if (!X) throw Error("Popup blocked. Please allow popups and retry.");
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
- X.document.title = "GemiGo Auth", X.document.body.innerHTML = "<div style=\"font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;padding:24px;\">Loading…</div>";
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 Z = buildBrokerUrl({
205
- platformOrigin: B,
206
- appId: H,
207
- scopes: U,
208
- state: G,
209
- codeChallenge: await sha256Base64Url(K),
210
- openerOrigin: q
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
- X.location.href = Z;
213
+ Z.location.href = Q;
214
214
  } catch {
215
- if (!window.open(Z, "gemigo_sdk_auth")) throw Error("Popup navigation failed. Please allow popups and retry.");
215
+ if (!window.open(Q, "gemigo_sdk_auth")) throw Error("Popup navigation failed. Please allow popups and retry.");
216
216
  }
217
- let Q = await exchangeCode(V, (await new Promise((f, V) => {
218
- let H = window.setTimeout(() => {
219
- U(), V(/* @__PURE__ */ Error("Login timeout."));
220
- }, W), U = () => {
221
- window.clearTimeout(H), window.removeEventListener("message", K);
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
- X.close();
223
+ Z.close();
224
224
  } catch {}
225
- }, K = (H) => {
226
- if (H.origin !== new URL(B).origin) return;
227
- let W = H.data;
228
- if (!(!W || typeof W != "object") && W.state === G) {
229
- if (W.type === "gemigo:sdk-auth-error") {
230
- U(), V(Error(String(W.error || "auth_error")));
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
- W.type === "gemigo:sdk-auth-code" && typeof W.code == "string" && (U(), f({ code: W.code }));
233
+ G.type === "gemigo:sdk-auth-code" && typeof G.code == "string" && (W(), f({ code: G.code }));
234
234
  }
235
235
  };
236
- window.addEventListener("message", K);
237
- })).code, K);
238
- return currentToken = Q, currentApiBaseUrl = V, Q;
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, B = {}) {
253
- let V = requireAccessToken(), H = getWebApiBaseUrl().replace(/\/+$/, ""), U = await fetch(`${H}${f}`, {
254
- ...B,
252
+ async function fetchJson(f, V = {}) {
253
+ let H = requireAccessToken(), U = getWebApiBaseUrl().replace(/\/+$/, ""), W = await fetch(`${U}${f}`, {
254
+ ...V,
255
255
  headers: {
256
- ...B.headers ?? {},
257
- Authorization: `Bearer ${V}`
256
+ ...V.headers ?? {},
257
+ Authorization: `Bearer ${H}`
258
258
  }
259
259
  });
260
- if (!U.ok) {
261
- let f = (await U.json().catch(() => ({}))).error || `Request failed: ${U.status}`;
262
- throw U.status === 401 || U.status === 403 ? new SDKError("PERMISSION_DENIED", f) : new SDKError("INTERNAL_ERROR", f);
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 U.json();
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, B, V) {
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: B,
277
- ifMatch: V?.ifMatch
276
+ value: V,
277
+ ifMatch: H?.ifMatch
278
278
  })
279
279
  });
280
280
  }
281
- async delete(f, B) {
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: B?.ifMatch
287
+ ifMatch: V?.ifMatch
288
288
  })
289
289
  });
290
290
  }
291
291
  async list(f) {
292
- let B = new URLSearchParams();
293
- f?.prefix && B.set("prefix", f.prefix), typeof f?.limit == "number" && B.set("limit", String(f.limit)), f?.cursor && B.set("cursor", f.cursor);
294
- let V = B.toString();
295
- return fetchJson(`/cloud/kv/list${V ? `?${V}` : ""}`);
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, B) {
298
+ constructor(f, V) {
299
299
  this.collectionName = f, this.state = {
300
- where: B?.where ?? [],
301
- orderBy: B?.orderBy ?? {
300
+ where: V?.where ?? [],
301
+ orderBy: V?.orderBy ?? {
302
302
  field: "createdAt",
303
303
  direction: "desc"
304
304
  },
305
- limit: B?.limit ?? 20,
306
- cursor: B?.cursor ?? null
305
+ limit: V?.limit ?? 20,
306
+ cursor: V?.cursor ?? null
307
307
  };
308
308
  }
309
- where(B, V, H) {
309
+ where(V, H, U) {
310
310
  return new f(this.collectionName, {
311
311
  ...this.state,
312
312
  where: [...this.state.where, {
313
- field: B,
314
- op: V,
315
- value: H
313
+ field: V,
314
+ op: H,
315
+ value: U
316
316
  }]
317
317
  });
318
318
  }
319
- orderBy(B, V = "desc") {
319
+ orderBy(V, H = "desc") {
320
320
  return new f(this.collectionName, {
321
321
  ...this.state,
322
322
  orderBy: {
323
- field: B,
324
- direction: V
323
+ field: V,
324
+ direction: H
325
325
  }
326
326
  });
327
327
  }
328
- limit(B) {
328
+ limit(V) {
329
329
  return new f(this.collectionName, {
330
330
  ...this.state,
331
- limit: B
331
+ limit: V
332
332
  });
333
333
  }
334
- startAfter(B) {
334
+ startAfter(V) {
335
335
  return new f(this.collectionName, {
336
336
  ...this.state,
337
- cursor: B
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, B) {
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: B?.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 B = this.name;
367
+ let V = this.name;
371
368
  return {
372
- get: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(B)}/docs/${encodeURIComponent(f)}`),
373
- set: async (V, H) => fetchJson(`/cloud/db/collections/${encodeURIComponent(B)}/docs/${encodeURIComponent(f)}`, {
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: V,
378
- ifMatch: H?.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 (V, H) => fetchJson(`/cloud/db/collections/${encodeURIComponent(B)}/docs/${encodeURIComponent(f)}`, {
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: V,
389
- ifMatch: H?.ifMatch
382
+ patch: H,
383
+ ifMatch: U?.ifMatch
390
384
  })
391
385
  }),
392
- delete: async () => fetchJson(`/cloud/db/collections/${encodeURIComponent(B)}/docs/${encodeURIComponent(f)}`, { method: "DELETE" }).then(() => void 0)
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 B = typeof f?.offset == "number" && Number.isFinite(f.offset) ? f.offset : void 0;
453
- return B === void 0 ? { __gemigoWxType: "serverDate" } : {
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: B
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, B, V, H) {
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: B.where,
467
- orderBy: B.orderBy,
468
- limit: H,
469
- cursor: V
478
+ where: V.where,
479
+ orderBy: V.orderBy,
480
+ limit: U,
481
+ cursor: H
470
482
  })
471
483
  });
472
484
  }
473
- function createWxQuery(f, B, V) {
474
- let H = {
475
- where: V?.where ?? {},
476
- orderBy: V?.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: V?.limit ?? 20,
481
- skip: V?.skip ?? 0,
482
- cursor: V?.cursor ?? null
492
+ limit: H?.limit ?? 20,
493
+ skip: H?.skip ?? 0,
494
+ cursor: H?.cursor ?? null
483
495
  };
484
496
  return {
485
- where(V) {
486
- return createWxQuery(f, B, {
487
- ...H,
497
+ where(H) {
498
+ return createWxQuery(f, V, {
499
+ ...U,
488
500
  where: {
489
- ...H.where,
490
- ...V ?? {}
501
+ ...U.where,
502
+ ...H ?? {}
491
503
  }
492
504
  });
493
505
  },
494
- orderBy(V, U) {
495
- return createWxQuery(f, B, {
496
- ...H,
506
+ orderBy(H, W) {
507
+ return createWxQuery(f, V, {
508
+ ...U,
497
509
  orderBy: {
498
- field: String(V),
499
- direction: normalizeWxDirection(U)
510
+ field: String(H),
511
+ direction: normalizeWxDirection(W)
500
512
  }
501
513
  });
502
514
  },
503
- limit(V) {
504
- return createWxQuery(f, B, {
505
- ...H,
506
- limit: Math.max(1, Math.floor(Number(V) || 0))
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(V) {
510
- return createWxQuery(f, B, {
511
- ...H,
512
- skip: Math.max(0, Math.floor(Number(V) || 0))
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(V) {
516
- let U = String(V ?? "").trim();
517
- if (!U) throw new SDKError("INTERNAL_ERROR", "startAfter(cursor) requires a non-empty cursor");
518
- return createWxQuery(f, B, {
519
- ...H,
520
- cursor: U
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: H.where })
539
+ body: JSON.stringify({ where: U.where })
528
540
  });
529
541
  },
530
- async update(B) {
531
- let V = B?.data;
532
- if (!V || typeof V != "object" || Array.isArray(V)) throw new SDKError("INTERNAL_ERROR", "update({data}) must be an object");
533
- if ("_openid" in V) throw new SDKError("PERMISSION_DENIED", "Cannot write system field _openid");
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: H.where,
539
- data: V
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: H.where })
559
+ body: JSON.stringify({ where: U.where })
548
560
  });
549
561
  },
550
562
  async get() {
551
- let B = Math.min(H.limit, 100), V = H.skip;
552
- if (V > 1e3) throw new SDKError("NOT_SUPPORTED", "skip(n) is capped at 1000; use cursor pagination instead.");
553
- let U = H.cursor ?? null, W = V, G = B, K = [], q = 0;
554
- for (; (W > 0 || G > 0) && q < 30;) {
555
- let B = await wxQueryPage(f, H, U, Math.min(100, W > 0 ? W : G));
556
- if (q += 1, B.items.length === 0) break;
557
- if (W > 0) {
558
- let f = Math.min(W, B.items.length);
559
- W -= f;
560
- let V = B.items.slice(f);
561
- if (W === 0 && G > 0 && V.length > 0) {
562
- let f = Math.min(G, V.length);
563
- K.push(...V.slice(0, f).map(toWxDoc)), G -= f;
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 K.push(...B.items.slice(0, G).map(toWxDoc)), G = Math.max(0, G - B.items.length);
566
- if (U = B.nextCursor, !U) break;
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 (q >= 30) throw new SDKError("NOT_SUPPORTED", "skip/limit query requires too many requests; narrow your query.");
580
+ if (J >= 30) throw new SDKError("NOT_SUPPORTED", "skip/limit query requires too many requests; narrow your query.");
569
581
  return {
570
- data: K,
571
- _meta: { nextCursor: U }
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(B) {
582
- let V = String(B).trim();
583
- if (!V) throw new SDKError("INTERNAL_ERROR", "collection name is required");
584
- let H = createWxQuery(V, f);
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
- ...H,
598
+ ...U,
587
599
  add: async (f) => {
588
- let B = f?.data;
589
- if (B && typeof B == "object" && !Array.isArray(B) && "_openid" in B) throw new SDKError("PERMISSION_DENIED", "Cannot write system field _openid");
590
- let H = B && typeof B == "object" && !Array.isArray(B) ? B._id : void 0, U = B && typeof B == "object" && !Array.isArray(B) ? { ...B } : B;
591
- return U && typeof U == "object" && !Array.isArray(U) && delete U._id, { _id: (await webCloud.db.collection(V).add(U, { id: H ? String(H) : void 0 })).id };
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 B = webCloud.db.collection(V).doc(String(f));
606
+ let V = webCloud.db.collection(H).doc(String(f));
595
607
  return {
596
- get: async () => ({ data: toWxDoc(await B.get()) }),
608
+ get: async () => ({ data: toWxDoc(await V.get()) }),
597
609
  set: async (f) => {
598
- let V = f?.data;
599
- if (V && typeof V == "object" && !Array.isArray(V) && "_openid" in V) throw new SDKError("PERMISSION_DENIED", "Cannot write system field _openid");
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 V = f?.data ?? {};
604
- if (!V || typeof V != "object" || Array.isArray(V)) throw new SDKError("INTERNAL_ERROR", "update({data}) must be an object");
605
- if ("_openid" in V) throw new SDKError("PERMISSION_DENIED", "Cannot write system field _openid");
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 B.delete(), { stats: { removed: 1 } })
618
+ remove: async () => (await V.delete(), { stats: { removed: 1 } })
609
619
  };
610
620
  },
611
- get: async () => H.get()
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 B = String(f).trim();
620
- if (!B) throw new SDKError("INTERNAL_ERROR", "collection name is required");
621
- return new WebCloudDbCollection(B);
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, B) {
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: B ?? null
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 B = String(f?.name ?? "").trim();
663
- if (!B) throw new SDKError("INTERNAL_ERROR", "callFunction name is required");
664
- return { result: await webCloud.functions.call(B, f?.data) };
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 B = String(f?.cloudPath ?? "").trim().replace(/^\/+/, "");
668
- if (!B) throw new SDKError("INTERNAL_ERROR", "cloudPath is required");
669
- let V = f?.filePath;
670
- if (!V) throw new SDKError("INTERNAL_ERROR", "filePath is required");
671
- let H = V.type ? String(V.type) : void 0, { fileId: U, uploadUrl: W } = await webCloud.blob.createUploadUrl({
672
- path: B,
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: H
684
+ contentType: U
675
685
  });
676
- return await fetch(W, {
686
+ return await fetch(G, {
677
687
  method: "PUT",
678
- headers: H ? { "Content-Type": H } : void 0,
679
- body: V
680
- }), { fileID: U };
688
+ headers: U ? { "Content-Type": U } : void 0,
689
+ body: H
690
+ }), { fileID: W };
681
691
  },
682
692
  async getTempFileURL(f) {
683
- let B = Array.isArray(f?.fileList) ? f.fileList : [];
684
- return { fileList: await Promise.all(B.map(async (f) => {
685
- let B = typeof f == "string" ? f : String(f?.fileID ?? "");
686
- if (!B) return {
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: B });
703
+ let { url: f } = await webCloud.blob.getDownloadUrl({ fileId: V });
694
704
  return {
695
- fileID: B,
705
+ fileID: V,
696
706
  tempFileURL: f,
697
707
  status: 0
698
708
  };
699
709
  } catch (f) {
700
710
  return {
701
- fileID: B,
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});
@@ -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: 'ownerId' | 'visibility' | 'refType' | 'refId';
45
+ field: string;
49
46
  op: CloudDbWhereOp;
50
- value: string;
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: CloudDbWhere['field'], op: CloudDbWhereOp, value: string): CloudDbQueryBuilder<T>;
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>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gemigo/app-sdk",
3
3
  "private": false,
4
- "version": "0.2.7",
4
+ "version": "0.2.8",
5
5
  "type": "module",
6
6
  "description": "GemiGo App SDK (auto-adapts for web/desktop/extension)",
7
7
  "main": "dist/gemigo-app-sdk.umd.js",