@rsdoctor/cli 1.5.6 → 1.5.7

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.
@@ -6,6 +6,7 @@ interface Options {
6
6
  baseline: string;
7
7
  open?: boolean;
8
8
  html?: boolean;
9
+ json?: boolean | string;
9
10
  output?: string;
10
11
  }
11
12
  export declare const bundleDiff: Command<Commands.BundleDiff, Options, RsdoctorSDK<{
package/dist/index.cjs CHANGED
@@ -1723,33 +1723,6 @@ var __webpack_modules__ = {
1723
1723
  };
1724
1724
  module.exports = createColors(), module.exports.createColors = createColors;
1725
1725
  },
1726
- "../../node_modules/.pnpm/proxy-from-env@1.1.0/node_modules/proxy-from-env/index.js" (__unused_rspack_module, exports1, __webpack_require__) {
1727
- "use strict";
1728
- var parseUrl = __webpack_require__("url").parse, DEFAULT_PORTS = {
1729
- ftp: 21,
1730
- gopher: 70,
1731
- http: 80,
1732
- https: 443,
1733
- ws: 80,
1734
- wss: 443
1735
- }, stringEndsWith = String.prototype.endsWith || function(s) {
1736
- return s.length <= this.length && -1 !== this.indexOf(s, this.length - s.length);
1737
- };
1738
- function getEnv(key) {
1739
- return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
1740
- }
1741
- exports1.getProxyForUrl = function(url) {
1742
- var hostname, port, NO_PROXY, parsedUrl = 'string' == typeof url ? parseUrl(url) : url || {}, proto = parsedUrl.protocol, hostname1 = parsedUrl.host, port1 = parsedUrl.port;
1743
- if ('string' != typeof hostname1 || !hostname1 || 'string' != typeof proto) return '';
1744
- if (proto = proto.split(':', 1)[0], hostname = hostname1 = hostname1.replace(/:\d*$/, ''), port = port1 = parseInt(port1) || DEFAULT_PORTS[proto] || 0, !(!(NO_PROXY = (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase()) || '*' !== NO_PROXY && NO_PROXY.split(/[,\s]/).every(function(proxy) {
1745
- if (!proxy) return !0;
1746
- var parsedProxy = proxy.match(/^(.+):(\d+)$/), parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy, parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
1747
- return !!parsedProxyPort && parsedProxyPort !== port || (/^[.*]/.test(parsedProxyHostname) ? ('*' === parsedProxyHostname.charAt(0) && (parsedProxyHostname = parsedProxyHostname.slice(1)), !stringEndsWith.call(hostname, parsedProxyHostname)) : hostname !== parsedProxyHostname);
1748
- }))) return '';
1749
- var proxy = getEnv('npm_config_' + proto + '_proxy') || getEnv(proto + '_proxy') || getEnv('npm_config_proxy') || getEnv('all_proxy');
1750
- return proxy && -1 === proxy.indexOf('://') && (proxy = proto + '://' + proxy), proxy;
1751
- };
1752
- },
1753
1726
  "../../node_modules/.pnpm/supports-color@5.5.0/node_modules/supports-color/index.js" (module, __unused_rspack_exports, __webpack_require__) {
1754
1727
  "use strict";
1755
1728
  let forceColor, os = __webpack_require__("os"), hasFlag = __webpack_require__("../../node_modules/.pnpm/has-flag@3.0.0/node_modules/has-flag/index.js"), env = process.env;
@@ -2829,7 +2802,7 @@ for(var __rspack_i in (()=>{
2829
2802
  return header && String(header).trim().toLowerCase();
2830
2803
  }
2831
2804
  function normalizeValue(value) {
2832
- return !1 === value || null == value ? value : utils.isArray(value) ? value.map(normalizeValue) : String(value);
2805
+ return !1 === value || null == value ? value : utils.isArray(value) ? value.map(normalizeValue) : String(value).replace(/[\r\n]+$/, '');
2833
2806
  }
2834
2807
  function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {
2835
2808
  if (utils.isFunction(filter)) return filter.call(this, value, header);
@@ -3031,7 +3004,18 @@ for(var __rspack_i in (()=>{
3031
3004
  let isRelativeUrl = !('string' == typeof (url = requestedURL) && /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url));
3032
3005
  return baseURL && (isRelativeUrl || !1 == allowAbsoluteUrls) ? (baseURL1 = baseURL, (relativeURL = requestedURL) ? baseURL1.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL1) : requestedURL;
3033
3006
  }
3034
- var proxy_from_env = __webpack_require__("../../node_modules/.pnpm/proxy-from-env@1.1.0/node_modules/proxy-from-env/index.js"), external_http_ = __webpack_require__("http"), external_https_ = __webpack_require__("https");
3007
+ var DEFAULT_PORTS = {
3008
+ ftp: 21,
3009
+ gopher: 70,
3010
+ http: 80,
3011
+ https: 443,
3012
+ ws: 80,
3013
+ wss: 443
3014
+ };
3015
+ function getEnv(key) {
3016
+ return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
3017
+ }
3018
+ var external_http_ = __webpack_require__("http"), external_https_ = __webpack_require__("https");
3035
3019
  let external_http2_namespaceObject = require("http2");
3036
3020
  var external_util_ = __webpack_require__("util"), follow_redirects = __webpack_require__("../../node_modules/.pnpm/follow-redirects@1.15.11/node_modules/follow-redirects/index.js");
3037
3021
  let external_zlib_namespaceObject = require("zlib");
@@ -3213,7 +3197,10 @@ for(var __rspack_i in (()=>{
3213
3197
  if (removed) return;
3214
3198
  removed = !0;
3215
3199
  let entries = authoritySessions, len = entries.length, i = len;
3216
- for(; i--;)if (entries[i][0] === session) return void (1 === len ? delete this.sessions[authority] : entries.splice(i, 1));
3200
+ for(; i--;)if (entries[i][0] === session) {
3201
+ 1 === len ? delete this.sessions[authority] : entries.splice(i, 1), session.closed || session.close();
3202
+ return;
3203
+ }
3217
3204
  }, originalRequestFn = session.request, { sessionTimeout } = options;
3218
3205
  if (null != sessionTimeout) {
3219
3206
  let timer, streamsCount = 0;
@@ -3380,7 +3367,7 @@ for(var __rspack_i in (()=>{
3380
3367
  }
3381
3368
  if (-1 === supportedProtocols.indexOf(protocol)) return reject(new core_AxiosError('Unsupported protocol ' + protocol, core_AxiosError.ERR_BAD_REQUEST, config));
3382
3369
  let headers = AxiosHeaders.from(config.headers).normalize();
3383
- headers.set('User-Agent', "axios/1.13.6", !1);
3370
+ headers.set('User-Agent', "axios/1.14.0", !1);
3384
3371
  let { onUploadProgress, onDownloadProgress } = config, maxRate = config.maxRate;
3385
3372
  if (utils.isSpecCompliantForm(data)) {
3386
3373
  let userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i);
@@ -3403,7 +3390,7 @@ for(var __rspack_i in (()=>{
3403
3390
  })(data, (formHeaders)=>{
3404
3391
  headers.set(formHeaders);
3405
3392
  }, {
3406
- tag: "axios-1.13.6-boundary",
3393
+ tag: "axios-1.14.0-boundary",
3407
3394
  boundary: userBoundary && userBoundary[1] || void 0
3408
3395
  });
3409
3396
  } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {
@@ -3455,7 +3442,22 @@ for(var __rspack_i in (()=>{
3455
3442
  utils.isUndefined(lookup) || (options.lookup = lookup), config.socketPath ? options.socketPath = config.socketPath : (options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname, options.port = parsed.port, function setProxy(options, configProxy, location) {
3456
3443
  let proxy = configProxy;
3457
3444
  if (!proxy && !1 !== proxy) {
3458
- let proxyUrl = proxy_from_env.getProxyForUrl(location);
3445
+ let proxyUrl = function(url) {
3446
+ var hostname, port, NO_PROXY, parsedUrl = ('string' == typeof url ? function(urlString) {
3447
+ try {
3448
+ return new URL(urlString);
3449
+ } catch {
3450
+ return null;
3451
+ }
3452
+ }(url) : url) || {}, proto = parsedUrl.protocol, hostname1 = parsedUrl.host, port1 = parsedUrl.port;
3453
+ if ('string' != typeof hostname1 || !hostname1 || 'string' != typeof proto || (proto = proto.split(':', 1)[0], hostname = hostname1 = hostname1.replace(/:\d*$/, ''), port = port1 = parseInt(port1) || DEFAULT_PORTS[proto] || 0, !(!(NO_PROXY = getEnv('no_proxy').toLowerCase()) || '*' !== NO_PROXY && NO_PROXY.split(/[,\s]/).every(function(proxy) {
3454
+ if (!proxy) return !0;
3455
+ var parsedProxy = proxy.match(/^(.+):(\d+)$/), parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy, parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
3456
+ return !!parsedProxyPort && parsedProxyPort !== port || (/^[.*]/.test(parsedProxyHostname) ? ('*' === parsedProxyHostname.charAt(0) && (parsedProxyHostname = parsedProxyHostname.slice(1)), !hostname.endsWith(parsedProxyHostname)) : hostname !== parsedProxyHostname);
3457
+ })))) return '';
3458
+ var proxy = getEnv(proto + '_proxy') || getEnv('all_proxy');
3459
+ return proxy && -1 === proxy.indexOf('://') && (proxy = proto + '://' + proxy), proxy;
3460
+ }(location);
3459
3461
  proxyUrl && (proxy = new URL(proxyUrl));
3460
3462
  }
3461
3463
  if (proxy) {
@@ -3771,14 +3773,14 @@ for(var __rspack_i in (()=>{
3771
3773
  }, globalFetchAPI, env), isFetchSupported = envFetch ? fetch_isFunction(envFetch) : 'function' == typeof fetch, isRequestSupported = fetch_isFunction(Request), isResponseSupported = fetch_isFunction(Response);
3772
3774
  if (!isFetchSupported) return !1;
3773
3775
  let isReadableStreamSupported = isFetchSupported && fetch_isFunction(fetch_ReadableStream), encodeText = isFetchSupported && ('function' == typeof fetch_TextEncoder ? (encoder = new fetch_TextEncoder(), (str)=>encoder.encode(str)) : async (str)=>new Uint8Array(await new Request(str).arrayBuffer())), supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(()=>{
3774
- let duplexAccessed = !1, hasContentType = new Request(platform.origin, {
3775
- body: new fetch_ReadableStream(),
3776
+ let duplexAccessed = !1, body = new fetch_ReadableStream(), hasContentType = new Request(platform.origin, {
3777
+ body,
3776
3778
  method: 'POST',
3777
3779
  get duplex () {
3778
3780
  return duplexAccessed = !0, 'half';
3779
3781
  }
3780
3782
  }).headers.has('Content-Type');
3781
- return duplexAccessed && !hasContentType;
3783
+ return body.cancel(), duplexAccessed && !hasContentType;
3782
3784
  }), supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(()=>utils.isReadableStream(new Response('').body)), resolvers = {
3783
3785
  stream: supportsResponseStream && ((res)=>res.body)
3784
3786
  };
@@ -3971,7 +3973,7 @@ for(var __rspack_i in (()=>{
3971
3973
  let deprecatedWarnings = {};
3972
3974
  validators.transitional = function(validator, version, message) {
3973
3975
  function formatMessage(opt, desc) {
3974
- return "[Axios v1.13.6] Transitional option '" + opt + "'" + desc + (message ? '. ' + message : '');
3976
+ return "[Axios v1.14.0] Transitional option '" + opt + "'" + desc + (message ? '. ' + message : '');
3975
3977
  }
3976
3978
  return (value, opt, opts)=>{
3977
3979
  if (!1 === validator) throw new core_AxiosError(formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), core_AxiosError.ERR_DEPRECATED);
@@ -4257,7 +4259,7 @@ for(var __rspack_i in (()=>{
4257
4259
  return createInstance(mergeConfig(defaultConfig, instanceConfig));
4258
4260
  }, instance;
4259
4261
  }(defaults_defaults);
4260
- axios.Axios = Axios, axios.CanceledError = cancel_CanceledError, axios.CancelToken = CancelToken, axios.isCancel = isCancel, axios.VERSION = "1.13.6", axios.toFormData = helpers_toFormData, axios.AxiosError = core_AxiosError, axios.Cancel = axios.CanceledError, axios.all = function(promises) {
4262
+ axios.Axios = Axios, axios.CanceledError = cancel_CanceledError, axios.CancelToken = CancelToken, axios.isCancel = isCancel, axios.VERSION = "1.14.0", axios.toFormData = helpers_toFormData, axios.AxiosError = core_AxiosError, axios.Cancel = axios.CanceledError, axios.all = function(promises) {
4261
4263
  return Promise.all(promises);
4262
4264
  }, axios.spread = function(callback) {
4263
4265
  return function(arr) {
@@ -4295,7 +4297,7 @@ for(var __rspack_i in (()=>{
4295
4297
  async function loadShardingFileWithSpinner(uri, cwd, spinner) {
4296
4298
  return loadShardingFile(uri, cwd).then((res)=>(spinner.text = `loaded "${uri}"`, res));
4297
4299
  }
4298
- var package_namespaceObject = JSON.parse('{"name":"@rsdoctor/cli","version":"1.5.6","repository":{"type":"git","url":"https://github.com/web-infra-dev/rsdoctor","directory":"packages/cli"},"bin":{"rsdoctor":"./bin/rsdoctor"},"files":["bin","dist"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.cjs"}},"license":"MIT","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"dev":"npm run start","build":"rslib build","start":"rslib build -w","test":"rstest run"},"type":"module","dependencies":{"ora":"^5.4.1","@rsdoctor/sdk":"workspace:*","@rsdoctor/types":"workspace:*","@rsdoctor/utils":"workspace:*","@rsdoctor/graph":"workspace:*"},"devDependencies":{"@rsdoctor/client":"workspace:*","cac":"^7.0.0","typescript":"^5.9.2","axios":"^1.13.6","picocolors":"^1.1.1"},"peerDependencies":{"@rsdoctor/client":"workspace:*"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"}}');
4300
+ var package_namespaceObject = JSON.parse('{"name":"@rsdoctor/cli","version":"1.5.7","repository":{"type":"git","url":"https://github.com/web-infra-dev/rsdoctor","directory":"packages/cli"},"bin":{"rsdoctor":"./bin/rsdoctor"},"files":["bin","dist"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.cjs"}},"license":"MIT","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"dev":"npm run start","build":"rslib build","start":"rslib build -w","test":"rstest run"},"type":"module","dependencies":{"ora":"^5.4.1","@rsdoctor/sdk":"workspace:*","@rsdoctor/types":"workspace:*","@rsdoctor/utils":"workspace:*","@rsdoctor/graph":"workspace:*"},"devDependencies":{"@rsdoctor/client":"workspace:*","cac":"^7.0.0","typescript":"^5.9.2","axios":"1.14.0","picocolors":"^1.1.1"},"peerDependencies":{"@rsdoctor/client":"workspace:*"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"}}');
4299
4301
  let constants_bin = Object.keys(package_namespaceObject.bin)[0], analyze = enhanceCommand(({ cwd, name, bin })=>({
4300
4302
  command: "analyze",
4301
4303
  description: `
@@ -4345,9 +4347,9 @@ use ${name} to open the bundle diff result in browser for analysis.
4345
4347
  example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4346
4348
  `.trim(),
4347
4349
  options (cli) {
4348
- cli.option('--current <path>', 'the url or file path of the profile json as the current').option('--baseline <path>', 'the url or file path of the profile json as the baseline').option('--html', 'output as a standalone HTML file').option('--output <path>', 'output file path for HTML mode (default: rsdoctor-diff.html)');
4350
+ cli.option('--current <path>', 'the url or file path of the profile json as the current').option('--baseline <path>', 'the url or file path of the profile json as the baseline').option('--html', 'output as a standalone HTML file').option('--json [path]', 'output as a JSON file, optionally specify file path (default: rsdoctor-diff.json)').option('--output <path>', 'output file path for HTML mode (default: rsdoctor-diff.html). For JSON output, use --json [path] to specify the file path.');
4349
4351
  },
4350
- async action ({ baseline, current, open = !0, html = !1, output = 'rsdoctor-diff.html' }) {
4352
+ async action ({ baseline, current, open = !0, html = !1, json = !1, output }) {
4351
4353
  let baselineDataValue, currentDataValue, spinner = external_ora_default()({
4352
4354
  prefixText: (0, picocolors.cyan)(`[${name}]`)
4353
4355
  }).start();
@@ -4377,6 +4379,16 @@ example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4377
4379
  if (currentData.cloudData) spinner.text = 'load the "currentData.cloudData" instead of the "currentData.data"', currentDataValue = await common_namespaceObject.Manifest.fetchShardingFiles(currentData.cloudData, (url)=>loadShardingFileWithSpinner(url, cwd, spinner));
4378
4380
  else throw spinner.fail((0, picocolors.red)(error.message)), error;
4379
4381
  }
4382
+ if (json && html) return spinner.fail((0, picocolors.red)('Options "--json" and "--html" cannot be used together. Please choose one.')), null;
4383
+ if (json) {
4384
+ spinner.text = 'Generating JSON output file...';
4385
+ let outputPath = external_path_default().resolve(cwd, 'string' == typeof json ? json : output || 'rsdoctor-diff.json');
4386
+ external_fs_default().mkdirSync(external_path_default().dirname(outputPath), {
4387
+ recursive: !0
4388
+ });
4389
+ let jsonData = common_namespaceObject.Graph.getBundleDiffResult(baselineDataValue, currentDataValue);
4390
+ return external_fs_default().writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), 'utf-8'), spinner.succeed(`Generated JSON output file at: ${outputPath}`), null;
4391
+ }
4380
4392
  if (!html) {
4381
4393
  spinner.text = "start server";
4382
4394
  let baselineSdk = new sdk_namespaceObject.RsdoctorSDK({
@@ -4437,7 +4449,7 @@ example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4437
4449
  `window.${types_namespaceObject.Constants.WINDOW_RSDOCTOR_TAG}.mode = 'diff';`
4438
4450
  ].map((script)=>`<script>${script}</script>`).join('\n');
4439
4451
  htmlContent = htmlContent.replace('<body>', `<body>${compressTextScripts}`);
4440
- let outputPath = external_path_default().resolve(cwd, output);
4452
+ let outputPath = external_path_default().resolve(cwd, output || 'rsdoctor-diff.html');
4441
4453
  external_fs_default().mkdirSync(external_path_default().dirname(outputPath), {
4442
4454
  recursive: !0
4443
4455
  }), external_fs_default().writeFileSync(outputPath, htmlContent, 'utf-8'), spinner.succeed(`Generated standalone HTML file at: ${outputPath}`);
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import * as __rspack_external_tty from "tty";
12
12
  import url_0, * as __rspack_external_url from "url";
13
13
  import util, * as __rspack_external_util from "util";
14
14
  import { __webpack_require__ } from "./rslib-runtime.js";
15
- import { Algorithm, Manifest, Url } from "@rsdoctor/utils/common";
15
+ import { Algorithm, Graph, Manifest, Url } from "@rsdoctor/utils/common";
16
16
  import { Client, Constants, Manifest as types_Manifest, SDK } from "@rsdoctor/types";
17
17
  import { RsdoctorSDK } from "@rsdoctor/sdk";
18
18
  import ora from "ora";
@@ -1707,32 +1707,6 @@ __webpack_require__.add({
1707
1707
  };
1708
1708
  module.exports = createColors(), module.exports.createColors = createColors;
1709
1709
  },
1710
- "../../node_modules/.pnpm/proxy-from-env@1.1.0/node_modules/proxy-from-env/index.js" (__unused_rspack_module, exports, __webpack_require__) {
1711
- var parseUrl = __webpack_require__("url?f119").parse, DEFAULT_PORTS = {
1712
- ftp: 21,
1713
- gopher: 70,
1714
- http: 80,
1715
- https: 443,
1716
- ws: 80,
1717
- wss: 443
1718
- }, stringEndsWith = String.prototype.endsWith || function(s) {
1719
- return s.length <= this.length && -1 !== this.indexOf(s, this.length - s.length);
1720
- };
1721
- function getEnv(key) {
1722
- return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
1723
- }
1724
- exports.getProxyForUrl = function(url) {
1725
- var hostname, port, NO_PROXY, parsedUrl = 'string' == typeof url ? parseUrl(url) : url || {}, proto = parsedUrl.protocol, hostname1 = parsedUrl.host, port1 = parsedUrl.port;
1726
- if ('string' != typeof hostname1 || !hostname1 || 'string' != typeof proto) return '';
1727
- if (proto = proto.split(':', 1)[0], hostname = hostname1 = hostname1.replace(/:\d*$/, ''), port = port1 = parseInt(port1) || DEFAULT_PORTS[proto] || 0, !(!(NO_PROXY = (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase()) || '*' !== NO_PROXY && NO_PROXY.split(/[,\s]/).every(function(proxy) {
1728
- if (!proxy) return !0;
1729
- var parsedProxy = proxy.match(/^(.+):(\d+)$/), parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy, parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
1730
- return !!parsedProxyPort && parsedProxyPort !== port || (/^[.*]/.test(parsedProxyHostname) ? ('*' === parsedProxyHostname.charAt(0) && (parsedProxyHostname = parsedProxyHostname.slice(1)), !stringEndsWith.call(hostname, parsedProxyHostname)) : hostname !== parsedProxyHostname);
1731
- }))) return '';
1732
- var proxy = getEnv('npm_config_' + proto + '_proxy') || getEnv(proto + '_proxy') || getEnv('npm_config_proxy') || getEnv('all_proxy');
1733
- return proxy && -1 === proxy.indexOf('://') && (proxy = proto + '://' + proxy), proxy;
1734
- };
1735
- },
1736
1710
  "../../node_modules/.pnpm/supports-color@5.5.0/node_modules/supports-color/index.js" (module, __unused_rspack_exports, __webpack_require__) {
1737
1711
  let forceColor, os = __webpack_require__("os"), hasFlag = __webpack_require__("../../node_modules/.pnpm/has-flag@3.0.0/node_modules/has-flag/index.js"), env = process.env;
1738
1712
  function getSupportLevel(stream) {
@@ -2759,7 +2733,7 @@ function normalizeHeader(header) {
2759
2733
  return header && String(header).trim().toLowerCase();
2760
2734
  }
2761
2735
  function normalizeValue(value) {
2762
- return !1 === value || null == value ? value : utils.isArray(value) ? value.map(normalizeValue) : String(value);
2736
+ return !1 === value || null == value ? value : utils.isArray(value) ? value.map(normalizeValue) : String(value).replace(/[\r\n]+$/, '');
2763
2737
  }
2764
2738
  function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {
2765
2739
  if (utils.isFunction(filter)) return filter.call(this, value, header);
@@ -2957,6 +2931,17 @@ function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {
2957
2931
  let isRelativeUrl = !('string' == typeof requestedURL && /^([a-z][a-z\d+\-.]*:)?\/\//i.test(requestedURL));
2958
2932
  return baseURL && (isRelativeUrl || !1 == allowAbsoluteUrls) ? requestedURL ? baseURL.replace(/\/?\/$/, '') + '/' + requestedURL.replace(/^\/+/, '') : baseURL : requestedURL;
2959
2933
  }
2934
+ var DEFAULT_PORTS = {
2935
+ ftp: 21,
2936
+ gopher: 70,
2937
+ http: 80,
2938
+ https: 443,
2939
+ ws: 80,
2940
+ wss: 443
2941
+ };
2942
+ function getEnv(key) {
2943
+ return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || '';
2944
+ }
2960
2945
  function parseProtocol(url) {
2961
2946
  let match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
2962
2947
  return match && match[1] || '';
@@ -3105,7 +3090,7 @@ let helpers_speedometer = function(samplesCount, min) {
3105
3090
  }),
3106
3091
  throttled[1]
3107
3092
  ];
3108
- }, asyncDecorator = (fn)=>(...args)=>utils.asap(()=>fn(...args)), proxy_from_env = __webpack_require__("../../node_modules/.pnpm/proxy-from-env@1.1.0/node_modules/proxy-from-env/index.js"), follow_redirects = __webpack_require__("../../node_modules/.pnpm/follow-redirects@1.15.11/node_modules/follow-redirects/index.js"), zlibOptions = {
3093
+ }, asyncDecorator = (fn)=>(...args)=>utils.asap(()=>fn(...args)), follow_redirects = __webpack_require__("../../node_modules/.pnpm/follow-redirects@1.15.11/node_modules/follow-redirects/index.js"), zlibOptions = {
3109
3094
  flush: zlib.constants.Z_SYNC_FLUSH,
3110
3095
  finishFlush: zlib.constants.Z_SYNC_FLUSH
3111
3096
  }, brotliOptions = {
@@ -3132,7 +3117,10 @@ let helpers_speedometer = function(samplesCount, min) {
3132
3117
  if (removed) return;
3133
3118
  removed = !0;
3134
3119
  let entries = authoritySessions, len = entries.length, i = len;
3135
- for(; i--;)if (entries[i][0] === session) return void (1 === len ? delete this.sessions[authority] : entries.splice(i, 1));
3120
+ for(; i--;)if (entries[i][0] === session) {
3121
+ 1 === len ? delete this.sessions[authority] : entries.splice(i, 1), session.closed || session.close();
3122
+ return;
3123
+ }
3136
3124
  }, originalRequestFn = session.request, { sessionTimeout } = options;
3137
3125
  if (null != sessionTimeout) {
3138
3126
  let timer, streamsCount = 0;
@@ -3299,7 +3287,7 @@ let isHttpAdapterSupported = "u" > typeof process && 'process' === utils.kindOf(
3299
3287
  }
3300
3288
  if (-1 === supportedProtocols.indexOf(protocol)) return reject(new core_AxiosError('Unsupported protocol ' + protocol, core_AxiosError.ERR_BAD_REQUEST, config));
3301
3289
  let headers = AxiosHeaders.from(config.headers).normalize();
3302
- headers.set('User-Agent', "axios/1.13.6", !1);
3290
+ headers.set('User-Agent', "axios/1.14.0", !1);
3303
3291
  let { onUploadProgress, onDownloadProgress } = config, maxRate = config.maxRate;
3304
3292
  if (utils.isSpecCompliantForm(data)) {
3305
3293
  let userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i);
@@ -3322,7 +3310,7 @@ let isHttpAdapterSupported = "u" > typeof process && 'process' === utils.kindOf(
3322
3310
  })(data, (formHeaders)=>{
3323
3311
  headers.set(formHeaders);
3324
3312
  }, {
3325
- tag: "axios-1.13.6-boundary",
3313
+ tag: "axios-1.14.0-boundary",
3326
3314
  boundary: userBoundary && userBoundary[1] || void 0
3327
3315
  });
3328
3316
  } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {
@@ -3374,7 +3362,22 @@ let isHttpAdapterSupported = "u" > typeof process && 'process' === utils.kindOf(
3374
3362
  utils.isUndefined(lookup) || (options.lookup = lookup), config.socketPath ? options.socketPath = config.socketPath : (options.hostname = parsed.hostname.startsWith('[') ? parsed.hostname.slice(1, -1) : parsed.hostname, options.port = parsed.port, function setProxy(options, configProxy, location) {
3375
3363
  let proxy = configProxy;
3376
3364
  if (!proxy && !1 !== proxy) {
3377
- let proxyUrl = proxy_from_env.getProxyForUrl(location);
3365
+ let proxyUrl = function(url) {
3366
+ var hostname, port, NO_PROXY, parsedUrl = ('string' == typeof url ? function(urlString) {
3367
+ try {
3368
+ return new URL(urlString);
3369
+ } catch {
3370
+ return null;
3371
+ }
3372
+ }(url) : url) || {}, proto = parsedUrl.protocol, hostname1 = parsedUrl.host, port1 = parsedUrl.port;
3373
+ if ('string' != typeof hostname1 || !hostname1 || 'string' != typeof proto || (proto = proto.split(':', 1)[0], hostname = hostname1 = hostname1.replace(/:\d*$/, ''), port = port1 = parseInt(port1) || DEFAULT_PORTS[proto] || 0, !(!(NO_PROXY = getEnv('no_proxy').toLowerCase()) || '*' !== NO_PROXY && NO_PROXY.split(/[,\s]/).every(function(proxy) {
3374
+ if (!proxy) return !0;
3375
+ var parsedProxy = proxy.match(/^(.+):(\d+)$/), parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy, parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0;
3376
+ return !!parsedProxyPort && parsedProxyPort !== port || (/^[.*]/.test(parsedProxyHostname) ? ('*' === parsedProxyHostname.charAt(0) && (parsedProxyHostname = parsedProxyHostname.slice(1)), !hostname.endsWith(parsedProxyHostname)) : hostname !== parsedProxyHostname);
3377
+ })))) return '';
3378
+ var proxy = getEnv(proto + '_proxy') || getEnv('all_proxy');
3379
+ return proxy && -1 === proxy.indexOf('://') && (proxy = proto + '://' + proxy), proxy;
3380
+ }(location);
3378
3381
  proxyUrl && (proxy = new URL(proxyUrl));
3379
3382
  }
3380
3383
  if (proxy) {
@@ -3690,14 +3693,14 @@ let resolveConfig = (config)=>{
3690
3693
  }, globalFetchAPI, env), isFetchSupported = envFetch ? fetch_isFunction(envFetch) : 'function' == typeof fetch, isRequestSupported = fetch_isFunction(Request), isResponseSupported = fetch_isFunction(Response);
3691
3694
  if (!isFetchSupported) return !1;
3692
3695
  let isReadableStreamSupported = isFetchSupported && fetch_isFunction(fetch_ReadableStream), encodeText = isFetchSupported && ('function' == typeof fetch_TextEncoder ? (encoder = new fetch_TextEncoder(), (str)=>encoder.encode(str)) : async (str)=>new Uint8Array(await new Request(str).arrayBuffer())), supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(()=>{
3693
- let duplexAccessed = !1, hasContentType = new Request(platform.origin, {
3694
- body: new fetch_ReadableStream(),
3696
+ let duplexAccessed = !1, body = new fetch_ReadableStream(), hasContentType = new Request(platform.origin, {
3697
+ body,
3695
3698
  method: 'POST',
3696
3699
  get duplex () {
3697
3700
  return duplexAccessed = !0, 'half';
3698
3701
  }
3699
3702
  }).headers.has('Content-Type');
3700
- return duplexAccessed && !hasContentType;
3703
+ return body.cancel(), duplexAccessed && !hasContentType;
3701
3704
  }), supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(()=>utils.isReadableStream(new Response('').body)), resolvers = {
3702
3705
  stream: supportsResponseStream && ((res)=>res.body)
3703
3706
  };
@@ -3890,7 +3893,7 @@ let validators = {};
3890
3893
  let deprecatedWarnings = {};
3891
3894
  validators.transitional = function(validator, version, message) {
3892
3895
  function formatMessage(opt, desc) {
3893
- return "[Axios v1.13.6] Transitional option '" + opt + "'" + desc + (message ? '. ' + message : '');
3896
+ return "[Axios v1.14.0] Transitional option '" + opt + "'" + desc + (message ? '. ' + message : '');
3894
3897
  }
3895
3898
  return (value, opt, opts)=>{
3896
3899
  if (!1 === validator) throw new core_AxiosError(formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), core_AxiosError.ERR_DEPRECATED);
@@ -4199,7 +4202,7 @@ async function loadShardingFile(uri, cwd) {
4199
4202
  async function loadShardingFileWithSpinner(uri, cwd, spinner) {
4200
4203
  return loadShardingFile(uri, cwd).then((res)=>(spinner.text = `loaded "${uri}"`, res));
4201
4204
  }
4202
- axios.Axios = Axios, axios.CanceledError = cancel_CanceledError, axios.CancelToken = CancelToken, axios.isCancel = isCancel, axios.VERSION = "1.13.6", axios.toFormData = helpers_toFormData, axios.AxiosError = core_AxiosError, axios.Cancel = axios.CanceledError, axios.all = function(promises) {
4205
+ axios.Axios = Axios, axios.CanceledError = cancel_CanceledError, axios.CancelToken = CancelToken, axios.isCancel = isCancel, axios.VERSION = "1.14.0", axios.toFormData = helpers_toFormData, axios.AxiosError = core_AxiosError, axios.Cancel = axios.CanceledError, axios.all = function(promises) {
4203
4206
  return Promise.all(promises);
4204
4207
  }, axios.spread = function(callback) {
4205
4208
  return function(arr) {
@@ -4208,7 +4211,7 @@ axios.Axios = Axios, axios.CanceledError = cancel_CanceledError, axios.CancelTok
4208
4211
  }, axios.isAxiosError = function(payload) {
4209
4212
  return utils.isObject(payload) && !0 === payload.isAxiosError;
4210
4213
  }, axios.mergeConfig = mergeConfig, axios.AxiosHeaders = AxiosHeaders, axios.formToJSON = (thing)=>helpers_formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing), axios.getAdapter = adapters_adapters_getAdapter, axios.HttpStatusCode = HttpStatusCode, axios.default = axios;
4211
- var package_namespaceObject = JSON.parse('{"name":"@rsdoctor/cli","version":"1.5.6","repository":{"type":"git","url":"https://github.com/web-infra-dev/rsdoctor","directory":"packages/cli"},"bin":{"rsdoctor":"./bin/rsdoctor"},"files":["bin","dist"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.cjs"}},"license":"MIT","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"dev":"npm run start","build":"rslib build","start":"rslib build -w","test":"rstest run"},"type":"module","dependencies":{"ora":"^5.4.1","@rsdoctor/sdk":"workspace:*","@rsdoctor/types":"workspace:*","@rsdoctor/utils":"workspace:*","@rsdoctor/graph":"workspace:*"},"devDependencies":{"@rsdoctor/client":"workspace:*","cac":"^7.0.0","typescript":"^5.9.2","axios":"^1.13.6","picocolors":"^1.1.1"},"peerDependencies":{"@rsdoctor/client":"workspace:*"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"}}');
4214
+ var package_namespaceObject = JSON.parse('{"name":"@rsdoctor/cli","version":"1.5.7","repository":{"type":"git","url":"https://github.com/web-infra-dev/rsdoctor","directory":"packages/cli"},"bin":{"rsdoctor":"./bin/rsdoctor"},"files":["bin","dist"],"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.cjs"}},"license":"MIT","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"dev":"npm run start","build":"rslib build","start":"rslib build -w","test":"rstest run"},"type":"module","dependencies":{"ora":"^5.4.1","@rsdoctor/sdk":"workspace:*","@rsdoctor/types":"workspace:*","@rsdoctor/utils":"workspace:*","@rsdoctor/graph":"workspace:*"},"devDependencies":{"@rsdoctor/client":"workspace:*","cac":"^7.0.0","typescript":"^5.9.2","axios":"1.14.0","picocolors":"^1.1.1"},"peerDependencies":{"@rsdoctor/client":"workspace:*"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"}}');
4212
4215
  let constants_bin = Object.keys(package_namespaceObject.bin)[0], picocolors = __webpack_require__("../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"), analyze = (fn = ({ cwd, name, bin })=>({
4213
4216
  command: "analyze",
4214
4217
  description: `
@@ -4256,9 +4259,9 @@ use ${name} to open the bundle diff result in browser for analysis.
4256
4259
  example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4257
4260
  `.trim(),
4258
4261
  options (cli) {
4259
- cli.option('--current <path>', 'the url or file path of the profile json as the current').option('--baseline <path>', 'the url or file path of the profile json as the baseline').option('--html', 'output as a standalone HTML file').option('--output <path>', 'output file path for HTML mode (default: rsdoctor-diff.html)');
4262
+ cli.option('--current <path>', 'the url or file path of the profile json as the current').option('--baseline <path>', 'the url or file path of the profile json as the baseline').option('--html', 'output as a standalone HTML file').option('--json [path]', 'output as a JSON file, optionally specify file path (default: rsdoctor-diff.json)').option('--output <path>', 'output file path for HTML mode (default: rsdoctor-diff.html). For JSON output, use --json [path] to specify the file path.');
4260
4263
  },
4261
- async action ({ baseline, current, open = !0, html = !1, output = 'rsdoctor-diff.html' }) {
4264
+ async action ({ baseline, current, open = !0, html = !1, json = !1, output }) {
4262
4265
  let baselineDataValue, currentDataValue, spinner = ora({
4263
4266
  prefixText: (0, picocolors.cyan)(`[${name}]`)
4264
4267
  }).start();
@@ -4288,6 +4291,16 @@ example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4288
4291
  if (currentData.cloudData) spinner.text = 'load the "currentData.cloudData" instead of the "currentData.data"', currentDataValue = await Manifest.fetchShardingFiles(currentData.cloudData, (url)=>loadShardingFileWithSpinner(url, cwd, spinner));
4289
4292
  else throw spinner.fail((0, picocolors.red)(error.message)), error;
4290
4293
  }
4294
+ if (json && html) return spinner.fail((0, picocolors.red)('Options "--json" and "--html" cannot be used together. Please choose one.')), null;
4295
+ if (json) {
4296
+ spinner.text = 'Generating JSON output file...';
4297
+ let outputPath = path_0.resolve(cwd, 'string' == typeof json ? json : output || 'rsdoctor-diff.json');
4298
+ fs.mkdirSync(path_0.dirname(outputPath), {
4299
+ recursive: !0
4300
+ });
4301
+ let jsonData = Graph.getBundleDiffResult(baselineDataValue, currentDataValue);
4302
+ return fs.writeFileSync(outputPath, JSON.stringify(jsonData, null, 2), 'utf-8'), spinner.succeed(`Generated JSON output file at: ${outputPath}`), null;
4303
+ }
4291
4304
  if (!html) {
4292
4305
  spinner.text = "start server";
4293
4306
  let baselineSdk = new RsdoctorSDK({
@@ -4348,7 +4361,7 @@ example: ${bin} bundle-diff --baseline="x.json" --current="x.json"
4348
4361
  `window.${Constants.WINDOW_RSDOCTOR_TAG}.mode = 'diff';`
4349
4362
  ].map((script)=>`<script>${script}</script>`).join('\n');
4350
4363
  htmlContent = htmlContent.replace('<body>', `<body>${compressTextScripts}`);
4351
- let outputPath = path_0.resolve(cwd, output);
4364
+ let outputPath = path_0.resolve(cwd, output || 'rsdoctor-diff.html');
4352
4365
  fs.mkdirSync(path_0.dirname(outputPath), {
4353
4366
  recursive: !0
4354
4367
  }), fs.writeFileSync(outputPath, htmlContent, 'utf-8'), spinner.succeed(`Generated standalone HTML file at: ${outputPath}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdoctor/cli",
3
- "version": "1.5.6",
3
+ "version": "1.5.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/rsdoctor",
@@ -26,20 +26,20 @@
26
26
  "type": "module",
27
27
  "dependencies": {
28
28
  "ora": "^5.4.1",
29
- "@rsdoctor/sdk": "1.5.6",
30
- "@rsdoctor/types": "1.5.6",
31
- "@rsdoctor/utils": "1.5.6",
32
- "@rsdoctor/graph": "1.5.6"
29
+ "@rsdoctor/sdk": "1.5.7",
30
+ "@rsdoctor/utils": "1.5.7",
31
+ "@rsdoctor/types": "1.5.7",
32
+ "@rsdoctor/graph": "1.5.7"
33
33
  },
34
34
  "devDependencies": {
35
35
  "cac": "^7.0.0",
36
36
  "typescript": "^5.9.2",
37
- "axios": "^1.13.6",
37
+ "axios": "1.14.0",
38
38
  "picocolors": "^1.1.1",
39
- "@rsdoctor/client": "1.5.6"
39
+ "@rsdoctor/client": "1.5.7"
40
40
  },
41
41
  "peerDependencies": {
42
- "@rsdoctor/client": "1.5.6"
42
+ "@rsdoctor/client": "1.5.7"
43
43
  },
44
44
  "publishConfig": {
45
45
  "access": "public",