使用sqlite替换nedb

This commit is contained in:
whyour 2022-01-06 22:51:12 +08:00
parent 653b1cef20
commit 5d19ee0ab5
38 changed files with 1040 additions and 856 deletions

View File

@ -50,7 +50,7 @@ export default (app: Router) => {
route.put( route.put(
'/run', '/run',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -68,7 +68,7 @@ export default (app: Router) => {
route.put( route.put(
'/stop', '/stop',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -86,7 +86,7 @@ export default (app: Router) => {
route.put( route.put(
'/disable', '/disable',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -104,7 +104,7 @@ export default (app: Router) => {
route.put( route.put(
'/enable', '/enable',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -123,7 +123,7 @@ export default (app: Router) => {
'/:id/log', '/:id/log',
celebrate({ celebrate({
params: Joi.object({ params: Joi.object({
id: Joi.string().required(), id: Joi.number().required(),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
@ -140,13 +140,13 @@ export default (app: Router) => {
); );
route.put( route.put(
'', '/',
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
command: Joi.string().optional(), command: Joi.string().optional(),
schedule: Joi.string().optional(), schedule: Joi.string().optional(),
name: Joi.string().optional(), name: Joi.string().optional(),
_id: Joi.string().required(), id: Joi.string().required(),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
@ -172,7 +172,7 @@ export default (app: Router) => {
route.delete( route.delete(
'/', '/',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -190,7 +190,7 @@ export default (app: Router) => {
route.put( route.put(
'/pin', '/pin',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -208,7 +208,7 @@ export default (app: Router) => {
route.put( route.put(
'/unpin', '/unpin',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -262,7 +262,7 @@ export default (app: Router) => {
'/status', '/status',
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
ids: Joi.array().items(Joi.string().required()), ids: Joi.array().items(Joi.number().required()),
status: Joi.string().required(), status: Joi.string().required(),
pid: Joi.string().optional(), pid: Joi.string().optional(),
log_path: Joi.string().optional(), log_path: Joi.string().optional(),

View File

@ -49,7 +49,7 @@ export default (app: Router) => {
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
name: Joi.string().required(), name: Joi.string().required(),
_id: Joi.string().required(), id: Joi.string().required(),
type: Joi.number().required(), type: Joi.number().required(),
remark: Joi.number().optional().allow(''), remark: Joi.number().optional().allow(''),
}), }),
@ -70,7 +70,7 @@ export default (app: Router) => {
route.delete( route.delete(
'/', '/',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -88,7 +88,7 @@ export default (app: Router) => {
route.delete( route.delete(
'/force', '/force',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -126,7 +126,7 @@ export default (app: Router) => {
route.put( route.put(
'/reinstall', '/reinstall',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');

View File

@ -51,7 +51,7 @@ export default (app: Router) => {
value: Joi.string().required(), value: Joi.string().required(),
name: Joi.string().required(), name: Joi.string().required(),
remarks: Joi.string().optional().allow(''), remarks: Joi.string().optional().allow(''),
_id: Joi.string().required(), id: Joi.string().required(),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
@ -70,7 +70,7 @@ export default (app: Router) => {
route.delete( route.delete(
'/', '/',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -112,7 +112,7 @@ export default (app: Router) => {
route.put( route.put(
'/disable', '/disable',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -130,7 +130,7 @@ export default (app: Router) => {
route.put( route.put(
'/enable', '/enable',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');
@ -149,7 +149,7 @@ export default (app: Router) => {
'/name', '/name',
celebrate({ celebrate({
body: Joi.object({ body: Joi.object({
ids: Joi.array().items(Joi.string().required()), ids: Joi.array().items(Joi.number().required()),
name: Joi.string().required(), name: Joi.string().required(),
}), }),
}), }),

View File

@ -49,7 +49,7 @@ export default (app: Router) => {
body: Joi.object({ body: Joi.object({
name: Joi.string().optional().allow(''), name: Joi.string().optional().allow(''),
scopes: Joi.array().items(Joi.string()), scopes: Joi.array().items(Joi.string()),
_id: Joi.string().required(), id: Joi.string().required(),
}), }),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
@ -68,7 +68,7 @@ export default (app: Router) => {
route.delete( route.delete(
'/apps', '/apps',
celebrate({ celebrate({
body: Joi.array().items(Joi.string().required()), body: Joi.array().items(Joi.number().required()),
}), }),
async (req: Request, res: Response, next: NextFunction) => { async (req: Request, res: Response, next: NextFunction) => {
const logger: Logger = Container.get('logger'); const logger: Logger = Container.get('logger');

View File

@ -1,14 +1,17 @@
import { sequelize } from '.';
import { DataTypes, Model, ModelDefined } from 'sequelize';
export class AuthInfo { export class AuthInfo {
ip?: string; ip?: string;
type: AuthDataType; type: AuthDataType;
info?: any; info?: any;
_id?: string; id?: number;
constructor(options: AuthInfo) { constructor(options: AuthInfo) {
this.ip = options.ip; this.ip = options.ip;
this.info = options.info; this.info = options.info;
this.type = options.type; this.type = options.type;
this._id = options._id; this.id = options.id;
} }
} }
@ -23,3 +26,13 @@ export enum AuthDataType {
'notification' = 'notification', 'notification' = 'notification',
'removeLogFrequency' = 'removeLogFrequency', 'removeLogFrequency' = 'removeLogFrequency',
} }
interface AuthInstance extends Model<AuthInfo, AuthInfo>, AuthInfo {}
export const AuthModel = sequelize.define<AuthInstance>('Auth', {
ip: DataTypes.STRING,
type: DataTypes.STRING,
info: {
type: DataTypes.JSON,
allowNull: true,
},
});

View File

@ -1,34 +1,40 @@
import { sequelize } from '.';
import { DataTypes, Model, ModelDefined } from 'sequelize';
export class Crontab { export class Crontab {
name?: string; name?: string;
command: string; command: string;
schedule: string; schedule: string;
timestamp?: string; timestamp?: string;
created?: number;
saved?: boolean; saved?: boolean;
_id?: string; id?: number;
status?: CrontabStatus; status?: CrontabStatus;
isSystem?: 1 | 0; isSystem?: 1 | 0;
pid?: number; pid?: number;
isDisabled?: 1 | 0; isDisabled?: 1 | 0;
log_path?: string; log_path?: string;
isPinned?: 1 | 0; isPinned?: 1 | 0;
last_running_time?: number;
last_execution_time?: number;
constructor(options: Crontab) { constructor(options: Crontab) {
this.name = options.name; this.name = options.name;
this.command = options.command; this.command = options.command;
this.schedule = options.schedule; this.schedule = options.schedule;
this.saved = options.saved; this.saved = options.saved;
this._id = options._id; this.id = options.id;
this.created = options.created; this.status =
this.status = CrontabStatus[options.status] options.status && CrontabStatus[options.status]
? options.status ? options.status
: CrontabStatus.idle; : CrontabStatus.idle;
this.timestamp = new Date().toString(); this.timestamp = new Date().toString();
this.isSystem = options.isSystem || 0; this.isSystem = options.isSystem || 0;
this.pid = options.pid; this.pid = options.pid;
this.isDisabled = options.isDisabled || 0; this.isDisabled = options.isDisabled || 0;
this.log_path = options.log_path || ''; this.log_path = options.log_path || '';
this.isPinned = options.isPinned || 0; this.isPinned = options.isPinned || 0;
this.last_running_time = options.last_running_time || 0;
this.last_execution_time = options.last_execution_time || 0;
} }
} }
@ -38,3 +44,20 @@ export enum CrontabStatus {
'disabled', 'disabled',
'queued', 'queued',
} }
interface CronInstance extends Model<Crontab, Crontab>, Crontab {}
export const CrontabModel = sequelize.define<CronInstance>('Crontab', {
name: DataTypes.STRING,
command: DataTypes.STRING,
schedule: DataTypes.STRING,
timestamp: DataTypes.STRING,
saved: DataTypes.BOOLEAN,
status: DataTypes.NUMBER,
isSystem: DataTypes.NUMBER,
pid: DataTypes.NUMBER,
isDisabled: DataTypes.NUMBER,
isPinned: DataTypes.NUMBER,
log_path: DataTypes.STRING,
last_running_time: DataTypes.NUMBER,
last_execution_time: DataTypes.NUMBER,
});

View File

@ -1,7 +1,9 @@
import { sequelize } from '.';
import { DataTypes, Model, ModelDefined } from 'sequelize';
export class Dependence { export class Dependence {
timestamp?: string; timestamp?: string;
created?: number; id?: number;
_id?: string;
status?: DependenceStatus; status?: DependenceStatus;
type?: DependenceTypes; type?: DependenceTypes;
name?: number; name?: number;
@ -9,8 +11,7 @@ export class Dependence {
remark?: string; remark?: string;
constructor(options: Dependence) { constructor(options: Dependence) {
this._id = options._id; this.id = options.id;
this.created = options.created || new Date().valueOf();
this.status = options.status || DependenceStatus.installing; this.status = options.status || DependenceStatus.installing;
this.type = options.type || DependenceTypes.nodejs; this.type = options.type || DependenceTypes.nodejs;
this.timestamp = new Date().toString(); this.timestamp = new Date().toString();
@ -46,3 +47,18 @@ export enum unInstallDependenceCommandTypes {
'pip3 uninstall -y', 'pip3 uninstall -y',
'apk del -f', 'apk del -f',
} }
interface DependenceInstance
extends Model<Dependence, Dependence>,
Dependence {}
export const DependenceModel = sequelize.define<DependenceInstance>(
'Dependence',
{
name: DataTypes.STRING,
type: DataTypes.STRING,
timestamp: DataTypes.STRING,
status: DataTypes.STRING,
log: DataTypes.JSON,
remark: DataTypes.STRING,
},
);

View File

@ -1,17 +1,18 @@
import { sequelize } from '.';
import { DataTypes, Model, ModelDefined } from 'sequelize';
export class Env { export class Env {
value?: string; value?: string;
timestamp?: string; timestamp?: string;
created?: number; id?: number;
_id?: string;
status?: EnvStatus; status?: EnvStatus;
position?: number; position?: number;
name?: number; name?: string;
remarks?: number; remarks?: string;
constructor(options: Env) { constructor(options: Env) {
this.value = options.value; this.value = options.value;
this._id = options._id; this.id = options.id;
this.created = options.created || new Date().valueOf();
this.status = options.status || EnvStatus.normal; this.status = options.status || EnvStatus.normal;
this.timestamp = new Date().toString(); this.timestamp = new Date().toString();
this.position = options.position; this.position = options.position;
@ -26,3 +27,13 @@ export enum EnvStatus {
} }
export const initEnvPosition = 9999999999; export const initEnvPosition = 9999999999;
interface EnvInstance extends Model<Env, Env>, Env {}
export const EnvModel = sequelize.define<EnvInstance>('Env', {
value: DataTypes.STRING,
timestamp: DataTypes.STRING,
status: DataTypes.NUMBER,
position: DataTypes.NUMBER,
name: DataTypes.STRING,
remarks: DataTypes.STRING,
});

8
back/data/index.ts Normal file
View File

@ -0,0 +1,8 @@
import { Sequelize } from 'sequelize';
import config from '../config/index';
export const sequelize = new Sequelize({
dialect: 'sqlite',
storage: `${config.dbPath}database.sqlite`,
logging: false,
});

View File

@ -1,23 +1,26 @@
import { sequelize } from '.';
import { DataTypes, Model, ModelDefined } from 'sequelize';
export class App { export class App {
name: string; name: string;
scopes: AppScope[]; scopes: AppScope[];
client_id: string; client_id: string;
client_secret: string; client_secret: string;
tokens?: AppToken[]; tokens?: AppToken[];
_id?: string; id?: number;
constructor(options: App) { constructor(options: App) {
this.name = options.name; this.name = options.name;
this.scopes = options.scopes; this.scopes = options.scopes;
this.client_id = options.client_id; this.client_id = options.client_id;
this.client_secret = options.client_secret; this.client_secret = options.client_secret;
this._id = options._id; this.id = options.id;
} }
} }
export interface AppToken { export interface AppToken {
value: string; value: string;
type: 'Bearer'; type?: 'Bearer';
expiration: number; expiration: number;
} }
@ -29,3 +32,12 @@ export enum CrontabStatus {
'disabled', 'disabled',
'queued', 'queued',
} }
interface AppInstance extends Model<App, App>, App {}
export const AppModel = sequelize.define<AppInstance>('App', {
name: DataTypes.STRING,
scopes: DataTypes.JSON,
client_id: DataTypes.STRING,
client_secret: DataTypes.STRING,
tokens: DataTypes.JSON,
});

View File

@ -1,7 +1,7 @@
export class SockMessage { export class SockMessage {
message?: string; message?: string;
type?: SockMessageType; type?: SockMessageType;
references?: string[]; references?: number[];
constructor(options: SockMessage) { constructor(options: SockMessage) {
this.type = options.type; this.type = options.type;

View File

@ -3,6 +3,12 @@ import config from '../config';
import Logger from './logger'; import Logger from './logger';
import fs from 'fs'; import fs from 'fs';
import { fileExist } from '../config/util'; import { fileExist } from '../config/util';
import { EnvModel } from '../data/env';
import { CrontabModel } from '../data/cron';
import { DependenceModel } from '../data/dependence';
import { AppModel } from '../data/open';
import { AuthModel } from '../data/auth';
import { sequelize } from '../data';
interface Dbs { interface Dbs {
cronDb: DataStore; cronDb: DataStore;
@ -53,6 +59,43 @@ export default async () => {
db.appDb.persistence.compactDatafile(); db.appDb.persistence.compactDatafile();
db.authDb.persistence.compactDatafile(); db.authDb.persistence.compactDatafile();
try {
await sequelize.sync();
} catch (error) {
console.log(error);
}
// migrate db to sqlite
setTimeout(async () => {
try {
const count = await CrontabModel.count();
if (count !== 0) {
return;
}
db.cronDb.find({}).exec(async (err, docs) => {
await CrontabModel.bulkCreate(docs);
});
db.dependenceDb.find({}).exec(async (err, docs) => {
await DependenceModel.bulkCreate(docs);
});
db.envDb.find({}).exec(async (err, docs) => {
await EnvModel.bulkCreate(docs);
});
db.appDb.find({}).exec(async (err, docs) => {
await AppModel.bulkCreate(docs);
});
db.authDb.find({}).exec(async (err, docs) => {
await AuthModel.bulkCreate(docs);
});
} catch (error) {
console.log(error);
}
}, 5000);
Logger.info('✌️ DB loaded'); Logger.info('✌️ DB loaded');
} catch (error) { } catch (error) {
Logger.info('✌️ DB load failed'); Logger.info('✌️ DB load failed');

View File

@ -1,33 +1,31 @@
import DependenceService from '../services/dependence'; import DependenceService from '../services/dependence';
import { exec } from 'child_process'; import { exec } from 'child_process';
import { Container } from 'typedi'; import { Container } from 'typedi';
import { Crontab, CrontabStatus } from '../data/cron'; import { Crontab, CrontabModel, CrontabStatus } from '../data/cron';
import CronService from '../services/cron'; import CronService from '../services/cron';
import EnvService from '../services/env'; import EnvService from '../services/env';
import _ from 'lodash'; import _ from 'lodash';
import { dbs } from '../loaders/db'; import { DependenceModel } from '../data/dependence';
import { Op } from 'sequelize';
export default async () => { export default async () => {
const cronService = Container.get(CronService); const cronService = Container.get(CronService);
const envService = Container.get(EnvService); const envService = Container.get(EnvService);
const dependenceService = Container.get(DependenceService); const dependenceService = Container.get(DependenceService);
const cronDb = dbs.cronDb;
const dependenceDb = dbs.dependenceDb;
// 初始化更新所有任务状态为空闲 // 初始化更新所有任务状态为空闲
cronDb.update( await CrontabModel.update(
{ status: { $in: [CrontabStatus.running, CrontabStatus.queued] } }, { status: CrontabStatus.idle },
{ $set: { status: CrontabStatus.idle } }, { where: { status: [CrontabStatus.running, CrontabStatus.queued] } },
{ multi: true },
); );
// 初始化时安装所有处于安装中,安装成功,安装失败的依赖 // 初始化时安装所有处于安装中,安装成功,安装失败的依赖
dependenceDb.find({ status: { $in: [0, 1, 2] } }).exec(async (err, docs) => { DependenceModel.findAll({ where: {} }).then(async (docs) => {
const groups = _.groupBy(docs, 'type'); const groups = _.groupBy(docs, 'type');
for (const key in groups) { for (const key in groups) {
if (Object.prototype.hasOwnProperty.call(groups, key)) { if (Object.prototype.hasOwnProperty.call(groups, key)) {
const group = groups[key]; const group = groups[key];
const depIds = group.map((x) => x._id); const depIds = group.map((x) => x.id);
for (const dep of depIds) { for (const dep of depIds) {
await dependenceService.reInstall([dep]); await dependenceService.reInstall([dep]);
} }
@ -36,38 +34,21 @@ export default async () => {
}); });
// 初始化时执行一次所有的ql repo 任务 // 初始化时执行一次所有的ql repo 任务
cronDb CrontabModel.findAll({
.find({ where: {
command: /ql (repo|raw)/, isDisabled: { [Op.ne]: 1 },
isDisabled: { $ne: 1 }, command: {
}) [Op.or]: [{ [Op.like]: `%ql repo%` }, { [Op.like]: `%$ql raw%` }],
.exec((err, docs) => { },
for (let i = 0; i < docs.length; i++) { },
const doc = docs[i]; }).then((docs) => {
if (doc) { for (let i = 0; i < docs.length; i++) {
exec(doc.command); const doc = docs[i];
} if (doc) {
exec(doc.command);
} }
}); }
});
// patch 禁用状态字段改变
cronDb
.find({
status: CrontabStatus.disabled,
})
.exec((err, docs) => {
if (docs.length > 0) {
const ids = docs.map((x) => x._id);
cronDb.update(
{ _id: { $in: ids } },
{ $set: { status: CrontabStatus.idle, isDisabled: 1 } },
{ multi: true },
(err) => {
cronService.autosave_crontab();
},
);
}
});
// 初始化保存一次ck和定时任务数据 // 初始化保存一次ck和定时任务数据
await cronService.autosave_crontab(); await cronService.autosave_crontab();

View File

@ -2,24 +2,14 @@ import schedule from 'node-schedule';
import express from 'express'; import express from 'express';
import { exec } from 'child_process'; import { exec } from 'child_process';
import Logger from './loaders/logger'; import Logger from './loaders/logger';
import { CrontabStatus } from './data/cron'; import { CrontabModel, CrontabStatus } from './data/cron';
import config from './config'; import config from './config';
import { dbs } from './loaders/db';
const app = express(); const app = express();
const run = async () => { const run = async () => {
const cronDb = dbs.cronDb; CrontabModel.findAll({ where: {} })
.then((docs) => {
cronDb
.find({})
.sort({ created: 1 })
.exec((err, docs) => {
if (err) {
Logger.error(err);
process.exit(1);
}
if (docs && docs.length > 0) { if (docs && docs.length > 0) {
for (let i = 0; i < docs.length; i++) { for (let i = 0; i < docs.length; i++) {
const task = docs[i]; const task = docs[i];
@ -40,6 +30,10 @@ const run = async () => {
} }
} }
} }
})
.catch((err) => {
Logger.error(err);
process.exit(1);
}); });
}; };

View File

@ -1,25 +1,17 @@
import { Service, Inject } from 'typedi'; import { Service, Inject } from 'typedi';
import winston from 'winston'; import winston from 'winston';
import DataStore from 'nedb';
import config from '../config'; import config from '../config';
import { Crontab, CrontabStatus } from '../data/cron'; import { Crontab, CrontabModel, CrontabStatus } from '../data/cron';
import { exec, execSync, spawn } from 'child_process'; import { exec, execSync, spawn } from 'child_process';
import fs from 'fs'; import fs from 'fs';
import cron_parser from 'cron-parser'; import cron_parser from 'cron-parser';
import { getFileContentByName, concurrentRun } from '../config/util'; import { getFileContentByName, concurrentRun } from '../config/util';
import PQueue from 'p-queue';
import { promises, existsSync } from 'fs'; import { promises, existsSync } from 'fs';
import { promisify } from 'util'; import { promisify } from 'util';
import { dbs } from '../loaders/db'; import { Op } from 'sequelize';
@Service() @Service()
export default class CronService { export default class CronService {
private cronDb = dbs.cronDb;
private queue = new PQueue({
concurrency: parseInt(process.env.MaxConcurrentNum as string) || 5,
});
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
private isSixCron(cron: Crontab) { private isSixCron(cron: Crontab) {
@ -32,7 +24,6 @@ export default class CronService {
public async create(payload: Crontab): Promise<Crontab> { public async create(payload: Crontab): Promise<Crontab> {
const tab = new Crontab(payload); const tab = new Crontab(payload);
tab.created = new Date().valueOf();
tab.saved = false; tab.saved = false;
const doc = await this.insert(tab); const doc = await this.insert(tab);
await this.set_crontab(this.isSixCron(doc)); await this.set_crontab(this.isSixCron(doc));
@ -40,20 +31,12 @@ export default class CronService {
} }
public async insert(payload: Crontab): Promise<Crontab> { public async insert(payload: Crontab): Promise<Crontab> {
return new Promise((resolve) => { return await CrontabModel.create(payload);
this.cronDb.insert(payload, (err, docs) => {
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
});
});
} }
public async update(payload: Crontab): Promise<Crontab> { public async update(payload: Crontab): Promise<Crontab> {
const { _id, ...other } = payload; const { id, ...other } = payload;
const doc = await this.get(_id); const doc = await this.get(id as number);
const tab = new Crontab({ ...doc, ...other }); const tab = new Crontab({ ...doc, ...other });
tab.saved = false; tab.saved = false;
const newDoc = await this.updateDb(tab); const newDoc = await this.updateDb(tab);
@ -62,20 +45,11 @@ export default class CronService {
} }
public async updateDb(payload: Crontab): Promise<Crontab> { public async updateDb(payload: Crontab): Promise<Crontab> {
return new Promise((resolve) => { const result = await CrontabModel.update(
this.cronDb.update( { ...payload },
{ _id: payload._id }, { where: { id: payload.id } },
payload, );
{ returnUpdatedDocs: true }, return result[1][0];
(err, num, docs: any) => {
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
},
);
});
} }
public async status({ public async status({
@ -86,7 +60,7 @@ export default class CronService {
last_running_time = 0, last_running_time = 0,
last_execution_time = 0, last_execution_time = 0,
}: { }: {
ids: string[]; ids: number[];
status: CrontabStatus; status: CrontabStatus;
pid: number; pid: number;
log_path: string; log_path: string;
@ -103,67 +77,35 @@ export default class CronService {
options.last_running_time = last_running_time; options.last_running_time = last_running_time;
} }
return new Promise((resolve) => { return await CrontabModel.update({ ...options }, { where: { id: ids } });
this.cronDb.update(
{ _id: { $in: ids } },
{
$set: options,
},
{ multi: true, returnUpdatedDocs: true },
(err) => {
resolve(null);
},
);
});
} }
public async remove(ids: string[]) { public async remove(ids: number[]) {
return new Promise((resolve: any) => { await CrontabModel.destroy({ where: { id: ids } });
this.cronDb.remove( await this.set_crontab(true);
{ _id: { $in: ids } },
{ multi: true },
async (err) => {
await this.set_crontab(true);
resolve();
},
);
});
} }
public async pin(ids: string[]) { public async pin(ids: number[]) {
return new Promise((resolve: any) => { await CrontabModel.update({ isPinned: 1 }, { where: { id: ids } });
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { isPinned: 1 } },
{ multi: true },
async (err) => {
resolve();
},
);
});
} }
public async unPin(ids: string[]) { public async unPin(ids: number[]) {
return new Promise((resolve: any) => { await CrontabModel.update({ isPinned: 0 }, { where: { id: ids } });
this.cronDb.update(
{ _id: { $in: ids } },
{ $set: { isPinned: 0 } },
{ multi: true },
async (err) => {
resolve();
},
);
});
} }
public async crontabs(searchText?: string): Promise<Crontab[]> { public async crontabs(searchText?: string): Promise<Crontab[]> {
let query = {}; let query = {};
if (searchText) { if (searchText) {
const encodeText = encodeURIComponent(searchText); const encodeText = encodeURIComponent(searchText);
const reg = new RegExp(`${searchText}|${encodeText}`, 'i'); const reg = {
[Op.or]: [
{ [Op.like]: `%${searchText}&` },
{ [Op.like]: `%${encodeText}%` },
],
};
query = { query = {
$or: [ [Op.or]: [
{ {
name: reg, name: reg,
}, },
@ -176,69 +118,56 @@ export default class CronService {
], ],
}; };
} }
return new Promise((resolve) => { try {
this.cronDb const result = await CrontabModel.findAll({ where: query });
.find(query) return result as any;
.sort({ created: -1 }) } catch (error) {
.exec((err, docs) => { throw error;
resolve(docs); }
});
});
} }
public async get(_id: string): Promise<Crontab> { public async get(id: number): Promise<Crontab> {
return new Promise((resolve) => { const result = await CrontabModel.findAll({ where: { id } });
this.cronDb.find({ _id }).exec((err, docs) => { return result[0] as any;
resolve(docs[0]);
});
});
} }
public async run(ids: string[]) { public async run(ids: number[]) {
this.cronDb.update( await CrontabModel.update(
{ _id: { $in: ids } }, { status: CrontabStatus.queued },
{ $set: { status: CrontabStatus.queued } }, { where: { id: ids } },
{ multi: true },
); );
concurrentRun( concurrentRun(
ids.map((id) => () => this.runSingle(id)), ids.map((id) => async () => await this.runSingle(id)),
10, 10,
); );
} }
public async stop(ids: string[]) { public async stop(ids: number[]) {
return new Promise((resolve: any) => { const docs = await CrontabModel.findAll({ where: { id: ids } });
this.cronDb for (const doc of docs) {
.find({ _id: { $in: ids } }) if (doc.pid) {
.exec(async (err, docs: Crontab[]) => { try {
for (const doc of docs) { process.kill(-doc.pid);
if (doc.pid) { } catch (error) {
try { this.logger.silly(error);
process.kill(-doc.pid); }
} catch (error) { }
this.logger.silly(error); const err = await this.killTask(doc.command);
} if (doc.log_path) {
} const str = err ? `\n${err}` : '';
const err = await this.killTask(doc.command); fs.appendFileSync(
if (doc.log_path) { `${doc.log_path}`,
const str = err ? `\n${err}` : ''; `${str}\n## 执行结束... ${new Date()
fs.appendFileSync( .toLocaleString('zh', { hour12: false })
`${doc.log_path}`, .replace(' 24:', ' 00:')} `,
`${str}\n## 执行结束... ${new Date() );
.toLocaleString('zh', { hour12: false }) }
.replace(' 24:', ' 00:')} `, }
);
} await CrontabModel.update(
} { status: CrontabStatus.queued, pid: undefined },
this.cronDb.update( { where: { id: ids } },
{ _id: { $in: ids } }, );
{ $set: { status: CrontabStatus.idle }, $unset: { pid: true } },
{ multi: true },
);
this.queue.clear();
resolve();
});
});
} }
public async killTask(name: string) { public async killTask(name: string) {
@ -273,18 +202,18 @@ export default class CronService {
} }
} }
private async runSingle(id: string): Promise<number> { private async runSingle(cronId: number): Promise<number> {
return new Promise(async (resolve: any) => { return new Promise(async (resolve: any) => {
const cron = await this.get(id); const cron = await this.get(cronId);
if (cron.status !== CrontabStatus.queued) { if (cron.status !== CrontabStatus.queued) {
resolve(); resolve();
return; return;
} }
let { _id, command, log_path } = cron; let { id, command, log_path } = cron;
this.logger.silly('Running job'); this.logger.silly('Running job');
this.logger.silly('ID: ' + _id); this.logger.silly('ID: ' + id);
this.logger.silly('Original command: ' + command); this.logger.silly('Original command: ' + command);
let cmdStr = command; let cmdStr = command;
@ -296,9 +225,10 @@ export default class CronService {
} }
const cp = spawn(cmdStr, { shell: '/bin/bash' }); const cp = spawn(cmdStr, { shell: '/bin/bash' });
this.cronDb.update(
{ _id }, await CrontabModel.update(
{ $set: { status: CrontabStatus.running, pid: cp.pid } }, { status: CrontabStatus.running, pid: cp.pid },
{ where: { id } },
); );
cp.stderr.on('data', (data) => { cp.stderr.on('data', (data) => {
if (log_path) { if (log_path) {
@ -311,57 +241,39 @@ export default class CronService {
} }
}); });
cp.on('exit', (code, signal) => { cp.on('exit', async (code, signal) => {
this.logger.info( this.logger.info(
`${command} pid: ${cp.pid} exit ${code} signal ${signal}`, `${command} pid: ${cp.pid} exit ${code} signal ${signal}`,
); );
this.cronDb.update( await CrontabModel.update(
{ _id }, { status: CrontabStatus.idle, pid: undefined },
{ $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, { where: { id } },
); );
resolve(); resolve();
}); });
cp.on('close', (code) => { cp.on('close', async (code) => {
this.logger.info(`${command} pid: ${cp.pid} closed ${code}`); this.logger.info(`${command} pid: ${cp.pid} closed ${code}`);
this.cronDb.update( await CrontabModel.update(
{ _id }, { status: CrontabStatus.idle, pid: undefined },
{ $set: { status: CrontabStatus.idle }, $unset: { pid: true } }, { where: { id } },
); );
resolve(); resolve();
}); });
}); });
} }
public async disabled(ids: string[]) { public async disabled(ids: number[]) {
return new Promise((resolve: any) => { await CrontabModel.update({ isDisabled: 1 }, { where: { id: ids } });
this.cronDb.update( await this.set_crontab(true);
{ _id: { $in: ids } },
{ $set: { isDisabled: 1 } },
{ multi: true },
async (err) => {
await this.set_crontab(true);
resolve();
},
);
});
} }
public async enabled(ids: string[]) { public async enabled(ids: number[]) {
return new Promise((resolve: any) => { await CrontabModel.update({ isDisabled: 0 }, { where: { id: ids } });
this.cronDb.update( await this.set_crontab(true);
{ _id: { $in: ids } },
{ $set: { isDisabled: 0 } },
{ multi: true },
async (err) => {
await this.set_crontab(true);
resolve();
},
);
});
} }
public async log(_id: string) { public async log(id: number) {
const doc = await this.get(_id); const doc = await this.get(id);
if (!doc) { if (!doc) {
return ''; return '';
} }
@ -401,7 +313,7 @@ export default class CronService {
} }
private make_command(tab: Crontab) { private make_command(tab: Crontab) {
const crontab_job_string = `ID=${tab._id} ${tab.command}`; const crontab_job_string = `ID=${tab.id} ${tab.command}`;
return crontab_job_string; return crontab_job_string;
} }
@ -431,7 +343,7 @@ export default class CronService {
if (needReloadSchedule) { if (needReloadSchedule) {
exec(`pm2 reload schedule`); exec(`pm2 reload schedule`);
} }
this.cronDb.update({}, { $set: { saved: true } }, { multi: true }); await CrontabModel.update({ saved: true }, { where: {} });
} }
public import_crontab() { public import_crontab() {
@ -439,7 +351,7 @@ export default class CronService {
var lines = stdout.split('\n'); var lines = stdout.split('\n');
var namePrefix = new Date().getTime(); var namePrefix = new Date().getTime();
lines.reverse().forEach((line, index) => { lines.reverse().forEach(async (line, index) => {
line = line.replace(/\t+/g, ' '); line = line.replace(/\t+/g, ' ');
var regex = var regex =
/^((\@[a-zA-Z]+\s+)|(([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+))/; /^((\@[a-zA-Z]+\s+)|(([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+))/;
@ -453,18 +365,16 @@ export default class CronService {
) { ) {
var name = namePrefix + '_' + index; var name = namePrefix + '_' + index;
this.cronDb.findOne({ command, schedule }, (err, doc) => { const _crontab = await CrontabModel.findOne({
if (err) { where: { command, schedule },
throw err;
}
if (!doc) {
this.create({ name, command, schedule });
} else {
doc.command = command;
doc.schedule = schedule;
this.update(doc);
}
}); });
if (!_crontab) {
await this.create({ name, command, schedule });
} else {
_crontab.command = command;
_crontab.schedule = schedule;
await this.update(_crontab);
}
} }
}); });
}); });

View File

@ -8,16 +8,15 @@ import {
DependenceStatus, DependenceStatus,
DependenceTypes, DependenceTypes,
unInstallDependenceCommandTypes, unInstallDependenceCommandTypes,
DependenceModel,
} from '../data/dependence'; } from '../data/dependence';
import _ from 'lodash'; import _ from 'lodash';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import SockService from './sock'; import SockService from './sock';
import { dbs } from '../loaders/db'; import { Op } from 'sequelize';
@Service() @Service()
export default class DependenceService { export default class DependenceService {
private dependenceDb = dbs.dependenceDb;
constructor( constructor(
@Inject('logger') private logger: winston.Logger, @Inject('logger') private logger: winston.Logger,
private sockService: SockService, private sockService: SockService,
@ -34,22 +33,15 @@ export default class DependenceService {
} }
public async insert(payloads: Dependence[]): Promise<Dependence[]> { public async insert(payloads: Dependence[]): Promise<Dependence[]> {
return new Promise((resolve) => { const docs = await DependenceModel.bulkCreate(payloads);
this.dependenceDb.insert(payloads, (err, docs) => { return docs;
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
});
});
} }
public async update( public async update(
payload: Dependence & { _id: string }, payload: Dependence & { id: string },
): Promise<Dependence> { ): Promise<Dependence> {
const { _id, ...other } = payload; const { id, ...other } = payload;
const doc = await this.get(_id); const doc = await this.get(id);
const tab = new Dependence({ const tab = new Dependence({
...doc, ...doc,
...other, ...other,
@ -61,46 +53,23 @@ export default class DependenceService {
} }
private async updateDb(payload: Dependence): Promise<Dependence> { private async updateDb(payload: Dependence): Promise<Dependence> {
return new Promise((resolve) => { const [, docs] = await DependenceModel.update(
this.dependenceDb.update( { ...payload },
{ _id: payload._id }, { where: { id: payload.id } },
payload, );
{ returnUpdatedDocs: true }, return docs[0];
(err, num, doc) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc as Dependence);
}
},
);
});
} }
public async remove(ids: string[]) { public async remove(ids: string[]) {
return new Promise((resolve: any) => { const [, docs] = await DependenceModel.update(
this.dependenceDb.update( { status: DependenceStatus.removing, log: [] },
{ _id: { $in: ids } }, { where: { id: ids } },
{ $set: { status: DependenceStatus.removing, log: [] } }, );
{ multi: true, returnUpdatedDocs: true }, this.installOrUninstallDependencies(docs, false);
async (err, num, docs: Dependence[]) => {
this.installOrUninstallDependencies(docs, false);
resolve(docs);
},
);
});
} }
public async removeDb(ids: string[]) { public async removeDb(ids: number[]) {
return new Promise((resolve: any) => { await DependenceModel.destroy({ where: { id: ids } });
this.dependenceDb.remove(
{ _id: { $in: ids } },
{ multi: true },
async (err) => {
resolve();
},
);
});
} }
public async dependencies( public async dependencies(
@ -110,68 +79,53 @@ export default class DependenceService {
): Promise<Dependence[]> { ): Promise<Dependence[]> {
let condition = { ...query, type: DependenceTypes[type as any] }; let condition = { ...query, type: DependenceTypes[type as any] };
if (searchValue) { if (searchValue) {
const reg = new RegExp(searchValue); const encodeText = encodeURIComponent(searchValue);
condition = { const reg = {
...condition, [Op.or]: [
$or: [ { [Op.like]: `%${encodeText}&` },
{ { [Op.like]: `%${encodeText}%` },
name: reg,
},
], ],
}; };
condition = {
...condition,
name: reg,
};
}
try {
const result = await this.find(condition);
return result as any;
} catch (error) {
throw error;
} }
const newDocs = await this.find(condition, sort);
return newDocs;
} }
public async reInstall(ids: string[]): Promise<Dependence[]> { public async reInstall(ids: string[]): Promise<Dependence[]> {
return new Promise((resolve: any) => { const [, docs] = await DependenceModel.update(
this.dependenceDb.update( { status: DependenceStatus.installing, log: [] },
{ _id: { $in: ids } }, { where: { id: ids } },
{ $set: { status: DependenceStatus.installing, log: [] } }, );
{ multi: true, returnUpdatedDocs: true }, await this.installOrUninstallDependencies(docs);
async (err, num, docs: Dependence[]) => { return docs;
await this.installOrUninstallDependencies(docs);
resolve(docs);
},
);
});
} }
private async find(query: any, sort: any): Promise<Dependence[]> { private async find(query: any, sort?: any): Promise<Dependence[]> {
return new Promise((resolve) => { const docs = await DependenceModel.findAll({ where: { ...query } });
this.dependenceDb return docs;
.find(query)
.sort({ ...sort })
.exec((err, docs) => {
resolve(docs);
});
});
} }
public async get(_id: string): Promise<Dependence> { public async get(id: string): Promise<Dependence> {
return new Promise((resolve) => { const docs = await DependenceModel.findAll({ where: { id } });
this.dependenceDb.find({ _id }).exec((err, docs) => { return docs[0];
resolve(docs[0]);
});
});
} }
private async updateLog(ids: string[], log: string): Promise<void> { private async updateLog(ids: number[], log: string): Promise<void> {
return new Promise((resolve) => { const doc = await DependenceModel.findOne({ where: { id: ids } });
this.dependenceDb.update( const newLog = doc?.log ? [...doc.log, log] : [log];
{ _id: { $in: ids } }, const [, docs] = await DependenceModel.update(
{ $push: { log } }, { status: DependenceStatus.installing, log: newLog },
{ multi: true }, { where: { id: ids } },
(err, num, doc) => { );
if (err) {
this.logger.error(err);
} else {
resolve();
}
},
);
});
} }
public installOrUninstallDependencies( public installOrUninstallDependencies(
@ -190,7 +144,7 @@ export default class DependenceService {
: unInstallDependenceCommandTypes : unInstallDependenceCommandTypes
)[dependencies[0].type as any]; )[dependencies[0].type as any];
const actionText = isInstall ? '安装' : '删除'; const actionText = isInstall ? '安装' : '删除';
const depIds = dependencies.map((x) => x._id) as string[]; const depIds = dependencies.map((x) => x.id) as number[];
const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' }); const cp = spawn(`${depRunCommand} ${depNames}`, { shell: '/bin/bash' });
const startTime = Date.now(); const startTime = Date.now();
this.sockService.sendMessage({ this.sockService.sendMessage({
@ -263,14 +217,8 @@ export default class DependenceService {
? DependenceStatus.installFailed ? DependenceStatus.installFailed
: DependenceStatus.removeFailed; : DependenceStatus.removeFailed;
} }
this.dependenceDb.update(
{ _id: { $in: depIds } }, DependenceModel.update({ status }, { where: { id: depIds } });
{
$set: { status },
$unset: { pid: true },
},
{ multi: true },
);
// 如果删除依赖成功3秒后删除数据库记录 // 如果删除依赖成功3秒后删除数据库记录
if (isSucceed && !isInstall) { if (isSucceed && !isInstall) {

View File

@ -4,14 +4,12 @@ import { getFileContentByName } from '../config/util';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
import DataStore from 'nedb'; import DataStore from 'nedb';
import { Env, EnvStatus, initEnvPosition } from '../data/env'; import { Env, EnvModel, EnvStatus, initEnvPosition } from '../data/env';
import _ from 'lodash'; import _ from 'lodash';
import { dbs } from '../loaders/db'; import { Op } from 'sequelize';
@Service() @Service()
export default class EnvService { export default class EnvService {
private envDb = dbs.envDb;
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
public async create(payloads: Env[]): Promise<Env[]> { public async create(payloads: Env[]): Promise<Env[]> {
@ -31,20 +29,13 @@ export default class EnvService {
} }
public async insert(payloads: Env[]): Promise<Env[]> { public async insert(payloads: Env[]): Promise<Env[]> {
return new Promise((resolve) => { const docs = await EnvModel.bulkCreate(payloads);
this.envDb.insert(payloads, (err, docs) => { return docs;
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
});
});
} }
public async update(payload: Env): Promise<Env> { public async update(payload: Env): Promise<Env> {
const { _id, ...other } = payload; const { id, ...other } = payload;
const doc = await this.get(_id); const doc = await this.get(id as number);
const tab = new Env({ ...doc, ...other }); const tab = new Env({ ...doc, ...other });
const newDoc = await this.updateDb(tab); const newDoc = await this.updateDb(tab);
await this.set_envs(); await this.set_envs();
@ -52,33 +43,19 @@ export default class EnvService {
} }
private async updateDb(payload: Env): Promise<Env> { private async updateDb(payload: Env): Promise<Env> {
return new Promise((resolve) => { const [, docs] = await EnvModel.update(
this.envDb.update( { ...payload },
{ _id: payload._id }, { where: { id: payload.id } },
payload, );
{ returnUpdatedDocs: true }, return docs[0];
(err, num, doc) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc as Env);
}
},
);
});
} }
public async remove(ids: string[]) { public async remove(ids: string[]) {
return new Promise((resolve: any) => { await EnvModel.destroy({ where: { id: ids } });
this.envDb.remove({ _id: { $in: ids } }, { multi: true }, async (err) => {
await this.set_envs();
resolve();
});
});
} }
public async move( public async move(
_id: string, id: number,
{ {
fromIndex, fromIndex,
toIndex, toIndex,
@ -100,7 +77,7 @@ export default class EnvService {
: (envs[toIndex].position + envs[toIndex + 1].position) / 2; : (envs[toIndex].position + envs[toIndex + 1].position) / 2;
} }
const newDoc = await this.update({ const newDoc = await this.update({
_id, id,
position: targetPosition, position: targetPosition,
}); });
return newDoc; return newDoc;
@ -114,104 +91,72 @@ export default class EnvService {
let condition = { ...query }; let condition = { ...query };
if (searchText) { if (searchText) {
const encodeText = encodeURIComponent(searchText); const encodeText = encodeURIComponent(searchText);
const reg = new RegExp(`${searchText}|${encodeText}`, 'i'); const reg = {
[Op.or]: [
{ [Op.like]: `%${searchText}&` },
{ [Op.like]: `%${encodeText}%` },
],
};
condition = { condition = {
$or: [ ...condition,
{ [Op.or]: [
value: reg,
},
{ {
name: reg, name: reg,
}, },
{ {
remarks: reg, command: reg,
},
{
schedule: reg,
}, },
], ],
}; };
} }
const newDocs = await this.find(condition, sort); try {
return newDocs; const result = await this.find(condition);
return result as any;
} catch (error) {
throw error;
}
} }
private async find(query: any, sort: any): Promise<Env[]> { private async find(query: any, sort?: any): Promise<Env[]> {
return new Promise((resolve) => { const docs = await EnvModel.findAll({ where: { ...query } });
this.envDb return docs;
.find(query)
.sort({ ...sort })
.exec((err, docs) => {
resolve(docs);
});
});
} }
public async get(_id: string): Promise<Env> { public async get(id: number): Promise<Env> {
return new Promise((resolve) => { const docs = await EnvModel.findAll({ where: { id } });
this.envDb.find({ _id }).exec((err, docs) => { return docs[0];
resolve(docs[0]);
});
});
}
public async getBySort(sort: any): Promise<Env> {
return new Promise((resolve) => {
this.envDb
.find({})
.sort({ ...sort })
.limit(1)
.exec((err, docs) => {
resolve(docs[0]);
});
});
} }
public async disabled(ids: string[]) { public async disabled(ids: string[]) {
return new Promise((resolve: any) => { const [, docs] = await EnvModel.update(
this.envDb.update( { status: EnvStatus.disabled },
{ _id: { $in: ids } }, { where: { id: ids } },
{ $set: { status: EnvStatus.disabled } }, );
{ multi: true }, await this.set_envs();
async (err) => {
await this.set_envs();
resolve();
},
);
});
} }
public async enabled(ids: string[]) { public async enabled(ids: string[]) {
return new Promise((resolve: any) => { const [, docs] = await EnvModel.update(
this.envDb.update( { status: EnvStatus.normal },
{ _id: { $in: ids } }, { where: { id: ids } },
{ $set: { status: EnvStatus.normal } }, );
{ multi: true }, await this.set_envs();
async (err, num) => {
await this.set_envs();
resolve();
},
);
});
} }
public async updateNames({ ids, name }: { ids: string[]; name: string }) { public async updateNames({ ids, name }: { ids: string[]; name: string }) {
return new Promise((resolve: any) => { const [, docs] = await EnvModel.update({ name }, { where: { id: ids } });
this.envDb.update( await this.set_envs();
{ _id: { $in: ids } },
{ $set: { name } },
{ multi: true },
async (err, num) => {
await this.set_envs();
resolve();
},
);
});
} }
public async set_envs() { public async set_envs() {
const envs = await this.envs( const envs = await this.envs(
'', '',
{ position: -1 }, { position: -1 },
{ name: { $exists: true } }, { name: { [Op.not]: null } },
); );
const groups = _.groupBy(envs, 'name'); const groups = _.groupBy(envs, 'name');
let env_string = ''; let env_string = '';

View File

@ -3,29 +3,23 @@ import winston from 'winston';
import { createRandomString } from '../config/util'; import { createRandomString } from '../config/util';
import config from '../config'; import config from '../config';
import DataStore from 'nedb'; import DataStore from 'nedb';
import { App } from '../data/open'; import { App, AppModel } from '../data/open';
import { v4 as uuidV4 } from 'uuid'; import { v4 as uuidV4 } from 'uuid';
import { dbs } from '../loaders/db'; import sequelize, { Op } from 'sequelize';
@Service() @Service()
export default class OpenService { export default class OpenService {
private appDb = dbs.appDb;
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
public async findTokenByValue(token: string): Promise<App> { public async findTokenByValue(token: string): Promise<App | null> {
return new Promise((resolve) => { const doc = await AppModel.findOne({
this.appDb.find( where: sequelize.fn(
{ tokens: { $elemMatch: { value: token } } }, 'JSON_CONTAINS',
(err, docs) => { sequelize.col('tokens'),
if (err) { JSON.stringify({ value: token }),
this.logger.error(err); ),
} else {
resolve(docs[0]);
}
},
);
}); });
return doc;
} }
public async create(payload: App): Promise<App> { public async create(payload: App): Promise<App> {
@ -37,52 +31,32 @@ export default class OpenService {
} }
public async insert(payloads: App[]): Promise<App[]> { public async insert(payloads: App[]): Promise<App[]> {
return new Promise((resolve) => { const docs = await AppModel.bulkCreate(payloads);
this.appDb.insert(payloads, (err, docs) => { return docs;
if (err) {
this.logger.error(err);
} else {
resolve(docs);
}
});
});
} }
public async update(payload: App): Promise<App> { public async update(payload: App): Promise<App> {
const { _id, client_id, client_secret, tokens, ...other } = payload; const { id, client_id, client_secret, tokens, ...other } = payload;
const doc = await this.get(_id); const doc = await this.get(id);
const tab = new App({ ...doc, ...other }); const tab = new App({ ...doc, ...other });
const newDoc = await this.updateDb(tab); const newDoc = await this.updateDb(tab);
return { ...newDoc, tokens: [] }; return { ...newDoc, tokens: [] };
} }
private async updateDb(payload: App): Promise<App> { private async updateDb(payload: App): Promise<App> {
return new Promise((resolve) => { const [, docs] = await AppModel.update(
this.appDb.update( { ...payload },
{ _id: payload._id }, { where: { id: payload.id } },
payload, );
{ returnUpdatedDocs: true }, return docs[0];
(err, num, doc, up) => {
if (err) {
this.logger.error(err);
} else {
resolve(doc);
}
},
);
});
} }
public async remove(ids: string[]) { public async remove(ids: number[]) {
return new Promise((resolve: any) => { await AppModel.destroy({ where: { id: ids } });
this.appDb.remove({ _id: { $in: ids } }, { multi: true }, async (err) => {
resolve();
});
});
} }
public async resetSecret(_id: string): Promise<App> { public async resetSecret(id: number): Promise<App> {
const doc = await this.get(_id); const doc = await this.get(id);
const tab = new App({ ...doc }); const tab = new App({ ...doc });
tab.client_secret = createRandomString(24, 24); tab.client_secret = createRandomString(24, 24);
tab.tokens = []; tab.tokens = [];
@ -98,43 +72,44 @@ export default class OpenService {
let condition = { ...query }; let condition = { ...query };
if (searchText) { if (searchText) {
const encodeText = encodeURIComponent(searchText); const encodeText = encodeURIComponent(searchText);
const reg = new RegExp(`${searchText}|${encodeText}`, 'i'); const reg = {
[Op.or]: [
{ [Op.like]: `%${searchText}&` },
{ [Op.like]: `%${encodeText}%` },
],
};
condition = { condition = {
$or: [ ...condition,
{ [Op.or]: [
value: reg,
},
{ {
name: reg, name: reg,
}, },
{ {
remarks: reg, command: reg,
},
{
schedule: reg,
}, },
], ],
}; };
} }
const newDocs = await this.find(condition, sort); try {
return newDocs.map((x) => ({ ...x, tokens: [] })); const result = await this.find(condition);
return result.map((x) => ({ ...x, tokens: [] }));
} catch (error) {
throw error;
}
} }
private async find(query: any, sort: any): Promise<App[]> { private async find(query: any, sort?: any): Promise<App[]> {
return new Promise((resolve) => { const docs = await AppModel.findAll({ where: { ...query } });
this.appDb return docs;
.find(query)
.sort({ ...sort })
.exec((err, docs) => {
resolve(docs);
});
});
} }
public async get(_id: string): Promise<App> { public async get(id: number): Promise<App> {
return new Promise((resolve) => { const docs = await AppModel.findAll({ where: { id } });
this.appDb.find({ _id }).exec((err, docs) => { return docs[0];
resolve(docs[0]);
});
});
} }
public async authToken({ public async authToken({
@ -146,28 +121,22 @@ export default class OpenService {
}): Promise<any> { }): Promise<any> {
const token = uuidV4(); const token = uuidV4();
const expiration = Math.round(Date.now() / 1000) + 2592000; // 2592000 30天 const expiration = Math.round(Date.now() / 1000) + 2592000; // 2592000 30天
return new Promise((resolve) => { const doc = await AppModel.findOne({ where: { client_id, client_secret } });
this.appDb.find({ client_id, client_secret }).exec((err, docs) => { if (doc) {
if (docs && docs[0]) { const [, docs] = await AppModel.update(
this.appDb.update( { tokens: [...(doc.tokens || []), { value: token, expiration }] },
{ client_id, client_secret }, { where: { client_id, client_secret } },
{ $push: { tokens: { value: token, expiration } } }, );
{}, return {
(err, num, doc) => { code: 200,
resolve({ data: {
code: 200, token,
data: { token_type: 'Bearer',
token, expiration,
token_type: 'Bearer', },
expiration, };
}, } else {
}); return { code: 400, message: 'client_id或client_seret有误' };
}, }
);
} else {
resolve({ code: 400, message: 'client_id或client_seret有误' });
}
});
});
} }
} }

View File

@ -6,22 +6,22 @@ import { exec } from 'child_process';
@Service() @Service()
export default class ScheduleService { export default class ScheduleService {
private scheduleStacks = new Map<string, nodeSchedule.Job>(); private scheduleStacks = new Map<number, nodeSchedule.Job>();
constructor(@Inject('logger') private logger: winston.Logger) {} constructor(@Inject('logger') private logger: winston.Logger) {}
async generateSchedule({ _id = '', command, name, schedule }: Crontab) { async generateSchedule({ id = 0, command, name, schedule }: Crontab) {
this.logger.info( this.logger.info(
'[创建定时任务]任务ID: %scron: %s任务名: %s执行命令: %s', '[创建定时任务]任务ID: %scron: %s任务名: %s执行命令: %s',
_id, id,
schedule, schedule,
name, name,
command, command,
); );
this.scheduleStacks.set( this.scheduleStacks.set(
_id, id,
nodeSchedule.scheduleJob(_id, schedule, async () => { nodeSchedule.scheduleJob(id + '', schedule, async () => {
try { try {
exec(command, async (error, stdout, stderr) => { exec(command, async (error, stdout, stderr) => {
if (error) { if (error) {
@ -55,8 +55,8 @@ export default class ScheduleService {
); );
} }
async cancelSchedule({ _id = '', name }: Crontab) { async cancelSchedule({ id = 0, name }: Crontab) {
this.logger.info('[取消定时任务],任务名:%s', name); this.logger.info('[取消定时任务],任务名:%s', name);
this.scheduleStacks.has(_id) && this.scheduleStacks.get(_id)?.cancel(); this.scheduleStacks.has(id) && this.scheduleStacks.get(id)?.cancel();
} }
} }

View File

@ -3,7 +3,7 @@ import winston from 'winston';
import config from '../config'; import config from '../config';
import * as fs from 'fs'; import * as fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import { AuthDataType, AuthInfo, LoginStatus } from '../data/auth'; import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth';
import { NotificationInfo } from '../data/notify'; import { NotificationInfo } from '../data/notify';
import NotificationService from './notify'; import NotificationService from './notify';
import ScheduleService from './schedule'; import ScheduleService from './schedule';
@ -16,7 +16,6 @@ import { dbs } from '../loaders/db';
export default class SystemService { export default class SystemService {
@Inject((type) => NotificationService) @Inject((type) => NotificationService)
private notificationService!: NotificationService; private notificationService!: NotificationService;
private authDb = dbs.authDb;
constructor( constructor(
@Inject('logger') private logger: winston.Logger, @Inject('logger') private logger: winston.Logger,
@ -25,34 +24,16 @@ export default class SystemService {
) {} ) {}
public async getLogRemoveFrequency() { public async getLogRemoveFrequency() {
return new Promise((resolve) => { const doc = await AuthModel.findOne({
this.authDb where: { type: AuthDataType.removeLogFrequency },
.find({ type: AuthDataType.removeLogFrequency })
.exec((err, docs) => {
if (err || docs.length === 0) {
resolve({});
} else {
resolve(docs[0].info);
}
});
}); });
return (doc && doc.info) || {};
} }
private async updateAuthDb(payload: AuthInfo): Promise<any> { private async updateAuthDb(payload: AuthInfo): Promise<any> {
return new Promise((resolve) => { await AuthModel.upsert({ ...payload });
this.authDb.update( const doc = await AuthModel.findOne({ where: { type: payload.type } });
{ type: payload.type }, return doc;
{ ...payload },
{ upsert: true, returnUpdatedDocs: true },
(err, num, doc: any) => {
if (err) {
resolve({} as NotificationInfo);
} else {
resolve({ ...doc.info, _id: doc._id });
}
},
);
});
} }
public async updateNotificationMode(notificationInfo: NotificationInfo) { public async updateNotificationMode(notificationInfo: NotificationInfo) {
@ -79,7 +60,7 @@ export default class SystemService {
info: { frequency }, info: { frequency },
}); });
const cron = { const cron = {
_id: result._id, id: result.id,
name: '删除日志', name: '删除日志',
command: `ql rmlog ${frequency}`, command: `ql rmlog ${frequency}`,
schedule: `5 23 */${frequency} * *`, schedule: `5 23 */${frequency} * *`,

View File

@ -6,8 +6,7 @@ import * as fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { authenticator } from '@otplib/preset-default'; import { authenticator } from '@otplib/preset-default';
import DataStore from 'nedb'; import { AuthDataType, AuthInfo, AuthModel, LoginStatus } from '../data/auth';
import { AuthDataType, AuthInfo, LoginStatus } from '../data/auth';
import { NotificationInfo } from '../data/notify'; import { NotificationInfo } from '../data/notify';
import NotificationService from './notify'; import NotificationService from './notify';
import { Request } from 'express'; import { Request } from 'express';
@ -15,13 +14,11 @@ import ScheduleService from './schedule';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import SockService from './sock'; import SockService from './sock';
import got from 'got'; import got from 'got';
import { dbs } from '../loaders/db';
@Service() @Service()
export default class UserService { export default class UserService {
@Inject((type) => NotificationService) @Inject((type) => NotificationService)
private notificationService!: NotificationService; private notificationService!: NotificationService;
private authDb = dbs.authDb;
constructor( constructor(
@Inject('logger') private logger: winston.Logger, @Inject('logger') private logger: winston.Logger,
@ -174,33 +171,24 @@ export default class UserService {
} }
public async getLoginLog(): Promise<AuthInfo[]> { public async getLoginLog(): Promise<AuthInfo[]> {
return new Promise((resolve) => { const docs = await AuthModel.findAll({
this.authDb.find({ type: AuthDataType.loginLog }).exec((err, docs) => { where: { type: AuthDataType.loginLog },
if (err || docs.length === 0) {
resolve([]);
} else {
const result = docs.sort(
(a, b) => b.info.timestamp - a.info.timestamp,
);
if (result.length > 100) {
this.authDb.remove({ _id: result[result.length - 1]._id });
}
resolve(result.map((x) => x.info));
}
});
}); });
if (docs && docs.length > 0) {
const result = docs.sort((a, b) => b.info.timestamp - a.info.timestamp);
if (result.length > 100) {
await AuthModel.destroy({
where: { id: result[result.length - 1].id },
});
}
return result.map((x) => x.info);
}
return [];
} }
private async insertDb(payload: AuthInfo): Promise<AuthInfo> { private async insertDb(payload: AuthInfo): Promise<AuthInfo> {
return new Promise((resolve) => { const doc = await AuthModel.create({ ...payload }, { returning: true });
this.authDb.insert(payload, (err, doc) => { return doc;
if (err) {
this.logger.error(err);
} else {
resolve(doc);
}
});
});
} }
private initAuthInfo() { private initAuthInfo() {
@ -315,48 +303,23 @@ export default class UserService {
} }
public async getNotificationMode(): Promise<NotificationInfo> { public async getNotificationMode(): Promise<NotificationInfo> {
return new Promise((resolve) => { const doc = await AuthModel.findOne({
this.authDb where: { type: AuthDataType.notification },
.find({ type: AuthDataType.notification })
.exec((err, docs) => {
if (err || docs.length === 0) {
resolve({} as NotificationInfo);
} else {
resolve(docs[0].info);
}
});
}); });
return (doc && doc.info) || {};
} }
public async getLogRemoveFrequency() { public async getLogRemoveFrequency() {
return new Promise((resolve) => { const doc = await AuthModel.findOne({
this.authDb where: { type: AuthDataType.removeLogFrequency },
.find({ type: AuthDataType.removeLogFrequency })
.exec((err, docs) => {
if (err || docs.length === 0) {
resolve({});
} else {
resolve(docs[0].info);
}
});
}); });
return (doc && doc.info) || {};
} }
private async updateAuthDb(payload: AuthInfo): Promise<any> { private async updateAuthDb(payload: AuthInfo): Promise<any> {
return new Promise((resolve) => { await AuthModel.upsert({ ...payload });
this.authDb.update( const doc = await AuthModel.findOne({ where: { type: payload.type } });
{ type: payload.type }, return doc;
{ ...payload },
{ upsert: true, returnUpdatedDocs: true },
(err, num, doc: any) => {
if (err) {
resolve({} as NotificationInfo);
} else {
resolve({ ...doc.info, _id: doc._id });
}
},
);
});
} }
public async updateNotificationMode(notificationInfo: NotificationInfo) { public async updateNotificationMode(notificationInfo: NotificationInfo) {
@ -383,7 +346,7 @@ export default class UserService {
info: { frequency }, info: { frequency },
}); });
const cron = { const cron = {
_id: result._id, id: result.id,
name: '删除日志', name: '删除日志',
command: `ql rmlog ${frequency}`, command: `ql rmlog ${frequency}`,
schedule: `5 23 */${frequency} * *`, schedule: `5 23 */${frequency} * *`,

View File

@ -42,4 +42,8 @@ server {
index index.html index.htm; index index.html index.htm;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
location ~ .*\.(html)$ {
add_header Cache-Control no-cache;
}
} }

View File

@ -25,8 +25,8 @@
}, },
"dependencies": { "dependencies": {
"@otplib/preset-default": "^12.0.1", "@otplib/preset-default": "^12.0.1",
"@sentry/node": "^6.14.0", "@sentry/node": "^6.16.1",
"@sentry/tracing": "^6.14.0", "@sentry/tracing": "^6.16.1",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"celebrate": "^13.0.3", "celebrate": "^13.0.3",
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
@ -47,8 +47,10 @@
"nodemailer": "^6.7.0", "nodemailer": "^6.7.0",
"p-queue": "6.6.2", "p-queue": "6.6.2",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"sequelize": "^7.0.0-alpha.3",
"serve-handler": "^6.1.3", "serve-handler": "^6.1.3",
"sockjs": "^0.3.21", "sockjs": "^0.3.21",
"sqlite3": "^5.0.2",
"typedi": "^0.8.0", "typedi": "^0.8.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"winston": "^3.3.3", "winston": "^3.3.3",
@ -58,7 +60,7 @@
"@ant-design/icons": "^4.6.2", "@ant-design/icons": "^4.6.2",
"@ant-design/pro-layout": "^6.26.0", "@ant-design/pro-layout": "^6.26.0",
"@monaco-editor/react": "^4.3.1", "@monaco-editor/react": "^4.3.1",
"@sentry/react": "^6.14.0", "@sentry/react": "^6.16.1",
"@sentry/webpack-plugin": "^1.18.3", "@sentry/webpack-plugin": "^1.18.3",
"@types/cors": "^2.8.10", "@types/cors": "^2.8.10",
"@types/express": "^4.17.8", "@types/express": "^4.17.8",
@ -76,6 +78,7 @@
"@types/serve-handler": "^6.1.1", "@types/serve-handler": "^6.1.1",
"@types/sockjs": "^0.3.33", "@types/sockjs": "^0.3.33",
"@types/sockjs-client": "^1.5.1", "@types/sockjs-client": "^1.5.1",
"@types/uuid": "^8.3.3",
"@umijs/plugin-antd": "^0.11.0", "@umijs/plugin-antd": "^0.11.0",
"@umijs/test": "^3.3.9", "@umijs/test": "^3.3.9",
"antd": "^4.17.0-alpha.6", "antd": "^4.17.0-alpha.6",

View File

@ -61,7 +61,7 @@ update_cron_api() {
-H "Origin: http://0.0.0.0:5700" \ -H "Origin: http://0.0.0.0:5700" \
-H "Referer: http://0.0.0.0:5700/crontab" \ -H "Referer: http://0.0.0.0:5700/crontab" \
-H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \
--data-raw "{\"name\":\"$name\",\"command\":\"$command\",\"schedule\":\"$schedule\",\"_id\":\"$id\"}" \ --data-raw "{\"name\":\"$name\",\"command\":\"$command\",\"schedule\":\"$schedule\",\"id\":\"$id\"}" \
--compressed --compressed
) )
code=$(echo $api | jq -r .code) code=$(echo $api | jq -r .code)
@ -93,7 +93,7 @@ update_cron_command_api() {
-H "Origin: http://0.0.0.0:5700" \ -H "Origin: http://0.0.0.0:5700" \
-H "Referer: http://0.0.0.0:5700/crontab" \ -H "Referer: http://0.0.0.0:5700/crontab" \
-H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \ -H "Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7" \
--data-raw "{\"command\":\"$command\",\"_id\":\"$id\"}" \ --data-raw "{\"command\":\"$command\",\"id\":\"$id\"}" \
--compressed --compressed
) )
code=$(echo $api | jq -r .code) code=$(echo $api | jq -r .code)

View File

@ -82,7 +82,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
goToScriptManager(record); goToScriptManager(record);
}} }}
> >
{record.name || record._id}{' '} {record.name || record.id}{' '}
{record.isPinned ? ( {record.isPinned ? (
<span> <span>
<PushpinOutlined /> <PushpinOutlined />
@ -408,12 +408,12 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
), ),
onOk() { onOk() {
request request
.delete(`${config.apiPrefix}crons`, { data: [record._id] }) .delete(`${config.apiPrefix}crons`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
message.success('删除成功'); message.success('删除成功');
const result = [...value]; const result = [...value];
const i = result.findIndex((x) => x._id === record._id); const i = result.findIndex((x) => x.id === record.id);
result.splice(i, 1); result.splice(i, 1);
setValue(result); setValue(result);
} else { } else {
@ -441,11 +441,11 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
), ),
onOk() { onOk() {
request request
.put(`${config.apiPrefix}crons/run`, { data: [record._id] }) .put(`${config.apiPrefix}crons/run`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
const result = [...value]; const result = [...value];
const i = result.findIndex((x) => x._id === record._id); const i = result.findIndex((x) => x.id === record.id);
result.splice(i, 1, { result.splice(i, 1, {
...record, ...record,
status: CrontabStatus.running, status: CrontabStatus.running,
@ -476,11 +476,11 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
), ),
onOk() { onOk() {
request request
.put(`${config.apiPrefix}crons/stop`, { data: [record._id] }) .put(`${config.apiPrefix}crons/stop`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
const result = [...value]; const result = [...value];
const i = result.findIndex((x) => x._id === record._id); const i = result.findIndex((x) => x.id === record.id);
result.splice(i, 1, { result.splice(i, 1, {
...record, ...record,
pid: null, pid: null,
@ -518,14 +518,14 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
record.isDisabled === 1 ? 'enable' : 'disable' record.isDisabled === 1 ? 'enable' : 'disable'
}`, }`,
{ {
data: [record._id], data: [record.id],
}, },
) )
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
const newStatus = record.isDisabled === 1 ? 0 : 1; const newStatus = record.isDisabled === 1 ? 0 : 1;
const result = [...value]; const result = [...value];
const i = result.findIndex((x) => x._id === record._id); const i = result.findIndex((x) => x.id === record.id);
result.splice(i, 1, { result.splice(i, 1, {
...record, ...record,
isDisabled: newStatus, isDisabled: newStatus,
@ -562,14 +562,14 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
record.isPinned === 1 ? 'unpin' : 'pin' record.isPinned === 1 ? 'unpin' : 'pin'
}`, }`,
{ {
data: [record._id], data: [record.id],
}, },
) )
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
const newStatus = record.isPinned === 1 ? 0 : 1; const newStatus = record.isPinned === 1 ? 0 : 1;
const result = [...value]; const result = [...value];
const i = result.findIndex((x) => x._id === record._id); const i = result.findIndex((x) => x.id === record.id);
result.splice(i, 1, { result.splice(i, 1, {
...record, ...record,
isPinned: newStatus, isPinned: newStatus,
@ -661,7 +661,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
}; };
const handleCrons = (cron: any) => { const handleCrons = (cron: any) => {
const index = value.findIndex((x) => x._id === cron._id); const index = value.findIndex((x) => x.id === cron.id);
const result = [...value]; const result = [...value];
cron.nextRunTime = cron_parser cron.nextRunTime = cron_parser
.parseExpression(cron.schedule) .parseExpression(cron.schedule)
@ -679,9 +679,9 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
const getCronDetail = (cron: any) => { const getCronDetail = (cron: any) => {
request request
.get(`${config.apiPrefix}crons/${cron._id}`) .get(`${config.apiPrefix}crons/${cron.id}`)
.then((data: any) => { .then((data: any) => {
const index = value.findIndex((x) => x._id === cron._id); const index = value.findIndex((x) => x.id === cron.id);
const result = [...value]; const result = [...value];
data.data.nextRunTime = cron_parser data.data.nextRunTime = cron_parser
.parseExpression(data.data.schedule) .parseExpression(data.data.schedule)
@ -774,7 +774,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
useEffect(() => { useEffect(() => {
if (logCron) { if (logCron) {
localStorage.setItem('logCron', logCron._id); localStorage.setItem('logCron', logCron.id);
setIsLogModalVisible(true); setIsLogModalVisible(true);
} }
}, [logCron]); }, [logCron]);
@ -873,7 +873,7 @@ const Crontab = ({ headerStyle, isPhone }: any) => {
pageSizeOptions: [10, 20, 50, 100, 200, 500, 1000], pageSizeOptions: [10, 20, 50, 100, 200, 500, 1000],
}} }}
dataSource={value} dataSource={value}
rowKey="_id" rowKey="id"
size="middle" size="middle"
scroll={{ x: 1000, y: tableScrollHeight }} scroll={{ x: 1000, y: tableScrollHeight }}
loading={loading} loading={loading}

View File

@ -36,9 +36,9 @@ const CronLogModal = ({
setLoading(true); setLoading(true);
} }
request request
.get(`${config.apiPrefix}crons/${cron._id}/log`) .get(`${config.apiPrefix}crons/${cron.id}/log`)
.then((data: any) => { .then((data: any) => {
if (localStorage.getItem('logCron') === cron._id) { if (localStorage.getItem('logCron') === cron.id) {
const log = data.data as string; const log = data.data as string;
setValue(log || '暂无日志'); setValue(log || '暂无日志');
setExecuting( setExecuting(

View File

@ -21,7 +21,7 @@ const CronModal = ({
const method = cron ? 'put' : 'post'; const method = cron ? 'put' : 'post';
const payload = { ...values }; const payload = { ...values };
if (cron) { if (cron) {
payload._id = cron._id; payload.id = cron.id;
} }
const { code, data } = await request[method](`${config.apiPrefix}crons`, { const { code, data } = await request[method](`${config.apiPrefix}crons`, {
data: payload, data: payload,

View File

@ -82,6 +82,12 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
); );
}, },
}, },
{
title: '备注',
dataIndex: 'remark',
key: 'remark',
align: 'center' as const,
},
{ {
title: '创建时间', title: '创建时间',
key: 'created', key: 'created',
@ -175,7 +181,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
), ),
onOk() { onOk() {
request request
.delete(`${config.apiPrefix}dependencies`, { data: [record._id] }) .delete(`${config.apiPrefix}dependencies`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
handleDependence(data.data[0]); handleDependence(data.data[0]);
@ -205,7 +211,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
onOk() { onOk() {
request request
.put(`${config.apiPrefix}dependencies/reinstall`, { .put(`${config.apiPrefix}dependencies/reinstall`, {
data: [record._id], data: [record.id],
}) })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
@ -231,7 +237,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
if (Array.isArray(dependence)) { if (Array.isArray(dependence)) {
result.push(...dependence); result.push(...dependence);
} else { } else {
const index = value.findIndex((x) => x._id === dependence._id); const index = value.findIndex((x) => x.id === dependence.id);
result.splice(index, 1, { result.splice(index, 1, {
...dependence, ...dependence,
}); });
@ -278,9 +284,9 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
const getDependenceDetail = (dependence: any) => { const getDependenceDetail = (dependence: any) => {
request request
.get(`${config.apiPrefix}dependencies/${dependence._id}`) .get(`${config.apiPrefix}dependencies/${dependence.id}`)
.then((data: any) => { .then((data: any) => {
const index = value.findIndex((x) => x._id === dependence._id); const index = value.findIndex((x) => x.id === dependence.id);
const result = [...value]; const result = [...value];
result.splice(index, 1, { result.splice(index, 1, {
...dependence, ...dependence,
@ -307,7 +313,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
useEffect(() => { useEffect(() => {
if (logDependence) { if (logDependence) {
localStorage.setItem('logDependence', logDependence._id); localStorage.setItem('logDependence', logDependence.id);
setIsLogModalVisible(true); setIsLogModalVisible(true);
} }
}, [logDependence]); }, [logDependence]);
@ -328,7 +334,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
} }
const result = [...value]; const result = [...value];
for (let i = 0; i < references.length; i++) { for (let i = 0; i < references.length; i++) {
const index = value.findIndex((x) => x._id === references[i]); const index = value.findIndex((x) => x.id === references[i]);
result.splice(index, 1, { result.splice(index, 1, {
...result[index], ...result[index],
status, status,
@ -340,7 +346,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
setTimeout(() => { setTimeout(() => {
const _result = [...value]; const _result = [...value];
for (let i = 0; i < references.length; i++) { for (let i = 0; i < references.length; i++) {
const index = value.findIndex((x) => x._id === references[i]); const index = value.findIndex((x) => x.id === references[i]);
_result.splice(index, 1); _result.splice(index, 1);
} }
setValue(_result); setValue(_result);
@ -372,7 +378,7 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
rowSelection={rowSelection} rowSelection={rowSelection}
pagination={false} pagination={false}
dataSource={value} dataSource={value}
rowKey="_id" rowKey="id"
size="middle" size="middle"
scroll={{ x: 768, y: tableScrollHeight }} scroll={{ x: 768, y: tableScrollHeight }}
loading={loading} loading={loading}
@ -432,11 +438,11 @@ const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => {
handleCancel={(needRemove?: boolean) => { handleCancel={(needRemove?: boolean) => {
setIsLogModalVisible(false); setIsLogModalVisible(false);
if (needRemove) { if (needRemove) {
const index = value.findIndex((x) => x._id === logDependence._id); const index = value.findIndex((x) => x.id === logDependence.id);
const result = [...value]; const result = [...value];
result.splice(index, 1); result.splice(index, 1);
setValue(result); setValue(result);
} else if ([...value].map((x) => x._id).includes(logDependence._id)) { } else if ([...value].map((x) => x.id).includes(logDependence.id)) {
getDependenceDetail(logDependence); getDependenceDetail(logDependence);
} }
}} }}

View File

@ -46,9 +46,9 @@ const DependenceLogModal = ({
const getDependenceLog = () => { const getDependenceLog = () => {
setLoading(true); setLoading(true);
request request
.get(`${config.apiPrefix}dependencies/${dependence._id}`) .get(`${config.apiPrefix}dependencies/${dependence.id}`)
.then((data: any) => { .then((data: any) => {
if (localStorage.getItem('logDependence') === dependence._id) { if (localStorage.getItem('logDependence') === dependence.id) {
const log = (data.data.log || []).join('\n') as string; const log = (data.data.log || []).join('\n') as string;
setValue(log); setValue(log);
setExecuting(!log.includes('结束时间')); setExecuting(!log.includes('结束时间'));
@ -64,7 +64,7 @@ const DependenceLogModal = ({
setRemoveLoading(true); setRemoveLoading(true);
request request
.delete(`${config.apiPrefix}dependencies/force`, { .delete(`${config.apiPrefix}dependencies/force`, {
data: [dependence._id], data: [dependence.id],
}) })
.then((data: any) => { .then((data: any) => {
cancel(true); cancel(true);

View File

@ -42,7 +42,7 @@ const DependenceModal = ({
payload = [{ name, type }]; payload = [{ name, type }];
} }
} else { } else {
payload = { ...values, _id: dependence._id }; payload = { ...values, id: dependence.id };
} }
try { try {
const { code, data } = await request[method]( const { code, data } = await request[method](

View File

@ -101,7 +101,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
{ {
title: '序号', title: '序号',
align: 'center' as const, align: 'center' as const,
width: 50, width: 60,
render: (text: string, record: any, index: number) => { render: (text: string, record: any, index: number) => {
return <span style={{ cursor: 'text' }}>{index + 1} </span>; return <span style={{ cursor: 'text' }}>{index + 1} </span>;
}, },
@ -197,7 +197,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
width: 100, width: 120,
align: 'center' as const, align: 'center' as const,
render: (text: string, record: any, index: number) => { render: (text: string, record: any, index: number) => {
const isPc = !isPhone; const isPc = !isPhone;
@ -270,7 +270,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
record.status === Status. ? 'enable' : 'disable' record.status === Status. ? 'enable' : 'disable'
}`, }`,
{ {
data: [record._id], data: [record.id],
}, },
) )
.then((data: any) => { .then((data: any) => {
@ -321,7 +321,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
), ),
onOk() { onOk() {
request request
.delete(`${config.apiPrefix}envs`, { data: [record._id] }) .delete(`${config.apiPrefix}envs`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
message.success('删除成功'); message.success('删除成功');
@ -351,7 +351,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
const handleEnv = (env: any) => { const handleEnv = (env: any) => {
const result = [...value]; const result = [...value];
const index = value.findIndex((x) => x._id === env._id); const index = value.findIndex((x) => x.id === env.id);
if (index === -1) { if (index === -1) {
env = Array.isArray(env) ? env : [env]; env = Array.isArray(env) ? env : [env];
result.push(...env); result.push(...env);
@ -376,7 +376,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
} }
const dragRow = value[dragIndex]; const dragRow = value[dragIndex];
request request
.put(`${config.apiPrefix}envs/${dragRow._id}/move`, { .put(`${config.apiPrefix}envs/${dragRow.id}/move`, {
data: { fromIndex: dragIndex, toIndex: hoverIndex }, data: { fromIndex: dragIndex, toIndex: hoverIndex },
}) })
.then((data: any) => { .then((data: any) => {
@ -534,7 +534,7 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
rowSelection={rowSelection} rowSelection={rowSelection}
pagination={false} pagination={false}
dataSource={value} dataSource={value}
rowKey="_id" rowKey="id"
size="middle" size="middle"
scroll={{ x: 1000, y: tableScrollHeight }} scroll={{ x: 1000, y: tableScrollHeight }}
components={components} components={components}

View File

@ -34,7 +34,7 @@ const EnvModal = ({
payload = [{ value, name, remarks }]; payload = [{ value, name, remarks }];
} }
} else { } else {
payload = { ...values, _id: env._id }; payload = { ...values, id: env.id };
} }
const { code, data } = await request[method](`${config.apiPrefix}envs`, { const { code, data } = await request[method](`${config.apiPrefix}envs`, {
data: payload, data: payload,

View File

@ -1,12 +1,11 @@
import { useState, useEffect, useCallback, Key, useRef } from 'react'; import { useState, useEffect, useCallback, Key, useRef } from 'react';
import { TreeSelect, Tree, Input } from 'antd'; import { TreeSelect, Tree, Input, Empty } from 'antd';
import config from '@/utils/config'; import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout'; import { PageContainer } from '@ant-design/pro-layout';
import Editor from '@monaco-editor/react'; import Editor from '@monaco-editor/react';
import { request } from '@/utils/http'; import { request } from '@/utils/http';
import styles from './index.module.less'; import styles from './index.module.less';
import { Controlled as CodeMirror } from 'react-codemirror2'; import { Controlled as CodeMirror } from 'react-codemirror2';
import { useCtx, useTheme } from '@/utils/hooks';
import SplitPane from 'react-split-pane'; import SplitPane from 'react-split-pane';
function getFilterData(keyword: string, data: any) { function getFilterData(keyword: string, data: any) {
@ -143,21 +142,39 @@ const Log = ({ headerStyle, isPhone, theme }: any) => {
{!isPhone && ( {!isPhone && (
<SplitPane split="vertical" size={200} maxSize={-100}> <SplitPane split="vertical" size={200} maxSize={-100}>
<div className={styles['left-tree-container']}> <div className={styles['left-tree-container']}>
<Input.Search {data.length > 0 ? (
className={styles['left-tree-search']} <>
onChange={onSearch} <Input.Search
></Input.Search> className={styles['left-tree-search']}
<div className={styles['left-tree-scroller']} ref={treeDom}> onChange={onSearch}
<Tree ></Input.Search>
className={styles['left-tree']} <div className={styles['left-tree-scroller']} ref={treeDom}>
treeData={filterData} <Tree
showIcon={true} className={styles['left-tree']}
height={height} treeData={filterData}
selectedKeys={[select]} showIcon={true}
showLine={{ showLeafIcon: true }} height={height}
onSelect={onTreeSelect} selectedKeys={[select]}
></Tree> showLine={{ showLeafIcon: true }}
</div> onSelect={onTreeSelect}
></Tree>
</div>
</>
) : (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Empty
description="暂无日志"
image={Empty.PRESENTED_IMAGE_SIMPLE}
/>
</div>
)}
</div> </div>
<Editor <Editor
language="shell" language="shell"

View File

@ -10,6 +10,7 @@ import {
Tooltip, Tooltip,
Dropdown, Dropdown,
Menu, Menu,
Empty,
} from 'antd'; } from 'antd';
import config from '@/utils/config'; import config from '@/utils/config';
import { PageContainer } from '@ant-design/pro-layout'; import { PageContainer } from '@ant-design/pro-layout';
@ -470,23 +471,41 @@ const Script = ({ headerStyle, isPhone, theme, socketMessage }: any) => {
{!isPhone && ( {!isPhone && (
<SplitPane split="vertical" size={200} maxSize={-100}> <SplitPane split="vertical" size={200} maxSize={-100}>
<div className={styles['left-tree-container']}> <div className={styles['left-tree-container']}>
<Input.Search {data.length > 0 ? (
className={styles['left-tree-search']} <>
onChange={onSearch} <Input.Search
></Input.Search> className={styles['left-tree-search']}
<div className={styles['left-tree-scroller']} ref={treeDom}> onChange={onSearch}
<Tree ></Input.Search>
className={styles['left-tree']} <div className={styles['left-tree-scroller']} ref={treeDom}>
treeData={filterData} <Tree
showIcon={true} className={styles['left-tree']}
height={height} treeData={filterData}
selectedKeys={[select]} showIcon={true}
expandedKeys={expandedKeys} height={height}
onExpand={onExpand} selectedKeys={[select]}
showLine={{ showLeafIcon: true }} expandedKeys={expandedKeys}
onSelect={onTreeSelect} onExpand={onExpand}
></Tree> showLine={{ showLeafIcon: true }}
</div> onSelect={onTreeSelect}
></Tree>
</div>
</>
) : (
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<Empty
description="暂无脚本"
image={Empty.PRESENTED_IMAGE_SIMPLE}
/>
</div>
)}
</div> </div>
<Editor <Editor
language={mode} language={mode}

View File

@ -20,7 +20,7 @@ const AppModal = ({
const method = app ? 'put' : 'post'; const method = app ? 'put' : 'post';
const payload = { ...values }; const payload = { ...values };
if (app) { if (app) {
payload._id = app._id; payload.id = app.id;
} }
const { code, data } = await request[method](`${config.apiPrefix}apps`, { const { code, data } = await request[method](`${config.apiPrefix}apps`, {
data: payload, data: payload,

View File

@ -164,7 +164,7 @@ const Setting = ({
), ),
onOk() { onOk() {
request request
.delete(`${config.apiPrefix}apps`, { data: [record._id] }) .delete(`${config.apiPrefix}apps`, { data: [record.id] })
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
message.success('删除成功'); message.success('删除成功');
@ -198,7 +198,7 @@ const Setting = ({
), ),
onOk() { onOk() {
request request
.put(`${config.apiPrefix}apps/${record._id}/reset-secret`) .put(`${config.apiPrefix}apps/${record.id}/reset-secret`)
.then((data: any) => { .then((data: any) => {
if (data.code === 200) { if (data.code === 200) {
message.success('重置成功'); message.success('重置成功');
@ -222,7 +222,7 @@ const Setting = ({
}; };
const handleApp = (app: any) => { const handleApp = (app: any) => {
const index = dataSource.findIndex((x) => x._id === app._id); const index = dataSource.findIndex((x) => x.id === app.id);
const result = [...dataSource]; const result = [...dataSource];
if (index === -1) { if (index === -1) {
result.push(app); result.push(app);
@ -339,7 +339,7 @@ const Setting = ({
columns={columns} columns={columns}
pagination={false} pagination={false}
dataSource={dataSource} dataSource={dataSource}
rowKey="_id" rowKey="id"
size="middle" size="middle"
scroll={{ x: 768 }} scroll={{ x: 768 }}
loading={loading} loading={loading}

View File

@ -73,7 +73,7 @@ const LoginLog = ({ data }: any) => {
columns={columns} columns={columns}
pagination={false} pagination={false}
dataSource={data} dataSource={data}
rowKey="_id" rowKey="id"
size="middle" size="middle"
scroll={{ x: 768 }} scroll={{ x: 768 }}
/> />

462
yarn.lock
View File

@ -866,14 +866,14 @@
resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a" resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a"
integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg== integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==
"@sentry/browser@6.14.0": "@sentry/browser@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.14.0.tgz#4e26da3b1094a688ee11438170a3dd974723c5dd" resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.16.1.tgz#4270ab0fbd1de425e339b3e7a364feb09f470a87"
integrity sha512-tdLTvgBwBuHhGG2iABdoRf5pUbS99xVapkHXKp9977slMGnUznMUrLUAVenitPx9fGoyYDZc8ukMfabAblfDyA== integrity sha512-F2I5RL7RTLQF9CccMrqt73GRdK3FdqaChED3RulGQX5lH6U3exHGFxwyZxSrY4x6FedfBFYlfXWWCJXpLnFkow==
dependencies: dependencies:
"@sentry/core" "6.14.0" "@sentry/core" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/cli@^1.70.1": "@sentry/cli@^1.70.1":
@ -888,84 +888,84 @@
progress "^2.0.3" progress "^2.0.3"
proxy-from-env "^1.1.0" proxy-from-env "^1.1.0"
"@sentry/core@6.14.0": "@sentry/core@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.14.0.tgz#5d0adb7e9f5f7c583fa3929381fe8a94e6cb1981" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.16.1.tgz#d9f7a75f641acaddf21b6aafa7a32e142f68f17c"
integrity sha512-GKs1A3yjcVB5ST4Mx9Eq4Z1yQaeq+AN1eJO1pnJhkOUnBXbmLGXvEp039W3Qn9iq9QuQmVRQz2C0+9GbrWmx9A== integrity sha512-UFI0264CPUc5cR1zJH+S2UPOANpm6dLJOnsvnIGTjsrwzR0h8Hdl6rC2R/GPq+WNbnipo9hkiIwDlqbqvIU5vw==
dependencies: dependencies:
"@sentry/hub" "6.14.0" "@sentry/hub" "6.16.1"
"@sentry/minimal" "6.14.0" "@sentry/minimal" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/hub@6.14.0": "@sentry/hub@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.14.0.tgz#ee464c1e95f124ef7641ad85f082fbb1747ee124" resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.16.1.tgz#526e19db51f4412da8634734044c605b936a7b80"
integrity sha512-27ZN0YOxxy+2BV8VyelCejeeVJXy3Bs91bF6ICv3fekfL6cpyGswVMFltmSxraZOMxS4+Xz2HEgjlddgtd8yDQ== integrity sha512-4PGtg6AfpqMkreTpL7ymDeQ/U1uXv03bKUuFdtsSTn/FRf9TLS4JB0KuTZCxfp1IRgAA+iFg6B784dDkT8R9eg==
dependencies: dependencies:
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/minimal@6.14.0": "@sentry/minimal@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.14.0.tgz#bc0c6a90276da838a6867a5097560644f72192cc" resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.16.1.tgz#6a9506a92623d2ff1fc17d60989688323326772e"
integrity sha512-LLw2xwCxfnVToYZQQYqVb5ZGYW5nzZWXT/HlnHObwy1IJLTuGsHzFNxwfrTDVe9bsmAFGTo+2yHF+1bdYIfiCQ== integrity sha512-dq+mI1EQIvUM+zJtGCVgH3/B3Sbx4hKlGf2Usovm9KoqWYA+QpfVBholYDe/H2RXgO7LFEefDLvOdHDkqeJoyA==
dependencies: dependencies:
"@sentry/hub" "6.14.0" "@sentry/hub" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/node@^6.14.0": "@sentry/node@^6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.14.0.tgz#f81365e3852dee34967dccbeb9e9cb54b9f09881" resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.16.1.tgz#d92916da3e95d23e1ada274e97d6bf369e74ac51"
integrity sha512-ZxTqzDwYoyyXCMRd8JGzFK/MXHf6ZTKbHhAYSzz6FVWWrRveihVS98xurKZeR5kTefqFtJhZNyQ+BCclIc1zzw== integrity sha512-SeDDoug2kUxeF1D7JGPa3h5EXxKtmA01mITBPYx5xbJ0sMksnv5I5bC1SJ8arRRzq6+W1C4IEeDBQtrVCk6ixA==
dependencies: dependencies:
"@sentry/core" "6.14.0" "@sentry/core" "6.16.1"
"@sentry/hub" "6.14.0" "@sentry/hub" "6.16.1"
"@sentry/tracing" "6.14.0" "@sentry/tracing" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
cookie "^0.4.1" cookie "^0.4.1"
https-proxy-agent "^5.0.0" https-proxy-agent "^5.0.0"
lru_map "^0.3.3" lru_map "^0.3.3"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/react@^6.14.0": "@sentry/react@^6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.14.0.tgz#b6d30ab1c349a05562c6226b7b51897c22577415" resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.16.1.tgz#d4930c4b23bcd307306a0549d20964d98caed38c"
integrity sha512-aIBK6+gijXyCzHyV8Iwl01wLPdn8Zxl8XR1ux4QceFyzgSsks2trnwdNWarJwIdiu1bG6e9U79038yB8c2WQNQ== integrity sha512-n8fOEKbym4kBi946q3AWXBNy1UKTmABj/hE2nAJbTWhi5IwdM7WBG6QCT2yq7oTHLuTxQrAwgKQc+A6zFTyVHg==
dependencies: dependencies:
"@sentry/browser" "6.14.0" "@sentry/browser" "6.16.1"
"@sentry/minimal" "6.14.0" "@sentry/minimal" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
hoist-non-react-statics "^3.3.2" hoist-non-react-statics "^3.3.2"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/tracing@6.14.0", "@sentry/tracing@^6.14.0": "@sentry/tracing@6.16.1", "@sentry/tracing@^6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.14.0.tgz#e8270b69fe491fb59d866c6263e1e58ad1467483" resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.16.1.tgz#32fba3e07748e9a955055afd559a65996acb7d71"
integrity sha512-tcnHaNsKwk7y5ggVTbCVYvRKk9mH1MXab2G+0Eg2UBtXB3KOH3iYqdIMjpldu/7Rn4YuCP9OWcSqN7jXTlfaiA== integrity sha512-MPSbqXX59P+OEeST+U2V/8Hu/8QjpTUxTNeNyTHWIbbchdcMMjDbXTS3etCgajZR6Ro+DHElOz5cdSxH6IBGlA==
dependencies: dependencies:
"@sentry/hub" "6.14.0" "@sentry/hub" "6.16.1"
"@sentry/minimal" "6.14.0" "@sentry/minimal" "6.16.1"
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
"@sentry/utils" "6.14.0" "@sentry/utils" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/types@6.14.0": "@sentry/types@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.14.0.tgz#2cf63d0d616109d3a9b99fd27c51e3be1319fa96" resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.16.1.tgz#4917607115b30315757c2cf84f80bac5100b8ac0"
integrity sha512-7t1YyKO69lLru2WZVGWik6f59qf8J75wSg41Sk5SySvsd7hjcxbj1PWz61/5ndRStvbZmabiVcn76nI2JKyD5A== integrity sha512-Wh354g30UsJ5kYJbercektGX4ZMc9MHU++1NjeN2bTMnbofEcpUDWIiKeulZEY65IC1iU+1zRQQgtYO+/hgCUQ==
"@sentry/utils@6.14.0": "@sentry/utils@6.16.1":
version "6.14.0" version "6.16.1"
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.14.0.tgz#955c7b3ea0f0f65d68e80aae54ab85d095204262" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.16.1.tgz#1b9e14c2831b6e8b816f7021b9876133bf2be008"
integrity sha512-uEpQ2sjvS2bSj/QNIRWbXFXgk2+rWmw+QXbvVCIiYB7LK7Y7kry6StTt42UumMHlVLFLgXVKlTa50XrIblr60g== integrity sha512-7ngq/i4R8JZitJo9Sl8PDnjSbDehOxgr1vsoMmerIsyRZ651C/8B+jVkMhaAPgSdyJ0AlE3O7DKKTP1FXFw9qw==
dependencies: dependencies:
"@sentry/types" "6.14.0" "@sentry/types" "6.16.1"
tslib "^1.9.3" tslib "^1.9.3"
"@sentry/webpack-plugin@^1.18.3": "@sentry/webpack-plugin@^1.18.3":
@ -1098,6 +1098,13 @@
resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080"
integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
"@types/debug@^4.1.7":
version "4.1.7"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82"
integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==
dependencies:
"@types/ms" "*"
"@types/eslint-scope@^3.7.0": "@types/eslint-scope@^3.7.0":
version "3.7.1" version "3.7.1"
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e"
@ -1226,6 +1233,11 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a"
integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==
"@types/ms@*":
version "0.7.31"
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/nedb@^1.8.11": "@types/nedb@^1.8.11":
version "1.8.12" version "1.8.12"
resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.12.tgz#597bb124ddaf16039c6d478f4abc0a8f2006b134" resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.12.tgz#597bb124ddaf16039c6d478f4abc0a8f2006b134"
@ -1426,6 +1438,11 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
"@types/uuid@^8.3.3":
version "8.3.3"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.3.tgz#c6a60686d953dbd1b1d45e66f4ecdbd5d471b4d0"
integrity sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==
"@types/yargs-parser@*": "@types/yargs-parser@*":
version "20.2.1" version "20.2.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
@ -2508,6 +2525,13 @@ bindings@^1.5.0:
dependencies: dependencies:
file-uri-to-path "1.0.0" file-uri-to-path "1.0.0"
block-stream@*:
version "0.0.9"
resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=
dependencies:
inherits "~2.0.0"
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
version "4.12.0" version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
@ -2904,6 +2928,11 @@ chokidar@^3.2.2, chokidar@^3.5.2:
optionalDependencies: optionalDependencies:
fsevents "~2.3.2" fsevents "~2.3.2"
chownr@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chownr@^2.0.0: chownr@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
@ -3558,6 +3587,13 @@ debug@^3.2.6:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4.3.3:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
dependencies:
ms "2.1.2"
decamelize@^1.2.0: decamelize@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
@ -3679,6 +3715,11 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
detect-newline@^3.0.0: detect-newline@^3.0.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
@ -3748,6 +3789,11 @@ dotenv@^8.2.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
dottie@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.2.tgz#cc91c0726ce3a054ebf11c55fbc92a7f266dd154"
integrity sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==
duplexer3@^0.1.4: duplexer3@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
@ -4406,6 +4452,13 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
fs-minipass@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
dependencies:
minipass "^2.6.0"
fs-minipass@^2.0.0: fs-minipass@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
@ -4431,6 +4484,16 @@ fsevents@^2.1.2, fsevents@~2.3.1, fsevents@~2.3.2:
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
fstream@^1.0.0, fstream@^1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"
integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==
dependencies:
graceful-fs "^4.1.2"
inherits "~2.0.0"
mkdirp ">=0.5 0"
rimraf "2"
function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@ -4522,6 +4585,18 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
glob@^7.0.3:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
version "7.1.7" version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
@ -4844,7 +4919,7 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
iconv-lite@0.4.24: iconv-lite@0.4.24, iconv-lite@^0.4.4:
version "0.4.24" version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@ -4875,6 +4950,13 @@ ignore-by-default@^1.0.1:
resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09"
integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk=
ignore-walk@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335"
integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==
dependencies:
minimatch "^3.0.4"
immediate@~3.0.5: immediate@~3.0.5:
version "3.0.6" version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
@ -4943,6 +5025,11 @@ infer-owner@^1.0.4:
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==
inflection@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.1.tgz#c5cadd80888a90cf84c2e96e340d7edc85d5f0cb"
integrity sha512-dldYtl2WlN0QDkIDtg8+xFwOS2Tbmp12t1cHa5/YClU6ZQjTFm7B66UcVbh9NQB+HvT5BAd2t5+yKsBkw5pcqA==
inflight@^1.0.4: inflight@^1.0.4:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -4951,7 +5038,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -6565,6 +6652,14 @@ minipass-pipeline@^1.2.2:
dependencies: dependencies:
minipass "^3.0.0" minipass "^3.0.0"
minipass@^2.6.0, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
dependencies:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minipass@^3.0.0, minipass@^3.1.1: minipass@^3.0.0, minipass@^3.1.1:
version "3.1.3" version "3.1.3"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
@ -6572,6 +6667,13 @@ minipass@^3.0.0, minipass@^3.1.1:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
minizlib@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
dependencies:
minipass "^2.9.0"
minizlib@^2.1.1: minizlib@^2.1.1:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
@ -6588,7 +6690,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2" for-in "^1.0.2"
is-extendable "^1.0.1" is-extendable "^1.0.1"
mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1: "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1:
version "0.5.5" version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@ -6600,7 +6702,14 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.24.0, moment@^2.25.3, moment@^2.27.0: moment-timezone@^0.5.34:
version "0.5.34"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c"
integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==
dependencies:
moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.24.0, moment@^2.25.3, moment@^2.27.0, moment@^2.29.1:
version "2.29.1" version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
@ -6663,6 +6772,15 @@ nedb@^1.8.0:
mkdirp "~0.5.1" mkdirp "~0.5.1"
underscore "~1.4.4" underscore "~1.4.4"
needle@^2.2.1:
version "2.9.1"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684"
integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
sax "^1.2.4"
negotiator@0.6.2: negotiator@0.6.2:
version "0.6.2" version "0.6.2"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
@ -6678,6 +6796,11 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-addon-api@^3.0.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
node-fetch@^1.0.1: node-fetch@^1.0.1:
version "1.7.3" version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@ -6698,6 +6821,24 @@ node-fetch@^2.6.1:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-gyp@3.x:
version "3.8.0"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c"
integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==
dependencies:
fstream "^1.0.0"
glob "^7.0.3"
graceful-fs "^4.1.2"
mkdirp "^0.5.0"
nopt "2 || 3"
npmlog "0 || 1 || 2 || 3 || 4"
osenv "0"
request "^2.87.0"
rimraf "2"
semver "~5.3.0"
tar "^2.0.0"
which "1"
node-int64@^0.4.0: node-int64@^0.4.0:
version "0.4.0" version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@ -6749,6 +6890,22 @@ node-notifier@^8.0.0:
uuid "^8.3.0" uuid "^8.3.0"
which "^2.0.2" which "^2.0.2"
node-pre-gyp@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054"
integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4"
node-releases@^1.1.71: node-releases@^1.1.71:
version "1.1.73" version "1.1.73"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
@ -6784,6 +6941,21 @@ nodemon@^2.0.4:
undefsafe "^2.0.3" undefsafe "^2.0.3"
update-notifier "^4.1.0" update-notifier "^4.1.0"
"nopt@2 || 3":
version "3.0.6"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k=
dependencies:
abbrev "1"
nopt@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
dependencies:
abbrev "1"
osenv "^0.1.4"
nopt@~1.0.10: nopt@~1.0.10:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
@ -6848,6 +7020,27 @@ normalize.css@^7.0.0:
resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf" resolved "https://registry.yarnpkg.com/normalize.css/-/normalize.css-7.0.0.tgz#abfb1dd82470674e0322b53ceb1aaf412938e4bf"
integrity sha1-q/sd2CRwZ04DIrU86xqvQSk45L8= integrity sha1-q/sd2CRwZ04DIrU86xqvQSk45L8=
npm-bundled@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1"
integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==
dependencies:
npm-normalize-package-bin "^1.0.1"
npm-normalize-package-bin@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
npm-packlist@^1.1.6:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
dependencies:
ignore-walk "^3.0.1"
npm-bundled "^1.0.1"
npm-normalize-package-bin "^1.0.1"
npm-run-path@^2.0.0: npm-run-path@^2.0.0:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
@ -6862,7 +7055,7 @@ npm-run-path@^4.0.0:
dependencies: dependencies:
path-key "^3.0.0" path-key "^3.0.0"
npmlog@^4.1.2: "npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2, npmlog@^4.1.2:
version "4.1.2" version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@ -7006,6 +7199,24 @@ os-browserify@^0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-tmpdir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
osenv@0, osenv@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-cancelable@^1.0.0: p-cancelable@^1.0.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc"
@ -7242,6 +7453,11 @@ performance-now@^2.1.0:
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pg-connection-string@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34"
integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
@ -8517,7 +8733,7 @@ rc-virtual-list@^3.4.1:
rc-resize-observer "^1.0.0" rc-resize-observer "^1.0.0"
rc-util "^5.0.7" rc-util "^5.0.7"
rc@^1.2.8: rc@^1.2.7, rc@^1.2.8:
version "1.2.8" version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
@ -8855,7 +9071,7 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1" stealthy-require "^1.1.1"
tough-cookie "^2.3.3" tough-cookie "^2.3.3"
request@^2.88.0: request@^2.87.0, request@^2.88.0:
version "2.88.2" version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@ -8973,6 +9189,18 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
retry-as-promised@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-5.0.0.tgz#f4ecc25133603a2d2a7aff4a128691d7bc506d54"
integrity sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==
rimraf@2, rimraf@^2.6.1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
dependencies:
glob "^7.1.3"
rimraf@^3.0.0, rimraf@^3.0.2: rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
@ -9157,7 +9385,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -9189,6 +9417,11 @@ sane@^4.0.3:
minimist "^1.1.1" minimist "^1.1.1"
walker "~1.0.5" walker "~1.0.5"
sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
saxes@^3.1.9: saxes@^3.1.9:
version "3.1.11" version "3.1.11"
resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b"
@ -9256,7 +9489,7 @@ semver-diff@^3.1.1:
dependencies: dependencies:
semver "^6.3.0" semver "^6.3.0"
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: "semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1" version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@ -9266,13 +9499,18 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2: semver@^7.3.2, semver@^7.3.5:
version "7.3.5" version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8=
send@0.17.1: send@0.17.1:
version "0.17.1" version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
@ -9292,6 +9530,32 @@ send@0.17.1:
range-parser "~1.2.1" range-parser "~1.2.1"
statuses "~1.5.0" statuses "~1.5.0"
sequelize-pool@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768"
integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==
sequelize@^7.0.0-alpha.3:
version "7.0.0-alpha.3"
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-7.0.0-alpha.3.tgz#59144f141644e58ba96bda00225809508649ade9"
integrity sha512-LfrfQJWOqzY89pHFjGOztVdOlefgkOcJvc9plFM7AhATqSoygx6SSPIemeh5t9DB2vzwOGcC0WBw/cJiEQ67yw==
dependencies:
"@types/debug" "^4.1.7"
debug "^4.3.3"
dottie "^2.0.2"
inflection "^1.13.1"
lodash "^4.17.21"
moment "^2.29.1"
moment-timezone "^0.5.34"
pg-connection-string "^2.5.0"
retry-as-promised "^5.0.0"
semver "^7.3.5"
sequelize-pool "^7.1.0"
toposort-class "^1.0.1"
uuid "^8.3.2"
validator "^13.7.0"
wkx "^0.5.0"
serialize-javascript@^5.0.1: serialize-javascript@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4"
@ -9601,6 +9865,16 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sqlite3@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.2.tgz#00924adcc001c17686e0a6643b6cbbc2d3965083"
integrity sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA==
dependencies:
node-addon-api "^3.0.0"
node-pre-gyp "^0.11.0"
optionalDependencies:
node-gyp "3.x"
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
@ -9901,6 +10175,28 @@ tapable@^2.1.1, tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
tar@^2.0.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40"
integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==
dependencies:
block-stream "*"
fstream "^1.0.12"
inherits "2"
tar@^4:
version "4.4.19"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
dependencies:
chownr "^1.1.4"
fs-minipass "^1.2.7"
minipass "^2.9.0"
minizlib "^1.3.3"
mkdirp "^0.5.5"
safe-buffer "^5.2.1"
yallist "^3.1.1"
tar@^6.0.2: tar@^6.0.2:
version "6.1.0" version "6.1.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
@ -10074,6 +10370,11 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
toposort-class@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988"
integrity sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=
touch@^3.1.0: touch@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b"
@ -10466,6 +10767,11 @@ validate-npm-package-license@^3.0.1:
spdx-correct "^3.0.0" spdx-correct "^3.0.0"
spdx-expression-parse "^3.0.0" spdx-expression-parse "^3.0.0"
validator@^13.7.0:
version "13.7.0"
resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857"
integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==
value-equal@^1.0.1: value-equal@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c"
@ -10693,7 +10999,7 @@ which-module@^2.0.0:
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
which@^1.2.9: which@1, which@^1.2.9:
version "1.3.1" version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@ -10744,6 +11050,13 @@ winston@^3.3.3:
triple-beam "^1.3.0" triple-beam "^1.3.0"
winston-transport "^4.4.0" winston-transport "^4.4.0"
wkx@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"
integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==
dependencies:
"@types/node" "*"
word-wrap@~1.2.3: word-wrap@~1.2.3:
version "1.2.3" version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
@ -10838,6 +11151,11 @@ yallist@^2.1.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
yallist@^3.0.0, yallist@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0: yallist@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"