@lushly-dev/afd-auth 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +134 -0
  2. package/dist/adapters/better-auth.d.ts +34 -6
  3. package/dist/adapters/better-auth.d.ts.map +1 -1
  4. package/dist/adapters/better-auth.js +73 -25
  5. package/dist/adapters/better-auth.js.map +1 -1
  6. package/dist/adapters/convex.d.ts +29 -6
  7. package/dist/adapters/convex.d.ts.map +1 -1
  8. package/dist/adapters/convex.js +139 -56
  9. package/dist/adapters/convex.js.map +1 -1
  10. package/dist/adapters/mock.d.ts +16 -4
  11. package/dist/adapters/mock.d.ts.map +1 -1
  12. package/dist/adapters/mock.js +13 -11
  13. package/dist/adapters/mock.js.map +1 -1
  14. package/dist/adapters/provider-errors.d.ts +16 -0
  15. package/dist/adapters/provider-errors.d.ts.map +1 -0
  16. package/dist/adapters/provider-errors.js +27 -0
  17. package/dist/adapters/provider-errors.js.map +1 -0
  18. package/dist/command-names.d.ts +13 -0
  19. package/dist/command-names.d.ts.map +1 -0
  20. package/dist/command-names.js +13 -0
  21. package/dist/command-names.js.map +1 -0
  22. package/dist/commands.d.ts +11 -2
  23. package/dist/commands.d.ts.map +1 -1
  24. package/dist/commands.js +141 -9
  25. package/dist/commands.js.map +1 -1
  26. package/dist/index.d.ts +5 -4
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -6
  29. package/dist/index.js.map +1 -1
  30. package/dist/listeners.d.ts +39 -0
  31. package/dist/listeners.d.ts.map +1 -0
  32. package/dist/listeners.js +72 -0
  33. package/dist/listeners.js.map +1 -0
  34. package/dist/middleware.d.ts +22 -3
  35. package/dist/middleware.d.ts.map +1 -1
  36. package/dist/middleware.js +32 -14
  37. package/dist/middleware.js.map +1 -1
  38. package/dist/react.d.ts.map +1 -1
  39. package/dist/react.js +19 -5
  40. package/dist/react.js.map +1 -1
  41. package/dist/session-state.d.ts +19 -0
  42. package/dist/session-state.d.ts.map +1 -0
  43. package/dist/session-state.js +42 -0
  44. package/dist/session-state.js.map +1 -0
  45. package/dist/session-sync-message.d.ts +29 -0
  46. package/dist/session-sync-message.d.ts.map +1 -0
  47. package/dist/session-sync-message.js +27 -0
  48. package/dist/session-sync-message.js.map +1 -0
  49. package/dist/session-sync.d.ts +35 -8
  50. package/dist/session-sync.d.ts.map +1 -1
  51. package/dist/session-sync.js +178 -44
  52. package/dist/session-sync.js.map +1 -1
  53. package/dist/types.d.ts +35 -2
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/types.js.map +1 -1
  56. package/package.json +21 -15
package/dist/commands.js CHANGED
@@ -3,20 +3,24 @@
3
3
  *
4
4
  * Requires optional peer dependencies: @lushly-dev/afd-server, zod
5
5
  */
6
- import { failure, success } from '@lushly-dev/afd-core';
7
- import { defineCommand } from '@lushly-dev/afd-server';
6
+ // The transport-free entry keeps this module free of the MCP SDK and Node builtins.
7
+ import { defineCommand, failure, success, } from '@lushly-dev/afd-server/define';
8
8
  import { z } from 'zod';
9
9
  import { AuthAdapterError } from './errors.js';
10
+ import { areSessionStatesEqual } from './session-state.js';
11
+ const DEFAULT_SIGN_IN_TIMEOUT_MS = 10_000;
12
+ const SESSION_GET_SUGGESTION = 'Call auth-session-get to check whether the session is active';
10
13
  /**
11
14
  * Create AFD command definitions for auth operations.
12
15
  *
13
16
  * Returns ZodCommandDefinition[] that can be passed directly to `createMcpServer`.
14
17
  * Requires `@lushly-dev/afd-server` and `zod` as peer dependencies.
15
18
  */
