better-auth-lead 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marc Stammerjohann, Gary Großgarten
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/client.d.mts CHANGED
@@ -1,8 +1,7 @@
1
- import { r as LeadOptions, t as lead } from "./index-CypeYbkn.mjs";
1
+ import { r as LeadOptions, t as lead } from "./index-BYw4ZSS5.mjs";
2
2
  import { StandardSchemaV1 } from "better-auth";
3
-
4
3
  //#region src/client.d.ts
5
- declare const leadClient: <TMetadata = undefined>() => {
4
+ export declare const leadClient: <TMetadata = undefined>() => {
6
5
  id: "lead";
7
6
  $InferServerPlugin: ReturnType<typeof lead<[TMetadata] extends [undefined] ? LeadOptions : LeadOptions & {
8
7
  metadata: {
@@ -11,5 +10,4 @@ declare const leadClient: <TMetadata = undefined>() => {
11
10
  }>>;
12
11
  };
13
12
  //#endregion
14
- export { leadClient };
15
13
  //# sourceMappingURL=client.d.mts.map
@@ -1,5 +1,4 @@
1
1
  import { InferOptionSchema, StandardSchemaV1 } from "better-auth";
2
-
3
2
  //#region src/schema.d.ts
4
3
  declare const lead$1: {
5
4
  lead: {
@@ -65,7 +64,6 @@ interface LeadOptions {
65
64
  * @param token the confirmation token
66
65
  * @param unsubscribeUrl the one-click unsubscribe URL (RFC 8058) to include in List-Unsubscribe headers
67
66
  */
68
-
69
67
  data: {
70
68
  lead: Lead;
71
69
  email: string;
@@ -77,7 +75,6 @@ interface LeadOptions {
77
75
  /**
78
76
  * @param lead the lead that confirmed their subscription
79
77
  */
80
-
81
78
  data: {
82
79
  lead: Lead;
83
80
  }, request?: Request) => Promise<void>;
@@ -207,42 +204,49 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
207
204
  };
208
205
  };
209
206
  endpoints: {
210
- listLeads?: import("better-auth").StrictEndpoint<"/lead/list-leads", {
207
+ subscribe: import("better-auth").StrictEndpoint<"/lead/subscribe", {
208
+ method: "POST";
209
+ body: import("zod").ZodObject<{
210
+ email: import("zod").ZodOptional<import("zod").ZodString>;
211
+ metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
212
+ }, import("zod/v4/core").$strip>;
213
+ metadata: {
214
+ $Infer: {
215
+ body: {
216
+ email?: string;
217
+ metadata?: (O extends {
218
+ metadata: {
219
+ validationSchema: import("better-auth").StandardSchemaV1<unknown, infer Out>;
220
+ };
221
+ } ? Out : Record<string, any>) | undefined;
222
+ };
223
+ };
224
+ };
225
+ }, {
226
+ status: boolean;
227
+ }>;
228
+ verify: import("better-auth").StrictEndpoint<"/lead/verify", {
211
229
  method: "GET";
212
230
  query: import("zod").ZodObject<{
213
- searchValue: import("zod").ZodOptional<import("zod").ZodString>;
214
- searchField: import("zod").ZodOptional<import("zod").ZodEnum<{
215
- email: "email";
216
- }>>;
217
- searchOperator: import("zod").ZodOptional<import("zod").ZodEnum<{
218
- contains: "contains";
219
- starts_with: "starts_with";
220
- ends_with: "ends_with";
221
- }>>;
222
- limit: import("zod").ZodOptional<import("zod").ZodCoercedNumber<unknown>>;
223
- offset: import("zod").ZodOptional<import("zod").ZodCoercedNumber<unknown>>;
224
- sortBy: import("zod").ZodOptional<import("zod").ZodString>;
225
- sortDirection: import("zod").ZodOptional<import("zod").ZodEnum<{
226
- asc: "asc";
227
- desc: "desc";
228
- }>>;
229
- filterField: import("zod").ZodOptional<import("zod").ZodString>;
230
- filterValue: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodNumber]>, import("zod").ZodBoolean]>, import("zod").ZodArray<import("zod").ZodString>]>, import("zod").ZodArray<import("zod").ZodNumber>]>>;
231
- filterOperator: import("zod").ZodOptional<import("zod").ZodEnum<{
232
- in: "in";
233
- contains: "contains";
234
- starts_with: "starts_with";
235
- ends_with: "ends_with";
236
- eq: "eq";
237
- ne: "ne";
238
- lt: "lt";
239
- lte: "lte";
240
- gt: "gt";
241
- gte: "gte";
242
- not_in: "not_in";
243
- }>>;
244
- }, import("better-auth").$strip>;
245
- use: ((inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
231
+ token: import("zod").ZodString;
232
+ }, import("zod/v4/core").$strip>;
233
+ }, {
234
+ status: boolean;
235
+ }>;
236
+ unsubscribe: import("better-auth").StrictEndpoint<"/lead/unsubscribe", {
237
+ method: "POST";
238
+ query: import("zod").ZodObject<{
239
+ token: import("zod").ZodString;
240
+ }, import("zod/v4/core").$strip>;
241
+ metadata: {
242
+ allowedMediaTypes: never[];
243
+ };
244
+ }, {
245
+ status: boolean;
246
+ }>;
247
+ unsubscribeSession: import("better-auth").StrictEndpoint<"/lead/unsubscribe-session", {
248
+ method: "POST";
249
+ use: import("better-auth").Middleware<import("better-auth").MiddlewareOptions, (inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
246
250
  session: {
247
251
  session: Record<string, any> & {
248
252
  id: string;
@@ -264,19 +268,24 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
264
268
  image?: string | null | undefined;
265
269
  };
266
270
  };
267
- }>)[];
271
+ }>>[];
268
272
  }, {
269
- leads: Lead[];
270
- total: number;
271
- limit: number;
272
- offset: number;
273
- }> | undefined;
274
- getLead?: import("better-auth").StrictEndpoint<"/lead/get-lead", {
275
- method: "GET";
276
- query: import("zod").ZodObject<{
277
- id: import("zod").ZodString;
278
- }, import("better-auth").$strip>;
279
- use: ((inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
273
+ status: boolean;
274
+ }>;
275
+ resend: import("better-auth").StrictEndpoint<"/lead/resend", {
276
+ method: "POST";
277
+ body: import("zod").ZodObject<{
278
+ email: import("zod").ZodOptional<import("zod").ZodString>;
279
+ }, import("zod/v4/core").$strip>;
280
+ }, {
281
+ status: boolean;
282
+ }>;
283
+ update: import("better-auth").StrictEndpoint<"/lead/update", {
284
+ method: "POST";
285
+ body: import("zod").ZodObject<{
286
+ metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
287
+ }, import("zod/v4/core").$strip>;
288
+ use: import("better-auth").Middleware<import("better-auth").MiddlewareOptions, (inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
280
289
  session: {
281
290
  session: Record<string, any> & {
282
291
  id: string;
@@ -298,14 +307,57 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
298
307
  image?: string | null | undefined;
299
308
  };
300
309
  };
301
- }>)[];
302
- }, Lead> | undefined;
303
- removeLead?: import("better-auth").StrictEndpoint<"/lead/remove-lead", {
304
- method: "POST";
305
- body: import("zod").ZodObject<{
306
- leadId: import("zod").ZodCoercedString<unknown>;
307
- }, import("better-auth").$strip>;
308
- use: ((inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
310
+ }>>[];
311
+ metadata: {
312
+ $Infer: {
313
+ body: {
314
+ metadata?: (O extends {
315
+ metadata: {
316
+ validationSchema: import("better-auth").StandardSchemaV1<unknown, infer Out>;
317
+ };
318
+ } ? Out : Record<string, any>) | undefined;
319
+ };
320
+ };
321
+ };
322
+ }, {
323
+ status: boolean;
324
+ }>;
325
+ listLeads?: import("better-auth").StrictEndpoint<"/lead/list-leads", {
326
+ method: "GET";
327
+ query: import("zod").ZodObject<{
328
+ searchValue: import("zod").ZodOptional<import("zod").ZodString>;
329
+ searchField: import("zod").ZodOptional<import("zod").ZodEnum<{
330
+ email: "email";
331
+ }>>;
332
+ searchOperator: import("zod").ZodOptional<import("zod").ZodEnum<{
333
+ contains: "contains";
334
+ ends_with: "ends_with";
335
+ starts_with: "starts_with";
336
+ }>>;
337
+ limit: import("zod").ZodOptional<import("zod").ZodCoercedNumber<unknown>>;
338
+ offset: import("zod").ZodOptional<import("zod").ZodCoercedNumber<unknown>>;
339
+ sortBy: import("zod").ZodOptional<import("zod").ZodString>;
340
+ sortDirection: import("zod").ZodOptional<import("zod").ZodEnum<{
341
+ asc: "asc";
342
+ desc: "desc";
343
+ }>>;
344
+ filterField: import("zod").ZodOptional<import("zod").ZodString>;
345
+ filterValue: import("zod").ZodOptional<import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodUnion<[import("zod").ZodString, import("zod").ZodNumber]>, import("zod").ZodBoolean]>, import("zod").ZodArray<import("zod").ZodString>]>, import("zod").ZodArray<import("zod").ZodNumber>]>>;
346
+ filterOperator: import("zod").ZodOptional<import("zod").ZodEnum<{
347
+ contains: "contains";
348
+ ends_with: "ends_with";
349
+ eq: "eq";
350
+ gt: "gt";
351
+ gte: "gte";
352
+ in: "in";
353
+ lt: "lt";
354
+ lte: "lte";
355
+ ne: "ne";
356
+ not_in: "not_in";
357
+ starts_with: "starts_with";
358
+ }>>;
359
+ }, import("zod/v4/core").$strip>;
360
+ use: import("better-auth").Middleware<import("better-auth").MiddlewareOptions, (inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
309
361
  session: {
310
362
  session: Record<string, any> & {
311
363
  id: string;
@@ -327,53 +379,19 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
327
379
  image?: string | null | undefined;
328
380
  };
329
381
  };
330
- }>)[];
382
+ }>>[];
331
383
  }, {
332
- success: boolean;
384
+ leads: Lead[];
385
+ total: number;
386
+ limit: number;
387
+ offset: number;
333
388
  }> | undefined;
