@deepkey/sdk 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/dist/index.cjs ADDED
@@ -0,0 +1,430 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Auth: () => Auth,
24
+ AuthError: () => AuthError,
25
+ DEEPKEY_API_URL: () => DEEPKEY_API_URL,
26
+ createAuthClient: () => createAuthClient
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/constants.ts
31
+ var DEEPKEY_API_URL = "https://deepkey.dev/api";
32
+ var resolveBaseUrl = (url) => {
33
+ const candidate = typeof url === "string" ? url.trim() : "";
34
+ return (candidate || DEEPKEY_API_URL).replace(/\/+$/, "");
35
+ };
36
+
37
+ // src/types.ts
38
+ var AuthError = class extends Error {
39
+ constructor(message, status, code) {
40
+ super(message);
41
+ this.name = "AuthError";
42
+ this.status = status;
43
+ this.code = code;
44
+ }
45
+ };
46
+
47
+ // src/fetch.ts
48
+ var request = async (options) => {
49
+ const fetchImpl = options.fetchImpl ?? fetch;
50
+ try {
51
+ const headers = { apikey: options.apikey };
52
+ if (options.body !== void 0) headers["Content-Type"] = "application/json";
53
+ if (options.accessToken) headers.Authorization = `Bearer ${options.accessToken}`;
54
+ const response = await fetchImpl(`${options.baseUrl}${options.path}`, {
55
+ method: options.method,
56
+ headers,
57
+ body: options.body !== void 0 ? JSON.stringify(options.body) : void 0
58
+ });
59
+ if (response.status === 204) return { data: {}, error: null };
60
+ let payload;
61
+ try {
62
+ payload = await response.json();
63
+ } catch {
64
+ payload = null;
65
+ }
66
+ if (!response.ok) {
67
+ const errorBody = payload?.error;
68
+ return {
69
+ data: null,
70
+ error: new AuthError(
71
+ errorBody?.message ?? `Request failed with status ${response.status}`,
72
+ response.status,
73
+ errorBody?.code
74
+ )
75
+ };
76
+ }
77
+ return { data: payload, error: null };
78
+ } catch (err) {
79
+ const message = err instanceof Error ? err.message : "Network request failed";
80
+ return { data: null, error: new AuthError(message, 0, "network_error") };
81
+ }
82
+ };
83
+
84
+ // src/storage.ts
85
+ var MemoryStorage = class {
86
+ constructor() {
87
+ this.store = /* @__PURE__ */ new Map();
88
+ }
89
+ getItem(key) {
90
+ return this.store.get(key) ?? null;
91
+ }
92
+ setItem(key, value) {
93
+ this.store.set(key, value);
94
+ }
95
+ removeItem(key) {
96
+ this.store.delete(key);
97
+ }
98
+ };
99
+ var defaultStorage = () => {
100
+ try {
101
+ if (typeof window !== "undefined" && window.localStorage) {
102
+ const probe = "__bt_auth_probe__";
103
+ window.localStorage.setItem(probe, "1");
104
+ window.localStorage.removeItem(probe);
105
+ return window.localStorage;
106
+ }
107
+ } catch {
108
+ }
109
+ return new MemoryStorage();
110
+ };
111
+ var deriveStorageKey = (publishableKey) => {
112
+ const match = publishableKey?.match(/^bt_pub_([a-z0-9-]+)_[A-Za-z0-9_-]+$/);
113
+ return match ? `bt-${match[1]}-auth-token` : "bt-auth-token";
114
+ };
115
+
116
+ // src/url.ts
117
+ var parseFragment = (hash) => {
118
+ if (!hash || hash.length < 2) return null;
119
+ const params = new URLSearchParams(hash.startsWith("#") ? hash.slice(1) : hash);
120
+ const error = params.get("error");
121
+ if (error) {
122
+ return {
123
+ authError: {
124
+ error,
125
+ error_code: params.get("error_code") ?? void 0,
126
+ error_description: params.get("error_description") ?? void 0
127
+ }
128
+ };
129
+ }
130
+ const accessToken = params.get("access_token");
131
+ const refreshToken = params.get("refresh_token");
132
+ if (!accessToken || !refreshToken) return null;
133
+ const expiresIn = Number(params.get("expires_in") ?? 3600);
134
+ const expiresAt = Number(params.get("expires_at") ?? Math.floor(Date.now() / 1e3) + expiresIn);
135
+ return {
136
+ tokens: {
137
+ access_token: accessToken,
138
+ refresh_token: refreshToken,
139
+ expires_in: expiresIn,
140
+ expires_at: expiresAt,
141
+ token_type: "bearer",
142
+ type: params.get("type") ?? void 0
143
+ }
144
+ };
145
+ };
146
+ var cleanFragmentFromUrl = () => {
147
+ if (typeof window === "undefined" || typeof history === "undefined") return;
148
+ history.replaceState(null, "", window.location.pathname + window.location.search);
149
+ };
150
+
151
+ // src/client.ts
152
+ var REFRESH_TICK_MS = 3e4;
153
+ var EXPIRY_MARGIN_SECONDS = 90;
154
+ var Auth = class {
155
+ constructor(publishableKey, options = {}) {
156
+ this.session = null;
157
+ this.listeners = /* @__PURE__ */ new Map();
158
+ this.listenerSeq = 0;
159
+ this.initializePromise = null;
160
+ this.refreshPromise = null;
161
+ this.refreshTimer = null;
162
+ this.baseUrl = resolveBaseUrl(options.__internalBaseUrl);
163
+ this.apikey = publishableKey ?? "";
164
+ this.persistSession = options.persistSession ?? true;
165
+ this.autoRefreshToken = options.autoRefreshToken ?? true;
166
+ this.detectSessionInUrl = options.detectSessionInUrl ?? true;
167
+ this.storage = options.storage ?? defaultStorage();
168
+ this.storageKey = options.storageKey ?? deriveStorageKey(publishableKey);
169
+ this.fetchImpl = options.fetch;
170
+ this.setupCrossTabSync();
171
+ }
172
+ // ---- public API (supabase-js compatible) ----
173
+ async signInWithOtp(credentials) {
174
+ const { error } = await this.request("POST", "/auth/v1/otp", {
175
+ email: credentials.email,
176
+ create_user: credentials.options?.shouldCreateUser,
177
+ redirect_to: credentials.options?.emailRedirectTo
178
+ });
179
+ return { data: { user: null, session: null }, error };
180
+ }
181
+ async verifyOtp(params) {
182
+ const { data, error } = await this.request("POST", "/auth/v1/verify", {
183
+ type: "email",
184
+ email: params.email,
185
+ token: params.token
186
+ });
187
+ if (error || !data) return { data: { user: null, session: null }, error };
188
+ await this.saveSession(data);
189
+ this.emit("SIGNED_IN", data);
190
+ return { data: { user: data.user, session: data }, error: null };
191
+ }
192
+ async signInWithOAuth(credentials) {
193
+ const url = new URL(`${this.baseUrl}/auth/v1/authorize`);
194
+ url.searchParams.set("provider", credentials.provider);
195
+ url.searchParams.set("apikey", this.apikey);
196
+ if (credentials.options?.redirectTo) url.searchParams.set("redirect_to", credentials.options.redirectTo);
197
+ if (credentials.options?.scopes) url.searchParams.set("scopes", credentials.options.scopes);
198
+ for (const [key, value] of Object.entries(credentials.options?.queryParams ?? {})) {
199
+ url.searchParams.set(key, value);
200
+ }
201
+ if (!credentials.options?.skipBrowserRedirect && typeof window !== "undefined") {
202
+ window.location.assign(url.toString());
203
+ }
204
+ return { data: { provider: credentials.provider, url: url.toString() }, error: null };
205
+ }
206
+ onAuthStateChange(callback) {
207
+ const id = `listener-${++this.listenerSeq}`;
208
+ this.listeners.set(id, callback);
209
+ this.initialize().then(() => {
210
+ if (this.listeners.has(id)) callback("INITIAL_SESSION", this.session);
211
+ });
212
+ return {
213
+ data: {
214
+ subscription: {
215
+ id,
216
+ unsubscribe: () => {
217
+ this.listeners.delete(id);
218
+ }
219
+ }
220
+ }
221
+ };
222
+ }
223
+ async signOut() {
224
+ await this.initialize();
225
+ const session = this.session;
226
+ if (session) {
227
+ await this.request("POST", "/auth/v1/logout", {}, session.access_token);
228
+ }
229
+ this.clearSession();
230
+ this.emit("SIGNED_OUT", null);
231
+ return { error: null };
232
+ }
233
+ async getSession() {
234
+ await this.initialize();
235
+ if (this.session && this.isExpired(this.session) && this.autoRefreshToken) {
236
+ const { error } = await this.refreshWithLock();
237
+ if (error && error.code !== "network_error") {
238
+ return { data: { session: null }, error: null };
239
+ }
240
+ }
241
+ return { data: { session: this.session }, error: null };
242
+ }
243
+ async getUser(jwt) {
244
+ let token = jwt;
245
+ if (!token) {
246
+ const {
247
+ data: { session }
248
+ } = await this.getSession();
249
+ token = session?.access_token;
250
+ }
251
+ if (!token) {
252
+ return { data: { user: null }, error: new AuthError("Auth session missing!", 400, "session_missing") };
253
+ }
254
+ const { data, error } = await this.request("GET", "/auth/v1/user", void 0, token);
255
+ return { data: { user: data }, error };
256
+ }
257
+ async refreshSession(currentSession) {
258
+ await this.initialize();
259
+ const refreshToken = currentSession?.refresh_token ?? this.session?.refresh_token;
260
+ if (!refreshToken) {
261
+ return {
262
+ data: { session: null, user: null },
263
+ error: new AuthError("Auth session missing!", 400, "session_missing")
264
+ };
265
+ }
266
+ return this.refreshWithLock(refreshToken);
267
+ }
268
+ // ---- internals ----
269
+ async request(method, path, body, accessToken) {
270
+ return request({
271
+ method,
272
+ path,
273
+ body,
274
+ accessToken,
275
+ apikey: this.apikey,
276
+ baseUrl: this.baseUrl,
277
+ fetchImpl: this.fetchImpl
278
+ });
279
+ }
280
+ initialize() {
281
+ this.initializePromise ?? (this.initializePromise = this.doInitialize());
282
+ return this.initializePromise;
283
+ }
284
+ async doInitialize() {
285
+ if (this.detectSessionInUrl && typeof window !== "undefined") {
286
+ const parsed = parseFragment(window.location.hash);
287
+ if (parsed) {
288
+ cleanFragmentFromUrl();
289
+ if ("authError" in parsed) {
290
+ console.warn(
291
+ `[deepkey] Auth redirect returned an error: ${parsed.authError.error_code ?? parsed.authError.error}`,
292
+ parsed.authError.error_description ?? ""
293
+ );
294
+ } else {
295
+ const { data: user } = await this.request("GET", "/auth/v1/user", void 0, parsed.tokens.access_token);
296
+ if (user) {
297
+ const session = { ...parsed.tokens, token_type: "bearer", user };
298
+ await this.saveSession(session);
299
+ this.emit("SIGNED_IN", session);
300
+ return;
301
+ }
302
+ }
303
+ }
304
+ }
305
+ const stored = this.loadStoredSession();
306
+ if (!stored) return;
307
+ if (this.isExpired(stored)) {
308
+ if (!this.autoRefreshToken) return;
309
+ this.session = stored;
310
+ const { error } = await this.refreshWithLock();
311
+ if (error && error.code !== "network_error") this.clearSession();
312
+ return;
313
+ }
314
+ this.session = stored;
315
+ this.startRefreshTimer();
316
+ }
317
+ isExpired(session) {
318
+ return session.expires_at <= Math.floor(Date.now() / 1e3) + EXPIRY_MARGIN_SECONDS;
319
+ }
320
+ async refreshWithLock(refreshToken) {
321
+ this.refreshPromise ?? (this.refreshPromise = this.doRefresh(refreshToken).finally(() => {
322
+ this.refreshPromise = null;
323
+ }));
324
+ return this.refreshPromise;
325
+ }
326
+ async doRefresh(refreshToken) {
327
+ const token = refreshToken ?? this.session?.refresh_token;
328
+ if (!token) {
329
+ return {
330
+ data: { session: null, user: null },
331
+ error: new AuthError("Auth session missing!", 400, "session_missing")
332
+ };
333
+ }
334
+ const { data, error } = await this.request("POST", "/auth/v1/token?grant_type=refresh_token", {
335
+ refresh_token: token
336
+ });
337
+ if (error) {
338
+ if (error.code !== "network_error") {
339
+ this.clearSession();
340
+ this.emit("SIGNED_OUT", null);
341
+ }
342
+ return { data: { session: null, user: null }, error };
343
+ }
344
+ if (data) {
345
+ await this.saveSession(data);
346
+ this.emit("TOKEN_REFRESHED", data);
347
+ return { data: { session: data, user: data.user }, error: null };
348
+ }
349
+ return { data: { session: null, user: null }, error: new AuthError("Empty refresh response") };
350
+ }
351
+ async saveSession(session) {
352
+ this.session = session;
353
+ if (this.persistSession) {
354
+ try {
355
+ this.storage.setItem(this.storageKey, JSON.stringify(session));
356
+ } catch {
357
+ }
358
+ }
359
+ this.startRefreshTimer();
360
+ }
361
+ clearSession() {
362
+ this.session = null;
363
+ try {
364
+ this.storage.removeItem(this.storageKey);
365
+ } catch {
366
+ }
367
+ this.stopRefreshTimer();
368
+ }
369
+ loadStoredSession() {
370
+ if (!this.persistSession) return null;
371
+ try {
372
+ const raw = this.storage.getItem(this.storageKey);
373
+ if (!raw) return null;
374
+ const parsed = JSON.parse(raw);
375
+ if (!parsed.access_token || !parsed.refresh_token) return null;
376
+ return parsed;
377
+ } catch {
378
+ return null;
379
+ }
380
+ }
381
+ startRefreshTimer() {
382
+ if (!this.autoRefreshToken || this.refreshTimer || typeof setInterval === "undefined") return;
383
+ this.refreshTimer = setInterval(() => {
384
+ if (this.session && this.isExpired(this.session)) void this.refreshWithLock();
385
+ }, REFRESH_TICK_MS);
386
+ const timer = this.refreshTimer;
387
+ if (typeof timer === "object" && typeof timer.unref === "function") timer.unref();
388
+ }
389
+ stopRefreshTimer() {
390
+ if (this.refreshTimer) {
391
+ clearInterval(this.refreshTimer);
392
+ this.refreshTimer = null;
393
+ }
394
+ }
395
+ setupCrossTabSync() {
396
+ if (typeof window === "undefined" || !this.persistSession) return;
397
+ window.addEventListener("storage", (event) => {
398
+ if (event.key !== this.storageKey) return;
399
+ if (!event.newValue) {
400
+ if (this.session) {
401
+ this.session = null;
402
+ this.stopRefreshTimer();
403
+ this.emit("SIGNED_OUT", null);
404
+ }
405
+ return;
406
+ }
407
+ try {
408
+ const next = JSON.parse(event.newValue);
409
+ const changed = next.access_token !== this.session?.access_token;
410
+ this.session = next;
411
+ this.startRefreshTimer();
412
+ if (changed) this.emit("TOKEN_REFRESHED", next);
413
+ } catch {
414
+ }
415
+ });
416
+ }
417
+ emit(event, session) {
418
+ for (const listener of this.listeners.values()) {
419
+ try {
420
+ listener(event, session);
421
+ } catch (err) {
422
+ console.error("[deepkey] onAuthStateChange listener threw", err);
423
+ }
424
+ }
425
+ }
426
+ };
427
+ var createAuthClient = (publishableKey, options) => {
428
+ return { auth: new Auth(publishableKey, options) };
429
+ };
430
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/types.ts","../src/fetch.ts","../src/storage.ts","../src/url.ts","../src/client.ts"],"sourcesContent":["export { createAuthClient, Auth, type AuthClient } from './client'\nexport { DEEPKEY_API_URL } from './constants'\nexport {\n AuthError,\n type AuthChangeEvent,\n type AuthClientOptions,\n type AuthResponse,\n type ServerClientOptions,\n type Session,\n type SignInWithOAuthCredentials,\n type SignInWithOtpCredentials,\n type StorageAdapter,\n type Subscription,\n type User,\n type UserIdentity,\n type VerifyOtpParams,\n} from './types'\n","// The hosted DeepKey API. Every client talks to this origin; only DeepKey's own\n// console and test suites replace it through the internal override.\nexport const DEEPKEY_API_URL = 'https://deepkey.dev/api'\n\n// Resolves the base URL used for every request. An absent or blank internal\n// override keeps the hosted API; a provided value has any trailing slash removed\n// so path joins stay predictable.\nexport const resolveBaseUrl = (url?: string | null): string => {\n const candidate = typeof url === 'string' ? url.trim() : ''\n return (candidate || DEEPKEY_API_URL).replace(/\\/+$/, '')\n}\n","export interface UserIdentity {\n identity_id: string\n id: string\n user_id: string\n provider: string\n identity_data: Record<string, unknown>\n last_sign_in_at: string | null\n created_at: string\n updated_at: string\n}\n\nexport interface User {\n id: string\n aud: string\n role: string\n email: string | null\n email_confirmed_at: string | null\n app_metadata: { provider?: string | null; providers?: string[]; [key: string]: unknown }\n user_metadata: {\n name?: string\n full_name?: string\n avatar_url?: string\n picture?: string\n email?: string\n [key: string]: unknown\n }\n identities?: UserIdentity[]\n created_at: string\n updated_at?: string\n last_sign_in_at?: string | null\n}\n\nexport interface Session {\n access_token: string\n refresh_token: string\n token_type: 'bearer'\n expires_in: number\n expires_at: number\n user: User\n}\n\nexport class AuthError extends Error {\n status?: number\n code?: string\n\n constructor(message: string, status?: number, code?: string) {\n super(message)\n this.name = 'AuthError'\n this.status = status\n this.code = code\n }\n}\n\nexport type AuthChangeEvent = 'INITIAL_SESSION' | 'SIGNED_IN' | 'SIGNED_OUT' | 'TOKEN_REFRESHED'\n\nexport interface Subscription {\n id: string\n unsubscribe: () => void\n}\n\nexport interface StorageAdapter {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n removeItem(key: string): void\n}\n\nexport interface AuthClientOptions {\n /**\n * @internal Replaces the hosted DeepKey API origin. Used only by DeepKey's own\n * console and test suites; not supported for consumers and stripped from the\n * published type declarations.\n */\n __internalBaseUrl?: string\n storageKey?: string\n autoRefreshToken?: boolean\n detectSessionInUrl?: boolean\n persistSession?: boolean\n storage?: StorageAdapter\n fetch?: typeof fetch\n}\n\nexport interface ServerClientOptions {\n /**\n * @internal Replaces the hosted DeepKey API origin. Used only by DeepKey's own\n * console and test suites; not supported for consumers and stripped from the\n * published type declarations.\n */\n __internalBaseUrl?: string\n fetch?: typeof fetch\n}\n\nexport interface SignInWithOtpCredentials {\n email: string\n options?: {\n emailRedirectTo?: string\n shouldCreateUser?: boolean\n data?: Record<string, unknown>\n }\n}\n\nexport interface VerifyOtpParams {\n email: string\n token: string\n type: 'email' | 'magiclink'\n}\n\nexport interface SignInWithOAuthCredentials {\n provider: string\n options?: {\n redirectTo?: string\n scopes?: string\n queryParams?: Record<string, string>\n skipBrowserRedirect?: boolean\n }\n}\n\nexport interface AuthResponse<T> {\n data: T\n error: AuthError | null\n}\n","import { AuthError } from './types'\n\nexport interface RequestOptions {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE'\n path: string\n apikey: string\n baseUrl: string\n accessToken?: string\n body?: unknown\n fetchImpl?: typeof fetch\n}\n\nexport interface RequestResult<T> {\n data: T | null\n error: AuthError | null\n}\n\n// All service errors are shaped { error: { code, message } }.\nexport const request = async <T>(options: RequestOptions): Promise<RequestResult<T>> => {\n const fetchImpl = options.fetchImpl ?? fetch\n try {\n const headers: Record<string, string> = { apikey: options.apikey }\n if (options.body !== undefined) headers['Content-Type'] = 'application/json'\n if (options.accessToken) headers.Authorization = `Bearer ${options.accessToken}`\n\n const response = await fetchImpl(`${options.baseUrl}${options.path}`, {\n method: options.method,\n headers,\n body: options.body !== undefined ? JSON.stringify(options.body) : undefined,\n })\n\n if (response.status === 204) return { data: {} as T, error: null }\n\n let payload: unknown\n try {\n payload = await response.json()\n } catch {\n payload = null\n }\n\n if (!response.ok) {\n const errorBody = (payload as { error?: { code?: string; message?: string } } | null)?.error\n return {\n data: null,\n error: new AuthError(\n errorBody?.message ?? `Request failed with status ${response.status}`,\n response.status,\n errorBody?.code,\n ),\n }\n }\n\n return { data: payload as T, error: null }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Network request failed'\n return { data: null, error: new AuthError(message, 0, 'network_error') }\n }\n}\n","import type { StorageAdapter } from './types'\n\nclass MemoryStorage implements StorageAdapter {\n private store = new Map<string, string>()\n getItem(key: string) {\n return this.store.get(key) ?? null\n }\n setItem(key: string, value: string) {\n this.store.set(key, value)\n }\n removeItem(key: string) {\n this.store.delete(key)\n }\n}\n\n// localStorage when available, in-memory fallback (SSR, tests, restricted contexts).\nexport const defaultStorage = (): StorageAdapter => {\n try {\n if (typeof window !== 'undefined' && window.localStorage) {\n const probe = '__bt_auth_probe__'\n window.localStorage.setItem(probe, '1')\n window.localStorage.removeItem(probe)\n return window.localStorage\n }\n } catch {\n // fall through to memory storage\n }\n return new MemoryStorage()\n}\n\n// Publishable keys look like `bt_pub_<project-slug>_<random>`; the slug namespaces the\n// persisted session per project (mirrors supabase's `sb-<ref>-auth-token`).\nexport const deriveStorageKey = (publishableKey: string | undefined): string => {\n const match = publishableKey?.match(/^bt_pub_([a-z0-9-]+)_[A-Za-z0-9_-]+$/)\n return match ? `bt-${match[1]}-auth-token` : 'bt-auth-token'\n}\n","export interface FragmentTokens {\n access_token: string\n refresh_token: string\n expires_in: number\n expires_at: number\n token_type: 'bearer'\n type?: string\n}\n\nexport interface FragmentError {\n error: string\n error_code?: string\n error_description?: string\n}\n\nexport type ParsedFragment = { tokens: FragmentTokens } | { authError: FragmentError } | null\n\n// Parses the implicit-flow return fragment (`#access_token=...` or `#error=...`).\nexport const parseFragment = (hash: string): ParsedFragment => {\n if (!hash || hash.length < 2) return null\n const params = new URLSearchParams(hash.startsWith('#') ? hash.slice(1) : hash)\n\n const error = params.get('error')\n if (error) {\n return {\n authError: {\n error,\n error_code: params.get('error_code') ?? undefined,\n error_description: params.get('error_description') ?? undefined,\n },\n }\n }\n\n const accessToken = params.get('access_token')\n const refreshToken = params.get('refresh_token')\n if (!accessToken || !refreshToken) return null\n\n const expiresIn = Number(params.get('expires_in') ?? 3600)\n const expiresAt = Number(params.get('expires_at') ?? Math.floor(Date.now() / 1000) + expiresIn)\n\n return {\n tokens: {\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_in: expiresIn,\n expires_at: expiresAt,\n token_type: 'bearer',\n type: params.get('type') ?? undefined,\n },\n }\n}\n\n// Removes the auth fragment from the address bar (before any await, so tokens never\n// linger in history).\nexport const cleanFragmentFromUrl = () => {\n if (typeof window === 'undefined' || typeof history === 'undefined') return\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import { resolveBaseUrl } from './constants'\nimport { request } from './fetch'\nimport { defaultStorage, deriveStorageKey } from './storage'\nimport {\n AuthError,\n type AuthChangeEvent,\n type AuthClientOptions,\n type AuthResponse,\n type Session,\n type SignInWithOAuthCredentials,\n type SignInWithOtpCredentials,\n type StorageAdapter,\n type Subscription,\n type User,\n type VerifyOtpParams,\n} from './types'\nimport { cleanFragmentFromUrl, parseFragment } from './url'\n\nconst REFRESH_TICK_MS = 30_000\n// Refresh when the access token is within this margin of expiry.\nconst EXPIRY_MARGIN_SECONDS = 90\n\ntype Listener = (event: AuthChangeEvent, session: Session | null) => void\n\nexport class Auth {\n private baseUrl: string\n private apikey: string\n private storage: StorageAdapter\n private storageKey: string\n private persistSession: boolean\n private autoRefreshToken: boolean\n private detectSessionInUrl: boolean\n private fetchImpl?: typeof fetch\n\n private session: Session | null = null\n private listeners = new Map<string, Listener>()\n private listenerSeq = 0\n private initializePromise: Promise<void> | null = null\n private refreshPromise: Promise<AuthResponse<{ session: Session | null; user: User | null }>> | null = null\n private refreshTimer: ReturnType<typeof setInterval> | null = null\n\n constructor(publishableKey: string, options: AuthClientOptions = {}) {\n // Lazy by design: an empty key must not throw at construction time (CI builds\n // with empty envs import this module transitively). Failures surface on first call.\n // The hosted DeepKey API is the only supported origin. The internal override\n // exists for DeepKey's console and tests and is not part of the public contract.\n this.baseUrl = resolveBaseUrl(options.__internalBaseUrl)\n this.apikey = publishableKey ?? ''\n this.persistSession = options.persistSession ?? true\n this.autoRefreshToken = options.autoRefreshToken ?? true\n this.detectSessionInUrl = options.detectSessionInUrl ?? true\n this.storage = options.storage ?? defaultStorage()\n this.storageKey = options.storageKey ?? deriveStorageKey(publishableKey)\n this.fetchImpl = options.fetch\n\n this.setupCrossTabSync()\n }\n\n // ---- public API (supabase-js compatible) ----\n\n async signInWithOtp(credentials: SignInWithOtpCredentials): Promise<AuthResponse<{ user: null; session: null }>> {\n const { error } = await this.request<Record<string, never>>('POST', '/auth/v1/otp', {\n email: credentials.email,\n create_user: credentials.options?.shouldCreateUser,\n redirect_to: credentials.options?.emailRedirectTo,\n })\n return { data: { user: null, session: null }, error }\n }\n\n async verifyOtp(params: VerifyOtpParams): Promise<AuthResponse<{ user: User | null; session: Session | null }>> {\n const { data, error } = await this.request<Session>('POST', '/auth/v1/verify', {\n type: 'email',\n email: params.email,\n token: params.token,\n })\n if (error || !data) return { data: { user: null, session: null }, error }\n\n await this.saveSession(data)\n this.emit('SIGNED_IN', data)\n return { data: { user: data.user, session: data }, error: null }\n }\n\n async signInWithOAuth(\n credentials: SignInWithOAuthCredentials,\n ): Promise<AuthResponse<{ provider: string; url: string }>> {\n const url = new URL(`${this.baseUrl}/auth/v1/authorize`)\n url.searchParams.set('provider', credentials.provider)\n url.searchParams.set('apikey', this.apikey)\n if (credentials.options?.redirectTo) url.searchParams.set('redirect_to', credentials.options.redirectTo)\n if (credentials.options?.scopes) url.searchParams.set('scopes', credentials.options.scopes)\n for (const [key, value] of Object.entries(credentials.options?.queryParams ?? {})) {\n url.searchParams.set(key, value)\n }\n\n if (!credentials.options?.skipBrowserRedirect && typeof window !== 'undefined') {\n window.location.assign(url.toString())\n }\n return { data: { provider: credentials.provider, url: url.toString() }, error: null }\n }\n\n onAuthStateChange(callback: Listener): { data: { subscription: Subscription } } {\n const id = `listener-${++this.listenerSeq}`\n this.listeners.set(id, callback)\n\n // Every subscriber receives INITIAL_SESSION asynchronously once initialization\n // settles — the supabase-js contract that AuthProviders rely on to resolve loading.\n this.initialize().then(() => {\n if (this.listeners.has(id)) callback('INITIAL_SESSION', this.session)\n })\n\n return {\n data: {\n subscription: {\n id,\n unsubscribe: () => {\n this.listeners.delete(id)\n },\n },\n },\n }\n }\n\n async signOut(): Promise<{ error: AuthError | null }> {\n await this.initialize()\n const session = this.session\n if (session) {\n // Best-effort server-side revocation; local sign-out always succeeds.\n await this.request('POST', '/auth/v1/logout', {}, session.access_token)\n }\n this.clearSession()\n this.emit('SIGNED_OUT', null)\n return { error: null }\n }\n\n async getSession(): Promise<AuthResponse<{ session: Session | null }>> {\n await this.initialize()\n\n if (this.session && this.isExpired(this.session) && this.autoRefreshToken) {\n const { error } = await this.refreshWithLock()\n if (error && error.code !== 'network_error') {\n return { data: { session: null }, error: null }\n }\n }\n\n return { data: { session: this.session }, error: null }\n }\n\n async getUser(jwt?: string): Promise<AuthResponse<{ user: User | null }>> {\n let token = jwt\n if (!token) {\n const {\n data: { session },\n } = await this.getSession()\n token = session?.access_token\n }\n if (!token) {\n return { data: { user: null }, error: new AuthError('Auth session missing!', 400, 'session_missing') }\n }\n\n const { data, error } = await this.request<User>('GET', '/auth/v1/user', undefined, token)\n return { data: { user: data }, error }\n }\n\n async refreshSession(currentSession?: {\n refresh_token: string\n }): Promise<AuthResponse<{ session: Session | null; user: User | null }>> {\n await this.initialize()\n const refreshToken = currentSession?.refresh_token ?? this.session?.refresh_token\n if (!refreshToken) {\n return {\n data: { session: null, user: null },\n error: new AuthError('Auth session missing!', 400, 'session_missing'),\n }\n }\n return this.refreshWithLock(refreshToken)\n }\n\n // ---- internals ----\n\n private async request<T>(method: 'GET' | 'POST', path: string, body?: unknown, accessToken?: string) {\n return request<T>({\n method,\n path,\n body,\n accessToken,\n apikey: this.apikey,\n baseUrl: this.baseUrl,\n fetchImpl: this.fetchImpl,\n })\n }\n\n private initialize(): Promise<void> {\n this.initializePromise ??= this.doInitialize()\n return this.initializePromise\n }\n\n private async doInitialize(): Promise<void> {\n if (this.detectSessionInUrl && typeof window !== 'undefined') {\n const parsed = parseFragment(window.location.hash)\n if (parsed) {\n // Strip tokens from the address bar synchronously, before any await.\n cleanFragmentFromUrl()\n\n if ('authError' in parsed) {\n console.warn(\n `[deepkey] Auth redirect returned an error: ${parsed.authError.error_code ?? parsed.authError.error}`,\n parsed.authError.error_description ?? '',\n )\n } else {\n const { data: user } = await this.request<User>('GET', '/auth/v1/user', undefined, parsed.tokens.access_token)\n if (user) {\n const session: Session = { ...parsed.tokens, token_type: 'bearer', user }\n await this.saveSession(session)\n this.emit('SIGNED_IN', session)\n return\n }\n }\n }\n }\n\n const stored = this.loadStoredSession()\n if (!stored) return\n\n if (this.isExpired(stored)) {\n if (!this.autoRefreshToken) return\n this.session = stored\n const { error } = await this.refreshWithLock()\n if (error && error.code !== 'network_error') this.clearSession()\n return\n }\n\n this.session = stored\n this.startRefreshTimer()\n }\n\n private isExpired(session: Session): boolean {\n return session.expires_at <= Math.floor(Date.now() / 1000) + EXPIRY_MARGIN_SECONDS\n }\n\n private async refreshWithLock(\n refreshToken?: string,\n ): Promise<AuthResponse<{ session: Session | null; user: User | null }>> {\n this.refreshPromise ??= this.doRefresh(refreshToken).finally(() => {\n this.refreshPromise = null\n })\n return this.refreshPromise\n }\n\n private async doRefresh(\n refreshToken?: string,\n ): Promise<AuthResponse<{ session: Session | null; user: User | null }>> {\n const token = refreshToken ?? this.session?.refresh_token\n if (!token) {\n return {\n data: { session: null, user: null },\n error: new AuthError('Auth session missing!', 400, 'session_missing'),\n }\n }\n\n const { data, error } = await this.request<Session>('POST', '/auth/v1/token?grant_type=refresh_token', {\n refresh_token: token,\n })\n\n if (error) {\n // Network failures keep the session (retry next tick); auth failures clear it.\n if (error.code !== 'network_error') {\n this.clearSession()\n this.emit('SIGNED_OUT', null)\n }\n return { data: { session: null, user: null }, error }\n }\n\n if (data) {\n await this.saveSession(data)\n this.emit('TOKEN_REFRESHED', data)\n return { data: { session: data, user: data.user }, error: null }\n }\n return { data: { session: null, user: null }, error: new AuthError('Empty refresh response') }\n }\n\n private async saveSession(session: Session) {\n this.session = session\n if (this.persistSession) {\n try {\n this.storage.setItem(this.storageKey, JSON.stringify(session))\n } catch {\n // Persistence is best-effort (private mode, quota).\n }\n }\n this.startRefreshTimer()\n }\n\n private clearSession() {\n this.session = null\n try {\n this.storage.removeItem(this.storageKey)\n } catch {\n // ignore\n }\n this.stopRefreshTimer()\n }\n\n private loadStoredSession(): Session | null {\n if (!this.persistSession) return null\n try {\n const raw = this.storage.getItem(this.storageKey)\n if (!raw) return null\n const parsed = JSON.parse(raw) as Session\n if (!parsed.access_token || !parsed.refresh_token) return null\n return parsed\n } catch {\n return null\n }\n }\n\n private startRefreshTimer() {\n if (!this.autoRefreshToken || this.refreshTimer || typeof setInterval === 'undefined') return\n this.refreshTimer = setInterval(() => {\n if (this.session && this.isExpired(this.session)) void this.refreshWithLock()\n }, REFRESH_TICK_MS)\n // Do not keep node processes alive because of the timer (no-op in browsers).\n const timer = this.refreshTimer as unknown as { unref?: () => void }\n if (typeof timer === 'object' && typeof timer.unref === 'function') timer.unref()\n }\n\n private stopRefreshTimer() {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer)\n this.refreshTimer = null\n }\n }\n\n private setupCrossTabSync() {\n if (typeof window === 'undefined' || !this.persistSession) return\n window.addEventListener('storage', event => {\n if (event.key !== this.storageKey) return\n if (!event.newValue) {\n if (this.session) {\n this.session = null\n this.stopRefreshTimer()\n this.emit('SIGNED_OUT', null)\n }\n return\n }\n try {\n const next = JSON.parse(event.newValue) as Session\n const changed = next.access_token !== this.session?.access_token\n this.session = next\n this.startRefreshTimer()\n if (changed) this.emit('TOKEN_REFRESHED', next)\n } catch {\n // ignore malformed writes\n }\n })\n }\n\n private emit(event: AuthChangeEvent, session: Session | null) {\n for (const listener of this.listeners.values()) {\n try {\n listener(event, session)\n } catch (err) {\n console.error('[deepkey] onAuthStateChange listener threw', err)\n }\n }\n }\n}\n\nexport interface AuthClient {\n auth: Auth\n}\n\nexport const createAuthClient = (publishableKey: string, options?: AuthClientOptions): AuthClient => {\n return { auth: new Auth(publishableKey, options) }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,72 @@
1
+ import { A as AuthClientOptions, S as SignInWithOtpCredentials, a as AuthResponse, V as VerifyOtpParams, U as User, b as Session, c as SignInWithOAuthCredentials, d as AuthChangeEvent, e as Subscription, f as AuthError } from './constants-BQhswdms.cjs';
2
+ export { D as DEEPKEY_API_URL, g as ServerClientOptions, h as StorageAdapter, i as UserIdentity } from './constants-BQhswdms.cjs';
3
+
4
+ type Listener = (event: AuthChangeEvent, session: Session | null) => void;
5
+ declare class Auth {
6
+ private baseUrl;
7
+ private apikey;
8
+ private storage;
9
+ private storageKey;
10
+ private persistSession;
11
+ private autoRefreshToken;
12
+ private detectSessionInUrl;
13
+ private fetchImpl?;
14
+ private session;
15
+ private listeners;
16
+ private listenerSeq;
17
+ private initializePromise;
18
+ private refreshPromise;
19
+ private refreshTimer;
20
+ constructor(publishableKey: string, options?: AuthClientOptions);
21
+ signInWithOtp(credentials: SignInWithOtpCredentials): Promise<AuthResponse<{
22
+ user: null;
23
+ session: null;
24
+ }>>;
25
+ verifyOtp(params: VerifyOtpParams): Promise<AuthResponse<{
26
+ user: User | null;
27
+ session: Session | null;
28
+ }>>;
29
+ signInWithOAuth(credentials: SignInWithOAuthCredentials): Promise<AuthResponse<{
30
+ provider: string;
31
+ url: string;
32
+ }>>;
33
+ onAuthStateChange(callback: Listener): {
34
+ data: {
35
+ subscription: Subscription;
36
+ };
37
+ };
38
+ signOut(): Promise<{
39
+ error: AuthError | null;
40
+ }>;
41
+ getSession(): Promise<AuthResponse<{
42
+ session: Session | null;
43
+ }>>;
44
+ getUser(jwt?: string): Promise<AuthResponse<{
45
+ user: User | null;
46
+ }>>;
47
+ refreshSession(currentSession?: {
48
+ refresh_token: string;
49
+ }): Promise<AuthResponse<{
50
+ session: Session | null;
51
+ user: User | null;
52
+ }>>;
53
+ private request;
54
+ private initialize;
55
+ private doInitialize;
56
+ private isExpired;
57
+ private refreshWithLock;
58
+ private doRefresh;
59
+ private saveSession;
60
+ private clearSession;
61
+ private loadStoredSession;
62
+ private startRefreshTimer;
63
+ private stopRefreshTimer;
64
+ private setupCrossTabSync;
65
+ private emit;
66
+ }
67
+ interface AuthClient {
68
+ auth: Auth;
69
+ }
70
+ declare const createAuthClient: (publishableKey: string, options?: AuthClientOptions) => AuthClient;
71
+
72
+ export { Auth, AuthChangeEvent, type AuthClient, AuthClientOptions, AuthError, AuthResponse, Session, SignInWithOAuthCredentials, SignInWithOtpCredentials, Subscription, User, VerifyOtpParams, createAuthClient };
@@ -0,0 +1,72 @@
1
+ import { A as AuthClientOptions, S as SignInWithOtpCredentials, a as AuthResponse, V as VerifyOtpParams, U as User, b as Session, c as SignInWithOAuthCredentials, d as AuthChangeEvent, e as Subscription, f as AuthError } from './constants-BQhswdms.js';
2
+ export { D as DEEPKEY_API_URL, g as ServerClientOptions, h as StorageAdapter, i as UserIdentity } from './constants-BQhswdms.js';
3
+
4
+ type Listener = (event: AuthChangeEvent, session: Session | null) => void;
5
+ declare class Auth {
6
+ private baseUrl;
7
+ private apikey;
8
+ private storage;
9
+ private storageKey;
10
+ private persistSession;
11
+ private autoRefreshToken;
12
+ private detectSessionInUrl;
13
+ private fetchImpl?;
14
+ private session;
15
+ private listeners;
16
+ private listenerSeq;
17
+ private initializePromise;
18
+ private refreshPromise;
19
+ private refreshTimer;
20
+ constructor(publishableKey: string, options?: AuthClientOptions);
21
+ signInWithOtp(credentials: SignInWithOtpCredentials): Promise<AuthResponse<{
22
+ user: null;
23
+ session: null;
24
+ }>>;
25
+ verifyOtp(params: VerifyOtpParams): Promise<AuthResponse<{
26
+ user: User | null;
27
+ session: Session | null;
28
+ }>>;
29
+ signInWithOAuth(credentials: SignInWithOAuthCredentials): Promise<AuthResponse<{
30
+ provider: string;
31
+ url: string;
32
+ }>>;
33
+ onAuthStateChange(callback: Listener): {
34
+ data: {
35
+ subscription: Subscription;
36
+ };
37
+ };
38
+ signOut(): Promise<{
39
+ error: AuthError | null;
40
+ }>;
41
+ getSession(): Promise<AuthResponse<{
42
+ session: Session | null;
43
+ }>>;
44
+ getUser(jwt?: string): Promise<AuthResponse<{
45
+ user: User | null;
46
+ }>>;
47
+ refreshSession(currentSession?: {
48
+ refresh_token: string;
49
+ }): Promise<AuthResponse<{
50
+ session: Session | null;
51
+ user: User | null;
52
+ }>>;
53
+ private request;
54
+ private initialize;
55
+ private doInitialize;
56
+ private isExpired;
57
+ private refreshWithLock;
58
+ private doRefresh;
59
+ private saveSession;
60
+ private clearSession;
61
+ private loadStoredSession;
62
+ private startRefreshTimer;
63
+ private stopRefreshTimer;
64
+ private setupCrossTabSync;
65
+ private emit;
66
+ }
67
+ interface AuthClient {
68
+ auth: Auth;
69
+ }
70
+ declare const createAuthClient: (publishableKey: string, options?: AuthClientOptions) => AuthClient;
71
+
72
+ export { Auth, AuthChangeEvent, type AuthClient, AuthClientOptions, AuthError, AuthResponse, Session, SignInWithOAuthCredentials, SignInWithOtpCredentials, Subscription, User, VerifyOtpParams, createAuthClient };