@netlify/identity 0.1.0-alpha.9 → 0.1.1-alpha.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/README.md CHANGED
@@ -92,6 +92,102 @@ getSettings(): Promise<Settings>
92
92
 
93
93
  Fetches your project's Identity settings (enabled providers, autoconfirm, signup disabled). Throws `MissingIdentityError` if not configured; throws `AuthError` if the endpoint is unreachable.
94
94
 
95
+ #### `login`
96
+
97
+ ```ts
98
+ login(email: string, password: string): Promise<User>
99
+ ```
100
+
101
+ Logs in with email and password. Browser only.
102
+
103
+ #### `signup`
104
+
105
+ ```ts
106
+ signup(email: string, password: string, data?: Record<string, unknown>): Promise<User>
107
+ ```
108
+
109
+ Creates a new account. Emits `'login'` if autoconfirm is enabled. Browser only.
110
+
111
+ #### `logout`
112
+
113
+ ```ts
114
+ logout(): Promise<void>
115
+ ```
116
+
117
+ Logs out the current user and clears the session. Browser only.
118
+
119
+ #### `oauthLogin`
120
+
121
+ ```ts
122
+ oauthLogin(provider: string): never
123
+ ```
124
+
125
+ Redirects to an OAuth provider. Always throws (the page navigates away). Browser only.
126
+
127
+ #### `handleAuthCallback`
128
+
129
+ ```ts
130
+ handleAuthCallback(): Promise<CallbackResult | null>
131
+ ```
132
+
133
+ Processes the URL hash after an OAuth redirect, email confirmation, password recovery, invite acceptance, or email change. Call on page load. Returns `null` if the hash contains no auth parameters. Browser only.
134
+
135
+ #### `onAuthChange`
136
+
137
+ ```ts
138
+ onAuthChange(callback: AuthCallback): () => void
139
+ ```
140
+
141
+ Subscribes to auth state changes (login, logout, token refresh, user updates). Returns an unsubscribe function. Also fires on cross-tab session changes. No-op on the server.
142
+
143
+ #### `requestPasswordRecovery`
144
+
145
+ ```ts
146
+ requestPasswordRecovery(email: string): Promise<void>
147
+ ```
148
+
149
+ Sends a password recovery email to the given address.
150
+
151
+ #### `recoverPassword`
152
+
153
+ ```ts
154
+ recoverPassword(token: string, newPassword: string): Promise<User>
155
+ ```
156
+
157
+ Redeems a recovery token and sets a new password. Logs the user in on success.
158
+
159
+ #### `confirmEmail`
160
+
161
+ ```ts
162
+ confirmEmail(token: string): Promise<User>
163
+ ```
164
+
165
+ Confirms an email address using the token from a confirmation email. Logs the user in on success.
166
+
167
+ #### `acceptInvite`
168
+
169
+ ```ts
170
+ acceptInvite(token: string, password: string): Promise<User>
171
+ ```
172
+
173
+ Accepts an invite token and sets a password for the new account. Logs the user in on success.
174
+
175
+ #### `verifyEmailChange`
176
+
177
+ ```ts
178
+ verifyEmailChange(token: string): Promise<User>
179
+ ```
180
+
181
+ Verifies an email change using the token from a verification email.
182
+
183
+ #### `updateUser`
184
+
185
+ ```ts
186
+ updateUser(updates: Record<string, unknown>): Promise<User>
187
+ ```
188
+
189
+ Updates the current user's metadata or credentials. Requires an active session.
190
+
95
191
  ### Types
96
192
 
97
193
  #### `User`
@@ -146,6 +242,28 @@ interface AppMetadata {
146
242
  }
