@@ -101,22 +101,129 @@ auth: {
101101}
102102```
103103
104+ ## Boolean Shorthand Pattern
105+
106+ For simple enable/disable scenarios, support ` boolean | object ` configuration:
107+
108+ ### Rules
109+
110+ 1 . ** ` true ` ** : Feature is ** enabled** with all default values
111+ 2 . ** ` false ` ** : Feature is ** disabled**
112+ 3 . ** ` {} ` ** : Feature is ** enabled** with all default values (same as ` true ` )
113+ 4 . ** ` { option: value } ` ** : Feature is ** enabled** with custom settings
114+ 5 . ** ` { enabled: false } ` ** : Feature is ** disabled** (allows pre-configuration)
115+ 6 . ** ` undefined ` ** : Feature is ** disabled** (default)
116+
117+ ### Benefits
118+
119+ - ** Concise** : ` jwt: true ` instead of ` jwt: {} `
120+ - ** Readable** : Clear intent at a glance
121+ - ** Flexible** : Can still use objects for customization
122+
123+ ### Implementation Example
124+
125+ ``` typescript
126+ // Interface definition
127+ interface IBetterAuth {
128+ jwt? : boolean | IBetterAuthJwtConfig ;
129+ twoFactor? : boolean | IBetterAuthTwoFactorConfig ;
130+ passkey? : boolean | IBetterAuthPasskeyConfig ;
131+ }
132+
133+ interface IBetterAuthJwtConfig {
134+ enabled? : boolean ;
135+ expiresIn? : string ;
136+ }
137+
138+ // Helper functions
139+ function isPluginEnabled<T extends { enabled? : boolean }>(
140+ config : boolean | T | undefined
141+ ): boolean {
142+ if (config === undefined ) return false ;
143+ if (typeof config === ' boolean' ) return config ;
144+ return config .enabled !== false ;
145+ }
146+
147+ function getPluginConfig<T extends { enabled? : boolean }>(
148+ config : boolean | T | undefined
149+ ): T | undefined {
150+ if (! isPluginEnabled (config )) return undefined ;
151+ if (typeof config === ' boolean' ) return {} as T ;
152+ return config ;
153+ }
154+
155+ // Usage in build logic
156+ const jwtConfig = getPluginConfig (config .jwt );
157+ if (jwtConfig ) {
158+ plugins .push (jwt ({ expirationTime: jwtConfig .expiresIn || ' 15m' }));
159+ }
160+ ```
161+
162+ ### Usage Examples
163+
164+ ``` typescript
165+ // config.env.ts
166+
167+ betterAuth : {
168+ // Boolean shorthand - enable with defaults
169+ jwt : true ,
170+ twoFactor : true ,
171+ passkey : true ,
172+ }
173+
174+ // Equivalent to:
175+ betterAuth : {
176+ jwt : {},
177+ twoFactor : {},
178+ passkey : {},
179+ }
180+
181+ // Mixed - some with defaults, some customized
182+ betterAuth : {
183+ jwt : true , // Enable with defaults
184+ twoFactor : { appName : ' My App' }, // Enable with custom settings
185+ passkey : false , // Explicitly disabled
186+ }
187+
188+ // Pre-configured but disabled
189+ betterAuth : {
190+ jwt : { enabled : false , expiresIn : ' 1h' }, // Ready to enable later
191+ }
192+ ```
193+
104194## Applied Features
105195
106196This pattern is currently applied to:
107197
108- | Feature | Config Path | Default Values |
109- | ---------| -------------| ----------------|
110- | Legacy Auth Rate Limiting | ` auth.rateLimit ` | ` max: 10 ` , ` windowSeconds: 60 ` |
111- | BetterAuth Rate Limiting | ` betterAuth.rateLimit ` | ` max: 10 ` , ` windowSeconds: 60 ` |
198+ | Feature | Config Path | Pattern | Default Values |
199+ | ---------| -------------| ---------| ----------------|
200+ | Legacy Auth Rate Limiting | ` auth.rateLimit ` | Presence Implies Enabled | ` max: 10 ` , ` windowSeconds: 60 ` |
201+ | BetterAuth Rate Limiting | ` betterAuth.rateLimit ` | Presence Implies Enabled | ` max: 10 ` , ` windowSeconds: 60 ` |
202+ | BetterAuth JWT Plugin | ` betterAuth.jwt ` | Boolean Shorthand | ` expiresIn: '15m' ` |
203+ | BetterAuth 2FA Plugin | ` betterAuth.twoFactor ` | Boolean Shorthand | ` appName: 'Nest Server' ` |
204+ | BetterAuth Passkey Plugin | ` betterAuth.passkey ` | Boolean Shorthand | ` rpName: 'Nest Server' ` |
112205
113206## Checklist for New Configurable Features
114207
115208When adding a new configurable feature:
116209
210+ ### For "Presence Implies Enabled" Pattern:
211+
117212- [ ] Define interface with ` enabled?: boolean ` as optional property
118213- [ ] Set ` enabled: false ` in DEFAULT_CONFIG
119214- [ ] Implement "presence implies enabled" logic in configure method
120215- [ ] Document all default values in interface JSDoc
121216- [ ] Add tests for: undefined config, empty object, partial config, explicit disable
217+
218+ ### For "Boolean Shorthand" Pattern:
219+
220+ - [ ] Define separate interface for config options (e.g., ` IBetterAuthJwtConfig ` )
221+ - [ ] Use union type: ` property?: boolean | IPropertyConfig `
222+ - [ ] Implement ` isPluginEnabled() ` helper for boolean/object handling
223+ - [ ] Implement ` getPluginConfig() ` helper to normalize to object
224+ - [ ] Add tests for: ` true ` , ` false ` , ` {} ` , ` { option: value } ` , ` { enabled: false } ` , ` undefined `
225+
226+ ### For Both Patterns:
227+
122228- [ ] Update this document with the new feature
229+ - [ ] Export new interfaces in ` src/index.ts ` (if needed)
0 commit comments