@delmaredigital/payload-better-auth 0.3.8 → 0.3.10
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/collections.d.ts +0 -1
- package/dist/adapter/collections.js +0 -2
- package/dist/adapter/index.d.ts +0 -1
- package/dist/adapter/index.js +0 -2
- package/dist/components/BeforeLogin.d.ts +0 -1
- package/dist/components/BeforeLogin.js +0 -2
- package/dist/components/LoginView.d.ts +0 -1
- package/dist/components/LoginView.js +0 -2
- package/dist/components/LoginViewWrapper.d.ts +0 -1
- package/dist/components/LoginViewWrapper.js +0 -2
- package/dist/components/LogoutButton.d.ts +0 -1
- package/dist/components/LogoutButton.js +0 -2
- package/dist/components/PasskeyRegisterButton.d.ts +0 -1
- package/dist/components/PasskeyRegisterButton.js +0 -2
- package/dist/components/PasskeySignInButton.d.ts +0 -1
- package/dist/components/PasskeySignInButton.js +0 -2
- package/dist/components/auth/ForgotPasswordView.d.ts +0 -1
- package/dist/components/auth/ForgotPasswordView.js +0 -2
- package/dist/components/auth/ResetPasswordView.d.ts +0 -1
- package/dist/components/auth/ResetPasswordView.js +0 -2
- package/dist/components/auth/index.d.ts +0 -1
- package/dist/components/auth/index.js +0 -2
- package/dist/components/management/ApiKeysManagementClient.d.ts +0 -1
- package/dist/components/management/ApiKeysManagementClient.js +0 -2
- package/dist/components/management/PasskeysManagementClient.d.ts +0 -1
- package/dist/components/management/PasskeysManagementClient.js +0 -2
- package/dist/components/management/SecurityNavLinks.d.ts +0 -1
- package/dist/components/management/SecurityNavLinks.js +0 -2
- package/dist/components/management/TwoFactorManagementClient.d.ts +0 -1
- package/dist/components/management/TwoFactorManagementClient.js +0 -2
- package/dist/components/management/index.d.ts +0 -1
- package/dist/components/management/index.js +0 -2
- package/dist/components/management/views/ApiKeysView.d.ts +0 -1
- package/dist/components/management/views/ApiKeysView.js +0 -2
- package/dist/components/management/views/PasskeysView.d.ts +0 -1
- package/dist/components/management/views/PasskeysView.js +0 -2
- package/dist/components/management/views/TwoFactorView.d.ts +0 -1
- package/dist/components/management/views/TwoFactorView.js +0 -2
- package/dist/components/management/views/index.d.ts +0 -1
- package/dist/components/management/views/index.js +0 -2
- package/dist/components/twoFactor/TwoFactorSetupView.d.ts +0 -1
- package/dist/components/twoFactor/TwoFactorSetupView.js +0 -2
- package/dist/components/twoFactor/TwoFactorVerifyView.d.ts +0 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.js +0 -2
- package/dist/components/twoFactor/index.d.ts +0 -1
- package/dist/components/twoFactor/index.js +0 -2
- package/dist/exports/client.d.ts +0 -1
- package/dist/exports/client.js +0 -2
- package/dist/exports/components.d.ts +0 -1
- package/dist/exports/components.js +0 -2
- package/dist/exports/management.d.ts +0 -1
- package/dist/exports/management.js +0 -2
- package/dist/exports/rsc.d.ts +0 -1
- package/dist/exports/rsc.js +0 -2
- package/dist/generated-types.d.ts +0 -1
- package/dist/generated-types.js +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -2
- package/dist/plugin/index.d.ts +0 -1
- package/dist/plugin/index.js +0 -2
- package/dist/scripts/generate-types.d.ts +0 -1
- package/dist/scripts/generate-types.js +0 -2
- package/dist/types/apiKey.d.ts +0 -1
- package/dist/types/apiKey.js +0 -2
- package/dist/types/betterAuth.d.ts +0 -1
- package/dist/types/betterAuth.js +0 -2
- package/dist/utils/access.d.ts +0 -1
- package/dist/utils/access.js +0 -2
- package/dist/utils/apiKeyAccess.d.ts +0 -1
- package/dist/utils/apiKeyAccess.js +0 -2
- package/dist/utils/betterAuthDefaults.d.ts +0 -1
- package/dist/utils/betterAuthDefaults.js +0 -2
- package/dist/utils/detectAuthConfig.d.ts +0 -1
- package/dist/utils/detectAuthConfig.js +0 -2
- package/dist/utils/detectEnabledPlugins.d.ts +0 -1
- package/dist/utils/detectEnabledPlugins.js +0 -2
- package/dist/utils/firstUserAdmin.d.ts +0 -1
- package/dist/utils/firstUserAdmin.js +0 -2
- package/dist/utils/generateScopes.d.ts +0 -1
- package/dist/utils/generateScopes.js +0 -2
- package/dist/utils/session.d.ts +0 -1
- package/dist/utils/session.js +0 -2
- package/package.json +34 -91
- package/dist/adapter/collections.d.ts.map +0 -1
- package/dist/adapter/collections.js.map +0 -1
- package/dist/adapter/index.d.ts.map +0 -1
- package/dist/adapter/index.js.map +0 -1
- package/dist/components/BeforeLogin.d.ts.map +0 -1
- package/dist/components/BeforeLogin.js.map +0 -1
- package/dist/components/LoginView.d.ts.map +0 -1
- package/dist/components/LoginView.js.map +0 -1
- package/dist/components/LoginViewWrapper.d.ts.map +0 -1
- package/dist/components/LoginViewWrapper.js.map +0 -1
- package/dist/components/LogoutButton.d.ts.map +0 -1
- package/dist/components/LogoutButton.js.map +0 -1
- package/dist/components/PasskeyRegisterButton.d.ts.map +0 -1
- package/dist/components/PasskeyRegisterButton.js.map +0 -1
- package/dist/components/PasskeySignInButton.d.ts.map +0 -1
- package/dist/components/PasskeySignInButton.js.map +0 -1
- package/dist/components/auth/ForgotPasswordView.d.ts.map +0 -1
- package/dist/components/auth/ForgotPasswordView.js.map +0 -1
- package/dist/components/auth/ResetPasswordView.d.ts.map +0 -1
- package/dist/components/auth/ResetPasswordView.js.map +0 -1
- package/dist/components/auth/index.d.ts.map +0 -1
- package/dist/components/auth/index.js.map +0 -1
- package/dist/components/management/ApiKeysManagementClient.d.ts.map +0 -1
- package/dist/components/management/ApiKeysManagementClient.js.map +0 -1
- package/dist/components/management/PasskeysManagementClient.d.ts.map +0 -1
- package/dist/components/management/PasskeysManagementClient.js.map +0 -1
- package/dist/components/management/SecurityNavLinks.d.ts.map +0 -1
- package/dist/components/management/SecurityNavLinks.js.map +0 -1
- package/dist/components/management/TwoFactorManagementClient.d.ts.map +0 -1
- package/dist/components/management/TwoFactorManagementClient.js.map +0 -1
- package/dist/components/management/index.d.ts.map +0 -1
- package/dist/components/management/index.js.map +0 -1
- package/dist/components/management/views/ApiKeysView.d.ts.map +0 -1
- package/dist/components/management/views/ApiKeysView.js.map +0 -1
- package/dist/components/management/views/PasskeysView.d.ts.map +0 -1
- package/dist/components/management/views/PasskeysView.js.map +0 -1
- package/dist/components/management/views/TwoFactorView.d.ts.map +0 -1
- package/dist/components/management/views/TwoFactorView.js.map +0 -1
- package/dist/components/management/views/index.d.ts.map +0 -1
- package/dist/components/management/views/index.js.map +0 -1
- package/dist/components/twoFactor/TwoFactorSetupView.d.ts.map +0 -1
- package/dist/components/twoFactor/TwoFactorSetupView.js.map +0 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.d.ts.map +0 -1
- package/dist/components/twoFactor/TwoFactorVerifyView.js.map +0 -1
- package/dist/components/twoFactor/index.d.ts.map +0 -1
- package/dist/components/twoFactor/index.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/exports/components.d.ts.map +0 -1
- package/dist/exports/components.js.map +0 -1
- package/dist/exports/management.d.ts.map +0 -1
- package/dist/exports/management.js.map +0 -1
- package/dist/exports/rsc.d.ts.map +0 -1
- package/dist/exports/rsc.js.map +0 -1
- package/dist/generated-types.d.ts.map +0 -1
- package/dist/generated-types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js.map +0 -1
- package/dist/scripts/generate-types.d.ts.map +0 -1
- package/dist/scripts/generate-types.js.map +0 -1
- package/dist/types/apiKey.d.ts.map +0 -1
- package/dist/types/apiKey.js.map +0 -1
- package/dist/types/betterAuth.d.ts.map +0 -1
- package/dist/types/betterAuth.js.map +0 -1
- package/dist/utils/access.d.ts.map +0 -1
- package/dist/utils/access.js.map +0 -1
- package/dist/utils/apiKeyAccess.d.ts.map +0 -1
- package/dist/utils/apiKeyAccess.js.map +0 -1
- package/dist/utils/betterAuthDefaults.d.ts.map +0 -1
- package/dist/utils/betterAuthDefaults.js.map +0 -1
- package/dist/utils/detectAuthConfig.d.ts.map +0 -1
- package/dist/utils/detectAuthConfig.js.map +0 -1
- package/dist/utils/detectEnabledPlugins.d.ts.map +0 -1
- package/dist/utils/detectEnabledPlugins.js.map +0 -1
- package/dist/utils/firstUserAdmin.d.ts.map +0 -1
- package/dist/utils/firstUserAdmin.js.map +0 -1
- package/dist/utils/generateScopes.d.ts.map +0 -1
- package/dist/utils/generateScopes.js.map +0 -1
- package/dist/utils/session.d.ts.map +0 -1
- package/dist/utils/session.js.map +0 -1
- package/src/adapter/collections.ts +0 -621
- package/src/adapter/index.ts +0 -712
- package/src/components/BeforeLogin.tsx +0 -39
- package/src/components/LoginView.tsx +0 -1516
- package/src/components/LoginViewWrapper.tsx +0 -35
- package/src/components/LogoutButton.tsx +0 -58
- package/src/components/PasskeyRegisterButton.tsx +0 -105
- package/src/components/PasskeySignInButton.tsx +0 -96
- package/src/components/auth/ForgotPasswordView.tsx +0 -274
- package/src/components/auth/ResetPasswordView.tsx +0 -331
- package/src/components/auth/index.ts +0 -8
- package/src/components/management/ApiKeysManagementClient.tsx +0 -988
- package/src/components/management/PasskeysManagementClient.tsx +0 -409
- package/src/components/management/SecurityNavLinks.tsx +0 -117
- package/src/components/management/TwoFactorManagementClient.tsx +0 -560
- package/src/components/management/index.ts +0 -20
- package/src/components/management/views/ApiKeysView.tsx +0 -57
- package/src/components/management/views/PasskeysView.tsx +0 -42
- package/src/components/management/views/TwoFactorView.tsx +0 -42
- package/src/components/management/views/index.ts +0 -10
- package/src/components/twoFactor/TwoFactorSetupView.tsx +0 -515
- package/src/components/twoFactor/TwoFactorVerifyView.tsx +0 -238
- package/src/components/twoFactor/index.ts +0 -8
- package/src/exports/client.ts +0 -77
- package/src/exports/components.ts +0 -30
- package/src/exports/management.ts +0 -25
- package/src/exports/rsc.ts +0 -11
- package/src/generated-types.ts +0 -269
- package/src/index.ts +0 -135
- package/src/plugin/index.ts +0 -834
- package/src/scripts/generate-types.ts +0 -269
- package/src/types/apiKey.ts +0 -63
- package/src/types/betterAuth.ts +0 -253
- package/src/utils/access.ts +0 -410
- package/src/utils/apiKeyAccess.ts +0 -443
- package/src/utils/betterAuthDefaults.ts +0 -102
- package/src/utils/detectAuthConfig.ts +0 -47
- package/src/utils/detectEnabledPlugins.ts +0 -69
- package/src/utils/firstUserAdmin.ts +0 -164
- package/src/utils/generateScopes.ts +0 -150
- package/src/utils/session.ts +0 -91
package/package.json
CHANGED
|
@@ -1,122 +1,65 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delmaredigital/payload-better-auth",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.10",
|
|
4
4
|
"description": "Better Auth adapter and plugins for Payload CMS",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"main": "./
|
|
8
|
-
"types": "./
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"import": "./
|
|
12
|
-
"types": "./
|
|
13
|
-
"default": "./
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
14
|
},
|
|
15
15
|
"./adapter": {
|
|
16
|
-
"import": "./
|
|
17
|
-
"types": "./
|
|
18
|
-
"default": "./
|
|
16
|
+
"import": "./dist/adapter/index.js",
|
|
17
|
+
"types": "./dist/adapter/index.d.ts",
|
|
18
|
+
"default": "./dist/adapter/index.js"
|
|
19
19
|
},
|
|
20
20
|
"./plugin": {
|
|
21
|
-
"import": "./
|
|
22
|
-
"types": "./
|
|
23
|
-
"default": "./
|
|
21
|
+
"import": "./dist/plugin/index.js",
|
|
22
|
+
"types": "./dist/plugin/index.d.ts",
|
|
23
|
+
"default": "./dist/plugin/index.js"
|
|
24
24
|
},
|
|
25
25
|
"./client": {
|
|
26
|
-
"import": "./
|
|
27
|
-
"types": "./
|
|
28
|
-
"default": "./
|
|
26
|
+
"import": "./dist/exports/client.js",
|
|
27
|
+
"types": "./dist/exports/client.d.ts",
|
|
28
|
+
"default": "./dist/exports/client.js"
|
|
29
29
|
},
|
|
30
30
|
"./components": {
|
|
31
|
-
"import": "./
|
|
32
|
-
"types": "./
|
|
33
|
-
"default": "./
|
|
31
|
+
"import": "./dist/exports/components.js",
|
|
32
|
+
"types": "./dist/exports/components.d.ts",
|
|
33
|
+
"default": "./dist/exports/components.js"
|
|
34
34
|
},
|
|
35
35
|
"./components/auth": {
|
|
36
|
-
"import": "./
|
|
37
|
-
"types": "./
|
|
38
|
-
"default": "./
|
|
36
|
+
"import": "./dist/components/auth/index.js",
|
|
37
|
+
"types": "./dist/components/auth/index.d.ts",
|
|
38
|
+
"default": "./dist/components/auth/index.js"
|
|
39
39
|
},
|
|
40
40
|
"./components/twoFactor": {
|
|
41
|
-
"import": "./
|
|
42
|
-
"types": "./
|
|
43
|
-
"default": "./
|
|
41
|
+
"import": "./dist/components/twoFactor/index.js",
|
|
42
|
+
"types": "./dist/components/twoFactor/index.d.ts",
|
|
43
|
+
"default": "./dist/components/twoFactor/index.js"
|
|
44
44
|
},
|
|
45
45
|
"./management": {
|
|
46
|
-
"import": "./
|
|
47
|
-
"types": "./
|
|
48
|
-
"default": "./
|
|
46
|
+
"import": "./dist/exports/management.js",
|
|
47
|
+
"types": "./dist/exports/management.d.ts",
|
|
48
|
+
"default": "./dist/exports/management.js"
|
|
49
49
|
},
|
|
50
50
|
"./components/management": {
|
|
51
|
-
"import": "./
|
|
52
|
-
"types": "./
|
|
53
|
-
"default": "./
|
|
51
|
+
"import": "./dist/components/management/index.js",
|
|
52
|
+
"types": "./dist/components/management/index.d.ts",
|
|
53
|
+
"default": "./dist/components/management/index.js"
|
|
54
54
|
},
|
|
55
55
|
"./rsc": {
|
|
56
|
-
"import": "./
|
|
57
|
-
"types": "./
|
|
58
|
-
"default": "./
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
"publishConfig": {
|
|
62
|
-
"main": "./dist/index.js",
|
|
63
|
-
"types": "./dist/index.d.ts",
|
|
64
|
-
"exports": {
|
|
65
|
-
".": {
|
|
66
|
-
"import": "./dist/index.js",
|
|
67
|
-
"types": "./dist/index.d.ts",
|
|
68
|
-
"default": "./dist/index.js"
|
|
69
|
-
},
|
|
70
|
-
"./adapter": {
|
|
71
|
-
"import": "./dist/adapter/index.js",
|
|
72
|
-
"types": "./dist/adapter/index.d.ts",
|
|
73
|
-
"default": "./dist/adapter/index.js"
|
|
74
|
-
},
|
|
75
|
-
"./plugin": {
|
|
76
|
-
"import": "./dist/plugin/index.js",
|
|
77
|
-
"types": "./dist/plugin/index.d.ts",
|
|
78
|
-
"default": "./dist/plugin/index.js"
|
|
79
|
-
},
|
|
80
|
-
"./client": {
|
|
81
|
-
"import": "./dist/exports/client.js",
|
|
82
|
-
"types": "./dist/exports/client.d.ts",
|
|
83
|
-
"default": "./dist/exports/client.js"
|
|
84
|
-
},
|
|
85
|
-
"./components": {
|
|
86
|
-
"import": "./dist/exports/components.js",
|
|
87
|
-
"types": "./dist/exports/components.d.ts",
|
|
88
|
-
"default": "./dist/exports/components.js"
|
|
89
|
-
},
|
|
90
|
-
"./components/auth": {
|
|
91
|
-
"import": "./dist/components/auth/index.js",
|
|
92
|
-
"types": "./dist/components/auth/index.d.ts",
|
|
93
|
-
"default": "./dist/components/auth/index.js"
|
|
94
|
-
},
|
|
95
|
-
"./components/twoFactor": {
|
|
96
|
-
"import": "./dist/components/twoFactor/index.js",
|
|
97
|
-
"types": "./dist/components/twoFactor/index.d.ts",
|
|
98
|
-
"default": "./dist/components/twoFactor/index.js"
|
|
99
|
-
},
|
|
100
|
-
"./management": {
|
|
101
|
-
"import": "./dist/exports/management.js",
|
|
102
|
-
"types": "./dist/exports/management.d.ts",
|
|
103
|
-
"default": "./dist/exports/management.js"
|
|
104
|
-
},
|
|
105
|
-
"./components/management": {
|
|
106
|
-
"import": "./dist/components/management/index.js",
|
|
107
|
-
"types": "./dist/components/management/index.d.ts",
|
|
108
|
-
"default": "./dist/components/management/index.js"
|
|
109
|
-
},
|
|
110
|
-
"./rsc": {
|
|
111
|
-
"import": "./dist/exports/rsc.js",
|
|
112
|
-
"types": "./dist/exports/rsc.d.ts",
|
|
113
|
-
"default": "./dist/exports/rsc.js"
|
|
114
|
-
}
|
|
56
|
+
"import": "./dist/exports/rsc.js",
|
|
57
|
+
"types": "./dist/exports/rsc.d.ts",
|
|
58
|
+
"default": "./dist/exports/rsc.js"
|
|
115
59
|
}
|
|
116
60
|
},
|
|
117
61
|
"files": [
|
|
118
|
-
"dist"
|
|
119
|
-
"src"
|
|
62
|
+
"dist"
|
|
120
63
|
],
|
|
121
64
|
"scripts": {
|
|
122
65
|
"build": "pnpm build:swc && pnpm build:types",
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1 +0,0 @@
|
|
|
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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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC7D,OAAO,KAAK,EACV,WAAW,EAGZ,MAAM,SAAS,CAAA;AAGhB,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,aAAa,EAAE,WAAW,GAAG,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;IAEzD;;OAEG;IACH,aAAa,CAAC,EAAE;QACd;;WAEG;QACH,eAAe,CAAC,EAAE,OAAO,CAAA;QAEzB;;;;;WAKG;QACH,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;QAE1B;;;;WAIG;QACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;QAE5B;;;;WAIG;QACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;KAC7B,CAAA;CACF,CAAA;AAgBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,cAAc,CAAC,EAC7B,aAAa,EACb,aAAkB,GACnB,EAAE,oBAAoB,GAAG,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAolBhE;AAED,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapter/index.ts"],"sourcesContent":["/**\n * Payload CMS Adapter for Better Auth\n *\n * Uses Better Auth's createAdapterFactory for schema-aware transformations,\n * eliminating hardcoded field mappings and supporting all Better Auth plugins.\n *\n * @packageDocumentation\n */\n\nimport {\n createAdapterFactory,\n type AdapterFactoryConfig,\n type CustomAdapter,\n} from 'better-auth/adapters'\nimport type { Adapter, BetterAuthOptions } from 'better-auth'\nimport type {\n BasePayload,\n Where as PayloadWhere,\n CollectionSlug,\n} from 'payload'\n\n\nexport type PayloadAdapterConfig = {\n /**\n * The Payload instance or a function that returns it.\n * Use a function for lazy initialization to avoid circular dependencies.\n */\n payloadClient: BasePayload | (() => Promise<BasePayload>)\n\n /**\n * Adapter configuration options\n */\n adapterConfig?: {\n /**\n * Enable debug logging for troubleshooting\n */\n enableDebugLogs?: boolean\n\n /**\n * ID type used by Payload.\n * If not specified, auto-detects from Better Auth's generateId setting.\n * - 'number' for SERIAL/auto-increment (Payload default)\n * - 'text' for UUID\n */\n idType?: 'number' | 'text'\n\n /**\n * Additional fields to convert to numeric IDs beyond the *Id heuristic.\n * Use when you have ID fields that don't follow the naming convention.\n * @example ['customOrgRef', 'legacyIdentifier']\n */\n idFieldsAllowlist?: string[]\n\n /**\n * Fields to exclude from numeric ID conversion.\n * Use when a field ends in 'Id' but isn't actually an ID reference.\n * @example ['visitorId', 'correlationId']\n */\n idFieldsBlocklist?: string[]\n }\n}\n\n/**\n * Detect ID type from Better Auth options.\n * Defaults to 'number' (SERIAL) since Payload uses SERIAL IDs by default.\n */\nfunction detectIdType(options: BetterAuthOptions): 'number' | 'text' {\n const generateId = options.advanced?.database?.generateId\n // If explicitly set to something other than 'serial', use text (UUID)\n if (generateId !== undefined && generateId !== 'serial') {\n return 'text'\n }\n // Default to number (SERIAL) - Payload's default\n return 'number'\n}\n\n/**\n * Creates a Better Auth adapter that uses Payload CMS as the database.\n *\n * Uses Better Auth's createAdapterFactory for proper schema-aware transformations,\n * automatically supporting all Better Auth plugins without hardcoded field mappings.\n *\n * @example Basic usage\n * ```ts\n * import { payloadAdapter } from '@delmaredigital/payload-better-auth/adapter'\n *\n * const auth = betterAuth({\n * database: payloadAdapter({\n * payloadClient: payload,\n * }),\n * // For serial IDs (Payload default), configure Better Auth:\n * advanced: {\n * database: {\n * generateId: 'serial',\n * },\n * },\n * })\n * ```\n *\n * @example Custom collection names\n * ```ts\n * const auth = betterAuth({\n * database: payloadAdapter({ payloadClient: payload }),\n * // Use BetterAuthOptions to customize collection names.\n * // Provide SINGULAR names - they get pluralized automatically:\n * user: { modelName: 'member' }, // → 'members' collection\n * session: { modelName: 'auth_session' }, // → 'auth_sessions' collection\n * })\n * ```\n */\nexport function payloadAdapter({\n payloadClient,\n adapterConfig = {},\n}: PayloadAdapterConfig): (options: BetterAuthOptions) => Adapter {\n const { enableDebugLogs = false, idFieldsAllowlist = [], idFieldsBlocklist = [] } = adapterConfig\n const idFieldsAllowlistSet = new Set(idFieldsAllowlist)\n const idFieldsBlocklistSet = new Set(idFieldsBlocklist)\n\n // Resolve payload client (supports lazy initialization)\n async function resolvePayloadClient(): Promise<BasePayload> {\n return typeof payloadClient === 'function'\n ? await payloadClient()\n : payloadClient\n }\n\n\n function convertOperator(\n operator: string,\n value: unknown\n ): Record<string, unknown> {\n switch (operator) {\n case 'eq':\n return { equals: value }\n case 'ne':\n return { not_equals: value }\n case 'gt':\n return { greater_than: value }\n case 'gte':\n return { greater_than_equal: value }\n case 'lt':\n return { less_than: value }\n case 'lte':\n return { less_than_equal: value }\n case 'in':\n return { in: value }\n case 'contains':\n return { contains: value }\n case 'starts_with':\n return { like: `${value}%` }\n case 'ends_with':\n return { like: `%${value}` }\n default:\n return { equals: value }\n }\n }\n\n /**\n * Extract single ID from where clause for optimization\n */\n function extractSingleId(\n where: Array<{ field: string; value: unknown; operator: string }>\n ): string | number | null {\n if (where.length !== 1) return null\n const w = where[0]\n if (w.field === 'id' && w.operator === 'eq') {\n const value = w.value\n if (typeof value === 'string' || typeof value === 'number') {\n return value\n }\n }\n return null\n }\n\n // Return the adapter factory function\n return (options: BetterAuthOptions): Adapter => {\n // Determine ID type: explicit config > auto-detect\n // Defaults to 'number' (SERIAL) since Payload uses SERIAL IDs by default\n const idType = adapterConfig.idType ?? detectIdType(options)\n const generateId = options.advanced?.database?.generateId\n\n // Warn if using number IDs but Better Auth is explicitly configured to generate its own IDs\n // This would cause Better Auth to generate UUIDs which won't work with SERIAL columns\n // Don't warn if generateId is undefined - that's the expected default case\n if (idType === 'number' && generateId !== undefined && generateId !== 'serial') {\n console.warn(\n '[payload-adapter] Warning: Using SERIAL (number) IDs but `generateId` is set to a non-serial value. ' +\n 'Either set `advanced: { database: { generateId: \"serial\" } }` to let Payload generate IDs, ' +\n 'or set `adapterConfig: { idType: \"text\" }` if using UUIDs.'\n )\n }\n\n // Warn if modelName appears to be already plural (ends with 's')\n // With usePlural: true, providing 'users' would become 'userss'\n const coreModels = ['user', 'session', 'account', 'verification'] as const\n for (const model of coreModels) {\n const modelName = options[model]?.modelName\n if (modelName && modelName.endsWith('s')) {\n console.warn(\n `[payload-adapter] Warning: modelName '${modelName}' for '${model}' appears to be plural. ` +\n `Use singular form (e.g., '${modelName.slice(0, -1)}') - it gets pluralized automatically. ` +\n `Using plural names will result in double-pluralization (e.g., '${modelName}s').`\n )\n }\n }\n\n // Create adapter config for createAdapterFactory\n const factoryConfig: AdapterFactoryConfig = {\n adapterId: 'payload-adapter',\n adapterName: 'Payload CMS Adapter',\n // Payload collections are plural by default (users, sessions, etc.)\n // Users can customize via BetterAuthOptions: user: { modelName: 'custom_users' }\n usePlural: true,\n // Let Payload generate IDs when using serial/auto-increment\n disableIdGeneration: idType === 'number',\n // Payload supports these features\n supportsNumericIds: true,\n supportsDates: true,\n supportsBooleans: true,\n supportsJSON: true,\n supportsArrays: false,\n // Payload doesn't expose transaction API at collection level\n transaction: false,\n // Enable debug logs if configured\n debugLogs: enableDebugLogs,\n }\n\n // We need to resolve the payload client before creating the adapter\n // The factory pattern requires we return an adapter synchronously,\n // so we'll resolve it lazily on first operation\n let resolvedPayload: BasePayload | null = null\n let resolvePromise: Promise<BasePayload> | null = null\n\n const getPayload = async (): Promise<BasePayload> => {\n if (resolvedPayload) return resolvedPayload\n if (!resolvePromise) {\n resolvePromise = resolvePayloadClient().then((p) => {\n resolvedPayload = p\n return p\n })\n }\n return resolvePromise\n }\n\n // Helper to convert ID based on type\n const convertId = (id: string | number): string | number => {\n if (idType === 'number' && typeof id === 'string') {\n const num = parseInt(id, 10)\n return isNaN(num) ? id : num\n }\n if (idType === 'text' && typeof id === 'number') {\n return String(id)\n }\n return id\n }\n\n // Create the adapter using createAdapterFactory\n // The factory handles all schema-aware transformations for us\n const adapterFactory = createAdapterFactory({\n config: factoryConfig,\n adapter: ({\n schema,\n getModelName,\n getFieldName,\n debugLog,\n }) => {\n // Log initialization\n if (enableDebugLogs) {\n debugLog('Adapter initialized', {\n idType,\n schema: Object.keys(schema),\n })\n }\n\n /**\n * Get the schema for a model, handling plural/singular lookups.\n * Better Auth queries with plural names when usePlural is true,\n * but schema keys are singular.\n */\n function getModelSchema(model: string) {\n // First try direct lookup\n if (schema[model]) return schema[model]\n\n // Try singular form (strip trailing 's') for plural model names\n const singular = model.endsWith('s') ? model.slice(0, -1) : model\n if (schema[singular]) return schema[singular]\n\n // Try without 'ies' → 'y' conversion (e.g., 'verifications' → 'verification')\n // This handles edge cases but 'verifications' → 'verification' works with simple 's' strip\n\n return undefined\n }\n\n /**\n * Transform a Better Auth field name to a Payload field name.\n *\n * For reference fields (those with `references` in schema), Payload collections\n * use the field name without the `Id`/`_id` suffix (e.g., `userId` → `user`).\n * This matches how betterAuthCollections() generates relationship fields.\n */\n function getPayloadFieldName(model: string, field: string): string {\n // First apply any custom field name mappings from BetterAuthOptions\n const mappedField = getFieldName({ model, field })\n\n // Check if this field is a reference field in the schema\n const modelSchema = getModelSchema(model)\n\n if (modelSchema?.fields?.[field]?.references) {\n // Strip _id or Id suffix for reference fields\n // This matches betterAuthCollections() which does: fieldName.replace(/(_id|Id)$/, '')\n return mappedField.replace(/(_id|Id)$/, '')\n }\n\n return mappedField\n }\n\n /**\n * Transform input data from Better Auth format to Payload format.\n * Converts reference field names (e.g., `userId` → `user`) and\n * converts reference field values to the correct ID type.\n */\n function transformDataForPayload(\n model: string,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const modelSchema = getModelSchema(model)\n if (!modelSchema?.fields) return data\n\n const transformed: Record<string, unknown> = {}\n\n for (const [key, value] of Object.entries(data)) {\n const payloadKey = getPayloadFieldName(model, key)\n let transformedValue = value\n\n // If this is a reference field, convert the ID to the correct type\n const fieldDef = modelSchema.fields[key]\n if (fieldDef?.references && value !== null && value !== undefined) {\n // Convert reference ID to the correct type (number for SERIAL, string for UUID)\n if (idType === 'number' && typeof value === 'string') {\n const numValue = parseInt(value as string, 10)\n if (!isNaN(numValue)) {\n transformedValue = numValue\n }\n } else if (idType === 'text' && typeof value === 'number') {\n transformedValue = String(value)\n }\n }\n\n transformed[payloadKey] = transformedValue\n }\n\n if (enableDebugLogs) {\n console.log('[payload-adapter] transformDataForPayload:', {\n model,\n inputKeys: Object.keys(data),\n outputKeys: Object.keys(transformed),\n transformedData: transformed,\n })\n }\n\n return transformed\n }\n\n /**\n * Transform output data from Payload format to Better Auth format.\n * Converts reference field names back (e.g., `user` → `userId`).\n */\n function transformDataFromPayload(\n model: string,\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const modelSchema = getModelSchema(model)\n if (!modelSchema?.fields || !data) return data\n\n const transformed: Record<string, unknown> = { ...data }\n\n // For each field in the schema that has references,\n // check if Payload returned the stripped name and map it back\n for (const [fieldKey, fieldDef] of Object.entries(modelSchema.fields)) {\n if ((fieldDef as { references?: unknown }).references) {\n const payloadFieldName = fieldKey.replace(/(_id|Id)$/, '')\n if (payloadFieldName in data && !(fieldKey in transformed)) {\n transformed[fieldKey] = data[payloadFieldName]\n // Keep both for compatibility - Better Auth expects userId\n }\n }\n }\n\n // Convert semantic ID fields to numbers when using serial IDs\n // Heuristic: fields ending in 'Id' or '_id' containing numeric strings\n // Modified by allowlist (add) and blocklist (exclude)\n if (idType === 'number') {\n for (const [key, value] of Object.entries(transformed)) {\n // Skip if not a string or already processed as a reference\n if (typeof value !== 'string') continue\n\n // Check if field should be converted\n const matchesHeuristic = /(?:Id|_id)$/.test(key)\n const inAllowlist = idFieldsAllowlistSet.has(key)\n const inBlocklist = idFieldsBlocklistSet.has(key)\n\n if ((matchesHeuristic || inAllowlist) && !inBlocklist) {\n // Only convert if it's a pure numeric string\n if (/^\\d+$/.test(value)) {\n transformed[key] = parseInt(value, 10)\n }\n }\n }\n }\n\n return transformed\n }\n\n /**\n * Convert Better Auth where clause to Payload where clause.\n * Handles field name transformations for reference fields.\n */\n function convertWhereToPayload(\n model: string,\n where: Array<{\n field: string\n value: unknown\n operator: string\n connector?: string\n }>\n ): PayloadWhere {\n if (!where || where.length === 0) return {}\n\n if (where.length === 1) {\n const w = where[0]\n return {\n [getPayloadFieldName(model, w.field)]: convertOperator(w.operator, w.value),\n }\n }\n\n const andConditions = where.filter((w) => w.connector !== 'OR')\n const orConditions = where.filter((w) => w.connector === 'OR')\n\n const result: PayloadWhere = {}\n\n if (andConditions.length > 0) {\n result.and = andConditions.map((w) => ({\n [getPayloadFieldName(model, w.field)]: convertOperator(w.operator, w.value),\n }))\n }\n\n if (orConditions.length > 0) {\n result.or = orConditions.map((w) => ({\n [getPayloadFieldName(model, w.field)]: convertOperator(w.operator, w.value),\n }))\n }\n\n return result\n }\n\n // Get Payload collection slug from model name\n // Uses factory's getModelName which respects BetterAuthOptions.modelName config\n const getCollection = (model: string): CollectionSlug => {\n return getModelName(model) as CollectionSlug\n }\n\n // The CustomAdapter interface uses generics (T) for return types.\n // Payload returns concrete types (JsonObject & TypeWithID).\n // We cast at the interface boundary - this is standard practice\n // when implementing generic interfaces with concrete implementations.\n // The official Better Auth adapters do the same (visible in compiled .mjs).\n return {\n create: async ({ model, data }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n const payloadData = transformDataForPayload(model, data as Record<string, unknown>)\n\n if (enableDebugLogs) {\n debugLog('create', { collection, model, data, payloadData })\n }\n\n try {\n const result = await payload.create({\n collection,\n data: payloadData,\n depth: 0,\n // Bypass access control - Better Auth handles its own auth\n overrideAccess: true,\n })\n // Transform back and merge with input data for Better Auth\n // Database result takes precedence (handles hooks that modify data like firstUserAdmin)\n const transformed = transformDataFromPayload(model, result as Record<string, unknown>)\n return { ...data, ...transformed } as typeof data\n } catch (error) {\n console.error('[payload-adapter] create failed:', {\n collection,\n model,\n error: error instanceof Error ? error.message : error,\n })\n throw error\n }\n },\n\n findOne: async ({ model, where, select, join }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n\n if (enableDebugLogs) {\n debugLog('findOne', { collection, model, where, join })\n }\n\n try {\n // Optimize for single ID queries\n const id = extractSingleId(where)\n if (id !== null) {\n try {\n const result = await payload.findByID({\n collection,\n id: convertId(id),\n depth: join ? 1 : 0,\n overrideAccess: true,\n })\n return transformDataFromPayload(model, result as Record<string, unknown>)\n } catch (error) {\n if (\n error instanceof Error &&\n 'status' in error &&\n (error as Error & { status: number }).status === 404\n ) {\n return null\n }\n throw error\n }\n }\n\n const payloadWhere = convertWhereToPayload(model, where)\n const result = await payload.find({\n collection,\n where: payloadWhere,\n limit: 1,\n depth: join ? 1 : 0,\n overrideAccess: true,\n })\n\n if (!result.docs[0]) return null\n return transformDataFromPayload(model, result.docs[0] as Record<string, unknown>)\n } catch (error) {\n console.error('[payload-adapter] findOne failed:', {\n model,\n where,\n error,\n })\n throw error\n }\n },\n\n findMany: async ({ model, where, limit, offset, sortBy, join }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n\n if (enableDebugLogs) {\n debugLog('findMany', {\n collection,\n model,\n where,\n limit,\n offset,\n sortBy,\n })\n }\n\n const payloadWhere = where ? convertWhereToPayload(model, where) : {}\n\n const result = await payload.find({\n collection,\n where: payloadWhere,\n limit: limit ?? 100,\n page: offset ? Math.floor(offset / (limit ?? 100)) + 1 : 1,\n sort: sortBy\n ? `${sortBy.direction === 'desc' ? '-' : ''}${getPayloadFieldName(model, sortBy.field)}`\n : undefined,\n depth: join ? 1 : 0,\n overrideAccess: true,\n })\n\n return result.docs.map((doc) =>\n transformDataFromPayload(model, doc as Record<string, unknown>)\n )\n },\n\n update: async ({ model, where, update: data }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n const payloadData = transformDataForPayload(model, data as Record<string, unknown>)\n\n if (enableDebugLogs) {\n debugLog('update', { collection, model, where, data, payloadData })\n }\n\n // Optimize for single ID queries\n const id = extractSingleId(where)\n if (id !== null) {\n const result = await payload.update({\n collection,\n id: convertId(id),\n data: payloadData,\n depth: 0,\n overrideAccess: true,\n })\n const transformed = transformDataFromPayload(model, result as Record<string, unknown>)\n return { ...data, ...transformed } as typeof data\n }\n\n const payloadWhere = convertWhereToPayload(model, where)\n const result = await payload.update({\n collection,\n where: payloadWhere,\n data: payloadData,\n depth: 0,\n overrideAccess: true,\n })\n\n if (!result.docs[0]) return null\n const transformed = transformDataFromPayload(model, result.docs[0] as Record<string, unknown>)\n return { ...data, ...transformed } as typeof data\n },\n\n updateMany: async ({ model, where, update: data }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n const payloadData = transformDataForPayload(model, data as Record<string, unknown>)\n\n if (enableDebugLogs) {\n debugLog('updateMany', { collection, model, where, data, payloadData })\n }\n\n const payloadWhere = convertWhereToPayload(model, where)\n\n const result = await payload.update({\n collection,\n where: payloadWhere,\n data: payloadData,\n depth: 0,\n overrideAccess: true,\n })\n\n return result.docs.length\n },\n\n delete: async ({ model, where }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n\n if (enableDebugLogs) {\n debugLog('delete', { collection, model, where })\n }\n\n // Optimize for single ID queries\n const id = extractSingleId(where)\n if (id !== null) {\n await payload.delete({\n collection,\n id: convertId(id),\n overrideAccess: true,\n })\n return\n }\n\n const payloadWhere = convertWhereToPayload(model, where)\n await payload.delete({ collection, where: payloadWhere, overrideAccess: true })\n },\n\n deleteMany: async ({ model, where }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n\n if (enableDebugLogs) {\n debugLog('deleteMany', { collection, model, where })\n }\n\n const payloadWhere = convertWhereToPayload(model, where)\n\n const result = await payload.delete({\n collection,\n where: payloadWhere,\n overrideAccess: true,\n })\n\n return result.docs.length\n },\n\n count: async ({ model, where }) => {\n const payload = await getPayload()\n const collection = getCollection(model)\n\n if (enableDebugLogs) {\n debugLog('count', { collection, model, where })\n }\n\n const payloadWhere = where ? convertWhereToPayload(model, where) : {}\n\n const result = await payload.count({\n collection,\n where: payloadWhere,\n overrideAccess: true,\n })\n\n return result.totalDocs\n },\n } as CustomAdapter\n },\n })\n\n return adapterFactory(options)\n }\n}\n\nexport type { Adapter, BetterAuthOptions }\n"],"names":["createAdapterFactory","detectIdType","options","generateId","advanced","database","undefined","payloadAdapter","payloadClient","adapterConfig","enableDebugLogs","idFieldsAllowlist","idFieldsBlocklist","idFieldsAllowlistSet","Set","idFieldsBlocklistSet","resolvePayloadClient","convertOperator","operator","value","equals","not_equals","greater_than","greater_than_equal","less_than","less_than_equal","in","contains","like","extractSingleId","where","length","w","field","idType","console","warn","coreModels","model","modelName","endsWith","slice","factoryConfig","adapterId","adapterName","usePlural","disableIdGeneration","supportsNumericIds","supportsDates","supportsBooleans","supportsJSON","supportsArrays","transaction","debugLogs","resolvedPayload","resolvePromise","getPayload","then","p","convertId","id","num","parseInt","isNaN","String","adapterFactory","config","adapter","schema","getModelName","getFieldName","debugLog","Object","keys","getModelSchema","singular","getPayloadFieldName","mappedField","modelSchema","fields","references","replace","transformDataForPayload","data","transformed","key","entries","payloadKey","transformedValue","fieldDef","numValue","log","inputKeys","outputKeys","transformedData","transformDataFromPayload","fieldKey","payloadFieldName","matchesHeuristic","test","inAllowlist","has","inBlocklist","convertWhereToPayload","andConditions","filter","connector","orConditions","result","and","map","or","getCollection","create","payload","collection","payloadData","depth","overrideAccess","error","Error","message","findOne","select","join","findByID","status","payloadWhere","find","limit","docs","findMany","offset","sortBy","page","Math","floor","sort","direction","doc","update","updateMany","delete","deleteMany","count","totalDocs"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BeforeLogin.d.ts","sourceRoot":"","sources":["../../src/components/BeforeLogin.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAyB,EAAE,EAAE,gBAAgB,+BAsB1E;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/BeforeLogin.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\nimport { useRouter } from 'next/navigation.js'\n\nexport type BeforeLoginProps = {\n /** URL to redirect to for login. Default: '/admin/login' */\n loginUrl?: string\n}\n\n/**\n * BeforeLogin component that redirects to the custom login page.\n * Injected into Payload's beforeLogin slot to intercept default login.\n */\nexport function BeforeLogin({ loginUrl = '/admin/login' }: BeforeLoginProps) {\n const router = useRouter()\n\n useEffect(() => {\n router.replace(loginUrl)\n }, [router, loginUrl])\n\n // Show loading state while redirecting\n return (\n <div\n style={{\n display: 'flex',\n minHeight: '100vh',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n color: 'var(--theme-text)',\n }}\n >\n <div>Redirecting to login...</div>\n </div>\n )\n}\n\nexport default BeforeLogin\n"],"names":["useEffect","useRouter","BeforeLogin","loginUrl","router","replace","div","style","display","minHeight","alignItems","justifyContent","background","color"],"mappings":"AAAA;;AAEA,SAASA,SAAS,QAAQ,QAAO;AACjC,SAASC,SAAS,QAAQ,qBAAoB;AAO9C;;;CAGC,GACD,OAAO,SAASC,YAAY,EAAEC,WAAW,cAAc,EAAoB;IACzE,MAAMC,SAASH;IAEfD,UAAU;QACRI,OAAOC,OAAO,CAACF;IACjB,GAAG;QAACC;QAAQD;KAAS;IAErB,uCAAuC;IACvC,qBACE,KAACG;QACCC,OAAO;YACLC,SAAS;YACTC,WAAW;YACXC,YAAY;YACZC,gBAAgB;YAChBC,YAAY;YACZC,OAAO;QACT;kBAEA,cAAA,KAACP;sBAAI;;;AAGX;AAEA,eAAeJ,YAAW"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LoginView.d.ts","sourceRoot":"","sources":["../../src/components/LoginView.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAG7B,MAAM,MAAM,cAAc,GAAG;IAC3B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAAA;IACvC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAChC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AA+BD,wBAAgB,SAAS,CAAC,EACxB,UAAU,EAAE,cAAc,EAC1B,IAAI,EACJ,KAAe,EACf,cAAyB,EACzB,YAAsB,EACtB,eAAuB,EACvB,aAAsB,EACtB,YAAqB,EACrB,iBAA0B,EAC1B,oBAA6B,EAC7B,gBAAgB,GACjB,EAAE,cAAc,+BA83ChB;AAED,eAAe,SAAS,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/LoginView.tsx"],"sourcesContent":["'use client'\n\nimport { useState, useEffect, type FormEvent } from 'react'\nimport { useRouter } from 'next/navigation.js'\nimport {\n createPayloadAuthClient,\n type PayloadAuthClient,\n} from '../exports/client.js'\nimport { hasAnyRole, hasAllRoles, normalizeRoles } from '../utils/access.js'\n\nexport type LoginViewProps = {\n /** Optional pre-configured auth client */\n authClient?: PayloadAuthClient\n /** Custom logo element */\n logo?: React.ReactNode\n /** Login page title. Default: 'Login' */\n title?: string\n /** Path to redirect after successful login. Default: '/admin' */\n afterLoginPath?: string\n /**\n * Required role(s) for admin access.\n * - string: Single role required (default: 'admin')\n * - string[]: Multiple roles (behavior depends on requireAllRoles)\n * - null/undefined: Disable role checking\n * For complex RBAC beyond these options, disable the login view and create your own.\n */\n requiredRole?: string | string[] | null\n /**\n * When requiredRole is an array, require ALL roles (true) or ANY role (false).\n * Default: false (any matching role grants access)\n */\n requireAllRoles?: boolean\n /**\n * Enable passkey (WebAuthn) sign-in option.\n * - true: Always show passkey button\n * - false: Never show passkey button\n * - 'auto' (default): Auto-detect if passkey plugin is available\n */\n enablePasskey?: boolean | 'auto'\n /**\n * Enable user registration (sign up) option.\n * - true: Always show \"Create account\" link\n * - false: Never show registration option\n * - 'auto' (default): Auto-detect if sign-up endpoint is available\n */\n enableSignUp?: boolean | 'auto'\n /**\n * Default role to assign to new users during registration.\n * Default: 'user'\n */\n defaultSignUpRole?: string\n /**\n * Enable forgot password option.\n * - true: Always show \"Forgot password?\" link\n * - false: Never show forgot password option\n * - 'auto' (default): Auto-detect if forget-password endpoint is available\n */\n enableForgotPassword?: boolean | 'auto'\n /**\n * Custom URL for password reset page. If provided, users will be redirected here\n * instead of showing the inline password reset form.\n * The reset token will be appended as ?token=xxx\n */\n resetPasswordUrl?: string\n}\n\n/**\n * Check if user has the required role(s)\n */\nfunction checkUserRoles(\n user: { role?: unknown } | null | undefined,\n requiredRole: string | string[] | null | undefined,\n requireAllRoles: boolean\n): boolean {\n // No role requirement = access granted\n if (!requiredRole) return true\n\n // No user = access denied\n if (!user) return false\n\n const roles = Array.isArray(requiredRole) ? requiredRole : [requiredRole]\n\n if (requireAllRoles) {\n return hasAllRoles(user, roles)\n }\n\n return hasAnyRole(user, roles)\n}\n\n/**\n * Full login page component matching Payload's admin theme.\n * Registered as a custom admin view at /admin/login.\n */\ntype ViewMode = 'login' | 'register' | 'forgotPassword' | 'resetSent' | 'twoFactor'\n\nexport function LoginView({\n authClient: providedClient,\n logo,\n title = 'Login',\n afterLoginPath = '/admin',\n requiredRole = 'admin',\n requireAllRoles = false,\n enablePasskey = 'auto',\n enableSignUp = 'auto',\n defaultSignUpRole = 'user',\n enableForgotPassword = 'auto',\n resetPasswordUrl,\n}: LoginViewProps) {\n const router = useRouter()\n\n // View state\n const [viewMode, setViewMode] = useState<ViewMode>('login')\n\n // Form fields\n const [email, setEmail] = useState('')\n const [password, setPassword] = useState('')\n const [name, setName] = useState('')\n const [confirmPassword, setConfirmPassword] = useState('')\n\n // UI state\n const [error, setError] = useState<string | null>(null)\n const [successMessage, setSuccessMessage] = useState<string | null>(null)\n const [loading, setLoading] = useState(false)\n const [passkeyLoading, setPasskeyLoading] = useState(false)\n const [checkingSession, setCheckingSession] = useState(true)\n const [accessDenied, setAccessDenied] = useState(false)\n\n // Feature availability\n const [passkeyAvailable, setPasskeyAvailable] = useState(enablePasskey === true)\n const [signUpAvailable, setSignUpAvailable] = useState(enableSignUp === true)\n const [forgotPasswordAvailable, setForgotPasswordAvailable] = useState(enableForgotPassword === true)\n\n // Two-factor authentication state\n const [totpCode, setTotpCode] = useState('')\n const [totpLoading, setTotpLoading] = useState(false)\n\n const getClient = () => providedClient ?? createPayloadAuthClient()\n\n // Check if user is already logged in on mount\n useEffect(() => {\n async function checkSession() {\n try {\n const client = getClient()\n const result = await client.getSession()\n\n if (result.data?.user) {\n const user = result.data.user as { role?: unknown }\n // User is logged in, check role\n if (checkUserRoles(user, requiredRole, requireAllRoles)) {\n router.push(afterLoginPath)\n return\n } else {\n setAccessDenied(true)\n }\n }\n } catch {\n // No session, show login form\n }\n setCheckingSession(false)\n }\n checkSession()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [afterLoginPath, requiredRole, requireAllRoles, router])\n\n // Auto-detect passkey availability if set to 'auto'\n useEffect(() => {\n if (enablePasskey === 'auto') {\n // Check if passkey endpoint exists (GET request)\n // Better Auth passkey routes are at /passkey/* (singular)\n fetch('/api/auth/passkey/generate-authenticate-options', {\n method: 'GET',\n credentials: 'include',\n })\n .then((res) => {\n // If we get a response (even 400/401 for not authenticated), passkey is available\n // 404 means passkey plugin is not installed\n setPasskeyAvailable(res.status !== 404)\n })\n .catch(() => {\n setPasskeyAvailable(false)\n })\n } else {\n setPasskeyAvailable(enablePasskey === true)\n }\n }, [enablePasskey])\n\n // Auto-detect sign up availability if set to 'auto'\n useEffect(() => {\n if (enableSignUp === 'auto') {\n // Check if sign-up endpoint exists\n fetch('/api/auth/sign-up/email', {\n method: 'OPTIONS',\n credentials: 'include',\n })\n .then((res) => {\n // 404 means sign-up is not available\n setSignUpAvailable(res.status !== 404)\n })\n .catch(() => {\n // If OPTIONS fails, try a HEAD or just assume it's available since it's a core endpoint\n setSignUpAvailable(true)\n })\n } else {\n setSignUpAvailable(enableSignUp === true)\n }\n }, [enableSignUp])\n\n // Auto-detect forgot password availability if set to 'auto'\n useEffect(() => {\n if (enableForgotPassword === 'auto') {\n // Check if request-password-reset endpoint exists\n fetch('/api/auth/request-password-reset', {\n method: 'OPTIONS',\n credentials: 'include',\n })\n .then((res) => {\n // 404 means request-password-reset is not available\n setForgotPasswordAvailable(res.status !== 404)\n })\n .catch(() => {\n // If OPTIONS fails, assume it's available since it's a core endpoint\n setForgotPasswordAvailable(true)\n })\n } else {\n setForgotPasswordAvailable(enableForgotPassword === true)\n }\n }, [enableForgotPassword])\n\n async function handleSubmit(e: FormEvent) {\n e.preventDefault()\n setLoading(true)\n setError(null)\n setSuccessMessage(null)\n setAccessDenied(false)\n\n try {\n const client = getClient()\n const result = await client.signIn.email({\n email,\n password,\n })\n\n // Check if 2FA is required (use 'in' operator for proper TypeScript inference)\n if (result.data && 'twoFactorRedirect' in result.data && result.data.twoFactorRedirect) {\n setViewMode('twoFactor')\n setLoading(false)\n return\n }\n\n if (result.error) {\n setError(result.error.message ?? 'Invalid credentials')\n setLoading(false)\n return\n }\n\n if (result.data?.user) {\n const user = result.data.user as { role?: unknown }\n // Check role if required\n if (!checkUserRoles(user, requiredRole, requireAllRoles)) {\n setAccessDenied(true)\n setLoading(false)\n return\n }\n\n router.push(afterLoginPath)\n router.refresh()\n }\n } catch {\n setError('An error occurred. Please try again.')\n setLoading(false)\n }\n }\n\n async function handleSignUp(e: FormEvent) {\n e.preventDefault()\n setLoading(true)\n setError(null)\n setSuccessMessage(null)\n\n // Validate passwords match\n if (password !== confirmPassword) {\n setError('Passwords do not match')\n setLoading(false)\n return\n }\n\n // Validate password strength (basic)\n if (password.length < 8) {\n setError('Password must be at least 8 characters')\n setLoading(false)\n return\n }\n\n try {\n const client = getClient()\n const result = await client.signUp.email({\n email,\n password,\n name,\n role: defaultSignUpRole,\n } as Parameters<typeof client.signUp.email>[0])\n\n if (result.error) {\n setError(result.error.message ?? 'Registration failed')\n setLoading(false)\n return\n }\n\n // Registration successful - either auto-signed in or need to verify email\n if (result.data?.user) {\n // Re-fetch session to get updated user data (role may have been changed by hooks)\n // This handles cases like firstUserAdmin where the role is set after creation\n const sessionResult = await client.getSession()\n\n if (sessionResult.data?.user) {\n const user = sessionResult.data.user as { role?: unknown }\n // Check role if required\n if (!checkUserRoles(user, requiredRole, requireAllRoles)) {\n setAccessDenied(true)\n setLoading(false)\n return\n }\n }\n\n router.push(afterLoginPath)\n router.refresh()\n } else {\n // Likely requires email verification - show success and switch to login\n setSuccessMessage('Account created! Please check your email to verify your account.')\n setViewMode('login')\n setPassword('')\n setConfirmPassword('')\n setLoading(false)\n }\n } catch {\n setError('An error occurred. Please try again.')\n setLoading(false)\n }\n }\n\n async function handleForgotPassword(e: FormEvent) {\n e.preventDefault()\n setLoading(true)\n setError(null)\n setSuccessMessage(null)\n\n try {\n const client = getClient()\n const result = await client.requestPasswordReset({\n email,\n redirectTo: resetPasswordUrl ?? `${window.location.origin}/admin/reset-password`,\n })\n\n if (result.error) {\n setError(result.error.message ?? 'Failed to send reset email')\n setLoading(false)\n return\n }\n\n // Success - show confirmation\n setViewMode('resetSent')\n setLoading(false)\n } catch {\n setError('An error occurred. Please try again.')\n setLoading(false)\n }\n }\n\n async function handleTotpVerify(e: FormEvent) {\n e.preventDefault()\n setTotpLoading(true)\n setError(null)\n\n try {\n const client = getClient()\n const result = await client.twoFactor.verifyTotp({ code: totpCode })\n\n if (result.error) {\n setError(result.error.message ?? 'Invalid verification code')\n setTotpLoading(false)\n return\n }\n\n // Verify-totp may not return all user fields (like custom 'role')\n // Fetch the session to get complete user data for role check\n if (requiredRole) {\n const sessionResult = await client.getSession()\n if (sessionResult.data?.user) {\n const user = sessionResult.data.user as { role?: unknown }\n if (!checkUserRoles(user, requiredRole, requireAllRoles)) {\n setAccessDenied(true)\n setTotpLoading(false)\n return\n }\n }\n }\n\n router.push(afterLoginPath)\n router.refresh()\n } catch {\n setError('An error occurred. Please try again.')\n setTotpLoading(false)\n }\n }\n\n function switchView(newView: ViewMode) {\n setViewMode(newView)\n setError(null)\n setSuccessMessage(null)\n // Reset form fields based on context\n if (newView === 'login') {\n setTotpCode('')\n setConfirmPassword('')\n } else if (newView === 'register') {\n setPassword('')\n setConfirmPassword('')\n } else if (newView === 'forgotPassword') {\n setPassword('')\n }\n }\n\n function handleBackToLogin() {\n switchView('login')\n }\n\n async function handlePasskeySignIn() {\n if (!passkeyAvailable) return\n\n setPasskeyLoading(true)\n setError(null)\n setAccessDenied(false)\n\n try {\n const client = getClient()\n const result = await client.signIn.passkey()\n\n if (result.error) {\n setError(result.error.message ?? 'Passkey authentication failed')\n setPasskeyLoading(false)\n return\n }\n\n // Passkey sign-in succeeded - fetch session to get full user data (including role)\n // This is more reliable than checking result.data.user which may vary by SDK version\n const sessionResult = await client.getSession()\n\n if (sessionResult.data?.user) {\n const user = sessionResult.data.user as { role?: unknown }\n // Check role if required\n if (!checkUserRoles(user, requiredRole, requireAllRoles)) {\n setAccessDenied(true)\n setPasskeyLoading(false)\n return\n }\n\n router.push(afterLoginPath)\n router.refresh()\n } else {\n // Session fetch failed - shouldn't happen after successful passkey auth\n setError('Authentication succeeded but session could not be verified')\n setPasskeyLoading(false)\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'NotAllowedError') {\n setError('Passkey authentication was cancelled or not allowed')\n } else {\n setError(err instanceof Error ? err.message : 'Passkey authentication failed')\n }\n setPasskeyLoading(false)\n }\n }\n\n async function handleSignOut() {\n const client = getClient()\n await client.signOut()\n setAccessDenied(false)\n router.refresh()\n }\n\n // Loading state while checking session\n if (checkingSession) {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n }}\n >\n <div style={{ color: 'var(--theme-text)', opacity: 0.7 }}>\n Loading...\n </div>\n </div>\n )\n }\n\n // Access denied state\n if (accessDenied) {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n textAlign: 'center',\n }}\n >\n <h1\n style={{\n color: 'var(--theme-error-500)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n margin: '0 0 var(--base) 0',\n }}\n >\n Access Denied\n </h1>\n <p\n style={{\n color: 'var(--theme-text)',\n opacity: 0.8,\n marginBottom: 'calc(var(--base) * 1.5)',\n fontSize: 'var(--font-size-small)',\n }}\n >\n You don't have permission to access the admin panel.\n Please contact an administrator if you believe this is an error.\n </p>\n <button\n onClick={handleSignOut}\n style={{\n padding: 'calc(var(--base) * 0.75) calc(var(--base) * 1.5)',\n background: 'var(--theme-elevation-150)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n cursor: 'pointer',\n }}\n >\n Sign out and try again\n </button>\n </div>\n </div>\n )\n }\n\n // Two-factor verification view\n if (viewMode === 'twoFactor') {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n }}\n >\n {logo && (\n <div\n style={{\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n {logo}\n </div>\n )}\n\n <h1\n style={{\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n margin: '0 0 calc(var(--base) * 0.5) 0',\n textAlign: 'center',\n }}\n >\n Two-Factor Authentication\n </h1>\n\n <p\n style={{\n color: 'var(--theme-text)',\n opacity: 0.7,\n fontSize: 'var(--font-size-small)',\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n Enter the 6-digit code from your authenticator app\n </p>\n\n <form onSubmit={handleTotpVerify}>\n <div style={{ marginBottom: 'calc(var(--base) * 1.5)' }}>\n <label\n htmlFor=\"totp-code\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Verification Code\n </label>\n <input\n id=\"totp-code\"\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n autoComplete=\"one-time-code\"\n value={totpCode}\n onChange={(e) => setTotpCode(e.target.value.replace(/\\D/g, '').slice(0, 6))}\n required\n placeholder=\"000000\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h4)',\n fontFamily: 'monospace',\n textAlign: 'center',\n letterSpacing: '0.5em',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n {error && (\n <div\n style={{\n color: 'var(--theme-error-500)',\n marginBottom: 'var(--base)',\n fontSize: 'var(--font-size-small)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'var(--theme-error-50)',\n borderRadius: 'var(--style-radius-s)',\n border: '1px solid var(--theme-error-200)',\n }}\n >\n {error}\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={totpLoading || totpCode.length !== 6}\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-elevation-800)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-elevation-50)',\n fontSize: 'var(--font-size-base)',\n fontWeight: 500,\n cursor: totpLoading || totpCode.length !== 6 ? 'not-allowed' : 'pointer',\n opacity: totpLoading || totpCode.length !== 6 ? 0.7 : 1,\n transition: 'opacity 150ms ease',\n }}\n >\n {totpLoading ? 'Verifying...' : 'Verify'}\n </button>\n </form>\n\n <button\n type=\"button\"\n onClick={handleBackToLogin}\n style={{\n width: '100%',\n marginTop: 'var(--base)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'transparent',\n border: 'none',\n color: 'var(--theme-text)',\n opacity: 0.7,\n fontSize: 'var(--font-size-small)',\n cursor: 'pointer',\n }}\n >\n ← Back to login\n </button>\n </div>\n </div>\n )\n }\n\n // Registration view\n if (viewMode === 'register') {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n }}\n >\n {logo && (\n <div\n style={{\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n {logo}\n </div>\n )}\n\n <h1\n style={{\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n margin: '0 0 calc(var(--base) * 1.5) 0',\n textAlign: 'center',\n }}\n >\n Create Account\n </h1>\n\n <form onSubmit={handleSignUp}>\n <div style={{ marginBottom: 'var(--base)' }}>\n <label\n htmlFor=\"name\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Name\n </label>\n <input\n id=\"name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n required\n autoComplete=\"name\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n <div style={{ marginBottom: 'var(--base)' }}>\n <label\n htmlFor=\"register-email\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Email\n </label>\n <input\n id=\"register-email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n <div style={{ marginBottom: 'var(--base)' }}>\n <label\n htmlFor=\"register-password\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Password\n </label>\n <input\n id=\"register-password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n autoComplete=\"new-password\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n <div style={{ marginBottom: 'calc(var(--base) * 1.5)' }}>\n <label\n htmlFor=\"confirm-password\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Confirm Password\n </label>\n <input\n id=\"confirm-password\"\n type=\"password\"\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n required\n autoComplete=\"new-password\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n {error && (\n <div\n style={{\n color: 'var(--theme-error-500)',\n marginBottom: 'var(--base)',\n fontSize: 'var(--font-size-small)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'var(--theme-error-50)',\n borderRadius: 'var(--style-radius-s)',\n border: '1px solid var(--theme-error-200)',\n }}\n >\n {error}\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading}\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-elevation-800)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-elevation-50)',\n fontSize: 'var(--font-size-base)',\n fontWeight: 500,\n cursor: loading ? 'not-allowed' : 'pointer',\n opacity: loading ? 0.7 : 1,\n transition: 'opacity 150ms ease',\n }}\n >\n {loading ? 'Creating account...' : 'Create Account'}\n </button>\n </form>\n\n <div\n style={{\n marginTop: 'calc(var(--base) * 1.5)',\n textAlign: 'center',\n fontSize: 'var(--font-size-small)',\n color: 'var(--theme-text)',\n opacity: 0.8,\n }}\n >\n Already have an account?{' '}\n <button\n type=\"button\"\n onClick={handleBackToLogin}\n style={{\n background: 'none',\n border: 'none',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n fontSize: 'inherit',\n textDecoration: 'underline',\n padding: 0,\n }}\n >\n Sign in\n </button>\n </div>\n </div>\n </div>\n )\n }\n\n // Forgot password view\n if (viewMode === 'forgotPassword') {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n }}\n >\n {logo && (\n <div\n style={{\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n {logo}\n </div>\n )}\n\n <h1\n style={{\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n margin: '0 0 calc(var(--base) * 0.5) 0',\n textAlign: 'center',\n }}\n >\n Reset Password\n </h1>\n\n <p\n style={{\n color: 'var(--theme-text)',\n opacity: 0.7,\n fontSize: 'var(--font-size-small)',\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n Enter your email and we'll send you a link to reset your password\n </p>\n\n <form onSubmit={handleForgotPassword}>\n <div style={{ marginBottom: 'calc(var(--base) * 1.5)' }}>\n <label\n htmlFor=\"forgot-email\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Email\n </label>\n <input\n id=\"forgot-email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n {error && (\n <div\n style={{\n color: 'var(--theme-error-500)',\n marginBottom: 'var(--base)',\n fontSize: 'var(--font-size-small)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'var(--theme-error-50)',\n borderRadius: 'var(--style-radius-s)',\n border: '1px solid var(--theme-error-200)',\n }}\n >\n {error}\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading}\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-elevation-800)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-elevation-50)',\n fontSize: 'var(--font-size-base)',\n fontWeight: 500,\n cursor: loading ? 'not-allowed' : 'pointer',\n opacity: loading ? 0.7 : 1,\n transition: 'opacity 150ms ease',\n }}\n >\n {loading ? 'Sending...' : 'Send Reset Link'}\n </button>\n </form>\n\n <button\n type=\"button\"\n onClick={handleBackToLogin}\n style={{\n width: '100%',\n marginTop: 'var(--base)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'transparent',\n border: 'none',\n color: 'var(--theme-text)',\n opacity: 0.7,\n fontSize: 'var(--font-size-small)',\n cursor: 'pointer',\n }}\n >\n ← Back to login\n </button>\n </div>\n </div>\n )\n }\n\n // Reset link sent confirmation view\n if (viewMode === 'resetSent') {\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n textAlign: 'center',\n }}\n >\n {logo && (\n <div\n style={{\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n {logo}\n </div>\n )}\n\n <div\n style={{\n width: '64px',\n height: '64px',\n background: 'var(--theme-success-100)',\n borderRadius: '50%',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n margin: '0 auto calc(var(--base) * 1.5)',\n fontSize: '28px',\n }}\n >\n ✓\n </div>\n\n <h1\n style={{\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n margin: '0 0 calc(var(--base) * 0.5) 0',\n }}\n >\n Check Your Email\n </h1>\n\n <p\n style={{\n color: 'var(--theme-text)',\n opacity: 0.7,\n fontSize: 'var(--font-size-small)',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n We've sent a password reset link to <strong>{email}</strong>\n </p>\n\n <p\n style={{\n color: 'var(--theme-text)',\n opacity: 0.6,\n fontSize: 'var(--font-size-small)',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n Didn't receive the email? Check your spam folder or try again.\n </p>\n\n <button\n type=\"button\"\n onClick={handleBackToLogin}\n style={{\n padding: 'calc(var(--base) * 0.75) calc(var(--base) * 1.5)',\n background: 'var(--theme-elevation-150)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n cursor: 'pointer',\n }}\n >\n Back to login\n </button>\n </div>\n </div>\n )\n }\n\n // Main login view\n return (\n <div\n style={{\n minHeight: '100vh',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'var(--theme-bg)',\n padding: 'var(--base)',\n }}\n >\n <div\n style={{\n background: 'var(--theme-elevation-50)',\n padding: 'calc(var(--base) * 2)',\n borderRadius: 'var(--style-radius-m)',\n boxShadow: '0 2px 20px rgba(0, 0, 0, 0.1)',\n width: '100%',\n maxWidth: '400px',\n }}\n >\n {logo && (\n <div\n style={{\n textAlign: 'center',\n marginBottom: 'calc(var(--base) * 1.5)',\n }}\n >\n {logo}\n </div>\n )}\n\n <h1\n style={{\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-h3)',\n fontWeight: 600,\n textAlign: 'center',\n margin: '0 0 calc(var(--base) * 1.5) 0',\n }}\n >\n {title}\n </h1>\n\n {successMessage && (\n <div\n style={{\n color: 'var(--theme-success-500)',\n marginBottom: 'var(--base)',\n fontSize: 'var(--font-size-small)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'var(--theme-success-50)',\n borderRadius: 'var(--style-radius-s)',\n border: '1px solid var(--theme-success-200)',\n }}\n >\n {successMessage}\n </div>\n )}\n\n <form onSubmit={handleSubmit}>\n <div style={{ marginBottom: 'var(--base)' }}>\n <label\n htmlFor=\"email\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Email\n </label>\n <input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n autoComplete=\"email\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n <div style={{ marginBottom: 'var(--base)' }}>\n <label\n htmlFor=\"password\"\n style={{\n display: 'block',\n color: 'var(--theme-text)',\n marginBottom: 'calc(var(--base) * 0.5)',\n fontSize: 'var(--font-size-small)',\n fontWeight: 500,\n }}\n >\n Password\n </label>\n <input\n id=\"password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n autoComplete=\"current-password\"\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-input-bg)',\n border: '1px solid var(--theme-elevation-150)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n outline: 'none',\n boxSizing: 'border-box',\n }}\n />\n </div>\n\n {forgotPasswordAvailable && (\n <div\n style={{\n marginBottom: 'calc(var(--base) * 1.5)',\n textAlign: 'right',\n }}\n >\n <button\n type=\"button\"\n onClick={() => switchView('forgotPassword')}\n style={{\n background: 'none',\n border: 'none',\n color: 'var(--theme-text)',\n opacity: 0.7,\n cursor: 'pointer',\n fontSize: 'var(--font-size-small)',\n padding: 0,\n textDecoration: 'underline',\n }}\n >\n Forgot password?\n </button>\n </div>\n )}\n\n {error && (\n <div\n style={{\n color: 'var(--theme-error-500)',\n marginBottom: 'var(--base)',\n fontSize: 'var(--font-size-small)',\n padding: 'calc(var(--base) * 0.5)',\n background: 'var(--theme-error-50)',\n borderRadius: 'var(--style-radius-s)',\n border: '1px solid var(--theme-error-200)',\n }}\n >\n {error}\n </div>\n )}\n\n <button\n type=\"submit\"\n disabled={loading || passkeyLoading}\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'var(--theme-elevation-800)',\n border: 'none',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-elevation-50)',\n fontSize: 'var(--font-size-base)',\n fontWeight: 500,\n cursor: loading || passkeyLoading ? 'not-allowed' : 'pointer',\n opacity: loading || passkeyLoading ? 0.7 : 1,\n transition: 'opacity 150ms ease',\n }}\n >\n {loading ? 'Signing in...' : 'Sign In'}\n </button>\n </form>\n\n {passkeyAvailable && (\n <>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n margin: 'calc(var(--base) * 1.5) 0',\n gap: 'calc(var(--base) * 1)',\n }}\n >\n <div\n style={{\n flex: 1,\n height: '1px',\n background: 'var(--theme-elevation-150)',\n }}\n />\n <span\n style={{\n color: 'var(--theme-text)',\n opacity: 0.6,\n fontSize: 'var(--font-size-small)',\n }}\n >\n or\n </span>\n <div\n style={{\n flex: 1,\n height: '1px',\n background: 'var(--theme-elevation-150)',\n }}\n />\n </div>\n\n <button\n type=\"button\"\n onClick={handlePasskeySignIn}\n disabled={loading || passkeyLoading}\n style={{\n width: '100%',\n padding: 'calc(var(--base) * 0.75)',\n background: 'transparent',\n border: '1px solid var(--theme-elevation-300)',\n borderRadius: 'var(--style-radius-s)',\n color: 'var(--theme-text)',\n fontSize: 'var(--font-size-base)',\n fontWeight: 500,\n cursor: loading || passkeyLoading ? 'not-allowed' : 'pointer',\n opacity: loading || passkeyLoading ? 0.7 : 1,\n transition: 'opacity 150ms ease',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: 'calc(var(--base) * 0.5)',\n }}\n >\n <span style={{ fontSize: '18px' }}>🔐</span>\n {passkeyLoading ? 'Authenticating...' : 'Sign in with Passkey'}\n </button>\n </>\n )}\n\n {signUpAvailable && (\n <div\n style={{\n marginTop: 'calc(var(--base) * 1.5)',\n textAlign: 'center',\n fontSize: 'var(--font-size-small)',\n color: 'var(--theme-text)',\n opacity: 0.8,\n }}\n >\n Don't have an account?{' '}\n <button\n type=\"button\"\n onClick={() => switchView('register')}\n style={{\n background: 'none',\n border: 'none',\n color: 'var(--theme-elevation-800)',\n cursor: 'pointer',\n fontSize: 'inherit',\n textDecoration: 'underline',\n padding: 0,\n }}\n >\n Create account\n </button>\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default LoginView\n"],"names":["useState","useEffect","useRouter","createPayloadAuthClient","hasAnyRole","hasAllRoles","checkUserRoles","user","requiredRole","requireAllRoles","roles","Array","isArray","LoginView","authClient","providedClient","logo","title","afterLoginPath","enablePasskey","enableSignUp","defaultSignUpRole","enableForgotPassword","resetPasswordUrl","router","viewMode","setViewMode","email","setEmail","password","setPassword","name","setName","confirmPassword","setConfirmPassword","error","setError","successMessage","setSuccessMessage","loading","setLoading","passkeyLoading","setPasskeyLoading","checkingSession","setCheckingSession","accessDenied","setAccessDenied","passkeyAvailable","setPasskeyAvailable","signUpAvailable","setSignUpAvailable","forgotPasswordAvailable","setForgotPasswordAvailable","totpCode","setTotpCode","totpLoading","setTotpLoading","getClient","checkSession","client","result","getSession","data","push","fetch","method","credentials","then","res","status","catch","handleSubmit","e","preventDefault","signIn","twoFactorRedirect","message","refresh","handleSignUp","length","signUp","role","sessionResult","handleForgotPassword","requestPasswordReset","redirectTo","window","location","origin","handleTotpVerify","twoFactor","verifyTotp","code","switchView","newView","handleBackToLogin","handlePasskeySignIn","passkey","err","Error","handleSignOut","signOut","div","style","minHeight","display","alignItems","justifyContent","background","color","opacity","padding","borderRadius","boxShadow","width","maxWidth","textAlign","h1","fontSize","fontWeight","margin","p","marginBottom","button","onClick","border","cursor","form","onSubmit","label","htmlFor","input","id","type","inputMode","pattern","autoComplete","value","onChange","target","replace","slice","required","placeholder","fontFamily","letterSpacing","outline","boxSizing","disabled","transition","marginTop","textDecoration","height","strong","gap","flex","span"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,EAAEC,SAAS,QAAwB,QAAO;AAC3D,SAASC,SAAS,QAAQ,qBAAoB;AAC9C,SACEC,uBAAuB,QAElB,uBAAsB;AAC7B,SAASC,UAAU,EAAEC,WAAW,QAAwB,qBAAoB;AA0D5E;;CAEC,GACD,SAASC,eACPC,IAA2C,EAC3CC,YAAkD,EAClDC,eAAwB;IAExB,uCAAuC;IACvC,IAAI,CAACD,cAAc,OAAO;IAE1B,0BAA0B;IAC1B,IAAI,CAACD,MAAM,OAAO;IAElB,MAAMG,QAAQC,MAAMC,OAAO,CAACJ,gBAAgBA,eAAe;QAACA;KAAa;IAEzE,IAAIC,iBAAiB;QACnB,OAAOJ,YAAYE,MAAMG;IAC3B;IAEA,OAAON,WAAWG,MAAMG;AAC1B;AAQA,OAAO,SAASG,UAAU,EACxBC,YAAYC,cAAc,EAC1BC,IAAI,EACJC,QAAQ,OAAO,EACfC,iBAAiB,QAAQ,EACzBV,eAAe,OAAO,EACtBC,kBAAkB,KAAK,EACvBU,gBAAgB,MAAM,EACtBC,eAAe,MAAM,EACrBC,oBAAoB,MAAM,EAC1BC,uBAAuB,MAAM,EAC7BC,gBAAgB,EACD;IACf,MAAMC,SAAStB;IAEf,aAAa;IACb,MAAM,CAACuB,UAAUC,YAAY,GAAG1B,SAAmB;IAEnD,cAAc;IACd,MAAM,CAAC2B,OAAOC,SAAS,GAAG5B,SAAS;IACnC,MAAM,CAAC6B,UAAUC,YAAY,GAAG9B,SAAS;IACzC,MAAM,CAAC+B,MAAMC,QAAQ,GAAGhC,SAAS;IACjC,MAAM,CAACiC,iBAAiBC,mBAAmB,GAAGlC,SAAS;IAEvD,WAAW;IACX,MAAM,CAACmC,OAAOC,SAAS,GAAGpC,SAAwB;IAClD,MAAM,CAACqC,gBAAgBC,kBAAkB,GAAGtC,SAAwB;IACpE,MAAM,CAACuC,SAASC,WAAW,GAAGxC,SAAS;IACvC,MAAM,CAACyC,gBAAgBC,kBAAkB,GAAG1C,SAAS;IACrD,MAAM,CAAC2C,iBAAiBC,mBAAmB,GAAG5C,SAAS;IACvD,MAAM,CAAC6C,cAAcC,gBAAgB,GAAG9C,SAAS;IAEjD,uBAAuB;IACvB,MAAM,CAAC+C,kBAAkBC,oBAAoB,GAAGhD,SAASmB,kBAAkB;IAC3E,MAAM,CAAC8B,iBAAiBC,mBAAmB,GAAGlD,SAASoB,iBAAiB;IACxE,MAAM,CAAC+B,yBAAyBC,2BAA2B,GAAGpD,SAASsB,yBAAyB;IAEhG,kCAAkC;IAClC,MAAM,CAAC+B,UAAUC,YAAY,GAAGtD,SAAS;IACzC,MAAM,CAACuD,aAAaC,eAAe,GAAGxD,SAAS;IAE/C,MAAMyD,YAAY,IAAM1C,kBAAkBZ;IAE1C,8CAA8C;IAC9CF,UAAU;QACR,eAAeyD;YACb,IAAI;gBACF,MAAMC,SAASF;gBACf,MAAMG,SAAS,MAAMD,OAAOE,UAAU;gBAEtC,IAAID,OAAOE,IAAI,EAAEvD,MAAM;oBACrB,MAAMA,OAAOqD,OAAOE,IAAI,CAACvD,IAAI;oBAC7B,gCAAgC;oBAChC,IAAID,eAAeC,MAAMC,cAAcC,kBAAkB;wBACvDe,OAAOuC,IAAI,CAAC7C;wBACZ;oBACF,OAAO;wBACL4B,gBAAgB;oBAClB;gBACF;YACF,EAAE,OAAM;YACN,8BAA8B;YAChC;YACAF,mBAAmB;QACrB;QACAc;IACA,uDAAuD;IACzD,GAAG;QAACxC;QAAgBV;QAAcC;QAAiBe;KAAO;IAE1D,oDAAoD;IACpDvB,UAAU;QACR,IAAIkB,kBAAkB,QAAQ;YAC5B,iDAAiD;YACjD,0DAA0D;YAC1D6C,MAAM,mDAAmD;gBACvDC,QAAQ;gBACRC,aAAa;YACf,GACGC,IAAI,CAAC,CAACC;gBACL,kFAAkF;gBAClF,4CAA4C;gBAC5CpB,oBAAoBoB,IAAIC,MAAM,KAAK;YACrC,GACCC,KAAK,CAAC;gBACLtB,oBAAoB;YACtB;QACJ,OAAO;YACLA,oBAAoB7B,kBAAkB;QACxC;IACF,GAAG;QAACA;KAAc;IAElB,oDAAoD;IACpDlB,UAAU;QACR,IAAImB,iBAAiB,QAAQ;YAC3B,mCAAmC;YACnC4C,MAAM,2BAA2B;gBAC/BC,QAAQ;gBACRC,aAAa;YACf,GACGC,IAAI,CAAC,CAACC;gBACL,qCAAqC;gBACrClB,mBAAmBkB,IAAIC,MAAM,KAAK;YACpC,GACCC,KAAK,CAAC;gBACL,wFAAwF;gBACxFpB,mBAAmB;YACrB;QACJ,OAAO;YACLA,mBAAmB9B,iBAAiB;QACtC;IACF,GAAG;QAACA;KAAa;IAEjB,4DAA4D;IAC5DnB,UAAU;QACR,IAAIqB,yBAAyB,QAAQ;YACnC,kDAAkD;YAClD0C,MAAM,oCAAoC;gBACxCC,QAAQ;gBACRC,aAAa;YACf,GACGC,IAAI,CAAC,CAACC;gBACL,oDAAoD;gBACpDhB,2BAA2BgB,IAAIC,MAAM,KAAK;YAC5C,GACCC,KAAK,CAAC;gBACL,qEAAqE;gBACrElB,2BAA2B;YAC7B;QACJ,OAAO;YACLA,2BAA2B9B,yBAAyB;QACtD;IACF,GAAG;QAACA;KAAqB;IAEzB,eAAeiD,aAAaC,CAAY;QACtCA,EAAEC,cAAc;QAChBjC,WAAW;QACXJ,SAAS;QACTE,kBAAkB;QAClBQ,gBAAgB;QAEhB,IAAI;YACF,MAAMa,SAASF;YACf,MAAMG,SAAS,MAAMD,OAAOe,MAAM,CAAC/C,KAAK,CAAC;gBACvCA;gBACAE;YACF;YAEA,+EAA+E;YAC/E,IAAI+B,OAAOE,IAAI,IAAI,uBAAuBF,OAAOE,IAAI,IAAIF,OAAOE,IAAI,CAACa,iBAAiB,EAAE;gBACtFjD,YAAY;gBACZc,WAAW;gBACX;YACF;YAEA,IAAIoB,OAAOzB,KAAK,EAAE;gBAChBC,SAASwB,OAAOzB,KAAK,CAACyC,OAAO,IAAI;gBACjCpC,WAAW;gBACX;YACF;YAEA,IAAIoB,OAAOE,IAAI,EAAEvD,MAAM;gBACrB,MAAMA,OAAOqD,OAAOE,IAAI,CAACvD,IAAI;gBAC7B,yBAAyB;gBACzB,IAAI,CAACD,eAAeC,MAAMC,cAAcC,kBAAkB;oBACxDqC,gBAAgB;oBAChBN,WAAW;oBACX;gBACF;gBAEAhB,OAAOuC,IAAI,CAAC7C;gBACZM,OAAOqD,OAAO;YAChB;QACF,EAAE,OAAM;YACNzC,SAAS;YACTI,WAAW;QACb;IACF;IAEA,eAAesC,aAAaN,CAAY;QACtCA,EAAEC,cAAc;QAChBjC,WAAW;QACXJ,SAAS;QACTE,kBAAkB;QAElB,2BAA2B;QAC3B,IAAIT,aAAaI,iBAAiB;YAChCG,SAAS;YACTI,WAAW;YACX;QACF;QAEA,qCAAqC;QACrC,IAAIX,SAASkD,MAAM,GAAG,GAAG;YACvB3C,SAAS;YACTI,WAAW;YACX;QACF;QAEA,IAAI;YACF,MAAMmB,SAASF;YACf,MAAMG,SAAS,MAAMD,OAAOqB,MAAM,CAACrD,KAAK,CAAC;gBACvCA;gBACAE;gBACAE;gBACAkD,MAAM5D;YACR;YAEA,IAAIuC,OAAOzB,KAAK,EAAE;gBAChBC,SAASwB,OAAOzB,KAAK,CAACyC,OAAO,IAAI;gBACjCpC,WAAW;gBACX;YACF;YAEA,0EAA0E;YAC1E,IAAIoB,OAAOE,IAAI,EAAEvD,MAAM;gBACrB,kFAAkF;gBAClF,8EAA8E;gBAC9E,MAAM2E,gBAAgB,MAAMvB,OAAOE,UAAU;gBAE7C,IAAIqB,cAAcpB,IAAI,EAAEvD,MAAM;oBAC5B,MAAMA,OAAO2E,cAAcpB,IAAI,CAACvD,IAAI;oBACpC,yBAAyB;oBACzB,IAAI,CAACD,eAAeC,MAAMC,cAAcC,kBAAkB;wBACxDqC,gBAAgB;wBAChBN,WAAW;wBACX;oBACF;gBACF;gBAEAhB,OAAOuC,IAAI,CAAC7C;gBACZM,OAAOqD,OAAO;YAChB,OAAO;gBACL,wEAAwE;gBACxEvC,kBAAkB;gBAClBZ,YAAY;gBACZI,YAAY;gBACZI,mBAAmB;gBACnBM,WAAW;YACb;QACF,EAAE,OAAM;YACNJ,SAAS;YACTI,WAAW;QACb;IACF;IAEA,eAAe2C,qBAAqBX,CAAY;QAC9CA,EAAEC,cAAc;QAChBjC,WAAW;QACXJ,SAAS;QACTE,kBAAkB;QAElB,IAAI;YACF,MAAMqB,SAASF;YACf,MAAMG,SAAS,MAAMD,OAAOyB,oBAAoB,CAAC;gBAC/CzD;gBACA0D,YAAY9D,oBAAoB,GAAG+D,OAAOC,QAAQ,CAACC,MAAM,CAAC,qBAAqB,CAAC;YAClF;YAEA,IAAI5B,OAAOzB,KAAK,EAAE;gBAChBC,SAASwB,OAAOzB,KAAK,CAACyC,OAAO,IAAI;gBACjCpC,WAAW;gBACX;YACF;YAEA,8BAA8B;YAC9Bd,YAAY;YACZc,WAAW;QACb,EAAE,OAAM;YACNJ,SAAS;YACTI,WAAW;QACb;IACF;IAEA,eAAeiD,iBAAiBjB,CAAY;QAC1CA,EAAEC,cAAc;QAChBjB,eAAe;QACfpB,SAAS;QAET,IAAI;YACF,MAAMuB,SAASF;YACf,MAAMG,SAAS,MAAMD,OAAO+B,SAAS,CAACC,UAAU,CAAC;gBAAEC,MAAMvC;YAAS;YAElE,IAAIO,OAAOzB,KAAK,EAAE;gBAChBC,SAASwB,OAAOzB,KAAK,CAACyC,OAAO,IAAI;gBACjCpB,eAAe;gBACf;YACF;YAEA,kEAAkE;YAClE,6DAA6D;YAC7D,IAAIhD,cAAc;gBAChB,MAAM0E,gBAAgB,MAAMvB,OAAOE,UAAU;gBAC7C,IAAIqB,cAAcpB,IAAI,EAAEvD,MAAM;oBAC5B,MAAMA,OAAO2E,cAAcpB,IAAI,CAACvD,IAAI;oBACpC,IAAI,CAACD,eAAeC,MAAMC,cAAcC,kBAAkB;wBACxDqC,gBAAgB;wBAChBU,eAAe;wBACf;oBACF;gBACF;YACF;YAEAhC,OAAOuC,IAAI,CAAC7C;YACZM,OAAOqD,OAAO;QAChB,EAAE,OAAM;YACNzC,SAAS;YACToB,eAAe;QACjB;IACF;IAEA,SAASqC,WAAWC,OAAiB;QACnCpE,YAAYoE;QACZ1D,SAAS;QACTE,kBAAkB;QAClB,qCAAqC;QACrC,IAAIwD,YAAY,SAAS;YACvBxC,YAAY;YACZpB,mBAAmB;QACrB,OAAO,IAAI4D,YAAY,YAAY;YACjChE,YAAY;YACZI,mBAAmB;QACrB,OAAO,IAAI4D,YAAY,kBAAkB;YACvChE,YAAY;QACd;IACF;IAEA,SAASiE;QACPF,WAAW;IACb;IAEA,eAAeG;QACb,IAAI,CAACjD,kBAAkB;QAEvBL,kBAAkB;QAClBN,SAAS;QACTU,gBAAgB;QAEhB,IAAI;YACF,MAAMa,SAASF;YACf,MAAMG,SAAS,MAAMD,OAAOe,MAAM,CAACuB,OAAO;YAE1C,IAAIrC,OAAOzB,KAAK,EAAE;gBAChBC,SAASwB,OAAOzB,KAAK,CAACyC,OAAO,IAAI;gBACjClC,kBAAkB;gBAClB;YACF;YAEA,mFAAmF;YACnF,qFAAqF;YACrF,MAAMwC,gBAAgB,MAAMvB,OAAOE,UAAU;YAE7C,IAAIqB,cAAcpB,IAAI,EAAEvD,MAAM;gBAC5B,MAAMA,OAAO2E,cAAcpB,IAAI,CAACvD,IAAI;gBACpC,yBAAyB;gBACzB,IAAI,CAACD,eAAeC,MAAMC,cAAcC,kBAAkB;oBACxDqC,gBAAgB;oBAChBJ,kBAAkB;oBAClB;gBACF;gBAEAlB,OAAOuC,IAAI,CAAC7C;gBACZM,OAAOqD,OAAO;YAChB,OAAO;gBACL,wEAAwE;gBACxEzC,SAAS;gBACTM,kBAAkB;YACpB;QACF,EAAE,OAAOwD,KAAK;YACZ,IAAIA,eAAeC,SAASD,IAAInE,IAAI,KAAK,mBAAmB;gBAC1DK,SAAS;YACX,OAAO;gBACLA,SAAS8D,eAAeC,QAAQD,IAAItB,OAAO,GAAG;YAChD;YACAlC,kBAAkB;QACpB;IACF;IAEA,eAAe0D;QACb,MAAMzC,SAASF;QACf,MAAME,OAAO0C,OAAO;QACpBvD,gBAAgB;QAChBtB,OAAOqD,OAAO;IAChB;IAEA,uCAAuC;IACvC,IAAIlC,iBAAiB;QACnB,qBACE,KAAC2D;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;YACd;sBAEA,cAAA,KAACN;gBAAIC,OAAO;oBAAEM,OAAO;oBAAqBC,SAAS;gBAAI;0BAAG;;;IAKhE;IAEA,sBAAsB;IACtB,IAAIjE,cAAc;QAChB,qBACE,KAACyD;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;gBACZG,SAAS;YACX;sBAEA,cAAA,MAACT;gBACCC,OAAO;oBACLK,YAAY;oBACZG,SAAS;oBACTC,cAAc;oBACdC,WAAW;oBACXC,OAAO;oBACPC,UAAU;oBACVC,WAAW;gBACb;;kCAEA,KAACC;wBACCd,OAAO;4BACLM,OAAO;4BACPS,UAAU;4BACVC,YAAY;4BACZC,QAAQ;wBACV;kCACD;;kCAGD,KAACC;wBACClB,OAAO;4BACLM,OAAO;4BACPC,SAAS;4BACTY,cAAc;4BACdJ,UAAU;wBACZ;kCACD;;kCAID,KAACK;wBACCC,SAASxB;wBACTG,OAAO;4BACLQ,SAAS;4BACTH,YAAY;4BACZiB,QAAQ;4BACRb,cAAc;4BACdH,OAAO;4BACPS,UAAU;4BACVQ,QAAQ;wBACV;kCACD;;;;;IAMT;IAEA,+BAA+B;IAC/B,IAAIrG,aAAa,aAAa;QAC5B,qBACE,KAAC6E;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;gBACZG,SAAS;YACX;sBAEA,cAAA,MAACT;gBACCC,OAAO;oBACLK,YAAY;oBACZG,SAAS;oBACTC,cAAc;oBACdC,WAAW;oBACXC,OAAO;oBACPC,UAAU;gBACZ;;oBAECnG,sBACC,KAACsF;wBACCC,OAAO;4BACLa,WAAW;4BACXM,cAAc;wBAChB;kCAEC1G;;kCAIL,KAACqG;wBACCd,OAAO;4BACLM,OAAO;4BACPS,UAAU;4BACVC,YAAY;4BACZC,QAAQ;4BACRJ,WAAW;wBACb;kCACD;;kCAID,KAACK;wBACClB,OAAO;4BACLM,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVF,WAAW;4BACXM,cAAc;wBAChB;kCACD;;kCAID,MAACK;wBAAKC,UAAUvC;;0CACd,MAACa;gCAAIC,OAAO;oCAAEmB,cAAc;gCAA0B;;kDACpD,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLC,WAAU;wCACVC,SAAQ;wCACRC,cAAa;wCACbC,OAAOpF;wCACPqF,UAAU,CAAClE,IAAMlB,YAAYkB,EAAEmE,MAAM,CAACF,KAAK,CAACG,OAAO,CAAC,OAAO,IAAIC,KAAK,CAAC,GAAG;wCACxEC,QAAQ;wCACRC,aAAY;wCACZxC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV0B,YAAY;4CACZ5B,WAAW;4CACX6B,eAAe;4CACfC,SAAS;4CACTC,WAAW;wCACb;;;;4BAIHhH,uBACC,KAACmE;gCACCC,OAAO;oCACLM,OAAO;oCACPa,cAAc;oCACdJ,UAAU;oCACVP,SAAS;oCACTH,YAAY;oCACZI,cAAc;oCACda,QAAQ;gCACV;0CAEC1F;;0CAIL,KAACwF;gCACCU,MAAK;gCACLe,UAAU7F,eAAeF,SAAS0B,MAAM,KAAK;gCAC7CwB,OAAO;oCACLW,OAAO;oCACPH,SAAS;oCACTH,YAAY;oCACZiB,QAAQ;oCACRb,cAAc;oCACdH,OAAO;oCACPS,UAAU;oCACVC,YAAY;oCACZO,QAAQvE,eAAeF,SAAS0B,MAAM,KAAK,IAAI,gBAAgB;oCAC/D+B,SAASvD,eAAeF,SAAS0B,MAAM,KAAK,IAAI,MAAM;oCACtDsE,YAAY;gCACd;0CAEC9F,cAAc,iBAAiB;;;;kCAIpC,KAACoE;wBACCU,MAAK;wBACLT,SAAS7B;wBACTQ,OAAO;4BACLW,OAAO;4BACPoC,WAAW;4BACXvC,SAAS;4BACTH,YAAY;4BACZiB,QAAQ;4BACRhB,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVQ,QAAQ;wBACV;kCACD;;;;;IAMT;IAEA,oBAAoB;IACpB,IAAIrG,aAAa,YAAY;QAC3B,qBACE,KAAC6E;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;gBACZG,SAAS;YACX;sBAEA,cAAA,MAACT;gBACCC,OAAO;oBACLK,YAAY;oBACZG,SAAS;oBACTC,cAAc;oBACdC,WAAW;oBACXC,OAAO;oBACPC,UAAU;gBACZ;;oBAECnG,sBACC,KAACsF;wBACCC,OAAO;4BACLa,WAAW;4BACXM,cAAc;wBAChB;kCAEC1G;;kCAIL,KAACqG;wBACCd,OAAO;4BACLM,OAAO;4BACPS,UAAU;4BACVC,YAAY;4BACZC,QAAQ;4BACRJ,WAAW;wBACb;kCACD;;kCAID,MAACW;wBAAKC,UAAUlD;;0CACd,MAACwB;gCAAIC,OAAO;oCAAEmB,cAAc;gCAAc;;kDACxC,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLI,OAAO1G;wCACP2G,UAAU,CAAClE,IAAMxC,QAAQwC,EAAEmE,MAAM,CAACF,KAAK;wCACvCK,QAAQ;wCACRN,cAAa;wCACbjC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV4B,SAAS;4CACTC,WAAW;wCACb;;;;0CAIJ,MAAC7C;gCAAIC,OAAO;oCAAEmB,cAAc;gCAAc;;kDACxC,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLI,OAAO9G;wCACP+G,UAAU,CAAClE,IAAM5C,SAAS4C,EAAEmE,MAAM,CAACF,KAAK;wCACxCK,QAAQ;wCACRN,cAAa;wCACbjC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV4B,SAAS;4CACTC,WAAW;wCACb;;;;0CAIJ,MAAC7C;gCAAIC,OAAO;oCAAEmB,cAAc;gCAAc;;kDACxC,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLI,OAAO5G;wCACP6G,UAAU,CAAClE,IAAM1C,YAAY0C,EAAEmE,MAAM,CAACF,KAAK;wCAC3CK,QAAQ;wCACRN,cAAa;wCACbjC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV4B,SAAS;4CACTC,WAAW;wCACb;;;;0CAIJ,MAAC7C;gCAAIC,OAAO;oCAAEmB,cAAc;gCAA0B;;kDACpD,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLI,OAAOxG;wCACPyG,UAAU,CAAClE,IAAMtC,mBAAmBsC,EAAEmE,MAAM,CAACF,KAAK;wCAClDK,QAAQ;wCACRN,cAAa;wCACbjC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV4B,SAAS;4CACTC,WAAW;wCACb;;;;4BAIHhH,uBACC,KAACmE;gCACCC,OAAO;oCACLM,OAAO;oCACPa,cAAc;oCACdJ,UAAU;oCACVP,SAAS;oCACTH,YAAY;oCACZI,cAAc;oCACda,QAAQ;gCACV;0CAEC1F;;0CAIL,KAACwF;gCACCU,MAAK;gCACLe,UAAU7G;gCACVgE,OAAO;oCACLW,OAAO;oCACPH,SAAS;oCACTH,YAAY;oCACZiB,QAAQ;oCACRb,cAAc;oCACdH,OAAO;oCACPS,UAAU;oCACVC,YAAY;oCACZO,QAAQvF,UAAU,gBAAgB;oCAClCuE,SAASvE,UAAU,MAAM;oCACzB8G,YAAY;gCACd;0CAEC9G,UAAU,wBAAwB;;;;kCAIvC,MAAC+D;wBACCC,OAAO;4BACL+C,WAAW;4BACXlC,WAAW;4BACXE,UAAU;4BACVT,OAAO;4BACPC,SAAS;wBACX;;4BACD;4BAC0B;0CACzB,KAACa;gCACCU,MAAK;gCACLT,SAAS7B;gCACTQ,OAAO;oCACLK,YAAY;oCACZiB,QAAQ;oCACRhB,OAAO;oCACPiB,QAAQ;oCACRR,UAAU;oCACViC,gBAAgB;oCAChBxC,SAAS;gCACX;0CACD;;;;;;;IAOX;IAEA,uBAAuB;IACvB,IAAItF,aAAa,kBAAkB;QACjC,qBACE,KAAC6E;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;gBACZG,SAAS;YACX;sBAEA,cAAA,MAACT;gBACCC,OAAO;oBACLK,YAAY;oBACZG,SAAS;oBACTC,cAAc;oBACdC,WAAW;oBACXC,OAAO;oBACPC,UAAU;gBACZ;;oBAECnG,sBACC,KAACsF;wBACCC,OAAO;4BACLa,WAAW;4BACXM,cAAc;wBAChB;kCAEC1G;;kCAIL,KAACqG;wBACCd,OAAO;4BACLM,OAAO;4BACPS,UAAU;4BACVC,YAAY;4BACZC,QAAQ;4BACRJ,WAAW;wBACb;kCACD;;kCAID,KAACK;wBACClB,OAAO;4BACLM,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVF,WAAW;4BACXM,cAAc;wBAChB;kCACD;;kCAID,MAACK;wBAAKC,UAAU7C;;0CACd,MAACmB;gCAAIC,OAAO;oCAAEmB,cAAc;gCAA0B;;kDACpD,KAACO;wCACCC,SAAQ;wCACR3B,OAAO;4CACLE,SAAS;4CACTI,OAAO;4CACPa,cAAc;4CACdJ,UAAU;4CACVC,YAAY;wCACd;kDACD;;kDAGD,KAACY;wCACCC,IAAG;wCACHC,MAAK;wCACLI,OAAO9G;wCACP+G,UAAU,CAAClE,IAAM5C,SAAS4C,EAAEmE,MAAM,CAACF,KAAK;wCACxCK,QAAQ;wCACRN,cAAa;wCACbjC,OAAO;4CACLW,OAAO;4CACPH,SAAS;4CACTH,YAAY;4CACZiB,QAAQ;4CACRb,cAAc;4CACdH,OAAO;4CACPS,UAAU;4CACV4B,SAAS;4CACTC,WAAW;wCACb;;;;4BAIHhH,uBACC,KAACmE;gCACCC,OAAO;oCACLM,OAAO;oCACPa,cAAc;oCACdJ,UAAU;oCACVP,SAAS;oCACTH,YAAY;oCACZI,cAAc;oCACda,QAAQ;gCACV;0CAEC1F;;0CAIL,KAACwF;gCACCU,MAAK;gCACLe,UAAU7G;gCACVgE,OAAO;oCACLW,OAAO;oCACPH,SAAS;oCACTH,YAAY;oCACZiB,QAAQ;oCACRb,cAAc;oCACdH,OAAO;oCACPS,UAAU;oCACVC,YAAY;oCACZO,QAAQvF,UAAU,gBAAgB;oCAClCuE,SAASvE,UAAU,MAAM;oCACzB8G,YAAY;gCACd;0CAEC9G,UAAU,eAAe;;;;kCAI9B,KAACoF;wBACCU,MAAK;wBACLT,SAAS7B;wBACTQ,OAAO;4BACLW,OAAO;4BACPoC,WAAW;4BACXvC,SAAS;4BACTH,YAAY;4BACZiB,QAAQ;4BACRhB,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVQ,QAAQ;wBACV;kCACD;;;;;IAMT;IAEA,oCAAoC;IACpC,IAAIrG,aAAa,aAAa;QAC5B,qBACE,KAAC6E;YACCC,OAAO;gBACLC,WAAW;gBACXC,SAAS;gBACTC,YAAY;gBACZC,gBAAgB;gBAChBC,YAAY;gBACZG,SAAS;YACX;sBAEA,cAAA,MAACT;gBACCC,OAAO;oBACLK,YAAY;oBACZG,SAAS;oBACTC,cAAc;oBACdC,WAAW;oBACXC,OAAO;oBACPC,UAAU;oBACVC,WAAW;gBACb;;oBAECpG,sBACC,KAACsF;wBACCC,OAAO;4BACLmB,cAAc;wBAChB;kCAEC1G;;kCAIL,KAACsF;wBACCC,OAAO;4BACLW,OAAO;4BACPsC,QAAQ;4BACR5C,YAAY;4BACZI,cAAc;4BACdP,SAAS;4BACTC,YAAY;4BACZC,gBAAgB;4BAChBa,QAAQ;4BACRF,UAAU;wBACZ;kCACD;;kCAID,KAACD;wBACCd,OAAO;4BACLM,OAAO;4BACPS,UAAU;4BACVC,YAAY;4BACZC,QAAQ;wBACV;kCACD;;kCAID,MAACC;wBACClB,OAAO;4BACLM,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVI,cAAc;wBAChB;;4BACD;0CAC0C,KAAC+B;0CAAQ9H;;;;kCAGpD,KAAC8F;wBACClB,OAAO;4BACLM,OAAO;4BACPC,SAAS;4BACTQ,UAAU;4BACVI,cAAc;wBAChB;kCACD;;kCAID,KAACC;wBACCU,MAAK;wBACLT,SAAS7B;wBACTQ,OAAO;4BACLQ,SAAS;4BACTH,YAAY;4BACZiB,QAAQ;4BACRb,cAAc;4BACdH,OAAO;4BACPS,UAAU;4BACVQ,QAAQ;wBACV;kCACD;;;;;IAMT;IAEA,kBAAkB;IAClB,qBACE,KAACxB;QACCC,OAAO;YACLC,WAAW;YACXC,SAAS;YACTC,YAAY;YACZC,gBAAgB;YAChBC,YAAY;YACZG,SAAS;QACX;kBAEA,cAAA,MAACT;YACCC,OAAO;gBACLK,YAAY;gBACZG,SAAS;gBACTC,cAAc;gBACdC,WAAW;gBACXC,OAAO;gBACPC,UAAU;YACZ;;gBAECnG,sBACC,KAACsF;oBACCC,OAAO;wBACLa,WAAW;wBACXM,cAAc;oBAChB;8BAEC1G;;8BAIL,KAACqG;oBACCd,OAAO;wBACLM,OAAO;wBACPS,UAAU;wBACVC,YAAY;wBACZH,WAAW;wBACXI,QAAQ;oBACV;8BAECvG;;gBAGFoB,gCACC,KAACiE;oBACCC,OAAO;wBACLM,OAAO;wBACPa,cAAc;wBACdJ,UAAU;wBACVP,SAAS;wBACTH,YAAY;wBACZI,cAAc;wBACda,QAAQ;oBACV;8BAECxF;;8BAIL,MAAC0F;oBAAKC,UAAUzD;;sCACd,MAAC+B;4BAAIC,OAAO;gCAAEmB,cAAc;4BAAc;;8CACxC,KAACO;oCACCC,SAAQ;oCACR3B,OAAO;wCACLE,SAAS;wCACTI,OAAO;wCACPa,cAAc;wCACdJ,UAAU;wCACVC,YAAY;oCACd;8CACD;;8CAGD,KAACY;oCACCC,IAAG;oCACHC,MAAK;oCACLI,OAAO9G;oCACP+G,UAAU,CAAClE,IAAM5C,SAAS4C,EAAEmE,MAAM,CAACF,KAAK;oCACxCK,QAAQ;oCACRN,cAAa;oCACbjC,OAAO;wCACLW,OAAO;wCACPH,SAAS;wCACTH,YAAY;wCACZiB,QAAQ;wCACRb,cAAc;wCACdH,OAAO;wCACPS,UAAU;wCACV4B,SAAS;wCACTC,WAAW;oCACb;;;;sCAIJ,MAAC7C;4BAAIC,OAAO;gCAAEmB,cAAc;4BAAc;;8CACxC,KAACO;oCACCC,SAAQ;oCACR3B,OAAO;wCACLE,SAAS;wCACTI,OAAO;wCACPa,cAAc;wCACdJ,UAAU;wCACVC,YAAY;oCACd;8CACD;;8CAGD,KAACY;oCACCC,IAAG;oCACHC,MAAK;oCACLI,OAAO5G;oCACP6G,UAAU,CAAClE,IAAM1C,YAAY0C,EAAEmE,MAAM,CAACF,KAAK;oCAC3CK,QAAQ;oCACRN,cAAa;oCACbjC,OAAO;wCACLW,OAAO;wCACPH,SAAS;wCACTH,YAAY;wCACZiB,QAAQ;wCACRb,cAAc;wCACdH,OAAO;wCACPS,UAAU;wCACV4B,SAAS;wCACTC,WAAW;oCACb;;;;wBAIHhG,yCACC,KAACmD;4BACCC,OAAO;gCACLmB,cAAc;gCACdN,WAAW;4BACb;sCAEA,cAAA,KAACO;gCACCU,MAAK;gCACLT,SAAS,IAAM/B,WAAW;gCAC1BU,OAAO;oCACLK,YAAY;oCACZiB,QAAQ;oCACRhB,OAAO;oCACPC,SAAS;oCACTgB,QAAQ;oCACRR,UAAU;oCACVP,SAAS;oCACTwC,gBAAgB;gCAClB;0CACD;;;wBAMJpH,uBACC,KAACmE;4BACCC,OAAO;gCACLM,OAAO;gCACPa,cAAc;gCACdJ,UAAU;gCACVP,SAAS;gCACTH,YAAY;gCACZI,cAAc;gCACda,QAAQ;4BACV;sCAEC1F;;sCAIL,KAACwF;4BACCU,MAAK;4BACLe,UAAU7G,WAAWE;4BACrB8D,OAAO;gCACLW,OAAO;gCACPH,SAAS;gCACTH,YAAY;gCACZiB,QAAQ;gCACRb,cAAc;gCACdH,OAAO;gCACPS,UAAU;gCACVC,YAAY;gCACZO,QAAQvF,WAAWE,iBAAiB,gBAAgB;gCACpDqE,SAASvE,WAAWE,iBAAiB,MAAM;gCAC3C4G,YAAY;4BACd;sCAEC9G,UAAU,kBAAkB;;;;gBAIhCQ,kCACC;;sCACE,MAACuD;4BACCC,OAAO;gCACLE,SAAS;gCACTC,YAAY;gCACZc,QAAQ;gCACRkC,KAAK;4BACP;;8CAEA,KAACpD;oCACCC,OAAO;wCACLoD,MAAM;wCACNH,QAAQ;wCACR5C,YAAY;oCACd;;8CAEF,KAACgD;oCACCrD,OAAO;wCACLM,OAAO;wCACPC,SAAS;wCACTQ,UAAU;oCACZ;8CACD;;8CAGD,KAAChB;oCACCC,OAAO;wCACLoD,MAAM;wCACNH,QAAQ;wCACR5C,YAAY;oCACd;;;;sCAIJ,MAACe;4BACCU,MAAK;4BACLT,SAAS5B;4BACToD,UAAU7G,WAAWE;4BACrB8D,OAAO;gCACLW,OAAO;gCACPH,SAAS;gCACTH,YAAY;gCACZiB,QAAQ;gCACRb,cAAc;gCACdH,OAAO;gCACPS,UAAU;gCACVC,YAAY;gCACZO,QAAQvF,WAAWE,iBAAiB,gBAAgB;gCACpDqE,SAASvE,WAAWE,iBAAiB,MAAM;gCAC3C4G,YAAY;gCACZ5C,SAAS;gCACTC,YAAY;gCACZC,gBAAgB;gCAChB+C,KAAK;4BACP;;8CAEA,KAACE;oCAAKrD,OAAO;wCAAEe,UAAU;oCAAO;8CAAG;;gCAClC7E,iBAAiB,sBAAsB;;;;;gBAK7CQ,iCACC,MAACqD;oBACCC,OAAO;wBACL+C,WAAW;wBACXlC,WAAW;wBACXE,UAAU;wBACVT,OAAO;wBACPC,SAAS;oBACX;;wBACD;wBAC6B;sCAC5B,KAACa;4BACCU,MAAK;4BACLT,SAAS,IAAM/B,WAAW;4BAC1BU,OAAO;gCACLK,YAAY;gCACZiB,QAAQ;gCACRhB,OAAO;gCACPiB,QAAQ;gCACRR,UAAU;gCACViC,gBAAgB;gCAChBxC,SAAS;4BACX;sCACD;;;;;;;AAQb;AAEA,eAAelG,UAAS"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LoginViewWrapper.d.ts","sourceRoot":"","sources":["../../src/components/LoginViewWrapper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAK7C,KAAK,qBAAqB,GAAG,cAAc,CAAA;AAE3C;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,EAAE,cAAc,EAAE,EAAE,qBAAqB,wCAoB/E;AAED,eAAe,gBAAgB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/LoginViewWrapper.tsx"],"sourcesContent":["import type { AdminViewProps } from 'payload'\nimport { LoginView, type LoginViewProps } from './LoginView.js'\n\ntype LoginConfig = Omit<LoginViewProps, 'authClient' | 'logo'>\n\ntype LoginViewWrapperProps = AdminViewProps\n\n/**\n * Server component wrapper for LoginView.\n * Reads login configuration from payload.config.custom.betterAuth.login\n * and passes it as props to the client LoginView component.\n */\nexport async function LoginViewWrapper({ initPageResult }: LoginViewWrapperProps) {\n const { req } = initPageResult\n const { payload } = req\n\n // Read login config from payload.config.custom.betterAuth.login\n const loginConfig = (payload.config.custom?.betterAuth?.login ?? {}) as LoginConfig\n\n return (\n <LoginView\n afterLoginPath={loginConfig.afterLoginPath}\n requiredRole={loginConfig.requiredRole}\n requireAllRoles={loginConfig.requireAllRoles}\n enablePasskey={loginConfig.enablePasskey}\n enableSignUp={loginConfig.enableSignUp}\n defaultSignUpRole={loginConfig.defaultSignUpRole}\n enableForgotPassword={loginConfig.enableForgotPassword}\n resetPasswordUrl={loginConfig.resetPasswordUrl}\n title={loginConfig.title}\n />\n )\n}\n\nexport default LoginViewWrapper\n"],"names":["LoginView","LoginViewWrapper","initPageResult","req","payload","loginConfig","config","custom","betterAuth","login","afterLoginPath","requiredRole","requireAllRoles","enablePasskey","enableSignUp","defaultSignUpRole","enableForgotPassword","resetPasswordUrl","title"],"mappings":";AACA,SAASA,SAAS,QAA6B,iBAAgB;AAM/D;;;;CAIC,GACD,OAAO,eAAeC,iBAAiB,EAAEC,cAAc,EAAyB;IAC9E,MAAM,EAAEC,GAAG,EAAE,GAAGD;IAChB,MAAM,EAAEE,OAAO,EAAE,GAAGD;IAEpB,gEAAgE;IAChE,MAAME,cAAeD,QAAQE,MAAM,CAACC,MAAM,EAAEC,YAAYC,SAAS,CAAC;IAElE,qBACE,KAACT;QACCU,gBAAgBL,YAAYK,cAAc;QAC1CC,cAAcN,YAAYM,YAAY;QACtCC,iBAAiBP,YAAYO,eAAe;QAC5CC,eAAeR,YAAYQ,aAAa;QACxCC,cAAcT,YAAYS,YAAY;QACtCC,mBAAmBV,YAAYU,iBAAiB;QAChDC,sBAAsBX,YAAYW,oBAAoB;QACtDC,kBAAkBZ,YAAYY,gBAAgB;QAC9CC,OAAOb,YAAYa,KAAK;;AAG9B;AAEA,eAAejB,iBAAgB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LogoutButton.d.ts","sourceRoot":"","sources":["../../src/components/LogoutButton.tsx"],"names":[],"mappings":"AAKA;;;GAGG;AACH,wBAAgB,YAAY,gCA8C3B;AAED,eAAe,YAAY,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/LogoutButton.tsx"],"sourcesContent":["'use client'\n\nimport { useState } from 'react'\nimport { useRouter } from 'next/navigation.js'\n\n/**\n * Logout button component styled to match Payload's admin nav.\n * Uses Payload's CSS classes and variables for native theme integration.\n */\nexport function LogoutButton() {\n const router = useRouter()\n const [isLoading, setIsLoading] = useState(false)\n\n async function handleLogout() {\n if (isLoading) return\n setIsLoading(true)\n\n try {\n await fetch('/api/auth/sign-out', {\n method: 'POST',\n credentials: 'include',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({}),\n })\n\n router.push('/admin/login')\n } catch (error) {\n console.error('[better-auth] Logout error:', error)\n setIsLoading(false)\n }\n }\n\n return (\n <button\n onClick={handleLogout}\n disabled={isLoading}\n type=\"button\"\n className=\"nav__link\"\n style={{\n background: 'none',\n border: 'none',\n cursor: isLoading ? 'not-allowed' : 'pointer',\n opacity: isLoading ? 0.7 : 1,\n width: '100%',\n textAlign: 'left',\n padding: 0,\n }}\n >\n <span className=\"nav__link-label\">\n {isLoading ? 'Logging out...' : 'Log out'}\n </span>\n </button>\n )\n}\n\nexport default LogoutButton\n"],"names":["useState","useRouter","LogoutButton","router","isLoading","setIsLoading","handleLogout","fetch","method","credentials","headers","body","JSON","stringify","push","error","console","button","onClick","disabled","type","className","style","background","border","cursor","opacity","width","textAlign","padding","span"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,QAAQ,QAAO;AAChC,SAASC,SAAS,QAAQ,qBAAoB;AAE9C;;;CAGC,GACD,OAAO,SAASC;IACd,MAAMC,SAASF;IACf,MAAM,CAACG,WAAWC,aAAa,GAAGL,SAAS;IAE3C,eAAeM;QACb,IAAIF,WAAW;QACfC,aAAa;QAEb,IAAI;YACF,MAAME,MAAM,sBAAsB;gBAChCC,QAAQ;gBACRC,aAAa;gBACbC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,MAAMC,KAAKC,SAAS,CAAC,CAAC;YACxB;YAEAV,OAAOW,IAAI,CAAC;QACd,EAAE,OAAOC,OAAO;YACdC,QAAQD,KAAK,CAAC,+BAA+BA;YAC7CV,aAAa;QACf;IACF;IAEA,qBACE,KAACY;QACCC,SAASZ;QACTa,UAAUf;QACVgB,MAAK;QACLC,WAAU;QACVC,OAAO;YACLC,YAAY;YACZC,QAAQ;YACRC,QAAQrB,YAAY,gBAAgB;YACpCsB,SAAStB,YAAY,MAAM;YAC3BuB,OAAO;YACPC,WAAW;YACXC,SAAS;QACX;kBAEA,cAAA,KAACC;YAAKT,WAAU;sBACbjB,YAAY,mBAAmB;;;AAIxC;AAEA,eAAeF,aAAY"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PasskeyRegisterButton.d.ts","sourceRoot":"","sources":["../../src/components/PasskeyRegisterButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,SAAS,CACV,GAAG;IACF,0CAA0C;IAC1C,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC5D,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,UAAU,EAAE,cAAc,EAC1B,WAAW,EACX,SAAS,EACT,OAAO,EACP,KAAqB,EACrB,YAA+B,EAC/B,QAAQ,EACR,QAAQ,EACR,GAAG,WAAW,EACf,EAAE,0BAA0B,+BA0C5B;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/PasskeyRegisterButton.tsx"],"sourcesContent":["'use client'\n\nimport { useState, type ButtonHTMLAttributes } from 'react'\nimport {\n createPayloadAuthClient,\n type PayloadAuthClient,\n} from '../exports/client.js'\n\nexport type PasskeyRegisterButtonProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n 'onClick'\n> & {\n /** Optional pre-configured auth client */\n authClient?: PayloadAuthClient\n /** Optional name for the passkey */\n passkeyName?: string\n /** Callback when registration succeeds */\n onSuccess?: (passkey: { id: string; name?: string }) => void\n /** Callback when registration fails */\n onError?: (error: string) => void\n /** Button text when idle. Default: 'Add Passkey' */\n label?: string\n /** Button text when loading. Default: 'Registering...' */\n loadingLabel?: string\n}\n\n/**\n * Standalone passkey registration button component.\n * Handles the WebAuthn registration flow with Better Auth.\n *\n * @example\n * ```tsx\n * import { PasskeyRegisterButton } from '@delmaredigital/payload-better-auth/components'\n *\n * function SecuritySettings() {\n * return (\n * <PasskeyRegisterButton\n * passkeyName=\"My MacBook\"\n * onSuccess={(passkey) => {\n * console.log('Passkey registered:', passkey.id)\n * refetchPasskeys()\n * }}\n * onError={(error) => {\n * setError(error)\n * }}\n * />\n * )\n * }\n * ```\n */\nexport function PasskeyRegisterButton({\n authClient: providedClient,\n passkeyName,\n onSuccess,\n onError,\n label = 'Add Passkey',\n loadingLabel = 'Registering...',\n disabled,\n children,\n ...buttonProps\n}: PasskeyRegisterButtonProps) {\n const [loading, setLoading] = useState(false)\n\n async function handleClick() {\n setLoading(true)\n\n try {\n const client = providedClient ?? createPayloadAuthClient()\n const result = await client.passkey.addPasskey({\n name: passkeyName,\n })\n\n if (result.error) {\n onError?.(result.error.message ?? 'Passkey registration failed')\n } else if (result.data) {\n onSuccess?.({ id: result.data.id, name: passkeyName })\n }\n } catch (err) {\n if (err instanceof Error && err.name === 'NotAllowedError') {\n onError?.('Passkey registration was cancelled or not allowed')\n } else if (err instanceof Error && err.name === 'InvalidStateError') {\n onError?.('This passkey is already registered')\n } else {\n onError?.(\n err instanceof Error ? err.message : 'Passkey registration failed'\n )\n }\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading}\n {...buttonProps}\n >\n {children ?? (loading ? loadingLabel : label)}\n </button>\n )\n}\n\nexport default PasskeyRegisterButton\n"],"names":["useState","createPayloadAuthClient","PasskeyRegisterButton","authClient","providedClient","passkeyName","onSuccess","onError","label","loadingLabel","disabled","children","buttonProps","loading","setLoading","handleClick","client","result","passkey","addPasskey","name","error","message","data","id","err","Error","button","type","onClick"],"mappings":"AAAA;;AAEA,SAASA,QAAQ,QAAmC,QAAO;AAC3D,SACEC,uBAAuB,QAElB,uBAAsB;AAoB7B;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GACD,OAAO,SAASC,sBAAsB,EACpCC,YAAYC,cAAc,EAC1BC,WAAW,EACXC,SAAS,EACTC,OAAO,EACPC,QAAQ,aAAa,EACrBC,eAAe,gBAAgB,EAC/BC,QAAQ,EACRC,QAAQ,EACR,GAAGC,aACwB;IAC3B,MAAM,CAACC,SAASC,WAAW,GAAGd,SAAS;IAEvC,eAAee;QACbD,WAAW;QAEX,IAAI;YACF,MAAME,SAASZ,kBAAkBH;YACjC,MAAMgB,SAAS,MAAMD,OAAOE,OAAO,CAACC,UAAU,CAAC;gBAC7CC,MAAMf;YACR;YAEA,IAAIY,OAAOI,KAAK,EAAE;gBAChBd,UAAUU,OAAOI,KAAK,CAACC,OAAO,IAAI;YACpC,OAAO,IAAIL,OAAOM,IAAI,EAAE;gBACtBjB,YAAY;oBAAEkB,IAAIP,OAAOM,IAAI,CAACC,EAAE;oBAAEJ,MAAMf;gBAAY;YACtD;QACF,EAAE,OAAOoB,KAAK;YACZ,IAAIA,eAAeC,SAASD,IAAIL,IAAI,KAAK,mBAAmB;gBAC1Db,UAAU;YACZ,OAAO,IAAIkB,eAAeC,SAASD,IAAIL,IAAI,KAAK,qBAAqB;gBACnEb,UAAU;YACZ,OAAO;gBACLA,UACEkB,eAAeC,QAAQD,IAAIH,OAAO,GAAG;YAEzC;QACF,SAAU;YACRR,WAAW;QACb;IACF;IAEA,qBACE,KAACa;QACCC,MAAK;QACLC,SAASd;QACTL,UAAUA,YAAYG;QACrB,GAAGD,WAAW;kBAEdD,YAAaE,CAAAA,UAAUJ,eAAeD,KAAI;;AAGjD;AAEA,eAAeN,sBAAqB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PasskeySignInButton.d.ts","sourceRoot":"","sources":["../../src/components/PasskeySignInButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,sBAAsB,CAAA;AAE7B,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,SAAS,CACV,GAAG;IACF,0CAA0C;IAC1C,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,qCAAqC;IACrC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IACxE,kCAAkC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,UAAU,EAAE,cAAc,EAC1B,SAAS,EACT,OAAO,EACP,KAA8B,EAC9B,YAAkC,EAClC,QAAQ,EACR,QAAQ,EACR,GAAG,WAAW,EACf,EAAE,wBAAwB,+BAsC1B;AAED,eAAe,mBAAmB,CAAA"}
|