@bernierllc/email-template-service 1.0.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/LICENSE +21 -0
- package/README.md +449 -0
- package/dist/__tests__/email-template-service.test.d.ts +2 -0
- package/dist/__tests__/email-template-service.test.d.ts.map +1 -0
- package/dist/__tests__/email-template-service.test.js +583 -0
- package/dist/__tests__/email-template-service.test.js.map +1 -0
- package/dist/database-adapter.d.ts +59 -0
- package/dist/database-adapter.d.ts.map +1 -0
- package/dist/database-adapter.js +134 -0
- package/dist/database-adapter.js.map +1 -0
- package/dist/email-template-service.d.ts +131 -0
- package/dist/email-template-service.d.ts.map +1 -0
- package/dist/email-template-service.js +574 -0
- package/dist/email-template-service.js.map +1 -0
- package/dist/errors.d.ts +69 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +128 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/provider-plugin.d.ts +91 -0
- package/dist/provider-plugin.d.ts.map +1 -0
- package/dist/provider-plugin.js +166 -0
- package/dist/provider-plugin.js.map +1 -0
- package/dist/types.d.ts +322 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Template, BaseTemplate, ListOptions, PaginatedResult } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Database adapter interface for template persistence
|
|
4
|
+
*
|
|
5
|
+
* Implementations should provide persistence for templates and base templates.
|
|
6
|
+
* This allows the service to work with any database backend.
|
|
7
|
+
*/
|
|
8
|
+
export interface DatabaseAdapter {
|
|
9
|
+
createTemplate(template: Template): Promise<Template>;
|
|
10
|
+
updateTemplate(id: string, updates: Partial<Template>): Promise<Template>;
|
|
11
|
+
deleteTemplate(id: string): Promise<void>;
|
|
12
|
+
getTemplate(id: string): Promise<Template | null>;
|
|
13
|
+
listTemplates(options: ListOptions): Promise<PaginatedResult<Template>>;
|
|
14
|
+
getTemplatesByContext(context: string): Promise<Template[]>;
|
|
15
|
+
findTemplateByProviderId(providerId: string, providerTemplateId: string): Promise<Template | null>;
|
|
16
|
+
createBaseTemplate(baseTemplate: BaseTemplate): Promise<BaseTemplate>;
|
|
17
|
+
updateBaseTemplate(id: string, updates: Partial<BaseTemplate>): Promise<BaseTemplate>;
|
|
18
|
+
deleteBaseTemplate(id: string): Promise<void>;
|
|
19
|
+
getBaseTemplate(id: string): Promise<BaseTemplate | null>;
|
|
20
|
+
createOrUpdateVariableContext(context: {
|
|
21
|
+
name: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
variables: Record<string, unknown>;
|
|
24
|
+
extends?: string[];
|
|
25
|
+
createdAt: Date;
|
|
26
|
+
updatedAt: Date;
|
|
27
|
+
}): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* In-memory database adapter for testing and development
|
|
31
|
+
*/
|
|
32
|
+
export declare class InMemoryDatabaseAdapter implements DatabaseAdapter {
|
|
33
|
+
private templates;
|
|
34
|
+
private baseTemplates;
|
|
35
|
+
private variableContexts;
|
|
36
|
+
createTemplate(template: Template): Promise<Template>;
|
|
37
|
+
updateTemplate(id: string, updates: Partial<Template>): Promise<Template>;
|
|
38
|
+
deleteTemplate(id: string): Promise<void>;
|
|
39
|
+
getTemplate(id: string): Promise<Template | null>;
|
|
40
|
+
listTemplates(options: ListOptions): Promise<PaginatedResult<Template>>;
|
|
41
|
+
getTemplatesByContext(context: string): Promise<Template[]>;
|
|
42
|
+
findTemplateByProviderId(providerId: string, providerTemplateId: string): Promise<Template | null>;
|
|
43
|
+
createBaseTemplate(baseTemplate: BaseTemplate): Promise<BaseTemplate>;
|
|
44
|
+
updateBaseTemplate(id: string, updates: Partial<BaseTemplate>): Promise<BaseTemplate>;
|
|
45
|
+
deleteBaseTemplate(id: string): Promise<void>;
|
|
46
|
+
getBaseTemplate(id: string): Promise<BaseTemplate | null>;
|
|
47
|
+
createOrUpdateVariableContext(context: {
|
|
48
|
+
name: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
variables: Record<string, unknown>;
|
|
51
|
+
extends?: string[];
|
|
52
|
+
createdAt: Date;
|
|
53
|
+
updatedAt: Date;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
clear(): void;
|
|
56
|
+
getAllTemplates(): Template[];
|
|
57
|
+
getAllBaseTemplates(): BaseTemplate[];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=database-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-adapter.d.ts","sourceRoot":"","sources":["../src/database-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.InMemoryDatabaseAdapter = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* In-memory database adapter for testing and development
|
|
13
|
+
*/
|
|
14
|
+
class InMemoryDatabaseAdapter {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.templates = new Map();
|
|
17
|
+
this.baseTemplates = new Map();
|
|
18
|
+
this.variableContexts = new Map();
|
|
19
|
+
}
|
|
20
|
+
async createTemplate(template) {
|
|
21
|
+
this.templates.set(template.id, template);
|
|
22
|
+
return template;
|
|
23
|
+
}
|
|
24
|
+
async updateTemplate(id, updates) {
|
|
25
|
+
const existing = this.templates.get(id);
|
|
26
|
+
if (!existing) {
|
|
27
|
+
throw new Error(`Template not found: ${id}`);
|
|
28
|
+
}
|
|
29
|
+
const updated = { ...existing, ...updates, updatedAt: new Date() };
|
|
30
|
+
this.templates.set(id, updated);
|
|
31
|
+
return updated;
|
|
32
|
+
}
|
|
33
|
+
async deleteTemplate(id) {
|
|
34
|
+
if (!this.templates.has(id)) {
|
|
35
|
+
throw new Error(`Template not found: ${id}`);
|
|
36
|
+
}
|
|
37
|
+
this.templates.delete(id);
|
|
38
|
+
}
|
|
39
|
+
async getTemplate(id) {
|
|
40
|
+
return this.templates.get(id) || null;
|
|
41
|
+
}
|
|
42
|
+
async listTemplates(options) {
|
|
43
|
+
let items = Array.from(this.templates.values());
|
|
44
|
+
// Apply filters
|
|
45
|
+
if (options.category) {
|
|
46
|
+
items = items.filter(t => t.category === options.category);
|
|
47
|
+
}
|
|
48
|
+
if (options.tags && options.tags.length > 0) {
|
|
49
|
+
items = items.filter(t => options.tags.some(tag => t.tags.includes(tag)));
|
|
50
|
+
}
|
|
51
|
+
if (options.isActive !== undefined) {
|
|
52
|
+
items = items.filter(t => t.isActive === options.isActive);
|
|
53
|
+
}
|
|
54
|
+
if (options.search) {
|
|
55
|
+
const search = options.search.toLowerCase();
|
|
56
|
+
items = items.filter(t => t.name.toLowerCase().includes(search) ||
|
|
57
|
+
(t.description?.toLowerCase().includes(search) ?? false));
|
|
58
|
+
}
|
|
59
|
+
// Apply sorting
|
|
60
|
+
const sortBy = options.sortBy || 'createdAt';
|
|
61
|
+
const sortOrder = options.sortOrder || 'desc';
|
|
62
|
+
items.sort((a, b) => {
|
|
63
|
+
const aVal = a[sortBy];
|
|
64
|
+
const bVal = b[sortBy];
|
|
65
|
+
if (aVal < bVal)
|
|
66
|
+
return sortOrder === 'asc' ? -1 : 1;
|
|
67
|
+
if (aVal > bVal)
|
|
68
|
+
return sortOrder === 'asc' ? 1 : -1;
|
|
69
|
+
return 0;
|
|
70
|
+
});
|
|
71
|
+
// Apply pagination
|
|
72
|
+
const page = options.page || 1;
|
|
73
|
+
const limit = options.limit || 10;
|
|
74
|
+
const offset = (page - 1) * limit;
|
|
75
|
+
const paginatedItems = items.slice(offset, offset + limit);
|
|
76
|
+
return {
|
|
77
|
+
items: paginatedItems,
|
|
78
|
+
total: items.length,
|
|
79
|
+
page,
|
|
80
|
+
limit,
|
|
81
|
+
hasMore: offset + paginatedItems.length < items.length
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async getTemplatesByContext(context) {
|
|
85
|
+
return Array.from(this.templates.values()).filter(t => t.context === context);
|
|
86
|
+
}
|
|
87
|
+
async findTemplateByProviderId(providerId, providerTemplateId) {
|
|
88
|
+
for (const template of this.templates.values()) {
|
|
89
|
+
if (template.providerTemplateIds[providerId] === providerTemplateId) {
|
|
90
|
+
return template;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
async createBaseTemplate(baseTemplate) {
|
|
96
|
+
this.baseTemplates.set(baseTemplate.id, baseTemplate);
|
|
97
|
+
return baseTemplate;
|
|
98
|
+
}
|
|
99
|
+
async updateBaseTemplate(id, updates) {
|
|
100
|
+
const existing = this.baseTemplates.get(id);
|
|
101
|
+
if (!existing) {
|
|
102
|
+
throw new Error(`Base template not found: ${id}`);
|
|
103
|
+
}
|
|
104
|
+
const updated = { ...existing, ...updates, updatedAt: new Date() };
|
|
105
|
+
this.baseTemplates.set(id, updated);
|
|
106
|
+
return updated;
|
|
107
|
+
}
|
|
108
|
+
async deleteBaseTemplate(id) {
|
|
109
|
+
if (!this.baseTemplates.has(id)) {
|
|
110
|
+
throw new Error(`Base template not found: ${id}`);
|
|
111
|
+
}
|
|
112
|
+
this.baseTemplates.delete(id);
|
|
113
|
+
}
|
|
114
|
+
async getBaseTemplate(id) {
|
|
115
|
+
return this.baseTemplates.get(id) || null;
|
|
116
|
+
}
|
|
117
|
+
async createOrUpdateVariableContext(context) {
|
|
118
|
+
this.variableContexts.set(context.name, context);
|
|
119
|
+
}
|
|
120
|
+
// Helper methods for testing
|
|
121
|
+
clear() {
|
|
122
|
+
this.templates.clear();
|
|
123
|
+
this.baseTemplates.clear();
|
|
124
|
+
this.variableContexts.clear();
|
|
125
|
+
}
|
|
126
|
+
getAllTemplates() {
|
|
127
|
+
return Array.from(this.templates.values());
|
|
128
|
+
}
|
|
129
|
+
getAllBaseTemplates() {
|
|
130
|
+
return Array.from(this.baseTemplates.values());
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.InMemoryDatabaseAdapter = InMemoryDatabaseAdapter;
|
|
134
|
+
//# sourceMappingURL=database-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-adapter.js","sourceRoot":"","sources":["../src/database-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Template, TemplateDefinition, TemplateUpdate, BaseTemplate, BaseTemplateDefinition, BuiltTemplate, VariableContext, ValidationResult, VariableSuggestion, ListOptions, PaginatedResult, SyncConfiguration, SyncResult, BatchSyncResult, TemplateVariable } from './types';
|
|
2
|
+
import { TemplateProviderPlugin } from './provider-plugin';
|
|
3
|
+
import { DatabaseAdapter } from './database-adapter';
|
|
4
|
+
/**
|
|
5
|
+
* Email template service configuration
|
|
6
|
+
*/
|
|
7
|
+
export interface EmailTemplateServiceConfig {
|
|
8
|
+
database: DatabaseAdapter;
|
|
9
|
+
templateEngine: TemplateEngine;
|
|
10
|
+
variableRegistry: VariableRegistry;
|
|
11
|
+
providers: TemplateProviderPlugin[];
|
|
12
|
+
syncConfig: SyncConfiguration;
|
|
13
|
+
logger?: Logger;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Minimal template engine interface
|
|
17
|
+
*/
|
|
18
|
+
export interface TemplateEngine {
|
|
19
|
+
extractVariables(content: string): Promise<TemplateVariable[]>;
|
|
20
|
+
validateTemplate(content: string): Promise<ValidationResult>;
|
|
21
|
+
buildCompleteTemplate(base: {
|
|
22
|
+
headerHtml: string;
|
|
23
|
+
footerHtml: string;
|
|
24
|
+
headerCss?: string;
|
|
25
|
+
footerCss?: string;
|
|
26
|
+
}, content: string, variables?: Record<string, unknown>): Promise<string>;
|
|
27
|
+
generateTextVersion(html: string): Promise<string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Minimal variable registry interface
|
|
31
|
+
*/
|
|
32
|
+
export interface VariableRegistry {
|
|
33
|
+
registerContext(name: string, context: VariableContext): Promise<void>;
|
|
34
|
+
validateTemplate(contextName: string, content: string): Promise<ValidationResult>;
|
|
35
|
+
getSuggestions(contextName: string, prefix?: string): Promise<VariableSuggestion[]>;
|
|
36
|
+
getContext(name: string): Promise<VariableContext | null>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Minimal logger interface
|
|
40
|
+
*/
|
|
41
|
+
export interface Logger {
|
|
42
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
43
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
44
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
45
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Email Template Service
|
|
49
|
+
*
|
|
50
|
+
* Orchestrates email template management with provider synchronization,
|
|
51
|
+
* variable context validation, and base template support.
|
|
52
|
+
*/
|
|
53
|
+
export declare class EmailTemplateService {
|
|
54
|
+
private readonly database;
|
|
55
|
+
private readonly templateEngine;
|
|
56
|
+
private readonly variableRegistry;
|
|
57
|
+
private readonly providers;
|
|
58
|
+
private readonly syncConfig;
|
|
59
|
+
private readonly logger?;
|
|
60
|
+
constructor(config: EmailTemplateServiceConfig);
|
|
61
|
+
/**
|
|
62
|
+
* Create a new template
|
|
63
|
+
*/
|
|
64
|
+
createTemplate(definition: TemplateDefinition): Promise<Template>;
|
|
65
|
+
/**
|
|
66
|
+
* Update an existing template
|
|
67
|
+
*/
|
|
68
|
+
updateTemplate(id: string, updates: TemplateUpdate): Promise<Template>;
|
|
69
|
+
/**
|
|
70
|
+
* Delete a template
|
|
71
|
+
*/
|
|
72
|
+
deleteTemplate(id: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Get a template by ID
|
|
75
|
+
*/
|
|
76
|
+
getTemplate(id: string): Promise<Template | null>;
|
|
77
|
+
/**
|
|
78
|
+
* List templates with filtering and pagination
|
|
79
|
+
*/
|
|
80
|
+
listTemplates(options?: ListOptions): Promise<PaginatedResult<Template>>;
|
|
81
|
+
/**
|
|
82
|
+
* Sync template to a specific provider
|
|
83
|
+
*/
|
|
84
|
+
syncToProvider(templateId: string, providerId: string): Promise<SyncResult>;
|
|
85
|
+
/**
|
|
86
|
+
* Sync template from a provider
|
|
87
|
+
*/
|
|
88
|
+
syncFromProvider(providerTemplateId: string, providerId: string): Promise<Template>;
|
|
89
|
+
/**
|
|
90
|
+
* Sync all templates to a provider
|
|
91
|
+
*/
|
|
92
|
+
syncAllTemplates(providerId: string): Promise<BatchSyncResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Create a base template
|
|
95
|
+
*/
|
|
96
|
+
createBaseTemplate(definition: BaseTemplateDefinition): Promise<BaseTemplate>;
|
|
97
|
+
/**
|
|
98
|
+
* Build complete template from base template and content
|
|
99
|
+
*/
|
|
100
|
+
buildTemplate(baseTemplateId: string, content: string, variables?: Record<string, unknown>): Promise<BuiltTemplate>;
|
|
101
|
+
/**
|
|
102
|
+
* Register a variable context
|
|
103
|
+
*/
|
|
104
|
+
registerContext(name: string, context: VariableContext): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Validate a template against its variable context
|
|
107
|
+
*/
|
|
108
|
+
validateTemplate(templateId: string, contextOverride?: string): Promise<ValidationResult>;
|
|
109
|
+
/**
|
|
110
|
+
* Get variable suggestions for a context
|
|
111
|
+
*/
|
|
112
|
+
getVariableSuggestions(context: string, prefix?: string): Promise<VariableSuggestion[]>;
|
|
113
|
+
private validateTemplateStructure;
|
|
114
|
+
private validateBaseTemplate;
|
|
115
|
+
private syncToAllProviders;
|
|
116
|
+
private detectSyncConflicts;
|
|
117
|
+
private updateSyncStatus;
|
|
118
|
+
private revalidateTemplate;
|
|
119
|
+
private generateId;
|
|
120
|
+
private deduplicateArray;
|
|
121
|
+
private log;
|
|
122
|
+
/**
|
|
123
|
+
* Get plugin by provider ID
|
|
124
|
+
*/
|
|
125
|
+
getPlugin(providerId: string): TemplateProviderPlugin | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Find template by provider ID and template ID
|
|
128
|
+
*/
|
|
129
|
+
findTemplateByProviderId(providerId: string, providerTemplateId: string): Promise<Template | null>;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=email-template-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-template-service.d.ts","sourceRoot":"","sources":["../src/email-template-service.ts"],"names":[],"mappings":"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"}
|