@wrelik/email 0.1.3 → 2.0.1
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/.turbo/turbo-build.log +25 -21
- package/.turbo/turbo-lint.log +5 -0
- package/.turbo/turbo-test.log +15 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/CHANGELOG.md +32 -0
- package/dist/client/index.d.mts +3 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.js +34 -0
- package/dist/client/index.mjs +9 -0
- package/dist/server/index.d.mts +54 -0
- package/dist/server/index.d.ts +54 -0
- package/dist/server/index.js +99 -0
- package/dist/server/index.mjs +70 -0
- package/dist/shared/index.d.mts +18 -0
- package/dist/shared/index.d.ts +18 -0
- package/dist/shared/index.js +18 -0
- package/dist/shared/index.mjs +0 -0
- package/package.json +36 -11
- package/src/client/index.test.ts +7 -0
- package/src/client/index.ts +5 -0
- package/src/server/index.test.ts +116 -0
- package/src/server/index.ts +117 -0
- package/src/shared/index.ts +1 -0
- package/src/shared/types.ts +10 -0
- package/dist/index.d.mts +0 -24
- package/dist/index.d.ts +0 -24
- package/dist/index.js +0 -80
- package/dist/index.mjs +0 -52
- package/dist/unsupported.d.mts +0 -2
- package/dist/unsupported.d.ts +0 -2
- package/dist/unsupported.js +0 -6
- package/dist/unsupported.mjs +0 -4
- package/src/index.ts +0 -73
- package/src/unsupported.ts +0 -4
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
|
|
2
|
-
> @wrelik/email@0.1
|
|
3
|
-
> tsup src/index.ts src/
|
|
2
|
+
> @wrelik/email@2.0.1 build /Users/lee/Projects/wrelik-kit/packages/email
|
|
3
|
+
> tsup src/server/index.ts src/client/index.ts src/shared/index.ts --format cjs,esm --dts --clean
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
CLI Building entry: src/client/index.ts, src/server/index.ts, src/shared/index.ts
|
|
6
|
+
CLI Using tsconfig: tsconfig.json
|
|
7
|
+
CLI tsup v8.5.1
|
|
8
|
+
CLI Target: es2022
|
|
9
|
+
CLI Cleaning output folder
|
|
10
|
+
CJS Build start
|
|
11
|
+
ESM Build start
|
|
12
|
+
ESM dist/shared/index.mjs 0 B
|
|
13
|
+
ESM dist/client/index.mjs 274.00 B
|
|
14
|
+
ESM dist/server/index.mjs 1.87 KB
|
|
15
|
+
ESM ⚡️ Build success in 264ms
|
|
16
|
+
CJS dist/client/index.js 1.28 KB
|
|
17
|
+
CJS dist/server/index.js 3.03 KB
|
|
18
|
+
CJS dist/shared/index.js 767.00 B
|
|
19
|
+
CJS ⚡️ Build success in 266ms
|
|
20
|
+
DTS Build start
|
|
21
|
+
DTS ⚡️ Build success in 1295ms
|
|
22
|
+
DTS dist/client/index.d.ts 77.00 B
|
|
23
|
+
DTS dist/server/index.d.ts 1.99 KB
|
|
24
|
+
DTS dist/shared/index.d.ts 364.00 B
|
|
25
|
+
DTS dist/client/index.d.mts 77.00 B
|
|
26
|
+
DTS dist/server/index.d.mts 1.99 KB
|
|
27
|
+
DTS dist/shared/index.d.mts 364.00 B
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
> @wrelik/email@2.0.1 test /Users/lee/Projects/wrelik-kit/packages/email
|
|
3
|
+
> vitest run --passWithNoTests
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv4.1.2 [39m[90m/Users/lee/Projects/wrelik-kit/packages/email[39m
|
|
7
|
+
|
|
8
|
+
[32m✓[39m src/client/index.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 75[2mms[22m[39m
|
|
9
|
+
[32m✓[39m src/server/index.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 19[2mms[22m[39m
|
|
10
|
+
|
|
11
|
+
[2m Test Files [22m [1m[32m2 passed[39m[22m[90m (2)[39m
|
|
12
|
+
[2m Tests [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
13
|
+
[2m Start at [22m 20:04:57
|
|
14
|
+
[2m Duration [22m 1.61s[2m (transform 734ms, setup 0ms, import 975ms, tests 94ms, environment 0ms)[22m
|
|
15
|
+
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @wrelik/email
|
|
2
2
|
|
|
3
|
+
## 2.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3262454: Upgrade runtime SDK and workspace tooling dependencies to latest compatible versions, including Clerk, Sentry, AWS SDK, Inngest, Resend, Upstash, Zod, TypeScript, Turbo, Vitest, TSUP, and ESLint.
|
|
8
|
+
|
|
9
|
+
Adopt root ESLint flat config and align wrapper peer ranges for updated SDK majors while preserving package export paths. Also apply a patched transitive Next.js resolution to close audit findings and keep production audit clean.
|
|
10
|
+
|
|
11
|
+
Note: Vite is pinned to the latest 7.x line for runtime compatibility in this environment; this avoids current rolldown native-binding failures seen with Vite 8 under Node 20.18.0.
|
|
12
|
+
|
|
13
|
+
Breaking change: `@wrelik/auth` and `@wrelik/clerk-next` now require `@clerk/nextjs@7.x` via updated peer ranges (`>=7 <8`). Consumers on Clerk v4-v6 must upgrade to Clerk v7 before adopting these versions.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [3262454]
|
|
16
|
+
- @wrelik/errors@2.0.1
|
|
17
|
+
|
|
18
|
+
## 2.0.0
|
|
19
|
+
|
|
20
|
+
### Major Changes
|
|
21
|
+
|
|
22
|
+
- 818ed58: Refactor runtime packages to strict subpath exports (`/server`, `/client`, `/shared`) with side-effect free entrypoints and hard CI/runtime boundary enforcement.
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- Add platform wrapper packages for Clerk (Next/Expo), Next Sentry client instrumentation, and Upstash server SDK access so apps can avoid direct vendor imports while staying inside the `@wrelik/*` boundary.
|
|
27
|
+
|
|
28
|
+
Add temporary deprecated server-side compatibility singleton exports to analytics, email, jobs, and storage to support DRX migration from root-import convenience APIs to runtime subpaths in one cutover.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [818ed58]
|
|
33
|
+
- @wrelik/errors@2.0.0
|
|
34
|
+
|
|
3
35
|
## 0.1.3
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/client/index.ts
|
|
21
|
+
var client_exports = {};
|
|
22
|
+
__export(client_exports, {
|
|
23
|
+
serverOnlyClientStub: () => serverOnlyClientStub
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(client_exports);
|
|
26
|
+
var serverOnlyClientStub = (() => {
|
|
27
|
+
throw new Error(
|
|
28
|
+
"@wrelik/email/client is a server-only adapter stub. Use @wrelik/email/server on the backend and call your backend API from client or Expo apps."
|
|
29
|
+
);
|
|
30
|
+
})();
|
|
31
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
32
|
+
0 && (module.exports = {
|
|
33
|
+
serverOnlyClientStub
|
|
34
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// src/client/index.ts
|
|
2
|
+
var serverOnlyClientStub = (() => {
|
|
3
|
+
throw new Error(
|
|
4
|
+
"@wrelik/email/client is a server-only adapter stub. Use @wrelik/email/server on the backend and call your backend API from client or Expo apps."
|
|
5
|
+
);
|
|
6
|
+
})();
|
|
7
|
+
export {
|
|
8
|
+
serverOnlyClientStub
|
|
9
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SendEmailOptions, TemplateRenderer } from '../shared/index.mjs';
|
|
2
|
+
|
|
3
|
+
interface EmailTransport {
|
|
4
|
+
emails: {
|
|
5
|
+
send: (input: {
|
|
6
|
+
from: string;
|
|
7
|
+
to: string | string[];
|
|
8
|
+
subject: string;
|
|
9
|
+
html?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
tags?: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
value: string;
|
|
14
|
+
}>;
|
|
15
|
+
react: null;
|
|
16
|
+
}) => Promise<{
|
|
17
|
+
data: unknown;
|
|
18
|
+
error: {
|
|
19
|
+
message: string;
|
|
20
|
+
} | null;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
declare function createEmailServer(config: {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
defaultFromAddress: string;
|
|
27
|
+
}, options?: {
|
|
28
|
+
transport?: EmailTransport;
|
|
29
|
+
}): {
|
|
30
|
+
sendEmail: ({ to, subject, html, text, from, tags }: SendEmailOptions) => Promise<unknown>;
|
|
31
|
+
defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
32
|
+
sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<unknown>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...) and explicit dependency wiring.
|
|
36
|
+
*/
|
|
37
|
+
declare function initEmail(config: {
|
|
38
|
+
apiKey: string;
|
|
39
|
+
defaultFromAddress: string;
|
|
40
|
+
}, options?: Parameters<typeof createEmailServer>[1]): void;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).defineTemplate(...)
|
|
43
|
+
*/
|
|
44
|
+
declare function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendEmail(...)
|
|
47
|
+
*/
|
|
48
|
+
declare function sendEmail(input: SendEmailOptions): Promise<unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendTemplate(...)
|
|
51
|
+
*/
|
|
52
|
+
declare function sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<unknown>;
|
|
53
|
+
|
|
54
|
+
export { type EmailTransport, SendEmailOptions, TemplateRenderer, createEmailServer, defineTemplate, initEmail, sendEmail, sendTemplate };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SendEmailOptions, TemplateRenderer } from '../shared/index.js';
|
|
2
|
+
|
|
3
|
+
interface EmailTransport {
|
|
4
|
+
emails: {
|
|
5
|
+
send: (input: {
|
|
6
|
+
from: string;
|
|
7
|
+
to: string | string[];
|
|
8
|
+
subject: string;
|
|
9
|
+
html?: string;
|
|
10
|
+
text?: string;
|
|
11
|
+
tags?: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
value: string;
|
|
14
|
+
}>;
|
|
15
|
+
react: null;
|
|
16
|
+
}) => Promise<{
|
|
17
|
+
data: unknown;
|
|
18
|
+
error: {
|
|
19
|
+
message: string;
|
|
20
|
+
} | null;
|
|
21
|
+
}>;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
declare function createEmailServer(config: {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
defaultFromAddress: string;
|
|
27
|
+
}, options?: {
|
|
28
|
+
transport?: EmailTransport;
|
|
29
|
+
}): {
|
|
30
|
+
sendEmail: ({ to, subject, html, text, from, tags }: SendEmailOptions) => Promise<unknown>;
|
|
31
|
+
defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
32
|
+
sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<unknown>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...) and explicit dependency wiring.
|
|
36
|
+
*/
|
|
37
|
+
declare function initEmail(config: {
|
|
38
|
+
apiKey: string;
|
|
39
|
+
defaultFromAddress: string;
|
|
40
|
+
}, options?: Parameters<typeof createEmailServer>[1]): void;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).defineTemplate(...)
|
|
43
|
+
*/
|
|
44
|
+
declare function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendEmail(...)
|
|
47
|
+
*/
|
|
48
|
+
declare function sendEmail(input: SendEmailOptions): Promise<unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendTemplate(...)
|
|
51
|
+
*/
|
|
52
|
+
declare function sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<unknown>;
|
|
53
|
+
|
|
54
|
+
export { type EmailTransport, SendEmailOptions, TemplateRenderer, createEmailServer, defineTemplate, initEmail, sendEmail, sendTemplate };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/server/index.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
createEmailServer: () => createEmailServer,
|
|
24
|
+
defineTemplate: () => defineTemplate,
|
|
25
|
+
initEmail: () => initEmail,
|
|
26
|
+
sendEmail: () => sendEmail,
|
|
27
|
+
sendTemplate: () => sendTemplate
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(server_exports);
|
|
30
|
+
var import_resend = require("resend");
|
|
31
|
+
var import_shared = require("@wrelik/errors/shared");
|
|
32
|
+
function createEmailServer(config, options) {
|
|
33
|
+
const client = options?.transport ?? new import_resend.Resend(config.apiKey);
|
|
34
|
+
const templates = /* @__PURE__ */ new Map();
|
|
35
|
+
const sendEmail2 = async ({ to, subject, html, text, from, tags }) => {
|
|
36
|
+
const result = await client.emails.send({
|
|
37
|
+
from: from ?? config.defaultFromAddress,
|
|
38
|
+
to,
|
|
39
|
+
subject,
|
|
40
|
+
html,
|
|
41
|
+
text,
|
|
42
|
+
tags,
|
|
43
|
+
react: null
|
|
44
|
+
});
|
|
45
|
+
if (result.error) {
|
|
46
|
+
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
47
|
+
}
|
|
48
|
+
return result.data;
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
sendEmail: sendEmail2,
|
|
52
|
+
defineTemplate(id, renderer) {
|
|
53
|
+
templates.set(id, renderer);
|
|
54
|
+
},
|
|
55
|
+
async sendTemplate(id, to, data, options2) {
|
|
56
|
+
const renderer = templates.get(id);
|
|
57
|
+
if (!renderer) {
|
|
58
|
+
throw new import_shared.ValidationError(`Template ${id} not found`);
|
|
59
|
+
}
|
|
60
|
+
const { subject, html, text } = renderer(data);
|
|
61
|
+
return sendEmail2({
|
|
62
|
+
to,
|
|
63
|
+
subject,
|
|
64
|
+
html,
|
|
65
|
+
text,
|
|
66
|
+
...options2
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
var emailSingleton = null;
|
|
72
|
+
function requireEmailSingleton() {
|
|
73
|
+
if (!emailSingleton) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
"@wrelik/email/server compatibility API is not initialized. Call initEmail({ apiKey, defaultFromAddress }) before sendEmail/sendTemplate."
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return emailSingleton;
|
|
79
|
+
}
|
|
80
|
+
function initEmail(config, options) {
|
|
81
|
+
emailSingleton = createEmailServer(config, options);
|
|
82
|
+
}
|
|
83
|
+
function defineTemplate(id, renderer) {
|
|
84
|
+
requireEmailSingleton().defineTemplate(id, renderer);
|
|
85
|
+
}
|
|
86
|
+
function sendEmail(input) {
|
|
87
|
+
return requireEmailSingleton().sendEmail(input);
|
|
88
|
+
}
|
|
89
|
+
function sendTemplate(id, to, data, options) {
|
|
90
|
+
return requireEmailSingleton().sendTemplate(id, to, data, options);
|
|
91
|
+
}
|
|
92
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
93
|
+
0 && (module.exports = {
|
|
94
|
+
createEmailServer,
|
|
95
|
+
defineTemplate,
|
|
96
|
+
initEmail,
|
|
97
|
+
sendEmail,
|
|
98
|
+
sendTemplate
|
|
99
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/server/index.ts
|
|
2
|
+
import { Resend } from "resend";
|
|
3
|
+
import { ValidationError } from "@wrelik/errors/shared";
|
|
4
|
+
function createEmailServer(config, options) {
|
|
5
|
+
const client = options?.transport ?? new Resend(config.apiKey);
|
|
6
|
+
const templates = /* @__PURE__ */ new Map();
|
|
7
|
+
const sendEmail2 = async ({ to, subject, html, text, from, tags }) => {
|
|
8
|
+
const result = await client.emails.send({
|
|
9
|
+
from: from ?? config.defaultFromAddress,
|
|
10
|
+
to,
|
|
11
|
+
subject,
|
|
12
|
+
html,
|
|
13
|
+
text,
|
|
14
|
+
tags,
|
|
15
|
+
react: null
|
|
16
|
+
});
|
|
17
|
+
if (result.error) {
|
|
18
|
+
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
19
|
+
}
|
|
20
|
+
return result.data;
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
sendEmail: sendEmail2,
|
|
24
|
+
defineTemplate(id, renderer) {
|
|
25
|
+
templates.set(id, renderer);
|
|
26
|
+
},
|
|
27
|
+
async sendTemplate(id, to, data, options2) {
|
|
28
|
+
const renderer = templates.get(id);
|
|
29
|
+
if (!renderer) {
|
|
30
|
+
throw new ValidationError(`Template ${id} not found`);
|
|
31
|
+
}
|
|
32
|
+
const { subject, html, text } = renderer(data);
|
|
33
|
+
return sendEmail2({
|
|
34
|
+
to,
|
|
35
|
+
subject,
|
|
36
|
+
html,
|
|
37
|
+
text,
|
|
38
|
+
...options2
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
var emailSingleton = null;
|
|
44
|
+
function requireEmailSingleton() {
|
|
45
|
+
if (!emailSingleton) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"@wrelik/email/server compatibility API is not initialized. Call initEmail({ apiKey, defaultFromAddress }) before sendEmail/sendTemplate."
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return emailSingleton;
|
|
51
|
+
}
|
|
52
|
+
function initEmail(config, options) {
|
|
53
|
+
emailSingleton = createEmailServer(config, options);
|
|
54
|
+
}
|
|
55
|
+
function defineTemplate(id, renderer) {
|
|
56
|
+
requireEmailSingleton().defineTemplate(id, renderer);
|
|
57
|
+
}
|
|
58
|
+
function sendEmail(input) {
|
|
59
|
+
return requireEmailSingleton().sendEmail(input);
|
|
60
|
+
}
|
|
61
|
+
function sendTemplate(id, to, data, options) {
|
|
62
|
+
return requireEmailSingleton().sendTemplate(id, to, data, options);
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
createEmailServer,
|
|
66
|
+
defineTemplate,
|
|
67
|
+
initEmail,
|
|
68
|
+
sendEmail,
|
|
69
|
+
sendTemplate
|
|
70
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface SendEmailOptions {
|
|
2
|
+
to: string | string[];
|
|
3
|
+
subject: string;
|
|
4
|
+
html?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
from?: string;
|
|
7
|
+
tags?: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
type TemplateRenderer<T> = (data: T) => {
|
|
13
|
+
subject: string;
|
|
14
|
+
html: string;
|
|
15
|
+
text?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type { SendEmailOptions, TemplateRenderer };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface SendEmailOptions {
|
|
2
|
+
to: string | string[];
|
|
3
|
+
subject: string;
|
|
4
|
+
html?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
from?: string;
|
|
7
|
+
tags?: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}>;
|
|
11
|
+
}
|
|
12
|
+
type TemplateRenderer<T> = (data: T) => {
|
|
13
|
+
subject: string;
|
|
14
|
+
html: string;
|
|
15
|
+
text?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type { SendEmailOptions, TemplateRenderer };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
|
|
16
|
+
// src/shared/index.ts
|
|
17
|
+
var shared_exports = {};
|
|
18
|
+
module.exports = __toCommonJS(shared_exports);
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrelik/email",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -9,22 +9,47 @@
|
|
|
9
9
|
"url": "https://github.com/lwhite702/wrelik-kit.git",
|
|
10
10
|
"directory": "packages/email"
|
|
11
11
|
},
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"exports": {
|
|
14
|
+
"./server": {
|
|
15
|
+
"types": "./dist/server/index.d.ts",
|
|
16
|
+
"import": "./dist/server/index.mjs",
|
|
17
|
+
"require": "./dist/server/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./client": {
|
|
20
|
+
"types": "./dist/client/index.d.ts",
|
|
21
|
+
"import": "./dist/client/index.mjs",
|
|
22
|
+
"require": "./dist/client/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./shared": {
|
|
25
|
+
"types": "./dist/shared/index.d.ts",
|
|
26
|
+
"import": "./dist/shared/index.mjs",
|
|
27
|
+
"require": "./dist/shared/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
15
31
|
"dependencies": {
|
|
16
|
-
"resend": "^
|
|
17
|
-
"@wrelik/errors": "0.
|
|
32
|
+
"resend": "^6.10.0",
|
|
33
|
+
"@wrelik/errors": "2.0.1"
|
|
18
34
|
},
|
|
19
35
|
"devDependencies": {
|
|
20
|
-
"tsup": "^8.
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"@wrelik/
|
|
36
|
+
"tsup": "^8.5.1",
|
|
37
|
+
"vite": "^7.3.1",
|
|
38
|
+
"vitest": "^4.1.2",
|
|
39
|
+
"@wrelik/eslint-config": "0.1.2",
|
|
40
|
+
"@wrelik/tsconfig": "0.1.2"
|
|
41
|
+
},
|
|
42
|
+
"wrelik": {
|
|
43
|
+
"runtimes": [
|
|
44
|
+
"server",
|
|
45
|
+
"client",
|
|
46
|
+
"shared"
|
|
47
|
+
]
|
|
24
48
|
},
|
|
25
49
|
"scripts": {
|
|
26
|
-
"build": "tsup src/index.ts src/
|
|
50
|
+
"build": "tsup src/server/index.ts src/client/index.ts src/shared/index.ts --format cjs,esm --dts --clean",
|
|
27
51
|
"lint": "eslint src/",
|
|
52
|
+
"typecheck": "tsc --noEmit",
|
|
28
53
|
"test": "vitest run --passWithNoTests"
|
|
29
54
|
}
|
|
30
55
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { ValidationError } from '@wrelik/errors/shared';
|
|
3
|
+
import { createEmailServer } from './index';
|
|
4
|
+
|
|
5
|
+
afterEach(() => {
|
|
6
|
+
vi.resetModules();
|
|
7
|
+
vi.clearAllMocks();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('@wrelik/email/server', () => {
|
|
11
|
+
it('registers templates and applies default sender in sendTemplate', async () => {
|
|
12
|
+
const send = vi.fn(async () => ({ data: { id: 'msg_1' }, error: null }));
|
|
13
|
+
const email = createEmailServer(
|
|
14
|
+
{ apiKey: 'rk_test', defaultFromAddress: 'hello@wrelik.com' },
|
|
15
|
+
{ transport: { emails: { send } } },
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
email.defineTemplate('welcome', (data: { name: string }) => ({
|
|
19
|
+
subject: `Welcome ${data.name}`,
|
|
20
|
+
html: `<p>${data.name}</p>`,
|
|
21
|
+
text: data.name,
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
const result = await email.sendTemplate('welcome', 'lee@example.com', { name: 'Lee' });
|
|
25
|
+
|
|
26
|
+
expect(result).toEqual({ id: 'msg_1' });
|
|
27
|
+
expect(send).toHaveBeenCalledWith({
|
|
28
|
+
from: 'hello@wrelik.com',
|
|
29
|
+
to: 'lee@example.com',
|
|
30
|
+
subject: 'Welcome Lee',
|
|
31
|
+
html: '<p>Lee</p>',
|
|
32
|
+
text: 'Lee',
|
|
33
|
+
tags: undefined,
|
|
34
|
+
react: null,
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('throws a validation error when template is missing', async () => {
|
|
39
|
+
const email = createEmailServer(
|
|
40
|
+
{ apiKey: 'rk_test', defaultFromAddress: 'hello@wrelik.com' },
|
|
41
|
+
{ transport: { emails: { send: vi.fn() } } },
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
await expect(email.sendTemplate('missing', 'a@b.com', {})).rejects.toThrow(ValidationError);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('surfaces provider errors from sendEmail', async () => {
|
|
48
|
+
const email = createEmailServer(
|
|
49
|
+
{ apiKey: 'rk_test', defaultFromAddress: 'hello@wrelik.com' },
|
|
50
|
+
{
|
|
51
|
+
transport: {
|
|
52
|
+
emails: {
|
|
53
|
+
send: vi.fn(async () => ({ data: null, error: { message: 'provider down' } })),
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
await expect(
|
|
60
|
+
email.sendEmail({
|
|
61
|
+
to: 'a@b.com',
|
|
62
|
+
subject: 'Hello',
|
|
63
|
+
html: '<p>hi</p>',
|
|
64
|
+
}),
|
|
65
|
+
).rejects.toThrow(/provider down/);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('compatibility singleton throws before initEmail', async () => {
|
|
69
|
+
const mod = await import('./index.js');
|
|
70
|
+
expect(() =>
|
|
71
|
+
mod.sendEmail({
|
|
72
|
+
to: 'a@b.com',
|
|
73
|
+
subject: 'Hello',
|
|
74
|
+
html: '<p>hi</p>',
|
|
75
|
+
}),
|
|
76
|
+
).toThrow(/initEmail/i);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('compatibility singleton delegates after initEmail', async () => {
|
|
80
|
+
const send = vi.fn(async () => ({ data: { id: 'msg_2' }, error: null }));
|
|
81
|
+
const mod = await import('./index.js');
|
|
82
|
+
|
|
83
|
+
mod.initEmail(
|
|
84
|
+
{ apiKey: 'rk_test', defaultFromAddress: 'hello@wrelik.com' },
|
|
85
|
+
{ transport: { emails: { send } } },
|
|
86
|
+
);
|
|
87
|
+
mod.defineTemplate('receipt', (data: { total: number }) => ({
|
|
88
|
+
subject: `Receipt ${data.total}`,
|
|
89
|
+
html: `<p>${data.total}</p>`,
|
|
90
|
+
text: String(data.total),
|
|
91
|
+
}));
|
|
92
|
+
|
|
93
|
+
await mod.sendTemplate('receipt', 'lee@example.com', { total: 42 });
|
|
94
|
+
await mod.sendEmail({ to: 'lee@example.com', subject: 'Ping', text: 'pong' });
|
|
95
|
+
|
|
96
|
+
expect(send).toHaveBeenCalledTimes(2);
|
|
97
|
+
expect(send).toHaveBeenNthCalledWith(1, {
|
|
98
|
+
from: 'hello@wrelik.com',
|
|
99
|
+
to: 'lee@example.com',
|
|
100
|
+
subject: 'Receipt 42',
|
|
101
|
+
html: '<p>42</p>',
|
|
102
|
+
text: '42',
|
|
103
|
+
tags: undefined,
|
|
104
|
+
react: null,
|
|
105
|
+
});
|
|
106
|
+
expect(send).toHaveBeenNthCalledWith(2, {
|
|
107
|
+
from: 'hello@wrelik.com',
|
|
108
|
+
to: 'lee@example.com',
|
|
109
|
+
subject: 'Ping',
|
|
110
|
+
html: undefined,
|
|
111
|
+
text: 'pong',
|
|
112
|
+
tags: undefined,
|
|
113
|
+
react: null,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Resend } from 'resend';
|
|
2
|
+
import { ValidationError } from '@wrelik/errors/shared';
|
|
3
|
+
import type { SendEmailOptions, TemplateRenderer } from '../shared';
|
|
4
|
+
export type { SendEmailOptions, TemplateRenderer } from '../shared';
|
|
5
|
+
|
|
6
|
+
export interface EmailTransport {
|
|
7
|
+
emails: {
|
|
8
|
+
send: (input: {
|
|
9
|
+
from: string;
|
|
10
|
+
to: string | string[];
|
|
11
|
+
subject: string;
|
|
12
|
+
html?: string;
|
|
13
|
+
text?: string;
|
|
14
|
+
tags?: Array<{ name: string; value: string }>;
|
|
15
|
+
react: null;
|
|
16
|
+
}) => Promise<{ data: unknown; error: { message: string } | null }>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createEmailServer(
|
|
21
|
+
config: { apiKey: string; defaultFromAddress: string },
|
|
22
|
+
options?: { transport?: EmailTransport },
|
|
23
|
+
) {
|
|
24
|
+
const client: EmailTransport = options?.transport ?? new Resend(config.apiKey);
|
|
25
|
+
const templates = new Map<string, TemplateRenderer<unknown>>();
|
|
26
|
+
const sendEmail = async ({ to, subject, html, text, from, tags }: SendEmailOptions) => {
|
|
27
|
+
const result = await client.emails.send({
|
|
28
|
+
from: from ?? config.defaultFromAddress,
|
|
29
|
+
to,
|
|
30
|
+
subject,
|
|
31
|
+
html,
|
|
32
|
+
text,
|
|
33
|
+
tags,
|
|
34
|
+
react: null,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (result.error) {
|
|
38
|
+
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return result.data;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
sendEmail,
|
|
46
|
+
|
|
47
|
+
defineTemplate<T>(id: string, renderer: TemplateRenderer<T>) {
|
|
48
|
+
templates.set(id, renderer as TemplateRenderer<unknown>);
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>) {
|
|
52
|
+
const renderer = templates.get(id);
|
|
53
|
+
if (!renderer) {
|
|
54
|
+
throw new ValidationError(`Template ${id} not found`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { subject, html, text } = renderer(data);
|
|
58
|
+
return sendEmail({
|
|
59
|
+
to,
|
|
60
|
+
subject,
|
|
61
|
+
html,
|
|
62
|
+
text,
|
|
63
|
+
...options,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type EmailServerCompat = ReturnType<typeof createEmailServer>;
|
|
70
|
+
|
|
71
|
+
let emailSingleton: EmailServerCompat | null = null;
|
|
72
|
+
|
|
73
|
+
function requireEmailSingleton(): EmailServerCompat {
|
|
74
|
+
if (!emailSingleton) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
'@wrelik/email/server compatibility API is not initialized. Call initEmail({ apiKey, defaultFromAddress }) before sendEmail/sendTemplate.',
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return emailSingleton;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...) and explicit dependency wiring.
|
|
85
|
+
*/
|
|
86
|
+
export function initEmail(
|
|
87
|
+
config: { apiKey: string; defaultFromAddress: string },
|
|
88
|
+
options?: Parameters<typeof createEmailServer>[1],
|
|
89
|
+
): void {
|
|
90
|
+
emailSingleton = createEmailServer(config, options);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).defineTemplate(...)
|
|
95
|
+
*/
|
|
96
|
+
export function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void {
|
|
97
|
+
requireEmailSingleton().defineTemplate(id, renderer);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendEmail(...)
|
|
102
|
+
*/
|
|
103
|
+
export function sendEmail(input: SendEmailOptions): Promise<unknown> {
|
|
104
|
+
return requireEmailSingleton().sendEmail(input);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @deprecated Temporary DRX compatibility singleton. Prefer createEmailServer(...).sendTemplate(...)
|
|
109
|
+
*/
|
|
110
|
+
export function sendTemplate<T>(
|
|
111
|
+
id: string,
|
|
112
|
+
to: string | string[],
|
|
113
|
+
data: T,
|
|
114
|
+
options?: Partial<SendEmailOptions>,
|
|
115
|
+
): Promise<unknown> {
|
|
116
|
+
return requireEmailSingleton().sendTemplate(id, to, data, options);
|
|
117
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { SendEmailOptions, TemplateRenderer } from './types';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface SendEmailOptions {
|
|
2
|
+
to: string | string[];
|
|
3
|
+
subject: string;
|
|
4
|
+
html?: string;
|
|
5
|
+
text?: string;
|
|
6
|
+
from?: string;
|
|
7
|
+
tags?: Array<{ name: string; value: string }>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type TemplateRenderer<T> = (data: T) => { subject: string; html: string; text?: string };
|
package/dist/index.d.mts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as resend from 'resend';
|
|
2
|
-
|
|
3
|
-
declare function initEmail(apiKey: string, defaultFromAddress: string): void;
|
|
4
|
-
interface SendEmailOptions {
|
|
5
|
-
to: string | string[];
|
|
6
|
-
subject: string;
|
|
7
|
-
html?: string;
|
|
8
|
-
text?: string;
|
|
9
|
-
from?: string;
|
|
10
|
-
tags?: Array<{
|
|
11
|
-
name: string;
|
|
12
|
-
value: string;
|
|
13
|
-
}>;
|
|
14
|
-
}
|
|
15
|
-
declare function sendEmail({ to, subject, html, text, from, tags }: SendEmailOptions): Promise<resend.CreateEmailResponseSuccess | null>;
|
|
16
|
-
type TemplateRenderer<T> = (data: T) => {
|
|
17
|
-
subject: string;
|
|
18
|
-
html: string;
|
|
19
|
-
text?: string;
|
|
20
|
-
};
|
|
21
|
-
declare function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
22
|
-
declare function sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<resend.CreateEmailResponseSuccess | null>;
|
|
23
|
-
|
|
24
|
-
export { type SendEmailOptions, defineTemplate, initEmail, sendEmail, sendTemplate };
|
package/dist/index.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as resend from 'resend';
|
|
2
|
-
|
|
3
|
-
declare function initEmail(apiKey: string, defaultFromAddress: string): void;
|
|
4
|
-
interface SendEmailOptions {
|
|
5
|
-
to: string | string[];
|
|
6
|
-
subject: string;
|
|
7
|
-
html?: string;
|
|
8
|
-
text?: string;
|
|
9
|
-
from?: string;
|
|
10
|
-
tags?: Array<{
|
|
11
|
-
name: string;
|
|
12
|
-
value: string;
|
|
13
|
-
}>;
|
|
14
|
-
}
|
|
15
|
-
declare function sendEmail({ to, subject, html, text, from, tags }: SendEmailOptions): Promise<resend.CreateEmailResponseSuccess | null>;
|
|
16
|
-
type TemplateRenderer<T> = (data: T) => {
|
|
17
|
-
subject: string;
|
|
18
|
-
html: string;
|
|
19
|
-
text?: string;
|
|
20
|
-
};
|
|
21
|
-
declare function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>): void;
|
|
22
|
-
declare function sendTemplate<T>(id: string, to: string | string[], data: T, options?: Partial<SendEmailOptions>): Promise<resend.CreateEmailResponseSuccess | null>;
|
|
23
|
-
|
|
24
|
-
export { type SendEmailOptions, defineTemplate, initEmail, sendEmail, sendTemplate };
|
package/dist/index.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
defineTemplate: () => defineTemplate,
|
|
24
|
-
initEmail: () => initEmail,
|
|
25
|
-
sendEmail: () => sendEmail,
|
|
26
|
-
sendTemplate: () => sendTemplate
|
|
27
|
-
});
|
|
28
|
-
module.exports = __toCommonJS(index_exports);
|
|
29
|
-
var import_resend = require("resend");
|
|
30
|
-
var import_errors = require("@wrelik/errors");
|
|
31
|
-
var client;
|
|
32
|
-
var defaultFrom;
|
|
33
|
-
function initEmail(apiKey, defaultFromAddress) {
|
|
34
|
-
client = new import_resend.Resend(apiKey);
|
|
35
|
-
defaultFrom = defaultFromAddress;
|
|
36
|
-
}
|
|
37
|
-
function getClient() {
|
|
38
|
-
if (!client) throw new Error("Email not initialized");
|
|
39
|
-
return client;
|
|
40
|
-
}
|
|
41
|
-
async function sendEmail({ to, subject, html, text, from, tags }) {
|
|
42
|
-
const result = await getClient().emails.send({
|
|
43
|
-
from: from || defaultFrom,
|
|
44
|
-
to,
|
|
45
|
-
subject,
|
|
46
|
-
html,
|
|
47
|
-
text,
|
|
48
|
-
tags,
|
|
49
|
-
react: null
|
|
50
|
-
});
|
|
51
|
-
if (result.error) {
|
|
52
|
-
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
53
|
-
}
|
|
54
|
-
return result.data;
|
|
55
|
-
}
|
|
56
|
-
var templates = /* @__PURE__ */ new Map();
|
|
57
|
-
function defineTemplate(id, renderer) {
|
|
58
|
-
templates.set(id, renderer);
|
|
59
|
-
}
|
|
60
|
-
async function sendTemplate(id, to, data, options) {
|
|
61
|
-
const renderer = templates.get(id);
|
|
62
|
-
if (!renderer) {
|
|
63
|
-
throw new import_errors.ValidationError(`Template ${id} not found`);
|
|
64
|
-
}
|
|
65
|
-
const { subject, html, text } = renderer(data);
|
|
66
|
-
return sendEmail({
|
|
67
|
-
to,
|
|
68
|
-
subject,
|
|
69
|
-
html,
|
|
70
|
-
text,
|
|
71
|
-
...options
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
75
|
-
0 && (module.exports = {
|
|
76
|
-
defineTemplate,
|
|
77
|
-
initEmail,
|
|
78
|
-
sendEmail,
|
|
79
|
-
sendTemplate
|
|
80
|
-
});
|
package/dist/index.mjs
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
import { Resend } from "resend";
|
|
3
|
-
import { ValidationError } from "@wrelik/errors";
|
|
4
|
-
var client;
|
|
5
|
-
var defaultFrom;
|
|
6
|
-
function initEmail(apiKey, defaultFromAddress) {
|
|
7
|
-
client = new Resend(apiKey);
|
|
8
|
-
defaultFrom = defaultFromAddress;
|
|
9
|
-
}
|
|
10
|
-
function getClient() {
|
|
11
|
-
if (!client) throw new Error("Email not initialized");
|
|
12
|
-
return client;
|
|
13
|
-
}
|
|
14
|
-
async function sendEmail({ to, subject, html, text, from, tags }) {
|
|
15
|
-
const result = await getClient().emails.send({
|
|
16
|
-
from: from || defaultFrom,
|
|
17
|
-
to,
|
|
18
|
-
subject,
|
|
19
|
-
html,
|
|
20
|
-
text,
|
|
21
|
-
tags,
|
|
22
|
-
react: null
|
|
23
|
-
});
|
|
24
|
-
if (result.error) {
|
|
25
|
-
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
26
|
-
}
|
|
27
|
-
return result.data;
|
|
28
|
-
}
|
|
29
|
-
var templates = /* @__PURE__ */ new Map();
|
|
30
|
-
function defineTemplate(id, renderer) {
|
|
31
|
-
templates.set(id, renderer);
|
|
32
|
-
}
|
|
33
|
-
async function sendTemplate(id, to, data, options) {
|
|
34
|
-
const renderer = templates.get(id);
|
|
35
|
-
if (!renderer) {
|
|
36
|
-
throw new ValidationError(`Template ${id} not found`);
|
|
37
|
-
}
|
|
38
|
-
const { subject, html, text } = renderer(data);
|
|
39
|
-
return sendEmail({
|
|
40
|
-
to,
|
|
41
|
-
subject,
|
|
42
|
-
html,
|
|
43
|
-
text,
|
|
44
|
-
...options
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
export {
|
|
48
|
-
defineTemplate,
|
|
49
|
-
initEmail,
|
|
50
|
-
sendEmail,
|
|
51
|
-
sendTemplate
|
|
52
|
-
};
|
package/dist/unsupported.d.mts
DELETED
package/dist/unsupported.d.ts
DELETED
package/dist/unsupported.js
DELETED
package/dist/unsupported.mjs
DELETED
package/src/index.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line no-restricted-imports
|
|
2
|
-
import { Resend } from 'resend';
|
|
3
|
-
import { ValidationError } from '@wrelik/errors';
|
|
4
|
-
|
|
5
|
-
let client: Resend;
|
|
6
|
-
let defaultFrom: string;
|
|
7
|
-
|
|
8
|
-
export function initEmail(apiKey: string, defaultFromAddress: string) {
|
|
9
|
-
client = new Resend(apiKey);
|
|
10
|
-
defaultFrom = defaultFromAddress;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function getClient() {
|
|
14
|
-
if (!client) throw new Error('Email not initialized');
|
|
15
|
-
return client;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface SendEmailOptions {
|
|
19
|
-
to: string | string[];
|
|
20
|
-
subject: string;
|
|
21
|
-
html?: string;
|
|
22
|
-
text?: string;
|
|
23
|
-
from?: string;
|
|
24
|
-
tags?: Array<{ name: string; value: string }>;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export async function sendEmail({ to, subject, html, text, from, tags }: SendEmailOptions) {
|
|
28
|
-
const result = await getClient().emails.send({
|
|
29
|
-
from: from || defaultFrom,
|
|
30
|
-
to,
|
|
31
|
-
subject,
|
|
32
|
-
html,
|
|
33
|
-
text,
|
|
34
|
-
tags,
|
|
35
|
-
react: null,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
if (result.error) {
|
|
39
|
-
throw new Error(`Failed to send email: ${result.error.message}`);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return result.data;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Template Registry
|
|
46
|
-
type TemplateRenderer<T> = (data: T) => { subject: string; html: string; text?: string };
|
|
47
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
-
const templates = new Map<string, TemplateRenderer<any>>();
|
|
49
|
-
|
|
50
|
-
export function defineTemplate<T>(id: string, renderer: TemplateRenderer<T>) {
|
|
51
|
-
templates.set(id, renderer);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export async function sendTemplate<T>(
|
|
55
|
-
id: string,
|
|
56
|
-
to: string | string[],
|
|
57
|
-
data: T,
|
|
58
|
-
options?: Partial<SendEmailOptions>,
|
|
59
|
-
) {
|
|
60
|
-
const renderer = templates.get(id);
|
|
61
|
-
if (!renderer) {
|
|
62
|
-
throw new ValidationError(`Template ${id} not found`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const { subject, html, text } = renderer(data);
|
|
66
|
-
return sendEmail({
|
|
67
|
-
to,
|
|
68
|
-
subject,
|
|
69
|
-
html,
|
|
70
|
-
text,
|
|
71
|
-
...options,
|
|
72
|
-
});
|
|
73
|
-
}
|
package/src/unsupported.ts
DELETED