@stacksjs/mail 0.3.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/bin/mail-aarch64-linux +0 -0
- package/bin/mail-aarch64-macos +0 -0
- package/bin/mail-x86_64-linux +0 -0
- package/bin/mail-x86_64-macos +0 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.js +274 -0
- package/package.json +51 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the path to the mail binary for a given platform/arch.
|
|
3
|
+
* Checks the package's bin/ directory first, then falls back to zig-out/.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getBinaryPath(platform?: Platform, arch?: Arch): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Get the path to the Linux binary for deployment to EC2.
|
|
8
|
+
* This is the primary function used by the deploy script.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getLinuxBinaryPath(arch?: Arch): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Get the path to the Zig project source for building from source on the server.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getSourcePath(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Build the mail binary for a specific target.
|
|
17
|
+
* Returns the path to the built binary.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildForTarget(target?: string, optimize?: string): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Convert a MailServerConfig to environment variables.
|
|
22
|
+
*/
|
|
23
|
+
export declare function configToEnv(config: MailServerConfig): Record<string, string>;
|
|
24
|
+
export declare function createMailAdminClient(options: MailAdminClientOptions): MailAdminClient;
|
|
25
|
+
/**
|
|
26
|
+
* Root of the sibling Zig mail package.
|
|
27
|
+
*/
|
|
28
|
+
export declare const ZIG_PROJECT_ROOT: unknown;
|
|
29
|
+
/**
|
|
30
|
+
* Directory containing pre-built binaries within this package
|
|
31
|
+
*/
|
|
32
|
+
export declare const BIN_DIR: unknown;
|
|
33
|
+
/**
|
|
34
|
+
* Default SMTP server ports
|
|
35
|
+
*/
|
|
36
|
+
export declare const PORTS: {
|
|
37
|
+
smtp: 25;
|
|
38
|
+
smtps: 465;
|
|
39
|
+
submission: 587;
|
|
40
|
+
imap: 143;
|
|
41
|
+
imaps: 993;
|
|
42
|
+
pop3: 110;
|
|
43
|
+
pop3s: 995
|
|
44
|
+
};
|
|
45
|
+
export declare interface MailServerConfig {
|
|
46
|
+
host?: string
|
|
47
|
+
port?: number
|
|
48
|
+
hostname?: string
|
|
49
|
+
enableTls?: boolean
|
|
50
|
+
tlsCert?: string
|
|
51
|
+
tlsKey?: string
|
|
52
|
+
enableAuth?: boolean
|
|
53
|
+
dbPath?: string
|
|
54
|
+
maxConnections?: number
|
|
55
|
+
maxMessageSize?: number
|
|
56
|
+
maxRecipients?: number
|
|
57
|
+
rateLimitPerIp?: number
|
|
58
|
+
rateLimitPerUser?: number
|
|
59
|
+
logLevel?: 'debug' | 'info' | 'warn' | 'error'
|
|
60
|
+
enableJsonLogging?: boolean
|
|
61
|
+
mailboxPath?: string
|
|
62
|
+
backupPath?: string
|
|
63
|
+
profile?: 'development' | 'staging' | 'production'
|
|
64
|
+
}
|
|
65
|
+
export declare interface MailAdminClientOptions {
|
|
66
|
+
baseUrl: string
|
|
67
|
+
username?: string
|
|
68
|
+
password?: string
|
|
69
|
+
token?: string
|
|
70
|
+
fetch?: typeof fetch
|
|
71
|
+
}
|
|
72
|
+
export declare interface MailboxUser {
|
|
73
|
+
id?: number | string
|
|
74
|
+
username: string
|
|
75
|
+
email: string
|
|
76
|
+
quota_mb?: number
|
|
77
|
+
used_mb?: number
|
|
78
|
+
enabled?: boolean
|
|
79
|
+
created_at?: string
|
|
80
|
+
last_login?: string
|
|
81
|
+
}
|
|
82
|
+
export declare interface CreateMailboxInput {
|
|
83
|
+
username: string
|
|
84
|
+
email: string
|
|
85
|
+
password: string
|
|
86
|
+
quota_mb?: number
|
|
87
|
+
}
|
|
88
|
+
export declare interface MailServerStats {
|
|
89
|
+
messages_received?: number
|
|
90
|
+
messages_sent?: number
|
|
91
|
+
messages_queued?: number
|
|
92
|
+
connections_active?: number
|
|
93
|
+
[key: string]: unknown
|
|
94
|
+
}
|
|
95
|
+
export declare interface MailServerHealth {
|
|
96
|
+
status: 'healthy' | 'degraded' | 'unhealthy'
|
|
97
|
+
version?: string
|
|
98
|
+
uptime?: number
|
|
99
|
+
components?: Record<string, { status: string, message?: string }>
|
|
100
|
+
}
|
|
101
|
+
declare type Platform = 'linux' | 'macos' | 'windows';
|
|
102
|
+
declare type Arch = 'x86_64' | 'aarch64';
|
|
103
|
+
export declare class MailAdminError extends Error {
|
|
104
|
+
public status: number;
|
|
105
|
+
public body?: unknown;
|
|
106
|
+
constructor(status: number, message: string, body?: unknown);
|
|
107
|
+
}
|
|
108
|
+
export declare class MailAdminClient {
|
|
109
|
+
constructor(options: MailAdminClientOptions);
|
|
110
|
+
listMailboxes(options?: {
|
|
111
|
+
offset?: number;
|
|
112
|
+
limit?: number }): Promise<{ users: MailboxUser[];
|
|
113
|
+
total: number;
|
|
114
|
+
}>;
|
|
115
|
+
getMailbox(username: string): Promise<MailboxUser>;
|
|
116
|
+
createMailbox(input: CreateMailboxInput): Promise<MailboxUser>;
|
|
117
|
+
updateMailbox(username: string, patch: Partial<Omit<CreateMailboxInput, 'username'>> & { enabled?: boolean }): Promise<MailboxUser>;
|
|
118
|
+
deleteMailbox(username: string): Promise<{ success: boolean, message?: string }>;
|
|
119
|
+
ensureMailbox(input: CreateMailboxInput): Promise<{ mailbox: MailboxUser, created: boolean }>;
|
|
120
|
+
stats(): Promise<MailServerStats>;
|
|
121
|
+
health(): Promise<MailServerHealth>;
|
|
122
|
+
queue(options?: { offset?: number, limit?: number, status?: string }): Promise<unknown>;
|
|
123
|
+
getConfig(): Promise<Record<string, unknown>>;
|
|
124
|
+
updateConfig(patch: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
125
|
+
ensureDomain(domain: string): Promise<{ domain: string, configured: boolean }>;
|
|
126
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/index.ts
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { join, resolve } from "path";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
var ZIG_PROJECT_ROOT = resolve(import.meta.dir, "..", "..", "zig");
|
|
7
|
+
var BIN_DIR = join(import.meta.dir, "..", "bin");
|
|
8
|
+
var PORTS = {
|
|
9
|
+
smtp: 25,
|
|
10
|
+
smtps: 465,
|
|
11
|
+
submission: 587,
|
|
12
|
+
imap: 143,
|
|
13
|
+
imaps: 993,
|
|
14
|
+
pop3: 110,
|
|
15
|
+
pop3s: 995
|
|
16
|
+
};
|
|
17
|
+
function detectPlatform() {
|
|
18
|
+
switch (process.platform) {
|
|
19
|
+
case "darwin":
|
|
20
|
+
return "macos";
|
|
21
|
+
case "win32":
|
|
22
|
+
return "windows";
|
|
23
|
+
default:
|
|
24
|
+
return "linux";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function detectArch() {
|
|
28
|
+
return process.arch === "arm64" ? "aarch64" : "x86_64";
|
|
29
|
+
}
|
|
30
|
+
function getBinaryPath(platform, arch) {
|
|
31
|
+
const p = platform || detectPlatform();
|
|
32
|
+
const a = arch || detectArch();
|
|
33
|
+
const label = `${a}-${p}`;
|
|
34
|
+
const packageBinary = join(BIN_DIR, `mail-${label}`);
|
|
35
|
+
if (existsSync(packageBinary))
|
|
36
|
+
return packageBinary;
|
|
37
|
+
const zigOutPaths = [
|
|
38
|
+
join(ZIG_PROJECT_ROOT, "zig-out", "bin", label, `mail-${label}`),
|
|
39
|
+
join(ZIG_PROJECT_ROOT, "zig-out", "bin", `mail-${label}`)
|
|
40
|
+
];
|
|
41
|
+
if (p === detectPlatform() && a === detectArch()) {
|
|
42
|
+
zigOutPaths.push(join(ZIG_PROJECT_ROOT, "zig-out", "bin", "mail"));
|
|
43
|
+
}
|
|
44
|
+
for (const path of zigOutPaths) {
|
|
45
|
+
if (existsSync(path))
|
|
46
|
+
return path;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
function getLinuxBinaryPath(arch = "x86_64") {
|
|
51
|
+
return getBinaryPath("linux", arch);
|
|
52
|
+
}
|
|
53
|
+
function getSourcePath() {
|
|
54
|
+
return ZIG_PROJECT_ROOT;
|
|
55
|
+
}
|
|
56
|
+
function buildForTarget(target = "x86_64-linux-gnu", optimize = "ReleaseFast") {
|
|
57
|
+
try {
|
|
58
|
+
console.log(`Building mail for ${target}...`);
|
|
59
|
+
execSync(`zig build -Doptimize=${optimize} -Dtarget=${target}`, {
|
|
60
|
+
cwd: ZIG_PROJECT_ROOT,
|
|
61
|
+
stdio: "inherit"
|
|
62
|
+
});
|
|
63
|
+
const parts = target.split("-");
|
|
64
|
+
const arch = parts[0];
|
|
65
|
+
const os = parts[1];
|
|
66
|
+
const label = `${arch}-${os}`;
|
|
67
|
+
const possiblePaths = [
|
|
68
|
+
join(ZIG_PROJECT_ROOT, "zig-out", "bin", label, `mail-${label}`),
|
|
69
|
+
join(ZIG_PROJECT_ROOT, "zig-out", "bin", `mail-${label}`),
|
|
70
|
+
join(ZIG_PROJECT_ROOT, "zig-out", "bin", "mail")
|
|
71
|
+
];
|
|
72
|
+
for (const path of possiblePaths) {
|
|
73
|
+
if (existsSync(path))
|
|
74
|
+
return path;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error(`Failed to build for ${target}:`, error);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function configToEnv(config) {
|
|
83
|
+
const env = {};
|
|
84
|
+
if (config.host)
|
|
85
|
+
env.SMTP_HOST = config.host;
|
|
86
|
+
if (config.port)
|
|
87
|
+
env.SMTP_PORT = String(config.port);
|
|
88
|
+
if (config.hostname)
|
|
89
|
+
env.SMTP_HOSTNAME = config.hostname;
|
|
90
|
+
if (config.enableTls !== undefined)
|
|
91
|
+
env.SMTP_ENABLE_TLS = String(config.enableTls);
|
|
92
|
+
if (config.tlsCert)
|
|
93
|
+
env.SMTP_TLS_CERT = config.tlsCert;
|
|
94
|
+
if (config.tlsKey)
|
|
95
|
+
env.SMTP_TLS_KEY = config.tlsKey;
|
|
96
|
+
if (config.enableAuth !== undefined)
|
|
97
|
+
env.SMTP_ENABLE_AUTH = String(config.enableAuth);
|
|
98
|
+
if (config.dbPath)
|
|
99
|
+
env.SMTP_DB_PATH = config.dbPath;
|
|
100
|
+
if (config.maxConnections)
|
|
101
|
+
env.SMTP_MAX_CONNECTIONS = String(config.maxConnections);
|
|
102
|
+
if (config.maxMessageSize)
|
|
103
|
+
env.SMTP_MAX_MESSAGE_SIZE = String(config.maxMessageSize);
|
|
104
|
+
if (config.maxRecipients)
|
|
105
|
+
env.SMTP_MAX_RECIPIENTS = String(config.maxRecipients);
|
|
106
|
+
if (config.rateLimitPerIp)
|
|
107
|
+
env.SMTP_RATE_LIMIT_PER_IP = String(config.rateLimitPerIp);
|
|
108
|
+
if (config.rateLimitPerUser)
|
|
109
|
+
env.SMTP_RATE_LIMIT_PER_USER = String(config.rateLimitPerUser);
|
|
110
|
+
if (config.logLevel)
|
|
111
|
+
env.SMTP_LOG_LEVEL = config.logLevel;
|
|
112
|
+
if (config.enableJsonLogging !== undefined)
|
|
113
|
+
env.SMTP_ENABLE_JSON_LOGGING = String(config.enableJsonLogging);
|
|
114
|
+
if (config.mailboxPath)
|
|
115
|
+
env.SMTP_MAILBOX_PATH = config.mailboxPath;
|
|
116
|
+
if (config.backupPath)
|
|
117
|
+
env.SMTP_BACKUP_PATH = config.backupPath;
|
|
118
|
+
if (config.profile)
|
|
119
|
+
env.SMTP_PROFILE = config.profile;
|
|
120
|
+
return env;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class MailAdminError extends Error {
|
|
124
|
+
status;
|
|
125
|
+
body;
|
|
126
|
+
constructor(status, message, body) {
|
|
127
|
+
super(message);
|
|
128
|
+
this.status = status;
|
|
129
|
+
this.body = body;
|
|
130
|
+
this.name = "MailAdminError";
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
class MailAdminClient {
|
|
135
|
+
baseUrl;
|
|
136
|
+
username;
|
|
137
|
+
password;
|
|
138
|
+
token;
|
|
139
|
+
requestFetch;
|
|
140
|
+
csrfToken;
|
|
141
|
+
constructor(options) {
|
|
142
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
143
|
+
this.username = options.username;
|
|
144
|
+
this.password = options.password;
|
|
145
|
+
this.token = options.token;
|
|
146
|
+
this.requestFetch = options.fetch ?? fetch;
|
|
147
|
+
}
|
|
148
|
+
headers(mutating = false) {
|
|
149
|
+
const headers = new Headers({ Accept: "application/json" });
|
|
150
|
+
if (this.token)
|
|
151
|
+
headers.set("Authorization", `Bearer ${this.token}`);
|
|
152
|
+
else if (this.username && this.password)
|
|
153
|
+
headers.set("Authorization", `Basic ${btoa(`${this.username}:${this.password}`)}`);
|
|
154
|
+
if (mutating)
|
|
155
|
+
headers.set("Content-Type", "application/json");
|
|
156
|
+
if (mutating && this.csrfToken)
|
|
157
|
+
headers.set("X-CSRF-Token", this.csrfToken);
|
|
158
|
+
return headers;
|
|
159
|
+
}
|
|
160
|
+
async csrf() {
|
|
161
|
+
if (this.csrfToken)
|
|
162
|
+
return this.csrfToken;
|
|
163
|
+
const response = await this.requestFetch(`${this.baseUrl}/api/csrf-token`, { headers: this.headers() });
|
|
164
|
+
const body = await this.readBody(response);
|
|
165
|
+
if (!response.ok)
|
|
166
|
+
throw new MailAdminError(response.status, "Unable to acquire mail admin CSRF token", body);
|
|
167
|
+
const record = body;
|
|
168
|
+
const token = String(record.csrf_token ?? record.token ?? "");
|
|
169
|
+
if (!token)
|
|
170
|
+
throw new MailAdminError(response.status, "Mail admin returned an empty CSRF token", body);
|
|
171
|
+
this.csrfToken = token;
|
|
172
|
+
return token;
|
|
173
|
+
}
|
|
174
|
+
async readBody(response) {
|
|
175
|
+
const text = await response.text();
|
|
176
|
+
if (!text)
|
|
177
|
+
return null;
|
|
178
|
+
try {
|
|
179
|
+
return JSON.parse(text);
|
|
180
|
+
} catch {
|
|
181
|
+
return text;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async request(path, init = {}) {
|
|
185
|
+
const method = String(init.method ?? "GET").toUpperCase();
|
|
186
|
+
const mutating = !["GET", "HEAD"].includes(method);
|
|
187
|
+
if (mutating)
|
|
188
|
+
await this.csrf();
|
|
189
|
+
const response = await this.requestFetch(`${this.baseUrl}${path}`, {
|
|
190
|
+
...init,
|
|
191
|
+
headers: this.headers(mutating)
|
|
192
|
+
});
|
|
193
|
+
const body = await this.readBody(response);
|
|
194
|
+
if (!response.ok) {
|
|
195
|
+
const message = typeof body === "object" && body !== null && "message" in body ? String(body.message) : `Mail admin request failed with HTTP ${response.status}`;
|
|
196
|
+
throw new MailAdminError(response.status, message, body);
|
|
197
|
+
}
|
|
198
|
+
return body;
|
|
199
|
+
}
|
|
200
|
+
async listMailboxes(options = {}) {
|
|
201
|
+
const query = new URLSearchParams;
|
|
202
|
+
if (options.offset !== undefined)
|
|
203
|
+
query.set("offset", String(options.offset));
|
|
204
|
+
if (options.limit !== undefined)
|
|
205
|
+
query.set("limit", String(options.limit));
|
|
206
|
+
const result = await this.request(`/api/users${query.size ? `?${query}` : ""}`);
|
|
207
|
+
return { users: result.users, total: result.total ?? result.count ?? result.users.length };
|
|
208
|
+
}
|
|
209
|
+
async getMailbox(username) {
|
|
210
|
+
return this.request(`/api/users/${encodeURIComponent(username)}`);
|
|
211
|
+
}
|
|
212
|
+
async createMailbox(input) {
|
|
213
|
+
return this.request("/api/users", { method: "POST", body: JSON.stringify(input) });
|
|
214
|
+
}
|
|
215
|
+
async updateMailbox(username, patch) {
|
|
216
|
+
return this.request(`/api/users/${encodeURIComponent(username)}`, { method: "PUT", body: JSON.stringify(patch) });
|
|
217
|
+
}
|
|
218
|
+
async deleteMailbox(username) {
|
|
219
|
+
return this.request(`/api/users/${encodeURIComponent(username)}`, { method: "DELETE" });
|
|
220
|
+
}
|
|
221
|
+
async ensureMailbox(input) {
|
|
222
|
+
try {
|
|
223
|
+
return { mailbox: await this.getMailbox(input.username), created: false };
|
|
224
|
+
} catch (error) {
|
|
225
|
+
if (!(error instanceof MailAdminError) || error.status !== 404)
|
|
226
|
+
throw error;
|
|
227
|
+
return { mailbox: await this.createMailbox(input), created: true };
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async stats() {
|
|
231
|
+
return this.request("/api/stats");
|
|
232
|
+
}
|
|
233
|
+
async health() {
|
|
234
|
+
return this.request("/health");
|
|
235
|
+
}
|
|
236
|
+
async queue(options = {}) {
|
|
237
|
+
const query = new URLSearchParams(Object.entries(options).filter(([, value]) => value !== undefined).map(([key, value]) => [key, String(value)]));
|
|
238
|
+
return this.request(`/api/queue${query.size ? `?${query}` : ""}`);
|
|
239
|
+
}
|
|
240
|
+
async getConfig() {
|
|
241
|
+
const result = await this.request("/api/config");
|
|
242
|
+
return typeof result.config === "object" && result.config !== null ? result.config : result;
|
|
243
|
+
}
|
|
244
|
+
async updateConfig(patch) {
|
|
245
|
+
return this.request("/api/config", { method: "PUT", body: JSON.stringify(patch) });
|
|
246
|
+
}
|
|
247
|
+
async ensureDomain(domain) {
|
|
248
|
+
const normalized = domain.trim().toLowerCase();
|
|
249
|
+
if (!/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/.test(normalized))
|
|
250
|
+
throw new TypeError(`Invalid mail domain: ${domain}`);
|
|
251
|
+
const config = await this.getConfig();
|
|
252
|
+
const current = Array.isArray(config.extra_local_domains) ? config.extra_local_domains.map(String) : [];
|
|
253
|
+
if (current.includes(normalized))
|
|
254
|
+
return { domain: normalized, configured: false };
|
|
255
|
+
await this.updateConfig({ extra_local_domains: [...current, normalized] });
|
|
256
|
+
return { domain: normalized, configured: true };
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function createMailAdminClient(options) {
|
|
260
|
+
return new MailAdminClient(options);
|
|
261
|
+
}
|
|
262
|
+
export {
|
|
263
|
+
getSourcePath,
|
|
264
|
+
getLinuxBinaryPath,
|
|
265
|
+
getBinaryPath,
|
|
266
|
+
createMailAdminClient,
|
|
267
|
+
configToEnv,
|
|
268
|
+
buildForTarget,
|
|
269
|
+
ZIG_PROJECT_ROOT,
|
|
270
|
+
PORTS,
|
|
271
|
+
MailAdminError,
|
|
272
|
+
MailAdminClient,
|
|
273
|
+
BIN_DIR
|
|
274
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stacksjs/mail",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.3.1",
|
|
5
|
+
"description": "Typed runtime and management client for the mail server",
|
|
6
|
+
"author": "Chris Breuer",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/mail-os/mail.git",
|
|
11
|
+
"directory": "packages/ts"
|
|
12
|
+
},
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"bun": "./dist/index.js",
|
|
17
|
+
"import": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./*": {
|
|
20
|
+
"bun": "./dist/*",
|
|
21
|
+
"import": "./dist/*"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"module": "dist/index.js",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"README.md",
|
|
28
|
+
"dist",
|
|
29
|
+
"bin"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "bun run build:sdk && bun build.ts",
|
|
33
|
+
"build:sdk": "bun build src/index.ts --outdir dist --target bun && bun x @stacksjs/dtsx generate --root src --entrypoints index.ts --outdir dist --exclude '**/*.test.ts' --validate",
|
|
34
|
+
"build:linux-x64": "bun build.ts --target x86_64-linux-gnu",
|
|
35
|
+
"build:linux-arm64": "bun build.ts --target aarch64-linux-gnu",
|
|
36
|
+
"build:all": "bun build.ts --all",
|
|
37
|
+
"prepublishOnly": "bun run build:sdk && bun run build:all"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@stacksjs/dtsx": "^0.11.5"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"smtp",
|
|
44
|
+
"mail",
|
|
45
|
+
"email",
|
|
46
|
+
"server",
|
|
47
|
+
"zig",
|
|
48
|
+
"imap",
|
|
49
|
+
"pop3"
|
|
50
|
+
]
|
|
51
|
+
}
|