contiguity 0.0.9 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -47,7 +47,7 @@ const response = await contiguity.email.send({
47
47
  to: "user@example.com",
48
48
  from: "Your App <no-reply@yourapp.com>",
49
49
  subject: "Welcome!",
50
- body: { text: "Welcome to our platform!" }
50
+ text: "Welcome to our platform!"
51
51
  });
52
52
  ```
53
53
 
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export type { ResponseMetadata } from "./types/responses.js";
8
8
  export type { WebhookEventBase, WebhookEventType, IncomingMessageData, TextIncomingData, ImessageIncomingData, TextDeliveryData, } from "./types/webhooks.js";
9
9
  export type { TextSendParams, TextReactParams } from "./schemas/text.js";
10
10
  export type { EmailSendParams } from "./schemas/email.js";
11
+ export { renderReactEmail } from "./utils/react-email.js";
11
12
  export type { OtpNewParams, OtpVerifyParams, OtpResendParams, OtpReverseInitiateParams } from "./schemas/otp.js";
12
13
  export type { ImessageSendParams, ImessageTypingParams, ImessageReactParams, ImessageReadParams, } from "./schemas/imessage.js";
13
14
  export type { WhatsappSendParams, WhatsappTypingParams, WhatsappReactParams } from "./schemas/whatsapp.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACjH,YAAY,EACR,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,YAAY,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACjH,YAAY,EACR,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC3G,YAAY,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -2,3 +2,4 @@ export { Contiguity } from "./client.js";
2
2
  export { ContiguityError } from "./utils/errors.js";
3
3
  export { verifyWebhookSignature } from "./webhook/verify.js";
4
4
  export { parseWebhookPayload } from "./webhook/parse.js";
5
+ export { renderReactEmail } from "./utils/react-email.js";
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/resources/email.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAE5C,IAAI,CAAC,MAAM,EAAE,eAAe;kBAEL,MAAM;;;;;;;;;CAKpC"}
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/resources/email.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAczD,qBAAa,aAAa;IACV,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAE5C,IAAI,CAAC,MAAM,EAAE,eAAe;kBAIH,MAAM;;;;;;;;;CAKxC"}
@@ -1,5 +1,17 @@
1
1
  import { request } from "../utils/request.js";
2
+ import { renderReactEmail } from "../utils/react-email.js";
2
3
  import { emailSendSchema } from "../schemas/email.js";
4
+ async function normalizeEmailBody(params) {
5
+ let html = params.html ?? params.body?.html ?? null;
6
+ let text = params.text ?? params.body?.text ?? null;
7
+ const react = params.react ?? params.body?.react;
8
+ if (react) {
9
+ const rendered = await renderReactEmail(react);
10
+ html = rendered.html;
11
+ text = rendered.text;
12
+ }
13
+ return { html: html ?? undefined, text: text ?? undefined };
14
+ }
3
15
  export class EmailResource {
4
16
  config;
5
17
  constructor(config) {
@@ -7,9 +19,11 @@ export class EmailResource {
7
19
  }
8
20
  async send(params) {
9
21
  const parsed = emailSendSchema.parse(params);
22
+ const body = await normalizeEmailBody(parsed);
23
+ const { body: _body, html: _html, text: _text, react: _react, ...rest } = parsed;
10
24
  return request(this.config, "/email", {
11
25
  method: "POST",
12
- body: parsed,
26
+ body: { ...rest, body },
13
27
  });
14
28
  }
15
29
  }
@@ -3,10 +3,14 @@ export declare const emailSendSchema: z.ZodObject<{
3
3
  to: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
4
4
  from: z.ZodString;
5
5
  subject: z.ZodString;
6
- body: z.ZodObject<{
6
+ html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
+ react: z.ZodOptional<z.ZodUnknown>;
9
+ body: z.ZodOptional<z.ZodObject<{
7
10
  text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
11
  html: z.ZodOptional<z.ZodNullable<z.ZodString>>;
9
- }, z.core.$strip>;
12
+ react: z.ZodOptional<z.ZodUnknown>;
13
+ }, z.core.$strip>>;
10
14
  reply_to: z.ZodOptional<z.ZodNullable<z.ZodString>>;
11
15
  cc: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
12
16
  bcc: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/schemas/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,eAAe;;;;;;;;;;;;iBAoBhB,CAAC;AAEb,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/schemas/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;iBAwBhB,CAAC;AAEb,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -1,22 +1,30 @@
1
1
  import { z } from "zod";
2
+ const bodySchema = z
3
+ .object({
4
+ text: z.string().nullable().optional(),
5
+ html: z.string().nullable().optional(),
6
+ react: z.unknown().optional(),
7
+ })
8
+ .optional();
2
9
  export const emailSendSchema = z
3
10
  .object({
4
11
  to: z.union([z.string(), z.array(z.string()).max(10)]),
5
12
  from: z.string(),
6
13
  subject: z.string(),
7
- body: z
8
- .object({
9
- text: z.string().nullable().optional(),
10
- html: z.string().nullable().optional(),
11
- })
12
- .refine((b) => {
13
- const has_text = b.text != null && b.text !== "";
14
- const has_html = b.html != null && b.html !== "";
15
- return has_text || has_html;
16
- }, "Either body.text or body.html must be provided (non-empty)"),
14
+ html: z.string().nullable().optional(),
15
+ text: z.string().nullable().optional(),
16
+ react: z.unknown().optional(),
17
+ /** @deprecated Use top-level html, text, or react instead */
18
+ body: bodySchema,
17
19
  reply_to: z.string().nullable().optional(),
18
20
  cc: z.union([z.string(), z.array(z.string()).max(10)]).nullable().optional(),
19
21
  bcc: z.union([z.string(), z.array(z.string()).max(10)]).nullable().optional(),
20
22
  headers: z.record(z.string(), z.string()).nullable().optional(),
21
23
  })
24
+ .refine((p) => {
25
+ const has_html = (p.html ?? p.body?.html) != null && (p.html ?? p.body?.html) !== "";
26
+ const has_text = (p.text ?? p.body?.text) != null && (p.text ?? p.body?.text) !== "";
27
+ const has_react = p.react ?? p.body?.react;
28
+ return has_html || has_text || !!has_react;
29
+ }, { message: "Either html, text, or react must be provided" })
22
30
  .loose();
@@ -0,0 +1,6 @@
1
+ /** Render React Email component to html and plain text. Requires @react-email/render (and react, react-dom). */
2
+ export declare function renderReactEmail(node: unknown): Promise<{
3
+ html: string;
4
+ text: string;
5
+ }>;
6
+ //# sourceMappingURL=react-email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-email.d.ts","sourceRoot":"","sources":["../../src/utils/react-email.ts"],"names":[],"mappings":"AAAA,gHAAgH;AAChH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAS7F"}
@@ -0,0 +1,9 @@
1
+ /** Render React Email component to html and plain text. Requires @react-email/render (and react, react-dom). */
2
+ export async function renderReactEmail(node) {
3
+ const mod = await import("@react-email/render").catch(() => {
4
+ throw new Error("Failed to render React component. Install `@react-email/render` (and peer deps react, react-dom).");
5
+ });
6
+ const html = await mod.render(node);
7
+ const text = mod.toPlainText(html);
8
+ return { html, text };
9
+ }
package/package.json CHANGED
@@ -1,46 +1,58 @@
1
1
  {
2
- "name": "contiguity",
3
- "version": "0.0.9",
4
- "description": "Contiguity JavaScript/TypeScript SDK",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
13
- }
14
- },
15
- "files": [
16
- "dist"
17
- ],
18
- "scripts": {
19
- "build": "tsc",
20
- "test": "bun run build && vitest run",
21
- "prepublishOnly": "tsc",
22
- "pack": "bun pm pack",
23
- "publish:dry": "bun run build && bun publish --dry-run",
24
- "publish": "bun run build && npm publish"
25
- },
26
- "keywords": [
27
- "contiguity",
28
- "sms",
29
- "email",
30
- "otp",
31
- "imessage",
32
- "whatsapp"
33
- ],
34
- "license": "MIT",
35
- "dependencies": {
36
- "zod": "^4.3.6"
37
- },
38
- "devDependencies": {
39
- "@types/node": "^22.19.11",
40
- "typescript": "^5.9.3",
41
- "vitest": "^3.2.4"
42
- },
43
- "engines": {
44
- "node": ">=18"
2
+ "name": "contiguity",
3
+ "version": "0.0.10",
4
+ "description": "Contiguity JavaScript/TypeScript SDK",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
45
13
  }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "test": "bun run build && vitest run",
21
+ "prepublishOnly": "tsc",
22
+ "pack": "bun pm pack",
23
+ "publish:dry": "bun run build && bun publish --dry-run",
24
+ "publish": "bun run build && npm publish"
25
+ },
26
+ "keywords": [
27
+ "contiguity",
28
+ "sms",
29
+ "email",
30
+ "otp",
31
+ "imessage",
32
+ "whatsapp"
33
+ ],
34
+ "license": "MIT",
35
+ "dependencies": {
36
+ "zod": "^4.3.6"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.19.11",
40
+ "@types/react": "^19.2.14",
41
+ "typescript": "^5.9.3",
42
+ "vitest": "^3.2.4",
43
+ "@react-email/render": "^2.0.4",
44
+ "react": "^19.0.0",
45
+ "react-dom": "^19.0.0"
46
+ },
47
+ "engines": {
48
+ "node": ">=18"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "@react-email/render": {
52
+ "optional": true
53
+ }
54
+ },
55
+ "peerDependencies": {
56
+ "@react-email/render": "^2.0.4"
57
+ }
46
58
  }