@node-cli/bundlecheck 1.3.0 → 1.4.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 CHANGED
@@ -17,6 +17,7 @@ A CLI tool to check the bundle size of npm packages, similar to [bundlephobia.co
17
17
  - Custom npm registry support (for private registries)
18
18
  - Fast bundling using esbuild (with pnpm support)
19
19
  - **Local caching** for faster repeated lookups (SQLite-based, max 100 entries)
20
+ - **Library API** for programmatic usage in Node.js applications
20
21
 
21
22
  ## Installation
22
23
 
@@ -152,6 +153,207 @@ bundlecheck express # auto-detects "node" from package.json engines
152
153
  bundlecheck lodash --force
153
154
  ```
154
155
 
156
+ ## Programmatic Usage (Library API)
157
+
158
+ In addition to the CLI, `@node-cli/bundlecheck` can be used as a library in your Node.js code.
159
+
160
+ ### Installation
161
+
162
+ ```bash
163
+ npm install @node-cli/bundlecheck
164
+ ```
165
+
166
+ ### Basic Usage
167
+
168
+ ```js
169
+ import { getBundleStats, getBundleTrend, getPackageVersions } from "@node-cli/bundlecheck";
170
+
171
+ // Get bundle stats for a single package
172
+ const stats = await getBundleStats({
173
+ package: "@mantine/core@7.0.0",
174
+ });
175
+ console.log(stats);
176
+ // {
177
+ // packageName: "@mantine/core",
178
+ // packageVersion: "7.0.0",
179
+ // rawSize: 234567,
180
+ // gzipSize: 45678,
181
+ // rawSizeFormatted: "229.07 kB",
182
+ // gzipSizeFormatted: "44.61 kB",
183
+ // exports: [],
184
+ // externals: ["react", "react-dom"],
185
+ // dependencies: ["@floating-ui/react", ...],
186
+ // platform: "browser",
187
+ // gzipLevel: 5,
188
+ // fromCache: false
189
+ // }
190
+
191
+ // Check specific exports (tree-shaking)
192
+ const buttonStats = await getBundleStats({
193
+ package: "@mantine/core",
194
+ exports: ["Button", "Input"],
195
+ });
196
+ console.log(buttonStats.gzipSizeFormatted); // "12.3 kB"
197
+
198
+ // Get bundle size trend across versions
199
+ const trend = await getBundleTrend({
200
+ package: "@mantine/core",
201
+ versionCount: 5,
202
+ });
203
+ console.log(trend);
204
+ // {
205
+ // packageName: "@mantine/core",
206
+ // versions: [
207
+ // { version: "7.0.0", rawSize: 234567, gzipSize: 45678, rawSizeFormatted: "229.07 kB", ... },
208
+ // { version: "6.0.0", rawSize: 220000, gzipSize: 42000, ... },
209
+ // ...
210
+ // ],
211
+ // change: {
212
+ // fromVersion: "5.0.0",
213
+ // toVersion: "7.0.0",
214
+ // rawDiff: 14567,
215
+ // rawPercent: 6.6,
216
+ // rawDiffFormatted: "+14.23 kB",
217
+ // gzipDiff: 3678,
218
+ // gzipPercent: 8.7,
219
+ // gzipDiffFormatted: "+3.59 kB"
220
+ // }
221
+ // }
222
+
223
+ // Get available versions for a package
224
+ const versions = await getPackageVersions({
225
+ package: "@mantine/core",
226
+ });
227
+ console.log(versions.tags.latest); // "7.0.0"
228
+ console.log(versions.versions.slice(0, 5)); // ["7.0.0", "6.0.21", "6.0.20", ...]
229
+ ```
230
+
231
+ ### API Reference
232
+
233
+ #### `getBundleStats(options)`
234
+
235
+ Get bundle size statistics for a single package.
236
+
237
+ **Options:**
238
+
239
+ | Option | Type | Default | Description |
240
+ | ------------ | ----------------------------- | ---------- | -------------------------------------------------------- |
241
+ | `package` | `string` | (required) | Package name with optional version (e.g., `lodash@4.17.0`) |
242
+ | `exports` | `string[]` | `undefined`| Specific exports to measure (tree-shaking) |
243
+ | `external` | `string[]` | `undefined`| Additional packages to mark as external |
244
+ | `noExternal` | `boolean` | `false` | Bundle everything including default externals |
245
+ | `gzipLevel` | `number` | `5` | Gzip compression level (1-9) |
246
+ | `registry` | `string` | `undefined`| Custom npm registry URL |
247
+ | `platform` | `"browser" \| "node" \| "auto"` | `"auto"` | Target platform |
248
+ | `force` | `boolean` | `false` | Bypass cache |
249
+
250
+ **Returns:** `Promise<BundleStats>`
251
+
252
+ ```ts
253
+ type BundleStats = {
254
+ packageName: string; // Display name (may include subpath)
255
+ packageVersion: string; // Resolved version
256
+ exports: string[]; // Exports analyzed
257
+ rawSize: number; // Raw size in bytes
258
+ gzipSize: number | null; // Gzip size in bytes (null for node platform)
259
+ gzipLevel: number; // Compression level used
260
+ externals: string[]; // External packages
261
+ dependencies: string[]; // Package dependencies
262
+ platform: "browser" | "node";
263
+ rawSizeFormatted: string; // Human-readable (e.g., "45.2 kB")
264
+ gzipSizeFormatted: string | null;
265
+ fromCache: boolean; // Whether result was from cache
266
+ };
267
+ ```
268
+
269
+ #### `getBundleTrend(options)`
270
+
271
+ Get bundle size trend across multiple versions.
272
+
273
+ **Options:**
274
+
275
+ | Option | Type | Default | Description |
276
+ | -------------- | ----------------------------- | ---------- | -------------------------------------------------------- |
277
+ | `package` | `string` | (required) | Package name (version ignored if provided) |
278
+ | `versionCount` | `number` | `5` | Number of versions to analyze |
279
+ | `exports` | `string[]` | `undefined`| Specific exports to measure |
280
+ | `external` | `string[]` | `undefined`| Additional packages to mark as external |
281
+ | `noExternal` | `boolean` | `false` | Bundle everything including default externals |
282
+ | `gzipLevel` | `number` | `5` | Gzip compression level (1-9) |
283
+ | `registry` | `string` | `undefined`| Custom npm registry URL |
284
+ | `platform` | `"browser" \| "node" \| "auto"` | `"auto"` | Target platform |
285
+ | `force` | `boolean` | `false` | Bypass cache |
286
+
287
+ **Returns:** `Promise<BundleTrend>`
288
+
289
+ ```ts
290
+ type BundleTrend = {
291
+ packageName: string;
292
+ versions: TrendVersionResult[]; // Results for each version (newest first)
293
+ change: TrendChange | null; // Change between oldest and newest
294
+ };
295
+
296
+ type TrendVersionResult = {
297
+ version: string;
298
+ rawSize: number;
299
+ gzipSize: number | null;
300
+ rawSizeFormatted: string;
301
+ gzipSizeFormatted: string | null;
302
+ };
303
+
304
+ type TrendChange = {
305
+ fromVersion: string;
306
+ toVersion: string;
307
+ rawDiff: number; // Positive = increase, negative = decrease
308
+ rawPercent: number | null; // null if oldest size was 0
309
+ rawDiffFormatted: string; // e.g., "+5.2 kB" or "-1.3 kB"
310
+ gzipDiff: number | null;
311
+ gzipPercent: number | null; // null if not applicable or oldest size was 0
312
+ gzipDiffFormatted: string | null;
313
+ };
314
+ ```
315
+
316
+ #### `getPackageVersions(options)`
317
+
318
+ Get available versions for an npm package.
319
+
320
+ **Options:**
321
+
322
+ | Option | Type | Default | Description |
323
+ | ---------- | -------- | ---------- | ---------------------------- |
324
+ | `package` | `string` | (required) | Package name |
325
+ | `registry` | `string` | `undefined`| Custom npm registry URL |
326
+
327
+ **Returns:** `Promise<PackageVersions>`
328
+
329
+ ```ts
330
+ type PackageVersions = {
331
+ versions: string[]; // All versions (newest first)
332
+ tags: Record<string, string>; // Dist tags (e.g., { latest: "7.0.0" })
333
+ };
334
+ ```
335
+
336
+ ### Utility Functions
337
+
338
+ ```js
339
+ import { formatBytes, parsePackageSpecifier, clearCache, getCacheCount } from "@node-cli/bundlecheck";
340
+
341
+ // Format bytes to human-readable string
342
+ formatBytes(1024); // "1 kB"
343
+ formatBytes(1536); // "1.5 kB"
344
+
345
+ // Parse a package specifier
346
+ parsePackageSpecifier("@scope/name@1.0.0");
347
+ // { name: "@scope/name", version: "1.0.0" }
348
+
349
+ parsePackageSpecifier("@scope/name/subpath@2.0.0");
350
+ // { name: "@scope/name", version: "2.0.0", subpath: "subpath" }
351
+
352
+ // Cache management
353
+ getCacheCount(); // Returns number of cached entries
354
+ clearCache(); // Clears all cached results
355
+ ```
356
+
155
357
  ## How It Works
156
358
 
157
359
  1. Creates a temporary directory
@@ -9,13 +9,13 @@ import { analyzeTrend, renderTrendGraph, selectTrendVersions } from "./trend.js"
9
9
  import { fetchPackageVersions, promptForVersion } from "./versions.js";
10
10
  const flags = config.flags;
11
11
  const parameters = config.parameters;
12
- // Disable kleur colors when --boring flag is set
12
+ // Disable kleur colors when --boring flag is set.
13
13
  kleur.enabled = !flags?.boring;
14
14
  const log = new Logger({
15
15
  boring: flags?.boring
16
16
  });
17
17
  /**
18
- * Display bundle result in a formatted box
18
+ * Display bundle result in a formatted box.
19
19
  */ function displayResult(result, isAutoDetected) {
20
20
  const blue = kleur.blue;
21
21
  const green = kleur.green;
@@ -43,28 +43,29 @@ async function main() {
43
43
  config.showHelp?.();
44
44
  process.exit(1);
45
45
  }
46
- // Parse additional externals if provided (comma-separated)
46
+ // Parse additional externals if provided (comma-separated).
47
47
  let additionalExternals;
48
48
  if (flags?.external) {
49
49
  additionalExternals = flags.external.split(",").map((e)=>e.trim()).filter(Boolean);
50
50
  }
51
- // Parse exports if provided (comma-separated)
51
+ // Parse exports if provided (comma-separated).
52
52
  let exports;
53
53
  const exportsArg = parameters?.["1"];
54
54
  if (exportsArg) {
55
55
  exports = exportsArg.split(",").map((e)=>e.trim()).filter(Boolean);
56
56
  }
57
- // Normalize platform from flag (handles aliases like "web" → "browser")
57
+ // Normalize platform from flag (handles aliases like "web" → "browser").
58
58
  const platform = normalizePlatform(flags?.platform);
59
- // If --trend flag is set, show bundle size trend across versions
60
- // --trend alone uses default (5), --trend N uses N versions
61
- const trendValue = flags?.trend;
59
+ /**
60
+ * If --trend flag is set, show bundle size trend across versions --trend alone
61
+ * uses default (5), --trend N uses N versions.
62
+ */ const trendValue = flags?.trend;
62
63
  if (trendValue !== undefined) {
63
64
  const parsedCount = Number.parseInt(trendValue, 10);
64
65
  const versionCount = !Number.isNaN(parsedCount) && parsedCount > 0 ? parsedCount : TREND_VERSION_COUNT;
65
66
  try {
66
67
  const { name, subpath } = parsePackageSpecifier(packageName);
67
- // Construct the full package path including subpath if present
68
+ // Construct the full package path including subpath if present.
68
69
  const fullPackagePath = subpath ? `${name}/${subpath}` : name;
69
70
  log.info(`\nFetching available versions for ${name}...`);
70
71
  const { versions } = await fetchPackageVersions({
@@ -75,7 +76,7 @@ async function main() {
75
76
  log.error("No versions found for this package");
76
77
  process.exit(1);
77
78
  }
78
- // Select versions for trend
79
+ // Select versions for trend.
79
80
  const trendVersions = selectTrendVersions(versions, versionCount);
80
81
  log.info(`Analyzing ${trendVersions.length} versions: ${trendVersions.join(", ")}`);
81
82
  log.info("");
@@ -95,7 +96,7 @@ async function main() {
95
96
  log.error("Failed to analyze any versions");
96
97
  process.exit(1);
97
98
  }
98
- // Render and display the trend graph
99
+ // Render and display the trend graph.
99
100
  const graphLines = renderTrendGraph(fullPackagePath, results, flags?.boring);
100
101
  for (const line of graphLines){
101
102
  log.log(line);
@@ -107,7 +108,7 @@ async function main() {
107
108
  process.exit(1);
108
109
  }
109
110
  }
110
- // If --versions flag is set, fetch and prompt for version selection
111
+ // If --versions flag is set, fetch and prompt for version selection.
111
112
  if (flags?.versions) {
112
113
  try {
113
114
  const { name, subpath } = parsePackageSpecifier(packageName);
@@ -121,7 +122,7 @@ async function main() {
121
122
  process.exit(1);
122
123
  }
123
124
  const selectedVersion = await promptForVersion(name, versions, tags);
124
- // Rebuild specifier preserving any subpath
125
+ // Rebuild specifier preserving any subpath.
125
126
  packageName = subpath ? `${name}/${subpath}@${selectedVersion}` : `${name}@${selectedVersion}`;
126
127
  log.info(`\nSelected: ${packageName}`);
127
128
  } catch (error) {
@@ -135,9 +136,9 @@ async function main() {
135
136
  log.info(`Exports: { ${exports.join(", ")} }`);
136
137
  }
137
138
  try {
138
- // Parse package specifier to get name and version
139
+ // Parse package specifier to get name and version.
139
140
  const { name: baseName, version: requestedVersion } = parsePackageSpecifier(packageName);
140
- // Resolve "latest" to actual version for cache key
141
+ // Resolve "latest" to actual version for cache key.
141
142
  let resolvedVersion = requestedVersion;
142
143
  if (requestedVersion === "latest") {
143
144
  const { tags } = await fetchPackageVersions({
@@ -146,11 +147,12 @@ async function main() {
146
147
  });
147
148
  resolvedVersion = tags.latest || requestedVersion;
148
149
  }
149
- // Compute externals for cache key (same logic as bundler)
150
+ // Compute externals for cache key (same logic as bundler).
150
151
  const externals = getExternals(baseName, additionalExternals, flags?.noExternal);
151
- // Build cache key
152
- // Note: platform can be undefined (auto-detect), which is stored as "auto" in cache
153
- const cacheKey = normalizeCacheKey({
152
+ /**
153
+ * Build cache key.
154
+ * NOTE: platform can be undefined (auto-detect), which is stored as "auto" in cache.
155
+ */ const cacheKey = normalizeCacheKey({
154
156
  packageName: baseName,
155
157
  version: resolvedVersion,
156
158
  exports,
@@ -159,7 +161,7 @@ async function main() {
159
161
  externals,
160
162
  noExternal: flags?.noExternal ?? false
161
163
  });
162
- // Check cache (unless --force flag is set)
164
+ // Check cache (unless --force flag is set).
163
165
  if (!flags?.force) {
164
166
  const cached = getCachedResult(cacheKey);
165
167
  if (cached) {
@@ -178,7 +180,7 @@ async function main() {
178
180
  registry: flags?.registry,
179
181
  platform
180
182
  });
181
- // Store result in cache
183
+ // Store result in cache.
182
184
  setCachedResult(cacheKey, result);
183
185
  displayResult(result, platform === undefined);
184
186
  process.exit(0);
@@ -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\tgetExternals,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport {\n\tgetCachedResult,\n\tnormalizeCacheKey,\n\tsetCachedResult,\n} from \"./cache.js\";\nimport { normalizePlatform, 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\n/**\n * Display bundle result in a formatted box\n */\nfunction displayResult(\n\tresult: {\n\t\tpackageName: string;\n\t\tpackageVersion: string;\n\t\texports: string[];\n\t\trawSize: number;\n\t\tgzipSize: number | null;\n\t\tgzipLevel: number;\n\t\texternals: string[];\n\t\tdependencies: string[];\n\t\tplatform: \"browser\" | \"node\";\n\t},\n\tisAutoDetected: boolean,\n): void {\n\tconst blue = kleur.blue;\n\tconst green = kleur.green;\n\n\tconst platformLabel = result.platform === \"node\" ? \"node\" : \"browser\";\n\tconst platformNote = isAutoDetected ? \" (auto-detected)\" : \"\";\n\n\tlog.printBox(\n\t\t[\n\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\tresult.exports.length > 0\n\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\"\",\n\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\tresult.gzipSize !== null\n\t\t\t\t? `${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`\n\t\t\t\t: `${blue(\"Gzip size:\")} N/A (not applicable for node platform)`,\n\t\t\t\"\",\n\t\t\tresult.externals.length > 0\n\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\tresult.dependencies.length > 0\n\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t`${blue(\"Platform:\")} ${platformLabel}${platformNote}`,\n\t\t],\n\t\t{\n\t\t\tborderStyle: \"round\",\n\t\t\talign: \"left\",\n\t\t},\n\t);\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// Normalize platform from flag (handles aliases like \"web\" → \"browser\")\n\tconst platform = normalizePlatform(flags?.platform);\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\tplatform,\n\t\t\t\tforce: flags?.force,\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\n\ttry {\n\t\t// Parse package specifier to get name and version\n\t\tconst { name: baseName, version: requestedVersion } =\n\t\t\tparsePackageSpecifier(packageName);\n\n\t\t// Resolve \"latest\" to actual version for cache key\n\t\tlet resolvedVersion = requestedVersion;\n\t\tif (requestedVersion === \"latest\") {\n\t\t\tconst { tags } = await fetchPackageVersions({\n\t\t\t\tpackageName: baseName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\t\t\tresolvedVersion = tags.latest || requestedVersion;\n\t\t}\n\n\t\t// Compute externals for cache key (same logic as bundler)\n\t\tconst externals = getExternals(\n\t\t\tbaseName,\n\t\t\tadditionalExternals,\n\t\t\tflags?.noExternal,\n\t\t);\n\n\t\t// Build cache key\n\t\t// Note: platform can be undefined (auto-detect), which is stored as \"auto\" in cache\n\t\tconst cacheKey = normalizeCacheKey({\n\t\t\tpackageName: baseName,\n\t\t\tversion: resolvedVersion,\n\t\t\texports,\n\t\t\tplatform,\n\t\t\tgzipLevel: flags?.gzipLevel ?? 5,\n\t\t\texternals,\n\t\t\tnoExternal: flags?.noExternal ?? false,\n\t\t});\n\n\t\t// Check cache (unless --force flag is set)\n\t\tif (!flags?.force) {\n\t\t\tconst cached = getCachedResult(cacheKey);\n\t\t\tif (cached) {\n\t\t\t\tlog.info(\"NOTE: Using cached results\\n\");\n\t\t\t\tdisplayResult(cached, platform === undefined);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\n\t\tlog.info(\"Please wait, installing and bundling...\\n\");\n\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\tplatform,\n\t\t});\n\n\t\t// Store result in cache\n\t\tsetCachedResult(cacheKey, result);\n\n\t\tdisplayResult(result, platform === undefined);\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","getExternals","parsePackageSpecifier","getCachedResult","normalizeCacheKey","setCachedResult","normalizePlatform","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","displayResult","result","isAutoDetected","blue","green","platformLabel","platform","platformNote","printBox","packageName","packageVersion","exports","length","join","rawSize","gzipSize","gzipLevel","externals","dependencies","borderStyle","align","main","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","registry","trendVersions","results","noExternal","force","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","baseName","version","requestedVersion","resolvedVersion","latest","cacheKey","cached"],"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\tgetExternals,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport {\n\tgetCachedResult,\n\tnormalizeCacheKey,\n\tsetCachedResult,\n} from \"./cache.js\";\nimport { normalizePlatform, 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\n/**\n * Display bundle result in a formatted box.\n */\nfunction displayResult(\n\tresult: {\n\t\tpackageName: string;\n\t\tpackageVersion: string;\n\t\texports: string[];\n\t\trawSize: number;\n\t\tgzipSize: number | null;\n\t\tgzipLevel: number;\n\t\texternals: string[];\n\t\tdependencies: string[];\n\t\tplatform: \"browser\" | \"node\";\n\t},\n\tisAutoDetected: boolean,\n): void {\n\tconst blue = kleur.blue;\n\tconst green = kleur.green;\n\n\tconst platformLabel = result.platform === \"node\" ? \"node\" : \"browser\";\n\tconst platformNote = isAutoDetected ? \" (auto-detected)\" : \"\";\n\n\tlog.printBox(\n\t\t[\n\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\tresult.exports.length > 0\n\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\"\",\n\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\tresult.gzipSize !== null\n\t\t\t\t? `${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`\n\t\t\t\t: `${blue(\"Gzip size:\")} N/A (not applicable for node platform)`,\n\t\t\t\"\",\n\t\t\tresult.externals.length > 0\n\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\tresult.dependencies.length > 0\n\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t`${blue(\"Platform:\")} ${platformLabel}${platformNote}`,\n\t\t],\n\t\t{\n\t\t\tborderStyle: \"round\",\n\t\t\talign: \"left\",\n\t\t},\n\t);\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// Normalize platform from flag (handles aliases like \"web\" → \"browser\").\n\tconst platform = normalizePlatform(flags?.platform);\n\n\t/**\n\t * If --trend flag is set, show bundle size trend across versions --trend alone\n\t * uses default (5), --trend N uses N versions.\n\t */\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\tplatform,\n\t\t\t\tforce: flags?.force,\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\n\ttry {\n\t\t// Parse package specifier to get name and version.\n\t\tconst { name: baseName, version: requestedVersion } =\n\t\t\tparsePackageSpecifier(packageName);\n\n\t\t// Resolve \"latest\" to actual version for cache key.\n\t\tlet resolvedVersion = requestedVersion;\n\t\tif (requestedVersion === \"latest\") {\n\t\t\tconst { tags } = await fetchPackageVersions({\n\t\t\t\tpackageName: baseName,\n\t\t\t\tregistry: flags?.registry,\n\t\t\t});\n\t\t\tresolvedVersion = tags.latest || requestedVersion;\n\t\t}\n\n\t\t// Compute externals for cache key (same logic as bundler).\n\t\tconst externals = getExternals(\n\t\t\tbaseName,\n\t\t\tadditionalExternals,\n\t\t\tflags?.noExternal,\n\t\t);\n\n\t\t/**\n\t\t * Build cache key.\n\t\t * NOTE: platform can be undefined (auto-detect), which is stored as \"auto\" in cache.\n\t\t */\n\t\tconst cacheKey = normalizeCacheKey({\n\t\t\tpackageName: baseName,\n\t\t\tversion: resolvedVersion,\n\t\t\texports,\n\t\t\tplatform,\n\t\t\tgzipLevel: flags?.gzipLevel ?? 5,\n\t\t\texternals,\n\t\t\tnoExternal: flags?.noExternal ?? false,\n\t\t});\n\n\t\t// Check cache (unless --force flag is set).\n\t\tif (!flags?.force) {\n\t\t\tconst cached = getCachedResult(cacheKey);\n\t\t\tif (cached) {\n\t\t\t\tlog.info(\"NOTE: Using cached results\\n\");\n\t\t\t\tdisplayResult(cached, platform === undefined);\n\t\t\t\tprocess.exit(0);\n\t\t\t}\n\t\t}\n\n\t\tlog.info(\"Please wait, installing and bundling...\\n\");\n\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\tplatform,\n\t\t});\n\n\t\t// Store result in cache.\n\t\tsetCachedResult(cacheKey, result);\n\n\t\tdisplayResult(result, platform === undefined);\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","getExternals","parsePackageSpecifier","getCachedResult","normalizeCacheKey","setCachedResult","normalizePlatform","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","displayResult","result","isAutoDetected","blue","green","platformLabel","platform","platformNote","printBox","packageName","packageVersion","exports","length","join","rawSize","gzipSize","gzipLevel","externals","dependencies","borderStyle","align","main","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","registry","trendVersions","results","noExternal","force","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","baseName","version","requestedVersion","resolvedVersion","latest","cacheKey","cached"],"mappings":"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"}
package/dist/bundler.d.ts CHANGED
@@ -4,7 +4,7 @@ export type ParsedPackage = {
4
4
  subpath?: string;
5
5
  };
6
6
  /**
7
- * Parse a package specifier to extract name, version, and subpath
7
+ * Parse a package specifier to extract name, version, and subpath.
8
8
  * Handles:
9
9
  * - @scope/package@1.0.0
10
10
  * - @scope/package/subpath@1.0.0
@@ -19,7 +19,9 @@ export type BundleOptions = {
19
19
  noExternal?: boolean;
20
20
  gzipLevel?: number;
21
21
  registry?: string;
22
- /** Target platform. If undefined, auto-detects from package.json engines */
22
+ /**
23
+ * Target platform. If undefined, auto-detects from package.json engines.
24
+ */
23
25
  platform?: "browser" | "node";
24
26
  };
