Skip to content

Commit d9fb5dd

Browse files
committed
Squashed 'vendor/whistle/' changes from 71c05db286..ce0b2be01d
ce0b2be01d docs: readme 9bba4a8e7c Update README.md 253656c975 feat: -p [IPv6]:port 7df5ce4158 docs: update ee4f8d0de3 refactor: refine code 5c85a33c35 style: build code 3438fba4f4 style: refine code fff38b79dc style: add ESC event 57d6e258f0 fix a typo in custom-certs.md 4e55aa0d46 Release v2.9.45 475a1600a7 refactor: refine code b333aaae10 feat: add copyText 5d13816d15 feat: lineProps://strictHtml lineProps://safeHtml 46ee88a312 feat: add copyText dc0dc17a79 Release v2.9.44 5a2ef34a22 fix: use querystring instead of qs eb68327455 Release v2.9.43 53bceb64d5 Release v2.9.43 b8bf964e50 feat: quickly create rules 51db455f44 feat: allow enable://capture to decode https from socks proxy 9313c899ba docs: mock e3cad6af92 Typo 87f81d1135 refactor: refine code c8123f6db2 Release v2.9.42 23e3e4a5ef style: refine interaction of delete button 4a8b58e72f style: refine composer 59909cb5f1 feat: hint the key of Values 159176baed Release v2.9.41 5922a3240d fix: network column settings 2c4c1cd3ec Release v2.9.40 fb309c2d31 docs: security 41a98b007a style: Expand All & Collapse All JSONTree 580f627fae feat: handle unhandledrejection b64b4f91fb feat: support early hints 41722a730d Release v2.9.39 e0b01a3f9e feat: show registry list b917dc609d refactor: refine code cfe37ffa61 feat: allow filter by process.env e06f396917 feat: highlight map local 332e32a48e style: search json view 1017a482e6 refactor: refine code 05a5048421 feat: save registry 0392c88c81 style: refine custom networ column 8b226554fb fix: filter request data by client ip 290f3e7b79 refactor: refine code 3c3279c15f Release v2.9.38 31fe7e689f feat: add ctx.getBuffer 44996de980 refactor: refine code f5be1651f7 refactor: allow custom encoding 9fbe31315f Release v2.9.38 18e85e7518 refactor: refine passThrough(...) 2aef63764b Release v2.9.37 a7f609cadf refactor: refine code ee2ca6b980 Release v2.9.36 231175418d feat: copy cell text 03e8ccf2e0 docs: style 7bba4a4237 refactor: refine code d4514a7a47 refactor: refine code 4ea290fe31 Relese v2.9.36 8f14bde979 Relese v2.9.36 6767b3a57d feat: allow to custom web worker by plugin ad54686d7f Release v2.9.36 159e2b7cd3 feat: custom column of network table by plugin 0b1d2ffc53 feat: delete://resC.xxx 490f4f0316 docs: delete://resC.xxx 50b65a5abf chore: ignore /biz/webui/htdocs/js/decode.js 1d383f9d30 feat: allow plugin to custom webWorker in the WebUI git-subtree-dir: vendor/whistle git-subtree-split: ce0b2be01d4b1d7685065324c51a890cfab3e1ae
1 parent c3b86d5 commit d9fb5dd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+3966
-1250
lines changed

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ assets/launcher
6767
CHANGELOG.md
6868
Dockerfile
6969
/README-zh_CN.md
70+
/biz/webui/htdocs/js/decode.js
7071

7172

7273
# Coveralls

