react-native-bundle-discovery-ui 2.6.0 → 2.7.0

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.
@@ -1,58 +1,39 @@
1
- const { FoamTree } = require("../vendors/foamtree.js");
2
-
1
+ let vendors_foamtree_js = require("../../../vendors/foamtree.js");
2
+ //#region src/client/views/foamtree.ts
3
3
  function injectTooltip(root) {
4
4
  const t = root.querySelector(".tooltip");
5
5
  if (t) return t;
6
-
7
6
  const tooltip = document.createElement("div");
8
7
  tooltip.className = "tooltip";
9
8
  tooltip.id = "foamtree-tooltip";
10
9
  root.appendChild(tooltip);
11
10
  return tooltip;
12
11
  }
13
-
14
12
  function prependDuplicateTo(label) {
15
- if (label.includes(" ~ ")) {
16
- return "<b class='i-duplicate'>Duplicate</b> " + label.split(" ~ ")[1];
17
- }
13
+ if (label.includes(" ~ "))
14
+ return `<b class='i-duplicate'>Duplicate</b> ${label.split(" ~ ")[1]}`;
18
15
  return label;
19
16
  }
20
-
21
- // Based on https://github.com/webpack-contrib/webpack-bundle-analyzer/blob/master/client/components/Treemap.jsx
22
- discovery.view.define("foamtree", function (el, config, rawData, context) {
23
- if (Array.isArray(rawData?.options?.series)) {
17
+ discovery.view.define("foamtree", (el, _config, rawData, context) => {
18
+ if (Array.isArray(rawData?.options?.series))
24
19
  rawData.options.series.forEach((e) => {
25
- if (e.data?.[0]?.value !== undefined) {
26
- // mutate data by link
20
+ if (e.data?.[0]?.value !== void 0)
27
21
  e.data = e.data.map((d) => d.value ?? null);
28
- }
29
22
  });
30
- }
31
-
32
- // console.log({ rawData });
33
-
34
- // Render after element will be added to the DOM
35
- // to avoid "FoamTree: element has zero dimensions: 0 x 0" error
36
23
  setTimeout(() => {
37
24
  try {
38
- // Dirty hack to fix shadow DOM issue, xd
39
25
  window.__el = el;
40
-
41
26
  const root = el.closest(".discovery-root");
42
27
  const tooltip = injectTooltip(root);
43
-
44
28
  window.addEventListener("resize", () => ft.resize(), { passive: true });
45
-
46
29
  root.addEventListener(
47
30
  "mousemove",
48
31
  (event) => {
49
32
  if (tooltip.style.display === "none") return;
50
- tooltip.style.left = event.pageX + 10 + "px";
51
- tooltip.style.top = event.pageY + 10 + "px";
52
- },
53
- {
54
- passive: true,
33
+ tooltip.style.left = `${event.pageX + 10}px`;
34
+ tooltip.style.top = `${event.pageY + 10}px`;
55
35
  },
36
+ { passive: true },
56
37
  );
57
38
  el.addEventListener("mouseover", () => {
58
39
  tooltip.style.display = "block";
@@ -60,8 +41,7 @@ discovery.view.define("foamtree", function (el, config, rawData, context) {
60
41
  el.addEventListener("mouseout", () => {
61
42
  tooltip.style.display = "none";
62
43
  });
63
-
64
- const ft = new FoamTree({
44
+ const ft = new vendors_foamtree_js.FoamTree({
65
45
  element: el,
66
46
  layout: "squarified",
67
47
  stacking: "flattened",
@@ -85,14 +65,10 @@ discovery.view.define("foamtree", function (el, config, rawData, context) {
85
65
  },
86
66
  onGroupDoubleClick: (e) => e.preventDefault(),
87
67
  onGroupHover(event) {
88
- // Ignoring hovering on `FoamTree` branding group and the root group
89
- if (event.group && event.group === rawData.options.dataObject) {
68
+ if (event.group && event.group === rawData.options.dataObject)
90
69
  return event.preventDefault();
91
- }
92
-
93
70
  const { group } = event;
94
-
95
- if (group && group.type) {
71
+ if (group?.type) {
96
72
  const htmlContent = [
97
73
  `<b class="tooltip-name">${group.type}</b>: ${prependDuplicateTo(group.label)}`,
98
74
  `<b>Size</b>: ${group.size}`,
@@ -101,22 +77,12 @@ discovery.view.define("foamtree", function (el, config, rawData, context) {
101
77
  ]
102
78
  .filter((e) => !!e)
103
79
  .join("<br/>");
104
-
105
80
  tooltip.style.display = "block";
106
81
  tooltip.innerHTML = htmlContent;
107
82
  } else {
108
83
  tooltip.style.display = "none";
109
84
  tooltip.innerHTML = "";
110
85
  }
111
-
112
- // if (group) {
113
- // this.setState({
114
- // showTooltip: true,
115
- // tooltipContent: this.getTooltipContent(group)
116
- // });
117
- // } else {
118
- // this.setState({showTooltip: false});
119
- // }
120
86
  },
121
87
  ...rawData.options,
122
88
  });
@@ -134,3 +100,4 @@ discovery.view.define("foamtree", function (el, config, rawData, context) {
134
100
  }
135
101
  }, 0);
136
102
  });
103
+ //#endregion
@@ -0,0 +1,33 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.js");
2
+ const require_views__theme = require("./_theme.js");
3
+ let vendors_highcharts_js = require("../../../vendors/highcharts.js");
4
+ vendors_highcharts_js = require_runtime.__toESM(vendors_highcharts_js);
5
+ require("../../../vendors/highcharts-networkgraph.js");
6
+ require("../../../vendors/highcharts-exporting.js");
7
+ //#region src/client/views/highcharts.ts
8
+ discovery.view.define("highcharts", (el, _config, rawData, context) => {
9
+ require_views__theme.doTheming(el);
10
+ if (Array.isArray(rawData?.options?.series))
11
+ rawData.options.series.forEach((e) => {
12
+ if (e.data?.[0]?.value !== void 0)
13
+ e.data = e.data.map((d) => d.value ?? null);
14
+ });
15
+ try {
16
+ vendors_highcharts_js.default.chart(
17
+ el,
18
+ vendors_highcharts_js.default.merge({}, rawData.options),
19
+ );
20
+ } catch (e) {
21
+ console.error(e, rawData);
22
+ discovery.view.render(
23
+ el,
24
+ {
25
+ view: "alert-danger",
26
+ data: '"Error rendering chart, please check the console for more information."',
27
+ },
28
+ rawData,
29
+ context,
30
+ );
31
+ }
32
+ });
33
+ //#endregion
@@ -1,3 +1,4 @@
1
+ //#region src/client/views/prettify.ts
1
2
  discovery.view.define(
2
3
  "source-prettify",
3
4
  async function renderPrettify(el, config, data, context) {
@@ -15,3 +16,4 @@ discovery.view.define(
15
16
  );
16
17
  },
17
18
  );
19
+ //#endregion
@@ -0,0 +1,26 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ let node_path = require("node:path");
3
+ node_path = require_rolldown_runtime.__toESM(node_path);
4
+ //#region src/discoveryrc.ts
5
+ const config = {
6
+ name: "react-native-bundle-discovery",
7
+ data: () =>
8
+ require(
9
+ node_path.default.resolve(__dirname, "../../../tmp/metro-stats.json"),
10
+ ),
11
+ setup: node_path.default.resolve(__dirname, "client/setup.js"),
12
+ view: {
13
+ assets: [
14
+ node_path.default.resolve(__dirname, "../assets/global.css"),
15
+ node_path.default.resolve(__dirname, "client/pages/default.js"),
16
+ node_path.default.resolve(__dirname, "client/pages/module.js"),
17
+ node_path.default.resolve(__dirname, "client/pages/package.js"),
18
+ node_path.default.resolve(__dirname, "../assets/highcharts.css"),
19
+ node_path.default.resolve(__dirname, "client/views/prettify.js"),
20
+ node_path.default.resolve(__dirname, "client/views/highcharts.js"),
21
+ node_path.default.resolve(__dirname, "client/views/foamtree.js"),
22
+ ],
23
+ },
24
+ };
25
+ //#endregion
26
+ module.exports = config;
@@ -0,0 +1,42 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if ((from && typeof from === "object") || typeof from === "function")
10
+ for (
11
+ var keys = __getOwnPropNames(from), i = 0, n = keys.length, key;
12
+ i < n;
13
+ i++
14
+ ) {
15
+ key = keys[i];
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, {
18
+ get: ((k) => from[k]).bind(null, key),
19
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
20
+ });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (
25
+ (target = mod != null ? __create(__getProtoOf(mod)) : {}),
26
+ __copyProps(
27
+ isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default")
28
+ ? __defProp(target, "default", {
29
+ value: mod,
30
+ enumerable: true,
31
+ })
32
+ : target,
33
+ mod,
34
+ )
35
+ );
36
+ //#endregion
37
+ Object.defineProperty(exports, "__toESM", {
38
+ enumerable: true,
39
+ get: function () {
40
+ return __toESM;
41
+ },
42
+ });
@@ -1,5 +1,7 @@
1
- const { resolve } = require("path");
2
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("./src-BSLX-He2.js");
3
+ let node_path = require("node:path");
4
+ //#region ../shared/src/rsdoctor.ts
3
5
  const possibleEntryFiles = [
4
6
  "index.js",
5
7
  "index.jsx",
@@ -8,91 +10,61 @@ const possibleEntryFiles = [
8
10
  "index.mjs",
9
11
  "index.cjs",
10
12
  ];
11
-
12
13
  const doStructureCheck = (rsdoctorData) => {
13
14
  if (!(
14
15
  Array.isArray(rsdoctorData?.data?.configs) &&
15
16
  rsdoctorData.data.configs.length === 1
16
- )) {
17
+ ))
17
18
  throw new Error(
18
19
  `Unexpected number of "data.configs[]" in rsdoctor-data.json. Work only with single config. Found: ${rsdoctorData?.data?.configs?.length}`,
19
20
  );
20
- }
21
-
22
- if (!Array.isArray(rsdoctorData?.data?.packageGraph?.packages)) {
21
+ if (!Array.isArray(rsdoctorData?.data?.packageGraph?.packages))
23
22
  throw new Error(
24
23
  `Unexpected "data.packageGraph.packages[]" in rsdoctor-data.json. Expected array. Found: ${typeof rsdoctorData?.data?.packageGraph?.packages}`,
25
24
  );
26
- }
27
-
28
25
  const firstConfig = rsdoctorData.data.configs[0];
29
-
30
- if (!(firstConfig.name === "rspack" || firstConfig.name === "webpack")) {
26
+ if (!(firstConfig.name === "rspack" || firstConfig.name === "webpack"))
31
27
  throw new Error(
32
28
  `Unsupported bundler: ${firstConfig.name}@${firstConfig.version}. Only 'rspack' and 'webpack' are supported.`,
33
29
  );
34
- }
35
30
  };
36
-
37
31
  const getDependenciesMap = (rsdoctorData) => {
38
- const depsMap = new Map(
32
+ return new Map(
39
33
  rsdoctorData.data.moduleGraph.dependencies.map((dep) => [dep.id, dep]),
40
34
  );
41
- return depsMap;
42
35
  };
43
-
44
36
  const getEntryFile = (rsdoctorData) => {
45
- const firstConfig = rsdoctorData?.data?.configs?.[0];
46
- const entry = firstConfig?.config?.entry;
37
+ const firstConfig = rsdoctorData.data.configs[0];
38
+ const main = firstConfig.config.entry?.main;
47
39
  const entryFile =
48
- typeof entry?.main === "string"
49
- ? entry.main
50
- : typeof entry?.main?.import === "string"
51
- ? entry.main.import
52
- : entry?.main.import[0];
53
-
54
- if (entryFile) {
55
- return resolve(firstConfig.root, entryFile);
56
- }
57
-
40
+ typeof main === "string"
41
+ ? main
42
+ : typeof main?.import === "string"
43
+ ? main.import
44
+ : main?.import[0];
45
+ if (entryFile) return (0, node_path.resolve)(firstConfig.root, entryFile);
58
46
  const pathsToCheck = possibleEntryFiles.map((f) =>
59
- resolve(firstConfig.root, f),
47
+ (0, node_path.resolve)(firstConfig.root, f),
60
48
  );
61
49
  const indexFile = rsdoctorData.data.moduleGraph.modules.find((mdl) =>
62
50
  pathsToCheck.some((entry) => mdl.path === entry),
63
51
  );
64
-
65
- if (indexFile && indexFile.imported?.length === 0) {
66
- return indexFile.path;
67
- }
68
-
52
+ if (indexFile && indexFile.imported?.length === 0) return indexFile.path;
69
53
  return `${firstConfig.root}/index.js`;
70
54
  };
71
-
72
55
  const transformRSDoctorData = (rsdoctorData) => {
73
56
  doStructureCheck(rsdoctorData);
74
57
  const tmpDependenciesMap = getDependenciesMap(rsdoctorData);
75
58
  const firstConfig = rsdoctorData.data.configs[0];
76
59
  return {
77
- date: Date.now(), // no info in rspack report
60
+ date: Date.now(),
78
61
  entryPoint: getEntryFile(rsdoctorData),
79
62
  rootFolder: firstConfig.root,
80
- // envs: {},
81
63
  transformOptions: {
82
- // customTransformOptions: {},
83
64
  dev: firstConfig.config.mode !== "production",
84
65
  minify: firstConfig.config.optimization?.minimize ?? false,
85
66
  platform: firstConfig.config.name ?? "ios",
86
- // type: "module",
87
- // unstable_transformProfile: "default",
88
67
  },
89
- // Example of package:
90
- // {
91
- // name: "@react-native/js-polyfills",
92
- // absolutePath:
93
- // "/Users/xd/tmp/RN84/node_modules/@react-native/js-polyfills",
94
- // version: "0.84.1",
95
- // }
96
68
  packages: rsdoctorData.data.packageGraph.packages.map((pkg) => ({
97
69
  name: pkg.name,
98
70
  absolutePath: pkg.root,
@@ -100,31 +72,11 @@ const transformRSDoctorData = (rsdoctorData) => {
100
72
  source: { sizeInBytes: pkg.size?.sourceSize ?? 1 },
101
73
  output: { sizeInBytes: pkg.size?.parsedSize ?? 1 },
102
74
  })),
103
- // Example of module:
104
- // {
105
- // "path": "/Users/xd/tmp/RN84/node_modules/react-native/Libraries/BatchedBridge/BatchedBridge.js",
106
- // "source": {
107
- // "code": "",
108
- // "lineCount": 32,
109
- // "sizeInBytes": 954
110
- // },
111
- // "output": {
112
- // "code": "",
113
- // "lineCount": 1,
114
- // "sizeInBytes": 219
115
- // },
116
- // "dependencies": [
117
- // {
118
- // "absolutePath": "/Users/xd/tmp/RN84/node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js",
119
- // "name": "./MessageQueue"
120
- // }
121
- // ]
122
- // },
123
75
  modules: rsdoctorData.data.moduleGraph.modules.map((mdl) => ({
124
76
  path: mdl.path,
125
77
  source: {
126
- code: "", // no code in rspack report
127
- lineCount: 0, // no code to count lines in rspack report
78
+ code: "",
79
+ lineCount: 0,
128
80
  sizeInBytes: mdl.size?.sourceSize ?? 0,
129
81
  },
130
82
  output: {
@@ -136,14 +88,15 @@ const transformRSDoctorData = (rsdoctorData) => {
136
88
  .map((depNumId) => {
137
89
  const dep = tmpDependenciesMap.get(depNumId);
138
90
  return dep
139
- ? { absolutePath: dep.resolvedRequest, name: dep.request }
91
+ ? {
92
+ absolutePath: dep.resolvedRequest,
93
+ name: dep.request,
94
+ }
140
95
  : null;
141
96
  })
142
97
  .filter((e) => e !== null),
143
98
  })),
144
99
  };
145
100
  };
146
-
147
- module.exports = {
148
- transformRSDoctorData,
149
- };
101
+ //#endregion
102
+ exports.transformRSDoctorData = transformRSDoctorData;
@@ -1,14 +1,7 @@
1
- const chalk = require("chalk");
2
-
3
- const isRsdoctorReportPath = (reportPath) => {
4
- try {
5
- const reportJson = require(reportPath);
6
- return isRsdoctorReport(reportJson, reportPath);
7
- } catch {
8
- return false;
9
- }
10
- };
11
-
1
+ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.js");
2
+ let chalk = require("chalk");
3
+ chalk = require_rolldown_runtime.__toESM(chalk);
4
+ //#region ../shared/src/isRsdoctorReport.ts
12
5
  const isRsdoctorReport = (reportJson, reportPath, noLogs) => {
13
6
  try {
14
7
  if (
@@ -17,7 +10,7 @@ const isRsdoctorReport = (reportJson, reportPath, noLogs) => {
17
10
  ) {
18
11
  !noLogs &&
19
12
  console.info(
20
- `Detected ${chalk.red("rsdoctor")} format in the input file: ${chalk.green(reportPath)}`,
13
+ `Detected ${chalk.default.red("rsdoctor")} format in the input file: ${chalk.default.green(reportPath)}`,
21
14
  );
22
15
  return true;
23
16
  }
@@ -26,8 +19,18 @@ const isRsdoctorReport = (reportJson, reportPath, noLogs) => {
26
19
  return false;
27
20
  }
28
21
  };
29
-
30
- module.exports = {
31
- isRsdoctorReport,
32
- isRsdoctorReportPath,
22
+ const isRsdoctorReportPath = (reportPath) => {
23
+ try {
24
+ const reportJson = require(reportPath);
25
+ return isRsdoctorReport(reportJson, reportPath);
26
+ } catch {
27
+ return false;
28
+ }
33
29
  };
30
+ //#endregion
31
+ Object.defineProperty(exports, "isRsdoctorReportPath", {
32
+ enumerable: true,
33
+ get: function () {
34
+ return isRsdoctorReportPath;
35
+ },
36
+ });
package/package.json CHANGED
@@ -1,18 +1,27 @@
1
1
  {
2
2
  "name": "react-native-bundle-discovery-ui",
3
- "version": "2.6.0",
4
- "main": "lib/bin.js",
5
- "bin": "lib/bin.js",
6
- "repository": "git@github.com:retyui/react-native-bundle-discovery.git",
3
+ "version": "2.7.0",
4
+ "description": "Browser UI for React Native bundle reports",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/retyui/react-native-bundle-discovery.git",
8
+ "directory": "packages/ui"
9
+ },
7
10
  "author": "David <4661784+retyui@users.noreply.github.com>",
8
11
  "license": "MIT",
12
+ "main": "./dist/bin.js",
13
+ "bin": "./dist/bin.js",
14
+ "files": [
15
+ "dist",
16
+ "!dist/.tmp.js",
17
+ "assets",
18
+ "vendors"
19
+ ],
9
20
  "scripts": {
10
- "srv": "node ./lib/bin.js server",
11
- "analyze": "node ./_cli/bin.js analyze",
12
- "tmp": "yarn srv /Users/davyd.narbutovich/tmp/RNDiscovery/metro-stats.json",
13
- "format": "prettier --write .",
14
- "start": "NODE_ENV=development npx discovery --config .discoveryrc.js",
15
- "build": "npx discovery-build --config .discoveryrc.js --output build --serve-only-assets --single-file"
21
+ "build": "run -T tsdown && run -T prettier --write --log-level warn --ignore-path= \"dist/**/*.js\"",
22
+ "typecheck": "run -T tsc -p tsconfig.json && run -T tsc -p src/client/tsconfig.json",
23
+ "dev": "run -T tsdown && NODE_ENV=development discovery --config dist/discoveryrc.js",
24
+ "prepack": "cp ../../README.md README.md"
16
25
  },
17
26
  "dependencies": {
18
27
  "@discoveryjs/cli": "2.14.7",
@@ -21,29 +30,19 @@
21
30
  "minimist": "^1.2.8",
22
31
  "prettier": "^3.9.6"
23
32
  },
33
+ "devDependencies": {
34
+ "@react-native-bundle-discovery/shared": "0.0.0",
35
+ "@types/minimist": "^1.2.5"
36
+ },
24
37
  "peerDependencies": {
25
- "metro": "*"
38
+ "metro": ">=0.68.0"
26
39
  },
27
40
  "peerDependenciesMeta": {
28
41
  "metro": {
29
42
  "optional": true
30
43
  }
31
44
  },
32
- "files": [
33
- "vendors",
34
- "lib",
35
- "!lib/.tmp.js",
36
- "views",
37
- "pages",
38
- "index.js",
39
- "setup.js",
40
- "prepare.js",
41
- "queryHelpers.js",
42
- ".discoveryrc.js"
43
- ],
44
- "packageManager": "yarn@4.18.0",
45
- "devDependencies": {
46
- "acorn": "^8.18.0",
47
- "acorn-walk": "^8.3.5"
45
+ "publishConfig": {
46
+ "access": "public"
48
47
  }
49
- }
48
+ }
package/.discoveryrc.js DELETED
@@ -1,22 +0,0 @@
1
- const path = require("path");
2
-
3
- module.exports = {
4
- name: "react-native-bundle-discovery",
5
- data: () => require("./tmp/metro-stats.json"),
6
- setup: path.resolve(__dirname, "setup.js"),
7
- view: {
8
- assets: [
9
- // Global styles
10
- path.resolve(__dirname, "views/global.css"),
11
- // Pages
12
- path.resolve(__dirname, "pages/default.js"),
13
- path.resolve(__dirname, "pages/module.js"),
14
- path.resolve(__dirname, "pages/package.js"),
15
- // Custom views
16
- path.resolve(__dirname, "views/highcharts.css"),
17
- path.resolve(__dirname, "views/prettify.js"),
18
- path.resolve(__dirname, "views/highcharts.js"),
19
- path.resolve(__dirname, "views/foamtree.js"),
20
- ],
21
- },
22
- };
package/lib/bin.js DELETED
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env node
2
- const minimist = require("minimist");
3
-
4
- function printHelp() {
5
- console.log(`react-native-bundle-discovery-ui
6
-
7
- Usage:
8
- react-native-bundle-discovery-ui <file> [port] [--verbose] # <- server can be omitted
9
- react-native-bundle-discovery-ui server <file> [port] [--verbose]
10
-
11
- react-native-bundle-discovery-ui build <file> [--output <path>] [--clean] [--single-file] [--verbose]
12
-
13
- Commands:
14
- server <file> [port] Run a web server to show a Metro bundler stat report
15
- build <file> Build a HTML report from the Metro bundler stat file
16
-
17
- Options:
18
- -v, --verbose Run with verbose logging
19
- -o, --output <path> Path for a build result (default: .bundle-discovery)
20
- -c, --clean Clean output directory before writing build files (default: true)
21
- -s, --single-file Output report build as a single HTML file (default: true)
22
- -p, --port <port> Port for server command (same as [port], default: 8079)
23
- -h, --help Show help
24
- `);
25
- }
26
-
27
- function fail(message) {
28
- console.error(message);
29
- console.error("Use --help to see usage.");
30
- process.exit(1);
31
- }
32
-
33
- const argv = minimist(process.argv.slice(2), {
34
- alias: {
35
- v: "verbose",
36
- h: "help",
37
- o: "output",
38
- c: "clean",
39
- s: "single-file",
40
- p: "port",
41
- },
42
- boolean: ["verbose", "help", "clean", "single-file"],
43
- string: ["output"],
44
- default: {
45
- clean: true,
46
- "single-file": true,
47
- },
48
- });
49
-
50
- const command = argv._[0];
51
- const isServerCommand = command === "server";
52
- const isBuildCommand = command === "build";
53
- const isImplicitServerCommand =
54
- Boolean(command) && !isServerCommand && !isBuildCommand;
55
-
56
- if (argv.help || !command) {
57
- printHelp();
58
- process.exit(0);
59
- }
60
-
61
- if (isServerCommand || isImplicitServerCommand) {
62
- const file = isImplicitServerCommand ? argv._[0] : argv._[1];
63
- if (!file) {
64
- fail("Missing required argument: <file>");
65
- }
66
-
67
- const rawPort =
68
- argv.port ?? (isImplicitServerCommand ? argv._[1] : argv._[2]) ?? 8079;
69
- const port = Number(rawPort);
70
- if (!Number.isFinite(port)) {
71
- fail(`Invalid port: ${rawPort}`);
72
- }
73
-
74
- const { serve } = require("./server.js");
75
- return serve(file, port, Boolean(argv.verbose));
76
- }
77
-
78
- if (isBuildCommand) {
79
- const file = argv._[1];
80
- if (!file) {
81
- fail("Missing required argument: <file>");
82
- }
83
-
84
- const { buildHtmlPage } = require("./build.js");
85
- return buildHtmlPage(
86
- file,
87
- argv.output,
88
- argv.clean,
89
- argv["single-file"],
90
- Boolean(argv.verbose),
91
- );
92
- }
93
-
94
- fail(`Unknown command: ${command}`);