@assetopt/cli
Advanced tools
+53
-14
@@ -53,2 +53,5 @@ #!/usr/bin/env node | ||
| const name = basename(asset.inputPath).padEnd(30); | ||
| if (asset.error !== void 0) { | ||
| return ` ${colorType(asset.assetType)} ${name} ${pc.red(`\u2716 ${asset.error}`)}`; | ||
| } | ||
| const inputStr = formatBytes(asset.inputSize).padStart(10); | ||
@@ -98,4 +101,5 @@ const outputStr = formatBytes(asset.outputSize).padStart(10); | ||
| const cachedStr = report.cachedCount > 0 ? ` \xB7 ${pc.dim(`${report.cachedCount} cached`)}` : ""; | ||
| const failedStr = report.errorCount > 0 ? ` \xB7 ${pc.red(pc.bold(`${report.errorCount} failed`))}` : ""; | ||
| console.log( | ||
| ` ${pc.bold(count)} \xB7 ${pc.dim(formatBytes(report.totalInputSize))} \u2192 ${pc.bold(formatBytes(report.totalOutputSize))} \xB7 ${verb} ${pc.bold(pc.green(savedStr))}${cachedStr} \xB7 ${pc.dim(formatDuration(report.durationMs))}` | ||
| ` ${pc.bold(count)} \xB7 ${pc.dim(formatBytes(report.totalInputSize))} \u2192 ${pc.bold(formatBytes(report.totalOutputSize))} \xB7 ${verb} ${pc.bold(pc.green(savedStr))}${cachedStr}${failedStr} \xB7 ${pc.dim(formatDuration(report.durationMs))}` | ||
| ); | ||
@@ -106,2 +110,3 @@ console.log(""); | ||
| // src/utils/error.ts | ||
| import pc2 from "picocolors"; | ||
| function handleCliError(err) { | ||
@@ -111,5 +116,13 @@ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); | ||
| } | ||
| function exitOnAssetErrors(report) { | ||
| if (report.errorCount > 0) { | ||
| console.error( | ||
| pc2.red(`\u2716 ${report.errorCount} asset${report.errorCount > 1 ? "s" : ""} failed to process`) | ||
| ); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| // src/utils/threshold.ts | ||
| import pc2 from "picocolors"; | ||
| import pc3 from "picocolors"; | ||
| function parseThreshold(raw) { | ||
@@ -126,3 +139,3 @@ const n = parseFloat(raw); | ||
| console.error( | ||
| pc2.red( | ||
| pc3.red( | ||
| `\u2716 Total savings ${report.totalSavedPercent.toFixed(1)}% below threshold of ${threshold}%` | ||
@@ -162,2 +175,3 @@ ) | ||
| } | ||
| exitOnAssetErrors(report); | ||
| if (options.minSavings !== void 0) { | ||
@@ -197,2 +211,3 @@ enforceMinSavings(report, options.minSavings); | ||
| } | ||
| exitOnAssetErrors(report); | ||
| if (options.minSavings !== void 0) { | ||
@@ -209,3 +224,3 @@ enforceMinSavings(report, options.minSavings); | ||
| import { resolve as resolve4 } from "path"; | ||
| import pc3 from "picocolors"; | ||
| import pc4 from "picocolors"; | ||
| import { loadConfig as loadConfig3, scanDirectory, getAssetType, getFileSize, runPipeline as runPipeline3 } from "@assetopt/core"; | ||
@@ -227,6 +242,7 @@ var SIZE_THRESHOLDS = { | ||
| const start = Date.now(); | ||
| const outputDir = resolve4(process.cwd(), config.output?.dir ?? "./optimized"); | ||
| if (options.savings) { | ||
| await runFullAudit(cwd, config, minSavings, start); | ||
| } else { | ||
| await runFastAudit(cwd, start); | ||
| await runFastAudit(cwd, start, outputDir); | ||
| } | ||
@@ -238,6 +254,6 @@ } catch (err) { | ||
| } | ||
| async function runFastAudit(cwd, start) { | ||
| const files = await scanDirectory(cwd); | ||
| async function runFastAudit(cwd, start, outputDir) { | ||
| const files = await scanDirectory(cwd, { excludePaths: [outputDir] }); | ||
| if (files.length === 0) { | ||
| console.log(pc3.yellow("No supported assets found.")); | ||
| console.log(pc4.yellow("No supported assets found.")); | ||
| return; | ||
@@ -263,3 +279,3 @@ } | ||
| if (assets.length === 0) { | ||
| console.log(pc3.yellow("No supported assets found.")); | ||
| console.log(pc4.yellow("No supported assets found.")); | ||
| return; | ||
@@ -270,2 +286,5 @@ } | ||
| const threshold = SIZE_THRESHOLDS[asset.assetType]; | ||
| if (asset.error !== void 0) { | ||
| issues.push(`error: ${asset.error}`); | ||
| } | ||
| if (threshold !== void 0 && asset.inputSize > threshold) { | ||
@@ -298,8 +317,8 @@ issues.push(`oversized (${formatBytes(asset.inputSize)} > ${formatBytes(threshold)})`); | ||
| console.log( | ||
| ` ${pc3.green(pc3.bold("All good!"))} ${pc3.dim(`${clean + flaggedCount} files checked \xB7 ${formatDuration(duration)}`)}` | ||
| ` ${pc4.green(pc4.bold("All good!"))} ${pc4.dim(`${clean + flaggedCount} files checked \xB7 ${formatDuration(duration)}`)}` | ||
| ); | ||
| } else { | ||
| const issueLabel = pc3.red(pc3.bold(`${flaggedCount} issue${flaggedCount > 1 ? "s" : ""} found`)); | ||
| const cleanLabel = pc3.dim(`${clean} file${clean !== 1 ? "s" : ""} clean`); | ||
| console.log(` ${issueLabel} \xB7 ${cleanLabel} \xB7 ${pc3.dim(formatDuration(duration))}`); | ||
| const issueLabel = pc4.red(pc4.bold(`${flaggedCount} issue${flaggedCount > 1 ? "s" : ""} found`)); | ||
| const cleanLabel = pc4.dim(`${clean} file${clean !== 1 ? "s" : ""} clean`); | ||
| console.log(` ${issueLabel} \xB7 ${cleanLabel} \xB7 ${pc4.dim(formatDuration(duration))}`); | ||
| } | ||
@@ -356,5 +375,25 @@ console.log(""); | ||
| // src/utils/version.ts | ||
| import path from "path"; | ||
| import { readFileSync } from "fs"; | ||
| import { fileURLToPath } from "url"; | ||
| function findCliVersion() { | ||
| let dir = path.dirname(fileURLToPath(import.meta.url)); | ||
| for (let i = 0; i < 10; i++) { | ||
| const candidate = path.join(dir, "package.json"); | ||
| try { | ||
| const pkg = JSON.parse(readFileSync(candidate, "utf-8")); | ||
| if (pkg.name === "@assetopt/cli" && pkg.version) return pkg.version; | ||
| } catch { | ||
| } | ||
| const parent = path.dirname(dir); | ||
| if (parent === dir) break; | ||
| dir = parent; | ||
| } | ||
| return "0.0.0-unknown"; | ||
| } | ||
| // src/index.ts | ||
| var program = new Command(); | ||
| program.name("assetopt").description("Static asset optimization tool").version("1.0.0"); | ||
| program.name("assetopt").description("Static asset optimization tool").version(findCliVersion()); | ||
| registerInit(program); | ||
@@ -361,0 +400,0 @@ registerAnalyze(program); |
+1
-1
| { | ||
| "name": "@assetopt/cli", | ||
| "version": "1.0.2", | ||
| "version": "1.0.3", | ||
| "description": "Command-line tool to optimize images, CSS, JS and SVG assets — open source, MIT.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
20078
7.4%383
11.01%3
50%