@aippy/runtime
Advanced tools
| var u = Object.defineProperty; | ||
| var l = (t, e, n) => e in t ? u(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n; | ||
| var c = (t, e, n) => l(t, typeof e != "symbol" ? e + "" : e, n); | ||
| import { UAParser as m } from "ua-parser-js"; | ||
| import { hasNativeBridge as f } from "./native-bridge-BnvipFJc.js"; | ||
| function w() { | ||
| try { | ||
| return typeof window < "u" && window.parent !== window; | ||
| } catch { | ||
| return !0; | ||
| } | ||
| } | ||
| function h(t, e) { | ||
| const n = t.split(".").map(Number), r = e.split(".").map(Number), o = Math.max(n.length, r.length); | ||
| for (let i = 0; i < o; i++) { | ||
| const s = n[i] || 0, a = r[i] || 0; | ||
| if (s < a) return -1; | ||
| if (s > a) return 1; | ||
| } | ||
| return 0; | ||
| } | ||
| class g { | ||
| constructor() { | ||
| c(this, "parser"); | ||
| this.parser = new m(); | ||
| } | ||
| /** | ||
| * Get platform information | ||
| */ | ||
| getPlatformInfo() { | ||
| const e = this.parser.getResult(), n = this.normalizePlatformName(e.os.name), r = this.normalizeBrowserName(e.browser.name), o = this.isMobileDevice(), i = !o; | ||
| return { | ||
| name: n, | ||
| version: e.os.version, | ||
| browser: r, | ||
| browserVersion: e.browser.version, | ||
| isMobile: o, | ||
| isDesktop: i | ||
| }; | ||
| } | ||
| /** | ||
| * Get raw UA parser result | ||
| */ | ||
| getRawParserResult() { | ||
| return this.parser.getResult(); | ||
| } | ||
| /** | ||
| * Get platform capabilities | ||
| */ | ||
| getCapabilities() { | ||
| return { | ||
| serviceWorker: "serviceWorker" in navigator, | ||
| pushNotifications: "PushManager" in window, | ||
| webShare: "share" in navigator, | ||
| clipboard: "clipboard" in navigator, | ||
| webRTC: !!(window.RTCPeerConnection || window.webkitRTCPeerConnection), | ||
| webGL: !!this.getWebGLContext(), | ||
| webAssembly: "WebAssembly" in window | ||
| }; | ||
| } | ||
| /** | ||
| * Check if device is mobile | ||
| */ | ||
| isMobileDevice() { | ||
| const e = navigator.userAgent; | ||
| return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e) || this.isTouchDevice(); | ||
| } | ||
| /** | ||
| * Check if device supports touch | ||
| */ | ||
| isTouchDevice() { | ||
| return "ontouchstart" in window || navigator.maxTouchPoints > 0; | ||
| } | ||
| /** | ||
| * Check if running in standalone mode (PWA) | ||
| */ | ||
| isStandalone() { | ||
| return window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === !0; | ||
| } | ||
| /** | ||
| * Check if running in iOS Safari | ||
| */ | ||
| isIOSSafari() { | ||
| const e = this.getPlatformInfo(); | ||
| return e.name === "ios" && e.browser === "safari"; | ||
| } | ||
| /** | ||
| * Check if running in Android Chrome | ||
| */ | ||
| isAndroidChrome() { | ||
| const e = this.getPlatformInfo(); | ||
| return e.name === "android" && e.browser === "chrome"; | ||
| } | ||
| /** | ||
| * Check if running in Android WebView (old app version) | ||
| * Detects by checking if browser name contains "webview" | ||
| */ | ||
| isAndroidWebView() { | ||
| return (this.parser.getResult().browser.name || "").toLowerCase().includes("webview"); | ||
| } | ||
| /** | ||
| * Check app environment and validate version | ||
| */ | ||
| checkAppEnvironment(e) { | ||
| const n = this.parseAippyInfo(); | ||
| if (n) { | ||
| const r = e[n.platform], o = h(n.version, r) >= 0; | ||
| return { | ||
| type: "new_app", | ||
| isValid: o, | ||
| aippyInfo: n, | ||
| message: o ? void 0 : `App version ${n.version} < ${r}` | ||
| }; | ||
| } | ||
| return f() ? { | ||
| type: "old_ios_app", | ||
| isValid: !1, | ||
| message: "Native bridge exists but no Aippy info (old iOS version)" | ||
| } : this.isAndroidWebView() ? { | ||
| type: "old_android_app", | ||
| isValid: !1, | ||
| message: "Android WebView detected but no Aippy info (old Android version)" | ||
| } : w() ? { type: "iframe", isValid: !0 } : { type: "web", isValid: !0 }; | ||
| } | ||
| /** | ||
| * Parse Aippy App info from User-Agent | ||
| */ | ||
| parseAippyInfo() { | ||
| const e = navigator.userAgent, n = /Aippy\/([^/]+)\/[^/]+\/(iOS|Android)/i, r = e.match(n); | ||
| if (r) { | ||
| const o = r[1]; | ||
| return { | ||
| platform: r[2], | ||
| version: o | ||
| }; | ||
| } | ||
| return null; | ||
| } | ||
| normalizePlatformName(e) { | ||
| if (!e) return "unknown"; | ||
| const n = e.toLowerCase(); | ||
| return n.includes("ios") ? "ios" : n.includes("android") ? "android" : n.includes("windows") ? "windows" : n.includes("mac") ? "macos" : n.includes("linux") ? "linux" : "unknown"; | ||
| } | ||
| normalizeBrowserName(e) { | ||
| if (!e) return "unknown"; | ||
| const n = e.toLowerCase(); | ||
| return n.includes("chrome") ? "chrome" : n.includes("firefox") ? "firefox" : n.includes("safari") ? "safari" : n.includes("edge") ? "edge" : "unknown"; | ||
| } | ||
| getWebGLContext() { | ||
| try { | ||
| const e = document.createElement("canvas"); | ||
| return e.getContext("webgl") || e.getContext("experimental-webgl"); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
| const b = new g(), p = "https://cdn.aippy.ai/asset/fd292077086044ee9565bd36ac3a8b78.svg"; | ||
| async function v(t) { | ||
| const e = document.createElement("div"); | ||
| e.style.cssText = "position:fixed;top:0;left:0;right:0;bottom:12px;display:flex;align-items:flex-end;justify-content:center;z-index:999999;pointer-events:none"; | ||
| const n = document.createElement("div"); | ||
| n.style.cssText = "background:#323232;border-radius:32px;padding:12px 30px 12px 24px;max-width:85%;display:flex;align-items:center;gap:12px;pointer-events:auto"; | ||
| let r = !1; | ||
| try { | ||
| r = (await fetch(p, { method: "HEAD" })).ok; | ||
| } catch { | ||
| r = !1; | ||
| } | ||
| if (r) { | ||
| const i = document.createElement("img"); | ||
| i.src = p, i.style.cssText = "width:36px;height:36px;flex-shrink:0", n.appendChild(i); | ||
| } | ||
| const o = document.createElement("span"); | ||
| o.style.cssText = "font-size:16px;color:#fff;line-height:1.4;white-space:pre-line", o.textContent = t, n.appendChild(o), e.appendChild(n), document.body.appendChild(e); | ||
| } | ||
| const x = { iOS: "1.6.7", Android: "1.1.8" }, y = { iOS: "1.6.7", Android: "1.1.8" }, d = { | ||
| userCredentials: x, | ||
| userInfo: y | ||
| }; | ||
| function A(t) { | ||
| const e = d[t]; | ||
| return e || (console.warn(`[AppVersionChecker] Unknown feature: ${t}`), { iOS: "999.0.0", Android: "999.0.0" }); | ||
| } | ||
| function C(t) { | ||
| const e = A(t), n = b.checkAppEnvironment(e), r = n.aippyInfo?.version, o = n.aippyInfo ? e[n.aippyInfo.platform] : void 0; | ||
| switch (n.type) { | ||
| case "new_app": | ||
| return { | ||
| supported: n.isValid, | ||
| envCheck: n, | ||
| currentVersion: r, | ||
| requiredVersion: o, | ||
| message: n.isValid ? void 0 : `App version ${r} does not support ${t}. Minimum required: ${o}` | ||
| }; | ||
| case "old_ios_app": | ||
| case "old_android_app": | ||
| return { | ||
| supported: !1, | ||
| envCheck: n, | ||
| message: `Old app version detected. Please upgrade to use ${t}.` | ||
| }; | ||
| default: | ||
| return { | ||
| supported: !0, | ||
| envCheck: n | ||
| }; | ||
| } | ||
| } | ||
| function _(t) { | ||
| const e = C(t); | ||
| if (!e.supported && (e.envCheck.type === "new_app" || e.envCheck.type === "old_ios_app" || e.envCheck.type === "old_android_app")) | ||
| throw console.warn(`[AppVersionChecker] ${e.message}`), v(`This project needs a newer version. | ||
| Update to view it.`), new Error(`App version too old: ${e.message}`); | ||
| return e; | ||
| } | ||
| function I() { | ||
| return Object.keys(d); | ||
| } | ||
| export { | ||
| g as P, | ||
| C as a, | ||
| I as b, | ||
| h as c, | ||
| A as g, | ||
| w as i, | ||
| b as p, | ||
| _ as r, | ||
| v as s | ||
| }; |
| import { a as y } from "./runtime-CmoG3v2m.js"; | ||
| import { r as h, s as b, i as p } from "./app-version-checker-GLONqMxq.js"; | ||
| const f = { | ||
| apiBaseUrl: "https://api.aippy.dev/api", | ||
| authToken: "", | ||
| currentUserId: null | ||
| }; | ||
| function L(n) { | ||
| Object.assign(f, n); | ||
| } | ||
| function C(n) { | ||
| f.authToken = n; | ||
| } | ||
| function q(n) { | ||
| f.currentUserId = n; | ||
| } | ||
| const U = 3e3, v = 50, g = 500, c = { uid: "", token: "" }; | ||
| let a = null, u = !1, l = null, t = null; | ||
| function w(n) { | ||
| if (!n || typeof n != "object") return null; | ||
| let e = n; | ||
| if (e.credentials && typeof e.credentials == "object" && (e = e.credentials), e.user && typeof e.user == "object" && e.token) { | ||
| const d = e.user; | ||
| e = { uid: d.uid || d.userId || d.id, token: e.token, apiBaseUrl: e.apiBaseUrl }; | ||
| } | ||
| const r = e.uid || e.userId || e.id || "", o = e.token || e.authToken || "", s = e.apiBaseUrl; | ||
| if (!r || !o) return null; | ||
| const i = { uid: String(r), token: o, apiBaseUrl: s }; | ||
| return q(i.uid), C(o), s && L({ apiBaseUrl: s }), i; | ||
| } | ||
| function m(n) { | ||
| if (console.log("🔄 [Bridge] processUserInfoData called with:", n), !n || typeof n != "object") | ||
| return console.warn("⚠️ [Bridge] Invalid data (null or not object):", n), null; | ||
| let e = n; | ||
| console.log("🔄 [Bridge] Initial obj keys:", Object.keys(e)), e.userInfo && typeof e.userInfo == "object" && (console.log("🔄 [Bridge] Unwrapping nested userInfo"), e = e.userInfo), e.user && typeof e.user == "object" && (console.log("🔄 [Bridge] Unwrapping nested user"), e = e.user), console.log("🔄 [Bridge] After unwrapping, obj:", e); | ||
| const r = e.uid || e.userId || e.id || ""; | ||
| if (!r) | ||
| return console.warn("⚠️ [Bridge] No uid found in data"), null; | ||
| const o = { uid: String(r), ...e }; | ||
| return console.log("✅ [Bridge] Created userInfo:", o), a = o, u = !0, console.log("✅ [Bridge] Cached userInfo, userInfoReceived = true"), o; | ||
| } | ||
| function A(n = g) { | ||
| return console.log("📱 [Bridge] requestCredentialsFromiOS called, timeout:", n), l ? (console.log("⏳ [Bridge] Pending credentials request exists, waiting..."), new Promise((e) => { | ||
| const r = l.resolve; | ||
| l.resolve = (o) => { | ||
| r(o), e(o); | ||
| }; | ||
| })) : new Promise((e) => { | ||
| (async () => { | ||
| let r = window.webkit?.messageHandlers?.aippyListener; | ||
| if (console.log("📱 [Bridge] Checking aippyListener for credentials:", { | ||
| hasWebkit: !!window.webkit, | ||
| hasMessageHandlers: !!window.webkit?.messageHandlers, | ||
| hasAippyListener: !!r | ||
| }), r || (console.log("⏳ [Bridge] aippyListener not found, waiting for injection..."), r = await k(1500)), !r) { | ||
| console.warn("⚠️ [Bridge] No aippyListener found after waiting, returning empty credentials"), e(c); | ||
| return; | ||
| } | ||
| const o = setTimeout(() => { | ||
| console.warn("⏰ [Bridge] Credentials request TIMEOUT after", n, "ms"), l = null, e(c); | ||
| }, n); | ||
| l = { | ||
| resolve: (s) => { | ||
| console.log("✅ [Bridge] pendingCredentialsRequest.resolve called with:", s), clearTimeout(o), l = null, e(s); | ||
| } | ||
| }, console.log("📱 [Bridge] pendingCredentialsRequest set"), y.receiveChannel.once("user.credentials", (s) => { | ||
| console.log("📩 [Bridge] Received user.credentials via receiveChannel:", s), clearTimeout(o); | ||
| const i = w(s) || c; | ||
| l && l.resolve(i); | ||
| }); | ||
| try { | ||
| const s = { | ||
| command: "user.getCredentials", | ||
| parameters: JSON.stringify({ timestamp: Date.now(), endpoint: "user.credentials" }) | ||
| }; | ||
| console.log("📤 [Bridge] Sending credentials request:", s), r.postMessage(s), console.log("📤 [Bridge] Credentials postMessage sent successfully"); | ||
| } catch (s) { | ||
| console.error("❌ [Bridge] Failed to send credentials postMessage:", s), clearTimeout(o), l = null, e(c); | ||
| } | ||
| })(); | ||
| }); | ||
| } | ||
| function E(n = g) { | ||
| return new Promise((e) => { | ||
| if (!p()) { | ||
| e(c); | ||
| return; | ||
| } | ||
| const r = setTimeout(() => { | ||
| window.removeEventListener("message", o), e(c); | ||
| }, n), o = (s) => { | ||
| s.data?.type === "user-credentials-response" && (clearTimeout(r), window.removeEventListener("message", o), e(w(s.data) || c)); | ||
| }; | ||
| window.addEventListener("message", o); | ||
| try { | ||
| window.parent.postMessage({ type: "user-credentials-request", timestamp: Date.now() }, "*"); | ||
| } catch { | ||
| clearTimeout(r), window.removeEventListener("message", o), e(c); | ||
| } | ||
| }); | ||
| } | ||
| const R = () => /Aippy\/[\d.]+\/\d+\/Android/i.test(navigator.userAgent); | ||
| async function k(n = 1500) { | ||
| if (!R()) | ||
| return console.log("📱 [Bridge] Not Android, skipping waitForAippyListener"), window.webkit?.messageHandlers?.aippyListener || null; | ||
| const e = Date.now(), r = 50; | ||
| for (console.log("🤖 [Bridge] Android: Waiting for aippyListener (max", n, "ms)..."); Date.now() - e < n; ) { | ||
| const o = window.webkit?.messageHandlers?.aippyListener; | ||
| if (o) | ||
| return console.log("✅ [Bridge] aippyListener became available after", Date.now() - e, "ms"), o; | ||
| await new Promise((s) => setTimeout(s, r)); | ||
| } | ||
| return console.warn("⏰ [Bridge] aippyListener not available after", n, "ms"), null; | ||
| } | ||
| function S(n = !1, e = g) { | ||
| return console.log("📱 [Bridge] requestUserInfoFromiOS called:", { forceRefresh: n, timeoutMs: e }), console.log("📱 [Bridge] Cache state:", { userInfoReceived: u, cachedUserInfo: a ? "(cached)" : null }), u && a && !n ? (console.log("✅ [Bridge] Returning cached userInfo from requestUserInfoFromiOS"), Promise.resolve(a)) : t ? (console.log("⏳ [Bridge] Pending userInfo request exists, waiting..."), new Promise((r) => { | ||
| const o = t.resolve; | ||
| t.resolve = (s) => { | ||
| console.log("⏳ [Bridge] Pending request resolved:", s), o(s), r(s); | ||
| }; | ||
| })) : new Promise((r) => { | ||
| (async () => { | ||
| let o = window.webkit?.messageHandlers?.aippyListener; | ||
| if (console.log("📱 [Bridge] Checking aippyListener:", { | ||
| hasWebkit: !!window.webkit, | ||
| hasMessageHandlers: !!window.webkit?.messageHandlers, | ||
| hasAippyListener: !!o | ||
| }), o || (console.log("⏳ [Bridge] aippyListener not found, waiting for injection..."), o = await k(1500)), !o) { | ||
| console.warn("⚠️ [Bridge] No aippyListener found after waiting, returning null"), r(null); | ||
| return; | ||
| } | ||
| console.log("📱 [Bridge] Setting up timeout:", e, "ms"); | ||
| const s = setTimeout(() => { | ||
| console.warn("⏰ [Bridge] UserInfo request TIMEOUT after", e, "ms"), t = null, r(null); | ||
| }, e); | ||
| t = { resolve: (i) => { | ||
| console.log("✅ [Bridge] pendingUserInfoRequest.resolve called with:", i), clearTimeout(s), t = null, r(i); | ||
| } }, console.log("📱 [Bridge] pendingUserInfoRequest set"), y.receiveChannel.once("user.info", (i) => { | ||
| console.log("📩 [Bridge] Received user.info via receiveChannel:", i), clearTimeout(s); | ||
| const d = m(i); | ||
| console.log("📩 [Bridge] Processed userInfo:", d), t ? t.resolve(d) : console.warn("⚠️ [Bridge] No pendingUserInfoRequest when receiveChannel fired"); | ||
| }), console.log("📱 [Bridge] receiveChannel.once registered for user.info"); | ||
| try { | ||
| const i = { | ||
| command: "user.getUserInfo", | ||
| parameters: JSON.stringify({ timestamp: Date.now(), endpoint: "user.info" }) | ||
| }; | ||
| console.log("📤 [Bridge] Sending to aippyListener:", i), o.postMessage(i), console.log("📤 [Bridge] postMessage sent successfully"); | ||
| } catch (i) { | ||
| console.error("❌ [Bridge] Failed to send postMessage:", i), clearTimeout(s), t = null, r(null); | ||
| } | ||
| })(); | ||
| }); | ||
| } | ||
| function T(n = g) { | ||
| return new Promise((e) => { | ||
| if (!p()) { | ||
| e(null); | ||
| return; | ||
| } | ||
| const r = setTimeout(() => { | ||
| window.removeEventListener("message", o), e(null); | ||
| }, n), o = (s) => { | ||
| s.data?.type === "user-info-response" && (clearTimeout(r), window.removeEventListener("message", o), e(m(s.data))); | ||
| }; | ||
| window.addEventListener("message", o); | ||
| try { | ||
| window.parent.postMessage({ type: "user-info-request", timestamp: Date.now() }, "*"); | ||
| } catch { | ||
| clearTimeout(r), window.removeEventListener("message", o), e(null); | ||
| } | ||
| }); | ||
| } | ||
| async function P() { | ||
| const { envCheck: n } = h("userCredentials"); | ||
| switch (n.type) { | ||
| case "new_app": { | ||
| const e = await A(U); | ||
| if (!e?.token) throw new Error("Token unavailable in app"); | ||
| return e.token; | ||
| } | ||
| case "iframe": { | ||
| const e = await E(v); | ||
| if (e?.token) return e.token; | ||
| throw b(`Sign in to continue. | ||
| Open this project in the app.`), new Error("Token unavailable: User needs to login"); | ||
| } | ||
| default: | ||
| return ""; | ||
| } | ||
| } | ||
| async function F(n = !1) { | ||
| if (console.log("🔍 [Bridge] getUserInfoAsync called, forceRefresh:", n), console.log("🔍 [Bridge] Current cache state:", { userInfoReceived: u, cachedUserInfo: a }), u && a && !n) | ||
| return console.log("✅ [Bridge] Returning cached userInfo"), a; | ||
| const { envCheck: e } = h("userInfo"); | ||
| switch (console.log("🔍 [Bridge] Environment check result:", e), e.type) { | ||
| case "new_app": | ||
| return console.log("📱 [Bridge] Detected new_app environment"), await S(n, U); | ||
| case "iframe": | ||
| return console.log("🖼️ [Bridge] Detected iframe environment"), await T(v); | ||
| default: | ||
| return console.log("🌐 [Bridge] Detected web environment, returning cached:", a), a; | ||
| } | ||
| } | ||
| async function M(n = g) { | ||
| return p() ? await T(n) : null; | ||
| } | ||
| function B(n) { | ||
| const e = w(n); | ||
| e && l && (l.resolve(e), l = null); | ||
| } | ||
| function I(n) { | ||
| console.log("📩 [Bridge] window.processUserInfo called with:", n), console.log("📩 [Bridge] pendingUserInfoRequest exists:", !!t); | ||
| const e = m(n); | ||
| t ? (console.log("✅ [Bridge] Resolving pendingUserInfoRequest with:", e), t.resolve(e), t = null) : (console.warn("⚠️ [Bridge] No pendingUserInfoRequest when processUserInfo called!"), console.warn("⚠️ [Bridge] UserInfo was processed but no one is waiting for it")); | ||
| } | ||
| function j() { | ||
| if (typeof window > "u") { | ||
| console.log("🔧 [Bridge] initUserBridge: window is undefined, skipping"); | ||
| return; | ||
| } | ||
| console.log("🔧 [Bridge] initUserBridge: Initializing..."), console.log("🔧 [Bridge] UserAgent:", navigator.userAgent), window.processUserCredentials = B, window.processUserInfo = I, console.log("🔧 [Bridge] Exposed window.processUserCredentials and window.processUserInfo"), window.addEventListener("message", (n) => { | ||
| n.data?.type === "user-credentials" && (console.log("📩 [Bridge] Received postMessage user-credentials:", n.data), B(n.data)), n.data?.type === "user-info" && (console.log("📩 [Bridge] Received postMessage user-info:", n.data), I(n.data)); | ||
| }), console.log("🔧 [Bridge] Added message event listener"), console.log("✅ [Bridge] initUserBridge complete"); | ||
| } | ||
| j(); | ||
| P().catch((n) => { | ||
| console.warn("[UserSDK] Auth check on load:", n.message); | ||
| }); | ||
| export { | ||
| P as getAuthTokenAsync, | ||
| F as getUserInfoAsync, | ||
| M as getUserInfoFromParent, | ||
| p as isInIframe, | ||
| B as processUserCredentials, | ||
| I as processUserInfo | ||
| }; |
| const n = { | ||
| mode: "development", | ||
| debug: !1, | ||
| apiBaseUrl: void 0, | ||
| headers: {} | ||
| }; | ||
| function o() { | ||
| const e = {}; | ||
| return typeof process < "u" && process.env && (process.env.NODE_ENV && (e.mode = process.env.NODE_ENV), process.env.AIPPY_DEBUG && (e.debug = process.env.AIPPY_DEBUG === "true"), process.env.AIPPY_API_BASE_URL && (e.apiBaseUrl = process.env.AIPPY_API_BASE_URL)), e; | ||
| } | ||
| function r(e) { | ||
| const s = o(); | ||
| return { | ||
| ...n, | ||
| ...s, | ||
| ...e, | ||
| headers: { | ||
| ...n.headers, | ||
| ...s.headers, | ||
| ...e?.headers | ||
| } | ||
| }; | ||
| } | ||
| export { | ||
| n as D, | ||
| o as g, | ||
| r as m | ||
| }; |
| import "react"; | ||
| import { getAuthTokenAsync as a } from "./bridge-BKcAlLAd.js"; | ||
| const r = "0.2.7-dev.6", i = { | ||
| version: r | ||
| }, o = i.version, c = "@aippy/runtime"; | ||
| function w() { | ||
| return { | ||
| name: c, | ||
| version: o, | ||
| buildTime: (/* @__PURE__ */ new Date()).toISOString() | ||
| }; | ||
| } | ||
| function p(n) { | ||
| const { token: t, existingHeaders: e } = n, s = new Headers(e); | ||
| return s.set("Aippy-Runtime-Authorization", `Bearer ${t}`), s.set("Aippy-Runtime-SDK-Version", o), typeof navigator < "u" && navigator.userAgent && s.set("Aippy-Runtime-UA", navigator.userAgent), s; | ||
| } | ||
| async function m(n) { | ||
| const t = await a(); | ||
| return p({ token: t, existingHeaders: n }); | ||
| } | ||
| function u(n) { | ||
| if (!(typeof window > "u")) | ||
| try { | ||
| const t = window.webkit?.messageHandlers?.aippyListener; | ||
| if (t) | ||
| try { | ||
| const e = { | ||
| command: "container.message", | ||
| parameters: n | ||
| }; | ||
| t.postMessage(e), console.log("📤 [Container Message] Sent message to iOS app container:", n); | ||
| } catch (e) { | ||
| console.warn("❌ [Container Message] Failed to send message to iOS app:", e); | ||
| } | ||
| if (window.parent && window.parent !== window) | ||
| try { | ||
| const e = { | ||
| type: "container.message", | ||
| data: n | ||
| }; | ||
| window.parent.postMessage(e, "*"), console.log("📤 [Container Message] Sent message to parent window:", n); | ||
| } catch (e) { | ||
| console.warn("❌ [Container Message] Failed to send message to parent window:", e); | ||
| } | ||
| } catch (t) { | ||
| console.warn("⚠️ [Container Message] Failed to send message:", t); | ||
| } | ||
| } | ||
| export { | ||
| c as S, | ||
| o as V, | ||
| m as a, | ||
| p as c, | ||
| w as g, | ||
| u as s | ||
| }; |
| /** | ||
| * Aippy Runtime Headers utilities. | ||
| * Shared header generation for all SDK modules. | ||
| */ | ||
| export interface CreateAippyHeadersOptions { | ||
| /** Auth token for Authorization header */ | ||
| token: string; | ||
| /** Optional existing headers to extend */ | ||
| existingHeaders?: HeadersInit; | ||
| } | ||
| /** | ||
| * Creates Aippy runtime headers with authentication and metadata. | ||
| * Can be used by any module to create consistent headers. | ||
| * | ||
| * Headers set: | ||
| * - Aippy-Runtime-Authorization: Bearer token for authentication | ||
| * - Aippy-Runtime-SDK-Version: SDK version number | ||
| * - Aippy-Runtime-UA: User agent from the shell app | ||
| * | ||
| * @param options - Options for creating headers | ||
| * @returns Headers object with Aippy runtime headers | ||
| */ | ||
| export declare function createAippyHeaders(options: CreateAippyHeadersOptions): Headers; | ||
| /** | ||
| * Async version that automatically gets the auth token. | ||
| * Convenient for most use cases. | ||
| * | ||
| * @param existingHeaders - Optional existing headers to extend | ||
| * @returns Promise resolving to Headers object with Aippy runtime headers | ||
| */ | ||
| export declare function createAippyHeadersAsync(existingHeaders?: HeadersInit): Promise<Headers>; |
| import { createOpenAICompatible as l } from "@ai-sdk/openai-compatible"; | ||
| import { s as u, a as y } from "./container-message-WJolNXso.js"; | ||
| import { AISDKError as f, DefaultChatTransport as d } from "ai"; | ||
| import { j as h } from "./url-c26cuIpu.js"; | ||
| const c = "https://api.aippy.dev", b = `${c}/aisdk/v1/`, A = `${c}/aisdk/v1/ui/`, w = "gpt-5-nano", v = ""; | ||
| function I(n = {}) { | ||
| return { | ||
| baseUrl: n.baseUrl ?? b | ||
| }; | ||
| } | ||
| function C(n = {}) { | ||
| return { | ||
| baseUrl: n.baseUrl ?? A | ||
| }; | ||
| } | ||
| function E(n, e) { | ||
| const r = n.status; | ||
| if (e && typeof e == "object" && "error" in e) { | ||
| const t = e, o = t.error.code, s = o != null ? `AippyAIError_${o}` : `AippyAIError_${r}`, a = e; | ||
| return "appMessage" in a && a.appMessage !== void 0 && u(a.appMessage), new f({ | ||
| name: s, | ||
| message: t.error.message, | ||
| cause: { | ||
| type: t.error.type ?? void 0, | ||
| param: t.error.param ?? void 0, | ||
| status: r | ||
| } | ||
| }); | ||
| } | ||
| if (e && typeof e == "object" && e !== null) { | ||
| const t = e; | ||
| "appMessage" in t && t.appMessage !== void 0 && u(t.appMessage); | ||
| } | ||
| return new f({ | ||
| name: `AippyAIError_${r}`, | ||
| message: `Request failed with status ${r}`, | ||
| cause: { status: r } | ||
| }); | ||
| } | ||
| function m() { | ||
| return async (n, e) => { | ||
| const r = await y(e?.headers), t = await globalThis.fetch(n, { ...e, headers: r }); | ||
| if (!t.ok) { | ||
| const o = await t.text().catch(() => null); | ||
| let s = null; | ||
| if (o) | ||
| try { | ||
| s = JSON.parse(o); | ||
| } catch { | ||
| s = { message: o }; | ||
| } | ||
| throw E(t, s); | ||
| } | ||
| return t; | ||
| }; | ||
| } | ||
| const S = [ | ||
| "gpt-image-1", | ||
| "gpt-image-1-mini", | ||
| "gpt-image-1.5" | ||
| ]; | ||
| function O(n) { | ||
| try { | ||
| const e = JSON.parse(n); | ||
| if (e.model && S.some((r) => e.model.startsWith(r))) { | ||
| const { response_format: r, ...t } = e; | ||
| return JSON.stringify(t); | ||
| } | ||
| } catch { | ||
| } | ||
| return n; | ||
| } | ||
| function L(n = {}) { | ||
| const { baseUrl: e } = I(n), r = m(); | ||
| return l({ | ||
| name: "aippy", | ||
| baseURL: e, | ||
| fetch: async (o, s) => o.toString().includes("/images/generations") && s?.method?.toUpperCase() === "POST" && s?.body ? r(o, { | ||
| ...s, | ||
| body: O(s.body) | ||
| }) : r(o, s), | ||
| // Enable structured outputs support (json_schema response format) | ||
| // This is required for Output.object() and Output.array() to work properly | ||
| supportsStructuredOutputs: !0 | ||
| }); | ||
| } | ||
| const _ = "/chat"; | ||
| function N(n = {}) { | ||
| const { baseUrl: e } = C(n), r = n.model ?? w, t = n.system ?? v, o = n.api ?? h(e, _), s = { model: r, system: t }, a = m(); | ||
| return { | ||
| transport: new d({ | ||
| api: o, | ||
| body: s, | ||
| // Ensure token is fetched fresh for every request | ||
| fetch: a | ||
| }) | ||
| }; | ||
| } | ||
| class p extends Error { | ||
| constructor(e, r) { | ||
| super(e), this.errors = r, this.name = "AIConfigValidationError"; | ||
| } | ||
| } | ||
| function g(n) { | ||
| const e = []; | ||
| if (!n || typeof n != "object") | ||
| throw new p("AIConfig must be an object", []); | ||
| const r = n; | ||
| for (const [t, o] of Object.entries(r)) { | ||
| if (!o || typeof o != "object") { | ||
| e.push({ key: t, message: "Item must be an object" }); | ||
| continue; | ||
| } | ||
| const s = o; | ||
| typeof s.index != "number" && e.push({ key: t, message: "index must be a number" }), typeof s.name != "string" && e.push({ key: t, message: "name must be a string" }), typeof s.description != "string" && e.push({ key: t, message: "description must be a string" }); | ||
| const a = s.type; | ||
| if (!["number", "boolean", "text", "enum"].includes(a)) { | ||
| e.push({ | ||
| key: t, | ||
| message: `type must be one of: number, boolean, text, enum (got: ${a})` | ||
| }); | ||
| continue; | ||
| } | ||
| if (a === "number") | ||
| typeof s.value != "number" && e.push({ key: t, message: 'value must be a number for type "number"' }), s.min !== void 0 && typeof s.min != "number" && e.push({ key: t, message: "min must be a number" }), s.max !== void 0 && typeof s.max != "number" && e.push({ key: t, message: "max must be a number" }), s.step !== void 0 && typeof s.step != "number" && e.push({ key: t, message: "step must be a number" }); | ||
| else if (a === "boolean") | ||
| typeof s.value != "boolean" && e.push({ key: t, message: 'value must be a boolean for type "boolean"' }); | ||
| else if (a === "text") | ||
| typeof s.value != "string" && e.push({ key: t, message: 'value must be a string for type "text"' }); | ||
| else if (a === "enum") { | ||
| if (!Array.isArray(s.options)) | ||
| e.push({ key: t, message: 'options must be an array for type "enum"' }); | ||
| else if (s.options.length === 0) | ||
| e.push({ key: t, message: 'options array cannot be empty for type "enum"' }); | ||
| else | ||
| for (let i = 0; i < s.options.length; i++) | ||
| typeof s.options[i] != "string" && e.push({ | ||
| key: t, | ||
| message: `options[${i}] must be a string` | ||
| }); | ||
| typeof s.value != "string" ? e.push({ key: t, message: 'value must be a string for type "enum"' }) : Array.isArray(s.options) && !s.options.includes(s.value) && e.push({ | ||
| key: t, | ||
| message: `value "${s.value}" is not in options: [${s.options.join(", ")}]` | ||
| }); | ||
| } | ||
| s.group !== void 0 && typeof s.group != "string" && e.push({ key: t, message: "group must be a string" }); | ||
| } | ||
| if (e.length > 0) | ||
| throw new p( | ||
| `AIConfig validation failed with ${e.length} error(s)`, | ||
| e | ||
| ); | ||
| } | ||
| function D(n) { | ||
| let e; | ||
| try { | ||
| e = JSON.parse(n); | ||
| } catch (r) { | ||
| throw new p("Invalid JSON", [ | ||
| { | ||
| key: "", | ||
| message: `JSON parse error: ${r instanceof Error ? r.message : String(r)}` | ||
| } | ||
| ]); | ||
| } | ||
| return g(e), e; | ||
| } | ||
| function U(n) { | ||
| return g(n), n; | ||
| } | ||
| function T(n, e) { | ||
| const r = n[e]; | ||
| if (!r) | ||
| throw new Error(`AIConfig key "${e}" not found`); | ||
| return r.value; | ||
| } | ||
| function x(n) { | ||
| if (!(typeof window > "u")) | ||
| try { | ||
| const e = window.webkit?.messageHandlers?.aippyListener; | ||
| if (e) | ||
| try { | ||
| const r = { | ||
| command: "ai.initialize", | ||
| parameters: JSON.stringify(n) | ||
| }; | ||
| e.postMessage(r); | ||
| } catch (r) { | ||
| console.warn("❌ [Aippy AI Config] Failed to send config to iOS app:", r); | ||
| } | ||
| if (window.parent && window.parent !== window) | ||
| try { | ||
| const r = { | ||
| type: "ai.initialize", | ||
| config: JSON.stringify(n) | ||
| }; | ||
| window.parent.postMessage(r, "*"); | ||
| } catch (r) { | ||
| console.warn("❌ [Aippy AI Config] Failed to send config to parent window:", r); | ||
| } | ||
| } catch (e) { | ||
| console.warn("⚠️ [Aippy AI Config] Failed to send config:", e); | ||
| } | ||
| } | ||
| function J(n) { | ||
| const e = U(n); | ||
| return x(e), new Proxy({}, { | ||
| get(r, t) { | ||
| if (typeof t == "string") | ||
| try { | ||
| return T(e, t); | ||
| } catch { | ||
| return; | ||
| } | ||
| }, | ||
| has(r, t) { | ||
| return typeof t != "string" ? !1 : t in e; | ||
| }, | ||
| ownKeys(r) { | ||
| return Object.keys(e); | ||
| } | ||
| }); | ||
| } | ||
| export { | ||
| p as A, | ||
| b as D, | ||
| _ as U, | ||
| L as a, | ||
| N as b, | ||
| A as c, | ||
| w as d, | ||
| v as e, | ||
| J as f, | ||
| T as g, | ||
| U as l, | ||
| E as n, | ||
| D as p, | ||
| x as s, | ||
| g as v | ||
| }; |
| import { useState as U, useEffect as y, useCallback as p } from "react"; | ||
| const g = { | ||
| avatar: "", | ||
| nickName: "用户", | ||
| username: "", | ||
| uid: "" | ||
| }; | ||
| let s = null, a = null; | ||
| const d = /* @__PURE__ */ new Set(); | ||
| function h() { | ||
| d.forEach((n) => n()); | ||
| } | ||
| const u = [100, 300, 500, 1e3], w = (n) => new Promise((o) => setTimeout(o, n)), A = () => /Aippy\/[\d.]+\/\d+\/Android/i.test(navigator.userAgent); | ||
| async function v() { | ||
| console.log("🔍 [useUserInfo] fetchUserInfoFromBridge started"); | ||
| const n = A(); | ||
| try { | ||
| const { getUserInfoAsync: o, getUserInfoFromParent: c, isInIframe: t } = await import("./bridge-BKcAlLAd.js"), { hasNativeBridge: f } = await import("./native-bridge-BnvipFJc.js"), i = f(), l = t(); | ||
| console.log("🔍 [useUserInfo] Environment check:", { | ||
| hasNativeBridge: i, | ||
| isInIframe: l, | ||
| isAndroid: n, | ||
| userAgent: navigator.userAgent | ||
| }); | ||
| let e = null; | ||
| if (i) | ||
| console.log("📱 [useUserInfo] Using native bridge to get user info..."), e = await o(), console.log("📱 [useUserInfo] Native bridge returned:", e); | ||
| else if (l) | ||
| console.log("🖼️ [useUserInfo] Using iframe parent to get user info..."), e = await c(), console.log("🖼️ [useUserInfo] Iframe parent returned:", e); | ||
| else { | ||
| if (console.log("🌐 [useUserInfo] Bridge not ready, trying getUserInfoAsync..."), e = await o(), !e && n) { | ||
| console.log("🤖 [useUserInfo] Android: First attempt failed, retrying..."); | ||
| for (let r = 0; r < u.length; r++) { | ||
| const I = u[r]; | ||
| if (console.log(`🔄 [useUserInfo] Android retry ${r + 1}/${u.length} after ${I}ms...`), await w(I), e = await o(), e) { | ||
| console.log(`✅ [useUserInfo] Retry ${r + 1} succeeded:`, e); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| console.log("🌐 [useUserInfo] Result:", e); | ||
| } | ||
| if (e) { | ||
| const r = { | ||
| avatar: String(e.avatar || e.photoUrl || ""), | ||
| nickName: String(e.nickName || e.nickname || e.displayName || "用户"), | ||
| username: String(e.username || ""), | ||
| uid: String(e.uid || "") | ||
| }; | ||
| return console.log("✅ [useUserInfo] Parsed user info:", r), r; | ||
| } | ||
| return console.warn("⚠️ [useUserInfo] No user info received (info is null/undefined)"), null; | ||
| } catch (o) { | ||
| return console.error("❌ [useUserInfo] fetchUserInfoFromBridge failed:", o), null; | ||
| } | ||
| } | ||
| async function m() { | ||
| if (console.log("🔄 [useUserInfo] getOrFetchUserInfo called, cachedUserInfo:", s), s) | ||
| return console.log("✅ [useUserInfo] Returning cached user info"), s; | ||
| if (a) { | ||
| console.log("⏳ [useUserInfo] Already fetching, waiting for existing promise..."); | ||
| const n = await a; | ||
| return console.log("⏳ [useUserInfo] Existing promise resolved:", n), n || g; | ||
| } | ||
| console.log("🚀 [useUserInfo] Starting new fetch..."), a = v(); | ||
| try { | ||
| const n = await a; | ||
| return console.log("🚀 [useUserInfo] Fetch completed:", n), n && (s = n, h()), n || g; | ||
| } finally { | ||
| a = null; | ||
| } | ||
| } | ||
| function N() { | ||
| const [n, o] = U(s || g), [c, t] = U(!s); | ||
| y(() => { | ||
| const i = () => { | ||
| s && (o(s), t(!1)); | ||
| }; | ||
| return d.add(i), s || (t(!0), m().then((l) => { | ||
| o(l), t(!1); | ||
| })), () => { | ||
| d.delete(i); | ||
| }; | ||
| }, []); | ||
| const f = p(async () => { | ||
| t(!0), s = null, a = null; | ||
| const i = await m(); | ||
| o(i), t(!1); | ||
| }, []); | ||
| return { ...n, isLoading: c, refetch: f }; | ||
| } | ||
| function S() { | ||
| s = null, a = null, h(); | ||
| } | ||
| export { | ||
| S as c, | ||
| N as u | ||
| }; |
| function o(n, t) { | ||
| const e = n.endsWith("/") ? n : `${n}/`, i = t.startsWith("/") ? t.slice(1) : t; | ||
| return new URL(i, e).href; | ||
| } | ||
| export { | ||
| o as j | ||
| }; |
| import { AppVersionConfig, AppEnvironmentCheckResult } from './platform'; | ||
| import { default as versionRequirements } from './app-version-requirements.json'; | ||
| /** | ||
| * Feature support check result | ||
| */ | ||
| export interface FeatureSupportResult { | ||
| /** Whether the feature is supported in current environment */ | ||
| supported: boolean; | ||
| /** Environment check result from platform detector */ | ||
| envCheck: AppEnvironmentCheckResult; | ||
| /** Current app version (if in app) */ | ||
| currentVersion?: string; | ||
| /** Minimum required version for this feature */ | ||
| requiredVersion?: string; | ||
| /** Error message if not supported */ | ||
| message?: string; | ||
| } | ||
| /** | ||
| * Available feature names for version checking | ||
| */ | ||
| export type FeatureName = keyof typeof versionRequirements; | ||
| /** | ||
| * Get version requirements for a feature | ||
| */ | ||
| export declare function getFeatureVersionRequirements(featureName: FeatureName): AppVersionConfig; | ||
| /** | ||
| * Check if app version supports a specific feature | ||
| * | ||
| * @param featureName - The feature to check (e.g., 'userCredentials', 'userInfo') | ||
| * @returns FeatureSupportResult with support status and details | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const result = checkFeatureSupport('userCredentials'); | ||
| * if (!result.supported) { | ||
| * console.log('Feature not supported:', result.message); | ||
| * } | ||
| * ``` | ||
| */ | ||
| export declare function checkFeatureSupport(featureName: FeatureName): FeatureSupportResult; | ||
| /** | ||
| * Check feature support and handle old version automatically | ||
| * | ||
| * This is a convenience function that: | ||
| * 1. Checks if the feature is supported | ||
| * 2. If not supported due to old app version, shows an alert and throws an error | ||
| * | ||
| * @param featureName - The feature to check | ||
| * @returns FeatureSupportResult (only returns if supported or web/iframe environment) | ||
| * @throws Error if app version is too old | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const result = requireFeatureSupport('userCredentials'); | ||
| * // Code here only runs if feature is supported | ||
| * ``` | ||
| */ | ||
| export declare function requireFeatureSupport(featureName: FeatureName): FeatureSupportResult; | ||
| /** | ||
| * Get all available feature names | ||
| */ | ||
| export declare function getAvailableFeatures(): FeatureName[]; |
| declare const _default: { | ||
| "userCredentials": { | ||
| "iOS": "1.6.7", | ||
| "Android": "1.1.8" | ||
| }, | ||
| "userInfo": { | ||
| "iOS": "1.6.7", | ||
| "Android": "1.1.8" | ||
| } | ||
| } | ||
| ; | ||
| export default _default; |
| /** | ||
| * URL utilities for Aippy Runtime SDK. | ||
| */ | ||
| /** | ||
| * Joins a base URL with a path segment. | ||
| */ | ||
| export declare function joinUrl(baseUrl: string, path: string): string; |
+2
-2
@@ -1,4 +0,4 @@ | ||
| import { A, D as r, d as n, e as C, c as e, U as E, a as I, b as _, f, g, l as T, n as p, p as t, s as U, v as D } from "../helper-BENVYOU-.js"; | ||
| import { A, D as r, d as n, e as C, c as e, U as E, a as I, b as _, f, g, l as T, n as p, p as t, s as U, v as D } from "../helper-yKJ_6uB-.js"; | ||
| import "react"; | ||
| import "../bridge-Ca3H2iN1.js"; | ||
| import "../bridge-BKcAlLAd.js"; | ||
| export { | ||
@@ -5,0 +5,0 @@ A as AIConfigValidationError, |
@@ -6,6 +6,2 @@ /** | ||
| /** | ||
| * Joins a base URL with a path segment. | ||
| */ | ||
| export declare function joinUrl(baseUrl: string, path: string): string; | ||
| /** | ||
| * Creates a fetch wrapper that injects Authorization header and handles error responses. | ||
@@ -12,0 +8,0 @@ * Error responses are intercepted and normalized errors are thrown immediately. |
@@ -6,2 +6,2 @@ /** | ||
| export { DEFAULT_BASE_URL, DEFAULT_UI_BASE_URL, DEFAULT_CHAT_MODEL, DEFAULT_CHAT_SYSTEM, resolveOpenAIConfig, resolveUIConfig, type AippyOpenAIConfig, type AippyUIConfig, type AippyChatConfig, } from './config'; | ||
| export { joinUrl, createAuthFetch } from './fetch'; | ||
| export { createAuthFetch } from './fetch'; |
@@ -5,3 +5,4 @@ export * from './types'; | ||
| export * from './version'; | ||
| export * from './headers'; | ||
| export * from './container-message'; | ||
| export * from './runtime'; |
+20
-50
@@ -1,53 +0,23 @@ | ||
| import { A as d, E as v, c as m } from "../errors-CDEBaBxB.js"; | ||
| import { s as A } from "../container-message-DGrno17o.js"; | ||
| import { A as g, C as R, R as I, a as P, p as l } from "../runtime-CmoG3v2m.js"; | ||
| const s = { | ||
| mode: "development", | ||
| debug: !1, | ||
| apiBaseUrl: void 0, | ||
| headers: {} | ||
| }; | ||
| function o() { | ||
| const e = {}; | ||
| return typeof process < "u" && process.env && (process.env.NODE_ENV && (e.mode = process.env.NODE_ENV), process.env.AIPPY_DEBUG && (e.debug = process.env.AIPPY_DEBUG === "true"), process.env.AIPPY_API_BASE_URL && (e.apiBaseUrl = process.env.AIPPY_API_BASE_URL)), e; | ||
| } | ||
| function p(e) { | ||
| const n = o(); | ||
| return { | ||
| ...s, | ||
| ...n, | ||
| ...e, | ||
| headers: { | ||
| ...s.headers, | ||
| ...n.headers, | ||
| ...e?.headers | ||
| } | ||
| }; | ||
| } | ||
| const r = "0.2.7-dev.5", a = { | ||
| version: r | ||
| }, t = a.version, i = "@aippy/runtime"; | ||
| function c() { | ||
| return { | ||
| name: i, | ||
| version: t, | ||
| buildTime: (/* @__PURE__ */ new Date()).toISOString() | ||
| }; | ||
| } | ||
| import { D as s, g as r, m as o } from "../config-B0A7gHQM.js"; | ||
| import { A as p, E as t, c as i } from "../errors-CDEBaBxB.js"; | ||
| import { S as c, V as A, c as E, a as R, g, s as C } from "../container-message-WJolNXso.js"; | ||
| import { A as y, C as D, R as l, a as x, p as O } from "../runtime-CmoG3v2m.js"; | ||
| export { | ||
| g as AippyRuntime, | ||
| d as AippyRuntimeError, | ||
| R as Cancellable, | ||
| y as AippyRuntime, | ||
| p as AippyRuntimeError, | ||
| D as Cancellable, | ||
| s as DEFAULT_CONFIG, | ||
| v as ERROR_CODES, | ||
| I as ReceiveChannel, | ||
| i as SDK_NAME, | ||
| t as VERSION, | ||
| P as aippyRuntime, | ||
| m as createError, | ||
| o as getConfigFromEnv, | ||
| c as getVersionInfo, | ||
| p as mergeConfig, | ||
| l as processMotionData, | ||
| A as sendMessageToContainer | ||
| t as ERROR_CODES, | ||
| l as ReceiveChannel, | ||
| c as SDK_NAME, | ||
| A as VERSION, | ||
| x as aippyRuntime, | ||
| E as createAippyHeaders, | ||
| R as createAippyHeadersAsync, | ||
| i as createError, | ||
| r as getConfigFromEnv, | ||
| g as getVersionInfo, | ||
| o as mergeConfig, | ||
| O as processMotionData, | ||
| C as sendMessageToContainer | ||
| }; |
+86
-78
@@ -1,83 +0,91 @@ | ||
| import { DEFAULT_CONFIG as o, SDK_NAME as r, VERSION as s, getConfigFromEnv as t, getVersionInfo as i, mergeConfig as n } from "../core/index.js"; | ||
| import { A, E as f, c as m } from "../errors-CDEBaBxB.js"; | ||
| import { s as C } from "../container-message-DGrno17o.js"; | ||
| import { A as E, C as d, R as l, a as g, p as u } from "../runtime-CmoG3v2m.js"; | ||
| import { CameraAPI as x, FileSystemAPI as T, GeolocationAPI as _, SensorsAPI as D, camera as U, fileSystem as M, geolocation as P, isMotionSupported as R, isOrientationSupported as y, requestMotionPermission as h, sensors as v, vibrate as O, watchMotion as F, watchOrientation as L } from "../device/index.js"; | ||
| import { P as N, c as b, i as V, p as H, s as k } from "../ui-y5N62DqC.js"; | ||
| import { a as G, P as q, p as z, b as K } from "../pwa-CilSlaik.js"; | ||
| import { a as Y, b as j } from "../useTweaks-QxMRmg7i.js"; | ||
| import { c as Q, a as X, i as Z, p as $, u as ee } from "../useAudioContext-D9F3x80Y.js"; | ||
| import { reportScore as oe, sendEvent as re, updateScore as se } from "../leaderboard/index.js"; | ||
| import { A as ie, D as ne, d as pe, e as Ae, c as fe, U as me, a as ce, b as Ce, f as Ie, g as Ee, l as de, n as le, p as ge, s as ue, v as Se } from "../helper-BENVYOU-.js"; | ||
| import { c as Te, u as _e } from "../hooks-CE9cjXHP.js"; | ||
| import { getAuthTokenAsync as Ue } from "../bridge-Ca3H2iN1.js"; | ||
| import { hasNativeBridge as Pe } from "../native-bridge-BnvipFJc.js"; | ||
| import { D as o, g as r, m as s } from "../config-B0A7gHQM.js"; | ||
| import { A as i, E as n, c as p } from "../errors-CDEBaBxB.js"; | ||
| import { S as m, V as f, c, a as u, g as C, s as g } from "../container-message-WJolNXso.js"; | ||
| import { A as I, C as d, R as E, a as S, p as x } from "../runtime-CmoG3v2m.js"; | ||
| import { CameraAPI as D, FileSystemAPI as U, GeolocationAPI as _, SensorsAPI as y, camera as R, fileSystem as F, geolocation as M, isMotionSupported as P, isOrientationSupported as h, requestMotionPermission as v, sensors as O, vibrate as L, watchMotion as b, watchOrientation as V } from "../device/index.js"; | ||
| import { P as H, a as N, c as k, b as q, g as B, i as j, p as G, r as z, s as K } from "../app-version-checker-GLONqMxq.js"; | ||
| import { a as Y, P as J, p as Q, b as X } from "../pwa-CilSlaik.js"; | ||
| import { j as $ } from "../url-c26cuIpu.js"; | ||
| import { a as ae, b as oe } from "../useTweaks-QxMRmg7i.js"; | ||
| import { c as se, a as te, i as ie, p as ne, u as pe } from "../useAudioContext-D9F3x80Y.js"; | ||
| import { reportScore as me, sendEvent as fe, updateScore as ce } from "../leaderboard/index.js"; | ||
| import { A as Ce, D as ge, d as le, e as Ie, c as de, U as Ee, a as Se, b as xe, f as Te, g as De, l as Ue, n as _e, p as ye, s as Re, v as Fe } from "../helper-yKJ_6uB-.js"; | ||
| import { c as Pe, u as he } from "../hooks-DgadJdiM.js"; | ||
| import { getAuthTokenAsync as Oe } from "../bridge-BKcAlLAd.js"; | ||
| import { hasNativeBridge as be } from "../native-bridge-BnvipFJc.js"; | ||
| export { | ||
| ie as AIConfigValidationError, | ||
| E as AippyRuntime, | ||
| A as AippyRuntimeError, | ||
| x as CameraAPI, | ||
| Ce as AIConfigValidationError, | ||
| I as AippyRuntime, | ||
| i as AippyRuntimeError, | ||
| D as CameraAPI, | ||
| d as Cancellable, | ||
| ne as DEFAULT_BASE_URL, | ||
| pe as DEFAULT_CHAT_MODEL, | ||
| Ae as DEFAULT_CHAT_SYSTEM, | ||
| ge as DEFAULT_BASE_URL, | ||
| le as DEFAULT_CHAT_MODEL, | ||
| Ie as DEFAULT_CHAT_SYSTEM, | ||
| o as DEFAULT_CONFIG, | ||
| fe as DEFAULT_UI_BASE_URL, | ||
| f as ERROR_CODES, | ||
| T as FileSystemAPI, | ||
| de as DEFAULT_UI_BASE_URL, | ||
| n as ERROR_CODES, | ||
| U as FileSystemAPI, | ||
| _ as GeolocationAPI, | ||
| G as PWAUtils, | ||
| q as PerformanceMonitor, | ||
| N as PlatformDetector, | ||
| l as ReceiveChannel, | ||
| r as SDK_NAME, | ||
| D as SensorsAPI, | ||
| me as UI_CHAT_ENDPOINT, | ||
| s as VERSION, | ||
| ce as aippyAIProvider, | ||
| Ce as aippyChatConfig, | ||
| g as aippyRuntime, | ||
| Y as aippyTweaks, | ||
| j as aippyTweaksRuntime, | ||
| U as camera, | ||
| Te as clearUserInfoCache, | ||
| b as compareVersions, | ||
| Ie as createAIConfig, | ||
| m as createError, | ||
| Q as createHiddenMediaElement, | ||
| M as fileSystem, | ||
| P as geolocation, | ||
| Ee as getAIConfigValue, | ||
| Ue as getAuthTokenAsync, | ||
| t as getConfigFromEnv, | ||
| i as getVersionInfo, | ||
| Pe as hasNativeBridge, | ||
| X as isIOSDevice, | ||
| V as isInIframe, | ||
| Z as isMediaStreamAudioSupported, | ||
| R as isMotionSupported, | ||
| y as isOrientationSupported, | ||
| de as loadAIConfig, | ||
| n as mergeConfig, | ||
| le as normalizeError, | ||
| ge as parseAIConfig, | ||
| $ as patchAudioContext, | ||
| z as performanceMonitor, | ||
| H as platform, | ||
| u as processMotionData, | ||
| K as pwa, | ||
| oe as reportScore, | ||
| h as requestMotionPermission, | ||
| ue as sendAIConfigToContainer, | ||
| re as sendEvent, | ||
| C as sendMessageToContainer, | ||
| v as sensors, | ||
| k as showAlert, | ||
| se as updateScore, | ||
| ee as useAudioContext, | ||
| _e as useUserInfo, | ||
| Se as validateAIConfig, | ||
| O as vibrate, | ||
| F as watchMotion, | ||
| L as watchOrientation | ||
| Y as PWAUtils, | ||
| J as PerformanceMonitor, | ||
| H as PlatformDetector, | ||
| E as ReceiveChannel, | ||
| m as SDK_NAME, | ||
| y as SensorsAPI, | ||
| Ee as UI_CHAT_ENDPOINT, | ||
| f as VERSION, | ||
| Se as aippyAIProvider, | ||
| xe as aippyChatConfig, | ||
| S as aippyRuntime, | ||
| ae as aippyTweaks, | ||
| oe as aippyTweaksRuntime, | ||
| R as camera, | ||
| N as checkFeatureSupport, | ||
| Pe as clearUserInfoCache, | ||
| k as compareVersions, | ||
| Te as createAIConfig, | ||
| c as createAippyHeaders, | ||
| u as createAippyHeadersAsync, | ||
| p as createError, | ||
| se as createHiddenMediaElement, | ||
| F as fileSystem, | ||
| M as geolocation, | ||
| De as getAIConfigValue, | ||
| Oe as getAuthTokenAsync, | ||
| q as getAvailableFeatures, | ||
| r as getConfigFromEnv, | ||
| B as getFeatureVersionRequirements, | ||
| C as getVersionInfo, | ||
| be as hasNativeBridge, | ||
| te as isIOSDevice, | ||
| j as isInIframe, | ||
| ie as isMediaStreamAudioSupported, | ||
| P as isMotionSupported, | ||
| h as isOrientationSupported, | ||
| $ as joinUrl, | ||
| Ue as loadAIConfig, | ||
| s as mergeConfig, | ||
| _e as normalizeError, | ||
| ye as parseAIConfig, | ||
| ne as patchAudioContext, | ||
| Q as performanceMonitor, | ||
| G as platform, | ||
| x as processMotionData, | ||
| X as pwa, | ||
| me as reportScore, | ||
| v as requestMotionPermission, | ||
| z as requireFeatureSupport, | ||
| Re as sendAIConfigToContainer, | ||
| fe as sendEvent, | ||
| g as sendMessageToContainer, | ||
| O as sensors, | ||
| K as showAlert, | ||
| ce as updateScore, | ||
| pe as useAudioContext, | ||
| he as useUserInfo, | ||
| Fe as validateAIConfig, | ||
| L as vibrate, | ||
| b as watchMotion, | ||
| V as watchOrientation | ||
| }; |
| /** | ||
| * User SDK Hooks | ||
| */ | ||
| /** Hook to get user info (avatar, nickName, username, uid) */ | ||
| export declare function useUserInfo(): { | ||
| export interface UserInfo { | ||
| avatar: string; | ||
@@ -10,4 +9,9 @@ nickName: string; | ||
| uid: string; | ||
| } | ||
| /** Hook to get user info (avatar, nickName, username, uid) with loading state */ | ||
| export declare function useUserInfo(): UserInfo & { | ||
| isLoading: boolean; | ||
| refetch: () => Promise<void>; | ||
| }; | ||
| /** Clear cached user info */ | ||
| export declare function clearUserInfoCache(): void; |
@@ -5,3 +5,4 @@ /** | ||
| export { useUserInfo, clearUserInfoCache } from './hooks'; | ||
| export type { UserInfo } from './hooks'; | ||
| export { getAuthTokenAsync, isInIframe } from './bridge'; | ||
| export type { IOSUserCredentials, IOSUserInfo } from './bridge'; |
@@ -1,4 +0,4 @@ | ||
| import { c as o, u as s } from "../hooks-CE9cjXHP.js"; | ||
| import { getAuthTokenAsync as f } from "../bridge-Ca3H2iN1.js"; | ||
| import { i as t } from "../ui-y5N62DqC.js"; | ||
| import { c as o, u as s } from "../hooks-DgadJdiM.js"; | ||
| import { getAuthTokenAsync as f } from "../bridge-BKcAlLAd.js"; | ||
| import { i as t } from "../app-version-checker-GLONqMxq.js"; | ||
| export { | ||
@@ -5,0 +5,0 @@ o as clearUserInfoCache, |
@@ -6,1 +6,3 @@ export * from './platform'; | ||
| export * from './ui'; | ||
| export * from './url'; | ||
| export * from './app-version-checker'; |
+17
-11
@@ -1,13 +0,19 @@ | ||
| import { P as o, c as s, i as e, p as t, s as m } from "../ui-y5N62DqC.js"; | ||
| import { a as f, P as i, p as n, b as c } from "../pwa-CilSlaik.js"; | ||
| import { P as a, a as s, c as o, b as t, g as p, i, p as m, r as n, s as f } from "../app-version-checker-GLONqMxq.js"; | ||
| import { a as c, P as l, p as P, b as F } from "../pwa-CilSlaik.js"; | ||
| import { j as g } from "../url-c26cuIpu.js"; | ||
| export { | ||
| f as PWAUtils, | ||
| i as PerformanceMonitor, | ||
| o as PlatformDetector, | ||
| s as compareVersions, | ||
| e as isInIframe, | ||
| n as performanceMonitor, | ||
| t as platform, | ||
| c as pwa, | ||
| m as showAlert | ||
| c as PWAUtils, | ||
| l as PerformanceMonitor, | ||
| a as PlatformDetector, | ||
| s as checkFeatureSupport, | ||
| o as compareVersions, | ||
| t as getAvailableFeatures, | ||
| p as getFeatureVersionRequirements, | ||
| i as isInIframe, | ||
| g as joinUrl, | ||
| P as performanceMonitor, | ||
| m as platform, | ||
| F as pwa, | ||
| n as requireFeatureSupport, | ||
| f as showAlert | ||
| }; |
@@ -11,2 +11,2 @@ /** | ||
| */ | ||
| export declare function showAlert(message: string): void; | ||
| export declare function showAlert(message: string): Promise<void>; |
+1
-1
| { | ||
| "name": "@aippy/runtime", | ||
| "version": "0.2.7-dev.5", | ||
| "version": "0.2.7-dev.6", | ||
| "description": "Aippy Runtime SDK - Runtime SDK for Aippy projects", | ||
@@ -5,0 +5,0 @@ "private": false, |
| import { a as y } from "./runtime-CmoG3v2m.js"; | ||
| import { p as T, s as v, i as f } from "./ui-y5N62DqC.js"; | ||
| const m = { | ||
| apiBaseUrl: "https://api.aippy.dev/api", | ||
| authToken: "", | ||
| currentUserId: null | ||
| }; | ||
| function b(n) { | ||
| Object.assign(m, n); | ||
| } | ||
| function P(n) { | ||
| m.authToken = n; | ||
| } | ||
| function O(n) { | ||
| m.currentUserId = n; | ||
| } | ||
| const k = { iOS: "1.6.6", Android: "1.1.8" }, E = 3e3, S = 50, l = 500, a = { uid: "", token: "" }; | ||
| let d = null, _ = !1, u = null, w = !1, o = null; | ||
| function g(n) { | ||
| if (!n || typeof n != "object") return null; | ||
| let e = n; | ||
| if (e.credentials && typeof e.credentials == "object" && (e = e.credentials), e.user && typeof e.user == "object" && e.token) { | ||
| const c = e.user; | ||
| e = { uid: c.uid || c.userId || c.id, token: e.token, apiBaseUrl: e.apiBaseUrl }; | ||
| } | ||
| const s = e.uid || e.userId || e.id || "", t = e.token || e.authToken || "", r = e.apiBaseUrl; | ||
| if (!s || !t) return null; | ||
| const i = { uid: String(s), token: t, apiBaseUrl: r }; | ||
| return O(i.uid), P(t), r && b({ apiBaseUrl: r }), d = i, _ = !0, i; | ||
| } | ||
| function h(n) { | ||
| if (!n || typeof n != "object") return null; | ||
| let e = n; | ||
| e.userInfo && typeof e.userInfo == "object" && (e = e.userInfo), e.user && typeof e.user == "object" && (e = e.user); | ||
| const s = e.uid || e.userId || e.id || ""; | ||
| if (!s) return null; | ||
| const t = { uid: String(s), ...e }; | ||
| return u = t, w = !0, t; | ||
| } | ||
| function p(n) { | ||
| throw console.warn(`[UserSDK] ${n}`), v("Your app version is outdated. Please upgrade to the latest version."), new Error("App version too old"); | ||
| } | ||
| function L(n = l) { | ||
| return _ && d ? Promise.resolve(d) : new Promise((e) => { | ||
| const s = window.webkit?.messageHandlers?.aippyListener; | ||
| if (!s) { | ||
| e(a); | ||
| return; | ||
| } | ||
| const t = setTimeout(() => e(a), n); | ||
| y.receiveChannel.once("user.credentials", (r) => { | ||
| clearTimeout(t), e(g(r) || a); | ||
| }); | ||
| try { | ||
| s.postMessage({ | ||
| command: "user.getCredentials", | ||
| parameters: JSON.stringify({ timestamp: Date.now(), endpoint: "user.credentials" }) | ||
| }); | ||
| } catch { | ||
| clearTimeout(t), e(a); | ||
| } | ||
| }); | ||
| } | ||
| function C(n = l) { | ||
| return new Promise((e) => { | ||
| if (!f()) { | ||
| e(a); | ||
| return; | ||
| } | ||
| const s = setTimeout(() => { | ||
| window.removeEventListener("message", t), e(a); | ||
| }, n), t = (r) => { | ||
| r.data?.type === "user-credentials-response" && (clearTimeout(s), window.removeEventListener("message", t), e(g(r.data) || a)); | ||
| }; | ||
| window.addEventListener("message", t); | ||
| try { | ||
| window.parent.postMessage({ type: "user-credentials-request", timestamp: Date.now() }, "*"); | ||
| } catch { | ||
| clearTimeout(s), window.removeEventListener("message", t), e(a); | ||
| } | ||
| }); | ||
| } | ||
| function D(n = !1, e = l) { | ||
| return w && u && !n ? Promise.resolve(u) : o ? new Promise((s) => { | ||
| const t = o.resolve; | ||
| o.resolve = (r) => { | ||
| t(r), s(r); | ||
| }; | ||
| }) : new Promise((s) => { | ||
| const t = window.webkit?.messageHandlers?.aippyListener; | ||
| if (!t) { | ||
| s(null); | ||
| return; | ||
| } | ||
| const r = setTimeout(() => { | ||
| o = null, s(null); | ||
| }, e); | ||
| o = { resolve: (i) => { | ||
| clearTimeout(r), o = null, s(i); | ||
| } }, y.receiveChannel.once("user.info", (i) => { | ||
| console.log("[UserSDK] Received user.info via receiveChannel:", i), clearTimeout(r); | ||
| const c = h(i); | ||
| o && o.resolve(c); | ||
| }); | ||
| try { | ||
| console.log("[UserSDK] Requesting user info from iOS"), t.postMessage({ | ||
| command: "user.getUserInfo", | ||
| parameters: JSON.stringify({ timestamp: Date.now(), endpoint: "user.info" }) | ||
| }); | ||
| } catch { | ||
| clearTimeout(r), o = null, s(null); | ||
| } | ||
| }); | ||
| } | ||
| function A(n = l) { | ||
| return new Promise((e) => { | ||
| if (!f()) { | ||
| e(null); | ||
| return; | ||
| } | ||
| const s = setTimeout(() => { | ||
| window.removeEventListener("message", t), e(null); | ||
| }, n), t = (r) => { | ||
| r.data?.type === "user-info-response" && (clearTimeout(s), window.removeEventListener("message", t), e(h(r.data))); | ||
| }; | ||
| window.addEventListener("message", t); | ||
| try { | ||
| window.parent.postMessage({ type: "user-info-request", timestamp: Date.now() }, "*"); | ||
| } catch { | ||
| clearTimeout(s), window.removeEventListener("message", t), e(null); | ||
| } | ||
| }); | ||
| } | ||
| async function M() { | ||
| const n = T.checkAppEnvironment(k); | ||
| switch (n.type) { | ||
| case "new_app": { | ||
| n.isValid || p(n.message || "App version too old"), await L(E); | ||
| const e = d?.token || ""; | ||
| if (!e) throw new Error("Token unavailable in app"); | ||
| return e; | ||
| } | ||
| case "old_ios_app": | ||
| case "old_android_app": | ||
| throw p(n.message || "Old app version"), new Error("Token unavailable: Old app version not supported"); | ||
| case "iframe": { | ||
| const e = await C(S); | ||
| if (e?.token) return e.token; | ||
| throw v("Please log in to use this feature."), new Error("Token unavailable: User needs to login"); | ||
| } | ||
| default: | ||
| return ""; | ||
| } | ||
| } | ||
| async function F(n = !1) { | ||
| if (w && u && !n) return u; | ||
| const e = T.checkAppEnvironment(k); | ||
| switch (e.type) { | ||
| case "new_app": | ||
| return e.isValid || p(e.message || "App version too old"), await D(n, E); | ||
| case "old_ios_app": | ||
| case "old_android_app": | ||
| return p(e.message || "Old app version"), u; | ||
| case "iframe": | ||
| return await A(S); | ||
| default: | ||
| return u; | ||
| } | ||
| } | ||
| async function B(n = l) { | ||
| return f() ? await A(n) : null; | ||
| } | ||
| function I(n) { | ||
| g(n); | ||
| } | ||
| function U(n) { | ||
| console.log("[UserSDK] processUserInfo called with:", n); | ||
| const e = h(n); | ||
| o && (o.resolve(e), o = null); | ||
| } | ||
| function j() { | ||
| typeof window > "u" || (window.processUserCredentials = I, window.processUserInfo = U, window.addEventListener("message", (n) => { | ||
| n.data?.type === "user-credentials" && I(n.data), n.data?.type === "user-info" && U(n.data); | ||
| })); | ||
| } | ||
| j(); | ||
| M().catch((n) => { | ||
| console.warn("[UserSDK] Auth check on load:", n.message); | ||
| }); | ||
| export { | ||
| M as getAuthTokenAsync, | ||
| F as getUserInfoAsync, | ||
| B as getUserInfoFromParent, | ||
| f as isInIframe, | ||
| I as processUserCredentials, | ||
| U as processUserInfo | ||
| }; |
| function o(n) { | ||
| if (!(typeof window > "u")) | ||
| try { | ||
| const s = window.webkit?.messageHandlers?.aippyListener; | ||
| if (s) | ||
| try { | ||
| const e = { | ||
| command: "container.message", | ||
| parameters: n | ||
| }; | ||
| s.postMessage(e), console.log("📤 [Container Message] Sent message to iOS app container:", n); | ||
| } catch (e) { | ||
| console.warn("❌ [Container Message] Failed to send message to iOS app:", e); | ||
| } | ||
| if (window.parent && window.parent !== window) | ||
| try { | ||
| const e = { | ||
| type: "container.message", | ||
| data: n | ||
| }; | ||
| window.parent.postMessage(e, "*"), console.log("📤 [Container Message] Sent message to parent window:", n); | ||
| } catch (e) { | ||
| console.warn("❌ [Container Message] Failed to send message to parent window:", e); | ||
| } | ||
| } catch (s) { | ||
| console.warn("⚠️ [Container Message] Failed to send message:", s); | ||
| } | ||
| } | ||
| export { | ||
| o as s | ||
| }; |
| import { createOpenAICompatible as l } from "@ai-sdk/openai-compatible"; | ||
| import "react"; | ||
| import { getAuthTokenAsync as y } from "./bridge-Ca3H2iN1.js"; | ||
| import { AISDKError as u, DefaultChatTransport as d } from "ai"; | ||
| import { s as f } from "./container-message-DGrno17o.js"; | ||
| const c = "https://api.aippy.dev", h = `${c}/aisdk/v1/`, b = `${c}/aisdk/v1/ui/`, A = "gpt-5-nano", w = ""; | ||
| function v(n = {}) { | ||
| return { | ||
| baseUrl: n.baseUrl ?? h | ||
| }; | ||
| } | ||
| function I(n = {}) { | ||
| return { | ||
| baseUrl: n.baseUrl ?? b | ||
| }; | ||
| } | ||
| function C(n, e) { | ||
| const s = n.status; | ||
| if (e && typeof e == "object" && "error" in e) { | ||
| const t = e, o = t.error.code, r = o != null ? `AippyAIError_${o}` : `AippyAIError_${s}`, a = e; | ||
| return "appMessage" in a && a.appMessage !== void 0 && f(a.appMessage), new u({ | ||
| name: r, | ||
| message: t.error.message, | ||
| cause: { | ||
| type: t.error.type ?? void 0, | ||
| param: t.error.param ?? void 0, | ||
| status: s | ||
| } | ||
| }); | ||
| } | ||
| if (e && typeof e == "object" && e !== null) { | ||
| const t = e; | ||
| "appMessage" in t && t.appMessage !== void 0 && f(t.appMessage); | ||
| } | ||
| return new u({ | ||
| name: `AippyAIError_${s}`, | ||
| message: `Request failed with status ${s}`, | ||
| cause: { status: s } | ||
| }); | ||
| } | ||
| function E(n, e) { | ||
| const s = n.endsWith("/") ? n : `${n}/`, t = e.startsWith("/") ? e.slice(1) : e; | ||
| return new URL(t, s).href; | ||
| } | ||
| function m() { | ||
| return async (n, e) => { | ||
| const s = await y(), t = new Headers(e?.headers); | ||
| t.set("Aippy-Runtime-Authorization", `Bearer ${s}`); | ||
| const o = await globalThis.fetch(n, { ...e, headers: t }); | ||
| if (!o.ok) { | ||
| const r = await o.text().catch(() => null); | ||
| let a = null; | ||
| if (r) | ||
| try { | ||
| a = JSON.parse(r); | ||
| } catch { | ||
| a = { message: r }; | ||
| } | ||
| throw C(o, a); | ||
| } | ||
| return o; | ||
| }; | ||
| } | ||
| const S = [ | ||
| "gpt-image-1", | ||
| "gpt-image-1-mini", | ||
| "gpt-image-1.5" | ||
| ]; | ||
| function O(n) { | ||
| try { | ||
| const e = JSON.parse(n); | ||
| if (e.model && S.some((s) => e.model.startsWith(s))) { | ||
| const { response_format: s, ...t } = e; | ||
| return JSON.stringify(t); | ||
| } | ||
| } catch { | ||
| } | ||
| return n; | ||
| } | ||
| function N(n = {}) { | ||
| const { baseUrl: e } = v(n), s = m(); | ||
| return l({ | ||
| name: "aippy", | ||
| baseURL: e, | ||
| fetch: async (o, r) => o.toString().includes("/images/generations") && r?.method?.toUpperCase() === "POST" && r?.body ? s(o, { | ||
| ...r, | ||
| body: O(r.body) | ||
| }) : s(o, r), | ||
| // Enable structured outputs support (json_schema response format) | ||
| // This is required for Output.object() and Output.array() to work properly | ||
| supportsStructuredOutputs: !0 | ||
| }); | ||
| } | ||
| const _ = "/chat"; | ||
| function D(n = {}) { | ||
| const { baseUrl: e } = I(n), s = n.model ?? A, t = n.system ?? w, o = n.api ?? E(e, _), r = { model: s, system: t }, a = m(); | ||
| return { | ||
| transport: new d({ | ||
| api: o, | ||
| body: r, | ||
| // Ensure token is fetched fresh for every request | ||
| fetch: a | ||
| }) | ||
| }; | ||
| } | ||
| class p extends Error { | ||
| constructor(e, s) { | ||
| super(e), this.errors = s, this.name = "AIConfigValidationError"; | ||
| } | ||
| } | ||
| function g(n) { | ||
| const e = []; | ||
| if (!n || typeof n != "object") | ||
| throw new p("AIConfig must be an object", []); | ||
| const s = n; | ||
| for (const [t, o] of Object.entries(s)) { | ||
| if (!o || typeof o != "object") { | ||
| e.push({ key: t, message: "Item must be an object" }); | ||
| continue; | ||
| } | ||
| const r = o; | ||
| typeof r.index != "number" && e.push({ key: t, message: "index must be a number" }), typeof r.name != "string" && e.push({ key: t, message: "name must be a string" }), typeof r.description != "string" && e.push({ key: t, message: "description must be a string" }); | ||
| const a = r.type; | ||
| if (!["number", "boolean", "text", "enum"].includes(a)) { | ||
| e.push({ | ||
| key: t, | ||
| message: `type must be one of: number, boolean, text, enum (got: ${a})` | ||
| }); | ||
| continue; | ||
| } | ||
| if (a === "number") | ||
| typeof r.value != "number" && e.push({ key: t, message: 'value must be a number for type "number"' }), r.min !== void 0 && typeof r.min != "number" && e.push({ key: t, message: "min must be a number" }), r.max !== void 0 && typeof r.max != "number" && e.push({ key: t, message: "max must be a number" }), r.step !== void 0 && typeof r.step != "number" && e.push({ key: t, message: "step must be a number" }); | ||
| else if (a === "boolean") | ||
| typeof r.value != "boolean" && e.push({ key: t, message: 'value must be a boolean for type "boolean"' }); | ||
| else if (a === "text") | ||
| typeof r.value != "string" && e.push({ key: t, message: 'value must be a string for type "text"' }); | ||
| else if (a === "enum") { | ||
| if (!Array.isArray(r.options)) | ||
| e.push({ key: t, message: 'options must be an array for type "enum"' }); | ||
| else if (r.options.length === 0) | ||
| e.push({ key: t, message: 'options array cannot be empty for type "enum"' }); | ||
| else | ||
| for (let i = 0; i < r.options.length; i++) | ||
| typeof r.options[i] != "string" && e.push({ | ||
| key: t, | ||
| message: `options[${i}] must be a string` | ||
| }); | ||
| typeof r.value != "string" ? e.push({ key: t, message: 'value must be a string for type "enum"' }) : Array.isArray(r.options) && !r.options.includes(r.value) && e.push({ | ||
| key: t, | ||
| message: `value "${r.value}" is not in options: [${r.options.join(", ")}]` | ||
| }); | ||
| } | ||
| r.group !== void 0 && typeof r.group != "string" && e.push({ key: t, message: "group must be a string" }); | ||
| } | ||
| if (e.length > 0) | ||
| throw new p( | ||
| `AIConfig validation failed with ${e.length} error(s)`, | ||
| e | ||
| ); | ||
| } | ||
| function R(n) { | ||
| let e; | ||
| try { | ||
| e = JSON.parse(n); | ||
| } catch (s) { | ||
| throw new p("Invalid JSON", [ | ||
| { | ||
| key: "", | ||
| message: `JSON parse error: ${s instanceof Error ? s.message : String(s)}` | ||
| } | ||
| ]); | ||
| } | ||
| return g(e), e; | ||
| } | ||
| function U(n) { | ||
| return g(n), n; | ||
| } | ||
| function T(n, e) { | ||
| const s = n[e]; | ||
| if (!s) | ||
| throw new Error(`AIConfig key "${e}" not found`); | ||
| return s.value; | ||
| } | ||
| function $(n) { | ||
| if (!(typeof window > "u")) | ||
| try { | ||
| const e = window.webkit?.messageHandlers?.aippyListener; | ||
| if (e) | ||
| try { | ||
| const s = { | ||
| command: "ai.initialize", | ||
| parameters: JSON.stringify(n) | ||
| }; | ||
| e.postMessage(s); | ||
| } catch (s) { | ||
| console.warn("❌ [Aippy AI Config] Failed to send config to iOS app:", s); | ||
| } | ||
| if (window.parent && window.parent !== window) | ||
| try { | ||
| const s = { | ||
| type: "ai.initialize", | ||
| config: JSON.stringify(n) | ||
| }; | ||
| window.parent.postMessage(s, "*"); | ||
| } catch (s) { | ||
| console.warn("❌ [Aippy AI Config] Failed to send config to parent window:", s); | ||
| } | ||
| } catch (e) { | ||
| console.warn("⚠️ [Aippy AI Config] Failed to send config:", e); | ||
| } | ||
| } | ||
| function B(n) { | ||
| const e = U(n); | ||
| return $(e), new Proxy({}, { | ||
| get(s, t) { | ||
| if (typeof t == "string") | ||
| try { | ||
| return T(e, t); | ||
| } catch { | ||
| return; | ||
| } | ||
| }, | ||
| has(s, t) { | ||
| return typeof t != "string" ? !1 : t in e; | ||
| }, | ||
| ownKeys(s) { | ||
| return Object.keys(e); | ||
| } | ||
| }); | ||
| } | ||
| export { | ||
| p as A, | ||
| h as D, | ||
| _ as U, | ||
| N as a, | ||
| D as b, | ||
| b as c, | ||
| A as d, | ||
| w as e, | ||
| B as f, | ||
| T as g, | ||
| U as l, | ||
| C as n, | ||
| R as p, | ||
| $ as s, | ||
| g as v | ||
| }; |
| import { useState as l, useEffect as c } from "react"; | ||
| let n = null, r = null; | ||
| function U() { | ||
| const [s, i] = l(n || { | ||
| avatar: "", | ||
| nickName: "用户", | ||
| username: "", | ||
| uid: "" | ||
| }); | ||
| return c(() => { | ||
| let t = !0; | ||
| return (async () => { | ||
| try { | ||
| if (n) { | ||
| t && i(n); | ||
| return; | ||
| } | ||
| if (r) { | ||
| await r, t && n && i(n); | ||
| return; | ||
| } | ||
| r = (async () => { | ||
| const { getUserInfoAsync: a, getUserInfoFromParent: o, isInIframe: f } = await import("./bridge-Ca3H2iN1.js"), { hasNativeBridge: u } = await import("./native-bridge-BnvipFJc.js"); | ||
| let e = null; | ||
| u() ? e = await a() : f() ? e = await o() : e = await a(), e && (n = { | ||
| avatar: String(e.avatar || e.photoUrl || ""), | ||
| nickName: String(e.nickName || e.displayName || "用户"), | ||
| username: String(e.username || ""), | ||
| uid: String(e.uid || "") | ||
| }); | ||
| })(), await r, r = null, t && n && i(n); | ||
| } catch (a) { | ||
| console.error("[useUserInfo] Failed:", a), r = null; | ||
| } | ||
| })(), () => { | ||
| t = !1; | ||
| }; | ||
| }, []), s; | ||
| } | ||
| function d() { | ||
| n = null, r = null; | ||
| } | ||
| export { | ||
| d as c, | ||
| U as u | ||
| }; |
| var d = Object.defineProperty; | ||
| var l = (o, e, n) => e in o ? d(o, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : o[e] = n; | ||
| var c = (o, e, n) => l(o, typeof e != "symbol" ? e + "" : e, n); | ||
| import { UAParser as u } from "ua-parser-js"; | ||
| import { hasNativeBridge as p } from "./native-bridge-BnvipFJc.js"; | ||
| function m() { | ||
| try { | ||
| return typeof window < "u" && window.parent !== window; | ||
| } catch { | ||
| return !0; | ||
| } | ||
| } | ||
| function f(o, e) { | ||
| const n = o.split(".").map(Number), r = e.split(".").map(Number), t = Math.max(n.length, r.length); | ||
| for (let i = 0; i < t; i++) { | ||
| const s = n[i] || 0, a = r[i] || 0; | ||
| if (s < a) return -1; | ||
| if (s > a) return 1; | ||
| } | ||
| return 0; | ||
| } | ||
| class w { | ||
| constructor() { | ||
| c(this, "parser"); | ||
| this.parser = new u(); | ||
| } | ||
| /** | ||
| * Get platform information | ||
| */ | ||
| getPlatformInfo() { | ||
| const e = this.parser.getResult(), n = this.normalizePlatformName(e.os.name), r = this.normalizeBrowserName(e.browser.name), t = this.isMobileDevice(), i = !t; | ||
| return { | ||
| name: n, | ||
| version: e.os.version, | ||
| browser: r, | ||
| browserVersion: e.browser.version, | ||
| isMobile: t, | ||
| isDesktop: i | ||
| }; | ||
| } | ||
| /** | ||
| * Get raw UA parser result | ||
| */ | ||
| getRawParserResult() { | ||
| return this.parser.getResult(); | ||
| } | ||
| /** | ||
| * Get platform capabilities | ||
| */ | ||
| getCapabilities() { | ||
| return { | ||
| serviceWorker: "serviceWorker" in navigator, | ||
| pushNotifications: "PushManager" in window, | ||
| webShare: "share" in navigator, | ||
| clipboard: "clipboard" in navigator, | ||
| webRTC: !!(window.RTCPeerConnection || window.webkitRTCPeerConnection), | ||
| webGL: !!this.getWebGLContext(), | ||
| webAssembly: "WebAssembly" in window | ||
| }; | ||
| } | ||
| /** | ||
| * Check if device is mobile | ||
| */ | ||
| isMobileDevice() { | ||
| const e = navigator.userAgent; | ||
| return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e) || this.isTouchDevice(); | ||
| } | ||
| /** | ||
| * Check if device supports touch | ||
| */ | ||
| isTouchDevice() { | ||
| return "ontouchstart" in window || navigator.maxTouchPoints > 0; | ||
| } | ||
| /** | ||
| * Check if running in standalone mode (PWA) | ||
| */ | ||
| isStandalone() { | ||
| return window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === !0; | ||
| } | ||
| /** | ||
| * Check if running in iOS Safari | ||
| */ | ||
| isIOSSafari() { | ||
| const e = this.getPlatformInfo(); | ||
| return e.name === "ios" && e.browser === "safari"; | ||
| } | ||
| /** | ||
| * Check if running in Android Chrome | ||
| */ | ||
| isAndroidChrome() { | ||
| const e = this.getPlatformInfo(); | ||
| return e.name === "android" && e.browser === "chrome"; | ||
| } | ||
| /** | ||
| * Check if running in Android WebView (old app version) | ||
| * Detects by checking if browser name contains "webview" | ||
| */ | ||
| isAndroidWebView() { | ||
| return (this.parser.getResult().browser.name || "").toLowerCase().includes("webview"); | ||
| } | ||
| /** | ||
| * Check app environment and validate version | ||
| */ | ||
| checkAppEnvironment(e) { | ||
| const n = this.parseAippyInfo(); | ||
| if (n) { | ||
| const r = e[n.platform], t = f(n.version, r) >= 0; | ||
| return { | ||
| type: "new_app", | ||
| isValid: t, | ||
| aippyInfo: n, | ||
| message: t ? void 0 : `App version ${n.version} < ${r}` | ||
| }; | ||
| } | ||
| return p() ? { | ||
| type: "old_ios_app", | ||
| isValid: !1, | ||
| message: "Native bridge exists but no Aippy info (old iOS version)" | ||
| } : this.isAndroidWebView() ? { | ||
| type: "old_android_app", | ||
| isValid: !1, | ||
| message: "Android WebView detected but no Aippy info (old Android version)" | ||
| } : m() ? { type: "iframe", isValid: !0 } : { type: "web", isValid: !0 }; | ||
| } | ||
| /** | ||
| * Parse Aippy App info from User-Agent | ||
| */ | ||
| parseAippyInfo() { | ||
| const e = navigator.userAgent, n = /Aippy\/([^/]+)\/[^/]+\/(iOS|Android)/i, r = e.match(n); | ||
| if (r) { | ||
| const t = r[1]; | ||
| return { | ||
| platform: r[2], | ||
| version: t | ||
| }; | ||
| } | ||
| return null; | ||
| } | ||
| normalizePlatformName(e) { | ||
| if (!e) return "unknown"; | ||
| const n = e.toLowerCase(); | ||
| return n.includes("ios") ? "ios" : n.includes("android") ? "android" : n.includes("windows") ? "windows" : n.includes("mac") ? "macos" : n.includes("linux") ? "linux" : "unknown"; | ||
| } | ||
| normalizeBrowserName(e) { | ||
| if (!e) return "unknown"; | ||
| const n = e.toLowerCase(); | ||
| return n.includes("chrome") ? "chrome" : n.includes("firefox") ? "firefox" : n.includes("safari") ? "safari" : n.includes("edge") ? "edge" : "unknown"; | ||
| } | ||
| getWebGLContext() { | ||
| try { | ||
| const e = document.createElement("canvas"); | ||
| return e.getContext("webgl") || e.getContext("experimental-webgl"); | ||
| } catch { | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
| const x = new w(); | ||
| function v(o) { | ||
| const e = document.createElement("div"); | ||
| e.style.cssText = "position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);display:flex;align-items:center;justify-content:center;z-index:999999"; | ||
| const n = document.createElement("div"); | ||
| n.style.cssText = "background:#fff;border-radius:12px;padding:24px 32px;max-width:80%;text-align:center;box-shadow:0 4px 20px rgba(0,0,0,0.15)"; | ||
| const r = document.createElement("p"); | ||
| r.style.cssText = "margin:0 0 20px;font-size:16px;color:#333;line-height:1.5", r.textContent = o; | ||
| const t = document.createElement("button"); | ||
| t.style.cssText = "background:#007AFF;color:#fff;border:none;border-radius:8px;padding:10px 32px;font-size:15px;cursor:pointer", t.textContent = "OK", t.onclick = () => e.remove(), n.appendChild(r), n.appendChild(t), e.appendChild(n), document.body.appendChild(e); | ||
| } | ||
| export { | ||
| w as P, | ||
| f as c, | ||
| m as i, | ||
| x as p, | ||
| v as s | ||
| }; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
150487
10.06%91
7.06%4531
7.17%12
20%