@node-cli/bundlecheck 1.1.1 → 1.2.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.
- package/README.md +20 -0
- package/dist/bundlecheck.js +12 -4
- package/dist/bundlecheck.js.map +1 -1
- package/dist/bundler.d.ts +1 -0
- package/dist/bundler.js +33 -5
- package/dist/bundler.js.map +1 -1
- package/dist/defaults.d.ts +2 -0
- package/dist/defaults.js +3 -1
- package/dist/defaults.js.map +1 -1
- package/dist/parse.d.ts +1 -0
- package/dist/parse.js +10 -0
- package/dist/parse.js.map +1 -1
- package/dist/trend.d.ts +1 -0
- package/dist/trend.js +40 -21
- package/dist/trend.js.map +1 -1
- package/dist/versions.d.ts +5 -1
- package/dist/versions.js +12 -2
- package/dist/versions.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ A CLI tool to check the bundle size of npm packages, similar to [bundlephobia.co
|
|
|
13
13
|
- Support for checking specific exports (tree-shaking)
|
|
14
14
|
- Automatic externalization of React and React-DOM
|
|
15
15
|
- Raw and gzip sizes with configurable compression level
|
|
16
|
+
- Custom npm registry support (for private registries)
|
|
16
17
|
- Fast bundling using esbuild (with pnpm support)
|
|
17
18
|
|
|
18
19
|
## Installation
|
|
@@ -101,6 +102,7 @@ bundlecheck lodash "debounce,throttle"
|
|
|
101
102
|
| `--gzipLevel <n>` | `-g <n>` | Gzip compression level (1-9, default: 5) |
|
|
102
103
|
| `--external <pkgs>` | `-e <pkgs>` | Comma-separated additional packages to mark as external |
|
|
103
104
|
| `--noExternal` | `-n` | Do not mark any packages as external |
|
|
105
|
+
| `--registry <url>` | `-r <url>` | Custom npm registry URL (default: registry.npmjs.org) |
|
|
104
106
|
|
|
105
107
|
### Examples
|
|
106
108
|
|
|
@@ -132,6 +134,9 @@ bundlecheck lodash --trend
|
|
|
132
134
|
|
|
133
135
|
# Show bundle size trend for 3 versions
|
|
134
136
|
bundlecheck lodash --trend 3
|
|
137
|
+
|
|
138
|
+
# Use a custom npm registry
|
|
139
|
+
bundlecheck @myorg/private-pkg --registry https://npm.mycompany.com
|
|
135
140
|
```
|
|
136
141
|
|
|
137
142
|
## How It Works
|
|
@@ -149,6 +154,21 @@ By default, `react` and `react-dom` are marked as external (not included in the
|
|
|
149
154
|
|
|
150
155
|
To include React/React-DOM in the bundle size calculation, use the `--no-external` flag.
|
|
151
156
|
|
|
157
|
+
## Custom Registry
|
|
158
|
+
|
|
159
|
+
Use the `--registry` flag to check packages from private or alternative npm registries:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# Private corporate registry
|
|
163
|
+
bundlecheck @myorg/myorg-ui-library --registry https://npm.mycompany.com
|
|
164
|
+
|
|
165
|
+
# Verdaccio local registry
|
|
166
|
+
bundlecheck my-local-pkg --registry http://localhost:4873
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Note: If the registry requires authentication, ensure your npm/pnpm is configured with the appropriate credentials (via `.npmrc` or environment variables).
|
|
171
|
+
|
|
152
172
|
## License
|
|
153
173
|
|
|
154
174
|
MIT - see [LICENSE](./LICENSE) for details.
|
package/dist/bundlecheck.js
CHANGED
|
@@ -42,7 +42,10 @@ async function main() {
|
|
|
42
42
|
// Construct the full package path including subpath if present
|
|
43
43
|
const fullPackagePath = subpath ? `${name}/${subpath}` : name;
|
|
44
44
|
log.info(`\nFetching available versions for ${name}...`);
|
|
45
|
-
const { versions } = await fetchPackageVersions(
|
|
45
|
+
const { versions } = await fetchPackageVersions({
|
|
46
|
+
packageName,
|
|
47
|
+
registry: flags?.registry
|
|
48
|
+
});
|
|
46
49
|
if (versions.length === 0) {
|
|
47
50
|
log.error("No versions found for this package");
|
|
48
51
|
process.exit(1);
|
|
@@ -58,7 +61,8 @@ async function main() {
|
|
|
58
61
|
additionalExternals,
|
|
59
62
|
noExternal: flags?.noExternal,
|
|
60
63
|
gzipLevel: flags?.gzipLevel,
|
|
61
|
-
boring: flags?.boring
|
|
64
|
+
boring: flags?.boring,
|
|
65
|
+
registry: flags?.registry
|
|
62
66
|
});
|
|
63
67
|
if (results.length === 0) {
|
|
64
68
|
log.error("Failed to analyze any versions");
|
|
@@ -81,7 +85,10 @@ async function main() {
|
|
|
81
85
|
try {
|
|
82
86
|
const { name, subpath } = parsePackageSpecifier(packageName);
|
|
83
87
|
log.info(`\nFetching available versions for ${name}...`);
|
|
84
|
-
const { versions, tags } = await fetchPackageVersions(
|
|
88
|
+
const { versions, tags } = await fetchPackageVersions({
|
|
89
|
+
packageName,
|
|
90
|
+
registry: flags?.registry
|
|
91
|
+
});
|
|
85
92
|
if (versions.length === 0) {
|
|
86
93
|
log.error("No versions found for this package");
|
|
87
94
|
process.exit(1);
|
|
@@ -107,7 +114,8 @@ async function main() {
|
|
|
107
114
|
exports,
|
|
108
115
|
additionalExternals,
|
|
109
116
|
noExternal: flags?.noExternal,
|
|
110
|
-
gzipLevel: flags?.gzipLevel
|
|
117
|
+
gzipLevel: flags?.gzipLevel,
|
|
118
|
+
registry: flags?.registry
|
|
111
119
|
});
|
|
112
120
|
const blue = kleur.blue;
|
|
113
121
|
const green = kleur.green;
|
package/dist/bundlecheck.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bundlecheck.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* istanbul ignore file */\n\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport {\n\tcheckBundleSize,\n\tformatBytes,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport { TREND_VERSION_COUNT } from \"./defaults.js\";\nimport { config } from \"./parse.js\";\nimport {\n\tanalyzeTrend,\n\trenderTrendGraph,\n\tselectTrendVersions,\n} from \"./trend.js\";\nimport { fetchPackageVersions, promptForVersion } from \"./versions.js\";\n\nconst flags = config.flags;\nconst parameters = config.parameters;\n\n// Disable kleur colors when --boring flag is set\nkleur.enabled = !flags?.boring;\n\nconst log = new Logger({\n\tboring: flags?.boring,\n});\n\nasync function main() {\n\tlet packageName = parameters?.[\"0\"];\n\n\tif (!packageName) {\n\t\tlog.error(\"Package name is required\");\n\t\tconfig.showHelp?.();\n\t\tprocess.exit(1);\n\t}\n\n\t// Parse additional externals if provided (comma-separated)\n\tlet additionalExternals: string[] | undefined;\n\tif (flags?.external) {\n\t\tadditionalExternals = flags.external\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Parse exports if provided (comma-separated)\n\tlet exports: string[] | undefined;\n\tconst exportsArg = parameters?.[\"1\"];\n\tif (exportsArg) {\n\t\texports = exportsArg\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// If --trend flag is set, show bundle size trend across versions\n\t// --trend alone uses default (5), --trend N uses N versions\n\tconst trendValue = flags?.trend;\n\tif (trendValue !== undefined) {\n\t\tconst parsedCount = Number.parseInt(trendValue, 10);\n\t\tconst versionCount =\n\t\t\t!Number.isNaN(parsedCount) && parsedCount > 0\n\t\t\t\t? parsedCount\n\t\t\t\t: TREND_VERSION_COUNT;\n\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\t// Construct the full package path including subpath if present\n\t\t\tconst fullPackagePath = subpath ? `${name}/${subpath}` : name;\n\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions } = await fetchPackageVersions(packageName);\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Select versions for trend\n\t\t\tconst trendVersions = selectTrendVersions(versions, versionCount);\n\n\t\t\tlog.info(\n\t\t\t\t`Analyzing ${trendVersions.length} versions: ${trendVersions.join(\", \")}`,\n\t\t\t);\n\t\t\tlog.info(\"\");\n\n\t\t\tconst results = await analyzeTrend({\n\t\t\t\tpackageName: fullPackagePath,\n\t\t\t\tversions: trendVersions,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal: flags?.noExternal,\n\t\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\t\tboring: flags?.boring,\n\t\t\t});\n\n\t\t\tif (results.length === 0) {\n\t\t\t\tlog.error(\"Failed to analyze any versions\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Render and display the trend graph\n\t\t\tconst graphLines = renderTrendGraph(\n\t\t\t\tfullPackagePath,\n\t\t\t\tresults,\n\t\t\t\tflags?.boring,\n\t\t\t);\n\t\t\tfor (const line of graphLines) {\n\t\t\t\tlog.log(line);\n\t\t\t}\n\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to analyze trend: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// If --versions flag is set, fetch and prompt for version selection\n\tif (flags?.versions) {\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions, tags } = await fetchPackageVersions(packageName);\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst selectedVersion = await promptForVersion(name, versions, tags);\n\t\t\t// Rebuild specifier preserving any subpath\n\t\t\tpackageName = subpath\n\t\t\t\t? `${name}/${subpath}@${selectedVersion}`\n\t\t\t\t: `${name}@${selectedVersion}`;\n\t\t\tlog.info(`\\nSelected: ${packageName}`);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to fetch versions: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tlog.info(`\\nAnalyzing bundle size for: ${packageName}`);\n\tif (exports && exports.length > 0) {\n\t\tlog.info(`Exports: { ${exports.join(\", \")} }`);\n\t}\n\tlog.info(\"Please wait, installing and bundling...\\n\");\n\n\ttry {\n\t\tconst result = await checkBundleSize({\n\t\t\tpackageName,\n\t\t\texports,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal: flags?.noExternal,\n\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t});\n\n\t\tconst blue = kleur.blue;\n\t\tconst green = kleur.green;\n\n\t\t// Display results\n\t\tlog.printBox(\n\t\t\t[\n\t\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\t\tresult.exports.length > 0\n\t\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\t\"\",\n\t\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\t\t`${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`,\n\t\t\t\t\"\",\n\t\t\t\tresult.externals.length > 0\n\t\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\t\tresult.dependencies.length > 0\n\t\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t],\n\t\t\t{\n\t\t\t\tborderStyle: \"round\",\n\t\t\t\talign: \"left\",\n\t\t\t},\n\t\t);\n\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tlog.error(`Failed to analyze bundle size: ${errorMessage}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nmain();\n"],"names":["Logger","kleur","checkBundleSize","formatBytes","parsePackageSpecifier","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","main","packageName","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exports","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","length","trendVersions","join","results","noExternal","gzipLevel","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","result","blue","green","printBox","packageVersion","rawSize","gzipSize","externals","dependencies","borderStyle","align"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/bundlecheck.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* istanbul ignore file */\n\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport {\n\tcheckBundleSize,\n\tformatBytes,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport { TREND_VERSION_COUNT } from \"./defaults.js\";\nimport { config } from \"./parse.js\";\nimport {\n\tanalyzeTrend,\n\trenderTrendGraph,\n\tselectTrendVersions,\n} from \"./trend.js\";\nimport { fetchPackageVersions, promptForVersion } from \"./versions.js\";\n\nconst flags = config.flags;\nconst parameters = config.parameters;\n\n// Disable kleur colors when --boring flag is set\nkleur.enabled = !flags?.boring;\n\nconst log = new Logger({\n\tboring: flags?.boring,\n});\n\nasync function main() {\n\tlet packageName = parameters?.[\"0\"];\n\n\tif (!packageName) {\n\t\tlog.error(\"Package name is required\");\n\t\tconfig.showHelp?.();\n\t\tprocess.exit(1);\n\t}\n\n\t// Parse additional externals if provided (comma-separated)\n\tlet additionalExternals: string[] | undefined;\n\tif (flags?.external) {\n\t\tadditionalExternals = flags.external\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Parse exports if provided (comma-separated)\n\tlet exports: string[] | undefined;\n\tconst exportsArg = parameters?.[\"1\"];\n\tif (exportsArg) {\n\t\texports = exportsArg\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// If --trend flag is set, show bundle size trend across versions\n\t// --trend alone uses default (5), --trend N uses N versions\n\tconst trendValue = flags?.trend;\n\tif (trendValue !== undefined) {\n\t\tconst parsedCount = Number.parseInt(trendValue, 10);\n\t\tconst versionCount =\n\t\t\t!Number.isNaN(parsedCount) && parsedCount > 0\n\t\t\t\t? parsedCount\n\t\t\t\t: TREND_VERSION_COUNT;\n\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\t// Construct the full package path including subpath if present\n\t\t\tconst fullPackagePath = subpath ? `${name}/${subpath}` : name;\n\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Select versions for trend\n\t\t\tconst trendVersions = selectTrendVersions(versions, versionCount);\n\n\t\t\tlog.info(\n\t\t\t\t`Analyzing ${trendVersions.length} versions: ${trendVersions.join(\", \")}`,\n\t\t\t);\n\t\t\tlog.info(\"\");\n\n\t\t\tconst results = await analyzeTrend({\n\t\t\t\tpackageName: fullPackagePath,\n\t\t\t\tversions: trendVersions,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal: flags?.noExternal,\n\t\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\t\tboring: flags?.boring,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (results.length === 0) {\n\t\t\t\tlog.error(\"Failed to analyze any versions\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Render and display the trend graph\n\t\t\tconst graphLines = renderTrendGraph(\n\t\t\t\tfullPackagePath,\n\t\t\t\tresults,\n\t\t\t\tflags?.boring,\n\t\t\t);\n\t\t\tfor (const line of graphLines) {\n\t\t\t\tlog.log(line);\n\t\t\t}\n\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to analyze trend: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// If --versions flag is set, fetch and prompt for version selection\n\tif (flags?.versions) {\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions, tags } = await fetchPackageVersions({\n\t\t\t\tpackageName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst selectedVersion = await promptForVersion(name, versions, tags);\n\t\t\t// Rebuild specifier preserving any subpath\n\t\t\tpackageName = subpath\n\t\t\t\t? `${name}/${subpath}@${selectedVersion}`\n\t\t\t\t: `${name}@${selectedVersion}`;\n\t\t\tlog.info(`\\nSelected: ${packageName}`);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to fetch versions: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tlog.info(`\\nAnalyzing bundle size for: ${packageName}`);\n\tif (exports && exports.length > 0) {\n\t\tlog.info(`Exports: { ${exports.join(\", \")} }`);\n\t}\n\tlog.info(\"Please wait, installing and bundling...\\n\");\n\n\ttry {\n\t\tconst result = await checkBundleSize({\n\t\t\tpackageName,\n\t\t\texports,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal: flags?.noExternal,\n\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\tregistry: flags?.registry,\n\t\t});\n\n\t\tconst blue = kleur.blue;\n\t\tconst green = kleur.green;\n\n\t\t// Display results\n\t\tlog.printBox(\n\t\t\t[\n\t\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\t\tresult.exports.length > 0\n\t\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\t\"\",\n\t\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\t\t`${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`,\n\t\t\t\t\"\",\n\t\t\t\tresult.externals.length > 0\n\t\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\t\tresult.dependencies.length > 0\n\t\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t],\n\t\t\t{\n\t\t\t\tborderStyle: \"round\",\n\t\t\t\talign: \"left\",\n\t\t\t},\n\t\t);\n\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tlog.error(`Failed to analyze bundle size: ${errorMessage}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nmain();\n"],"names":["Logger","kleur","checkBundleSize","formatBytes","parsePackageSpecifier","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","main","packageName","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exports","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","registry","length","trendVersions","join","results","noExternal","gzipLevel","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","result","blue","green","printBox","packageVersion","rawSize","gzipSize","externals","dependencies","borderStyle","align"],"mappings":"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"}
|
package/dist/bundler.d.ts
CHANGED
package/dist/bundler.js
CHANGED
|
@@ -122,16 +122,44 @@ const gzipAsync = promisify(zlib.gzip);
|
|
|
122
122
|
}
|
|
123
123
|
// Cache the result of pnpm availability check
|
|
124
124
|
let usePnpm = null;
|
|
125
|
+
/**
|
|
126
|
+
* Validate and sanitize a registry URL to prevent command injection
|
|
127
|
+
* @param registry - The registry URL to validate
|
|
128
|
+
* @returns The sanitized URL or undefined if invalid
|
|
129
|
+
* @throws Error if the URL is invalid or contains potentially malicious characters
|
|
130
|
+
*/ function validateRegistryUrl(registry) {
|
|
131
|
+
// Parse as URL to validate format
|
|
132
|
+
let url;
|
|
133
|
+
try {
|
|
134
|
+
url = new URL(registry);
|
|
135
|
+
} catch {
|
|
136
|
+
throw new Error(`Invalid registry URL: ${registry}. Must be a valid URL (e.g., https://registry.example.com)`);
|
|
137
|
+
}
|
|
138
|
+
// Only allow http and https protocols
|
|
139
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
140
|
+
throw new Error(`Invalid registry URL protocol: ${url.protocol}. Only http: and https: are allowed`);
|
|
141
|
+
}
|
|
142
|
+
// Return the sanitized URL (URL constructor normalizes it)
|
|
143
|
+
return url.toString();
|
|
144
|
+
}
|
|
125
145
|
/**
|
|
126
146
|
* Get the install command (pnpm preferred, npm fallback)
|
|
127
|
-
|
|
147
|
+
* @param registry - Optional custom npm registry URL
|
|
148
|
+
*/ function getInstallCommand(registry) {
|
|
128
149
|
if (usePnpm === null) {
|
|
129
150
|
usePnpm = isPnpmAvailable();
|
|
130
151
|
}
|
|
152
|
+
let registryArg = "";
|
|
153
|
+
if (registry) {
|
|
154
|
+
// Validate and sanitize the registry URL to prevent command injection
|
|
155
|
+
const sanitizedRegistry = validateRegistryUrl(registry);
|
|
156
|
+
// Quote the URL to handle any special characters safely
|
|
157
|
+
registryArg = ` --registry "${sanitizedRegistry}"`;
|
|
158
|
+
}
|
|
131
159
|
if (usePnpm) {
|
|
132
|
-
return
|
|
160
|
+
return `pnpm install --ignore-scripts --no-frozen-lockfile${registryArg}`;
|
|
133
161
|
}
|
|
134
|
-
return
|
|
162
|
+
return `npm install --legacy-peer-deps --ignore-scripts${registryArg}`;
|
|
135
163
|
}
|
|
136
164
|
/**
|
|
137
165
|
* Generate the entry file content based on package, subpath, and exports
|
|
@@ -326,7 +354,7 @@ let usePnpm = null;
|
|
|
326
354
|
/**
|
|
327
355
|
* Check the bundle size of an npm package
|
|
328
356
|
*/ export async function checkBundleSize(options) {
|
|
329
|
-
const { packageName: packageSpecifier, exports, additionalExternals, noExternal, gzipLevel = 5 } = options;
|
|
357
|
+
const { packageName: packageSpecifier, exports, additionalExternals, noExternal, gzipLevel = 5, registry } = options;
|
|
330
358
|
// Parse the package specifier to extract name, version, and subpath
|
|
331
359
|
const { name: packageName, version: requestedVersion, subpath } = parsePackageSpecifier(packageSpecifier);
|
|
332
360
|
const tmpDir = createTempDir();
|
|
@@ -342,7 +370,7 @@ let usePnpm = null;
|
|
|
342
370
|
};
|
|
343
371
|
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify(packageJson, null, 2));
|
|
344
372
|
// Install the main package (try pnpm first, fallback to npm)
|
|
345
|
-
const installCmd = getInstallCommand();
|
|
373
|
+
const installCmd = getInstallCommand(registry);
|
|
346
374
|
execSync(installCmd, {
|
|
347
375
|
cwd: tmpDir,
|
|
348
376
|
stdio: "pipe"
|
package/dist/bundler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bundler.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport zlib from \"node:zlib\";\nimport * as esbuild from \"esbuild\";\nimport { DEFAULT_EXTERNALS } from \"./defaults.js\";\n\nconst gzipAsync = promisify(zlib.gzip);\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegExp(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport type ParsedPackage = {\n\tname: string;\n\tversion: string;\n\tsubpath?: string;\n};\n\n/**\n * Parse a package specifier to extract name, version, and subpath\n * Handles:\n * - @scope/package@1.0.0\n * - @scope/package/subpath@1.0.0\n * - @scope/package/subpath\n * - package/subpath@1.0.0\n */\nexport function parsePackageSpecifier(specifier: string): ParsedPackage {\n\tlet workingSpec = specifier;\n\tlet version = \"latest\";\n\n\t// Handle scoped packages (@scope/name...)\n\tif (workingSpec.startsWith(\"@\")) {\n\t\t// Find the second @ which would separate version\n\t\tconst secondAtIndex = workingSpec.indexOf(\"@\", 1);\n\t\tif (secondAtIndex !== -1) {\n\t\t\tversion = workingSpec.substring(secondAtIndex + 1);\n\t\t\tworkingSpec = workingSpec.substring(0, secondAtIndex);\n\t\t}\n\n\t\t// Now workingSpec is like @scope/name or @scope/name/subpath\n\t\t// Split by / and check if there are more than 2 parts\n\t\tconst parts = workingSpec.split(\"/\");\n\t\tif (parts.length > 2) {\n\t\t\t// Has subpath: @scope/name/subpath/more\n\t\t\tconst name = `${parts[0]}/${parts[1]}`;\n\t\t\tconst subpath = parts.slice(2).join(\"/\");\n\t\t\treturn { name, version, subpath };\n\t\t}\n\t\t// No subpath: @scope/name\n\t\treturn { name: workingSpec, version };\n\t}\n\n\t// Handle non-scoped packages (name@version or name/subpath@version)\n\tconst atIndex = workingSpec.indexOf(\"@\");\n\tif (atIndex !== -1) {\n\t\tversion = workingSpec.substring(atIndex + 1);\n\t\tworkingSpec = workingSpec.substring(0, atIndex);\n\t}\n\n\t// Check for subpath in non-scoped packages\n\tconst slashIndex = workingSpec.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst name = workingSpec.substring(0, slashIndex);\n\t\tconst subpath = workingSpec.substring(slashIndex + 1);\n\t\treturn { name, version, subpath };\n\t}\n\n\treturn { name: workingSpec, version };\n}\n\nexport type BundleOptions = {\n\tpackageName: string;\n\texports?: string[];\n\tadditionalExternals?: string[];\n\tnoExternal?: boolean;\n\tgzipLevel?: number;\n};\n\nexport type BundleResult = {\n\tpackageName: string;\n\tpackageVersion: string;\n\texports: string[];\n\trawSize: number;\n\tgzipSize: number;\n\tgzipLevel: number;\n\texternals: string[];\n\tdependencies: string[];\n};\n\n/**\n * Format bytes to human-readable string\n */\nexport function formatBytes(bytes: number): string {\n\tif (bytes === 0) {\n\t\treturn \"0 B\";\n\t}\n\tconst k = 1024;\n\tconst sizes = [\"B\", \"kB\", \"MB\", \"GB\"];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\treturn `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Create a temporary directory for bundling\n */\nfunction createTempDir(): string {\n\tconst tmpDir = path.join(os.tmpdir(), `bundlecheck-${Date.now()}`);\n\tfs.mkdirSync(tmpDir, { recursive: true });\n\treturn tmpDir;\n}\n\n/**\n * Clean up temporary directory\n */\nfunction cleanupTempDir(tmpDir: string): void {\n\ttry {\n\t\tfs.rmSync(tmpDir, { recursive: true, force: true });\n\t} catch {\n\t\t// Ignore cleanup errors\n\t}\n}\n\n/**\n * Check if pnpm is available\n */\nfunction isPnpmAvailable(): boolean {\n\ttry {\n\t\texecSync(\"pnpm --version\", { stdio: \"pipe\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// Cache the result of pnpm availability check\nlet usePnpm: boolean | null = null;\n\n/**\n * Get the install command (pnpm preferred, npm fallback)\n */\nfunction getInstallCommand(): string {\n\tif (usePnpm === null) {\n\t\tusePnpm = isPnpmAvailable();\n\t}\n\n\tif (usePnpm) {\n\t\treturn \"pnpm install --ignore-scripts --no-frozen-lockfile\";\n\t}\n\treturn \"npm install --legacy-peer-deps --ignore-scripts\";\n}\n\nexport type EntryContentOptions = {\n\tpackageName: string;\n\tsubpath?: string;\n\texports?: string[];\n\tallSubpaths?: string[];\n\texportToSubpath?: Map<string, string>;\n};\n\n/**\n * Generate the entry file content based on package, subpath, and exports\n */\nfunction generateEntryContent(options: EntryContentOptions): string {\n\tconst { packageName, subpath, exports, allSubpaths, exportToSubpath } =\n\t\toptions;\n\n\t// If we have exports mapped to different subpaths\n\tif (exportToSubpath && exportToSubpath.size > 0) {\n\t\t// Group exports by subpath\n\t\tconst subpathToExports = new Map<string, string[]>();\n\t\tfor (const [exportName, sp] of exportToSubpath) {\n\t\t\tconst existing = subpathToExports.get(sp) || [];\n\t\t\texisting.push(exportName);\n\t\t\tsubpathToExports.set(sp, existing);\n\t\t}\n\n\t\t// Generate imports for each subpath\n\t\tconst lines: string[] = [];\n\t\tconst allExportNames: string[] = [];\n\n\t\tfor (const [sp, exportNames] of subpathToExports) {\n\t\t\tconst importPath = `${packageName}/${sp}`;\n\t\t\tconst names = exportNames.join(\", \");\n\t\t\tlines.push(`import { ${names} } from \"${importPath}\";`);\n\t\t\tallExportNames.push(...exportNames);\n\t\t}\n\n\t\tlines.push(`export { ${allExportNames.join(\", \")} };`);\n\t\treturn lines.join(\"\\n\") + \"\\n\";\n\t}\n\n\t// If we have specific exports to import\n\tif (exports && exports.length > 0) {\n\t\t// Determine the import path\n\t\tconst importPath = subpath ? `${packageName}/${subpath}` : packageName;\n\t\tconst importNames = exports.join(\", \");\n\t\treturn `import { ${importNames} } from \"${importPath}\";\\nexport { ${importNames} };\\n`;\n\t}\n\n\t// If we have a specific subpath (but no specific exports)\n\tif (subpath) {\n\t\tconst importPath = `${packageName}/${subpath}`;\n\t\treturn `import * as pkg from \"${importPath}\";\\nexport default pkg;\\n`;\n\t}\n\n\t// If package has subpath exports only (no main entry), import all subpaths\n\tif (allSubpaths && allSubpaths.length > 0) {\n\t\tconst imports = allSubpaths\n\t\t\t.map(\n\t\t\t\t(sp, i) =>\n\t\t\t\t\t`import * as sub${i} from \"${packageName}/${sp}\";\\nexport { sub${i} };`,\n\t\t\t)\n\t\t\t.join(\"\\n\");\n\t\treturn imports + \"\\n\";\n\t}\n\n\t// Default: import everything from main entry\n\treturn `import * as pkg from \"${packageName}\";\\nexport default pkg;\\n`;\n}\n\n/**\n * Get externals list based on options\n */\nfunction getExternals(\n\tpackageName: string,\n\texternals?: string[],\n\tnoExternal?: boolean,\n): string[] {\n\tif (noExternal) {\n\t\treturn [];\n\t}\n\n\t// Start with default externals (react, react-dom)\n\tlet result = [...DEFAULT_EXTERNALS];\n\n\t// If checking react or react-dom themselves, don't mark them as external\n\tif (packageName === \"react\") {\n\t\tresult = result.filter((e) => e !== \"react\");\n\t} else if (packageName === \"react-dom\") {\n\t\tresult = result.filter((e) => e !== \"react-dom\");\n\t}\n\n\t// Add any additional externals\n\tif (externals && externals.length > 0) {\n\t\tresult = [...new Set([...result, ...externals])];\n\t}\n\n\treturn result;\n}\n\nexport type PackageExports = Record<\n\tstring,\n\tstring | { import?: string; types?: string }\n>;\n\nexport type PackageInfo = {\n\tversion: string;\n\tdependencies: Record<string, string>;\n\tpeerDependencies: Record<string, string>;\n\texports: PackageExports | null;\n\thasMainEntry: boolean;\n};\n\n/**\n * Get version, dependencies, peer dependencies, and exports from an installed package\n */\nfunction getPackageInfo(tmpDir: string, packageName: string): PackageInfo {\n\ttry {\n\t\t// Handle scoped packages - the package name in node_modules\n\t\tconst pkgJsonPath = path.join(\n\t\t\ttmpDir,\n\t\t\t\"node_modules\",\n\t\t\tpackageName,\n\t\t\t\"package.json\",\n\t\t);\n\t\tif (fs.existsSync(pkgJsonPath)) {\n\t\t\tconst pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf-8\"));\n\n\t\t\t// Check if package has a main entry point\n\t\t\tconst hasMainEntry = Boolean(\n\t\t\t\tpkgJson.main ||\n\t\t\t\t\tpkgJson.module ||\n\t\t\t\t\tpkgJson.exports?.[\".\"] ||\n\t\t\t\t\tpkgJson.exports?.[\"./index\"] ||\n\t\t\t\t\t(!pkgJson.exports && !pkgJson.main && !pkgJson.module),\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tversion: pkgJson.version || \"unknown\",\n\t\t\t\tdependencies: pkgJson.dependencies || {},\n\t\t\t\tpeerDependencies: pkgJson.peerDependencies || {},\n\t\t\t\texports: pkgJson.exports || null,\n\t\t\t\thasMainEntry,\n\t\t\t};\n\t\t}\n\t} catch {\n\t\t// Ignore errors reading package info\n\t}\n\treturn {\n\t\tversion: \"unknown\",\n\t\tdependencies: {},\n\t\tpeerDependencies: {},\n\t\texports: null,\n\t\thasMainEntry: true,\n\t};\n}\n\n/**\n * Extract subpath export names from package exports field\n * Returns array of subpaths like [\"header\", \"body\", \"datagrid\"]\n */\nfunction getSubpathExports(exports: PackageExports | null): string[] {\n\tif (!exports) {\n\t\treturn [];\n\t}\n\n\tconst subpaths: string[] = [];\n\tfor (const key of Object.keys(exports)) {\n\t\t// Skip the main entry point and package.json\n\t\tif (key === \".\" || key === \"./package.json\") {\n\t\t\tcontinue;\n\t\t}\n\t\t// Remove leading \"./\" to get subpath name\n\t\tif (key.startsWith(\"./\")) {\n\t\t\tsubpaths.push(key.substring(2));\n\t\t}\n\t}\n\treturn subpaths;\n}\n\n/**\n * Result of finding subpaths for exports\n */\ntype SubpathMapping = {\n\t// Single subpath if all exports are from the same subpath\n\tsingleSubpath?: string;\n\t// Map of export name to subpath for multiple subpaths\n\texportToSubpath?: Map<string, string>;\n};\n\n/**\n * Find which subpath(s) export the given component names\n * Reads type definition files or JS files to find the exports\n */\nfunction findSubpathsForExports(\n\ttmpDir: string,\n\tpackageName: string,\n\texports: PackageExports,\n\tcomponentNames: string[],\n): SubpathMapping {\n\tconst packageDir = path.join(tmpDir, \"node_modules\", packageName);\n\tconst exportToSubpath = new Map<string, string>();\n\n\tfor (const [subpathKey, subpathValue] of Object.entries(exports)) {\n\t\t// Skip main entry and package.json\n\t\tif (subpathKey === \".\" || subpathKey === \"./package.json\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Get the types or import path\n\t\tlet filePath: string | undefined;\n\t\tif (typeof subpathValue === \"object\" && subpathValue !== null) {\n\t\t\t// Prefer types file for more accurate export detection\n\t\t\tfilePath = subpathValue.types || subpathValue.import;\n\t\t} else if (typeof subpathValue === \"string\") {\n\t\t\tfilePath = subpathValue;\n\t\t}\n\n\t\tif (!filePath) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Resolve the file path\n\t\tconst fullPath = path.join(packageDir, filePath);\n\n\t\ttry {\n\t\t\tif (fs.existsSync(fullPath)) {\n\t\t\t\tconst content = fs.readFileSync(fullPath, \"utf-8\");\n\t\t\t\tconst subpath = subpathKey.startsWith(\"./\")\n\t\t\t\t\t? subpathKey.substring(2)\n\t\t\t\t\t: subpathKey;\n\n\t\t\t\t// Check each component name\n\t\t\t\tfor (const name of componentNames) {\n\t\t\t\t\t// Skip if already found\n\t\t\t\t\tif (exportToSubpath.has(name)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Escape regex special characters in the name to prevent injection\n\t\t\t\t\tconst escapedName = escapeRegExp(name);\n\n\t\t\t\t\t// Look for various export patterns\n\t\t\t\t\tconst patterns = [\n\t\t\t\t\t\tnew RegExp(`export\\\\s*\\\\{[^}]*\\\\b${escapedName}\\\\b[^}]*\\\\}`, \"m\"),\n\t\t\t\t\t\tnew RegExp(\n\t\t\t\t\t\t\t`export\\\\s+declare\\\\s+(?:const|function|class)\\\\s+${escapedName}\\\\b`,\n\t\t\t\t\t\t\t\"m\",\n\t\t\t\t\t\t),\n\t\t\t\t\t\tnew RegExp(\n\t\t\t\t\t\t\t`export\\\\s+(?:const|function|class)\\\\s+${escapedName}\\\\b`,\n\t\t\t\t\t\t\t\"m\",\n\t\t\t\t\t\t),\n\t\t\t\t\t];\n\n\t\t\t\t\tif (patterns.some((pattern) => pattern.test(content))) {\n\t\t\t\t\t\texportToSubpath.set(name, subpath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read errors, continue to next subpath\n\t\t}\n\t}\n\n\t// Check if all exports were found\n\tif (exportToSubpath.size !== componentNames.length) {\n\t\treturn {}; // Not all exports found\n\t}\n\n\t// Check if all exports are from the same subpath\n\tconst subpaths = new Set(exportToSubpath.values());\n\tif (subpaths.size === 1) {\n\t\treturn { singleSubpath: [...subpaths][0] };\n\t}\n\n\t// Multiple subpaths needed\n\treturn { exportToSubpath };\n}\n\n/**\n * Check the bundle size of an npm package\n */\nexport async function checkBundleSize(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tpackageName: packageSpecifier,\n\t\texports,\n\t\tadditionalExternals,\n\t\tnoExternal,\n\t\tgzipLevel = 5,\n\t} = options;\n\n\t// Parse the package specifier to extract name, version, and subpath\n\tconst {\n\t\tname: packageName,\n\t\tversion: requestedVersion,\n\t\tsubpath,\n\t} = parsePackageSpecifier(packageSpecifier);\n\n\tconst tmpDir = createTempDir();\n\n\ttry {\n\t\t// Create initial package.json\n\t\tconst packageJson: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\ttype: string;\n\t\t\tdependencies: Record<string, string>;\n\t\t} = {\n\t\t\tname: \"bundlecheck-temp\",\n\t\t\tversion: \"1.0.0\",\n\t\t\ttype: \"module\",\n\t\t\tdependencies: {\n\t\t\t\t[packageName]: requestedVersion,\n\t\t\t},\n\t\t};\n\n\t\tfs.writeFileSync(\n\t\t\tpath.join(tmpDir, \"package.json\"),\n\t\t\tJSON.stringify(packageJson, null, 2),\n\t\t);\n\n\t\t// Install the main package (try pnpm first, fallback to npm)\n\t\tconst installCmd = getInstallCommand();\n\t\texecSync(installCmd, {\n\t\t\tcwd: tmpDir,\n\t\t\tstdio: \"pipe\",\n\t\t});\n\n\t\t// Get package info (version, dependencies, peer dependencies, exports)\n\t\tconst pkgInfo = getPackageInfo(tmpDir, packageName);\n\t\tconst peerDepKeys = Object.keys(pkgInfo.peerDependencies);\n\n\t\t// Collect all dependency names (prod + peer)\n\t\tconst allDependencies = [\n\t\t\t...new Set([...Object.keys(pkgInfo.dependencies), ...peerDepKeys]),\n\t\t].sort();\n\n\t\tif (peerDepKeys.length > 0) {\n\t\t\t// Add peer dependencies to package.json\n\t\t\tfor (const dep of peerDepKeys) {\n\t\t\t\t// Use the version range from peer dependencies\n\t\t\t\tpackageJson.dependencies[dep] = pkgInfo.peerDependencies[dep];\n\t\t\t}\n\n\t\t\t// Update package.json and reinstall\n\t\t\tfs.writeFileSync(\n\t\t\t\tpath.join(tmpDir, \"package.json\"),\n\t\t\t\tJSON.stringify(packageJson, null, 2),\n\t\t\t);\n\n\t\t\texecSync(installCmd, {\n\t\t\t\tcwd: tmpDir,\n\t\t\t\tstdio: \"pipe\",\n\t\t\t});\n\t\t}\n\n\t\t// Determine if we need to use all subpath exports or find the right subpath(s)\n\t\tlet allSubpaths: string[] | undefined;\n\t\tlet resolvedSubpath = subpath;\n\t\tlet exportToSubpath: Map<string, string> | undefined;\n\n\t\tif (!subpath && !pkgInfo.hasMainEntry && pkgInfo.exports) {\n\t\t\tif (exports && exports.length > 0) {\n\t\t\t\t// User specified exports but no subpath - try to find the right subpath(s)\n\t\t\t\tconst mapping = findSubpathsForExports(\n\t\t\t\t\ttmpDir,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tpkgInfo.exports,\n\t\t\t\t\texports,\n\t\t\t\t);\n\n\t\t\t\tif (mapping.singleSubpath) {\n\t\t\t\t\t// All exports from the same subpath\n\t\t\t\t\tresolvedSubpath = mapping.singleSubpath;\n\t\t\t\t} else if (mapping.exportToSubpath) {\n\t\t\t\t\t// Exports from multiple subpaths\n\t\t\t\t\texportToSubpath = mapping.exportToSubpath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If still no subpath resolved and no mapping, bundle all subpaths\n\t\t\tif (!resolvedSubpath && !exportToSubpath) {\n\t\t\t\tallSubpaths = getSubpathExports(pkgInfo.exports);\n\t\t\t}\n\t\t}\n\n\t\t// Create entry file with appropriate content\n\t\tconst entryContent = generateEntryContent({\n\t\t\tpackageName,\n\t\t\tsubpath: resolvedSubpath,\n\t\t\texports,\n\t\t\tallSubpaths,\n\t\t\texportToSubpath,\n\t\t});\n\t\tconst entryFile = path.join(tmpDir, \"entry.js\");\n\t\tfs.writeFileSync(entryFile, entryContent);\n\n\t\t// Get externals\n\t\tconst externals = getExternals(\n\t\t\tpackageName,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal,\n\t\t);\n\n\t\t// Bundle with esbuild\n\t\tconst result = await esbuild.build({\n\t\t\tentryPoints: [entryFile],\n\t\t\tbundle: true,\n\t\t\twrite: false,\n\t\t\tformat: \"esm\",\n\t\t\tplatform: \"browser\",\n\t\t\ttarget: \"es2020\",\n\t\t\tminify: true,\n\t\t\ttreeShaking: true,\n\t\t\texternal: externals,\n\t\t\tmetafile: true,\n\t\t});\n\n\t\t// Get raw size\n\t\tconst bundleContent = result.outputFiles[0].contents;\n\t\tconst rawSize = bundleContent.length;\n\n\t\t// Gzip the bundle\n\t\tconst gzipped = await gzipAsync(Buffer.from(bundleContent), {\n\t\t\tlevel: gzipLevel,\n\t\t});\n\t\tconst gzipSize = gzipped.length;\n\n\t\t// Determine the display name\n\t\tlet displayName = packageName;\n\t\tif (resolvedSubpath) {\n\t\t\tdisplayName = `${packageName}/${resolvedSubpath}`;\n\t\t} else if (exportToSubpath && exportToSubpath.size > 0) {\n\t\t\t// Multiple subpaths - show them all\n\t\t\tconst uniqueSubpaths = [...new Set(exportToSubpath.values())].sort();\n\t\t\tdisplayName = `${packageName}/{${uniqueSubpaths.join(\", \")}}`;\n\t\t}\n\n\t\treturn {\n\t\t\tpackageName: displayName,\n\t\t\tpackageVersion: pkgInfo.version,\n\t\t\texports: exports || [],\n\t\t\trawSize,\n\t\t\tgzipSize,\n\t\t\tgzipLevel,\n\t\t\texternals,\n\t\t\tdependencies: allDependencies,\n\t\t};\n\t} finally {\n\t\tcleanupTempDir(tmpDir);\n\t}\n}\n"],"names":["execSync","fs","os","path","promisify","zlib","esbuild","DEFAULT_EXTERNALS","gzipAsync","gzip","escapeRegExp","str","replace","parsePackageSpecifier","specifier","workingSpec","version","startsWith","secondAtIndex","indexOf","substring","parts","split","length","name","subpath","slice","join","atIndex","slashIndex","formatBytes","bytes","k","sizes","i","Math","floor","log","Number","parseFloat","toFixed","createTempDir","tmpDir","tmpdir","Date","now","mkdirSync","recursive","cleanupTempDir","rmSync","force","isPnpmAvailable","stdio","usePnpm","getInstallCommand","generateEntryContent","options","packageName","exports","allSubpaths","exportToSubpath","size","subpathToExports","Map","exportName","sp","existing","get","push","set","lines","allExportNames","exportNames","importPath","names","importNames","imports","map","getExternals","externals","noExternal","result","filter","e","Set","getPackageInfo","pkgJsonPath","existsSync","pkgJson","JSON","parse","readFileSync","hasMainEntry","Boolean","main","module","dependencies","peerDependencies","getSubpathExports","subpaths","key","Object","keys","findSubpathsForExports","componentNames","packageDir","subpathKey","subpathValue","entries","filePath","types","import","fullPath","content","has","escapedName","patterns","RegExp","some","pattern","test","values","singleSubpath","checkBundleSize","packageSpecifier","additionalExternals","gzipLevel","requestedVersion","packageJson","type","writeFileSync","stringify","installCmd","cwd","pkgInfo","peerDepKeys","allDependencies","sort","dep","resolvedSubpath","mapping","entryContent","entryFile","build","entryPoints","bundle","write","format","platform","target","minify","treeShaking","external","metafile","bundleContent","outputFiles","contents","rawSize","gzipped","Buffer","from","level","gzipSize","displayName","uniqueSubpaths","packageVersion"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/bundler.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport zlib from \"node:zlib\";\nimport * as esbuild from \"esbuild\";\nimport { DEFAULT_EXTERNALS } from \"./defaults.js\";\n\nconst gzipAsync = promisify(zlib.gzip);\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegExp(str: string): string {\n\treturn str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nexport type ParsedPackage = {\n\tname: string;\n\tversion: string;\n\tsubpath?: string;\n};\n\n/**\n * Parse a package specifier to extract name, version, and subpath\n * Handles:\n * - @scope/package@1.0.0\n * - @scope/package/subpath@1.0.0\n * - @scope/package/subpath\n * - package/subpath@1.0.0\n */\nexport function parsePackageSpecifier(specifier: string): ParsedPackage {\n\tlet workingSpec = specifier;\n\tlet version = \"latest\";\n\n\t// Handle scoped packages (@scope/name...)\n\tif (workingSpec.startsWith(\"@\")) {\n\t\t// Find the second @ which would separate version\n\t\tconst secondAtIndex = workingSpec.indexOf(\"@\", 1);\n\t\tif (secondAtIndex !== -1) {\n\t\t\tversion = workingSpec.substring(secondAtIndex + 1);\n\t\t\tworkingSpec = workingSpec.substring(0, secondAtIndex);\n\t\t}\n\n\t\t// Now workingSpec is like @scope/name or @scope/name/subpath\n\t\t// Split by / and check if there are more than 2 parts\n\t\tconst parts = workingSpec.split(\"/\");\n\t\tif (parts.length > 2) {\n\t\t\t// Has subpath: @scope/name/subpath/more\n\t\t\tconst name = `${parts[0]}/${parts[1]}`;\n\t\t\tconst subpath = parts.slice(2).join(\"/\");\n\t\t\treturn { name, version, subpath };\n\t\t}\n\t\t// No subpath: @scope/name\n\t\treturn { name: workingSpec, version };\n\t}\n\n\t// Handle non-scoped packages (name@version or name/subpath@version)\n\tconst atIndex = workingSpec.indexOf(\"@\");\n\tif (atIndex !== -1) {\n\t\tversion = workingSpec.substring(atIndex + 1);\n\t\tworkingSpec = workingSpec.substring(0, atIndex);\n\t}\n\n\t// Check for subpath in non-scoped packages\n\tconst slashIndex = workingSpec.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst name = workingSpec.substring(0, slashIndex);\n\t\tconst subpath = workingSpec.substring(slashIndex + 1);\n\t\treturn { name, version, subpath };\n\t}\n\n\treturn { name: workingSpec, version };\n}\n\nexport type BundleOptions = {\n\tpackageName: string;\n\texports?: string[];\n\tadditionalExternals?: string[];\n\tnoExternal?: boolean;\n\tgzipLevel?: number;\n\tregistry?: string;\n};\n\nexport type BundleResult = {\n\tpackageName: string;\n\tpackageVersion: string;\n\texports: string[];\n\trawSize: number;\n\tgzipSize: number;\n\tgzipLevel: number;\n\texternals: string[];\n\tdependencies: string[];\n};\n\n/**\n * Format bytes to human-readable string\n */\nexport function formatBytes(bytes: number): string {\n\tif (bytes === 0) {\n\t\treturn \"0 B\";\n\t}\n\tconst k = 1024;\n\tconst sizes = [\"B\", \"kB\", \"MB\", \"GB\"];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\treturn `${Number.parseFloat((bytes / k ** i).toFixed(2))} ${sizes[i]}`;\n}\n\n/**\n * Create a temporary directory for bundling\n */\nfunction createTempDir(): string {\n\tconst tmpDir = path.join(os.tmpdir(), `bundlecheck-${Date.now()}`);\n\tfs.mkdirSync(tmpDir, { recursive: true });\n\treturn tmpDir;\n}\n\n/**\n * Clean up temporary directory\n */\nfunction cleanupTempDir(tmpDir: string): void {\n\ttry {\n\t\tfs.rmSync(tmpDir, { recursive: true, force: true });\n\t} catch {\n\t\t// Ignore cleanup errors\n\t}\n}\n\n/**\n * Check if pnpm is available\n */\nfunction isPnpmAvailable(): boolean {\n\ttry {\n\t\texecSync(\"pnpm --version\", { stdio: \"pipe\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// Cache the result of pnpm availability check\nlet usePnpm: boolean | null = null;\n\n/**\n * Validate and sanitize a registry URL to prevent command injection\n * @param registry - The registry URL to validate\n * @returns The sanitized URL or undefined if invalid\n * @throws Error if the URL is invalid or contains potentially malicious characters\n */\nfunction validateRegistryUrl(registry: string): string {\n\t// Parse as URL to validate format\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(registry);\n\t} catch {\n\t\tthrow new Error(\n\t\t\t`Invalid registry URL: ${registry}. Must be a valid URL (e.g., https://registry.example.com)`,\n\t\t);\n\t}\n\n\t// Only allow http and https protocols\n\tif (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n\t\tthrow new Error(\n\t\t\t`Invalid registry URL protocol: ${url.protocol}. Only http: and https: are allowed`,\n\t\t);\n\t}\n\n\t// Return the sanitized URL (URL constructor normalizes it)\n\treturn url.toString();\n}\n\n/**\n * Get the install command (pnpm preferred, npm fallback)\n * @param registry - Optional custom npm registry URL\n */\nfunction getInstallCommand(registry?: string): string {\n\tif (usePnpm === null) {\n\t\tusePnpm = isPnpmAvailable();\n\t}\n\n\tlet registryArg = \"\";\n\tif (registry) {\n\t\t// Validate and sanitize the registry URL to prevent command injection\n\t\tconst sanitizedRegistry = validateRegistryUrl(registry);\n\t\t// Quote the URL to handle any special characters safely\n\t\tregistryArg = ` --registry \"${sanitizedRegistry}\"`;\n\t}\n\n\tif (usePnpm) {\n\t\treturn `pnpm install --ignore-scripts --no-frozen-lockfile${registryArg}`;\n\t}\n\treturn `npm install --legacy-peer-deps --ignore-scripts${registryArg}`;\n}\n\nexport type EntryContentOptions = {\n\tpackageName: string;\n\tsubpath?: string;\n\texports?: string[];\n\tallSubpaths?: string[];\n\texportToSubpath?: Map<string, string>;\n};\n\n/**\n * Generate the entry file content based on package, subpath, and exports\n */\nfunction generateEntryContent(options: EntryContentOptions): string {\n\tconst { packageName, subpath, exports, allSubpaths, exportToSubpath } =\n\t\toptions;\n\n\t// If we have exports mapped to different subpaths\n\tif (exportToSubpath && exportToSubpath.size > 0) {\n\t\t// Group exports by subpath\n\t\tconst subpathToExports = new Map<string, string[]>();\n\t\tfor (const [exportName, sp] of exportToSubpath) {\n\t\t\tconst existing = subpathToExports.get(sp) || [];\n\t\t\texisting.push(exportName);\n\t\t\tsubpathToExports.set(sp, existing);\n\t\t}\n\n\t\t// Generate imports for each subpath\n\t\tconst lines: string[] = [];\n\t\tconst allExportNames: string[] = [];\n\n\t\tfor (const [sp, exportNames] of subpathToExports) {\n\t\t\tconst importPath = `${packageName}/${sp}`;\n\t\t\tconst names = exportNames.join(\", \");\n\t\t\tlines.push(`import { ${names} } from \"${importPath}\";`);\n\t\t\tallExportNames.push(...exportNames);\n\t\t}\n\n\t\tlines.push(`export { ${allExportNames.join(\", \")} };`);\n\t\treturn lines.join(\"\\n\") + \"\\n\";\n\t}\n\n\t// If we have specific exports to import\n\tif (exports && exports.length > 0) {\n\t\t// Determine the import path\n\t\tconst importPath = subpath ? `${packageName}/${subpath}` : packageName;\n\t\tconst importNames = exports.join(\", \");\n\t\treturn `import { ${importNames} } from \"${importPath}\";\\nexport { ${importNames} };\\n`;\n\t}\n\n\t// If we have a specific subpath (but no specific exports)\n\tif (subpath) {\n\t\tconst importPath = `${packageName}/${subpath}`;\n\t\treturn `import * as pkg from \"${importPath}\";\\nexport default pkg;\\n`;\n\t}\n\n\t// If package has subpath exports only (no main entry), import all subpaths\n\tif (allSubpaths && allSubpaths.length > 0) {\n\t\tconst imports = allSubpaths\n\t\t\t.map(\n\t\t\t\t(sp, i) =>\n\t\t\t\t\t`import * as sub${i} from \"${packageName}/${sp}\";\\nexport { sub${i} };`,\n\t\t\t)\n\t\t\t.join(\"\\n\");\n\t\treturn imports + \"\\n\";\n\t}\n\n\t// Default: import everything from main entry\n\treturn `import * as pkg from \"${packageName}\";\\nexport default pkg;\\n`;\n}\n\n/**\n * Get externals list based on options\n */\nfunction getExternals(\n\tpackageName: string,\n\texternals?: string[],\n\tnoExternal?: boolean,\n): string[] {\n\tif (noExternal) {\n\t\treturn [];\n\t}\n\n\t// Start with default externals (react, react-dom)\n\tlet result = [...DEFAULT_EXTERNALS];\n\n\t// If checking react or react-dom themselves, don't mark them as external\n\tif (packageName === \"react\") {\n\t\tresult = result.filter((e) => e !== \"react\");\n\t} else if (packageName === \"react-dom\") {\n\t\tresult = result.filter((e) => e !== \"react-dom\");\n\t}\n\n\t// Add any additional externals\n\tif (externals && externals.length > 0) {\n\t\tresult = [...new Set([...result, ...externals])];\n\t}\n\n\treturn result;\n}\n\nexport type PackageExports = Record<\n\tstring,\n\tstring | { import?: string; types?: string }\n>;\n\nexport type PackageInfo = {\n\tversion: string;\n\tdependencies: Record<string, string>;\n\tpeerDependencies: Record<string, string>;\n\texports: PackageExports | null;\n\thasMainEntry: boolean;\n};\n\n/**\n * Get version, dependencies, peer dependencies, and exports from an installed package\n */\nfunction getPackageInfo(tmpDir: string, packageName: string): PackageInfo {\n\ttry {\n\t\t// Handle scoped packages - the package name in node_modules\n\t\tconst pkgJsonPath = path.join(\n\t\t\ttmpDir,\n\t\t\t\"node_modules\",\n\t\t\tpackageName,\n\t\t\t\"package.json\",\n\t\t);\n\t\tif (fs.existsSync(pkgJsonPath)) {\n\t\t\tconst pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, \"utf-8\"));\n\n\t\t\t// Check if package has a main entry point\n\t\t\tconst hasMainEntry = Boolean(\n\t\t\t\tpkgJson.main ||\n\t\t\t\t\tpkgJson.module ||\n\t\t\t\t\tpkgJson.exports?.[\".\"] ||\n\t\t\t\t\tpkgJson.exports?.[\"./index\"] ||\n\t\t\t\t\t(!pkgJson.exports && !pkgJson.main && !pkgJson.module),\n\t\t\t);\n\n\t\t\treturn {\n\t\t\t\tversion: pkgJson.version || \"unknown\",\n\t\t\t\tdependencies: pkgJson.dependencies || {},\n\t\t\t\tpeerDependencies: pkgJson.peerDependencies || {},\n\t\t\t\texports: pkgJson.exports || null,\n\t\t\t\thasMainEntry,\n\t\t\t};\n\t\t}\n\t} catch {\n\t\t// Ignore errors reading package info\n\t}\n\treturn {\n\t\tversion: \"unknown\",\n\t\tdependencies: {},\n\t\tpeerDependencies: {},\n\t\texports: null,\n\t\thasMainEntry: true,\n\t};\n}\n\n/**\n * Extract subpath export names from package exports field\n * Returns array of subpaths like [\"header\", \"body\", \"datagrid\"]\n */\nfunction getSubpathExports(exports: PackageExports | null): string[] {\n\tif (!exports) {\n\t\treturn [];\n\t}\n\n\tconst subpaths: string[] = [];\n\tfor (const key of Object.keys(exports)) {\n\t\t// Skip the main entry point and package.json\n\t\tif (key === \".\" || key === \"./package.json\") {\n\t\t\tcontinue;\n\t\t}\n\t\t// Remove leading \"./\" to get subpath name\n\t\tif (key.startsWith(\"./\")) {\n\t\t\tsubpaths.push(key.substring(2));\n\t\t}\n\t}\n\treturn subpaths;\n}\n\n/**\n * Result of finding subpaths for exports\n */\ntype SubpathMapping = {\n\t// Single subpath if all exports are from the same subpath\n\tsingleSubpath?: string;\n\t// Map of export name to subpath for multiple subpaths\n\texportToSubpath?: Map<string, string>;\n};\n\n/**\n * Find which subpath(s) export the given component names\n * Reads type definition files or JS files to find the exports\n */\nfunction findSubpathsForExports(\n\ttmpDir: string,\n\tpackageName: string,\n\texports: PackageExports,\n\tcomponentNames: string[],\n): SubpathMapping {\n\tconst packageDir = path.join(tmpDir, \"node_modules\", packageName);\n\tconst exportToSubpath = new Map<string, string>();\n\n\tfor (const [subpathKey, subpathValue] of Object.entries(exports)) {\n\t\t// Skip main entry and package.json\n\t\tif (subpathKey === \".\" || subpathKey === \"./package.json\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Get the types or import path\n\t\tlet filePath: string | undefined;\n\t\tif (typeof subpathValue === \"object\" && subpathValue !== null) {\n\t\t\t// Prefer types file for more accurate export detection\n\t\t\tfilePath = subpathValue.types || subpathValue.import;\n\t\t} else if (typeof subpathValue === \"string\") {\n\t\t\tfilePath = subpathValue;\n\t\t}\n\n\t\tif (!filePath) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Resolve the file path\n\t\tconst fullPath = path.join(packageDir, filePath);\n\n\t\ttry {\n\t\t\tif (fs.existsSync(fullPath)) {\n\t\t\t\tconst content = fs.readFileSync(fullPath, \"utf-8\");\n\t\t\t\tconst subpath = subpathKey.startsWith(\"./\")\n\t\t\t\t\t? subpathKey.substring(2)\n\t\t\t\t\t: subpathKey;\n\n\t\t\t\t// Check each component name\n\t\t\t\tfor (const name of componentNames) {\n\t\t\t\t\t// Skip if already found\n\t\t\t\t\tif (exportToSubpath.has(name)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Escape regex special characters in the name to prevent injection\n\t\t\t\t\tconst escapedName = escapeRegExp(name);\n\n\t\t\t\t\t// Look for various export patterns\n\t\t\t\t\tconst patterns = [\n\t\t\t\t\t\tnew RegExp(`export\\\\s*\\\\{[^}]*\\\\b${escapedName}\\\\b[^}]*\\\\}`, \"m\"),\n\t\t\t\t\t\tnew RegExp(\n\t\t\t\t\t\t\t`export\\\\s+declare\\\\s+(?:const|function|class)\\\\s+${escapedName}\\\\b`,\n\t\t\t\t\t\t\t\"m\",\n\t\t\t\t\t\t),\n\t\t\t\t\t\tnew RegExp(\n\t\t\t\t\t\t\t`export\\\\s+(?:const|function|class)\\\\s+${escapedName}\\\\b`,\n\t\t\t\t\t\t\t\"m\",\n\t\t\t\t\t\t),\n\t\t\t\t\t];\n\n\t\t\t\t\tif (patterns.some((pattern) => pattern.test(content))) {\n\t\t\t\t\t\texportToSubpath.set(name, subpath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore read errors, continue to next subpath\n\t\t}\n\t}\n\n\t// Check if all exports were found\n\tif (exportToSubpath.size !== componentNames.length) {\n\t\treturn {}; // Not all exports found\n\t}\n\n\t// Check if all exports are from the same subpath\n\tconst subpaths = new Set(exportToSubpath.values());\n\tif (subpaths.size === 1) {\n\t\treturn { singleSubpath: [...subpaths][0] };\n\t}\n\n\t// Multiple subpaths needed\n\treturn { exportToSubpath };\n}\n\n/**\n * Check the bundle size of an npm package\n */\nexport async function checkBundleSize(\n\toptions: BundleOptions,\n): Promise<BundleResult> {\n\tconst {\n\t\tpackageName: packageSpecifier,\n\t\texports,\n\t\tadditionalExternals,\n\t\tnoExternal,\n\t\tgzipLevel = 5,\n\t\tregistry,\n\t} = options;\n\n\t// Parse the package specifier to extract name, version, and subpath\n\tconst {\n\t\tname: packageName,\n\t\tversion: requestedVersion,\n\t\tsubpath,\n\t} = parsePackageSpecifier(packageSpecifier);\n\n\tconst tmpDir = createTempDir();\n\n\ttry {\n\t\t// Create initial package.json\n\t\tconst packageJson: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\ttype: string;\n\t\t\tdependencies: Record<string, string>;\n\t\t} = {\n\t\t\tname: \"bundlecheck-temp\",\n\t\t\tversion: \"1.0.0\",\n\t\t\ttype: \"module\",\n\t\t\tdependencies: {\n\t\t\t\t[packageName]: requestedVersion,\n\t\t\t},\n\t\t};\n\n\t\tfs.writeFileSync(\n\t\t\tpath.join(tmpDir, \"package.json\"),\n\t\t\tJSON.stringify(packageJson, null, 2),\n\t\t);\n\n\t\t// Install the main package (try pnpm first, fallback to npm)\n\t\tconst installCmd = getInstallCommand(registry);\n\t\texecSync(installCmd, {\n\t\t\tcwd: tmpDir,\n\t\t\tstdio: \"pipe\",\n\t\t});\n\n\t\t// Get package info (version, dependencies, peer dependencies, exports)\n\t\tconst pkgInfo = getPackageInfo(tmpDir, packageName);\n\t\tconst peerDepKeys = Object.keys(pkgInfo.peerDependencies);\n\n\t\t// Collect all dependency names (prod + peer)\n\t\tconst allDependencies = [\n\t\t\t...new Set([...Object.keys(pkgInfo.dependencies), ...peerDepKeys]),\n\t\t].sort();\n\n\t\tif (peerDepKeys.length > 0) {\n\t\t\t// Add peer dependencies to package.json\n\t\t\tfor (const dep of peerDepKeys) {\n\t\t\t\t// Use the version range from peer dependencies\n\t\t\t\tpackageJson.dependencies[dep] = pkgInfo.peerDependencies[dep];\n\t\t\t}\n\n\t\t\t// Update package.json and reinstall\n\t\t\tfs.writeFileSync(\n\t\t\t\tpath.join(tmpDir, \"package.json\"),\n\t\t\t\tJSON.stringify(packageJson, null, 2),\n\t\t\t);\n\n\t\t\texecSync(installCmd, {\n\t\t\t\tcwd: tmpDir,\n\t\t\t\tstdio: \"pipe\",\n\t\t\t});\n\t\t}\n\n\t\t// Determine if we need to use all subpath exports or find the right subpath(s)\n\t\tlet allSubpaths: string[] | undefined;\n\t\tlet resolvedSubpath = subpath;\n\t\tlet exportToSubpath: Map<string, string> | undefined;\n\n\t\tif (!subpath && !pkgInfo.hasMainEntry && pkgInfo.exports) {\n\t\t\tif (exports && exports.length > 0) {\n\t\t\t\t// User specified exports but no subpath - try to find the right subpath(s)\n\t\t\t\tconst mapping = findSubpathsForExports(\n\t\t\t\t\ttmpDir,\n\t\t\t\t\tpackageName,\n\t\t\t\t\tpkgInfo.exports,\n\t\t\t\t\texports,\n\t\t\t\t);\n\n\t\t\t\tif (mapping.singleSubpath) {\n\t\t\t\t\t// All exports from the same subpath\n\t\t\t\t\tresolvedSubpath = mapping.singleSubpath;\n\t\t\t\t} else if (mapping.exportToSubpath) {\n\t\t\t\t\t// Exports from multiple subpaths\n\t\t\t\t\texportToSubpath = mapping.exportToSubpath;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If still no subpath resolved and no mapping, bundle all subpaths\n\t\t\tif (!resolvedSubpath && !exportToSubpath) {\n\t\t\t\tallSubpaths = getSubpathExports(pkgInfo.exports);\n\t\t\t}\n\t\t}\n\n\t\t// Create entry file with appropriate content\n\t\tconst entryContent = generateEntryContent({\n\t\t\tpackageName,\n\t\t\tsubpath: resolvedSubpath,\n\t\t\texports,\n\t\t\tallSubpaths,\n\t\t\texportToSubpath,\n\t\t});\n\t\tconst entryFile = path.join(tmpDir, \"entry.js\");\n\t\tfs.writeFileSync(entryFile, entryContent);\n\n\t\t// Get externals\n\t\tconst externals = getExternals(\n\t\t\tpackageName,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal,\n\t\t);\n\n\t\t// Bundle with esbuild\n\t\tconst result = await esbuild.build({\n\t\t\tentryPoints: [entryFile],\n\t\t\tbundle: true,\n\t\t\twrite: false,\n\t\t\tformat: \"esm\",\n\t\t\tplatform: \"browser\",\n\t\t\ttarget: \"es2020\",\n\t\t\tminify: true,\n\t\t\ttreeShaking: true,\n\t\t\texternal: externals,\n\t\t\tmetafile: true,\n\t\t});\n\n\t\t// Get raw size\n\t\tconst bundleContent = result.outputFiles[0].contents;\n\t\tconst rawSize = bundleContent.length;\n\n\t\t// Gzip the bundle\n\t\tconst gzipped = await gzipAsync(Buffer.from(bundleContent), {\n\t\t\tlevel: gzipLevel,\n\t\t});\n\t\tconst gzipSize = gzipped.length;\n\n\t\t// Determine the display name\n\t\tlet displayName = packageName;\n\t\tif (resolvedSubpath) {\n\t\t\tdisplayName = `${packageName}/${resolvedSubpath}`;\n\t\t} else if (exportToSubpath && exportToSubpath.size > 0) {\n\t\t\t// Multiple subpaths - show them all\n\t\t\tconst uniqueSubpaths = [...new Set(exportToSubpath.values())].sort();\n\t\t\tdisplayName = `${packageName}/{${uniqueSubpaths.join(\", \")}}`;\n\t\t}\n\n\t\treturn {\n\t\t\tpackageName: displayName,\n\t\t\tpackageVersion: pkgInfo.version,\n\t\t\texports: exports || [],\n\t\t\trawSize,\n\t\t\tgzipSize,\n\t\t\tgzipLevel,\n\t\t\texternals,\n\t\t\tdependencies: allDependencies,\n\t\t};\n\t} finally {\n\t\tcleanupTempDir(tmpDir);\n\t}\n}\n"],"names":["execSync","fs","os","path","promisify","zlib","esbuild","DEFAULT_EXTERNALS","gzipAsync","gzip","escapeRegExp","str","replace","parsePackageSpecifier","specifier","workingSpec","version","startsWith","secondAtIndex","indexOf","substring","parts","split","length","name","subpath","slice","join","atIndex","slashIndex","formatBytes","bytes","k","sizes","i","Math","floor","log","Number","parseFloat","toFixed","createTempDir","tmpDir","tmpdir","Date","now","mkdirSync","recursive","cleanupTempDir","rmSync","force","isPnpmAvailable","stdio","usePnpm","validateRegistryUrl","registry","url","URL","Error","protocol","toString","getInstallCommand","registryArg","sanitizedRegistry","generateEntryContent","options","packageName","exports","allSubpaths","exportToSubpath","size","subpathToExports","Map","exportName","sp","existing","get","push","set","lines","allExportNames","exportNames","importPath","names","importNames","imports","map","getExternals","externals","noExternal","result","filter","e","Set","getPackageInfo","pkgJsonPath","existsSync","pkgJson","JSON","parse","readFileSync","hasMainEntry","Boolean","main","module","dependencies","peerDependencies","getSubpathExports","subpaths","key","Object","keys","findSubpathsForExports","componentNames","packageDir","subpathKey","subpathValue","entries","filePath","types","import","fullPath","content","has","escapedName","patterns","RegExp","some","pattern","test","values","singleSubpath","checkBundleSize","packageSpecifier","additionalExternals","gzipLevel","requestedVersion","packageJson","type","writeFileSync","stringify","installCmd","cwd","pkgInfo","peerDepKeys","allDependencies","sort","dep","resolvedSubpath","mapping","entryContent","entryFile","build","entryPoints","bundle","write","format","platform","target","minify","treeShaking","external","metafile","bundleContent","outputFiles","contents","rawSize","gzipped","Buffer","from","level","gzipSize","displayName","uniqueSubpaths","packageVersion"],"mappings":"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"}
|
package/dist/defaults.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare const defaultFlags: {
|
|
|
4
4
|
external: string;
|
|
5
5
|
noExternal: boolean;
|
|
6
6
|
versions: boolean;
|
|
7
|
+
registry: string;
|
|
7
8
|
};
|
|
8
9
|
export declare const TREND_VERSION_COUNT = 5;
|
|
9
10
|
export declare const DEFAULT_EXTERNALS: string[];
|
|
11
|
+
export declare const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
package/dist/defaults.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
gzipLevel: 5,
|
|
4
4
|
external: "",
|
|
5
5
|
noExternal: false,
|
|
6
|
-
versions: false
|
|
6
|
+
versions: false,
|
|
7
|
+
registry: ""
|
|
7
8
|
};
|
|
8
9
|
export const TREND_VERSION_COUNT = 5;
|
|
9
10
|
export const DEFAULT_EXTERNALS = [
|
|
10
11
|
"react",
|
|
11
12
|
"react-dom"
|
|
12
13
|
];
|
|
14
|
+
export const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
13
15
|
|
|
14
16
|
//# sourceMappingURL=defaults.js.map
|
package/dist/defaults.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["/* istanbul ignore file */\n\nexport const defaultFlags = {\n\tboring: false,\n\tgzipLevel: 5,\n\texternal: \"\",\n\tnoExternal: false,\n\tversions: false,\n};\n\nexport const TREND_VERSION_COUNT = 5;\n\nexport const DEFAULT_EXTERNALS = [\"react\", \"react-dom\"];\n"],"names":["defaultFlags","boring","gzipLevel","external","noExternal","versions","TREND_VERSION_COUNT","DEFAULT_EXTERNALS"],"mappings":"AAAA,wBAAwB,GAExB,OAAO,MAAMA,eAAe;IAC3BC,QAAQ;IACRC,WAAW;IACXC,UAAU;IACVC,YAAY;IACZC,UAAU;AACX,EAAE;AAEF,OAAO,MAAMC,sBAAsB,EAAE;AAErC,OAAO,MAAMC,oBAAoB;IAAC;IAAS;CAAY,CAAC"}
|
|
1
|
+
{"version":3,"sources":["../src/defaults.ts"],"sourcesContent":["/* istanbul ignore file */\n\nexport const defaultFlags = {\n\tboring: false,\n\tgzipLevel: 5,\n\texternal: \"\",\n\tnoExternal: false,\n\tversions: false,\n\tregistry: \"\",\n};\n\nexport const TREND_VERSION_COUNT = 5;\n\nexport const DEFAULT_EXTERNALS = [\"react\", \"react-dom\"];\n\nexport const DEFAULT_REGISTRY = \"https://registry.npmjs.org\";\n"],"names":["defaultFlags","boring","gzipLevel","external","noExternal","versions","registry","TREND_VERSION_COUNT","DEFAULT_EXTERNALS","DEFAULT_REGISTRY"],"mappings":"AAAA,wBAAwB,GAExB,OAAO,MAAMA,eAAe;IAC3BC,QAAQ;IACRC,WAAW;IACXC,UAAU;IACVC,YAAY;IACZC,UAAU;IACVC,UAAU;AACX,EAAE;AAEF,OAAO,MAAMC,sBAAsB,EAAE;AAErC,OAAO,MAAMC,oBAAoB;IAAC;IAAS;CAAY,CAAC;AAExD,OAAO,MAAMC,mBAAmB,6BAA6B"}
|
package/dist/parse.d.ts
CHANGED
package/dist/parse.js
CHANGED
|
@@ -42,6 +42,10 @@ export const config = parser({
|
|
|
42
42
|
{
|
|
43
43
|
command: "bundlecheck lodash --trend 3",
|
|
44
44
|
comment: "## Show bundle size trend for 3 versions"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
command: "bundlecheck lodash --registry https://registry.example.com",
|
|
48
|
+
comment: "## Use a custom npm registry"
|
|
45
49
|
}
|
|
46
50
|
],
|
|
47
51
|
flags: {
|
|
@@ -89,6 +93,12 @@ export const config = parser({
|
|
|
89
93
|
shortFlag: "t",
|
|
90
94
|
description: "Show bundle size trend for N recent versions (default: 5)",
|
|
91
95
|
type: "string"
|
|
96
|
+
},
|
|
97
|
+
registry: {
|
|
98
|
+
shortFlag: "r",
|
|
99
|
+
default: defaultFlags.registry,
|
|
100
|
+
description: "Custom npm registry URL (default: https://registry.npmjs.org)",
|
|
101
|
+
type: "string"
|
|
92
102
|
}
|
|
93
103
|
},
|
|
94
104
|
parameters: {
|
package/dist/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parse.ts"],"sourcesContent":["/* istanbul ignore file */\nimport { parser } from \"@node-cli/parser\";\nimport { DEFAULT_EXTERNALS, defaultFlags } from \"./defaults.js\";\n\nexport type Flags = {\n\tboring?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tversions?: boolean;\n\ttrend?: string;\n\tgzipLevel?: number;\n\texternal?: string;\n\tnoExternal?: boolean;\n};\n\nexport type Parameters = {\n\t[\"0\"]?: string; // package name\n\t[\"1\"]?: string; // exports (comma-separated)\n};\n\nexport type Configuration = {\n\tflags?: Flags;\n\tparameters?: Parameters;\n\tusage?: boolean;\n\tshowHelp?: () => void;\n};\n\nexport const config: Configuration = parser({\n\tmeta: import.meta,\n\texamples: [\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash\",\n\t\t\tcomment: \"## Check the bundle size of the entire lodash package\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash@4.17.0\",\n\t\t\tcomment: \"## Check a specific version of a package\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck @mantine/core\",\n\t\t\tcomment: \"## Check the bundle size of the entire @mantine/core package\",\n\t\t},\n\t\t{\n\t\t\tcommand: 'bundlecheck @mantine/core \"ScrollArea,Button\"',\n\t\t\tcomment:\n\t\t\t\t\"## Check the bundle size of specific exports from @mantine/core\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck react --no-external\",\n\t\t\tcomment:\n\t\t\t\t\"## Check the bundle size of react itself (not marked as external)\",\n\t\t},\n\t\t{\n\t\t\tcommand: 'bundlecheck some-pkg --external \"vue,svelte\"',\n\t\t\tcomment: \"## Add vue and svelte as additional external dependencies\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --gzip-level 6\",\n\t\t\tcomment: \"## Use a different gzip compression level (1-9)\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --versions\",\n\t\t\tcomment: \"## Choose from available versions interactively\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --trend\",\n\t\t\tcomment: \"## Show bundle size trend (default: 5 versions)\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --trend 3\",\n\t\t\tcomment: \"## Show bundle size trend for 3 versions\",\n\t\t},\n\t],\n\tflags: {\n\t\tgzipLevel: {\n\t\t\tshortFlag: \"g\",\n\t\t\tdefault: defaultFlags.gzipLevel,\n\t\t\tdescription: \"Gzip compression level (1-9, default: 5)\",\n\t\t\ttype: \"number\",\n\t\t},\n\t\texternal: {\n\t\t\tshortFlag: \"e\",\n\t\t\tdefault: defaultFlags.external,\n\t\t\tdescription: `Comma-separated additional externals (default externals: ${DEFAULT_EXTERNALS.join(\", \")})`,\n\t\t\ttype: \"string\",\n\t\t},\n\t\tnoExternal: {\n\t\t\tshortFlag: \"n\",\n\t\t\tdefault: defaultFlags.noExternal,\n\t\t\tdescription:\n\t\t\t\t\"Do not mark any packages as external (useful for checking react/react-dom themselves)\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tboring: {\n\t\t\tshortFlag: \"b\",\n\t\t\tdefault: defaultFlags.boring,\n\t\t\tdescription: \"Do not use color output\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\thelp: {\n\t\t\tshortFlag: \"h\",\n\t\t\tdescription: \"Display help instructions\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tversion: {\n\t\t\tshortFlag: \"v\",\n\t\t\tdescription: \"Output the current version\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tversions: {\n\t\t\tshortFlag: \"V\",\n\t\t\tdefault: defaultFlags.versions,\n\t\t\tdescription: \"Choose from available package versions interactively\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\ttrend: {\n\t\t\tshortFlag: \"t\",\n\t\t\tdescription: \"Show bundle size trend for N recent versions (default: 5)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t},\n\tparameters: {\n\t\tpackage: {\n\t\t\tdescription: \"The npm package to check (e.g., lodash, @mantine/core)\",\n\t\t},\n\t\texports: {\n\t\t\tdescription:\n\t\t\t\t'Comma-separated list of exports to check (e.g., \"ScrollArea,Button\")',\n\t\t},\n\t},\n\trestrictions: [\n\t\t{\n\t\t\texit: 1,\n\t\t\tmessage: () => \"Error: Package name is required\",\n\t\t\ttest: (flags, parameters) => !parameters?.[\"0\"],\n\t\t},\n\t\t{\n\t\t\texit: 1,\n\t\t\tmessage: () => \"Error: Gzip level must be between 1 and 9\",\n\t\t\ttest: (flags) =>\n\t\t\t\tflags.gzipLevel !== undefined &&\n\t\t\t\t(flags.gzipLevel < 1 || flags.gzipLevel > 9),\n\t\t},\n\t],\n\tusage: true,\n\tdefaultFlags,\n});\n"],"names":["parser","DEFAULT_EXTERNALS","defaultFlags","config","meta","examples","command","comment","flags","gzipLevel","shortFlag","default","description","type","external","join","noExternal","boring","help","version","versions","trend","parameters","package","exports","restrictions","exit","message","test","undefined","usage"],"mappings":"AAAA,wBAAwB,GACxB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,iBAAiB,EAAEC,YAAY,QAAQ,gBAAgB;
|
|
1
|
+
{"version":3,"sources":["../src/parse.ts"],"sourcesContent":["/* istanbul ignore file */\nimport { parser } from \"@node-cli/parser\";\nimport { DEFAULT_EXTERNALS, defaultFlags } from \"./defaults.js\";\n\nexport type Flags = {\n\tboring?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tversions?: boolean;\n\ttrend?: string;\n\tgzipLevel?: number;\n\texternal?: string;\n\tnoExternal?: boolean;\n\tregistry?: string;\n};\n\nexport type Parameters = {\n\t[\"0\"]?: string; // package name\n\t[\"1\"]?: string; // exports (comma-separated)\n};\n\nexport type Configuration = {\n\tflags?: Flags;\n\tparameters?: Parameters;\n\tusage?: boolean;\n\tshowHelp?: () => void;\n};\n\nexport const config: Configuration = parser({\n\tmeta: import.meta,\n\texamples: [\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash\",\n\t\t\tcomment: \"## Check the bundle size of the entire lodash package\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash@4.17.0\",\n\t\t\tcomment: \"## Check a specific version of a package\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck @mantine/core\",\n\t\t\tcomment: \"## Check the bundle size of the entire @mantine/core package\",\n\t\t},\n\t\t{\n\t\t\tcommand: 'bundlecheck @mantine/core \"ScrollArea,Button\"',\n\t\t\tcomment:\n\t\t\t\t\"## Check the bundle size of specific exports from @mantine/core\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck react --no-external\",\n\t\t\tcomment:\n\t\t\t\t\"## Check the bundle size of react itself (not marked as external)\",\n\t\t},\n\t\t{\n\t\t\tcommand: 'bundlecheck some-pkg --external \"vue,svelte\"',\n\t\t\tcomment: \"## Add vue and svelte as additional external dependencies\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --gzip-level 6\",\n\t\t\tcomment: \"## Use a different gzip compression level (1-9)\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --versions\",\n\t\t\tcomment: \"## Choose from available versions interactively\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --trend\",\n\t\t\tcomment: \"## Show bundle size trend (default: 5 versions)\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --trend 3\",\n\t\t\tcomment: \"## Show bundle size trend for 3 versions\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --registry https://registry.example.com\",\n\t\t\tcomment: \"## Use a custom npm registry\",\n\t\t},\n\t],\n\tflags: {\n\t\tgzipLevel: {\n\t\t\tshortFlag: \"g\",\n\t\t\tdefault: defaultFlags.gzipLevel,\n\t\t\tdescription: \"Gzip compression level (1-9, default: 5)\",\n\t\t\ttype: \"number\",\n\t\t},\n\t\texternal: {\n\t\t\tshortFlag: \"e\",\n\t\t\tdefault: defaultFlags.external,\n\t\t\tdescription: `Comma-separated additional externals (default externals: ${DEFAULT_EXTERNALS.join(\", \")})`,\n\t\t\ttype: \"string\",\n\t\t},\n\t\tnoExternal: {\n\t\t\tshortFlag: \"n\",\n\t\t\tdefault: defaultFlags.noExternal,\n\t\t\tdescription:\n\t\t\t\t\"Do not mark any packages as external (useful for checking react/react-dom themselves)\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tboring: {\n\t\t\tshortFlag: \"b\",\n\t\t\tdefault: defaultFlags.boring,\n\t\t\tdescription: \"Do not use color output\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\thelp: {\n\t\t\tshortFlag: \"h\",\n\t\t\tdescription: \"Display help instructions\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tversion: {\n\t\t\tshortFlag: \"v\",\n\t\t\tdescription: \"Output the current version\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\tversions: {\n\t\t\tshortFlag: \"V\",\n\t\t\tdefault: defaultFlags.versions,\n\t\t\tdescription: \"Choose from available package versions interactively\",\n\t\t\ttype: \"boolean\",\n\t\t},\n\t\ttrend: {\n\t\t\tshortFlag: \"t\",\n\t\t\tdescription: \"Show bundle size trend for N recent versions (default: 5)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t\tregistry: {\n\t\t\tshortFlag: \"r\",\n\t\t\tdefault: defaultFlags.registry,\n\t\t\tdescription:\n\t\t\t\t\"Custom npm registry URL (default: https://registry.npmjs.org)\",\n\t\t\ttype: \"string\",\n\t\t},\n\t},\n\tparameters: {\n\t\tpackage: {\n\t\t\tdescription: \"The npm package to check (e.g., lodash, @mantine/core)\",\n\t\t},\n\t\texports: {\n\t\t\tdescription:\n\t\t\t\t'Comma-separated list of exports to check (e.g., \"ScrollArea,Button\")',\n\t\t},\n\t},\n\trestrictions: [\n\t\t{\n\t\t\texit: 1,\n\t\t\tmessage: () => \"Error: Package name is required\",\n\t\t\ttest: (flags, parameters) => !parameters?.[\"0\"],\n\t\t},\n\t\t{\n\t\t\texit: 1,\n\t\t\tmessage: () => \"Error: Gzip level must be between 1 and 9\",\n\t\t\ttest: (flags) =>\n\t\t\t\tflags.gzipLevel !== undefined &&\n\t\t\t\t(flags.gzipLevel < 1 || flags.gzipLevel > 9),\n\t\t},\n\t],\n\tusage: true,\n\tdefaultFlags,\n});\n"],"names":["parser","DEFAULT_EXTERNALS","defaultFlags","config","meta","examples","command","comment","flags","gzipLevel","shortFlag","default","description","type","external","join","noExternal","boring","help","version","versions","trend","registry","parameters","package","exports","restrictions","exit","message","test","undefined","usage"],"mappings":"AAAA,wBAAwB,GACxB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,SAASC,iBAAiB,EAAEC,YAAY,QAAQ,gBAAgB;AA0BhE,OAAO,MAAMC,SAAwBH,OAAO;IAC3CI,MAAM;IACNC,UAAU;QACT;YACCC,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SACC;QACF;QACA;YACCD,SAAS;YACTC,SACC;QACF;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;QACA;YACCD,SAAS;YACTC,SAAS;QACV;KACA;IACDC,OAAO;QACNC,WAAW;YACVC,WAAW;YACXC,SAAST,aAAaO,SAAS;YAC/BG,aAAa;YACbC,MAAM;QACP;QACAC,UAAU;YACTJ,WAAW;YACXC,SAAST,aAAaY,QAAQ;YAC9BF,aAAa,CAAC,yDAAyD,EAAEX,kBAAkBc,IAAI,CAAC,MAAM,CAAC,CAAC;YACxGF,MAAM;QACP;QACAG,YAAY;YACXN,WAAW;YACXC,SAAST,aAAac,UAAU;YAChCJ,aACC;YACDC,MAAM;QACP;QACAI,QAAQ;YACPP,WAAW;YACXC,SAAST,aAAae,MAAM;YAC5BL,aAAa;YACbC,MAAM;QACP;QACAK,MAAM;YACLR,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAM,SAAS;YACRT,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAO,UAAU;YACTV,WAAW;YACXC,SAAST,aAAakB,QAAQ;YAC9BR,aAAa;YACbC,MAAM;QACP;QACAQ,OAAO;YACNX,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAS,UAAU;YACTZ,WAAW;YACXC,SAAST,aAAaoB,QAAQ;YAC9BV,aACC;YACDC,MAAM;QACP;IACD;IACAU,YAAY;QACXC,SAAS;YACRZ,aAAa;QACd;QACAa,SAAS;YACRb,aACC;QACF;IACD;IACAc,cAAc;QACb;YACCC,MAAM;YACNC,SAAS,IAAM;YACfC,MAAM,CAACrB,OAAOe,aAAe,CAACA,YAAY,CAAC,IAAI;QAChD;QACA;YACCI,MAAM;YACNC,SAAS,IAAM;YACfC,MAAM,CAACrB,QACNA,MAAMC,SAAS,KAAKqB,aACnBtB,CAAAA,MAAMC,SAAS,GAAG,KAAKD,MAAMC,SAAS,GAAG,CAAA;QAC5C;KACA;IACDsB,OAAO;IACP7B;AACD,GAAG"}
|
package/dist/trend.d.ts
CHANGED
package/dist/trend.js
CHANGED
|
@@ -15,7 +15,7 @@ import { TREND_VERSION_COUNT } from "./defaults.js";
|
|
|
15
15
|
/**
|
|
16
16
|
* Analyze bundle size trend across multiple versions
|
|
17
17
|
*/ export async function analyzeTrend(options) {
|
|
18
|
-
const { packageName, versions, exports, additionalExternals, noExternal, gzipLevel, boring } = options;
|
|
18
|
+
const { packageName, versions, exports, additionalExternals, noExternal, gzipLevel, boring, registry } = options;
|
|
19
19
|
const log = new Logger({
|
|
20
20
|
boring
|
|
21
21
|
});
|
|
@@ -29,7 +29,8 @@ import { TREND_VERSION_COUNT } from "./defaults.js";
|
|
|
29
29
|
exports,
|
|
30
30
|
additionalExternals,
|
|
31
31
|
noExternal,
|
|
32
|
-
gzipLevel
|
|
32
|
+
gzipLevel,
|
|
33
|
+
registry
|
|
33
34
|
});
|
|
34
35
|
results.push({
|
|
35
36
|
version,
|
|
@@ -54,27 +55,41 @@ import { TREND_VERSION_COUNT } from "./defaults.js";
|
|
|
54
55
|
const lines = [];
|
|
55
56
|
// Color helper (respects boring flag)
|
|
56
57
|
const blue = (text)=>boring ? text : kleur.blue(text);
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
// Create maps from formatted string to representative value
|
|
59
|
+
// This ensures values that display the same get the same bar length
|
|
60
|
+
const gzipFormattedToValue = new Map();
|
|
61
|
+
const rawFormattedToValue = new Map();
|
|
62
|
+
for (const result of results){
|
|
63
|
+
const gzipFormatted = formatBytes(result.gzipSize);
|
|
64
|
+
const rawFormatted = formatBytes(result.rawSize);
|
|
65
|
+
// Use first occurrence as representative value for each formatted string
|
|
66
|
+
if (!gzipFormattedToValue.has(gzipFormatted)) {
|
|
67
|
+
gzipFormattedToValue.set(gzipFormatted, result.gzipSize);
|
|
68
|
+
}
|
|
69
|
+
if (!rawFormattedToValue.has(rawFormatted)) {
|
|
70
|
+
rawFormattedToValue.set(rawFormatted, result.rawSize);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Get unique representative values for min/max calculation
|
|
74
|
+
const uniqueGzipValues = [
|
|
75
|
+
...gzipFormattedToValue.values()
|
|
76
|
+
];
|
|
77
|
+
const uniqueRawValues = [
|
|
78
|
+
...rawFormattedToValue.values()
|
|
79
|
+
];
|
|
80
|
+
const minGzipSize = Math.min(...uniqueGzipValues);
|
|
81
|
+
const maxGzipSize = Math.max(...uniqueGzipValues);
|
|
82
|
+
const minRawSize = Math.min(...uniqueRawValues);
|
|
83
|
+
const maxRawSize = Math.max(...uniqueRawValues);
|
|
69
84
|
// Find max version length for alignment
|
|
70
85
|
const maxVersionLen = Math.max(...results.map((r)=>r.version.length));
|
|
71
86
|
// Bar width (characters)
|
|
72
87
|
const barWidth = 30;
|
|
73
88
|
const minBarWidth = 10; // Minimum bar length for smallest value
|
|
74
89
|
// Helper to calculate bar length with min-max scaling
|
|
75
|
-
const calcBarLength = (value, min, max
|
|
76
|
-
if (max === min
|
|
77
|
-
return barWidth; // All values are
|
|
90
|
+
const calcBarLength = (value, min, max)=>{
|
|
91
|
+
if (max === min) {
|
|
92
|
+
return barWidth; // All values are the same
|
|
78
93
|
}
|
|
79
94
|
// Scale from minBarWidth to barWidth based on position between min and max
|
|
80
95
|
const ratio = (value - min) / (max - min);
|
|
@@ -88,20 +103,24 @@ import { TREND_VERSION_COUNT } from "./defaults.js";
|
|
|
88
103
|
// Gzip size bars
|
|
89
104
|
lines.push(blue("Gzip Size:"));
|
|
90
105
|
for (const result of results){
|
|
91
|
-
const
|
|
106
|
+
const sizeStr = formatBytes(result.gzipSize);
|
|
107
|
+
// Use representative value for this formatted string to ensure consistent bar length
|
|
108
|
+
const representativeValue = gzipFormattedToValue.get(sizeStr);
|
|
109
|
+
const barLength = calcBarLength(representativeValue, minGzipSize, maxGzipSize);
|
|
92
110
|
const bar = "▇".repeat(barLength);
|
|
93
111
|
const padding = " ".repeat(maxVersionLen - result.version.length);
|
|
94
|
-
const sizeStr = formatBytes(result.gzipSize);
|
|
95
112
|
lines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);
|
|
96
113
|
}
|
|
97
114
|
lines.push("");
|
|
98
115
|
// Raw size bars
|
|
99
116
|
lines.push(blue("Raw Size:"));
|
|
100
117
|
for (const result of results){
|
|
101
|
-
const
|
|
118
|
+
const sizeStr = formatBytes(result.rawSize);
|
|
119
|
+
// Use representative value for this formatted string to ensure consistent bar length
|
|
120
|
+
const representativeValue = rawFormattedToValue.get(sizeStr);
|
|
121
|
+
const barLength = calcBarLength(representativeValue, minRawSize, maxRawSize);
|
|
102
122
|
const bar = "▇".repeat(barLength);
|
|
103
123
|
const padding = " ".repeat(maxVersionLen - result.version.length);
|
|
104
|
-
const sizeStr = formatBytes(result.rawSize);
|
|
105
124
|
lines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);
|
|
106
125
|
}
|
|
107
126
|
lines.push("");
|
package/dist/trend.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/trend.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport { prerelease } from \"semver\";\nimport { checkBundleSize, formatBytes } from \"./bundler.js\";\nimport { TREND_VERSION_COUNT } from \"./defaults.js\";\n\nexport type TrendResult = {\n\tversion: string;\n\trawSize: number;\n\tgzipSize: number;\n};\n\nexport type TrendOptions = {\n\tpackageName: string;\n\tversions: string[];\n\texports?: string[];\n\tadditionalExternals?: string[];\n\tnoExternal?: boolean;\n\tgzipLevel?: number;\n\tboring?: boolean;\n};\n\n/**\n * Select versions for trend analysis\n * Returns the most recent stable versions (newest first)\n * Filters out prerelease versions (canary, alpha, beta, rc, etc.)\n */\nexport function selectTrendVersions(\n\tallVersions: string[],\n\tcount: number = TREND_VERSION_COUNT,\n): string[] {\n\t// Filter out prerelease versions (canary, alpha, beta, rc, etc.)\n\tconst stableVersions = allVersions.filter((v) => !prerelease(v));\n\treturn stableVersions.slice(0, count);\n}\n\n/**\n * Analyze bundle size trend across multiple versions\n */\nexport async function analyzeTrend(\n\toptions: TrendOptions,\n): Promise<TrendResult[]> {\n\tconst {\n\t\tpackageName,\n\t\tversions,\n\t\texports,\n\t\tadditionalExternals,\n\t\tnoExternal,\n\t\tgzipLevel,\n\t\tboring,\n\t} = options;\n\n\tconst log = new Logger({ boring });\n\tconst results: TrendResult[] = [];\n\n\tfor (const version of versions) {\n\t\tconst versionedPackage = `${packageName}@${version}`;\n\t\tlog.info(` Checking ${version}...`);\n\n\t\ttry {\n\t\t\tconst result = await checkBundleSize({\n\t\t\t\tpackageName: versionedPackage,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal,\n\t\t\t\tgzipLevel,\n\t\t\t});\n\n\t\t\tresults.push({\n\t\t\t\tversion,\n\t\t\t\trawSize: result.rawSize,\n\t\t\t\tgzipSize: result.gzipSize,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Skip versions that fail to analyze\n\t\t\tlog.info(` Skipping ${version} (failed to analyze)`);\n\t\t}\n\t}\n\n\treturn results;\n}\n\n/**\n * Render a bar graph showing bundle size trend\n */\nexport function renderTrendGraph(\n\tpackageName: string,\n\tresults: TrendResult[],\n\tboring: boolean = false,\n): string[] {\n\tif (results.length === 0) {\n\t\treturn [\"No data to display\"];\n\t}\n\n\tconst lines: string[] = [];\n\n\t// Color helper (respects boring flag)\n\tconst blue = (text: string) => (boring ? text : kleur.blue(text));\n\n\t// Find min/max sizes for scaling (use min-max scaling to show differences)\n\tconst gzipSizes = results.map((r) => r.gzipSize);\n\tconst rawSizes = results.map((r) => r.rawSize);\n\n\tconst minGzipSize = Math.min(...gzipSizes);\n\tconst maxGzipSize = Math.max(...gzipSizes);\n\tconst minRawSize = Math.min(...rawSizes);\n\tconst maxRawSize = Math.max(...rawSizes);\n\n\t// Check if all formatted values are the same (to avoid misleading bar differences)\n\tconst formattedGzipSizes = results.map((r) => formatBytes(r.gzipSize));\n\tconst formattedRawSizes = results.map((r) => formatBytes(r.rawSize));\n\tconst allGzipSame = new Set(formattedGzipSizes).size === 1;\n\tconst allRawSame = new Set(formattedRawSizes).size === 1;\n\n\t// Find max version length for alignment\n\tconst maxVersionLen = Math.max(...results.map((r) => r.version.length));\n\n\t// Bar width (characters)\n\tconst barWidth = 30;\n\tconst minBarWidth = 10; // Minimum bar length for smallest value\n\n\t// Helper to calculate bar length with min-max scaling\n\tconst calcBarLength = (\n\t\tvalue: number,\n\t\tmin: number,\n\t\tmax: number,\n\t\tallSame: boolean,\n\t): number => {\n\t\tif (max === min || allSame) {\n\t\t\treturn barWidth; // All values are effectively the same\n\t\t}\n\t\t// Scale from minBarWidth to barWidth based on position between min and max\n\t\tconst ratio = (value - min) / (max - min);\n\t\treturn Math.round(minBarWidth + ratio * (barWidth - minBarWidth));\n\t};\n\n\t// Header\n\tlines.push(\"\");\n\tlines.push(`${blue(\"Bundle Size:\")} ${packageName}`);\n\tlines.push(\"─\".repeat(60));\n\tlines.push(\"\");\n\n\t// Gzip size bars\n\tlines.push(blue(\"Gzip Size:\"));\n\tfor (const result of results) {\n\t\tconst barLength = calcBarLength(\n\t\t\tresult.gzipSize,\n\t\t\tminGzipSize,\n\t\t\tmaxGzipSize,\n\t\t\tallGzipSame,\n\t\t);\n\t\tconst bar = \"▇\".repeat(barLength);\n\t\tconst padding = \" \".repeat(maxVersionLen - result.version.length);\n\t\tconst sizeStr = formatBytes(result.gzipSize);\n\t\tlines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Raw size bars\n\tlines.push(blue(\"Raw Size:\"));\n\tfor (const result of results) {\n\t\tconst barLength = calcBarLength(\n\t\t\tresult.rawSize,\n\t\t\tminRawSize,\n\t\t\tmaxRawSize,\n\t\t\tallRawSame,\n\t\t);\n\t\tconst bar = \"▇\".repeat(barLength);\n\t\tconst padding = \" \".repeat(maxVersionLen - result.version.length);\n\t\tconst sizeStr = formatBytes(result.rawSize);\n\t\tlines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Summary\n\tconst oldestResult = results[results.length - 1];\n\tconst newestResult = results[0];\n\n\tif (results.length > 1) {\n\t\tconst gzipDiff = newestResult.gzipSize - oldestResult.gzipSize;\n\t\tconst gzipPercent = ((gzipDiff / oldestResult.gzipSize) * 100).toFixed(1);\n\t\tconst rawDiff = newestResult.rawSize - oldestResult.rawSize;\n\t\tconst rawPercent = ((rawDiff / oldestResult.rawSize) * 100).toFixed(1);\n\n\t\tconst gzipTrend =\n\t\t\tgzipDiff >= 0\n\t\t\t\t? `+${formatBytes(gzipDiff)}`\n\t\t\t\t: `-${formatBytes(Math.abs(gzipDiff))}`;\n\t\tconst rawTrend =\n\t\t\trawDiff >= 0\n\t\t\t\t? `+${formatBytes(rawDiff)}`\n\t\t\t\t: `-${formatBytes(Math.abs(rawDiff))}`;\n\n\t\tlines.push(\"─\".repeat(60));\n\t\tlines.push(\n\t\t\t`Change from ${oldestResult.version} to ${newestResult.version}:`,\n\t\t);\n\t\tlines.push(\n\t\t\t` ${blue(\"Gzip:\")} ${gzipTrend} (${gzipDiff >= 0 ? \"+\" : \"\"}${gzipPercent}%)`,\n\t\t);\n\t\tlines.push(\n\t\t\t` ${blue(\"Raw:\")} ${rawTrend} (${rawDiff >= 0 ? \"+\" : \"\"}${rawPercent}%)`,\n\t\t);\n\t}\n\n\tlines.push(\"\");\n\n\treturn lines;\n}\n"],"names":["Logger","kleur","prerelease","checkBundleSize","formatBytes","TREND_VERSION_COUNT","selectTrendVersions","allVersions","count","stableVersions","filter","v","slice","analyzeTrend","options","packageName","versions","exports","additionalExternals","noExternal","gzipLevel","boring","log","results","version","versionedPackage","info","result","push","rawSize","gzipSize","renderTrendGraph","length","lines","blue","text","gzipSizes","map","r","rawSizes","minGzipSize","Math","min","maxGzipSize","max","minRawSize","maxRawSize","formattedGzipSizes","formattedRawSizes","allGzipSame","Set","size","allRawSame","maxVersionLen","barWidth","minBarWidth","calcBarLength","value","allSame","ratio","round","repeat","barLength","bar","padding","sizeStr","oldestResult","newestResult","gzipDiff","gzipPercent","toFixed","rawDiff","rawPercent","gzipTrend","abs","rawTrend"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/trend.ts"],"sourcesContent":["import { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport { prerelease } from \"semver\";\nimport { checkBundleSize, formatBytes } from \"./bundler.js\";\nimport { TREND_VERSION_COUNT } from \"./defaults.js\";\n\nexport type TrendResult = {\n\tversion: string;\n\trawSize: number;\n\tgzipSize: number;\n};\n\nexport type TrendOptions = {\n\tpackageName: string;\n\tversions: string[];\n\texports?: string[];\n\tadditionalExternals?: string[];\n\tnoExternal?: boolean;\n\tgzipLevel?: number;\n\tboring?: boolean;\n\tregistry?: string;\n};\n\n/**\n * Select versions for trend analysis\n * Returns the most recent stable versions (newest first)\n * Filters out prerelease versions (canary, alpha, beta, rc, etc.)\n */\nexport function selectTrendVersions(\n\tallVersions: string[],\n\tcount: number = TREND_VERSION_COUNT,\n): string[] {\n\t// Filter out prerelease versions (canary, alpha, beta, rc, etc.)\n\tconst stableVersions = allVersions.filter((v) => !prerelease(v));\n\treturn stableVersions.slice(0, count);\n}\n\n/**\n * Analyze bundle size trend across multiple versions\n */\nexport async function analyzeTrend(\n\toptions: TrendOptions,\n): Promise<TrendResult[]> {\n\tconst {\n\t\tpackageName,\n\t\tversions,\n\t\texports,\n\t\tadditionalExternals,\n\t\tnoExternal,\n\t\tgzipLevel,\n\t\tboring,\n\t\tregistry,\n\t} = options;\n\n\tconst log = new Logger({ boring });\n\tconst results: TrendResult[] = [];\n\n\tfor (const version of versions) {\n\t\tconst versionedPackage = `${packageName}@${version}`;\n\t\tlog.info(` Checking ${version}...`);\n\n\t\ttry {\n\t\t\tconst result = await checkBundleSize({\n\t\t\t\tpackageName: versionedPackage,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal,\n\t\t\t\tgzipLevel,\n\t\t\t\tregistry,\n\t\t\t});\n\n\t\t\tresults.push({\n\t\t\t\tversion,\n\t\t\t\trawSize: result.rawSize,\n\t\t\t\tgzipSize: result.gzipSize,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Skip versions that fail to analyze\n\t\t\tlog.info(` Skipping ${version} (failed to analyze)`);\n\t\t}\n\t}\n\n\treturn results;\n}\n\n/**\n * Render a bar graph showing bundle size trend\n */\nexport function renderTrendGraph(\n\tpackageName: string,\n\tresults: TrendResult[],\n\tboring: boolean = false,\n): string[] {\n\tif (results.length === 0) {\n\t\treturn [\"No data to display\"];\n\t}\n\n\tconst lines: string[] = [];\n\n\t// Color helper (respects boring flag)\n\tconst blue = (text: string) => (boring ? text : kleur.blue(text));\n\n\t// Create maps from formatted string to representative value\n\t// This ensures values that display the same get the same bar length\n\tconst gzipFormattedToValue = new Map<string, number>();\n\tconst rawFormattedToValue = new Map<string, number>();\n\n\tfor (const result of results) {\n\t\tconst gzipFormatted = formatBytes(result.gzipSize);\n\t\tconst rawFormatted = formatBytes(result.rawSize);\n\t\t// Use first occurrence as representative value for each formatted string\n\t\tif (!gzipFormattedToValue.has(gzipFormatted)) {\n\t\t\tgzipFormattedToValue.set(gzipFormatted, result.gzipSize);\n\t\t}\n\t\tif (!rawFormattedToValue.has(rawFormatted)) {\n\t\t\trawFormattedToValue.set(rawFormatted, result.rawSize);\n\t\t}\n\t}\n\n\t// Get unique representative values for min/max calculation\n\tconst uniqueGzipValues = [...gzipFormattedToValue.values()];\n\tconst uniqueRawValues = [...rawFormattedToValue.values()];\n\n\tconst minGzipSize = Math.min(...uniqueGzipValues);\n\tconst maxGzipSize = Math.max(...uniqueGzipValues);\n\tconst minRawSize = Math.min(...uniqueRawValues);\n\tconst maxRawSize = Math.max(...uniqueRawValues);\n\n\t// Find max version length for alignment\n\tconst maxVersionLen = Math.max(...results.map((r) => r.version.length));\n\n\t// Bar width (characters)\n\tconst barWidth = 30;\n\tconst minBarWidth = 10; // Minimum bar length for smallest value\n\n\t// Helper to calculate bar length with min-max scaling\n\tconst calcBarLength = (value: number, min: number, max: number): number => {\n\t\tif (max === min) {\n\t\t\treturn barWidth; // All values are the same\n\t\t}\n\t\t// Scale from minBarWidth to barWidth based on position between min and max\n\t\tconst ratio = (value - min) / (max - min);\n\t\treturn Math.round(minBarWidth + ratio * (barWidth - minBarWidth));\n\t};\n\n\t// Header\n\tlines.push(\"\");\n\tlines.push(`${blue(\"Bundle Size:\")} ${packageName}`);\n\tlines.push(\"─\".repeat(60));\n\tlines.push(\"\");\n\n\t// Gzip size bars\n\tlines.push(blue(\"Gzip Size:\"));\n\tfor (const result of results) {\n\t\tconst sizeStr = formatBytes(result.gzipSize);\n\t\t// Use representative value for this formatted string to ensure consistent bar length\n\t\tconst representativeValue = gzipFormattedToValue.get(sizeStr) as number;\n\t\tconst barLength = calcBarLength(\n\t\t\trepresentativeValue,\n\t\t\tminGzipSize,\n\t\t\tmaxGzipSize,\n\t\t);\n\t\tconst bar = \"▇\".repeat(barLength);\n\t\tconst padding = \" \".repeat(maxVersionLen - result.version.length);\n\t\tlines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Raw size bars\n\tlines.push(blue(\"Raw Size:\"));\n\tfor (const result of results) {\n\t\tconst sizeStr = formatBytes(result.rawSize);\n\t\t// Use representative value for this formatted string to ensure consistent bar length\n\t\tconst representativeValue = rawFormattedToValue.get(sizeStr) as number;\n\t\tconst barLength = calcBarLength(\n\t\t\trepresentativeValue,\n\t\t\tminRawSize,\n\t\t\tmaxRawSize,\n\t\t);\n\t\tconst bar = \"▇\".repeat(barLength);\n\t\tconst padding = \" \".repeat(maxVersionLen - result.version.length);\n\t\tlines.push(` ${result.version}${padding} ${bar} ${sizeStr}`);\n\t}\n\n\tlines.push(\"\");\n\n\t// Summary\n\tconst oldestResult = results[results.length - 1];\n\tconst newestResult = results[0];\n\n\tif (results.length > 1) {\n\t\tconst gzipDiff = newestResult.gzipSize - oldestResult.gzipSize;\n\t\tconst gzipPercent = ((gzipDiff / oldestResult.gzipSize) * 100).toFixed(1);\n\t\tconst rawDiff = newestResult.rawSize - oldestResult.rawSize;\n\t\tconst rawPercent = ((rawDiff / oldestResult.rawSize) * 100).toFixed(1);\n\n\t\tconst gzipTrend =\n\t\t\tgzipDiff >= 0\n\t\t\t\t? `+${formatBytes(gzipDiff)}`\n\t\t\t\t: `-${formatBytes(Math.abs(gzipDiff))}`;\n\t\tconst rawTrend =\n\t\t\trawDiff >= 0\n\t\t\t\t? `+${formatBytes(rawDiff)}`\n\t\t\t\t: `-${formatBytes(Math.abs(rawDiff))}`;\n\n\t\tlines.push(\"─\".repeat(60));\n\t\tlines.push(\n\t\t\t`Change from ${oldestResult.version} to ${newestResult.version}:`,\n\t\t);\n\t\tlines.push(\n\t\t\t` ${blue(\"Gzip:\")} ${gzipTrend} (${gzipDiff >= 0 ? \"+\" : \"\"}${gzipPercent}%)`,\n\t\t);\n\t\tlines.push(\n\t\t\t` ${blue(\"Raw:\")} ${rawTrend} (${rawDiff >= 0 ? \"+\" : \"\"}${rawPercent}%)`,\n\t\t);\n\t}\n\n\tlines.push(\"\");\n\n\treturn lines;\n}\n"],"names":["Logger","kleur","prerelease","checkBundleSize","formatBytes","TREND_VERSION_COUNT","selectTrendVersions","allVersions","count","stableVersions","filter","v","slice","analyzeTrend","options","packageName","versions","exports","additionalExternals","noExternal","gzipLevel","boring","registry","log","results","version","versionedPackage","info","result","push","rawSize","gzipSize","renderTrendGraph","length","lines","blue","text","gzipFormattedToValue","Map","rawFormattedToValue","gzipFormatted","rawFormatted","has","set","uniqueGzipValues","values","uniqueRawValues","minGzipSize","Math","min","maxGzipSize","max","minRawSize","maxRawSize","maxVersionLen","map","r","barWidth","minBarWidth","calcBarLength","value","ratio","round","repeat","sizeStr","representativeValue","get","barLength","bar","padding","oldestResult","newestResult","gzipDiff","gzipPercent","toFixed","rawDiff","rawPercent","gzipTrend","abs","rawTrend"],"mappings":"AAAA,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,WAAW,QAAQ;AAC1B,SAASC,UAAU,QAAQ,SAAS;AACpC,SAASC,eAAe,EAAEC,WAAW,QAAQ,eAAe;AAC5D,SAASC,mBAAmB,QAAQ,gBAAgB;AAmBpD;;;;CAIC,GACD,OAAO,SAASC,oBACfC,WAAqB,EACrBC,QAAgBH,mBAAmB;IAEnC,iEAAiE;IACjE,MAAMI,iBAAiBF,YAAYG,MAAM,CAAC,CAACC,IAAM,CAACT,WAAWS;IAC7D,OAAOF,eAAeG,KAAK,CAAC,GAAGJ;AAChC;AAEA;;CAEC,GACD,OAAO,eAAeK,aACrBC,OAAqB;IAErB,MAAM,EACLC,WAAW,EACXC,QAAQ,EACRC,OAAO,EACPC,mBAAmB,EACnBC,UAAU,EACVC,SAAS,EACTC,MAAM,EACNC,QAAQ,EACR,GAAGR;IAEJ,MAAMS,MAAM,IAAIvB,OAAO;QAAEqB;IAAO;IAChC,MAAMG,UAAyB,EAAE;IAEjC,KAAK,MAAMC,WAAWT,SAAU;QAC/B,MAAMU,mBAAmB,GAAGX,YAAY,CAAC,EAAEU,SAAS;QACpDF,IAAII,IAAI,CAAC,CAAC,WAAW,EAAEF,QAAQ,GAAG,CAAC;QAEnC,IAAI;YACH,MAAMG,SAAS,MAAMzB,gBAAgB;gBACpCY,aAAaW;gBACbT;gBACAC;gBACAC;gBACAC;gBACAE;YACD;YAEAE,QAAQK,IAAI,CAAC;gBACZJ;gBACAK,SAASF,OAAOE,OAAO;gBACvBC,UAAUH,OAAOG,QAAQ;YAC1B;QACD,EAAE,OAAM;YACP,qCAAqC;YACrCR,IAAII,IAAI,CAAC,CAAC,WAAW,EAAEF,QAAQ,oBAAoB,CAAC;QACrD;IACD;IAEA,OAAOD;AACR;AAEA;;CAEC,GACD,OAAO,SAASQ,iBACfjB,WAAmB,EACnBS,OAAsB,EACtBH,SAAkB,KAAK;IAEvB,IAAIG,QAAQS,MAAM,KAAK,GAAG;QACzB,OAAO;YAAC;SAAqB;IAC9B;IAEA,MAAMC,QAAkB,EAAE;IAE1B,sCAAsC;IACtC,MAAMC,OAAO,CAACC,OAAkBf,SAASe,OAAOnC,MAAMkC,IAAI,CAACC;IAE3D,4DAA4D;IAC5D,oEAAoE;IACpE,MAAMC,uBAAuB,IAAIC;IACjC,MAAMC,sBAAsB,IAAID;IAEhC,KAAK,MAAMV,UAAUJ,QAAS;QAC7B,MAAMgB,gBAAgBpC,YAAYwB,OAAOG,QAAQ;QACjD,MAAMU,eAAerC,YAAYwB,OAAOE,OAAO;QAC/C,yEAAyE;QACzE,IAAI,CAACO,qBAAqBK,GAAG,CAACF,gBAAgB;YAC7CH,qBAAqBM,GAAG,CAACH,eAAeZ,OAAOG,QAAQ;QACxD;QACA,IAAI,CAACQ,oBAAoBG,GAAG,CAACD,eAAe;YAC3CF,oBAAoBI,GAAG,CAACF,cAAcb,OAAOE,OAAO;QACrD;IACD;IAEA,2DAA2D;IAC3D,MAAMc,mBAAmB;WAAIP,qBAAqBQ,MAAM;KAAG;IAC3D,MAAMC,kBAAkB;WAAIP,oBAAoBM,MAAM;KAAG;IAEzD,MAAME,cAAcC,KAAKC,GAAG,IAAIL;IAChC,MAAMM,cAAcF,KAAKG,GAAG,IAAIP;IAChC,MAAMQ,aAAaJ,KAAKC,GAAG,IAAIH;IAC/B,MAAMO,aAAaL,KAAKG,GAAG,IAAIL;IAE/B,wCAAwC;IACxC,MAAMQ,gBAAgBN,KAAKG,GAAG,IAAI3B,QAAQ+B,GAAG,CAAC,CAACC,IAAMA,EAAE/B,OAAO,CAACQ,MAAM;IAErE,yBAAyB;IACzB,MAAMwB,WAAW;IACjB,MAAMC,cAAc,IAAI,wCAAwC;IAEhE,sDAAsD;IACtD,MAAMC,gBAAgB,CAACC,OAAeX,KAAaE;QAClD,IAAIA,QAAQF,KAAK;YAChB,OAAOQ,UAAU,0BAA0B;QAC5C;QACA,2EAA2E;QAC3E,MAAMI,QAAQ,AAACD,CAAAA,QAAQX,GAAE,IAAME,CAAAA,MAAMF,GAAE;QACvC,OAAOD,KAAKc,KAAK,CAACJ,cAAcG,QAASJ,CAAAA,WAAWC,WAAU;IAC/D;IAEA,SAAS;IACTxB,MAAML,IAAI,CAAC;IACXK,MAAML,IAAI,CAAC,GAAGM,KAAK,gBAAgB,CAAC,EAAEpB,aAAa;IACnDmB,MAAML,IAAI,CAAC,IAAIkC,MAAM,CAAC;IACtB7B,MAAML,IAAI,CAAC;IAEX,iBAAiB;IACjBK,MAAML,IAAI,CAACM,KAAK;IAChB,KAAK,MAAMP,UAAUJ,QAAS;QAC7B,MAAMwC,UAAU5D,YAAYwB,OAAOG,QAAQ;QAC3C,qFAAqF;QACrF,MAAMkC,sBAAsB5B,qBAAqB6B,GAAG,CAACF;QACrD,MAAMG,YAAYR,cACjBM,qBACAlB,aACAG;QAED,MAAMkB,MAAM,IAAIL,MAAM,CAACI;QACvB,MAAME,UAAU,IAAIN,MAAM,CAACT,gBAAgB1B,OAAOH,OAAO,CAACQ,MAAM;QAChEC,MAAML,IAAI,CAAC,CAAC,EAAE,EAAED,OAAOH,OAAO,GAAG4C,QAAQ,EAAE,EAAED,IAAI,CAAC,EAAEJ,SAAS;IAC9D;IAEA9B,MAAML,IAAI,CAAC;IAEX,gBAAgB;IAChBK,MAAML,IAAI,CAACM,KAAK;IAChB,KAAK,MAAMP,UAAUJ,QAAS;QAC7B,MAAMwC,UAAU5D,YAAYwB,OAAOE,OAAO;QAC1C,qFAAqF;QACrF,MAAMmC,sBAAsB1B,oBAAoB2B,GAAG,CAACF;QACpD,MAAMG,YAAYR,cACjBM,qBACAb,YACAC;QAED,MAAMe,MAAM,IAAIL,MAAM,CAACI;QACvB,MAAME,UAAU,IAAIN,MAAM,CAACT,gBAAgB1B,OAAOH,OAAO,CAACQ,MAAM;QAChEC,MAAML,IAAI,CAAC,CAAC,EAAE,EAAED,OAAOH,OAAO,GAAG4C,QAAQ,EAAE,EAAED,IAAI,CAAC,EAAEJ,SAAS;IAC9D;IAEA9B,MAAML,IAAI,CAAC;IAEX,UAAU;IACV,MAAMyC,eAAe9C,OAAO,CAACA,QAAQS,MAAM,GAAG,EAAE;IAChD,MAAMsC,eAAe/C,OAAO,CAAC,EAAE;IAE/B,IAAIA,QAAQS,MAAM,GAAG,GAAG;QACvB,MAAMuC,WAAWD,aAAaxC,QAAQ,GAAGuC,aAAavC,QAAQ;QAC9D,MAAM0C,cAAc,AAAC,CAAA,AAACD,WAAWF,aAAavC,QAAQ,GAAI,GAAE,EAAG2C,OAAO,CAAC;QACvE,MAAMC,UAAUJ,aAAazC,OAAO,GAAGwC,aAAaxC,OAAO;QAC3D,MAAM8C,aAAa,AAAC,CAAA,AAACD,UAAUL,aAAaxC,OAAO,GAAI,GAAE,EAAG4C,OAAO,CAAC;QAEpE,MAAMG,YACLL,YAAY,IACT,CAAC,CAAC,EAAEpE,YAAYoE,WAAW,GAC3B,CAAC,CAAC,EAAEpE,YAAY4C,KAAK8B,GAAG,CAACN,YAAY;QACzC,MAAMO,WACLJ,WAAW,IACR,CAAC,CAAC,EAAEvE,YAAYuE,UAAU,GAC1B,CAAC,CAAC,EAAEvE,YAAY4C,KAAK8B,GAAG,CAACH,WAAW;QAExCzC,MAAML,IAAI,CAAC,IAAIkC,MAAM,CAAC;QACtB7B,MAAML,IAAI,CACT,CAAC,YAAY,EAAEyC,aAAa7C,OAAO,CAAC,IAAI,EAAE8C,aAAa9C,OAAO,CAAC,CAAC,CAAC;QAElES,MAAML,IAAI,CACT,CAAC,EAAE,EAAEM,KAAK,SAAS,CAAC,EAAE0C,UAAU,EAAE,EAAEL,YAAY,IAAI,MAAM,KAAKC,YAAY,EAAE,CAAC;QAE/EvC,MAAML,IAAI,CACT,CAAC,EAAE,EAAEM,KAAK,QAAQ,EAAE,EAAE4C,SAAS,EAAE,EAAEJ,WAAW,IAAI,MAAM,KAAKC,WAAW,EAAE,CAAC;IAE7E;IAEA1C,MAAML,IAAI,CAAC;IAEX,OAAOK;AACR"}
|
package/dist/versions.d.ts
CHANGED
|
@@ -2,7 +2,11 @@ export type NpmPackageInfo = {
|
|
|
2
2
|
versions: string[];
|
|
3
3
|
tags: Record<string, string>;
|
|
4
4
|
};
|
|
5
|
-
export
|
|
5
|
+
export type FetchVersionsOptions = {
|
|
6
|
+
packageName: string;
|
|
7
|
+
registry?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function fetchPackageVersions(packageNameOrOptions: string | FetchVersionsOptions): Promise<NpmPackageInfo>;
|
|
6
10
|
/**
|
|
7
11
|
* Prompt user to select a version from available versions
|
|
8
12
|
*/
|
package/dist/versions.js
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import select from "@inquirer/select";
|
|
2
2
|
import { rsort } from "semver";
|
|
3
3
|
import { parsePackageSpecifier } from "./bundler.js";
|
|
4
|
-
|
|
4
|
+
import { DEFAULT_REGISTRY } from "./defaults.js";
|
|
5
|
+
export async function fetchPackageVersions(packageNameOrOptions) {
|
|
6
|
+
// Support both string (legacy) and options object
|
|
7
|
+
const { packageName, registry } = typeof packageNameOrOptions === "string" ? {
|
|
8
|
+
packageName: packageNameOrOptions,
|
|
9
|
+
registry: undefined
|
|
10
|
+
} : packageNameOrOptions;
|
|
5
11
|
// Parse the package specifier to get just the name (without version)
|
|
6
12
|
const { name } = parsePackageSpecifier(packageName);
|
|
7
|
-
|
|
13
|
+
// Use custom registry or default
|
|
14
|
+
const registryUrl = registry || DEFAULT_REGISTRY;
|
|
15
|
+
// Ensure no trailing slash
|
|
16
|
+
const baseUrl = registryUrl.replace(/\/$/, "");
|
|
17
|
+
const url = `${baseUrl}/${name}`;
|
|
8
18
|
const response = await fetch(url);
|
|
9
19
|
if (!response.ok) {
|
|
10
20
|
throw new Error(`Failed to fetch package info: ${response.statusText}`);
|
package/dist/versions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/versions.ts"],"sourcesContent":["import select from \"@inquirer/select\";\nimport { rsort } from \"semver\";\nimport { parsePackageSpecifier } from \"./bundler.js\";\n\nexport type NpmPackageInfo = {\n\tversions: string[];\n\ttags: Record<string, string>;\n};\n\n/**\n * Fetch available versions for an npm package from the registry\n */\ntype NpmRegistryResponse = {\n\tversions?: Record<string, unknown>;\n\t\"dist-tags\"?: Record<string, string>;\n};\n\nexport async function fetchPackageVersions(\n\
|
|
1
|
+
{"version":3,"sources":["../src/versions.ts"],"sourcesContent":["import select from \"@inquirer/select\";\nimport { rsort } from \"semver\";\nimport { parsePackageSpecifier } from \"./bundler.js\";\nimport { DEFAULT_REGISTRY } from \"./defaults.js\";\n\nexport type NpmPackageInfo = {\n\tversions: string[];\n\ttags: Record<string, string>;\n};\n\n/**\n * Fetch available versions for an npm package from the registry\n */\ntype NpmRegistryResponse = {\n\tversions?: Record<string, unknown>;\n\t\"dist-tags\"?: Record<string, string>;\n};\n\nexport type FetchVersionsOptions = {\n\tpackageName: string;\n\tregistry?: string;\n};\n\nexport async function fetchPackageVersions(\n\tpackageNameOrOptions: string | FetchVersionsOptions,\n): Promise<NpmPackageInfo> {\n\t// Support both string (legacy) and options object\n\tconst { packageName, registry } =\n\t\ttypeof packageNameOrOptions === \"string\"\n\t\t\t? { packageName: packageNameOrOptions, registry: undefined }\n\t\t\t: packageNameOrOptions;\n\n\t// Parse the package specifier to get just the name (without version)\n\tconst { name } = parsePackageSpecifier(packageName);\n\n\t// Use custom registry or default\n\tconst registryUrl = registry || DEFAULT_REGISTRY;\n\t// Ensure no trailing slash\n\tconst baseUrl = registryUrl.replace(/\\/$/, \"\");\n\tconst url = `${baseUrl}/${name}`;\n\tconst response = await fetch(url);\n\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch package info: ${response.statusText}`);\n\t}\n\n\tconst data = (await response.json()) as NpmRegistryResponse;\n\n\t// Get all versions sorted by semver (newest first)\n\tconst versions = rsort(Object.keys(data.versions || {}));\n\n\t// Get dist-tags (latest, next, beta, etc.)\n\tconst tags = data[\"dist-tags\"] || {};\n\n\treturn { versions, tags };\n}\n\n/**\n * Prompt user to select a version from available versions\n */\nexport async function promptForVersion(\n\tpackageName: string,\n\tversions: string[],\n\ttags: Record<string, string>,\n): Promise<string> {\n\t// Build choices with tags highlighted\n\tconst taggedVersions = new Set(Object.values(tags));\n\tconst tagByVersion = Object.fromEntries(\n\t\tObject.entries(tags).map(([tag, ver]) => [ver, tag]),\n\t);\n\n\t// Limit to most recent 20 versions for usability, but include all tagged versions\n\tconst recentVersions = versions.slice(0, 20);\n\tconst displayVersions = [\n\t\t...new Set([...Object.values(tags), ...recentVersions]),\n\t];\n\n\t// Sort so tagged versions appear first, then by version order\n\tdisplayVersions.sort((a, b) => {\n\t\tconst aTagged = taggedVersions.has(a);\n\t\tconst bTagged = taggedVersions.has(b);\n\t\tif (aTagged && !bTagged) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (!aTagged && bTagged) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn versions.indexOf(a) - versions.indexOf(b);\n\t});\n\n\tconst choices = displayVersions.map((ver) => {\n\t\tconst tag = tagByVersion[ver];\n\t\treturn {\n\t\t\tname: tag ? `${ver} (${tag})` : ver,\n\t\t\tvalue: ver,\n\t\t};\n\t});\n\n\tconst selectedVersion = await select({\n\t\tmessage: `Select a version for ${packageName}:`,\n\t\tchoices,\n\t\tpageSize: 15,\n\t});\n\n\treturn selectedVersion;\n}\n"],"names":["select","rsort","parsePackageSpecifier","DEFAULT_REGISTRY","fetchPackageVersions","packageNameOrOptions","packageName","registry","undefined","name","registryUrl","baseUrl","replace","url","response","fetch","ok","Error","statusText","data","json","versions","Object","keys","tags","promptForVersion","taggedVersions","Set","values","tagByVersion","fromEntries","entries","map","tag","ver","recentVersions","slice","displayVersions","sort","a","b","aTagged","has","bTagged","indexOf","choices","value","selectedVersion","message","pageSize"],"mappings":"AAAA,OAAOA,YAAY,mBAAmB;AACtC,SAASC,KAAK,QAAQ,SAAS;AAC/B,SAASC,qBAAqB,QAAQ,eAAe;AACrD,SAASC,gBAAgB,QAAQ,gBAAgB;AAoBjD,OAAO,eAAeC,qBACrBC,oBAAmD;IAEnD,kDAAkD;IAClD,MAAM,EAAEC,WAAW,EAAEC,QAAQ,EAAE,GAC9B,OAAOF,yBAAyB,WAC7B;QAAEC,aAAaD;QAAsBE,UAAUC;IAAU,IACzDH;IAEJ,qEAAqE;IACrE,MAAM,EAAEI,IAAI,EAAE,GAAGP,sBAAsBI;IAEvC,iCAAiC;IACjC,MAAMI,cAAcH,YAAYJ;IAChC,2BAA2B;IAC3B,MAAMQ,UAAUD,YAAYE,OAAO,CAAC,OAAO;IAC3C,MAAMC,MAAM,GAAGF,QAAQ,CAAC,EAAEF,MAAM;IAChC,MAAMK,WAAW,MAAMC,MAAMF;IAE7B,IAAI,CAACC,SAASE,EAAE,EAAE;QACjB,MAAM,IAAIC,MAAM,CAAC,8BAA8B,EAAEH,SAASI,UAAU,EAAE;IACvE;IAEA,MAAMC,OAAQ,MAAML,SAASM,IAAI;IAEjC,mDAAmD;IACnD,MAAMC,WAAWpB,MAAMqB,OAAOC,IAAI,CAACJ,KAAKE,QAAQ,IAAI,CAAC;IAErD,2CAA2C;IAC3C,MAAMG,OAAOL,IAAI,CAAC,YAAY,IAAI,CAAC;IAEnC,OAAO;QAAEE;QAAUG;IAAK;AACzB;AAEA;;CAEC,GACD,OAAO,eAAeC,iBACrBnB,WAAmB,EACnBe,QAAkB,EAClBG,IAA4B;IAE5B,sCAAsC;IACtC,MAAME,iBAAiB,IAAIC,IAAIL,OAAOM,MAAM,CAACJ;IAC7C,MAAMK,eAAeP,OAAOQ,WAAW,CACtCR,OAAOS,OAAO,CAACP,MAAMQ,GAAG,CAAC,CAAC,CAACC,KAAKC,IAAI,GAAK;YAACA;YAAKD;SAAI;IAGpD,kFAAkF;IAClF,MAAME,iBAAiBd,SAASe,KAAK,CAAC,GAAG;IACzC,MAAMC,kBAAkB;WACpB,IAAIV,IAAI;eAAIL,OAAOM,MAAM,CAACJ;eAAUW;SAAe;KACtD;IAED,8DAA8D;IAC9DE,gBAAgBC,IAAI,CAAC,CAACC,GAAGC;QACxB,MAAMC,UAAUf,eAAegB,GAAG,CAACH;QACnC,MAAMI,UAAUjB,eAAegB,GAAG,CAACF;QACnC,IAAIC,WAAW,CAACE,SAAS;YACxB,OAAO,CAAC;QACT;QACA,IAAI,CAACF,WAAWE,SAAS;YACxB,OAAO;QACR;QACA,OAAOtB,SAASuB,OAAO,CAACL,KAAKlB,SAASuB,OAAO,CAACJ;IAC/C;IAEA,MAAMK,UAAUR,gBAAgBL,GAAG,CAAC,CAACE;QACpC,MAAMD,MAAMJ,YAAY,CAACK,IAAI;QAC7B,OAAO;YACNzB,MAAMwB,MAAM,GAAGC,IAAI,EAAE,EAAED,IAAI,CAAC,CAAC,GAAGC;YAChCY,OAAOZ;QACR;IACD;IAEA,MAAMa,kBAAkB,MAAM/C,OAAO;QACpCgD,SAAS,CAAC,qBAAqB,EAAE1C,YAAY,CAAC,CAAC;QAC/CuC;QACAI,UAAU;IACX;IAEA,OAAOF;AACR"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-cli/bundlecheck",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"description": "CLI tool to check the bundle size of npm packages (like bundlephobia)",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"@vitest/coverage-v8": "4.0.18",
|
|
49
49
|
"vitest": "4.0.18"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "82338f6450ba5ce414dadef36a1a46966868548c"
|
|
52
52
|
}
|