@travetto/email-compiler 3.4.5 → 4.0.0-rc.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/package.json +8 -8
- package/src/compiler.ts +25 -30
- package/src/util.ts +4 -4
- package/support/bin/config.ts +5 -5
- package/support/bin/editor.ts +4 -4
- package/support/bin/manager.ts +1 -1
- package/support/bin/send.ts +3 -3
- package/support/cli.email_compile.ts +3 -3
- package/support/cli.email_editor.ts +3 -4
- package/support/cli.email_test.ts +1 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/email-compiler",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-rc.0",
|
|
4
4
|
"description": "Email compiling module",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"email",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"directory": "module/email-compiler"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/base": "^
|
|
30
|
-
"@travetto/config": "^
|
|
31
|
-
"@travetto/di": "^
|
|
32
|
-
"@travetto/email": "^
|
|
33
|
-
"@travetto/image": "^
|
|
34
|
-
"@travetto/worker": "^
|
|
29
|
+
"@travetto/base": "^4.0.0-rc.0",
|
|
30
|
+
"@travetto/config": "^4.0.0-rc.0",
|
|
31
|
+
"@travetto/di": "^4.0.0-rc.0",
|
|
32
|
+
"@travetto/email": "^4.0.0-rc.0",
|
|
33
|
+
"@travetto/image": "^4.0.0-rc.0",
|
|
34
|
+
"@travetto/worker": "^4.0.0-rc.0",
|
|
35
35
|
"@types/inline-css": "^3.0.3",
|
|
36
36
|
"html-entities": "^2.4.0",
|
|
37
37
|
"inline-css": "^4.0.2",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"sass": "^1.69.5"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@travetto/cli": "^
|
|
42
|
+
"@travetto/cli": "^4.0.0-rc.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependenciesMeta": {
|
|
45
45
|
"@travetto/cli": {
|
package/src/compiler.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { FileLoader, TypedObject, WatchEvent, watchCompiler } from '@travetto/base';
|
|
4
4
|
import { EmailCompileSource, EmailCompiled, EmailCompileContext, MailUtil } from '@travetto/email';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { RuntimeIndex, path } from '@travetto/manifest';
|
|
6
|
+
import { WorkQueue } from '@travetto/worker';
|
|
7
7
|
|
|
8
8
|
import { EmailCompileUtil } from './util';
|
|
9
9
|
|
|
10
10
|
const VALID_FILE = (file: string): boolean => /[.](scss|css|png|jpe?g|gif|ya?ml)$/.test(file) && !/[.]compiled[.]/.test(file);
|
|
11
11
|
|
|
12
|
-
type WatchEvent = { action: 'create' | 'update' | 'delete', file: string, folder: string };
|
|
13
|
-
|
|
14
12
|
/**
|
|
15
13
|
* Email compilation support
|
|
16
14
|
*/
|
|
@@ -20,20 +18,23 @@ export class EmailCompiler {
|
|
|
20
18
|
* Watch folders as needed
|
|
21
19
|
*/
|
|
22
20
|
static async #watchFolders(folders: string[], handler: (ev: WatchEvent) => void, signal: AbortSignal): Promise<void> {
|
|
23
|
-
const lib = await import('@parcel/watcher');
|
|
24
21
|
for (const src of folders) {
|
|
25
|
-
|
|
26
|
-
for (const ev of
|
|
27
|
-
|
|
22
|
+
(async (): Promise<void> => {
|
|
23
|
+
for await (const ev of fs.watch(src, {
|
|
24
|
+
recursive: true,
|
|
25
|
+
signal,
|
|
26
|
+
persistent: false
|
|
27
|
+
})) {
|
|
28
|
+
const exists = ev.filename ? await fs.stat(ev.filename).catch(() => false) : false;
|
|
29
|
+
handler({ action: !!exists ? 'create' : 'delete', file: path.toPosix(ev.filename!), folder: src });
|
|
28
30
|
}
|
|
29
|
-
});
|
|
30
|
-
signal.addEventListener('abort', () => cleanup.unsubscribe());
|
|
31
|
+
})();
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
/** Load Template */
|
|
35
36
|
static async loadTemplate(file: string): Promise<EmailCompileContext> {
|
|
36
|
-
const entry =
|
|
37
|
+
const entry = RuntimeIndex.getEntry(file);
|
|
37
38
|
if (!entry) {
|
|
38
39
|
throw new Error(`Unable to find template for ${file}`);
|
|
39
40
|
}
|
|
@@ -53,7 +54,7 @@ export class EmailCompiler {
|
|
|
53
54
|
* Grab list of all available templates
|
|
54
55
|
*/
|
|
55
56
|
static findAllTemplates(mod?: string): string[] {
|
|
56
|
-
return
|
|
57
|
+
return RuntimeIndex
|
|
57
58
|
.find({
|
|
58
59
|
module: m => !mod ? m.roles.includes('std') : mod === m.name,
|
|
59
60
|
folder: f => f === 'support',
|
|
@@ -66,8 +67,8 @@ export class EmailCompiler {
|
|
|
66
67
|
* Get output files
|
|
67
68
|
*/
|
|
68
69
|
static getOutputFiles(file: string): EmailCompiled {
|
|
69
|
-
const entry =
|
|
70
|
-
const mod =
|
|
70
|
+
const entry = RuntimeIndex.getEntry(file)!;
|
|
71
|
+
const mod = RuntimeIndex.getModule(entry.module)!;
|
|
71
72
|
return EmailCompileUtil.getOutputs(file, path.join(mod.sourcePath, 'resources'));
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -118,29 +119,23 @@ export class EmailCompiler {
|
|
|
118
119
|
* Watch compilation
|
|
119
120
|
*/
|
|
120
121
|
static async * watchCompile(): AsyncIterable<string> {
|
|
121
|
-
const all =
|
|
122
|
-
.map(x =>
|
|
123
|
-
|
|
124
|
-
if (!a.set.has(v)) {
|
|
125
|
-
a.set.add(v);
|
|
126
|
-
a.arr.push(v);
|
|
127
|
-
}
|
|
128
|
-
return a;
|
|
129
|
-
}, { set: new Set(), arr: [] }).arr;
|
|
122
|
+
const all = FileLoader.resolvePaths(
|
|
123
|
+
this.findAllTemplates().map(x => `${RuntimeIndex.getEntry(x)!.module}#resources`)
|
|
124
|
+
);
|
|
130
125
|
|
|
131
126
|
const ctrl = new AbortController();
|
|
132
|
-
const stream = new
|
|
127
|
+
const stream = new WorkQueue<WatchEvent>([], ctrl.signal);
|
|
133
128
|
|
|
134
129
|
// watch resources
|
|
135
130
|
this.#watchFolders(all, ev => stream.add(ev), ctrl.signal);
|
|
136
131
|
|
|
137
132
|
// Watch template files
|
|
138
|
-
|
|
139
|
-
const src =
|
|
133
|
+
watchCompiler(ev => {
|
|
134
|
+
const src = RuntimeIndex.getEntry(ev.file);
|
|
140
135
|
if (src && EmailCompileUtil.isTemplateFile(src.sourceFile)) {
|
|
141
136
|
setTimeout(() => stream.add({ ...ev, file: src.sourceFile }), 100); // Wait for it to be loaded
|
|
142
137
|
}
|
|
143
|
-
});
|
|
138
|
+
}, { signal: ctrl.signal });
|
|
144
139
|
|
|
145
140
|
for await (const { file, action } of stream) {
|
|
146
141
|
if (action === 'delete') {
|
|
@@ -154,7 +149,7 @@ export class EmailCompiler {
|
|
|
154
149
|
yield file;
|
|
155
150
|
} else if (VALID_FILE(file)) {
|
|
156
151
|
const rootFile = file.replace(/\/resources.*/, '/package.json');
|
|
157
|
-
const mod =
|
|
152
|
+
const mod = RuntimeIndex.getFromSource(rootFile)!.module;
|
|
158
153
|
const changed = await this.compileAll(mod);
|
|
159
154
|
console.log(`Successfully compiled ${changed.length} templates`, { changed, file });
|
|
160
155
|
yield* changed;
|
package/src/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import util from 'util';
|
|
2
|
-
import { Readable } from 'stream';
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
import { Readable } from 'node:stream';
|
|
3
3
|
|
|
4
4
|
import { ResourceLoader, StreamUtil } from '@travetto/base';
|
|
5
5
|
import {
|
|
@@ -80,12 +80,12 @@ export class EmailCompileUtil {
|
|
|
80
80
|
/**
|
|
81
81
|
* Compile SCSS content with roots as search paths for additional assets
|
|
82
82
|
*/
|
|
83
|
-
static async compileSass(src: { data: string } | { file: string }, roots: string[]): Promise<string> {
|
|
83
|
+
static async compileSass(src: { data: string } | { file: string }, roots: string[] | readonly string[]): Promise<string> {
|
|
84
84
|
const sass = await import('sass');
|
|
85
85
|
const result = await util.promisify(sass.render)({
|
|
86
86
|
...src,
|
|
87
87
|
sourceMap: false,
|
|
88
|
-
includePaths: roots
|
|
88
|
+
includePaths: roots.slice(0)
|
|
89
89
|
});
|
|
90
90
|
return result!.css.toString();
|
|
91
91
|
}
|
package/support/bin/config.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
2
|
|
|
3
|
-
import { IndexedModule,
|
|
3
|
+
import { IndexedModule, RuntimeIndex, path } from '@travetto/manifest';
|
|
4
4
|
import { YamlUtil } from '@travetto/yaml';
|
|
5
5
|
|
|
6
6
|
interface ConfigType {
|
|
@@ -40,7 +40,7 @@ export class $EditorConfig {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
#getEmailConfig(mod: IndexedModule): string {
|
|
43
|
-
return this.#configFile[mod.name] ??= path.resolve(mod.sourcePath, 'resources/email/
|
|
43
|
+
return this.#configFile[mod.name] ??= path.resolve(mod.sourcePath, 'resources/email/local.yml');
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/**
|
|
@@ -48,7 +48,7 @@ export class $EditorConfig {
|
|
|
48
48
|
*/
|
|
49
49
|
async get(file: string): Promise<ConfigType> {
|
|
50
50
|
try {
|
|
51
|
-
const mod =
|
|
51
|
+
const mod = RuntimeIndex.getModuleFromSource(file)!;
|
|
52
52
|
const resolved = this.#getEmailConfig(mod);
|
|
53
53
|
const content = await fs.readFile(resolved, 'utf8');
|
|
54
54
|
return YamlUtil.parse<ConfigType>(content);
|
|
@@ -74,7 +74,7 @@ export class $EditorConfig {
|
|
|
74
74
|
|
|
75
75
|
async ensureConfig(file: string): Promise<string> {
|
|
76
76
|
console.log('Ensuring config', file);
|
|
77
|
-
const mod =
|
|
77
|
+
const mod = RuntimeIndex.getModuleFromSource(file)!;
|
|
78
78
|
const resolved = this.#getEmailConfig(mod);
|
|
79
79
|
if (!(await fs.stat(resolved).catch(() => { }))) {
|
|
80
80
|
await fs.mkdir(path.dirname(resolved), { recursive: true });
|
package/support/bin/editor.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExecUtil } from '@travetto/base';
|
|
2
2
|
|
|
3
3
|
import { EmailCompilationManager } from './manager';
|
|
4
4
|
import { EditorSendService } from './send';
|
|
@@ -54,8 +54,8 @@ export class EditorState {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
response(response: OutboundMessage): void {
|
|
57
|
-
if (process.
|
|
58
|
-
process.send(response);
|
|
57
|
+
if (process.connected) {
|
|
58
|
+
process.send?.(response);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -108,7 +108,7 @@ export class EditorState {
|
|
|
108
108
|
}
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
ExecUtil.exitOnDisconnect();
|
|
112
112
|
process.send?.('ready');
|
|
113
113
|
|
|
114
114
|
for await (const f of EmailCompiler.watchCompile()) {
|
package/support/bin/manager.ts
CHANGED
package/support/bin/send.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { MailTransportTarget } from '@travetto/email/src/internal/types';
|
|
|
3
3
|
import { DependencyRegistry } from '@travetto/di';
|
|
4
4
|
|
|
5
5
|
import { EditorConfig } from './config';
|
|
6
|
-
import {
|
|
6
|
+
import { RuntimeIndex } from '@travetto/manifest';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Util for sending emails
|
|
@@ -16,7 +16,7 @@ export class EditorSendService {
|
|
|
16
16
|
* Get mail service
|
|
17
17
|
*/
|
|
18
18
|
static async getMailService(file: string): Promise<MailService> {
|
|
19
|
-
const mod =
|
|
19
|
+
const mod = RuntimeIndex.getModuleFromSource(file)!.name;
|
|
20
20
|
|
|
21
21
|
if (!this.#svc[mod]) {
|
|
22
22
|
const senderConfig = await EditorConfig.getSenderConfig(file);
|
|
@@ -34,7 +34,7 @@ export class EditorSendService {
|
|
|
34
34
|
DependencyRegistry.install(cls, { curr: cls, type: 'added' });
|
|
35
35
|
} else if (!DependencyRegistry.getCandidateTypes(MailTransportTarget).length) {
|
|
36
36
|
const errorMessage = `
|
|
37
|
-
Please configure your email setup and/or credentials for testing. In the file \`email/
|
|
37
|
+
Please configure your email setup and/or credentials for testing. In the file \`email/local.yml\`, you can specify \`sender\` configuration.
|
|
38
38
|
Email sending will not work until the above is fixed. A sample configuration would look like:
|
|
39
39
|
|
|
40
40
|
${EditorConfig.getDefaultConfig()}`.trim();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RootRegistry } from '@travetto/registry';
|
|
2
2
|
import { CliCommandShape, CliCommand, cliTpl } from '@travetto/cli';
|
|
3
|
-
import { Env
|
|
3
|
+
import { Env } from '@travetto/base';
|
|
4
4
|
|
|
5
5
|
import { EmailCompiler } from '../src/compiler';
|
|
6
6
|
|
|
@@ -14,8 +14,8 @@ export class EmailCompileCommand implements CliCommandShape {
|
|
|
14
14
|
watch?: boolean;
|
|
15
15
|
|
|
16
16
|
preMain(): void {
|
|
17
|
-
Env.
|
|
18
|
-
|
|
17
|
+
Env.DEBUG.set(false);
|
|
18
|
+
Env.TRV_DYNAMIC.set(this.watch);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async main(): Promise<void> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Env
|
|
1
|
+
import { Env } from '@travetto/base';
|
|
2
2
|
import { CliCommand, CliUtil } from '@travetto/cli';
|
|
3
3
|
import { RootRegistry } from '@travetto/registry';
|
|
4
4
|
|
|
@@ -6,12 +6,11 @@ import { EditorState } from './bin/editor';
|
|
|
6
6
|
import { EmailCompilationManager } from './bin/manager';
|
|
7
7
|
|
|
8
8
|
/** The email editor compilation service and output serving */
|
|
9
|
-
@CliCommand()
|
|
9
|
+
@CliCommand({ addEnv: true })
|
|
10
10
|
export class EmailEditorCommand {
|
|
11
11
|
|
|
12
12
|
preMain(): void {
|
|
13
|
-
Env.
|
|
14
|
-
defineEnv({ envName: 'dev', dynamic: true });
|
|
13
|
+
Env.TRV_DYNAMIC.set(true);
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
async main(): Promise<void> {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { path } from '@travetto/manifest';
|
|
2
2
|
import { RootRegistry } from '@travetto/registry';
|
|
3
3
|
import { CliCommandShape, CliCommand } from '@travetto/cli';
|
|
4
|
-
import { Env, defineEnv } from '@travetto/base';
|
|
5
4
|
|
|
6
5
|
import { EmailCompilationManager } from './bin/manager';
|
|
7
6
|
import { EditorConfig } from './bin/config';
|
|
@@ -12,14 +11,9 @@ import { EmailCompiler } from '../src/compiler';
|
|
|
12
11
|
/**
|
|
13
12
|
* CLI Entry point for running the email server
|
|
14
13
|
*/
|
|
15
|
-
@CliCommand()
|
|
14
|
+
@CliCommand({ addEnv: true })
|
|
16
15
|
export class EmailTestCommand implements CliCommandShape {
|
|
17
16
|
|
|
18
|
-
preMain(): void {
|
|
19
|
-
Env.addToList('TRV_PROFILES', 'email-dev');
|
|
20
|
-
defineEnv({ envName: 'dev' });
|
|
21
|
-
}
|
|
22
|
-
|
|
23
17
|
async main(file: string, to: string): Promise<void> {
|
|
24
18
|
file = path.resolve(file);
|
|
25
19
|
await RootRegistry.init();
|