@lushly-dev/afd-auth 0.3.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapters/better-auth.d.ts +68 -0
  3. package/dist/adapters/better-auth.d.ts.map +1 -0
  4. package/dist/adapters/better-auth.js +109 -0
  5. package/dist/adapters/better-auth.js.map +1 -0
  6. package/dist/adapters/convex.d.ts +28 -0
  7. package/dist/adapters/convex.d.ts.map +1 -0
  8. package/dist/adapters/convex.js +77 -0
  9. package/dist/adapters/convex.js.map +1 -0
  10. package/dist/adapters/mock.d.ts +29 -0
  11. package/dist/adapters/mock.d.ts.map +1 -0
  12. package/dist/adapters/mock.js +94 -0
  13. package/dist/adapters/mock.js.map +1 -0
  14. package/dist/commands.d.ts +15 -0
  15. package/dist/commands.d.ts.map +1 -0
  16. package/dist/commands.js +106 -0
  17. package/dist/commands.js.map +1 -0
  18. package/dist/errors.d.ts +23 -0
  19. package/dist/errors.d.ts.map +1 -0
  20. package/dist/errors.js +61 -0
  21. package/dist/errors.js.map +1 -0
  22. package/dist/index.d.ts +20 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +18 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/middleware.d.ts +18 -0
  27. package/dist/middleware.d.ts.map +1 -0
  28. package/dist/middleware.js +39 -0
  29. package/dist/middleware.js.map +1 -0
  30. package/dist/react.d.ts +18 -0
  31. package/dist/react.d.ts.map +1 -0
  32. package/dist/react.js +35 -0
  33. package/dist/react.js.map +1 -0
  34. package/dist/session-sync.d.ts +61 -0
  35. package/dist/session-sync.d.ts.map +1 -0
  36. package/dist/session-sync.js +183 -0
  37. package/dist/session-sync.js.map +1 -0
  38. package/dist/types.d.ts +61 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +25 -0
  41. package/dist/types.js.map +1 -0
  42. package/package.json +92 -0
