@node-cli/bundlecheck 1.2.0 → 1.3.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 +85 -11
- package/dist/bundlecheck.js +69 -21
- package/dist/bundlecheck.js.map +1 -1
- package/dist/bundler.d.ts +10 -1
- package/dist/bundler.js +26 -12
- package/dist/bundler.js.map +1 -1
- package/dist/cache.d.ts +59 -0
- package/dist/cache.js +192 -0
- package/dist/cache.js.map +1 -0
- package/dist/defaults.d.ts +13 -0
- package/dist/defaults.js +65 -1
- package/dist/defaults.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/parse.d.ts +2 -0
- package/dist/parse.js +26 -1
- package/dist/parse.js.map +1 -1
- package/dist/trend.d.ts +6 -1
- package/dist/trend.js +69 -25
- package/dist/trend.js.map +1 -1
- package/package.json +4 -2
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import type { BundleResult } from "./bundler.js";
|
|
3
|
+
export type CacheKey = {
|
|
4
|
+
packageName: string;
|
|
5
|
+
version: string;
|
|
6
|
+
exports: string;
|
|
7
|
+
/** Platform: "browser", "node", or "auto" (for auto-detection) */
|
|
8
|
+
platform: "browser" | "node" | "auto";
|
|
9
|
+
gzipLevel: number;
|
|
10
|
+
externals: string;
|
|
11
|
+
noExternal: number;
|
|
12
|
+
};
|
|
13
|
+
export type CachedBundleResult = BundleResult;
|
|
14
|
+
/**
|
|
15
|
+
* Initialize the cache database with proper pragmas and schema
|
|
16
|
+
*/
|
|
17
|
+
export declare function initCache(): Database.Database;
|
|
18
|
+
/**
|
|
19
|
+
* Normalize cache key options to a consistent format
|
|
20
|
+
* Sorts exports and externals to ensure consistent cache hits
|
|
21
|
+
*
|
|
22
|
+
* Note: platform can be "browser", "node", or "auto" (when user doesn't specify).
|
|
23
|
+
* Using "auto" in the cache key ensures that auto-detected results are cached
|
|
24
|
+
* separately from explicitly specified platform results.
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeCacheKey(options: {
|
|
27
|
+
packageName: string;
|
|
28
|
+
version: string;
|
|
29
|
+
exports?: string[];
|
|
30
|
+
/** Platform: "browser", "node", or undefined (treated as "auto") */
|
|
31
|
+
platform: "browser" | "node" | undefined;
|
|
32
|
+
gzipLevel: number;
|
|
33
|
+
externals: string[];
|
|
34
|
+
noExternal: boolean;
|
|
35
|
+
}): CacheKey;
|
|
36
|
+
/**
|
|
37
|
+
* Get a cached result if it exists
|
|
38
|
+
* Returns null if not found or if an error occurs (graceful degradation)
|
|
39
|
+
*/
|
|
40
|
+
export declare function getCachedResult(key: CacheKey): CachedBundleResult | null;
|
|
41
|
+
/**
|
|
42
|
+
* Store a result in the cache
|
|
43
|
+
* Silently fails on errors (graceful degradation - CLI continues without caching)
|
|
44
|
+
*/
|
|
45
|
+
export declare function setCachedResult(key: CacheKey, result: BundleResult): void;
|
|
46
|
+
/**
|
|
47
|
+
* Clear all cache entries
|
|
48
|
+
* Silently fails on errors
|
|
49
|
+
*/
|
|
50
|
+
export declare function clearCache(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Get the number of cached entries
|
|
53
|
+
* Returns 0 on error
|
|
54
|
+
*/
|
|
55
|
+
export declare function getCacheCount(): number;
|
|
56
|
+
/**
|
|
57
|
+
* Close the database connection (useful for testing)
|
|
58
|
+
*/
|
|
59
|
+
export declare function closeCache(): void;
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import Database from "better-sqlite3";
|
|
5
|
+
const MAX_CACHE_ENTRIES = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Get the cache directory path (computed lazily to support testing)
|
|
8
|
+
*/ function getCacheDir() {
|
|
9
|
+
return path.join(os.homedir(), ".bundlecheck");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the cache database path (computed lazily to support testing)
|
|
13
|
+
*/ function getCacheDbPath() {
|
|
14
|
+
return path.join(getCacheDir(), "cache.db");
|
|
15
|
+
}
|
|
16
|
+
let db = null;
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the cache database with proper pragmas and schema
|
|
19
|
+
*/ export function initCache() {
|
|
20
|
+
if (db) {
|
|
21
|
+
return db;
|
|
22
|
+
}
|
|
23
|
+
// Ensure cache directory exists
|
|
24
|
+
const cacheDir = getCacheDir();
|
|
25
|
+
if (!fs.existsSync(cacheDir)) {
|
|
26
|
+
fs.mkdirSync(cacheDir, {
|
|
27
|
+
recursive: true
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
db = new Database(getCacheDbPath());
|
|
31
|
+
// Apply pragmas for better CLI performance
|
|
32
|
+
db.pragma("journal_mode = WAL");
|
|
33
|
+
db.pragma("foreign_keys = ON");
|
|
34
|
+
// Create table if not exists
|
|
35
|
+
db.exec(`
|
|
36
|
+
CREATE TABLE IF NOT EXISTS bundle_cache (
|
|
37
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
38
|
+
package_name TEXT NOT NULL,
|
|
39
|
+
version TEXT NOT NULL,
|
|
40
|
+
exports TEXT NOT NULL DEFAULT '',
|
|
41
|
+
platform TEXT NOT NULL,
|
|
42
|
+
gzip_level INTEGER NOT NULL,
|
|
43
|
+
externals TEXT NOT NULL DEFAULT '',
|
|
44
|
+
no_external INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
raw_size INTEGER NOT NULL,
|
|
46
|
+
gzip_size INTEGER,
|
|
47
|
+
dependencies TEXT NOT NULL DEFAULT '[]',
|
|
48
|
+
display_name TEXT NOT NULL,
|
|
49
|
+
created_at INTEGER NOT NULL,
|
|
50
|
+
UNIQUE(package_name, version, exports, platform, gzip_level, externals, no_external)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_created_at ON bundle_cache(created_at);
|
|
54
|
+
`);
|
|
55
|
+
return db;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Normalize cache key options to a consistent format
|
|
59
|
+
* Sorts exports and externals to ensure consistent cache hits
|
|
60
|
+
*
|
|
61
|
+
* Note: platform can be "browser", "node", or "auto" (when user doesn't specify).
|
|
62
|
+
* Using "auto" in the cache key ensures that auto-detected results are cached
|
|
63
|
+
* separately from explicitly specified platform results.
|
|
64
|
+
*/ export function normalizeCacheKey(options) {
|
|
65
|
+
return {
|
|
66
|
+
packageName: options.packageName,
|
|
67
|
+
version: options.version,
|
|
68
|
+
exports: (options.exports || []).slice().sort().join(","),
|
|
69
|
+
// Use "auto" when platform is undefined to distinguish from explicit platform
|
|
70
|
+
platform: options.platform ?? "auto",
|
|
71
|
+
gzipLevel: options.gzipLevel,
|
|
72
|
+
externals: options.externals.slice().sort().join(","),
|
|
73
|
+
noExternal: options.noExternal ? 1 : 0
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get a cached result if it exists
|
|
78
|
+
* Returns null if not found or if an error occurs (graceful degradation)
|
|
79
|
+
*/ export function getCachedResult(key) {
|
|
80
|
+
try {
|
|
81
|
+
const database = initCache();
|
|
82
|
+
const stmt = database.prepare(`
|
|
83
|
+
SELECT * FROM bundle_cache
|
|
84
|
+
WHERE package_name = ?
|
|
85
|
+
AND version = ?
|
|
86
|
+
AND exports = ?
|
|
87
|
+
AND platform = ?
|
|
88
|
+
AND gzip_level = ?
|
|
89
|
+
AND externals = ?
|
|
90
|
+
AND no_external = ?
|
|
91
|
+
`);
|
|
92
|
+
const row = stmt.get(key.packageName, key.version, key.exports, key.platform, key.gzipLevel, key.externals, key.noExternal);
|
|
93
|
+
if (!row) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
// Parse dependencies with error handling for corrupted data
|
|
97
|
+
let dependencies = [];
|
|
98
|
+
try {
|
|
99
|
+
dependencies = JSON.parse(row.dependencies);
|
|
100
|
+
} catch {
|
|
101
|
+
// If JSON is corrupted, use empty array
|
|
102
|
+
dependencies = [];
|
|
103
|
+
}
|
|
104
|
+
// Convert row to BundleResult
|
|
105
|
+
return {
|
|
106
|
+
packageName: row.display_name,
|
|
107
|
+
packageVersion: row.version,
|
|
108
|
+
exports: row.exports ? row.exports.split(",").filter(Boolean) : [],
|
|
109
|
+
rawSize: row.raw_size,
|
|
110
|
+
gzipSize: row.gzip_size,
|
|
111
|
+
gzipLevel: row.gzip_level,
|
|
112
|
+
externals: row.externals ? row.externals.split(",").filter(Boolean) : [],
|
|
113
|
+
dependencies,
|
|
114
|
+
platform: row.platform
|
|
115
|
+
};
|
|
116
|
+
} catch {
|
|
117
|
+
// On any database error, return null (graceful degradation - continue without cache)
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Store a result in the cache
|
|
123
|
+
* Silently fails on errors (graceful degradation - CLI continues without caching)
|
|
124
|
+
*/ export function setCachedResult(key, result) {
|
|
125
|
+
try {
|
|
126
|
+
const database = initCache();
|
|
127
|
+
// Use INSERT OR REPLACE to handle duplicates
|
|
128
|
+
// Note: This updates created_at on replace, making this LRU-style eviction
|
|
129
|
+
const stmt = database.prepare(`
|
|
130
|
+
INSERT OR REPLACE INTO bundle_cache (
|
|
131
|
+
package_name, version, exports, platform, gzip_level, externals, no_external,
|
|
132
|
+
raw_size, gzip_size, dependencies, display_name, created_at
|
|
133
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
134
|
+
`);
|
|
135
|
+
stmt.run(key.packageName, key.version, key.exports, key.platform, key.gzipLevel, key.externals, key.noExternal, result.rawSize, result.gzipSize, JSON.stringify(result.dependencies), result.packageName, Date.now());
|
|
136
|
+
// Enforce max entries (LRU-style eviction based on created_at)
|
|
137
|
+
enforceMaxEntries(database);
|
|
138
|
+
} catch {
|
|
139
|
+
// On any database error, silently continue (graceful degradation)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Enforce maximum cache entries by removing entries with oldest timestamps
|
|
144
|
+
* Uses LRU-style eviction: entries that are re-checked get updated timestamps
|
|
145
|
+
* and move to the end of the eviction queue
|
|
146
|
+
*/ function enforceMaxEntries(database) {
|
|
147
|
+
const countResult = database.prepare("SELECT COUNT(*) as count FROM bundle_cache").get();
|
|
148
|
+
if (countResult.count > MAX_CACHE_ENTRIES) {
|
|
149
|
+
const toDelete = countResult.count - MAX_CACHE_ENTRIES;
|
|
150
|
+
database.prepare(`
|
|
151
|
+
DELETE FROM bundle_cache
|
|
152
|
+
WHERE id IN (
|
|
153
|
+
SELECT id FROM bundle_cache
|
|
154
|
+
ORDER BY created_at ASC
|
|
155
|
+
LIMIT ?
|
|
156
|
+
)
|
|
157
|
+
`).run(toDelete);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Clear all cache entries
|
|
162
|
+
* Silently fails on errors
|
|
163
|
+
*/ export function clearCache() {
|
|
164
|
+
try {
|
|
165
|
+
const database = initCache();
|
|
166
|
+
database.prepare("DELETE FROM bundle_cache").run();
|
|
167
|
+
} catch {
|
|
168
|
+
// Silently ignore errors
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Get the number of cached entries
|
|
173
|
+
* Returns 0 on error
|
|
174
|
+
*/ export function getCacheCount() {
|
|
175
|
+
try {
|
|
176
|
+
const database = initCache();
|
|
177
|
+
const result = database.prepare("SELECT COUNT(*) as count FROM bundle_cache").get();
|
|
178
|
+
return result.count;
|
|
179
|
+
} catch {
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Close the database connection (useful for testing)
|
|
185
|
+
*/ export function closeCache() {
|
|
186
|
+
if (db) {
|
|
187
|
+
db.close();
|
|
188
|
+
db = null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport Database from \"better-sqlite3\";\nimport type { BundleResult } from \"./bundler.js\";\n\nconst MAX_CACHE_ENTRIES = 100;\n\n/**\n * Get the cache directory path (computed lazily to support testing)\n */\nfunction getCacheDir(): string {\n\treturn path.join(os.homedir(), \".bundlecheck\");\n}\n\n/**\n * Get the cache database path (computed lazily to support testing)\n */\nfunction getCacheDbPath(): string {\n\treturn path.join(getCacheDir(), \"cache.db\");\n}\n\nexport type CacheKey = {\n\tpackageName: string;\n\tversion: string;\n\texports: string;\n\t/** Platform: \"browser\", \"node\", or \"auto\" (for auto-detection) */\n\tplatform: \"browser\" | \"node\" | \"auto\";\n\tgzipLevel: number;\n\texternals: string;\n\tnoExternal: number;\n};\n\nexport type CachedBundleResult = BundleResult;\n\ntype CacheRow = {\n\tid: number;\n\tpackage_name: string;\n\tversion: string;\n\texports: string;\n\tplatform: string;\n\tgzip_level: number;\n\texternals: string;\n\tno_external: number;\n\traw_size: number;\n\tgzip_size: number | null;\n\tdependencies: string;\n\tdisplay_name: string;\n\tcreated_at: number;\n};\n\nlet db: Database.Database | null = null;\n\n/**\n * Initialize the cache database with proper pragmas and schema\n */\nexport function initCache(): Database.Database {\n\tif (db) {\n\t\treturn db;\n\t}\n\n\t// Ensure cache directory exists\n\tconst cacheDir = getCacheDir();\n\tif (!fs.existsSync(cacheDir)) {\n\t\tfs.mkdirSync(cacheDir, { recursive: true });\n\t}\n\n\tdb = new Database(getCacheDbPath());\n\n\t// Apply pragmas for better CLI performance\n\tdb.pragma(\"journal_mode = WAL\");\n\tdb.pragma(\"foreign_keys = ON\");\n\n\t// Create table if not exists\n\tdb.exec(`\n\t\tCREATE TABLE IF NOT EXISTS bundle_cache (\n\t\t\tid INTEGER PRIMARY KEY AUTOINCREMENT,\n\t\t\tpackage_name TEXT NOT NULL,\n\t\t\tversion TEXT NOT NULL,\n\t\t\texports TEXT NOT NULL DEFAULT '',\n\t\t\tplatform TEXT NOT NULL,\n\t\t\tgzip_level INTEGER NOT NULL,\n\t\t\texternals TEXT NOT NULL DEFAULT '',\n\t\t\tno_external INTEGER NOT NULL DEFAULT 0,\n\t\t\traw_size INTEGER NOT NULL,\n\t\t\tgzip_size INTEGER,\n\t\t\tdependencies TEXT NOT NULL DEFAULT '[]',\n\t\t\tdisplay_name TEXT NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\tUNIQUE(package_name, version, exports, platform, gzip_level, externals, no_external)\n\t\t);\n\n\t\tCREATE INDEX IF NOT EXISTS idx_created_at ON bundle_cache(created_at);\n\t`);\n\n\treturn db;\n}\n\n/**\n * Normalize cache key options to a consistent format\n * Sorts exports and externals to ensure consistent cache hits\n *\n * Note: platform can be \"browser\", \"node\", or \"auto\" (when user doesn't specify).\n * Using \"auto\" in the cache key ensures that auto-detected results are cached\n * separately from explicitly specified platform results.\n */\nexport function normalizeCacheKey(options: {\n\tpackageName: string;\n\tversion: string;\n\texports?: string[];\n\t/** Platform: \"browser\", \"node\", or undefined (treated as \"auto\") */\n\tplatform: \"browser\" | \"node\" | undefined;\n\tgzipLevel: number;\n\texternals: string[];\n\tnoExternal: boolean;\n}): CacheKey {\n\treturn {\n\t\tpackageName: options.packageName,\n\t\tversion: options.version,\n\t\texports: (options.exports || []).slice().sort().join(\",\"),\n\t\t// Use \"auto\" when platform is undefined to distinguish from explicit platform\n\t\tplatform: options.platform ?? \"auto\",\n\t\tgzipLevel: options.gzipLevel,\n\t\texternals: options.externals.slice().sort().join(\",\"),\n\t\tnoExternal: options.noExternal ? 1 : 0,\n\t};\n}\n\n/**\n * Get a cached result if it exists\n * Returns null if not found or if an error occurs (graceful degradation)\n */\nexport function getCachedResult(key: CacheKey): CachedBundleResult | null {\n\ttry {\n\t\tconst database = initCache();\n\n\t\tconst stmt = database.prepare<\n\t\t\t[string, string, string, string, number, string, number]\n\t\t>(`\n\t\t\tSELECT * FROM bundle_cache\n\t\t\tWHERE package_name = ?\n\t\t\tAND version = ?\n\t\t\tAND exports = ?\n\t\t\tAND platform = ?\n\t\t\tAND gzip_level = ?\n\t\t\tAND externals = ?\n\t\t\tAND no_external = ?\n\t\t`);\n\n\t\tconst row = stmt.get(\n\t\t\tkey.packageName,\n\t\t\tkey.version,\n\t\t\tkey.exports,\n\t\t\tkey.platform,\n\t\t\tkey.gzipLevel,\n\t\t\tkey.externals,\n\t\t\tkey.noExternal,\n\t\t) as CacheRow | undefined;\n\n\t\tif (!row) {\n\t\t\treturn null;\n\t\t}\n\n\t\t// Parse dependencies with error handling for corrupted data\n\t\tlet dependencies: string[] = [];\n\t\ttry {\n\t\t\tdependencies = JSON.parse(row.dependencies) as string[];\n\t\t} catch {\n\t\t\t// If JSON is corrupted, use empty array\n\t\t\tdependencies = [];\n\t\t}\n\n\t\t// Convert row to BundleResult\n\t\treturn {\n\t\t\tpackageName: row.display_name,\n\t\t\tpackageVersion: row.version,\n\t\t\texports: row.exports ? row.exports.split(\",\").filter(Boolean) : [],\n\t\t\trawSize: row.raw_size,\n\t\t\tgzipSize: row.gzip_size,\n\t\t\tgzipLevel: row.gzip_level,\n\t\t\texternals: row.externals ? row.externals.split(\",\").filter(Boolean) : [],\n\t\t\tdependencies,\n\t\t\tplatform: row.platform as \"browser\" | \"node\",\n\t\t};\n\t} catch {\n\t\t// On any database error, return null (graceful degradation - continue without cache)\n\t\treturn null;\n\t}\n}\n\n/**\n * Store a result in the cache\n * Silently fails on errors (graceful degradation - CLI continues without caching)\n */\nexport function setCachedResult(key: CacheKey, result: BundleResult): void {\n\ttry {\n\t\tconst database = initCache();\n\n\t\t// Use INSERT OR REPLACE to handle duplicates\n\t\t// Note: This updates created_at on replace, making this LRU-style eviction\n\t\tconst stmt = database.prepare(`\n\t\t\tINSERT OR REPLACE INTO bundle_cache (\n\t\t\t\tpackage_name, version, exports, platform, gzip_level, externals, no_external,\n\t\t\t\traw_size, gzip_size, dependencies, display_name, created_at\n\t\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n\t\t`);\n\n\t\tstmt.run(\n\t\t\tkey.packageName,\n\t\t\tkey.version,\n\t\t\tkey.exports,\n\t\t\tkey.platform,\n\t\t\tkey.gzipLevel,\n\t\t\tkey.externals,\n\t\t\tkey.noExternal,\n\t\t\tresult.rawSize,\n\t\t\tresult.gzipSize,\n\t\t\tJSON.stringify(result.dependencies),\n\t\t\tresult.packageName,\n\t\t\tDate.now(),\n\t\t);\n\n\t\t// Enforce max entries (LRU-style eviction based on created_at)\n\t\tenforceMaxEntries(database);\n\t} catch {\n\t\t// On any database error, silently continue (graceful degradation)\n\t}\n}\n\n/**\n * Enforce maximum cache entries by removing entries with oldest timestamps\n * Uses LRU-style eviction: entries that are re-checked get updated timestamps\n * and move to the end of the eviction queue\n */\nfunction enforceMaxEntries(database: Database.Database): void {\n\tconst countResult = database\n\t\t.prepare(\"SELECT COUNT(*) as count FROM bundle_cache\")\n\t\t.get() as { count: number };\n\n\tif (countResult.count > MAX_CACHE_ENTRIES) {\n\t\tconst toDelete = countResult.count - MAX_CACHE_ENTRIES;\n\t\tdatabase\n\t\t\t.prepare(\n\t\t\t\t`\n\t\t\tDELETE FROM bundle_cache\n\t\t\tWHERE id IN (\n\t\t\t\tSELECT id FROM bundle_cache\n\t\t\t\tORDER BY created_at ASC\n\t\t\t\tLIMIT ?\n\t\t\t)\n\t\t`,\n\t\t\t)\n\t\t\t.run(toDelete);\n\t}\n}\n\n/**\n * Clear all cache entries\n * Silently fails on errors\n */\nexport function clearCache(): void {\n\ttry {\n\t\tconst database = initCache();\n\t\tdatabase.prepare(\"DELETE FROM bundle_cache\").run();\n\t} catch {\n\t\t// Silently ignore errors\n\t}\n}\n\n/**\n * Get the number of cached entries\n * Returns 0 on error\n */\nexport function getCacheCount(): number {\n\ttry {\n\t\tconst database = initCache();\n\t\tconst result = database\n\t\t\t.prepare(\"SELECT COUNT(*) as count FROM bundle_cache\")\n\t\t\t.get() as { count: number };\n\t\treturn result.count;\n\t} catch {\n\t\treturn 0;\n\t}\n}\n\n/**\n * Close the database connection (useful for testing)\n */\nexport function closeCache(): void {\n\tif (db) {\n\t\tdb.close();\n\t\tdb = null;\n\t}\n}\n"],"names":["fs","os","path","Database","MAX_CACHE_ENTRIES","getCacheDir","join","homedir","getCacheDbPath","db","initCache","cacheDir","existsSync","mkdirSync","recursive","pragma","exec","normalizeCacheKey","options","packageName","version","exports","slice","sort","platform","gzipLevel","externals","noExternal","getCachedResult","key","database","stmt","prepare","row","get","dependencies","JSON","parse","display_name","packageVersion","split","filter","Boolean","rawSize","raw_size","gzipSize","gzip_size","gzip_level","setCachedResult","result","run","stringify","Date","now","enforceMaxEntries","countResult","count","toDelete","clearCache","getCacheCount","closeCache","close"],"mappings":"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"}
|
package/dist/defaults.d.ts
CHANGED
|
@@ -5,7 +5,20 @@ export declare const defaultFlags: {
|
|
|
5
5
|
noExternal: boolean;
|
|
6
6
|
versions: boolean;
|
|
7
7
|
registry: string;
|
|
8
|
+
platform: string;
|
|
9
|
+
force: boolean;
|
|
8
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Normalize platform aliases to canonical esbuild platform values
|
|
13
|
+
* - "auto" → undefined (triggers auto-detection based on package engines)
|
|
14
|
+
* - Browser aliases: "browser", "web", "desktop", "client" → "browser"
|
|
15
|
+
* - Node aliases: "node", "server", "nodejs", "backend" → "node"
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizePlatform(platform: string | undefined): "browser" | "node" | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a platform value is valid (either canonical or alias)
|
|
20
|
+
*/
|
|
21
|
+
export declare function isValidPlatform(platform: string | undefined): boolean;
|
|
9
22
|
export declare const TREND_VERSION_COUNT = 5;
|
|
10
23
|
export declare const DEFAULT_EXTERNALS: string[];
|
|
11
24
|
export declare const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
package/dist/defaults.js
CHANGED
|
@@ -4,8 +4,72 @@
|
|
|
4
4
|
external: "",
|
|
5
5
|
noExternal: false,
|
|
6
6
|
versions: false,
|
|
7
|
-
registry: ""
|
|
7
|
+
registry: "",
|
|
8
|
+
platform: "auto",
|
|
9
|
+
force: false
|
|
8
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Normalize platform aliases to canonical esbuild platform values
|
|
13
|
+
* - "auto" → undefined (triggers auto-detection based on package engines)
|
|
14
|
+
* - Browser aliases: "browser", "web", "desktop", "client" → "browser"
|
|
15
|
+
* - Node aliases: "node", "server", "nodejs", "backend" → "node"
|
|
16
|
+
*/ export function normalizePlatform(platform) {
|
|
17
|
+
if (!platform) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const normalized = platform.toLowerCase().trim();
|
|
21
|
+
// Auto-detect from package.json engines
|
|
22
|
+
if (normalized === "auto") {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
// Node aliases
|
|
26
|
+
if ([
|
|
27
|
+
"node",
|
|
28
|
+
"server",
|
|
29
|
+
"nodejs",
|
|
30
|
+
"backend"
|
|
31
|
+
].includes(normalized)) {
|
|
32
|
+
return "node";
|
|
33
|
+
}
|
|
34
|
+
// Browser aliases
|
|
35
|
+
if ([
|
|
36
|
+
"browser",
|
|
37
|
+
"web",
|
|
38
|
+
"desktop",
|
|
39
|
+
"client"
|
|
40
|
+
].includes(normalized)) {
|
|
41
|
+
return "browser";
|
|
42
|
+
}
|
|
43
|
+
// Invalid value - will be caught by validation
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Check if a platform value is valid (either canonical or alias)
|
|
48
|
+
*/ export function isValidPlatform(platform) {
|
|
49
|
+
if (platform === undefined) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
const normalized = platform.toLowerCase().trim();
|
|
53
|
+
// Empty string after trim is invalid
|
|
54
|
+
if (normalized === "") {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const validValues = [
|
|
58
|
+
// Auto-detect
|
|
59
|
+
"auto",
|
|
60
|
+
// Browser
|
|
61
|
+
"browser",
|
|
62
|
+
"web",
|
|
63
|
+
"desktop",
|
|
64
|
+
"client",
|
|
65
|
+
// Node
|
|
66
|
+
"node",
|
|
67
|
+
"server",
|
|
68
|
+
"nodejs",
|
|
69
|
+
"backend"
|
|
70
|
+
];
|
|
71
|
+
return validValues.includes(normalized);
|
|
72
|
+
}
|
|
9
73
|
export const TREND_VERSION_COUNT = 5;
|
|
10
74
|
export const DEFAULT_EXTERNALS = [
|
|
11
75
|
"react",
|
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\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;
|
|
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\tplatform: \"auto\",\n\tforce: false,\n};\n\n/**\n * Normalize platform aliases to canonical esbuild platform values\n * - \"auto\" → undefined (triggers auto-detection based on package engines)\n * - Browser aliases: \"browser\", \"web\", \"desktop\", \"client\" → \"browser\"\n * - Node aliases: \"node\", \"server\", \"nodejs\", \"backend\" → \"node\"\n */\nexport function normalizePlatform(\n\tplatform: string | undefined,\n): \"browser\" | \"node\" | undefined {\n\tif (!platform) {\n\t\treturn undefined;\n\t}\n\n\tconst normalized = platform.toLowerCase().trim();\n\n\t// Auto-detect from package.json engines\n\tif (normalized === \"auto\") {\n\t\treturn undefined;\n\t}\n\n\t// Node aliases\n\tif ([\"node\", \"server\", \"nodejs\", \"backend\"].includes(normalized)) {\n\t\treturn \"node\";\n\t}\n\n\t// Browser aliases\n\tif ([\"browser\", \"web\", \"desktop\", \"client\"].includes(normalized)) {\n\t\treturn \"browser\";\n\t}\n\n\t// Invalid value - will be caught by validation\n\treturn normalized as \"browser\" | \"node\";\n}\n\n/**\n * Check if a platform value is valid (either canonical or alias)\n */\nexport function isValidPlatform(platform: string | undefined): boolean {\n\tif (platform === undefined) {\n\t\treturn true;\n\t}\n\n\tconst normalized = platform.toLowerCase().trim();\n\n\t// Empty string after trim is invalid\n\tif (normalized === \"\") {\n\t\treturn false;\n\t}\n\tconst validValues = [\n\t\t// Auto-detect\n\t\t\"auto\",\n\t\t// Browser\n\t\t\"browser\",\n\t\t\"web\",\n\t\t\"desktop\",\n\t\t\"client\",\n\t\t// Node\n\t\t\"node\",\n\t\t\"server\",\n\t\t\"nodejs\",\n\t\t\"backend\",\n\t];\n\n\treturn validValues.includes(normalized);\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","platform","force","normalizePlatform","undefined","normalized","toLowerCase","trim","includes","isValidPlatform","validValues","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;IACVC,UAAU;IACVC,OAAO;AACR,EAAE;AAEF;;;;;CAKC,GACD,OAAO,SAASC,kBACfF,QAA4B;IAE5B,IAAI,CAACA,UAAU;QACd,OAAOG;IACR;IAEA,MAAMC,aAAaJ,SAASK,WAAW,GAAGC,IAAI;IAE9C,wCAAwC;IACxC,IAAIF,eAAe,QAAQ;QAC1B,OAAOD;IACR;IAEA,eAAe;IACf,IAAI;QAAC;QAAQ;QAAU;QAAU;KAAU,CAACI,QAAQ,CAACH,aAAa;QACjE,OAAO;IACR;IAEA,kBAAkB;IAClB,IAAI;QAAC;QAAW;QAAO;QAAW;KAAS,CAACG,QAAQ,CAACH,aAAa;QACjE,OAAO;IACR;IAEA,+CAA+C;IAC/C,OAAOA;AACR;AAEA;;CAEC,GACD,OAAO,SAASI,gBAAgBR,QAA4B;IAC3D,IAAIA,aAAaG,WAAW;QAC3B,OAAO;IACR;IAEA,MAAMC,aAAaJ,SAASK,WAAW,GAAGC,IAAI;IAE9C,qCAAqC;IACrC,IAAIF,eAAe,IAAI;QACtB,OAAO;IACR;IACA,MAAMK,cAAc;QACnB,cAAc;QACd;QACA,UAAU;QACV;QACA;QACA;QACA;QACA,OAAO;QACP;QACA;QACA;QACA;KACA;IAED,OAAOA,YAAYF,QAAQ,CAACH;AAC7B;AAEA,OAAO,MAAMM,sBAAsB,EAAE;AAErC,OAAO,MAAMC,oBAAoB;IAAC;IAAS;CAAY,CAAC;AAExD,OAAO,MAAMC,mBAAmB,6BAA6B"}
|
package/dist/index.d.ts
CHANGED
package/dist/parse.d.ts
CHANGED
package/dist/parse.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* istanbul ignore file */ import { parser } from "@node-cli/parser";
|
|
2
|
-
import { DEFAULT_EXTERNALS, defaultFlags } from "./defaults.js";
|
|
2
|
+
import { DEFAULT_EXTERNALS, defaultFlags, isValidPlatform } from "./defaults.js";
|
|
3
3
|
export const config = parser({
|
|
4
4
|
meta: import.meta,
|
|
5
5
|
examples: [
|
|
@@ -46,6 +46,14 @@ export const config = parser({
|
|
|
46
46
|
{
|
|
47
47
|
command: "bundlecheck lodash --registry https://registry.example.com",
|
|
48
48
|
comment: "## Use a custom npm registry"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
command: "bundlecheck express --platform node",
|
|
52
|
+
comment: "## Check bundle size for Node.js platform (aliases: server, nodejs, backend)"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
command: "bundlecheck lodash --force",
|
|
56
|
+
comment: "## Bypass cache and force re-fetch/re-calculation"
|
|
49
57
|
}
|
|
50
58
|
],
|
|
51
59
|
flags: {
|
|
@@ -99,6 +107,18 @@ export const config = parser({
|
|
|
99
107
|
default: defaultFlags.registry,
|
|
100
108
|
description: "Custom npm registry URL (default: https://registry.npmjs.org)",
|
|
101
109
|
type: "string"
|
|
110
|
+
},
|
|
111
|
+
platform: {
|
|
112
|
+
shortFlag: "p",
|
|
113
|
+
default: defaultFlags.platform,
|
|
114
|
+
description: 'Target platform: "auto" (default, detects from engines), "browser" or "node"',
|
|
115
|
+
type: "string"
|
|
116
|
+
},
|
|
117
|
+
force: {
|
|
118
|
+
shortFlag: "f",
|
|
119
|
+
default: defaultFlags.force,
|
|
120
|
+
description: "Bypass cache and force re-fetch/re-calculation",
|
|
121
|
+
type: "boolean"
|
|
102
122
|
}
|
|
103
123
|
},
|
|
104
124
|
parameters: {
|
|
@@ -119,6 +139,11 @@ export const config = parser({
|
|
|
119
139
|
exit: 1,
|
|
120
140
|
message: ()=>"Error: Gzip level must be between 1 and 9",
|
|
121
141
|
test: (flags)=>flags.gzipLevel !== undefined && (flags.gzipLevel < 1 || flags.gzipLevel > 9)
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
exit: 1,
|
|
145
|
+
message: ()=>'Error: Invalid platform. Use "browser" (or web, desktop, client) or "node" (or server, nodejs, backend)',
|
|
146
|
+
test: (flags)=>!isValidPlatform(flags.platform)
|
|
122
147
|
}
|
|
123
148
|
],
|
|
124
149
|
usage: true,
|
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 {
|
|
1
|
+
{"version":3,"sources":["../src/parse.ts"],"sourcesContent":["/* istanbul ignore file */\nimport { parser } from \"@node-cli/parser\";\nimport {\n\tDEFAULT_EXTERNALS,\n\tdefaultFlags,\n\tisValidPlatform,\n} 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\tplatform?: string;\n\tforce?: 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\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\t{\n\t\t\tcommand: \"bundlecheck express --platform node\",\n\t\t\tcomment:\n\t\t\t\t\"## Check bundle size for Node.js platform (aliases: server, nodejs, backend)\",\n\t\t},\n\t\t{\n\t\t\tcommand: \"bundlecheck lodash --force\",\n\t\t\tcomment: \"## Bypass cache and force re-fetch/re-calculation\",\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\tplatform: {\n\t\t\tshortFlag: \"p\",\n\t\t\tdefault: defaultFlags.platform,\n\t\t\tdescription:\n\t\t\t\t'Target platform: \"auto\" (default, detects from engines), \"browser\" or \"node\"',\n\t\t\ttype: \"string\",\n\t\t},\n\t\tforce: {\n\t\t\tshortFlag: \"f\",\n\t\t\tdefault: defaultFlags.force,\n\t\t\tdescription: \"Bypass cache and force re-fetch/re-calculation\",\n\t\t\ttype: \"boolean\",\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\t{\n\t\t\texit: 1,\n\t\t\tmessage: () =>\n\t\t\t\t'Error: Invalid platform. Use \"browser\" (or web, desktop, client) or \"node\" (or server, nodejs, backend)',\n\t\t\ttest: (flags) => !isValidPlatform(flags.platform),\n\t\t},\n\t],\n\tusage: true,\n\tdefaultFlags,\n});\n"],"names":["parser","DEFAULT_EXTERNALS","defaultFlags","isValidPlatform","config","meta","examples","command","comment","flags","gzipLevel","shortFlag","default","description","type","external","join","noExternal","boring","help","version","versions","trend","registry","platform","force","parameters","package","exports","restrictions","exit","message","test","undefined","usage"],"mappings":"AAAA,wBAAwB,GACxB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,SACCC,iBAAiB,EACjBC,YAAY,EACZC,eAAe,QACT,gBAAgB;AA4BvB,OAAO,MAAMC,SAAwBJ,OAAO;IAC3CK,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;QACA;YACCD,SAAS;YACTC,SACC;QACF;QACA;YACCD,SAAS;YACTC,SAAS;QACV;KACA;IACDC,OAAO;QACNC,WAAW;YACVC,WAAW;YACXC,SAASV,aAAaQ,SAAS;YAC/BG,aAAa;YACbC,MAAM;QACP;QACAC,UAAU;YACTJ,WAAW;YACXC,SAASV,aAAaa,QAAQ;YAC9BF,aAAa,CAAC,yDAAyD,EAAEZ,kBAAkBe,IAAI,CAAC,MAAM,CAAC,CAAC;YACxGF,MAAM;QACP;QACAG,YAAY;YACXN,WAAW;YACXC,SAASV,aAAae,UAAU;YAChCJ,aACC;YACDC,MAAM;QACP;QACAI,QAAQ;YACPP,WAAW;YACXC,SAASV,aAAagB,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,SAASV,aAAamB,QAAQ;YAC9BR,aAAa;YACbC,MAAM;QACP;QACAQ,OAAO;YACNX,WAAW;YACXE,aAAa;YACbC,MAAM;QACP;QACAS,UAAU;YACTZ,WAAW;YACXC,SAASV,aAAaqB,QAAQ;YAC9BV,aACC;YACDC,MAAM;QACP;QACAU,UAAU;YACTb,WAAW;YACXC,SAASV,aAAasB,QAAQ;YAC9BX,aACC;YACDC,MAAM;QACP;QACAW,OAAO;YACNd,WAAW;YACXC,SAASV,aAAauB,KAAK;YAC3BZ,aAAa;YACbC,MAAM;QACP;IACD;IACAY,YAAY;QACXC,SAAS;YACRd,aAAa;QACd;QACAe,SAAS;YACRf,aACC;QACF;IACD;IACAgB,cAAc;QACb;YACCC,MAAM;YACNC,SAAS,IAAM;YACfC,MAAM,CAACvB,OAAOiB,aAAe,CAACA,YAAY,CAAC,IAAI;QAChD;QACA;YACCI,MAAM;YACNC,SAAS,IAAM;YACfC,MAAM,CAACvB,QACNA,MAAMC,SAAS,KAAKuB,aACnBxB,CAAAA,MAAMC,SAAS,GAAG,KAAKD,MAAMC,SAAS,GAAG,CAAA;QAC5C;QACA;YACCoB,MAAM;YACNC,SAAS,IACR;YACDC,MAAM,CAACvB,QAAU,CAACN,gBAAgBM,MAAMe,QAAQ;QACjD;KACA;IACDU,OAAO;IACPhC;AACD,GAAG"}
|
package/dist/trend.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export type TrendResult = {
|
|
2
2
|
version: string;
|
|
3
3
|
rawSize: number;
|
|
4
|
-
|
|
4
|
+
/** Gzip size in bytes, or null for node platform */
|
|
5
|
+
gzipSize: number | null;
|
|
5
6
|
};
|
|
6
7
|
export type TrendOptions = {
|
|
7
8
|
packageName: string;
|
|
@@ -12,6 +13,10 @@ export type TrendOptions = {
|
|
|
12
13
|
gzipLevel?: number;
|
|
13
14
|
boring?: boolean;
|
|
14
15
|
registry?: string;
|
|
16
|
+
/** Target platform. If undefined, auto-detects from package.json engines */
|
|
17
|
+
platform?: "browser" | "node";
|
|
18
|
+
/** Bypass cache and force re-fetch/re-calculation */
|
|
19
|
+
force?: boolean;
|
|
15
20
|
};
|
|
16
21
|
/**
|
|
17
22
|
* Select versions for trend analysis
|