@bernierllc/email-sender-manager 1.0.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/LICENSE +5 -0
- package/README.md +466 -0
- package/dist/__tests__/manager.test.d.ts +2 -0
- package/dist/__tests__/manager.test.d.ts.map +1 -0
- package/dist/__tests__/manager.test.js +344 -0
- package/dist/__tests__/manager.test.js.map +1 -0
- package/dist/__tests__/mocks/mock-database.d.ts +15 -0
- package/dist/__tests__/mocks/mock-database.d.ts.map +1 -0
- package/dist/__tests__/mocks/mock-database.js +219 -0
- package/dist/__tests__/mocks/mock-database.js.map +1 -0
- package/dist/__tests__/selection/selector.test.d.ts +2 -0
- package/dist/__tests__/selection/selector.test.d.ts.map +1 -0
- package/dist/__tests__/selection/selector.test.js +351 -0
- package/dist/__tests__/selection/selector.test.js.map +1 -0
- package/dist/__tests__/utils/domain-utils.test.d.ts +2 -0
- package/dist/__tests__/utils/domain-utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/domain-utils.test.js +91 -0
- package/dist/__tests__/utils/domain-utils.test.js.map +1 -0
- package/dist/__tests__/utils/validation-utils.test.d.ts +2 -0
- package/dist/__tests__/utils/validation-utils.test.d.ts.map +1 -0
- package/dist/__tests__/utils/validation-utils.test.js +117 -0
- package/dist/__tests__/utils/validation-utils.test.js.map +1 -0
- package/dist/database/bootstrap.d.ts +35 -0
- package/dist/database/bootstrap.d.ts.map +1 -0
- package/dist/database/bootstrap.js +183 -0
- package/dist/database/bootstrap.js.map +1 -0
- package/dist/database/schema.d.ts +13 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +72 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.d.ts +85 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +469 -0
- package/dist/manager.js.map +1 -0
- package/dist/selection/selector.d.ts +27 -0
- package/dist/selection/selector.d.ts.map +1 -0
- package/dist/selection/selector.js +107 -0
- package/dist/selection/selector.js.map +1 -0
- package/dist/types.d.ts +257 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/domain-utils.d.ts +21 -0
- package/dist/utils/domain-utils.d.ts.map +1 -0
- package/dist/utils/domain-utils.js +65 -0
- package/dist/utils/domain-utils.js.map +1 -0
- package/dist/utils/validation-utils.d.ts +23 -0
- package/dist/utils/validation-utils.d.ts.map +1 -0
- package/dist/utils/validation-utils.js +148 -0
- package/dist/utils/validation-utils.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { DatabaseAdapter, BootstrapConfig, BootstrapResult } from '../types.js';
|
|
2
|
+
export declare class SenderBootstrap {
|
|
3
|
+
private database;
|
|
4
|
+
private config;
|
|
5
|
+
constructor(database: DatabaseAdapter, config: BootstrapConfig);
|
|
6
|
+
/**
|
|
7
|
+
* Run bootstrap process
|
|
8
|
+
*/
|
|
9
|
+
bootstrap(): Promise<BootstrapResult>;
|
|
10
|
+
/**
|
|
11
|
+
* Ensure database schema exists
|
|
12
|
+
*/
|
|
13
|
+
private ensureSchema;
|
|
14
|
+
/**
|
|
15
|
+
* Seed default senders
|
|
16
|
+
*/
|
|
17
|
+
private seedDefaultSenders;
|
|
18
|
+
/**
|
|
19
|
+
* Check if sender exists by email
|
|
20
|
+
*/
|
|
21
|
+
private senderExists;
|
|
22
|
+
/**
|
|
23
|
+
* Create a sender during bootstrap
|
|
24
|
+
*/
|
|
25
|
+
private createSender;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure exactly one default sender exists
|
|
28
|
+
*/
|
|
29
|
+
private ensureDefaultSender;
|
|
30
|
+
/**
|
|
31
|
+
* Generate unique sender ID
|
|
32
|
+
*/
|
|
33
|
+
private generateId;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/database/bootstrap.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,eAAe,EAGhB,MAAM,aAAa,CAAC;AAIrB,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,MAAM;gBADN,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,eAAe;IAGjC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAwC3C;;OAEG;YACW,YAAY;IAQ1B;;OAEG;YACW,kBAAkB;IAmBhC;;OAEG;YACW,YAAY;IAQ1B;;OAEG;YACW,YAAY;IAgE1B;;OAEG;YACW,mBAAmB;IAiCjC;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
import { getAllSchemas } from './schema.js';
|
|
9
|
+
import { extractDomain } from '../utils/domain-utils.js';
|
|
10
|
+
export class SenderBootstrap {
|
|
11
|
+
database;
|
|
12
|
+
config;
|
|
13
|
+
constructor(database, config) {
|
|
14
|
+
this.database = database;
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Run bootstrap process
|
|
19
|
+
*/
|
|
20
|
+
async bootstrap() {
|
|
21
|
+
const errors = [];
|
|
22
|
+
let tablesCreated = false;
|
|
23
|
+
let seedersRun = 0;
|
|
24
|
+
try {
|
|
25
|
+
// Create tables if enabled
|
|
26
|
+
if (this.config.createTables) {
|
|
27
|
+
await this.ensureSchema();
|
|
28
|
+
tablesCreated = true;
|
|
29
|
+
}
|
|
30
|
+
// Seed default senders if enabled
|
|
31
|
+
if (this.config.seedDefaultSenders && this.config.defaultSenders.length > 0) {
|
|
32
|
+
seedersRun = await this.seedDefaultSenders(this.config.defaultSenders);
|
|
33
|
+
}
|
|
34
|
+
// Ensure exactly one default sender
|
|
35
|
+
await this.ensureDefaultSender();
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
tablesCreated,
|
|
39
|
+
seedersRun,
|
|
40
|
+
message: `Bootstrap completed successfully. Tables created: ${tablesCreated}, Senders seeded: ${seedersRun}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
45
|
+
errors.push(errorMessage);
|
|
46
|
+
return {
|
|
47
|
+
success: false,
|
|
48
|
+
tablesCreated,
|
|
49
|
+
seedersRun,
|
|
50
|
+
message: 'Bootstrap failed',
|
|
51
|
+
errors,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Ensure database schema exists
|
|
57
|
+
*/
|
|
58
|
+
async ensureSchema() {
|
|
59
|
+
const schemas = getAllSchemas();
|
|
60
|
+
for (const schema of schemas) {
|
|
61
|
+
await this.database.execute(schema);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Seed default senders
|
|
66
|
+
*/
|
|
67
|
+
async seedDefaultSenders(senders) {
|
|
68
|
+
let count = 0;
|
|
69
|
+
for (const sender of senders) {
|
|
70
|
+
const exists = await this.senderExists(sender.fromEmail);
|
|
71
|
+
if (!exists) {
|
|
72
|
+
await this.createSender({
|
|
73
|
+
...sender,
|
|
74
|
+
createdBy: 'system-bootstrap',
|
|
75
|
+
});
|
|
76
|
+
count++;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return count;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if sender exists by email
|
|
83
|
+
*/
|
|
84
|
+
async senderExists(email) {
|
|
85
|
+
const result = await this.database.queryOne('SELECT COUNT(*) as count FROM email_senders WHERE from_email = ?', [email]);
|
|
86
|
+
return (result?.count ?? 0) > 0;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Create a sender during bootstrap
|
|
90
|
+
*/
|
|
91
|
+
async createSender(request) {
|
|
92
|
+
const id = this.generateId();
|
|
93
|
+
const domain = extractDomain(request.fromEmail);
|
|
94
|
+
const now = new Date();
|
|
95
|
+
const sender = {
|
|
96
|
+
id,
|
|
97
|
+
name: request.name,
|
|
98
|
+
...(request.description !== undefined && { description: request.description }),
|
|
99
|
+
fromEmail: request.fromEmail,
|
|
100
|
+
fromName: request.fromName,
|
|
101
|
+
...(request.replyToEmail !== undefined && { replyToEmail: request.replyToEmail }),
|
|
102
|
+
...(request.replyToName !== undefined && { replyToName: request.replyToName }),
|
|
103
|
+
provider: request.provider,
|
|
104
|
+
...(request.providerSenderId !== undefined && { providerSenderId: request.providerSenderId }),
|
|
105
|
+
...(request.providerMetadata !== undefined && { providerMetadata: request.providerMetadata }),
|
|
106
|
+
isVerified: false,
|
|
107
|
+
verificationStatus: 'pending',
|
|
108
|
+
isDefault: false,
|
|
109
|
+
isActive: true,
|
|
110
|
+
priority: request.priority ?? 100,
|
|
111
|
+
...(request.allowedDomains !== undefined && { allowedDomains: request.allowedDomains }),
|
|
112
|
+
domain,
|
|
113
|
+
createdAt: now,
|
|
114
|
+
updatedAt: now,
|
|
115
|
+
createdBy: request.createdBy,
|
|
116
|
+
lastModifiedBy: request.createdBy,
|
|
117
|
+
};
|
|
118
|
+
await this.database.execute(`INSERT INTO email_senders (
|
|
119
|
+
id, name, description, from_email, from_name, reply_to_email, reply_to_name,
|
|
120
|
+
provider, provider_sender_id, provider_metadata,
|
|
121
|
+
is_verified, verification_status, is_default, is_active, priority,
|
|
122
|
+
allowed_domains, domain, created_at, updated_at, created_by, last_modified_by
|
|
123
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
124
|
+
sender.id,
|
|
125
|
+
sender.name,
|
|
126
|
+
sender.description ?? null,
|
|
127
|
+
sender.fromEmail,
|
|
128
|
+
sender.fromName,
|
|
129
|
+
sender.replyToEmail ?? null,
|
|
130
|
+
sender.replyToName ?? null,
|
|
131
|
+
sender.provider,
|
|
132
|
+
sender.providerSenderId ?? null,
|
|
133
|
+
sender.providerMetadata ? JSON.stringify(sender.providerMetadata) : null,
|
|
134
|
+
sender.isVerified,
|
|
135
|
+
sender.verificationStatus,
|
|
136
|
+
sender.isDefault,
|
|
137
|
+
sender.isActive,
|
|
138
|
+
sender.priority,
|
|
139
|
+
sender.allowedDomains ? JSON.stringify(sender.allowedDomains) : null,
|
|
140
|
+
sender.domain,
|
|
141
|
+
sender.createdAt,
|
|
142
|
+
sender.updatedAt,
|
|
143
|
+
sender.createdBy,
|
|
144
|
+
sender.lastModifiedBy,
|
|
145
|
+
]);
|
|
146
|
+
return sender;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Ensure exactly one default sender exists
|
|
150
|
+
*/
|
|
151
|
+
async ensureDefaultSender() {
|
|
152
|
+
const defaultSenders = await this.database.query('SELECT id, last_verified_at, created_at FROM email_senders WHERE is_default = TRUE AND is_active = TRUE');
|
|
153
|
+
if (defaultSenders.length === 0) {
|
|
154
|
+
// Set the first active sender as default
|
|
155
|
+
const firstActive = await this.database.queryOne('SELECT id FROM email_senders WHERE is_active = TRUE ORDER BY created_at ASC LIMIT 1');
|
|
156
|
+
if (firstActive) {
|
|
157
|
+
await this.database.execute('UPDATE email_senders SET is_default = TRUE WHERE id = ?', [
|
|
158
|
+
firstActive.id,
|
|
159
|
+
]);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (defaultSenders.length > 1) {
|
|
163
|
+
// Keep only one default (most recently verified, or oldest)
|
|
164
|
+
const sorted = defaultSenders.sort((a, b) => {
|
|
165
|
+
if (a.last_verified_at && b.last_verified_at) {
|
|
166
|
+
return new Date(b.last_verified_at).getTime() - new Date(a.last_verified_at).getTime();
|
|
167
|
+
}
|
|
168
|
+
return new Date(a.created_at).getTime() - new Date(b.created_at).getTime();
|
|
169
|
+
});
|
|
170
|
+
const keepId = sorted[0].id;
|
|
171
|
+
await this.database.execute('UPDATE email_senders SET is_default = FALSE WHERE id != ?', [
|
|
172
|
+
keepId,
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Generate unique sender ID
|
|
178
|
+
*/
|
|
179
|
+
generateId() {
|
|
180
|
+
return `sender_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/database/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database schema for email senders table
|
|
3
|
+
*/
|
|
4
|
+
export declare const EMAIL_SENDERS_SCHEMA = "\nCREATE TABLE IF NOT EXISTS email_senders (\n id VARCHAR(255) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n description TEXT,\n\n -- Email configuration\n from_email VARCHAR(255) NOT NULL UNIQUE,\n from_name VARCHAR(255) NOT NULL,\n reply_to_email VARCHAR(255),\n reply_to_name VARCHAR(255),\n\n -- Provider integration\n provider VARCHAR(100) NOT NULL,\n provider_sender_id VARCHAR(255),\n provider_metadata JSON,\n\n -- Validation and status\n is_verified BOOLEAN DEFAULT FALSE,\n verification_status VARCHAR(50) DEFAULT 'pending',\n last_verified_at TIMESTAMP NULL,\n verification_error TEXT,\n\n -- Configuration\n is_default BOOLEAN DEFAULT FALSE,\n is_active BOOLEAN DEFAULT TRUE,\n priority INTEGER DEFAULT 100,\n\n -- Domain information\n allowed_domains JSON,\n domain VARCHAR(255) NOT NULL,\n\n -- Metadata\n created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n created_by VARCHAR(255),\n last_modified_by VARCHAR(255),\n\n -- Indexes\n INDEX idx_email_senders_from_email (from_email),\n INDEX idx_email_senders_domain (domain),\n INDEX idx_email_senders_provider (provider),\n INDEX idx_email_senders_active (is_active),\n INDEX idx_email_senders_default (is_default),\n INDEX idx_email_senders_priority (priority)\n);\n";
|
|
5
|
+
/**
|
|
6
|
+
* Migration to add name column if missing
|
|
7
|
+
*/
|
|
8
|
+
export declare const ADD_NAME_COLUMN_MIGRATION = "\nALTER TABLE email_senders\nADD COLUMN IF NOT EXISTS name VARCHAR(255)\nDEFAULT 'Unnamed Sender'\n";
|
|
9
|
+
/**
|
|
10
|
+
* Get all schema creation statements
|
|
11
|
+
*/
|
|
12
|
+
export declare function getAllSchemas(): string[];
|
|
13
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/database/schema.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,eAAO,MAAM,oBAAoB,m0CA8ChC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yBAAyB,wGAIrC,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Database schema for email senders table
|
|
10
|
+
*/
|
|
11
|
+
export const EMAIL_SENDERS_SCHEMA = `
|
|
12
|
+
CREATE TABLE IF NOT EXISTS email_senders (
|
|
13
|
+
id VARCHAR(255) PRIMARY KEY,
|
|
14
|
+
name VARCHAR(255) NOT NULL,
|
|
15
|
+
description TEXT,
|
|
16
|
+
|
|
17
|
+
-- Email configuration
|
|
18
|
+
from_email VARCHAR(255) NOT NULL UNIQUE,
|
|
19
|
+
from_name VARCHAR(255) NOT NULL,
|
|
20
|
+
reply_to_email VARCHAR(255),
|
|
21
|
+
reply_to_name VARCHAR(255),
|
|
22
|
+
|
|
23
|
+
-- Provider integration
|
|
24
|
+
provider VARCHAR(100) NOT NULL,
|
|
25
|
+
provider_sender_id VARCHAR(255),
|
|
26
|
+
provider_metadata JSON,
|
|
27
|
+
|
|
28
|
+
-- Validation and status
|
|
29
|
+
is_verified BOOLEAN DEFAULT FALSE,
|
|
30
|
+
verification_status VARCHAR(50) DEFAULT 'pending',
|
|
31
|
+
last_verified_at TIMESTAMP NULL,
|
|
32
|
+
verification_error TEXT,
|
|
33
|
+
|
|
34
|
+
-- Configuration
|
|
35
|
+
is_default BOOLEAN DEFAULT FALSE,
|
|
36
|
+
is_active BOOLEAN DEFAULT TRUE,
|
|
37
|
+
priority INTEGER DEFAULT 100,
|
|
38
|
+
|
|
39
|
+
-- Domain information
|
|
40
|
+
allowed_domains JSON,
|
|
41
|
+
domain VARCHAR(255) NOT NULL,
|
|
42
|
+
|
|
43
|
+
-- Metadata
|
|
44
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
45
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
46
|
+
created_by VARCHAR(255),
|
|
47
|
+
last_modified_by VARCHAR(255),
|
|
48
|
+
|
|
49
|
+
-- Indexes
|
|
50
|
+
INDEX idx_email_senders_from_email (from_email),
|
|
51
|
+
INDEX idx_email_senders_domain (domain),
|
|
52
|
+
INDEX idx_email_senders_provider (provider),
|
|
53
|
+
INDEX idx_email_senders_active (is_active),
|
|
54
|
+
INDEX idx_email_senders_default (is_default),
|
|
55
|
+
INDEX idx_email_senders_priority (priority)
|
|
56
|
+
);
|
|
57
|
+
`;
|
|
58
|
+
/**
|
|
59
|
+
* Migration to add name column if missing
|
|
60
|
+
*/
|
|
61
|
+
export const ADD_NAME_COLUMN_MIGRATION = `
|
|
62
|
+
ALTER TABLE email_senders
|
|
63
|
+
ADD COLUMN IF NOT EXISTS name VARCHAR(255)
|
|
64
|
+
DEFAULT 'Unnamed Sender'
|
|
65
|
+
`;
|
|
66
|
+
/**
|
|
67
|
+
* Get all schema creation statements
|
|
68
|
+
*/
|
|
69
|
+
export function getAllSchemas() {
|
|
70
|
+
return [EMAIL_SENDERS_SCHEMA, ADD_NAME_COLUMN_MIGRATION];
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/database/schema.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CnC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;;;;CAIxC,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { EmailSenderManager } from './manager.js';
|
|
2
|
+
export type { SenderConfiguration, CreateSenderRequest, UpdateSenderRequest, ListSendersOptions, PaginatedResult, ValidationError, ValidationWarning, ProviderValidationResult, SenderValidationResult, VerificationResult, SelectionOptions, DomainMatchingRule, BootstrapConfig, SelectionConfig, ValidationConfig, DatabaseAdapter, ProviderSender, SenderProviderPlugin, SyncResult, BootstrapResult, CleanupResult, SenderManagerConfig, } from './types.js';
|
|
3
|
+
export { extractDomain, isDomainMatch, isValidEmail, getParentDomain, isSubdomainOf } from './utils/domain-utils.js';
|
|
4
|
+
export { validateCreateSenderRequest, validateDomainAllowed, validateSenderConfiguration } from './utils/validation-utils.js';
|
|
5
|
+
export { SenderBootstrap } from './database/bootstrap.js';
|
|
6
|
+
export { EMAIL_SENDERS_SCHEMA, getAllSchemas } from './database/schema.js';
|
|
7
|
+
export { SenderSelector } from './selection/selector.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,YAAY,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,aAAa,EACb,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACrH,OAAO,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAG9H,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG3E,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
// Main exports
|
|
9
|
+
export { EmailSenderManager } from './manager.js';
|
|
10
|
+
// Utility exports
|
|
11
|
+
export { extractDomain, isDomainMatch, isValidEmail, getParentDomain, isSubdomainOf } from './utils/domain-utils.js';
|
|
12
|
+
export { validateCreateSenderRequest, validateDomainAllowed, validateSenderConfiguration } from './utils/validation-utils.js';
|
|
13
|
+
// Database exports
|
|
14
|
+
export { SenderBootstrap } from './database/bootstrap.js';
|
|
15
|
+
export { EMAIL_SENDERS_SCHEMA, getAllSchemas } from './database/schema.js';
|
|
16
|
+
// Selection exports
|
|
17
|
+
export { SenderSelector } from './selection/selector.js';
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;EAME;AAEF,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AA4BlD,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACrH,OAAO,EAAE,2BAA2B,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAE9H,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E,oBAAoB;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { SenderManagerConfig, SenderConfiguration, CreateSenderRequest, UpdateSenderRequest, ListSendersOptions, PaginatedResult, SenderValidationResult, VerificationResult, SelectionOptions, BootstrapResult, SyncResult, CleanupResult, SenderProviderPlugin, ProviderSender } from './types.js';
|
|
2
|
+
export declare class EmailSenderManager {
|
|
3
|
+
private database;
|
|
4
|
+
private providers;
|
|
5
|
+
private bootstrap;
|
|
6
|
+
private selector;
|
|
7
|
+
private bootstrapConfig;
|
|
8
|
+
private validationConfig;
|
|
9
|
+
private selectionConfig;
|
|
10
|
+
private systemUser;
|
|
11
|
+
constructor(config: SenderManagerConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Bootstrap database and seed default senders
|
|
14
|
+
*/
|
|
15
|
+
bootstrapDatabase(): Promise<BootstrapResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Create a new sender configuration
|
|
18
|
+
*/
|
|
19
|
+
createSender(request: CreateSenderRequest): Promise<SenderConfiguration>;
|
|
20
|
+
/**
|
|
21
|
+
* Update an existing sender
|
|
22
|
+
*/
|
|
23
|
+
updateSender(id: string, updates: UpdateSenderRequest): Promise<SenderConfiguration>;
|
|
24
|
+
/**
|
|
25
|
+
* Delete a sender
|
|
26
|
+
*/
|
|
27
|
+
deleteSender(id: string): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Get a single sender by ID
|
|
30
|
+
*/
|
|
31
|
+
getSender(id: string): Promise<SenderConfiguration | null>;
|
|
32
|
+
/**
|
|
33
|
+
* List senders with pagination and filtering
|
|
34
|
+
*/
|
|
35
|
+
listSenders(options?: ListSendersOptions): Promise<PaginatedResult<SenderConfiguration>>;
|
|
36
|
+
/**
|
|
37
|
+
* Validate a sender configuration
|
|
38
|
+
*/
|
|
39
|
+
validateSender(id: string): Promise<SenderValidationResult>;
|
|
40
|
+
/**
|
|
41
|
+
* Verify sender with provider
|
|
42
|
+
*/
|
|
43
|
+
verifySender(id: string, providerId?: string): Promise<VerificationResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Refresh verification status from provider
|
|
46
|
+
*/
|
|
47
|
+
refreshVerificationStatus(id: string): Promise<SenderConfiguration>;
|
|
48
|
+
/**
|
|
49
|
+
* Select best sender for an email address
|
|
50
|
+
*/
|
|
51
|
+
selectBestSender(fromEmail: string, options?: SelectionOptions): Promise<SenderConfiguration | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Get the default sender
|
|
54
|
+
*/
|
|
55
|
+
getDefaultSender(provider?: string): Promise<SenderConfiguration | null>;
|
|
56
|
+
/**
|
|
57
|
+
* Get senders by domain
|
|
58
|
+
*/
|
|
59
|
+
getSendersByDomain(domain: string): Promise<SenderConfiguration[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Register a provider plugin
|
|
62
|
+
*/
|
|
63
|
+
registerProvider(provider: SenderProviderPlugin): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Get provider senders
|
|
66
|
+
*/
|
|
67
|
+
getProviderSenders(providerId: string): Promise<ProviderSender[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Sync with all providers
|
|
70
|
+
*/
|
|
71
|
+
syncWithProviders(): Promise<SyncResult[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Clean up inactive senders
|
|
74
|
+
*/
|
|
75
|
+
cleanupInactiveSenders(): Promise<CleanupResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Map database row to SenderConfiguration
|
|
78
|
+
*/
|
|
79
|
+
private mapRowToSender;
|
|
80
|
+
/**
|
|
81
|
+
* Generate unique sender ID
|
|
82
|
+
*/
|
|
83
|
+
private generateId;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../src/manager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EAKf,MAAM,YAAY,CAAC;AASpB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,SAAS,CAAgD;IACjE,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,UAAU,CAAS;gBAEf,MAAM,EAAE,mBAAmB;IA0CvC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,eAAe,CAAC;IAanD;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAgF9E;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA8C1F;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C;;OAEG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAShE;;OAEG;IACG,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC;IA8DlG;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmBjE;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiDhF;;OAEG;IACG,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAczE;;OAEG;IACG,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAqBtC;;OAEG;IACG,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;IAiB9E;;OAEG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAKxE;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrE;;OAEG;IACG,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IASvE;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAwBhD;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,aAAa,CAAC;IAkBtD;;OAEG;IACH,OAAO,CAAC,cAAc;IAgDtB;;OAEG;IACH,OAAO,CAAC,UAAU;CAGnB"}
|