mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-04-24 08:41:31 +00:00
basic support for typescript
This commit is contained in:
parent
71477d5aae
commit
f3aed00b34
10
bin/anyproxy
10
bin/anyproxy
@ -5,9 +5,9 @@
|
|||||||
const program = require('commander'),
|
const program = require('commander'),
|
||||||
color = require('colorful'),
|
color = require('colorful'),
|
||||||
packageInfo = require('../package.json'),
|
packageInfo = require('../package.json'),
|
||||||
ruleLoader = require('../lib/ruleLoader'),
|
ruleLoader = require('../dist/ruleLoader'),
|
||||||
util = require('../lib/util'),
|
util = require('../dist/util'),
|
||||||
logUtil = require('../lib/log');
|
logUtil = require('../dist/log');
|
||||||
|
|
||||||
program
|
program
|
||||||
.version(packageInfo.version)
|
.version(packageInfo.version)
|
||||||
@ -23,13 +23,13 @@ program
|
|||||||
.parse(process.argv);
|
.parse(process.argv);
|
||||||
|
|
||||||
if (program.clear) {
|
if (program.clear) {
|
||||||
require('../lib/certMgr').clearCerts(() => {
|
require('../dist/certMgr').clearCerts(() => {
|
||||||
util.deleteFolderContentsRecursive(util.getAnyProxyPath('cache'));
|
util.deleteFolderContentsRecursive(util.getAnyProxyPath('cache'));
|
||||||
console.log(color.green('done !'));
|
console.log(color.green('done !'));
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
} else if (program.root) {
|
} else if (program.root) {
|
||||||
require('../lib/certMgr').generateRootCA(() => {
|
require('../dist/certMgr').generateRootCA(() => {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
21
gulpfile.js
Normal file
21
gulpfile.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const gulp = require('gulp');
|
||||||
|
const ts = require('gulp-typescript');
|
||||||
|
|
||||||
|
const tsObject = ts.createProject('./tsconfig.json');
|
||||||
|
const tsFileList = ['./*.ts', 'lib/*.ts', 'lib/**/*.js'];
|
||||||
|
/*
|
||||||
|
* transfer electron ts to js
|
||||||
|
*/
|
||||||
|
|
||||||
|
function compileTS() {
|
||||||
|
gulp.src(tsFileList, { base: './lib' })
|
||||||
|
.pipe(tsObject())
|
||||||
|
.pipe(gulp.dest('./dist/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
compileTS();
|
||||||
|
|
||||||
|
// gulp.watch(tsFileList, (event) => {
|
||||||
|
// console.info('file changed');
|
||||||
|
// compileTS();
|
||||||
|
// });
|
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* a util to set and get all configuable constant
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const USER_HOME = process.env.HOME || process.env.USERPROFILE;
|
|
||||||
const DEFAULT_ANYPROXY_HOME = path.join(USER_HOME, '/.anyproxy/');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* return AnyProxy's home path
|
|
||||||
*/
|
|
||||||
module.exports.getAnyProxyHome = function () {
|
|
||||||
const ENV_ANYPROXY_HOME = process.env.ANYPROXY_HOME || '';
|
|
||||||
return ENV_ANYPROXY_HOME || DEFAULT_ANYPROXY_HOME;
|
|
||||||
}
|
|
20
lib/configUtil.ts
Normal file
20
lib/configUtil.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* a util to set and get all configuable constant
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function (): void {
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const USER_HOME = process.env.HOME || process.env.USERPROFILE;
|
||||||
|
const DEFAULT_ANYPROXY_HOME = path.join(USER_HOME, '/.anyproxy/');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return AnyProxy's home path
|
||||||
|
*/
|
||||||
|
module.exports.getAnyProxyHome = function (): string {
|
||||||
|
const ENV_ANYPROXY_HOME = process.env.ANYPROXY_HOME || '';
|
||||||
|
return ENV_ANYPROXY_HOME || DEFAULT_ANYPROXY_HOME;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
105
lib/log.js
105
lib/log.js
@ -1,105 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const color = require('colorful');
|
|
||||||
const util = require('./util');
|
|
||||||
|
|
||||||
let ifPrint = true;
|
|
||||||
let logLevel = 0;
|
|
||||||
const LogLevelMap = {
|
|
||||||
tip: 0,
|
|
||||||
system_error: 1,
|
|
||||||
rule_error: 2,
|
|
||||||
warn: 3,
|
|
||||||
debug: 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
function setPrintStatus(status) {
|
|
||||||
ifPrint = !!status;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLogLevel(level) {
|
|
||||||
logLevel = parseInt(level, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function printLog(content, type) {
|
|
||||||
if (!ifPrint) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const timeString = util.formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss');
|
|
||||||
switch (type) {
|
|
||||||
case LogLevelMap.tip: {
|
|
||||||
if (logLevel > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LogLevelMap.system_error: {
|
|
||||||
if (logLevel > 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
console.error(color.red(`[AnyProxy ERROR][${timeString}]: ` + content));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LogLevelMap.rule_error: {
|
|
||||||
if (logLevel > 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(color.red(`[AnyProxy RULE_ERROR][${timeString}]: ` + content));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LogLevelMap.warn: {
|
|
||||||
if (logLevel > 3) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(color.magenta(`[AnyProxy WARN][${timeString}]: ` + content));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case LogLevelMap.debug: {
|
|
||||||
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
default : {
|
|
||||||
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.printLog = printLog;
|
|
||||||
|
|
||||||
module.exports.debug = (content) => {
|
|
||||||
printLog(content, LogLevelMap.debug);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.info = (content) => {
|
|
||||||
printLog(content, LogLevelMap.tip);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.warn = (content) => {
|
|
||||||
printLog(content, LogLevelMap.warn);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.error = (content) => {
|
|
||||||
printLog(content, LogLevelMap.error);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.ruleError = (content) => {
|
|
||||||
printLog(content, LogLevelMap.rule_error);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.setPrintStatus = setPrintStatus;
|
|
||||||
module.exports.setLogLevel = setLogLevel;
|
|
||||||
module.exports.T_TIP = LogLevelMap.tip;
|
|
||||||
module.exports.T_ERR = LogLevelMap.system_error;
|
|
||||||
module.exports.T_RULE_ERROR = LogLevelMap.rule_error;
|
|
||||||
module.exports.T_WARN = LogLevelMap.warn;
|
|
||||||
module.exports.T_DEBUG = LogLevelMap.debug;
|
|
125
lib/log.ts
Normal file
125
lib/log.ts
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import * as color from 'colorful';
|
||||||
|
import util from './util';
|
||||||
|
|
||||||
|
let ifPrint = true;
|
||||||
|
let logLevel = 0;
|
||||||
|
enum LogLevelMap {
|
||||||
|
tip = 0,
|
||||||
|
system_error = 1,
|
||||||
|
error = 1,
|
||||||
|
rule_error = 2,
|
||||||
|
warn = 3,
|
||||||
|
debug = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
function setPrintStatus(status: boolean): void {
|
||||||
|
ifPrint = !!status;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLogLevel(level: string): void {
|
||||||
|
logLevel = parseInt(level, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function printLog(content: string, type?: LogLevelMap) {
|
||||||
|
if (!ifPrint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeString = util.formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss');
|
||||||
|
switch (type) {
|
||||||
|
case LogLevelMap.tip: {
|
||||||
|
if (logLevel > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LogLevelMap.system_error: {
|
||||||
|
if (logLevel > 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.error(color.red(`[AnyProxy ERROR][${timeString}]: ` + content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LogLevelMap.rule_error: {
|
||||||
|
if (logLevel > 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(color.red(`[AnyProxy RULE_ERROR][${timeString}]: ` + content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LogLevelMap.warn: {
|
||||||
|
if (logLevel > 3) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(color.magenta(`[AnyProxy WARN][${timeString}]: ` + content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case LogLevelMap.debug: {
|
||||||
|
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
console.log(color.cyan(`[AnyProxy Log][${timeString}]: ` + content));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.printLog = printLog;
|
||||||
|
|
||||||
|
function debug (content): void {
|
||||||
|
printLog(content, LogLevelMap.debug);
|
||||||
|
};
|
||||||
|
|
||||||
|
function info (content): void {
|
||||||
|
printLog(content, LogLevelMap.tip);
|
||||||
|
};
|
||||||
|
|
||||||
|
function warn (content) {
|
||||||
|
printLog(content, LogLevelMap.warn);
|
||||||
|
};
|
||||||
|
|
||||||
|
function error (content) {
|
||||||
|
printLog(content, LogLevelMap.system_error);
|
||||||
|
};
|
||||||
|
|
||||||
|
function ruleError (content) {
|
||||||
|
printLog(content, LogLevelMap.rule_error);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.setPrintStatus = setPrintStatus;
|
||||||
|
module.exports.setLogLevel = setLogLevel;
|
||||||
|
module.exports.T_TIP = LogLevelMap.tip;
|
||||||
|
module.exports.T_ERR = LogLevelMap.system_error;
|
||||||
|
module.exports.T_RULE_ERROR = LogLevelMap.rule_error;
|
||||||
|
module.exports.T_WARN = LogLevelMap.warn;
|
||||||
|
module.exports.T_DEBUG = LogLevelMap.debug;
|
||||||
|
|
||||||
|
const LogUtil = {
|
||||||
|
setPrintStatus,
|
||||||
|
setLogLevel,
|
||||||
|
printLog,
|
||||||
|
debug,
|
||||||
|
info,
|
||||||
|
warn,
|
||||||
|
error,
|
||||||
|
ruleError,
|
||||||
|
T_TIP: LogLevelMap.tip,
|
||||||
|
T_ERR: LogLevelMap.error,
|
||||||
|
T_RULE_ERROR: LogLevelMap.rule_error,
|
||||||
|
T_WARN: LogLevelMap.warn,
|
||||||
|
T_DEBUG: LogLevelMap.debug
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LogUtil;
|
||||||
|
module.exports = LogUtil;
|
323
lib/util.js
323
lib/util.js
@ -1,323 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const fs = require('fs'),
|
|
||||||
path = require('path'),
|
|
||||||
mime = require('mime-types'),
|
|
||||||
color = require('colorful'),
|
|
||||||
crypto = require('crypto'),
|
|
||||||
Buffer = require('buffer').Buffer,
|
|
||||||
logUtil = require('./log');
|
|
||||||
const networkInterfaces = require('os').networkInterfaces();
|
|
||||||
|
|
||||||
// {"Content-Encoding":"gzip"} --> {"content-encoding":"gzip"}
|
|
||||||
module.exports.lower_keys = (obj) => {
|
|
||||||
for (const key in obj) {
|
|
||||||
const val = obj[key];
|
|
||||||
delete obj[key];
|
|
||||||
|
|
||||||
obj[key.toLowerCase()] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.merge = function (baseObj, extendObj) {
|
|
||||||
for (const key in extendObj) {
|
|
||||||
baseObj[key] = extendObj[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseObj;
|
|
||||||
};
|
|
||||||
|
|
||||||
function getUserHome() {
|
|
||||||
return process.env.HOME || process.env.USERPROFILE;
|
|
||||||
}
|
|
||||||
module.exports.getUserHome = getUserHome;
|
|
||||||
|
|
||||||
function getAnyProxyHome() {
|
|
||||||
const home = path.join(getUserHome(), '/.anyproxy/');
|
|
||||||
if (!fs.existsSync(home)) {
|
|
||||||
fs.mkdirSync(home);
|
|
||||||
}
|
|
||||||
return home;
|
|
||||||
}
|
|
||||||
module.exports.getAnyProxyHome = getAnyProxyHome;
|
|
||||||
|
|
||||||
module.exports.getAnyProxyPath = function (pathName) {
|
|
||||||
const home = getAnyProxyHome();
|
|
||||||
const targetPath = path.join(home, pathName);
|
|
||||||
if (!fs.existsSync(targetPath)) {
|
|
||||||
fs.mkdirSync(targetPath);
|
|
||||||
}
|
|
||||||
return targetPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.simpleRender = function (str, object, regexp) {
|
|
||||||
return String(str).replace(regexp || (/\{\{([^{}]+)\}\}/g), (match, name) => {
|
|
||||||
if (match.charAt(0) === '\\') {
|
|
||||||
return match.slice(1);
|
|
||||||
}
|
|
||||||
return (object[name] != null) ? object[name] : '';
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.filewalker = function (root, cb) {
|
|
||||||
root = root || process.cwd();
|
|
||||||
|
|
||||||
const ret = {
|
|
||||||
directory: [],
|
|
||||||
file: []
|
|
||||||
};
|
|
||||||
|
|
||||||
fs.readdir(root, (err, list) => {
|
|
||||||
if (list && list.length) {
|
|
||||||
list.map((item) => {
|
|
||||||
const fullPath = path.join(root, item),
|
|
||||||
stat = fs.lstatSync(fullPath);
|
|
||||||
|
|
||||||
if (stat.isFile()) {
|
|
||||||
ret.file.push({
|
|
||||||
name: item,
|
|
||||||
fullPath
|
|
||||||
});
|
|
||||||
} else if (stat.isDirectory()) {
|
|
||||||
ret.directory.push({
|
|
||||||
name: item,
|
|
||||||
fullPath
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cb && cb.apply(null, [null, ret]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 获取文件所对应的content-type以及content-length等信息
|
|
||||||
* 比如在useLocalResponse的时候会使用到
|
|
||||||
*/
|
|
||||||
module.exports.contentType = function (filepath) {
|
|
||||||
return mime.contentType(path.extname(filepath));
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 读取file的大小,以byte为单位
|
|
||||||
*/
|
|
||||||
module.exports.contentLength = function (filepath) {
|
|
||||||
try {
|
|
||||||
const stat = fs.statSync(filepath);
|
|
||||||
return stat.size;
|
|
||||||
} catch (e) {
|
|
||||||
logUtil.printLog(color.red('\nfailed to ready local file : ' + filepath));
|
|
||||||
logUtil.printLog(color.red(e));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* remove the cache before requiring, the path SHOULD BE RELATIVE TO UTIL.JS
|
|
||||||
*/
|
|
||||||
module.exports.freshRequire = function (modulePath) {
|
|
||||||
delete require.cache[require.resolve(modulePath)];
|
|
||||||
return require(modulePath);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* format the date string
|
|
||||||
* @param date Date or timestamp
|
|
||||||
* @param formatter YYYYMMDDHHmmss
|
|
||||||
*/
|
|
||||||
module.exports.formatDate = function (date, formatter) {
|
|
||||||
if (typeof date !== 'object') {
|
|
||||||
date = new Date(date);
|
|
||||||
}
|
|
||||||
const transform = function (value) {
|
|
||||||
return value < 10 ? '0' + value : value;
|
|
||||||
};
|
|
||||||
return formatter.replace(/^YYYY|MM|DD|hh|mm|ss/g, (match) => {
|
|
||||||
switch (match) {
|
|
||||||
case 'YYYY':
|
|
||||||
return transform(date.getFullYear());
|
|
||||||
case 'MM':
|
|
||||||
return transform(date.getMonth() + 1);
|
|
||||||
case 'mm':
|
|
||||||
return transform(date.getMinutes());
|
|
||||||
case 'DD':
|
|
||||||
return transform(date.getDate());
|
|
||||||
case 'hh':
|
|
||||||
return transform(date.getHours());
|
|
||||||
case 'ss':
|
|
||||||
return transform(date.getSeconds());
|
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get headers(Object) from rawHeaders(Array)
|
|
||||||
* @param rawHeaders [key, value, key2, value2, ...]
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports.getHeaderFromRawHeaders = function (rawHeaders) {
|
|
||||||
const headerObj = {};
|
|
||||||
const _handleSetCookieHeader = function (key, value) {
|
|
||||||
if (headerObj[key].constructor === Array) {
|
|
||||||
headerObj[key].push(value);
|
|
||||||
} else {
|
|
||||||
headerObj[key] = [headerObj[key], value];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!!rawHeaders) {
|
|
||||||
for (let i = 0; i < rawHeaders.length; i += 2) {
|
|
||||||
const key = rawHeaders[i];
|
|
||||||
let value = rawHeaders[i + 1];
|
|
||||||
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
value = value.replace(/\0+$/g, ''); // 去除 \u0000的null字符串
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!headerObj[key]) {
|
|
||||||
headerObj[key] = value;
|
|
||||||
} else {
|
|
||||||
// headers with same fields could be combined with comma. Ref: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
|
||||||
// set-cookie should NOT be combined. Ref: https://tools.ietf.org/html/rfc6265
|
|
||||||
if (key.toLowerCase() === 'set-cookie') {
|
|
||||||
_handleSetCookieHeader(key, value);
|
|
||||||
} else {
|
|
||||||
headerObj[key] = headerObj[key] + ',' + value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return headerObj;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports.getAllIpAddress = function getAllIpAddress() {
|
|
||||||
const allIp = [];
|
|
||||||
|
|
||||||
Object.keys(networkInterfaces).map((nic) => {
|
|
||||||
networkInterfaces[nic].filter((detail) => {
|
|
||||||
if (detail.family.toLowerCase() === 'ipv4') {
|
|
||||||
allIp.push(detail.address);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return allIp.length ? allIp : ['127.0.0.1'];
|
|
||||||
};
|
|
||||||
|
|
||||||
function deleteFolderContentsRecursive(dirPath, ifClearFolderItself) {
|
|
||||||
if (!dirPath.trim() || dirPath === '/') {
|
|
||||||
throw new Error('can_not_delete_this_dir');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.existsSync(dirPath)) {
|
|
||||||
fs.readdirSync(dirPath).forEach((file) => {
|
|
||||||
const curPath = path.join(dirPath, file);
|
|
||||||
if (fs.lstatSync(curPath).isDirectory()) {
|
|
||||||
deleteFolderContentsRecursive(curPath, true);
|
|
||||||
} else { // delete all files
|
|
||||||
fs.unlinkSync(curPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (ifClearFolderItself) {
|
|
||||||
try {
|
|
||||||
// ref: https://github.com/shelljs/shelljs/issues/49
|
|
||||||
const start = Date.now();
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
fs.rmdirSync(dirPath);
|
|
||||||
break;
|
|
||||||
} catch (er) {
|
|
||||||
if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM')) {
|
|
||||||
// Retry on windows, sometimes it takes a little time before all the files in the directory are gone
|
|
||||||
if (Date.now() - start > 1000) throw er;
|
|
||||||
} else if (er.code === 'ENOENT') {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
throw er;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
throw new Error('could not remove directory (code ' + e.code + '): ' + dirPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.deleteFolderContentsRecursive = deleteFolderContentsRecursive;
|
|
||||||
|
|
||||||
module.exports.getFreePort = function () {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const server = require('net').createServer();
|
|
||||||
server.unref();
|
|
||||||
server.on('error', reject);
|
|
||||||
server.listen(0, () => {
|
|
||||||
const port = server.address().port;
|
|
||||||
server.close(() => {
|
|
||||||
resolve(port);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.collectErrorLog = function (error) {
|
|
||||||
if (error && error.code && error.toString()) {
|
|
||||||
return error.toString();
|
|
||||||
} else {
|
|
||||||
let result = [error, error.stack].join('\n');
|
|
||||||
try {
|
|
||||||
const errorString = error.toString();
|
|
||||||
if (errorString.indexOf('You may only yield a function') >= 0) {
|
|
||||||
result = 'Function is not yieldable. Did you forget to provide a generator or promise in rule file ? \nFAQ http://anyproxy.io/4.x/#faq';
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.isFunc = function (source) {
|
|
||||||
return source && Object.tostring.call(source) === '[object Function]';
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {object} content
|
|
||||||
* @returns the size of the content
|
|
||||||
*/
|
|
||||||
module.exports.getByteSize = function (content) {
|
|
||||||
return Buffer.byteLength(content);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* identify whether the
|
|
||||||
*/
|
|
||||||
module.exports.isIpDomain = function (domain) {
|
|
||||||
if (!domain) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const ipReg = /^\d+?\.\d+?\.\d+?\.\d+?$/;
|
|
||||||
|
|
||||||
return ipReg.test(domain);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To generic a Sec-WebSocket-Accept value
|
|
||||||
* 1. append the `Sec-WebSocket-Key` request header with `matic string`
|
|
||||||
* 2. get sha1 hash of the string
|
|
||||||
* 3. get base64 of the sha1 hash
|
|
||||||
*/
|
|
||||||
module.exports.genericWsSecAccept = function (wsSecKey) {
|
|
||||||
// the string to generate the Sec-WebSocket-Accept
|
|
||||||
const magicString = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
|
||||||
const targetString = `${wsSecKey}${magicString}`;
|
|
||||||
const shasum = crypto.createHash('sha1');
|
|
||||||
shasum.update(targetString);
|
|
||||||
return shasum.digest('base64');
|
|
||||||
}
|
|
366
lib/util.ts
Normal file
366
lib/util.ts
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// (function (): void {
|
||||||
|
// const fs = require('fs'),
|
||||||
|
// path = require('path'),
|
||||||
|
// mime = require('mime-types'),
|
||||||
|
// color = require('colorful'),
|
||||||
|
// crypto = require('crypto'),
|
||||||
|
// Buffer = require('buffer').Buffer,
|
||||||
|
// logUtil = require('./log');
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as mime from 'mime-types';
|
||||||
|
import * as color from 'colorful';
|
||||||
|
import {Buffer} from 'buffer';
|
||||||
|
import * as crypto from 'crypto';
|
||||||
|
// import buffer from 'buffer';
|
||||||
|
import logUtil from './log';
|
||||||
|
// const Buffer = buffer.Buffer;
|
||||||
|
|
||||||
|
const networkInterfaces = require('os').networkInterfaces();
|
||||||
|
|
||||||
|
// {"Content-Encoding":"gzip"} --> {"content-encoding":"gzip"}
|
||||||
|
function lower_keys (obj: object): object {
|
||||||
|
for (const key in obj) {
|
||||||
|
const val = obj[key];
|
||||||
|
delete obj[key];
|
||||||
|
|
||||||
|
obj[key.toLowerCase()] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
function merge (baseObj: object, extendObj: object): object {
|
||||||
|
for (const key in extendObj) {
|
||||||
|
baseObj[key] = extendObj[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getUserHome(): string {
|
||||||
|
return process.env.HOME || process.env.USERPROFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAnyProxyHome(): string {
|
||||||
|
const home = path.join(getUserHome(), '/.anyproxy/');
|
||||||
|
if (!fs.existsSync(home)) {
|
||||||
|
fs.mkdirSync(home);
|
||||||
|
}
|
||||||
|
return home;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAnyProxyPath (pathName): string {
|
||||||
|
const home = getAnyProxyHome();
|
||||||
|
const targetPath = path.join(home, pathName);
|
||||||
|
if (!fs.existsSync(targetPath)) {
|
||||||
|
fs.mkdirSync(targetPath);
|
||||||
|
}
|
||||||
|
return targetPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简易字符串render替换
|
||||||
|
*/
|
||||||
|
function simpleRender (str: string, object: object, regexp: RegExp) {
|
||||||
|
return String(str).replace(regexp || (/\{\{([^{}]+)\}\}/g), (match, name) => {
|
||||||
|
if (match.charAt(0) === '\\') {
|
||||||
|
return match.slice(1);
|
||||||
|
}
|
||||||
|
return (object[name] != null) ? object[name] : '';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取指定目录下的子目录
|
||||||
|
*/
|
||||||
|
function filewalker (root: string, cb: Function) {
|
||||||
|
root = root || process.cwd();
|
||||||
|
|
||||||
|
const ret = {
|
||||||
|
directory: [],
|
||||||
|
file: []
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.readdir(root, (err, list) => {
|
||||||
|
if (list && list.length) {
|
||||||
|
list.map((item) => {
|
||||||
|
const fullPath = path.join(root, item),
|
||||||
|
stat = fs.lstatSync(fullPath);
|
||||||
|
|
||||||
|
if (stat.isFile()) {
|
||||||
|
ret.file.push({
|
||||||
|
name: item,
|
||||||
|
fullPath
|
||||||
|
});
|
||||||
|
} else if (stat.isDirectory()) {
|
||||||
|
ret.directory.push({
|
||||||
|
name: item,
|
||||||
|
fullPath
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cb && cb.apply(null, [null, ret]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 获取文件所对应的content-type以及content-length等信息
|
||||||
|
* 比如在useLocalResponse的时候会使用到
|
||||||
|
*/
|
||||||
|
function contentType (filepath: string): string {
|
||||||
|
return mime.contentType(path.extname(filepath));
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 读取file的大小,以byte为单位
|
||||||
|
*/
|
||||||
|
function contentLength (filepath: string): number {
|
||||||
|
try {
|
||||||
|
const stat = fs.statSync(filepath);
|
||||||
|
return stat.size;
|
||||||
|
} catch (e) {
|
||||||
|
logUtil.printLog(color.red('\nfailed to ready local file : ' + filepath));
|
||||||
|
logUtil.printLog(color.red(e));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove the cache before requiring, the path SHOULD BE RELATIVE TO UTIL.JS
|
||||||
|
*/
|
||||||
|
function freshRequire (modulePath: string): NodeModule {
|
||||||
|
delete require.cache[require.resolve(modulePath)];
|
||||||
|
return require(modulePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* format the date string
|
||||||
|
* @param date Date or timestamp
|
||||||
|
* @param formatter YYYYMMDDHHmmss
|
||||||
|
*/
|
||||||
|
function formatDate (date: Date | number, formatter: string): string {
|
||||||
|
let finalDate : Date;
|
||||||
|
if (typeof date !== 'object') {
|
||||||
|
finalDate = new Date(date);
|
||||||
|
} else {
|
||||||
|
finalDate = date;
|
||||||
|
}
|
||||||
|
const transform = function (value) {
|
||||||
|
return value < 10 ? '0' + value : value;
|
||||||
|
};
|
||||||
|
return formatter.replace(/^YYYY|MM|DD|hh|mm|ss/g, (match) => {
|
||||||
|
switch (match) {
|
||||||
|
case 'YYYY':
|
||||||
|
return transform(finalDate.getFullYear());
|
||||||
|
case 'MM':
|
||||||
|
return transform(finalDate.getMonth() + 1);
|
||||||
|
case 'mm':
|
||||||
|
return transform(finalDate.getMinutes());
|
||||||
|
case 'DD':
|
||||||
|
return transform(finalDate.getDate());
|
||||||
|
case 'hh':
|
||||||
|
return transform(finalDate.getHours());
|
||||||
|
case 'ss':
|
||||||
|
return transform(finalDate.getSeconds());
|
||||||
|
default:
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get headers(Object) from rawHeaders(Array)
|
||||||
|
* @param rawHeaders [key, value, key2, value2, ...]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
function getHeaderFromRawHeaders (rawHeaders: Array<string>) {
|
||||||
|
const headerObj = {};
|
||||||
|
const _handleSetCookieHeader = function (key, value) {
|
||||||
|
if (headerObj[key].constructor === Array) {
|
||||||
|
headerObj[key].push(value);
|
||||||
|
} else {
|
||||||
|
headerObj[key] = [headerObj[key], value];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!!rawHeaders) {
|
||||||
|
for (let i = 0; i < rawHeaders.length; i += 2) {
|
||||||
|
const key = rawHeaders[i];
|
||||||
|
let value = rawHeaders[i + 1];
|
||||||
|
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = value.replace(/\0+$/g, ''); // 去除 \u0000的null字符串
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!headerObj[key]) {
|
||||||
|
headerObj[key] = value;
|
||||||
|
} else {
|
||||||
|
// headers with same fields could be combined with comma. Ref: https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
|
||||||
|
// set-cookie should NOT be combined. Ref: https://tools.ietf.org/html/rfc6265
|
||||||
|
if (key.toLowerCase() === 'set-cookie') {
|
||||||
|
_handleSetCookieHeader(key, value);
|
||||||
|
} else {
|
||||||
|
headerObj[key] = headerObj[key] + ',' + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headerObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getAllIpAddress (): Array<string> {
|
||||||
|
const allIp = [];
|
||||||
|
|
||||||
|
Object.keys(networkInterfaces).map((nic) => {
|
||||||
|
networkInterfaces[nic].filter((detail) => {
|
||||||
|
if (detail.family.toLowerCase() === 'ipv4') {
|
||||||
|
allIp.push(detail.address);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return allIp.length ? allIp : ['127.0.0.1'];
|
||||||
|
};
|
||||||
|
|
||||||
|
function deleteFolderContentsRecursive(dirPath: string, ifClearFolderItself: boolean): void {
|
||||||
|
if (!dirPath.trim() || dirPath === '/') {
|
||||||
|
throw new Error('can_not_delete_this_dir');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs.existsSync(dirPath)) {
|
||||||
|
fs.readdirSync(dirPath).forEach((file) => {
|
||||||
|
const curPath = path.join(dirPath, file);
|
||||||
|
if (fs.lstatSync(curPath).isDirectory()) {
|
||||||
|
deleteFolderContentsRecursive(curPath, true);
|
||||||
|
} else { // delete all files
|
||||||
|
fs.unlinkSync(curPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ifClearFolderItself) {
|
||||||
|
try {
|
||||||
|
// ref: https://github.com/shelljs/shelljs/issues/49
|
||||||
|
const start = Date.now();
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
fs.rmdirSync(dirPath);
|
||||||
|
break;
|
||||||
|
} catch (er) {
|
||||||
|
if (process.platform === 'win32' && (er.code === 'ENOTEMPTY' || er.code === 'EBUSY' || er.code === 'EPERM')) {
|
||||||
|
// Retry on windows, sometimes it takes a little time before all the files in the directory are gone
|
||||||
|
if (Date.now() - start > 1000) throw er;
|
||||||
|
} else if (er.code === 'ENOENT') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
throw er;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('could not remove directory (code ' + e.code + '): ' + dirPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFreePort (): Promise<number> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const server = require('net').createServer();
|
||||||
|
server.unref();
|
||||||
|
server.on('error', reject);
|
||||||
|
server.listen(0, () => {
|
||||||
|
const port = server.address().port;
|
||||||
|
server.close(() => {
|
||||||
|
resolve(port);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectErrorLog (error: any): string {
|
||||||
|
if (error && error.code && error.toString()) {
|
||||||
|
return error.toString();
|
||||||
|
} else {
|
||||||
|
let result = [error, error.stack].join('\n');
|
||||||
|
try {
|
||||||
|
const errorString = error.toString();
|
||||||
|
if (errorString.indexOf('You may only yield a function') >= 0) {
|
||||||
|
result = 'Function is not yieldable. Did you forget to provide a generator or promise in rule file ? \nFAQ http://anyproxy.io/4.x/#faq';
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFunc (source: object): boolean {
|
||||||
|
return source && Object.prototype.toString.call(source) === '[object Function]';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} content
|
||||||
|
* @returns the size of the content
|
||||||
|
*/
|
||||||
|
function getByteSize (content: Buffer): number {
|
||||||
|
return Buffer.byteLength(content);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* identify whether the
|
||||||
|
*/
|
||||||
|
function isIpDomain (domain: string): boolean {
|
||||||
|
if (!domain) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const ipReg = /^\d+?\.\d+?\.\d+?\.\d+?$/;
|
||||||
|
|
||||||
|
return ipReg.test(domain);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To generic a Sec-WebSocket-Accept value
|
||||||
|
* 1. append the `Sec-WebSocket-Key` request header with `matic string`
|
||||||
|
* 2. get sha1 hash of the string
|
||||||
|
* 3. get base64 of the sha1 hash
|
||||||
|
*/
|
||||||
|
function genericWsSecAccept (wsSecKey) {
|
||||||
|
// the string to generate the Sec-WebSocket-Accept
|
||||||
|
const magicString = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
|
||||||
|
const targetString = `${wsSecKey}${magicString}`;
|
||||||
|
const shasum = crypto.createHash('sha1');
|
||||||
|
shasum.update(targetString);
|
||||||
|
return shasum.digest('base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
const Util = {
|
||||||
|
lower_keys,
|
||||||
|
merge,
|
||||||
|
getUserHome,
|
||||||
|
contentType,
|
||||||
|
getAnyProxyPath,
|
||||||
|
getAnyProxyHome,
|
||||||
|
simpleRender,
|
||||||
|
filewalker,
|
||||||
|
contentLength,
|
||||||
|
freshRequire,
|
||||||
|
getHeaderFromRawHeaders,
|
||||||
|
getAllIpAddress,
|
||||||
|
getFreePort,
|
||||||
|
collectErrorLog,
|
||||||
|
isFunc,
|
||||||
|
isIpDomain,
|
||||||
|
getByteSize,
|
||||||
|
deleteFolderContentsRecursive,
|
||||||
|
genericWsSecAccept,
|
||||||
|
formatDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Util;
|
||||||
|
module.exports = Util;
|
||||||
|
// })();
|
10
package.json
10
package.json
@ -39,6 +39,7 @@
|
|||||||
"ws": "^5.1.0"
|
"ws": "^5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^8.10.21",
|
||||||
"antd": "^2.5.0",
|
"antd": "^2.5.0",
|
||||||
"autoprefixer": "^6.4.1",
|
"autoprefixer": "^6.4.1",
|
||||||
"babel-core": "^6.14.0",
|
"babel-core": "^6.14.0",
|
||||||
@ -60,6 +61,8 @@
|
|||||||
"eslint-plugin-react": "^7.4.0",
|
"eslint-plugin-react": "^7.4.0",
|
||||||
"extract-text-webpack-plugin": "^3.0.2",
|
"extract-text-webpack-plugin": "^3.0.2",
|
||||||
"file-loader": "^0.9.0",
|
"file-loader": "^0.9.0",
|
||||||
|
"gulp": "^3.9.1",
|
||||||
|
"gulp-typescript": "^5.0.0-alpha.3",
|
||||||
"https-proxy-agent": "^1.0.0",
|
"https-proxy-agent": "^1.0.0",
|
||||||
"jasmine": "^2.5.3",
|
"jasmine": "^2.5.3",
|
||||||
"koa": "^1.2.1",
|
"koa": "^1.2.1",
|
||||||
@ -85,12 +88,16 @@
|
|||||||
"stream-equal": "0.1.8",
|
"stream-equal": "0.1.8",
|
||||||
"style-loader": "^0.13.1",
|
"style-loader": "^0.13.1",
|
||||||
"svg-inline-loader": "^0.7.1",
|
"svg-inline-loader": "^0.7.1",
|
||||||
|
"typescript": "^2.9.2",
|
||||||
"url-loader": "^0.5.7",
|
"url-loader": "^0.5.7",
|
||||||
|
"vuepress": "^0.10.2",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"worker-loader": "^0.7.1"
|
"worker-loader": "^0.7.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublish": "npm run buildweb",
|
"prepublish": "npm run buildweb",
|
||||||
|
"build": "NODE_ENV=production && node gulpfile.js",
|
||||||
|
"dev": "NODE_ENV=test && node gulpfile.js",
|
||||||
"test": "node test.js",
|
"test": "node test.js",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"testserver": "node test/server/startServer.js",
|
"testserver": "node test/server/startServer.js",
|
||||||
@ -98,7 +105,8 @@
|
|||||||
"buildweb": "NODE_ENV=production webpack --config web/webpack.config.js --colors",
|
"buildweb": "NODE_ENV=production webpack --config web/webpack.config.js --colors",
|
||||||
"webserver": "NODE_ENV=test webpack --config web/webpack.config.js --colors --watch",
|
"webserver": "NODE_ENV=test webpack --config web/webpack.config.js --colors --watch",
|
||||||
"doc:serve": "node build_scripts/prebuild-doc.js && gitbook serve ./docs-src ./docs --log debug",
|
"doc:serve": "node build_scripts/prebuild-doc.js && gitbook serve ./docs-src ./docs --log debug",
|
||||||
"doc:build": "./build_scripts/build-doc-site.sh"
|
"doc:build": "./build_scripts/build-doc-site.sh",
|
||||||
|
"doc:dev": "node build_scripts/prebuild-doc.js && vuepress dev docs-src"
|
||||||
},
|
},
|
||||||
"pre-commit": [
|
"pre-commit": [
|
||||||
"lint"
|
"lint"
|
||||||
|
14
proxy.js
14
proxy.js
@ -4,14 +4,14 @@ const http = require('http'),
|
|||||||
https = require('https'),
|
https = require('https'),
|
||||||
async = require('async'),
|
async = require('async'),
|
||||||
color = require('colorful'),
|
color = require('colorful'),
|
||||||
certMgr = require('./lib/certMgr'),
|
certMgr = require('./dist/certMgr'),
|
||||||
Recorder = require('./lib/recorder'),
|
Recorder = require('./dist/recorder'),
|
||||||
logUtil = require('./lib/log'),
|
logUtil = require('./dist/log'),
|
||||||
util = require('./lib/util'),
|
util = require('./dist/util'),
|
||||||
events = require('events'),
|
events = require('events'),
|
||||||
co = require('co'),
|
co = require('co'),
|
||||||
WebInterface = require('./lib/webInterface'),
|
WebInterface = require('./dist/webInterface'),
|
||||||
wsServerMgr = require('./lib/wsServerMgr'),
|
wsServerMgr = require('./dist/wsServerMgr'),
|
||||||
ThrottleGroup = require('stream-throttle').ThrottleGroup;
|
ThrottleGroup = require('stream-throttle').ThrottleGroup;
|
||||||
|
|
||||||
// const memwatch = require('memwatch-next');
|
// const memwatch = require('memwatch-next');
|
||||||
@ -382,6 +382,6 @@ module.exports.ProxyServer = ProxyServer;
|
|||||||
module.exports.ProxyRecorder = Recorder;
|
module.exports.ProxyRecorder = Recorder;
|
||||||
module.exports.ProxyWebServer = WebInterface;
|
module.exports.ProxyWebServer = WebInterface;
|
||||||
module.exports.utils = {
|
module.exports.utils = {
|
||||||
systemProxyMgr: require('./lib/systemProxyMgr'),
|
systemProxyMgr: require('./dist/systemProxyMgr'),
|
||||||
certMgr,
|
certMgr,
|
||||||
};
|
};
|
||||||
|
22
tsconfig.json
Normal file
22
tsconfig.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOnSave": true,
|
||||||
|
"compilerOptions": {
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"target": "es5",
|
||||||
|
"module": "commonjs",
|
||||||
|
"baseUrl": "./lib",
|
||||||
|
"allowJs": true,
|
||||||
|
"lib": ["es6"],
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"outDir": "./dist"
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"./dist"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"./lib/*",
|
||||||
|
"./bin/*"
|
||||||
|
]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user