CHANGELOG.md

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,88 @@
1+
# v2.9.45
2+
1. feat: 插件界面提供 `copyText` 方法
3+
2. feat: 支持 `lineProps://strictHtml``lineProsy://safeHtml` 只对当前行的规则生效
4+
3. style: Mock Dialog 支持直接保存 Value
5+
6+
# v2.9.44
7+
1. fix: 解决 `qs` 模块不存在问题
8+
9+
# v2.9.43
10+
1. feat: 允许通过 `enable://capture` 解析 socks 代理的 HTTPS 请求
11+
2. feat: 支持通过 Network 右键菜单 `Mock` 按钮快速创建规则:http://wproxy.org/whistle/webui/mock.html
12+
13+
# v2.9.42
14+
1. style: 支持自动提示 Values 的 Key
15+
2. style: Composer 的 History 选项改成箭头按钮
16+
3. feat: 支持批量删除 Rules & Values
17+
18+
# v2.9.41
19+
1. fix: Network Settings 列设置刷新失效问题
20+
2. style: WebForm 支持显示 JSON 对象
21+
3. style: Preview 优先显示 JSON View
22+
23+
# v2.9.40
24+
1. refactor: `Network / Tools / Console & Server` 支持捕获 `unhandledrejection` 的错误信息,且`Console & Server` 最大缓存日志条数调整为 230
25+
2. feat: 支持 earlyHints
26+
3. feat: JSONView 右键支持 `Expand All``Collapse All`
27+
28+
# v2.9.39
29+
1. feat: JSON View 支持搜索
30+
2. feat: 自动记录用过的 npm registry
31+
3. feat: 模板字符串支持 `${env.xxx}` 获取环境变量 `xxx` 对应的值
32+
4. feat: 支持通过环境变量 `excludeFilter://env.xxx=pattern`
33+
5. style: 匹配 map local 的抓包字体颜色显示成黑色
34+
35+
# v2.9.38
36+
1. refactor: `req.passThrough(handleReq?, handleRes?)` 提供更多功能
37+
``` js
38+
req.passThrough(function(rawBuffer, next, ctx) {
39+
ctx.getText((err, text) => {
40+
console.log(err, text);
41+
}, encoding?); // 自动 unzip 并转成字符串,字符编码 encoding 可选
42+
ctx.getJson((err, text) => {
43+
console.log(err, text);
44+
next({
45+
body: rawBuffer,
46+
rules: '* file://(abc)'
47+
});
48+
}, encoding?); // 自动 unzip 并转成json
49+
}, function(rawBuffer, next, ctx) {
50+
ctx.getText((err, text) => {
51+
console.log(err, text);
52+
}, encoding?); // 自动 unzip 并转成字符串,字符编码 encoding 可选
53+
ctx.getJson((err, text) => {
54+
console.log(err, text);
55+
next({
56+
body: rawBuffer,
57+
rules: '* file://(abc)'
58+
});
59+
}, encoding?); // 自动 unzip 并转成json
60+
});
61+
```
62+
63+
# v2.9.37
64+
1. fix: `resCookies://` 设置失败问题
65+
66+
# v2.9.36
67+
1. feat: 支持通过插件的配置 `whistleConfig.networkColumn: { title: 'xxx', key: 'xxx', width: 90 }` 扩展 Network 表格的列
68+
2. feat: 支持通过插件的配置 `whistleConfig.webWorker: path` 自定义脚本在界面中执行,可以结合自定义列的功能实现查看接口返回错误码(后续补例子)
69+
3. feat: 插件处理非 WebSocket 及 Socket 请求的 `req.passThrough(handleReq?, handleRes?)` 支持传人两个方法(可选)获取请求或响应内容并返回请求内容及规则
70+
``` js
71+
req.passThrough(function(buffer, next) {
72+
next({
73+
body: buffer,
74+
rules: '* file://(abc)'
75+
});
76+
}, function(buffer, next) {
77+
next({
78+
body: buffer,
79+
rules: '* resCookies://x-test=123'
80+
});
81+
});
82+
```
83+
4. refactor: `delete://resCookie.xxx``delete://cookie.xxx` 可以删除浏览器中的 cookie(只支持 `path: /``Domain=父代` 或本域名)
84+
5. style: Network 右键菜单支持 `Copy Cell Text`
85+
186
# v2.9.35
287
1. feat: Netwok 的 table 表头支持通过右键调整列宽度
388
2. feat: Network / Settings 自定义列支持设置关联的 `Data Key`,可以在界面获取抓包数据,无需配置 `style`
@@ -611,7 +696,7 @@
611696
# v2.4.7
612697
1. fix: https://github.com/avwo/whistle/pull/383
613698
2. refactor: HTTP/2 支持 delete 请求携带 body
614-
3. style: `HTTPS > View custom certs info` 支持高亮显示过期证书,且支持 copy 证书安装路径
699+
3. style: `HTTPS > View all custom certificates` 支持高亮显示过期证书,且支持 copy 证书安装路径
615700
3. fix: 设置 `reqBody://(xxxx) method://post` 无法同时生效问题
616701

