@troychaplin/component2block 0.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 (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +160 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +89 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config.d.ts +38 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +256 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/generators/content-scss.d.ts +3 -0
  12. package/dist/generators/content-scss.d.ts.map +1 -0
  13. package/dist/generators/content-scss.js +207 -0
  14. package/dist/generators/content-scss.js.map +1 -0
  15. package/dist/generators/fluid.d.ts +7 -0
  16. package/dist/generators/fluid.d.ts.map +1 -0
  17. package/dist/generators/fluid.js +31 -0
  18. package/dist/generators/fluid.js.map +1 -0
  19. package/dist/generators/fonts-css.d.ts +3 -0
  20. package/dist/generators/fonts-css.d.ts.map +1 -0
  21. package/dist/generators/fonts-css.js +33 -0
  22. package/dist/generators/fonts-css.js.map +1 -0
  23. package/dist/generators/integrate-php.d.ts +2 -0
  24. package/dist/generators/integrate-php.d.ts.map +1 -0
  25. package/dist/generators/integrate-php.js +9 -0
  26. package/dist/generators/integrate-php.js.map +1 -0
  27. package/dist/generators/theme-json.d.ts +3 -0
  28. package/dist/generators/theme-json.d.ts.map +1 -0
  29. package/dist/generators/theme-json.js +245 -0
  30. package/dist/generators/theme-json.js.map +1 -0
  31. package/dist/generators/tokens-css.d.ts +3 -0
  32. package/dist/generators/tokens-css.d.ts.map +1 -0
  33. package/dist/generators/tokens-css.js +32 -0
  34. package/dist/generators/tokens-css.js.map +1 -0
  35. package/dist/generators/tokens-wp-css.d.ts +3 -0
  36. package/dist/generators/tokens-wp-css.d.ts.map +1 -0
  37. package/dist/generators/tokens-wp-css.js +37 -0
  38. package/dist/generators/tokens-wp-css.js.map +1 -0
  39. package/dist/index.d.ts +16 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +50 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/preset.d.ts +13 -0
  44. package/dist/preset.d.ts.map +1 -0
  45. package/dist/preset.js +31 -0
  46. package/dist/preset.js.map +1 -0
  47. package/dist/types.d.ts +166 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +123 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +58 -0
  52. package/templates/integrate.php.tpl +133 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Troy Chaplin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ <img src="docs/images/banner.png" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;">
2
+
3
+ # component2block
4
+
5
+ A design token generator for Storybook component libraries that target WordPress block themes. Define your tokens once in a single JSON config, and component2block generates everything both platforms need — CSS variables, `@font-face` declarations, base typography, WordPress `theme.json`, and PHP integration hooks.
6
+
7
+ ## The Problem
8
+
9
+ Building a component library that works in both Storybook/React and WordPress means maintaining design tokens in multiple formats. Colors, spacing, fonts, and typography settings need to exist as CSS custom properties for your components, as `theme.json` presets for the WordPress Site Editor, and as PHP hooks to wire it all together. Keeping these in sync manually is tedious and error-prone.
10
+
11
+ ## How It Works
12
+
13
+ You write one config file. The generator produces everything.
14
+
15
+ ```
16
+ c2b.config.json single source of truth
17
+
18
+ │ npx c2b generate
19
+
20
+ ├──► src/styles/tokens.css CSS custom properties
21
+ ├──► src/styles/fonts.css @font-face declarations
22
+ ├──► src/styles/_content-generated.scss Base typography (zero-specificity)
23
+
24
+ ├──► dist/wp/theme.json WordPress settings + styles
25
+ ├──► dist/wp/tokens.wp.css CSS vars mapped to --wp--preset--*
26
+ ├──► dist/wp/tokens.css CSS vars with hardcoded values
27
+ └──► dist/wp/integrate.php PHP hooks for the theme.json cascade
28
+ ```
29
+
30
+ Your components always reference `--prefix--*` CSS variables. In Storybook, those resolve to hardcoded values. In WordPress, they can optionally map to `--wp--preset--*` variables so themes can override them via the Site Editor.
31
+
32
+ ## Key Concepts
33
+
34
+ - **Single source of truth** — One config drives all outputs. Change a color once, it updates everywhere.
35
+ - **12 token categories** — Colors, gradients, spacing, font families, font sizes, shadows, layout, font weights, line heights, border radii, transitions, and z-index.
36
+ - **Locked vs themeable** — By default, tokens are hardcoded (locked). Set `output.wpThemeable: true` to let WordPress themes override them.
37
+ - **Zero-specificity base styles** — Generated SCSS uses `:where()` selectors so component BEM classes always win over base typography.
38
+ - **Storybook preset** — Auto-injects all generated styles into Storybook. No manual imports.
39
+ - **WordPress default layer** — The generated `theme.json` injects at the lowest priority layer, so any theme can override it.
40
+
41
+ ## Quick Example
42
+
43
+ ```json
44
+ {
45
+ "prefix": "mylib",
46
+ "tokens": {
47
+ "color": {
48
+ "primary": "#0073aa",
49
+ "primary-hover": { "value": "#005a87", "cssOnly": true }
50
+ },
51
+ "fontSize": {
52
+ "small": { "min": "0.875rem", "max": "1rem" }
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ ```bash
59
+ npx c2b generate
60
+ ```
61
+
62
+ Then in your components:
63
+
64
+ ```scss
65
+ .mylib-card {
66
+ color: var(--mylib--color-primary);
67
+ font-size: var(--mylib--font-size-small);
68
+ }
69
+ ```
70
+
71
+ ## CLI
72
+
73
+ ```
74
+ npx c2b generate [options]
75
+
76
+ Options:
77
+ --config <path> Path to config file (default: ./c2b.config.json)
78
+ --dry-run Output to stdout instead of writing files
79
+ ```
80
+
81
+ ## Programmatic API
82
+
83
+ ```ts
84
+ import { generate } from 'component2block';
85
+
86
+ const result = generate('./c2b.config.json');
87
+ // result.files: Array<{ path: string; size: number }>
88
+ ```
89
+
90
+ Individual generators are also exported:
91
+
92
+ ```ts
93
+ import {
94
+ loadConfig,
95
+ generateTokensCss,
96
+ generateTokensWpCss,
97
+ generateThemeJson,
98
+ generateFontsCss,
99
+ generateContentScss,
100
+ generateIntegratePhp,
101
+ } from 'component2block';
102
+ ```
103
+
104
+ ## Documentation
105
+
106
+ [Getting Started](./docs/README.md) — Install, configure, and generate
107
+
108
+ ### Configuration Reference
109
+
110
+ | Guide | Description |
111
+ |-------|-------------|
112
+ | [Overview](./docs/config/README.md) | Global fields, token categories, generated files, and full example |
113
+ | [Colors & Gradients](./docs/config/colors.md) | Color palette, gradients, cssOnly tokens, and locked vs themeable mode |
114
+ | [Spacing](./docs/config/spacing.md) | Spacing scale, WordPress slug conventions, and responsive values |
115
+ | [Shadows](./docs/config/shadow.md) | Box shadows, preset vs custom behavior, and Site Editor integration |
116
+ | [Fonts](./docs/config/fonts.md) | Static fonts, variable fonts, Google Fonts, and file placement |
117
+ | [Base Styles](./docs/config/base-styles.md) | Elements, typography, colors, spacing, and `:where()` selectors |
118
+
119
+ ### Guides
120
+
121
+ | Guide | Description |
122
+ |-------|-------------|
123
+ | [Tokens](./docs/guides/tokens.md) | Token syntax, categories, fluid fonts, CSS output |
124
+ | [Markup Patterns](./docs/guides/markup.md) | Layout classes for Storybook and WordPress |
125
+ | [Storybook Preset](./docs/guides/storybook-preset.md) | Auto-injecting generated styles into Storybook |
126
+ | [CLI & Build](./docs/guides/cli-and-build.md) | CLI commands, build scripts, and publishing setup |
127
+
128
+ ### WordPress
129
+
130
+ | Guide | Description |
131
+ |-------|-------------|
132
+ | [Integration](./docs/wordpress/integration.md) | Adding compiled assets to a WordPress block theme |
133
+ | [Theming](./docs/wordpress/theming.md) | Locked vs themeable mode, overrides, style variations |
134
+ | [Blocks](./docs/wordpress/blocks.md) | Block plugin setup and component registration |
135
+ | [Editor Styles](./docs/wordpress/editor-styles.md) | Loading styles inside the block editor iframe |
136
+ | [theme.json Reference](./docs/wordpress/theme-json-reference.md) | Full settings and styles structure |
137
+
138
+ ### Advanced
139
+
140
+ | Guide | Description |
141
+ |-------|-------------|
142
+ | [Architecture](./docs/advanced/architecture.md) | Design decisions, project structure, category registry |
143
+ | [Token Flow](./docs/advanced/token-flow.md) | How tokens resolve differently per output |
144
+
145
+ ## Development
146
+
147
+ ```bash
148
+ npm install
149
+ npm run build # Compile TypeScript
150
+ npm test # Run 191 tests
151
+ ```
152
+
153
+ ## Screenshots
154
+
155
+ | Before | After |
156
+ |-------|-------------|
157
+ | <img src="docs/images/before-01-styles.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> | <img src="docs/images/after-01-styles.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> |
158
+ | <img src="docs/images/before-02-typography.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> | <img src="docs/images/after-02-typography.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> |
159
+ | <img src="docs/images/before-03-colors.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> | <img src="docs/images/after-03-colors.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> |
160
+ | <img src="docs/images/before-04-template.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> | <img src="docs/images/after-04-template.jpg" alt="Block Finder Plugin Banner" style="width: 100%; height: auto;"> |
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ import { generate } from './index.js';
3
+ const args = process.argv.slice(2);
4
+ const command = args[0];
5
+ if (!command || command === 'help' || command === '--help') {
6
+ printUsage();
7
+ process.exit(0);
8
+ }
9
+ if (command !== 'generate') {
10
+ console.error(`Unknown command: ${command}`);
11
+ printUsage();
12
+ process.exit(1);
13
+ }
14
+ // Parse flags
15
+ let configPath;
16
+ let dryRun = false;
17
+ for (let i = 1; i < args.length; i++) {
18
+ if (args[i] === '--config' && args[i + 1]) {
19
+ configPath = args[++i];
20
+ }
21
+ else if (args[i] === '--dry-run') {
22
+ dryRun = true;
23
+ }
24
+ }
25
+ try {
26
+ if (dryRun) {
27
+ const { loadConfig } = await import('./config.js');
28
+ const { generateTokensCss } = await import('./generators/tokens-css.js');
29
+ const { generateTokensWpCss } = await import('./generators/tokens-wp-css.js');
30
+ const { generateThemeJson } = await import('./generators/theme-json.js');
31
+ const { generateIntegratePhp } = await import('./generators/integrate-php.js');
32
+ const { generateFontsCss } = await import('./generators/fonts-css.js');
33
+ const { generateContentScss } = await import('./generators/content-scss.js');
34
+ const config = loadConfig(configPath);
35
+ console.log('=== tokens.css ===');
36
+ console.log(generateTokensCss(config));
37
+ const fontsCss = generateFontsCss(config);
38
+ if (fontsCss) {
39
+ console.log('=== fonts.css ===');
40
+ console.log(fontsCss);
41
+ }
42
+ const contentScss = generateContentScss(config);
43
+ if (contentScss) {
44
+ console.log('=== _content-generated.scss ===');
45
+ console.log(contentScss);
46
+ }
47
+ if (config.wpThemeable) {
48
+ console.log('=== tokens.wp.css ===');
49
+ console.log(generateTokensWpCss(config));
50
+ }
51
+ console.log('=== theme.json ===');
52
+ console.log(generateThemeJson(config));
53
+ console.log('=== integrate.php ===');
54
+ console.log(generateIntegratePhp());
55
+ }
56
+ else {
57
+ const result = generate(configPath);
58
+ console.log('c2b: generated files:');
59
+ for (const file of result.files) {
60
+ console.log(` ${file.path} (${file.size} bytes)`);
61
+ }
62
+ }
63
+ }
64
+ catch (error) {
65
+ if (error instanceof Error) {
66
+ console.error(`c2b: ${error.message}`);
67
+ }
68
+ else {
69
+ console.error('c2b: An unexpected error occurred.');
70
+ }
71
+ process.exit(1);
72
+ }
73
+ function printUsage() {
74
+ console.log(`
75
+ c2b — Generate WordPress assets from design token config
76
+
77
+ Usage:
78
+ c2b generate [options]
79
+
80
+ Options:
81
+ --config <path> Path to config file (default: ./c2b.config.json)
82
+ --dry-run Output to stdout instead of writing files
83
+
84
+ Commands:
85
+ generate Read config and generate all output files
86
+ help Show this help message
87
+ `.trim());
88
+ }
89
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { C2bConfig, C2bConfigInput, TokenCategory, BaseStyleElementDef } from './types.js';
2
+ export declare function loadConfig(configPath?: string): C2bConfig;
3
+ export declare function validateConfig(input: C2bConfigInput): C2bConfig;
4
+ export interface ResolvedTokenRef {
5
+ category: TokenCategory;
6
+ key: string;
7
+ slug?: string;
8
+ cssSegment: string;
9
+ wpPreset?: string;
10
+ }
11
+ /**
12
+ * Check if a value matches a token key in any category.
13
+ * Returns resolution info if found, null if it's a raw value.
14
+ *
15
+ * When `preferCategory` is provided, that category is checked first.
16
+ * This resolves ambiguity when the same key exists in multiple categories
17
+ * (e.g. "large" in both fontSize and spacing).
18
+ */
19
+ export declare function resolveTokenRef(value: string, tokens: C2bConfig['tokens'], preferCategory?: TokenCategory): ResolvedTokenRef | null;
20
+ /**
21
+ * Resolve a baseStyles value to a CSS var() reference for SCSS output.
22
+ * Token keys become var(--{prefix}--{cssSegment}-{key}).
23
+ * Raw values pass through unchanged.
24
+ */
25
+ export declare function resolveForScss(value: string, prefix: string, tokens: C2bConfig['tokens'], preferCategory?: TokenCategory): string;
26
+ /**
27
+ * Resolve a baseStyles value to a CSS var() reference for theme.json output.
28
+ * Token keys become var(--wp--preset--{wpCategory}--{slug}).
29
+ * Uses slug when available (e.g. spacing slug "60"), falls back to key.
30
+ * Raw values pass through unchanged.
31
+ */
32
+ export declare function resolveForThemeJson(value: string, tokens: C2bConfig['tokens'], preferCategory?: TokenCategory): string;
33
+ /**
34
+ * For individual heading elements, ensure fontStyle is present.
35
+ * If the config doesn't specify fontStyle, default to "normal".
36
+ */
37
+ export declare function ensureFontStyle(def: BaseStyleElementDef): BaseStyleElementDef;
38
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAA4D,mBAAmB,EAAc,MAAM,YAAY,CAAC;AAWtK,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAkBzD;AAiJD,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,SAAS,CA0B/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,aAAa,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC3B,cAAc,CAAC,EAAE,aAAa,GAC7B,gBAAgB,GAAG,IAAI,CA8BzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC3B,cAAc,CAAC,EAAE,aAAa,GAC7B,MAAM,CAMR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,EAC3B,cAAc,CAAC,EAAE,aAAa,GAC7B,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,mBAAmB,GAAG,mBAAmB,CAG7E"}
package/dist/config.js ADDED
@@ -0,0 +1,256 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { CATEGORY_REGISTRY, INPUT_CATEGORY_MAP, VALID_CATEGORIES, kebabToTitle } from './types.js';
4
+ const DEFAULTS = {
5
+ tokensPath: 'src/styles/tokens.css',
6
+ wpDir: 'dist/wp',
7
+ };
8
+ /** Reserved config keys that are not token categories (legacy flat format) */
9
+ const CONFIG_KEYS = ['prefix', 'tokensPath', 'outDir', 'wpThemeable', 'output', 'tokens', 'baseStyles'];
10
+ export function loadConfig(configPath) {
11
+ const resolvedPath = resolve(configPath ?? 'c2b.config.json');
12
+ let raw;
13
+ try {
14
+ raw = readFileSync(resolvedPath, 'utf-8');
15
+ }
16
+ catch {
17
+ throw new Error(`Config file not found: ${resolvedPath}`);
18
+ }
19
+ let input;
20
+ try {
21
+ input = JSON.parse(raw);
22
+ }
23
+ catch {
24
+ throw new Error(`Invalid JSON in config file: ${resolvedPath}`);
25
+ }
26
+ return validateConfig(input);
27
+ }
28
+ /**
29
+ * Check if an input looks like a fluid shorthand: { min: string, max: string }
30
+ * without a "value" key. Distinguishes from a full TokenEntry object.
31
+ */
32
+ function isFluidInput(input) {
33
+ if (typeof input !== 'object' || input === null)
34
+ return false;
35
+ const obj = input;
36
+ return (typeof obj.min === 'string' &&
37
+ typeof obj.max === 'string' &&
38
+ !('value' in obj));
39
+ }
40
+ /**
41
+ * Determine if string shorthand should register as a preset for this category.
42
+ * Preset-capable categories (those with wpPreset) register strings as presets.
43
+ * Custom-only and excluded categories keep strings as CSS-only.
44
+ */
45
+ function isPresetCategory(internalCategory) {
46
+ const def = CATEGORY_REGISTRY[internalCategory];
47
+ return !!def?.wpPreset;
48
+ }
49
+ /**
50
+ * Expand a token entry input (string, fluid shorthand, or object) into a full TokenEntry.
51
+ *
52
+ * String shorthand behavior depends on the category:
53
+ * - Preset categories (color, gradient, shadow, fontFamily, fontSize): registers as preset
54
+ * - Custom-only categories (fontWeight, radius): CSS-only
55
+ *
56
+ * Fluid shorthand { "min": "...", "max": "..." } expands to { value: max, fluid: { min, max } }.
57
+ */
58
+ function expandTokenEntry(key, input, isDirectMap, internalCategory) {
59
+ const isShorthand = typeof input === 'string';
60
+ let entry;
61
+ if (isShorthand) {
62
+ entry = { value: input };
63
+ }
64
+ else if (isFluidInput(input)) {
65
+ // Fluid shorthand: { min, max } → { value: max, fluid: { min, max } }
66
+ entry = { value: input.max, fluid: { min: input.min, max: input.max } };
67
+ }
68
+ else {
69
+ entry = { ...input };
70
+ }
71
+ // Direct-map categories (layout) don't use name/slug
72
+ if (isDirectMap) {
73
+ return entry;
74
+ }
75
+ // Auto-derive value from fluid.max when fluid is set but value is missing
76
+ if (!entry.value && entry.fluid?.max) {
77
+ entry.value = entry.fluid.max;
78
+ }
79
+ // Determine CSS-only status based on category and entry form
80
+ const presetCapable = internalCategory ? isPresetCategory(internalCategory) : false;
81
+ const isCssOnly = isShorthand
82
+ ? !presetCapable // String shorthand: preset for preset categories, CSS-only otherwise
83
+ : entry.cssOnly === true;
84
+ if (!isCssOnly) {
85
+ if (!entry.slug) {
86
+ entry.slug = key;
87
+ }
88
+ if (!entry.name) {
89
+ entry.name = kebabToTitle(key);
90
+ }
91
+ }
92
+ return entry;
93
+ }
94
+ /**
95
+ * Normalize a token group, expanding shorthand and auto-deriving slug/name.
96
+ */
97
+ function normalizeTokenGroup(group, isDirectMap, internalCategory) {
98
+ const normalized = {};
99
+ for (const [key, input] of Object.entries(group)) {
100
+ normalized[key] = expandTokenEntry(key, input, isDirectMap, internalCategory);
101
+ }
102
+ return normalized;
103
+ }
104
+ /**
105
+ * Extract token categories from the config input.
106
+ * Supports both new format (tokens wrapper) and legacy flat format.
107
+ * Maps user-facing category names to internal names (e.g. "color" → "colorPalette").
108
+ */
109
+ function extractTokens(input) {
110
+ const tokens = {};
111
+ const validInputCategories = [
112
+ ...Object.keys(INPUT_CATEGORY_MAP),
113
+ ...VALID_CATEGORIES,
114
+ ];
115
+ // Determine source: new tokens wrapper or legacy flat format
116
+ const source = input.tokens ?? input;
117
+ for (const [key, value] of Object.entries(source)) {
118
+ // Skip reserved config keys (only relevant for legacy flat format)
119
+ if (CONFIG_KEYS.includes(key))
120
+ continue;
121
+ // Skip undefined values
122
+ if (value === undefined)
123
+ continue;
124
+ // Must be an object (token group)
125
+ if (typeof value !== 'object') {
126
+ // In legacy flat format, non-object values like booleans are config keys
127
+ if (!input.tokens)
128
+ continue;
129
+ throw new Error(`Config error: "${key}" must be an object.`);
130
+ }
131
+ // Map user-facing name to internal category name
132
+ const internalCategory = INPUT_CATEGORY_MAP[key] ?? key;
133
+ // Validate category name
134
+ if (!VALID_CATEGORIES.includes(internalCategory)) {
135
+ throw new Error(`Config error: Unknown token category "${key}". Valid categories: ${validInputCategories.filter(c => VALID_CATEGORIES.includes((INPUT_CATEGORY_MAP[c] ?? c))).join(', ')}`);
136
+ }
137
+ const def = CATEGORY_REGISTRY[internalCategory];
138
+ tokens[internalCategory] = normalizeTokenGroup(value, def.directMap, internalCategory);
139
+ }
140
+ return tokens;
141
+ }
142
+ export function validateConfig(input) {
143
+ if (!input.prefix || typeof input.prefix !== 'string') {
144
+ throw new Error('Config error: "prefix" is required and must be a string.');
145
+ }
146
+ const tokens = extractTokens(input);
147
+ // Validate each category
148
+ for (const [category, group] of Object.entries(tokens)) {
149
+ validateTokenGroup(category, group);
150
+ }
151
+ // Resolve output settings: new output wrapper takes precedence over legacy root-level keys
152
+ const output = input.output ?? {};
153
+ const tokensPath = output.tokensPath ?? input.tokensPath ?? DEFAULTS.tokensPath;
154
+ const wpDir = output.wpDir ?? input.outDir ?? DEFAULTS.wpDir;
155
+ const wpThemeable = output.wpThemeable ?? input.wpThemeable ?? false;
156
+ return {
157
+ prefix: input.prefix,
158
+ tokensPath,
159
+ wpDir,
160
+ wpThemeable: wpThemeable === true,
161
+ tokens,
162
+ baseStyles: input.baseStyles,
163
+ };
164
+ }
165
+ /**
166
+ * Check if a value matches a token key in any category.
167
+ * Returns resolution info if found, null if it's a raw value.
168
+ *
169
+ * When `preferCategory` is provided, that category is checked first.
170
+ * This resolves ambiguity when the same key exists in multiple categories
171
+ * (e.g. "large" in both fontSize and spacing).
172
+ */
173
+ export function resolveTokenRef(value, tokens, preferCategory) {
174
+ // Check preferred category first to resolve ambiguous keys
175
+ if (preferCategory) {
176
+ const group = tokens[preferCategory];
177
+ if (group && value in group) {
178
+ const def = CATEGORY_REGISTRY[preferCategory];
179
+ return {
180
+ category: preferCategory,
181
+ key: value,
182
+ slug: group[value].slug,
183
+ cssSegment: def.cssSegment,
184
+ wpPreset: def.wpPreset,
185
+ };
186
+ }
187
+ }
188
+ for (const [category, group] of Object.entries(tokens)) {
189
+ if (!group)
190
+ continue;
191
+ if (value in group) {
192
+ const def = CATEGORY_REGISTRY[category];
193
+ return {
194
+ category: category,
195
+ key: value,
196
+ slug: group[value].slug,
197
+ cssSegment: def.cssSegment,
198
+ wpPreset: def.wpPreset,
199
+ };
200
+ }
201
+ }
202
+ return null;
203
+ }
204
+ /**
205
+ * Resolve a baseStyles value to a CSS var() reference for SCSS output.
206
+ * Token keys become var(--{prefix}--{cssSegment}-{key}).
207
+ * Raw values pass through unchanged.
208
+ */
209
+ export function resolveForScss(value, prefix, tokens, preferCategory) {
210
+ const ref = resolveTokenRef(value, tokens, preferCategory);
211
+ if (ref) {
212
+ return `var(--${prefix}--${ref.cssSegment}-${ref.key})`;
213
+ }
214
+ return value;
215
+ }
216
+ /**
217
+ * Resolve a baseStyles value to a CSS var() reference for theme.json output.
218
+ * Token keys become var(--wp--preset--{wpCategory}--{slug}).
219
+ * Uses slug when available (e.g. spacing slug "60"), falls back to key.
220
+ * Raw values pass through unchanged.
221
+ */
222
+ export function resolveForThemeJson(value, tokens, preferCategory) {
223
+ const ref = resolveTokenRef(value, tokens, preferCategory);
224
+ if (ref && ref.wpPreset) {
225
+ return `var(${ref.wpPreset}--${ref.slug ?? ref.key})`;
226
+ }
227
+ return value;
228
+ }
229
+ /**
230
+ * For individual heading elements, ensure fontStyle is present.
231
+ * If the config doesn't specify fontStyle, default to "normal".
232
+ */
233
+ export function ensureFontStyle(def) {
234
+ if (def.fontStyle !== undefined)
235
+ return def;
236
+ return { ...def, fontStyle: 'normal' };
237
+ }
238
+ function validateTokenGroup(category, group) {
239
+ for (const [key, entry] of Object.entries(group)) {
240
+ if (!entry.value && entry.value !== '0') {
241
+ throw new Error(`Config error: Token "${category}.${key}" is missing a "value".`);
242
+ }
243
+ if (typeof entry.value !== 'string') {
244
+ throw new Error(`Config error: Token "${category}.${key}.value" must be a string.`);
245
+ }
246
+ // Validate fontFace entries if present
247
+ if (entry.fontFace) {
248
+ for (const [i, face] of entry.fontFace.entries()) {
249
+ if (!face.weight || !face.style || !face.src) {
250
+ throw new Error(`Config error: Token "${category}.${key}.fontFace[${i}]" must have "weight", "style", and "src".`);
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { C2bConfig } from '../types.js';
2
+ export declare function generateContentScss(config: C2bConfig): string | null;
3
+ //# sourceMappingURL=content-scss.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-scss.d.ts","sourceRoot":"","sources":["../../src/generators/content-scss.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAoE,MAAM,aAAa,CAAC;AAU/G,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAsHpE"}