16
- export function createAuthCommands(adapter) {
19
+ export function createAuthCommands(adapter, options = {}) {
20
+ const signInTimeoutMs = options.signInTimeoutMs ?? DEFAULT_SIGN_IN_TIMEOUT_MS;
17
21
  const signIn = defineCommand({
18
22
  name: 'auth-sign-in',
19
- description: 'Sign in with credentials or OAuth provider',
23
+ description: 'Sign in with credentials or OAuth provider. Returns the new session, or the current state with a warning when sign-in continues at the provider (redirect) or has not completed yet.',
20
24
  category: 'auth',
21
25
  tags: ['auth', 'session'],
22
26
  mutation: true,
@@ -35,12 +39,16 @@ export function createAuthCommands(adapter) {
35
39
  }),
36
40
  ]),
37
41
  async handler(input) {
42
+ const before = adapter.getSession();
43
+ // Subscribe before signIn() so a state change it triggers is not missed.
44
+ const watcher = watchAuthState(adapter);
38
45
  try {
39
- await adapter.signIn(input);
40
- const session = adapter.getSession();
41
- return success(session, {
42
- reasoning: `Signed in via ${input.method}`,
43
- });
46
+ const outcome = toOutcome(await adapter.signIn(input));
47
+ if (outcome?.kind === 'redirect' || outcome?.kind === 'pending') {
48
+ return incompleteSignIn(adapter.getSession(), input, outcome);
49
+ }
50
+ const settled = await watcher.settle(before, signInTimeoutMs);
51
+ return settledSignIn(adapter.getSession(), settled, input, signInTimeoutMs);
44
52
  }
45
53
  catch (error) {
46
54
  if (error instanceof AuthAdapterError) {
@@ -53,6 +61,9 @@ export function createAuthCommands(adapter) {
53
61
  }
54
62
  throw error;
55
63
  }
64
+ finally {
65
+ watcher.stop();
66
+ }
56
67
  },
57
68
  });
