@farm.js/email 0.1.0-beta.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 +22 -0
- package/README.md +11 -0
- package/dist/client.d.ts +109 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +37 -0
- package/dist/index.d.ts +130 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +378 -0
- package/dist/schedule.d.ts +29 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/schedule.js +60 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Farm.js Team
|
|
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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @farm.js/email
|
|
2
|
+
|
|
3
|
+
Email and Resend integration for Farm.js
|
|
4
|
+
|
|
5
|
+
Farm.js is currently in beta.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @farm.js/email@beta
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
See the [Farm.js repository](https://github.com/farming-labs/farm.js) for documentation, examples, and support.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { ComponentProps, ComponentType } from "react";
|
|
2
|
+
import type { Attachment, Tag } from "resend";
|
|
3
|
+
import { api } from "@farm.js/core/client";
|
|
4
|
+
import { type InferPathInferredClientAPI, type PathInferredClientOperation } from "@farm.js/integration-utils/integration";
|
|
5
|
+
import type { FarmWebhookAckResult } from "@farm.js/integration-utils/webhooks";
|
|
6
|
+
import type { EmailScheduleWhen } from "./schedule.js";
|
|
7
|
+
export type { EmailScheduleDelay, EmailScheduleWhen } from "./schedule.js";
|
|
8
|
+
export type EmailTemplateComponent<TData> = ComponentType<TData> & {
|
|
9
|
+
PreviewProps?: TData;
|
|
10
|
+
};
|
|
11
|
+
export interface EmailTemplate<TData> {
|
|
12
|
+
component: EmailTemplateComponent<TData>;
|
|
13
|
+
subject: string | ((data: TData) => string | Promise<string>);
|
|
14
|
+
previewText?: string | ((data: TData) => string | Promise<string>);
|
|
15
|
+
from?: string | ((data: TData) => string | Promise<string>);
|
|
16
|
+
replyTo?: string | string[] | ((data: TData) => string | string[] | Promise<string | string[]>);
|
|
17
|
+
}
|
|
18
|
+
export type EmailTemplates = Record<string, EmailTemplate<any>>;
|
|
19
|
+
export type InferTemplateData<TTemplate> = TTemplate extends EmailTemplate<infer TData> ? TData : never;
|
|
20
|
+
export declare function template<TComponent extends EmailTemplateComponent<any>>(component: TComponent, config: Omit<EmailTemplate<ComponentProps<TComponent>>, "component">): EmailTemplate<ComponentProps<TComponent>>;
|
|
21
|
+
export interface EmailSendBaseInput {
|
|
22
|
+
to: string | string[];
|
|
23
|
+
cc?: string | string[];
|
|
24
|
+
bcc?: string | string[];
|
|
25
|
+
from?: string;
|
|
26
|
+
replyTo?: string | string[];
|
|
27
|
+
headers?: Record<string, string>;
|
|
28
|
+
tags?: Tag[];
|
|
29
|
+
attachments?: Attachment[];
|
|
30
|
+
topicId?: string | null;
|
|
31
|
+
scheduledAt?: string;
|
|
32
|
+
idempotencyKey?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface EmailScheduleBaseInput extends Omit<EmailSendBaseInput, "scheduledAt"> {
|
|
35
|
+
when: EmailScheduleWhen;
|
|
36
|
+
}
|
|
37
|
+
export type ResendEmailSendInput<TTemplates extends EmailTemplates> = {
|
|
38
|
+
[TTemplateId in keyof TTemplates & string]: EmailSendBaseInput & {
|
|
39
|
+
templateId: TTemplateId;
|
|
40
|
+
data: InferTemplateData<TTemplates[TTemplateId]>;
|
|
41
|
+
};
|
|
42
|
+
}[keyof TTemplates & string];
|
|
43
|
+
export type ResendEmailScheduleInput<TTemplates extends EmailTemplates> = {
|
|
44
|
+
[TTemplateId in keyof TTemplates & string]: EmailScheduleBaseInput & {
|
|
45
|
+
templateId: TTemplateId;
|
|
46
|
+
data: InferTemplateData<TTemplates[TTemplateId]>;
|
|
47
|
+
};
|
|
48
|
+
}[keyof TTemplates & string];
|
|
49
|
+
export type ResendEmailPreviewInput<TTemplates extends EmailTemplates> = {
|
|
50
|
+
[TTemplateId in keyof TTemplates & string]: {
|
|
51
|
+
templateId: TTemplateId;
|
|
52
|
+
data: InferTemplateData<TTemplates[TTemplateId]>;
|
|
53
|
+
};
|
|
54
|
+
}[keyof TTemplates & string];
|
|
55
|
+
export type ResendEmailSendResult<TTemplates extends EmailTemplates = EmailTemplates> = {
|
|
56
|
+
[TTemplateId in keyof TTemplates & string]: {
|
|
57
|
+
id: string;
|
|
58
|
+
provider: "resend";
|
|
59
|
+
templateId: TTemplateId;
|
|
60
|
+
from: string;
|
|
61
|
+
to: string[];
|
|
62
|
+
subject: string;
|
|
63
|
+
previewText: string | null;
|
|
64
|
+
};
|
|
65
|
+
}[keyof TTemplates & string];
|
|
66
|
+
export type ResendEmailScheduleResult<TTemplates extends EmailTemplates = EmailTemplates> = {
|
|
67
|
+
[TTemplateId in keyof TTemplates & string]: ResendEmailSendResult<TTemplates> & {
|
|
68
|
+
templateId: TTemplateId;
|
|
69
|
+
when: string;
|
|
70
|
+
};
|
|
71
|
+
}[keyof TTemplates & string];
|
|
72
|
+
export type ResendEmailPreviewResult<TTemplates extends EmailTemplates = EmailTemplates> = {
|
|
73
|
+
[TTemplateId in keyof TTemplates & string]: {
|
|
74
|
+
templateId: TTemplateId;
|
|
75
|
+
subject: string;
|
|
76
|
+
previewText: string | null;
|
|
77
|
+
html: string;
|
|
78
|
+
text: string;
|
|
79
|
+
};
|
|
80
|
+
}[keyof TTemplates & string];
|
|
81
|
+
export type ResendEmailTemplateInfo<TTemplates extends EmailTemplates = EmailTemplates> = {
|
|
82
|
+
[TTemplateId in keyof TTemplates & string]: {
|
|
83
|
+
id: TTemplateId;
|
|
84
|
+
hasPreviewText: boolean;
|
|
85
|
+
hasCustomFrom: boolean;
|
|
86
|
+
hasCustomReplyTo: boolean;
|
|
87
|
+
previewProps: InferTemplateData<TTemplates[TTemplateId]> | null;
|
|
88
|
+
};
|
|
89
|
+
}[keyof TTemplates & string];
|
|
90
|
+
export type ResendWebhookResult = FarmWebhookAckResult;
|
|
91
|
+
export interface ResendClientPathOptions {
|
|
92
|
+
sendPath?: string;
|
|
93
|
+
schedulePath?: string;
|
|
94
|
+
previewPath?: string;
|
|
95
|
+
templatesPath?: string;
|
|
96
|
+
}
|
|
97
|
+
type ResolvedResendClientPath<TPath extends string | undefined, TDefault extends string> = TPath extends string ? TPath : TDefault;
|
|
98
|
+
type ResendClientEntries<TTemplates extends EmailTemplates, TInput extends ResendClientPathOptions> = [
|
|
99
|
+
PathInferredClientOperation<ResolvedResendClientPath<TInput["sendPath"], "/api/email/send">, ReturnType<typeof api.post<ResendEmailSendInput<TTemplates>, ResendEmailSendResult<TTemplates>>>>,
|
|
100
|
+
PathInferredClientOperation<ResolvedResendClientPath<TInput["schedulePath"], "/api/email/schedule">, ReturnType<typeof api.post<ResendEmailScheduleInput<TTemplates>, ResendEmailScheduleResult<TTemplates>>>>,
|
|
101
|
+
PathInferredClientOperation<ResolvedResendClientPath<TInput["previewPath"], "/api/email/preview">, ReturnType<typeof api.post<ResendEmailPreviewInput<TTemplates>, ResendEmailPreviewResult<TTemplates>>>>,
|
|
102
|
+
PathInferredClientOperation<ResolvedResendClientPath<TInput["templatesPath"], "/api/email/templates">, ReturnType<typeof api.get<Array<ResendEmailTemplateInfo<TTemplates>>>>>
|
|
103
|
+
];
|
|
104
|
+
export type ResendClientAPI<TTemplates extends EmailTemplates, TInput extends ResendClientPathOptions = {}> = InferPathInferredClientAPI<ResendClientEntries<TTemplates, TInput>>;
|
|
105
|
+
export type ResendDefaultClientAPI<TTemplates extends EmailTemplates = EmailTemplates> = ResendClientAPI<TTemplates>;
|
|
106
|
+
export declare function createResendClientApi<TTemplates extends EmailTemplates>(): ResendDefaultClientAPI<TTemplates>;
|
|
107
|
+
export declare function createResendClientApi<TTemplates extends EmailTemplates, const TInput extends ResendClientPathOptions>(input: TInput): ResendClientAPI<TTemplates, TInput>;
|
|
108
|
+
export declare const resendClient: ResendDefaultClientAPI;
|
|
109
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { api } from "@farm.js/core/client";
|
|
2
|
+
import { createPathInferredClientApi, } from "@farm.js/integration-utils/integration";
|
|
3
|
+
export function template(component, config) {
|
|
4
|
+
return {
|
|
5
|
+
component,
|
|
6
|
+
...config,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function createResendClientApi(input) {
|
|
10
|
+
const sendPath = (input?.sendPath ?? "/api/email/send");
|
|
11
|
+
const schedulePath = (input?.schedulePath ?? "/api/email/schedule");
|
|
12
|
+
const previewPath = (input?.previewPath ?? "/api/email/preview");
|
|
13
|
+
const templatesPath = (input?.templatesPath ??
|
|
14
|
+
"/api/email/templates");
|
|
15
|
+
return createPathInferredClientApi({
|
|
16
|
+
path: sendPath,
|
|
17
|
+
operation: api.post(sendPath, {
|
|
18
|
+
responseFormat: "json",
|
|
19
|
+
}),
|
|
20
|
+
}, {
|
|
21
|
+
path: schedulePath,
|
|
22
|
+
operation: api.post(schedulePath, {
|
|
23
|
+
responseFormat: "json",
|
|
24
|
+
}),
|
|
25
|
+
}, {
|
|
26
|
+
path: previewPath,
|
|
27
|
+
operation: api.post(previewPath, {
|
|
28
|
+
responseFormat: "json",
|
|
29
|
+
}),
|
|
30
|
+
}, {
|
|
31
|
+
path: templatesPath,
|
|
32
|
+
operation: api.get(templatesPath, {
|
|
33
|
+
responseFormat: "json",
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export const resendClient = createResendClientApi();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type FarmIntegrationLogger } from "@farm.js/core";
|
|
2
|
+
import type { FarmWebhookConfig, FarmWebhookEvent } from "@farm.js/integration-utils/webhooks";
|
|
3
|
+
import { type EmailTemplates, type ResendEmailScheduleInput, type ResendEmailScheduleResult, type ResendEmailPreviewInput, type ResendEmailPreviewResult, type ResendEmailSendInput, type ResendEmailSendResult, type ResendEmailTemplateInfo } from "./client.js";
|
|
4
|
+
import { Resend as ResendSdk, type WebhookEventPayload } from "resend";
|
|
5
|
+
export type { EmailScheduleDelay, EmailScheduleWhen, EmailTemplate, EmailTemplates, ResendClientAPI, ResendClientPathOptions, ResendDefaultClientAPI, ResendEmailScheduleInput, ResendEmailScheduleResult, ResendEmailPreviewInput, ResendEmailPreviewResult, ResendEmailSendInput, ResendEmailSendResult, ResendEmailTemplateInfo, ResendWebhookResult, } from "./client.js";
|
|
6
|
+
export type { WebhookEventPayload } from "resend";
|
|
7
|
+
export { createResendClientApi, resendClient, template } from "./client.js";
|
|
8
|
+
export { emailSchedule } from "./schedule.js";
|
|
9
|
+
export interface ResendWebhookEvent extends FarmWebhookEvent<"resend", WebhookEventPayload["type"], WebhookEventPayload["data"], WebhookEventPayload> {
|
|
10
|
+
}
|
|
11
|
+
export type ResendWebhookConfig = FarmWebhookConfig<ResendWebhookEvent>;
|
|
12
|
+
export type ResendIntegrationInstance = ResendSdk;
|
|
13
|
+
export interface ResendIntegrationDefaults {
|
|
14
|
+
from?: string;
|
|
15
|
+
replyTo?: string | string[];
|
|
16
|
+
}
|
|
17
|
+
export interface ResendIntegrationInput<TTemplates extends EmailTemplates = EmailTemplates> {
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
instance?: ResendSdk;
|
|
20
|
+
basePath?: string;
|
|
21
|
+
defaults?: ResendIntegrationDefaults;
|
|
22
|
+
templates: TTemplates;
|
|
23
|
+
webhooks?: ResendWebhookConfig;
|
|
24
|
+
log?: FarmIntegrationLogger;
|
|
25
|
+
}
|
|
26
|
+
interface ResolvedResendConfig {
|
|
27
|
+
apiKey?: string;
|
|
28
|
+
from?: string;
|
|
29
|
+
replyTo?: string | string[];
|
|
30
|
+
webhookSecret?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function resend<const TTemplates extends EmailTemplates>(input: ResendIntegrationInput<TTemplates>): import("@farm.js/core").DefinedIntegration<{
|
|
33
|
+
category: "email";
|
|
34
|
+
type: string;
|
|
35
|
+
instance: {
|
|
36
|
+
basePath: string;
|
|
37
|
+
defaults: {
|
|
38
|
+
from: string | null;
|
|
39
|
+
replyTo: string[];
|
|
40
|
+
};
|
|
41
|
+
templateIds: string[];
|
|
42
|
+
liveMode: boolean;
|
|
43
|
+
};
|
|
44
|
+
config: import("@farm.js/core").FarmIntegrationConfigDefinition<ResolvedResendConfig, import("@farm.js/core").FarmIntegrationSchema | undefined>;
|
|
45
|
+
api: {
|
|
46
|
+
send: {
|
|
47
|
+
post: {
|
|
48
|
+
readonly kind: "farm-integration-api-operation";
|
|
49
|
+
path: string;
|
|
50
|
+
method: "POST";
|
|
51
|
+
bodyFormat?: import("@farm.js/core/client").FarmIntegrationAPIBodyFormat | undefined;
|
|
52
|
+
responseFormat?: import("@farm.js/core/client").FarmIntegrationAPIResponseFormat | undefined;
|
|
53
|
+
headers?: {
|
|
54
|
+
[x: string]: string;
|
|
55
|
+
} | undefined;
|
|
56
|
+
credentials?: RequestCredentials | undefined;
|
|
57
|
+
isServer?: false | undefined;
|
|
58
|
+
__pathless?: boolean | undefined;
|
|
59
|
+
__types?: {
|
|
60
|
+
body: ResendEmailSendInput<TTemplates> extends infer T ? T extends ResendEmailSendInput<TTemplates> ? T extends (...args: any[]) => any ? T : T extends object ? { [TKey in keyof T]: T[TKey] extends infer T_1 ? T_1 extends T[TKey] ? T_1 extends (...args: any[]) => any ? T_1 : T_1 extends object ? { [TKey_2 in keyof T_1]: T_1[TKey_2] extends infer T_2 ? T_2 extends T_1[TKey_2] ? T_2 extends (...args: any[]) => any ? T_2 : T_2 extends object ? { [TKey_3 in keyof T_2]: T_2[TKey_3] extends infer T_3 ? T_3 extends T_2[TKey_3] ? T_3 extends (...args: any[]) => any ? T_3 : T_3 extends object ? { [TKey_4 in keyof T_3]: T_3[TKey_4] extends infer T_4 ? T_4 extends T_3[TKey_4] ? T_4 extends (...args: any[]) => any ? T_4 : T_4 extends object ? { [TKey_5 in keyof T_4]: T_4[TKey_5] extends infer T_5 ? T_5 extends T_4[TKey_5] ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_6 in keyof T_5]: T_5[TKey_6] extends infer T_6 ? T_6 extends T_5[TKey_6] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? /*elided*/ any : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never; } : T_1 : never : never; } : T : never : never;
|
|
61
|
+
query: never;
|
|
62
|
+
response: ResendEmailSendResult<TTemplates> extends infer T_1 ? T_1 extends ResendEmailSendResult<TTemplates> ? T_1 extends (...args: any[]) => any ? T_1 : T_1 extends object ? { [TKey_1 in keyof T_1]: T_1[TKey_1] extends infer T_2 ? T_2 extends T_1[TKey_1] ? T_2 extends (...args: any[]) => any ? T_2 : T_2 extends object ? { [TKey_3 in keyof T_2]: T_2[TKey_3] extends infer T_3 ? T_3 extends T_2[TKey_3] ? T_3 extends (...args: any[]) => any ? T_3 : T_3 extends object ? { [TKey_4 in keyof T_3]: T_3[TKey_4] extends infer T_4 ? T_4 extends T_3[TKey_4] ? T_4 extends (...args: any[]) => any ? T_4 : T_4 extends object ? { [TKey_5 in keyof T_4]: T_4[TKey_5] extends infer T_5 ? T_5 extends T_4[TKey_5] ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_6 in keyof T_5]: T_5[TKey_6] extends infer T_6 ? T_6 extends T_5[TKey_6] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? /*elided*/ any : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never; } : T_1 : never : never;
|
|
63
|
+
} | undefined;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
schedule: {
|
|
67
|
+
post: {
|
|
68
|
+
readonly kind: "farm-integration-api-operation";
|
|
69
|
+
path: string;
|
|
70
|
+
method: "POST";
|
|
71
|
+
bodyFormat?: import("@farm.js/core/client").FarmIntegrationAPIBodyFormat | undefined;
|
|
72
|
+
responseFormat?: import("@farm.js/core/client").FarmIntegrationAPIResponseFormat | undefined;
|
|
73
|
+
headers?: {
|
|
74
|
+
[x: string]: string;
|
|
75
|
+
} | undefined;
|
|
76
|
+
credentials?: RequestCredentials | undefined;
|
|
77
|
+
isServer?: false | undefined;
|
|
78
|
+
__pathless?: boolean | undefined;
|
|
79
|
+
__types?: {
|
|
80
|
+
body: ResendEmailScheduleInput<TTemplates> extends infer T_2 ? T_2 extends ResendEmailScheduleInput<TTemplates> ? T_2 extends (...args: any[]) => any ? T_2 : T_2 extends object ? { [TKey_2 in keyof T_2]: T_2[TKey_2] extends infer T_3 ? T_3 extends T_2[TKey_2] ? T_3 extends (...args: any[]) => any ? T_3 : T_3 extends object ? { [TKey_4 in keyof T_3]: T_3[TKey_4] extends infer T_4 ? T_4 extends T_3[TKey_4] ? T_4 extends (...args: any[]) => any ? T_4 : T_4 extends object ? { [TKey_5 in keyof T_4]: T_4[TKey_5] extends infer T_5 ? T_5 extends T_4[TKey_5] ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_6 in keyof T_5]: T_5[TKey_6] extends infer T_6 ? T_6 extends T_5[TKey_6] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? { [TKey_9 in keyof T_8]: T_8[TKey_9] extends infer T_9 ? T_9 extends T_8[TKey_9] ? T_9 extends (...args: any[]) => any ? T_9 : T_9 extends object ? /*elided*/ any : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never; } : T_2 : never : never;
|
|
81
|
+
query: never;
|
|
82
|
+
response: ResendEmailScheduleResult<TTemplates> extends infer T_3 ? T_3 extends ResendEmailScheduleResult<TTemplates> ? T_3 extends (...args: any[]) => any ? T_3 : T_3 extends object ? { [TKey_3 in keyof T_3]: T_3[TKey_3] extends infer T_4 ? T_4 extends T_3[TKey_3] ? T_4 extends (...args: any[]) => any ? T_4 : T_4 extends object ? { [TKey_5 in keyof T_4]: T_4[TKey_5] extends infer T_5 ? T_5 extends T_4[TKey_5] ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_6 in keyof T_5]: T_5[TKey_6] extends infer T_6 ? T_6 extends T_5[TKey_6] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? { [TKey_9 in keyof T_8]: T_8[TKey_9] extends infer T_9 ? T_9 extends T_8[TKey_9] ? T_9 extends (...args: any[]) => any ? T_9 : T_9 extends object ? { [TKey_10 in keyof T_9]: T_9[TKey_10] extends infer T_10 ? T_10 extends T_9[TKey_10] ? T_10 extends (...args: any[]) => any ? T_10 : T_10 extends object ? /*elided*/ any : T_10 : never : never; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never; } : T_3 : never : never;
|
|
83
|
+
} | undefined;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
preview: {
|
|
87
|
+
post: {
|
|
88
|
+
readonly kind: "farm-integration-api-operation";
|
|
89
|
+
path: string;
|
|
90
|
+
method: "POST";
|
|
91
|
+
bodyFormat?: import("@farm.js/core/client").FarmIntegrationAPIBodyFormat | undefined;
|
|
92
|
+
responseFormat?: import("@farm.js/core/client").FarmIntegrationAPIResponseFormat | undefined;
|
|
93
|
+
headers?: {
|
|
94
|
+
[x: string]: string;
|
|
95
|
+
} | undefined;
|
|
96
|
+
credentials?: RequestCredentials | undefined;
|
|
97
|
+
isServer?: false | undefined;
|
|
98
|
+
__pathless?: boolean | undefined;
|
|
99
|
+
__types?: {
|
|
100
|
+
body: ResendEmailPreviewInput<TTemplates> extends infer T_4 ? T_4 extends ResendEmailPreviewInput<TTemplates> ? T_4 extends (...args: any[]) => any ? T_4 : T_4 extends object ? { [TKey_4 in keyof T_4]: T_4[TKey_4] extends infer T_5 ? T_5 extends T_4[TKey_4] ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_6 in keyof T_5]: T_5[TKey_6] extends infer T_6 ? T_6 extends T_5[TKey_6] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? { [TKey_9 in keyof T_8]: T_8[TKey_9] extends infer T_9 ? T_9 extends T_8[TKey_9] ? T_9 extends (...args: any[]) => any ? T_9 : T_9 extends object ? { [TKey_10 in keyof T_9]: T_9[TKey_10] extends infer T_10 ? T_10 extends T_9[TKey_10] ? T_10 extends (...args: any[]) => any ? T_10 : T_10 extends object ? { [TKey_11 in keyof T_10]: T_10[TKey_11] extends infer T_11 ? T_11 extends T_10[TKey_11] ? T_11 extends (...args: any[]) => any ? T_11 : T_11 extends object ? /*elided*/ any : T_11 : never : never; } : T_10 : never : never; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never; } : T_4 : never : never;
|
|
101
|
+
query: never;
|
|
102
|
+
response: ResendEmailPreviewResult<TTemplates> extends infer T_5 ? T_5 extends ResendEmailPreviewResult<TTemplates> ? T_5 extends (...args: any[]) => any ? T_5 : T_5 extends object ? { [TKey_5 in keyof T_5]: T_5[TKey_5] extends infer T_6 ? T_6 extends T_5[TKey_5] ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_7 in keyof T_6]: T_6[TKey_7] extends infer T_7 ? T_7 extends T_6[TKey_7] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? { [TKey_9 in keyof T_8]: T_8[TKey_9] extends infer T_9 ? T_9 extends T_8[TKey_9] ? T_9 extends (...args: any[]) => any ? T_9 : T_9 extends object ? { [TKey_10 in keyof T_9]: T_9[TKey_10] extends infer T_10 ? T_10 extends T_9[TKey_10] ? T_10 extends (...args: any[]) => any ? T_10 : T_10 extends object ? { [TKey_11 in keyof T_10]: T_10[TKey_11] extends infer T_11 ? T_11 extends T_10[TKey_11] ? T_11 extends (...args: any[]) => any ? T_11 : T_11 extends object ? { [TKey_12 in keyof T_11]: T_11[TKey_12] extends infer T_12 ? T_12 extends T_11[TKey_12] ? T_12 extends (...args: any[]) => any ? T_12 : T_12 extends object ? /*elided*/ any : T_12 : never : never; } : T_11 : never : never; } : T_10 : never : never; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never; } : T_5 : never : never;
|
|
103
|
+
} | undefined;
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
templates: {
|
|
107
|
+
get: {
|
|
108
|
+
readonly kind: "farm-integration-api-operation";
|
|
109
|
+
path: string;
|
|
110
|
+
method: "GET";
|
|
111
|
+
bodyFormat?: import("@farm.js/core/client").FarmIntegrationAPIBodyFormat | undefined;
|
|
112
|
+
responseFormat?: import("@farm.js/core/client").FarmIntegrationAPIResponseFormat | undefined;
|
|
113
|
+
headers?: {
|
|
114
|
+
[x: string]: string;
|
|
115
|
+
} | undefined;
|
|
116
|
+
credentials?: RequestCredentials | undefined;
|
|
117
|
+
isServer?: false | undefined;
|
|
118
|
+
__pathless?: boolean | undefined;
|
|
119
|
+
__types?: {
|
|
120
|
+
body: never;
|
|
121
|
+
query: (ResendEmailTemplateInfo<TTemplates> extends infer T_6 ? T_6 extends ResendEmailTemplateInfo<TTemplates> ? T_6 extends (...args: any[]) => any ? T_6 : T_6 extends object ? { [TKey_6 in keyof T_6]: T_6[TKey_6] extends infer T_7 ? T_7 extends T_6[TKey_6] ? T_7 extends (...args: any[]) => any ? T_7 : T_7 extends object ? { [TKey_8 in keyof T_7]: T_7[TKey_8] extends infer T_8 ? T_8 extends T_7[TKey_8] ? T_8 extends (...args: any[]) => any ? T_8 : T_8 extends object ? { [TKey_9 in keyof T_8]: T_8[TKey_9] extends infer T_9 ? T_9 extends T_8[TKey_9] ? T_9 extends (...args: any[]) => any ? T_9 : T_9 extends object ? { [TKey_10 in keyof T_9]: T_9[TKey_10] extends infer T_10 ? T_10 extends T_9[TKey_10] ? T_10 extends (...args: any[]) => any ? T_10 : T_10 extends object ? { [TKey_11 in keyof T_10]: T_10[TKey_11] extends infer T_11 ? T_11 extends T_10[TKey_11] ? T_11 extends (...args: any[]) => any ? T_11 : T_11 extends object ? { [TKey_12 in keyof T_11]: T_11[TKey_12] extends infer T_12 ? T_12 extends T_11[TKey_12] ? T_12 extends (...args: any[]) => any ? T_12 : T_12 extends object ? { [TKey_13 in keyof T_12]: T_12[TKey_13] extends infer T_13 ? T_13 extends T_12[TKey_13] ? T_13 extends (...args: any[]) => any ? T_13 : T_13 extends object ? /*elided*/ any : T_13 : never : never; } : T_12 : never : never; } : T_11 : never : never; } : T_10 : never : never; } : T_9 : never : never; } : T_8 : never : never; } : T_7 : never : never; } : T_6 : never : never)[];
|
|
122
|
+
response: unknown;
|
|
123
|
+
} | undefined;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
log: FarmIntegrationLogger | undefined;
|
|
128
|
+
routes: (import("@farm.js/core").FarmTypedIntegrationRoute<string, never, never, import("@farm.js/integration-utils").FarmWebhookAckResult, false, "POST", import("@farm.js/core").FarmIntegrationSchema | undefined> | import("@farm.js/core").FarmTypedIntegrationRoute<`${string}/send`, ResendEmailSendInput<TTemplates>, never, ResendEmailSendResult<TTemplates>, false, "POST", import("@farm.js/core").FarmIntegrationSchema | undefined> | import("@farm.js/core").FarmTypedIntegrationRoute<`${string}/schedule`, ResendEmailScheduleInput<TTemplates>, never, ResendEmailScheduleResult<TTemplates>, false, "POST", import("@farm.js/core").FarmIntegrationSchema | undefined> | import("@farm.js/core").FarmTypedIntegrationRoute<`${string}/preview`, ResendEmailPreviewInput<TTemplates>, never, ResendEmailPreviewResult<TTemplates>, false, "POST", import("@farm.js/core").FarmIntegrationSchema | undefined> | import("@farm.js/core").FarmTypedIntegrationRoute<`${string}/templates`, never, never, ResendEmailTemplateInfo<TTemplates>[], false, "GET", import("@farm.js/core").FarmIntegrationSchema | undefined>)[];
|
|
129
|
+
}>;
|
|
130
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAuC,KAAK,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEhG,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAC/F,OAAO,EAGL,KAAK,cAAc,EAInB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAG7B,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,KAAK,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAEvE,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB,CAC1D,QAAQ,EACR,mBAAmB,CAAC,MAAM,CAAC,EAC3B,mBAAmB,CAAC,MAAM,CAAC,EAC3B,mBAAmB,CACpB;CAAG;AAEJ,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;AACxE,MAAM,MAAM,yBAAyB,GAAG,SAAS,CAAC;AAElD,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB,CAAC,UAAU,SAAS,cAAc,GAAG,cAAc;IACxF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,GAAG,CAAC,EAAE,qBAAqB,CAAC;CAC7B;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAoED,wBAAgB,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,cAAc,EAC5D,KAAK,EAAE,sBAAsB,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8b1C"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import { render, toPlainText } from "@react-email/render";
|
|
2
|
+
import { defineIntegration, integrationRoute } from "@farm.js/core";
|
|
3
|
+
import { integrationConfig, normalizeWebhookConfig } from "@farm.js/integration-utils";
|
|
4
|
+
import { createResendClientApi, } from "./client.js";
|
|
5
|
+
import { createElement } from "react";
|
|
6
|
+
import { resolveEmailScheduleWhen } from "./schedule.js";
|
|
7
|
+
import { Resend as ResendSdk } from "resend";
|
|
8
|
+
export { createResendClientApi, resendClient, template } from "./client.js";
|
|
9
|
+
export { emailSchedule } from "./schedule.js";
|
|
10
|
+
function createResendApi(input = {}) {
|
|
11
|
+
return createResendClientApi(input);
|
|
12
|
+
}
|
|
13
|
+
function normalizeBasePath(path) {
|
|
14
|
+
if (!path) {
|
|
15
|
+
return "/api/email";
|
|
16
|
+
}
|
|
17
|
+
return path.endsWith("/") ? path.slice(0, -1) : path;
|
|
18
|
+
}
|
|
19
|
+
async function resolveTemplateString(value, data) {
|
|
20
|
+
if (typeof value === "function") {
|
|
21
|
+
return await value(data);
|
|
22
|
+
}
|
|
23
|
+
return value ?? null;
|
|
24
|
+
}
|
|
25
|
+
async function resolveReplyToValue(value, data) {
|
|
26
|
+
if (typeof value === "function") {
|
|
27
|
+
return await value(data);
|
|
28
|
+
}
|
|
29
|
+
return value ?? null;
|
|
30
|
+
}
|
|
31
|
+
function normalizeToArray(value) {
|
|
32
|
+
if (!value) {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
return Array.isArray(value) ? value : [value];
|
|
36
|
+
}
|
|
37
|
+
function getWebhookHeader(headers, name) {
|
|
38
|
+
const value = headers.get(name);
|
|
39
|
+
if (!value) {
|
|
40
|
+
throw new Error(`Missing Resend webhook header: ${name}`);
|
|
41
|
+
}
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
function isResendSdk(value) {
|
|
45
|
+
return !!value && typeof value === "object" && "emails" in value && "webhooks" in value;
|
|
46
|
+
}
|
|
47
|
+
function getTemplatePreviewProps(component) {
|
|
48
|
+
return component.PreviewProps ?? null;
|
|
49
|
+
}
|
|
50
|
+
export function resend(input) {
|
|
51
|
+
const apiKey = input.apiKey ?? process.env.RESEND_API_KEY ?? undefined;
|
|
52
|
+
const basePath = normalizeBasePath(input.basePath);
|
|
53
|
+
const defaults = {
|
|
54
|
+
from: input.defaults?.from ?? process.env.RESEND_FROM_EMAIL ?? undefined,
|
|
55
|
+
replyTo: input.defaults?.replyTo ?? process.env.RESEND_REPLY_TO_EMAIL ?? undefined,
|
|
56
|
+
};
|
|
57
|
+
const webhookSecret = process.env.RESEND_WEBHOOK_SECRET ?? undefined;
|
|
58
|
+
if (!input.instance && !apiKey) {
|
|
59
|
+
throw new Error("Resend integration requires RESEND_API_KEY or an explicit instance.");
|
|
60
|
+
}
|
|
61
|
+
const sendPath = `${basePath}/send`;
|
|
62
|
+
const schedulePath = `${basePath}/schedule`;
|
|
63
|
+
const previewPath = `${basePath}/preview`;
|
|
64
|
+
const templatesPath = `${basePath}/templates`;
|
|
65
|
+
const webhookDefinitions = normalizeWebhookConfig({
|
|
66
|
+
webhooks: input.webhooks,
|
|
67
|
+
defaultName: "default",
|
|
68
|
+
defaultPath: `${basePath}/webhook`,
|
|
69
|
+
defaultSecret: webhookSecret,
|
|
70
|
+
});
|
|
71
|
+
const sdk = input.instance ?? new ResendSdk(apiKey);
|
|
72
|
+
if (!isResendSdk(sdk)) {
|
|
73
|
+
throw new Error("Resend integration instance is invalid.");
|
|
74
|
+
}
|
|
75
|
+
const templateEntries = Object.entries(input.templates);
|
|
76
|
+
async function resolveTemplate(templateId) {
|
|
77
|
+
const match = templateEntries.find(([candidate]) => candidate === templateId);
|
|
78
|
+
return match;
|
|
79
|
+
}
|
|
80
|
+
const webhookRoutes = webhookDefinitions.map((definition) => integrationRoute.post(definition.path, {
|
|
81
|
+
rawBody: true,
|
|
82
|
+
responseFormat: "json",
|
|
83
|
+
async handler(request, context) {
|
|
84
|
+
const rawBody = await request.text();
|
|
85
|
+
const webhookContext = {
|
|
86
|
+
request,
|
|
87
|
+
route: context,
|
|
88
|
+
rawBody,
|
|
89
|
+
headers: request.headers,
|
|
90
|
+
webhook: {
|
|
91
|
+
name: definition.name,
|
|
92
|
+
path: definition.path,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
try {
|
|
96
|
+
if (!definition.secret) {
|
|
97
|
+
throw new Error("Resend webhook secret is required to verify webhook events.");
|
|
98
|
+
}
|
|
99
|
+
const payload = sdk.webhooks.verify({
|
|
100
|
+
payload: rawBody,
|
|
101
|
+
webhookSecret: definition.secret,
|
|
102
|
+
headers: {
|
|
103
|
+
id: getWebhookHeader(request.headers, "svix-id"),
|
|
104
|
+
timestamp: getWebhookHeader(request.headers, "svix-timestamp"),
|
|
105
|
+
signature: getWebhookHeader(request.headers, "svix-signature"),
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
const eventId = request.headers.get("svix-id") ?? `${payload.type}:${Date.now()}`;
|
|
109
|
+
const event = {
|
|
110
|
+
provider: "resend",
|
|
111
|
+
id: eventId,
|
|
112
|
+
type: payload.type,
|
|
113
|
+
data: payload.data,
|
|
114
|
+
raw: payload,
|
|
115
|
+
};
|
|
116
|
+
await definition.onEvent?.(event, webhookContext);
|
|
117
|
+
return Response.json({
|
|
118
|
+
received: true,
|
|
119
|
+
provider: "resend",
|
|
120
|
+
webhook: definition.name,
|
|
121
|
+
eventId: event.id,
|
|
122
|
+
type: event.type,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const override = await definition.onError?.(error, webhookContext);
|
|
127
|
+
if (override) {
|
|
128
|
+
return override;
|
|
129
|
+
}
|
|
130
|
+
return Response.json({
|
|
131
|
+
error: error instanceof Error ? error.message : "Resend webhook verification failed.",
|
|
132
|
+
}, {
|
|
133
|
+
status: 400,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
}));
|
|
138
|
+
return defineIntegration({
|
|
139
|
+
category: "email",
|
|
140
|
+
type: "resend",
|
|
141
|
+
instance: {
|
|
142
|
+
basePath,
|
|
143
|
+
defaults: {
|
|
144
|
+
from: defaults.from ?? null,
|
|
145
|
+
replyTo: normalizeToArray(defaults.replyTo),
|
|
146
|
+
},
|
|
147
|
+
templateIds: templateEntries.map(([id]) => id),
|
|
148
|
+
liveMode: !!apiKey,
|
|
149
|
+
},
|
|
150
|
+
config: integrationConfig({
|
|
151
|
+
label: "Resend integration",
|
|
152
|
+
env: {
|
|
153
|
+
apiKey: "RESEND_API_KEY",
|
|
154
|
+
from: "RESEND_FROM_EMAIL",
|
|
155
|
+
replyTo: "RESEND_REPLY_TO_EMAIL",
|
|
156
|
+
webhookSecret: "RESEND_WEBHOOK_SECRET",
|
|
157
|
+
},
|
|
158
|
+
input: {
|
|
159
|
+
apiKey,
|
|
160
|
+
from: defaults.from,
|
|
161
|
+
replyTo: defaults.replyTo,
|
|
162
|
+
webhookSecret,
|
|
163
|
+
},
|
|
164
|
+
required: input.instance ? [] : ["apiKey"],
|
|
165
|
+
}),
|
|
166
|
+
api: createResendApi({
|
|
167
|
+
sendPath,
|
|
168
|
+
schedulePath,
|
|
169
|
+
previewPath,
|
|
170
|
+
templatesPath,
|
|
171
|
+
}),
|
|
172
|
+
log: input.log,
|
|
173
|
+
routes: [
|
|
174
|
+
integrationRoute.post(sendPath, {
|
|
175
|
+
responseFormat: "json",
|
|
176
|
+
async handler(request, context) {
|
|
177
|
+
const body = (await request.json());
|
|
178
|
+
const resolved = await resolveTemplate(body.templateId);
|
|
179
|
+
if (!resolved) {
|
|
180
|
+
return Response.json({
|
|
181
|
+
error: `Unknown email template "${body.templateId}".`,
|
|
182
|
+
}, {
|
|
183
|
+
status: 400,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const [templateId, configuredTemplate] = resolved;
|
|
187
|
+
context.req.set("email.templateId", templateId);
|
|
188
|
+
context.req.set("email.data", body.data);
|
|
189
|
+
const subject = await resolveTemplateString(configuredTemplate.subject, body.data);
|
|
190
|
+
const previewText = await resolveTemplateString(configuredTemplate.previewText, body.data);
|
|
191
|
+
const from = body.from ??
|
|
192
|
+
(await resolveTemplateString(configuredTemplate.from, body.data)) ??
|
|
193
|
+
defaults.from;
|
|
194
|
+
if (!subject) {
|
|
195
|
+
return Response.json({
|
|
196
|
+
error: `Email template "${templateId}" produced an empty subject.`,
|
|
197
|
+
}, {
|
|
198
|
+
status: 400,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (!from) {
|
|
202
|
+
return Response.json({
|
|
203
|
+
error: "Resend email sending requires a from address. Configure defaults.from, RESEND_FROM_EMAIL, or pass body.from.",
|
|
204
|
+
}, {
|
|
205
|
+
status: 400,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
const replyTo = body.replyTo ??
|
|
209
|
+
(await resolveReplyToValue(configuredTemplate.replyTo, body.data)) ??
|
|
210
|
+
defaults.replyTo;
|
|
211
|
+
const reactNode = createElement(configuredTemplate.component, body.data);
|
|
212
|
+
const result = await sdk.emails.send({
|
|
213
|
+
from,
|
|
214
|
+
to: body.to,
|
|
215
|
+
cc: body.cc,
|
|
216
|
+
bcc: body.bcc,
|
|
217
|
+
replyTo: replyTo ?? undefined,
|
|
218
|
+
subject,
|
|
219
|
+
react: reactNode,
|
|
220
|
+
headers: body.headers,
|
|
221
|
+
tags: body.tags,
|
|
222
|
+
attachments: body.attachments,
|
|
223
|
+
topicId: body.topicId,
|
|
224
|
+
scheduledAt: body.scheduledAt,
|
|
225
|
+
}, body.idempotencyKey ? { idempotencyKey: body.idempotencyKey } : undefined);
|
|
226
|
+
if (result.error || !result.data?.id) {
|
|
227
|
+
return Response.json({
|
|
228
|
+
error: result.error?.message ?? "Resend email send failed.",
|
|
229
|
+
}, {
|
|
230
|
+
status: result.error?.statusCode ?? 400,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return Response.json({
|
|
234
|
+
id: result.data.id,
|
|
235
|
+
provider: "resend",
|
|
236
|
+
templateId,
|
|
237
|
+
from,
|
|
238
|
+
to: normalizeToArray(body.to),
|
|
239
|
+
subject,
|
|
240
|
+
previewText,
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
}),
|
|
244
|
+
integrationRoute.post(schedulePath, {
|
|
245
|
+
responseFormat: "json",
|
|
246
|
+
async handler(request, context) {
|
|
247
|
+
const body = (await request.json());
|
|
248
|
+
let when;
|
|
249
|
+
try {
|
|
250
|
+
when = resolveEmailScheduleWhen(body.when);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
return Response.json({
|
|
254
|
+
error: error instanceof Error ? error.message : "Invalid email scheduling input.",
|
|
255
|
+
}, {
|
|
256
|
+
status: 400,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const resolved = await resolveTemplate(body.templateId);
|
|
260
|
+
if (!resolved) {
|
|
261
|
+
return Response.json({
|
|
262
|
+
error: `Unknown email template "${body.templateId}".`,
|
|
263
|
+
}, {
|
|
264
|
+
status: 400,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const [templateId, configuredTemplate] = resolved;
|
|
268
|
+
context.req.set("email.templateId", templateId);
|
|
269
|
+
context.req.set("email.data", body.data);
|
|
270
|
+
context.req.set("email.when", when);
|
|
271
|
+
const subject = await resolveTemplateString(configuredTemplate.subject, body.data);
|
|
272
|
+
const previewText = await resolveTemplateString(configuredTemplate.previewText, body.data);
|
|
273
|
+
const from = body.from ??
|
|
274
|
+
(await resolveTemplateString(configuredTemplate.from, body.data)) ??
|
|
275
|
+
defaults.from;
|
|
276
|
+
if (!subject) {
|
|
277
|
+
return Response.json({
|
|
278
|
+
error: `Email template "${templateId}" produced an empty subject.`,
|
|
279
|
+
}, {
|
|
280
|
+
status: 400,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (!from) {
|
|
284
|
+
return Response.json({
|
|
285
|
+
error: "Resend email scheduling requires a from address. Configure defaults.from, RESEND_FROM_EMAIL, or pass body.from.",
|
|
286
|
+
}, {
|
|
287
|
+
status: 400,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
const replyTo = body.replyTo ??
|
|
291
|
+
(await resolveReplyToValue(configuredTemplate.replyTo, body.data)) ??
|
|
292
|
+
defaults.replyTo;
|
|
293
|
+
const reactNode = createElement(configuredTemplate.component, body.data);
|
|
294
|
+
const result = await sdk.emails.send({
|
|
295
|
+
from,
|
|
296
|
+
to: body.to,
|
|
297
|
+
cc: body.cc,
|
|
298
|
+
bcc: body.bcc,
|
|
299
|
+
replyTo: replyTo ?? undefined,
|
|
300
|
+
subject,
|
|
301
|
+
react: reactNode,
|
|
302
|
+
headers: body.headers,
|
|
303
|
+
tags: body.tags,
|
|
304
|
+
attachments: body.attachments,
|
|
305
|
+
topicId: body.topicId,
|
|
306
|
+
scheduledAt: when,
|
|
307
|
+
}, body.idempotencyKey ? { idempotencyKey: body.idempotencyKey } : undefined);
|
|
308
|
+
if (result.error || !result.data?.id) {
|
|
309
|
+
return Response.json({
|
|
310
|
+
error: result.error?.message ?? "Resend email scheduling failed.",
|
|
311
|
+
}, {
|
|
312
|
+
status: result.error?.statusCode ?? 400,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return Response.json({
|
|
316
|
+
id: result.data.id,
|
|
317
|
+
provider: "resend",
|
|
318
|
+
templateId,
|
|
319
|
+
from,
|
|
320
|
+
to: normalizeToArray(body.to),
|
|
321
|
+
subject,
|
|
322
|
+
previewText,
|
|
323
|
+
when,
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
}),
|
|
327
|
+
integrationRoute.post(previewPath, {
|
|
328
|
+
responseFormat: "json",
|
|
329
|
+
async handler(request, context) {
|
|
330
|
+
const body = (await request.json());
|
|
331
|
+
const resolved = await resolveTemplate(body.templateId);
|
|
332
|
+
if (!resolved) {
|
|
333
|
+
return Response.json({
|
|
334
|
+
error: `Unknown email template "${body.templateId}".`,
|
|
335
|
+
}, {
|
|
336
|
+
status: 400,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
const [templateId, configuredTemplate] = resolved;
|
|
340
|
+
context.req.set("email.templateId", templateId);
|
|
341
|
+
context.req.set("email.data", body.data);
|
|
342
|
+
const subject = await resolveTemplateString(configuredTemplate.subject, body.data);
|
|
343
|
+
const previewText = await resolveTemplateString(configuredTemplate.previewText, body.data);
|
|
344
|
+
if (!subject) {
|
|
345
|
+
return Response.json({
|
|
346
|
+
error: `Email template "${templateId}" produced an empty subject.`,
|
|
347
|
+
}, {
|
|
348
|
+
status: 400,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
const reactNode = createElement(configuredTemplate.component, body.data);
|
|
352
|
+
const html = await render(reactNode);
|
|
353
|
+
const text = toPlainText(html);
|
|
354
|
+
return Response.json({
|
|
355
|
+
templateId,
|
|
356
|
+
subject,
|
|
357
|
+
previewText,
|
|
358
|
+
html,
|
|
359
|
+
text,
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
}),
|
|
363
|
+
integrationRoute.get(templatesPath, {
|
|
364
|
+
responseFormat: "json",
|
|
365
|
+
async handler() {
|
|
366
|
+
return Response.json(templateEntries.map(([id, configuredTemplate]) => ({
|
|
367
|
+
id,
|
|
368
|
+
hasPreviewText: Boolean(configuredTemplate.previewText),
|
|
369
|
+
hasCustomFrom: Boolean(configuredTemplate.from),
|
|
370
|
+
hasCustomReplyTo: Boolean(configuredTemplate.replyTo),
|
|
371
|
+
previewProps: getTemplatePreviewProps(configuredTemplate.component),
|
|
372
|
+
})));
|
|
373
|
+
},
|
|
374
|
+
}),
|
|
375
|
+
...webhookRoutes,
|
|
376
|
+
],
|
|
377
|
+
});
|
|
378
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface EmailScheduleDelay {
|
|
2
|
+
kind: "delay";
|
|
3
|
+
seconds: number;
|
|
4
|
+
}
|
|
5
|
+
export type EmailScheduleWhen = string | number | Date | EmailScheduleDelay;
|
|
6
|
+
export declare const emailSchedule: {
|
|
7
|
+
readonly after: {
|
|
8
|
+
readonly seconds: (seconds: number) => EmailScheduleDelay;
|
|
9
|
+
readonly second: (seconds: number) => EmailScheduleDelay;
|
|
10
|
+
readonly sec: (seconds: number) => EmailScheduleDelay;
|
|
11
|
+
readonly minutes: (minutes: number) => EmailScheduleDelay;
|
|
12
|
+
readonly minute: (minutes: number) => EmailScheduleDelay;
|
|
13
|
+
readonly min: (minutes: number) => EmailScheduleDelay;
|
|
14
|
+
readonly hours: (hours: number) => EmailScheduleDelay;
|
|
15
|
+
readonly hour: (hours: number) => EmailScheduleDelay;
|
|
16
|
+
readonly hr: (hours: number) => EmailScheduleDelay;
|
|
17
|
+
readonly days: (days: number) => EmailScheduleDelay;
|
|
18
|
+
readonly day: (days: number) => EmailScheduleDelay;
|
|
19
|
+
};
|
|
20
|
+
readonly presets: {
|
|
21
|
+
readonly in30Minutes: EmailScheduleDelay;
|
|
22
|
+
readonly in1Hour: EmailScheduleDelay;
|
|
23
|
+
readonly in2Hours: EmailScheduleDelay;
|
|
24
|
+
readonly in1Day: EmailScheduleDelay;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export declare function isEmailScheduleDelay(value: unknown): value is EmailScheduleDelay;
|
|
28
|
+
export declare function resolveEmailScheduleWhen(when: EmailScheduleWhen, now?: number): string;
|
|
29
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,kBAAkB,CAAC;AAS5E,eAAO,MAAM,aAAa;;oCAEH,MAAM;mCACP,MAAM;gCACT,MAAM;oCACF,MAAM;mCACP,MAAM;gCACT,MAAM;gCACN,MAAM;+BACP,MAAM;6BACR,MAAM;8BACL,MAAM;6BACP,MAAM;;;;;;;;CAQZ,CAAC;AAEX,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,kBAAkB,CAShF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,SAAa,UAgCjF"}
|
package/dist/schedule.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
function createScheduleDelay(seconds) {
|
|
2
|
+
return {
|
|
3
|
+
kind: "delay",
|
|
4
|
+
seconds,
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export const emailSchedule = {
|
|
8
|
+
after: {
|
|
9
|
+
seconds: (seconds) => createScheduleDelay(seconds),
|
|
10
|
+
second: (seconds) => createScheduleDelay(seconds),
|
|
11
|
+
sec: (seconds) => createScheduleDelay(seconds),
|
|
12
|
+
minutes: (minutes) => createScheduleDelay(minutes * 60),
|
|
13
|
+
minute: (minutes) => createScheduleDelay(minutes * 60),
|
|
14
|
+
min: (minutes) => createScheduleDelay(minutes * 60),
|
|
15
|
+
hours: (hours) => createScheduleDelay(hours * 60 * 60),
|
|
16
|
+
hour: (hours) => createScheduleDelay(hours * 60 * 60),
|
|
17
|
+
hr: (hours) => createScheduleDelay(hours * 60 * 60),
|
|
18
|
+
days: (days) => createScheduleDelay(days * 24 * 60 * 60),
|
|
19
|
+
day: (days) => createScheduleDelay(days * 24 * 60 * 60),
|
|
20
|
+
},
|
|
21
|
+
presets: {
|
|
22
|
+
in30Minutes: createScheduleDelay(30 * 60),
|
|
23
|
+
in1Hour: createScheduleDelay(60 * 60),
|
|
24
|
+
in2Hours: createScheduleDelay(2 * 60 * 60),
|
|
25
|
+
in1Day: createScheduleDelay(24 * 60 * 60),
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
export function isEmailScheduleDelay(value) {
|
|
29
|
+
return (!!value &&
|
|
30
|
+
typeof value === "object" &&
|
|
31
|
+
"kind" in value &&
|
|
32
|
+
"seconds" in value &&
|
|
33
|
+
value.kind === "delay" &&
|
|
34
|
+
typeof value.seconds === "number");
|
|
35
|
+
}
|
|
36
|
+
export function resolveEmailScheduleWhen(when, now = Date.now()) {
|
|
37
|
+
if (when instanceof Date) {
|
|
38
|
+
return when.toISOString();
|
|
39
|
+
}
|
|
40
|
+
if (typeof when === "number") {
|
|
41
|
+
if (!Number.isFinite(when) || when <= 0) {
|
|
42
|
+
throw new Error("Email schedule delay seconds must be a positive finite number.");
|
|
43
|
+
}
|
|
44
|
+
return new Date(now + when * 1000).toISOString();
|
|
45
|
+
}
|
|
46
|
+
if (isEmailScheduleDelay(when)) {
|
|
47
|
+
if (!Number.isFinite(when.seconds) || when.seconds <= 0) {
|
|
48
|
+
throw new Error("Email schedule delay seconds must be a positive finite number.");
|
|
49
|
+
}
|
|
50
|
+
return new Date(now + when.seconds * 1000).toISOString();
|
|
51
|
+
}
|
|
52
|
+
if (typeof when === "string") {
|
|
53
|
+
const value = when.trim();
|
|
54
|
+
if (!value) {
|
|
55
|
+
throw new Error("Email scheduling requires a non-empty when value.");
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
throw new Error("Unsupported email schedule value.");
|
|
60
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@farm.js/email",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Email and Resend integration for Farm.js",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/farming-labs/farm.js",
|
|
9
|
+
"directory": "packages/farm-email"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./client": {
|
|
24
|
+
"types": "./dist/client.d.ts",
|
|
25
|
+
"import": "./dist/client.js"
|
|
26
|
+
},
|
|
27
|
+
"./schedule": {
|
|
28
|
+
"types": "./dist/schedule.d.ts",
|
|
29
|
+
"import": "./dist/schedule.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@react-email/render": "2.0.6",
|
|
37
|
+
"resend": "6.10.0",
|
|
38
|
+
"@farm.js/core": "0.1.0-beta.0",
|
|
39
|
+
"@farm.js/integration-utils": "0.1.0-beta.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/react": "19.2.13"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"react": "^18.2.0 || ^19.0.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc",
|
|
49
|
+
"dev": "tsc --watch",
|
|
50
|
+
"type-check": "tsc --noEmit",
|
|
51
|
+
"test": "echo 'No tests in this package'"
|
|
52
|
+
}
|
|
53
|
+
}
|