faire-auth 1.0.0
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/LICENSE +661 -0
- package/README.md +34 -0
- package/dist/access-B5bBI4uT.mjs +39 -0
- package/dist/access-Crt-IJ2P.cjs +51 -0
- package/dist/adapter-factory-BXei1QRX.mjs +881 -0
- package/dist/adapter-factory-DT-_2aHJ.cjs +893 -0
- package/dist/adapters/drizzle-adapter/index.cjs +208 -0
- package/dist/adapters/drizzle-adapter/index.d.cts +48 -0
- package/dist/adapters/drizzle-adapter/index.d.mts +48 -0
- package/dist/adapters/drizzle-adapter/index.mjs +207 -0
- package/dist/adapters/index.cjs +23 -0
- package/dist/adapters/index.d.cts +157 -0
- package/dist/adapters/index.d.mts +157 -0
- package/dist/adapters/index.mjs +17 -0
- package/dist/adapters/kysely-adapter/index.cjs +11 -0
- package/dist/adapters/kysely-adapter/index.d.cts +52 -0
- package/dist/adapters/kysely-adapter/index.d.mts +52 -0
- package/dist/adapters/kysely-adapter/index.mjs +9 -0
- package/dist/adapters/memory-adapter/index.cjs +9 -0
- package/dist/adapters/memory-adapter/index.d.cts +15 -0
- package/dist/adapters/memory-adapter/index.d.mts +15 -0
- package/dist/adapters/memory-adapter/index.mjs +9 -0
- package/dist/adapters/mongodb-adapter/index.cjs +9 -0
- package/dist/adapters/mongodb-adapter/index.d.cts +4 -0
- package/dist/adapters/mongodb-adapter/index.d.mts +4 -0
- package/dist/adapters/mongodb-adapter/index.mjs +9 -0
- package/dist/adapters/prisma-adapter/index.cjs +156 -0
- package/dist/adapters/prisma-adapter/index.d.cts +35 -0
- package/dist/adapters/prisma-adapter/index.d.mts +35 -0
- package/dist/adapters/prisma-adapter/index.mjs +155 -0
- package/dist/adapters/test.cjs +797 -0
- package/dist/adapters/test.d.cts +82 -0
- package/dist/adapters/test.d.mts +82 -0
- package/dist/adapters/test.mjs +793 -0
- package/dist/api/index.cjs +20 -0
- package/dist/api/index.d.cts +3 -0
- package/dist/api/index.d.mts +3 -0
- package/dist/api/index.mjs +20 -0
- package/dist/api/middleware/index.cjs +16 -0
- package/dist/api/middleware/index.d.cts +16 -0
- package/dist/api/middleware/index.d.mts +16 -0
- package/dist/api/middleware/index.mjs +11 -0
- package/dist/api-Bm89BLgN.cjs +1899 -0
- package/dist/api-_B7qO28y.mjs +1892 -0
- package/dist/auth-Bo9PDt5j.cjs +739 -0
- package/dist/auth-Ds4AG4h4.mjs +709 -0
- package/dist/bearer-0SeEmaS4.mjs +54 -0
- package/dist/bearer-CHeREcGT.cjs +60 -0
- package/dist/bun-sqlite-dialect-CfkBo2v5.mjs +155 -0
- package/dist/bun-sqlite-dialect-wuaC2-gh.cjs +156 -0
- package/dist/chunk-Ceigfy4P.mjs +39 -0
- package/dist/chunk-oakRccI5.cjs +60 -0
- package/dist/client/index.cjs +22 -0
- package/dist/client/index.d.cts +8 -0
- package/dist/client/index.d.mts +8 -0
- package/dist/client/index.mjs +19 -0
- package/dist/client/lynx/index.cjs +79 -0
- package/dist/client/lynx/index.d.cts +156 -0
- package/dist/client/lynx/index.d.mts +156 -0
- package/dist/client/lynx/index.mjs +76 -0
- package/dist/client/plugins/index.cjs +11 -0
- package/dist/client/plugins/index.d.cts +17 -0
- package/dist/client/plugins/index.d.mts +17 -0
- package/dist/client/plugins/index.mjs +10 -0
- package/dist/client/react/index.cjs +79 -0
- package/dist/client/react/index.d.cts +156 -0
- package/dist/client/react/index.d.mts +156 -0
- package/dist/client/react/index.mjs +76 -0
- package/dist/client/solid/index.cjs +51 -0
- package/dist/client/solid/index.d.cts +90 -0
- package/dist/client/solid/index.d.mts +90 -0
- package/dist/client/solid/index.mjs +50 -0
- package/dist/client/svelte/index.cjs +28 -0
- package/dist/client/svelte/index.d.cts +110 -0
- package/dist/client/svelte/index.d.mts +110 -0
- package/dist/client/svelte/index.mjs +28 -0
- package/dist/client/vue/index.cjs +68 -0
- package/dist/client/vue/index.d.cts +123 -0
- package/dist/client/vue/index.d.mts +123 -0
- package/dist/client/vue/index.mjs +67 -0
- package/dist/cookies-B5xeA6i8.cjs +456 -0
- package/dist/cookies-Ch1JfQIz.mjs +367 -0
- package/dist/crypto/index.cjs +11 -0
- package/dist/crypto/index.d.cts +22 -0
- package/dist/crypto/index.d.mts +22 -0
- package/dist/crypto/index.mjs +5 -0
- package/dist/crypto-CcTxYH82.cjs +57 -0
- package/dist/crypto-CyQRFtkq.mjs +41 -0
- package/dist/db/index.cjs +40 -0
- package/dist/db/index.d.cts +4 -0
- package/dist/db/index.d.mts +4 -0
- package/dist/db/index.mjs +16 -0
- package/dist/db-BTKyYu-_.cjs +1180 -0
- package/dist/db-xiJtoDgz.mjs +1119 -0
- package/dist/defu-B0Svx_x4.cjs +34 -0
- package/dist/defu-SZkpHhbR.mjs +28 -0
- package/dist/email-verification-C-AsfJsb.cjs +247 -0
- package/dist/email-verification-CWhj2qfb.mjs +228 -0
- package/dist/hono-BEq1NYVX.cjs +526 -0
- package/dist/hono-Cdukwu5K.cjs +13 -0
- package/dist/hono-CoKYWnXA.mjs +7 -0
- package/dist/hono-Covz10jU.mjs +508 -0
- package/dist/hono-DOM31WQz.d.cts +18 -0
- package/dist/hono-DuE14mmj.d.mts +18 -0
- package/dist/index-B-WeOMzg.d.cts +13350 -0
- package/dist/index-B09P9p5_.d.cts +33 -0
- package/dist/index-B5_0QTLg.d.mts +3 -0
- package/dist/index-B7SKyR_a.d.cts +3 -0
- package/dist/index-BVHscLQl.d.cts +992 -0
- package/dist/index-C2-2QDyS.d.cts +35 -0
- package/dist/index-CTwrVluH.d.mts +41 -0
- package/dist/index-CWAqWfoZ.d.cts +27 -0
- package/dist/index-CYSShrFx.d.mts +27 -0
- package/dist/index-Qu-iJGNr.d.mts +992 -0
- package/dist/index-cs4Sh0En.d.cts +41 -0
- package/dist/index-jlessPI0.d.mts +13350 -0
- package/dist/index-ppgcFe12.d.mts +33 -0
- package/dist/index-to0RO38U.d.mts +35 -0
- package/dist/index.cjs +85 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +27 -0
- package/dist/integrations/next-js.cjs +50 -0
- package/dist/integrations/next-js.d.cts +23 -0
- package/dist/integrations/next-js.d.mts +23 -0
- package/dist/integrations/next-js.mjs +49 -0
- package/dist/integrations/node.cjs +139 -0
- package/dist/integrations/node.d.cts +22 -0
- package/dist/integrations/node.d.mts +22 -0
- package/dist/integrations/node.mjs +134 -0
- package/dist/integrations/react-start.cjs +37 -0
- package/dist/integrations/react-start.d.cts +17 -0
- package/dist/integrations/react-start.d.mts +17 -0
- package/dist/integrations/react-start.mjs +37 -0
- package/dist/integrations/solid-start.cjs +14 -0
- package/dist/integrations/solid-start.d.cts +13 -0
- package/dist/integrations/solid-start.d.mts +13 -0
- package/dist/integrations/solid-start.mjs +13 -0
- package/dist/integrations/svelte-kit.cjs +52 -0
- package/dist/integrations/svelte-kit.d.cts +42 -0
- package/dist/integrations/svelte-kit.d.mts +42 -0
- package/dist/integrations/svelte-kit.mjs +49 -0
- package/dist/ip-B5SwXaMB.cjs +54 -0
- package/dist/ip-BjNYspCH.mjs +36 -0
- package/dist/json-B1v2qRTQ.mjs +24 -0
- package/dist/json-CcJ2HjGo.cjs +30 -0
- package/dist/kysely-adapter-Bxi7sPdG.cjs +288 -0
- package/dist/kysely-adapter-DRuoT_X8.mjs +270 -0
- package/dist/logged-CyGfp8_H.mjs +187 -0
- package/dist/logged-DQK3C64b.cjs +193 -0
- package/dist/memory-adapter-BlnDIAAX.cjs +154 -0
- package/dist/memory-adapter-Db3tsJTn.mjs +148 -0
- package/dist/middleware-CE6OhDkq.mjs +29 -0
- package/dist/middleware-CWvRH4EW.cjs +47 -0
- package/dist/mongodb-adapter-C_qGQED5.mjs +291 -0
- package/dist/mongodb-adapter-C_qfK87x.cjs +297 -0
- package/dist/node-sqlite-dialect-BfBzyOAg.mjs +155 -0
- package/dist/node-sqlite-dialect-mJWC8LWQ.cjs +156 -0
- package/dist/oauth2/index.cjs +25 -0
- package/dist/oauth2/index.d.cts +42 -0
- package/dist/oauth2/index.d.mts +42 -0
- package/dist/oauth2/index.mjs +16 -0
- package/dist/oauth2-B8M0lW9l.mjs +159 -0
- package/dist/oauth2-BLeOEi7Y.cjs +177 -0
- package/dist/origin-check-8Gajklvh.mjs +228 -0
- package/dist/origin-check-id9lTnqZ.cjs +246 -0
- package/dist/parser-CdncAl9i.cjs +83 -0
- package/dist/parser-CeAer-RM.mjs +71 -0
- package/dist/passkey-B6N20LSS.cjs +512 -0
- package/dist/passkey-DJsR_GX3.mjs +505 -0
- package/dist/plugins/access/index.cjs +4 -0
- package/dist/plugins/access/index.d.cts +2 -0
- package/dist/plugins/access/index.d.mts +2 -0
- package/dist/plugins/access/index.mjs +3 -0
- package/dist/plugins/bearer/index.cjs +7 -0
- package/dist/plugins/bearer/index.d.cts +4 -0
- package/dist/plugins/bearer/index.d.mts +4 -0
- package/dist/plugins/bearer/index.mjs +7 -0
- package/dist/plugins/index.cjs +49 -0
- package/dist/plugins/index.d.cts +9326 -0
- package/dist/plugins/index.d.mts +9326 -0
- package/dist/plugins/index.mjs +26 -0
- package/dist/plugins/passkey/index.cjs +15 -0
- package/dist/plugins/passkey/index.d.cts +4 -0
- package/dist/plugins/passkey/index.d.mts +4 -0
- package/dist/plugins/passkey/index.mjs +15 -0
- package/dist/plugins-C1lm2Wj3.cjs +5254 -0
- package/dist/plugins-Dai1QkRU.mjs +5199 -0
- package/dist/request-1NL_1lyJ.mjs +58 -0
- package/dist/request-CPNlp-DK.cjs +100 -0
- package/dist/schema-D-qjygfE.cjs +179 -0
- package/dist/schema-DTIwLLmf.mjs +125 -0
- package/dist/session-De9POJTW.cjs +641 -0
- package/dist/session-rH8ougDl.mjs +538 -0
- package/dist/social-providers/index.cjs +10 -0
- package/dist/social-providers/index.d.cts +2 -0
- package/dist/social-providers/index.d.mts +2 -0
- package/dist/social-providers/index.mjs +5 -0
- package/dist/social-providers-DcFNUT0S.cjs +13 -0
- package/dist/social-providers-DoYJhBe3.mjs +9 -0
- package/dist/state--f7fwIGh.cjs +99 -0
- package/dist/state-CqJfCIl9.mjs +86 -0
- package/dist/test-utils/index.cjs +27492 -0
- package/dist/test-utils/index.d.cts +4584 -0
- package/dist/test-utils/index.d.mts +4584 -0
- package/dist/test-utils/index.mjs +27490 -0
- package/dist/types/index.cjs +0 -0
- package/dist/types/index.d.cts +3 -0
- package/dist/types/index.d.mts +3 -0
- package/dist/types/index.mjs +1 -0
- package/dist/url-BoUuoIwZ.mjs +88 -0
- package/dist/url-D2yvKaM7.cjs +118 -0
- package/dist/utils/cookies.cjs +51 -0
- package/dist/utils/cookies.d.cts +179 -0
- package/dist/utils/cookies.d.mts +179 -0
- package/dist/utils/cookies.mjs +7 -0
- package/dist/utils-44aDDP8f.cjs +2 -0
- package/dist/utils-D4vZd1-9.mjs +4 -0
- package/dist/vanilla-Bu2PmFzE.cjs +30 -0
- package/dist/vanilla-TfHqeiC7.mjs +25 -0
- package/package.json +470 -0
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
import { t as getBaseURL } from "./url-BoUuoIwZ.mjs";
|
|
2
|
+
import { a as removeIndexString, i as normaliseHeaders, n as mergeHeaders, o as replaceUrlParam, r as mergePath, s as replaceUrlProtocol, t as buildSearchParams } from "./request-1NL_1lyJ.mjs";
|
|
3
|
+
import { t as defu } from "./defu-SZkpHhbR.mjs";
|
|
4
|
+
import { t as parseJSON } from "./parser-CeAer-RM.mjs";
|
|
5
|
+
import { serialize } from "hono/utils/cookie";
|
|
6
|
+
import { createFetch } from "@better-fetch/fetch";
|
|
7
|
+
import { atom, onMount } from "nanostores";
|
|
8
|
+
|
|
9
|
+
//#region src/client/fetch-plugins.ts
|
|
10
|
+
const redirectPlugin = {
|
|
11
|
+
id: "redirect",
|
|
12
|
+
name: "Redirect",
|
|
13
|
+
hooks: { onSuccess(context) {
|
|
14
|
+
if (context.data?.url && context.data?.redirect) {
|
|
15
|
+
if (typeof window !== "undefined" && window.location) {
|
|
16
|
+
if (window.location) try {
|
|
17
|
+
window.location.href = context.data.url;
|
|
18
|
+
} catch {}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
} }
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/client/plugins/lifecycle.ts
|
|
26
|
+
const lifecycle = (options) => ({
|
|
27
|
+
id: "lifecycle-hooks",
|
|
28
|
+
name: "lifecycle-hooks",
|
|
29
|
+
hooks: {
|
|
30
|
+
...options?.fetchOptions?.onSuccess && { onSuccess: options?.fetchOptions?.onSuccess },
|
|
31
|
+
...options?.fetchOptions?.onError && { onError: options.fetchOptions.onError },
|
|
32
|
+
...options?.fetchOptions?.onRequest && { onRequest: options.fetchOptions.onRequest },
|
|
33
|
+
...options?.fetchOptions?.onResponse && { onResponse: options.fetchOptions.onResponse }
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/client/query.ts
|
|
39
|
+
const isServer = typeof window === "undefined";
|
|
40
|
+
const useAuthQuery = (initializedAtom, path, $fetch, options) => {
|
|
41
|
+
const value = atom({
|
|
42
|
+
data: null,
|
|
43
|
+
error: null,
|
|
44
|
+
isPending: true,
|
|
45
|
+
isRefetching: false,
|
|
46
|
+
refetch: async () => fn()
|
|
47
|
+
});
|
|
48
|
+
const fn = async () => {
|
|
49
|
+
const opts = typeof options === "function" ? options({
|
|
50
|
+
data: value.get().data,
|
|
51
|
+
error: value.get().error,
|
|
52
|
+
isPending: value.get().isPending
|
|
53
|
+
}) : options;
|
|
54
|
+
return $fetch(path, {
|
|
55
|
+
...opts,
|
|
56
|
+
onSuccess: async (context) => {
|
|
57
|
+
value.set({
|
|
58
|
+
data: context.data,
|
|
59
|
+
error: null,
|
|
60
|
+
isPending: false,
|
|
61
|
+
isRefetching: false,
|
|
62
|
+
refetch: value.value.refetch
|
|
63
|
+
});
|
|
64
|
+
await opts?.onSuccess?.(context);
|
|
65
|
+
},
|
|
66
|
+
onError: async (context) => {
|
|
67
|
+
const { request } = context;
|
|
68
|
+
const retryAttempts = typeof request.retry === "number" ? request.retry : request.retry?.attempts;
|
|
69
|
+
const retryAttempt = request.retryAttempt ?? 0;
|
|
70
|
+
if (retryAttempts != null && retryAttempt < retryAttempts) return;
|
|
71
|
+
value.set({
|
|
72
|
+
error: context.error,
|
|
73
|
+
data: null,
|
|
74
|
+
isPending: false,
|
|
75
|
+
isRefetching: false,
|
|
76
|
+
refetch: value.value.refetch
|
|
77
|
+
});
|
|
78
|
+
await opts?.onError?.(context);
|
|
79
|
+
},
|
|
80
|
+
onRequest: async (context) => {
|
|
81
|
+
const currentValue = value.get();
|
|
82
|
+
value.set({
|
|
83
|
+
isPending: currentValue.data === null,
|
|
84
|
+
data: currentValue.data,
|
|
85
|
+
error: null,
|
|
86
|
+
isRefetching: true,
|
|
87
|
+
refetch: value.value.refetch
|
|
88
|
+
});
|
|
89
|
+
await opts?.onRequest?.(context);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
initializedAtom = Array.isArray(initializedAtom) ? initializedAtom : [initializedAtom];
|
|
94
|
+
let isMounted = false;
|
|
95
|
+
for (const initAtom of initializedAtom) initAtom.subscribe(() => {
|
|
96
|
+
if (isServer) return;
|
|
97
|
+
if (isMounted) fn();
|
|
98
|
+
else onMount(value, () => {
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
fn();
|
|
101
|
+
}, 0);
|
|
102
|
+
isMounted = true;
|
|
103
|
+
return () => {
|
|
104
|
+
value.off();
|
|
105
|
+
initAtom.off();
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
return value;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/client/broadcast-channel.ts
|
|
114
|
+
const now$1 = () => Math.floor(Date.now() / 1e3);
|
|
115
|
+
function createBroadcastChannel(name = "faire-auth.message") {
|
|
116
|
+
return {
|
|
117
|
+
receive(onReceive) {
|
|
118
|
+
const handler = (event) => {
|
|
119
|
+
if (event.key !== name) return;
|
|
120
|
+
const message = JSON.parse(event.newValue ?? "{}");
|
|
121
|
+
if (message?.event !== "session" || !message?.data) return;
|
|
122
|
+
onReceive(message);
|
|
123
|
+
};
|
|
124
|
+
window.addEventListener("storage", handler);
|
|
125
|
+
return () => window.removeEventListener("storage", handler);
|
|
126
|
+
},
|
|
127
|
+
post(message) {
|
|
128
|
+
if (typeof window === "undefined") return;
|
|
129
|
+
try {
|
|
130
|
+
localStorage.setItem(name, JSON.stringify({
|
|
131
|
+
...message,
|
|
132
|
+
timestamp: now$1()
|
|
133
|
+
}));
|
|
134
|
+
} catch {}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/client/session-refresh.ts
|
|
141
|
+
const now = () => Math.floor(Date.now() / 1e3);
|
|
142
|
+
function createSessionRefreshManager(opts) {
|
|
143
|
+
const { sessionAtom, sessionSignal, options = {} } = opts;
|
|
144
|
+
const { refetchInterval = 0, refetchOnWindowFocus = true, refetchWhenOffline = false } = options?.sessionOptions || {};
|
|
145
|
+
const state = {
|
|
146
|
+
lastSync: 0,
|
|
147
|
+
cachedSession: void 0
|
|
148
|
+
};
|
|
149
|
+
let isOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
|
|
150
|
+
const broadcast = createBroadcastChannel();
|
|
151
|
+
const shouldRefetch = () => {
|
|
152
|
+
if (typeof window === "undefined") return false;
|
|
153
|
+
return refetchWhenOffline || isOnline;
|
|
154
|
+
};
|
|
155
|
+
const triggerRefetch = (event) => {
|
|
156
|
+
if (!shouldRefetch()) return;
|
|
157
|
+
if (event?.event === "storage") {
|
|
158
|
+
state.lastSync = now();
|
|
159
|
+
sessionSignal.set(!sessionSignal.get());
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const currentSession = sessionAtom.get();
|
|
163
|
+
if (currentSession?.data === null || currentSession?.data === void 0 || event?.event === "poll" || event?.event === "visibilitychange") {
|
|
164
|
+
state.lastSync = now();
|
|
165
|
+
sessionSignal.set(!sessionSignal.get());
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const broadcastSessionUpdate = (trigger) => {
|
|
169
|
+
broadcast.post({
|
|
170
|
+
event: "session",
|
|
171
|
+
data: { trigger },
|
|
172
|
+
clientId: Math.random().toString(36).substring(7)
|
|
173
|
+
});
|
|
174
|
+
};
|
|
175
|
+
const setupPolling = () => {
|
|
176
|
+
if (refetchInterval && refetchInterval > 0) state.pollInterval = setInterval(() => {
|
|
177
|
+
if (sessionAtom.get()?.data) triggerRefetch({ event: "poll" });
|
|
178
|
+
}, refetchInterval * 1e3);
|
|
179
|
+
};
|
|
180
|
+
const setupBroadcast = () => {
|
|
181
|
+
state.unsubscribeBroadcast = broadcast.receive(() => {
|
|
182
|
+
triggerRefetch({ event: "storage" });
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
const setupVisibilityChange = () => {
|
|
186
|
+
if (!refetchOnWindowFocus) return;
|
|
187
|
+
if (typeof document === "undefined") return;
|
|
188
|
+
const visibilityHandler = () => {
|
|
189
|
+
if (document.visibilityState === "visible") triggerRefetch({ event: "visibilitychange" });
|
|
190
|
+
};
|
|
191
|
+
document.addEventListener("visibilitychange", visibilityHandler, false);
|
|
192
|
+
state.unsubscribeVisibility = () => {
|
|
193
|
+
document.removeEventListener("visibilitychange", visibilityHandler, false);
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
const setupOnlineDetection = () => {
|
|
197
|
+
if (typeof window === "undefined") return;
|
|
198
|
+
const setOnline = () => {
|
|
199
|
+
isOnline = true;
|
|
200
|
+
triggerRefetch({ event: "visibilitychange" });
|
|
201
|
+
};
|
|
202
|
+
const setOffline = () => {
|
|
203
|
+
isOnline = false;
|
|
204
|
+
};
|
|
205
|
+
window.addEventListener("online", setOnline);
|
|
206
|
+
window.addEventListener("offline", setOffline);
|
|
207
|
+
state.unsubscribeOnline = () => window.removeEventListener("online", setOnline);
|
|
208
|
+
state.unsubscribeOffline = () => window.removeEventListener("offline", setOffline);
|
|
209
|
+
};
|
|
210
|
+
const init = () => {
|
|
211
|
+
if (typeof window === "undefined") return;
|
|
212
|
+
setupPolling();
|
|
213
|
+
setupBroadcast();
|
|
214
|
+
setupVisibilityChange();
|
|
215
|
+
setupOnlineDetection();
|
|
216
|
+
};
|
|
217
|
+
const cleanup = () => {
|
|
218
|
+
if (state.pollInterval) {
|
|
219
|
+
clearInterval(state.pollInterval);
|
|
220
|
+
state.pollInterval = void 0;
|
|
221
|
+
}
|
|
222
|
+
if (state.unsubscribeBroadcast) {
|
|
223
|
+
state.unsubscribeBroadcast();
|
|
224
|
+
state.unsubscribeBroadcast = void 0;
|
|
225
|
+
}
|
|
226
|
+
if (state.unsubscribeVisibility) {
|
|
227
|
+
state.unsubscribeVisibility();
|
|
228
|
+
state.unsubscribeVisibility = void 0;
|
|
229
|
+
}
|
|
230
|
+
if (state.unsubscribeOnline) {
|
|
231
|
+
state.unsubscribeOnline();
|
|
232
|
+
state.unsubscribeOnline = void 0;
|
|
233
|
+
}
|
|
234
|
+
if (state.unsubscribeOffline) {
|
|
235
|
+
state.unsubscribeOffline();
|
|
236
|
+
state.unsubscribeOffline = void 0;
|
|
237
|
+
}
|
|
238
|
+
state.lastSync = 0;
|
|
239
|
+
state.cachedSession = void 0;
|
|
240
|
+
};
|
|
241
|
+
return {
|
|
242
|
+
init,
|
|
243
|
+
cleanup,
|
|
244
|
+
triggerRefetch,
|
|
245
|
+
broadcastSessionUpdate
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/client/session-atom.ts
|
|
251
|
+
const getSessionAtom = ($fetch, options) => {
|
|
252
|
+
const $signal = atom(false);
|
|
253
|
+
const session = useAuthQuery($signal, "/get-session", $fetch, { method: "GET" });
|
|
254
|
+
if (typeof window !== "undefined") onMount(session, () => {
|
|
255
|
+
const refreshManager = createSessionRefreshManager({
|
|
256
|
+
sessionAtom: session,
|
|
257
|
+
sessionSignal: $signal,
|
|
258
|
+
$fetch,
|
|
259
|
+
options
|
|
260
|
+
});
|
|
261
|
+
refreshManager.init();
|
|
262
|
+
return () => {
|
|
263
|
+
refreshManager.cleanup();
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
session,
|
|
268
|
+
$sessionSignal: $signal
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/client/config.ts
|
|
274
|
+
const getClientConfig = (options) => {
|
|
275
|
+
const baseURL = () => getBaseURL(options?.baseURL, options?.basePath) ?? "/api/auth";
|
|
276
|
+
const plugins = options?.plugins ?? [];
|
|
277
|
+
const pluginsFetchPlugins = plugins.flatMap((plugin) => plugin.fetchPlugins).filter((pl) => pl !== void 0);
|
|
278
|
+
const { onSuccess: _, onError: __, onRequest: ___, onResponse: ____,...restOfFetchOptions } = options?.fetchOptions ?? {};
|
|
279
|
+
const $fetch = createFetch({
|
|
280
|
+
get baseURL() {
|
|
281
|
+
return baseURL();
|
|
282
|
+
},
|
|
283
|
+
..."credentials" in Request.prototype && { credentials: "include" },
|
|
284
|
+
method: "GET",
|
|
285
|
+
jsonParser(text) {
|
|
286
|
+
if (!text) return null;
|
|
287
|
+
return parseJSON(text, { strict: false });
|
|
288
|
+
},
|
|
289
|
+
customFetchImpl: fetch,
|
|
290
|
+
...restOfFetchOptions,
|
|
291
|
+
plugins: [
|
|
292
|
+
lifecycle(options),
|
|
293
|
+
...restOfFetchOptions.plugins ?? [],
|
|
294
|
+
...options?.disableDefaultFetchPlugins ? [] : [redirectPlugin],
|
|
295
|
+
...pluginsFetchPlugins
|
|
296
|
+
]
|
|
297
|
+
});
|
|
298
|
+
const sessionAtom = getSessionAtom($fetch);
|
|
299
|
+
const pluginsActions = {};
|
|
300
|
+
const pluginsAtoms = sessionAtom;
|
|
301
|
+
const pluginPathMethods = {
|
|
302
|
+
"/sign-out": "POST",
|
|
303
|
+
"/revoke-sessions": "POST",
|
|
304
|
+
"/revoke-other-sessions": "POST",
|
|
305
|
+
"/delete-user": "POST"
|
|
306
|
+
};
|
|
307
|
+
const atomListeners = [{
|
|
308
|
+
signal: "$sessionSignal",
|
|
309
|
+
matcher(path) {
|
|
310
|
+
return path === "/sign-out" || path === "/update-user" || path.startsWith("/sign-in") || path.startsWith("/sign-up") || path === "/delete-user" || path === "/verify-email";
|
|
311
|
+
}
|
|
312
|
+
}];
|
|
313
|
+
for (const plugin of plugins) {
|
|
314
|
+
if (plugin.getAtoms) Object.assign(pluginsAtoms, plugin.getAtoms?.($fetch));
|
|
315
|
+
if (plugin.pathMethods) Object.assign(pluginPathMethods, plugin.pathMethods);
|
|
316
|
+
if (plugin.atomListeners) atomListeners.push(...plugin.atomListeners);
|
|
317
|
+
}
|
|
318
|
+
const $store = {
|
|
319
|
+
notify: (signal) => {
|
|
320
|
+
if (signal) pluginsAtoms[signal].set(!pluginsAtoms[signal].get());
|
|
321
|
+
},
|
|
322
|
+
listen: (signal, listener) => {
|
|
323
|
+
pluginsAtoms[signal].subscribe(listener);
|
|
324
|
+
},
|
|
325
|
+
atoms: pluginsAtoms
|
|
326
|
+
};
|
|
327
|
+
for (const plugin of plugins) if (plugin.getActions) Object.assign(pluginsActions, plugin.getActions?.($fetch, $store, options));
|
|
328
|
+
return {
|
|
329
|
+
get baseURL() {
|
|
330
|
+
return baseURL();
|
|
331
|
+
},
|
|
332
|
+
pluginsActions,
|
|
333
|
+
pluginsAtoms,
|
|
334
|
+
pluginPathMethods,
|
|
335
|
+
atomListeners,
|
|
336
|
+
$fetch,
|
|
337
|
+
$store
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/client/hono.ts
|
|
343
|
+
const isPromise = (value) => value != null && typeof value.then === "function";
|
|
344
|
+
const isHonoRequestLike = (value) => value != null && typeof value === "object" && "raw" in value && value.raw instanceof Request && "header" in value && typeof value.header === "function" && "query" in value && typeof value.query === "function" && "param" in value && typeof value.param === "function" && "json" in value && typeof value.json === "function" && "path" in value && typeof value.path === "string";
|
|
345
|
+
const isInputOpts = (value) => value == null || typeof value === "object" && Object.keys(value).every((k) => k !== "fetchOptions" && k !== "fetch" && k !== "websocket" && k !== "init" && k !== "headers");
|
|
346
|
+
const returnFromRoutesIfFn = (fullPath, routes) => {
|
|
347
|
+
let current = routes;
|
|
348
|
+
for (const segment of fullPath) if (current && typeof current === "object" && segment in current) current = current[segment];
|
|
349
|
+
else {
|
|
350
|
+
current = void 0;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
if (typeof current === "function" || fullPath[0] === "$fetch" || fullPath[0] === "$store") return current;
|
|
354
|
+
};
|
|
355
|
+
const createProxy = (callback, path, routes) => {
|
|
356
|
+
return new Proxy(() => {}, {
|
|
357
|
+
get(_obj, key) {
|
|
358
|
+
if (typeof key !== "string" || key === "then" || key === "catch" || key === "finally") return void 0;
|
|
359
|
+
const fullPath = [...path, key];
|
|
360
|
+
const maybeFn = returnFromRoutesIfFn(fullPath, routes);
|
|
361
|
+
if (maybeFn) return maybeFn;
|
|
362
|
+
return createProxy(callback, fullPath, routes);
|
|
363
|
+
},
|
|
364
|
+
apply(_1, _2, args) {
|
|
365
|
+
return callback({
|
|
366
|
+
path,
|
|
367
|
+
args
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
};
|
|
372
|
+
var ClientRequestImpl = class {
|
|
373
|
+
url;
|
|
374
|
+
path;
|
|
375
|
+
method;
|
|
376
|
+
queryParams = void 0;
|
|
377
|
+
pathParams = {};
|
|
378
|
+
rBody;
|
|
379
|
+
cType = void 0;
|
|
380
|
+
$fetch;
|
|
381
|
+
atoms;
|
|
382
|
+
atomListeners;
|
|
383
|
+
constructor(url, path, method, $fetch, atoms, atomListeners) {
|
|
384
|
+
this.url = url;
|
|
385
|
+
this.path = path;
|
|
386
|
+
this.method = method;
|
|
387
|
+
this.$fetch = $fetch;
|
|
388
|
+
if (atoms) this.atoms = atoms;
|
|
389
|
+
if (atomListeners) this.atomListeners = atomListeners;
|
|
390
|
+
}
|
|
391
|
+
fetch = async (args, opt) => {
|
|
392
|
+
if (isHonoRequestLike(opt.fetch)) return this.$fetch(opt.fetch.url, opt.fetch.raw);
|
|
393
|
+
if (args) {
|
|
394
|
+
if (args.query) this.queryParams = buildSearchParams(args.query);
|
|
395
|
+
if (args.form) {
|
|
396
|
+
const form = new FormData();
|
|
397
|
+
for (const [k, v] of Object.entries(args.form)) if (Array.isArray(v)) for (const v2 of v) form.append(k, v2);
|
|
398
|
+
else form.append(k, v);
|
|
399
|
+
this.rBody = form;
|
|
400
|
+
}
|
|
401
|
+
if (args.json) {
|
|
402
|
+
this.rBody = JSON.stringify(args.json);
|
|
403
|
+
this.cType = "application/json";
|
|
404
|
+
}
|
|
405
|
+
if (args.param) this.pathParams = args.param;
|
|
406
|
+
}
|
|
407
|
+
let methodUpperCase = this.method.toUpperCase();
|
|
408
|
+
let headers = normaliseHeaders(opt.headers);
|
|
409
|
+
if (isPromise(headers)) headers = await headers;
|
|
410
|
+
if (args?.header) Object.entries(args.header).forEach(([k, v]) => headers.set(k, v));
|
|
411
|
+
if (args?.cookie) {
|
|
412
|
+
const cookies = [];
|
|
413
|
+
for (const [key, value] of Object.entries(args.cookie)) cookies.push(serialize(key, value, { path: "/" }));
|
|
414
|
+
headers.set("Cookie", cookies.join(","));
|
|
415
|
+
}
|
|
416
|
+
if (this.cType) headers.set("Content-Type", this.cType);
|
|
417
|
+
let url = this.url;
|
|
418
|
+
url = removeIndexString(url);
|
|
419
|
+
url = replaceUrlParam(url, this.pathParams);
|
|
420
|
+
if (this.queryParams && this.queryParams.size > 0) url = url + "?" + this.queryParams.toString();
|
|
421
|
+
methodUpperCase = this.method.toUpperCase();
|
|
422
|
+
const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
|
|
423
|
+
return this.$fetch(url, {
|
|
424
|
+
customFetchImpl: opt.fetch,
|
|
425
|
+
...opt.fetchOptions,
|
|
426
|
+
...setBody === true && { body: this.rBody },
|
|
427
|
+
method: methodUpperCase,
|
|
428
|
+
headers,
|
|
429
|
+
...opt.init,
|
|
430
|
+
onSuccess: async (context) => {
|
|
431
|
+
if (opt.fetchOptions?.onSuccess) await opt.fetchOptions.onSuccess(context);
|
|
432
|
+
/**
|
|
433
|
+
* We trigger listeners
|
|
434
|
+
*/
|
|
435
|
+
const matches = this.atomListeners?.filter((s) => s.matcher(this.path));
|
|
436
|
+
if (!matches?.length) return;
|
|
437
|
+
for (const match of matches) {
|
|
438
|
+
const signal = this.atoms?.[match.signal];
|
|
439
|
+
if (!signal) return;
|
|
440
|
+
/**
|
|
441
|
+
* To avoid race conditions we set the signal in a setTimeout
|
|
442
|
+
*/
|
|
443
|
+
const val = signal.get();
|
|
444
|
+
setTimeout(() => signal.set(!val), 10);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
};
|
|
449
|
+
};
|
|
450
|
+
const createHonoClient = (options, routes, $fetch, atoms, atomListeners) => createProxy(function proxyCallback(opts) {
|
|
451
|
+
const parts = opts.path.map((segment) => segment.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`));
|
|
452
|
+
const lastParts = parts.slice(-3).reverse();
|
|
453
|
+
if (lastParts[0] === "toString") {
|
|
454
|
+
if (lastParts[1] === "name") return lastParts[2] ?? "";
|
|
455
|
+
return proxyCallback.toString();
|
|
456
|
+
}
|
|
457
|
+
if (lastParts[0] === "valueOf") {
|
|
458
|
+
if (lastParts[1] === "name") return lastParts[2] ?? "";
|
|
459
|
+
return proxyCallback;
|
|
460
|
+
}
|
|
461
|
+
let method = "";
|
|
462
|
+
if (/^\$/.test(lastParts[0])) {
|
|
463
|
+
const last = parts.pop();
|
|
464
|
+
if (last) method = last.replace(/^\$/, "");
|
|
465
|
+
}
|
|
466
|
+
const { input, clientOpts } = isInputOpts(opts.args[0]) ? {
|
|
467
|
+
input: opts.args[0] ?? {},
|
|
468
|
+
clientOpts: opts.args[1] ?? {}
|
|
469
|
+
} : {
|
|
470
|
+
input: {},
|
|
471
|
+
clientOpts: opts.args[0] ?? {}
|
|
472
|
+
};
|
|
473
|
+
const path = `/${parts.join("/")}`;
|
|
474
|
+
const url = mergePath(options.baseURL, path);
|
|
475
|
+
clientOpts.headers = mergeHeaders(options?.createFetchOptions?.headers, clientOpts.fetchOptions?.headers, clientOpts.headers);
|
|
476
|
+
if (method === "url" || method === "path") {
|
|
477
|
+
let result = url;
|
|
478
|
+
if (input.param) result = replaceUrlParam(url, input.param);
|
|
479
|
+
if (input.query) {
|
|
480
|
+
const sp = buildSearchParams(input.query);
|
|
481
|
+
if (sp.size > 0) result += "?" + sp.toString();
|
|
482
|
+
}
|
|
483
|
+
result = removeIndexString(result);
|
|
484
|
+
if (method === "url") return new URL(result);
|
|
485
|
+
const base = (options.baseURL ?? "").replace(/\/+$/, "");
|
|
486
|
+
return result.slice(base.length).replace(/^\/?/, "/");
|
|
487
|
+
}
|
|
488
|
+
if (method === "ws") {
|
|
489
|
+
const webSocketUrl = replaceUrlProtocol(input.param ? replaceUrlParam(url, input.param) : url, "ws");
|
|
490
|
+
const targetUrl = new URL(webSocketUrl);
|
|
491
|
+
const queryParams = input.query;
|
|
492
|
+
if (queryParams) Object.entries(queryParams).forEach(([key, value]) => {
|
|
493
|
+
if (Array.isArray(value)) value.forEach((item) => targetUrl.searchParams.append(key, item));
|
|
494
|
+
else targetUrl.searchParams.set(key, value);
|
|
495
|
+
});
|
|
496
|
+
const establishWebSocket = (...args) => {
|
|
497
|
+
if (options?.webSocket !== void 0 && typeof options.webSocket === "function") return options.webSocket(...args);
|
|
498
|
+
return new WebSocket(...args);
|
|
499
|
+
};
|
|
500
|
+
return establishWebSocket(targetUrl.toString());
|
|
501
|
+
}
|
|
502
|
+
const req = new ClientRequestImpl(url, path, method, $fetch, atoms, atomListeners);
|
|
503
|
+
clientOpts.fetchOptions = defu(clientOpts.fetchOptions, options.createFetchOptions);
|
|
504
|
+
return req.fetch(input, clientOpts);
|
|
505
|
+
}, [], routes);
|
|
506
|
+
|
|
507
|
+
//#endregion
|
|
508
|
+
export { getClientConfig as n, useAuthQuery as r, createHonoClient as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ENV } from "@faire-auth/core/env";
|
|
2
|
+
import { Exec, ExecOpts, Fn, MinRouteConfig } from "@faire-auth/core/types";
|
|
3
|
+
import { Context } from "hono";
|
|
4
|
+
|
|
5
|
+
//#region src/types/hono.d.ts
|
|
6
|
+
type ContextVars<E extends object = object> = {
|
|
7
|
+
Bindings: typeof ENV;
|
|
8
|
+
Variables: E;
|
|
9
|
+
};
|
|
10
|
+
type Execute<C extends MinRouteConfig> = Exec<C, ContextVars<any>>;
|
|
11
|
+
type ToExecFull<T extends Execute<any>> = T extends Fn<infer Par extends any[], infer Ret> ? {
|
|
12
|
+
<AsResponse extends boolean = false, ReturnHeaders extends boolean = false>(...args: Par extends [infer Input, infer Ctx] ? Ctx extends Context<any> ? [Input, (Ctx | ExecOpts<AsResponse, ReturnHeaders>)?] : Par : Par extends [infer Ctx] ? [(Ctx | ExecOpts<AsResponse, ReturnHeaders>)?] : Par): Ret extends Promise<infer R> ? Promise<AsResponse extends true ? Response : ReturnHeaders extends true ? {
|
|
13
|
+
headers: Headers;
|
|
14
|
+
response: R;
|
|
15
|
+
} : R> : never;
|
|
16
|
+
} : never;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Execute as n, ToExecFull as r, ContextVars as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ENV } from "@faire-auth/core/env";
|
|
2
|
+
import { Context } from "hono";
|
|
3
|
+
import { Exec, ExecOpts, Fn, MinRouteConfig } from "@faire-auth/core/types";
|
|
4
|
+
|
|
5
|
+
//#region src/types/hono.d.ts
|
|
6
|
+
type ContextVars<E extends object = object> = {
|
|
7
|
+
Bindings: typeof ENV;
|
|
8
|
+
Variables: E;
|
|
9
|
+
};
|
|
10
|
+
type Execute<C extends MinRouteConfig> = Exec<C, ContextVars<any>>;
|
|
11
|
+
type ToExecFull<T extends Execute<any>> = T extends Fn<infer Par extends any[], infer Ret> ? {
|
|
12
|
+
<AsResponse extends boolean = false, ReturnHeaders extends boolean = false>(...args: Par extends [infer Input, infer Ctx] ? Ctx extends Context<any> ? [Input, (Ctx | ExecOpts<AsResponse, ReturnHeaders>)?] : Par : Par extends [infer Ctx] ? [(Ctx | ExecOpts<AsResponse, ReturnHeaders>)?] : Par): Ret extends Promise<infer R> ? Promise<AsResponse extends true ? Response : ReturnHeaders extends true ? {
|
|
13
|
+
headers: Headers;
|
|
14
|
+
response: R;
|
|
15
|
+
} : R> : never;
|
|
16
|
+
} : never;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Execute as n, ToExecFull as r, ContextVars as t };
|