58
69
  const signOut = defineCommand({
@@ -103,4 +114,125 @@ export function createAuthCommands(adapter) {
103
114
  // Cast needed for heterogeneous generic command arrays (same pattern as todo example)
104
115
  return [signIn, signOut, sessionGet];
105
116
  }
117
+ // ═══════════════════════════════════════════════════════════════════════════════
118
+ // SIGN-IN RESULT
119
+ // ═══════════════════════════════════════════════════════════════════════════════
120
+ function describeMethod(input) {
121
+ return input.method === 'oauth' ? input.provider : 'credentials';
122
+ }
123
+ /**
124
+ * Read the adapter's sign-in outcome. Adapters written before SignInOutcome
125
+ * resolve with nothing, and untyped ones may resolve with a provider
126
+ * response; neither counts as an outcome.
127
+ */
128
+ function toOutcome(value) {
129
+ if (typeof value !== 'object' || value === null || !('kind' in value))
130
+ return undefined;
131
+ switch (value.kind) {
132
+ case 'signed-in':
133
+ return { kind: 'signed-in' };
134
+ case 'pending':
135
+ return { kind: 'pending' };
136
+ case 'redirect':
137
+ return 'url' in value && typeof value.url === 'string'
138
+ ? { kind: 'redirect', url: value.url }
139
+ : { kind: 'redirect' };
140
+ default:
141
+ return undefined;
142
+ }
143
+ }
144
+ function incompleteSignIn(state, input, outcome) {
145
+ const via = describeMethod(input);
146
+ if (outcome.kind === 'redirect') {
147
+ return success(state, {
148
+ reasoning: `Not signed in yet: sign-in via ${via} continues at the provider, and the session starts after the provider redirects back`,
149
+ warnings: [
150
+ {
151
+ code: 'SIGN_IN_REDIRECT',
152
+ message: `Sign-in via ${via} continues at the provider`,
153
+ severity: 'info',
154
+ ...(outcome.url === undefined ? {} : { details: { url: outcome.url } }),
155
+ },
156
+ ],
157
+ suggestions: [
158
+ 'Complete sign-in at the provider',
159
+ 'After the provider redirects back, call auth-session-get to confirm the session',
160
+ ],
161
+ });
162
+ }
163
+ return success(state, {
164
+ reasoning: `Not signed in yet: sign-in via ${via} needs another step, such as email verification, before a session exists`,
165
+ warnings: [
166
+ {
167
+ code: 'SIGN_IN_PENDING',
168
+ message: `Sign-in via ${via} needs another step before a session exists`,
169
+ severity: 'warning',
170
+ },
171
+ ],
172
+ suggestions: ["Complete the provider's verification step", SESSION_GET_SUGGESTION],
173
+ });
174
+ }
175
+ function settledSignIn(current, settled, input, timeoutMs) {
176
+ const via = describeMethod(input);
177
+ const state = settled ?? current;
178
+ if (state.status === 'authenticated') {
179
+ return success(state, {
180
+ reasoning: `Signed in via ${via} as ${state.user.email}`,
181
+ });
182
+ }
183
+ if (settled?.status === 'unauthenticated') {
184
+ return failure({
185
+ code: 'PROVIDER_ERROR',
186
+ message: `Sign-in via ${via} completed, but the provider reports no active session`,
187
+ suggestion: 'Check that the provider can store its session (cookies or tokens) in this environment, then sign in again',
188
+ retryable: false,
189
+ });
190
+ }
191
+ return success(current, {
192
+ reasoning: `Not signed in yet: the sign-in via ${via} was accepted, but no session was confirmed within ${timeoutMs} ms (status: ${current.status})`,
193
+ warnings: [
194
+ {
195
+ code: 'SIGN_IN_PENDING',
196
+ message: `No session confirmed within ${timeoutMs} ms of sign-in`,
197
+ severity: 'warning',
198
+ },
199
+ ],
200
+ suggestions: [SESSION_GET_SUGGESTION],
201
+ });
202
+ }
203
+ function watchAuthState(adapter) {
204
+ let changed = false;
205
+ let onSettled = null;
206
+ const subscription = adapter.onAuthStateChange((state) => {
207
+ changed = true;
208
+ if (state.status !== 'loading' && onSettled) {
209
+ const resolve = onSettled;
210
+ onSettled = null;
211
+ resolve(state);
212
+ }
213
+ });
214
+ return {
215
+ settle(before, timeoutMs) {
216
+ const current = adapter.getSession();
217
+ if (current.status === 'authenticated' &&
218
+ (changed || !areSessionStatesEqual(before, current))) {
219
+ return Promise.resolve(current);
220
+ }
221
+ return new Promise((resolve) => {
222
+ const timer = setTimeout(() => {
223
+ onSettled = null;
224
+ resolve(null);
225
+ }, timeoutMs);
226
+ onSettled = (state) => {
227
+ clearTimeout(timer);
228
+ resolve(state);
229
+ };
230
+ });
231
+ },
232
+ stop() {
233
+ onSettled = null;
234
+ subscription.unsubscribe();
235
+ },
236
+ };
237
+ }
106
238
  //# sourceMappingURL=commands.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -5,16 +5,17 @@
5
5
  */
6
6
  export type { BetterAuthAdapterOptions } from './adapters/better-auth.js';
7
7
  export { BetterAuthAdapter } from './adapters/better-auth.js';
8
- export type { ConvexAuthAdapterOptions } from './adapters/convex.js';
9
- export { useConvexAuthAdapter } from './adapters/convex.js';
10
8
  export type { MockAuthAdapterOptions } from './adapters/mock.js';
11
9
  export { MockAuthAdapter } from './adapters/mock.js';
12
- export { createAuthCommands } from './commands.js';
10
+ export { AUTH_COMMAND_NAMES } from './command-names.js';
13
11
  export type { AuthErrorCode } from './errors.js';
14
12
  export { AuthAdapterError } from './errors.js';
13
+ export type { ListenerErrorHandler } from './listeners.js';
14
+ export type { AuthMiddlewareOptions } from './middleware.js';
15
15
  export { createAuthMiddleware } from './middleware.js';
16
16
  export type { SessionSyncOptions } from './session-sync.js';
17
17
  export { SessionSync } from './session-sync.js';
18
- export type { AuthAdapter, AuthSessionState, CredentialsSignInOptions, OAuthSignInOptions, Provider, Session, SignInOptions, User, } from './types.js';
18
+ export type { SessionSyncMessage, SessionSyncMessageType } from './session-sync-message.js';
19
+ export type { AuthAdapter, AuthenticatedSessionState, AuthSessionState, CredentialsSignInOptions, OAuthSignInOptions, Provider, Session, SignInOptions, SignInOutcome, User, } from './types.js';
19
20
  export { LOADING, UNAUTHENTICATED } from './types.js';
20
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAE5F,YAAY,EACX,WAAW,EACX,yBAAyB,EACzB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,QAAQ,EACR,OAAO,EACP,aAAa,EACb,aAAa,EACb,IAAI,GACJ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -4,15 +4,11 @@
4
4
  * @packageDocumentation
5
5
  */
6
6
  export { BetterAuthAdapter } from './adapters/better-auth.js';
7
- export { useConvexAuthAdapter } from './adapters/convex.js';
8
- // Adapters
9
7
  export { MockAuthAdapter } from './adapters/mock.js';
10
- // Commands
11
- export { createAuthCommands } from './commands.js';
8
+ // Built-in command names (always allowed by the middleware)
9
+ export { AUTH_COMMAND_NAMES } from './command-names.js';
12
10
  export { AuthAdapterError } from './errors.js';
13
- // Middleware
14
11
  export { createAuthMiddleware } from './middleware.js';
15
- // Session sync
16
12
  export { SessionSync } from './session-sync.js';
17
13
  export { LOADING, UNAUTHENTICATED } from './types.js';
18
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,4DAA4D;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAehD,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Listener fan-out with per-listener error isolation
3
+ *
4
+ * Shared by every adapter and by SessionSync so that one throwing subscriber
5
+ * cannot stop later subscribers from seeing a state change (for example a
6
+ * sign-out), and cannot make the operation that triggered the change reject.
7
+ */
8
+ /**
9
+ * Receives an error thrown by a subscriber. When no handler is configured the
10
+ * error is rethrown in a microtask, so it still reaches the host's uncaught
11
+ * error reporting (`window.onerror`, `process.on('uncaughtException')`).
12
+ */
13
+ export type ListenerErrorHandler = (error: unknown) => void;
14
+ /**
15
+ * Report a subscriber error without interrupting the caller.
16
+ *
17
+ * The error goes to `onListenerError` when one is given. If there is none, or
18
+ * the handler itself throws, the error is rethrown asynchronously.
19
+ */
20
+ export declare function reportListenerError(error: unknown, onListenerError?: ListenerErrorHandler): void;
21
+ /**
22
+ * A set of subscribers that are each called in isolation.
23
+ */
24
+ export declare class ListenerSet<T> {
25
+ private readonly listeners;
26
+ private readonly onListenerError;
27
+ constructor(onListenerError?: ListenerErrorHandler);
28
+ get size(): number;
29
+ add(listener: (value: T) => void): {
30
+ unsubscribe: () => void;
31
+ };
32
+ /**
33
+ * Call every subscriber with `value`. A subscriber that throws is reported
34
+ * and skipped; the remaining subscribers still run and `emit` never throws.
35
+ */
36
+ emit(value: T): void;
37
+ clear(): void;
38
+ }
39
+ //# sourceMappingURL=listeners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listeners.d.ts","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,eAAe,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAahG;AAED;;GAEG;AACH,qBAAa,WAAW,CAAC,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;IAC3D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;gBAEvD,eAAe,CAAC,EAAE,oBAAoB;IAIlD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG;QAAE,WAAW,EAAE,MAAM,IAAI,CAAA;KAAE;IAS9D;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAcpB,KAAK,IAAI,IAAI;CAGb"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @fileoverview Listener fan-out with per-listener error isolation
3
+ *
4
+ * Shared by every adapter and by SessionSync so that one throwing subscriber
5
+ * cannot stop later subscribers from seeing a state change (for example a
6
+ * sign-out), and cannot make the operation that triggered the change reject.
7
+ */
8
+ /**
9
+ * Report a subscriber error without interrupting the caller.
10
+ *
11
+ * The error goes to `onListenerError` when one is given. If there is none, or
12
+ * the handler itself throws, the error is rethrown asynchronously.
13
+ */
14
+ export function reportListenerError(error, onListenerError) {
15
+ let unhandled = error;
16
+ if (onListenerError) {
17
+ try {
18
+ onListenerError(error);
19
+ return;
20
+ }
21
+ catch (handlerError) {
22
+ unhandled = handlerError;
23
+ }
24
+ }
25
+ queueMicrotask(() => {
26
+ throw unhandled;
27
+ });
28
+ }
29
+ /**
30
+ * A set of subscribers that are each called in isolation.
31
+ */
32
+ export class ListenerSet {
33
+ listeners = new Set();
34
+ onListenerError;
35
+ constructor(onListenerError) {
36
+ this.onListenerError = onListenerError;
37
+ }
38
+ get size() {
39
+ return this.listeners.size;
40
+ }
41
+ add(listener) {
42
+ this.listeners.add(listener);
43
+ return {
44
+ unsubscribe: () => {
45
+ this.listeners.delete(listener);
46
+ },
47
+ };
48
+ }
49
+ /**
50
+ * Call every subscriber with `value`. A subscriber that throws is reported
51
+ * and skipped; the remaining subscribers still run and `emit` never throws.
52
+ */
53
+ emit(value) {
54
+ // Iterate a snapshot so a subscriber added during this emit waits for the
55
+ // next one, and re-check membership so a subscriber removed by an earlier
56
+ // one is not called.
57
+ for (const listener of Array.from(this.listeners)) {
58
+ if (!this.listeners.has(listener))
59
+ continue;
60
+ try {
61
+ listener(value);
62
+ }
63
+ catch (error) {
64
+ reportListenerError(error, this.onListenerError);
65
+ }
66
+ }
67
+ }
68
+ clear() {
69
+ this.listeners.clear();
70
+ }
71
+ }
72
+ //# sourceMappingURL=listeners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listeners.js","sourceRoot":"","sources":["../src/listeners.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAc,EAAE,eAAsC;IACzF,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,eAAe,EAAE,CAAC;QACrB,IAAI,CAAC;YACJ,eAAe,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACR,CAAC;QAAC,OAAO,YAAY,EAAE,CAAC;YACvB,SAAS,GAAG,YAAY,CAAC;QAC1B,CAAC;IACF,CAAC;IACD,cAAc,CAAC,GAAG,EAAE;QACnB,MAAM,SAAS,CAAC;IACjB,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,WAAW;IACN,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC1C,eAAe,CAAmC;IAEnE,YAAY,eAAsC;QACjD,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;IACxC,CAAC;IAED,IAAI,IAAI;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,GAAG,CAAC,QAA4B;QAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO;YACN,WAAW,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,CAAC;SACD,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAI,CAAC,KAAQ;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qBAAqB;QACrB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC5C,IAAI,CAAC;gBACJ,QAAQ,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YAClD,CAAC;QACF,CAAC;IACF,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACD"}
@@ -2,9 +2,24 @@
2
2
  * @fileoverview Auth middleware for gating commands behind authentication
3
3
  */
4
4
  import type { CommandMiddleware } from '@lushly-dev/afd-core';
5
- import type { AuthAdapter } from './types.js';
5
+ import type { AuthAdapter, AuthenticatedSessionState } from './types.js';
6
+ declare module '@lushly-dev/afd-core' {
7
+ interface CommandContext {
8
+ /**
9
+ * The verified, unexpired session, set by `createAuthMiddleware`.
10
+ *
11
+ * The middleware sets or deletes this on every call, excluded commands
12
+ * included, so a value supplied by the caller never reaches a handler.
13
+ */
14
+ auth?: AuthenticatedSessionState;
15
+ }
16
+ }
6
17
  export interface AuthMiddlewareOptions {
7
- /** Command names that bypass auth checks */
18
+ /**
19
+ * Command names that bypass auth checks. The built-in auth commands
20
+ * (`auth-sign-in`, `auth-sign-out`, `auth-session-get`) always bypass them
21
+ * and do not need to be listed.
22
+ */
8
23
  exclude?: string[];
9
24
  }
10
25
  /**
@@ -12,7 +27,11 @@ export interface AuthMiddlewareOptions {
12
27
  *
13
28
  * - Unauthenticated → failure with UNAUTHORIZED
14
29
  * - Loading → failure with UNAUTHORIZED (retryable)
15
- * - Authenticated → injects `context.auth` and calls next()
30
+ * - Authenticated but `expiresAt` reached → failure with TOKEN_EXPIRED (retryable)
31
+ * - Authenticated → sets `context.auth` and calls next()
32
+ *
33
+ * Excluded commands, and the built-in auth commands, always run. They see
34
+ * `context.auth` only when the adapter holds an unexpired session.
16
35
  */
17
36
  export declare function createAuthMiddleware(adapter: AuthAdapter, options?: AuthMiddlewareOptions): CommandMiddleware;
18
37
  //# sourceMappingURL=middleware.d.ts.map
@@ -1 +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"}
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;AAI9D,OAAO,KAAK,EAAE,WAAW,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEzE,OAAO,QAAQ,sBAAsB,CAAC;IACrC,UAAU,cAAc;QACvB;;;;;WAKG;QACH,IAAI,CAAC,EAAE,yBAAyB,CAAC;KACjC;CACD;AAED,MAAM,WAAW,qBAAqB;IACrC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,qBAA0B,GACjC,iBAAiB,CA6CnB"}
@@ -2,27 +2,33 @@
2
2
  * @fileoverview Auth middleware for gating commands behind authentication
3
3
  */
4
4
  import { failure } from '@lushly-dev/afd-core';
5
+ import { AUTH_COMMAND_NAMES } from './command-names.js';
6
+ import { isSessionExpired } from './session-state.js';
5
7
  /**
6
8
  * Create middleware that gates commands behind authentication.
7
9
  *
8
10
  * - Unauthenticated → failure with UNAUTHORIZED
9
11
  * - Loading → failure with UNAUTHORIZED (retryable)
10
- * - Authenticated → injects `context.auth` and calls next()
12
+ * - Authenticated but `expiresAt` reached → failure with TOKEN_EXPIRED (retryable)
13
+ * - Authenticated → sets `context.auth` and calls next()
14
+ *
15
+ * Excluded commands, and the built-in auth commands, always run. They see
16
+ * `context.auth` only when the adapter holds an unexpired session.
11
17
  */
12
18
  export function createAuthMiddleware(adapter, options = {}) {
13
- const excluded = new Set(options.exclude ?? []);
19
+ const excluded = new Set([...AUTH_COMMAND_NAMES, ...(options.exclude ?? [])]);
14
20
  return async (commandName, _input, context, next) => {
15
- if (excluded.has(commandName)) {
16
- return next();
17
- }
18
21
  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
- });
22
+ const verified = state.status === 'authenticated' && !isSessionExpired(state.session) ? state : undefined;
23
+ // Overwrite or remove whatever the caller put in the context.
24
+ if (verified) {
25
+ context.auth = verified;
26
+ }
27
+ else {
28
+ delete context.auth;
29
+ }
30
+ if (excluded.has(commandName) || verified) {
31
+ return next();
26
32
  }
27
33
  if (state.status === 'loading') {
28
34
  return failure({
@@ -32,8 +38,20 @@ export function createAuthMiddleware(adapter, options = {}) {
32
38
  retryable: true,
33
39
  });
34
40
  }
35
- context.auth = state;
36
- return next();
41
+ if (state.status === 'authenticated') {
42
+ return failure({
43
+ code: 'TOKEN_EXPIRED',
44
+ message: 'Session has expired',
45
+ suggestion: 'Try again once the auth provider has refreshed the session, or sign in again with auth-sign-in',
46
+ retryable: true,
47
+ });
48
+ }
49
+ return failure({
50
+ code: 'UNAUTHORIZED',
51
+ message: 'Authentication required',
52
+ suggestion: 'Sign in with auth-sign-in to access this command',
53
+ retryable: false,
54
+ });
37
55
  };
38
56
  }
39
57
  //# sourceMappingURL=middleware.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAwBtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CACnC,OAAoB,EACpB,UAAiC,EAAE;IAEnC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACnD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,QAAQ,GACb,KAAK,CAAC,MAAM,KAAK,eAAe,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,8DAA8D;QAC9D,IAAI,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;QACzB,CAAC;aAAM,CAAC;YACP,OAAO,OAAO,CAAC,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC3C,OAAO,IAAI,EAAE,CAAC;QACf,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,IAAI,KAAK,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;YACtC,OAAO,OAAO,CAAC;gBACd,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,qBAAqB;gBAC9B,UAAU,EACT,gGAAgG;gBACjG,SAAS,EAAE,IAAI;aACf,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC;YACd,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,yBAAyB;YAClC,UAAU,EAAE,kDAAkD;YAC9D,SAAS,EAAE,KAAK;SAChB,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC"}
@@ -1 +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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,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,CAyC/D"}
package/dist/react.js CHANGED
@@ -3,26 +3,40 @@
3
3
  *
4
4
  * Sub-path export: import from '@lushly-dev/afd-auth/react'
5
5
  */
6
- import { useCallback, useRef, useSyncExternalStore } from 'react';
6
+ import { useCallback, useSyncExternalStore } from 'react';
7
+ import { areSessionStatesEqual } from './session-state.js';
7
8
  import { LOADING } from './types.js';
8
9
  export { useConvexAuthAdapter } from './adapters/convex.js';
9
10
  /**
10
11
  * Create React hooks bound to an auth adapter instance.
11
12
  */
12
13
  export function createAuthHooks(adapter) {
14
+ // Providers may return a new object from getSession() on every read, but
15
+ // React's external-store contract requires the snapshot itself to be cached,
16
+ // so compare the session's values before replacing it.
17
+ let cachedSnapshot;
18
+ const readSnapshot = () => {
19
+ const nextSnapshot = adapter.getSession();
20
+ if (cachedSnapshot && areSessionStatesEqual(cachedSnapshot, nextSnapshot)) {
21
+ return cachedSnapshot;
22
+ }
23
+ cachedSnapshot = nextSnapshot;
24
+ return nextSnapshot;
25
+ };
13
26
  function useAuth() {
14
27
  return adapter;
15
28
  }
16
29
  function useSession() {
17
- const snapshotRef = useRef(adapter.getSession());
18
30
  const subscribe = useCallback((onStoreChange) => {
19
- const { unsubscribe } = adapter.onAuthStateChange((state) => {
20
- snapshotRef.current = state;
31
+ const { unsubscribe } = adapter.onAuthStateChange(() => {
21
32
  onStoreChange();
22
33
  });
23
34
  return unsubscribe;
24
35
  }, []);
25
- const getSnapshot = useCallback(() => snapshotRef.current, []);
36
+ // Read the adapter at snapshot time. useSyncExternalStore checks this
37
+ // value again immediately after subscribing, which closes the render to
38
+ // subscription race where an auth event arrives between those phases.
39
+ const getSnapshot = useCallback(readSnapshot, []);
26
40
  const getServerSnapshot = useCallback(() => LOADING, []);
27
41
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
28
42
  }
package/dist/react.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAQ5D;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAAoB;IACnD,yEAAyE;IACzE,6EAA6E;IAC7E,uDAAuD;IACvD,IAAI,cAA4C,CAAC;IACjD,MAAM,YAAY,GAAG,GAAqB,EAAE;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QAC1C,IAAI,cAAc,IAAI,qBAAqB,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,CAAC;YAC3E,OAAO,cAAc,CAAC;QACvB,CAAC;QACD,cAAc,GAAG,YAAY,CAAC;QAC9B,OAAO,YAAY,CAAC;IACrB,CAAC,CAAC;IAEF,SAAS,OAAO;QACf,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,SAAS,UAAU;QAClB,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,aAAyB,EAAE,EAAE;YAC3D,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,GAAG,EAAE;gBACtD,aAAa,EAAE,CAAC;YACjB,CAAC,CAAC,CAAC;YACH,OAAO,WAAW,CAAC;QACpB,CAAC,EAAE,EAAE,CAAC,CAAC;QAEP,sEAAsE;QACtE,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAClD,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,19 @@
1
+ /**
2
+ * @fileoverview Session state comparison and expiry helpers shared by the
3
+ * adapters, the middleware and the React hooks.
4
+ */
5
+ import type { AuthSessionState, Session, User } from './types.js';
6
+ export declare function areUsersEqual(left: User, right: User): boolean;
7
+ /**
8
+ * Compare two session states by value. Providers may allocate a new state
9
+ * object on every read, so identity is not a usable signal for "changed".
10
+ */
11
+ export declare function areSessionStatesEqual(left: AuthSessionState, right: AuthSessionState): boolean;
12
+ /**
13
+ * Whether a session has reached its expiry. A session without `expiresAt`
14
+ * does not expire here, because its provider manages the token lifetime. An
15
+ * `expiresAt` that is not a valid date counts as expired, so a malformed value
16
+ * fails closed.
17
+ */
18
+ export declare function isSessionExpired(session: Session, now?: number): boolean;
19
+ //# sourceMappingURL=session-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-state.d.ts","sourceRoot":"","sources":["../src/session-state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElE,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAO9D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAS9F;AASD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAIpF"}