@vbarbarosh/node-helpers 3.77.0 → 3.78.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/browser.js +1 -1
- package/dist/index.html +8 -16
- package/package.json +5 -5
- package/src/crypto_decrypt_aes256.js +43 -7
- package/src/crypto_decrypt_aes256.md +15 -10
- package/src/crypto_encrypt_aes256.js +23 -9
- package/src/crypto_encrypt_aes256.md +20 -10
- package/src/escape_content_disposition.js +8 -2
- package/src/escape_content_disposition.md +10 -2
- package/src/escape_content_disposition_utf8.js +11 -0
- package/src/escape_content_disposition_utf8.md +11 -0
- package/src/fastdl.js +7 -1
- package/src/fastdl.md +5 -0
- package/src/format_date_fs.js +8 -0
- package/src/format_error_report.js +102 -4
- package/src/format_error_report.md +47 -0
- package/src/http_get_stream_range.js +5 -1
- package/src/http_get_stream_range.md +2 -1
- package/src/http_stream_range.js +14 -1
- package/src/http_stream_range.md +3 -1
- package/src/make_progress.js +16 -9
- package/src/make_progress.md +7 -4
- package/src/pgid_exists.js +5 -0
- package/src/pgid_exists.md +4 -0
- package/src/pgid_kill_grace.js +5 -0
- package/src/pgid_kill_grace.md +3 -0
- package/src/pid_exists.js +5 -0
- package/src/pid_exists.md +4 -0
- package/src/pid_kill_grace.js +5 -0
- package/src/pid_kill_grace.md +3 -0
- package/src/redis_poll_zshift_callback_rpush.js +4 -0
- package/src/redis_poll_zshift_callback_rpush.md +4 -3
- package/src/redis_poll_zshift_spawn_rpush.js +4 -0
- package/src/redis_poll_zshift_spawn_rpush.md +4 -3
- package/src/shell.js +1 -1
- package/src/shell.md +2 -1
- package/src/shell_json.js +1 -1
- package/src/shell_json.md +2 -1
- package/src/stream_strpbrk.js +9 -1
- package/src/stream_xml_analyze.js +6 -1
- package/src/stream_xml_parse.js +11 -3
- package/src/urlmod.md +3 -1
- package/src/urlparts.js +111 -15
- package/src/urlparts.md +44 -12
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ npm install @vbarbarosh/node-helpers
|
|
|
20
20
|
A subset of `@vbarbarosh/node-helpers` is available for browser:
|
|
21
21
|
|
|
22
22
|
```html
|
|
23
|
-
<script src="https://unpkg.com/@vbarbarosh/node-helpers@3.
|
|
23
|
+
<script src="https://unpkg.com/@vbarbarosh/node-helpers@3.78.1/dist/browser.js"></script>
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
⚠️ All browser functions are exposed globally.
|
package/dist/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var t={932(t){t.exports=function(t){return"number"==typeof t&&isFinite(t)}},5392(t,e,n){const r=n(932);t.exports=function(t,e){return r(t)&&t>e}},4106(t,e){function n(t,e){var n=[],r=[];return null==e&&(e=function(t,e){return n[0]===e?"[Circular ~]":"[Circular ~."+r.slice(0,n.indexOf(e)).join(".")+"]"}),function(o,s){if(n.length>0){var u=n.indexOf(this);~u?n.splice(u+1):n.push(this),~u?r.splice(u,1/0,o):r.push(o),~n.indexOf(s)&&(s=e.call(this,o,s))}else n.push(s);return null==t?s:t.call(this,o,s)}}(t.exports=function(t,e,r,o){return JSON.stringify(t,n(e,o),r)}).getSerialize=n},6083(t){t.exports=function(t=[],e=1){if(e<1)throw new Error("Limit value should be at least 1");const n=[];for(let r=0,o=t.length;r<o;r+=e)n.push(t.slice(r,r+e));return n}},2458(t,e,n){const r=n(7727);t.exports=function(t=[],e=1,n=1){const o=r(1,e,Math.floor(t.length/n)),s=Math.floor(t.length/o);let u=t.length%o;const c=[];for(let e=0;e<t.length;){const n=s+(u?1:0);c.push(t.slice(e,e+n)),e+=n,u&&u--}return c}},353(t,e,n){const r=n(4476),o=1e-5;t.exports=function(t,e){const n=Math.floor(t*e);if(n<=1)return[0];const s=[];for(let e=0;e<n;++e)s.push(r(e/(n-1)*(t-o),o));return s}},6372(t,e,n){const r=n(6785);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),0)}},3537(t){t.exports=function(t,e){const n=new Map;return t.forEach(function(t){const r=e(t);n.has(r)||n.set(r,{key:r,items:[]}),n.get(r).items.push(t)}),n.values().toArray()}},2976(t){t.exports=function(t,e){const n={};return t.forEach(function(t){const r=e(t);n[r]=n[r]||{key:r,items:[]},n[r].items.push(t)}),n}},2166(t,e,n){const r=n(956);t.exports=function(t,e=r){const n={};return t.forEach(t=>n[e(t)]=t),n}},7866(t,e,n){const r=n(7347);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),1)}},6772(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o<r)&&(s=!0,o=r,n=t)}),n}},42(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o>r)&&(s=!0,o=r,n=t)}),n}},3685(t){t.exports=function t(e,n=e.length){if(n!==e.length)return function(e,n){if(0===n)return[[]];if(e.length<n)return[];const r=[];for(let o=0;o<e.length;o++){const s=e.slice(0,o).concat(e.slice(o+1));for(const u of t(s,n-1))r.push([e[o],...u])}return r}(e,n);let r,o,s=(e=e.slice()).length,u=[e.slice()],c=new Array(s).fill(0),a=1;for(;a<s;)c[a]<a?(r=a%2&&c[a],o=e[a],e[a]=e[r],e[r]=o,++c[a],a=1,u.push(e.slice())):(c[a]=0,++a);return u}},4943(t){t.exports=function(t){for(let e=t.length;--e>0;){const n=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[n],t[n]=r}return t}},2356(t,e,n){const r=n(8310),o=n(4332);t.exports=function(t,e,n=r){const s=new Map;return t.sort(function(t,r){if(!s.has(t)){const n=e(t);s.set(t,Array.isArray(n)?n:[n])}if(!s.has(r)){const t=e(r);s.set(r,Array.isArray(t)?t:[t])}return o(s.get(t),s.get(r),n)})}},5181(t,e,n){const r=n(8310);t.exports=function(t,e,n,o=r){const s=Object.create(null);return n.forEach((t,e)=>s[t]=e+1),t.sort(function(t,n){const r=s[e(t)],u=s[e(n)];return r&&u?r-u:r?-1:u?1:o(t,n)})}},453(t){t.exports=function(t,e=Number){let n=0;return t.forEach(function(t){n+=e(t)}),n}},3523(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=new Set;return t.filter(function(t){const r=e(t);return!n.has(r)&&(n.add(r),!0)})}},6382(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=[],o=new Set;for(let r=t.length;--r>=0;){const s=t[r],u=e(s);o.has(u)||(o.add(u),n.push(s))}return n.reverse()}},7727(t){t.exports=function(t,e,n){return Math.max(t,Math.min(e,n))}},9870(t){t.exports=function(t,e){return t.setHours(t.getHours()+e),t}},5799(t){t.exports=function(t,e){return t.setMilliseconds(t.getMilliseconds()+e),t}},3160(t){t.exports=function(t,e){return t.setMinutes(t.getMinutes()+e),t}},1570(t){t.exports=function(t,e){if(!e)return t;const n=t.getDate();return t.setMonth(t.getMonth()+e),t.getDate()!==n&&t.setDate(0),t}},9296(t){t.exports=function(t,e){return t.setSeconds(t.getSeconds()+e),t}},5488(t){t.exports=function(t,e){return Math.floor((t.getTime()-e.getTime())/1e3)}},3752(t){t.exports=function(t){const e=t.getFullYear();return e%4==0&&e%100!=0||e%400==0}},3150(t){t.exports=function(t){return t=Math.trunc(Math.abs(t)),[Math.floor(t/36e5),Math.floor(t%36e5/6e4),Math.floor(t%6e4/1e3),t%1e3]}},2806(t){t.exports=function(t,e){return t.getTime()-e.getTime()}},8310(t,e,n){const r=n(7668);t.exports=function(t,e){return"string"==typeof t&&"string"==typeof e?r(t,e):t<e?-1:t>e?1:0}},2092(t,e,n){const r=n(8310);t.exports=function(t,e){return r(e,t)}},3553(t){function e(t){return"-"===t[0]?(t=t.slice(1),function(e,r){return n(r[t],e[t])}):function(e,r){return n(e[t],r[t])}}function n(t,e){return"string"==typeof t&&"string"==typeof e?t.localeCompare(e):t-e}t.exports=function(t){const n=t.map(e);switch(n.length){case 0:return()=>0;case 1:return n[0];case 2:return function(t,e){return n[0](t,e)||n[1](t,e)};case 3:return function(t,e){return n[0](t,e)||n[1](t,e)||n[2](t,e)};default:return function(t,e){for(let r=0;r<n.length;++r){const o=n[r](t,e);if(o)return o}return 0}}}},3129(t){t.exports=function(t,e){return t-e}},4332(t,e,n){const r=n(8310);t.exports=function(t,e,n=r){const o=Math.min(t.length,e.length);for(let r=0;r<o;++r){const o=n(t[r],e[r]);if(o)return o}return 0}},3106(t){t.exports=function(t,e){return t<e?-1:t>e?1:0}},2271(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"base"})}},4457(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"variant"})}},7668(t){function e(t,e){const r=t.replace(/^0+/,""),o=e.replace(/^0+/,"");return r.length-o.length||n(r,o)||t.length-e.length}function n(t,e){return t<e?-1:t>e?1:0}t.exports=function(t,r){const o=t.match(/\d+|\D+/g)||[],s=r.match(/\d+|\D+/g)||[],u=Math.min(o.length,s.length);for(let t=0;t<u;++t){const r=o[t][0]<="9"&&s[t][0]<="9"&&o[t][0]>="0"&&s[t][0]>="0"?e(o[t],s[t]):n(o[t],s[t]);if(r)return r}return o.length-s.length}},4385(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})}},8951(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"variant"})}},4734(t,e,n){const r=n(8310),o=n(2092),s=n(956),u=Symbol("fcmpx.missing");function c(t){const{read:e,fcmp:n}=a(t);return function(t,r){return n(e(t),e(r))}}function a(t){if("function"==typeof t)return{read:i(t),fcmp:f(r)};if("string"==typeof t){const e=t.startsWith("-");return{read:i(e?t.slice(1):t),fcmp:f(e?o:r)}}const e=t.fcmp,n=i(t.read),s=f(t.desc?e?(t,n)=>e(n,t):o:e??r);if(Array.isArray(t.top)){const e=new Map(t.top.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??e.size,fcmp:s}}if(Array.isArray(t.bottom)){const e=new Map(t.bottom.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??-1,fcmp:s}}return{read:n,fcmp:s}}function i(t){if(void 0===t||""===t||"."===t)return s;if("function"==typeof t)return function(e){return t(e)??u};if("string"==typeof t){const e=t.split("."),[n,r,o,s,c]=e;switch(e.length){case 1:return t=>t?.[n]??u;case 2:return t=>t?.[n]?.[r]??u;case 3:return t=>t?.[n]?.[r]?.[o]??u;case 4:return t=>t?.[n]?.[r]?.[o]?.[s]??u;case 5:return t=>t?.[n]?.[r]?.[o]?.[s]?.[c]??u;default:return t=>e.reduce((t,e)=>t?.[e],t)??u}}return e=>e?.[t]??u}function f(t){return function(e,n){return e===u?n===u?0:1:n===u?-1:t(e,n)}}t.exports=function t(e){if("string"==typeof e)return e.includes(",")?t(e.split(",")):c(e);if(!Array.isArray(e))return c(e);const n=e.map(a);return function(t,e){const r=n.map(e=>e.read(t)),o=n.map(t=>t.read(e));for(let t=0;t<n.length;++t){const e=n[t].fcmp(r[t],o[t]);if(e)return e}return 0}}},7960(t){function e(t){let e,n,r;return e=t.replaceAll("^",""),n=e.length!==t.length,e=(t=e).replaceAll("$",""),r=e.length!==t.length,e=(t=e).replaceAll("!",""),(t.length-e.length)%2?n&&r?t=>!(t.startsWith(e)&&t.endsWith(e)):n?t=>!t.startsWith(e):r?t=>!t.endsWith(e):t=>!t.includes(e):n&&r?t=>t.startsWith(e)&&t.endsWith(e):n?t=>t.startsWith(e):r?t=>t.endsWith(e):t=>t.includes(e)}t.exports=function(t){let n,r,o,s;const u=function(t){return t.split("/").filter(t=>t).map(e)}(t);switch(u.length){case 0:return()=>!0;case 1:return u[0];case 2:return[n,r]=u,t=>n(t)&&r(t);case 3:return[n,r,o]=u,t=>n(t)&&r(t)&&o(t);case 4:return[n,r,o,s]=u,t=>n(t)&&r(t)&&o(t)&&s(t);default:return t=>u.every(e=>e(t))}}},6017(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0KB";if(t<1024)return"1KB";const e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/1024**e).toFixed(t>1048576?2:0)}${["B","KB","MB","GB","TB","PB"][e]}`.replace(/\.00/,".0")}},1284(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()} 0${t.getHours()}:0${t.getMinutes()}:0${t.getSeconds()}`.replace(/0(\d\d)/g,"$1")}},5224(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+e(t.getMonth()+1)+e(t.getDate())+"_"+(e(t.getHours())+e(t.getMinutes())+e(t.getSeconds()))}},1690(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+"/"+e(t.getMonth()+1)+"/"+e(t.getDate())+" "+e(t.getHours())+":"+e(t.getMinutes())+":"+e(t.getSeconds())}},6997(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()}`.replace(/0(\d\d)/g,"$1")}},9009(t,e,n){const r=n(3332);t.exports=function(t){return t?t.response?.status&&t.response?.statusText&&t.response?.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.response.config.method||"").toUpperCase()} ${t.response.config.url}\n\n${JSON.stringify(t.response.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- RESPONSE ---\n\n${t.response.status} ${t.response.statusText}\n\n${String(t.response.data??"").slice(0,10240)||"n/a"}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):t.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.config.method||"").toUpperCase()} ${t.config.url}\n\n${JSON.stringify(t.config.headers||{},null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):r({code:t.code,name:t.name,message:t.message??"n/a",stack:t.stack&&t.stack.split(/\n\s*/)},null,4):r({error:void 0===t?"---undefined---":t})}},6015(t){t.exports=function(t,e=6){const[n,r]=t;return(n+r/1e9).toFixed(e)+"s"}},4153(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0";if(t<1e3)return t.toFixed(0);const e=parseInt(Math.floor(Math.log(t)/Math.log(1e3)),10);return`${(t/1e3**e).toFixed(2)}${["","K","M","G","T","P"][e]}`}},1120(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s]=r(t);return n?e+`0${n}:0${o}:0${s}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}`.replace(/0+(?=\d\d)/g,"")}},7336(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s,u]=r(10*Math.round(Math.abs(t)/10));return n?e+`0${n}:0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,"")}},495(t,e,n){const r=n(3150);t.exports=function(t,e=!1){t||(t=0);const n=t<0?"-":"",[o,s,u,c]=r(t);return o||e?n+`0${o}:0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,""):n+`0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,"")}},7882(t){t.exports=function(t){return(100*t).toFixed(2).replace(/^(0|100).00$/,"$1")+"%"}},7111(t,e,n){const r=n(6017),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},5051(t,e,n){const r=n(4153),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},3527(t){t.exports=function(t){const e=Math.abs(Math.trunc(t)),n=`0${Math.floor(e/60/60)}:0${Math.floor(e/60)%60}:0${e%60}`.replace(/0(\d\d)/g,"$1");return t<=-1?"-"+n:n}},2677(t){t.exports=function(t){return t.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,",")}},4206(t,e,n){const r=n(3719);t.exports=function(t,e){return r.delete(t,{responseType:"json",...e}).then(t=>t.data)}},4131(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"blob",...e}).then(t=>t.data)}},706(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"arraybuffer",...e}).then(t=>t.data)}},3066(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"json",...e}).then(t=>t.data)}},3019(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"text",responseEncoding:"utf8",...e}).then(t=>t.data)}},7379(t,e,n){const r=n(3719);t.exports=function(t,e){return r.head(t,e).then(t=>t.request.res.headers)}},2552(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.patch(t,e,n).then(t=>t.data)}},7484(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.post(t,e,n).then(t=>t.data)}},5420(t,e,n){const r=n(8241),o=n(3719);t.exports=function(t,e,n){const s=new r;for(let t=0,n=e.length;t<n;++t){const n=e[t];n.options?s.append(n.name,n.body,n.options):s.append(n.name,n.body)}if(s.getHeaders){const e={...n};return e.headers={...e.headers,...s.getHeaders()},Promise.resolve(o.post(t,s,e)).then(t=>t.data)}return Promise.resolve(o.post(t,s,n)).then(t=>t.data)}},4605(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},6357(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},2380(t,e,n){const r=n(3719);t.exports=async function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},956(t){t.exports=function(t){return t}},1828(t){t.exports=function(){}},3332(t,e,n){const r=n(4106);t.exports=r},6785(t){t.exports=function t(e,n){return n?t(n,e%n):Math.abs(e)}},7347(t,e,n){const r=n(6785);t.exports=function(t,e){return Math.abs(t*e)/r(t,e)}},792(t){t.exports=function(t,e,n,r){return 0===t&&"string"==typeof r?r:t%10==1&&t%100!=11?e.split("#").join(t):n.split("#").join(t)}},131(t){t.exports=function(t,e){return Math.floor(Math.random()*(e-t+1)+t)}},4476(t){t.exports=function(t,e=1){if(0===e)return t;const n=1/e,r=Math.sign(t),o=function(t){if(Math.floor(t)===t)return 0;const[e,n]=t.toExponential().split("e"),r=(e.split(".")[1]||"").length;return Math.max(0,r-parseInt(n,10))}(e),s=1e-12*r,u=Math.round(t*n+s)/n;return Number(u.toFixed(o))}},7233(t){t.exports=function(t,e){const n=String(t||""),r=Object.entries(e||{});if(!r.length)return n;const o=n.indexOf("#"),s=-1===o?"":n.slice(o),u=-1===o?n:n.slice(0,o),c=u.indexOf("?"),a=-1===c?u:u.slice(0,c),i=-1===c?"":u.slice(c+1),f=new URLSearchParams(i);r.forEach(function([t,e]){switch(e){case null:case void 0:f.delete(t);break;case!0:f.set(t,"1");break;case!1:f.set(t,"0");break;default:f.set(t,String(e))}});const p=f.toString();return a+(p?`?${p}`:"")+s}},6966(t,e,n){const r=n(2468);t.exports=function(t){return new r(function(e,n){t(function(t,r){t?n(t):e(r)})})}},7072(t,e,n){const r={"./array_chunk.js":6083,"./array_chunk_balanced.js":2458,"./array_fps.js":353,"./array_gcd.js":6372,"./array_group.js":3537,"./array_group_map.js":2976,"./array_index.js":2166,"./array_lcm.js":7866,"./array_max.js":6772,"./array_min.js":42,"./array_permutations.js":3685,"./array_shuffle.js":4943,"./array_sort.js":2356,"./array_sort_other.js":5181,"./array_sum.js":453,"./array_unique.js":3523,"./array_unique_last.js":6382,"./date_add_hours.js":9870,"./date_add_milliseconds.js":5799,"./date_add_minutes.js":3160,"./date_add_months.js":1570,"./date_add_seconds.js":9296,"./date_diff_seconds.js":5488,"./date_is_leap_year.js":3752,"./fcmp_dates.js":2806,"./fcmp_default.js":8310,"./fcmp_default_desc.js":2092,"./fcmp_from_spec.js":3553,"./fcmp_numbers.js":3129,"./fcmp_tuples.js":4332,"./fcmp_utf8_bin.js":3106,"./fcmp_utf8_ci.js":2271,"./fcmp_utf8_cs.js":4457,"./fcmp_utf8_natural_bin.js":7668,"./fcmp_utf8_natural_ci.js":4385,"./fcmp_utf8_natural_cs.js":8951,"./fcmpx.js":4734,"./filter1_from_spec.js":7960,"./format_bytes.js":6017,"./format_date.js":1284,"./format_date_fs.js":5224,"./format_date_human.js":1690,"./format_date_ymd.js":6997,"./format_error_report.js":9009,"./format_hrtime.js":6015,"./format_kilo.js":4153,"./format_ms.js":1120,"./format_ms2.js":7336,"./format_ms3.js":495,"./format_percents.js":7882,"./format_progress_bytes.js":7111,"./format_progress_kilo.js":5051,"./format_seconds.js":3527,"./format_thousands.js":2677,"./http_delete.js":4206,"./http_get_blob.js":4131,"./http_get_buffer.js":706,"./http_get_json.js":3066,"./http_get_utf8.js":3019,"./http_head.js":7379,"./http_patch_json.js":2552,"./http_post_json.js":7484,"./http_post_multipart.js":5420,"./http_put_buffer.js":4605,"./http_put_json.js":6357,"./http_put_utf8.js":2380,"./identity.js":956,"./ignore.js":1828,"./plural.js":792,"./random_int.js":131,"./urlmod.js":7233,"./waitcb.js":6966};function o(t){const e=s(t);return n(e)}function s(t){if(!n.o(r,t)){const e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return r[t]}o.keys=function(){return Object.keys(r)},o.resolve=s,t.exports=o,o.id=7072},8241(t){"use strict";t.exports=FormData},2468(t){"use strict";t.exports=Promise},3719(t){"use strict";t.exports=axios}};const e={};function n(r){const o=e[r];if(void 0!==o)return o.exports;const s=e[r]={exports:{}};return t[r](s,s.exports,n),s.exports}n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);const r=new URL(document.currentScript.src).searchParams.get("var")??"h";if(void 0!==window[r])console.log(`❌ @vbarbarosh/node-helpers@3.77.0 was not injected — window.${r} is already in use`);else{console.log(`🎉 @vbarbarosh/node-helpers@3.77.0 successfully exposed as window.${r}`),window[r]={};const t=n(7072);t.keys().forEach(function(e){const[,n]=e.match(/([^/]+)\.js$/);window[r][n]=t(e)})}})();
|
|
1
|
+
(()=>{var t={932(t){t.exports=function(t){return"number"==typeof t&&isFinite(t)}},5392(t,e,n){const r=n(932);t.exports=function(t,e){return r(t)&&t>e}},4106(t,e){function n(t,e){var n=[],r=[];return null==e&&(e=function(t,e){return n[0]===e?"[Circular ~]":"[Circular ~."+r.slice(0,n.indexOf(e)).join(".")+"]"}),function(o,s){if(n.length>0){var u=n.indexOf(this);~u?n.splice(u+1):n.push(this),~u?r.splice(u,1/0,o):r.push(o),~n.indexOf(s)&&(s=e.call(this,o,s))}else n.push(s);return null==t?s:t.call(this,o,s)}}(t.exports=function(t,e,r,o){return JSON.stringify(t,n(e,o),r)}).getSerialize=n},6083(t){t.exports=function(t=[],e=1){if(e<1)throw new Error("Limit value should be at least 1");const n=[];for(let r=0,o=t.length;r<o;r+=e)n.push(t.slice(r,r+e));return n}},2458(t,e,n){const r=n(7727);t.exports=function(t=[],e=1,n=1){const o=r(1,e,Math.floor(t.length/n)),s=Math.floor(t.length/o);let u=t.length%o;const c=[];for(let e=0;e<t.length;){const n=s+(u?1:0);c.push(t.slice(e,e+n)),e+=n,u&&u--}return c}},353(t,e,n){const r=n(4476),o=1e-5;t.exports=function(t,e){const n=Math.floor(t*e);if(n<=1)return[0];const s=[];for(let e=0;e<n;++e)s.push(r(e/(n-1)*(t-o),o));return s}},6372(t,e,n){const r=n(6785);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),0)}},3537(t){t.exports=function(t,e){const n=new Map;return t.forEach(function(t){const r=e(t);n.has(r)||n.set(r,{key:r,items:[]}),n.get(r).items.push(t)}),n.values().toArray()}},2976(t){t.exports=function(t,e){const n={};return t.forEach(function(t){const r=e(t);n[r]=n[r]||{key:r,items:[]},n[r].items.push(t)}),n}},2166(t,e,n){const r=n(956);t.exports=function(t,e=r){const n={};return t.forEach(t=>n[e(t)]=t),n}},7866(t,e,n){const r=n(7347);t.exports=function(t,e=Number){return t.map(t=>e(t)).reduce((t,e)=>r(t,e),1)}},6772(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o<r)&&(s=!0,o=r,n=t)}),n}},42(t,e,n){const r=n(956);t.exports=function(t,e=r){let n=null,o=null,s=!1;return t.forEach(function(t){const r=e(t);Number.isNaN(r)||(!s||o>r)&&(s=!0,o=r,n=t)}),n}},3685(t){t.exports=function t(e,n=e.length){if(n!==e.length)return function(e,n){if(0===n)return[[]];if(e.length<n)return[];const r=[];for(let o=0;o<e.length;o++){const s=e.slice(0,o).concat(e.slice(o+1));for(const u of t(s,n-1))r.push([e[o],...u])}return r}(e,n);let r,o,s=(e=e.slice()).length,u=[e.slice()],c=new Array(s).fill(0),a=1;for(;a<s;)c[a]<a?(r=a%2&&c[a],o=e[a],e[a]=e[r],e[r]=o,++c[a],a=1,u.push(e.slice())):(c[a]=0,++a);return u}},4943(t){t.exports=function(t){for(let e=t.length;--e>0;){const n=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[n],t[n]=r}return t}},2356(t,e,n){const r=n(8310),o=n(4332);t.exports=function(t,e,n=r){const s=new Map;return t.sort(function(t,r){if(!s.has(t)){const n=e(t);s.set(t,Array.isArray(n)?n:[n])}if(!s.has(r)){const t=e(r);s.set(r,Array.isArray(t)?t:[t])}return o(s.get(t),s.get(r),n)})}},5181(t,e,n){const r=n(8310);t.exports=function(t,e,n,o=r){const s=Object.create(null);return n.forEach((t,e)=>s[t]=e+1),t.sort(function(t,n){const r=s[e(t)],u=s[e(n)];return r&&u?r-u:r?-1:u?1:o(t,n)})}},453(t){t.exports=function(t,e=Number){let n=0;return t.forEach(function(t){n+=e(t)}),n}},3523(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=new Set;return t.filter(function(t){const r=e(t);return!n.has(r)&&(n.add(r),!0)})}},6382(t,e,n){const r=n(956);t.exports=function(t,e=r){const n=[],o=new Set;for(let r=t.length;--r>=0;){const s=t[r],u=e(s);o.has(u)||(o.add(u),n.push(s))}return n.reverse()}},7727(t){t.exports=function(t,e,n){return Math.max(t,Math.min(e,n))}},9870(t){t.exports=function(t,e){return t.setHours(t.getHours()+e),t}},5799(t){t.exports=function(t,e){return t.setMilliseconds(t.getMilliseconds()+e),t}},3160(t){t.exports=function(t,e){return t.setMinutes(t.getMinutes()+e),t}},1570(t){t.exports=function(t,e){if(!e)return t;const n=t.getDate();return t.setMonth(t.getMonth()+e),t.getDate()!==n&&t.setDate(0),t}},9296(t){t.exports=function(t,e){return t.setSeconds(t.getSeconds()+e),t}},5488(t){t.exports=function(t,e){return Math.floor((t.getTime()-e.getTime())/1e3)}},3752(t){t.exports=function(t){const e=t.getFullYear();return e%4==0&&e%100!=0||e%400==0}},3150(t){t.exports=function(t){return t=Math.trunc(Math.abs(t)),[Math.floor(t/36e5),Math.floor(t%36e5/6e4),Math.floor(t%6e4/1e3),t%1e3]}},2806(t){t.exports=function(t,e){return t.getTime()-e.getTime()}},8310(t,e,n){const r=n(7668);t.exports=function(t,e){return"string"==typeof t&&"string"==typeof e?r(t,e):t<e?-1:t>e?1:0}},2092(t,e,n){const r=n(8310);t.exports=function(t,e){return r(e,t)}},3553(t){function e(t){return"-"===t[0]?(t=t.slice(1),function(e,r){return n(r[t],e[t])}):function(e,r){return n(e[t],r[t])}}function n(t,e){return"string"==typeof t&&"string"==typeof e?t.localeCompare(e):t-e}t.exports=function(t){const n=t.map(e);switch(n.length){case 0:return()=>0;case 1:return n[0];case 2:return function(t,e){return n[0](t,e)||n[1](t,e)};case 3:return function(t,e){return n[0](t,e)||n[1](t,e)||n[2](t,e)};default:return function(t,e){for(let r=0;r<n.length;++r){const o=n[r](t,e);if(o)return o}return 0}}}},3129(t){t.exports=function(t,e){return t-e}},4332(t,e,n){const r=n(8310);t.exports=function(t,e,n=r){const o=Math.min(t.length,e.length);for(let r=0;r<o;++r){const o=n(t[r],e[r]);if(o)return o}return 0}},3106(t){t.exports=function(t,e){return t<e?-1:t>e?1:0}},2271(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"base"})}},4457(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{sensitivity:"variant"})}},7668(t){function e(t,e){const r=t.replace(/^0+/,""),o=e.replace(/^0+/,"");return r.length-o.length||n(r,o)||t.length-e.length}function n(t,e){return t<e?-1:t>e?1:0}t.exports=function(t,r){const o=t.match(/\d+|\D+/g)||[],s=r.match(/\d+|\D+/g)||[],u=Math.min(o.length,s.length);for(let t=0;t<u;++t){const r=o[t][0]<="9"&&s[t][0]<="9"&&o[t][0]>="0"&&s[t][0]>="0"?e(o[t],s[t]):n(o[t],s[t]);if(r)return r}return o.length-s.length}},4385(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"base"})}},8951(t){t.exports=function(t,e){return t.localeCompare(e,void 0,{numeric:!0,sensitivity:"variant"})}},4734(t,e,n){const r=n(8310),o=n(2092),s=n(956),u=Symbol("fcmpx.missing");function c(t){const{read:e,fcmp:n}=a(t);return function(t,r){return n(e(t),e(r))}}function a(t){if("function"==typeof t)return{read:i(t),fcmp:f(r)};if("string"==typeof t){const e=t.startsWith("-");return{read:i(e?t.slice(1):t),fcmp:f(e?o:r)}}const e=t.fcmp,n=i(t.read),s=f(t.desc?e?(t,n)=>e(n,t):o:e??r);if(Array.isArray(t.top)){const e=new Map(t.top.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??e.size,fcmp:s}}if(Array.isArray(t.bottom)){const e=new Map(t.bottom.map((t,e)=>[t,e]));return{read:t=>e.get(n(t))??-1,fcmp:s}}return{read:n,fcmp:s}}function i(t){if(void 0===t||""===t||"."===t)return s;if("function"==typeof t)return function(e){return t(e)??u};if("string"==typeof t){const e=t.split("."),[n,r,o,s,c]=e;switch(e.length){case 1:return t=>t?.[n]??u;case 2:return t=>t?.[n]?.[r]??u;case 3:return t=>t?.[n]?.[r]?.[o]??u;case 4:return t=>t?.[n]?.[r]?.[o]?.[s]??u;case 5:return t=>t?.[n]?.[r]?.[o]?.[s]?.[c]??u;default:return t=>e.reduce((t,e)=>t?.[e],t)??u}}return e=>e?.[t]??u}function f(t){return function(e,n){return e===u?n===u?0:1:n===u?-1:t(e,n)}}t.exports=function t(e){if("string"==typeof e)return e.includes(",")?t(e.split(",")):c(e);if(!Array.isArray(e))return c(e);const n=e.map(a);return function(t,e){const r=n.map(e=>e.read(t)),o=n.map(t=>t.read(e));for(let t=0;t<n.length;++t){const e=n[t].fcmp(r[t],o[t]);if(e)return e}return 0}}},7960(t){function e(t){let e,n,r;return e=t.replaceAll("^",""),n=e.length!==t.length,e=(t=e).replaceAll("$",""),r=e.length!==t.length,e=(t=e).replaceAll("!",""),(t.length-e.length)%2?n&&r?t=>!(t.startsWith(e)&&t.endsWith(e)):n?t=>!t.startsWith(e):r?t=>!t.endsWith(e):t=>!t.includes(e):n&&r?t=>t.startsWith(e)&&t.endsWith(e):n?t=>t.startsWith(e):r?t=>t.endsWith(e):t=>t.includes(e)}t.exports=function(t){let n,r,o,s;const u=function(t){return t.split("/").filter(t=>t).map(e)}(t);switch(u.length){case 0:return()=>!0;case 1:return u[0];case 2:return[n,r]=u,t=>n(t)&&r(t);case 3:return[n,r,o]=u,t=>n(t)&&r(t)&&o(t);case 4:return[n,r,o,s]=u,t=>n(t)&&r(t)&&o(t)&&s(t);default:return t=>u.every(e=>e(t))}}},6017(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0KB";if(t<1024)return"1KB";const e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/1024**e).toFixed(t>1048576?2:0)}${["B","KB","MB","GB","TB","PB"][e]}`.replace(/\.00/,".0")}},1284(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()} 0${t.getHours()}:0${t.getMinutes()}:0${t.getSeconds()}`.replace(/0(\d\d)/g,"$1")}},5224(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+e(t.getMonth()+1)+e(t.getDate())+"_"+(e(t.getHours())+e(t.getMinutes())+e(t.getSeconds()))}},1690(t){function e(t){return t>9?`${t}`:`0${t}`}t.exports=function(t){return t.getFullYear()+"/"+e(t.getMonth()+1)+"/"+e(t.getDate())+" "+e(t.getHours())+":"+e(t.getMinutes())+":"+e(t.getSeconds())}},6997(t){t.exports=function(t){return t.getFullYear()+`/0${t.getMonth()+1}/0${t.getDate()}`.replace(/0(\d\d)/g,"$1")}},9009(t,e,n){const r=n(3332),o="***",s=new Set(["api-key","authorization","cookie","proxy-authorization","set-cookie","x-api-key","x-auth-token"]),u=new Set(["accesstoken","apikey","auth","authorization","key","pass","passwd","password","pwd","secret","sig","signature","token"]);function c(t){if(!t||"object"!=typeof t)return t;if("function"==typeof t.toJSON&&(t=t.toJSON()),Array.isArray(t))return t.map(c);const e={};return Object.entries(t).forEach(function([t,n]){s.has(String(t).toLowerCase())?e[t]=o:e[t]=c(n)}),e}function a(t){return null==t?t:String(t).replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@]*@/i,`$1${o}@`).replace(/([?&])([^=&#]*)=[^&#]*/g,function(t,e,n){return function(t){try{t=decodeURIComponent(t)}catch{}return!!u.has(t.toLowerCase().replace(/[^a-z0-9]/g,""))||t.replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase().split(/[^a-z0-9]+/).some(t=>u.has(t))}(n)?`${e}${n}=${o}`:t})}t.exports=function(t){return t?t.response?.status&&t.response?.statusText&&t.response?.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.response.config.method||"").toUpperCase()} ${a(t.response.config.url)}\n\n${JSON.stringify(c(t.response.config.headers||{}),null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- RESPONSE ---\n\n${t.response.status} ${t.response.statusText}\n\n${String(t.response.data??"").slice(0,10240)||"n/a"}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):t.config?function(t){return`\n${t.message??"n/a"}\n\n--- REQUEST ---\n\n${(t.config.method||"").toUpperCase()} ${a(t.config.url)}\n\n${JSON.stringify(c(t.config.headers||{}),null,4).slice(1,-1).replace(/^\s+|,$/gm,"").trim()}\n\n--- STACK ---\n\n${t.stack??"n/a"}\n`.trimStart()}(t):r({code:t.code,name:t.name,message:t.message??"n/a",stack:t.stack&&t.stack.split(/\n\s*/)},null,4):r({error:void 0===t?"---undefined---":t})}},6015(t){t.exports=function(t,e=6){const[n,r]=t;return(n+r/1e9).toFixed(e)+"s"}},4153(t){t.exports=function(t){if("number"!=typeof t||Number.isNaN(t))return"n/a";if(!t)return"0";if(t<1e3)return t.toFixed(0);const e=parseInt(Math.floor(Math.log(t)/Math.log(1e3)),10);return`${(t/1e3**e).toFixed(2)}${["","K","M","G","T","P"][e]}`}},1120(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s]=r(t);return n?e+`0${n}:0${o}:0${s}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}`.replace(/0+(?=\d\d)/g,"")}},7336(t,e,n){const r=n(3150);t.exports=function(t){t||(t=0);const e=t<0?"-":"",[n,o,s,u]=r(10*Math.round(Math.abs(t)/10));return n?e+`0${n}:0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,""):e+`0${o}:0${s}.0${u/10}`.replace(/0+(?=\d\d)/g,"")}},495(t,e,n){const r=n(3150);t.exports=function(t,e=!1){t||(t=0);const n=t<0?"-":"",[o,s,u,c]=r(t);return o||e?n+`0${o}:0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,""):n+`0${s}:0${u}.00${c}`.replace(/0+(?=\d\d+[:.]|\d\d\d)/g,"")}},7882(t){t.exports=function(t){return(100*t).toFixed(2).replace(/^(0|100).00$/,"$1")+"%"}},7111(t,e,n){const r=n(6017),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},5051(t,e,n){const r=n(4153),o=n(7882),s=n(3527),u=n(5392);t.exports=function({percents:t,total:e,done:n,rate:c,eta:a,duration:i}){const f=u(c,0)?`${r(c)}/s`:"~";if(n>e)return`${r(n)} at ${f} duration=${s(i)}`;if(u(e,0)){const c=u(a,0)?s(a):"~";return`${o(t)} | ${r(n)} of ${r(e)} at ${f} ETA ${c} duration=${s(i)}`}return u(n,0)?`${r(n)} of ~ at ${f} duration=${s(i)}`:u(i,0)?`~ duration=${s(i)}`:"~"}},3527(t){t.exports=function(t){const e=Math.abs(Math.trunc(t)),n=`0${Math.floor(e/60/60)}:0${Math.floor(e/60)%60}:0${e%60}`.replace(/0(\d\d)/g,"$1");return t<=-1?"-"+n:n}},2677(t){t.exports=function(t){return t.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,",")}},4206(t,e,n){const r=n(3719);t.exports=function(t,e){return r.delete(t,{responseType:"json",...e}).then(t=>t.data)}},4131(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"blob",...e}).then(t=>t.data)}},706(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"arraybuffer",...e}).then(t=>t.data)}},3066(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"json",...e}).then(t=>t.data)}},3019(t,e,n){const r=n(3719);t.exports=function(t,e){return r.get(t,{responseType:"text",responseEncoding:"utf8",...e}).then(t=>t.data)}},7379(t,e,n){const r=n(3719);t.exports=function(t,e){return r.head(t,e).then(t=>t.request.res.headers)}},2552(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.patch(t,e,n).then(t=>t.data)}},7484(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.post(t,e,n).then(t=>t.data)}},5420(t,e,n){const r=n(8241),o=n(3719);t.exports=function(t,e,n){const s=new r;for(let t=0,n=e.length;t<n;++t){const n=e[t];n.options?s.append(n.name,n.body,n.options):s.append(n.name,n.body)}if(s.getHeaders){const e={...n};return e.headers={...e.headers,...s.getHeaders()},Promise.resolve(o.post(t,s,e)).then(t=>t.data)}return Promise.resolve(o.post(t,s,n)).then(t=>t.data)}},4605(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},6357(t,e,n){const r=n(3719);t.exports=function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},2380(t,e,n){const r=n(3719);t.exports=async function(t,e,n){return r.put(t,e,n).then(t=>t.data)}},956(t){t.exports=function(t){return t}},1828(t){t.exports=function(){}},3332(t,e,n){const r=n(4106);t.exports=r},6785(t){t.exports=function t(e,n){return n?t(n,e%n):Math.abs(e)}},7347(t,e,n){const r=n(6785);t.exports=function(t,e){return Math.abs(t*e)/r(t,e)}},792(t){t.exports=function(t,e,n,r){return 0===t&&"string"==typeof r?r:t%10==1&&t%100!=11?e.split("#").join(t):n.split("#").join(t)}},131(t){t.exports=function(t,e){return Math.floor(Math.random()*(e-t+1)+t)}},4476(t){t.exports=function(t,e=1){if(0===e)return t;const n=1/e,r=Math.sign(t),o=function(t){if(Math.floor(t)===t)return 0;const[e,n]=t.toExponential().split("e"),r=(e.split(".")[1]||"").length;return Math.max(0,r-parseInt(n,10))}(e),s=1e-12*r,u=Math.round(t*n+s)/n;return Number(u.toFixed(o))}},7233(t){t.exports=function(t,e){const n=String(t||""),r=Object.entries(e||{});if(!r.length)return n;const o=n.indexOf("#"),s=-1===o?"":n.slice(o),u=-1===o?n:n.slice(0,o),c=u.indexOf("?"),a=-1===c?u:u.slice(0,c),i=-1===c?"":u.slice(c+1),f=new URLSearchParams(i);r.forEach(function([t,e]){switch(e){case null:case void 0:f.delete(t);break;case!0:f.set(t,"1");break;case!1:f.set(t,"0");break;default:f.set(t,String(e))}});const p=f.toString();return a+(p?`?${p}`:"")+s}},6966(t,e,n){const r=n(2468);t.exports=function(t){return new r(function(e,n){t(function(t,r){t?n(t):e(r)})})}},9258(t,e,n){const r={"./array_chunk.js":6083,"./array_chunk_balanced.js":2458,"./array_fps.js":353,"./array_gcd.js":6372,"./array_group.js":3537,"./array_group_map.js":2976,"./array_index.js":2166,"./array_lcm.js":7866,"./array_max.js":6772,"./array_min.js":42,"./array_permutations.js":3685,"./array_shuffle.js":4943,"./array_sort.js":2356,"./array_sort_other.js":5181,"./array_sum.js":453,"./array_unique.js":3523,"./array_unique_last.js":6382,"./date_add_hours.js":9870,"./date_add_milliseconds.js":5799,"./date_add_minutes.js":3160,"./date_add_months.js":1570,"./date_add_seconds.js":9296,"./date_diff_seconds.js":5488,"./date_is_leap_year.js":3752,"./fcmp_dates.js":2806,"./fcmp_default.js":8310,"./fcmp_default_desc.js":2092,"./fcmp_from_spec.js":3553,"./fcmp_numbers.js":3129,"./fcmp_tuples.js":4332,"./fcmp_utf8_bin.js":3106,"./fcmp_utf8_ci.js":2271,"./fcmp_utf8_cs.js":4457,"./fcmp_utf8_natural_bin.js":7668,"./fcmp_utf8_natural_ci.js":4385,"./fcmp_utf8_natural_cs.js":8951,"./fcmpx.js":4734,"./filter1_from_spec.js":7960,"./format_bytes.js":6017,"./format_date.js":1284,"./format_date_fs.js":5224,"./format_date_human.js":1690,"./format_date_ymd.js":6997,"./format_error_report.js":9009,"./format_hrtime.js":6015,"./format_kilo.js":4153,"./format_ms.js":1120,"./format_ms2.js":7336,"./format_ms3.js":495,"./format_percents.js":7882,"./format_progress_bytes.js":7111,"./format_progress_kilo.js":5051,"./format_seconds.js":3527,"./format_thousands.js":2677,"./http_delete.js":4206,"./http_get_blob.js":4131,"./http_get_buffer.js":706,"./http_get_json.js":3066,"./http_get_utf8.js":3019,"./http_head.js":7379,"./http_patch_json.js":2552,"./http_post_json.js":7484,"./http_post_multipart.js":5420,"./http_put_buffer.js":4605,"./http_put_json.js":6357,"./http_put_utf8.js":2380,"./identity.js":956,"./ignore.js":1828,"./plural.js":792,"./random_int.js":131,"./urlmod.js":7233,"./waitcb.js":6966};function o(t){const e=s(t);return n(e)}function s(t){if(!n.o(r,t)){const e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return r[t]}o.keys=function(){return Object.keys(r)},o.resolve=s,t.exports=o,o.id=9258},8241(t){"use strict";t.exports=FormData},2468(t){"use strict";t.exports=Promise},3719(t){"use strict";t.exports=axios}};const e={};function n(r){const o=e[r];if(void 0!==o)return o.exports;const s=e[r]={exports:{}};return t[r](s,s.exports,n),s.exports}n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);const r=new URL(document.currentScript.src).searchParams.get("var")??"h";if(void 0!==window[r])console.log(`❌ @vbarbarosh/node-helpers@3.78.1 was not injected — window.${r} is already in use`);else{console.log(`🎉 @vbarbarosh/node-helpers@3.78.1 successfully exposed as window.${r}`),window[r]={};const t=n(9258);t.keys().forEach(function(e){const[,n]=e.match(/([^/]+)\.js$/);window[r][n]=t(e)})}})();
|
package/dist/index.html
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
|
6
|
-
<link href="https://unpkg.com/@vbarbarosh/smcss@1.2.0/dist/reset.css" rel="stylesheet">
|
|
7
|
-
<link href="https://unpkg.com/@vbarbarosh/smcss@1.2.0/dist/sm.css" rel="stylesheet">
|
|
8
|
-
<title>@vbarbarsh/node-helpers</title>
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
1
|
+
<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><link href=https://unpkg.com/@vbarbarosh/smcss@1.2.0/dist/reset.css rel=stylesheet><link href=https://unpkg.com/@vbarbarosh/smcss@1.2.0/dist/sm.css rel=stylesheet><title>@vbarbarsh/node-helpers</title></head><body>
|
|
11
2
|
|
|
12
|
-
<div id=
|
|
3
|
+
<div id=app></div>
|
|
13
4
|
|
|
14
|
-
<script src=
|
|
15
|
-
<script src=
|
|
16
|
-
<script src=
|
|
5
|
+
<script src=https://unpkg.com/axios@1.20.0/dist/axios.js></script>
|
|
6
|
+
<script src=https://unpkg.com/bluebird@3.7.2/js/browser/bluebird.js></script>
|
|
7
|
+
<script src=browser.js></script>
|
|
17
8
|
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
</body></html>
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"author": "Vladimir Barbarosh <vladimir.barbarosh@gmail.com>",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "@vbarbarosh/node-helpers",
|
|
5
|
-
"version": "3.
|
|
5
|
+
"version": "3.78.1",
|
|
6
6
|
"description": "A set of helpers for JavaScript/Node.js",
|
|
7
7
|
"unpkg": "dist/browser.js",
|
|
8
8
|
"jsdelivr": "dist/browser.js",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@paralleldrive/cuid2": "^3.3.0",
|
|
49
|
-
"@vbarbarosh/type-helpers": "^0.
|
|
50
|
-
"axios": "1.
|
|
49
|
+
"@vbarbarosh/type-helpers": "^0.4.0",
|
|
50
|
+
"axios": "1.20.0",
|
|
51
51
|
"bluebird": "^3.7.2",
|
|
52
52
|
"csv-parse": "^7.0.1",
|
|
53
53
|
"form-data": "^4.0.1",
|
|
@@ -65,12 +65,12 @@
|
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@eslint/js": "^10.0.1",
|
|
67
67
|
"@vbarbarosh/tree": "^0.5.0",
|
|
68
|
-
"c8": "^
|
|
68
|
+
"c8": "^12.0.0",
|
|
69
69
|
"copy-webpack-plugin": "^14.0.0",
|
|
70
70
|
"eslint": "^10.7.0",
|
|
71
71
|
"express": "^5.2.1",
|
|
72
72
|
"globals": "^17.7.0",
|
|
73
|
-
"mocha": "^
|
|
73
|
+
"mocha": "^12.0.3",
|
|
74
74
|
"redis-v1": "npm:redis@1",
|
|
75
75
|
"redis-v2": "npm:redis@2",
|
|
76
76
|
"redis-v3": "npm:redis@3",
|
|
@@ -1,16 +1,52 @@
|
|
|
1
1
|
const crypto = require('crypto');
|
|
2
2
|
|
|
3
|
+
const VERSION = 1;
|
|
4
|
+
const SALT_LENGTH = 16;
|
|
5
|
+
const NONCE_LENGTH = 12;
|
|
6
|
+
const TAG_LENGTH = 16;
|
|
7
|
+
const HEADER_LENGTH = 1 + SALT_LENGTH + NONCE_LENGTH;
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
10
|
+
* Decrypts an envelope produced by crypto_encrypt_aes256. Throws when the
|
|
11
|
+
* envelope is malformed, the password is wrong, or the data was tampered
|
|
12
|
+
* with.
|
|
13
|
+
*
|
|
14
|
+
* @link https://nodejs.org/api/crypto.html#class-decipher
|
|
6
15
|
*/
|
|
7
16
|
function crypto_decrypt_aes256(password, ivenc)
|
|
8
17
|
{
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
18
|
+
if (!(ivenc instanceof Uint8Array)) {
|
|
19
|
+
throw new Error('crypto_decrypt_aes256: envelope should be a Buffer');
|
|
20
|
+
}
|
|
21
|
+
if (!Buffer.isBuffer(ivenc)) {
|
|
22
|
+
ivenc = Buffer.from(ivenc.buffer, ivenc.byteOffset, ivenc.byteLength);
|
|
23
|
+
}
|
|
24
|
+
if (ivenc[0] !== VERSION) {
|
|
25
|
+
throw new Error('crypto_decrypt_aes256: malformed envelope');
|
|
26
|
+
}
|
|
27
|
+
return decrypt_v1(password, ivenc);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function decrypt_v1(password, ivenc)
|
|
31
|
+
{
|
|
32
|
+
if (ivenc.length < HEADER_LENGTH + TAG_LENGTH) {
|
|
33
|
+
throw new Error('crypto_decrypt_aes256: malformed envelope');
|
|
34
|
+
}
|
|
35
|
+
const header = ivenc.subarray(0, HEADER_LENGTH);
|
|
36
|
+
const salt = ivenc.subarray(1, 1 + SALT_LENGTH);
|
|
37
|
+
const nonce = ivenc.subarray(1 + SALT_LENGTH, HEADER_LENGTH);
|
|
38
|
+
const tag = ivenc.subarray(HEADER_LENGTH, HEADER_LENGTH + TAG_LENGTH);
|
|
39
|
+
const enc = ivenc.subarray(HEADER_LENGTH + TAG_LENGTH);
|
|
40
|
+
const key = crypto.scryptSync(password, salt, 32);
|
|
41
|
+
const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);
|
|
42
|
+
decipher.setAAD(header);
|
|
43
|
+
decipher.setAuthTag(tag);
|
|
44
|
+
try {
|
|
45
|
+
return Buffer.concat([decipher.update(enc), decipher.final()]);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw new Error('crypto_decrypt_aes256: authentication failed (wrong password or tampered data)', {cause: error});
|
|
49
|
+
}
|
|
14
50
|
}
|
|
15
51
|
|
|
16
52
|
module.exports = crypto_decrypt_aes256;
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
Decrypts a `Buffer` produced by `crypto_encrypt_aes256`
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
Decrypts a `Buffer` envelope produced by `crypto_encrypt_aes256` and returns
|
|
2
|
+
the plaintext as a `Buffer` — call `.toString('utf8')` for text.
|
|
3
|
+
|
|
4
|
+
The version 1 envelope is
|
|
5
|
+
`[0x01][16-byte salt][12-byte nonce][16-byte GCM tag][ciphertext]`
|
|
6
|
+
(`aes-256-gcm`, key = `crypto.scryptSync(password, salt, 32)`, header
|
|
7
|
+
authenticated as additional data). Decryption **throws** when:
|
|
8
|
+
|
|
9
|
+
- the password is wrong or the envelope was modified in any byte
|
|
10
|
+
(`authentication failed (wrong password or tampered data)`);
|
|
11
|
+
- the envelope is malformed: not a `Buffer`/`Uint8Array`, too short, or an
|
|
12
|
+
unknown version byte (`malformed envelope`).
|
|
4
13
|
|
|
5
14
|
```js
|
|
6
|
-
const
|
|
7
|
-
crypto_decrypt_aes256('pass123',
|
|
8
|
-
crypto_decrypt_aes256('wrong',
|
|
15
|
+
const envelope = crypto_encrypt_aes256('pass123', 'hello');
|
|
16
|
+
crypto_decrypt_aes256('pass123', envelope).toString('utf8'); // 'hello'
|
|
17
|
+
crypto_decrypt_aes256('wrong', envelope); // throws
|
|
9
18
|
```
|
|
10
|
-
|
|
11
|
-
**No integrity check:** CTR mode does not authenticate — a wrong password or
|
|
12
|
-
tampered ciphertext yields garbage bytes, never an error, so verify the result
|
|
13
|
-
yourself if you need to detect bad input.
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
const crypto = require('crypto');
|
|
2
2
|
|
|
3
|
+
const VERSION = 1;
|
|
4
|
+
const SALT_LENGTH = 16;
|
|
5
|
+
const NONCE_LENGTH = 12;
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
8
|
+
* Authenticated encryption with a password.
|
|
9
|
+
*
|
|
10
|
+
* Envelope (version 1):
|
|
11
|
+
* [0x01][16-byte salt][12-byte nonce][16-byte GCM tag][ciphertext]
|
|
12
|
+
*
|
|
13
|
+
* The key is scrypt(password, salt, 32) and the version/salt/nonce header
|
|
14
|
+
* is authenticated together with the ciphertext (AES-256-GCM with the
|
|
15
|
+
* header as additional data), so any modification is detected on decrypt.
|
|
16
|
+
*
|
|
17
|
+
* @link https://nodejs.org/api/crypto.html#cryptoscryptsyncpassword-salt-keylen-options
|
|
18
|
+
* @link https://nodejs.org/api/crypto.html#class-cipher
|
|
6
19
|
*/
|
|
7
20
|
function crypto_encrypt_aes256(password, data)
|
|
8
21
|
{
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
const salt = crypto.randomBytes(SALT_LENGTH);
|
|
23
|
+
const nonce = crypto.randomBytes(NONCE_LENGTH);
|
|
24
|
+
const key = crypto.scryptSync(password, salt, 32);
|
|
25
|
+
const header = Buffer.concat([Buffer.from([VERSION]), salt, nonce]);
|
|
26
|
+
const cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);
|
|
27
|
+
cipher.setAAD(header);
|
|
28
|
+
const enc = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
29
|
+
return Buffer.concat([header, cipher.getAuthTag(), enc]);
|
|
16
30
|
}
|
|
17
31
|
|
|
18
32
|
module.exports = crypto_encrypt_aes256;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
Encrypts data with
|
|
2
|
-
|
|
3
|
-
different output. Returns a `Buffer` laid out as `[iv_length, iv, ciphertext]`
|
|
4
|
-
(1 + 16 + data-length bytes); pass it as-is to `crypto_decrypt_aes256`.
|
|
1
|
+
Encrypts data with a password using authenticated encryption. Returns a
|
|
2
|
+
`Buffer` envelope; pass it as-is to `crypto_decrypt_aes256`.
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
**Envelope (version 1), 45 bytes + data length:**
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
[0x01][16-byte salt][12-byte nonce][16-byte GCM tag][ciphertext]
|
|
10
8
|
```
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
- The key is `crypto.scryptSync(password, salt, 32)` with a fresh random salt
|
|
11
|
+
per call, so guessing passwords offline is expensive and the same password
|
|
12
|
+
never yields the same key twice.
|
|
13
|
+
- The cipher is `aes-256-gcm` with a fresh random nonce per call; the
|
|
14
|
+
version/salt/nonce header is authenticated as additional data together with
|
|
15
|
+
the ciphertext. Any modification of the envelope, or a wrong password, makes
|
|
16
|
+
`crypto_decrypt_aes256` throw instead of returning garbage.
|
|
17
|
+
- Encrypting the same input twice gives different output.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
const envelope = crypto_encrypt_aes256('pass123', 'hello');
|
|
21
|
+
// <Buffer 01 ...> — 50 bytes: version, 16-byte salt, 12-byte nonce, 16-byte tag, 5-byte ciphertext
|
|
22
|
+
crypto_decrypt_aes256('pass123', envelope).toString('utf8'); // 'hello'
|
|
23
|
+
```
|
|
@@ -7,8 +7,14 @@ function escape_content_disposition(s)
|
|
|
7
7
|
const out = s.replaceAll('\\', '\\\\')
|
|
8
8
|
.replaceAll('"', '\\"')
|
|
9
9
|
.replaceAll('%', '\\%')
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// Control characters (\n, \r, \0, \x01..., DEL) are illegal in a
|
|
11
|
+
// header value; encode every one of them as %xHH.
|
|
12
|
+
// eslint-disable-next-line no-control-regex
|
|
13
|
+
.replace(/[\x00-\x1f\x7f]/g, c => '%x' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'))
|
|
14
|
+
// A quoted-string may carry ISO-8859-1 only; anything above U+00FF
|
|
15
|
+
// is replaced with '?' (use escape_content_disposition_utf8 for the RFC 5987 filename*).
|
|
16
|
+
// eslint-disable-next-line no-control-regex
|
|
17
|
+
.replace(/[^\x00-\xff]/g, '?');
|
|
12
18
|
// A bare value must be a pure RFC 7230 token: any other character
|
|
13
19
|
// (space, ';', ',', '"', '\', ...) requires the whole value to be a
|
|
14
20
|
// quoted-string — an unquoted 'a\"b' or 'a,b' breaks header parsing.
|
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
Escapes a value (typically a filename) for use in a `Content-Disposition`
|
|
2
2
|
header. A pure RFC 7230 token (letters, digits, `!#$%&'*+.^_`|~-`) is returned
|
|
3
3
|
as-is; anything else — spaces, `;`, `,`, quotes, etc. — becomes a quoted-string
|
|
4
|
-
with `\` `"` `%` backslash-escaped
|
|
5
|
-
|
|
4
|
+
with `\` `"` `%` backslash-escaped, every control character (`\0`-`\x1f`,
|
|
5
|
+
`\x7f`, so `\n`, `\r`, `\x01`...) encoded as `%xHH`, and any character above
|
|
6
|
+
U+00FF (not representable in ISO-8859-1) replaced with `?`. The result is
|
|
7
|
+
always a valid header value. An unquoted `a"b` or `a,b` would break header
|
|
8
|
+
parsing.
|
|
9
|
+
|
|
10
|
+
See `escape_content_disposition_utf8` for the RFC 5987 `filename*` form that
|
|
11
|
+
carries a non-ASCII name alongside the `?`-degraded `filename` fallback.
|
|
6
12
|
|
|
7
13
|
```js
|
|
8
14
|
escape_content_disposition('report.pdf') // 'report.pdf'
|
|
9
15
|
escape_content_disposition('foo bar.txt') // '"foo bar.txt"'
|
|
10
16
|
escape_content_disposition('foo"bar') // '"foo\\"bar"'
|
|
11
17
|
escape_content_disposition('foo\nbar') // '"foo%x0Abar"'
|
|
18
|
+
escape_content_disposition('foo\rbar') // '"foo%x0Dbar"'
|
|
19
|
+
escape_content_disposition('файл.txt') // '"????.txt"'
|
|
12
20
|
escape_content_disposition('') // '""'
|
|
13
21
|
```
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 5987 ext-value for a `filename*` parameter: `UTF-8''<percent-encoded>`.
|
|
3
|
+
* Everything outside attr-char is percent-encoded, as jshttp/content-disposition does.
|
|
4
|
+
*/
|
|
5
|
+
function escape_content_disposition_utf8(s)
|
|
6
|
+
{
|
|
7
|
+
// eslint-disable-next-line no-control-regex
|
|
8
|
+
return `UTF-8''` + encodeURIComponent(s).replace(/[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
module.exports = escape_content_disposition_utf8;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Returns the RFC 5987 ext-value `UTF-8''<percent-encoded>` for a
|
|
2
|
+
`Content-Disposition` `filename*` parameter, so a non-ASCII filename can be
|
|
3
|
+
sent alongside the `?`-degraded `filename` fallback produced by
|
|
4
|
+
`escape_content_disposition`. Everything outside RFC 5987 attr-char is
|
|
5
|
+
percent-encoded, as jshttp/content-disposition does.
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
escape_content_disposition_utf8('файл.txt') // "UTF-8''%D1%84%D0%B0%D0%B9%D0%BB.txt"
|
|
9
|
+
escape_content_disposition_utf8('foo bar.txt') // "UTF-8''foo%20bar.txt"
|
|
10
|
+
// Content-Disposition: attachment; filename="????.txt"; filename*=UTF-8''%D1%84%D0%B0%D0%B9%D0%BB.txt
|
|
11
|
+
```
|
package/src/fastdl.js
CHANGED
|
@@ -54,6 +54,11 @@ async function download({file, read_stream_with_range, concurrency, user_friendl
|
|
|
54
54
|
const rs0 = await read_stream_with_range(0, chunk_min_bytes);
|
|
55
55
|
|
|
56
56
|
const total = rs0.content_range.total;
|
|
57
|
+
if (!Number.isInteger(total)) {
|
|
58
|
+
rs0.once('error', ignore);
|
|
59
|
+
rs0.destroy();
|
|
60
|
+
throw new UserFriendlyError('Server did not return the resource size (it may have ignored the Range header)');
|
|
61
|
+
}
|
|
57
62
|
const chunk_size = Math.max(chunk_min_bytes, Math.min(chunk_max_bytes, Math.trunc(total/concurrency)));
|
|
58
63
|
const progress = make_progress(total);
|
|
59
64
|
|
|
@@ -62,7 +67,7 @@ async function download({file, read_stream_with_range, concurrency, user_friendl
|
|
|
62
67
|
let total_written = 0;
|
|
63
68
|
let rs0_used = false;
|
|
64
69
|
|
|
65
|
-
|
|
70
|
+
let timer = null;
|
|
66
71
|
function tick() {
|
|
67
72
|
progress.refresh();
|
|
68
73
|
user_friendly_status(`${format_progress_bytes(progress)} connections=${connections}`);
|
|
@@ -71,6 +76,7 @@ async function download({file, read_stream_with_range, concurrency, user_friendl
|
|
|
71
76
|
user_friendly_status(`${format_bytes(total)} [${format_thousands(total)} bytes] to download`);
|
|
72
77
|
|
|
73
78
|
try {
|
|
79
|
+
timer = setInterval(tick, 1000);
|
|
74
80
|
await parallel({concurrency, spawn});
|
|
75
81
|
}
|
|
76
82
|
catch (error) {
|
package/src/fastdl.md
CHANGED
|
@@ -8,6 +8,11 @@ flushed, closed, and atomically renamed over `file`. A failed request, exhausted
|
|
|
8
8
|
retry, size mismatch, or write error removes the temporary file and preserves
|
|
9
9
|
an existing destination.
|
|
10
10
|
|
|
11
|
+
The first range response must carry an integer `content_range.total`. When the
|
|
12
|
+
server ignores `Range` and answers with an unknown size (for example a chunked
|
|
13
|
+
200), the stream is destroyed and the call rejects with a `UserFriendlyError`
|
|
14
|
+
without leaving a progress timer behind.
|
|
15
|
+
|
|
11
16
|
```js
|
|
12
17
|
await fastdl({
|
|
13
18
|
file: fs_path_basename(new URL(url).pathname),
|
package/src/format_date_fs.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
// // 20260916_210411, local time
|
|
2
|
+
// function format_date_fs(date)
|
|
3
|
+
// {
|
|
4
|
+
// return [date.getFullYear(), date.getMonth() + 1, date.getDate(), '_',
|
|
5
|
+
// date.getHours(), date.getMinutes(), date.getSeconds()]
|
|
6
|
+
// .map(v => typeof v === 'string' || v > 9 ? v : `0${v}`).join('');
|
|
7
|
+
// }
|
|
8
|
+
|
|
1
9
|
function format_date_fs(d)
|
|
2
10
|
{
|
|
3
11
|
const ymd = d.getFullYear() + dd(d.getMonth() + 1) + dd(d.getDate());
|
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
const json_stringify_safe = require('./json_stringify_safe');
|
|
2
2
|
|
|
3
|
+
const MASK = '***';
|
|
4
|
+
|
|
5
|
+
// Header names (lower-cased) whose value is masked in the report
|
|
6
|
+
const SENSITIVE_HEADERS = new Set([
|
|
7
|
+
'api-key',
|
|
8
|
+
'authorization',
|
|
9
|
+
'cookie',
|
|
10
|
+
'proxy-authorization',
|
|
11
|
+
'set-cookie',
|
|
12
|
+
'x-api-key',
|
|
13
|
+
'x-auth-token',
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
// A query parameter is sensitive when any of its name's segments (split on
|
|
17
|
+
// `_`, `-`, `.` and camelCase boundaries, lower-cased) is one of these words,
|
|
18
|
+
// so `api_key`, `apiKey`, `access_token`, `x-auth-token`, `sig` and `key`
|
|
19
|
+
// match while `keyword`, `design`, `author`, `keyboard`, `signal` do not
|
|
20
|
+
const SENSITIVE_QUERY_WORDS = new Set([
|
|
21
|
+
'accesstoken',
|
|
22
|
+
'apikey',
|
|
23
|
+
'auth',
|
|
24
|
+
'authorization',
|
|
25
|
+
'key',
|
|
26
|
+
'pass',
|
|
27
|
+
'passwd',
|
|
28
|
+
'password',
|
|
29
|
+
'pwd',
|
|
30
|
+
'secret',
|
|
31
|
+
'sig',
|
|
32
|
+
'signature',
|
|
33
|
+
'token',
|
|
34
|
+
]);
|
|
35
|
+
|
|
3
36
|
function format_error_report(error)
|
|
4
37
|
{
|
|
5
38
|
if (!error) {
|
|
@@ -29,9 +62,9 @@ ${error.message ?? 'n/a'}
|
|
|
29
62
|
|
|
30
63
|
--- REQUEST ---
|
|
31
64
|
|
|
32
|
-
${(error.response.config.method||'').toUpperCase()} ${error.response.config.url}
|
|
65
|
+
${(error.response.config.method||'').toUpperCase()} ${mask_url(error.response.config.url)}
|
|
33
66
|
|
|
34
|
-
${JSON.stringify(error.response.config.headers||{}, null, 4).slice(1, -1).replace(/^\s+|,$/mg, '').trim()}
|
|
67
|
+
${JSON.stringify(mask_headers(error.response.config.headers||{}), null, 4).slice(1, -1).replace(/^\s+|,$/mg, '').trim()}
|
|
35
68
|
|
|
36
69
|
--- RESPONSE ---
|
|
37
70
|
|
|
@@ -52,9 +85,9 @@ ${error.message ?? 'n/a'}
|
|
|
52
85
|
|
|
53
86
|
--- REQUEST ---
|
|
54
87
|
|
|
55
|
-
${(error.config.method||'').toUpperCase()} ${error.config.url}
|
|
88
|
+
${(error.config.method||'').toUpperCase()} ${mask_url(error.config.url)}
|
|
56
89
|
|
|
57
|
-
${JSON.stringify(error.config.headers||{}, null, 4).slice(1, -1).replace(/^\s+|,$/mg, '').trim()}
|
|
90
|
+
${JSON.stringify(mask_headers(error.config.headers||{}), null, 4).slice(1, -1).replace(/^\s+|,$/mg, '').trim()}
|
|
58
91
|
|
|
59
92
|
--- STACK ---
|
|
60
93
|
|
|
@@ -62,4 +95,69 @@ ${error.stack ?? 'n/a'}
|
|
|
62
95
|
`.trimStart();
|
|
63
96
|
}
|
|
64
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Returns a copy of `headers` with sensitive values replaced by [MASK].
|
|
100
|
+
* Header names are matched case-insensitively. Axios may nest headers per
|
|
101
|
+
* method (`headers.common`, `headers.get`, ...) and may pass an AxiosHeaders
|
|
102
|
+
* instance (which serializes via `toJSON`), so nested objects are walked too.
|
|
103
|
+
*/
|
|
104
|
+
function mask_headers(headers)
|
|
105
|
+
{
|
|
106
|
+
if (!headers || typeof headers !== 'object') {
|
|
107
|
+
return headers;
|
|
108
|
+
}
|
|
109
|
+
if (typeof headers.toJSON === 'function') {
|
|
110
|
+
headers = headers.toJSON();
|
|
111
|
+
}
|
|
112
|
+
if (Array.isArray(headers)) {
|
|
113
|
+
return headers.map(mask_headers);
|
|
114
|
+
}
|
|
115
|
+
const out = {};
|
|
116
|
+
Object.entries(headers).forEach(function ([key, value]) {
|
|
117
|
+
if (SENSITIVE_HEADERS.has(String(key).toLowerCase())) {
|
|
118
|
+
out[key] = MASK;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
out[key] = mask_headers(value);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Replaces URL userinfo (`scheme://user:pass@host`) and the values of query
|
|
129
|
+
* parameters with a sensitive-looking name by [MASK]. Works on the raw
|
|
130
|
+
* string so the rest of the URL is reported exactly as it was requested.
|
|
131
|
+
*/
|
|
132
|
+
function mask_url(url)
|
|
133
|
+
{
|
|
134
|
+
if (url === undefined || url === null) {
|
|
135
|
+
return url;
|
|
136
|
+
}
|
|
137
|
+
return String(url)
|
|
138
|
+
.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@]*@/i, `$1${MASK}@`)
|
|
139
|
+
.replace(/([?&])([^=&#]*)=[^&#]*/g, function (match, sep, name) {
|
|
140
|
+
return is_sensitive_query_name(name) ? `${sep}${name}=${MASK}` : match;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function is_sensitive_query_name(name)
|
|
145
|
+
{
|
|
146
|
+
try {
|
|
147
|
+
name = decodeURIComponent(name);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// keep the raw name
|
|
151
|
+
}
|
|
152
|
+
// whole names such as `apikey`, `accesstoken`, `api-key`
|
|
153
|
+
if (SENSITIVE_QUERY_WORDS.has(name.toLowerCase().replace(/[^a-z0-9]/g, ''))) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return name
|
|
157
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
158
|
+
.toLowerCase()
|
|
159
|
+
.split(/[^a-z0-9]+/)
|
|
160
|
+
.some(segment => SENSITIVE_QUERY_WORDS.has(segment));
|
|
161
|
+
}
|
|
162
|
+
|
|
65
163
|
module.exports = format_error_report;
|