@delmaredigital/payload-better-auth 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/dist/adapter/collections.d.ts.map +1 -1
- package/dist/adapter/collections.js +126 -88
- package/dist/adapter/collections.js.map +1 -1
- package/dist/adapter/index.js +197 -150
- package/dist/adapter/index.js.map +1 -1
- package/dist/components/BeforeLogin.d.ts +1 -1
- package/dist/components/BeforeLogin.d.ts.map +1 -1
- package/dist/components/BeforeLogin.js +15 -7
- package/dist/components/BeforeLogin.js.map +1 -1
- package/dist/components/LoginView.d.ts +2 -2
- package/dist/components/LoginView.d.ts.map +1 -1
- package/dist/components/LoginView.js +660 -218
- package/dist/components/LoginView.js.map +1 -1
- package/dist/components/LoginViewWrapper.d.ts +1 -1
- package/dist/components/LoginViewWrapper.d.ts.map +1 -1
- package/dist/components/LoginViewWrapper.js +14 -4
- package/dist/components/LoginViewWrapper.js.map +1 -1
- package/dist/components/LogoutButton.d.ts +1 -1
- package/dist/components/LogoutButton.d.ts.map +1 -1
- package/dist/components/LogoutButton.js +19 -11
- package/dist/components/LogoutButton.js.map +1 -1
- package/dist/components/PasskeyRegisterButton.d.ts +2 -2
- package/dist/components/PasskeyRegisterButton.d.ts.map +1 -1
- package/dist/components/PasskeyRegisterButton.js +20 -16
- package/dist/components/PasskeyRegisterButton.js.map +1 -1
- package/dist/components/PasskeySignInButton.d.ts +2 -2
- package/dist/components/PasskeySignInButton.d.ts.map +1 -1
- package/dist/components/PasskeySignInButton.js +14 -12
- package/dist/components/PasskeySignInButton.js.map +1 -1
- package/dist/components/auth/ForgotPasswordView.d.ts +1 -1
- package/dist/components/auth/ForgotPasswordView.d.ts.map +1 -1
- package/dist/components/auth/ForgotPasswordView.js +133 -43
- package/dist/components/auth/ForgotPasswordView.js.map +1 -1
- package/dist/components/auth/ResetPasswordView.d.ts +1 -1
- package/dist/components/auth/ResetPasswordView.d.ts.map +1 -1
- package/dist/components/auth/ResetPasswordView.js +154 -50
- package/dist/components/auth/ResetPasswordView.js.map +1 -1
- package/dist/components/auth/index.js +2 -2
- package/dist/components/auth/index.js.map +1 -1
- package/dist/components/management/ApiKeysManagementClient.d.ts +2 -2
- package/dist/components/management/ApiKeysManagementClient.d.ts.map +1 -1
- package/dist/components/management/ApiKeysManagementClient.js +539 -222
- package/dist/components/management/ApiKeysManagementClient.js.map +1 -1
- package/dist/components/management/PasskeysManagementClient.d.ts +2 -2
- package/dist/components/management/PasskeysManagementClient.d.ts.map +1 -1
- package/dist/components/management/PasskeysManagementClient.js +215 -92
- package/dist/components/management/PasskeysManagementClient.js.map +1 -1
- package/dist/components/management/SecurityNavLinks.d.ts +1 -1
- package/dist/components/management/SecurityNavLinks.d.ts.map +1 -1
- package/dist/components/management/SecurityNavLinks.js +51 -24
- package/dist/components/management/SecurityNavLinks.js.map +1 -1
- package/dist/components/management/TwoFactorManagementClient.d.ts +2 -2
- package/dist/components/management/TwoFactorManagementClient.d.ts.map +1 -1
- package/dist/components/management/TwoFactorManagementClient.js +270 -111
- package/dist/components/management/TwoFactorManagementClient.js.map +1 -1
- package/dist/components/management/index.js +2 -2
- package/dist/components/management/index.js.map +1 -1
- package/dist/components/management/views/ApiKeysView.d.ts +1 -1
- package/dist/components/management/views/ApiKeysView.d.ts.map +1 -1
- package/dist/components/management/views/ApiKeysView.js +19 -4
- package/dist/components/management/views/ApiKeysView.js.map +1 -1
- package/dist/components/management/views/PasskeysView.d.ts +1 -1
- package/dist/components/management/views/PasskeysView.d.ts.map +1 -1
- package/dist/components/management/views/PasskeysView.js +16 -4
- package/dist/components/management/views/PasskeysView.js.map +1 -1
- package/dist/components/management/views/TwoFactorView.d.ts +1 -1
- package/dist/components/management/views/TwoFactorView.d.ts.map +1 -1
- package/dist/components/management/views/TwoFactorView.js +16 -4
- package/dist/components/management/views/TwoFactorView.js.map +1 -1
- package/dist/components/management/views/index.js +2 -2
- package/dist/components/management/views/index.js.map +1 -1
- package/dist/components/twoFactor/TwoFactorSetupView.d.ts +1 -1
- package/dist/components/twoFactor/TwoFactorSetupView.d.ts.map +1 -1
- package/dist/components/twoFactor/TwoFactorSetupView.js +240 -87
- package/dist/components/twoFactor/TwoFactorSetupView.js.map +1 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.d.ts +1 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.d.ts.map +1 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.js +108 -45
- package/dist/components/twoFactor/TwoFactorVerifyView.js.map +1 -1
- package/dist/components/twoFactor/index.js +2 -2
- package/dist/components/twoFactor/index.js.map +1 -1
- package/dist/exports/client.js +9 -10
- package/dist/exports/client.js.map +1 -1
- package/dist/exports/components.js +2 -2
- package/dist/exports/components.js.map +1 -1
- package/dist/exports/management.js +3 -3
- package/dist/exports/management.js.map +1 -1
- package/dist/exports/rsc.js +2 -2
- package/dist/exports/rsc.js.map +1 -1
- package/dist/generated-types.js +4 -2
- package/dist/generated-types.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +198 -162
- package/dist/plugin/index.js.map +1 -1
- package/dist/scripts/generate-types.js +66 -50
- package/dist/scripts/generate-types.js.map +1 -1
- package/dist/types/apiKey.js +7 -2
- package/dist/types/apiKey.js.map +1 -1
- package/dist/types/betterAuth.js +23 -2
- package/dist/types/betterAuth.js.map +1 -1
- package/dist/utils/access.js +78 -81
- package/dist/utils/access.js.map +1 -1
- package/dist/utils/apiKeyAccess.js +65 -72
- package/dist/utils/apiKeyAccess.js.map +1 -1
- package/dist/utils/betterAuthDefaults.js +8 -8
- package/dist/utils/betterAuthDefaults.js.map +1 -1
- package/dist/utils/detectAuthConfig.js +8 -11
- package/dist/utils/detectAuthConfig.js.map +1 -1
- package/dist/utils/detectEnabledPlugins.js +6 -7
- package/dist/utils/detectEnabledPlugins.js.map +1 -1
- package/dist/utils/firstUserAdmin.js +18 -20
- package/dist/utils/firstUserAdmin.js.map +1 -1
- package/dist/utils/generateScopes.js +40 -41
- package/dist/utils/generateScopes.js.map +1 -1
- package/dist/utils/session.js +8 -9
- package/dist/utils/session.js.map +1 -1
- package/package.json +27 -13
package/README.md
CHANGED
|
@@ -367,12 +367,23 @@ betterAuthCollections({
|
|
|
367
367
|
| `betterAuthOptions` | `BetterAuthOptions` | Your Better Auth options |
|
|
368
368
|
| `skipCollections` | `string[]` | Collections to skip generating (default: `['user']`) |
|
|
369
369
|
| `adminGroup` | `string` | Admin panel group name (default: `'Auth'`) |
|
|
370
|
-
| `access` | `CollectionConfig['access']` | Custom access control for generated collections |
|
|
370
|
+
| `access` | `CollectionConfig['access']` | Custom access control for generated collections. **Note**: Replaces default access entirely (see caution below). |
|
|
371
371
|
| `usePlural` | `boolean` | Pluralize collection slugs (default: `true`) |
|
|
372
372
|
| `configureSaveToJWT` | `boolean` | Auto-configure `saveToJWT` for session-critical fields (default: `true`) |
|
|
373
373
|
| `firstUserAdmin` | `boolean \| FirstUserAdminOptions` | Make first registered user an admin (default: `true`) |
|
|
374
374
|
| `customizeCollection` | `(modelKey, collection) => CollectionConfig` | Customize generated collections |
|
|
375
375
|
|
|
376
|
+
> **⚠️ Caution on Custom Access:**
|
|
377
|
+
> When providing the `access` option, it **completely replaces** the default access object for all auto-generated collections. It does not merge with or override individual properties.
|
|
378
|
+
>
|
|
379
|
+
> By default, the plugin sets:
|
|
380
|
+
> - `read`: `isAdmin()`
|
|
381
|
+
> - `delete`: `isAdmin()`
|
|
382
|
+
> - `create`: `() => false` (Manual creation disabled - Better Auth manages these)
|
|
383
|
+
> - `update`: `() => false` (Manual update disabled - Better Auth manages these)
|
|
384
|
+
>
|
|
385
|
+
> You must explicitly handle all access types to ensure your collections remain secure and functional.
|
|
386
|
+
|
|
376
387
|
**First User Admin:**
|
|
377
388
|
|
|
378
389
|
By default, the first user to register is automatically assigned the admin role. This provides a better out-of-the-box experience - no need to manually update the database to create your first admin.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/adapter/collections.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAU,gBAAgB,EAAS,MAAM,EAA8B,MAAM,SAAS,CAAA;AAClG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/adapter/collections.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAU,gBAAgB,EAAS,MAAM,EAA8B,MAAM,SAAS,CAAA;AAClG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAGvE,YAAY,EAAE,qBAAqB,EAAE,CAAA;AAErC,MAAM,MAAM,4BAA4B,GAAG;IACzC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IAErC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAE1B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAEnC;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAE5B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,qBAAqB,CAAA;IAEhD;;;;;;;;;;;;;;;;;;OAkBG;IACH,mBAAmB,CAAC,EAAE,CACpB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,gBAAgB,KACzB,gBAAgB,CAAA;CACtB,CAAA;AA2XD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,MAAM,CAuGR"}
|
|
@@ -2,69 +2,82 @@
|
|
|
2
2
|
* Auto-generate Payload collections from Better Auth schema
|
|
3
3
|
*
|
|
4
4
|
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
import {
|
|
5
|
+
*/ import { getAuthTables } from 'better-auth/db';
|
|
6
|
+
import { isAdmin } from '../utils/access.js';
|
|
7
7
|
/**
|
|
8
8
|
* Creates a beforeChange hook that makes the first user an admin.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return async ({ data, operation, req }) => {
|
|
9
|
+
*/ function createFirstUserAdminHook(options, usersSlug) {
|
|
10
|
+
const { adminRole = 'admin', defaultRole = 'user', roleField = 'role' } = options;
|
|
11
|
+
return async ({ data, operation, req })=>{
|
|
13
12
|
if (operation !== 'create') {
|
|
14
13
|
return data;
|
|
15
14
|
}
|
|
16
15
|
try {
|
|
17
16
|
const { totalDocs } = await req.payload.count({
|
|
18
17
|
collection: usersSlug,
|
|
19
|
-
overrideAccess: true
|
|
18
|
+
overrideAccess: true
|
|
20
19
|
});
|
|
21
20
|
if (totalDocs === 0) {
|
|
22
21
|
// First user becomes admin
|
|
23
22
|
return {
|
|
24
23
|
...data,
|
|
25
|
-
[roleField]: adminRole
|
|
24
|
+
[roleField]: adminRole
|
|
26
25
|
};
|
|
27
26
|
}
|
|
28
27
|
// Subsequent users get default role if not already set
|
|
29
28
|
return {
|
|
30
29
|
...data,
|
|
31
|
-
[roleField]: data[roleField] ?? defaultRole
|
|
30
|
+
[roleField]: data[roleField] ?? defaultRole
|
|
32
31
|
};
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
32
|
+
} catch (error) {
|
|
35
33
|
// On error, don't block user creation - just use provided or default role
|
|
36
34
|
console.warn('[betterAuthCollections] Failed to check user count:', error);
|
|
37
35
|
return {
|
|
38
36
|
...data,
|
|
39
|
-
[roleField]: data[roleField] ?? defaultRole
|
|
37
|
+
[roleField]: data[roleField] ?? defaultRole
|
|
40
38
|
};
|
|
41
39
|
}
|
|
42
40
|
};
|
|
43
41
|
}
|
|
44
42
|
/**
|
|
45
43
|
* Inject the first-user-admin hook into a collection's hooks.
|
|
46
|
-
*/
|
|
47
|
-
function injectFirstUserAdminHook(collection, options, usersSlug) {
|
|
44
|
+
*/ function injectFirstUserAdminHook(collection, options, usersSlug) {
|
|
48
45
|
const hook = createFirstUserAdminHook(options, usersSlug);
|
|
49
46
|
const existingHooks = collection.hooks?.beforeChange ?? [];
|
|
50
47
|
return {
|
|
51
48
|
...collection,
|
|
52
49
|
hooks: {
|
|
53
50
|
...collection.hooks,
|
|
54
|
-
beforeChange: [
|
|
55
|
-
|
|
51
|
+
beforeChange: [
|
|
52
|
+
hook,
|
|
53
|
+
...Array.isArray(existingHooks) ? existingHooks : [
|
|
54
|
+
existingHooks
|
|
55
|
+
]
|
|
56
|
+
]
|
|
57
|
+
}
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
/**
|
|
59
61
|
* Determine if a field should be saved to JWT.
|
|
60
62
|
* Session-critical fields are included, large data fields are excluded.
|
|
61
|
-
*/
|
|
62
|
-
function getSaveToJWT(modelKey, fieldName) {
|
|
63
|
+
*/ function getSaveToJWT(modelKey, fieldName) {
|
|
63
64
|
// Session fields - include core session data
|
|
64
65
|
if (modelKey === 'session') {
|
|
65
|
-
const includeFields = [
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
const includeFields = [
|
|
67
|
+
'token',
|
|
68
|
+
'expiresAt',
|
|
69
|
+
'user',
|
|
70
|
+
'userId',
|
|
71
|
+
'ipAddress',
|
|
72
|
+
'userAgent',
|
|
73
|
+
'activeOrganizationId',
|
|
74
|
+
'activeTeamId'
|
|
75
|
+
];
|
|
76
|
+
const excludeFields = [
|
|
77
|
+
'createdAt',
|
|
78
|
+
'updatedAt'
|
|
79
|
+
];
|
|
80
|
+
if (includeFields.some((f)=>fieldName === f || fieldName.endsWith(f.charAt(0).toUpperCase() + f.slice(1)))) {
|
|
68
81
|
return true;
|
|
69
82
|
}
|
|
70
83
|
if (excludeFields.includes(fieldName)) {
|
|
@@ -73,8 +86,19 @@ function getSaveToJWT(modelKey, fieldName) {
|
|
|
73
86
|
}
|
|
74
87
|
// User fields - include essential auth data
|
|
75
88
|
if (modelKey === 'user') {
|
|
76
|
-
const includeFields = [
|
|
77
|
-
|
|
89
|
+
const includeFields = [
|
|
90
|
+
'role',
|
|
91
|
+
'email',
|
|
92
|
+
'emailVerified',
|
|
93
|
+
'name',
|
|
94
|
+
'twoFactorEnabled',
|
|
95
|
+
'banned'
|
|
96
|
+
];
|
|
97
|
+
const excludeFields = [
|
|
98
|
+
'image',
|
|
99
|
+
'password',
|
|
100
|
+
'banReason'
|
|
101
|
+
];
|
|
78
102
|
if (includeFields.includes(fieldName)) {
|
|
79
103
|
return true;
|
|
80
104
|
}
|
|
@@ -95,17 +119,15 @@ function getSaveToJWT(modelKey, fieldName) {
|
|
|
95
119
|
}
|
|
96
120
|
/**
|
|
97
121
|
* Simple pluralization (add 's' suffix)
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
if (name.endsWith('s'))
|
|
101
|
-
return name;
|
|
122
|
+
*/ function pluralize(name) {
|
|
123
|
+
if (name.endsWith('s')) return name;
|
|
102
124
|
return `${name}s`;
|
|
103
125
|
}
|
|
104
126
|
function mapFieldType(type, fieldName, hasReferences) {
|
|
105
127
|
if (hasReferences) {
|
|
106
128
|
return 'relationship';
|
|
107
129
|
}
|
|
108
|
-
switch
|
|
130
|
+
switch(type){
|
|
109
131
|
case 'boolean':
|
|
110
132
|
return 'checkbox';
|
|
111
133
|
case 'number':
|
|
@@ -113,15 +135,15 @@ function mapFieldType(type, fieldName, hasReferences) {
|
|
|
113
135
|
case 'date':
|
|
114
136
|
return 'date';
|
|
115
137
|
case 'string':
|
|
116
|
-
if (fieldName === 'email')
|
|
117
|
-
return 'email';
|
|
138
|
+
if (fieldName === 'email') return 'email';
|
|
118
139
|
return 'text';
|
|
119
140
|
case 'json':
|
|
120
141
|
case 'object':
|
|
121
142
|
return 'json';
|
|
122
143
|
case 'string[]':
|
|
123
144
|
case 'array':
|
|
124
|
-
return 'json'
|
|
145
|
+
return 'json' // Payload doesn't have native string array, use JSON
|
|
146
|
+
;
|
|
125
147
|
default:
|
|
126
148
|
return 'text';
|
|
127
149
|
}
|
|
@@ -135,8 +157,12 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
135
157
|
const baseName = table.modelName ?? modelKey;
|
|
136
158
|
const slug = usePlural ? pluralize(baseName) : baseName;
|
|
137
159
|
const fields = [];
|
|
138
|
-
for (const [fieldKey, fieldDef] of Object.entries(table.fields))
|
|
139
|
-
if ([
|
|
160
|
+
for (const [fieldKey, fieldDef] of Object.entries(table.fields)){
|
|
161
|
+
if ([
|
|
162
|
+
'id',
|
|
163
|
+
'createdAt',
|
|
164
|
+
'updatedAt'
|
|
165
|
+
].includes(fieldKey)) {
|
|
140
166
|
continue;
|
|
141
167
|
}
|
|
142
168
|
const fieldName = fieldDef.fieldName ?? fieldKey;
|
|
@@ -147,8 +173,7 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
147
173
|
let relationTo;
|
|
148
174
|
if (fieldDef.references?.model) {
|
|
149
175
|
relationTo = usePlural ? pluralize(fieldDef.references.model) : fieldDef.references.model;
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
176
|
+
} else {
|
|
152
177
|
relationTo = extractRelationTarget(fieldKey, usePlural);
|
|
153
178
|
}
|
|
154
179
|
const relFieldName = fieldName.replace(/(_id|Id)$/, '');
|
|
@@ -159,7 +184,9 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
159
184
|
relationTo,
|
|
160
185
|
required: fieldDef.required ?? false,
|
|
161
186
|
index: true,
|
|
162
|
-
...
|
|
187
|
+
...saveToJWT !== undefined && {
|
|
188
|
+
saveToJWT
|
|
189
|
+
}
|
|
163
190
|
});
|
|
164
191
|
continue;
|
|
165
192
|
}
|
|
@@ -167,10 +194,11 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
167
194
|
const field = {
|
|
168
195
|
name: fieldName,
|
|
169
196
|
type: fieldType,
|
|
170
|
-
...
|
|
197
|
+
...saveToJWT !== undefined && {
|
|
198
|
+
saveToJWT
|
|
199
|
+
}
|
|
171
200
|
};
|
|
172
|
-
if (fieldDef.required)
|
|
173
|
-
field.required = true;
|
|
201
|
+
if (fieldDef.required) field.required = true;
|
|
174
202
|
if (fieldDef.unique) {
|
|
175
203
|
field.unique = true;
|
|
176
204
|
field.index = true;
|
|
@@ -180,8 +208,7 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
180
208
|
if (typeof defaultValue === 'function') {
|
|
181
209
|
try {
|
|
182
210
|
defaultValue = defaultValue();
|
|
183
|
-
}
|
|
184
|
-
catch {
|
|
211
|
+
} catch {
|
|
185
212
|
defaultValue = undefined;
|
|
186
213
|
}
|
|
187
214
|
}
|
|
@@ -191,33 +218,37 @@ function generateCollection(modelKey, table, usePlural, adminGroup, customAccess
|
|
|
191
218
|
}
|
|
192
219
|
fields.push(field);
|
|
193
220
|
}
|
|
194
|
-
const titleField = [
|
|
221
|
+
const titleField = [
|
|
222
|
+
'name',
|
|
223
|
+
'email',
|
|
224
|
+
'title',
|
|
225
|
+
'identifier'
|
|
226
|
+
].find((f)=>fields.some((field)=>'name' in field && field.name === f));
|
|
195
227
|
// Default access: admin-only read/delete, disabled manual create/update via admin UI
|
|
196
228
|
// The adapter uses overrideAccess: true for programmatic operations from Better Auth
|
|
197
229
|
const defaultAccess = {
|
|
198
|
-
read: (
|
|
199
|
-
create: ()
|
|
200
|
-
update: ()
|
|
201
|
-
delete: (
|
|
230
|
+
read: isAdmin(),
|
|
231
|
+
create: ()=>false,
|
|
232
|
+
update: ()=>false,
|
|
233
|
+
delete: isAdmin()
|
|
202
234
|
};
|
|
203
235
|
return {
|
|
204
236
|
slug,
|
|
205
237
|
admin: {
|
|
206
238
|
useAsTitle: titleField ?? 'id',
|
|
207
239
|
group: adminGroup,
|
|
208
|
-
description: `Auto-generated from Better Auth schema (${modelKey})
|
|
240
|
+
description: `Auto-generated from Better Auth schema (${modelKey})`
|
|
209
241
|
},
|
|
210
242
|
access: customAccess ?? defaultAccess,
|
|
211
243
|
fields,
|
|
212
|
-
timestamps: true
|
|
244
|
+
timestamps: true
|
|
213
245
|
};
|
|
214
246
|
}
|
|
215
247
|
/**
|
|
216
248
|
* Get existing field names from a collection, handling nested field structures.
|
|
217
|
-
*/
|
|
218
|
-
function getExistingFieldNames(fields) {
|
|
249
|
+
*/ function getExistingFieldNames(fields) {
|
|
219
250
|
const names = new Set();
|
|
220
|
-
for (const field of fields)
|
|
251
|
+
for (const field of fields){
|
|
221
252
|
if ('name' in field && field.name) {
|
|
222
253
|
names.add(field.name);
|
|
223
254
|
}
|
|
@@ -227,21 +258,22 @@ function getExistingFieldNames(fields) {
|
|
|
227
258
|
/**
|
|
228
259
|
* Augment an existing collection with missing fields from Better Auth schema.
|
|
229
260
|
* This ensures user-defined collections (like 'users') get plugin fields automatically.
|
|
230
|
-
*/
|
|
231
|
-
function augmentCollectionWithMissingFields(collection, table, usePlural, modelKey, configureSaveToJWT = true) {
|
|
261
|
+
*/ function augmentCollectionWithMissingFields(collection, table, usePlural, modelKey, configureSaveToJWT = true) {
|
|
232
262
|
const existingFieldNames = getExistingFieldNames(collection.fields);
|
|
233
263
|
const missingFields = [];
|
|
234
|
-
for (const [fieldKey, fieldDef] of Object.entries(table.fields))
|
|
264
|
+
for (const [fieldKey, fieldDef] of Object.entries(table.fields)){
|
|
235
265
|
// Skip standard fields that Payload handles
|
|
236
|
-
if ([
|
|
266
|
+
if ([
|
|
267
|
+
'id',
|
|
268
|
+
'createdAt',
|
|
269
|
+
'updatedAt'
|
|
270
|
+
].includes(fieldKey)) {
|
|
237
271
|
continue;
|
|
238
272
|
}
|
|
239
273
|
const fieldName = fieldDef.fieldName ?? fieldKey;
|
|
240
274
|
const hasReferences = fieldDef.references !== undefined;
|
|
241
275
|
// For reference fields, check the name without Id suffix
|
|
242
|
-
const payloadFieldName = hasReferences
|
|
243
|
-
? fieldName.replace(/(_id|Id)$/, '')
|
|
244
|
-
: fieldName;
|
|
276
|
+
const payloadFieldName = hasReferences ? fieldName.replace(/(_id|Id)$/, '') : fieldName;
|
|
245
277
|
// Skip if field already exists
|
|
246
278
|
if (existingFieldNames.has(payloadFieldName)) {
|
|
247
279
|
continue;
|
|
@@ -252,8 +284,7 @@ function augmentCollectionWithMissingFields(collection, table, usePlural, modelK
|
|
|
252
284
|
let relationTo;
|
|
253
285
|
if (fieldDef.references?.model) {
|
|
254
286
|
relationTo = usePlural ? pluralize(fieldDef.references.model) : fieldDef.references.model;
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
287
|
+
} else {
|
|
257
288
|
relationTo = extractRelationTarget(fieldKey, usePlural);
|
|
258
289
|
}
|
|
259
290
|
const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, payloadFieldName) : undefined;
|
|
@@ -264,23 +295,25 @@ function augmentCollectionWithMissingFields(collection, table, usePlural, modelK
|
|
|
264
295
|
required: fieldDef.required ?? false,
|
|
265
296
|
index: true,
|
|
266
297
|
admin: {
|
|
267
|
-
description: `Auto-added by Better Auth (${fieldKey})
|
|
298
|
+
description: `Auto-added by Better Auth (${fieldKey})`
|
|
268
299
|
},
|
|
269
|
-
...
|
|
300
|
+
...saveToJWT !== undefined && {
|
|
301
|
+
saveToJWT
|
|
302
|
+
}
|
|
270
303
|
});
|
|
271
|
-
}
|
|
272
|
-
else {
|
|
304
|
+
} else {
|
|
273
305
|
const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, payloadFieldName) : undefined;
|
|
274
306
|
const field = {
|
|
275
307
|
name: payloadFieldName,
|
|
276
308
|
type: fieldType,
|
|
277
309
|
admin: {
|
|
278
|
-
description: `Auto-added by Better Auth (${fieldKey})
|
|
310
|
+
description: `Auto-added by Better Auth (${fieldKey})`
|
|
279
311
|
},
|
|
280
|
-
...
|
|
312
|
+
...saveToJWT !== undefined && {
|
|
313
|
+
saveToJWT
|
|
314
|
+
}
|
|
281
315
|
};
|
|
282
|
-
if (fieldDef.required)
|
|
283
|
-
field.required = true;
|
|
316
|
+
if (fieldDef.required) field.required = true;
|
|
284
317
|
if (fieldDef.unique) {
|
|
285
318
|
field.unique = true;
|
|
286
319
|
field.index = true;
|
|
@@ -290,8 +323,7 @@ function augmentCollectionWithMissingFields(collection, table, usePlural, modelK
|
|
|
290
323
|
if (typeof defaultValue === 'function') {
|
|
291
324
|
try {
|
|
292
325
|
defaultValue = defaultValue();
|
|
293
|
-
}
|
|
294
|
-
catch {
|
|
326
|
+
} catch {
|
|
295
327
|
defaultValue = undefined;
|
|
296
328
|
}
|
|
297
329
|
}
|
|
@@ -309,7 +341,10 @@ function augmentCollectionWithMissingFields(collection, table, usePlural, modelK
|
|
|
309
341
|
// Return augmented collection
|
|
310
342
|
return {
|
|
311
343
|
...collection,
|
|
312
|
-
fields: [
|
|
344
|
+
fields: [
|
|
345
|
+
...collection.fields,
|
|
346
|
+
...missingFields
|
|
347
|
+
]
|
|
313
348
|
};
|
|
314
349
|
}
|
|
315
350
|
/**
|
|
@@ -344,26 +379,25 @@ function augmentCollectionWithMissingFields(collection, table, usePlural, modelK
|
|
|
344
379
|
* },
|
|
345
380
|
* })
|
|
346
381
|
* ```
|
|
347
|
-
*/
|
|
348
|
-
|
|
349
|
-
|
|
382
|
+
*/ export function betterAuthCollections(options = {}) {
|
|
383
|
+
const { betterAuthOptions = {}, skipCollections = [
|
|
384
|
+
'user'
|
|
385
|
+
], adminGroup = 'Auth', access, usePlural = true, configureSaveToJWT = true, firstUserAdmin, customizeCollection } = options;
|
|
350
386
|
// Parse firstUserAdmin option (defaults to true)
|
|
351
|
-
const firstUserAdminOptions = firstUserAdmin === false
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
387
|
+
const firstUserAdminOptions = firstUserAdmin === false ? null : typeof firstUserAdmin === 'object' ? firstUserAdmin : {} // true or undefined = enabled with defaults
|
|
388
|
+
;
|
|
389
|
+
return (incomingConfig)=>{
|
|
390
|
+
const existingCollections = new Map((incomingConfig.collections ?? []).map((c)=>[
|
|
391
|
+
c.slug,
|
|
392
|
+
c
|
|
393
|
+
]));
|
|
358
394
|
const tables = getAuthTables(betterAuthOptions);
|
|
359
395
|
const generatedCollections = [];
|
|
360
396
|
const augmentedCollections = [];
|
|
361
397
|
// Calculate users collection slug for firstUserAdmin hook
|
|
362
398
|
const userTable = tables['user'];
|
|
363
|
-
const usersSlug = usePlural
|
|
364
|
-
|
|
365
|
-
: (userTable?.modelName ?? 'user');
|
|
366
|
-
for (const [modelKey, table] of Object.entries(tables)) {
|
|
399
|
+
const usersSlug = usePlural ? pluralize(userTable?.modelName ?? 'user') : userTable?.modelName ?? 'user';
|
|
400
|
+
for (const [modelKey, table] of Object.entries(tables)){
|
|
367
401
|
// Calculate slug
|
|
368
402
|
const baseName = table.modelName ?? modelKey;
|
|
369
403
|
const slug = usePlural ? pluralize(baseName) : baseName;
|
|
@@ -398,14 +432,18 @@ export function betterAuthCollections(options = {}) {
|
|
|
398
432
|
generatedCollections.push(collection);
|
|
399
433
|
}
|
|
400
434
|
// Merge: replace augmented collections, add new ones
|
|
401
|
-
const finalCollections = (incomingConfig.collections ?? []).map((c)
|
|
402
|
-
const augmented = augmentedCollections.find((a)
|
|
435
|
+
const finalCollections = (incomingConfig.collections ?? []).map((c)=>{
|
|
436
|
+
const augmented = augmentedCollections.find((a)=>a.slug === c.slug);
|
|
403
437
|
return augmented ?? c;
|
|
404
438
|
});
|
|
405
439
|
return {
|
|
406
440
|
...incomingConfig,
|
|
407
|
-
collections: [
|
|
441
|
+
collections: [
|
|
442
|
+
...finalCollections,
|
|
443
|
+
...generatedCollections
|
|
444
|
+
]
|
|
408
445
|
};
|
|
409
446
|
};
|
|
410
447
|
}
|
|
448
|
+
|
|
411
449
|
//# sourceMappingURL=collections.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collections.js","sourceRoot":"","sources":["../../src/adapter/collections.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/adapter/collections.ts"],"sourcesContent":["/**\n * Auto-generate Payload collections from Better Auth schema\n *\n * @packageDocumentation\n */\n\nimport type { Config, CollectionConfig, Field, Plugin, CollectionBeforeChangeHook } from 'payload'\nimport type { BetterAuthOptions } from 'better-auth'\nimport { getAuthTables } from 'better-auth/db'\nimport type { FirstUserAdminOptions } from '../utils/firstUserAdmin.js'\nimport { isAdmin } from '../utils/access.js'\n\nexport type { FirstUserAdminOptions }\n\nexport type BetterAuthCollectionsOptions = {\n /**\n * Better Auth options. Pass the same options you use for betterAuth().\n * The plugin reads the schema to generate collections.\n */\n betterAuthOptions?: BetterAuthOptions\n\n /**\n * Collections to skip (they already exist in your config)\n * Default: ['user'] - assumes you have a Users collection\n */\n skipCollections?: string[]\n\n /**\n * Admin group name for generated collections\n * Default: 'Auth'\n */\n adminGroup?: string\n\n /**\n * Custom access control for generated collections.\n * By default, only admins can read/delete, and create/update are disabled.\n */\n access?: CollectionConfig['access']\n\n /**\n * Whether to pluralize collection slugs (add 's' suffix).\n * Should match your adapter's usePlural setting.\n * Default: true (matches Payload conventions)\n */\n usePlural?: boolean\n\n /**\n * Configure saveToJWT for session-related fields.\n * This controls which fields are included in JWT tokens.\n * Default: true\n */\n configureSaveToJWT?: boolean\n\n /**\n * Automatically make the first registered user an admin.\n * Enabled by default. Set to `false` to disable, or provide options to customize.\n *\n * @default true\n *\n * @example Disable\n * ```ts\n * betterAuthCollections({\n * betterAuthOptions: authOptions,\n * firstUserAdmin: false,\n * })\n * ```\n *\n * @example Custom roles\n * ```ts\n * betterAuthCollections({\n * betterAuthOptions: authOptions,\n * firstUserAdmin: {\n * adminRole: 'super-admin',\n * defaultRole: 'member',\n * },\n * })\n * ```\n */\n firstUserAdmin?: boolean | FirstUserAdminOptions\n\n /**\n * Customize a generated collection before it's added to config.\n * Use this to add hooks, modify fields, or adjust any collection setting.\n *\n * @example\n * ```ts\n * customizeCollection: (modelKey, collection) => {\n * if (modelKey === 'session') {\n * return {\n * ...collection,\n * hooks: {\n * afterDelete: [myCleanupHook],\n * },\n * }\n * }\n * return collection\n * }\n * ```\n */\n customizeCollection?: (\n modelKey: string,\n collection: CollectionConfig\n ) => CollectionConfig\n}\n\n/**\n * Creates a beforeChange hook that makes the first user an admin.\n */\nfunction createFirstUserAdminHook(\n options: FirstUserAdminOptions,\n usersSlug: string\n): CollectionBeforeChangeHook {\n const {\n adminRole = 'admin',\n defaultRole = 'user',\n roleField = 'role',\n } = options\n\n return async ({ data, operation, req }) => {\n if (operation !== 'create') {\n return data\n }\n\n try {\n const { totalDocs } = await req.payload.count({\n collection: usersSlug,\n overrideAccess: true,\n })\n\n if (totalDocs === 0) {\n // First user becomes admin\n return {\n ...data,\n [roleField]: adminRole,\n }\n }\n\n // Subsequent users get default role if not already set\n return {\n ...data,\n [roleField]: data[roleField] ?? defaultRole,\n }\n } catch (error) {\n // On error, don't block user creation - just use provided or default role\n console.warn('[betterAuthCollections] Failed to check user count:', error)\n return {\n ...data,\n [roleField]: data[roleField] ?? defaultRole,\n }\n }\n }\n}\n\n/**\n * Inject the first-user-admin hook into a collection's hooks.\n */\nfunction injectFirstUserAdminHook(\n collection: CollectionConfig,\n options: FirstUserAdminOptions,\n usersSlug: string\n): CollectionConfig {\n const hook = createFirstUserAdminHook(options, usersSlug)\n const existingHooks = collection.hooks?.beforeChange ?? []\n\n return {\n ...collection,\n hooks: {\n ...collection.hooks,\n beforeChange: [hook, ...(Array.isArray(existingHooks) ? existingHooks : [existingHooks])],\n },\n }\n}\n\n/**\n * Determine if a field should be saved to JWT.\n * Session-critical fields are included, large data fields are excluded.\n */\nfunction getSaveToJWT(modelKey: string, fieldName: string): boolean | undefined {\n // Session fields - include core session data\n if (modelKey === 'session') {\n const includeFields = ['token', 'expiresAt', 'user', 'userId', 'ipAddress', 'userAgent', 'activeOrganizationId', 'activeTeamId']\n const excludeFields = ['createdAt', 'updatedAt']\n\n if (includeFields.some(f => fieldName === f || fieldName.endsWith(f.charAt(0).toUpperCase() + f.slice(1)))) {\n return true\n }\n if (excludeFields.includes(fieldName)) {\n return false\n }\n }\n\n // User fields - include essential auth data\n if (modelKey === 'user') {\n const includeFields = ['role', 'email', 'emailVerified', 'name', 'twoFactorEnabled', 'banned']\n const excludeFields = ['image', 'password', 'banReason']\n\n if (includeFields.includes(fieldName)) {\n return true\n }\n if (excludeFields.includes(fieldName)) {\n return false\n }\n }\n\n // Account fields - generally not in JWT\n if (modelKey === 'account') {\n return false\n }\n\n // Verification fields - not in JWT\n if (modelKey === 'verification') {\n return false\n }\n\n // Default: don't set (let Payload decide)\n return undefined\n}\n\n/**\n * Simple pluralization (add 's' suffix)\n */\nfunction pluralize(name: string): string {\n if (name.endsWith('s')) return name\n return `${name}s`\n}\n\nfunction mapFieldType(\n type: string,\n fieldName: string,\n hasReferences: boolean\n): Field['type'] {\n if (hasReferences) {\n return 'relationship'\n }\n\n switch (type) {\n case 'boolean':\n return 'checkbox'\n case 'number':\n return 'number'\n case 'date':\n return 'date'\n case 'string':\n if (fieldName === 'email') return 'email'\n return 'text'\n case 'json':\n case 'object':\n return 'json'\n case 'string[]':\n case 'array':\n return 'json' // Payload doesn't have native string array, use JSON\n default:\n return 'text'\n }\n}\n\nfunction extractRelationTarget(\n fieldName: string,\n usePlural: boolean\n): string {\n const base = fieldName.replace(/(_id|Id)$/, '')\n return usePlural ? pluralize(base) : base\n}\n\nfunction generateCollection(\n modelKey: string,\n table: ReturnType<typeof getAuthTables>[string],\n usePlural: boolean,\n adminGroup: string,\n customAccess?: BetterAuthCollectionsOptions['access'],\n configureSaveToJWT = true\n): CollectionConfig {\n // Use modelName from schema if set, otherwise apply pluralization to modelKey\n const baseName = table.modelName ?? modelKey\n const slug = usePlural ? pluralize(baseName) : baseName\n const fields: Field[] = []\n\n for (const [fieldKey, fieldDef] of Object.entries(table.fields)) {\n if (['id', 'createdAt', 'updatedAt'].includes(fieldKey)) {\n continue\n }\n\n const fieldName = fieldDef.fieldName ?? fieldKey\n const hasReferences = fieldDef.references !== undefined\n const fieldType = mapFieldType(fieldDef.type as string, fieldKey, hasReferences)\n\n if (fieldType === 'relationship') {\n // Use schema reference if available, otherwise infer from field name\n let relationTo: string\n if (fieldDef.references?.model) {\n relationTo = usePlural ? pluralize(fieldDef.references.model) : fieldDef.references.model\n } else {\n relationTo = extractRelationTarget(fieldKey, usePlural)\n }\n\n const relFieldName = fieldName.replace(/(_id|Id)$/, '')\n const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, relFieldName) : undefined\n\n fields.push({\n name: relFieldName,\n type: 'relationship',\n relationTo,\n required: fieldDef.required ?? false,\n index: true,\n ...(saveToJWT !== undefined && { saveToJWT }),\n } as Field)\n continue\n }\n\n const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, fieldName) : undefined\n const field: Record<string, unknown> = {\n name: fieldName,\n type: fieldType,\n ...(saveToJWT !== undefined && { saveToJWT }),\n }\n\n if (fieldDef.required) field.required = true\n if (fieldDef.unique) {\n field.unique = true\n field.index = true\n }\n\n if (fieldDef.defaultValue !== undefined) {\n let defaultValue: unknown = fieldDef.defaultValue\n if (typeof defaultValue === 'function') {\n try {\n defaultValue = (defaultValue as () => unknown)()\n } catch {\n defaultValue = undefined\n }\n }\n if (defaultValue !== undefined && defaultValue !== null) {\n field.defaultValue = defaultValue\n }\n }\n\n fields.push(field as Field)\n }\n\n const titleField = ['name', 'email', 'title', 'identifier'].find((f) =>\n fields.some((field) => 'name' in field && field.name === f)\n )\n\n // Default access: admin-only read/delete, disabled manual create/update via admin UI\n // The adapter uses overrideAccess: true for programmatic operations from Better Auth\n const defaultAccess: CollectionConfig['access'] = {\n read: isAdmin(),\n create: () => false, // Manual creation disabled - Better Auth manages these\n update: () => false, // Manual update disabled - Better Auth manages these\n delete: isAdmin(),\n }\n\n return {\n slug,\n admin: {\n useAsTitle: titleField ?? 'id',\n group: adminGroup,\n description: `Auto-generated from Better Auth schema (${modelKey})`,\n },\n access: customAccess ?? defaultAccess,\n fields,\n timestamps: true,\n }\n}\n\n/**\n * Get existing field names from a collection, handling nested field structures.\n */\nfunction getExistingFieldNames(fields: Field[]): Set<string> {\n const names = new Set<string>()\n for (const field of fields) {\n if ('name' in field && field.name) {\n names.add(field.name)\n }\n }\n return names\n}\n\n/**\n * Augment an existing collection with missing fields from Better Auth schema.\n * This ensures user-defined collections (like 'users') get plugin fields automatically.\n */\nfunction augmentCollectionWithMissingFields(\n collection: CollectionConfig,\n table: ReturnType<typeof getAuthTables>[string],\n usePlural: boolean,\n modelKey: string,\n configureSaveToJWT = true\n): CollectionConfig {\n const existingFieldNames = getExistingFieldNames(collection.fields)\n const missingFields: Field[] = []\n\n for (const [fieldKey, fieldDef] of Object.entries(table.fields)) {\n // Skip standard fields that Payload handles\n if (['id', 'createdAt', 'updatedAt'].includes(fieldKey)) {\n continue\n }\n\n const fieldName = fieldDef.fieldName ?? fieldKey\n const hasReferences = fieldDef.references !== undefined\n\n // For reference fields, check the name without Id suffix\n const payloadFieldName = hasReferences\n ? fieldName.replace(/(_id|Id)$/, '')\n : fieldName\n\n // Skip if field already exists\n if (existingFieldNames.has(payloadFieldName)) {\n continue\n }\n\n // Generate the missing field\n const fieldType = mapFieldType(fieldDef.type as string, fieldKey, hasReferences)\n\n if (fieldType === 'relationship') {\n let relationTo: string\n if (fieldDef.references?.model) {\n relationTo = usePlural ? pluralize(fieldDef.references.model) : fieldDef.references.model\n } else {\n relationTo = extractRelationTarget(fieldKey, usePlural)\n }\n\n const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, payloadFieldName) : undefined\n\n missingFields.push({\n name: payloadFieldName,\n type: 'relationship',\n relationTo,\n required: fieldDef.required ?? false,\n index: true,\n admin: {\n description: `Auto-added by Better Auth (${fieldKey})`,\n },\n ...(saveToJWT !== undefined && { saveToJWT }),\n } as Field)\n } else {\n const saveToJWT = configureSaveToJWT ? getSaveToJWT(modelKey, payloadFieldName) : undefined\n const field: Record<string, unknown> = {\n name: payloadFieldName,\n type: fieldType,\n admin: {\n description: `Auto-added by Better Auth (${fieldKey})`,\n },\n ...(saveToJWT !== undefined && { saveToJWT }),\n }\n\n if (fieldDef.required) field.required = true\n if (fieldDef.unique) {\n field.unique = true\n field.index = true\n }\n\n if (fieldDef.defaultValue !== undefined) {\n let defaultValue: unknown = fieldDef.defaultValue\n if (typeof defaultValue === 'function') {\n try {\n defaultValue = (defaultValue as () => unknown)()\n } catch {\n defaultValue = undefined\n }\n }\n if (defaultValue !== undefined && defaultValue !== null) {\n field.defaultValue = defaultValue\n }\n }\n\n missingFields.push(field as Field)\n }\n }\n\n // Return original if no fields to add\n if (missingFields.length === 0) {\n return collection\n }\n\n // Return augmented collection\n return {\n ...collection,\n fields: [...collection.fields, ...missingFields],\n }\n}\n\n/**\n * Payload plugin that auto-generates collections from Better Auth schema.\n *\n * @example Basic usage\n * ```ts\n * import { betterAuthCollections } from '@delmaredigital/payload-better-auth'\n *\n * export default buildConfig({\n * plugins: [\n * betterAuthCollections({\n * betterAuthOptions: { ... },\n * skipCollections: ['user'], // Define Users yourself\n * }),\n * ],\n * })\n * ```\n *\n * @example With customization callback\n * ```ts\n * betterAuthCollections({\n * betterAuthOptions: authOptions,\n * customizeCollection: (modelKey, collection) => {\n * if (modelKey === 'session') {\n * return {\n * ...collection,\n * hooks: { afterDelete: [cleanupHook] },\n * }\n * }\n * return collection\n * },\n * })\n * ```\n */\nexport function betterAuthCollections(\n options: BetterAuthCollectionsOptions = {}\n): Plugin {\n const {\n betterAuthOptions = {},\n skipCollections = ['user'],\n adminGroup = 'Auth',\n access,\n usePlural = true,\n configureSaveToJWT = true,\n firstUserAdmin,\n customizeCollection,\n } = options\n\n // Parse firstUserAdmin option (defaults to true)\n const firstUserAdminOptions: FirstUserAdminOptions | null =\n firstUserAdmin === false\n ? null\n : typeof firstUserAdmin === 'object'\n ? firstUserAdmin\n : {} // true or undefined = enabled with defaults\n\n return (incomingConfig: Config): Config => {\n const existingCollections = new Map(\n (incomingConfig.collections ?? []).map((c) => [c.slug, c])\n )\n\n const tables = getAuthTables(betterAuthOptions)\n const generatedCollections: CollectionConfig[] = []\n const augmentedCollections: CollectionConfig[] = []\n\n // Calculate users collection slug for firstUserAdmin hook\n const userTable = tables['user']\n const usersSlug = usePlural\n ? pluralize(userTable?.modelName ?? 'user')\n : (userTable?.modelName ?? 'user')\n\n for (const [modelKey, table] of Object.entries(tables)) {\n // Calculate slug\n const baseName = table.modelName ?? modelKey\n const slug = usePlural ? pluralize(baseName) : baseName\n\n // Check if this collection already exists\n const existingCollection = existingCollections.get(slug)\n\n if (existingCollection) {\n // Augment existing collection with missing fields from Better Auth schema\n let augmented = augmentCollectionWithMissingFields(\n existingCollection,\n table,\n usePlural,\n modelKey,\n configureSaveToJWT\n )\n\n // Inject first-user-admin hook for user collection\n if (modelKey === 'user' && firstUserAdminOptions) {\n augmented = injectFirstUserAdminHook(augmented, firstUserAdminOptions, usersSlug)\n }\n\n if (augmented !== existingCollection) {\n augmentedCollections.push(augmented)\n existingCollections.set(slug, augmented)\n }\n continue\n }\n\n // Skip if explicitly told to (but still augment if exists above)\n if (skipCollections.includes(modelKey)) {\n continue\n }\n\n let collection = generateCollection(\n modelKey,\n table,\n usePlural,\n adminGroup,\n access,\n configureSaveToJWT\n )\n\n // Inject first-user-admin hook for user collection\n if (modelKey === 'user' && firstUserAdminOptions) {\n collection = injectFirstUserAdminHook(collection, firstUserAdminOptions, usersSlug)\n }\n\n // Apply customization callback if provided\n if (customizeCollection) {\n collection = customizeCollection(modelKey, collection)\n }\n\n generatedCollections.push(collection)\n }\n\n // Merge: replace augmented collections, add new ones\n const finalCollections = (incomingConfig.collections ?? []).map((c) => {\n const augmented = augmentedCollections.find((a) => a.slug === c.slug)\n return augmented ?? c\n })\n\n return {\n ...incomingConfig,\n collections: [...finalCollections, ...generatedCollections],\n }\n }\n}\n"],"names":["getAuthTables","isAdmin","createFirstUserAdminHook","options","usersSlug","adminRole","defaultRole","roleField","data","operation","req","totalDocs","payload","count","collection","overrideAccess","error","console","warn","injectFirstUserAdminHook","hook","existingHooks","hooks","beforeChange","Array","isArray","getSaveToJWT","modelKey","fieldName","includeFields","excludeFields","some","f","endsWith","charAt","toUpperCase","slice","includes","undefined","pluralize","name","mapFieldType","type","hasReferences","extractRelationTarget","usePlural","base","replace","generateCollection","table","adminGroup","customAccess","configureSaveToJWT","baseName","modelName","slug","fields","fieldKey","fieldDef","Object","entries","references","fieldType","relationTo","model","relFieldName","saveToJWT","push","required","index","field","unique","defaultValue","titleField","find","defaultAccess","read","create","update","delete","admin","useAsTitle","group","description","access","timestamps","getExistingFieldNames","names","Set","add","augmentCollectionWithMissingFields","existingFieldNames","missingFields","payloadFieldName","has","length","betterAuthCollections","betterAuthOptions","skipCollections","firstUserAdmin","customizeCollection","firstUserAdminOptions","incomingConfig","existingCollections","Map","collections","map","c","tables","generatedCollections","augmentedCollections","userTable","existingCollection","get","augmented","set","finalCollections","a"],"mappings":"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"}
|