@sanvika/mail 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@sanvika/mail",
3
+ "version": "0.1.0",
4
+ "description": "Server client for Sanvika Mail — mail site profile + From / Reply-To / footer placeholders over S2S API",
5
+ "type": "module",
6
+ "main": "./src/server/index.js",
7
+ "exports": {
8
+ ".": "./src/index.js",
9
+ "./server": "./src/server/index.js"
10
+ },
11
+ "files": ["src"],
12
+ "license": "UNLICENSED",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/sanvikaproduction/sanvika-mail"
19
+ }
20
+ }
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export { SanvikaMailClient } from "./server/index.js";
@@ -0,0 +1,74 @@
1
+ // @sanvika/mail/server — S2S client for sanvika-mail
2
+ export class SanvikaMailClient {
3
+ constructor({
4
+ clientId,
5
+ clientSecret,
6
+ baseUrl = "https://mail.sanvikaproduction.com",
7
+ } = {}) {
8
+ this.clientId = clientId;
9
+ this.clientSecret = clientSecret;
10
+ this.baseUrl = String(baseUrl || "").replace(/\/+$/, "");
11
+ }
12
+
13
+ static fromProcessEnv() {
14
+ return new SanvikaMailClient({
15
+ clientId: process.env.NEXT_PUBLIC_MAIL_CLIENT_ID,
16
+ clientSecret: process.env.MAIL_CLIENT_SECRET,
17
+ baseUrl: process.env.NEXT_PUBLIC_MAIL_URL || "https://mail.sanvikaproduction.com",
18
+ });
19
+ }
20
+
21
+ isConfigured() {
22
+ return Boolean(this.clientId && this.clientSecret && this.baseUrl);
23
+ }
24
+
25
+ #headers() {
26
+ return {
27
+ "Content-Type": "application/json",
28
+ "x-client-id": this.clientId,
29
+ "x-client-secret": this.clientSecret,
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Latest saved mail site profile + resolved placeholders (FROM_NAME, UNSUBSCRIBE_BASE, …).
35
+ * @param {RequestInit} [fetchInit]
36
+ */
37
+ async getSiteProfile(fetchInit = {}) {
38
+ const res = await fetch(`${this.baseUrl}/api/v1/mail-site-profile`, {
39
+ method: "GET",
40
+ headers: this.#headers(),
41
+ ...fetchInit,
42
+ });
43
+ const data = await res.json().catch(() => ({}));
44
+ if (!res.ok) throw new Error(data?.code || `SanvikaMail getSiteProfile: ${res.status}`);
45
+ return { profile: data.profile, placeholders: data.placeholders };
46
+ }
47
+
48
+ /**
49
+ * @param {RequestInit} [fetchInit]
50
+ */
51
+ async getSiteProfileSafe(fetchInit = {}) {
52
+ if (!this.isConfigured()) {
53
+ return {
54
+ ok: false,
55
+ status: 503,
56
+ code: "MAIL_ENV_INCOMPLETE",
57
+ profile: null,
58
+ placeholders: null,
59
+ };
60
+ }
61
+ try {
62
+ const { profile, placeholders } = await this.getSiteProfile(fetchInit);
63
+ return { ok: true, status: 200, code: null, profile, placeholders };
64
+ } catch {
65
+ return {
66
+ ok: false,
67
+ status: 502,
68
+ code: "MAIL_FETCH_ERROR",
69
+ profile: null,
70
+ placeholders: null,
71
+ };
72
+ }
73
+ }
74
+ }