@lunora/auth 1.0.0-alpha.2 → 1.0.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/adapter.mjs CHANGED
@@ -19,6 +19,7 @@ const lunoraAuthAdapter = (store) => createAdapterFactory({
19
19
  const [row] = await store.read(model, { limit: 1, where });
20
20
  return asRowOrNull(row);
21
21
  },
22
+ incrementOne: async ({ increment, model, set, where }) => asRowOrNull(await store.incrementOne(model, where, increment, set)),
22
23
  update: async ({ model, update, where }) => {
23
24
  const [row] = await store.update(model, where, update);
24
25
  return asRowOrNull(row);
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { lunoraAuthAdapter, lunoraD1Adapter } from "./adapter.mjs";
2
- import { L as LunoraAuth, a as LunoraAuthOptions } from "./packem_shared/create-auth.d-M36jwG_Y.mjs";
3
- export { c as createAuth } from "./packem_shared/create-auth.d-M36jwG_Y.mjs";
2
+ import { LunoraError } from '@lunora/errors';
3
+ import { L as LunoraAuth, a as LunoraAuthOptions } from "./packem_shared/create-auth.d-Mwhb4gSc.mjs";
4
+ export { c as createAuth, r as resolveAuthOptions } from "./packem_shared/create-auth.d-Mwhb4gSc.mjs";
4
5
  export { type LunoraAuthApiContext, LunoraAuthHeadersError, type WithAuthPluginsMiddleware, type WithAuthPluginsOptions, withAuthPlugins } from "./middleware.mjs";
5
6
  export { default as authTables } from "./schema.mjs";
6
7
  import { BetterAuthOptions } from 'better-auth';
@@ -90,6 +91,35 @@ interface AuthInvitation {
90
91
  role?: null | string;
91
92
  status?: null | string;
92
93
  }
94
+ /** One team row (from the `organization` plugin with `teams.enabled`). */
95
+ interface AuthTeam {
96
+ [key: string]: unknown;
97
+ createdAt?: AuthTimestamp;
98
+ id: string;
99
+ name?: null | string;
100
+ organizationId: string;
101
+ }
102
+ /** One team-membership row (teams). */
103
+ interface AuthTeamMember {
104
+ [key: string]: unknown;
105
+ createdAt?: AuthTimestamp;
106
+ id: string;
107
+ teamId: string;
108
+ userId: string;
109
+ }
110
+ /**
111
+ * One custom organization role (from the organization plugin's dynamic
112
+ * access-control). `permission` is a JSON string of a `resource → actions[]` map
113
+ * as stored; the studio parses it for display/editing.
114
+ */
115
+ interface AuthOrgRole {
116
+ [key: string]: unknown;
117
+ createdAt?: AuthTimestamp;
118
+ id: string;
119
+ organizationId: string;
120
+ permission?: null | string;
121
+ role?: null | string;
122
+ }
93
123
  /** One registered passkey. Credential secrets (`publicKey`) are stripped. */
94
124
  interface AuthPasskey {
95
125
  [key: string]: unknown;
@@ -123,6 +153,63 @@ interface AuthCapabilities {
123
153
  /** The `two-factor` plugin: per-user 2FA status / disable. */
124
154
  twoFactor: boolean;
125
155
  }
156
+ /**
157
+ * One app/plugin-defined field the create-user form should render, derived from
158
+ * the merged better-auth `user` table (core + plugin + `additionalFields`). Only
159
+ * user-settable columns are surfaced — server-managed flags (`input: false`),
160
+ * foreign keys (`references`), and the core columns the form already handles
161
+ * (`email`/`name`/`role`/ban state/…) are filtered out upstream.
162
+ */
163
+ interface AuthUserFieldSpec {
164
+ /** Logical field name (the key passed back in `createUser`'s `data`). */
165
+ name: string;
166
+ /** Best-effort plugin id the field originates from (`username`, `phone-number`, …); `undefined` for app `additionalFields`. */
167
+ plugin?: string;
168
+ required: boolean;
169
+ /** Coarse input kind the studio maps to a control (checkbox / number / date / text). */
170
+ type: "boolean" | "date" | "number" | "string";
171
+ unique: boolean;
172
+ }
173
+ /**
174
+ * A rich, read-only description of the deployment's auth configuration for the
175
+ * studio's config panel and dynamic create-user form. Unlike
176
+ * {@link AuthCapabilities} (five booleans that gate panels), this exposes *what*
177
+ * is configured — enabled plugins, email/password + social sign-in, the
178
+ * user-settable fields, organization sub-features (teams / custom roles), and
179
+ * the session + rate-limit policy — without ever leaking a secret.
180
+ */
181
+ interface AuthConfigInfo {
182
+ /** The same capability booleans {@link AuthAdmin.capabilities} returns, embedded so a single call drives the whole panel. */
183
+ capabilities: AuthCapabilities;
184
+ /** Whether email + password sign-in is enabled. */
185
+ emailAndPassword: boolean;
186
+ /** Organization plugin sub-features. */
187
+ organization: {
188
+ enabled: boolean; /** Custom roles / dynamic access control (`organizationRole` table present). */
189
+ roles: boolean;
190
+ /** Teams (`team` table present). */
191
+ teams: boolean;
192
+ };
193
+ /** Enabled better-auth plugin ids, sorted. */
194
+ plugins: string[];
195
+ /** Rate-limit policy (window is in seconds). */
196
+ rateLimit: {
197
+ enabled: boolean;
198
+ max?: number;
199
+ window?: number;
200
+ };
201
+ /** Session policy (all durations in seconds). */
202
+ session: {
203
+ cookieCache?: boolean;
204
+ expiresIn?: number;
205
+ freshAge?: number;
206
+ updateAge?: number;
207
+ };
208
+ /** Configured social/OAuth provider ids, sorted. */
209
+ socialProviders: string[];
210
+ /** User-settable extra fields for the create-user form (plugin + app `additionalFields`). */
211
+ userFields: AuthUserFieldSpec[];
212
+ }
126
213
  /** A scalar value usable in an adapter `where` clause / filter. */
127
214
  type WhereValue = boolean | number | string;
128
215
  /** Filtering / paging options for {@link AuthAdmin.listUsers}. */
@@ -158,6 +245,17 @@ interface ImpersonationResult {
158
245
  * surfaces the underlying adapter error.
159
246
  */
160
247
  interface AuthAdmin {
248
+ /** Directly add an existing user as an org member (server-side, no invitation/acceptance). */
249
+ addMember: (input: {
250
+ organizationId: string;
251
+ role?: string;
252
+ userId: string;
253
+ }) => Promise<AuthMember>;
254
+ /** Add a user to a team. */
255
+ addTeamMember: (input: {
256
+ teamId: string;
257
+ userId: string;
258
+ }) => Promise<AuthTeamMember>;
161
259
  banUser: (input: {
162
260
  expiresInSeconds?: number;
163
261
  reason?: string;
@@ -167,6 +265,27 @@ interface AuthAdmin {
167
265
  invitationId: string;
168
266
  }) => Promise<void>;
169
267
  capabilities: () => Promise<AuthCapabilities>;
268
+ /** Rich, read-only description of the auth configuration (plugins, fields, session policy, …). */
269
+ config: () => Promise<AuthConfigInfo>;
270
+ /** Create an organization; optionally seed an `owner` member for `ownerId`. */
271
+ createOrganization: (input: {
272
+ logo?: string;
273
+ metadata?: Record<string, unknown>;
274
+ name: string;
275
+ ownerId?: string;
276
+ slug?: string;
277
+ }) => Promise<AuthOrganization>;
278
+ /** Create a custom org role with a permission grant (a `resource → actions[]` map). */
279
+ createOrgRole: (input: {
280
+ organizationId: string;
281
+ permission: Record<string, string[]>;
282
+ role: string;
283
+ }) => Promise<AuthOrgRole>;
284
+ /** Create a team under an organization. */
285
+ createTeam: (input: {
286
+ name: string;
287
+ organizationId: string;
288
+ }) => Promise<AuthTeam>;
170
289
  createUser: (input: {
171
290
  data?: Record<string, unknown>;
172
291
  email: string;
@@ -174,6 +293,14 @@ interface AuthAdmin {
174
293
  password?: string;
175
294
  role?: string | string[];
176
295
  }) => Promise<AuthAdminUser>;
296
+ /** Delete an organization and cascade-delete its members, invitations, teams, and custom roles. */
297
+ deleteOrganization: (input: {
298
+ organizationId: string;
299
+ }) => Promise<void>;
300
+ /** Delete a custom org role. */
301
+ deleteOrgRole: (input: {
302
+ roleId: string;
303
+ }) => Promise<void>;
177
304
  deletePasskey: (input: {
178
305
  passkeyId: string;
179
306
  }) => Promise<void>;
@@ -183,6 +310,13 @@ interface AuthAdmin {
183
310
  impersonateUser: (input: {
184
311
  userId: string;
185
312
  }) => Promise<ImpersonationResult>;
313
+ /** Create a pending email invitation to an org (no acceptance side effects). */
314
+ inviteMember: (input: {
315
+ email: string;
316
+ inviterId?: string;
317
+ organizationId: string;
318
+ role?: string;
319
+ }) => Promise<AuthInvitation>;
186
320
  listAccounts: (input: {
187
321
  userId: string;
188
322
  }) => Promise<AuthAccount[]>;
@@ -200,6 +334,12 @@ interface AuthAdmin {
200
334
  limit?: number;
201
335
  offset?: number;
202
336
  }) => Promise<AuthPage<AuthOrganization>>;
337
+ /** List an org's custom roles. */
338
+ listOrgRoles: (options: {
339
+ limit?: number;
340
+ offset?: number;
341
+ organizationId: string;
342
+ }) => Promise<AuthPage<AuthOrgRole>>;
203
343
  listPasskeys: (input: {
204
344
  userId: string;
205
345
  }) => Promise<AuthPasskey[]>;
@@ -208,10 +348,30 @@ interface AuthAdmin {
208
348
  offset?: number;
209
349
  userId?: string;
210
350
  }) => Promise<AuthPage<AuthAdminSession>>;
351
+ /** List a team's members. */
352
+ listTeamMembers: (options: {
353
+ limit?: number;
354
+ offset?: number;
355
+ teamId: string;
356
+ }) => Promise<AuthPage<AuthTeamMember>>;
357
+ /** List an org's teams. */
358
+ listTeams: (options: {
359
+ limit?: number;
360
+ offset?: number;
361
+ organizationId: string;
362
+ }) => Promise<AuthPage<AuthTeam>>;
211
363
  listUsers: (options: ListUsersOptions) => Promise<AuthPage<AuthAdminUser>>;
212
364
  removeMember: (input: {
213
365
  memberId: string;
214
366
  }) => Promise<void>;
367
+ /** Delete a team and its memberships. */
368
+ removeTeam: (input: {
369
+ teamId: string;
370
+ }) => Promise<void>;
371
+ /** Remove a member from a team. */
372
+ removeTeamMember: (input: {
373
+ teamMemberId: string;
374
+ }) => Promise<void>;
215
375
  removeUser: (input: {
216
376
  userId: string;
217
377
  }) => Promise<void>;
@@ -236,6 +396,29 @@ interface AuthAdmin {
236
396
  accountId: string;
237
397
  userId: string;
238
398
  }) => Promise<void>;
399
+ /** Change a member's role. */
400
+ updateMemberRole: (input: {
401
+ memberId: string;
402
+ role: string | string[];
403
+ }) => Promise<AuthMember>;
404
+ /** Update an organization's name/slug/logo/metadata. */
405
+ updateOrganization: (input: {
406
+ logo?: string;
407
+ metadata?: Record<string, unknown>;
408
+ name?: string;
409
+ organizationId: string;
410
+ slug?: string;
411
+ }) => Promise<AuthOrganization>;
412
+ /** Replace a custom org role's permission grant. */
413
+ updateOrgRole: (input: {
414
+ permission: Record<string, string[]>;
415
+ roleId: string;
416
+ }) => Promise<AuthOrgRole>;
417
+ /** Rename a team. */
418
+ updateTeam: (input: {
419
+ name: string;
420
+ teamId: string;
421
+ }) => Promise<AuthTeam>;
239
422
  updateUser: (input: {
240
423
  data: Record<string, unknown>;
241
424
  userId: string;
@@ -271,8 +454,7 @@ interface CreateAuthAdminOptions {
271
454
  * surface that `code` so the runtime can map it onto an HTTP status and the
272
455
  * studio can show a meaningful message instead of a generic 500.
273
456
  */
274
- declare class LunoraAuthAdminError extends Error {
275
- readonly code: string;
457
+ declare class LunoraAuthAdminError extends LunoraError {
276
458
  constructor(message: string, code: string);
277
459
  }
278
460
  /**
@@ -333,6 +515,12 @@ declare const ensureMigrated: (auth: LunoraAuth | {
333
515
  * Compile better-auth's migrations to a single SQL string. Useful for
334
516
  * `wrangler d1 execute --file -` in CI so the deploy step applies the schema
335
517
  * before the first user request.
518
+ *
519
+ * Compiles from the SAME resolved options `createAuth` runs with (via
520
+ * `resolveAuthOptions`), not the raw caller options — so the schema includes the
521
+ * `rateLimit` table the worker's default-on durable limiter writes to. Compiling
522
+ * from the raw options would omit it, and the running worker would then write to
523
+ * a table the migration never created.
336
524
  */
337
525
  declare const compileMigrationsSql: (options: LunoraAuthOptions) => Promise<string>;
338
526
  /**
@@ -378,9 +566,13 @@ declare const validateSessionPolicy: (policy: SessionPolicy) => SessionPolicy;
378
566
  * });
379
567
  * ```
380
568
  *
381
- * - `rolling` — balanced default: 7-day absolute expiry, rotated once per day.
382
- * - `strict` short, security-sensitive: 1-hour expiry, 15-minute rotation.
383
- * - `longLived` — low-friction consumer apps: 30-day expiry, daily rotation.
569
+ * - `rolling` — balanced default: 7-day absolute expiry, rotated once per day,
570
+ * with a 60s signed-cookie session cache so bursts of authenticated calls
571
+ * skip the per-request DB session read.
572
+ * - `strict` — short, security-sensitive: 1-hour expiry, 15-minute rotation,
573
+ * cookie cache **off** (fast revocation / short freshness is the whole point).
574
+ * - `longLived` — low-friction consumer apps: 30-day expiry, daily rotation,
575
+ * with the same 60s cookie cache as `rolling`.
384
576
  */
385
577
  declare const sessionPresets: Record<"longLived" | "rolling" | "strict", SessionPolicy>;
386
578
  export { type AuthAccount, type AuthAdmin, type AuthAdminSession, type AuthAdminUser, type AuthCapabilities, type AuthInvitation, type AuthMember, type AuthOrganization, type AuthPage, type AuthPasskey, type AuthTimestamp, type CreateAuthAdminOptions, DEFAULT_AUTH_BASE_PATH, type ImpersonationResult, type ListUsersOptions, type LunoraAuth, LunoraAuthAdminError, type LunoraAuthOptions, type SessionPolicy, compileMigrationsSql, createAuthAdmin, ensureMigrated, handleAuthRequest, sessionPresets, validateSessionPolicy };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { lunoraAuthAdapter, lunoraD1Adapter } from "./adapter.js";
2
- import { L as LunoraAuth, a as LunoraAuthOptions } from "./packem_shared/create-auth.d-M36jwG_Y.js";
3
- export { c as createAuth } from "./packem_shared/create-auth.d-M36jwG_Y.js";
2
+ import { LunoraError } from '@lunora/errors';
3
+ import { L as LunoraAuth, a as LunoraAuthOptions } from "./packem_shared/create-auth.d-Mwhb4gSc.js";
4
+ export { c as createAuth, r as resolveAuthOptions } from "./packem_shared/create-auth.d-Mwhb4gSc.js";
4
5
  export { type LunoraAuthApiContext, LunoraAuthHeadersError, type WithAuthPluginsMiddleware, type WithAuthPluginsOptions, withAuthPlugins } from "./middleware.js";
5
6
  export { default as authTables } from "./schema.js";
6
7
  import { BetterAuthOptions } from 'better-auth';
@@ -90,6 +91,35 @@ interface AuthInvitation {
90
91
  role?: null | string;
91
92
  status?: null | string;
92
93
  }
94
+ /** One team row (from the `organization` plugin with `teams.enabled`). */
95
+ interface AuthTeam {
96
+ [key: string]: unknown;
97
+ createdAt?: AuthTimestamp;
98
+ id: string;
99
+ name?: null | string;
100
+ organizationId: string;
101
+ }
102
+ /** One team-membership row (teams). */
103
+ interface AuthTeamMember {
104
+ [key: string]: unknown;
105
+ createdAt?: AuthTimestamp;
106
+ id: string;
107
+ teamId: string;
108
+ userId: string;
109
+ }
110
+ /**
111
+ * One custom organization role (from the organization plugin's dynamic
112
+ * access-control). `permission` is a JSON string of a `resource → actions[]` map
113
+ * as stored; the studio parses it for display/editing.
114
+ */
115
+ interface AuthOrgRole {
116
+ [key: string]: unknown;
117
+ createdAt?: AuthTimestamp;
118
+ id: string;
119
+ organizationId: string;
120
+ permission?: null | string;
121
+ role?: null | string;
122
+ }
93
123
  /** One registered passkey. Credential secrets (`publicKey`) are stripped. */
94
124
  interface AuthPasskey {
95
125
  [key: string]: unknown;
@@ -123,6 +153,63 @@ interface AuthCapabilities {
123
153
  /** The `two-factor` plugin: per-user 2FA status / disable. */
124
154
  twoFactor: boolean;
125
155
  }
156
+ /**
157
+ * One app/plugin-defined field the create-user form should render, derived from
158
+ * the merged better-auth `user` table (core + plugin + `additionalFields`). Only
159
+ * user-settable columns are surfaced — server-managed flags (`input: false`),
160
+ * foreign keys (`references`), and the core columns the form already handles
161
+ * (`email`/`name`/`role`/ban state/…) are filtered out upstream.
162
+ */
163
+ interface AuthUserFieldSpec {
164
+ /** Logical field name (the key passed back in `createUser`'s `data`). */
165
+ name: string;
166
+ /** Best-effort plugin id the field originates from (`username`, `phone-number`, …); `undefined` for app `additionalFields`. */
167
+ plugin?: string;
168
+ required: boolean;
169
+ /** Coarse input kind the studio maps to a control (checkbox / number / date / text). */
170
+ type: "boolean" | "date" | "number" | "string";
171
+ unique: boolean;
172
+ }
173
+ /**
174
+ * A rich, read-only description of the deployment's auth configuration for the
175
+ * studio's config panel and dynamic create-user form. Unlike
176
+ * {@link AuthCapabilities} (five booleans that gate panels), this exposes *what*
177
+ * is configured — enabled plugins, email/password + social sign-in, the
178
+ * user-settable fields, organization sub-features (teams / custom roles), and
179
+ * the session + rate-limit policy — without ever leaking a secret.
180
+ */
181
+ interface AuthConfigInfo {
182
+ /** The same capability booleans {@link AuthAdmin.capabilities} returns, embedded so a single call drives the whole panel. */
183
+ capabilities: AuthCapabilities;
184
+ /** Whether email + password sign-in is enabled. */
185
+ emailAndPassword: boolean;
186
+ /** Organization plugin sub-features. */
187
+ organization: {
188
+ enabled: boolean; /** Custom roles / dynamic access control (`organizationRole` table present). */
189
+ roles: boolean;
190
+ /** Teams (`team` table present). */
191
+ teams: boolean;
192
+ };
193
+ /** Enabled better-auth plugin ids, sorted. */
194
+ plugins: string[];
195
+ /** Rate-limit policy (window is in seconds). */
196
+ rateLimit: {
197
+ enabled: boolean;
198
+ max?: number;
199
+ window?: number;
200
+ };
201
+ /** Session policy (all durations in seconds). */
202
+ session: {
203
+ cookieCache?: boolean;
204
+ expiresIn?: number;
205
+ freshAge?: number;
206
+ updateAge?: number;
207
+ };
208
+ /** Configured social/OAuth provider ids, sorted. */
209
+ socialProviders: string[];
210
+ /** User-settable extra fields for the create-user form (plugin + app `additionalFields`). */
211
+ userFields: AuthUserFieldSpec[];
212
+ }
126
213
  /** A scalar value usable in an adapter `where` clause / filter. */
127
214
  type WhereValue = boolean | number | string;
128
215
  /** Filtering / paging options for {@link AuthAdmin.listUsers}. */
@@ -158,6 +245,17 @@ interface ImpersonationResult {
158
245
  * surfaces the underlying adapter error.
159
246
  */
160
247
  interface AuthAdmin {
248
+ /** Directly add an existing user as an org member (server-side, no invitation/acceptance). */
249
+ addMember: (input: {
250
+ organizationId: string;
251
+ role?: string;
252
+ userId: string;
253
+ }) => Promise<AuthMember>;
254
+ /** Add a user to a team. */
255
+ addTeamMember: (input: {
256
+ teamId: string;
257
+ userId: string;
258
+ }) => Promise<AuthTeamMember>;
161
259
  banUser: (input: {
162
260
  expiresInSeconds?: number;
163
261
  reason?: string;
@@ -167,6 +265,27 @@ interface AuthAdmin {
167
265
  invitationId: string;
168
266
  }) => Promise<void>;
169
267
  capabilities: () => Promise<AuthCapabilities>;
268
+ /** Rich, read-only description of the auth configuration (plugins, fields, session policy, …). */
269
+ config: () => Promise<AuthConfigInfo>;
270
+ /** Create an organization; optionally seed an `owner` member for `ownerId`. */
271
+ createOrganization: (input: {
272
+ logo?: string;
273
+ metadata?: Record<string, unknown>;
274
+ name: string;
275
+ ownerId?: string;
276
+ slug?: string;
277
+ }) => Promise<AuthOrganization>;
278
+ /** Create a custom org role with a permission grant (a `resource → actions[]` map). */
279
+ createOrgRole: (input: {
280
+ organizationId: string;
281
+ permission: Record<string, string[]>;
282
+ role: string;
283
+ }) => Promise<AuthOrgRole>;
284
+ /** Create a team under an organization. */
285
+ createTeam: (input: {
286
+ name: string;
287
+ organizationId: string;
288
+ }) => Promise<AuthTeam>;
170
289
  createUser: (input: {
171
290
  data?: Record<string, unknown>;
172
291
  email: string;
@@ -174,6 +293,14 @@ interface AuthAdmin {
174
293
  password?: string;
175
294
  role?: string | string[];
176
295
  }) => Promise<AuthAdminUser>;
296
+ /** Delete an organization and cascade-delete its members, invitations, teams, and custom roles. */
297
+ deleteOrganization: (input: {
298
+ organizationId: string;
299
+ }) => Promise<void>;
300
+ /** Delete a custom org role. */
301
+ deleteOrgRole: (input: {
302
+ roleId: string;
303
+ }) => Promise<void>;
177
304
  deletePasskey: (input: {
178
305
  passkeyId: string;
179
306
  }) => Promise<void>;
@@ -183,6 +310,13 @@ interface AuthAdmin {
183
310
  impersonateUser: (input: {
184
311
  userId: string;
185
312
  }) => Promise<ImpersonationResult>;
313
+ /** Create a pending email invitation to an org (no acceptance side effects). */
314
+ inviteMember: (input: {
315
+ email: string;
316
+ inviterId?: string;
317
+ organizationId: string;
318
+ role?: string;
319
+ }) => Promise<AuthInvitation>;
186
320
  listAccounts: (input: {
187
321
  userId: string;
188
322
  }) => Promise<AuthAccount[]>;
@@ -200,6 +334,12 @@ interface AuthAdmin {
200
334
  limit?: number;
201
335
  offset?: number;
202
336
  }) => Promise<AuthPage<AuthOrganization>>;
337
+ /** List an org's custom roles. */
338
+ listOrgRoles: (options: {
339
+ limit?: number;
340
+ offset?: number;
341
+ organizationId: string;
342
+ }) => Promise<AuthPage<AuthOrgRole>>;
203
343
  listPasskeys: (input: {
204
344
  userId: string;
205
345
  }) => Promise<AuthPasskey[]>;
@@ -208,10 +348,30 @@ interface AuthAdmin {
208
348
  offset?: number;
209
349
  userId?: string;
210
350
  }) => Promise<AuthPage<AuthAdminSession>>;
351
+ /** List a team's members. */
352
+ listTeamMembers: (options: {
353
+ limit?: number;
354
+ offset?: number;
355
+ teamId: string;
356
+ }) => Promise<AuthPage<AuthTeamMember>>;
357
+ /** List an org's teams. */
358
+ listTeams: (options: {
359
+ limit?: number;
360
+ offset?: number;
361
+ organizationId: string;
362
+ }) => Promise<AuthPage<AuthTeam>>;
211
363
  listUsers: (options: ListUsersOptions) => Promise<AuthPage<AuthAdminUser>>;
212
364
  removeMember: (input: {
213
365
  memberId: string;
214
366
  }) => Promise<void>;
367
+ /** Delete a team and its memberships. */
368
+ removeTeam: (input: {
369
+ teamId: string;
370
+ }) => Promise<void>;
371
+ /** Remove a member from a team. */
372
+ removeTeamMember: (input: {
373
+ teamMemberId: string;
374
+ }) => Promise<void>;
215
375
  removeUser: (input: {
216
376
  userId: string;
217
377
  }) => Promise<void>;
@@ -236,6 +396,29 @@ interface AuthAdmin {
236
396
  accountId: string;
237
397
  userId: string;
238
398
  }) => Promise<void>;
399
+ /** Change a member's role. */
400
+ updateMemberRole: (input: {
401
+ memberId: string;
402
+ role: string | string[];
403
+ }) => Promise<AuthMember>;
404
+ /** Update an organization's name/slug/logo/metadata. */
405
+ updateOrganization: (input: {
406
+ logo?: string;
407
+ metadata?: Record<string, unknown>;
408
+ name?: string;
409
+ organizationId: string;
410
+ slug?: string;
411
+ }) => Promise<AuthOrganization>;
412
+ /** Replace a custom org role's permission grant. */
413
+ updateOrgRole: (input: {
414
+ permission: Record<string, string[]>;
415
+ roleId: string;
416
+ }) => Promise<AuthOrgRole>;
417
+ /** Rename a team. */
418
+ updateTeam: (input: {
419
+ name: string;
420
+ teamId: string;
421
+ }) => Promise<AuthTeam>;
239
422
  updateUser: (input: {
240
423
  data: Record<string, unknown>;
241
424
  userId: string;
@@ -271,8 +454,7 @@ interface CreateAuthAdminOptions {
271
454
  * surface that `code` so the runtime can map it onto an HTTP status and the
272
455
  * studio can show a meaningful message instead of a generic 500.
273
456
  */
274
- declare class LunoraAuthAdminError extends Error {
275
- readonly code: string;
457
+ declare class LunoraAuthAdminError extends LunoraError {
276
458
  constructor(message: string, code: string);
277
459
  }
278
460
  /**
@@ -333,6 +515,12 @@ declare const ensureMigrated: (auth: LunoraAuth | {
333
515
  * Compile better-auth's migrations to a single SQL string. Useful for
334
516
  * `wrangler d1 execute --file -` in CI so the deploy step applies the schema
335
517
  * before the first user request.
518
+ *
519
+ * Compiles from the SAME resolved options `createAuth` runs with (via
520
+ * `resolveAuthOptions`), not the raw caller options — so the schema includes the
521
+ * `rateLimit` table the worker's default-on durable limiter writes to. Compiling
522
+ * from the raw options would omit it, and the running worker would then write to
523
+ * a table the migration never created.
336
524
  */
337
525
  declare const compileMigrationsSql: (options: LunoraAuthOptions) => Promise<string>;
338
526
  /**
@@ -378,9 +566,13 @@ declare const validateSessionPolicy: (policy: SessionPolicy) => SessionPolicy;
378
566
  * });
379
567
  * ```
380
568
  *
381
- * - `rolling` — balanced default: 7-day absolute expiry, rotated once per day.
382
- * - `strict` short, security-sensitive: 1-hour expiry, 15-minute rotation.
383
- * - `longLived` — low-friction consumer apps: 30-day expiry, daily rotation.
569
+ * - `rolling` — balanced default: 7-day absolute expiry, rotated once per day,
570
+ * with a 60s signed-cookie session cache so bursts of authenticated calls
571
+ * skip the per-request DB session read.
572
+ * - `strict` — short, security-sensitive: 1-hour expiry, 15-minute rotation,
573
+ * cookie cache **off** (fast revocation / short freshness is the whole point).
574
+ * - `longLived` — low-friction consumer apps: 30-day expiry, daily rotation,
575
+ * with the same 60s cookie cache as `rolling`.
384
576
  */
385
577
  declare const sessionPresets: Record<"longLived" | "rolling" | "strict", SessionPolicy>;
386
578
  export { type AuthAccount, type AuthAdmin, type AuthAdminSession, type AuthAdminUser, type AuthCapabilities, type AuthInvitation, type AuthMember, type AuthOrganization, type AuthPage, type AuthPasskey, type AuthTimestamp, type CreateAuthAdminOptions, DEFAULT_AUTH_BASE_PATH, type ImpersonationResult, type ListUsersOptions, type LunoraAuth, LunoraAuthAdminError, type LunoraAuthOptions, type SessionPolicy, compileMigrationsSql, createAuthAdmin, ensureMigrated, handleAuthRequest, sessionPresets, validateSessionPolicy };
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  export { lunoraAuthAdapter, lunoraD1Adapter } from './adapter.mjs';
2
- export { LunoraAuthAdminError, createAuthAdmin } from './packem_shared/LunoraAuthAdminError-BxrfEeA_.mjs';
3
- export { createAuth } from './packem_shared/createAuth-B-tvsvQU.mjs';
2
+ export { LunoraAuthAdminError, createAuthAdmin } from './packem_shared/LunoraAuthAdminError-D4L7n6gN.mjs';
3
+ export { createAuth, resolveAuthOptions } from './packem_shared/createAuth-BVMMllTm.mjs';
4
4
  export { DEFAULT_AUTH_BASE_PATH, handleAuthRequest } from './packem_shared/DEFAULT_AUTH_BASE_PATH-DjcUWEQl.mjs';
5
5
  export { LunoraAuthHeadersError, withAuthPlugins } from './middleware.mjs';
6
- export { compileMigrationsSql, ensureMigrated } from './packem_shared/compileMigrationsSql-wZH3oXDu.mjs';
6
+ export { compileMigrationsSql, ensureMigrated } from './packem_shared/compileMigrationsSql-B9bj-mJv.mjs';
7
7
  export { default as authTables } from './schema.mjs';
8
- export { sessionPresets, validateSessionPolicy } from './packem_shared/sessionPresets-B95rXrd8.mjs';
8
+ export { sessionPresets, validateSessionPolicy } from './packem_shared/sessionPresets-Dwwd74_J.mjs';
9
9
  export { createSqlAuthStore, d1Executor } from './sql-store.mjs';
10
10
  export { createMemoryAuthStore, matchesWhere } from './store.mjs';
11
11
  export { TURNSTILE_VERIFY_ENDPOINT, verifyTurnstile } from './turnstile.mjs';
@@ -1,4 +1,5 @@
1
- import { L as LunoraAuth } from "./packem_shared/create-auth.d-M36jwG_Y.mjs";
1
+ import { LunoraError } from '@lunora/errors';
2
+ import { L as LunoraAuth } from "./packem_shared/create-auth.d-Mwhb4gSc.mjs";
2
3
  import 'better-auth';
3
4
  /**
4
5
  * Structural mirror of `@lunora/server`'s `MiddlewareNext` — the continuation
@@ -22,7 +23,7 @@ interface MiddlewareNext<ContextIn> {
22
23
  * advisor lint — both treat a header-less `ctx.authApi.*` call as an
23
24
  * authorization bypass, so a call that trips the lint also trips this guard.
24
25
  */
25
- declare class LunoraAuthHeadersError extends Error {
26
+ declare class LunoraAuthHeadersError extends LunoraError {
26
27
  /** The `ctx.authApi.&lt;method>` that was called without `headers`. */
27
28
  readonly method: string;
28
29
  constructor(method: string);
@@ -1,4 +1,5 @@
1
- import { L as LunoraAuth } from "./packem_shared/create-auth.d-M36jwG_Y.js";
1
+ import { LunoraError } from '@lunora/errors';
2
+ import { L as LunoraAuth } from "./packem_shared/create-auth.d-Mwhb4gSc.js";
2
3
  import 'better-auth';
3
4
  /**
4
5
  * Structural mirror of `@lunora/server`'s `MiddlewareNext` — the continuation
@@ -22,7 +23,7 @@ interface MiddlewareNext<ContextIn> {
22
23
  * advisor lint — both treat a header-less `ctx.authApi.*` call as an
23
24
  * authorization bypass, so a call that trips the lint also trips this guard.
24
25
  */
25
- declare class LunoraAuthHeadersError extends Error {
26
+ declare class LunoraAuthHeadersError extends LunoraError {
26
27
  /** The `ctx.authApi.&lt;method>` that was called without `headers`. */
27
28
  readonly method: string;
28
29
  constructor(method: string);
@@ -1,3 +1,5 @@
1
+ import { LunoraError } from '@lunora/errors';
2
+
1
3
  const callHasHeaders = (argument) => {
2
4
  if (argument === void 0) {
3
5
  return false;
@@ -30,14 +32,15 @@ const guardAuthApi = (api) => {
30
32
  }
31
33
  });
32
34
  };
33
- class LunoraAuthHeadersError extends Error {
35
+ class LunoraAuthHeadersError extends LunoraError {
34
36
  /** The `ctx.authApi.&lt;method>` that was called without `headers`. */
35
37
  method;
36
38
  constructor(method) {
37
39
  super(
38
- `@lunora/auth: ctx.authApi.${method}(…) was called without \`headers\`. better-auth treats a header-less call as a trusted server-to-server invocation and skips session authorization entirely — an authorization bypass. Pass the inbound request headers: ctx.authApi.${method}({ body, headers: request.headers }). If you genuinely intend an unauthenticated server-to-server call, opt out explicitly via ctx.authApi.withoutHeaders().<method>(…), or disable the guard for the whole middleware with withAuthPlugins(auth, { enforceHeaders: false }).`
40
+ "AUTH_HEADERS_MISSING",
41
+ `@lunora/auth: ctx.authApi.${method}(…) was called without \`headers\`. better-auth treats a header-less call as a trusted server-to-server invocation and skips session authorization entirely — an authorization bypass. Pass the inbound request headers: ctx.authApi.${method}({ body, headers: request.headers }). If you genuinely intend an unauthenticated server-to-server call, opt out explicitly via ctx.authApi.withoutHeaders().<method>(…), or disable the guard for the whole middleware with withAuthPlugins(auth, { enforceHeaders: false }).`,
42
+ { name: "LunoraAuthHeadersError" }
39
43
  );
40
- this.name = "LunoraAuthHeadersError";
41
44
  this.method = method;
42
45
  }
43
46
  }