334
- subscribe: import("better-auth").StrictEndpoint<"/lead/subscribe", {
335
- method: "POST";
336
- body: import("zod").ZodObject<{
337
- email: import("zod").ZodOptional<import("zod").ZodString>;
338
- metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
339
- }, import("better-auth").$strip>;
340
- metadata: {
341
- $Infer: {
342
- body: {
343
- email?: string;
344
- metadata?: (O extends {
345
- metadata: {
346
- validationSchema: import("better-auth").StandardSchemaV1<unknown, infer Out>;
347
- };
348
- } ? Out : Record<string, any>) | undefined;
349
- };
350
- };
351
- };
352
- }, {
353
- status: boolean;
354
- }>;
355
- verify: import("better-auth").StrictEndpoint<"/lead/verify", {
389
+ getLead?: import("better-auth").StrictEndpoint<"/lead/get-lead", {
356
390
  method: "GET";
357
391
  query: import("zod").ZodObject<{
358
- token: import("zod").ZodString;
359
- }, import("better-auth").$strip>;
360
- }, {
361
- status: boolean;
362
- }>;
363
- unsubscribe: import("better-auth").StrictEndpoint<"/lead/unsubscribe", {
364
- method: "POST";
365
- query: import("zod").ZodObject<{
366
- token: import("zod").ZodString;
367
- }, import("better-auth").$strip>;
368
- metadata: {
369
- allowedMediaTypes: never[];
370
- };
371
- }, {
372
- status: boolean;
373
- }>;
374
- unsubscribeSession: import("better-auth").StrictEndpoint<"/lead/unsubscribe-session", {
375
- method: "POST";
376
- use: ((inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
392
+ id: import("zod").ZodString;
393
+ }, import("zod/v4/core").$strip>;
394
+ use: import("better-auth").Middleware<import("better-auth").MiddlewareOptions, (inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
377
395
  session: {
378
396
  session: Record<string, any> & {
379
397
  id: string;
@@ -395,24 +413,14 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
395
413
  image?: string | null | undefined;
396
414
  };
397
415
  };
398
- }>)[];
399
- }, {
400
- status: boolean;
401
- }>;
402
- resend: import("better-auth").StrictEndpoint<"/lead/resend", {
403
- method: "POST";
404
- body: import("zod").ZodObject<{
405
- email: import("zod").ZodOptional<import("zod").ZodString>;
406
- }, import("better-auth").$strip>;
407
- }, {
408
- status: boolean;
409
- }>;
410
- update: import("better-auth").StrictEndpoint<"/lead/update", {
416
+ }>>[];
417
+ }, Lead> | undefined;
418
+ removeLead?: import("better-auth").StrictEndpoint<"/lead/remove-lead", {
411
419
  method: "POST";
412
420
  body: import("zod").ZodObject<{
413
- metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
414
- }, import("better-auth").$strip>;
415
- use: ((inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
421
+ leadId: import("zod").ZodCoercedString<unknown>;
422
+ }, import("zod/v4/core").$strip>;
423
+ use: import("better-auth").Middleware<import("better-auth").MiddlewareOptions, (inputContext: import("better-auth").MiddlewareInputContext<import("better-auth").MiddlewareOptions>) => Promise<{
416
424
  session: {
417
425
  session: Record<string, any> & {
418
426
  id: string;
@@ -434,21 +442,10 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
434
442
  image?: string | null | undefined;
435
443
  };
436
444
  };
437
- }>)[];
438
- metadata: {
439
- $Infer: {
440
- body: {
441
- metadata?: (O extends {
442
- metadata: {
443
- validationSchema: import("better-auth").StandardSchemaV1<unknown, infer Out>;
444
- };
445
- } ? Out : Record<string, any>) | undefined;
446
- };
447
- };
448
- };
445
+ }>>[];
449
446
  }, {
450
- status: boolean;
451
- }>;
447
+ success: boolean;
448
+ }> | undefined;
452
449
  };
