zerodrop-client 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.
@@ -0,0 +1,36 @@
1
+ export interface ZeroDropEmail {
2
+ id: string;
3
+ from: string;
4
+ to: string;
5
+ subject: string;
6
+ body: string;
7
+ rawBody: string;
8
+ receivedAt: Date;
9
+ }
10
+ export interface WaitForLatestOptions {
11
+ timeout?: number;
12
+ pollInterval?: number;
13
+ }
14
+ export interface ZeroDropOptions {
15
+ baseUrl?: string;
16
+ }
17
+ export declare class ZeroDropTimeoutError extends Error {
18
+ constructor(inbox: string, timeoutMs: number);
19
+ }
20
+ export declare class ZeroDropAuthError extends Error {
21
+ constructor();
22
+ }
23
+ export declare class ZeroDrop {
24
+ private apiKey;
25
+ private baseUrl;
26
+ constructor(apiKey?: string, options?: ZeroDropOptions);
27
+ generateInbox(): string;
28
+ fetchLatest(inbox: string): Promise<ZeroDropEmail | null>;
29
+ waitForLatest(inbox: string, options?: WaitForLatestOptions): Promise<ZeroDropEmail>;
30
+ onReceived(inbox: string, webhookUrl: string): Promise<{
31
+ registered: boolean;
32
+ }>;
33
+ private sleep;
34
+ }
35
+ export default ZeroDrop;
36
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAMD,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAO7C;AAED,qBAAa,iBAAkB,SAAQ,KAAK;;CAK3C;AAuCD,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB;IAmB1D,aAAa,IAAI,MAAM;IAYjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAoDzD,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,aAAa,CAAC;IAoBnB,UAAU,CACd,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IA2BnC,OAAO,CAAC,KAAK;CAGd;AAMD,eAAe,QAAQ,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ // ============================================
3
+ // @zerodrop/client
4
+ // Instant temporary email inboxes for CI/CD
5
+ // ============================================
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ZeroDrop = exports.ZeroDropAuthError = exports.ZeroDropTimeoutError = void 0;
8
+ const BASE_URL = "https://zerodrop.dev";
9
+ const FREE_DOMAIN = "zerodrop-sandbox.online";
10
+ const POLL_INTERVAL = 2000;
11
+ // ============================================
12
+ // Custom Errors
13
+ // ============================================
14
+ class ZeroDropTimeoutError extends Error {
15
+ constructor(inbox, timeoutMs) {
16
+ super(`ZeroDrop: No email received at "${inbox}" within ${timeoutMs}ms. ` +
17
+ `Check that your app is sending to the correct address.`);
18
+ this.name = "ZeroDropTimeoutError";
19
+ }
20
+ }
21
+ exports.ZeroDropTimeoutError = ZeroDropTimeoutError;
22
+ class ZeroDropAuthError extends Error {
23
+ constructor() {
24
+ super("ZeroDrop: Invalid or missing API key.");
25
+ this.name = "ZeroDropAuthError";
26
+ }
27
+ }
28
+ exports.ZeroDropAuthError = ZeroDropAuthError;
29
+ // ============================================
30
+ // Email body extractor
31
+ // ============================================
32
+ function extractBody(raw) {
33
+ if (!raw)
34
+ return "";
35
+ const plainMatch = raw.match(/Content-Type: text\/plain[^\r\n]*\r\n\r\n([\s\S]*?)(?:\r\n--|\r\n\r\n--)/);
36
+ if (plainMatch)
37
+ return plainMatch[1].trim();
38
+ const lines = raw.split("\r\n");
39
+ const bodyStart = lines.findIndex((l) => l === "");
40
+ return lines
41
+ .slice(bodyStart + 1)
42
+ .join("\n")
43
+ .trim()
44
+ .substring(0, 5000);
45
+ }
46
+ // ============================================
47
+ // Random inbox generator (zero-auth)
48
+ // ============================================
49
+ function generateRandomInboxName() {
50
+ const adjectives = [
51
+ "swift", "dark", "cold", "null", "void",
52
+ "zero", "dead", "raw", "base", "core"
53
+ ];
54
+ const adj = adjectives[Math.floor(Math.random() * adjectives.length)];
55
+ const id = Math.random().toString(36).substring(2, 9);
56
+ return `${adj}-${id}`;
57
+ }
58
+ // ============================================
59
+ // Main ZeroDrop Client
60
+ // ============================================
61
+ class ZeroDrop {
62
+ constructor(apiKey, options = {}) {
63
+ this.apiKey = apiKey || null;
64
+ this.baseUrl = options.baseUrl || BASE_URL;
65
+ if (!apiKey) {
66
+ console.warn("[ZeroDrop] No API key provided. Running in public sandbox mode.\n" +
67
+ "[ZeroDrop] Emails are AI-filtered and inboxes expire in 30 minutes.\n" +
68
+ "[ZeroDrop] For CI pipelines, upgrade to a Workspace: https://zerodrop.dev");
69
+ }
70
+ }
71
+ // ============================================
72
+ // generateInbox()
73
+ // Returns a ready-to-use email address instantly
74
+ // No network request needed
75
+ // ============================================
76
+ generateInbox() {
77
+ const name = generateRandomInboxName();
78
+ const domain = FREE_DOMAIN;
79
+ return `${name}@${domain}`;
80
+ }
81
+ // ============================================
82
+ // fetchLatest()
83
+ // Fetches current emails for an inbox
84
+ // Returns null if empty
85
+ // ============================================
86
+ async fetchLatest(inbox) {
87
+ const inboxName = inbox.split("@")[0].toLowerCase();
88
+ const headers = {
89
+ "Content-Type": "application/json",
90
+ };
91
+ if (this.apiKey) {
92
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
93
+ }
94
+ const res = await fetch(`${this.baseUrl}/api/inbox/${inboxName}`, { headers });
95
+ if (res.status === 401)
96
+ throw new ZeroDropAuthError();
97
+ if (!res.ok) {
98
+ throw new Error(`ZeroDrop: API error ${res.status}`);
99
+ }
100
+ const data = await res.json();
101
+ if (!data.emails || data.emails.length === 0)
102
+ return null;
103
+ const latest = data.emails[0];
104
+ return {
105
+ id: latest.id,
106
+ from: latest.from,
107
+ to: latest.to,
108
+ subject: latest.subject || "",
109
+ body: extractBody(latest.raw),
110
+ rawBody: latest.raw,
111
+ receivedAt: new Date(latest.receivedAt),
112
+ };
113
+ }
114
+ // ============================================
115
+ // waitForLatest()
116
+ // Polls until an email arrives or timeout
117
+ // Throws ZeroDropTimeoutError on timeout
118
+ // ============================================
119
+ async waitForLatest(inbox, options = {}) {
120
+ var _a, _b;
121
+ const timeout = (_a = options.timeout) !== null && _a !== void 0 ? _a : 10000;
122
+ const pollInterval = (_b = options.pollInterval) !== null && _b !== void 0 ? _b : POLL_INTERVAL;
123
+ const startTime = Date.now();
124
+ while (Date.now() - startTime < timeout) {
125
+ const email = await this.fetchLatest(inbox);
126
+ if (email)
127
+ return email;
128
+ await this.sleep(pollInterval);
129
+ }
130
+ throw new ZeroDropTimeoutError(inbox, timeout);
131
+ }
132
+ // ============================================
133
+ // onReceived()
134
+ // Registers a webhook for a workspace inbox
135
+ // Requires API key
136
+ // ============================================
137
+ async onReceived(inbox, webhookUrl) {
138
+ if (!this.apiKey) {
139
+ throw new ZeroDropAuthError();
140
+ }
141
+ const res = await fetch(`${this.baseUrl}/api/webhooks/register`, {
142
+ method: "POST",
143
+ headers: {
144
+ "Content-Type": "application/json",
145
+ "Authorization": `Bearer ${this.apiKey}`,
146
+ },
147
+ body: JSON.stringify({ inbox, webhookUrl }),
148
+ });
149
+ if (res.status === 401)
150
+ throw new ZeroDropAuthError();
151
+ if (!res.ok) {
152
+ throw new Error(`ZeroDrop: Failed to register webhook ${res.status}`);
153
+ }
154
+ return { registered: true };
155
+ }
156
+ // ============================================
157
+ // Private helpers
158
+ // ============================================
159
+ sleep(ms) {
160
+ return new Promise((resolve) => setTimeout(resolve, ms));
161
+ }
162
+ }
163
+ exports.ZeroDrop = ZeroDrop;
164
+ // ============================================
165
+ // Default export for convenience
166
+ // ============================================
167
+ exports.default = ZeroDrop;
168
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "zerodrop-client",
3
+ "version": "0.1.0",
4
+ "description": "Instant temporary email inboxes for CI pipelines and QA testing",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": ["dist"],
8
+ "scripts": {
9
+ "build": "tsc",
10
+ "dev": "tsc --watch"
11
+ },
12
+ "keywords": ["email", "testing", "ci", "playwright", "cypress", "qa", "temporary-email", "sandbox"],
13
+ "author": "ZeroDrop",
14
+ "license": "MIT",
15
+ "devDependencies": {
16
+ "typescript": "^6.0.3"
17
+ }
18
+ }