dispersa 0.4.3 → 1.1.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 (58) hide show
  1. package/README.md +65 -30
  2. package/dist/android-CRDfSB3_.d.cts +126 -0
  3. package/dist/android-DANJjjPO.d.ts +126 -0
  4. package/dist/builders.cjs +206 -62
  5. package/dist/builders.cjs.map +1 -1
  6. package/dist/builders.d.cts +12 -11
  7. package/dist/builders.d.ts +12 -11
  8. package/dist/builders.js +206 -62
  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 +799 -353
  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 +793 -353
  35. package/dist/index.js.map +1 -1
  36. package/dist/lint.cjs +1029 -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 +1009 -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.d.cts +2 -2
  49. package/dist/transforms.d.ts +2 -2
  50. package/dist/{types-CZb19kiq.d.ts → types-8MLtztK3.d.ts} +56 -1
  51. package/dist/{types-CussyWwe.d.cts → types-BHBHRm0a.d.cts} +56 -1
  52. package/dist/{types-BAv39mum.d.cts → types-BltzwVYK.d.cts} +1 -1
  53. package/dist/{types-DWKq-eJj.d.cts → types-CAdUV-fa.d.cts} +1 -1
  54. package/dist/{types-CzHa7YkW.d.ts → types-DztXKlka.d.ts} +1 -1
  55. package/dist/{types-Bc0kA7De.d.ts → types-TQHV1MrY.d.cts} +19 -1
  56. package/dist/{types-Bc0kA7De.d.cts → types-TQHV1MrY.d.ts} +19 -1
  57. package/dist/{types-BzNcG-rI.d.ts → types-ebxDimRz.d.ts} +1 -1
  58. package/package.json +19 -9