453
450
  options: NoInfer<O>;
454
451
  rateLimit: {
@@ -457,16 +454,16 @@ declare const lead: <O extends LeadOptions>(options?: O) => {
457
454
  max: number;
458
455
  }[];
459
456
  $ERROR_CODES: {
457
+ ADMIN_PLUGIN_REQUIRED: import("better-auth").RawError<"ADMIN_PLUGIN_REQUIRED">;
458
+ EMAIL_OR_SESSION_REQUIRED: import("better-auth").RawError<"EMAIL_OR_SESSION_REQUIRED">;
460
459
  FORBIDDEN: import("better-auth").RawError<"FORBIDDEN">;
461
460
  INVALID_EMAIL: import("better-auth").RawError<"INVALID_EMAIL">;
462
- INVALID_TOKEN: import("better-auth").RawError<"INVALID_TOKEN">;
463
- TOKEN_EXPIRED: import("better-auth").RawError<"TOKEN_EXPIRED">;
464
461
  INVALID_METADATA: import("better-auth").RawError<"INVALID_METADATA">;
465
- EMAIL_OR_SESSION_REQUIRED: import("better-auth").RawError<"EMAIL_OR_SESSION_REQUIRED">;
466
- ADMIN_PLUGIN_REQUIRED: import("better-auth").RawError<"ADMIN_PLUGIN_REQUIRED">;
462
+ INVALID_TOKEN: import("better-auth").RawError<"INVALID_TOKEN">;
467
463
  LEAD_NOT_FOUND: import("better-auth").RawError<"LEAD_NOT_FOUND">;
464
+ TOKEN_EXPIRED: import("better-auth").RawError<"TOKEN_EXPIRED">;
468
465
  };
469
466
  };
470
467
  //#endregion
471
468
  export { LeadPayload as i, Lead as n, LeadOptions as r, lead as t };
