重构环境变量管理,添加脚本查看

This commit is contained in:
hanhh
2021-06-20 17:47:12 +08:00
parent 7ed1abde36
commit 0fade7a5a9
30 changed files with 848 additions and 976 deletions
+28 -24
View File
@@ -5,33 +5,40 @@ import { Logger } from 'winston';
import config from '../config';
import * as fs from 'fs';
import { celebrate, Joi } from 'celebrate';
import { execSync } from 'child_process';
const route = Router();
export default (app: Router) => {
app.use('/', route);
route.get(
'/config/:key',
'/configs/files',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
let content = '未找到文件';
switch (req.params.key) {
case 'config':
content = getFileContentByName(config.confFile);
break;
case 'sample':
content = getFileContentByName(config.sampleFile);
break;
case 'crontab':
content = getFileContentByName(config.crontabFile);
break;
case 'extra':
content = getFileContentByName(config.extraFile);
break;
default:
break;
}
const fileList = fs.readdirSync(config.configPath, 'utf-8');
res.send({
code: 200,
data: fileList
.filter((x) => !config.blackFileList.includes(x))
.map((x) => {
return { title: x, value: x };
}),
});
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
route.get(
'/configs/:file',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const content = getFileContentByName(
`${config.configPath}${req.params.file}`,
);
res.send({ code: 200, data: content });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -41,7 +48,7 @@ export default (app: Router) => {
);
route.post(
'/save',
'/configs/save',
celebrate({
body: Joi.object({
name: Joi.string().required(),
@@ -52,11 +59,8 @@ export default (app: Router) => {
const logger: Logger = Container.get('logger');
try {
const { name, content } = req.body;
const path = (config.fileMap as any)[name];
const path = `${config.configPath}${name}`;
fs.writeFileSync(path, content);
if (name === 'crontab.list') {
execSync(`crontab ${path}`);
}
res.send({ code: 200, msg: '保存成功' });
} catch (e) {
logger.error('🔥 error: %o', e);
+53 -46
View File
@@ -1,6 +1,6 @@
import { Router, Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import CookieService from '../services/cookie';
import EnvService from '../services/env';
import { Logger } from 'winston';
import { celebrate, Joi } from 'celebrate';
const route = Router();
@@ -8,12 +8,12 @@ const route = Router();
export default (app: Router) => {
app.use('/', route);
route.get(
'/cookies',
'/envs',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.cookies('', { position: -1 }, true);
const envService = Container.get(EnvService);
const data = await envService.envs('', { position: -1 });
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -23,15 +23,19 @@ export default (app: Router) => {
);
route.post(
'/cookies',
'/envs',
celebrate({
body: Joi.array().items(Joi.string().required()).min(1),
body: Joi.object({
value: Joi.string().required(),
name: Joi.string().required(),
remarks: Joi.string().optional(),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.create(req.body);
const envService = Container.get(EnvService);
const data = await envService.create(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -41,18 +45,20 @@ export default (app: Router) => {
);
route.put(
'/cookies',
'/envs',
celebrate({
body: Joi.object({
value: Joi.string().required(),
name: Joi.string().required(),
remarks: Joi.string().optional(),
_id: Joi.string().required(),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.update(req.body);
const envService = Container.get(EnvService);
const data = await envService.update(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -62,15 +68,15 @@ export default (app: Router) => {
);
route.delete(
'/cookies',
'/envs',
celebrate({
body: Joi.array().items(Joi.string().required()),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.remove(req.body);
const envService = Container.get(EnvService);
const data = await envService.remove(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -80,7 +86,7 @@ export default (app: Router) => {
);
route.put(
'/cookies/:id/move',
'/envs/:id/move',
celebrate({
params: Joi.object({
id: Joi.string().required(),
@@ -93,28 +99,8 @@ export default (app: Router) => {
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.move(req.params.id, req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
route.get(
'/cookies/:id/refresh',
celebrate({
params: Joi.object({
id: Joi.string().required(),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.refreshCookie(req.params.id);
const envService = Container.get(EnvService);
const data = await envService.move(req.params.id, req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -124,15 +110,15 @@ export default (app: Router) => {
);
route.put(
'/cookies/disable',
'/envs/disable',
celebrate({
body: Joi.array().items(Joi.string().required()),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.disabled(req.body);
const envService = Container.get(EnvService);
const data = await envService.disabled(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -142,15 +128,36 @@ export default (app: Router) => {
);
route.put(
'/cookies/enable',
'/envs/enable',
celebrate({
body: Joi.array().items(Joi.string().required()),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.enabled(req.body);
const envService = Container.get(EnvService);
const data = await envService.enabled(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
route.put(
'/envs/name',
celebrate({
body: Joi.object({
ids: Joi.array().items(Joi.string().required()),
name: Joi.string().required(),
}),
}),
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const envService = Container.get(EnvService);
const data = await envService.updateNames(req.body);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
@@ -160,7 +167,7 @@ export default (app: Router) => {
);
route.get(
'/cookies/:id',
'/envs/:id',
celebrate({
params: Joi.object({
id: Joi.string().required(),
@@ -169,8 +176,8 @@ export default (app: Router) => {
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const cookieService = Container.get(CookieService);
const data = await cookieService.get(req.params.id);
const envService = Container.get(EnvService);
const data = await envService.get(req.params.id);
return res.send({ code: 200, data });
} catch (e) {
logger.error('🔥 error: %o', e);
+4 -2
View File
@@ -1,17 +1,19 @@
import { Router } from 'express';
import auth from './auth';
import cookie from './cookie';
import env from './env';
import config from './config';
import log from './log';
import cron from './cron';
import script from './script';
export default () => {
const app = Router();
auth(app);
cookie(app);
env(app);
config(app);
log(app);
cron(app);
script(app);
return app;
};
+48
View File
@@ -0,0 +1,48 @@
import { getFileContentByName, getLastModifyFilePath } from '../config/util';
import { Router, Request, Response, NextFunction } from 'express';
import { Container } from 'typedi';
import { Logger } from 'winston';
import config from '../config';
import * as fs from 'fs';
import { celebrate, Joi } from 'celebrate';
const route = Router();
export default (app: Router) => {
app.use('/', route);
route.get(
'/scripts/files',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
const fileList = fs.readdirSync(config.scriptPath, 'utf-8');
res.send({
code: 200,
data: fileList.map((x) => {
return { title: x, value: x, key: x };
}),
});
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
route.get(
'/scripts/:file',
async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger');
try {
console.log(req.params.file);
const content = getFileContentByName(
`${config.scriptPath}${req.params.file}`,
);
res.send({ code: 200, data: content });
} catch (e) {
logger.error('🔥 error: %o', e);
return next(e);
}
},
);
};
+9 -9
View File
@@ -5,13 +5,15 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const envFound = dotenv.config();
const rootPath = path.resolve(__dirname, '../../');
const cookieFile = path.join(rootPath, 'config/cookie.sh');
const envFile = path.join(rootPath, 'config/env.sh');
const confFile = path.join(rootPath, 'config/config.sh');
const sampleFile = path.join(rootPath, 'sample/config.sample.sh');
const crontabFile = path.join(rootPath, 'config/crontab.list');
const confBakDir = path.join(rootPath, 'config/bak/');
const authConfigFile = path.join(rootPath, 'config/auth.json');
const extraFile = path.join(rootPath, 'config/extra.sh');
const configPath = path.join(rootPath, 'config/');
const scriptPath = path.join(rootPath, 'scripts/');
const logPath = path.join(rootPath, 'log/');
const authError = '错误的用户名密码,请重试';
const loginFaild = '请先登录!';
@@ -19,7 +21,7 @@ const configString = 'config sample crontab shareCode diy';
const dbPath = path.join(rootPath, 'db/');
const manualLogPath = path.join(rootPath, 'manual_log/');
const cronDbFile = path.join(rootPath, 'db/crontab.db');
const cookieDbFile = path.join(rootPath, 'db/cookie.db');
const envDbFile = path.join(rootPath, 'db/env.db');
const configFound = dotenv.config({ path: confFile });
if (envFound.error) {
@@ -50,14 +52,12 @@ export default {
crontabFile,
sampleFile,
confFile,
cookieFile,
fileMap: {
'config.sh': confFile,
'crontab.list': crontabFile,
'extra.sh': extraFile,
},
envFile,
dbPath,
cronDbFile,
cookieDbFile,
envDbFile,
manualLogPath,
configPath,
scriptPath,
blackFileList: ['auth.json', 'config.sh.sample', 'cookie.sh', 'crontab.list'],
};
+10 -7
View File
@@ -1,22 +1,25 @@
export class Cookie {
export class Env {
value?: string;
timestamp?: string;
created?: number;
_id?: string;
status?: CookieStatus;
status?: EnvStatus;
position?: number;
name?: number;
remarks?: number;
constructor(options: Cookie) {
constructor(options: Env) {
this.value = options.value;
this._id = options._id;
this.created = options.created || new Date().valueOf();
this.status = options.status || CookieStatus.noacquired;
this.status = options.status || EnvStatus.noacquired;
this.timestamp = new Date().toString();
this.position = options.position;
this.name = options.name;
this.remarks = options.remarks;
}
}
export enum CookieStatus {
export enum EnvStatus {
'noacquired',
'normal',
'disabled',
@@ -24,4 +27,4 @@ export enum CookieStatus {
'abnormal',
}
export const initCookiePosition = 9999999999;
export const initEnvPosition = 9999999999;
+3 -3
View File
@@ -2,7 +2,7 @@ import { exec } from 'child_process';
import { Container } from 'typedi';
import { Crontab, CrontabStatus } from '../data/cron';
import CronService from '../services/cron';
import CookieService from '../services/cookie';
import EnvService from '../services/env';
const initData = [
{
@@ -30,7 +30,7 @@ const initData = [
export default async () => {
const cronService = Container.get(CronService);
const cookieService = Container.get(CookieService);
const envService = Container.get(EnvService);
const cronDb = cronService.getDb();
cronDb.count({}, async (err, count) => {
@@ -97,7 +97,7 @@ export default async () => {
// 初始化保存一次ck和定时任务数据
await cronService.autosave_crontab();
await cookieService.set_cookies();
await envService.set_envs();
};
function randomSchedule(from: number, to: number) {
-333
View File
@@ -1,333 +0,0 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import fetch from 'node-fetch';
import { getFileContentByName } from '../config/util';
import config from '../config';
import * as fs from 'fs';
import got from 'got';
import DataStore from 'nedb';
import { Cookie, CookieStatus, initCookiePosition } from '../data/cookie';
@Service()
export default class CookieService {
private cronDb = new DataStore({ filename: config.cookieDbFile });
constructor(@Inject('logger') private logger: winston.Logger) {
this.cronDb.loadDatabase((err) => {
if (err) throw err;
});
}
public async getCookies() {
const content = getFileContentByName(config.cookieFile);
return this.formatCookie(content.split('\n').filter((x) => !!x));
}
public async addCookie(cookies: string[]) {
let content = getFileContentByName(config.cookieFile);
const originCookies = content.split('\n').filter((x) => !!x);
const result = originCookies.concat(cookies);
fs.writeFileSync(config.cookieFile, result.join('\n'));
return '';
}
public async updateCookie({ cookie, oldCookie }) {
let content = getFileContentByName(config.cookieFile);
const cookies = content.split('\n');
const index = cookies.findIndex((x) => x === oldCookie);
if (index !== -1) {
cookies[index] = cookie;
fs.writeFileSync(config.cookieFile, cookies.join('\n'));
return '';
} else {
return '未找到要原有Cookie';
}
}
public async deleteCookie(cookie: string) {
let content = getFileContentByName(config.cookieFile);
const cookies = content.split('\n');
const index = cookies.findIndex((x) => x === cookie);
if (index !== -1) {
cookies.splice(index, 1);
fs.writeFileSync(config.cookieFile, cookies.join('\n'));
return '';
} else {
return '未找到要删除的Cookie';
}
}
private async formatCookie(data: any[]) {
const result = [];
for (const x of data) {
const { nickname, status } = await this.getJdInfo(x);
if (/pt_pin=(.+?);/.test(x)) {
result.push({
pin: x.match(/pt_pin=(.+?);/)[1],
cookie: x,
status,
nickname: nickname,
});
} else {
result.push({
pin: 'pin未匹配到',
cookie: x,
status,
nickname: nickname,
});
}
}
return result;
}
public async refreshCookie(_id: string) {
const current = await this.get(_id);
const { status, nickname } = await this.getJdInfo(current.value);
return {
...current,
status,
nickname,
};
}
private getJdInfo(cookie: string) {
return fetch(
`https://me-api.jd.com/user_new/info/GetJDUserInfoUnion?orgFlag=JD_PinGou_New&callSource=mainorder&channel=4&isHomewhite=0&sceneval=2&_=${Date.now()}&sceneval=2&g_login_type=1&g_ty=ls`,
{
method: 'get',
headers: {
Accept: '*/*',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-cn',
Connection: 'keep-alive',
Cookie: cookie,
Referer: 'https://home.m.jd.com/myJd/newhome.action',
'User-Agent':
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1',
Host: 'me-api.jd.com',
},
},
)
.then((x) => x.json())
.then((x) => {
if (x.retcode === '0' && x.data && x.data.userInfo) {
return {
nickname: x.data.userInfo.baseInfo.nickname,
status: CookieStatus.normal,
};
} else if (x.retcode === 13) {
return { status: CookieStatus.invalid, nickname: '-' };
}
return { status: CookieStatus.abnormal, nickname: '-' };
});
}
private async formatCookies(cookies: Cookie[]) {
const result = [];
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i];
if (cookie.status !== CookieStatus.disabled) {
const { status, nickname } = await this.getJdInfo(cookie.value);
result.push({ ...cookie, status, nickname });
} else {
result.push({ ...cookie, nickname: '-' });
}
}
return result;
}
public async create(payload: string[]): Promise<Cookie[]> {
const cookies = await this.cookies();
let position = initCookiePosition;
if (cookies && cookies.length > 0) {
position = cookies[cookies.length - 1].position;
}
const tabs = payload.map((x) => {
const cookie = new Cookie({ value: x, position });
position = position / 2;
cookie.position = position;
return cookie;
});
const docs = await this.insert(tabs);
await this.set_cookies();
return await this.formatCookies(docs);
}
public async insert(payload: Cookie[]): Promise<Cookie[]> {
return new Promise((resolve) => {
this.cronDb.insert(payload, (err, docs) => {
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
});
});
}
public async update(payload: Cookie): Promise<Cookie> {
const { _id, ...other } = payload;
const doc = await this.get(_id);
const tab = new Cookie({ ...doc, ...other });
const newDoc = await this.updateDb(tab);
await this.set_cookies();
const [newCookie] = await this.formatCookies([newDoc]);
return newCookie;
}
private async updateDb(payload: Cookie): Promise<Cookie> {
return new Promise((resolve) => {
this.cronDb.update(
{ _id: payload._id },
payload,
{ returnUpdatedDocs: true },
(err, num, doc) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc as Cookie);
}
},
);
});
}
public async remove(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.remove(
{ _id: { $in: ids } },
{ multi: true },
async (err) => {
await this.set_cookies();
resolve();
},
);
});
}
public async move(
_id: string,
{
fromIndex,
toIndex,
}: {
fromIndex: number;
toIndex: number;
},
) {
let targetPosition: number;
const isUpward = fromIndex > toIndex;
const cookies = await this.cookies();
if (toIndex === 0 || toIndex === cookies.length - 1) {
targetPosition = isUpward
? cookies[0].position * 2
: cookies[toIndex].position / 2;
} else {
targetPosition = isUpward
? (cookies[toIndex].position + cookies[toIndex - 1].position) / 2
: (cookies[toIndex].position + cookies[toIndex + 1].position) / 2;
}
this.update({
_id,
position: targetPosition,
});
await this.set_cookies();
}
public async cookies(
searchText?: string,
sort: any = { position: -1 },
needDetail: boolean = false,
): Promise<Cookie[]> {
let query = {};
if (searchText) {
const reg = new RegExp(searchText);
query = {
$or: [
{
name: reg,
},
{
command: reg,
},
],
};
}
const newDocs = await this.find(query, sort);
if (needDetail) {
return await this.formatCookies(newDocs);
} else {
return newDocs;
}
}
private async find(query: any, sort: any): Promise<Cookie[]> {
return new Promise((resolve) => {
this.cronDb
.find(query)
.sort({ ...sort })
.exec((err, docs) => {
resolve(docs);
});
});
}
public async get(_id: string): Promise<Cookie> {
return new Promise((resolve) => {
this.cronDb.find({ _id }).exec((err, docs) => {
resolve(docs[0]);
});
});
}
public async getBySort(sort: any): Promise<Cookie> {
return new Promise((resolve) => {
this.cronDb
.find({})
.sort({ ...sort })
.limit(1)
.exec((err, docs) => {
resolve(docs[0]);
});
});
}
public async disabled(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { status: CookieStatus.disabled } },
{ multi: true },
async (err) => {
await this.set_cookies();
resolve();
},
);
});
}
public async enabled(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { status: CookieStatus.noacquired } },
{ multi: true },
async (err, num) => {
await this.set_cookies();
resolve();
},
);
});
}
public async set_cookies() {
const cookies = await this.cookies();
let cookie_string = '';
cookies.forEach((tab) => {
if (tab.status !== CookieStatus.disabled) {
cookie_string += tab.value;
cookie_string += '\n';
}
});
fs.writeFileSync(config.cookieFile, cookie_string);
}
}
+227
View File
@@ -0,0 +1,227 @@
import { Service, Inject } from 'typedi';
import winston from 'winston';
import { getFileContentByName } from '../config/util';
import config from '../config';
import * as fs from 'fs';
import DataStore from 'nedb';
import { Env, EnvStatus, initEnvPosition } from '../data/env';
import _ from 'lodash';
@Service()
export default class EnvService {
private cronDb = new DataStore({ filename: config.envDbFile });
constructor(@Inject('logger') private logger: winston.Logger) {
this.cronDb.loadDatabase((err) => {
if (err) throw err;
});
}
public async create(payload: Env): Promise<Env> {
const envs = await this.envs();
let position = initEnvPosition;
if (envs && envs.length > 0) {
position = envs[envs.length - 1].position;
}
const tab = new Env({ ...payload, position: position / 2 });
const doc = await this.insert(tab);
await this.set_envs();
return doc;
}
public async insert(payload: Env): Promise<Env> {
return new Promise((resolve) => {
this.cronDb.insert(payload, (err, doc) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc);
}
});
});
}
public async update(payload: Env): Promise<Env> {
const { _id, ...other } = payload;
const doc = await this.get(_id);
const tab = new Env({ ...doc, ...other });
const newDoc = await this.updateDb(tab);
await this.set_envs();
return newDoc;
}
private async updateDb(payload: Env): Promise<Env> {
return new Promise((resolve) => {
this.cronDb.update(
{ _id: payload._id },
payload,
{ returnUpdatedDocs: true },
(err, num, doc) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc as Env);
}
},
);
});
}
public async remove(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.remove(
{ _id: { $in: ids } },
{ multi: true },
async (err) => {
await this.set_envs();
resolve();
},
);
});
}
public async move(
_id: string,
{
fromIndex,
toIndex,
}: {
fromIndex: number;
toIndex: number;
},
) {
let targetPosition: number;
const isUpward = fromIndex > toIndex;
const envs = await this.envs();
if (toIndex === 0 || toIndex === envs.length - 1) {
targetPosition = isUpward
? envs[0].position * 2
: envs[toIndex].position / 2;
} else {
targetPosition = isUpward
? (envs[toIndex].position + envs[toIndex - 1].position) / 2
: (envs[toIndex].position + envs[toIndex + 1].position) / 2;
}
this.update({
_id,
position: targetPosition,
});
await this.set_envs();
}
public async envs(
searchText?: string,
sort: any = { position: -1 },
query: any = {},
): Promise<Env[]> {
let condition = { ...query };
if (searchText) {
const reg = new RegExp(searchText);
condition = {
$or: [
{
value: reg,
},
{
name: reg,
},
{
remarks: reg,
},
],
};
}
const newDocs = await this.find(condition, sort);
return newDocs;
}
private async find(query: any, sort: any): Promise<Env[]> {
return new Promise((resolve) => {
this.cronDb
.find(query)
.sort({ ...sort })
.exec((err, docs) => {
resolve(docs);
});
});
}
public async get(_id: string): Promise<Env> {
return new Promise((resolve) => {
this.cronDb.find({ _id }).exec((err, docs) => {
resolve(docs[0]);
});
});
}
public async getBySort(sort: any): Promise<Env> {
return new Promise((resolve) => {
this.cronDb
.find({})
.sort({ ...sort })
.limit(1)
.exec((err, docs) => {
resolve(docs[0]);
});
});
}
public async disabled(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { status: EnvStatus.disabled } },
{ multi: true },
async (err) => {
await this.set_envs();
resolve();
},
);
});
}
public async enabled(ids: string[]) {
return new Promise((resolve: any) => {
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { status: EnvStatus.noacquired } },
{ multi: true },
async (err, num) => {
await this.set_envs();
resolve();
},
);
});
}
public async updateNames({ ids, name }: { ids: string[]; name: string }) {
return new Promise((resolve: any) => {
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { name } },
{ multi: true },
async (err, num) => {
await this.set_envs();
resolve();
},
);
});
}
public async set_envs() {
const envs = await this.envs(
'',
{ position: -1 },
{ status: { $ne: EnvStatus.disabled }, name: { $exists: true } },
);
const groups = _.groupBy(envs, 'name');
console.log(groups);
let env_string = '';
for (const key in groups) {
if (Object.prototype.hasOwnProperty.call(groups, key)) {
const group = groups[key];
env_string += `export ${key}="${_.map(group, 'value').join('&')}"\n`;
}
}
fs.writeFileSync(config.envFile, env_string);
}
}