better-auth-lead 0.0.1-dev.2 → 0.1.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/README.md +50 -0
- package/dist/client.d.mts +2 -2
- package/dist/client.mjs +2 -3
- package/dist/client.mjs.map +1 -1
- package/dist/{error-codes-d1rquQlA.mjs → error-codes-CZUPEOrE.mjs} +4 -4
- package/dist/{error-codes-d1rquQlA.mjs.map → error-codes-CZUPEOrE.mjs.map} +1 -1
- package/dist/index-B-BhgW_e.d.mts +206 -0
- package/dist/index.d.mts +2 -100
- package/dist/index.mjs +21 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/dist/type-KTJzD7Eo.d.mts +0 -98
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ npm install better-auth-lead
|
|
|
11
11
|
pnpm add better-auth-lead
|
|
12
12
|
# yarn
|
|
13
13
|
yarn add better-auth-lead
|
|
14
|
+
# bun
|
|
15
|
+
bun add better-auth-lead
|
|
14
16
|
```
|
|
15
17
|
|
|
16
18
|
Add the plugin to your auth config
|
|
@@ -28,7 +30,14 @@ const betterAuth = createBetterAuth({
|
|
|
28
30
|
Run better auth migration to create the lead table:
|
|
29
31
|
|
|
30
32
|
```bash
|
|
33
|
+
# npm
|
|
31
34
|
npx auth@latest generate
|
|
35
|
+
# pnpm
|
|
36
|
+
pnpm dlx auth@latest generate
|
|
37
|
+
# yarn
|
|
38
|
+
yarn dlx auth@latest generate
|
|
39
|
+
# bun
|
|
40
|
+
bun x auth@latest generate
|
|
32
41
|
```
|
|
33
42
|
|
|
34
43
|
Add the lead plugin to your auth client:
|
|
@@ -99,6 +108,14 @@ const { data, error } = await authClient.lead.update({
|
|
|
99
108
|
|
|
100
109
|
### Email Verification
|
|
101
110
|
|
|
111
|
+
To enable email verification, you need to pass a function that sends a verification email with a link. The `sendVerificationEmail` takes a data object with the following properties:
|
|
112
|
+
|
|
113
|
+
- `email`: The lead email.
|
|
114
|
+
- `url`: The URL to send to the user which contains the token.
|
|
115
|
+
- `token`: A verification token used to complete the email verification.
|
|
116
|
+
|
|
117
|
+
and a `request` object as the second parameter.
|
|
118
|
+
|
|
102
119
|
```ts
|
|
103
120
|
// server/auth.ts
|
|
104
121
|
import { betterAuth } from 'better-auth';
|
|
@@ -115,6 +132,10 @@ export const auth = betterAuth({
|
|
|
115
132
|
text: `Click the link to verify your email: ${url}`,
|
|
116
133
|
});
|
|
117
134
|
},
|
|
135
|
+
onEmailVerified: async ({ lead }) => {
|
|
136
|
+
// do something when a lead's email is verified
|
|
137
|
+
console.log(`Lead ${lead.email} has been verified!`);
|
|
138
|
+
},
|
|
118
139
|
}),
|
|
119
140
|
],
|
|
120
141
|
});
|
|
@@ -122,6 +143,35 @@ export const auth = betterAuth({
|
|
|
122
143
|
|
|
123
144
|
> Avoid awaiting the email sending to prevent timing attacks.
|
|
124
145
|
|
|
146
|
+
Additionally, you can provide an `onEmailVerified` callback to execute logic after a lead's email is verified.
|
|
147
|
+
|
|
148
|
+
### Metadata Validation
|
|
149
|
+
|
|
150
|
+
To validate and parse metadata, you can pass a Standard Schema compatible schema (e.g. Zod, Valibot, ArkType).
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
// server/auth.ts
|
|
154
|
+
import { betterAuth } from 'better-auth';
|
|
155
|
+
import { lead } from 'better-auth-lead';
|
|
156
|
+
import * as z from 'zod';
|
|
157
|
+
|
|
158
|
+
const metadataSchema = z.object({
|
|
159
|
+
preferences: z.enum(['engineering', 'marketing', 'design']),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
export const auth = betterAuth({
|
|
163
|
+
plugins: [
|
|
164
|
+
lead({
|
|
165
|
+
metadata: {
|
|
166
|
+
validationSchema: metadataSchema,
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
],
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
If the schema validation fails, the API `subscribe` and `update` routes will return a `400 Bad Request` error with `INVALID_METADATA`.
|
|
174
|
+
|
|
125
175
|
## Schema
|
|
126
176
|
|
|
127
177
|
### Lead
|
package/dist/client.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import "./
|
|
2
|
-
import { lead } from "./index.mjs";
|
|
1
|
+
import { t as lead } from "./index-B-BhgW_e.mjs";
|
|
3
2
|
import * as better_auth0 from "better-auth";
|
|
4
3
|
|
|
5
4
|
//#region src/client.d.ts
|
|
@@ -10,6 +9,7 @@ declare const leadClient: () => {
|
|
|
10
9
|
INVALID_EMAIL: better_auth0.RawError<"INVALID_EMAIL">;
|
|
11
10
|
INVALID_TOKEN: better_auth0.RawError<"INVALID_TOKEN">;
|
|
12
11
|
TOKEN_EXPIRED: better_auth0.RawError<"TOKEN_EXPIRED">;
|
|
12
|
+
INVALID_METADATA: better_auth0.RawError<"INVALID_METADATA">;
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
15
|
//#endregion
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { t as LEAD_ERROR_CODES } from "./error-codes-
|
|
2
|
-
|
|
1
|
+
import { t as LEAD_ERROR_CODES } from "./error-codes-CZUPEOrE.mjs";
|
|
3
2
|
//#region src/client.ts
|
|
4
3
|
const leadClient = () => {
|
|
5
4
|
return {
|
|
@@ -8,7 +7,7 @@ const leadClient = () => {
|
|
|
8
7
|
$ERROR_CODES: LEAD_ERROR_CODES
|
|
9
8
|
};
|
|
10
9
|
};
|
|
11
|
-
|
|
12
10
|
//#endregion
|
|
13
11
|
export { leadClient };
|
|
12
|
+
|
|
14
13
|
//# sourceMappingURL=client.mjs.map
|
package/dist/client.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from 'better-auth/client';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport type { lead } from './index';\n\nexport const leadClient = () => {\n return {\n id: 'lead',\n $InferServerPlugin: {} as ReturnType<typeof lead>,\n $ERROR_CODES: LEAD_ERROR_CODES,\n } satisfies BetterAuthClientPlugin;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { BetterAuthClientPlugin } from 'better-auth/client';\n\nimport { LEAD_ERROR_CODES } from './error-codes';\nimport type { lead } from './index';\n\nexport const leadClient = () => {\n return {\n id: 'lead',\n $InferServerPlugin: {} as ReturnType<typeof lead>,\n $ERROR_CODES: LEAD_ERROR_CODES,\n } satisfies BetterAuthClientPlugin;\n};\n"],"mappings":";;AAKA,MAAa,mBAAmB;AAC9B,QAAO;EACL,IAAI;EACJ,oBAAoB,EAAE;EACtB,cAAc;EACf"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineErrorCodes } from "better-auth";
|
|
2
|
-
|
|
3
2
|
//#region src/error-codes.ts
|
|
4
3
|
const LEAD_ERROR_CODES = defineErrorCodes({
|
|
5
4
|
INVALID_EMAIL: "Invalid email",
|
|
6
5
|
INVALID_TOKEN: "Invalid token",
|
|
7
|
-
TOKEN_EXPIRED: "Token expired"
|
|
6
|
+
TOKEN_EXPIRED: "Token expired",
|
|
7
|
+
INVALID_METADATA: "Invalid metadata"
|
|
8
8
|
});
|
|
9
|
-
|
|
10
9
|
//#endregion
|
|
11
10
|
export { LEAD_ERROR_CODES as t };
|
|
12
|
-
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=error-codes-CZUPEOrE.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-codes-
|
|
1
|
+
{"version":3,"file":"error-codes-CZUPEOrE.mjs","names":[],"sources":["../src/error-codes.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});\n"],"mappings":";;AAEA,MAAa,mBAAmB,iBAAiB;CAC/C,eAAe;CACf,eAAe;CACf,eAAe;CACf,kBAAkB;CACnB,CAAC"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import * as better_auth0 from "better-auth";
|
|
2
|
+
import { InferOptionSchema, StandardSchemaV1 } from "better-auth";
|
|
3
|
+
import * as zod from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/schema.d.ts
|
|
6
|
+
declare const lead$1: {
|
|
7
|
+
lead: {
|
|
8
|
+
fields: {
|
|
9
|
+
createdAt: {
|
|
10
|
+
type: "date";
|
|
11
|
+
defaultValue: () => Date;
|
|
12
|
+
required: true;
|
|
13
|
+
input: false;
|
|
14
|
+
};
|
|
15
|
+
updatedAt: {
|
|
16
|
+
type: "date";
|
|
17
|
+
defaultValue: () => Date;
|
|
18
|
+
onUpdate: () => Date;
|
|
19
|
+
required: true;
|
|
20
|
+
input: false;
|
|
21
|
+
};
|
|
22
|
+
email: {
|
|
23
|
+
type: "string";
|
|
24
|
+
required: true;
|
|
25
|
+
unique: true;
|
|
26
|
+
};
|
|
27
|
+
emailVerified: {
|
|
28
|
+
type: "boolean";
|
|
29
|
+
defaultValue: false;
|
|
30
|
+
required: true;
|
|
31
|
+
input: false;
|
|
32
|
+
};
|
|
33
|
+
metadata: {
|
|
34
|
+
type: "string";
|
|
35
|
+
required: false;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/type.d.ts
|
|
42
|
+
interface LeadOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Send a verification email
|
|
45
|
+
* @param data the data object
|
|
46
|
+
* @param request the request object
|
|
47
|
+
*/
|
|
48
|
+
sendVerificationEmail?: (
|
|
49
|
+
/**
|
|
50
|
+
* @param email the email to send the verification email to
|
|
51
|
+
* @param url the verification url
|
|
52
|
+
* @param token the verification token
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
data: {
|
|
56
|
+
email: string;
|
|
57
|
+
url: string;
|
|
58
|
+
token: string;
|
|
59
|
+
}, request?: Request) => Promise<void>;
|
|
60
|
+
onEmailVerified?: (
|
|
61
|
+
/**
|
|
62
|
+
* @param lead the lead that was verified
|
|
63
|
+
*/
|
|
64
|
+
|
|
65
|
+
data: {
|
|
66
|
+
lead: Lead;
|
|
67
|
+
}, request?: Request) => Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Number of seconds the verification token is
|
|
70
|
+
* valid for.
|
|
71
|
+
* @default 3600 seconds (1 hour)
|
|
72
|
+
*/
|
|
73
|
+
expiresIn?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Rate limit configuration for /lead/subscribe and /lead/resend endpoints.
|
|
76
|
+
*/
|
|
77
|
+
rateLimit?: {
|
|
78
|
+
/**
|
|
79
|
+
* Time window in seconds for which the rate limit applies.
|
|
80
|
+
* @default 10 seconds
|
|
81
|
+
*/
|
|
82
|
+
window: number;
|
|
83
|
+
/**
|
|
84
|
+
* Maximum number of requests allowed within the time window.
|
|
85
|
+
* @default 3 requests
|
|
86
|
+
*/
|
|
87
|
+
max: number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Schema for the lead plugin
|
|
91
|
+
*/
|
|
92
|
+
schema?: InferOptionSchema<typeof lead$1> | undefined;
|
|
93
|
+
metadata?: {
|
|
94
|
+
validationSchema?: StandardSchemaV1;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
interface Lead {
|
|
98
|
+
/**
|
|
99
|
+
* Database identifier
|
|
100
|
+
*/
|
|
101
|
+
id: string;
|
|
102
|
+
createdAt: Date;
|
|
103
|
+
updatedAt: Date;
|
|
104
|
+
email: string;
|
|
105
|
+
emailVerified: boolean;
|
|
106
|
+
metadata?: string;
|
|
107
|
+
}
|
|
108
|
+
type LeadPayload = Omit<Lead, 'id' | 'createdAt' | 'updatedAt' | 'emailVerified'>;
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/index.d.ts
|
|
111
|
+
declare const lead: <O extends LeadOptions>(options?: O) => {
|
|
112
|
+
id: "lead";
|
|
113
|
+
schema: {
|
|
114
|
+
lead: {
|
|
115
|
+
fields: {
|
|
116
|
+
createdAt: {
|
|
117
|
+
type: "date";
|
|
118
|
+
defaultValue: () => Date;
|
|
119
|
+
required: true;
|
|
120
|
+
input: false;
|
|
121
|
+
};
|
|
122
|
+
updatedAt: {
|
|
123
|
+
type: "date";
|
|
124
|
+
defaultValue: () => Date;
|
|
125
|
+
onUpdate: () => Date;
|
|
126
|
+
required: true;
|
|
127
|
+
input: false;
|
|
128
|
+
};
|
|
129
|
+
email: {
|
|
130
|
+
type: "string";
|
|
131
|
+
required: true;
|
|
132
|
+
unique: true;
|
|
133
|
+
};
|
|
134
|
+
emailVerified: {
|
|
135
|
+
type: "boolean";
|
|
136
|
+
defaultValue: false;
|
|
137
|
+
required: true;
|
|
138
|
+
input: false;
|
|
139
|
+
};
|
|
140
|
+
metadata: {
|
|
141
|
+
type: "string";
|
|
142
|
+
required: false;
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
};
|
|
147
|
+
endpoints: {
|
|
148
|
+
subscribe: better_auth0.StrictEndpoint<"/lead/subscribe", {
|
|
149
|
+
method: "POST";
|
|
150
|
+
body: zod.ZodObject<{
|
|
151
|
+
email: zod.ZodString;
|
|
152
|
+
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
|
|
153
|
+
}, better_auth0.$strip>;
|
|
154
|
+
}, {
|
|
155
|
+
status: boolean;
|
|
156
|
+
}>;
|
|
157
|
+
verify: better_auth0.StrictEndpoint<"/lead/verify", {
|
|
158
|
+
method: "GET";
|
|
159
|
+
query: zod.ZodObject<{
|
|
160
|
+
token: zod.ZodString;
|
|
161
|
+
}, better_auth0.$strip>;
|
|
162
|
+
}, {
|
|
163
|
+
status: boolean;
|
|
164
|
+
}>;
|
|
165
|
+
unsubscribe: better_auth0.StrictEndpoint<"/lead/unsubscribe", {
|
|
166
|
+
method: "POST";
|
|
167
|
+
body: zod.ZodObject<{
|
|
168
|
+
id: zod.ZodString;
|
|
169
|
+
}, better_auth0.$strip>;
|
|
170
|
+
}, {
|
|
171
|
+
status: boolean;
|
|
172
|
+
}>;
|
|
173
|
+
resend: better_auth0.StrictEndpoint<"/lead/resend", {
|
|
174
|
+
method: "POST";
|
|
175
|
+
body: zod.ZodObject<{
|
|
176
|
+
email: zod.ZodString;
|
|
177
|
+
}, better_auth0.$strip>;
|
|
178
|
+
}, {
|
|
179
|
+
status: boolean;
|
|
180
|
+
}>;
|
|
181
|
+
update: better_auth0.StrictEndpoint<"/lead/update", {
|
|
182
|
+
method: "POST";
|
|
183
|
+
body: zod.ZodObject<{
|
|
184
|
+
id: zod.ZodString;
|
|
185
|
+
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
|
|
186
|
+
}, better_auth0.$strip>;
|
|
187
|
+
}, {
|
|
188
|
+
status: boolean;
|
|
189
|
+
}>;
|
|
190
|
+
};
|
|
191
|
+
options: NoInfer<O>;
|
|
192
|
+
rateLimit: {
|
|
193
|
+
pathMatcher: (path: string) => boolean;
|
|
194
|
+
window: number;
|
|
195
|
+
max: number;
|
|
196
|
+
}[];
|
|
197
|
+
$ERROR_CODES: {
|
|
198
|
+
INVALID_EMAIL: better_auth0.RawError<"INVALID_EMAIL">;
|
|
199
|
+
INVALID_TOKEN: better_auth0.RawError<"INVALID_TOKEN">;
|
|
200
|
+
TOKEN_EXPIRED: better_auth0.RawError<"TOKEN_EXPIRED">;
|
|
201
|
+
INVALID_METADATA: better_auth0.RawError<"INVALID_METADATA">;
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
//#endregion
|
|
205
|
+
export { LeadPayload as i, Lead as n, LeadOptions as r, lead as t };
|
|
206
|
+
//# sourceMappingURL=index-B-BhgW_e.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,100 +1,2 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
|
|
3
|
-
import * as zod from "zod";
|
|
4
|
-
|
|
5
|
-
//#region src/index.d.ts
|
|
6
|
-
declare const lead: <O extends LeadOptions>(options?: O) => {
|
|
7
|
-
id: "lead";
|
|
8
|
-
schema: {
|
|
9
|
-
lead: {
|
|
10
|
-
fields: {
|
|
11
|
-
createdAt: {
|
|
12
|
-
type: "date";
|
|
13
|
-
defaultValue: () => Date;
|
|
14
|
-
required: true;
|
|
15
|
-
input: false;
|
|
16
|
-
};
|
|
17
|
-
updatedAt: {
|
|
18
|
-
type: "date";
|
|
19
|
-
defaultValue: () => Date;
|
|
20
|
-
onUpdate: () => Date;
|
|
21
|
-
required: true;
|
|
22
|
-
input: false;
|
|
23
|
-
};
|
|
24
|
-
email: {
|
|
25
|
-
type: "string";
|
|
26
|
-
required: true;
|
|
27
|
-
unique: true;
|
|
28
|
-
};
|
|
29
|
-
emailVerified: {
|
|
30
|
-
type: "boolean";
|
|
31
|
-
defaultValue: false;
|
|
32
|
-
required: true;
|
|
33
|
-
input: false;
|
|
34
|
-
};
|
|
35
|
-
metadata: {
|
|
36
|
-
type: "string";
|
|
37
|
-
required: false;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
endpoints: {
|
|
43
|
-
subscribe: better_auth0.StrictEndpoint<"/lead/subscribe", {
|
|
44
|
-
method: "POST";
|
|
45
|
-
body: zod.ZodObject<{
|
|
46
|
-
email: zod.ZodString;
|
|
47
|
-
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
|
|
48
|
-
}, better_auth0.$strip>;
|
|
49
|
-
}, {
|
|
50
|
-
status: boolean;
|
|
51
|
-
}>;
|
|
52
|
-
verify: better_auth0.StrictEndpoint<"/lead/verify", {
|
|
53
|
-
method: "GET";
|
|
54
|
-
query: zod.ZodObject<{
|
|
55
|
-
token: zod.ZodString;
|
|
56
|
-
}, better_auth0.$strip>;
|
|
57
|
-
}, {
|
|
58
|
-
status: boolean;
|
|
59
|
-
}>;
|
|
60
|
-
unsubscribe: better_auth0.StrictEndpoint<"/lead/unsubscribe", {
|
|
61
|
-
method: "POST";
|
|
62
|
-
body: zod.ZodObject<{
|
|
63
|
-
id: zod.ZodString;
|
|
64
|
-
}, better_auth0.$strip>;
|
|
65
|
-
}, {
|
|
66
|
-
status: boolean;
|
|
67
|
-
}>;
|
|
68
|
-
resend: better_auth0.StrictEndpoint<"/lead/resend", {
|
|
69
|
-
method: "POST";
|
|
70
|
-
body: zod.ZodObject<{
|
|
71
|
-
email: zod.ZodString;
|
|
72
|
-
}, better_auth0.$strip>;
|
|
73
|
-
}, {
|
|
74
|
-
status: boolean;
|
|
75
|
-
}>;
|
|
76
|
-
update: better_auth0.StrictEndpoint<"/lead/update", {
|
|
77
|
-
method: "POST";
|
|
78
|
-
body: zod.ZodObject<{
|
|
79
|
-
id: zod.ZodString;
|
|
80
|
-
metadata: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
|
|
81
|
-
}, better_auth0.$strip>;
|
|
82
|
-
}, {
|
|
83
|
-
status: boolean;
|
|
84
|
-
}>;
|
|
85
|
-
};
|
|
86
|
-
options: NoInfer<O>;
|
|
87
|
-
rateLimit: {
|
|
88
|
-
pathMatcher: (path: string) => boolean;
|
|
89
|
-
window: number;
|
|
90
|
-
max: number;
|
|
91
|
-
}[];
|
|
92
|
-
$ERROR_CODES: {
|
|
93
|
-
INVALID_EMAIL: better_auth0.RawError<"INVALID_EMAIL">;
|
|
94
|
-
INVALID_TOKEN: better_auth0.RawError<"INVALID_TOKEN">;
|
|
95
|
-
TOKEN_EXPIRED: better_auth0.RawError<"TOKEN_EXPIRED">;
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
//#endregion
|
|
99
|
-
export { Lead, LeadOptions, LeadPayload, lead };
|
|
100
|
-
//# sourceMappingURL=index.d.mts.map
|
|
1
|
+
import { i as LeadPayload, n as Lead, r as LeadOptions, t as lead } from "./index-B-BhgW_e.mjs";
|
|
2
|
+
export { Lead, LeadOptions, LeadPayload, lead };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { t as LEAD_ERROR_CODES } from "./error-codes-
|
|
2
|
-
import "better-auth";
|
|
1
|
+
import { t as LEAD_ERROR_CODES } from "./error-codes-CZUPEOrE.mjs";
|
|
2
|
+
import { BASE_ERROR_CODES } from "better-auth";
|
|
3
3
|
import { APIError, createAuthEndpoint, createEmailVerificationToken } from "better-auth/api";
|
|
4
4
|
import { jwtVerify } from "jose";
|
|
5
5
|
import { JWTExpired } from "jose/errors";
|
|
6
6
|
import * as z from "zod";
|
|
7
7
|
import { mergeSchema } from "better-auth/db";
|
|
8
|
-
|
|
9
8
|
//#region src/routes.ts
|
|
10
9
|
const subscribeSchema = z.object({
|
|
11
10
|
email: z.string().meta({ description: "Email address of the lead" }),
|
|
@@ -15,8 +14,9 @@ const subscribe = (options) => createAuthEndpoint("/lead/subscribe", {
|
|
|
15
14
|
method: "POST",
|
|
16
15
|
body: subscribeSchema
|
|
17
16
|
}, async (ctx) => {
|
|
18
|
-
const { email
|
|
17
|
+
const { email } = ctx.body;
|
|
19
18
|
if (!z.email().safeParse(email).success) throw APIError.from("BAD_REQUEST", LEAD_ERROR_CODES.INVALID_EMAIL);
|
|
19
|
+
const metadata = validateMetadata(options, ctx.body.metadata, ctx.context.logger);
|
|
20
20
|
const normalizedEmail = email.toLowerCase();
|
|
21
21
|
let lead = await ctx.context.adapter.findOne({
|
|
22
22
|
model: "lead",
|
|
@@ -68,7 +68,7 @@ const verify = (options) => createAuthEndpoint("/lead/verify", {
|
|
|
68
68
|
throw APIError.from("UNAUTHORIZED", LEAD_ERROR_CODES.INVALID_TOKEN);
|
|
69
69
|
}
|
|
70
70
|
const parsed = subscribeSchema.parse(jwt.payload);
|
|
71
|
-
|
|
71
|
+
let lead = await ctx.context.adapter.findOne({
|
|
72
72
|
model: "lead",
|
|
73
73
|
where: [{
|
|
74
74
|
field: "email",
|
|
@@ -77,7 +77,7 @@ const verify = (options) => createAuthEndpoint("/lead/verify", {
|
|
|
77
77
|
});
|
|
78
78
|
if (!lead) return ctx.json({ status: true });
|
|
79
79
|
if (lead.emailVerified) return ctx.json({ status: true });
|
|
80
|
-
await ctx.context.adapter.update({
|
|
80
|
+
lead = await ctx.context.adapter.update({
|
|
81
81
|
model: "lead",
|
|
82
82
|
where: [{
|
|
83
83
|
field: "email",
|
|
@@ -85,6 +85,8 @@ const verify = (options) => createAuthEndpoint("/lead/verify", {
|
|
|
85
85
|
}],
|
|
86
86
|
update: { emailVerified: true }
|
|
87
87
|
});
|
|
88
|
+
if (!lead) return ctx.json({ status: true });
|
|
89
|
+
if (options.onEmailVerified) await ctx.context.runInBackgroundOrAwait(options.onEmailVerified({ lead }, ctx.request));
|
|
88
90
|
return ctx.json({ status: true });
|
|
89
91
|
});
|
|
90
92
|
const unsubscribeSchema = z.object({ id: z.string().meta({ description: "The id of the lead to unsubscribe" }) });
|
|
@@ -144,7 +146,7 @@ const update = (options) => createAuthEndpoint("/lead/update", {
|
|
|
144
146
|
method: "POST",
|
|
145
147
|
body: updateSchema
|
|
146
148
|
}, async (ctx) => {
|
|
147
|
-
const { id
|
|
149
|
+
const { id } = ctx.body;
|
|
148
150
|
if (!await ctx.context.adapter.findOne({
|
|
149
151
|
model: "lead",
|
|
150
152
|
where: [{
|
|
@@ -152,6 +154,7 @@ const update = (options) => createAuthEndpoint("/lead/update", {
|
|
|
152
154
|
value: id
|
|
153
155
|
}]
|
|
154
156
|
})) return ctx.json({ status: true });
|
|
157
|
+
const metadata = validateMetadata(options, ctx.body.metadata, ctx.context.logger);
|
|
155
158
|
await ctx.context.adapter.update({
|
|
156
159
|
model: "lead",
|
|
157
160
|
where: [{
|
|
@@ -162,7 +165,16 @@ const update = (options) => createAuthEndpoint("/lead/update", {
|
|
|
162
165
|
});
|
|
163
166
|
return ctx.json({ status: true });
|
|
164
167
|
});
|
|
165
|
-
|
|
168
|
+
function validateMetadata(options, metadata, logger) {
|
|
169
|
+
if (!metadata || !options.metadata?.validationSchema) return metadata;
|
|
170
|
+
const validationResult = options.metadata.validationSchema["~standard"].validate(metadata);
|
|
171
|
+
if (validationResult instanceof Promise) throw APIError.from("INTERNAL_SERVER_ERROR", BASE_ERROR_CODES.ASYNC_VALIDATION_NOT_SUPPORTED);
|
|
172
|
+
if (validationResult.issues) {
|
|
173
|
+
logger.error("Invalid metadata", validationResult.issues);
|
|
174
|
+
throw APIError.from("BAD_REQUEST", LEAD_ERROR_CODES.INVALID_METADATA);
|
|
175
|
+
}
|
|
176
|
+
return validationResult.value;
|
|
177
|
+
}
|
|
166
178
|
//#endregion
|
|
167
179
|
//#region src/schema.ts
|
|
168
180
|
const lead$1 = { lead: { fields: {
|
|
@@ -198,7 +210,6 @@ const lead$1 = { lead: { fields: {
|
|
|
198
210
|
const getSchema = (options) => {
|
|
199
211
|
return mergeSchema(lead$1, options.schema);
|
|
200
212
|
};
|
|
201
|
-
|
|
202
213
|
//#endregion
|
|
203
214
|
//#region src/index.ts
|
|
204
215
|
const lead = (options = {}) => {
|
|
@@ -221,7 +232,7 @@ const lead = (options = {}) => {
|
|
|
221
232
|
$ERROR_CODES: LEAD_ERROR_CODES
|
|
222
233
|
};
|
|
223
234
|
};
|
|
224
|
-
|
|
225
235
|
//#endregion
|
|
226
236
|
export { lead };
|
|
237
|
+
|
|
227
238
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["lead"],"sources":["../src/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["import { APIError, createAuthEndpoint, createEmailVerificationToken } from 'better-auth/api';\nimport { 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\nconst subscribeSchema = z.object({\n email: z.string().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 },\n async (ctx) => {\n const { email, metadata } = ctx.body;\n\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 const normalizedEmail = email.toLowerCase();\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n\n if (!lead) {\n try {\n lead = await ctx.context.adapter.create<LeadPayload, Lead>({\n model: 'lead',\n data: {\n email: normalizedEmail,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\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: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n }\n }\n\n if (options.sendVerificationEmail && lead && !lead.emailVerified) {\n const token = await createEmailVerificationToken(\n ctx.context.secret,\n normalizedEmail,\n undefined,\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n\n await ctx.context.runInBackgroundOrAwait(\n options.sendVerificationEmail({ email: normalizedEmail, url, token }, ctx.request),\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 parsed = subscribeSchema.parse(jwt.payload);\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: parsed.email,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (lead.emailVerified) {\n return ctx.json({\n status: true,\n });\n }\n\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: parsed.email,\n },\n ],\n update: {\n emailVerified: true,\n },\n });\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst unsubscribeSchema = z.object({\n id: z.string().meta({\n description: 'The id of the lead to unsubscribe',\n }),\n});\n\nexport const unsubscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe',\n {\n method: 'POST',\n body: unsubscribeSchema,\n },\n async (ctx) => {\n const { id } = ctx.body;\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\nconst resendSchema = z.object({\n email: z.string().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;\n\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 const normalizedEmail = email.toLowerCase();\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.sendVerificationEmail && lead && !lead.emailVerified) {\n const token = await createEmailVerificationToken(\n ctx.context.secret,\n normalizedEmail,\n undefined,\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n\n await ctx.context.runInBackgroundOrAwait(\n options.sendVerificationEmail({ email: normalizedEmail, url, token }, ctx.request),\n );\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst updateSchema = z.object({\n id: z.string().meta({\n description: 'The id of the lead to update',\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 update = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/update',\n {\n method: 'POST',\n body: updateSchema,\n },\n async (ctx) => {\n const { id, metadata } = ctx.body;\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.update<Lead>({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n update: {\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\n });\n\n return ctx.json({\n status: true,\n });\n },\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: true,\n unique: true,\n },\n emailVerified: {\n type: 'boolean',\n defaultValue: false,\n required: true,\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 { resend, subscribe, unsubscribe, update, verify } from './routes';\nimport { getSchema } from './schema';\nimport type { LeadOptions } from './type';\n\nexport const lead = <O extends LeadOptions>(options: O = {} as O) => {\n return {\n id: 'lead',\n schema: getSchema(options),\n endpoints: {\n subscribe: subscribe(options),\n verify: verify(options),\n unsubscribe: unsubscribe(options),\n resend: resend(options),\n update: update(options),\n },\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/routes.ts","../src/schema.ts","../src/index.ts"],"sourcesContent":["import { BASE_ERROR_CODES, type InternalLogger } from 'better-auth';\nimport { APIError, createAuthEndpoint, createEmailVerificationToken } from 'better-auth/api';\nimport { 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\nconst subscribeSchema = z.object({\n email: z.string().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 },\n async (ctx) => {\n const { email } = ctx.body;\n\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 const metadata = validateMetadata(options, ctx.body.metadata, ctx.context.logger);\n\n const normalizedEmail = email.toLowerCase();\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n\n if (!lead) {\n try {\n lead = await ctx.context.adapter.create<LeadPayload, Lead>({\n model: 'lead',\n data: {\n email: normalizedEmail,\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\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: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n }\n }\n\n if (options.sendVerificationEmail && lead && !lead.emailVerified) {\n const token = await createEmailVerificationToken(\n ctx.context.secret,\n normalizedEmail,\n undefined,\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n\n await ctx.context.runInBackgroundOrAwait(\n options.sendVerificationEmail({ email: normalizedEmail, url, token }, ctx.request),\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 parsed = subscribeSchema.parse(jwt.payload);\n\n let lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: parsed.email,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (lead.emailVerified) {\n return ctx.json({\n status: true,\n });\n }\n\n lead = await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: parsed.email,\n },\n ],\n update: {\n emailVerified: true,\n },\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.onEmailVerified) {\n await ctx.context.runInBackgroundOrAwait(options.onEmailVerified({ lead }, ctx.request));\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst unsubscribeSchema = z.object({\n id: z.string().meta({\n description: 'The id of the lead to unsubscribe',\n }),\n});\n\nexport const unsubscribe = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/unsubscribe',\n {\n method: 'POST',\n body: unsubscribeSchema,\n },\n async (ctx) => {\n const { id } = ctx.body;\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\nconst resendSchema = z.object({\n email: z.string().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;\n\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 const normalizedEmail = email.toLowerCase();\n\n const lead = await ctx.context.adapter.findOne<Lead>({\n model: 'lead',\n where: [\n {\n field: 'email',\n value: normalizedEmail,\n },\n ],\n });\n\n if (!lead) {\n return ctx.json({\n status: true,\n });\n }\n\n if (options.sendVerificationEmail && lead && !lead.emailVerified) {\n const token = await createEmailVerificationToken(\n ctx.context.secret,\n normalizedEmail,\n undefined,\n options.expiresIn ?? 3600,\n );\n const url = `${ctx.context.baseURL}/lead/verify?token=${token}`;\n\n await ctx.context.runInBackgroundOrAwait(\n options.sendVerificationEmail({ email: normalizedEmail, url, token }, ctx.request),\n );\n }\n\n return ctx.json({\n status: true,\n });\n },\n );\n\nconst updateSchema = z.object({\n id: z.string().meta({\n description: 'The id of the lead to update',\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 update = <O extends LeadOptions>(options: O) =>\n createAuthEndpoint(\n '/lead/update',\n {\n method: 'POST',\n body: updateSchema,\n },\n async (ctx) => {\n const { id } = ctx.body;\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 const metadata = validateMetadata(options, ctx.body.metadata, ctx.context.logger);\n\n await ctx.context.adapter.update<Lead>({\n model: 'lead',\n where: [\n {\n field: 'id',\n value: id,\n },\n ],\n update: {\n metadata: metadata ? JSON.stringify(metadata) : undefined,\n },\n });\n\n return ctx.json({\n status: true,\n });\n },\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: true,\n unique: true,\n },\n emailVerified: {\n type: 'boolean',\n defaultValue: false,\n required: true,\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 { resend, subscribe, unsubscribe, update, verify } from './routes';\nimport { getSchema } from './schema';\nimport type { LeadOptions } from './type';\n\nexport const lead = <O extends LeadOptions>(options: O = {} as O) => {\n return {\n id: 'lead',\n schema: getSchema(options),\n endpoints: {\n subscribe: subscribe(options),\n verify: verify(options),\n unsubscribe: unsubscribe(options),\n resend: resend(options),\n update: update(options),\n },\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.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Better Auth Lead plugin",
|
|
5
5
|
"homepage": "https://github.com/marcjulian/better-auth-plugins#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"./package.json": "./package.json"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"jose": "^6.1
|
|
28
|
+
"jose": "^6.2.1",
|
|
29
29
|
"zod": "^4.3.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@types/node": "^25.3.
|
|
32
|
+
"@types/node": "^25.3.5",
|
|
33
33
|
"bumpp": "^10.4.1",
|
|
34
|
-
"tsdown": "^0.
|
|
34
|
+
"tsdown": "^0.21.1",
|
|
35
35
|
"typescript": "^5.9.3",
|
|
36
36
|
"vitest": "^4.0.18"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"better-auth": "^1.5.
|
|
39
|
+
"better-auth": "^1.5.0"
|
|
40
40
|
},
|
|
41
41
|
"scripts": {
|
|
42
42
|
"build": "tsdown",
|
package/dist/type-KTJzD7Eo.d.mts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { InferOptionSchema } from "better-auth";
|
|
2
|
-
|
|
3
|
-
//#region src/schema.d.ts
|
|
4
|
-
declare const lead: {
|
|
5
|
-
lead: {
|
|
6
|
-
fields: {
|
|
7
|
-
createdAt: {
|
|
8
|
-
type: "date";
|
|
9
|
-
defaultValue: () => Date;
|
|
10
|
-
required: true;
|
|
11
|
-
input: false;
|
|
12
|
-
};
|
|
13
|
-
updatedAt: {
|
|
14
|
-
type: "date";
|
|
15
|
-
defaultValue: () => Date;
|
|
16
|
-
onUpdate: () => Date;
|
|
17
|
-
required: true;
|
|
18
|
-
input: false;
|
|
19
|
-
};
|
|
20
|
-
email: {
|
|
21
|
-
type: "string";
|
|
22
|
-
required: true;
|
|
23
|
-
unique: true;
|
|
24
|
-
};
|
|
25
|
-
emailVerified: {
|
|
26
|
-
type: "boolean";
|
|
27
|
-
defaultValue: false;
|
|
28
|
-
required: true;
|
|
29
|
-
input: false;
|
|
30
|
-
};
|
|
31
|
-
metadata: {
|
|
32
|
-
type: "string";
|
|
33
|
-
required: false;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
//#endregion
|
|
39
|
-
//#region src/type.d.ts
|
|
40
|
-
interface LeadOptions {
|
|
41
|
-
/**
|
|
42
|
-
* Send a verification email
|
|
43
|
-
* @param data the data object
|
|
44
|
-
* @param request the request object
|
|
45
|
-
*/
|
|
46
|
-
sendVerificationEmail?: (
|
|
47
|
-
/**
|
|
48
|
-
* @param email the email to send the verification email to
|
|
49
|
-
* @param url the verification url
|
|
50
|
-
* @param token the verification token
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
|
-
data: {
|
|
54
|
-
email: string;
|
|
55
|
-
url: string;
|
|
56
|
-
token: string;
|
|
57
|
-
}, request?: Request) => Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Number of seconds the verification token is
|
|
60
|
-
* valid for.
|
|
61
|
-
* @default 3600 seconds (1 hour)
|
|
62
|
-
*/
|
|
63
|
-
expiresIn?: number;
|
|
64
|
-
/**
|
|
65
|
-
* Rate limit configuration for /lead/subscribe and /lead/resend endpoints.
|
|
66
|
-
*/
|
|
67
|
-
rateLimit?: {
|
|
68
|
-
/**
|
|
69
|
-
* Time window in seconds for which the rate limit applies.
|
|
70
|
-
* @default 10 seconds
|
|
71
|
-
*/
|
|
72
|
-
window: number;
|
|
73
|
-
/**
|
|
74
|
-
* Maximum number of requests allowed within the time window.
|
|
75
|
-
* @default 3 requests
|
|
76
|
-
*/
|
|
77
|
-
max: number;
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Schema for the lead plugin
|
|
81
|
-
*/
|
|
82
|
-
schema?: InferOptionSchema<typeof lead> | undefined;
|
|
83
|
-
}
|
|
84
|
-
interface Lead {
|
|
85
|
-
/**
|
|
86
|
-
* Database identifier
|
|
87
|
-
*/
|
|
88
|
-
id: string;
|
|
89
|
-
createdAt: Date;
|
|
90
|
-
updatedAt: Date;
|
|
91
|
-
email: string;
|
|
92
|
-
emailVerified: boolean;
|
|
93
|
-
metadata?: string;
|
|
94
|
-
}
|
|
95
|
-
type LeadPayload = Omit<Lead, 'id' | 'createdAt' | 'updatedAt' | 'emailVerified'>;
|
|
96
|
-
//#endregion
|
|
97
|
-
export { LeadOptions as n, LeadPayload as r, Lead as t };
|
|
98
|
-
//# sourceMappingURL=type-KTJzD7Eo.d.mts.map
|