blotdev 1.0.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
@@ -1,29 +1,33 @@
1
1
  # blotdev
2
2
 
3
- Scan codebases for brand consistency issues. Catches hardcoded colors, fonts, and styles that should use design tokens.
3
+ Scan codebases for brand consistency issues. Catches hardcoded colors, undefined CSS tokens, and non-brand fonts.
4
4
 
5
- ## Install
5
+ ## Quick Start
6
6
 
7
7
  ```bash
8
- npm install blotdev
8
+ npx blotdev --init
9
+ npx blotdev
9
10
  ```
10
11
 
11
- ## Usage
12
+ That's it. The first command scans your codebase and creates `blot.config.json` with all detected colors, fonts, and CSS tokens. The second command scans for violations.
12
13
 
13
- ```bash
14
- npx blotdev # full scan, outputs brand-issues.md
15
- npx blotdev --staged # staged files only (for pre-commit)
16
- ```
14
+ ## What it Checks
15
+
16
+ - **Hardcoded colors** - hex values not in your config
17
+ - **Undefined tokens** - `var(--color-foo)` where `--color-foo` isn't defined
18
+ - **Non-brand fonts** - font-family declarations not in your config
19
+ - **Inline styles** - `style={{}}` in JSX (optional)
17
20
 
18
21
  ## Config
19
22
 
20
- Create `blot.config.json` in your project root:
23
+ `blot.config.json` is auto-generated but you can edit it:
21
24
 
22
25
  ```json
23
26
  {
24
- "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
25
- "fonts": ["Inter", "Space Grotesk"],
26
- "allowInlineStyles": false
27
+ "colors": ["#1a1a1a", "#ffffff"],
28
+ "fonts": ["Inter"],
29
+ "tokens": ["--color-ink", "--color-paper"],
30
+ "allowInlineStyles": true
27
31
  }
28
32
  ```
29
33
 
@@ -31,28 +35,16 @@ Create `blot.config.json` in your project root:
31
35
  |--------|-------------|
32
36
  | `colors` | Allowed hex colors |
33
37
  | `fonts` | Allowed font families |
38
+ | `tokens` | Defined CSS custom properties |
34
39
  | `allowInlineStyles` | Allow `style={{}}` in JSX |
35
40
 
36
- ## Output
37
-
38
- ```
39
- Scanned 42 files
40
-
41
- Colors (2):
42
- src/components/Button.tsx:14 #3b82f6
43
- src/components/Card.tsx:8 #ef4444
44
-
45
- Fonts (1):
46
- src/styles/globals.css:22 Helvetica
41
+ ## Pre-commit
47
42
 
48
- 3 issues found.
43
+ ```bash
44
+ npx blotdev --staged
49
45
  ```
50
46
 
51
- Full scans also write `brand-issues.md` with a checklist format.
52
-
53
- ## Pre-commit
54
-
55
- With lint-staged:
47
+ Exits with code 1 if issues found. Use with husky/lint-staged:
56
48
 
57
49
  ```json
