@fiction/sdk 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sdk.js +1198 -1737
- package/dist/sdk.js.map +1 -1
- package/dist/sdkClient-C9BL_Op4.js +731 -0
- package/dist/sdkClient-C9BL_Op4.js.map +1 -0
- package/dist/self/index.d.ts +1 -1
- package/dist/self/ui/SelfModal.vue.d.ts +4 -4
- package/dist/self/ui/SelfProvider.vue.d.ts +2 -1
- package/dist/self/ui/{FictionWidget.vue.d.ts → SelfWidget.vue.d.ts} +1 -1
- package/dist/self/ui/SelfWrap.vue.d.ts +3 -1
- package/dist/self.js +786 -781
- package/dist/self.js.map +1 -1
- package/package.json +2 -2
- package/dist/base-CEr2lLFg.js +0 -194
- package/dist/base-CEr2lLFg.js.map +0 -1
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
var O = Object.defineProperty;
|
|
2
|
+
var Q = (c, t, e) => t in c ? O(c, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[t] = e;
|
|
3
|
+
var l = (c, t) => O(c, "name", { value: t, configurable: !0 });
|
|
4
|
+
var n = (c, t, e) => Q(c, typeof t != "symbol" ? t + "" : t, e);
|
|
5
|
+
import { objectId as M } from "@fiction/utils";
|
|
6
|
+
import { watch as P, ref as k, computed as G } from "vue";
|
|
7
|
+
import { hc as H } from "hono/client";
|
|
8
|
+
const y = globalThis.process, g = typeof window < "u", x = typeof y < "u" && !g, m = g ? typeof window < "u" && window.location && !window.location.hostname.includes("localhost") : x && typeof y < "u" && y.env?.NODE_ENV === "production", Y = !m, S = {
|
|
9
|
+
error: { priority: 50, color: "#FF0000", nodeColor: "\x1B[31m" },
|
|
10
|
+
warn: { priority: 40, color: "#FFA500", nodeColor: "\x1B[33m" },
|
|
11
|
+
info: { priority: 30, color: "#00ABFF", nodeColor: "\x1B[36m" },
|
|
12
|
+
debug: { priority: 20, color: "#00BD0C", nodeColor: "\x1B[32m" },
|
|
13
|
+
trace: { priority: 10, color: "#5233FF", nodeColor: "\x1B[35m" }
|
|
14
|
+
}, X = ["password", "token", "secret", "apikey", "api_key", "authorization", "cookie"], p = class p {
|
|
15
|
+
constructor(t = {}, e) {
|
|
16
|
+
n(this, "settings");
|
|
17
|
+
n(this, "enabledInBrowser", !1);
|
|
18
|
+
n(this, "context");
|
|
19
|
+
this.context = e, this.settings = {
|
|
20
|
+
enabled: t.enabled ?? !0,
|
|
21
|
+
minLevel: t.minLevel ?? this.getDefaultLevel(),
|
|
22
|
+
timestamps: t.timestamps ?? !0
|
|
23
|
+
}, g && this.initBrowserLogging();
|
|
24
|
+
}
|
|
25
|
+
getDefaultLevel() {
|
|
26
|
+
if (x && typeof y < "u" && y.env?.LOG_LEVEL)
|
|
27
|
+
return y.env.LOG_LEVEL;
|
|
28
|
+
if (g && typeof localStorage < "u") {
|
|
29
|
+
const t = localStorage.getItem("FICTION_LOG_LEVEL");
|
|
30
|
+
if (t)
|
|
31
|
+
return t;
|
|
32
|
+
}
|
|
33
|
+
return m ? "info" : "debug";
|
|
34
|
+
}
|
|
35
|
+
initBrowserLogging() {
|
|
36
|
+
if (!g)
|
|
37
|
+
return;
|
|
38
|
+
const e = localStorage.getItem("FICTION_LOG") === "true", r = window.location?.hostname || "";
|
|
39
|
+
this.enabledInBrowser = Y || e || r === "localhost" || r.includes("127.0.0.1"), m && !e && !p.hasShownHelp && (console.log(
|
|
40
|
+
"%cFiction WWW Logger (disabled in production)",
|
|
41
|
+
"color: #888; font-size: 12px"
|
|
42
|
+
), console.log(
|
|
43
|
+
'%cTo enable: localStorage.setItem("FICTION_LOG", "true")',
|
|
44
|
+
"color: #888; font-size: 11px"
|
|
45
|
+
), p.hasShownHelp = !0);
|
|
46
|
+
}
|
|
47
|
+
shouldLog(t) {
|
|
48
|
+
if (!this.settings.enabled || g && !this.enabledInBrowser)
|
|
49
|
+
return !1;
|
|
50
|
+
const e = S[t].priority, r = S[this.settings.minLevel].priority;
|
|
51
|
+
return e >= r;
|
|
52
|
+
}
|
|
53
|
+
formatTimestamp() {
|
|
54
|
+
return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB", {
|
|
55
|
+
hour12: !1,
|
|
56
|
+
hour: "2-digit",
|
|
57
|
+
minute: "2-digit",
|
|
58
|
+
second: "2-digit"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
formatISOTimestamp() {
|
|
62
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
63
|
+
}
|
|
64
|
+
redactSensitive(t) {
|
|
65
|
+
if (typeof t != "object" || t === null)
|
|
66
|
+
return t;
|
|
67
|
+
if (Array.isArray(t))
|
|
68
|
+
return t.map((r) => this.redactSensitive(r));
|
|
69
|
+
const e = {};
|
|
70
|
+
for (const [r, o] of Object.entries(t)) {
|
|
71
|
+
const s = r.toLowerCase();
|
|
72
|
+
X.some((i) => s.includes(i)) ? e[r] = "[REDACTED]" : typeof o == "object" && o !== null ? e[r] = this.redactSensitive(o) : e[r] = o;
|
|
73
|
+
}
|
|
74
|
+
return e;
|
|
75
|
+
}
|
|
76
|
+
formatData(t, e = 3, r = 0) {
|
|
77
|
+
if (r >= e)
|
|
78
|
+
return "[Max Depth]";
|
|
79
|
+
if (t == null)
|
|
80
|
+
return t;
|
|
81
|
+
if (t instanceof Error)
|
|
82
|
+
return {
|
|
83
|
+
name: t.name,
|
|
84
|
+
message: t.message,
|
|
85
|
+
stack: m ? t.stack?.split(`
|
|
86
|
+
`).slice(0, 3).join(`
|
|
87
|
+
`) : t.stack,
|
|
88
|
+
...t
|
|
89
|
+
// Include any additional error properties
|
|
90
|
+
};
|
|
91
|
+
if (t instanceof Date)
|
|
92
|
+
return t.toISOString();
|
|
93
|
+
if (typeof t != "object")
|
|
94
|
+
return t;
|
|
95
|
+
if (Array.isArray(t))
|
|
96
|
+
return t.length > 20 && m ? `Array(${t.length}) [${t.slice(0, 3).map((o) => this.formatData(o, e, r + 1)).join(", ")}, ...]` : t.map((o) => this.formatData(o, e, r + 1));
|
|
97
|
+
try {
|
|
98
|
+
const o = {}, s = Object.entries(t), i = m ? 50 : 200;
|
|
99
|
+
for (const [u, d] of s.slice(0, i))
|
|
100
|
+
o[u] = this.formatData(d, e, r + 1);
|
|
101
|
+
return s.length > i && (o["..."] = `${s.length - i} more properties`), this.redactSensitive(o);
|
|
102
|
+
} catch {
|
|
103
|
+
return "[Unserializable]";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
logToBrowser(t) {
|
|
107
|
+
if (!g || !this.shouldLog(t.level))
|
|
108
|
+
return;
|
|
109
|
+
const { level: e, description: r, context: o, data: s, error: i } = t, u = S[e], a = `[${o || this.context || "www"}] ${e.toUpperCase()}:`, I = `color: ${u.color}; font-weight: bold;`;
|
|
110
|
+
s !== void 0 ? console[e](`%c${a}`, I, r, this.formatData(s)) : console[e](`%c${a}`, I, r), i && (i instanceof Error ? console.error(i) : console.error("Error details:", i));
|
|
111
|
+
}
|
|
112
|
+
async logToNode(t) {
|
|
113
|
+
if (!x || !this.shouldLog(t.level))
|
|
114
|
+
return;
|
|
115
|
+
const { level: e, description: r, context: o, data: s, error: i } = t, u = o || this.context || "www";
|
|
116
|
+
if (m) {
|
|
117
|
+
const d = {
|
|
118
|
+
timestamp: this.formatISOTimestamp(),
|
|
119
|
+
level: e.toUpperCase()
|
|
120
|
+
};
|
|
121
|
+
s && (d.data = this.formatData(s)), i && (d.error = this.formatData(i)), console[e](`${d.timestamp} ${d.level} [${u}] ${r}`, s || i ? JSON.stringify({ data: s, error: i }) : "");
|
|
122
|
+
} else
|
|
123
|
+
try {
|
|
124
|
+
const a = (await import("./index-C-0XxdQQ.js").catch(() => null))?.default, I = S[e], N = this.formatTimestamp();
|
|
125
|
+
if (a) {
|
|
126
|
+
const K = a.dim, B = a.hex(I.color), V = K(`${N} `), J = B(`${e.toUpperCase()} `), W = B(`(${u}): `), _ = `${V}${J}${W}${r}`;
|
|
127
|
+
console[e](_), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), i && (i instanceof Error && a ? (console.error(a.red("Error:"), i.message), i.stack && console.error(a.gray(i.stack))) : console.error("Error:", i));
|
|
128
|
+
} else
|
|
129
|
+
console[e](`${N} ${e.toUpperCase()} (${u}): ${r}`), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), i && console.error("Error:", i);
|
|
130
|
+
} catch {
|
|
131
|
+
console[e](`${this.formatTimestamp()} ${e.toUpperCase()} (${u}): ${r}`), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), i && console.error("Error:", i);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
log(t) {
|
|
135
|
+
g ? this.logToBrowser(t) : x && this.logToNode(t).catch(console.error);
|
|
136
|
+
}
|
|
137
|
+
error(t, e) {
|
|
138
|
+
this.log({ level: "error", description: t, data: e, context: this.context });
|
|
139
|
+
}
|
|
140
|
+
warn(t, e) {
|
|
141
|
+
this.log({ level: "warn", description: t, data: e, context: this.context });
|
|
142
|
+
}
|
|
143
|
+
info(t, e) {
|
|
144
|
+
this.log({ level: "info", description: t, data: e, context: this.context });
|
|
145
|
+
}
|
|
146
|
+
debug(t, e) {
|
|
147
|
+
this.log({ level: "debug", description: t, data: e, context: this.context });
|
|
148
|
+
}
|
|
149
|
+
trace(t, e) {
|
|
150
|
+
this.log({ level: "trace", description: t, data: e, context: this.context });
|
|
151
|
+
}
|
|
152
|
+
isEnabled() {
|
|
153
|
+
return g ? this.enabledInBrowser : !0;
|
|
154
|
+
}
|
|
155
|
+
setLevel(t) {
|
|
156
|
+
this.settings.minLevel = t;
|
|
157
|
+
}
|
|
158
|
+
createContextLogger(t) {
|
|
159
|
+
const e = new p(this.settings, t);
|
|
160
|
+
return {
|
|
161
|
+
error: /* @__PURE__ */ l((r, o) => e.error(r, o), "error"),
|
|
162
|
+
warn: /* @__PURE__ */ l((r, o) => e.warn(r, o), "warn"),
|
|
163
|
+
info: /* @__PURE__ */ l((r, o) => e.info(r, o), "info"),
|
|
164
|
+
debug: /* @__PURE__ */ l((r, o) => e.debug(r, o), "debug"),
|
|
165
|
+
trace: /* @__PURE__ */ l((r, o) => e.trace(r, o), "trace"),
|
|
166
|
+
isEnabled: /* @__PURE__ */ l(() => e.isEnabled(), "isEnabled"),
|
|
167
|
+
setLevel: /* @__PURE__ */ l((r) => e.setLevel(r), "setLevel")
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
l(p, "Logger"), n(p, "hasShownHelp", !1);
|
|
172
|
+
let U = p;
|
|
173
|
+
function q(c) {
|
|
174
|
+
return new U({}, c).createContextLogger(c);
|
|
175
|
+
}
|
|
176
|
+
l(q, "createLogger");
|
|
177
|
+
const f = new U();
|
|
178
|
+
f.error.bind(f);
|
|
179
|
+
f.warn.bind(f);
|
|
180
|
+
f.info.bind(f);
|
|
181
|
+
f.debug.bind(f);
|
|
182
|
+
f.trace.bind(f);
|
|
183
|
+
const A = class A {
|
|
184
|
+
constructor(t, e) {
|
|
185
|
+
n(this, "name");
|
|
186
|
+
n(this, "settings");
|
|
187
|
+
n(this, "logger");
|
|
188
|
+
this.name = t, this.settings = e, this.logger = q(t);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
l(A, "SettingsObject");
|
|
192
|
+
let E = A;
|
|
193
|
+
const F = class F {
|
|
194
|
+
constructor() {
|
|
195
|
+
// Configuration properties
|
|
196
|
+
n(this, "tokenName", "auth-token");
|
|
197
|
+
n(this, "tokenMaxAge", 3600 * 24 * 7);
|
|
198
|
+
// 7 days
|
|
199
|
+
n(this, "fallbackStorageKey", "token");
|
|
200
|
+
// For localStorage migration
|
|
201
|
+
n(this, "productionDomain", ".fiction.com");
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get cookie value by name
|
|
205
|
+
*/
|
|
206
|
+
getCookie(t) {
|
|
207
|
+
if (typeof document > "u")
|
|
208
|
+
return null;
|
|
209
|
+
const e = document.cookie.split(";");
|
|
210
|
+
for (const r of e) {
|
|
211
|
+
const [o, s] = r.trim().split("=");
|
|
212
|
+
if (o === t)
|
|
213
|
+
return decodeURIComponent(s || "");
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Set cookie with secure defaults
|
|
219
|
+
*/
|
|
220
|
+
setCookie(t, e, r = {}) {
|
|
221
|
+
if (typeof document > "u")
|
|
222
|
+
return;
|
|
223
|
+
const {
|
|
224
|
+
secure: o = !0,
|
|
225
|
+
sameSite: s = "lax",
|
|
226
|
+
maxAge: i = 3600 * 24 * 7,
|
|
227
|
+
// 7 days default
|
|
228
|
+
domain: u,
|
|
229
|
+
path: d = "/"
|
|
230
|
+
} = r;
|
|
231
|
+
let a = `${t}=${encodeURIComponent(e)}`;
|
|
232
|
+
a += `; Path=${d}`, a += `; Max-Age=${i}`, a += `; SameSite=${s}`, o && (a += "; Secure"), u && (a += `; Domain=${u}`), document.cookie = a;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Remove cookie by setting expired date
|
|
236
|
+
*/
|
|
237
|
+
removeCookie(t, e = {}) {
|
|
238
|
+
this.setCookie(t, "", { ...e, maxAge: 0 });
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get auth token with fallback to localStorage for migration
|
|
242
|
+
*/
|
|
243
|
+
getAuthToken() {
|
|
244
|
+
const t = this.getCookie(this.tokenName);
|
|
245
|
+
if (t)
|
|
246
|
+
return t;
|
|
247
|
+
if (typeof localStorage < "u") {
|
|
248
|
+
const e = localStorage.getItem(this.fallbackStorageKey);
|
|
249
|
+
if (e)
|
|
250
|
+
return this.setAuthToken(e), localStorage.removeItem(this.fallbackStorageKey), e;
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Set auth token in cookie with production-ready settings
|
|
256
|
+
*/
|
|
257
|
+
setAuthToken(t) {
|
|
258
|
+
const e = typeof window < "u" && window.location.hostname !== "localhost";
|
|
259
|
+
this.setCookie(this.tokenName, t, {
|
|
260
|
+
secure: e,
|
|
261
|
+
sameSite: "lax",
|
|
262
|
+
maxAge: this.tokenMaxAge,
|
|
263
|
+
domain: e ? this.productionDomain : void 0,
|
|
264
|
+
path: "/"
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Remove auth token
|
|
269
|
+
*/
|
|
270
|
+
removeAuthToken() {
|
|
271
|
+
const t = typeof window < "u" && window.location.hostname !== "localhost";
|
|
272
|
+
this.removeCookie(this.tokenName, {
|
|
273
|
+
domain: t ? this.productionDomain : void 0,
|
|
274
|
+
path: "/"
|
|
275
|
+
}), typeof localStorage < "u" && localStorage.removeItem(this.fallbackStorageKey);
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
l(F, "CookieUtil");
|
|
279
|
+
let L = F;
|
|
280
|
+
const w = new L();
|
|
281
|
+
function Z(c, t) {
|
|
282
|
+
const e = c.apiBase || (c.isDev ? "http://localhost:5555" : "https://app.fiction.com");
|
|
283
|
+
return H(e, {
|
|
284
|
+
fetch: /* @__PURE__ */ l(async (o, s) => {
|
|
285
|
+
const i = await fetch(o, {
|
|
286
|
+
...s,
|
|
287
|
+
credentials: "include",
|
|
288
|
+
headers: {
|
|
289
|
+
...s?.headers,
|
|
290
|
+
"Content-Type": "application/json",
|
|
291
|
+
Authorization: `Bearer ${w.getAuthToken() || ""}`
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
if (t) {
|
|
295
|
+
const u = i.json.bind(i), d = i.clone();
|
|
296
|
+
return Object.defineProperty(d, "json", {
|
|
297
|
+
value: /* @__PURE__ */ l(async () => {
|
|
298
|
+
const a = await u();
|
|
299
|
+
return typeof a == "object" && a !== null && "ok" in a && ("user" in a || "token" in a) && t(a), a;
|
|
300
|
+
}, "value")
|
|
301
|
+
}), d;
|
|
302
|
+
}
|
|
303
|
+
return i;
|
|
304
|
+
}, "fetch")
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
l(Z, "createApiClient");
|
|
308
|
+
let ee = Symbol("clean"), h = [], v = 0;
|
|
309
|
+
const b = 4;
|
|
310
|
+
let z = /* @__PURE__ */ l((c) => {
|
|
311
|
+
let t = [], e = {
|
|
312
|
+
get() {
|
|
313
|
+
return e.lc || e.listen(() => {
|
|
314
|
+
})(), e.value;
|
|
315
|
+
},
|
|
316
|
+
lc: 0,
|
|
317
|
+
listen(r) {
|
|
318
|
+
return e.lc = t.push(r), () => {
|
|
319
|
+
for (let s = v + b; s < h.length; )
|
|
320
|
+
h[s] === r ? h.splice(s, b) : s += b;
|
|
321
|
+
let o = t.indexOf(r);
|
|
322
|
+
~o && (t.splice(o, 1), --e.lc || e.off());
|
|
323
|
+
};
|
|
324
|
+
},
|
|
325
|
+
notify(r, o) {
|
|
326
|
+
let s = !h.length;
|
|
327
|
+
for (let i of t)
|
|
328
|
+
h.push(i, e.value, r, o);
|
|
329
|
+
if (s) {
|
|
330
|
+
for (v = 0; v < h.length; v += b)
|
|
331
|
+
h[v](
|
|
332
|
+
h[v + 1],
|
|
333
|
+
h[v + 2],
|
|
334
|
+
h[v + 3]
|
|
335
|
+
);
|
|
336
|
+
h.length = 0;
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
/* It will be called on last listener unsubscribing.
|
|
340
|
+
We will redefine it in onMount and onStop. */
|
|
341
|
+
off() {
|
|
342
|
+
},
|
|
343
|
+
set(r) {
|
|
344
|
+
let o = e.value;
|
|
345
|
+
o !== r && (e.value = r, e.notify(o));
|
|
346
|
+
},
|
|
347
|
+
subscribe(r) {
|
|
348
|
+
let o = e.listen(r);
|
|
349
|
+
return r(e.value), o;
|
|
350
|
+
},
|
|
351
|
+
value: c
|
|
352
|
+
};
|
|
353
|
+
return process.env.NODE_ENV !== "production" && (e[ee] = () => {
|
|
354
|
+
t = [], e.lc = 0, e.off();
|
|
355
|
+
}), e;
|
|
356
|
+
}, "atom");
|
|
357
|
+
const C = z(void 0), $ = z(null), j = class j {
|
|
358
|
+
constructor() {
|
|
359
|
+
n(this, "logger", q("SDKStorage"));
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Sync Vue reactive refs with global nanostores for cross-page persistence
|
|
363
|
+
*/
|
|
364
|
+
syncWithGlobalStores(t, e) {
|
|
365
|
+
const r = C.get(), o = $.get();
|
|
366
|
+
r && (t.value = r), o && (e.value = o), P(t, (s) => {
|
|
367
|
+
C.set(s);
|
|
368
|
+
}, { immediate: !0 }), P(e, (s) => {
|
|
369
|
+
$.set(s);
|
|
370
|
+
}, { immediate: !0 }), C.subscribe((s) => {
|
|
371
|
+
s !== t.value && (t.value = s);
|
|
372
|
+
}), $.subscribe((s) => {
|
|
373
|
+
s !== e.value && (e.value = s);
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Load user and token from browser storage on initialization
|
|
378
|
+
*/
|
|
379
|
+
loadFromStorage(t, e) {
|
|
380
|
+
if (typeof window > "u")
|
|
381
|
+
return;
|
|
382
|
+
const r = w.getAuthToken();
|
|
383
|
+
r && (e.value = r);
|
|
384
|
+
try {
|
|
385
|
+
const o = localStorage.getItem("fiction-user");
|
|
386
|
+
o && (t.value = JSON.parse(o));
|
|
387
|
+
} catch (o) {
|
|
388
|
+
this.logger.error("Failed to load user from localStorage", { data: o });
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Save current user and token to browser storage
|
|
393
|
+
*/
|
|
394
|
+
saveToStorage(t, e) {
|
|
395
|
+
if (!(typeof window > "u")) {
|
|
396
|
+
e.value ? w.setAuthToken(e.value) : w.removeAuthToken();
|
|
397
|
+
try {
|
|
398
|
+
t.value ? localStorage.setItem("fiction-user", JSON.stringify(t.value)) : localStorage.removeItem("fiction-user");
|
|
399
|
+
} catch (r) {
|
|
400
|
+
this.logger.error("Failed to save user to localStorage", { data: r });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Clear all stored user data and tokens
|
|
406
|
+
*/
|
|
407
|
+
clearStorage() {
|
|
408
|
+
if (!(typeof window > "u")) {
|
|
409
|
+
w.removeAuthToken();
|
|
410
|
+
try {
|
|
411
|
+
localStorage.removeItem("fiction-user");
|
|
412
|
+
} catch (t) {
|
|
413
|
+
this.logger.error("Failed to clear user from localStorage", { data: t });
|
|
414
|
+
}
|
|
415
|
+
C.set(void 0), $.set(null);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Generic localStorage getter
|
|
420
|
+
*/
|
|
421
|
+
getItem(t) {
|
|
422
|
+
if (typeof window > "u")
|
|
423
|
+
return null;
|
|
424
|
+
try {
|
|
425
|
+
return localStorage.getItem(t);
|
|
426
|
+
} catch (e) {
|
|
427
|
+
return this.logger.error("Failed to get item from localStorage", { key: t, error: e }), null;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Generic localStorage setter
|
|
432
|
+
*/
|
|
433
|
+
setItem(t, e) {
|
|
434
|
+
if (!(typeof window > "u"))
|
|
435
|
+
try {
|
|
436
|
+
localStorage.setItem(t, e);
|
|
437
|
+
} catch (r) {
|
|
438
|
+
this.logger.error("Failed to set item in localStorage", { key: t, error: r });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
l(j, "SDKStorage");
|
|
443
|
+
let T = j;
|
|
444
|
+
const D = class D extends E {
|
|
445
|
+
constructor(e = {}) {
|
|
446
|
+
super("FictionSDK", e);
|
|
447
|
+
// Vue reactive state
|
|
448
|
+
n(this, "activeUser", k());
|
|
449
|
+
n(this, "token", k(null));
|
|
450
|
+
n(this, "loading", k(!1));
|
|
451
|
+
n(this, "error", k(null));
|
|
452
|
+
n(this, "apiBase", this.settings.apiBase || void 0);
|
|
453
|
+
// Storage handler for persistence
|
|
454
|
+
n(this, "storage", new T());
|
|
455
|
+
// Auto-managed session ID for usage tracking
|
|
456
|
+
n(this, "sessionId", M({ prefix: "ses" }));
|
|
457
|
+
// Typed Hono RPC client - uses SDKAppType (auth/self/usage routes only)
|
|
458
|
+
n(this, "apiClient");
|
|
459
|
+
// Computed properties derived from activeUser (matches UserClient pattern)
|
|
460
|
+
n(this, "currentSelf", G(() => {
|
|
461
|
+
const e = this.activeUser.value;
|
|
462
|
+
if (!e?.selves)
|
|
463
|
+
return;
|
|
464
|
+
const r = e.primarySelfId || e.selves[0]?.selfId;
|
|
465
|
+
if (r)
|
|
466
|
+
return e.selves.find((o) => o.selfId === r);
|
|
467
|
+
}));
|
|
468
|
+
n(this, "currentOrg", G(() => {
|
|
469
|
+
const e = this.currentSelf.value;
|
|
470
|
+
if (!e?.orgId)
|
|
471
|
+
return;
|
|
472
|
+
const r = this.activeUser.value;
|
|
473
|
+
if (r?.orgs)
|
|
474
|
+
return r.orgs.find((o) => o.orgId === e.orgId);
|
|
475
|
+
}));
|
|
476
|
+
// Initialization state
|
|
477
|
+
n(this, "initialized");
|
|
478
|
+
n(this, "resolveUser");
|
|
479
|
+
this.apiClient = Z(
|
|
480
|
+
{ isDev: this.isDev, apiBase: this.apiBase },
|
|
481
|
+
this.processApiResponse.bind(this)
|
|
482
|
+
), this.logger.info("FictionSDK initialized"), this.storage.loadFromStorage(this.activeUser, this.token), this.storage.syncWithGlobalStores(this.activeUser, this.token), this.initialized = new Promise((r) => {
|
|
483
|
+
this.resolveUser = r;
|
|
484
|
+
}), this.token.value && !this.activeUser.value ? this.getCurrentUser().then((r) => {
|
|
485
|
+
this.resolveUser && (this.resolveUser(r), this.resolveUser = void 0);
|
|
486
|
+
}).catch((r) => {
|
|
487
|
+
this.logger.error("Auto user fetch failed", { data: r }), this.resolveUser && (this.resolveUser(void 0), this.resolveUser = void 0);
|
|
488
|
+
}) : this.activeUser.value ? this.resolveUser?.(this.activeUser.value) : this.resolveUser?.(void 0);
|
|
489
|
+
}
|
|
490
|
+
get isDev() {
|
|
491
|
+
return this.settings.isDev ?? (typeof window < "u" ? window.location.hostname === "localhost" || window.location.hostname.includes("127.0.0.1") : !1);
|
|
492
|
+
}
|
|
493
|
+
// Bypass stub typing for route access (production builds use SDKAppType stub)
|
|
494
|
+
// Runtime types are validated via Zod at API boundaries
|
|
495
|
+
get api() {
|
|
496
|
+
return this.apiClient.api;
|
|
497
|
+
}
|
|
498
|
+
// Process ApiResponse for automatic user/token updates - public for dependency injection
|
|
499
|
+
processApiResponse(e) {
|
|
500
|
+
e.ok && e.user && (this.activeUser.value = e.user, this.logger.info("User updated from API response", { data: e.user })), e.ok && e.token && (this.token.value = e.token, this.storage.saveToStorage(this.activeUser, this.token), this.logger.info("Token updated from API response")), this.resolveUser && e.ok && (this.resolveUser(e.user), this.resolveUser = void 0);
|
|
501
|
+
}
|
|
502
|
+
// Clear all user data and tokens
|
|
503
|
+
clearSession() {
|
|
504
|
+
this.logger.info("Clearing session"), this.activeUser.value = void 0, this.token.value = null, this.error.value = null, this.storage.clearStorage();
|
|
505
|
+
}
|
|
506
|
+
// Convenience methods for common auth operations
|
|
507
|
+
async sendCode(e) {
|
|
508
|
+
this.loading.value = !0, this.error.value = null;
|
|
509
|
+
try {
|
|
510
|
+
const o = await (await this.api.auth["check-email"].$post({
|
|
511
|
+
json: { email: e }
|
|
512
|
+
})).json();
|
|
513
|
+
if (!o.ok)
|
|
514
|
+
throw this.error.value = o.error, new Error(o.error);
|
|
515
|
+
} catch (r) {
|
|
516
|
+
this.logger.error("Send code error", { data: r });
|
|
517
|
+
const o = r instanceof Error ? r.message : "Failed to send verification code";
|
|
518
|
+
throw this.error.value = o, r;
|
|
519
|
+
} finally {
|
|
520
|
+
this.loading.value = !1;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
async verifyCode(e, r) {
|
|
524
|
+
this.loading.value = !0, this.error.value = null;
|
|
525
|
+
try {
|
|
526
|
+
const s = await (await this.api.auth["verify-code"].$post({
|
|
527
|
+
json: { email: e, code: r }
|
|
528
|
+
})).json();
|
|
529
|
+
if (!s.ok)
|
|
530
|
+
throw this.error.value = s.error, new Error(s.error);
|
|
531
|
+
} catch (o) {
|
|
532
|
+
this.logger.error("Verify code error", { data: o });
|
|
533
|
+
const s = o instanceof Error ? o.message : "Failed to verify code";
|
|
534
|
+
throw this.error.value = s, o;
|
|
535
|
+
} finally {
|
|
536
|
+
this.loading.value = !1;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
async login(e, r) {
|
|
540
|
+
this.loading.value = !0, this.error.value = null;
|
|
541
|
+
try {
|
|
542
|
+
const s = await (await this.api.auth.login.$post({
|
|
543
|
+
json: { email: e, password: r }
|
|
544
|
+
})).json();
|
|
545
|
+
if (!s.ok)
|
|
546
|
+
throw this.error.value = s.error, new Error(s.error);
|
|
547
|
+
} catch (o) {
|
|
548
|
+
this.logger.error("Login error", { data: o });
|
|
549
|
+
const s = o instanceof Error ? o.message : "Login failed";
|
|
550
|
+
throw this.error.value = s, o;
|
|
551
|
+
} finally {
|
|
552
|
+
this.loading.value = !1;
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async logout() {
|
|
556
|
+
this.loading.value = !0, this.error.value = null;
|
|
557
|
+
try {
|
|
558
|
+
await this.api.auth.logout.$post(), this.activeUser.value = void 0, this.token.value = null, this.storage.clearStorage();
|
|
559
|
+
} catch (e) {
|
|
560
|
+
this.logger.error("Logout error (user still logged out locally)", { data: e }), this.activeUser.value = void 0, this.token.value = null, this.storage.clearStorage();
|
|
561
|
+
} finally {
|
|
562
|
+
this.loading.value = !1;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
async getCurrentUser() {
|
|
566
|
+
if (this.token.value) {
|
|
567
|
+
this.loading.value = !0;
|
|
568
|
+
try {
|
|
569
|
+
const r = await (await this.api.auth.me.$get()).json();
|
|
570
|
+
if (!r.ok) {
|
|
571
|
+
this.error.value = r.error, r.error.includes("Authentication") && (this.activeUser.value = void 0, this.token.value = null, this.storage.clearStorage());
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
return r.user;
|
|
575
|
+
} catch (e) {
|
|
576
|
+
this.logger.error("Get current user error", { data: e }), this.error.value = e instanceof Error ? e.message : "Failed to get user info";
|
|
577
|
+
return;
|
|
578
|
+
} finally {
|
|
579
|
+
this.loading.value = !1;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
async getPublicSelf(e) {
|
|
584
|
+
this.loading.value = !0, this.error.value = null;
|
|
585
|
+
try {
|
|
586
|
+
const o = await (await this.api.self.public[":handle"].$get({
|
|
587
|
+
param: { handle: e.handle }
|
|
588
|
+
})).json();
|
|
589
|
+
if (!o.ok) {
|
|
590
|
+
this.error.value = o.error, this.logger.error("Failed to fetch public self", { handle: e.handle, error: o.error });
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
return o.data;
|
|
594
|
+
} catch (r) {
|
|
595
|
+
this.logger.error("Get public self error", { handle: e.handle, error: r }), this.error.value = r instanceof Error ? r.message : "Failed to fetch self";
|
|
596
|
+
return;
|
|
597
|
+
} finally {
|
|
598
|
+
this.loading.value = !1;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
async requestAuthCode(e) {
|
|
602
|
+
this.loading.value = !0, this.error.value = null;
|
|
603
|
+
try {
|
|
604
|
+
const o = await (await this.api.auth["check-email"].$post({
|
|
605
|
+
json: { email: e.email }
|
|
606
|
+
})).json();
|
|
607
|
+
return o.ok ? (this.logger.info("Auth code requested successfully", { email: e.email }), !0) : (this.error.value = o.error, this.logger.error("Failed to request auth code", { email: e.email, error: o.error }), !1);
|
|
608
|
+
} catch (r) {
|
|
609
|
+
return this.logger.error("Request auth code error", { email: e.email, error: r }), this.error.value = r instanceof Error ? r.message : "Failed to request auth code", !1;
|
|
610
|
+
} finally {
|
|
611
|
+
this.loading.value = !1;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
async loginWithCode(e) {
|
|
615
|
+
this.loading.value = !0, this.error.value = null;
|
|
616
|
+
try {
|
|
617
|
+
const o = await (await this.api.auth["verify-code"].$post({
|
|
618
|
+
json: { email: e.email, code: e.code }
|
|
619
|
+
})).json();
|
|
620
|
+
return o.ok ? (this.logger.info("Login successful", { email: e.email }), e.orgId && e.autoCreateContact !== !1 && this.activeUser.value?.userId && await this.autoCreateContact({
|
|
621
|
+
userId: this.activeUser.value.userId,
|
|
622
|
+
orgId: e.orgId
|
|
623
|
+
}), !0) : (this.error.value = o.error, this.logger.error("Login failed", { email: e.email, error: o.error }), !1);
|
|
624
|
+
} catch (r) {
|
|
625
|
+
return this.logger.error("Login with code error", { email: e.email, error: r }), this.error.value = r instanceof Error ? r.message : "Login failed", !1;
|
|
626
|
+
} finally {
|
|
627
|
+
this.loading.value = !1;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
async trackUsage(e) {
|
|
631
|
+
try {
|
|
632
|
+
const r = this.currentSelf.value;
|
|
633
|
+
if (!r?.orgId)
|
|
634
|
+
return this.logger.error("Cannot track usage: no current self with orgId", { args: e }), !1;
|
|
635
|
+
const s = await (await this.api.usage.record.$post({
|
|
636
|
+
json: {
|
|
637
|
+
orgId: r.orgId,
|
|
638
|
+
selfId: e.selfId,
|
|
639
|
+
sessionId: this.sessionId,
|
|
640
|
+
// Auto-managed by SDK
|
|
641
|
+
type: e.type,
|
|
642
|
+
quantity: e.quantity,
|
|
643
|
+
// Track the participant if provided, otherwise use current user or anonymous
|
|
644
|
+
userId: e.participantId || this.activeUser.value?.userId || "anonymous"
|
|
645
|
+
}
|
|
646
|
+
})).json();
|
|
647
|
+
return s.ok ? !0 : (this.logger.error("Failed to track usage", { error: s.error, args: e }), !1);
|
|
648
|
+
} catch (r) {
|
|
649
|
+
return this.logger.error("Track usage error", { error: r, args: e }), !1;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Auto-create contact on authentication
|
|
654
|
+
* Called internally by loginWithCode - can be disabled with autoCreateContact: false
|
|
655
|
+
*/
|
|
656
|
+
async autoCreateContact(e) {
|
|
657
|
+
try {
|
|
658
|
+
const o = await (await this.api.contact.resolve.$post({
|
|
659
|
+
json: { userId: e.userId, orgId: e.orgId }
|
|
660
|
+
})).json();
|
|
661
|
+
return o.ok ? (this.logger.info("Contact resolved", { userId: e.userId, orgId: e.orgId }), !0) : (this.logger.error("Failed to auto-create contact", { error: o.error, args: e }), !1);
|
|
662
|
+
} catch (r) {
|
|
663
|
+
return this.logger.error("Auto-create contact error", { error: r, args: e }), !1;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Start conversation session (auto-creates conversation if needed)
|
|
668
|
+
* Returns conversation data for tracking messages
|
|
669
|
+
*/
|
|
670
|
+
async startConversation(e) {
|
|
671
|
+
try {
|
|
672
|
+
const r = this.currentSelf.value;
|
|
673
|
+
if (!r?.orgId) {
|
|
674
|
+
this.logger.error("Cannot start conversation: no current self with orgId", { args: e });
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
const s = await (await this.api.conversation.start.$post({
|
|
678
|
+
json: {
|
|
679
|
+
orgId: r.orgId,
|
|
680
|
+
selfId: e.selfId,
|
|
681
|
+
userId: e.userId || this.activeUser.value?.userId,
|
|
682
|
+
anonId: e.anonId
|
|
683
|
+
}
|
|
684
|
+
})).json();
|
|
685
|
+
if (!s.ok || !s.data) {
|
|
686
|
+
const i = s.ok ? "No conversation data returned" : "error" in s ? s.error : "Unknown error";
|
|
687
|
+
this.logger.error("Failed to start conversation", { error: i, args: e });
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
return this.logger.info("Conversation started", { conversationId: s.data.conversationId }), s.data;
|
|
691
|
+
} catch (r) {
|
|
692
|
+
this.logger.error("Start conversation error", { error: r, args: e });
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
/**
|
|
697
|
+
* Generate anonymous ID for tracking unauthenticated users
|
|
698
|
+
* Stored in localStorage for persistence across sessions
|
|
699
|
+
*/
|
|
700
|
+
generateAnonId() {
|
|
701
|
+
const e = "fictionAnonId";
|
|
702
|
+
let r = this.storage.getItem(e);
|
|
703
|
+
return r || (r = M({ prefix: "anon" }), this.storage.setItem(e, r)), r;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Save message to conversation
|
|
707
|
+
* Called by SelfController to persist messages
|
|
708
|
+
*/
|
|
709
|
+
async saveMessage(e) {
|
|
710
|
+
try {
|
|
711
|
+
const o = await (await this.api.conversation.messages.$post({
|
|
712
|
+
json: {
|
|
713
|
+
sessionId: e.conversationId,
|
|
714
|
+
participantId: e.participantId,
|
|
715
|
+
content: e.content,
|
|
716
|
+
role: e.role
|
|
717
|
+
}
|
|
718
|
+
})).json();
|
|
719
|
+
return o.ok ? !0 : (this.logger.error("Failed to save message", { error: "error" in o ? o.error : "Unknown error", args: e }), !1);
|
|
720
|
+
} catch (r) {
|
|
721
|
+
return this.logger.error("Save message error", { error: r, args: e }), !1;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
l(D, "FictionSDK");
|
|
726
|
+
let R = D;
|
|
727
|
+
export {
|
|
728
|
+
R as F,
|
|
729
|
+
E as S
|
|
730
|
+
};
|
|
731
|
+
//# sourceMappingURL=sdkClient-C9BL_Op4.js.map
|