frontend-guardian 0.1.6 → 0.1.8

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.
Files changed (2) hide show
  1. package/dist/cli.js +58 -9
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -193,7 +193,7 @@ function printResult(projectName, result) {
193
193
  if (num && !byFile.get(file).includes(num))
194
194
  byFile.get(file).push(num);
195
195
  }
196
- return [...byFile.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([file, lines]) => lines.length > 0 ? `${file}: ${chalk.italic("line " + [...lines].sort((a, b) => a - b).join(", line "))}` : file);
196
+ return [...byFile.entries()].sort((a, b) => a[0].localeCompare(b[0])).map(([file, lines]) => lines.length > 0 ? `${file}: line ${[...lines].sort((a, b) => a - b).join(", line ")}` : file);
197
197
  }
198
198
  if (allIssues.length > 0) {
199
199
  console.log(chalk.yellow(" ⚠ ") + chalk.bold("Issues Found") + "\n");
@@ -208,7 +208,7 @@ function printResult(projectName, result) {
208
208
  }
209
209
  if (issue.fileLines.length > 0) {
210
210
  console.log(INDENT + chalk.bold("Files:"));
211
- const raw = STYLE_TITLES.has(issue.title) ? groupFileLines(issue.fileLines) : issue.fileLines.map((f) => (f.includes(":") ? f.replace(/:(\s*\d+)$/, ": " + chalk.italic("line $1")) : f));
211
+ const raw = STYLE_TITLES.has(issue.title) ? groupFileLines(issue.fileLines) : issue.fileLines.map((f) => (f.includes(":") ? f.replace(/:(\s*\d+)$/, ": line $1") : f));
212
212
  raw.forEach((f) => wrapLine(FILES_INDENT, f, FILES_INDENT));
213
213
  }
214
214
  if (i < allIssues.length - 1)
@@ -220,16 +220,43 @@ function printResult(projectName, result) {
220
220
  console.log(chalk.bold(" Scan Complete"));
221
221
  console.log(chalk.gray(" © Justinmoto · Frontend Guardian") + "\n");
222
222
  }
223
+ function parseArgs() {
224
+ const argv = process.argv.slice(2);
225
+ const pathArg = argv[0];
226
+ if (!pathArg || pathArg.startsWith("-")) {
227
+ return { path: "", json: false, failOnScore: null };
228
+ }
229
+ let json = false;
230
+ let failOnScore = null;
231
+ for (let i = 1; i < argv.length; i++) {
232
+ const a = argv[i];
233
+ if (a === "--json")
234
+ json = true;
235
+ else if (a === "--fail-on-score" && argv[i + 1] != null) {
236
+ const n = parseInt(argv[i + 1], 10);
237
+ if (!Number.isNaN(n) && n >= 0 && n <= 100)
238
+ failOnScore = n;
239
+ i++;
240
+ }
241
+ else if (a.startsWith("--fail-on-score=")) {
242
+ const n = parseInt(a.slice("--fail-on-score=".length), 10);
243
+ if (!Number.isNaN(n) && n >= 0 && n <= 100)
244
+ failOnScore = n;
245
+ }
246
+ }
247
+ return { path: pathArg, json, failOnScore };
248
+ }
223
249
  async function main() {
224
- const arg = process.argv[2];
225
- if (!arg) {
226
- console.error("Usage: frontend-guardian <path>");
250
+ const { path: pathArg, json: outputJson, failOnScore } = parseArgs();
251
+ if (!pathArg) {
252
+ console.error("Usage: frontend-guardian <path> [options]");
227
253
  console.error(" npx frontend-guardian .");
228
- console.error(" npx frontend-guardian ./src");
229
- console.error(" npx frontend-guardian project.zip");
254
+ console.error(" npx frontend-guardian . --fail-on-score 70");
255
+ console.error(" npx frontend-guardian . --json");
256
+ console.error("Options: --json Output result as JSON. --fail-on-score <0-100> Exit 1 if score below threshold.");
230
257
  process.exit(1);
231
258
  }
232
- const resolved = path.resolve(process.cwd(), arg);
259
+ const resolved = path.resolve(process.cwd(), pathArg);
233
260
  if (!fs.existsSync(resolved)) {
234
261
  console.error("Path not found:", resolved);
235
262
  process.exit(1);
@@ -269,7 +296,29 @@ async function main() {
269
296
  console.error("Provide a folder path or a .zip file.");
270
297
  process.exit(1);
271
298
  }
272
- printResult(projectName, result);
299
+ if (outputJson) {
300
+ const out = {
301
+ projectName,
302
+ score: result.score,
303
+ filesScanned: result.filesScanned,
304
+ warningsCount: result.warnings.length,
305
+ duplicatesCount: result.duplicates.length,
306
+ warnings: result.warnings,
307
+ duplicates: result.duplicates,
308
+ };
309
+ console.log(JSON.stringify(out, null, 0));
310
+ }
311
+ else {
312
+ printResult(projectName, result);
313
+ }
314
+ if (failOnScore != null && result.score < failOnScore) {
315
+ const msg = `Score ${result.score} is below required ${failOnScore}. Failing.`;
316
+ if (outputJson)
317
+ console.error(msg);
318
+ else
319
+ console.error(chalk.red("\n" + msg));
320
+ process.exit(1);
321
+ }
273
322
  }
274
323
  main().catch((err) => {
275
324
  console.error(err);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "frontend-guardian",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Scan frontend projects for Tailwind & component consistency (Phase 1 CLI)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,7 +13,7 @@
13
13
  "dependencies": {
14
14
  "chalk": "^5.3.0",
15
15
  "ora": "^8.0.1",
16
- "@justinmoto/frontend-guardian-core": "0.1.7"
16
+ "@justinmoto/frontend-guardian-core": "0.1.9"
17
17
  },
18
18
  "devDependencies": {
19
19
  "typescript": "^5"