package/README.md CHANGED
@@ -8,6 +8,7 @@ A TypeScript build system for processing [DTCG 2025.10](https://www.designtokens
8
8
  - **Multiple outputs** -- CSS custom properties, JSON, JS/TS modules
9
9
  - **Extensible pipeline** -- custom preprocessors, filters, transforms, and renderers
10
10
  - **Schema validation** -- AJV runtime validation with schema-generated TypeScript types
11
+ - **Linting** -- Plugin-based lint rules for design token validation
11
12
  - **In-memory mode** -- use without the filesystem for build tools, APIs, and testing
12
13
  - **CLI** -- config-first workflow with auto-discovery
13
14
 
@@ -17,6 +18,23 @@ A TypeScript build system for processing [DTCG 2025.10](https://www.designtokens
17
18
 
18
19
  **Composite types:** `shadow`, `typography`, `border`, `strokeStyle`, `transition`, `gradient`
19
20
 
21
+ ## Linting
22
+
23
+ Dispersa includes a plugin-based linting system to validate design tokens against semantic rules. Linting can run standalone or as part of the build pipeline.
24
+
25
+ ```typescript
26
+ import { lint } from 'dispersa'
27
+ import { dispersaPlugin, recommendedConfig } from 'dispersa/lint'
28
+
29
+ const result = await lint({
30
+ resolver: './tokens.resolver.json',
31
+ ...recommendedConfig,
32
+ })
33
+ console.log(`Found ${result.errorCount} errors, ${result.warningCount} warnings`)
34
+ ```
35
+
36
+ Built-in rules include `require-description`, `naming-convention`, `no-deprecated-usage`, `no-duplicate-values`, and `path-schema`. Create custom rules with the `createRule()` factory or build reusable plugins.
37
+
20
38
  ## Getting started
21
39
 
22
40
  ### New project
@@ -39,7 +57,7 @@ Define tokens inline and build CSS -- no files needed:
39
57
 
40
58
  ```typescript
41
59
  import type { ResolverDocument } from 'dispersa'
42
- import { Dispersa, css } from 'dispersa'
60
+ import { build, css } from 'dispersa'
43
61
  import { colorToHex } from 'dispersa/transforms'
44
62
 
45
63
  const resolver: ResolverDocument = {
@@ -100,9 +118,11 @@ const resolver: ResolverDocument = {
100
118
  resolutionOrder: [{ $ref: '#/sets/base' }, { $ref: '#/modifiers/theme' }],
101
119
  }
102
120
 
103
- const dispersa = new Dispersa({ resolver })
121
+ import { build, css } from 'dispersa'
122
+ import { colorToHex } from 'dispersa/transforms'
104
123
 
105
- const result = await dispersa.build({
124
+ const result = await build({
125
+ resolver,
106
126
  outputs: [
107
127
  css({
108
128
  name: 'css',
@@ -568,7 +588,7 @@ Dispersa can run entirely without the filesystem. Pass a `ResolverDocument` obje
568
588
 
569
589
  ```typescript
570
590
  import type { ResolverDocument } from 'dispersa'
571
- import { Dispersa, css } from 'dispersa'
591
+ import { build, css } from 'dispersa'
572
592
  import { colorToHex } from 'dispersa/transforms'
573
593
 
574
594
  const resolver: ResolverDocument = {
@@ -590,9 +610,8 @@ const resolver: ResolverDocument = {
590
610
  resolutionOrder: [{ $ref: '#/sets/base' }],
591
611
  }
592
612
 
593
- const dispersa = new Dispersa({ resolver })
594
-
595
- const result = await dispersa.build({
613
+ const result = await build({
614
+ resolver,
596
615
  outputs: [
597
616
  css({
598
617
  name: 'css',
@@ -734,43 +753,59 @@ export default defineConfig({
734
753
 
735
754
  ## API reference
736
755
 
737
- ### `Dispersa` class
756
+ ### Core functions
757
+
758
+ Dispersa provides standalone functions for all operations:
738
759
 
739
760
  ```typescript
740
- const dispersa = new Dispersa(options?: DispersaOptions)
761
+ import {
762
+ build,
763
+ buildOrThrow,
764
+ buildPermutation,
765
+ resolveTokens,
766
+ lint,
767
+ resolveAllPermutations,
768
+ generateTypes,
769
+ } from 'dispersa'
741
770
  ```
742
771
 
743
- **Constructor options:**
744
-
745
- | Option | Type | Description |
746
- | ------------ | --------------------------------------- | ------------------------------------------------------ |
747
- | `resolver` | `string \| ResolverDocument` | Default resolver (file path or inline object) |
748
- | `buildPath` | `string` | Default output directory |
749
- | `validation` | `{ mode?: 'error' \| 'warn' \| 'off' }` | Validation behavior (`'warn'` logs via `console.warn`) |
750
-
751
- **Methods:**
752
-
753
- | Method | Description |
772
+ | Function | Description |
754
773
  | ------------------------------------------- | ----------------------------------------------------- |
755
774
  | `build(config)` | Build tokens. Returns `BuildResult` (never throws). |
756
775
  | `buildOrThrow(config)` | Build tokens. Throws on failure. |
757
776
  | `buildPermutation(config, modifierInputs?)` | Build a single permutation. |
758
777
  | `resolveTokens(resolver, modifierInputs?)` | Resolve tokens for one permutation without rendering. |
778
+ | `lint(options)` | Run lint rules on resolved tokens. |
759
779
  | `resolveAllPermutations(resolver)` | Resolve tokens for every permutation. |
760
780
  | `generateTypes(tokens, fileName, options?)` | Generate a `.d.ts` file from resolved tokens. |
761
781
 
782
+ ### BuildConfig
783
+
784
+ When calling `build()` or `buildOrThrow()`, pass a `BuildConfig` object:
785
+
786
+ | Option | Type | Description |
787
+ | ------------ | --------------------------------------- | ------------------------------------- |
788
+ | `resolver` | `string \| ResolverDocument` | Resolver (file path or inline object) |
789
+ | `buildPath` | `string` | Output directory |
790
+ | `outputs` | `OutputConfig[]` | Array of output configurations |
791
+ | `validation` | `{ mode?: 'error' \| 'warn' \| 'off' }` | Validation behavior |
792
+ | `filters` | `Filter[]` | Global filters |
793
+ | `transforms` | `Transform[]` | Global transforms |
794
+ | `lint` | `LintBuildConfig` | Lint configuration |
795
+
762
796
  ### Subpath exports
763
797
 
764
- | Export | Description |
765
- | ------------------------ | ---------------------------------------------------------------------------- |
766
- | `dispersa` | `Dispersa` class, builder functions (`css`, `json`, `js`, `tailwind`), types |
767
- | `dispersa/transforms` | Built-in transform factories |
768
- | `dispersa/filters` | Built-in filter factories |
769
- | `dispersa/builders` | Output builder functions |
770
- | `dispersa/renderers` | Renderer types, `defineRenderer`, and `outputTree` helper |
771
- | `dispersa/preprocessors` | Preprocessor type |
772
- | `dispersa/errors` | Error classes (`DispersaError`, `TokenReferenceError`, etc.) |
773
- | `dispersa/config` | `defineConfig` helper for CLI config files |
798
+ | Export | Description |
799
+ | ------------------------ | ---------------------------------------------------------------------- |
800
+ | `dispersa` | Core functions (`build`, `lint`, etc.), builder functions, types |
801
+ | `dispersa/transforms` | Built-in transform factories |
802
+ | `dispersa/filters` | Built-in filter factories |
803
+ | `dispersa/builders` | Output builder functions |
804
+ | `dispersa/renderers` | Renderer types, `defineRenderer`, and `outputTree` helper |
805
+ | `dispersa/preprocessors` | Preprocessor type |
806
+ | `dispersa/errors` | Error classes (`DispersaError`, `TokenReferenceError`, etc.) |
807
+ | `dispersa/config` | `defineConfig` helper for CLI config files |
808
+ | `dispersa/lint` | Linting system: `LintRunner`, built-in rules, `createRule`, formatters |
774
809
 
775
810
  Everything outside these entry points is internal and not a stable API contract.
776
811
 
@@ -0,0 +1,126 @@
1
+ import { S as SelectorFunction, M as MediaQueryFunction } from './index-De6SjZYH.cjs';
2
+
3
+ /**
4
+ * @license MIT
5
+ * Copyright (c) 2025-present Dispersa Contributors
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ /**
12
+ * Options for Tailwind CSS v4 renderer
13
+ *
14
+ * Controls how tokens are converted to Tailwind v4 @theme CSS variables.
15
+ *
16
+ * @example Bundle with dark mode overrides
17
+ * ```typescript
18
+ * tailwind({
19
+ * name: 'tailwind',
20
+ * file: 'theme.css',
21
+ * preset: 'bundle',
22
+ * selector: (modifier, context, isBase) => {
23
+ * if (isBase) return ':root'
24
+ * return `[data-${modifier}="${context}"]`
25
+ * },
26
+ * })
27
+ * ```
28
+ */
29
+ type TailwindRendererOptions = {
30
+ preset?: 'bundle' | 'standalone';
31
+ includeImport?: boolean;
32
+ namespace?: string;
33
+ minify?: boolean;
34
+ selector?: string | SelectorFunction;
35
+ mediaQuery?: string | MediaQueryFunction;
36
+ };
37
+
38
+ /**
39
+ * @license MIT
40
+ * Copyright (c) 2025-present Dispersa Contributors
41
+ *
42
+ * This source code is licensed under the MIT license found in the
43
+ * LICENSE file in the root directory of this source tree.
44
+ */
45
+
46
+ /**
47
+ * Options for iOS/SwiftUI renderer
48
+ */
49
+ type IosRendererOptions = {
50
+ preset?: 'standalone';
51
+ accessLevel?: 'public' | 'internal';
52
+ /**
53
+ * Output structure:
54
+ * - `'enum'` — nested enums inside a single root enum
55
+ * - `'grouped'` — namespace enum with separate extensions per token group
56
+ */
57
+ structure?: 'enum' | 'grouped';
58
+ enumName?: string;
59
+ /** Namespace enum name used in grouped mode (default: 'DesignTokens') */
60
+ extensionNamespace?: string;
61
+ colorSpace?: 'sRGB' | 'displayP3';
62
+ /**
63
+ * Target Swift language version.
64
+ * - `'5.9'` (default) — standard static let declarations
65
+ * - `'6.0'` — adds `nonisolated(unsafe)` to static properties for
66
+ * Swift 6 strict concurrency compliance
67
+ */
68
+ swiftVersion?: '5.9' | '6.0';
69
+ /** Number of spaces per indentation level (default 4) */
70
+ indent?: number;
71
+ /** Add @frozen annotation to enums and structs for ABI stability (default false) */
72
+ frozen?: boolean;
73
+ };
74
+
75
+ /**
76
+ * @license MIT
77
+ * Copyright (c) 2025-present Dispersa Contributors
78
+ *
79
+ * This source code is licensed under the MIT license found in the
80
+ * LICENSE file in the root directory of this source tree.
81
+ */
82
+
83
+ /**
84
+ * Options for Android/Jetpack Compose renderer
85
+ *
86
+ * Note: `packageName` is marked optional for type compatibility with the Renderer
87
+ * generic, but is validated as required at runtime in the renderer's format() method.
88
+ *
89
+ * @experimental This type is experimental. Properties and behavior may change.
90
+ */
91
+ type AndroidRendererOptions = {
92
+ preset?: 'standalone' | 'bundle';
93
+ packageName?: string;
94
+ objectName?: string;
95
+ /**
96
+ * Color output format for Kotlin Color initializers.
97
+ * - `'argb_hex'` (default) — `Color(0xAARRGGBB)` hex literal
98
+ * - `'argb_float'` — `Color(r, g, b, a)` float components
99
+ *
100
+ * Legacy aliases: `'argb8'` maps to `'argb_hex'`, `'argb_floats'` maps to `'argb_float'`.
101
+ */
102
+ colorFormat?: 'argb_hex' | 'argb_float' | 'argb8' | 'argb_floats';
103
+ /**
104
+ * Color space for generated Color values.
105
+ * - `'sRGB'` (default) — standard sRGB color space
106
+ * - `'displayP3'` — Display P3 wide gamut via `ColorSpaces.DisplayP3`
107
+ */
108
+ colorSpace?: 'sRGB' | 'displayP3';
109
+ /**
110
+ * Structure mode for token organization.
111
+ * - `'nested'` (default) — mirror token path hierarchy as nested objects
112
+ * - `'flat'` — group tokens by $type into semantic sub-objects (Colors, Spacing, etc.)
113
+ */
114
+ structure?: 'nested' | 'flat';
115
+ /**
116
+ * Kotlin visibility modifier for the generated object and its members.
117
+ * - `undefined` (default) — no explicit modifier, which means `public` in Kotlin
118
+ * - `'public'` — explicit `public object` / `public val`
119
+ * - `'internal'` — `internal object` / `internal val` (useful for KMP / multi-module)
120
+ */
121
+ visibility?: 'public' | 'internal';
122
+ /** Number of spaces per indentation level (default 4) */
123
+ indent?: number;
124
+ };
125
+
126
+ export type { AndroidRendererOptions as A, IosRendererOptions as I, TailwindRendererOptions as T };
@@ -0,0 +1,126 @@
1
+ import { S as SelectorFunction, M as MediaQueryFunction } from './index-Dajm5rvM.js';
2
+
3
+ /**
4
+ * @license MIT
5
+ * Copyright (c) 2025-present Dispersa Contributors
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ /**
12
+ * Options for Tailwind CSS v4 renderer
13
+ *
14
+ * Controls how tokens are converted to Tailwind v4 @theme CSS variables.
15
+ *
16
+ * @example Bundle with dark mode overrides
17
+ * ```typescript
18
+ * tailwind({
19
+ * name: 'tailwind',
20
+ * file: 'theme.css',
21
+ * preset: 'bundle',
22
+ * selector: (modifier, context, isBase) => {
23
+ * if (isBase) return ':root'
24
+ * return `[data-${modifier}="${context}"]`
25
+ * },
26
+ * })
27
+ * ```
28
+ */
29
+ type TailwindRendererOptions = {
30
+ preset?: 'bundle' | 'standalone';
31
+ includeImport?: boolean;
32
+ namespace?: string;
33
+ minify?: boolean;
34
+ selector?: string | SelectorFunction;
35
+ mediaQuery?: string | MediaQueryFunction;
36
+ };
37
+
38
+ /**
39
+ * @license MIT
40
+ * Copyright (c) 2025-present Dispersa Contributors
41
+ *
42
+ * This source code is licensed under the MIT license found in the
43
+ * LICENSE file in the root directory of this source tree.
44
+ */
45
+
46
+ /**
47
+ * Options for iOS/SwiftUI renderer
48
+ */
49
+ type IosRendererOptions = {
50
+ preset?: 'standalone';
51
+ accessLevel?: 'public' | 'internal';
52
+ /**
53
+ * Output structure:
54
+ * - `'enum'` — nested enums inside a single root enum
55
+ * - `'grouped'` — namespace enum with separate extensions per token group
56
+ */
57
+ structure?: 'enum' | 'grouped';
58
+ enumName?: string;
59
+ /** Namespace enum name used in grouped mode (default: 'DesignTokens') */
60
+ extensionNamespace?: string;
61
+ colorSpace?: 'sRGB' | 'displayP3';
62
+ /**
63
+ * Target Swift language version.
64
+ * - `'5.9'` (default) — standard static let declarations
65
+ * - `'6.0'` — adds `nonisolated(unsafe)` to static properties for
66
+ * Swift 6 strict concurrency compliance
67
+ */
68
+ swiftVersion?: '5.9' | '6.0';
69
+ /** Number of spaces per indentation level (default 4) */
70
+ indent?: number;
71
+ /** Add @frozen annotation to enums and structs for ABI stability (default false) */
72
+ frozen?: boolean;
73
+ };
74
+
75
+ /**
76
+ * @license MIT
77
+ * Copyright (c) 2025-present Dispersa Contributors
78
+ *
79
+ * This source code is licensed under the MIT license found in the
80
+ * LICENSE file in the root directory of this source tree.
81
+ */
82
+
83
+ /**
84
+ * Options for Android/Jetpack Compose renderer
85
+ *
86
+ * Note: `packageName` is marked optional for type compatibility with the Renderer
87
+ * generic, but is validated as required at runtime in the renderer's format() method.
88
+ *
89
+ * @experimental This type is experimental. Properties and behavior may change.
90
+ */
91
+ type AndroidRendererOptions = {
92
+ preset?: 'standalone' | 'bundle';
93
+ packageName?: string;
94
+ objectName?: string;
95
+ /**
96
+ * Color output format for Kotlin Color initializers.
97
+ * - `'argb_hex'` (default) — `Color(0xAARRGGBB)` hex literal
98
+ * - `'argb_float'` — `Color(r, g, b, a)` float components
99
+ *
100
+ * Legacy aliases: `'argb8'` maps to `'argb_hex'`, `'argb_floats'` maps to `'argb_float'`.
101
+ */
102
+ colorFormat?: 'argb_hex' | 'argb_float' | 'argb8' | 'argb_floats';
103
+ /**
104
+ * Color space for generated Color values.
105
+ * - `'sRGB'` (default) — standard sRGB color space
106
+ * - `'displayP3'` — Display P3 wide gamut via `ColorSpaces.DisplayP3`
107
+ */
108
+ colorSpace?: 'sRGB' | 'displayP3';
109
+ /**
110
+ * Structure mode for token organization.
111
+ * - `'nested'` (default) — mirror token path hierarchy as nested objects
112
+ * - `'flat'` — group tokens by $type into semantic sub-objects (Colors, Spacing, etc.)
113
+ */
114
+ structure?: 'nested' | 'flat';
115
+ /**
116
+ * Kotlin visibility modifier for the generated object and its members.
117
+ * - `undefined` (default) — no explicit modifier, which means `public` in Kotlin
118
+ * - `'public'` — explicit `public object` / `public val`
119
+ * - `'internal'` — `internal object` / `internal val` (useful for KMP / multi-module)
120
+ */
121
+ visibility?: 'public' | 'internal';
122
+ /** Number of spaces per indentation level (default 4) */
123
+ indent?: number;
124
+ };
125
+
126
+ export type { AndroidRendererOptions as A, IosRendererOptions as I, TailwindRendererOptions as T };