@opensaas/stack-auth 0.20.1 → 0.22.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 (50) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +122 -0
  3. package/CLAUDE.md +115 -17
  4. package/INTEGRATION_SUMMARY.md +21 -20
  5. package/README.md +82 -48
  6. package/dist/config/adopt-better-auth-tables.d.ts +107 -0
  7. package/dist/config/adopt-better-auth-tables.d.ts.map +1 -0
  8. package/dist/config/adopt-better-auth-tables.js +70 -0
  9. package/dist/config/adopt-better-auth-tables.js.map +1 -0
  10. package/dist/config/derive-auth-lists.d.ts +50 -0
  11. package/dist/config/derive-auth-lists.d.ts.map +1 -0
  12. package/dist/config/derive-auth-lists.js +274 -0
  13. package/dist/config/derive-auth-lists.js.map +1 -0
  14. package/dist/config/index.d.ts.map +1 -1
  15. package/dist/config/index.js +43 -0
  16. package/dist/config/index.js.map +1 -1
  17. package/dist/config/plugin.d.ts +1 -1
  18. package/dist/config/plugin.d.ts.map +1 -1
  19. package/dist/config/plugin.js +52 -9
  20. package/dist/config/plugin.js.map +1 -1
  21. package/dist/config/types.d.ts +130 -3
  22. package/dist/config/types.d.ts.map +1 -1
  23. package/dist/index.d.ts +4 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +6 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/lists/index.d.ts +17 -11
  28. package/dist/lists/index.d.ts.map +1 -1
  29. package/dist/lists/index.js +34 -208
  30. package/dist/lists/index.js.map +1 -1
  31. package/dist/server/index.d.ts.map +1 -1
  32. package/dist/server/index.js +28 -7
  33. package/dist/server/index.js.map +1 -1
  34. package/dist/server/schema-converter.d.ts +1 -1
  35. package/dist/server/schema-converter.js +1 -1
  36. package/package.json +3 -3
  37. package/src/config/adopt-better-auth-tables.ts +146 -0
  38. package/src/config/derive-auth-lists.ts +323 -0
  39. package/src/config/index.ts +58 -0
  40. package/src/config/plugin.ts +67 -10
  41. package/src/config/types.ts +146 -3
  42. package/src/index.ts +13 -0
  43. package/src/lists/index.ts +42 -202
  44. package/src/server/index.ts +33 -10
  45. package/src/server/schema-converter.ts +1 -1
  46. package/tests/adopt-better-auth-tables.test.ts +183 -0
  47. package/tests/derive-auth-lists.test.ts +232 -0
  48. package/tests/plugin-derived-keys.test.ts +138 -0
  49. package/tests/plugin-schema-placement.test.ts +121 -0
  50. package/tsconfig.tsbuildinfo +1 -1
@@ -1,3 +1,4 @@
1
+ import { getDbKey } from '@opensaas/stack-core';
1
2
  import { normalizeAuthConfig } from './index.js';
2
3
  import { getAuthLists } from '../lists/index.js';
3
4
  import { convertBetterAuthSchema } from '../server/schema-converter.js';
@@ -32,8 +33,12 @@ export function authPlugin(config) {
32
33
  typeName: 'AuthRuntimeServices',
33
34
  },