147
243
  ```
148
244
 
245
+ #### `AuthEvent`
246
+
247
+ ```ts
248
+ type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'
249
+ ```
250
+
251
+ #### `AuthCallback`
252
+
253
+ ```ts
254
+ type AuthCallback = (event: AuthEvent, user: User | null) => void
255
+ ```
256
+
257
+ #### `CallbackResult`
258
+
259
+ ```ts
260
+ interface CallbackResult {
261
+ type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'
262
+ user: User | null
263
+ token?: string
264
+ }
265
+ ```
266
+
149
267
  ### Errors
150
268
 
151
269
  #### `AuthError`
package/dist/index.cjs CHANGED
@@ -32,10 +32,22 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AuthError: () => AuthError,
34
34
  MissingIdentityError: () => MissingIdentityError,
35
+ acceptInvite: () => acceptInvite,
36
+ confirmEmail: () => confirmEmail,
35
37
  getIdentityConfig: () => getIdentityConfig,
36
38
  getSettings: () => getSettings,
37
39
  getUser: () => getUser,
38
- isAuthenticated: () => isAuthenticated
40
+ handleAuthCallback: () => handleAuthCallback,
41
+ isAuthenticated: () => isAuthenticated,
42
+ login: () => login,
43
+ logout: () => logout,
44
+ oauthLogin: () => oauthLogin,
45
+ onAuthChange: () => onAuthChange,
46
+ recoverPassword: () => recoverPassword,
47
+ requestPasswordRecovery: () => requestPasswordRecovery,
48
+ signup: () => signup,
49
+ updateUser: () => updateUser,
50
+ verifyEmailChange: () => verifyEmailChange
39
51
  });
40
52
  module.exports = __toCommonJS(index_exports);
41
53
 
@@ -44,6 +56,26 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
44
56
 
45
57
  // src/environment.ts
46
58
  var import_gotrue_js = __toESM(require("gotrue-js"), 1);
59
+
60
+ // src/errors.ts
61
+ var AuthError = class extends Error {
62
+ constructor(message, status, options) {
63
+ super(message);
64
+ this.name = "AuthError";
65
+ this.status = status;
66
+ if (options && "cause" in options) {
67
+ this.cause = options.cause;
68
+ }
69
+ }
70
+ };
71
+ var MissingIdentityError = class extends Error {
72
+ constructor(message = "Identity is not available in this environment") {
73
+ super(message);
74
+ this.name = "MissingIdentityError";
75
+ }
76
+ };
77
+
78
+ // src/environment.ts
47
79
  var goTrueClient = null;
48
80
  var cachedApiUrl;
49
81
  var warnedMissingUrl = false;
@@ -77,6 +109,11 @@ var getGoTrueClient = () => {
77
109
  goTrueClient = new import_gotrue_js.default({ APIUrl: apiUrl, setCookie: isBrowser() });
78
110
  return goTrueClient;
79
111
  };
112
+ var getClient = () => {
113
+ const client = getGoTrueClient();
114
+ if (!client) throw new MissingIdentityError();
115
+ return client;
116
+ };
80
117
  var getIdentityContext = () => {
81
118
  const identityContext = globalThis.netlifyIdentityContext;
82
119
  if (identityContext?.url && typeof identityContext.url === "string") {
@@ -138,24 +175,6 @@ var getUser = () => {
138
175
  };
139
176
  var isAuthenticated = () => getUser() !== null;
140
177
 
141
- // src/errors.ts
142
- var AuthError = class extends Error {
143
- constructor(message, status, options) {
144
- super(message);
145
- this.name = "AuthError";
146
- this.status = status;
147
- if (options && "cause" in options) {
148
- this.cause = options.cause;
149
- }
150
- }
151
- };
152
- var MissingIdentityError = class extends Error {
153
- constructor(message = "Identity is not available in this environment") {
154
- super(message);
155
- this.name = "MissingIdentityError";
156
- }
157
- };
158
-
159
178
  // src/config.ts
160
179
  var getIdentityConfig = () => {
161
180
  if (isBrowser()) {
@@ -164,8 +183,7 @@ var getIdentityConfig = () => {
164
183
  return getIdentityContext();
165
184
  };
166
185
  var getSettings = async () => {
167
- const client = getGoTrueClient();
168
- if (!client) throw new MissingIdentityError();
186
+ const client = getClient();
169
187
  try {
170
188
  const raw = await client.settings();
171
189
  const external = raw.external ?? {};
@@ -186,13 +204,233 @@ var getSettings = async () => {
186
204
  throw new AuthError(err instanceof Error ? err.message : "Failed to fetch identity settings", 502, { cause: err });
187
205
  }
188
206
  };
207
+
208
+ // src/auth.ts
209
+ var persistSession = true;
210
+ var listeners = /* @__PURE__ */ new Set();
211
+ var emitAuthEvent = (event, user) => {
212
+ for (const listener of listeners) {
213
+ listener(event, user);
214
+ }
215
+ };
216
+ var storageListenerAttached = false;
217
+ var attachStorageListener = () => {
218
+ if (storageListenerAttached) return;
219
+ storageListenerAttached = true;
220
+ window.addEventListener("storage", (event) => {
221
+ if (event.key !== "gotrue.user") return;
222
+ if (event.newValue) {
223
+ const client = getGoTrueClient();
224
+ const currentUser = client?.currentUser();
225
+ emitAuthEvent("login", currentUser ? toUser(currentUser) : null);
226
+ } else {
227
+ emitAuthEvent("logout", null);
228
+ }
229
+ });
230
+ };
231
+ var onAuthChange = (callback) => {
232
+ if (!isBrowser()) {
233
+ return () => {
234
+ };
235
+ }
236
+ listeners.add(callback);
237
+ attachStorageListener();
238
+ return () => {
239
+ listeners.delete(callback);
240
+ };
241
+ };
242
+ var login = async (email, password) => {
243
+ const client = getClient();
244
+ try {
245
+ const gotrueUser = await client.login(email, password, persistSession);
246
+ const user = toUser(gotrueUser);
247
+ emitAuthEvent("login", user);
248
+ return user;
249
+ } catch (error) {
250
+ throw new AuthError(error.message, void 0, { cause: error });
251
+ }
252
+ };
253
+ var signup = async (email, password, data) => {
254
+ const client = getClient();
255
+ try {
256
+ const response = await client.signup(email, password, data);
257
+ const user = toUser(response);
258
+ if (response.confirmed_at) {
259
+ emitAuthEvent("login", user);
260
+ }
261
+ return user;
262
+ } catch (error) {
263
+ throw new AuthError(error.message, void 0, { cause: error });
264
+ }
265
+ };
266
+ var logout = async () => {
267
+ const client = getClient();
268
+ try {
269
+ const currentUser = client.currentUser();
270
+ if (currentUser) {
271
+ await currentUser.logout();
272
+ }
273
+ emitAuthEvent("logout", null);
274
+ } catch (error) {
275
+ throw new AuthError(error.message, void 0, { cause: error });
276
+ }
277
+ };
278
+ var oauthLogin = (provider) => {
279
+ if (!isBrowser()) {
280
+ throw new Error("oauthLogin() is only available in the browser");
281
+ }
282
+ const client = getClient();
283
+ window.location.href = client.loginExternalUrl(provider);
284
+ throw new Error("Redirecting to OAuth provider");
285
+ };
286
+ var handleAuthCallback = async () => {
287
+ if (!isBrowser()) return null;
288
+ const hash = window.location.hash.substring(1);
289
+ if (!hash) return null;
290
+ const client = getClient();
291
+ try {
292
+ const params = new URLSearchParams(hash);
293
+ const accessToken = params.get("access_token");
294
+ if (accessToken) {
295
+ const gotrueUser = await client.createUser(
296
+ {
297
+ access_token: accessToken,
298
+ token_type: params.get("token_type") ?? "bearer",
299
+ expires_in: Number(params.get("expires_in")),
300
+ expires_at: Number(params.get("expires_at")),
301
+ refresh_token: params.get("refresh_token") ?? ""
302
+ },
303
+ persistSession
304
+ );
305
+ const user = toUser(gotrueUser);
306
+ clearHash();
307
+ emitAuthEvent("login", user);
308
+ return { type: "oauth", user };
309
+ }
310
+ const confirmationToken = params.get("confirmation_token");
311
+ if (confirmationToken) {
312
+ const gotrueUser = await client.confirm(confirmationToken, persistSession);
313
+ const user = toUser(gotrueUser);
314
+ clearHash();
315
+ emitAuthEvent("login", user);
316
+ return { type: "confirmation", user };
317
+ }
318
+ const recoveryToken = params.get("recovery_token");
319
+ if (recoveryToken) {
320
+ const gotrueUser = await client.recover(recoveryToken, persistSession);
321
+ const user = toUser(gotrueUser);
322
+ clearHash();
323
+ emitAuthEvent("login", user);
324
+ return { type: "recovery", user };
325
+ }
326
+ const inviteToken = params.get("invite_token");
327
+ if (inviteToken) {
328
+ clearHash();
329
+ return { type: "invite", user: null, token: inviteToken };
330
+ }
331
+ const emailChangeToken = params.get("email_change_token");
332
+ if (emailChangeToken) {
333
+ const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
334
+ const user = toUser(gotrueUser);
335
+ clearHash();
336
+ emitAuthEvent("user_updated", user);
337
+ return { type: "email_change", user };
338
+ }
339
+ return null;
340
+ } catch (error) {
341
+ throw new AuthError(error.message, void 0, { cause: error });
342
+ }
343
+ };
344
+ var clearHash = () => {
345
+ history.replaceState(null, "", window.location.pathname + window.location.search);
346
+ };
347
+
348
+ // src/account.ts
349
+ var requestPasswordRecovery = async (email) => {
350
+ const client = getClient();
351
+ try {
352
+ await client.requestPasswordRecovery(email);
353
+ } catch (error) {
354
+ throw new AuthError(error.message, void 0, { cause: error });
355
+ }
356
+ };
357
+ var recoverPassword = async (token, newPassword) => {
358
+ const client = getClient();
359
+ try {
360
+ const gotrueUser = await client.recover(token, persistSession);
361
+ const updatedUser = await gotrueUser.update({ password: newPassword });
362
+ const user = toUser(updatedUser);
363
+ emitAuthEvent("login", user);
364
+ return user;
365
+ } catch (error) {
366
+ throw new AuthError(error.message, void 0, { cause: error });
367
+ }
368
+ };
369
+ var confirmEmail = async (token) => {
370
+ const client = getClient();
371
+ try {
372
+ const gotrueUser = await client.confirm(token, persistSession);
373
+ const user = toUser(gotrueUser);
374
+ emitAuthEvent("login", user);
375
+ return user;
376
+ } catch (error) {
377
+ throw new AuthError(error.message, void 0, { cause: error });
378
+ }
379
+ };
380
+ var acceptInvite = async (token, password) => {
381
+ const client = getClient();
382
+ try {
383
+ const gotrueUser = await client.acceptInvite(token, password, persistSession);
384
+ const user = toUser(gotrueUser);
385
+ emitAuthEvent("login", user);
386
+ return user;
387
+ } catch (error) {
388
+ throw new AuthError(error.message, void 0, { cause: error });
389
+ }
390
+ };
391
+ var verifyEmailChange = async (token) => {
392
+ const client = getClient();
393
+ try {
394
+ const gotrueUser = await client.verify("email_change", token, persistSession);
395
+ const user = toUser(gotrueUser);
396
+ emitAuthEvent("user_updated", user);
397
+ return user;
398
+ } catch (error) {
399
+ throw new AuthError(error.message, void 0, { cause: error });
400
+ }
401
+ };
402
+ var updateUser = async (updates) => {
403
+ const client = getClient();
404
+ const currentUser = client.currentUser();
405
+ if (!currentUser) throw new AuthError("No user is currently logged in");
406
+ try {
407
+ const updatedUser = await currentUser.update(updates);
408
+ const user = toUser(updatedUser);
409
+ emitAuthEvent("user_updated", user);
410
+ return user;
411
+ } catch (error) {
412
+ throw new AuthError(error.message, void 0, { cause: error });
413
+ }
414
+ };
189
415
  // Annotate the CommonJS export names for ESM import in node:
190
416
  0 && (module.exports = {
191
417
  AuthError,
192
418
  MissingIdentityError,
419
+ acceptInvite,
420
+ confirmEmail,
193
421
  getIdentityConfig,
194
422
  getSettings,
195
423
  getUser,
196
- isAuthenticated
424
+ handleAuthCallback,
425
+ isAuthenticated,
426
+ login,
427
+ logout,
428
+ oauthLogin,
429
+ onAuthChange,
430
+ recoverPassword,
431
+ requestPasswordRecovery,
432
+ signup,
433
+ updateUser,
434
+ verifyEmailChange
197
435
  });
198
436
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/user.ts","../src/errors.ts","../src/config.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError, MissingIdentityError } from './errors.js'\nimport { getGoTrueClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export type { User } from './user.js'\nexport { getUser, isAuthenticated } from './user.js'\nexport { getIdentityConfig, getSettings } from './config.js'\nexport type { AuthCallback, AuthEvent, CallbackResult } from './auth.js'\nexport { login, signup, logout, oauthLogin, onAuthChange, handleAuthCallback } from './auth.js'\nexport { AuthError, MissingIdentityError } from './errors.js'\nexport type { AppMetadata, AuthProvider, IdentityConfig, Settings } from './types.js'\nexport {\n requestPasswordRecovery,\n recoverPassword,\n confirmEmail,\n acceptInvite,\n verifyEmailChange,\n updateUser,\n} from './account.js'\n","export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Browser only. */\nexport const login = async (email: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Browser only. */\nexport const logout = async (): Promise<void> => {\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":"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","names":["GoTrue"]}
package/dist/index.d.cts CHANGED
@@ -51,6 +51,34 @@ declare const getIdentityConfig: () => IdentityConfig | null;
51
51
  */
52
52
  declare const getSettings: () => Promise<Settings>;
53
53
 
54
+ type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated';
55
+
56
+ type AuthCallback = (event: AuthEvent, user: User | null) => void;
57
+ /**
58
+ * Subscribes to auth state changes (login, logout, token refresh, user updates).
59
+ * Returns an unsubscribe function. No-op on the server.
60
+ */
61
+ declare const onAuthChange: (callback: AuthCallback) => (() => void);
62
+ /** Logs in with email and password. Browser only. */
63
+ declare const login: (email: string, password: string) => Promise<User>;
64
+ /** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */
65
+ declare const signup: (email: string, password: string, data?: Record<string, unknown>) => Promise<User>;
66
+ /** Logs out the current user and clears the session. Browser only. */
67
+ declare const logout: () => Promise<void>;
68
+ /** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */
69
+ declare const oauthLogin: (provider: string) => never;
70
+ interface CallbackResult {
71
+ type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change';
72
+ user: User | null;
73
+ token?: string;
74
+ }
75
+ /**
76
+ * Processes the URL hash after an OAuth redirect, email confirmation, password
77
+ * recovery, invite acceptance, or email change. Call on page load. Browser only.
78
+ * Returns `null` if the hash contains no auth parameters.
79
+ */
80
+ declare const handleAuthCallback: () => Promise<CallbackResult | null>;
81
+
54
82
  declare class AuthError extends Error {
55
83
  name: string;
56
84
  status?: number;
@@ -64,4 +92,17 @@ declare class MissingIdentityError extends Error {
64
92
  constructor(message?: string);
65
93
  }
66
94
 
67
- export { type AppMetadata, AuthError, type AuthProvider, type IdentityConfig, MissingIdentityError, type Settings, type User, getIdentityConfig, getSettings, getUser, isAuthenticated };
95
+ /** Sends a password recovery email to the given address. */
96
+ declare const requestPasswordRecovery: (email: string) => Promise<void>;
97
+ /** Redeems a recovery token and sets a new password. Logs the user in on success. */
98
+ declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
99
+ /** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
100
+ declare const confirmEmail: (token: string) => Promise<User>;
101
+ /** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
102
+ declare const acceptInvite: (token: string, password: string) => Promise<User>;
103
+ /** Verifies an email change using the token from a verification email. */
104
+ declare const verifyEmailChange: (token: string) => Promise<User>;
105
+ /** Updates the current user's metadata or credentials. Requires an active session. */
106
+ declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
107
+
108
+ export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
package/dist/index.d.ts CHANGED
@@ -51,6 +51,34 @@ declare const getIdentityConfig: () => IdentityConfig | null;
51
51
  */
52
52
  declare const getSettings: () => Promise<Settings>;
53
53
 
54
+ type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated';
55
+
56
+ type AuthCallback = (event: AuthEvent, user: User | null) => void;
57
+ /**
58
+ * Subscribes to auth state changes (login, logout, token refresh, user updates).
59
+ * Returns an unsubscribe function. No-op on the server.
60
+ */
61
+ declare const onAuthChange: (callback: AuthCallback) => (() => void);
62
+ /** Logs in with email and password. Browser only. */
63
+ declare const login: (email: string, password: string) => Promise<User>;
64
+ /** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */
65
+ declare const signup: (email: string, password: string, data?: Record<string, unknown>) => Promise<User>;
66
+ /** Logs out the current user and clears the session. Browser only. */
67
+ declare const logout: () => Promise<void>;
68
+ /** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */
69
+ declare const oauthLogin: (provider: string) => never;
70
+ interface CallbackResult {
71
+ type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change';
72
+ user: User | null;
73
+ token?: string;
74
+ }
75
+ /**
76
+ * Processes the URL hash after an OAuth redirect, email confirmation, password
77
+ * recovery, invite acceptance, or email change. Call on page load. Browser only.
78
+ * Returns `null` if the hash contains no auth parameters.
79
+ */
80
+ declare const handleAuthCallback: () => Promise<CallbackResult | null>;
81
+
54
82
  declare class AuthError extends Error {
55
83
  name: string;
56
84
  status?: number;
@@ -64,4 +92,17 @@ declare class MissingIdentityError extends Error {
64
92
  constructor(message?: string);
65
93
  }
66
94
 
67
- export { type AppMetadata, AuthError, type AuthProvider, type IdentityConfig, MissingIdentityError, type Settings, type User, getIdentityConfig, getSettings, getUser, isAuthenticated };
95
+ /** Sends a password recovery email to the given address. */
96
+ declare const requestPasswordRecovery: (email: string) => Promise<void>;
97
+ /** Redeems a recovery token and sets a new password. Logs the user in on success. */
98
+ declare const recoverPassword: (token: string, newPassword: string) => Promise<User>;
99
+ /** Confirms an email address using the token from a confirmation email. Logs the user in on success. */
100
+ declare const confirmEmail: (token: string) => Promise<User>;
101
+ /** Accepts an invite token and sets a password for the new account. Logs the user in on success. */
102
+ declare const acceptInvite: (token: string, password: string) => Promise<User>;
103
+ /** Verifies an email change using the token from a verification email. */
104
+ declare const verifyEmailChange: (token: string) => Promise<User>;
105
+ /** Updates the current user's metadata or credentials. Requires an active session. */
106
+ declare const updateUser: (updates: Record<string, unknown>) => Promise<User>;
107
+
108
+ export { type AppMetadata, type AuthCallback, AuthError, type AuthEvent, type AuthProvider, type CallbackResult, type IdentityConfig, MissingIdentityError, type Settings, type User, acceptInvite, confirmEmail, getIdentityConfig, getSettings, getUser, handleAuthCallback, isAuthenticated, login, logout, oauthLogin, onAuthChange, recoverPassword, requestPasswordRecovery, signup, updateUser, verifyEmailChange };
package/dist/index.js CHANGED
@@ -3,6 +3,26 @@ var AUTH_PROVIDERS = ["google", "github", "gitlab", "bitbucket", "facebook", "sa
3
3
 
4
4
  // src/environment.ts
5
5
  import GoTrue from "gotrue-js";
6
+
7
+ // src/errors.ts
8
+ var AuthError = class extends Error {
9
+ constructor(message, status, options) {
10
+ super(message);
11
+ this.name = "AuthError";
12
+ this.status = status;
13
+ if (options && "cause" in options) {
14
+ this.cause = options.cause;
15
+ }
16
+ }
17
+ };
18
+ var MissingIdentityError = class extends Error {
19
+ constructor(message = "Identity is not available in this environment") {
20
+ super(message);
21
+ this.name = "MissingIdentityError";
22
+ }
23
+ };
24
+
25
+ // src/environment.ts
6
26
  var goTrueClient = null;
7
27
  var cachedApiUrl;
8
28
  var warnedMissingUrl = false;
@@ -36,6 +56,11 @@ var getGoTrueClient = () => {
36
56
  goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() });
37
57
  return goTrueClient;
38
58
  };
59
+ var getClient = () => {
60
+ const client = getGoTrueClient();
61
+ if (!client) throw new MissingIdentityError();
62
+ return client;
63
+ };
39
64
  var getIdentityContext = () => {
40
65
  const identityContext = globalThis.netlifyIdentityContext;
41
66
  if (identityContext?.url && typeof identityContext.url === "string") {
@@ -97,24 +122,6 @@ var getUser = () => {
97
122
  };
98
123
  var isAuthenticated = () => getUser() !== null;
99
124
 
100
- // src/errors.ts
101
- var AuthError = class extends Error {
102
- constructor(message, status, options) {
103
- super(message);
104
- this.name = "AuthError";
105
- this.status = status;
106
- if (options && "cause" in options) {
107
- this.cause = options.cause;
108
- }
109
- }
110
- };
111
- var MissingIdentityError = class extends Error {
112
- constructor(message = "Identity is not available in this environment") {
113
- super(message);
114
- this.name = "MissingIdentityError";
115
- }
116
- };
117
-
118
125
  // src/config.ts
119
126
  var getIdentityConfig = () => {
120
127
  if (isBrowser()) {
@@ -123,8 +130,7 @@ var getIdentityConfig = () => {
123
130
  return getIdentityContext();
124
131
  };
125
132
  var getSettings = async () => {
126
- const client = getGoTrueClient();
127
- if (!client) throw new MissingIdentityError();
133
+ const client = getClient();
128
134
  try {
129
135
  const raw = await client.settings();
130
136
  const external = raw.external ?? {};
@@ -145,12 +151,232 @@ var getSettings = async () => {
145
151
  throw new AuthError(err instanceof Error ? err.message : "Failed to fetch identity settings", 502, { cause: err });
146
152
  }
147
153
  };
154
+
155
+ // src/auth.ts
156
+ var persistSession = true;
157
+ var listeners = /* @__PURE__ */ new Set();
158
+ var emitAuthEvent = (event, user) => {
159
+ for (const listener of listeners) {
160
+ listener(event, user);
161
+ }
162
+ };
163
+ var storageListenerAttached = false;
164
+ var attachStorageListener = () => {
165
+ if (storageListenerAttached) return;
166
+ storageListenerAttached = true;
167
+ window.addEventListener("storage", (event) => {
168
+ if (event.key !== "gotrue.user") return;
169
+ if (event.newValue) {
170
+ const client = getGoTrueClient();
171
+ const currentUser = client?.currentUser();
172
+ emitAuthEvent("login", currentUser ? toUser(currentUser) : null);
173
+ } else {
174
+ emitAuthEvent("logout", null);
175
+ }
176
+ });
177
+ };
178
+ var onAuthChange = (callback) => {
179
+ if (!isBrowser()) {
180
+ return () => {
181
+ };
182
+ }
183
+ listeners.add(callback);
184
+ attachStorageListener();
185
+ return () => {
186
+ listeners.delete(callback);
187
+ };
188
+ };
189
+ var login = async (email, password) => {
190
+ const client = getClient();
191
+ try {
192
+ const gotrueUser = await client.login(email, password, persistSession);
193
+ const user = toUser(gotrueUser);
194
+ emitAuthEvent("login", user);
195
+ return user;
196
+ } catch (error) {
197
+ throw new AuthError(error.message, void 0, { cause: error });
198
+ }
199
+ };
200
+ var signup = async (email, password, data) => {
201
+ const client = getClient();
202
+ try {
203
+ const response = await client.signup(email, password, data);
204
+ const user = toUser(response);
205
+ if (response.confirmed_at) {
206
+ emitAuthEvent("login", user);
207
+ }
208
+ return user;
209
+ } catch (error) {
210
+ throw new AuthError(error.message, void 0, { cause: error });
211
+ }
212
+ };
213
+ var logout = async () => {
214
+ const client = getClient();
215
+ try {
216
+ const currentUser = client.currentUser();
217
+ if (currentUser) {
218
+ await currentUser.logout();
219
+ }
220
+ emitAuthEvent("logout", null);
221
+ } catch (error) {
222
+ throw new AuthError(error.message, void 0, { cause: error });
223
+ }
224
+ };
225
+ var oauthLogin = (provider) => {
226
+ if (!isBrowser()) {
227
+ throw new Error("oauthLogin() is only available in the browser");
228
+ }
229
+ const client = getClient();
230
+ window.location.href = client.loginExternalUrl(provider);
231
+ throw new Error("Redirecting to OAuth provider");
232
+ };
233
+ var handleAuthCallback = async () => {
234
+ if (!isBrowser()) return null;
235
+ const hash = window.location.hash.substring(1);
236
+ if (!hash) return null;
237
+ const client = getClient();
238
+ try {
239
+ const params = new URLSearchParams(hash);
240
+ const accessToken = params.get("access_token");
241
+ if (accessToken) {
242
+ const gotrueUser = await client.createUser(
243
+ {
244
+ access_token: accessToken,
245
+ token_type: params.get("token_type") ?? "bearer",
246
+ expires_in: Number(params.get("expires_in")),
247
+ expires_at: Number(params.get("expires_at")),
248
+ refresh_token: params.get("refresh_token") ?? ""
249
+ },
250
+ persistSession
251
+ );
252
+ const user = toUser(gotrueUser);
253
+ clearHash();
254
+ emitAuthEvent("login", user);
255
+ return { type: "oauth", user };
256
+ }
257
+ const confirmationToken = params.get("confirmation_token");
258
+ if (confirmationToken) {
259
+ const gotrueUser = await client.confirm(confirmationToken, persistSession);
260
+ const user = toUser(gotrueUser);
261
+ clearHash();
262
+ emitAuthEvent("login", user);
263
+ return { type: "confirmation", user };
264
+ }
265
+ const recoveryToken = params.get("recovery_token");
266
+ if (recoveryToken) {
267
+ const gotrueUser = await client.recover(recoveryToken, persistSession);
268
+ const user = toUser(gotrueUser);
269
+ clearHash();
270
+ emitAuthEvent("login", user);
271
+ return { type: "recovery", user };
272
+ }
273
+ const inviteToken = params.get("invite_token");
274
+ if (inviteToken) {
275
+ clearHash();
276
+ return { type: "invite", user: null, token: inviteToken };
277
+ }
278
+ const emailChangeToken = params.get("email_change_token");
279
+ if (emailChangeToken) {
280
+ const gotrueUser = await client.verify("email_change", emailChangeToken, persistSession);
281
+ const user = toUser(gotrueUser);
282
+ clearHash();
283
+ emitAuthEvent("user_updated", user);
284
+ return { type: "email_change", user };
285
+ }
286
+ return null;
287
+ } catch (error) {
288
+ throw new AuthError(error.message, void 0, { cause: error });
289
+ }
290
+ };
291
+ var clearHash = () => {
292
+ history.replaceState(null, "", window.location.pathname + window.location.search);
293
+ };
294
+
295
+ // src/account.ts
296
+ var requestPasswordRecovery = async (email) => {
297
+ const client = getClient();
298
+ try {
299
+ await client.requestPasswordRecovery(email);
300
+ } catch (error) {
301
+ throw new AuthError(error.message, void 0, { cause: error });
302
+ }
303
+ };
304
+ var recoverPassword = async (token, newPassword) => {
305
+ const client = getClient();
306
+ try {
307
+ const gotrueUser = await client.recover(token, persistSession);
308
+ const updatedUser = await gotrueUser.update({ password: newPassword });
309
+ const user = toUser(updatedUser);
310
+ emitAuthEvent("login", user);
311
+ return user;
312
+ } catch (error) {
313
+ throw new AuthError(error.message, void 0, { cause: error });
314
+ }
315
+ };
316
+ var confirmEmail = async (token) => {
317
+ const client = getClient();
318
+ try {
319
+ const gotrueUser = await client.confirm(token, persistSession);
320
+ const user = toUser(gotrueUser);
321
+ emitAuthEvent("login", user);
322
+ return user;
323
+ } catch (error) {
324
+ throw new AuthError(error.message, void 0, { cause: error });
325
+ }
326
+ };
327
+ var acceptInvite = async (token, password) => {
328
+ const client = getClient();
329
+ try {
330
+ const gotrueUser = await client.acceptInvite(token, password, persistSession);
331
+ const user = toUser(gotrueUser);
332
+ emitAuthEvent("login", user);
333
+ return user;
334
+ } catch (error) {
335
+ throw new AuthError(error.message, void 0, { cause: error });
336
+ }
337
+ };
338
+ var verifyEmailChange = async (token) => {
339
+ const client = getClient();
340
+ try {
341
+ const gotrueUser = await client.verify("email_change", token, persistSession);
342
+ const user = toUser(gotrueUser);
343
+ emitAuthEvent("user_updated", user);
344
+ return user;
345
+ } catch (error) {
346
+ throw new AuthError(error.message, void 0, { cause: error });
347
+ }
348
+ };
349
+ var updateUser = async (updates) => {
350
+ const client = getClient();
351
+ const currentUser = client.currentUser();
352
+ if (!currentUser) throw new AuthError("No user is currently logged in");
353
+ try {
354
+ const updatedUser = await currentUser.update(updates);
355
+ const user = toUser(updatedUser);
356
+ emitAuthEvent("user_updated", user);
357
+ return user;
358
+ } catch (error) {
359
+ throw new AuthError(error.message, void 0, { cause: error });
360
+ }
361
+ };
148
362
  export {
149
363
  AuthError,
150
364
  MissingIdentityError,
365
+ acceptInvite,
366
+ confirmEmail,
151
367
  getIdentityConfig,
152
368
  getSettings,
153
369
  getUser,
154
- isAuthenticated
370
+ handleAuthCallback,
371
+ isAuthenticated,
372
+ login,
373
+ logout,
374
+ oauthLogin,
375
+ onAuthChange,
376
+ recoverPassword,
377
+ requestPasswordRecovery,
378
+ signup,
379
+ updateUser,
380
+ verifyEmailChange
155
381
  };
156
382
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/user.ts","../src/errors.ts","../src/config.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError, MissingIdentityError } from './errors.js'\nimport { getGoTrueClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/types.ts","../src/environment.ts","../src/errors.ts","../src/user.ts","../src/config.ts","../src/auth.ts","../src/account.ts"],"sourcesContent":["export const AUTH_PROVIDERS = ['google', 'github', 'gitlab', 'bitbucket', 'facebook', 'saml', 'email'] as const\nexport type AuthProvider = (typeof AUTH_PROVIDERS)[number]\n\nexport interface AppMetadata {\n provider: AuthProvider\n roles?: string[]\n [key: string]: unknown\n}\n\nexport interface IdentityConfig {\n url: string\n token?: string // this is an operator token, only available on the server\n}\n\nexport interface Settings {\n autoconfirm: boolean\n disableSignup: boolean\n providers: Record<AuthProvider, boolean>\n}\n","import GoTrue from 'gotrue-js'\n\nimport type { IdentityConfig } from './types.js'\nimport { MissingIdentityError } from './errors.js'\n\nlet goTrueClient: GoTrue | null = null\nlet cachedApiUrl: string | null | undefined\nlet warnedMissingUrl = false\n\nexport const isBrowser = (): boolean => typeof window !== 'undefined' && typeof window.location !== 'undefined'\n\n/**\n * Discovers and caches the GoTrue API URL.\n *\n * Browser: uses `window.location.origin` + `/.netlify/identity`.\n * Server: reads from `globalThis.netlifyIdentityContext`.\n */\nconst discoverApiUrl = (): string | null => {\n if (cachedApiUrl !== undefined) return cachedApiUrl\n\n if (isBrowser()) {\n cachedApiUrl = `${window.location.origin}/.netlify/identity`\n } else {\n const identityContext = getIdentityContext()\n if (identityContext?.url) {\n cachedApiUrl = identityContext.url\n } else if (globalThis.Netlify?.context?.url) {\n cachedApiUrl = new URL('/.netlify/identity', globalThis.Netlify.context.url).href\n }\n }\n\n return cachedApiUrl ?? null\n}\n\n/**\n * Returns (and lazily creates) a singleton gotrue-js client.\n * Returns `null` and logs a warning if no identity URL can be discovered.\n */\nexport const getGoTrueClient = (): GoTrue | null => {\n if (goTrueClient) return goTrueClient\n\n const apiUrl = discoverApiUrl()\n if (!apiUrl) {\n if (!warnedMissingUrl) {\n console.warn(\n '@netlify/identity: Could not determine the Identity endpoint URL. ' +\n 'Make sure your site has Netlify Identity enabled, or run your app with `netlify dev`.',\n )\n warnedMissingUrl = true\n }\n return null\n }\n\n goTrueClient = new GoTrue({ APIUrl: apiUrl, setCookie: isBrowser() })\n return goTrueClient\n}\n\n/**\n * Returns the singleton gotrue-js client, or throws if Identity is not configured.\n */\nexport const getClient = (): GoTrue => {\n const client = getGoTrueClient()\n if (!client) throw new MissingIdentityError()\n return client\n}\n\n/**\n * Reads the server-side identity context set by the Netlify bootstrap.\n * Returns `null` outside the Netlify serverless environment.\n */\nexport const getIdentityContext = (): IdentityConfig | null => {\n // TODO(kh): After Stargate deploys EX-1764, netlifyIdentityContext will have\n // typed `url` and `token` fields. Remove the typeof guards and use direct access.\n // https://linear.app/netlify/issue/EX-1764/identity-stargate-needs-to-set-identity-url-and-providertoken\n const identityContext = globalThis.netlifyIdentityContext\n if (identityContext?.url && typeof identityContext.url === 'string') {\n return {\n url: identityContext.url,\n token: typeof identityContext.token === 'string' ? identityContext.token : undefined,\n }\n }\n\n if (globalThis.Netlify?.context?.url) {\n return { url: new URL('/.netlify/identity', globalThis.Netlify.context.url).href }\n }\n\n return null\n}\n\n/** Reset cached state for tests. */\nexport const resetTestGoTrueClient = (): void => {\n goTrueClient = null\n cachedApiUrl = undefined\n warnedMissingUrl = false\n}\n","export class AuthError extends Error {\n override name = 'AuthError'\n status?: number\n declare cause?: unknown\n\n constructor(message: string, status?: number, options?: { cause?: unknown }) {\n super(message)\n this.status = status\n if (options && 'cause' in options) {\n this.cause = options.cause\n }\n }\n}\n\nexport class MissingIdentityError extends Error {\n override name = 'MissingIdentityError'\n\n constructor(message = 'Identity is not available in this environment') {\n super(message)\n }\n}\n","import type { UserData } from 'gotrue-js'\nimport { AUTH_PROVIDERS, type AuthProvider } from './types.js'\nimport { getGoTrueClient, isBrowser } from './environment.js'\n\nconst toAuthProvider = (value: unknown): AuthProvider | undefined =>\n typeof value === 'string' && (AUTH_PROVIDERS as readonly string[]).includes(value)\n ? (value as AuthProvider)\n : undefined\n\nexport interface User {\n id: string\n email?: string\n emailVerified?: boolean\n createdAt?: string\n updatedAt?: string\n provider?: AuthProvider\n name?: string\n pictureUrl?: string\n metadata?: Record<string, unknown>\n rawGoTrueData?: Record<string, unknown>\n}\n\nexport const toUser = (userData: UserData): User => {\n const userMeta = userData.user_metadata ?? {}\n const appMeta = userData.app_metadata ?? {}\n const name = userMeta.full_name || userMeta.name\n const pictureUrl = userMeta.avatar_url\n\n return {\n id: userData.id,\n email: userData.email,\n emailVerified: !!userData.confirmed_at,\n createdAt: userData.created_at,\n updatedAt: userData.updated_at,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n pictureUrl: typeof pictureUrl === 'string' ? pictureUrl : undefined,\n metadata: userMeta,\n rawGoTrueData: { ...userData },\n }\n}\n\n/**\n * Converts raw JWT claims from the identity header into a User.\n * JWT claims use a different shape than the gotrue-js UserData class.\n */\nconst claimsToUser = (claims: Record<string, unknown>): User => {\n const appMeta = (claims.app_metadata ?? {}) as Record<string, unknown>\n const userMeta = (claims.user_metadata ?? {}) as Record<string, unknown>\n const name = userMeta.full_name || userMeta.name\n\n return {\n id: typeof claims.sub === 'string' ? claims.sub : '',\n email: typeof claims.email === 'string' ? claims.email : undefined,\n provider: toAuthProvider(appMeta.provider),\n name: typeof name === 'string' ? name : undefined,\n metadata: userMeta,\n }\n}\n\n/**\n * Returns the currently authenticated user, or `null` if not logged in.\n * Synchronous. Never throws.\n */\nexport const getUser = (): User | null => {\n if (isBrowser()) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser() ?? null\n if (!currentUser) return null\n return toUser(currentUser)\n }\n\n const identityContext = globalThis.netlifyIdentityContext\n if (!identityContext) return null\n\n const claims = identityContext.user ?? (identityContext.sub ? identityContext : null)\n if (!claims) return null\n return claimsToUser(claims as Record<string, unknown>)\n}\n\n/**\n * Returns `true` if a user is currently authenticated.\n */\nexport const isAuthenticated = (): boolean => getUser() !== null\n","import type { AuthProvider, IdentityConfig, Settings } from './types.js'\nimport { AuthError } from './errors.js'\nimport { getClient, getIdentityContext, isBrowser } from './environment.js'\n\n/**\n * Returns the identity configuration for the current environment.\n * Browser: always returns `{ url }` derived from `window.location.origin`.\n * Server: returns `{ url, token }` from the identity context, or `null` if unavailable.\n * Never throws.\n */\nexport const getIdentityConfig = (): IdentityConfig | null => {\n if (isBrowser()) {\n return { url: `${window.location.origin}/.netlify/identity` }\n }\n\n return getIdentityContext()\n}\n\n/**\n * Fetches the GoTrue `/settings` endpoint.\n * Throws `MissingIdentityError` if Identity is not configured.\n * Throws `AuthError` if the endpoint is unreachable.\n */\nexport const getSettings = async (): Promise<Settings> => {\n const client = getClient()\n\n try {\n const raw = await client.settings()\n const external: Partial<Record<AuthProvider, boolean>> = raw.external ?? {}\n return {\n autoconfirm: raw.autoconfirm,\n disableSignup: raw.disable_signup,\n providers: {\n google: external.google ?? false,\n github: external.github ?? false,\n gitlab: external.gitlab ?? false,\n bitbucket: external.bitbucket ?? false,\n facebook: external.facebook ?? false,\n email: external.email ?? false,\n saml: external.saml ?? false,\n },\n }\n } catch (err) {\n throw new AuthError(err instanceof Error ? err.message : 'Failed to fetch identity settings', 502, { cause: err })\n }\n}\n","import type { UserData } from 'gotrue-js'\n\nimport type { AppMetadata } from './types.js'\n\nexport type AuthEvent = 'login' | 'logout' | 'token_refresh' | 'user_updated'\nimport type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getGoTrueClient, getClient, isBrowser } from './environment.js'\nimport { AuthError } from './errors.js'\n\nexport interface JWTClaims {\n sub: string // UUID\n email: string\n exp: number\n iat: number\n aud: string\n app_metadata: AppMetadata\n user_metadata: Record<string, unknown>\n}\n\nexport type AuthCallback = (event: AuthEvent, user: User | null) => void\n\n/** Persist the session to localStorage so it survives page reloads. */\nexport const persistSession = true\n\nconst listeners = new Set<AuthCallback>()\n\nexport const emitAuthEvent = (event: AuthEvent, user: User | null): void => {\n for (const listener of listeners) {\n listener(event, user)\n }\n}\n\nlet storageListenerAttached = false\n\nconst attachStorageListener = (): void => {\n if (storageListenerAttached) return\n storageListenerAttached = true\n\n window.addEventListener('storage', (event: StorageEvent) => {\n if (event.key !== 'gotrue.user') return\n\n if (event.newValue) {\n const client = getGoTrueClient()\n const currentUser = client?.currentUser()\n emitAuthEvent('login', currentUser ? toUser(currentUser) : null)\n } else {\n emitAuthEvent('logout', null)\n }\n })\n}\n\n/**\n * Subscribes to auth state changes (login, logout, token refresh, user updates).\n * Returns an unsubscribe function. No-op on the server.\n */\nexport const onAuthChange = (callback: AuthCallback): (() => void) => {\n if (!isBrowser()) {\n return () => {}\n }\n\n listeners.add(callback)\n attachStorageListener()\n\n return () => {\n listeners.delete(callback)\n }\n}\n\n/** Logs in with email and password. Browser only. */\nexport const login = async (email: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.login(email, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Creates a new account. Emits 'login' if autoconfirm is enabled. Browser only. */\nexport const signup = async (email: string, password: string, data?: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n try {\n const response = await client.signup(email, password, data)\n const user = toUser(response as UserData)\n if (response.confirmed_at) {\n emitAuthEvent('login', user)\n }\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Logs out the current user and clears the session. Browser only. */\nexport const logout = async (): Promise<void> => {\n const client = getClient()\n\n try {\n const currentUser = client.currentUser()\n if (currentUser) {\n await currentUser.logout()\n }\n emitAuthEvent('logout', null)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redirects to an OAuth provider. Always throws (the page navigates away). Browser only. */\nexport const oauthLogin = (provider: string): never => {\n if (!isBrowser()) {\n throw new Error('oauthLogin() is only available in the browser')\n }\n const client = getClient()\n\n window.location.href = client.loginExternalUrl(provider)\n throw new Error('Redirecting to OAuth provider')\n}\n\nexport interface CallbackResult {\n type: 'oauth' | 'confirmation' | 'recovery' | 'invite' | 'email_change'\n user: User | null\n token?: string\n}\n\n/**\n * Processes the URL hash after an OAuth redirect, email confirmation, password\n * recovery, invite acceptance, or email change. Call on page load. Browser only.\n * Returns `null` if the hash contains no auth parameters.\n */\nexport const handleAuthCallback = async (): Promise<CallbackResult | null> => {\n if (!isBrowser()) return null\n\n const hash = window.location.hash.substring(1)\n if (!hash) return null\n\n const client = getClient()\n\n try {\n const params = new URLSearchParams(hash)\n\n const accessToken = params.get('access_token')\n if (accessToken) {\n const gotrueUser = await client.createUser(\n {\n access_token: accessToken,\n token_type: (params.get('token_type') as 'bearer') ?? 'bearer',\n expires_in: Number(params.get('expires_in')),\n expires_at: Number(params.get('expires_at')),\n refresh_token: params.get('refresh_token') ?? '',\n },\n persistSession,\n )\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'oauth', user }\n }\n\n const confirmationToken = params.get('confirmation_token')\n if (confirmationToken) {\n const gotrueUser = await client.confirm(confirmationToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'confirmation', user }\n }\n\n const recoveryToken = params.get('recovery_token')\n if (recoveryToken) {\n const gotrueUser = await client.recover(recoveryToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('login', user)\n return { type: 'recovery', user }\n }\n\n const inviteToken = params.get('invite_token')\n if (inviteToken) {\n clearHash()\n return { type: 'invite', user: null, token: inviteToken }\n }\n\n const emailChangeToken = params.get('email_change_token')\n if (emailChangeToken) {\n const gotrueUser = await client.verify('email_change', emailChangeToken, persistSession)\n const user = toUser(gotrueUser)\n clearHash()\n emitAuthEvent('user_updated', user)\n return { type: 'email_change', user }\n }\n\n return null\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\nconst clearHash = (): void => {\n history.replaceState(null, '', window.location.pathname + window.location.search)\n}\n","import type { User } from './user.js'\nimport { toUser } from './user.js'\nimport { getClient } from './environment.js'\nimport { emitAuthEvent, persistSession } from './auth.js'\nimport { AuthError } from './errors.js'\n\n/** Sends a password recovery email to the given address. */\nexport const requestPasswordRecovery = async (email: string): Promise<void> => {\n const client = getClient()\n\n try {\n await client.requestPasswordRecovery(email)\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Redeems a recovery token and sets a new password. Logs the user in on success. */\nexport const recoverPassword = async (token: string, newPassword: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.recover(token, persistSession)\n const updatedUser = await gotrueUser.update({ password: newPassword })\n const user = toUser(updatedUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Confirms an email address using the token from a confirmation email. Logs the user in on success. */\nexport const confirmEmail = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.confirm(token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Accepts an invite token and sets a password for the new account. Logs the user in on success. */\nexport const acceptInvite = async (token: string, password: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.acceptInvite(token, password, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('login', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Verifies an email change using the token from a verification email. */\nexport const verifyEmailChange = async (token: string): Promise<User> => {\n const client = getClient()\n\n try {\n const gotrueUser = await client.verify('email_change', token, persistSession)\n const user = toUser(gotrueUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n\n/** Updates the current user's metadata or credentials. Requires an active session. */\nexport const updateUser = async (updates: Record<string, unknown>): Promise<User> => {\n const client = getClient()\n\n const currentUser = client.currentUser()\n if (!currentUser) throw new AuthError('No user is currently logged in')\n\n try {\n const updatedUser = await currentUser.update(updates)\n const user = toUser(updatedUser)\n emitAuthEvent('user_updated', user)\n return user\n } catch (error) {\n throw new AuthError((error as Error).message, undefined, { cause: error })\n }\n}\n"],"mappings":";AAAO,IAAM,iBAAiB,CAAC,UAAU,UAAU,UAAU,aAAa,YAAY,QAAQ,OAAO;;;ACArG,OAAO,YAAY;;;ACAZ,IAAM,YAAN,cAAwB,MAAM;AAAA,EAKnC,YAAY,SAAiB,QAAiB,SAA+B;AAC3E,UAAM,OAAO;AALf,SAAS,OAAO;AAMd,SAAK,SAAS;AACd,QAAI,WAAW,WAAW,SAAS;AACjC,WAAK,QAAQ,QAAQ;AAAA,IACvB;AAAA,EACF;AACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAG9C,YAAY,UAAU,iDAAiD;AACrE,UAAM,OAAO;AAHf,SAAS,OAAO;AAAA,EAIhB;AACF;;;ADfA,IAAI,eAA8B;AAClC,IAAI;AACJ,IAAI,mBAAmB;AAEhB,IAAM,YAAY,MAAe,OAAO,WAAW,eAAe,OAAO,OAAO,aAAa;AAQpG,IAAM,iBAAiB,MAAqB;AAC1C,MAAI,iBAAiB,OAAW,QAAO;AAEvC,MAAI,UAAU,GAAG;AACf,mBAAe,GAAG,OAAO,SAAS,MAAM;AAAA,EAC1C,OAAO;AACL,UAAM,kBAAkB,mBAAmB;AAC3C,QAAI,iBAAiB,KAAK;AACxB,qBAAe,gBAAgB;AAAA,IACjC,WAAW,WAAW,SAAS,SAAS,KAAK;AAC3C,qBAAe,IAAI,IAAI,sBAAsB,WAAW,QAAQ,QAAQ,GAAG,EAAE;AAAA,IAC/E;AAAA,EACF;AAEA,SAAO,gBAAgB;AACzB;AAMO,IAAM,kBAAkB,MAAqB;AAClD,MAAI,aAAc,QAAO;AAEzB,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,QAAQ;AACX,QAAI,CAAC,kBAAkB;AACrB,cAAQ;AAAA,QACN;AAAA,MAEF;AACA,yBAAmB;AAAA,IACrB;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,IAAI,OAAO,EAAE,QAAQ,QAAQ,WAAW,UAAU,EAAE,CAAC;AACpE,SAAO;AACT;AAKO,IAAM,YAAY,MAAc;AACrC,QAAM,SAAS,gBAAgB;AAC/B,MAAI,CAAC,OAAQ,OAAM,IAAI,qBAAqB;AAC5C,SAAO;AACT;AAMO,IAAM,qBAAqB,MAA6B;AAI7D,QAAM,kBAAkB,WAAW;AACnC,MAAI,iBAAiB,OAAO,OAAO,gBAAgB,QAAQ,UAAU;AACnE,WAAO;AAAA,MACL,KAAK,gBAAgB;AAAA,MACrB,OAAO,OAAO,gBAAgB,UAAU,WAAW,gBAAgB,QAAQ;AAAA,IAC7E;AAAA,EACF;AAEA,MAAI,WAAW,SAAS,SAAS,KAAK;AACpC,WAAO,EAAE,KAAK,IAAI,IAAI,sBAAsB,WAAW,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA,EACnF;AAEA,SAAO;AACT;;;AEnFA,IAAM,iBAAiB,CAAC,UACtB,OAAO,UAAU,YAAa,eAAqC,SAAS,KAAK,IAC5E,QACD;AAeC,IAAM,SAAS,CAAC,aAA6B;AAClD,QAAM,WAAW,SAAS,iBAAiB,CAAC;AAC5C,QAAM,UAAU,SAAS,gBAAgB,CAAC;AAC1C,QAAM,OAAO,SAAS,aAAa,SAAS;AAC5C,QAAM,aAAa,SAAS;AAE5B,SAAO;AAAA,IACL,IAAI,SAAS;AAAA,IACb,OAAO,SAAS;AAAA,IAChB,eAAe,CAAC,CAAC,SAAS;AAAA,IAC1B,WAAW,SAAS;AAAA,IACpB,WAAW,SAAS;AAAA,IACpB,UAAU,eAAe,QAAQ,QAAQ;AAAA,IACzC,MAAM,OAAO,SAAS,WAAW,OAAO;AAAA,IACxC,YAAY,OAAO,eAAe,WAAW,aAAa;AAAA,IAC1D,UAAU;AAAA,IACV,eAAe,EAAE,GAAG,SAAS;AAAA,EAC/B;AACF;AAMA,IAAM,eAAe,CAAC,WAA0C;AAC9D,QAAM,UAAW,OAAO,gBAAgB,CAAC;AACzC,QAAM,WAAY,OAAO,iBAAiB,CAAC;AAC3C,QAAM,OAAO,SAAS,aAAa,SAAS;AAE5C,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;AAAA,IAClD,OAAO,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,IACzD,UAAU,eAAe,QAAQ,QAAQ;AAAA,IACzC,MAAM,OAAO,SAAS,WAAW,OAAO;AAAA,IACxC,UAAU;AAAA,EACZ;AACF;AAMO,IAAM,UAAU,MAAmB;AACxC,MAAI,UAAU,GAAG;AACf,UAAM,SAAS,gBAAgB;AAC/B,UAAM,cAAc,QAAQ,YAAY,KAAK;AAC7C,QAAI,CAAC,YAAa,QAAO;AACzB,WAAO,OAAO,WAAW;AAAA,EAC3B;AAEA,QAAM,kBAAkB,WAAW;AACnC,MAAI,CAAC,gBAAiB,QAAO;AAE7B,QAAM,SAAS,gBAAgB,SAAS,gBAAgB,MAAM,kBAAkB;AAChF,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,aAAa,MAAiC;AACvD;AAKO,IAAM,kBAAkB,MAAe,QAAQ,MAAM;;;ACzErD,IAAM,oBAAoB,MAA6B;AAC5D,MAAI,UAAU,GAAG;AACf,WAAO,EAAE,KAAK,GAAG,OAAO,SAAS,MAAM,qBAAqB;AAAA,EAC9D;AAEA,SAAO,mBAAmB;AAC5B;AAOO,IAAM,cAAc,YAA+B;AACxD,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,MAAM,MAAM,OAAO,SAAS;AAClC,UAAM,WAAmD,IAAI,YAAY,CAAC;AAC1E,WAAO;AAAA,MACL,aAAa,IAAI;AAAA,MACjB,eAAe,IAAI;AAAA,MACnB,WAAW;AAAA,QACT,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU;AAAA,QAC3B,QAAQ,SAAS,UAAU;AAAA,QAC3B,WAAW,SAAS,aAAa;AAAA,QACjC,UAAU,SAAS,YAAY;AAAA,QAC/B,OAAO,SAAS,SAAS;AAAA,QACzB,MAAM,SAAS,QAAQ;AAAA,MACzB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,IAAI,UAAU,eAAe,QAAQ,IAAI,UAAU,qCAAqC,KAAK,EAAE,OAAO,IAAI,CAAC;AAAA,EACnH;AACF;;;ACtBO,IAAM,iBAAiB;AAE9B,IAAM,YAAY,oBAAI,IAAkB;AAEjC,IAAM,gBAAgB,CAAC,OAAkB,SAA4B;AAC1E,aAAW,YAAY,WAAW;AAChC,aAAS,OAAO,IAAI;AAAA,EACtB;AACF;AAEA,IAAI,0BAA0B;AAE9B,IAAM,wBAAwB,MAAY;AACxC,MAAI,wBAAyB;AAC7B,4BAA0B;AAE1B,SAAO,iBAAiB,WAAW,CAAC,UAAwB;AAC1D,QAAI,MAAM,QAAQ,cAAe;AAEjC,QAAI,MAAM,UAAU;AAClB,YAAM,SAAS,gBAAgB;AAC/B,YAAM,cAAc,QAAQ,YAAY;AACxC,oBAAc,SAAS,cAAc,OAAO,WAAW,IAAI,IAAI;AAAA,IACjE,OAAO;AACL,oBAAc,UAAU,IAAI;AAAA,IAC9B;AAAA,EACF,CAAC;AACH;AAMO,IAAM,eAAe,CAAC,aAAyC;AACpE,MAAI,CAAC,UAAU,GAAG;AAChB,WAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,YAAU,IAAI,QAAQ;AACtB,wBAAsB;AAEtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;AAGO,IAAM,QAAQ,OAAO,OAAe,aAAoC;AAC7E,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,MAAM,OAAO,UAAU,cAAc;AACrE,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,SAAS,OAAO,OAAe,UAAkB,SAAkD;AAC9G,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,WAAW,MAAM,OAAO,OAAO,OAAO,UAAU,IAAI;AAC1D,UAAM,OAAO,OAAO,QAAoB;AACxC,QAAI,SAAS,cAAc;AACzB,oBAAc,SAAS,IAAI;AAAA,IAC7B;AACA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,SAAS,YAA2B;AAC/C,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,cAAc,OAAO,YAAY;AACvC,QAAI,aAAa;AACf,YAAM,YAAY,OAAO;AAAA,IAC3B;AACA,kBAAc,UAAU,IAAI;AAAA,EAC9B,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,aAAa,CAAC,aAA4B;AACrD,MAAI,CAAC,UAAU,GAAG;AAChB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,QAAM,SAAS,UAAU;AAEzB,SAAO,SAAS,OAAO,OAAO,iBAAiB,QAAQ;AACvD,QAAM,IAAI,MAAM,+BAA+B;AACjD;AAaO,IAAM,qBAAqB,YAA4C;AAC5E,MAAI,CAAC,UAAU,EAAG,QAAO;AAEzB,QAAM,OAAO,OAAO,SAAS,KAAK,UAAU,CAAC;AAC7C,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,SAAS,IAAI,gBAAgB,IAAI;AAEvC,UAAM,cAAc,OAAO,IAAI,cAAc;AAC7C,QAAI,aAAa;AACf,YAAM,aAAa,MAAM,OAAO;AAAA,QAC9B;AAAA,UACE,cAAc;AAAA,UACd,YAAa,OAAO,IAAI,YAAY,KAAkB;AAAA,UACtD,YAAY,OAAO,OAAO,IAAI,YAAY,CAAC;AAAA,UAC3C,YAAY,OAAO,OAAO,IAAI,YAAY,CAAC;AAAA,UAC3C,eAAe,OAAO,IAAI,eAAe,KAAK;AAAA,QAChD;AAAA,QACA;AAAA,MACF;AACA,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,SAAS,KAAK;AAAA,IAC/B;AAEA,UAAM,oBAAoB,OAAO,IAAI,oBAAoB;AACzD,QAAI,mBAAmB;AACrB,YAAM,aAAa,MAAM,OAAO,QAAQ,mBAAmB,cAAc;AACzE,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,gBAAgB,KAAK;AAAA,IACtC;AAEA,UAAM,gBAAgB,OAAO,IAAI,gBAAgB;AACjD,QAAI,eAAe;AACjB,YAAM,aAAa,MAAM,OAAO,QAAQ,eAAe,cAAc;AACrE,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,SAAS,IAAI;AAC3B,aAAO,EAAE,MAAM,YAAY,KAAK;AAAA,IAClC;AAEA,UAAM,cAAc,OAAO,IAAI,cAAc;AAC7C,QAAI,aAAa;AACf,gBAAU;AACV,aAAO,EAAE,MAAM,UAAU,MAAM,MAAM,OAAO,YAAY;AAAA,IAC1D;AAEA,UAAM,mBAAmB,OAAO,IAAI,oBAAoB;AACxD,QAAI,kBAAkB;AACpB,YAAM,aAAa,MAAM,OAAO,OAAO,gBAAgB,kBAAkB,cAAc;AACvF,YAAM,OAAO,OAAO,UAAU;AAC9B,gBAAU;AACV,oBAAc,gBAAgB,IAAI;AAClC,aAAO,EAAE,MAAM,gBAAgB,KAAK;AAAA,IACtC;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAEA,IAAM,YAAY,MAAY;AAC5B,UAAQ,aAAa,MAAM,IAAI,OAAO,SAAS,WAAW,OAAO,SAAS,MAAM;AAClF;;;ACvMO,IAAM,0BAA0B,OAAO,UAAiC;AAC7E,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,OAAO,wBAAwB,KAAK;AAAA,EAC5C,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,kBAAkB,OAAO,OAAe,gBAAuC;AAC1F,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc;AAC7D,UAAM,cAAc,MAAM,WAAW,OAAO,EAAE,UAAU,YAAY,CAAC;AACrE,UAAM,OAAO,OAAO,WAAW;AAC/B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,eAAe,OAAO,UAAiC;AAClE,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,QAAQ,OAAO,cAAc;AAC7D,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,eAAe,OAAO,OAAe,aAAoC;AACpF,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,aAAa,OAAO,UAAU,cAAc;AAC5E,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,SAAS,IAAI;AAC3B,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,oBAAoB,OAAO,UAAiC;AACvE,QAAM,SAAS,UAAU;AAEzB,MAAI;AACF,UAAM,aAAa,MAAM,OAAO,OAAO,gBAAgB,OAAO,cAAc;AAC5E,UAAM,OAAO,OAAO,UAAU;AAC9B,kBAAc,gBAAgB,IAAI;AAClC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;AAGO,IAAM,aAAa,OAAO,YAAoD;AACnF,QAAM,SAAS,UAAU;AAEzB,QAAM,cAAc,OAAO,YAAY;AACvC,MAAI,CAAC,YAAa,OAAM,IAAI,UAAU,gCAAgC;AAEtE,MAAI;AACF,UAAM,cAAc,MAAM,YAAY,OAAO,OAAO;AACpD,UAAM,OAAO,OAAO,WAAW;AAC/B,kBAAc,gBAAgB,IAAI;AAClC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI,UAAW,MAAgB,SAAS,QAAW,EAAE,OAAO,MAAM,CAAC;AAAA,EAC3E;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/identity",
3
- "version": "0.1.0-alpha.9",
3
+ "version": "0.1.1-alpha.0",
4
4
  "type": "module",
5
5
  "description": "Add authentication to your Netlify site with a few lines of code",
6
6
  "main": "./dist/index.cjs",