dispersa 0.4.2 → 1.0.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.
Files changed (62) hide show
  1. package/README.md +73 -39
  2. package/dist/android-CRDfSB3_.d.cts +126 -0
  3. package/dist/android-DANJjjPO.d.ts +126 -0
  4. package/dist/builders.cjs +220 -64
  5. package/dist/builders.cjs.map +1 -1
  6. package/dist/builders.d.cts +15 -13
  7. package/dist/builders.d.ts +15 -13
  8. package/dist/builders.js +220 -64
  9. package/dist/builders.js.map +1 -1
  10. package/dist/cli/cli.js +120 -7
  11. package/dist/cli/cli.js.map +1 -1
  12. package/dist/cli/config.d.ts +321 -0
  13. package/dist/cli/config.js.map +1 -1
  14. package/dist/cli/index.js +119 -7
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/dispersa-BC1kDF5u.d.ts +118 -0
  17. package/dist/dispersa-DL3J_Pmz.d.cts +118 -0
  18. package/dist/errors-qT4sJgSA.d.cts +104 -0
  19. package/dist/errors-qT4sJgSA.d.ts +104 -0
  20. package/dist/errors.cjs.map +1 -1
  21. package/dist/errors.d.cts +1 -83
  22. package/dist/errors.d.ts +1 -83
  23. package/dist/errors.js.map +1 -1
  24. package/dist/filters.cjs.map +1 -1
  25. package/dist/filters.d.cts +2 -2
  26. package/dist/filters.d.ts +2 -2
  27. package/dist/filters.js.map +1 -1
  28. package/dist/{index-CNT2Meyf.d.cts → index-Dajm5rvM.d.ts} +311 -132
  29. package/dist/{index-CqdaN3X0.d.ts → index-De6SjZYH.d.cts} +311 -132
  30. package/dist/index.cjs +813 -355
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +8 -329
  33. package/dist/index.d.ts +8 -329
  34. package/dist/index.js +807 -355
  35. package/dist/index.js.map +1 -1
  36. package/dist/lint.cjs +1017 -0
  37. package/dist/lint.cjs.map +1 -0
  38. package/dist/lint.d.cts +463 -0
  39. package/dist/lint.d.ts +463 -0
  40. package/dist/lint.js +997 -0
  41. package/dist/lint.js.map +1 -0
  42. package/dist/preprocessors.d.cts +2 -2
  43. package/dist/preprocessors.d.ts +2 -2
  44. package/dist/renderers.cjs.map +1 -1
  45. package/dist/renderers.d.cts +7 -6
  46. package/dist/renderers.d.ts +7 -6
  47. package/dist/renderers.js.map +1 -1
  48. package/dist/transforms.cjs +0 -12
  49. package/dist/transforms.cjs.map +1 -1
  50. package/dist/transforms.d.cts +3 -7
  51. package/dist/transforms.d.ts +3 -7
  52. package/dist/transforms.js +1 -12
  53. package/dist/transforms.js.map +1 -1
  54. package/dist/{types-CZb19kiq.d.ts → types-8MLtztK3.d.ts} +56 -1
  55. package/dist/{types-CussyWwe.d.cts → types-BHBHRm0a.d.cts} +56 -1
  56. package/dist/{types-BAv39mum.d.cts → types-BltzwVYK.d.cts} +1 -1
  57. package/dist/{types-DWKq-eJj.d.cts → types-CAdUV-fa.d.cts} +1 -1
  58. package/dist/{types-CzHa7YkW.d.ts → types-DztXKlka.d.ts} +1 -1
  59. package/dist/{types-Bc0kA7De.d.ts → types-TQHV1MrY.d.cts} +19 -1
  60. package/dist/{types-Bc0kA7De.d.cts → types-TQHV1MrY.d.ts} +19 -1
  61. package/dist/{types-BzNcG-rI.d.ts → types-ebxDimRz.d.ts} +1 -1
  62. package/package.json +11 -1
package/dist/cli/index.js CHANGED
@@ -3,9 +3,59 @@ import { access } from 'fs/promises';
3
3
  import { createRequire } from 'module';
4
4
  import { dirname, resolve, isAbsolute } from 'path';
5
5
  import process2 from 'process';
6
- import { Dispersa } from 'dispersa';
6
+ import { build, lint } from 'dispersa';
7
7
  import { createJiti } from 'jiti';
8
8
 
9
+ // src/cli/formatters/lint-formatter.ts
10
+ var formatLintJson = (result) => {
11
+ return JSON.stringify(result, null, 2);
12
+ };
13
+ var formatLintStylish = (result) => {
14
+ const lines = [];
15
+ if (result.issues.length === 0) {
16
+ return "\u2713 No lint issues found";
17
+ }
18
+ const byToken = /* @__PURE__ */ new Map();
19
+ for (const issue of result.issues) {
20
+ const existing = byToken.get(issue.tokenName) ?? [];
21
+ existing.push(issue);
22
+ byToken.set(issue.tokenName, existing);
23
+ }
24
+ for (const [tokenName, issues] of byToken) {
25
+ lines.push(``);
26
+ lines.push(` ${tokenName}`);
27
+ for (const issue of issues) {
28
+ const severity = issue.severity === "error" ? "\u2716" : "\u26A0";
29
+ const label = issue.severity === "error" ? "error" : "warning";
30
+ lines.push(` ${severity} ${label}: ${issue.message} [${issue.ruleId}]`);
31
+ }
32
+ }
33
+ lines.push(``);
34
+ if (result.errorCount > 0 || result.warningCount > 0) {
35
+ const parts = [];
36
+ if (result.errorCount > 0) {
37
+ parts.push(`${result.errorCount} error${result.errorCount === 1 ? "" : "s"}`);
38
+ }
39
+ if (result.warningCount > 0) {
40
+ parts.push(`${result.warningCount} warning${result.warningCount === 1 ? "" : "s"}`);
41
+ }
42
+ lines.push(`\u2716 ${parts.join(", ")}`);
43
+ }
44
+ return lines.join("\n");
45
+ };
46
+ var formatLintCompact = (result) => {
47
+ const lines = [];
48
+ for (const issue of result.issues) {
49
+ const severity = issue.severity.toUpperCase();
50
+ lines.push(`${severity}: ${issue.ruleId} - ${issue.message} (token: ${issue.tokenName})`);
51
+ }
52
+ if (result.errorCount > 0 || result.warningCount > 0) {
53
+ lines.push(`SUMMARY: ${result.errorCount} errors, ${result.warningCount} warnings`);
54
+ }
55
+ return lines.join("\n");
56
+ };
57
+
58
+ // src/cli/cli.ts
9
59
  var defaultConfigNames = [
10
60
  "dispersa.config.ts",
11
61
  "dispersa.config.js",
@@ -27,6 +77,9 @@ async function runCli(args, options = {}) {
27
77
  printHelp(io);
28
78
  return 0;
29
79
  }
80
+ if (command === "lint") {
81
+ return runLintCommand(args.slice(1), cwd, io);
82
+ }
30
83
  if (command !== "build") {
31
84
  io.stderr(`Unknown command: ${command}`);
32
85
  printHelp(io);
@@ -47,8 +100,7 @@ async function runCli(args, options = {}) {
47
100
  }
48
101
  }
49
102
  const startTime = Date.now();
50
- const dispersa = new Dispersa({ resolver, buildPath, validation });
51
- const result = await dispersa.build(buildConfig);
103
+ const result = await build({ resolver, buildPath, validation, ...buildConfig });
52
104
  const elapsed = Date.now() - startTime;
53
105
  return reportBuildResult(result, verbose, elapsed, io);
54
106
  }
@@ -103,6 +155,50 @@ function reportBuildResult(result, verbose, elapsed, io) {
103
155
  }
104
156
  return 0;
105
157
  }
