@stack0/sdk 0.2.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/README.md +388 -0
- package/dist/cdn/index.d.mts +322 -0
- package/dist/cdn/index.d.ts +322 -0
- package/dist/cdn/index.js +347 -0
- package/dist/cdn/index.js.map +1 -0
- package/dist/cdn/index.mjs +345 -0
- package/dist/cdn/index.mjs.map +1 -0
- package/dist/http-client-Wr9lXo9_.d.mts +10 -0
- package/dist/http-client-Wr9lXo9_.d.ts +10 -0
- package/dist/index.d.mts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +421 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +414 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mail/index.d.mts +101 -0
- package/dist/mail/index.d.ts +101 -0
- package/dist/mail/index.js +125 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/index.mjs +123 -0
- package/dist/mail/index.mjs.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/lib/http-client.ts
|
|
4
|
+
var HttpClient = class {
|
|
5
|
+
apiKey;
|
|
6
|
+
baseUrl;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.apiKey = config.apiKey;
|
|
9
|
+
this.baseUrl = config.baseUrl || "https://api.stack0.com/v1";
|
|
10
|
+
}
|
|
11
|
+
getHeaders() {
|
|
12
|
+
return {
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async request(method, path, body) {
|
|
18
|
+
const url = `${this.baseUrl}${path}`;
|
|
19
|
+
try {
|
|
20
|
+
const response = await fetch(url, {
|
|
21
|
+
method,
|
|
22
|
+
headers: this.getHeaders(),
|
|
23
|
+
body: body ? JSON.stringify(body) : void 0
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
await this.handleErrorResponse(response);
|
|
27
|
+
}
|
|
28
|
+
const data = await response.json();
|
|
29
|
+
return data;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
throw this.createError("Network error", error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async handleErrorResponse(response) {
|
|
38
|
+
let errorBody;
|
|
39
|
+
try {
|
|
40
|
+
errorBody = await response.json();
|
|
41
|
+
} catch {
|
|
42
|
+
errorBody = { message: response.statusText };
|
|
43
|
+
}
|
|
44
|
+
const error = new Error(errorBody?.message || `HTTP ${response.status}`);
|
|
45
|
+
error.statusCode = response.status;
|
|
46
|
+
error.code = errorBody?.code ?? "";
|
|
47
|
+
error.response = errorBody;
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
createError(message, cause) {
|
|
51
|
+
const error = new Error(message);
|
|
52
|
+
error.cause = cause;
|
|
53
|
+
return error;
|
|
54
|
+
}
|
|
55
|
+
async get(path) {
|
|
56
|
+
return this.request("GET", path);
|
|
57
|
+
}
|
|
58
|
+
async post(path, body) {
|
|
59
|
+
return this.request("POST", path, body);
|
|
60
|
+
}
|
|
61
|
+
async put(path, body) {
|
|
62
|
+
return this.request("PUT", path, body);
|
|
63
|
+
}
|
|
64
|
+
async delete(path) {
|
|
65
|
+
return this.request("DELETE", path);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// src/mail/client.ts
|
|
70
|
+
var Mail = class {
|
|
71
|
+
http;
|
|
72
|
+
constructor(config) {
|
|
73
|
+
this.http = new HttpClient(config);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Send an email
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const result = await mail.send({
|
|
81
|
+
* from: 'noreply@example.com',
|
|
82
|
+
* to: 'user@example.com',
|
|
83
|
+
* subject: 'Hello World',
|
|
84
|
+
* html: '<p>Welcome!</p>',
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async send(request) {
|
|
89
|
+
const response = await this.http.post("/mail/send", request);
|
|
90
|
+
if (typeof response.createdAt === "string") {
|
|
91
|
+
response.createdAt = new Date(response.createdAt);
|
|
92
|
+
}
|
|
93
|
+
return response;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Get email details by ID
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* const email = await mail.get('email-id');
|
|
101
|
+
* console.log(email.status); // 'delivered'
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
async get(id) {
|
|
105
|
+
const response = await this.http.get(`/mail/${id}`);
|
|
106
|
+
const dateFields = [
|
|
107
|
+
"createdAt",
|
|
108
|
+
"sentAt",
|
|
109
|
+
"deliveredAt",
|
|
110
|
+
"openedAt",
|
|
111
|
+
"clickedAt",
|
|
112
|
+
"bouncedAt"
|
|
113
|
+
];
|
|
114
|
+
for (const field of dateFields) {
|
|
115
|
+
if (response[field] && typeof response[field] === "string") {
|
|
116
|
+
response[field] = new Date(response[field]);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return response;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
exports.Mail = Mail;
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
125
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.com/v1\";\n }\n\n private getHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Stack0 Mail Client\n * API compatible with Resend for easy migration\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type { SendEmailRequest, SendEmailResponse, GetEmailResponse } from \"./types\";\n\nexport class Mail {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n /**\n * Send an email\n *\n * @example\n * ```typescript\n * const result = await mail.send({\n * from: 'noreply@example.com',\n * to: 'user@example.com',\n * subject: 'Hello World',\n * html: '<p>Welcome!</p>',\n * });\n * ```\n */\n async send(request: SendEmailRequest): Promise<SendEmailResponse> {\n const response = await this.http.post<SendEmailResponse>(\"/mail/send\", request);\n\n // Convert date strings to Date objects if needed\n if (typeof response.createdAt === \"string\") {\n response.createdAt = new Date(response.createdAt);\n }\n\n return response;\n }\n\n /**\n * Get email details by ID\n *\n * @example\n * ```typescript\n * const email = await mail.get('email-id');\n * console.log(email.status); // 'delivered'\n * ```\n */\n async get(id: string): Promise<GetEmailResponse> {\n const response = await this.http.get<GetEmailResponse>(`/mail/${id}`);\n\n // Convert date strings to Date objects\n const dateFields = [\n \"createdAt\",\n \"sentAt\",\n \"deliveredAt\",\n \"openedAt\",\n \"clickedAt\",\n \"bouncedAt\",\n ] as const;\n\n for (const field of dateFields) {\n if (response[field] && typeof response[field] === \"string\") {\n (response[field] as any) = new Date(response[field] as string);\n }\n }\n\n return response;\n }\n}\n"]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// src/lib/http-client.ts
|
|
2
|
+
var HttpClient = class {
|
|
3
|
+
apiKey;
|
|
4
|
+
baseUrl;
|
|
5
|
+
constructor(config) {
|
|
6
|
+
this.apiKey = config.apiKey;
|
|
7
|
+
this.baseUrl = config.baseUrl || "https://api.stack0.com/v1";
|
|
8
|
+
}
|
|
9
|
+
getHeaders() {
|
|
10
|
+
return {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
async request(method, path, body) {
|
|
16
|
+
const url = `${this.baseUrl}${path}`;
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(url, {
|
|
19
|
+
method,
|
|
20
|
+
headers: this.getHeaders(),
|
|
21
|
+
body: body ? JSON.stringify(body) : void 0
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
await this.handleErrorResponse(response);
|
|
25
|
+
}
|
|
26
|
+
const data = await response.json();
|
|
27
|
+
return data;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (error instanceof Error && "statusCode" in error) {
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
throw this.createError("Network error", error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async handleErrorResponse(response) {
|
|
36
|
+
let errorBody;
|
|
37
|
+
try {
|
|
38
|
+
errorBody = await response.json();
|
|
39
|
+
} catch {
|
|
40
|
+
errorBody = { message: response.statusText };
|
|
41
|
+
}
|
|
42
|
+
const error = new Error(errorBody?.message || `HTTP ${response.status}`);
|
|
43
|
+
error.statusCode = response.status;
|
|
44
|
+
error.code = errorBody?.code ?? "";
|
|
45
|
+
error.response = errorBody;
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
createError(message, cause) {
|
|
49
|
+
const error = new Error(message);
|
|
50
|
+
error.cause = cause;
|
|
51
|
+
return error;
|
|
52
|
+
}
|
|
53
|
+
async get(path) {
|
|
54
|
+
return this.request("GET", path);
|
|
55
|
+
}
|
|
56
|
+
async post(path, body) {
|
|
57
|
+
return this.request("POST", path, body);
|
|
58
|
+
}
|
|
59
|
+
async put(path, body) {
|
|
60
|
+
return this.request("PUT", path, body);
|
|
61
|
+
}
|
|
62
|
+
async delete(path) {
|
|
63
|
+
return this.request("DELETE", path);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// src/mail/client.ts
|
|
68
|
+
var Mail = class {
|
|
69
|
+
http;
|
|
70
|
+
constructor(config) {
|
|
71
|
+
this.http = new HttpClient(config);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Send an email
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const result = await mail.send({
|
|
79
|
+
* from: 'noreply@example.com',
|
|
80
|
+
* to: 'user@example.com',
|
|
81
|
+
* subject: 'Hello World',
|
|
82
|
+
* html: '<p>Welcome!</p>',
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
async send(request) {
|
|
87
|
+
const response = await this.http.post("/mail/send", request);
|
|
88
|
+
if (typeof response.createdAt === "string") {
|
|
89
|
+
response.createdAt = new Date(response.createdAt);
|
|
90
|
+
}
|
|
91
|
+
return response;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get email details by ID
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const email = await mail.get('email-id');
|
|
99
|
+
* console.log(email.status); // 'delivered'
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
async get(id) {
|
|
103
|
+
const response = await this.http.get(`/mail/${id}`);
|
|
104
|
+
const dateFields = [
|
|
105
|
+
"createdAt",
|
|
106
|
+
"sentAt",
|
|
107
|
+
"deliveredAt",
|
|
108
|
+
"openedAt",
|
|
109
|
+
"clickedAt",
|
|
110
|
+
"bouncedAt"
|
|
111
|
+
];
|
|
112
|
+
for (const field of dateFields) {
|
|
113
|
+
if (response[field] && typeof response[field] === "string") {
|
|
114
|
+
response[field] = new Date(response[field]);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return response;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export { Mail };
|
|
122
|
+
//# sourceMappingURL=index.mjs.map
|
|
123
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/http-client.ts","../../src/mail/client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * HTTP client for Stack0 API\n * Handles authentication, request/response formatting, and error handling\n */\n\nexport interface HttpClientConfig {\n apiKey: string;\n baseUrl?: string;\n}\n\nexport class HttpClient {\n private apiKey: string;\n private baseUrl: string;\n\n constructor(config: HttpClientConfig) {\n this.apiKey = config.apiKey;\n this.baseUrl = config.baseUrl || \"https://api.stack0.com/v1\";\n }\n\n private getHeaders(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.apiKey}`,\n };\n }\n\n async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n\n try {\n const response = await fetch(url, {\n method,\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n const data = await response.json();\n return data as T;\n } catch (error) {\n if (error instanceof Error && \"statusCode\" in error) {\n throw error; // Re-throw our custom errors\n }\n throw this.createError(\"Network error\", error);\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorBody: { message: string } | undefined;\n try {\n errorBody = (await response.json()) as { message: string };\n } catch {\n errorBody = { message: response.statusText };\n }\n\n const error = new Error(errorBody?.message || `HTTP ${response.status}`) as Error & {\n statusCode: number;\n code: string;\n response: unknown;\n };\n error.statusCode = response.status;\n error.code = (errorBody as unknown as { code: string } | undefined)?.code ?? \"\";\n error.response = errorBody;\n throw error;\n }\n\n private createError(message: string, cause?: unknown): Error {\n const error = new Error(message) as Error & { cause: unknown };\n error.cause = cause;\n return error;\n }\n\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n async post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n async put<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(\"PUT\", path, body);\n }\n\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","/**\n * Stack0 Mail Client\n * API compatible with Resend for easy migration\n */\n\nimport { HttpClient, type HttpClientConfig } from \"../lib/http-client\";\nimport type { SendEmailRequest, SendEmailResponse, GetEmailResponse } from \"./types\";\n\nexport class Mail {\n private http: HttpClient;\n\n constructor(config: HttpClientConfig) {\n this.http = new HttpClient(config);\n }\n\n /**\n * Send an email\n *\n * @example\n * ```typescript\n * const result = await mail.send({\n * from: 'noreply@example.com',\n * to: 'user@example.com',\n * subject: 'Hello World',\n * html: '<p>Welcome!</p>',\n * });\n * ```\n */\n async send(request: SendEmailRequest): Promise<SendEmailResponse> {\n const response = await this.http.post<SendEmailResponse>(\"/mail/send\", request);\n\n // Convert date strings to Date objects if needed\n if (typeof response.createdAt === \"string\") {\n response.createdAt = new Date(response.createdAt);\n }\n\n return response;\n }\n\n /**\n * Get email details by ID\n *\n * @example\n * ```typescript\n * const email = await mail.get('email-id');\n * console.log(email.status); // 'delivered'\n * ```\n */\n async get(id: string): Promise<GetEmailResponse> {\n const response = await this.http.get<GetEmailResponse>(`/mail/${id}`);\n\n // Convert date strings to Date objects\n const dateFields = [\n \"createdAt\",\n \"sentAt\",\n \"deliveredAt\",\n \"openedAt\",\n \"clickedAt\",\n \"bouncedAt\",\n ] as const;\n\n for (const field of dateFields) {\n if (response[field] && typeof response[field] === \"string\") {\n (response[field] as any) = new Date(response[field] as string);\n }\n }\n\n return response;\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stack0/sdk",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Official Stack0 SDK for Node.js",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"./mail": {
|
|
15
|
+
"types": "./dist/mail/index.d.ts",
|
|
16
|
+
"require": "./dist/mail/index.js",
|
|
17
|
+
"import": "./dist/mail/index.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./cdn": {
|
|
20
|
+
"types": "./dist/cdn/index.d.ts",
|
|
21
|
+
"require": "./dist/cdn/index.js",
|
|
22
|
+
"import": "./dist/cdn/index.mjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"keywords": [
|
|
30
|
+
"stack0",
|
|
31
|
+
"email",
|
|
32
|
+
"mail",
|
|
33
|
+
"transactional-email",
|
|
34
|
+
"cdn",
|
|
35
|
+
"assets",
|
|
36
|
+
"file-upload",
|
|
37
|
+
"api",
|
|
38
|
+
"sdk"
|
|
39
|
+
],
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/CampbellVentures/stack0.git",
|
|
43
|
+
"directory": "packages/sdk"
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "bun test",
|
|
50
|
+
"prepublishOnly": "bun run build"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^22.5.0",
|
|
55
|
+
"tsup": "^8.0.2",
|
|
56
|
+
"typescript": "^5.5.4"
|
|
57
|
+
}
|
|
58
|
+
}
|