25
27
  export type BundleResult = {
@@ -27,7 +29,9 @@ export type BundleResult = {
27
29
  packageVersion: string;
28
30
  exports: string[];
29
31
  rawSize: number;
30
- /** Gzip size in bytes, or null for node platform (gzip not applicable) */
32
+ /**
33
+ * Gzip size in bytes, or null for node platform (gzip not applicable).
34
+ */
31
35
  gzipSize: number | null;
32
36
  gzipLevel: number;
33
37
  externals: string[];
@@ -35,7 +39,7 @@ export type BundleResult = {
35
39
  platform: "browser" | "node";
36
40
  };
37
41
  /**
38
- * Format bytes to human-readable string
42
+ * Format bytes to human-readable string.
39
43
  */
40
44
  export declare function formatBytes(bytes: number): string;
41
45
  export type EntryContentOptions = {
@@ -46,7 +50,7 @@ export type EntryContentOptions = {
46
50
  exportToSubpath?: Map<string, string>;
47
51
  };
48
52
  /**
49
- * Get externals list based on options
53
+ * Get externals list based on options.
50
54
  */
51
55
  export declare function getExternals(packageName: string, externals?: string[], noExternal?: boolean): string[];
52
56
  export type PackageExports = Record<string, string | {
@@ -62,6 +66,6 @@ export type PackageInfo = {
62
66
  engines: Record<string, string> | null;
63
67
  };
64
68
  /**
65
- * Check the bundle size of an npm package
69
+ * Check the bundle size of an npm package.
66
70
  */
67
71
  export declare function checkBundleSize(options: BundleOptions): Promise<BundleResult>;