package/dist/errors.js ADDED
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview Auth-specific error types
3
+ *
4
+ * Provides structured errors for authentication failures with
5
+ * retryable flags and static factory methods.
6
+ */
7
+ const RETRYABLE_CODES = new Set(['NETWORK_ERROR', 'REFRESH_FAILED']);
8
+ // ═══════════════════════════════════════════════════════════════════════════════
9
+ // AUTH ADAPTER ERROR
10
+ // ═══════════════════════════════════════════════════════════════════════════════
11
+ export class AuthAdapterError extends Error {
12
+ code;
13
+ suggestion;
14
+ retryable;
15
+ constructor(error) {
16
+ super(error.message);
17
+ this.name = 'AuthAdapterError';
18
+ this.code = error.code;
19
+ this.suggestion = error.suggestion;
20
+ this.retryable = RETRYABLE_CODES.has(error.code);
21
+ }
22
+ static invalidCredentials() {
23
+ return new AuthAdapterError({
24
+ code: 'INVALID_CREDENTIALS',
25
+ message: 'Invalid email or password',
26
+ suggestion: 'Check your credentials and try again',
27
+ });
28
+ }
29
+ static tokenExpired() {
30
+ return new AuthAdapterError({
31
+ code: 'TOKEN_EXPIRED',
32
+ message: 'Session has expired',
33
+ suggestion: 'Sign in again to continue',
34
+ });
35
+ }
36
+ static providerError(provider, details) {
37
+ const message = details
38
+ ? `Authentication provider '${provider}' error: ${details}`
39
+ : `Authentication provider '${provider}' encountered an error`;
40
+ return new AuthAdapterError({
41
+ code: 'PROVIDER_ERROR',
42
+ message,
43
+ suggestion: `Try again or use a different sign-in method`,
44
+ });
45
+ }
46
+ static networkError() {
47
+ return new AuthAdapterError({
48
+ code: 'NETWORK_ERROR',
49
+ message: 'Network request failed',
50
+ suggestion: 'Check your connection and try again',
51
+ });
52
+ }
53
+ static refreshFailed() {
54
+ return new AuthAdapterError({
55
+ code: 'REFRESH_FAILED',
56
+ message: 'Failed to refresh session',
57
+ suggestion: 'Sign in again to continue',
58
+ });
59
+ }
60
+ }
61
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAgB,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC,CAAC;AAEpF,kFAAkF;AAClF,qBAAqB;AACrB,kFAAkF;AAElF,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,IAAI,CAAgB;IACpB,UAAU,CAAS;IACnB,SAAS,CAAU;IAE5B,YAAY,KAIX;QACA,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,CAAC,kBAAkB;QACxB,OAAO,IAAI,gBAAgB,CAAC;YAC3B,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,2BAA2B;YACpC,UAAU,EAAE,sCAAsC;SAClD,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY;QAClB,OAAO,IAAI,gBAAgB,CAAC;YAC3B,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,qBAAqB;YAC9B,UAAU,EAAE,2BAA2B;SACvC,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,QAAgB,EAAE,OAAgB;QACtD,MAAM,OAAO,GAAG,OAAO;YACtB,CAAC,CAAC,4BAA4B,QAAQ,YAAY,OAAO,EAAE;YAC3D,CAAC,CAAC,4BAA4B,QAAQ,wBAAwB,CAAC;QAChE,OAAO,IAAI,gBAAgB,CAAC;YAC3B,IAAI,EAAE,gBAAgB;YACtB,OAAO;YACP,UAAU,EAAE,6CAA6C;SACzD,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY;QAClB,OAAO,IAAI,gBAAgB,CAAC;YAC3B,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,wBAAwB;YACjC,UAAU,EAAE,qCAAqC;SACjD,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,aAAa;QACnB,OAAO,IAAI,gBAAgB,CAAC;YAC3B,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,2BAA2B;YACpC,UAAU,EAAE,2BAA2B;SACvC,CAAC,CAAC;IACJ,CAAC;CACD"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview @lushly-dev/afd-auth - Provider-agnostic authentication adapter
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export type { BetterAuthAdapterOptions } from './adapters/better-auth.js';
7
+ export { BetterAuthAdapter } from './adapters/better-auth.js';
8
+ export type { ConvexAuthAdapterOptions } from './adapters/convex.js';
9
+ export { useConvexAuthAdapter } from './adapters/convex.js';
10
+ export type { MockAuthAdapterOptions } from './adapters/mock.js';
11
+ export { MockAuthAdapter } from './adapters/mock.js';
12
+ export { createAuthCommands } from './commands.js';
13
+ export type { AuthErrorCode } from './errors.js';
14
+ export { AuthAdapterError } from './errors.js';
15
+ export { createAuthMiddleware } from './middleware.js';
16
+ export type { SessionSyncOptions } from './session-sync.js';
17
+ export { SessionSync } from './session-sync.js';
18
+ export type { AuthAdapter, AuthSessionState, CredentialsSignInOptions, OAuthSignInOptions, Provider, Session, SignInOptions, User, } from './types.js';
19
+ export { LOADING, UNAUTHENTICATED } from './types.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,YAAY,EACX,WAAW,EACX,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,QAAQ,EACR,OAAO,EACP,aAAa,EACb,IAAI,GACJ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview @lushly-dev/afd-auth - Provider-agnostic authentication adapter
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ export { BetterAuthAdapter } from './adapters/better-auth.js';
7
+ export { useConvexAuthAdapter } from './adapters/convex.js';
8
+ // Adapters
9
+ export { MockAuthAdapter } from './adapters/mock.js';
10
+ // Commands
11
+ export { createAuthCommands } from './commands.js';
12
+ export { AuthAdapterError } from './errors.js';
13
+ // Middleware
14
+ export { createAuthMiddleware } from './middleware.js';
15
+ // Session sync
16
+ export { SessionSync } from './session-sync.js';
17
+ export { LOADING, UNAUTHENTICATED } from './types.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,WAAW;AACX,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,WAAW;AACX,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,aAAa;AACb,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAYhD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview Auth middleware for gating commands behind authentication
3
+ */
4
+ import type { CommandMiddleware } from '@lushly-dev/afd-core';
5
+ import type { AuthAdapter } from './types.js';
6
+ export interface AuthMiddlewareOptions {
7
+ /** Command names that bypass auth checks */
8
+ exclude?: string[];
9
+ }
10
+ /**
11
+ * Create middleware that gates commands behind authentication.
12
+ *
13
+ * - Unauthenticated → failure with UNAUTHORIZED
14
+ * - Loading → failure with UNAUTHORIZED (retryable)
15
+ * - Authenticated → injects `context.auth` and calls next()
16
+ */
17
+ export declare function createAuthMiddleware(adapter: AuthAdapter, options?: AuthMiddlewareOptions): CommandMiddleware;
18
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,WAAW,qBAAqB;IACrC,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,qBAA0B,GACjC,iBAAiB,CA+BnB"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Auth middleware for gating commands behind authentication
3
+ */
4
+ import { failure } from '@lushly-dev/afd-core';
5
+ /**
6
+ * Create middleware that gates commands behind authentication.
7
+ *
8
+ * - Unauthenticated → failure with UNAUTHORIZED
9
+ * - Loading → failure with UNAUTHORIZED (retryable)
10
+ * - Authenticated → injects `context.auth` and calls next()
11
+ */
12
+ export function createAuthMiddleware(adapter, options = {}) {
13
+ const excluded = new Set(options.exclude ?? []);
14
+ return async (commandName, _input, context, next) => {
15
+ if (excluded.has(commandName)) {
16
+ return next();
17
+ }
18
+ const state = adapter.getSession();
19
+ if (state.status === 'unauthenticated') {
20
+ return failure({
21
+ code: 'UNAUTHORIZED',
22
+ message: 'Authentication required',
23
+ suggestion: 'Sign in to access this command',
24
+ retryable: false,
25
+ });
26
+ }
27
+ if (state.status === 'loading') {
28
+ return failure({
29
+ code: 'UNAUTHORIZED',
30
+ message: 'Authentication state is loading',
31
+ suggestion: 'Wait for authentication to complete and try again',
32
+ retryable: true,
33
+ });
34
+ }
35
+ context.auth = state;
36
+ return next();
37
+ };
38
+ }
39
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAQ/C;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CACnC,OAAoB,EACpB,UAAiC,EAAE;IAEnC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAEhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACnD,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,EAAE,CAAC;QACf,CAAC;QAED,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC;gBACd,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,yBAAyB;gBAClC,UAAU,EAAE,gCAAgC;gBAC5C,SAAS,EAAE,KAAK;aAChB,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC;gBACd,IAAI,EAAE,cAAc;gBACpB,OAAO,EAAE,iCAAiC;gBAC1C,UAAU,EAAE,mDAAmD;gBAC/D,SAAS,EAAE,IAAI;aACf,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC;QACrB,OAAO,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview React hooks for AFD auth
3
+ *
4
+ * Sub-path export: import from '@lushly-dev/afd-auth/react'
5
+ */
6
+ import type { AuthAdapter, AuthSessionState, User } from './types.js';
7
+ export type { ConvexAuthAdapterOptions } from './adapters/convex.js';
8
+ export { useConvexAuthAdapter } from './adapters/convex.js';
9
+ export interface AuthHooks {
10
+ useAuth: () => AuthAdapter;
11
+ useSession: () => AuthSessionState;
12
+ useUser: () => User | null;
13
+ }
14
+ /**
15
+ * Create React hooks bound to an auth adapter instance.
16
+ */
17
+ export declare function createAuthHooks(adapter: AuthAdapter): AuthHooks;
18
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGtE,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,WAAW,CAAC;IAC3B,UAAU,EAAE,MAAM,gBAAgB,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CA4B/D"}
package/dist/react.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview React hooks for AFD auth
3
+ *
4
+ * Sub-path export: import from '@lushly-dev/afd-auth/react'
5
+ */
6
+ import { useCallback, useRef, useSyncExternalStore } from 'react';
7
+ import { LOADING } from './types.js';
8
+ export { useConvexAuthAdapter } from './adapters/convex.js';
9
+ /**
10
+ * Create React hooks bound to an auth adapter instance.
11
+ */
12
+ export function createAuthHooks(adapter) {
13
+ function useAuth() {
14
+ return adapter;
15
+ }
16
+ function useSession() {
17
+ const snapshotRef = useRef(adapter.getSession());
18
+ const subscribe = useCallback((onStoreChange) => {
19
+ const { unsubscribe } = adapter.onAuthStateChange((state) => {
20
+ snapshotRef.current = state;
21
+ onStoreChange();
22
+ });
23
+ return unsubscribe;
24
+ }, []);
25
+ const getSnapshot = useCallback(() => snapshotRef.current, []);
26
+ const getServerSnapshot = useCallback(() => LOADING, []);
27
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
28
+ }
29
+ function useUser() {
30
+ const session = useSession();
31
+ return session.status === 'authenticated' ? session.user : null;
32
+ }
33
+ return { useAuth, useSession, useUser };
34
+ }
35
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAElE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQ5D;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoB;IACnD,SAAS,OAAO;QACf,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,SAAS,UAAU;QAClB,MAAM,WAAW,GAAG,MAAM,CAAmB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAEnE,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,aAAyB,EAAE,EAAE;YAC3D,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC3D,WAAW,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC5B,aAAa,EAAE,CAAC;YACjB,CAAC,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACpB,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEzD,OAAO,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;IACxE,CAAC;IAED,SAAS,OAAO;QACf,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,MAAM,KAAK,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjE,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview Multi-tab session synchronization
3
+ *
4
+ * Uses BroadcastChannel (primary) with localStorage fallback.
5
+ * All browser APIs are guarded with typeof checks for SSR safety.
6
+ */
7
+ export interface SessionSyncOptions {
8
+ /** Channel name for BroadcastChannel (default: 'afd-auth-session') */
9
+ channelName?: string;
10
+ /** localStorage key for fallback sync (default: 'afd-auth-sync') */
11
+ storageKey?: string;
12
+ /** Lock key for refresh coordination (default: 'afd-auth-refresh-lock') */
13
+ lockKey?: string;
14
+ /** Lock timeout in ms (default: 10_000) */
15
+ lockTimeoutMs?: number;
16
+ /** Double-check delay for lock acquisition in ms (default: 50) */
17
+ lockCheckDelayMs?: number;
18
+ /** Debounce interval for state updates in ms (default: 100) */
19
+ debounceMs?: number;
20
+ /** Re-check session after tab hidden for this long in ms (default: 300_000 = 5 min) */
21
+ visibilityRefreshMs?: number;
22
+ }
23
+ export declare class SessionSync {
24
+ private readonly options;
25
+ private channel;
26
+ private listeners;
27
+ private debounceTimer;
28
+ private hiddenAt;
29
+ private visibilityHandler;
30
+ private storageHandler;
31
+ private disposed;
32
+ constructor(options?: SessionSyncOptions);
33
+ /**
34
+ * Broadcast a session change to other tabs.
35
+ */
36
+ notifySessionChanged(data: unknown): void;
37
+ /**
38
+ * Subscribe to session changes from other tabs.
39
+ */
40
+ onSessionChanged(callback: (data: unknown) => void): {
41
+ unsubscribe: () => void;
42
+ };
43
+ /**
44
+ * Attempt to acquire a refresh lock to coordinate token refresh across tabs.
45
+ * Returns true if lock was acquired, false if another tab holds it.
46
+ */
47
+ acquireRefreshLock(): boolean;
48
+ /**
49
+ * Release the refresh lock.
50
+ */
51
+ releaseRefreshLock(): void;
52
+ /**
53
+ * Clean up all resources.
54
+ */
55
+ dispose(): void;
56
+ private init;
57
+ private notifyViaStorage;
58
+ private debouncedNotify;
59
+ private hasLocalStorage;
60
+ }
61
+ //# sourceMappingURL=session-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-sync.d.ts","sourceRoot":"","sources":["../src/session-sync.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IAClC,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uFAAuF;IACvF,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAYD,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,aAAa,CAA8C;IACnE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,iBAAiB,CAA6B;IACtD,OAAO,CAAC,cAAc,CAA4C;IAClE,OAAO,CAAC,QAAQ,CAAS;gBAEb,OAAO,GAAE,kBAAuB;IAK5C;;OAEG;IACH,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAezC;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GAAG;QAAE,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE;IAShF;;;OAGG;IACH,kBAAkB,IAAI,OAAO;IAiB7B;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAK1B;;OAEG;IACH,OAAO,IAAI,IAAI;IA0Bf,OAAO,CAAC,IAAI;IA6CZ,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,eAAe;CAOvB"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * @fileoverview Multi-tab session synchronization
3
+ *
4
+ * Uses BroadcastChannel (primary) with localStorage fallback.
5
+ * All browser APIs are guarded with typeof checks for SSR safety.
6
+ */
7
+ const DEFAULTS = {
8
+ channelName: 'afd-auth-session',
9
+ storageKey: 'afd-auth-sync',
10
+ lockKey: 'afd-auth-refresh-lock',
11
+ lockTimeoutMs: 10_000,
12
+ lockCheckDelayMs: 50,
13
+ debounceMs: 100,
14
+ visibilityRefreshMs: 300_000,
15
+ };
16
+ export class SessionSync {
17
+ options;
18
+ channel = null;
19
+ listeners = new Set();
20
+ debounceTimer = null;
21
+ hiddenAt = null;
22
+ visibilityHandler = null;
23
+ storageHandler = null;
24
+ disposed = false;
25
+ constructor(options = {}) {
26
+ this.options = { ...DEFAULTS, ...options };
27
+ this.init();
28
+ }
29
+ /**
30
+ * Broadcast a session change to other tabs.
31
+ */
32
+ notifySessionChanged(data) {
33
+ if (this.disposed)
34
+ return;
35
+ if (this.channel) {
36
+ try {
37
+ this.channel.postMessage(data);
38
+ return;
39
+ }
40
+ catch {
41
+ // Fall through to localStorage
42
+ }
43
+ }
44
+ this.notifyViaStorage(data);
45
+ }
46
+ /**
47
+ * Subscribe to session changes from other tabs.
48
+ */
49
+ onSessionChanged(callback) {
50
+ this.listeners.add(callback);
51
+ return {
52
+ unsubscribe: () => {
53
+ this.listeners.delete(callback);
54
+ },
55
+ };
56
+ }
57
+ /**
58
+ * Attempt to acquire a refresh lock to coordinate token refresh across tabs.
59
+ * Returns true if lock was acquired, false if another tab holds it.
60
+ */
61
+ acquireRefreshLock() {
62
+ if (!this.hasLocalStorage())
63
+ return true;
64
+ const now = Date.now();
65
+ const existing = localStorage.getItem(this.options.lockKey);
66
+ if (existing) {
67
+ const timestamp = Number.parseInt(existing, 10);
68
+ if (now - timestamp < this.options.lockTimeoutMs) {
69
+ return false; // Another tab holds a valid lock
70
+ }
71
+ }
72
+ localStorage.setItem(this.options.lockKey, String(now));
73
+ return true;
74
+ }
75
+ /**
76
+ * Release the refresh lock.
77
+ */
78
+ releaseRefreshLock() {
79
+ if (!this.hasLocalStorage())
80
+ return;
81
+ localStorage.removeItem(this.options.lockKey);
82
+ }
83
+ /**
84
+ * Clean up all resources.
85
+ */
86
+ dispose() {
87
+ this.disposed = true;
88
+ if (this.debounceTimer !== null) {
89
+ clearTimeout(this.debounceTimer);
90
+ this.debounceTimer = null;
91
+ }
92
+ if (this.channel) {
93
+ this.channel.close();
94
+ this.channel = null;
95
+ }
96
+ if (this.storageHandler && typeof window !== 'undefined') {
97
+ window.removeEventListener('storage', this.storageHandler);
98
+ this.storageHandler = null;
99
+ }
100
+ if (this.visibilityHandler && typeof document !== 'undefined') {
101
+ document.removeEventListener('visibilitychange', this.visibilityHandler);
102
+ this.visibilityHandler = null;
103
+ }
104
+ this.listeners.clear();
105
+ }
106
+ init() {
107
+ // Try BroadcastChannel first
108
+ if (typeof BroadcastChannel !== 'undefined') {
109
+ try {
110
+ this.channel = new BroadcastChannel(this.options.channelName);
111
+ this.channel.onmessage = (event) => {
112
+ this.debouncedNotify(event.data);
113
+ };
114
+ }
115
+ catch {
116
+ // BroadcastChannel unavailable, fall through to localStorage
117
+ }
118
+ }
119
+ // localStorage fallback for storage events
120
+ if (!this.channel && this.hasLocalStorage() && typeof window !== 'undefined') {
121
+ this.storageHandler = (e) => {
122
+ if (e.key === this.options.storageKey && e.newValue) {
123
+ try {
124
+ const data = JSON.parse(e.newValue);
125
+ this.debouncedNotify(data);
126
+ }
127
+ catch {
128
+ // Ignore malformed data
129
+ }
130
+ }
131
+ };
132
+ window.addEventListener('storage', this.storageHandler);
133
+ }
134
+ // Visibility change handler
135
+ if (typeof document !== 'undefined') {
136
+ this.visibilityHandler = () => {
137
+ if (document.visibilityState === 'hidden') {
138
+ this.hiddenAt = Date.now();
139
+ }
140
+ else if (document.visibilityState === 'visible' && this.hiddenAt !== null) {
141
+ const elapsed = Date.now() - this.hiddenAt;
142
+ this.hiddenAt = null;
143
+ if (elapsed >= this.options.visibilityRefreshMs) {
144
+ this.debouncedNotify({ type: 'visibility-refresh' });
145
+ }
146
+ }
147
+ };
148
+ document.addEventListener('visibilitychange', this.visibilityHandler);
149
+ }
150
+ }
151
+ notifyViaStorage(data) {
152
+ if (!this.hasLocalStorage())
153
+ return;
154
+ try {
155
+ localStorage.setItem(this.options.storageKey, JSON.stringify(data));
156
+ // Clean up immediately — the storage event fires in other tabs
157
+ localStorage.removeItem(this.options.storageKey);
158
+ }
159
+ catch {
160
+ // localStorage full or unavailable
161
+ }
162
+ }
163
+ debouncedNotify(data) {
164
+ if (this.debounceTimer !== null) {
165
+ clearTimeout(this.debounceTimer);
166
+ }
167
+ this.debounceTimer = setTimeout(() => {
168
+ this.debounceTimer = null;
169
+ for (const listener of this.listeners) {
170
+ listener(data);
171
+ }
172
+ }, this.options.debounceMs);
173
+ }
174
+ hasLocalStorage() {
175
+ try {
176
+ return typeof localStorage !== 'undefined';
177
+ }
178
+ catch {
179
+ return false;
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=session-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-sync.js","sourceRoot":"","sources":["../src/session-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview Core auth types for AFD authentication adapter
3
+ *
4
+ * Uses discriminated unions for type-safe session access.
5
+ * Consumers check `status` before accessing `user` — TypeScript enforces this at compile time.
6
+ */
7
+ export interface Session {
8
+ id: string;
9
+ expiresAt: Date;
10
+ }
11
+ export interface User {
12
+ id: string;
13
+ email: string;
14
+ name?: string;
15
+ image?: string;
16
+ }
17
+ export type Provider = 'github' | 'google' | 'email' | (string & {});
18
+ export interface CredentialsSignInOptions {
19
+ method: 'credentials';
20
+ email: string;
21
+ password?: string;
22
+ }
23
+ export interface OAuthSignInOptions {
24
+ method: 'oauth';
25
+ provider: Provider;
26
+ scopes?: string[];
27
+ redirectTo?: string;
28
+ }
29
+ export type SignInOptions = CredentialsSignInOptions | OAuthSignInOptions;
30
+ export type AuthSessionState = {
31
+ status: 'unauthenticated';
32
+ session: null;
33
+ user: null;
34
+ } | {
35
+ status: 'loading';
36
+ session: null;
37
+ user: null;
38
+ } | {
39
+ status: 'authenticated';
40
+ session: Session;
41
+ user: User;
42
+ };
43
+ /**
44
+ * Constant for the unauthenticated state.
45
+ * Reuse this to avoid object allocation on every check.
46
+ */
47
+ export declare const UNAUTHENTICATED: AuthSessionState;
48
+ /**
49
+ * Constant for the loading state.
50
+ * Reuse this to avoid object allocation on every check.
51
+ */
52
+ export declare const LOADING: AuthSessionState;
53
+ export interface AuthAdapter {
54
+ signIn(options: SignInOptions): Promise<void>;
55
+ signOut(): Promise<void>;
56
+ getSession(): AuthSessionState;
57
+ onAuthStateChange(callback: (state: AuthSessionState) => void): {
58
+ unsubscribe: () => void;
59
+ };
60
+ }
61
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,OAAO;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,IAAI;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAMD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErE,MAAM,WAAW,wBAAwB;IACxC,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,wBAAwB,GAAG,kBAAkB,CAAC;AAM1E,MAAM,MAAM,gBAAgB,GACzB;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GACxD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,CAAC;AAE7D;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,gBAI5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,gBAIpB,CAAC;AAMH,MAAM,WAAW,WAAW;IAC3B,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,IAAI,gBAAgB,CAAC;IAC/B,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG;QAAE,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAC5F"}
package/dist/types.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @fileoverview Core auth types for AFD authentication adapter
3
+ *
4
+ * Uses discriminated unions for type-safe session access.
5
+ * Consumers check `status` before accessing `user` — TypeScript enforces this at compile time.
6
+ */
7
+ /**
8
+ * Constant for the unauthenticated state.
9
+ * Reuse this to avoid object allocation on every check.
10
+ */
11
+ export const UNAUTHENTICATED = Object.freeze({
12
+ status: 'unauthenticated',
13
+ session: null,
14
+ user: null,
15
+ });
16
+ /**
17
+ * Constant for the loading state.
18
+ * Reuse this to avoid object allocation on every check.
19
+ */
20
+ export const LOADING = Object.freeze({
21
+ status: 'loading',
22
+ session: null,
23
+ user: null,
24
+ });
25
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgDH;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAqB,MAAM,CAAC,MAAM,CAAC;IAC9D,MAAM,EAAE,iBAA0B;IAClC,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;CACV,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAqB,MAAM,CAAC,MAAM,CAAC;IACtD,MAAM,EAAE,SAAkB;IAC1B,OAAO,EAAE,IAAI;IACb,IAAI,EAAE,IAAI;CACV,CAAC,CAAC"}