58
50
  {
@@ -64,10 +56,11 @@ With lint-staged:
64
56
 
65
57
  ## Options
66
58
 
67
- | Flag | Description |
68
- |------|-------------|
69
- | `-s, --staged` | Scan staged files only |
70
- | `-h, --help` | Show help |
59
+ ```
60
+ -i, --init Create config (auto-detects values)
61
+ -s, --staged Scan staged files only
62
+ -h, --help Show help
63
+ ```
71
64
 
72
65
  ## License
73
66
 
@@ -1,5 +1,6 @@
1
1
  {
2
- "colors": ["#1a1a1a", "#ffffff", "#FF6B35"],
3
- "fonts": ["Inter", "Space Grotesk"],
4
- "allowInlineStyles": false
2
+ "colors": ["#1a1a1a", "#ffffff"],
3
+ "fonts": ["Inter"],
4
+ "tokens": ["--color-ink", "--color-paper"],
5
+ "allowInlineStyles": true
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAQjC,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAqB9D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AASjC,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAsB9D"}
package/dist/config.js CHANGED
@@ -39,12 +39,13 @@ const path = __importStar(require("path"));
39
39
  const DEFAULT_CONFIG = {
40
40
  colors: [],
41
41
  fonts: [],
42
+ tokens: [],
42
43
  allowInlineStyles: true,
43
44
  };
44
45
  function loadConfig(cwd = process.cwd()) {
45
46
  const configPath = path.join(cwd, "blot.config.json");
46
47
  if (!fs.existsSync(configPath)) {
47
- console.error("Warning: No blot.config.json found, using defaults");
48
+ console.error("No blot.config.json found. Run: npx blotdev --init");
48
49
  return DEFAULT_CONFIG;
49
50
  }
50
51
  try {
@@ -53,11 +54,12 @@ function loadConfig(cwd = process.cwd()) {
53
54
  return {
54
55
  colors: Array.isArray(parsed.colors) ? parsed.colors : [],
55
56
  fonts: Array.isArray(parsed.fonts) ? parsed.fonts : [],
57
+ tokens: Array.isArray(parsed.tokens) ? parsed.tokens : [],
56
58
  allowInlineStyles: parsed.allowInlineStyles ?? true,
57
59
  };
58
60
  }
59
61
  catch {
60
- console.error("Warning: Failed to parse blot.config.json, using defaults");
62
+ console.error("Failed to parse blot.config.json");
61
63
  return DEFAULT_CONFIG;
62
64
  }
63
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,gCAqBC;AA/BD,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,iBAAiB,EAAE,IAAI;CACxB,CAAC;AAEF,SAAgB,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAEtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/B,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzD,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACtD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,IAAI;SACpD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC3E,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,gCAsBC;AAjCD,uCAAyB;AACzB,2CAA6B;AAG7B,MAAM,cAAc,GAAW;IAC7B,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;IACV,iBAAiB,EAAE,IAAI;CACxB,CAAC;AAEF,SAAgB,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAEtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/B,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzD,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACtD,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzD,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,IAAI;SACpD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAClD,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAiF5C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAS9E"}
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AA0G5C,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAU9E"}
package/dist/detectors.js CHANGED
@@ -39,6 +39,7 @@ const scanner_1 = require("./scanner");
39
39
  const HEX_COLOR = /#([0-9a-fA-F]{3}){1,2}\b/g;
40
40
  const FONT_FAMILY = /font-family\s*:\s*['"]?([^'";,}]+)/gi;
41
41
  const INLINE_STYLE = /style\s*=\s*\{\s*\{/g;
42
+ const CSS_VAR_USE = /var\(--([a-zA-Z0-9-]+)\)/g;
42
43
  function detectColors(lines, file, config) {
43
44
  const violations = [];
44
45
  const allowedColors = config.colors.map((c) => c.toLowerCase());
@@ -101,6 +102,27 @@ function detectInlineStyles(lines, file, config) {
101
102
  });
102
103
  return violations;
103
104
  }
105
+ function detectUndefinedTokens(lines, file, config) {
106
+ if (config.tokens.length === 0)
107
+ return [];
108
+ const violations = [];
109
+ const definedTokens = config.tokens.map((t) => t.toLowerCase());
110
+ lines.forEach((line, index) => {
111
+ const matches = line.matchAll(CSS_VAR_USE);
112
+ for (const match of matches) {
113
+ const token = `--${match[1]}`.toLowerCase();
114
+ if (!definedTokens.includes(token)) {
115
+ violations.push({
116
+ file,
117
+ line: index + 1,
118
+ type: "undefined-token",
119
+ found: `var(--${match[1]})`,
120
+ });
121
+ }
122
+ }
123
+ });
124
+ return violations;
125
+ }
104
126
  function detectViolations(filePath, config) {
105
127
  const lines = (0, scanner_1.readFileLines)(filePath);
106
128
  const relativePath = path.relative(process.cwd(), filePath);
@@ -108,6 +130,7 @@ function detectViolations(filePath, config) {
108
130
  ...detectColors(lines, relativePath, config),
109
131
  ...detectFonts(lines, relativePath, config),
110
132
  ...detectInlineStyles(lines, relativePath, config),
133
+ ...detectUndefinedTokens(lines, relativePath, config),
111
134
  ];
112
135
  }
113
136
  //# sourceMappingURL=detectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,39 +1,109 @@
1
1
  #!/usr/bin/env node
2
2
  "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
3
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
4
39
  const config_1 = require("./config");
5
40
  const scanner_1 = require("./scanner");
6
41
  const detectors_1 = require("./detectors");
7
42
  const output_1 = require("./output");
43
+ const HEX_COLOR = /#([0-9a-fA-F]{3}){1,2}\b/g;
44
+ const FONT_FAMILY = /font-family\s*:\s*['"]?([^'";,}]+)/gi;
45
+ const CSS_VAR_DEF = /--([a-zA-Z0-9-]+)\s*:/g;
8
46
  function parseArgs(args) {
9
47
  return {
10
48
  staged: args.includes("--staged") || args.includes("-s"),
11
49
  help: args.includes("--help") || args.includes("-h"),
50
+ init: args.includes("--init") || args.includes("-i"),
12
51
  };
13
52
  }
14
53
  function printHelp() {
15
- console.log(`
16
- blotdev - Scan for brand consistency issues
54
+ console.log(`blotdev - Scan for brand consistency issues
17
55
 
18
56
  Usage:
19
57
  blotdev Scan codebase, output brand-issues.md
58
+ blotdev --init Create config with auto-detected values
20
59
  blotdev --staged Scan staged files only (pre-commit)
21
60
 
22
61
  Options:
23
- -s, --staged Only scan git staged files
24
- -h, --help Show this help
62
+ -i, --init Create blot.config.json
63
+ -s, --staged Scan staged files only
64
+ -h, --help Show help
25
65
 
26
- Config:
27
- Create blot.config.json in project root:
28
-
29
- {
30
- "colors": ["#1a1a1a", "#ffffff"],
31
- "fonts": ["Inter", "Space Grotesk"],
32
- "allowInlineStyles": false
33
- }
34
-
35
- https://blot.dev
36
- `);
66
+ https://blot.dev`);
67
+ }
68
+ async function createConfig() {
69
+ const cwd = process.cwd();
70
+ const configPath = path.join(cwd, "blot.config.json");
71
+ if (fs.existsSync(configPath)) {
72
+ console.error("blot.config.json already exists");
73
+ process.exit(1);
74
+ }
75
+ const files = await (0, scanner_1.getAllFiles)(cwd);
76
+ const colors = new Set();
77
+ const fonts = new Set();
78
+ const tokens = new Set();
79
+ for (const file of files) {
80
+ const lines = (0, scanner_1.readFileLines)(file);
81
+ for (const line of lines) {
82
+ const colorMatches = line.matchAll(HEX_COLOR);
83
+ for (const match of colorMatches) {
84
+ colors.add(match[0].toLowerCase());
85
+ }
86
+ const fontMatches = line.matchAll(FONT_FAMILY);
87
+ for (const match of fontMatches) {
88
+ const font = match[1].trim();
89
+ if (font && !font.startsWith("var(")) {
90
+ fonts.add(font);
91
+ }
92
+ }
93
+ const tokenMatches = line.matchAll(CSS_VAR_DEF);
94
+ for (const match of tokenMatches) {
95
+ tokens.add(`--${match[1]}`);
96
+ }
97
+ }
98
+ }
99
+ const config = {
100
+ colors: Array.from(colors).sort(),
101
+ fonts: Array.from(fonts).sort(),
102
+ tokens: Array.from(tokens).sort(),
103
+ allowInlineStyles: true,
104
+ };
105
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
106
+ console.log(`blot.config.json (${colors.size} colors, ${fonts.size} fonts, ${tokens.size} tokens)`);
37
107
  }
38
108
  async function main() {
39
109
  const options = parseArgs(process.argv.slice(2));
@@ -41,11 +111,15 @@ async function main() {
41
111
  printHelp();
42
112
  process.exit(0);
43
113
  }
114
+ if (options.init) {
115
+ await createConfig();
116
+ process.exit(0);
117
+ }
44
118
  const cwd = process.cwd();
45
119
  const config = (0, config_1.loadConfig)(cwd);
46
120
  const files = options.staged ? (0, scanner_1.getStagedFiles)(cwd) : await (0, scanner_1.getAllFiles)(cwd);
47
121
  if (files.length === 0) {
48
- console.log("No files to scan.");
122
+ console.log("No files found.");
49
123
  process.exit(0);
50
124
  }
51
125
  const violations = [];
@@ -59,7 +133,7 @@ async function main() {
59
133
  process.exit(violations.length > 0 ? 1 : 0);
60
134
  }
61
135
  main().catch((err) => {
62
- console.error("Error:", err.message || err);
136
+ console.error("error:", err.message || err);
63
137
  process.exit(1);
64
138
  });
65
139
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,qCAAsC;AACtC,uCAAwD;AACxD,2CAA+C;AAC/C,qCAA+D;AAG/D,SAAS,SAAS,CAAC,IAAc;IAC/B,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QACxD,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;KACrD,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,wBAAc,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAA,qBAAW,EAAC,GAAG,CAAC,CAAC;IAE5E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,UAAU,CAAC,IAAI,CAAC,GAAG,IAAA,4BAAgB,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,CAAC;IAED,IAAA,uBAAc,EAAC,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEzC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACpB,IAAA,4BAAmB,EAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;IAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAkBpC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CA2BhE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAIjE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAgC/E"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAkBpC,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAiChE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAIjE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAsC/E"}
package/dist/output.js CHANGED
@@ -70,38 +70,49 @@ function generateMarkdown(violations) {
70
70
  sections.push(grouped["inline-style"].map(formatViolation).join("\n"));
71
71
  sections.push("");
72
72
  }
73
+ if (grouped["undefined-token"]?.length) {
74
+ sections.push("## Undefined Tokens\n");
75
+ sections.push(grouped["undefined-token"].map(formatViolation).join("\n"));
76
+ sections.push("");
77
+ }
73
78
  return sections.join("\n");
74
79
  }
75
80
  function writeMarkdownReport(violations) {
76
81
  const content = generateMarkdown(violations);
77
82
  fs.writeFileSync("brand-issues.md", content);
78
- console.log("\nWrote brand-issues.md");
83
+ console.log("wrote brand-issues.md");
79
84
  }
80
85
  function printToConsole(violations, fileCount) {
81
- console.log(`Scanned ${fileCount} files\n`);
82
86
  if (violations.length === 0) {
83
- console.log("No issues found.");
87
+ console.log(`${fileCount} files, no issues`);
84
88
  return;
85
89
  }
86
90
  const grouped = groupByType(violations);
91
+ const parts = [];
87
92
  if (grouped["color"]?.length) {
88
- console.log(`Colors (${grouped["color"].length}):`);
93
+ parts.push(`${grouped["color"].length} colors`);
89
94
  grouped["color"].forEach((v) => {
90
95
  console.log(` ${v.file}:${v.line} ${v.found}`);
91
96
  });
92
97
  }
93
98
  if (grouped["font"]?.length) {
94
- console.log(`Fonts (${grouped["font"].length}):`);
99
+ parts.push(`${grouped["font"].length} fonts`);
95
100
  grouped["font"].forEach((v) => {
96
101
  console.log(` ${v.file}:${v.line} ${v.found}`);
97
102
  });
98
103
  }
99
104
  if (grouped["inline-style"]?.length) {
100
- console.log(`Inline styles (${grouped["inline-style"].length}):`);
105
+ parts.push(`${grouped["inline-style"].length} inline styles`);
101
106
  grouped["inline-style"].forEach((v) => {
102
107
  console.log(` ${v.file}:${v.line}`);
103
108
  });
104
109
  }
105
- console.log(`\n${violations.length} issues found.`);
110
+ if (grouped["undefined-token"]?.length) {
111
+ parts.push(`${grouped["undefined-token"].length} undefined tokens`);
112
+ grouped["undefined-token"].forEach((v) => {
113
+ console.log(` ${v.file}:${v.line} ${v.found}`);
114
+ });
115
+ }
116
+ console.log(`\n${fileCount} files, ${parts.join(", ")}`);
106
117
  }
107
118
  //# sourceMappingURL=output.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,17 +1,19 @@
1
1
  export interface Config {
2
2
  colors: string[];
3
3
  fonts: string[];
4
+ tokens: string[];
4
5
  allowInlineStyles: boolean;
5
6
  }
6
7
  export interface Violation {
7
8
  file: string;
8
9
  line: number;
9
- type: "color" | "font" | "inline-style";
10
+ type: "color" | "font" | "inline-style" | "undefined-token";
10
11
  found: string;
11
12
  suggestion?: string;
12
13
  }
13
14
  export interface Options {
14
15
  staged: boolean;
15
16
  help: boolean;
17
+ init: boolean;
16
18
  }
17
19
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,CAAC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,cAAc,GAAG,iBAAiB,CAAC;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blotdev",
3
- "version": "1.0.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI tool to scan codebases for brand consistency issues - catches hardcoded colors, fonts, and styles that should use design tokens.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",