158
+ async function runLintCommand(args, cwd, io) {
159
+ const verbose = hasFlag(args, "--verbose") || hasFlag(args, "-v");
160
+ const formatArg = getArgValue(args, "--format");
161
+ const format = formatArg === "json" || formatArg === "compact" ? formatArg : "stylish";
162
+ const loaded = await resolveAndLoadConfig(args, cwd, io, verbose);
163
+ if (!loaded) {
164
+ return 1;
165
+ }
166
+ const normalizedConfig = normalizeConfigPaths(loaded.config, loaded.configDir);
167
+ const { lint: lintConfig, validation, resolver } = normalizedConfig;
168
+ if (!lintConfig) {
169
+ io.stderr("No lint configuration found in config file.");
170
+ io.stderr('Add a "lint" property to your dispersa.config.ts');
171
+ return 1;
172
+ }
173
+ if (!resolver) {
174
+ io.stderr("No resolver configuration found in config file.");
175
+ io.stderr('Add a "resolver" property to your dispersa.config.ts');
176
+ return 1;
177
+ }
178
+ if (verbose) {
179
+ io.stdout(`Resolver: ${typeof resolver === "string" ? resolver : "(inline)"}`);
180
+ io.stdout(`Format: ${format}`);
181
+ }
182
+ const startTime = Date.now();
183
+ try {
184
+ const result = await lint({ resolver, ...lintConfig, validation });
185
+ const elapsed = Date.now() - startTime;
186
+ const formatter = format === "json" ? formatLintJson : format === "compact" ? formatLintCompact : formatLintStylish;
187
+ const output = formatter(result);
188
+ io.stdout(output);
189
+ if (verbose) {
190
+ io.stdout(`Duration: ${elapsed}ms`);
191
+ }
192
+ return result.errorCount > 0 ? 1 : 0;
193
+ } catch (error) {
194
+ io.stderr("Lint failed.");
195
+ io.stderr(`- ${error instanceof Error ? error.message : String(error)}`);
196
+ if (verbose) {
197
+ io.stderr(`Duration: ${Date.now() - startTime}ms`);
198
+ }
199
+ return 1;
200
+ }
201
+ }
106
202
  function getArgValue(args, flag) {
107
203
  const index = args.indexOf(flag);
108
204
  if (index === -1 || index === args.length - 1) {
@@ -197,15 +293,31 @@ function isPackageResolvable(name, cwd) {
197
293
  }
198
294
  }
199
295
  function printHelp(io) {
200
- io.stdout("dispersa build [options]");
296
+ io.stdout("dispersa <command> [options]");
297
+ io.stdout("");
298
+ io.stdout("Commands:");
299
+ io.stdout(" build Build design tokens");
300
+ io.stdout(" lint Lint design tokens without building");
301
+ io.stdout("");
302
+ io.stdout("Build Options:");
303
+ io.stdout(" --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)");
304
+ io.stdout(" --verbose, -v Show detailed build output (timing, error context)");
201
305
  io.stdout("");
202
- io.stdout("Options:");
203
- io.stdout(" --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)");
204
- io.stdout(" --verbose, -v Show detailed build output (timing, error context)");
306
+ io.stdout("Lint Options:");
307
+ io.stdout(" --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)");
308
+ io.stdout(" --format <format> Output format: stylish (default), json, compact");
309
+ io.stdout(" --verbose, -v Show detailed lint output");
205
310
  }
206
311
 
207
312
  // src/cli/index.ts
208
313
  var exitCode = await runCli(process.argv.slice(2));
209
314
  process.exitCode = exitCode;
315
+ /**
316
+ * @license MIT
317
+ * Copyright (c) 2025-present Dispersa
318
+ *
319
+ * This source code is licensed under the MIT license found in the
320
+ * LICENSE file in the root directory of this source tree.
321
+ */
210
322
  //# sourceMappingURL=index.js.map
211
323
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/cli.ts","../../src/cli/index.ts"],"names":["process","require"],"mappings":"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","file":"index.js","sourcesContent":["import { access } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, isAbsolute, resolve } from 'node:path'\nimport process from 'node:process'\n\nimport { Dispersa, type BuildConfig } from 'dispersa'\nimport { createJiti } from 'jiti'\n\nimport type { CliConfig } from './config'\n\ntype CliIO = {\n stdout: (message: string) => void\n stderr: (message: string) => void\n}\n\ntype RunOptions = {\n cwd?: string\n io?: CliIO\n}\n\nconst defaultConfigNames = [\n 'dispersa.config.ts',\n 'dispersa.config.js',\n 'dispersa.config.mts',\n 'dispersa.config.mjs',\n 'dispersa.config.cts',\n 'dispersa.config.cjs',\n]\n\nexport async function runCli(args: string[], options: RunOptions = {}): Promise<number> {\n const cwd = options.cwd ?? process.cwd()\n const io: CliIO = options.io ?? {\n stdout: (message) => process.stdout.write(`${message}\\n`),\n stderr: (message) => process.stderr.write(`${message}\\n`),\n }\n\n const command = args[0] ?? 'build'\n if (command === '--help' || command === '-h' || command === 'help') {\n printHelp(io)\n return 0\n }\n\n if (command !== 'build') {\n io.stderr(`Unknown command: ${command}`)\n printHelp(io)\n return 1\n }\n\n const verbose = hasFlag(args, '--verbose') || hasFlag(args, '-v')\n const loaded = await resolveAndLoadConfig(args, cwd, io, verbose)\n if (!loaded) {\n return 1\n }\n\n const normalizedConfig = normalizeConfigPaths(loaded.config, loaded.configDir)\n const { validation, resolver, buildPath, ...buildConfig } = normalizedConfig\n\n if (verbose) {\n const outputCount = buildConfig.outputs?.length ?? 0\n io.stdout(`Outputs: ${outputCount} configured`)\n if (buildPath) {\n io.stdout(`Build path: ${buildPath}`)\n }\n }\n\n const startTime = Date.now()\n const dispersa = new Dispersa({ resolver, buildPath, validation })\n const result = await dispersa.build(buildConfig as BuildConfig)\n const elapsed = Date.now() - startTime\n\n return reportBuildResult(result, verbose, elapsed, io)\n}\n\nasync function resolveAndLoadConfig(\n args: string[],\n cwd: string,\n io: CliIO,\n verbose: boolean,\n): Promise<{ config: CliConfig; configDir: string } | undefined> {\n const configPath = getArgValue(args, '--config')\n const resolvedPath = await resolveConfigPath(configPath, cwd)\n if (resolvedPath === undefined) {\n io.stderr(\n `No config found. Expected one of: ${defaultConfigNames.join(', ')} ` +\n 'or pass --config <path>.',\n )\n return undefined\n }\n\n if (verbose) {\n io.stdout(`Config: ${resolvedPath}`)\n }\n\n try {\n const config = await loadConfig(resolvedPath, cwd)\n return { config, configDir: dirname(resolvedPath) }\n } catch (error) {\n io.stderr(`Failed to load config: ${resolvedPath}`)\n io.stderr(`- ${error instanceof Error ? error.message : String(error)}`)\n return undefined\n }\n}\n\nfunction reportBuildResult(\n result: Awaited<ReturnType<Dispersa['build']>>,\n verbose: boolean,\n elapsed: number,\n io: CliIO,\n): number {\n if (!result.success) {\n io.stderr('Build failed.')\n for (const error of result.errors ?? []) {\n io.stderr(`- [${error.code}] ${error.message}`)\n if (verbose && error.tokenPath) {\n io.stderr(` Token: ${error.tokenPath}`)\n }\n if (verbose && error.path) {\n io.stderr(` File: ${error.path}`)\n }\n if (verbose && error.suggestions && error.suggestions.length > 0) {\n io.stderr(` Suggestions: ${error.suggestions.join(', ')}`)\n }\n }\n if (verbose) {\n io.stderr(`Duration: ${elapsed}ms`)\n }\n return 1\n }\n\n io.stdout('Build succeeded.')\n for (const output of result.outputs) {\n const location = output.path ?? '(in-memory)'\n io.stdout(`- ${output.name}: ${location}`)\n }\n\n if (verbose) {\n io.stdout(`Duration: ${elapsed}ms`)\n }\n\n return 0\n}\n\nfunction getArgValue(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag)\n if (index === -1 || index === args.length - 1) {\n return undefined\n }\n const value = args[index + 1]\n if (value == null || value.startsWith('-')) {\n return undefined\n }\n return value\n}\n\nfunction hasFlag(args: string[], flag: string): boolean {\n return args.includes(flag)\n}\n\nasync function resolveConfigPath(\n configPath: string | undefined,\n cwd: string,\n): Promise<string | undefined> {\n if (configPath) {\n const fullPath = resolve(cwd, configPath)\n if (!(await fileExists(fullPath))) {\n return undefined\n }\n return fullPath\n }\n\n for (const name of defaultConfigNames) {\n const fullPath = resolve(cwd, name)\n if (await fileExists(fullPath)) {\n return fullPath\n }\n }\n\n return undefined\n}\n\nasync function loadConfig(configPath: string, cwd: string): Promise<CliConfig> {\n const alias = await buildAliasMap(cwd)\n const loader = createJiti(cwd, {\n interopDefault: true,\n alias,\n })\n const loaded = await loader(configPath)\n const config = (loaded as { default?: CliConfig }).default ?? (loaded as CliConfig)\n\n if (config == null || typeof config !== 'object') {\n throw new Error(`Invalid config: ${configPath} did not export an object`)\n }\n\n return config\n}\n\nfunction normalizeConfigPaths(config: CliConfig, configDir: string): CliConfig {\n const resolver =\n typeof config.resolver === 'string'\n ? resolveIfRelative(config.resolver, configDir)\n : config.resolver\n const buildPath = resolveIfRelative(config.buildPath, configDir)\n const outputs = config.outputs ?? []\n\n return {\n ...config,\n resolver,\n buildPath,\n outputs,\n }\n}\n\nfunction resolveIfRelative(value: string | undefined, baseDir: string): string | undefined {\n if (!value) {\n return value\n }\n return isAbsolute(value) ? value : resolve(baseDir, value)\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path)\n return true\n } catch {\n return false\n }\n}\n\nasync function buildAliasMap(cwd: string): Promise<Record<string, string>> {\n const alias: Record<string, string> = {}\n\n // Dev monorepo: point to source files for hot-reload\n const coreSourcePath = resolve(cwd, 'packages/core/src/index.ts')\n if (await fileExists(coreSourcePath)) {\n alias['dispersa'] = coreSourcePath\n return alias\n }\n\n // Not resolvable from cwd — try from the CLI module's own location\n // (handles workspace symlinks and global installs)\n if (!isPackageResolvable('dispersa', cwd)) {\n const require = createRequire(import.meta.url)\n try {\n alias['dispersa'] = require.resolve('dispersa')\n } catch {\n // Not resolvable at all; config loading will fail with a clear error\n }\n }\n\n return alias\n}\n\nfunction isPackageResolvable(name: string, cwd: string): boolean {\n const require = createRequire(import.meta.url)\n try {\n require.resolve(name, { paths: [cwd] })\n return true\n } catch {\n return false\n }\n}\n\nfunction printHelp(io: CliIO): void {\n io.stdout('dispersa build [options]')\n io.stdout('')\n io.stdout('Options:')\n io.stdout(' --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)')\n io.stdout(' --verbose, -v Show detailed build output (timing, error context)')\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli.js'\n\nconst exitCode = await runCli(process.argv.slice(2))\nprocess.exitCode = exitCode\n"]}
1
+ {"version":3,"sources":["../../src/cli/formatters/lint-formatter.ts","../../src/cli/cli.ts","../../src/cli/index.ts"],"names":["process","require"],"mappings":";;;;;;;;;AAiBO,IAAM,cAAA,GAAgC,CAAC,MAAA,KAA+B;AAC3E,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAA;AACvC,CAAA;AAKO,IAAM,iBAAA,GAAmC,CAAC,MAAA,KAA+B;AAC9E,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC9B,IAAA,OAAO,6BAAA;AAAA,EACT;AAGA,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAyB;AAC7C,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,MAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,SAAS,KAAK,EAAC;AAClD,IAAA,QAAA,CAAS,KAAK,KAAK,CAAA;AACnB,IAAA,OAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAAA,EACvC;AAGA,EAAA,KAAA,MAAW,CAAC,SAAA,EAAW,MAAM,CAAA,IAAK,OAAA,EAAS;AACzC,IAAA,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AACb,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,SAAS,CAAA,CAAE,CAAA;AAC3B,IAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,MAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,KAAa,OAAA,GAAU,QAAA,GAAM,QAAA;AACpD,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,KAAa,OAAA,GAAU,OAAA,GAAU,SAAA;AACrD,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,IAAA,EAAO,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,EAAA,EAAK,KAAA,CAAM,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IAC3E;AAAA,EACF;AAGA,EAAA,KAAA,CAAM,KAAK,CAAA,CAAE,CAAA;AACb,EAAA,IAAI,MAAA,CAAO,UAAA,GAAa,CAAA,IAAK,MAAA,CAAO,eAAe,CAAA,EAAG;AACpD,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,IAAI,MAAA,CAAO,aAAa,CAAA,EAAG;AACzB,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,MAAA,CAAO,UAAU,CAAA,MAAA,EAAS,OAAO,UAAA,KAAe,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,CAAE,CAAA;AAAA,IAC9E;AACA,IAAA,IAAI,MAAA,CAAO,eAAe,CAAA,EAAG;AAC3B,MAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,MAAA,CAAO,YAAY,CAAA,QAAA,EAAW,OAAO,YAAA,KAAiB,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,CAAE,CAAA;AAAA,IACpF;AACA,IAAA,KAAA,CAAM,KAAK,CAAA,OAAA,EAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,EACpC;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB,CAAA;AAKO,IAAM,iBAAA,GAAmC,CAAC,MAAA,KAA+B;AAC9E,EAAA,MAAM,QAAkB,EAAC;AAEzB,EAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,CAAS,WAAA,EAAY;AAC5C,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,MAAM,CAAA,GAAA,EAAM,KAAA,CAAM,OAAO,CAAA,SAAA,EAAY,KAAA,CAAM,SAAS,CAAA,CAAA,CAAG,CAAA;AAAA,EAC1F;AAEA,EAAA,IAAI,MAAA,CAAO,UAAA,GAAa,CAAA,IAAK,MAAA,CAAO,eAAe,CAAA,EAAG;AACpD,IAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,MAAA,CAAO,UAAU,CAAA,SAAA,EAAY,MAAA,CAAO,YAAY,CAAA,SAAA,CAAW,CAAA;AAAA,EACpF;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB,CAAA;;;AC5DA,IAAM,kBAAA,GAAqB;AAAA,EACzB,oBAAA;AAAA,EACA,oBAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA;AAEA,eAAsB,MAAA,CAAO,IAAA,EAAgB,OAAA,GAAsB,EAAC,EAAoB;AACtF,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAOA,QAAAA,CAAQ,GAAA,EAAI;AACvC,EAAA,MAAM,EAAA,GAAY,QAAQ,EAAA,IAAM;AAAA,IAC9B,QAAQ,CAAC,OAAA,KAAYA,SAAQ,MAAA,CAAO,KAAA,CAAM,GAAG,OAAO;AAAA,CAAI,CAAA;AAAA,IACxD,QAAQ,CAAC,OAAA,KAAYA,SAAQ,MAAA,CAAO,KAAA,CAAM,GAAG,OAAO;AAAA,CAAI;AAAA,GAC1D;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,CAAC,CAAA,IAAK,OAAA;AAC3B,EAAA,IAAI,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,IAAA,IAAQ,YAAY,MAAA,EAAQ;AAClE,IAAA,SAAA,CAAU,EAAE,CAAA;AACZ,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,OAAO,eAAe,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA,EAAG,KAAK,EAAE,CAAA;AAAA,EAC9C;AAEA,EAAA,IAAI,YAAY,OAAA,EAAS;AACvB,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,iBAAA,EAAoB,OAAO,CAAA,CAAE,CAAA;AACvC,IAAA,SAAA,CAAU,EAAE,CAAA;AACZ,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,EAAM,WAAW,CAAA,IAAK,OAAA,CAAQ,MAAM,IAAI,CAAA;AAChE,EAAA,MAAM,SAAS,MAAM,oBAAA,CAAqB,IAAA,EAAM,GAAA,EAAK,IAAI,OAAO,CAAA;AAChE,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,gBAAA,GAAmB,oBAAA,CAAqB,MAAA,CAAO,MAAA,EAAQ,OAAO,SAAS,CAAA;AAC7E,EAAA,MAAM,EAAE,UAAA,EAAY,QAAA,EAAU,SAAA,EAAW,GAAG,aAAY,GAAI,gBAAA;AAE5D,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,EAAS,MAAA,IAAU,CAAA;AACnD,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,SAAA,EAAY,WAAW,CAAA,WAAA,CAAa,CAAA;AAC9C,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,EAAA,CAAG,MAAA,CAAO,CAAA,YAAA,EAAe,SAAS,CAAA,CAAE,CAAA;AAAA,IACtC;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,EAAA,MAAM,MAAA,GAAS,MAAM,KAAA,CAAM,EAAE,UAAU,SAAA,EAAW,UAAA,EAAY,GAAG,WAAA,EAA4B,CAAA;AAC7F,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAE7B,EAAA,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,EAAE,CAAA;AACvD;AAEA,eAAe,oBAAA,CACb,IAAA,EACA,GAAA,EACA,EAAA,EACA,OAAA,EAC+D;AAC/D,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,IAAA,EAAM,UAAU,CAAA;AAC/C,EAAA,MAAM,YAAA,GAAe,MAAM,iBAAA,CAAkB,UAAA,EAAY,GAAG,CAAA;AAC5D,EAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,IAAA,EAAA,CAAG,MAAA;AAAA,MACD,CAAA,kCAAA,EAAqC,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAC,CAAA,yBAAA;AAAA,KAEpE;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,QAAA,EAAW,YAAY,CAAA,CAAE,CAAA;AAAA,EACrC;AAEA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,YAAA,EAAc,GAAG,CAAA;AACjD,IAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,OAAA,CAAQ,YAAY,CAAA,EAAE;AAAA,EACpD,SAAS,KAAA,EAAO;AACd,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,uBAAA,EAA0B,YAAY,CAAA,CAAE,CAAA;AAClD,IAAA,EAAA,CAAG,MAAA,CAAO,KAAK,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AACvE,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAEA,SAAS,iBAAA,CACP,MAAA,EACA,OAAA,EACA,OAAA,EACA,EAAA,EACQ;AACR,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,EAAA,CAAG,OAAO,eAAe,CAAA;AACzB,IAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,IAAU,EAAC,EAAG;AACvC,MAAA,EAAA,CAAG,OAAO,CAAA,GAAA,EAAM,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA;AAC9C,MAAA,IAAI,OAAA,IAAW,MAAM,SAAA,EAAW;AAC9B,QAAA,EAAA,CAAG,MAAA,CAAO,CAAA,SAAA,EAAY,KAAA,CAAM,SAAS,CAAA,CAAE,CAAA;AAAA,MACzC;AACA,MAAA,IAAI,OAAA,IAAW,MAAM,IAAA,EAAM;AACzB,QAAA,EAAA,CAAG,MAAA,CAAO,CAAA,QAAA,EAAW,KAAA,CAAM,IAAI,CAAA,CAAE,CAAA;AAAA,MACnC;AACA,MAAA,IAAI,WAAW,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,WAAA,CAAY,SAAS,CAAA,EAAG;AAChE,QAAA,EAAA,CAAG,OAAO,CAAA,eAAA,EAAkB,KAAA,CAAM,YAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,MAC5D;AAAA,IACF;AACA,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,EAAA,CAAG,MAAA,CAAO,CAAA,UAAA,EAAa,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,IACpC;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,EAAA,CAAG,OAAO,kBAAkB,CAAA;AAC5B,EAAA,KAAA,MAAW,MAAA,IAAU,OAAO,OAAA,EAAS;AACnC,IAAA,MAAM,QAAA,GAAW,OAAO,IAAA,IAAQ,aAAA;AAChC,IAAA,EAAA,CAAG,OAAO,CAAA,EAAA,EAAK,MAAA,CAAO,IAAI,CAAA,EAAA,EAAK,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC3C;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,UAAA,EAAa,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,EACpC;AAEA,EAAA,OAAO,CAAA;AACT;AAEA,eAAe,cAAA,CAAe,IAAA,EAAgB,GAAA,EAAa,EAAA,EAA4B;AACrF,EAAA,MAAM,UAAU,OAAA,CAAQ,IAAA,EAAM,WAAW,CAAA,IAAK,OAAA,CAAQ,MAAM,IAAI,CAAA;AAChE,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAA,EAAM,UAAU,CAAA;AAC9C,EAAA,MAAM,MAAA,GACJ,SAAA,KAAc,MAAA,IAAU,SAAA,KAAc,YAAY,SAAA,GAAY,SAAA;AAEhE,EAAA,MAAM,SAAS,MAAM,oBAAA,CAAqB,IAAA,EAAM,GAAA,EAAK,IAAI,OAAO,CAAA;AAChE,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,MAAM,gBAAA,GAAmB,oBAAA,CAAqB,MAAA,CAAO,MAAA,EAAQ,OAAO,SAAS,CAAA;AAC7E,EAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAY,UAAA,EAAY,UAAS,GAAI,gBAAA;AAEnD,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,EAAA,CAAG,OAAO,6CAA6C,CAAA;AACvD,IAAA,EAAA,CAAG,OAAO,kDAAkD,CAAA;AAC5D,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,EAAA,CAAG,OAAO,iDAAiD,CAAA;AAC3D,IAAA,EAAA,CAAG,OAAO,sDAAsD,CAAA;AAChE,IAAA,OAAO,CAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,EAAA,CAAG,OAAO,CAAA,UAAA,EAAa,OAAO,aAAa,QAAA,GAAW,QAAA,GAAW,UAAU,CAAA,CAAE,CAAA;AAC7E,IAAA,EAAA,CAAG,MAAA,CAAO,CAAA,QAAA,EAAW,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/B;AAEA,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,EAAE,UAAU,GAAG,UAAA,EAAY,YAAY,CAAA;AACjE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAE7B,IAAA,MAAM,YACJ,MAAA,KAAW,MAAA,GACP,cAAA,GACA,MAAA,KAAW,YACT,iBAAA,GACA,iBAAA;AAER,IAAA,MAAM,MAAA,GAAS,UAAU,MAAM,CAAA;AAC/B,IAAA,EAAA,CAAG,OAAO,MAAM,CAAA;AAEhB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,EAAA,CAAG,MAAA,CAAO,CAAA,UAAA,EAAa,OAAO,CAAA,EAAA,CAAI,CAAA;AAAA,IACpC;AAEA,IAAA,OAAO,MAAA,CAAO,UAAA,GAAa,CAAA,GAAI,CAAA,GAAI,CAAA;AAAA,EACrC,SAAS,KAAA,EAAO;AACd,IAAA,EAAA,CAAG,OAAO,cAAc,CAAA;AACxB,IAAA,EAAA,CAAG,MAAA,CAAO,KAAK,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA,CAAE,CAAA;AACvE,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,EAAA,CAAG,OAAO,CAAA,UAAA,EAAa,IAAA,CAAK,GAAA,EAAI,GAAI,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,IACnD;AACA,IAAA,OAAO,CAAA;AAAA,EACT;AACF;AAEA,SAAS,WAAA,CAAY,MAAgB,IAAA,EAAkC;AACrE,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA;AAC/B,EAAA,IAAI,KAAA,KAAU,EAAA,IAAM,KAAA,KAAU,IAAA,CAAK,SAAS,CAAA,EAAG;AAC7C,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,GAAQ,CAAC,CAAA;AAC5B,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,EAAG;AAC1C,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,OAAA,CAAQ,MAAgB,IAAA,EAAuB;AACtD,EAAA,OAAO,IAAA,CAAK,SAAS,IAAI,CAAA;AAC3B;AAEA,eAAe,iBAAA,CACb,YACA,GAAA,EAC6B;AAC7B,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,EAAK,UAAU,CAAA;AACxC,IAAA,IAAI,CAAE,MAAM,UAAA,CAAW,QAAQ,CAAA,EAAI;AACjC,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,KAAA,MAAW,QAAQ,kBAAA,EAAoB;AACrC,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,EAAK,IAAI,CAAA;AAClC,IAAA,IAAI,MAAM,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC9B,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,eAAe,UAAA,CAAW,YAAoB,GAAA,EAAiC;AAC7E,EAAA,MAAM,KAAA,GAAQ,MAAM,aAAA,CAAc,GAAG,CAAA;AACrC,EAAA,MAAM,MAAA,GAAS,WAAW,GAAA,EAAK;AAAA,IAC7B,cAAA,EAAgB,IAAA;AAAA,IAChB;AAAA,GACD,CAAA;AACD,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,UAAU,CAAA;AACtC,EAAA,MAAM,MAAA,GAAU,OAAmC,OAAA,IAAY,MAAA;AAE/D,EAAA,IAAI,MAAA,IAAU,IAAA,IAAQ,OAAO,MAAA,KAAW,QAAA,EAAU;AAChD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,UAAU,CAAA,yBAAA,CAA2B,CAAA;AAAA,EAC1E;AAEA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,oBAAA,CAAqB,QAAmB,SAAA,EAA8B;AAC7E,EAAA,MAAM,QAAA,GACJ,OAAO,MAAA,CAAO,QAAA,KAAa,QAAA,GACvB,kBAAkB,MAAA,CAAO,QAAA,EAAU,SAAS,CAAA,GAC5C,MAAA,CAAO,QAAA;AACb,EAAA,MAAM,SAAA,GAAY,iBAAA,CAAkB,MAAA,CAAO,SAAA,EAAW,SAAS,CAAA;AAC/D,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,IAAW,EAAC;AAEnC,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,iBAAA,CAAkB,OAA2B,OAAA,EAAqC;AACzF,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,WAAW,KAAK,CAAA,GAAI,KAAA,GAAQ,OAAA,CAAQ,SAAS,KAAK,CAAA;AAC3D;AAEA,eAAe,WAAW,IAAA,EAAgC;AACxD,EAAA,IAAI;AACF,IAAA,MAAM,OAAO,IAAI,CAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,eAAe,cAAc,GAAA,EAA8C;AACzE,EAAA,MAAM,QAAgC,EAAC;AAGvC,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,EAAK,4BAA4B,CAAA;AAChE,EAAA,IAAI,MAAM,UAAA,CAAW,cAAc,CAAA,EAAG;AACpC,IAAA,KAAA,CAAM,UAAU,CAAA,GAAI,cAAA;AACpB,IAAA,OAAO,KAAA;AAAA,EACT;AAIA,EAAA,IAAI,CAAC,mBAAA,CAAoB,UAAA,EAAY,GAAG,CAAA,EAAG;AACzC,IAAA,MAAMC,QAAAA,GAAU,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC7C,IAAA,IAAI;AACF,MAAA,KAAA,CAAM,UAAU,CAAA,GAAIA,QAAAA,CAAQ,OAAA,CAAQ,UAAU,CAAA;AAAA,IAChD,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,mBAAA,CAAoB,MAAc,GAAA,EAAsB;AAC/D,EAAA,MAAMA,QAAAA,GAAU,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC7C,EAAA,IAAI;AACF,IAAAA,QAAAA,CAAQ,QAAQ,IAAA,EAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAA;AACtC,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,SAAS,UAAU,EAAA,EAAiB;AAClC,EAAA,EAAA,CAAG,OAAO,8BAA8B,CAAA;AACxC,EAAA,EAAA,CAAG,OAAO,EAAE,CAAA;AACZ,EAAA,EAAA,CAAG,OAAO,WAAW,CAAA;AACrB,EAAA,EAAA,CAAG,OAAO,0CAA0C,CAAA;AACpD,EAAA,EAAA,CAAG,OAAO,0DAA0D,CAAA;AACpE,EAAA,EAAA,CAAG,OAAO,EAAE,CAAA;AACZ,EAAA,EAAA,CAAG,OAAO,gBAAgB,CAAA;AAC1B,EAAA,EAAA,CAAG,OAAO,sEAAsE,CAAA;AAChF,EAAA,EAAA,CAAG,OAAO,yEAAyE,CAAA;AACnF,EAAA,EAAA,CAAG,OAAO,EAAE,CAAA;AACZ,EAAA,EAAA,CAAG,OAAO,eAAe,CAAA;AACzB,EAAA,EAAA,CAAG,OAAO,sEAAsE,CAAA;AAChF,EAAA,EAAA,CAAG,OAAO,sEAAsE,CAAA;AAChF,EAAA,EAAA,CAAG,OAAO,gDAAgD,CAAA;AAC5D;;;ACrVA,IAAM,WAAW,MAAM,MAAA,CAAO,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAC,CAAA;AACnD,OAAA,CAAQ,QAAA,GAAW,QAAA","file":"index.js","sourcesContent":["/**\n * @license MIT\n * Copyright (c) 2025-present Dispersa\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n/**\n * @fileoverview Lint output formatter interface and utilities\n */\n\nimport type { LintIssue, LintResult, LintFormatter } from '@lint/types'\n\n/**\n * Format lint results as JSON\n */\nexport const formatLintJson: LintFormatter = (result: LintResult): string => {\n return JSON.stringify(result, null, 2)\n}\n\n/**\n * Format lint results in a human-readable stylish format\n */\nexport const formatLintStylish: LintFormatter = (result: LintResult): string => {\n const lines: string[] = []\n\n if (result.issues.length === 0) {\n return '✓ No lint issues found'\n }\n\n // Group issues by token\n const byToken = new Map<string, LintIssue[]>()\n for (const issue of result.issues) {\n const existing = byToken.get(issue.tokenName) ?? []\n existing.push(issue)\n byToken.set(issue.tokenName, existing)\n }\n\n // Output issues\n for (const [tokenName, issues] of byToken) {\n lines.push(``)\n lines.push(` ${tokenName}`)\n for (const issue of issues) {\n const severity = issue.severity === 'error' ? '✖' : '⚠'\n const label = issue.severity === 'error' ? 'error' : 'warning'\n lines.push(` ${severity} ${label}: ${issue.message} [${issue.ruleId}]`)\n }\n }\n\n // Summary\n lines.push(``)\n if (result.errorCount > 0 || result.warningCount > 0) {\n const parts: string[] = []\n if (result.errorCount > 0) {\n parts.push(`${result.errorCount} error${result.errorCount === 1 ? '' : 's'}`)\n }\n if (result.warningCount > 0) {\n parts.push(`${result.warningCount} warning${result.warningCount === 1 ? '' : 's'}`)\n }\n lines.push(`✖ ${parts.join(', ')}`)\n }\n\n return lines.join('\\n')\n}\n\n/**\n * Format lint results for CI output (compact, parseable)\n */\nexport const formatLintCompact: LintFormatter = (result: LintResult): string => {\n const lines: string[] = []\n\n for (const issue of result.issues) {\n const severity = issue.severity.toUpperCase()\n lines.push(`${severity}: ${issue.ruleId} - ${issue.message} (token: ${issue.tokenName})`)\n }\n\n if (result.errorCount > 0 || result.warningCount > 0) {\n lines.push(`SUMMARY: ${result.errorCount} errors, ${result.warningCount} warnings`)\n }\n\n return lines.join('\\n')\n}\n","import { access } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { dirname, isAbsolute, resolve } from 'node:path'\nimport process from 'node:process'\n\nimport type { LintOutputFormat } from '@lint/types'\nimport { build, lint, type BuildConfig } from 'dispersa'\nimport { createJiti } from 'jiti'\n\nimport type { CliConfig } from './config'\nimport { formatLintCompact, formatLintJson, formatLintStylish } from './formatters/lint-formatter'\n\ntype CliIO = {\n stdout: (message: string) => void\n stderr: (message: string) => void\n}\n\ntype RunOptions = {\n cwd?: string\n io?: CliIO\n}\n\nconst defaultConfigNames = [\n 'dispersa.config.ts',\n 'dispersa.config.js',\n 'dispersa.config.mts',\n 'dispersa.config.mjs',\n 'dispersa.config.cts',\n 'dispersa.config.cjs',\n]\n\nexport async function runCli(args: string[], options: RunOptions = {}): Promise<number> {\n const cwd = options.cwd ?? process.cwd()\n const io: CliIO = options.io ?? {\n stdout: (message) => process.stdout.write(`${message}\\n`),\n stderr: (message) => process.stderr.write(`${message}\\n`),\n }\n\n const command = args[0] ?? 'build'\n if (command === '--help' || command === '-h' || command === 'help') {\n printHelp(io)\n return 0\n }\n\n if (command === 'lint') {\n return runLintCommand(args.slice(1), cwd, io)\n }\n\n if (command !== 'build') {\n io.stderr(`Unknown command: ${command}`)\n printHelp(io)\n return 1\n }\n\n const verbose = hasFlag(args, '--verbose') || hasFlag(args, '-v')\n const loaded = await resolveAndLoadConfig(args, cwd, io, verbose)\n if (!loaded) {\n return 1\n }\n\n const normalizedConfig = normalizeConfigPaths(loaded.config, loaded.configDir)\n const { validation, resolver, buildPath, ...buildConfig } = normalizedConfig\n\n if (verbose) {\n const outputCount = buildConfig.outputs?.length ?? 0\n io.stdout(`Outputs: ${outputCount} configured`)\n if (buildPath) {\n io.stdout(`Build path: ${buildPath}`)\n }\n }\n\n const startTime = Date.now()\n const result = await build({ resolver, buildPath, validation, ...buildConfig } as BuildConfig)\n const elapsed = Date.now() - startTime\n\n return reportBuildResult(result, verbose, elapsed, io)\n}\n\nasync function resolveAndLoadConfig(\n args: string[],\n cwd: string,\n io: CliIO,\n verbose: boolean,\n): Promise<{ config: CliConfig; configDir: string } | undefined> {\n const configPath = getArgValue(args, '--config')\n const resolvedPath = await resolveConfigPath(configPath, cwd)\n if (resolvedPath === undefined) {\n io.stderr(\n `No config found. Expected one of: ${defaultConfigNames.join(', ')} ` +\n 'or pass --config <path>.',\n )\n return undefined\n }\n\n if (verbose) {\n io.stdout(`Config: ${resolvedPath}`)\n }\n\n try {\n const config = await loadConfig(resolvedPath, cwd)\n return { config, configDir: dirname(resolvedPath) }\n } catch (error) {\n io.stderr(`Failed to load config: ${resolvedPath}`)\n io.stderr(`- ${error instanceof Error ? error.message : String(error)}`)\n return undefined\n }\n}\n\nfunction reportBuildResult(\n result: Awaited<ReturnType<typeof build>>,\n verbose: boolean,\n elapsed: number,\n io: CliIO,\n): number {\n if (!result.success) {\n io.stderr('Build failed.')\n for (const error of result.errors ?? []) {\n io.stderr(`- [${error.code}] ${error.message}`)\n if (verbose && error.tokenPath) {\n io.stderr(` Token: ${error.tokenPath}`)\n }\n if (verbose && error.path) {\n io.stderr(` File: ${error.path}`)\n }\n if (verbose && error.suggestions && error.suggestions.length > 0) {\n io.stderr(` Suggestions: ${error.suggestions.join(', ')}`)\n }\n }\n if (verbose) {\n io.stderr(`Duration: ${elapsed}ms`)\n }\n return 1\n }\n\n io.stdout('Build succeeded.')\n for (const output of result.outputs) {\n const location = output.path ?? '(in-memory)'\n io.stdout(`- ${output.name}: ${location}`)\n }\n\n if (verbose) {\n io.stdout(`Duration: ${elapsed}ms`)\n }\n\n return 0\n}\n\nasync function runLintCommand(args: string[], cwd: string, io: CliIO): Promise<number> {\n const verbose = hasFlag(args, '--verbose') || hasFlag(args, '-v')\n const formatArg = getArgValue(args, '--format')\n const format: LintOutputFormat =\n formatArg === 'json' || formatArg === 'compact' ? formatArg : 'stylish'\n\n const loaded = await resolveAndLoadConfig(args, cwd, io, verbose)\n if (!loaded) {\n return 1\n }\n\n const normalizedConfig = normalizeConfigPaths(loaded.config, loaded.configDir)\n const { lint: lintConfig, validation, resolver } = normalizedConfig\n\n if (!lintConfig) {\n io.stderr('No lint configuration found in config file.')\n io.stderr('Add a \"lint\" property to your dispersa.config.ts')\n return 1\n }\n\n if (!resolver) {\n io.stderr('No resolver configuration found in config file.')\n io.stderr('Add a \"resolver\" property to your dispersa.config.ts')\n return 1\n }\n\n if (verbose) {\n io.stdout(`Resolver: ${typeof resolver === 'string' ? resolver : '(inline)'}`)\n io.stdout(`Format: ${format}`)\n }\n\n const startTime = Date.now()\n\n try {\n const result = await lint({ resolver, ...lintConfig, validation })\n const elapsed = Date.now() - startTime\n\n const formatter =\n format === 'json'\n ? formatLintJson\n : format === 'compact'\n ? formatLintCompact\n : formatLintStylish\n\n const output = formatter(result)\n io.stdout(output)\n\n if (verbose) {\n io.stdout(`Duration: ${elapsed}ms`)\n }\n\n return result.errorCount > 0 ? 1 : 0\n } catch (error) {\n io.stderr('Lint failed.')\n io.stderr(`- ${error instanceof Error ? error.message : String(error)}`)\n if (verbose) {\n io.stderr(`Duration: ${Date.now() - startTime}ms`)\n }\n return 1\n }\n}\n\nfunction getArgValue(args: string[], flag: string): string | undefined {\n const index = args.indexOf(flag)\n if (index === -1 || index === args.length - 1) {\n return undefined\n }\n const value = args[index + 1]\n if (value == null || value.startsWith('-')) {\n return undefined\n }\n return value\n}\n\nfunction hasFlag(args: string[], flag: string): boolean {\n return args.includes(flag)\n}\n\nasync function resolveConfigPath(\n configPath: string | undefined,\n cwd: string,\n): Promise<string | undefined> {\n if (configPath) {\n const fullPath = resolve(cwd, configPath)\n if (!(await fileExists(fullPath))) {\n return undefined\n }\n return fullPath\n }\n\n for (const name of defaultConfigNames) {\n const fullPath = resolve(cwd, name)\n if (await fileExists(fullPath)) {\n return fullPath\n }\n }\n\n return undefined\n}\n\nasync function loadConfig(configPath: string, cwd: string): Promise<CliConfig> {\n const alias = await buildAliasMap(cwd)\n const loader = createJiti(cwd, {\n interopDefault: true,\n alias,\n })\n const loaded = await loader(configPath)\n const config = (loaded as { default?: CliConfig }).default ?? (loaded as CliConfig)\n\n if (config == null || typeof config !== 'object') {\n throw new Error(`Invalid config: ${configPath} did not export an object`)\n }\n\n return config\n}\n\nfunction normalizeConfigPaths(config: CliConfig, configDir: string): CliConfig {\n const resolver =\n typeof config.resolver === 'string'\n ? resolveIfRelative(config.resolver, configDir)\n : config.resolver\n const buildPath = resolveIfRelative(config.buildPath, configDir)\n const outputs = config.outputs ?? []\n\n return {\n ...config,\n resolver,\n buildPath,\n outputs,\n }\n}\n\nfunction resolveIfRelative(value: string | undefined, baseDir: string): string | undefined {\n if (!value) {\n return value\n }\n return isAbsolute(value) ? value : resolve(baseDir, value)\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await access(path)\n return true\n } catch {\n return false\n }\n}\n\nasync function buildAliasMap(cwd: string): Promise<Record<string, string>> {\n const alias: Record<string, string> = {}\n\n // Dev monorepo: point to source files for hot-reload\n const coreSourcePath = resolve(cwd, 'packages/core/src/index.ts')\n if (await fileExists(coreSourcePath)) {\n alias['dispersa'] = coreSourcePath\n return alias\n }\n\n // Not resolvable from cwd — try from the CLI module's own location\n // (handles workspace symlinks and global installs)\n if (!isPackageResolvable('dispersa', cwd)) {\n const require = createRequire(import.meta.url)\n try {\n alias['dispersa'] = require.resolve('dispersa')\n } catch {\n // Not resolvable at all; config loading will fail with a clear error\n }\n }\n\n return alias\n}\n\nfunction isPackageResolvable(name: string, cwd: string): boolean {\n const require = createRequire(import.meta.url)\n try {\n require.resolve(name, { paths: [cwd] })\n return true\n } catch {\n return false\n }\n}\n\nfunction printHelp(io: CliIO): void {\n io.stdout('dispersa <command> [options]')\n io.stdout('')\n io.stdout('Commands:')\n io.stdout(' build Build design tokens')\n io.stdout(' lint Lint design tokens without building')\n io.stdout('')\n io.stdout('Build Options:')\n io.stdout(' --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)')\n io.stdout(' --verbose, -v Show detailed build output (timing, error context)')\n io.stdout('')\n io.stdout('Lint Options:')\n io.stdout(' --config <path> Path to dispersa.config.(ts|js|mts|mjs|cts|cjs)')\n io.stdout(' --format <format> Output format: stylish (default), json, compact')\n io.stdout(' --verbose, -v Show detailed lint output')\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli.js'\n\nconst exitCode = await runCli(process.argv.slice(2))\nprocess.exitCode = exitCode\n"]}
@@ -0,0 +1,118 @@
1
+ import { B as BuildConfig, d as BuildResult, j as ModifierInputs, k as ResolverDocument, a as ValidationOptions, m as LintConfig, n as LintResult } from './index-Dajm5rvM.js';
2
+ import { a as ResolvedTokens } from './types-TQHV1MrY.js';
3
+
4
+ /**
5
+ * @license
6
+ * Copyright (c) 2025 Dispersa Contributors
7
+ * SPDX-License-Identifier: MIT
8
+ */
9
+
10
+ /**
11
+ * DTCG design token processor with multi-format output support
12
+ *
13
+ * Dispersa processes DTCG-compliant design tokens through a configurable pipeline,
14
+ * resolves references and aliases, applies transforms and filters, and generates output
15
+ * in multiple formats (CSS, JSON, JavaScript).
16
+ *
17
+ * **Runtime Validation:**
18
+ * All functions validate their configuration inputs at runtime, including build configs,
19
+ * output configs, and custom component registrations. This catches configuration errors
20
+ * early with helpful error messages.
21
+ *
22
+ * Features:
23
+ * - **Transforms**: Modify token values and names (e.g., convert colors, change case)
24
+ * - **Filters**: Select which tokens to include in output
25
+ * - **Preprocessors**: Transform raw token data before parsing
26
+ * - **Renderers**: Generate output in various formats
27
+ * - **Runtime validation**: JSON schema validation for all user inputs
28
+ *
29
+ * @example Basic build usage
30
+ * ```typescript
31
+ * import { build, css } from 'dispersa'
32
+ * import { nameKebabCase } from 'dispersa/transforms'
33
+ *
34
+ * const result = await build({
35
+ * resolver: './tokens.resolver.json',
36
+ * buildPath: './output',
37
+ * outputs: [
38
+ * css({
39
+ * name: 'css',
40
+ * file: 'tokens.css',
41
+ * preset: 'bundle',
42
+ * selector: ':root',
43
+ * transforms: [nameKebabCase()]
44
+ * })
45
+ * ]
46
+ * })
47
+ * ```
48
+ *
49
+ * @example Mixed presets per output
50
+ * ```typescript
51
+ * import { build, css, json } from 'dispersa'
52
+ *
53
+ * const result = await build({
54
+ * resolver: './tokens.resolver.json',
55
+ * buildPath: './output',
56
+ * outputs: [
57
+ * css({
58
+ * name: 'css',
59
+ * file: 'tokens.css',
60
+ * preset: 'bundle',
61
+ * selector: ':root', // All themes in one CSS file
62
+ * transforms: [nameKebabCase()]
63
+ * }),
64
+ * json({
65
+ * name: 'json',
66
+ * file: 'tokens-{theme}.json', // Separate file per theme
67
+ * preset: 'standalone',
68
+ * structure: 'flat'
69
+ * })
70
+ * ]
71
+ * })
72
+ * ```
73
+ *
74
+ * @example Using filters and preprocessors
75
+ * ```typescript
76
+ * import { build, css } from 'dispersa'
77
+ * import { byType } from 'dispersa/filters'
78
+ * import { nameKebabCase } from 'dispersa/transforms'
79
+ *
80
+ * const result = await build({
81
+ * resolver: './tokens.resolver.json',
82
+ * buildPath: './output',
83
+ * outputs: [
84
+ * css({
85
+ * name: 'colors-only',
86
+ * file: 'colors.css',
87
+ * preset: 'standalone',
88
+ * selector: ':root',
89
+ * filters: [byType('color')],
90
+ * transforms: [nameKebabCase()]
91
+ * })
92
+ * ],
93
+ * permutations: [
94
+ * { theme: 'light' },
95
+ * { theme: 'dark' }
96
+ * ]
97
+ * })
98
+ * ```
99
+ */
100
+ declare function build(config: BuildConfig): Promise<BuildResult>;
101
+ declare function buildOrThrow(config: BuildConfig): Promise<BuildResult>;
102
+ declare function buildPermutation(config: BuildConfig, modifierInputs?: ModifierInputs): Promise<BuildResult>;
103
+ declare function resolveTokens(resolver: string | ResolverDocument, modifierInputs?: ModifierInputs, validation?: ValidationOptions): Promise<ResolvedTokens>;
104
+ type LintOptions = {
105
+ resolver: string | ResolverDocument;
106
+ modifierInputs?: ModifierInputs;
107
+ validation?: ValidationOptions;
108
+ } & LintConfig;
109
+ declare function lint(options: LintOptions): Promise<LintResult>;
110
+ declare function resolveAllPermutations(resolver: string | ResolverDocument): Promise<{
111
+ tokens: ResolvedTokens;
112
+ modifierInputs: ModifierInputs;
113
+ }[]>;
114
+ declare function generateTypes(tokens: ResolvedTokens, fileName: string, options?: {
115
+ moduleName?: string;
116
+ }): Promise<void>;
117
+
118
+ export { type LintOptions as L, buildOrThrow as a, build as b, buildPermutation as c, resolveAllPermutations as d, generateTypes as g, lint as l, resolveTokens as r };
@@ -0,0 +1,118 @@
1
+ import { B as BuildConfig, d as BuildResult, j as ModifierInputs, k as ResolverDocument, a as ValidationOptions, m as LintConfig, n as LintResult } from './index-De6SjZYH.cjs';
2
+ import { a as ResolvedTokens } from './types-TQHV1MrY.cjs';
3
+
4
+ /**
5
+ * @license
6
+ * Copyright (c) 2025 Dispersa Contributors
7
+ * SPDX-License-Identifier: MIT
8
+ */
9
+
10
+ /**
11
+ * DTCG design token processor with multi-format output support
12
+ *
13
+ * Dispersa processes DTCG-compliant design tokens through a configurable pipeline,
14
+ * resolves references and aliases, applies transforms and filters, and generates output
15
+ * in multiple formats (CSS, JSON, JavaScript).
16
+ *
17
+ * **Runtime Validation:**
18
+ * All functions validate their configuration inputs at runtime, including build configs,
19
+ * output configs, and custom component registrations. This catches configuration errors
20
+ * early with helpful error messages.
21
+ *
22
+ * Features:
23
+ * - **Transforms**: Modify token values and names (e.g., convert colors, change case)
24
+ * - **Filters**: Select which tokens to include in output
25
+ * - **Preprocessors**: Transform raw token data before parsing
26
+ * - **Renderers**: Generate output in various formats
27
+ * - **Runtime validation**: JSON schema validation for all user inputs
28
+ *
29
+ * @example Basic build usage
30
+ * ```typescript
31
+ * import { build, css } from 'dispersa'
32
+ * import { nameKebabCase } from 'dispersa/transforms'
33
+ *
34
+ * const result = await build({
35
+ * resolver: './tokens.resolver.json',
36
+ * buildPath: './output',
37
+ * outputs: [
38
+ * css({
39
+ * name: 'css',
40
+ * file: 'tokens.css',
41
+ * preset: 'bundle',
42
+ * selector: ':root',
43
+ * transforms: [nameKebabCase()]
44
+ * })
45
+ * ]
46
+ * })
47
+ * ```
48
+ *
49
+ * @example Mixed presets per output
50
+ * ```typescript
51
+ * import { build, css, json } from 'dispersa'
52
+ *
53
+ * const result = await build({
54
+ * resolver: './tokens.resolver.json',
55
+ * buildPath: './output',
56
+ * outputs: [
57
+ * css({
58
+ * name: 'css',
59
+ * file: 'tokens.css',
60
+ * preset: 'bundle',
61
+ * selector: ':root', // All themes in one CSS file
62
+ * transforms: [nameKebabCase()]
63
+ * }),
64
+ * json({
65
+ * name: 'json',
66
+ * file: 'tokens-{theme}.json', // Separate file per theme
67
+ * preset: 'standalone',
68
+ * structure: 'flat'
69
+ * })
70
+ * ]
71
+ * })
72
+ * ```
73
+ *
74
+ * @example Using filters and preprocessors
75
+ * ```typescript
76
+ * import { build, css } from 'dispersa'
77
+ * import { byType } from 'dispersa/filters'
78
+ * import { nameKebabCase } from 'dispersa/transforms'
79
+ *
80
+ * const result = await build({
81
+ * resolver: './tokens.resolver.json',
82
+ * buildPath: './output',
83
+ * outputs: [
84
+ * css({
85
+ * name: 'colors-only',
86
+ * file: 'colors.css',
87
+ * preset: 'standalone',
88
+ * selector: ':root',
89
+ * filters: [byType('color')],
90
+ * transforms: [nameKebabCase()]
91
+ * })
92
+ * ],
93
+ * permutations: [
94
+ * { theme: 'light' },
95
+ * { theme: 'dark' }
96
+ * ]
97
+ * })
98
+ * ```
99
+ */
100
+ declare function build(config: BuildConfig): Promise<BuildResult>;
101
+ declare function buildOrThrow(config: BuildConfig): Promise<BuildResult>;
102
+ declare function buildPermutation(config: BuildConfig, modifierInputs?: ModifierInputs): Promise<BuildResult>;
103
+ declare function resolveTokens(resolver: string | ResolverDocument, modifierInputs?: ModifierInputs, validation?: ValidationOptions): Promise<ResolvedTokens>;
104
+ type LintOptions = {
105
+ resolver: string | ResolverDocument;
106
+ modifierInputs?: ModifierInputs;
107
+ validation?: ValidationOptions;
108
+ } & LintConfig;
109
+ declare function lint(options: LintOptions): Promise<LintResult>;
110
+ declare function resolveAllPermutations(resolver: string | ResolverDocument): Promise<{
111
+ tokens: ResolvedTokens;
112
+ modifierInputs: ModifierInputs;
113
+ }[]>;
114
+ declare function generateTypes(tokens: ResolvedTokens, fileName: string, options?: {
115
+ moduleName?: string;
116
+ }): Promise<void>;
117
+
118
+ export { type LintOptions as L, buildOrThrow as a, build as b, buildPermutation as c, resolveAllPermutations as d, generateTypes as g, lint as l, resolveTokens as r };
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @fileoverview Custom error classes for Dispersa
3
+ *
4
+ * Error classes are intentionally kept as simple value objects with no
5
+ * imports from utility modules. Suggestion formatting is done at call
6
+ * sites to keep the error hierarchy dependency-free.
7
+ */
8
+ /**
9
+ * Base error class for all Dispersa errors
10
+ */
11
+ declare class DispersaError extends Error {
12
+ constructor(message: string);
13
+ }
14
+ /**
15
+ * Thrown when a token reference cannot be resolved
16
+ *
17
+ * @param referenceName - The token name that could not be found
18
+ * @param suggestions - Similar token names for "did you mean?" hints
19
+ * @param message - Optional custom message (overrides auto-generated message)
20
+ */
21
+ declare class TokenReferenceError extends DispersaError {
22
+ referenceName: string;
23
+ suggestions: string[];
24
+ constructor(referenceName: string, suggestions?: string[], message?: string);
25
+ private static formatHint;
26
+ }
27
+ /**
28
+ * Thrown when a circular reference is detected
29
+ */
30
+ declare class CircularReferenceError extends DispersaError {
31
+ tokenName: string;
32
+ referencePath: string[];
33
+ constructor(tokenName: string, referencePath: string[]);
34
+ }
35
+ /**
36
+ * Thrown when validation fails
37
+ */
38
+ declare class ValidationError extends DispersaError {
39
+ errors: {
40
+ message: string;
41
+ path?: string;
42
+ }[];
43
+ constructor(message: string, errors: {
44
+ message: string;
45
+ path?: string;
46
+ }[]);
47
+ }
48
+ /**
49
+ * Thrown when file operations fail
50
+ */
51
+ declare class FileOperationError extends DispersaError {
52
+ operation: 'read' | 'write';
53
+ filePath: string;
54
+ originalError: Error;
55
+ constructor(operation: 'read' | 'write', filePath: string, originalError: Error);
56
+ }
57
+ /**
58
+ * Thrown when a build configuration is invalid
59
+ */
60
+ declare class ConfigurationError extends DispersaError {
61
+ constructor(message: string);
62
+ }
63
+ /**
64
+ * Thrown when base permutation cannot be determined
65
+ */
66
+ declare class BasePermutationError extends DispersaError {
67
+ constructor(message?: string);
68
+ }
69
+ /**
70
+ * Thrown when an unknown modifier or context is used
71
+ *
72
+ * @param modifierName - Name of the modifier that failed validation
73
+ * @param contextValue - The invalid context value (if applicable)
74
+ * @param availableValues - Valid options (context names or modifier names) for the error message
75
+ */
76
+ declare class ModifierError extends DispersaError {
77
+ modifierName: string;
78
+ contextValue?: string | undefined;
79
+ availableValues: string[];
80
+ constructor(modifierName: string, contextValue?: string | undefined, availableValues?: string[]);
81
+ }
82
+ /**
83
+ * Thrown when lint errors are found and failOnError is true
84
+ *
85
+ * @param issues - Array of lint issues that caused the error
86
+ */
87
+ declare class LintError extends DispersaError {
88
+ issues: Array<{
89
+ ruleId: string;
90
+ severity: 'error' | 'warn';
91
+ message: string;
92
+ tokenName: string;
93
+ tokenPath: string[];
94
+ }>;
95
+ constructor(issues: Array<{
96
+ ruleId: string;
97
+ severity: 'error' | 'warn';
98
+ message: string;
99
+ tokenName: string;
100
+ tokenPath: string[];
101
+ }>);
102
+ }
103
+
104
+ export { BasePermutationError as B, CircularReferenceError as C, DispersaError as D, FileOperationError as F, LintError as L, ModifierError as M, TokenReferenceError as T, ValidationError as V, ConfigurationError as a };