472
- //# sourceMappingURL=index-CypeYbkn.d.mts.map
469
+ //# sourceMappingURL=index-BYw4ZSS5.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { i as LeadPayload, n as Lead, r as LeadOptions, t as lead } from "./index-CypeYbkn.mjs";
1
+ import { i as LeadPayload, n as Lead, r as LeadOptions, t as lead } from "./index-BYw4ZSS5.mjs";
2
2
  export { type Lead, type LeadOptions, type LeadPayload, lead };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["lead"],"sources":["../src/error-codes.ts","../src/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["import { defineErrorCodes } from 'better-auth';\n\nexport const LEAD_ERROR_CODES = defineErrorCodes({\n INVALID_EMAIL: 'Invalid email',\n INVALID_TOKEN: 'Invalid token',\n TOKEN_EXPIRED: 'Token expired',\n INVALID_METADATA: 'Invalid metadata',\n EMAIL_OR_SESSION_REQUIRED: 'Email or session is required',\n ADMIN_PLUGIN_REQUIRED: 'Admin plugin is required',\n FORBIDDEN: 'Forbidden',\n LEAD_NOT_FOUND: 'Lead not found',\n});\n","import {\n BASE_ERROR_CODES,\n type InternalLogger,\n type StandardSchemaV1,\n type Where,\n} from 'better-auth';\nimport { whereOperators } from 'better-auth/adapters';\nimport {\n APIError,\n createAuthEndpoint,\n getSessionFromCtx,\n sessionMiddleware,\n} from 'better-auth/api';\nimport { SignJWT, jwtVerify } from 'jose';\nimport type { JWTPayload, JWTVerifyResult } from 'jose';\nimport { JWTExpired } from 'jose/errors';\nimport * as z from 'zod';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport type { Lead, LeadOptions, LeadPayload } from './type';\n\ntype InferMetadata<O extends LeadOptions> = O extends {\n metadata: { validationSchema: StandardSchemaV1<unknown, infer Out> };\n}\n ? Out\n : Record<string, any>;\n\ntype IdentifierType = 'email' | 'user';\n\nconst subscribeSchema = z.object({\n email: z.string().optional().meta({\n description: 'Email address of the lead',\n }),\n metadata: z.record(z.string(), z.any()).optional().meta({\n description: 'Additional metadata to store with the lead',\n }),\n});\n\nexport const subscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/subscribe',\n {\n method: 'POST',\n body: subscribeSchema,\n metadata: {\n $Infer: {\n body: {} as {\n email?: string;\n metadata?: InferMetadata<O>;\n },\n },\n },\n },\n async (ctx) => {\n const email = ctx.body.email;\n\n const metadata = validateMetadata(\n options,\n ctx.body.metadata as Record<string, any> | undefined,\n ctx.context.logger,\n );\n\n let identifierType: IdentifierType;\n let leadIdentifier: string;\n let leadEmail: string;\n let createData: LeadPayload;\n\n if (email) {\n const isValidEmail = z.email().safeParse(email);\n if (!isValidEmail.success) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_EMAIL);\n }\n\n leadIdentifier = email.toLowerCase();\n identifierType = 'email';\n leadEmail = leadIdentifier;\n createData = {\n email: leadIdentifier,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n };\n } else {\n const session = await getSessionFromCtx(ctx);\n\n if (!session) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.EMAIL_OR_SESSION_REQUIRED);\n }\n\n leadIdentifier = session.user.id;\n identifierType = 'user';\n leadEmail = session.user.email;\n createData = {\n userId: leadIdentifier,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n };\n }\n\n const whereField = identifierType === 'email' ? 'email' : 'userId';\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n\n if (!lead) {\n try {\n lead = await ctx.context.adapter.create<LeadPayload, Lead>({\n model: 'lead',\n data: createData,\n });\n } catch (e) {\n ctx.context.logger.info('Error creating lead');\n lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n }\n }\n\n if (options.sendConfirmationEmail && lead && !lead.confirmed) {\n const token = await createConfirmationToken(\n ctx.context.secret,\n { identifier: leadIdentifier, type: identifierType },\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n const unsubscribeToken = await createUnsubscribeToken(\n ctx.context.secret,\n lead.id,\n options.unsubscribeExpiresIn,\n );\n const unsubscribeUrl = `${ctx.context.baseURL}/lead/unsubscribe?token=${unsubscribeToken}`;\n\n const sent = await options.sendConfirmationEmail(\n {\n lead,\n email: leadEmail,\n url,\n token,\n unsubscribeUrl,\n },\n ctx.request,\n );\n\n if (sent) {\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n update: { confirmationSentAt: new Date() },\n });\n }\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst verifySchema = z.object({\n token: z.string().meta({\n description: 'The token to verify the email',\n }),\n});\n\nexport const verify = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/verify',\n {\n method: 'GET',\n query: verifySchema,\n },\n async (ctx) => {\n const { token } = ctx.query;\n\n let jwt: JWTVerifyResult<JWTPayload>;\n try {\n jwt = await jwtVerify(token, new TextEncoder().encode(ctx.context.secret), {\n algorithms: ['HS256'],\n });\n } catch (e) {\n if (e instanceof JWTExpired) {\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.TOKEN_EXPIRED);\n }\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.INVALID_TOKEN);\n }\n\n const confirmationPayloadSchema = z.object({\n identifier: z.string(),\n type: z.enum(['email', 'user']),\n });\n const parsed = confirmationPayloadSchema.parse(jwt.payload);\n\n const whereField = parsed.type === 'user' ? 'userId' : 'email';\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: parsed.identifier }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (lead.confirmed) {\n return ctx.json({\n status: true,\n });\n }\n\n lead = await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: parsed.identifier }],\n update: {\n confirmed: true,\n },\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.onConfirmed) {\n await ctx.context.runInBackgroundOrAwait(options.onConfirmed({ lead }, ctx.request));\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst unsubscribeQuerySchema = z.object({\n token: z.string().meta({\n description: 'Signed unsubscribe token',\n }),\n});\n\nexport const unsubscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe',\n {\n method: 'POST',\n query: unsubscribeQuerySchema,\n metadata: {\n // Empty array overrides the router-level JSON-only restriction,\n // allowing POST with no body (required for RFC 8058 one-click unsubscribe).\n allowedMediaTypes: [],\n },\n },\n async (ctx) => {\n let payload: JWTPayload;\n try {\n const result = await jwtVerify(\n ctx.query.token,\n new TextEncoder().encode(ctx.context.secret),\n { algorithms: ['HS256'] },\n );\n payload = result.payload;\n } catch (e) {\n if (e instanceof JWTExpired) {\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.TOKEN_EXPIRED);\n }\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.INVALID_TOKEN);\n }\n\n const id = payload['id'] as string;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nexport const unsubscribeSession = <O extends LeadOptions>(_options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe-session',\n {\n method: 'POST',\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session.user.id;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst resendSchema = z.object({\n email: z.string().optional().meta({\n description: 'Email address to resend the verification email to',\n }),\n});\n\nexport const resend = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/resend',\n {\n method: 'POST',\n body: resendSchema,\n },\n async (ctx) => {\n const email = ctx.body.email;\n\n let identifierType: IdentifierType;\n let leadIdentifier: string;\n let leadEmail: string;\n\n if (email) {\n const isValidEmail = z.email().safeParse(email);\n if (!isValidEmail.success) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_EMAIL);\n }\n\n leadIdentifier = email.toLowerCase();\n identifierType = 'email';\n leadEmail = leadIdentifier;\n } else {\n const session = await getSessionFromCtx(ctx);\n\n if (!session) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.EMAIL_OR_SESSION_REQUIRED);\n }\n leadIdentifier = session.user.id;\n identifierType = 'user';\n leadEmail = session.user.email;\n }\n\n const whereField = identifierType === 'email' ? 'email' : 'userId';\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.sendConfirmationEmail && !lead.confirmed) {\n const token = await createConfirmationToken(\n ctx.context.secret,\n { identifier: leadIdentifier, type: identifierType },\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n const unsubscribeToken = await createUnsubscribeToken(\n ctx.context.secret,\n lead.id,\n options.unsubscribeExpiresIn,\n );\n const unsubscribeUrl = `${ctx.context.baseURL}/lead/unsubscribe?token=${unsubscribeToken}`;\n\n const sent = await options.sendConfirmationEmail(\n {\n lead,\n email: leadEmail,\n url,\n token,\n unsubscribeUrl,\n },\n ctx.request,\n );\n\n if (sent) {\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n update: { confirmationSentAt: new Date() },\n });\n }\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst updateSchema = z.object({\n metadata: z.record(z.string(), z.any()).optional().meta({\n description: 'Additional metadata to store with the lead',\n }),\n});\n\nexport const update = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/update',\n {\n method: 'POST',\n body: updateSchema,\n use: [sessionMiddleware],\n metadata: {\n $Infer: {\n body: {} as {\n metadata?: InferMetadata<O>;\n },\n },\n },\n },\n async (ctx) => {\n const userId = ctx.context.session.user.id;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n const metadata = validateMetadata(\n options,\n ctx.body.metadata as Record<string, any> | undefined,\n ctx.context.logger,\n );\n\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n update: {\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst listQuerySchema = z.object({\n searchValue: z.string().optional().meta({\n description: 'The value to search for. Eg: \"some name\"',\n }),\n searchField: z\n .enum(['email'])\n .meta({\n description: 'The field to search in, defaults to email.',\n })\n .optional(),\n searchOperator: z\n .enum(['contains', 'starts_with', 'ends_with'])\n .meta({\n description:\n 'The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`. Eg: \"contains\"',\n })\n .optional(),\n limit: z.coerce\n .number()\n .meta({\n description: 'The number of lead to return',\n })\n .optional(),\n offset: z.coerce\n .number()\n .meta({\n description: 'The offset to start from',\n })\n .optional(),\n sortBy: z\n .string()\n .meta({\n description: 'The field to sort by',\n })\n .optional(),\n sortDirection: z\n .enum(['asc', 'desc'])\n .meta({\n description: 'The direction to sort by',\n })\n .optional(),\n filterField: z\n .string()\n .meta({\n description: 'The field to filter by',\n })\n .optional(),\n filterValue: z\n .string()\n .meta({\n description: 'The value to filter by',\n })\n .or(z.number())\n .or(z.boolean())\n .or(z.array(z.string()))\n .or(z.array(z.number()))\n .optional(),\n filterOperator: z\n .enum(whereOperators)\n .meta({\n description: 'The operator to use for the filter',\n })\n .optional(),\n});\n\nexport const listLeads = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/list-leads',\n {\n method: 'GET',\n query: listQuerySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const where: Where[] = [];\n\n if (ctx.query?.searchValue) {\n where.push({\n field: ctx.query.searchField || 'email',\n operator: ctx.query.searchOperator || 'contains',\n value: ctx.query.searchValue,\n });\n }\n\n if (ctx.query?.filterValue !== undefined) {\n where.push({\n field: ctx.query.filterField || 'email',\n operator: ctx.query.filterOperator || 'eq',\n value: ctx.query.filterValue,\n });\n }\n\n const limit = ctx.query.limit ?? 100;\n const offset = ctx.query.offset ?? 0;\n\n const [leads, total] = await Promise.all([\n ctx.context.adapter.findMany<Lead>({\n model: 'lead',\n limit,\n offset,\n ...(ctx.query.sortBy && {\n sortBy: {\n field: ctx.query.sortBy,\n direction: ctx.query.sortDirection || 'asc',\n },\n }),\n where: where.length ? where : undefined,\n }),\n ctx.context.adapter.count({ model: 'lead' }),\n ]);\n\n return ctx.json({ leads, total, limit, offset });\n },\n );\n\nconst getLeadQuerySchema = z.object({\n id: z.string().meta({\n description: 'The id of the Lead',\n }),\n});\n\nexport const getLead = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/get-lead',\n {\n method: 'GET',\n query: getLeadQuerySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n if (!lead) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.LEAD_NOT_FOUND);\n }\n\n return lead;\n },\n );\n\nconst removeLeadBodySchema = z.object({\n leadId: z.coerce.string().meta({\n description: 'The lead id',\n }),\n});\n\nexport const removeLead = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/remove-lead',\n {\n method: 'POST',\n body: removeLeadBodySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n if (!lead) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.LEAD_NOT_FOUND);\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n return ctx.json({ success: true });\n },\n );\n\nasync function createConfirmationToken(\n secret: string,\n payload: { identifier: string; type: IdentifierType },\n expiresIn: number,\n) {\n return new SignJWT(payload)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(Math.floor(Date.now() / 1000) + expiresIn)\n .sign(new TextEncoder().encode(secret));\n}\n\nasync function createUnsubscribeToken(secret: string, leadId: string, expiresIn?: number) {\n const jwt = new SignJWT({ id: leadId }).setProtectedHeader({ alg: 'HS256' }).setIssuedAt();\n if (expiresIn !== undefined) {\n jwt.setExpirationTime(Math.floor(Date.now() / 1000) + expiresIn);\n }\n return jwt.sign(new TextEncoder().encode(secret));\n}\n\nfunction validateMetadata(\n options: LeadOptions,\n metadata: Record<string, any> | undefined,\n logger: InternalLogger,\n) {\n if (!metadata || !options.metadata?.validationSchema) {\n return metadata;\n }\n const validationResult = options.metadata.validationSchema['~standard'].validate(metadata);\n\n if (validationResult instanceof Promise) {\n throw APIError.from('INTERNAL_SERVER_ERROR', BASE_ERROR_CODES.ASYNC_VALIDATION_NOT_SUPPORTED);\n }\n\n if (validationResult.issues) {\n logger.error('Invalid metadata', validationResult.issues);\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_METADATA);\n }\n\n return validationResult.value as Record<string, any>;\n}\n","import { type BetterAuthPluginDBSchema } from 'better-auth';\nimport { mergeSchema } from 'better-auth/db';\n\nimport type { LeadOptions } from './type';\n\nexport const lead = {\n lead: {\n fields: {\n createdAt: {\n type: 'date',\n defaultValue: () => new Date(),\n required: true,\n input: false,\n },\n updatedAt: {\n type: 'date',\n defaultValue: () => new Date(),\n onUpdate: () => new Date(),\n required: true,\n input: false,\n },\n email: {\n type: 'string',\n required: false,\n unique: true,\n },\n userId: {\n type: 'string',\n required: false,\n unique: true,\n references: {\n model: 'user',\n field: 'id',\n },\n },\n confirmed: {\n type: 'boolean',\n defaultValue: false,\n required: true,\n input: false,\n },\n confirmationSentAt: {\n type: 'date',\n required: false,\n input: false,\n },\n metadata: {\n type: 'string',\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const getSchema = <O extends LeadOptions>(options: O) => {\n return mergeSchema(lead, options.schema);\n};\n","import type { BetterAuthPlugin } from 'better-auth';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport {\n getLead,\n listLeads,\n removeLead,\n resend,\n subscribe,\n unsubscribe,\n unsubscribeSession,\n update,\n verify,\n} from './routes';\nimport { getSchema } from './schema';\nimport type { LeadOptions } from './type';\n\nexport const lead = <O extends LeadOptions>(options: O = {} as O) => {\n const endpoints = {\n subscribe: subscribe(options),\n verify: verify(options),\n unsubscribe: unsubscribe(options),\n unsubscribeSession: unsubscribeSession(options),\n resend: resend(options),\n update: update(options),\n ...(options.admin?.enabled\n ? {\n listLeads: listLeads(options),\n getLead: getLead(options),\n removeLead: removeLead(options),\n }\n : {}),\n };\n\n return {\n id: 'lead',\n schema: getSchema(options),\n endpoints,\n options: options as NoInfer<O>,\n rateLimit: [\n {\n pathMatcher: (path) => ['/lead/subscribe', '/lead/resend'].includes(path),\n window: options.rateLimit?.window ?? 10,\n max: options.rateLimit?.max ?? 3,\n },\n ],\n $ERROR_CODES: LEAD_ERROR_CODES,\n } satisfies BetterAuthPlugin;\n};\n\nexport type * from './type';\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["lead"],"sources":["../src/error-codes.ts","../src/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["import { defineErrorCodes } from 'better-auth';\n\nexport const LEAD_ERROR_CODES = defineErrorCodes({\n INVALID_EMAIL: 'Invalid email',\n INVALID_TOKEN: 'Invalid token',\n TOKEN_EXPIRED: 'Token expired',\n INVALID_METADATA: 'Invalid metadata',\n EMAIL_OR_SESSION_REQUIRED: 'Email or session is required',\n ADMIN_PLUGIN_REQUIRED: 'Admin plugin is required',\n FORBIDDEN: 'Forbidden',\n LEAD_NOT_FOUND: 'Lead not found',\n});\n","import {\n BASE_ERROR_CODES,\n type InternalLogger,\n type StandardSchemaV1,\n type Where,\n} from 'better-auth';\nimport { whereOperators } from 'better-auth/adapters';\nimport {\n APIError,\n createAuthEndpoint,\n getSessionFromCtx,\n sessionMiddleware,\n} from 'better-auth/api';\nimport { SignJWT, jwtVerify } from 'jose';\nimport type { JWTPayload, JWTVerifyResult } from 'jose';\nimport { JWTExpired } from 'jose/errors';\nimport * as z from 'zod';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport type { Lead, LeadOptions, LeadPayload } from './type';\n\ntype InferMetadata<O extends LeadOptions> = O extends {\n metadata: { validationSchema: StandardSchemaV1<unknown, infer Out> };\n}\n ? Out\n : Record<string, any>;\n\ntype IdentifierType = 'email' | 'user';\n\nconst subscribeSchema = z.object({\n email: z.string().optional().meta({\n description: 'Email address of the lead',\n }),\n metadata: z.record(z.string(), z.any()).optional().meta({\n description: 'Additional metadata to store with the lead',\n }),\n});\n\nexport const subscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/subscribe',\n {\n method: 'POST',\n body: subscribeSchema,\n metadata: {\n $Infer: {\n body: {} as {\n email?: string;\n metadata?: InferMetadata<O>;\n },\n },\n },\n },\n async (ctx) => {\n const email = ctx.body.email;\n\n const metadata = validateMetadata(\n options,\n ctx.body.metadata as Record<string, any> | undefined,\n ctx.context.logger,\n );\n\n let identifierType: IdentifierType;\n let leadIdentifier: string;\n let leadEmail: string;\n let createData: LeadPayload;\n\n if (email) {\n const isValidEmail = z.email().safeParse(email);\n if (!isValidEmail.success) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_EMAIL);\n }\n\n leadIdentifier = email.toLowerCase();\n identifierType = 'email';\n leadEmail = leadIdentifier;\n createData = {\n email: leadIdentifier,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n };\n } else {\n const session = await getSessionFromCtx(ctx);\n\n if (!session) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.EMAIL_OR_SESSION_REQUIRED);\n }\n\n leadIdentifier = session.user.id;\n identifierType = 'user';\n leadEmail = session.user.email;\n createData = {\n userId: leadIdentifier,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n };\n }\n\n const whereField = identifierType === 'email' ? 'email' : 'userId';\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n\n if (!lead) {\n try {\n lead = await ctx.context.adapter.create<LeadPayload, Lead>({\n model: 'lead',\n data: createData,\n });\n } catch (e) {\n ctx.context.logger.info('Error creating lead');\n lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n }\n }\n\n if (options.sendConfirmationEmail && lead && !lead.confirmed) {\n const token = await createConfirmationToken(\n ctx.context.secret,\n { identifier: leadIdentifier, type: identifierType },\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n const unsubscribeToken = await createUnsubscribeToken(\n ctx.context.secret,\n lead.id,\n options.unsubscribeExpiresIn,\n );\n const unsubscribeUrl = `${ctx.context.baseURL}/lead/unsubscribe?token=${unsubscribeToken}`;\n\n const sent = await options.sendConfirmationEmail(\n {\n lead,\n email: leadEmail,\n url,\n token,\n unsubscribeUrl,\n },\n ctx.request,\n );\n\n if (sent) {\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n update: { confirmationSentAt: new Date() },\n });\n }\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst verifySchema = z.object({\n token: z.string().meta({\n description: 'The token to verify the email',\n }),\n});\n\nexport const verify = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/verify',\n {\n method: 'GET',\n query: verifySchema,\n },\n async (ctx) => {\n const { token } = ctx.query;\n\n let jwt: JWTVerifyResult<JWTPayload>;\n try {\n jwt = await jwtVerify(token, new TextEncoder().encode(ctx.context.secret), {\n algorithms: ['HS256'],\n });\n } catch (e) {\n if (e instanceof JWTExpired) {\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.TOKEN_EXPIRED);\n }\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.INVALID_TOKEN);\n }\n\n const confirmationPayloadSchema = z.object({\n identifier: z.string(),\n type: z.enum(['email', 'user']),\n });\n const parsed = confirmationPayloadSchema.parse(jwt.payload);\n\n const whereField = parsed.type === 'user' ? 'userId' : 'email';\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: parsed.identifier }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (lead.confirmed) {\n return ctx.json({\n status: true,\n });\n }\n\n lead = await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: parsed.identifier }],\n update: {\n confirmed: true,\n },\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.onConfirmed) {\n await ctx.context.runInBackgroundOrAwait(options.onConfirmed({ lead }, ctx.request));\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst unsubscribeQuerySchema = z.object({\n token: z.string().meta({\n description: 'Signed unsubscribe token',\n }),\n});\n\nexport const unsubscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe',\n {\n method: 'POST',\n query: unsubscribeQuerySchema,\n metadata: {\n // Empty array overrides the router-level JSON-only restriction,\n // allowing POST with no body (required for RFC 8058 one-click unsubscribe).\n allowedMediaTypes: [],\n },\n },\n async (ctx) => {\n let payload: JWTPayload;\n try {\n const result = await jwtVerify(\n ctx.query.token,\n new TextEncoder().encode(ctx.context.secret),\n { algorithms: ['HS256'] },\n );\n payload = result.payload;\n } catch (e) {\n if (e instanceof JWTExpired) {\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.TOKEN_EXPIRED);\n }\n throw APIError.from('UNAUTHORIZED', LEAD_ERROR_CODES.INVALID_TOKEN);\n }\n\n const id = payload['id'] as string;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nexport const unsubscribeSession = <O extends LeadOptions>(_options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe-session',\n {\n method: 'POST',\n use: [sessionMiddleware],\n },\n async (ctx) => {\n const userId = ctx.context.session.user.id;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst resendSchema = z.object({\n email: z.string().optional().meta({\n description: 'Email address to resend the verification email to',\n }),\n});\n\nexport const resend = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/resend',\n {\n method: 'POST',\n body: resendSchema,\n },\n async (ctx) => {\n const email = ctx.body.email;\n\n let identifierType: IdentifierType;\n let leadIdentifier: string;\n let leadEmail: string;\n\n if (email) {\n const isValidEmail = z.email().safeParse(email);\n if (!isValidEmail.success) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_EMAIL);\n }\n\n leadIdentifier = email.toLowerCase();\n identifierType = 'email';\n leadEmail = leadIdentifier;\n } else {\n const session = await getSessionFromCtx(ctx);\n\n if (!session) {\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.EMAIL_OR_SESSION_REQUIRED);\n }\n leadIdentifier = session.user.id;\n identifierType = 'user';\n leadEmail = session.user.email;\n }\n\n const whereField = identifierType === 'email' ? 'email' : 'userId';\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.sendConfirmationEmail && !lead.confirmed) {\n const token = await createConfirmationToken(\n ctx.context.secret,\n { identifier: leadIdentifier, type: identifierType },\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n const unsubscribeToken = await createUnsubscribeToken(\n ctx.context.secret,\n lead.id,\n options.unsubscribeExpiresIn,\n );\n const unsubscribeUrl = `${ctx.context.baseURL}/lead/unsubscribe?token=${unsubscribeToken}`;\n\n const sent = await options.sendConfirmationEmail(\n {\n lead,\n email: leadEmail,\n url,\n token,\n unsubscribeUrl,\n },\n ctx.request,\n );\n\n if (sent) {\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: whereField, value: leadIdentifier }],\n update: { confirmationSentAt: new Date() },\n });\n }\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst updateSchema = z.object({\n metadata: z.record(z.string(), z.any()).optional().meta({\n description: 'Additional metadata to store with the lead',\n }),\n});\n\nexport const update = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/update',\n {\n method: 'POST',\n body: updateSchema,\n use: [sessionMiddleware],\n metadata: {\n $Infer: {\n body: {} as {\n metadata?: InferMetadata<O>;\n },\n },\n },\n },\n async (ctx) => {\n const userId = ctx.context.session.user.id;\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n const metadata = validateMetadata(\n options,\n ctx.body.metadata as Record<string, any> | undefined,\n ctx.context.logger,\n );\n\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [{ field: 'userId', value: userId }],\n update: {\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst listQuerySchema = z.object({\n searchValue: z.string().optional().meta({\n description: 'The value to search for. Eg: \"some name\"',\n }),\n searchField: z\n .enum(['email'])\n .meta({\n description: 'The field to search in, defaults to email.',\n })\n .optional(),\n searchOperator: z\n .enum(['contains', 'starts_with', 'ends_with'])\n .meta({\n description:\n 'The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`. Eg: \"contains\"',\n })\n .optional(),\n limit: z.coerce\n .number()\n .meta({\n description: 'The number of lead to return',\n })\n .optional(),\n offset: z.coerce\n .number()\n .meta({\n description: 'The offset to start from',\n })\n .optional(),\n sortBy: z\n .string()\n .meta({\n description: 'The field to sort by',\n })\n .optional(),\n sortDirection: z\n .enum(['asc', 'desc'])\n .meta({\n description: 'The direction to sort by',\n })\n .optional(),\n filterField: z\n .string()\n .meta({\n description: 'The field to filter by',\n })\n .optional(),\n filterValue: z\n .string()\n .meta({\n description: 'The value to filter by',\n })\n .or(z.number())\n .or(z.boolean())\n .or(z.array(z.string()))\n .or(z.array(z.number()))\n .optional(),\n filterOperator: z\n .enum(whereOperators)\n .meta({\n description: 'The operator to use for the filter',\n })\n .optional(),\n});\n\nexport const listLeads = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/list-leads',\n {\n method: 'GET',\n query: listQuerySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const where: Where[] = [];\n\n if (ctx.query?.searchValue) {\n where.push({\n field: ctx.query.searchField || 'email',\n operator: ctx.query.searchOperator || 'contains',\n value: ctx.query.searchValue,\n });\n }\n\n if (ctx.query?.filterValue !== undefined) {\n where.push({\n field: ctx.query.filterField || 'email',\n operator: ctx.query.filterOperator || 'eq',\n value: ctx.query.filterValue,\n });\n }\n\n const limit = ctx.query.limit ?? 100;\n const offset = ctx.query.offset ?? 0;\n\n const [leads, total] = await Promise.all([\n ctx.context.adapter.findMany<Lead>({\n model: 'lead',\n limit,\n offset,\n ...(ctx.query.sortBy && {\n sortBy: {\n field: ctx.query.sortBy,\n direction: ctx.query.sortDirection || 'asc',\n },\n }),\n where: where.length ? where : undefined,\n }),\n ctx.context.adapter.count({ model: 'lead' }),\n ]);\n\n return ctx.json({ leads, total, limit, offset });\n },\n );\n\nconst getLeadQuerySchema = z.object({\n id: z.string().meta({\n description: 'The id of the Lead',\n }),\n});\n\nexport const getLead = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/get-lead',\n {\n method: 'GET',\n query: getLeadQuerySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n if (!lead) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.LEAD_NOT_FOUND);\n }\n\n return lead;\n },\n );\n\nconst removeLeadBodySchema = z.object({\n leadId: z.coerce.string().meta({\n description: 'The lead id',\n }),\n});\n\nexport const removeLead = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/remove-lead',\n {\n method: 'POST',\n body: removeLeadBodySchema,\n use: [sessionMiddleware],\n },\n async (ctx) => {\n if (!ctx.context.hasPlugin('admin')) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.ADMIN_PLUGIN_REQUIRED);\n }\n\n const allowedRoles = options.admin?.roles ?? ['admin'];\n const userRole = (ctx.context.session.user as { role?: string }).role ?? '';\n const userRoles = userRole\n .split(',')\n .map((r) => r.trim())\n .filter(Boolean);\n const hasRole = userRoles.some((r) => allowedRoles.includes(r));\n\n if (!hasRole) {\n throw APIError.from('FORBIDDEN', LEAD_ERROR_CODES.FORBIDDEN);\n }\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n if (!lead) {\n throw APIError.from('NOT_FOUND', LEAD_ERROR_CODES.LEAD_NOT_FOUND);\n }\n\n await ctx.context.adapter.delete({\n model: 'lead',\n where: [{ field: 'id', value: ctx.body.leadId }],\n });\n\n return ctx.json({ success: true });\n },\n );\n\nasync function createConfirmationToken(\n secret: string,\n payload: { identifier: string; type: IdentifierType },\n expiresIn: number,\n) {\n return new SignJWT(payload)\n .setProtectedHeader({ alg: 'HS256' })\n .setIssuedAt()\n .setExpirationTime(Math.floor(Date.now() / 1000) + expiresIn)\n .sign(new TextEncoder().encode(secret));\n}\n\nasync function createUnsubscribeToken(secret: string, leadId: string, expiresIn?: number) {\n const jwt = new SignJWT({ id: leadId }).setProtectedHeader({ alg: 'HS256' }).setIssuedAt();\n if (expiresIn !== undefined) {\n jwt.setExpirationTime(Math.floor(Date.now() / 1000) + expiresIn);\n }\n return jwt.sign(new TextEncoder().encode(secret));\n}\n\nfunction validateMetadata(\n options: LeadOptions,\n metadata: Record<string, any> | undefined,\n logger: InternalLogger,\n) {\n if (!metadata || !options.metadata?.validationSchema) {\n return metadata;\n }\n const validationResult = options.metadata.validationSchema['~standard'].validate(metadata);\n\n if (validationResult instanceof Promise) {\n throw APIError.from('INTERNAL_SERVER_ERROR', BASE_ERROR_CODES.ASYNC_VALIDATION_NOT_SUPPORTED);\n }\n\n if (validationResult.issues) {\n logger.error('Invalid metadata', validationResult.issues);\n throw APIError.from('BAD_REQUEST', LEAD_ERROR_CODES.INVALID_METADATA);\n }\n\n return validationResult.value as Record<string, any>;\n}\n","import { type BetterAuthPluginDBSchema } from 'better-auth';\nimport { mergeSchema } from 'better-auth/db';\n\nimport type { LeadOptions } from './type';\n\nexport const lead = {\n lead: {\n fields: {\n createdAt: {\n type: 'date',\n defaultValue: () => new Date(),\n required: true,\n input: false,\n },\n updatedAt: {\n type: 'date',\n defaultValue: () => new Date(),\n onUpdate: () => new Date(),\n required: true,\n input: false,\n },\n email: {\n type: 'string',\n required: false,\n unique: true,\n },\n userId: {\n type: 'string',\n required: false,\n unique: true,\n references: {\n model: 'user',\n field: 'id',\n },\n },\n confirmed: {\n type: 'boolean',\n defaultValue: false,\n required: true,\n input: false,\n },\n confirmationSentAt: {\n type: 'date',\n required: false,\n input: false,\n },\n metadata: {\n type: 'string',\n required: false,\n },\n },\n },\n} satisfies BetterAuthPluginDBSchema;\n\nexport const getSchema = <O extends LeadOptions>(options: O) => {\n return mergeSchema(lead, options.schema);\n};\n","import type { BetterAuthPlugin } from 'better-auth';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport {\n getLead,\n listLeads,\n removeLead,\n resend,\n subscribe,\n unsubscribe,\n unsubscribeSession,\n update,\n verify,\n} from './routes';\nimport { getSchema } from './schema';\nimport type { LeadOptions } from './type';\n\nexport const lead = <O extends LeadOptions>(options: O = {} as O) => {\n const endpoints = {\n subscribe: subscribe(options),\n verify: verify(options),\n unsubscribe: unsubscribe(options),\n unsubscribeSession: unsubscribeSession(options),\n resend: resend(options),\n update: update(options),\n ...(options.admin?.enabled\n ? {\n listLeads: listLeads(options),\n getLead: getLead(options),\n removeLead: removeLead(options),\n }\n : {}),\n };\n\n return {\n id: 'lead',\n schema: getSchema(options),\n endpoints,\n options: options as NoInfer<O>,\n rateLimit: [\n {\n pathMatcher: (path) => ['/lead/subscribe', '/lead/resend'].includes(path),\n window: options.rateLimit?.window ?? 10,\n max: options.rateLimit?.max ?? 3,\n },\n ],\n $ERROR_CODES: LEAD_ERROR_CODES,\n } satisfies BetterAuthPlugin;\n};\n\nexport type * from './type';\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth-lead",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Better Auth Lead plugin",
5
5
  "homepage": "https://github.com/marcjulian/better-auth-plugins#readme",
6
6
  "bugs": {
@@ -26,22 +26,24 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "jose": "^6.2.3",
29
- "zod": "^4.4.3"
29
+ "zod": "4.6.5"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/node": "^25.6.2",
33
- "bumpp": "^11.1.0",
34
- "tsdown": "^0.22.0",
35
- "typescript": "^6.0.3",
36
- "vitest": "^4.1.7"
33
+ "better-auth": "1.7.5",
34
+ "bumpp": "11.1.0",
35
+ "tsdown": "0.23.0",
36
+ "typescript": "7.0.2",
37
+ "vitest": "4.1.11"
37
38
  },
38
39
  "peerDependencies": {
39
- "better-auth": "^1.5.0"
40
+ "better-auth": "^1.7.5"
40
41
  },
41
42
  "scripts": {
42
43
  "build": "tsdown",
43
44
  "dev": "tsdown --watch",
44
45
  "test": "vitest",
45
- "typecheck": "tsc --noEmit"
46
+ "typecheck": "tsc --noEmit",
47
+ "release": "bumpp"
46
48
  }
47
49
  }