617702
# v2.4.6
@@ -845,7 +930,7 @@
845930

846931
# v1.16.0
847932
1. feat: 支持插件通过 `options.getRules(cb), options.getValues(cb), options.getCustomCertsInfo(cb)`,分别获取插件Rules、Values、自定义证书信息
848-
2. style: HTTPS菜单的对话框添加 `View custom certs info` 按钮,用于查看自定义证书状态(是否过期等)
933+
2. style: HTTPS菜单的对话框添加 `View all custom certificates` 按钮,用于查看自定义证书状态(是否过期等)
849934
3. fix: WebSocket请求无法设置 `reqDelay://msNum` 的问题
850935

851936
# v1.15.16

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
# whistle
88
[![NPM version](https://img.shields.io/npm/v/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
99
[![node version](https://img.shields.io/badge/node.js-%3E=_8-green.svg?style=flat-square)](http://nodejs.org/download/)
10-
[![build status](https://img.shields.io/travis/avwo/whistle.svg?style=flat-square)](https://travis-ci.org/avwo/whistle)
1110
[![Test coverage](https://codecov.io/gh/avwo/whistle/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/avwo/whistle)
1211
[![npm download](https://img.shields.io/npm/dm/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
1312
[![NPM count](https://img.shields.io/npm/dt/whistle.svg?style=flat-square)](https://www.npmjs.com/package/whistle)
@@ -35,6 +34,8 @@ Whistle 是基于 Node 实现的跨平台抓包调试工具,其主要特点:
3534
npm i -g whistle && w2 start --init
3635
```
3736
> 上述命令会先全局安装 Whistle 的 npm 包后,启动 Whistle 并设置系统全局代理,以及安装系统根证书,目前一键安装只支持 Mac & Windows 系统,其它系统按照下面 **手动安装** 的方式操作。
37+
>
38+
> 如果安装过程时报错 `Bad CPU type in executable`,在命令执行 `arch -x86_64 zsh` 再重新执行一键安装命令。
3839
3. 一键安装过程中注意事项:
3940
* Mac 需要两次输入开机密码或指纹验证
4041
<p>
@@ -68,6 +69,10 @@ Whistle 是基于 Node 实现的跨平台抓包调试工具,其主要特点:
6869
### 详细用法参见:[Whistle 帮助文档](https://wproxy.org/whistle/quickstart.html)
6970

7071
# 通过 SwitchyOmega 设置代理
72+
### 安装 SwitchyOmega
73+
打开 Chrome 扩展商店进行安装 https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif
74+
75+
### 配置 SwitchyOmega
7176
全局代理如果会影响到某些客户端的请求(客户端设置了 ssl pinning),也可以使用 Chrome 插件设置代理(只对 Chrome 生效):
7277
> 可以通过 `w2 proxy off` 关闭全局代理
7378
@@ -78,6 +83,9 @@ Whistle 是基于 Node 实现的跨平台抓包调试工具,其主要特点:
7883

7984
<img width="180" alt="image" src="https://user-images.githubusercontent.com/11450939/173984519-143615b2-2a99-4486-a22a-fec71fe00423.png">
8085

86+
# 安全设置
87+
1. 通过启动参数给管理界面设置用户名密码:`w2 restart -n yourusername -w yourpassword`
88+
2. 通过插件给经过代理的请求设置用户名密码:https://github.com/whistle-plugins/whistle.proxyauth
8189

8290
# License
8391
[MIT](./LICENSE)

assets/js/log.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,4 +387,15 @@
387387
setTimeout(attachOnError, 600);
388388
};
389389
attachOnError();
390+
391+
if (typeof window.addEventListener === 'function') {
392+
window.addEventListener('unhandledrejection', function(e) {
393+
var reason = 'UnhandledRejection';
394+
if (e) {
395+
e = e.reason || stringifyObj(e) || String(e);
396+
reason += (/^[\w.-]*:/.test(e) ? ' ' : ': ') + e;
397+
}
398+
wConsole.error(reason);
399+
});
400+
}
390401
})();

assets/js/worker.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
var exports = {};
3+
var module = { exports: exports };
4+
5+
;(function() {
6+
var self = null;
7+
try {
8+
(function() {
9+
/*sourcecode*/
10+
})();
11+
} catch (e) {
12+
setTimeout(function() {
13+
throw e;
14+
}, 20);
15+
}
16+
})();
17+
18+
;(function() {
19+
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){try{return i(e)}catch(t){}}var o,i=n(1).toByteArray,a=n(2).Base64.decode,s=n(3);if(self.TextDecoder)try{o=new self.TextDecoder("GB18030")}catch(l){}self.getText=function(e){var t=e&&r(e);if(!t)return"";if(!s(t))try{if(o)return o.decode(t)}catch(n){}try{return a(e)}catch(n){}return""}},function(e,t){"use strict";function n(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");-1===n&&(n=t);var r=n===t?0:4-n%4;return[n,r]}function r(e){var t=n(e),r=t[0],o=t[1];return 3*(r+o)/4-o}function o(e,t,n){return 3*(t+n)/4-n}function i(e){var t,r,i=n(e),a=i[0],s=i[1],l=new d(o(e,a,s)),c=0,p=s>0?a-4:a;for(r=0;p>r;r+=4)t=u[e.charCodeAt(r)]<<18|u[e.charCodeAt(r+1)]<<12|u[e.charCodeAt(r+2)]<<6|u[e.charCodeAt(r+3)],l[c++]=t>>16&255,l[c++]=t>>8&255,l[c++]=255&t;return 2===s&&(t=u[e.charCodeAt(r)]<<2|u[e.charCodeAt(r+1)]>>4,l[c++]=255&t),1===s&&(t=u[e.charCodeAt(r)]<<10|u[e.charCodeAt(r+1)]<<4|u[e.charCodeAt(r+2)]>>2,l[c++]=t>>8&255,l[c++]=255&t),l}function a(e){return c[e>>18&63]+c[e>>12&63]+c[e>>6&63]+c[63&e]}function s(e,t,n){for(var r,o=[],i=t;n>i;i+=3)r=(e[i]<<16&16711680)+(e[i+1]<<8&65280)+(255&e[i+2]),o.push(a(r));return o.join("")}function l(e){for(var t,n=e.length,r=n%3,o=[],i=16383,a=0,l=n-r;l>a;a+=i)o.push(s(e,a,a+i>l?l:a+i));return 1===r?(t=e[n-1],o.push(c[t>>2]+c[t<<4&63]+"==")):2===r&&(t=(e[n-2]<<8)+e[n-1],o.push(c[t>>10]+c[t>>4&63]+c[t<<2&63]+"=")),o.join("")}t.byteLength=r,t.toByteArray=i,t.fromByteArray=l;for(var c=[],u=[],d="undefined"!=typeof Uint8Array?Uint8Array:Array,p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",f=0,g=p.length;g>f;++f)c[f]=p[f],u[p.charCodeAt(f)]=f;u["-".charCodeAt(0)]=62,u["_".charCodeAt(0)]=63},function(e,t,n){var r,o;(function(n){!function(t,n){e.exports=n(t)}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof n?n:this,function(n){"use strict";n=n||{};var i,a=n.Base64,s="2.6.4",l="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=function(e){for(var t={},n=0,r=e.length;r>n;n++)t[e.charAt(n)]=n;return t}(l),u=String.fromCharCode,d=function(e){if(e.length<2){var t=e.charCodeAt(0);return 128>t?e:2048>t?u(192|t>>>6)+u(128|63&t):u(224|t>>>12&15)+u(128|t>>>6&63)+u(128|63&t)}var t=65536+1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320);return u(240|t>>>18&7)+u(128|t>>>12&63)+u(128|t>>>6&63)+u(128|63&t)},p=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,f=function(e){return e.replace(p,d)},g=function(e){var t=[0,2,1][e.length%3],n=e.charCodeAt(0)<<16|(e.length>1?e.charCodeAt(1):0)<<8|(e.length>2?e.charCodeAt(2):0),r=[l.charAt(n>>>18),l.charAt(n>>>12&63),t>=2?"=":l.charAt(n>>>6&63),t>=1?"=":l.charAt(63&n)];return r.join("")},h=n.btoa&&"function"==typeof n.btoa?function(e){return n.btoa(e)}:function(e){if(e.match(/[^\x00-\xFF]/))throw new RangeError("The string contains invalid characters.");return e.replace(/[\s\S]{1,3}/g,g)},m=function(e){return h(f(String(e)))},A=function(e){return e.replace(/[+\/]/g,function(e){return"+"==e?"-":"_"}).replace(/=/g,"")},M=function(e,t){return t?A(m(e)):m(e)},w=function(e){return M(e,!0)};n.Uint8Array&&(i=function(e,t){for(var n="",r=0,o=e.length;o>r;r+=3){var i=e[r],a=e[r+1],s=e[r+2],c=i<<16|a<<8|s;n+=l.charAt(c>>>18)+l.charAt(c>>>12&63)+("undefined"!=typeof a?l.charAt(c>>>6&63):"=")+("undefined"!=typeof s?l.charAt(63&c):"=")}return t?A(n):n});var b,y=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g,v=function(e){switch(e.length){case 4:var t=(7&e.charCodeAt(0))<<18|(63&e.charCodeAt(1))<<12|(63&e.charCodeAt(2))<<6|63&e.charCodeAt(3),n=t-65536;return u((n>>>10)+55296)+u((1023&n)+56320);case 3:return u((15&e.charCodeAt(0))<<12|(63&e.charCodeAt(1))<<6|63&e.charCodeAt(2));default:return u((31&e.charCodeAt(0))<<6|63&e.charCodeAt(1))}},T=function(e){return e.replace(y,v)},x=function(e){var t=e.length,n=t%4,r=(t>0?c[e.charAt(0)]<<18:0)|(t>1?c[e.charAt(1)]<<12:0)|(t>2?c[e.charAt(2)]<<6:0)|(t>3?c[e.charAt(3)]:0),o=[u(r>>>16),u(r>>>8&255),u(255&r)];return o.length-=[0,0,2,1][n],o.join("")},N=n.atob&&"function"==typeof n.atob?function(e){return n.atob(e)}:function(e){return e.replace(/\S{1,4}/g,x)},C=function(e){return N(String(e).replace(/[^A-Za-z0-9\+\/]/g,""))},I=function(e){return T(N(e))},E=function(e){return String(e).replace(/[-_]/g,function(e){return"-"==e?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,"")},D=function(e){return I(E(e))};n.Uint8Array&&(b=function(e){return Uint8Array.from(C(E(e)),function(e){return e.charCodeAt(0)})});var L=function(){var e=n.Base64;return n.Base64=a,e};if(n.Base64={VERSION:s,atob:C,btoa:h,fromBase64:D,toBase64:M,utob:f,encode:M,encodeURI:w,btou:T,decode:D,noConflict:L,fromUint8Array:i,toUint8Array:b},"function"==typeof Object.defineProperty){var S=function(e){return{value:e,enumerable:!1,writable:!0,configurable:!0}};n.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",S(function(){return D(this)})),Object.defineProperty(String.prototype,"toBase64",S(function(e){return M(this,e)})),Object.defineProperty(String.prototype,"toBase64URI",S(function(){return M(this,!0)}))}}return n.Meteor&&(Base64=n.Base64),"undefined"!=typeof e&&e.exports?e.exports.Base64=n.Base64:(r=[],o=function(){return n.Base64}.apply(t,r),!(void 0!==o&&(e.exports=o))),{Base64:n.Base64}})}).call(t,function(){return this}())},function(e,t){"use strict";function n(e,t){t=t||0;for(var n=Math.min(e.length,r);n>t;t++){var o=e[t];if(!(9==o||10==o||13==o||o>=32&&127>=o)){++t;var i=e[t];if(o>=194&&223>=o){if(i>=128&&191>=i)continue;return!i}++t;var a=e[t];if(224==o){if(i>=160&&191>=i&&a>=128&&191>=a)continue;return!a}if(o>=225&&236>=o||238==o||239==o){if(i>=128&&191>=i&&a>=128&&191>=a)continue;return!a}if(237==o){if(i>=128&&159>=i&&a>=128&&191>=a)continue;return!a}++t;var s=e[t];if(240==o){if(i>=144&&191>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}if(o>=241&&243>=o){if(i>=128&&191>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}if(244==o){if(i>=128&&143>=i&&a>=128&&191>=a&&s>=128&&191>=s)continue;return!s}return!1}}return!0}var r=32768;e.exports=function(e){return n(e)?!0:0===e[0]&&n(e,5)}}]);
20+
21+
var getText = function(obj) {
22+
return self.getText(obj.base64);
23+
};
24+
var parseJson = function(str) {
25+
if (!str || !/^(?:\{[\s\S]*\}|\[[\s\S]*\])$/) {
26+
return;
27+
}
28+
try {
29+
return JSON.parse(str);
30+
} catch (e) {}
31+
};
32+
33+
var defineProps = function (obj) {
34+
if (Object.defineProperties) {
35+
var body, json;
36+
var getBody = function () {
37+
if (body === undefined) {
38+
body = getText(obj);
39+
}
40+
return body;
41+
}
42+
Object.defineProperties(obj, {
43+
body: { get: getBody },
44+
json: {
45+
get: function () {
46+
if (json === undefined) {
47+
json = parseJson(getBody()) || null;
48+
}
49+
return json;
50+
}
51+
}
52+
});
53+
} else {
54+
obj.body = getText(obj) || '';
55+
obj.json = parseJson(obj) || null;
56+
}
57+
return obj;
58+
};
59+
var handle = module.exports;
60+
if (typeof handle !== 'function') {
61+
handle = null;
62+
}
63+
64+
self.onmessage = function(e) {
65+
var data = handle && e.data;
66+
var id = data && data.id;
67+
if (!id) {
68+
return;
69+
}
70+
data.res = defineProps(data.res || {});
71+
data.req = defineProps(data.req || {});
72+
data.req.headers = data.req.headers || {};
73+
data.res.headers = data.res.headers || {};
74+
handle(data, function(result) {
75+
result && self.postMessage({
76+
id: id,
77+
data: result
78+
});
79+
});
80+
};
81+
})();
82+
83+
self.postMessage(true);
84+

assets/menu.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
Object.keys(options.msgBox).forEach(function(name) {
158158
toast[name] = options.msgBox[name];
159159
});
160+
whistleBridge.copyText = options.copyText;
160161
whistleBridge.pageId = options.pageId;
161162
whistleBridge.compose = options.compose;
162163
whistleBridge.decodeBase64 = options.decodeBase64;

bin/plugin.js

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ var getWhistlePath = commonUtil.getWhistlePath;
1010
var REMOTE_URL_RE = commonUtil.REMOTE_URL_RE;
1111
var CMD_SUFFIX = process.platform === 'win32' ? '.cmd' : '';
1212
var CUSTOM_PLUGIN_PATH = path.join(getWhistlePath(), 'custom_plugins');
13+
var DEFAULT_PATH = commonUtil.getDefaultWhistlePath();
14+
var REGISTRY_LIST = path.join(DEFAULT_PATH, '.registry.list');
1315
var PACKAGE_JSON = '{"repository":"https://github.com/avwo/whistle","license":"MIT"}';
1416
var LICENSE = 'Copyright (c) 2019 avwo';
1517
var RESP_URL = 'https://github.com/avwo/whistle';
1618
var WHISTLE_PLUGIN_RE = /^((?:@[\w-]+\/)?whistle\.[a-z\d_-]+)(?:\@([\w.^~*-]*))?$/;
19+
var MAX_REG_COUNT = 100;
1720

1821
function getInstallPath(name, dir) {
1922
return path.join(dir || CUSTOM_PLUGIN_PATH, name);
@@ -104,7 +107,8 @@ function install(cmd, name, argv, ver, pluginsCache, callback) {
104107
callback();
105108
} else {
106109
if (!isPkg) {
107-
var deps = fse.readJsonSync(path.join(installPath, 'package.json')).dependencies;
110+
var deps = commonUtil.readJsonSync(path.join(installPath, 'package.json'));
111+
deps = deps && deps.dependencies;
108112
name = deps && getPluginNameFormDeps(deps);
109113
}
110114
if (!name) {
@@ -136,23 +140,26 @@ function install(cmd, name, argv, ver, pluginsCache, callback) {
136140
});
137141
}
138142

139-
function readJson(pkgPath) {
140-
try {
141-
return fse.readJsonSync(pkgPath);
142-
} catch (e) {
143-
try {
144-
return fse.readJsonSync(pkgPath);
145-
} catch (e) {}
143+
function getRegistry(argv) {
144+
for (var i = 0, len = argv.length; i < len; i++) {
145+
var name = argv[i];
146+
if (name === '--registry') {
147+
return commonUtil.getRegistry(argv[i + 1]);
148+
}
149+
if (/^--registry=(.+)/.test(name)) {
150+
return commonUtil.getRegistry(RegExp.$1);
151+
}
146152
}
147153
}
148154

149155
function installPlugins(cmd, plugins, argv, pluginsCache, deep) {
150156
deep = deep || 0;
151157
var count = 0;
152158
var peerPlugins = [];
159+
var registry = getRegistry(argv);
153160
var callback = function(pkgPath) {
154161
if (pkgPath) {
155-
var pkg = readJson(pkgPath) || {};
162+
var pkg = commonUtil.readJsonSync(pkgPath) || {};
156163
var list = pkg.whistleConfig && (pkg.whistleConfig.peerPluginList || pkg.whistleConfig.peerPlugins);
157164
if (Array.isArray(list) && list.length < 16) {
158165
list.forEach(function(name) {
@@ -165,6 +172,32 @@ function installPlugins(cmd, plugins, argv, pluginsCache, deep) {
165172
}
166173
});
167174
}
175+
if (registry) {
176+
try {
177+
fse.ensureDirSync(DEFAULT_PATH);
178+
} catch (e) {}
179+
var regList = commonUtil.readJsonSync(REGISTRY_LIST);
180+
var result = [registry];
181+
registry = null;
182+
if (Array.isArray(regList)) {
183+
regList.forEach(function(url) {
184+
url = commonUtil.getRegistry(url);
185+
if (url && result.indexOf(url) === -1) {
186+
result.push(url);
187+
}
188+
});
189+
}
190+
try {
191+
if (REGISTRY_LIST.length > MAX_REG_COUNT) {
192+
REGISTRY_LIST = REGISTRY_LIST.slice(0, MAX_REG_COUNT);
193+
}
194+
fse.writeJsonSync(REGISTRY_LIST, result);
195+
} catch (e) {
196+
try {
197+
fse.writeJsonSync(REGISTRY_LIST, result);
198+
} catch (e) {}
199+
}
200+
}
168201
}
169202
if (--count <= 0 && deep < 16) {
170203
peerPlugins = peerPlugins.filter(function(name) {

0 commit comments

Comments
 (0)