/
waline.provider.ts
148 lines (147 loc) · 3.96 KB
/
waline.provider.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { Injectable, Logger } from '@nestjs/common';
import { ChildProcess, spawn } from 'node:child_process';
import { config } from 'src/config';
import { WalineSetting } from 'src/dto/setting.dto';
import { MetaProvider } from '../meta/meta.provider';
import { SettingProvider } from '../setting/setting.provider';
@Injectable()
export class WalineProvider {
// constructor() {}
ctx: ChildProcess = null;
logger = new Logger(WalineProvider.name);
env = {};
constructor(
private metaProvider: MetaProvider,
private readonly settingProvider: SettingProvider,
) {}
mapConfig2Env(config: WalineSetting) {
const walineEnvMapping = {
'smtp.port': 'SMTP_PORT',
'smtp.host': 'SMTP_HOST',
'smtp.user': 'SMTP_USER',
'sender.name': 'SENDER_NAME',
'sender.email': 'SENDER_EMAIL',
'smtp.password': 'SMTP_PASS',
authorEmail: 'AUTHOR_EMAIL',
webhook: 'WEBHOOK',
forceLoginComment: 'LOGIN',
};
const result = {};
if (!config) {
return result;
}
for (const key of Object.keys(config)) {
if (key == 'forceLoginComment') {
if (config.forceLoginComment) {
result['LOGIN'] = 'force';
}
} else {
const rKey = walineEnvMapping[key];
if (rKey) {
result[rKey] = config[key];
}
}
}
if (!config['smtp.enabled']) {
const r2 = {};
for (const [k, v] of Object.entries(result)) {
if (
![
'SMTP_PASS',
'SMTP_USER',
'SMTP_HOST',
'SMTP_PORT',
'SENDER_NAME',
'SENDER_EMAIL',
].includes(k)
) {
r2[k] = v;
}
}
return r2;
}
// console.log(result);
return result;
}
async loadEnv() {
const url = new URL(config.mongoUrl);
const mongoEnv = {
MONGO_HOST: url.hostname,
MONGO_PORT: url.port,
MONGO_USER: url.username,
MONGO_PASSWORD: url.password,
MONGO_DB: config.walineDB,
MONGO_AUTHSOURCE: 'admin',
};
const siteInfo = await this.metaProvider.getSiteInfo();
const otherEnv = {
SITE_NAME: siteInfo?.siteName || undefined,
SITE_URL: siteInfo?.baseUrl || undefined,
};
const walineConfig = await this.settingProvider.getWalineSetting();
const walineConfigEnv = this.mapConfig2Env(walineConfig);
this.env = {
...mongoEnv,
...otherEnv,
...walineConfigEnv,
};
this.logger.log(`waline 配置: ${JSON.stringify(this.env, null, 2)}`);
}
async init() {
this.run();
}
async restart(reason: string) {
this.logger.log(`${reason}重启 waline`);
if (this.ctx) {
await this.stop();
}
await this.run();
}
async stop() {
if (this.ctx) {
this.ctx.unref();
process.kill(-this.ctx.pid);
this.ctx = null;
this.logger.log('waline 停止成功!');
}
}
async run(): Promise<any> {
await this.loadEnv();
const base = '../waline/node_modules/@waline/vercel/vanilla.js';
if (this.ctx == null) {
this.ctx = spawn('node', [base], {
env: {
...process.env,
...this.env,
},
cwd: process.cwd(),
detached: true,
});
this.ctx.on('message', (message) => {
this.logger.log(message);
});
this.ctx.on('exit', () => {
this.ctx = null;
this.logger.warn('Waline 进程退出');
});
this.ctx.on('error', (err) => {
this.logger.error('Waline 错误' + err);
});
this.ctx.on('close', () => {
this.logger.warn('Waline 进程退出');
this.ctx = null;
});
this.ctx.stdout.on('data', (data) => {
const t = data.toString();
if (!t.includes('Cannot find module')) {
this.logger.log(data.toString());
}
});
this.ctx.stderr.on('data', (data) => {
this.logger.error(data.toString());
});
} else {
this.logger.log('Waline 启动成功!');
}
}
}