34
35
  init: async (context) => {
35
- // Get auth lists from base Better Auth schema
36
- const authLists = getAuthLists(normalized.extendUserList);
36
+ // Derive the auth lists from the better-auth model config (modelName +
37
+ // field column maps). With no overrides this yields the historical
38
+ // User/Session/Account/Verification keys; with overrides (e.g.
39
+ // user.modelName: 'AuthUser') the lists are keyed and column-mapped to
40
+ // match the developer's live better-auth tables.
41
+ const authLists = getAuthLists(normalized.extendUserList, normalized.models);
37
42
  // Extract additional lists from Better Auth plugins
38
43
  for (const plugin of normalized.betterAuthPlugins) {
39
44
  if (plugin && typeof plugin === 'object' && 'schema' in plugin) {
@@ -58,10 +63,18 @@ export function authPlugin(config) {
58
63
  }
59
64
  }
60
65
  }
61
- // Add all auth lists
66
+ // Add all auth lists.
67
+ //
68
+ // The plugin only ever touches its OWN derived keys. When a developer
69
+ // renames the auth user model (e.g. user.modelName: 'AuthUser'), the
70
+ // derived key is 'AuthUser' and an app's separate 'User' list is left
71
+ // untouched — the plugin never extends/overwrites a list it didn't
72
+ // derive. Extending only kicks in when an existing list shares the
73
+ // derived key (e.g. the default 'User'), which is the intended
74
+ // "merge auth fields into my User" behaviour.
62
75
  for (const [listName, listConfig] of Object.entries(authLists)) {
63
76
  if (context.config.lists[listName]) {
64
- // If user defined a User list, extend it with auth fields
77
+ // A list already exists under this derived key merge auth fields in.
65
78
  context.extendList(listName, {
66
79
  fields: listConfig.fields,
67
80
  hooks: listConfig.hooks,
@@ -78,7 +91,40 @@ export function authPlugin(config) {
78
91
  // Access at runtime via: config._pluginData.auth
79
92
  context.setPluginData('auth', normalized);
80
93
  },
94
+ beforeGenerate: (generationConfig) => {
95
+ // Collect every schema the Auth lists are placed in (per-model schema,
96
+ // else the plugin-level schema). When none is configured the Auth lists
97
+ // stay in the default `public` schema and we leave the config untouched —
98
+ // the greenfield default Prisma schema is unchanged (no `schemas`, no
99
+ // `previewFeatures`, no `@@schema`).
100
+ const authSchemas = Array.from(new Set(Object.values(normalized.models)
101
+ .map((model) => model.schema)
102
+ .filter((schema) => Boolean(schema))));
103
+ if (authSchemas.length === 0) {
104
+ return generationConfig;
105
+ }
106
+ // Multi-schema Prisma requires the datasource to list every schema in use
107
+ // AND every model to carry an `@@schema`. Merge the auth schema(s) into the
108
+ // datasource `schemas` array (always including `public` for the app's own
109
+ // lists), and default any list without an explicit `db.schema` to `public`
110
+ // so the generated multi-schema schema is coherent and valid.
111
+ const schemas = Array.from(new Set(['public', ...(generationConfig.db.schemas ?? []), ...authSchemas]));
112
+ const lists = Object.fromEntries(Object.entries(generationConfig.lists).map(([listKey, listConfig]) => {
113
+ if (listConfig.db?.schema) {
114
+ return [listKey, listConfig];
115
+ }
116
+ return [listKey, { ...listConfig, db: { ...listConfig.db, schema: 'public' } }];
117
+ }));
118
+ return {
119
+ ...generationConfig,
120
+ db: { ...generationConfig.db, schemas },
121
+ lists,
122
+ };
123
+ },
81
124
  runtime: (context) => {
125
+ // Resolve the user list's context.db key from the configured user model.
126
+ // context.db is keyed camelCase, so 'User' -> 'user', 'AuthUser' -> 'authUser'.
127
+ const userDbKey = getDbKey(normalized.models.user.modelName);
82
128
  // Provide auth-related utilities at runtime
83
129
  return {
84
130
  /**
@@ -86,9 +132,7 @@ export function authPlugin(config) {
86
132
  * Uses the access-controlled context to fetch user data
87
133
  */
88
134
  getUser: async (userId) => {
89
- // Use 'authUser' if custom User list name was provided, otherwise 'user'
90
- const userListKey = 'user'; // TODO: Make this configurable based on list name
91
- return await context.db[userListKey].findUnique({
135
+ return await context.db[userDbKey].findUnique({
92
136
  where: { id: userId },
93
137
  });
94
138
  },
@@ -100,8 +144,7 @@ export function authPlugin(config) {
100
144
  if (!context.session?.userId) {
101
145
  return null;
102
146
  }
103
- const userListKey = 'user';
104
- return await context.db[userListKey].findUnique({
147
+ return await context.db[userDbKey].findUnique({
105
148
  where: { id: context.session.userId },
106
149
  });
107
150
  },
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/config/plugin.ts"],"names":[],"mappings":"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"}
@@ -75,6 +75,54 @@ export type SessionConfig = {
75
75
  */
76
76
  updateAge?: boolean;
77
77
  };
78
+ /**
79
+ * Per-model better-auth configuration block.
80
+ *
81
+ * Mirrors better-auth's own `BetterAuthDBOptions` (the `user`/`session`/
82
+ * `account`/`verification` config a developer already writes): `modelName`
83
+ * renames the table/list and `fields` maps individual better-auth field names
84
+ * to database column names. The auth plugin derives its Auth lists from this
85
+ * config so the generated lists carry the same keys and column maps as the
86
+ * developer's live better-auth tables.
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * authPlugin({
91
+ * user: { modelName: 'AuthUser', fields: { name: 'full_name' } },
92
+ * session: { modelName: 'AuthSession' },
93
+ * })
94
+ * ```
95
+ */
96
+ export type AuthModelConfig = {
97
+ /**
98
+ * The table/list name for this model.
99
+ * Becomes the OpenSaaS list key (and Prisma model name) and the table `@@map`.
100
+ * @default the default better-auth model name (e.g. 'User', 'Session')
101
+ */
102
+ modelName?: string;
103
+ /**
104
+ * Map better-auth field names to database column names.
105
+ * Each entry generates a `@map("column")` on the derived field.
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * fields: { name: 'full_name', emailVerified: 'email_verified' }
110
+ * ```
111
+ */
112
+ fields?: Record<string, string>;
113
+ /**
114
+ * Database schema (Postgres) for this auth model.
115
+ * Generates a `@@schema("...")` on the derived list, overriding the
116
+ * plugin-level {@link AuthConfig.schema} for this one model.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * // Place the verification table in a different schema from the rest
121
+ * verification: { schema: 'auth_internal' }
122
+ * ```
123
+ */
124
+ schema?: string;
125
+ };
78
126
  /**
79
127
  * Auth configuration options
80
128
  */
@@ -102,9 +150,56 @@ export type AuthConfig = {
102
150
  */
103
151
  socialProviders?: SocialProvidersConfig;
104
152
  /**
105
- * Session configuration
153
+ * Session configuration.
154
+ *
155
+ * Carries session expiry settings as well as the better-auth `session` model
156
+ * config (`modelName` + field column `fields` maps) used to derive the Auth
157
+ * session list.
158
+ */
159
+ session?: SessionConfig & AuthModelConfig;
160
+ /**
161
+ * better-auth `user` model configuration (modelName + field column maps).
162
+ * Used to derive the Auth user list's key, table `@@map`, and field `@map`s.
163
+ *
164
+ * Custom fields beyond the better-auth basics are added via `extendUserList`.
106
165
  */
107
- session?: SessionConfig;
166
+ user?: AuthModelConfig;
167
+ /**
168
+ * better-auth `account` model configuration (modelName + field column maps).
169
+ */
170
+ account?: AuthModelConfig;
171
+ /**
172
+ * better-auth `verification` model configuration (modelName + field column maps).
173
+ */
174
+ verification?: AuthModelConfig;
175
+ /**
176
+ * Database schema (Postgres) for the generated Auth lists.
177
+ *
178
+ * When set, all four Auth lists (user/session/account/verification) are placed
179
+ * in this schema via `@@schema(...)`, and the stack's multi-schema support is
180
+ * wired automatically: the datasource `schemas` array gains this schema (plus
181
+ * `public`) and the `multiSchema` preview feature is enabled. A per-model
182
+ * {@link AuthModelConfig.schema} overrides this for an individual list.
183
+ *
184
+ * Useful for adopting an existing separate-schema better-auth installation
185
+ * (e.g. an `auth` Postgres schema) so the generated lists diff clean against
186
+ * the live tables. When unset, the Auth lists stay in the default `public`
187
+ * schema and no `@@schema` is emitted (greenfield default unchanged).
188
+ *
189
+ * Only applies to the `postgresql` provider.
190
+ *
191
+ * @example Adopt an `auth`-schema better-auth install
192
+ * ```typescript
193
+ * authPlugin({
194
+ * schema: 'auth',
195
+ * user: { modelName: 'AuthUser' },
196
+ * session: { modelName: 'AuthSession' },
197
+ * account: { modelName: 'AuthAccount' },
198
+ * verification: { modelName: 'AuthVerification' },
199
+ * })
200
+ * ```
201
+ */
202
+ schema?: string;
108
203
  /**
109
204
  * Which fields to include in the session object
110
205
  * This determines what data is available in access control functions
@@ -194,14 +289,46 @@ export type AuthConfig = {
194
289
  max?: number;
195
290
  };
196
291
  };
292
+ /**
293
+ * Resolved per-model auth configuration after normalization.
294
+ * Always carries a concrete `modelName` (the developer's override or the
295
+ * better-auth default) and a (possibly empty) `fields` column map. `schema`
296
+ * carries the resolved Postgres schema for the model (per-model override, else
297
+ * the plugin-level schema, else `undefined` for the default `public` schema).
298
+ */
299
+ export type NormalizedAuthModelConfig = {
300
+ modelName: string;
301
+ fields: Record<string, string>;
302
+ schema?: string;
303
+ };
304
+ /**
305
+ * Resolved auth model configuration for all four better-auth models.
306
+ * Consumed by the Auth-list derivation and the runtime user-key resolution.
307
+ */
308
+ export type NormalizedAuthModels = {
309
+ user: NormalizedAuthModelConfig;
310
+ session: NormalizedAuthModelConfig;
311
+ account: NormalizedAuthModelConfig;
312
+ verification: NormalizedAuthModelConfig;
313
+ };
197
314
  /**
198
315
  * Internal normalized auth configuration
199
316
  * Used after parsing user config
200
317
  */
201
- export type NormalizedAuthConfig = Required<Omit<AuthConfig, 'emailAndPassword' | 'emailVerification' | 'passwordReset' | 'betterAuthPlugins' | 'rateLimit'>> & {
318
+ export type NormalizedAuthConfig = Required<Omit<AuthConfig, 'emailAndPassword' | 'emailVerification' | 'passwordReset' | 'betterAuthPlugins' | 'rateLimit' | 'session' | 'user' | 'account' | 'verification' | 'schema'>> & {
202
319
  emailAndPassword: Required<EmailPasswordConfig>;
203
320
  emailVerification: Required<EmailVerificationConfig>;
204
321
  passwordReset: Required<PasswordResetConfig>;
322
+ /** Resolved session expiry settings (model config lives under `models.session`). */
323
+ session: Required<SessionConfig>;
324
+ /** Resolved better-auth model config (modelName + field column maps + schema) for all auth models. */
325
+ models: NormalizedAuthModels;
326
+ /**
327
+ * Plugin-level Postgres schema for the Auth lists, if any. Resolved per-model
328
+ * schemas live on `models.<model>.schema`; this is the unresolved plugin-level
329
+ * default (used to wire the datasource `schemas` array during generation).
330
+ */
331
+ schema?: string;
205
332
  betterAuthPlugins: any[];
206
333
  rateLimit?: {
207
334
  enabled: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,10 @@ export { normalizeAuthConfig } from './config/index.js';
31
31
  export { authPlugin } from './config/plugin.js';
32
32
  export type { AuthConfig, NormalizedAuthConfig } from './config/index.js';
33
33
  export type * from './config/types.js';
34
+ export { deriveAuthLists } from './config/derive-auth-lists.js';
35
+ export type { DerivedAuthLists } from './config/derive-auth-lists.js';
36
+ export { adoptBetterAuthTables } from './config/adopt-better-auth-tables.js';
37
+ export type { AdoptBetterAuthTablesOptions, AdoptBetterAuthTablesConfig, } from './config/adopt-better-auth-tables.js';
34
38
  export type { AuthRuntimeServices } from './runtime/types.js';
35
39
  export { getAuthLists, createUserList, createSessionList, createAccountList, createVerificationList, } from './lists/index.js';
36
40
  export type { ExtendUserListConfig } from './lists/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACzE,mBAAmB,mBAAmB,CAAA;AAGtC,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACzE,mBAAmB,mBAAmB,CAAA;AAGtC,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAKrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAC5E,YAAY,EACV,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,sCAAsC,CAAA;AAG7C,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAG7D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -30,6 +30,12 @@
30
30
  // Config exports
31
31
  export { normalizeAuthConfig } from './config/index.js';
32
32
  export { authPlugin } from './config/plugin.js';
33
+ // Pure better-auth config -> Auth lists derivation (advanced use cases)
34
+ export { deriveAuthLists } from './config/derive-auth-lists.js';
35
+ // "Adopt existing better-auth tables" recipe — sets the model/schema knobs that
36
+ // match a pre-existing separate-schema better-auth install so a migrating
37
+ // project reaches Schema parity without rebuilding the config by hand.
38
+ export { adoptBetterAuthTables } from './config/adopt-better-auth-tables.js';
33
39
  // List generators (for advanced use cases)
34
40
  export { getAuthLists, createUserList, createSessionList, createAccountList, createVerificationList, } from './lists/index.js';
35
41
  //# 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iBAAiB;AACjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAO/C,2CAA2C;AAC3C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,iBAAiB;AACjB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAI/C,wEAAwE;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAG/D,gFAAgF;AAChF,0EAA0E;AAC1E,uEAAuE;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAA;AAS5E,2CAA2C;AAC3C,OAAO,EACL,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import type { ListConfig, FieldConfig } from '@opensaas/stack-core';
2
+ import type { NormalizedAuthModels } from '../config/types.js';
2
3
  /**
3
4
  * Configuration for extending the auto-generated User list
4
5
  */
@@ -19,28 +20,33 @@ export type ExtendUserListConfig = {
19
20
  hooks?: ListConfig<any>['hooks'];
20
21
  };
21
22
  /**
22
- * Create the base User list with better-auth required fields
23
- * This matches the better-auth user schema
23
+ * Create the base User list with better-auth required fields.
24
+ *
25
+ * Backwards-compatible helper: derives the default `User` list (keyed `User`,
26
+ * default field shapes) via {@link deriveAuthLists}.
24
27
  */
25
28
  export declare function createUserList(config?: ExtendUserListConfig): ListConfig<any>;
26
29
  /**
27
- * Create the Session list for better-auth
28
- * Stores active user sessions
30
+ * Create the Session list for better-auth (default `Session` key).
29
31
  */
30
32
  export declare function createSessionList(): ListConfig<any>;
31
33
  /**
32
- * Create the Account list for better-auth
33
- * Stores OAuth provider accounts and credentials
34
+ * Create the Account list for better-auth (default `Account` key).
34
35
  */
35
36
  export declare function createAccountList(): ListConfig<any>;
36
37
  /**
37
- * Create the Verification list for better-auth
38
- * Stores email verification tokens, password reset tokens, etc.
38
+ * Create the Verification list for better-auth (default `Verification` key).
39
39
  */
40
40
  export declare function createVerificationList(): ListConfig<any>;
41
41
  /**
42
- * Get all auth lists required by better-auth
43
- * This is the main export used by withAuth()
42
+ * Get all auth lists required by better-auth.
43
+ *
44
+ * Derives the Auth lists from the resolved better-auth model config. When no
45
+ * `models` are supplied (or none carry overrides), the result is the historical
46
+ * default set keyed `User`/`Session`/`Account`/`Verification`.
47
+ *
48
+ * @param userConfig - Extra User-list fields/access/hooks (from `extendUserList`)
49
+ * @param models - Resolved better-auth model config; defaults to the better-auth defaults
44
50
  */
45
- export declare function getAuthLists(userConfig?: ExtendUserListConfig): Record<string, ListConfig<any>>;
51
+ export declare function getAuthLists(userConfig?: ExtendUserListConfig, models?: NormalizedAuthModels): Record<string, ListConfig<any>>;
46
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lists/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAEnE;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACpC;;;OAGG;IAEH,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IAClC;;OAEG;IAEH,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;CACjC,CAAA;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,oBAAoB,GAC5B,UAAU,CAAC,GAAG,CAAC,CAqDjB;AAED;;;GAGG;AAEH,wBAAgB,iBAAiB,IAAI,UAAU,CAAC,GAAG,CAAC,CA+CnD;AAED;;;GAGG;AAEH,wBAAgB,iBAAiB,IAAI,UAAU,CAAC,GAAG,CAAC,CA0DnD;AAED;;;GAGG;AAEH,wBAAgB,sBAAsB,IAAI,UAAU,CAAC,GAAG,CAAC,CA2BxD;AAED;;;GAGG;AAEH,wBAAgB,YAAY,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAO/F"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lists/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAG9D;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACpC;;;OAGG;IAEH,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAA;IAClC;;OAEG;IAEH,KAAK,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAA;CACjC,CAAA;AAeD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,oBAAoB,GAE5B,UAAU,CAAC,GAAG,CAAC,CAEjB;AAED;;GAEG;AAEH,wBAAgB,iBAAiB,IAAI,UAAU,CAAC,GAAG,CAAC,CAEnD;AAED;;GAEG;AAEH,wBAAgB,iBAAiB,IAAI,UAAU,CAAC,GAAG,CAAC,CAEnD;AAED;;GAEG;AAEH,wBAAgB,sBAAsB,IAAI,UAAU,CAAC,GAAG,CAAC,CAExD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,UAAU,CAAC,EAAE,oBAAoB,EACjC,MAAM,GAAE,oBAAqC,GAE5C,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAEjC"}
@@ -1,231 +1,57 @@
1
- import { list } from '@opensaas/stack-core';
2
- import { text, timestamp, checkbox, relationship } from '@opensaas/stack-core/fields';
1
+ import { deriveAuthLists } from '../config/derive-auth-lists.js';
3
2
  /**
4
- * Create the base User list with better-auth required fields
5
- * This matches the better-auth user schema
3
+ * The default better-auth model config (no `modelName`/`fields` overrides).
4
+ * Produces the historical `User`/`Session`/`Account`/`Verification` keys with
5
+ * their original field shapes. Used by the backwards-compatible
6
+ * `createUserList`/`getAuthLists` helpers.
7
+ */
8
+ const DEFAULT_MODELS = {
9
+ user: { modelName: 'User', fields: {} },
10
+ session: { modelName: 'Session', fields: {} },
11
+ account: { modelName: 'Account', fields: {} },
12
+ verification: { modelName: 'Verification', fields: {} },
13
+ };
14
+ /**
15
+ * Create the base User list with better-auth required fields.
16
+ *
17
+ * Backwards-compatible helper: derives the default `User` list (keyed `User`,
18
+ * default field shapes) via {@link deriveAuthLists}.
6
19
  */
7
20
  export function createUserList(config) {
8
- return list({
9
- fields: {
10
- // Better-auth required fields
11
- name: text({
12
- validation: { isRequired: true },
13
- }),
14
- email: text({
15
- validation: { isRequired: true },
16
- isIndexed: 'unique',
17
- }),
18
- emailVerified: checkbox({
19
- defaultValue: false,
20
- }),
21
- image: text(),
22
- // Relationships to other auth tables
23
- sessions: relationship({
24
- ref: 'Session.user',
25
- many: true,
26
- }),
27
- accounts: relationship({
28
- ref: 'Account.user',
29
- many: true,
30
- }),
31
- // Custom fields from user config
32
- ...(config?.fields || {}),
33
- },
34
- access: config?.access || {
35
- operation: {
36
- // Anyone can query users (for displaying names, etc.)
37
- query: () => true,
38
- // Anyone can create a user (sign up)
39
- create: () => true,
40
- // Only update your own user record
41
- update: ({ session, item }) => {
42
- if (!session)
43
- return false;
44
- const userId = session.userId;
45
- const itemId = item?.id;
46
- return userId === itemId;
47
- },
48
- // Only delete your own user record
49
- delete: ({ session, item }) => {
50
- if (!session)
51
- return false;
52
- const userId = session.userId;
53
- const itemId = item?.id;
54
- return userId === itemId;
55
- },
56
- },
57
- },
58
- hooks: config?.hooks,
59
- });
21
+ return deriveAuthLists(DEFAULT_MODELS, config).lists.User;
60
22
  }
61
23
  /**
62
- * Create the Session list for better-auth
63
- * Stores active user sessions
24
+ * Create the Session list for better-auth (default `Session` key).
64
25
  */
65
26
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
66
27
  export function createSessionList() {
67
- return list({
68
- fields: {
69
- // Session token (stored in cookie, used as primary key)
70
- token: text({
71
- validation: { isRequired: true },
72
- isIndexed: 'unique',
73
- }),
74
- // Expiration timestamp
75
- expiresAt: timestamp(),
76
- // Optional: IP address for security
77
- ipAddress: text(),
78
- // Optional: User agent for security
79
- userAgent: text(),
80
- // Relationship to user (userId will be auto-generated)
81
- user: relationship({
82
- ref: 'User.sessions',
83
- }),
84
- },
85
- access: {
86
- operation: {
87
- // Only the session owner can query their sessions
88
- query: ({ session }) => {
89
- if (!session)
90
- return false;
91
- const userId = session.userId;
92
- if (!userId)
93
- return false;
94
- // Return Prisma filter for nested relationship
95
- return {
96
- user: {
97
- id: { equals: userId },
98
- },
99
- };
100
- },
101
- // Better-auth handles session creation
102
- create: () => true,
103
- // No manual updates
104
- update: () => false,
105
- // Better-auth handles session deletion (logout)
106
- delete: ({ session, item }) => {
107
- if (!session)
108
- return false;
109
- const userId = session.userId;
110
- const itemUserId = item?.user?.id;
111
- return userId === itemUserId;
112
- },
113
- },
114
- },
115
- });
28
+ return deriveAuthLists(DEFAULT_MODELS).lists.Session;
116
29
  }
117
30
  /**
118
- * Create the Account list for better-auth
119
- * Stores OAuth provider accounts and credentials
31
+ * Create the Account list for better-auth (default `Account` key).
120
32
  */
121
33
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
122
34
  export function createAccountList() {
123
- return list({
124
- fields: {
125
- // Account identifier from provider
126
- accountId: text({
127
- validation: { isRequired: true },
128
- }),
129
- // Provider identifier (e.g., 'github', 'google', 'credentials')
130
- providerId: text({
131
- validation: { isRequired: true },
132
- }),
133
- // Relationship to user (userId will be auto-generated)
134
- user: relationship({
135
- ref: 'User.accounts',
136
- }),
137
- // OAuth tokens
138
- accessToken: text(),
139
- refreshToken: text(),
140
- accessTokenExpiresAt: timestamp(),
141
- refreshTokenExpiresAt: timestamp(),
142
- scope: text(),
143
- idToken: text(),
144
- // Password hash for credential provider (better-auth stores in account table)
145
- password: text(),
146
- },
147
- access: {
148
- operation: {
149
- // Only the account owner can query their accounts
150
- query: ({ session }) => {
151
- if (!session)
152
- return false;
153
- const userId = session.userId;
154
- if (!userId)
155
- return false;
156
- // Return Prisma filter for nested relationship
157
- return {
158
- user: {
159
- id: { equals: userId },
160
- },
161
- };
162
- },
163
- // Better-auth handles account creation
164
- create: () => true,
165
- // Better-auth handles account updates (token refresh)
166
- update: ({ session, item }) => {
167
- if (!session)
168
- return false;
169
- const userId = session.userId;
170
- const itemUserId = item?.user?.id;
171
- return userId === itemUserId;
172
- },
173
- // Account owner can delete their accounts
174
- delete: ({ session, item }) => {
175
- if (!session)
176
- return false;
177
- const userId = session.userId;
178
- const itemUserId = item?.user?.id;
179
- return userId === itemUserId;
180
- },
181
- },
182
- },
183
- });
35
+ return deriveAuthLists(DEFAULT_MODELS).lists.Account;
184
36
  }
185
37
  /**
186
- * Create the Verification list for better-auth
187
- * Stores email verification tokens, password reset tokens, etc.
38
+ * Create the Verification list for better-auth (default `Verification` key).
188
39
  */
189
40
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
190
41
  export function createVerificationList() {
191
- return list({
192
- fields: {
193
- // Identifier (e.g., email address)
194
- identifier: text({
195
- validation: { isRequired: true },
196
- }),
197
- // Token value
198
- value: text({
199
- validation: { isRequired: true },
200
- }),
201
- // Expiration timestamp
202
- expiresAt: timestamp(),
203
- },
204
- access: {
205
- operation: {
206
- // No public querying (better-auth handles verification internally)
207
- query: () => false,
208
- // Better-auth creates verification tokens
209
- create: () => true,
210
- // No updates
211
- update: () => false,
212
- // Better-auth deletes used/expired tokens
213
- delete: () => true,
214
- },
215
- },
216
- });
42
+ return deriveAuthLists(DEFAULT_MODELS).lists.Verification;
217
43
  }
218
44
  /**
219
- * Get all auth lists required by better-auth
220
- * This is the main export used by withAuth()
45
+ * Get all auth lists required by better-auth.
46
+ *
47
+ * Derives the Auth lists from the resolved better-auth model config. When no
48
+ * `models` are supplied (or none carry overrides), the result is the historical
49
+ * default set keyed `User`/`Session`/`Account`/`Verification`.
50
+ *
51
+ * @param userConfig - Extra User-list fields/access/hooks (from `extendUserList`)
52
+ * @param models - Resolved better-auth model config; defaults to the better-auth defaults
221
53
  */
222
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- ListConfig must accept any TypeInfo
223
- export function getAuthLists(userConfig) {
224
- return {
225
- User: createUserList(userConfig),
226
- Session: createSessionList(),
227
- Account: createAccountList(),
228
- Verification: createVerificationList(),
229
- };
54
+ export function getAuthLists(userConfig, models = DEFAULT_MODELS) {
55
+ return deriveAuthLists(models, userConfig || {}).lists;
230
56
  }
231
57
  //# sourceMappingURL=index.js.map