@refrakt-md/cli 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +277 -9
- package/dist/bin.js.map +1 -1
- package/dist/commands/contracts.d.ts +6 -0
- package/dist/commands/contracts.d.ts.map +1 -0
- package/dist/commands/contracts.js +41 -0
- package/dist/commands/contracts.js.map +1 -0
- package/dist/commands/inspect.d.ts +33 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +269 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/scaffold-css.d.ts +6 -0
- package/dist/commands/scaffold-css.d.ts.map +1 -0
- package/dist/commands/scaffold-css.js +113 -0
- package/dist/commands/scaffold-css.js.map +1 -0
- package/dist/commands/validate.d.ts +6 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +70 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/write.d.ts +7 -0
- package/dist/commands/write.d.ts.map +1 -1
- package/dist/commands/write.js +66 -10
- package/dist/commands/write.js.map +1 -1
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -2
- package/dist/config.js.map +1 -1
- package/dist/lib/css-audit.d.ts +23 -0
- package/dist/lib/css-audit.d.ts.map +1 -0
- package/dist/lib/css-audit.js +99 -0
- package/dist/lib/css-audit.js.map +1 -0
- package/dist/lib/css-resolve.d.ts +20 -0
- package/dist/lib/css-resolve.d.ts.map +1 -0
- package/dist/lib/css-resolve.js +57 -0
- package/dist/lib/css-resolve.js.map +1 -0
- package/dist/lib/fixtures.d.ts +10 -0
- package/dist/lib/fixtures.d.ts.map +1 -0
- package/dist/lib/fixtures.js +356 -0
- package/dist/lib/fixtures.js.map +1 -0
- package/dist/lib/format.d.ts +35 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +215 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/variants.d.ts +17 -0
- package/dist/lib/variants.d.ts.map +1 -0
- package/dist/lib/variants.js +32 -0
- package/dist/lib/variants.js.map +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { getFixture } from '../lib/fixtures.js';
|
|
2
|
+
import { discoverVariants } from '../lib/variants.js';
|
|
3
|
+
import { parseCssFile, auditSelectors, collectAllSelectors, } from '../lib/css-audit.js';
|
|
4
|
+
import { resolveCssDir, readCssForBlock, readAllCss } from '../lib/css-resolve.js';
|
|
5
|
+
import { formatConfig, formatSelectors, formatInput, formatHtml, formatRuneList, buildJsonOutput, formatAuditResult, formatAuditSummary, buildAuditJson, heading, } from '../lib/format.js';
|
|
6
|
+
export async function inspectCommand(options, deps) {
|
|
7
|
+
const { runes, baseConfig, } = deps;
|
|
8
|
+
// --list mode: show all available runes
|
|
9
|
+
if (options.list) {
|
|
10
|
+
return listRunes(runes, options.json);
|
|
11
|
+
}
|
|
12
|
+
// Resolve theme config
|
|
13
|
+
const config = await resolveTheme(options.theme, baseConfig);
|
|
14
|
+
// --all --audit: full-theme audit
|
|
15
|
+
if (options.all && options.audit) {
|
|
16
|
+
return runFullAudit(config, runes, options, deps);
|
|
17
|
+
}
|
|
18
|
+
// --all without --audit: not supported yet
|
|
19
|
+
if (options.all) {
|
|
20
|
+
throw new Error('--all currently requires --audit. Use --list to see available runes.');
|
|
21
|
+
}
|
|
22
|
+
if (!options.runeName) {
|
|
23
|
+
throw new Error('Missing rune name. Use --list to see available runes.\n\nUsage: refrakt inspect <rune> [options]');
|
|
24
|
+
}
|
|
25
|
+
// Resolve the rune by name or alias
|
|
26
|
+
const rune = findRune(options.runeName, runes);
|
|
27
|
+
if (!rune) {
|
|
28
|
+
const available = Object.values(runes)
|
|
29
|
+
.map(r => ` ${r.name}${r.aliases.length > 0 ? ` (${r.aliases.join(', ')})` : ''}`)
|
|
30
|
+
.join('\n');
|
|
31
|
+
throw new Error(`Unknown rune "${options.runeName}"\n\nAvailable runes:\n${available}`);
|
|
32
|
+
}
|
|
33
|
+
// --audit mode for a single rune
|
|
34
|
+
if (options.audit) {
|
|
35
|
+
return runSingleAudit(rune, config, options, deps);
|
|
36
|
+
}
|
|
37
|
+
// Check for variant expansion (e.g., --type=all)
|
|
38
|
+
const schemaVariants = discoverVariants(rune.schema);
|
|
39
|
+
const expandAttr = findExpandAttr(options.flags, schemaVariants);
|
|
40
|
+
if (expandAttr) {
|
|
41
|
+
// Expand all variants for this attribute
|
|
42
|
+
const values = schemaVariants[expandAttr];
|
|
43
|
+
if (options.json) {
|
|
44
|
+
const results = [];
|
|
45
|
+
for (const value of values) {
|
|
46
|
+
const overrides = { ...options.flags, [expandAttr]: value };
|
|
47
|
+
results.push(inspectSingle(rune, config, overrides, deps));
|
|
48
|
+
}
|
|
49
|
+
console.log(JSON.stringify(results, null, 2));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
for (const value of values) {
|
|
53
|
+
console.log(heading(`Variant: ${expandAttr}=${value}`));
|
|
54
|
+
const overrides = { ...options.flags, [expandAttr]: value };
|
|
55
|
+
outputFormatted(rune, config, overrides, deps);
|
|
56
|
+
console.log('');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// Single variant
|
|
62
|
+
if (options.json) {
|
|
63
|
+
const result = inspectSingle(rune, config, options.flags, deps);
|
|
64
|
+
console.log(JSON.stringify(result, null, 2));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
outputFormatted(rune, config, options.flags, deps);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Run audit for a single rune */
|
|
72
|
+
function runSingleAudit(rune, config, options, deps) {
|
|
73
|
+
const cssDir = resolveCssDir(options.cssDir);
|
|
74
|
+
if (!cssDir) {
|
|
75
|
+
throw new Error('No CSS directory found. Use --css <dir> to specify the path to rune CSS files.');
|
|
76
|
+
}
|
|
77
|
+
const runeTypeof = rune.type?.name;
|
|
78
|
+
const runeConfig = runeTypeof ? config.runes[runeTypeof] : undefined;
|
|
79
|
+
if (!runeConfig) {
|
|
80
|
+
throw new Error(`No engine config found for rune "${rune.name}". It may be a component-only rune without identity transform config.`);
|
|
81
|
+
}
|
|
82
|
+
// Read CSS for this block
|
|
83
|
+
const cssFile = readCssForBlock(cssDir, runeConfig.block);
|
|
84
|
+
const cssMatches = cssFile
|
|
85
|
+
? parseCssFile(cssFile.content, cssFile.path)
|
|
86
|
+
: [];
|
|
87
|
+
// Collect all possible selectors across variants
|
|
88
|
+
const schemaVariants = discoverVariants(rune.schema);
|
|
89
|
+
const allSelectors = collectAllSelectors(rune.name, runeConfig.block, config.prefix, schemaVariants, runeConfig.contextModifiers, runeConfig.staticModifiers, (flags) => {
|
|
90
|
+
const { tree } = runPipeline(rune, config, flags, deps);
|
|
91
|
+
return deps.extractSelectors(tree, config.prefix);
|
|
92
|
+
});
|
|
93
|
+
const result = auditSelectors(rune.name, allSelectors, cssMatches);
|
|
94
|
+
if (options.json) {
|
|
95
|
+
console.log(JSON.stringify(buildAuditJson([result], options.theme), null, 2));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(formatAuditResult(result, options.theme));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Run audit for all runes in the theme */
|
|
102
|
+
function runFullAudit(config, runes, options, deps) {
|
|
103
|
+
const cssDir = resolveCssDir(options.cssDir);
|
|
104
|
+
if (!cssDir) {
|
|
105
|
+
throw new Error('No CSS directory found. Use --css <dir> to specify the path to rune CSS files.');
|
|
106
|
+
}
|
|
107
|
+
// Parse all CSS files upfront
|
|
108
|
+
const cssFiles = readAllCss(cssDir);
|
|
109
|
+
const allCssMatches = [];
|
|
110
|
+
for (const file of cssFiles) {
|
|
111
|
+
allCssMatches.push(...parseCssFile(file.content, file.path));
|
|
112
|
+
}
|
|
113
|
+
const results = [];
|
|
114
|
+
// Iterate over all runes that have engine config
|
|
115
|
+
for (const rune of Object.values(runes)) {
|
|
116
|
+
const runeTypeof = rune.type?.name;
|
|
117
|
+
const runeConfig = runeTypeof ? config.runes[runeTypeof] : undefined;
|
|
118
|
+
if (!runeConfig)
|
|
119
|
+
continue; // Skip runes without identity transform config
|
|
120
|
+
const schemaVariants = discoverVariants(rune.schema);
|
|
121
|
+
let allSelectors;
|
|
122
|
+
try {
|
|
123
|
+
allSelectors = collectAllSelectors(rune.name, runeConfig.block, config.prefix, schemaVariants, runeConfig.contextModifiers, runeConfig.staticModifiers, (flags) => {
|
|
124
|
+
const { tree } = runPipeline(rune, config, flags, deps);
|
|
125
|
+
return deps.extractSelectors(tree, config.prefix);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Skip runes whose fixtures fail to transform
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
// Filter CSS matches to only those relevant to this rune's block
|
|
133
|
+
const blockPrefix = `.${config.prefix}-${runeConfig.block}`;
|
|
134
|
+
const relevantCss = allCssMatches.filter(m => m.selector.startsWith(blockPrefix) || m.selector.startsWith('[data-'));
|
|
135
|
+
results.push(auditSelectors(rune.name, allSelectors, relevantCss));
|
|
136
|
+
}
|
|
137
|
+
// Sort results: complete first, then partial, then not-started, alphabetically within each group
|
|
138
|
+
results.sort((a, b) => {
|
|
139
|
+
const order = { 'complete': 0, 'partial': 1, 'not-started': 2 };
|
|
140
|
+
const statusDiff = order[a.status] - order[b.status];
|
|
141
|
+
if (statusDiff !== 0)
|
|
142
|
+
return statusDiff;
|
|
143
|
+
return a.rune.localeCompare(b.rune);
|
|
144
|
+
});
|
|
145
|
+
if (options.json) {
|
|
146
|
+
console.log(JSON.stringify(buildAuditJson(results, options.theme), null, 2));
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
console.log(formatAuditSummary(results, options.theme));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** Run the full pipeline for a single rune variant and return structured data */
|
|
153
|
+
function inspectSingle(rune, config, flags, deps) {
|
|
154
|
+
const { tree, source } = runPipeline(rune, config, flags, deps);
|
|
155
|
+
const html = deps.renderToHtml(tree, { pretty: true });
|
|
156
|
+
const selectors = deps.extractSelectors(tree, config.prefix);
|
|
157
|
+
const runeTypeof = rune.type?.name;
|
|
158
|
+
const runeConfig = runeTypeof ? config.runes[runeTypeof] : undefined;
|
|
159
|
+
return buildJsonOutput({
|
|
160
|
+
rune: rune.name,
|
|
161
|
+
theme: 'base',
|
|
162
|
+
input: source,
|
|
163
|
+
config: runeConfig,
|
|
164
|
+
html,
|
|
165
|
+
selectors,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/** Run the full pipeline and output formatted text */
|
|
169
|
+
function outputFormatted(rune, config, flags, deps) {
|
|
170
|
+
const { tree, source } = runPipeline(rune, config, flags, deps);
|
|
171
|
+
const html = deps.renderToHtml(tree, { pretty: true });
|
|
172
|
+
const selectors = deps.extractSelectors(tree, config.prefix);
|
|
173
|
+
const runeTypeof = rune.type?.name;
|
|
174
|
+
console.log(heading('Input'));
|
|
175
|
+
console.log(formatInput(source));
|
|
176
|
+
if (runeTypeof) {
|
|
177
|
+
console.log(heading('Config Applied'));
|
|
178
|
+
console.log(formatConfig(runeTypeof, config));
|
|
179
|
+
}
|
|
180
|
+
console.log(heading('Output HTML'));
|
|
181
|
+
console.log(formatHtml(html));
|
|
182
|
+
console.log(heading('Selectors'));
|
|
183
|
+
console.log(formatSelectors(selectors));
|
|
184
|
+
}
|
|
185
|
+
/** Run the Markdoc parse → transform → serialize → identity transform pipeline */
|
|
186
|
+
function runPipeline(rune, config, flags, deps) {
|
|
187
|
+
const source = getFixture(rune.name, flags);
|
|
188
|
+
const ast = deps.Markdoc.parse(source);
|
|
189
|
+
const headings = deps.extractHeadings(ast);
|
|
190
|
+
const transformed = deps.Markdoc.transform(ast, {
|
|
191
|
+
tags: deps.tags,
|
|
192
|
+
nodes: deps.nodes,
|
|
193
|
+
variables: {
|
|
194
|
+
generatedIds: new Set(),
|
|
195
|
+
path: '/inspect.md',
|
|
196
|
+
headings,
|
|
197
|
+
__source: source,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
const serialized = deps.serializeTree(transformed);
|
|
201
|
+
const identityTransform = deps.createTransform(config);
|
|
202
|
+
const tree = identityTransform(serialized);
|
|
203
|
+
return { tree, source };
|
|
204
|
+
}
|
|
205
|
+
/** List all available runes */
|
|
206
|
+
function listRunes(runes, json) {
|
|
207
|
+
const list = Object.values(runes).map(rune => ({
|
|
208
|
+
name: rune.name,
|
|
209
|
+
aliases: rune.aliases,
|
|
210
|
+
description: rune.description,
|
|
211
|
+
variants: discoverVariants(rune.schema),
|
|
212
|
+
}));
|
|
213
|
+
if (json) {
|
|
214
|
+
console.log(JSON.stringify(list, null, 2));
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.log(heading('Available Runes'));
|
|
218
|
+
console.log('');
|
|
219
|
+
console.log(formatRuneList(list));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/** Find a rune by name or alias */
|
|
223
|
+
function findRune(name, runes) {
|
|
224
|
+
// Direct match on rune key
|
|
225
|
+
if (runes[name])
|
|
226
|
+
return runes[name];
|
|
227
|
+
// Search by name or alias
|
|
228
|
+
for (const rune of Object.values(runes)) {
|
|
229
|
+
if (rune.name === name || rune.aliases.includes(name)) {
|
|
230
|
+
return rune;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return undefined;
|
|
234
|
+
}
|
|
235
|
+
/** Check if any flag has value "all" and corresponds to a known variant */
|
|
236
|
+
function findExpandAttr(flags, variants) {
|
|
237
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
238
|
+
if (value === 'all' && variants[key]) {
|
|
239
|
+
return key;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
/** Resolve a theme name to a ThemeConfig */
|
|
245
|
+
async function resolveTheme(theme, baseConfig) {
|
|
246
|
+
if (theme === 'base')
|
|
247
|
+
return baseConfig;
|
|
248
|
+
// Try dynamic import — works for package names (e.g., '@refrakt-md/lumina')
|
|
249
|
+
// and file paths (e.g., './src/config.ts')
|
|
250
|
+
const importPath = theme.startsWith('.') || theme.startsWith('/')
|
|
251
|
+
? (await import('node:path')).resolve(theme)
|
|
252
|
+
: theme + '/transform';
|
|
253
|
+
try {
|
|
254
|
+
const mod = await import(importPath);
|
|
255
|
+
// Look for common export names
|
|
256
|
+
const config = mod.themeConfig ?? mod.config ?? mod.default;
|
|
257
|
+
if (config && typeof config === 'object' && config.runes && config.prefix) {
|
|
258
|
+
return config;
|
|
259
|
+
}
|
|
260
|
+
console.error(`Warning: "${importPath}" does not export a valid ThemeConfig, using base config.\n`);
|
|
261
|
+
return baseConfig;
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
console.error(`Warning: Could not load theme "${theme}" (${importPath}): ${err.message}\n`);
|
|
265
|
+
console.error(`Falling back to base config.\n`);
|
|
266
|
+
return baseConfig;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/commands/inspect.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACN,YAAY,EACZ,cAAc,EACd,mBAAmB,GAGnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACN,YAAY,EACZ,eAAe,EACf,WAAW,EACX,UAAU,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,OAAO,GACP,MAAM,kBAAkB,CAAC;AA4B1B,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,OAAuB,EACvB,IAAiB;IAEjB,MAAM,EACL,KAAK,EACL,UAAU,GACV,GAAG,IAAI,CAAC;IAET,wCAAwC;IACxC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,uBAAuB;IACvB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;IAE7D,kCAAkC;IAClC,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,2CAA2C;IAC3C,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;IACrH,CAAC;IAED,oCAAoC;IACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;aACpC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;aAClF,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,OAAO,CAAC,QAAQ,0BAA0B,SAAS,EAAE,CAAC,CAAC;IACzF,CAAC;IAED,iCAAiC;IACjC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,iDAAiD;IACjD,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAEjE,IAAI,UAAU,EAAE,CAAC;QAChB,yCAAyC;QACzC,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,EAAE,CAAC;YACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC;gBAC5D,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,UAAU,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;gBACxD,MAAM,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC;gBAC5D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACF,CAAC;IACF,CAAC;SAAM,CAAC;QACP,iBAAiB;QACjB,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACP,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;IACF,CAAC;AACF,CAAC;AAED,kCAAkC;AAClC,SAAS,cAAc,CACtB,IAAU,EACV,MAAmB,EACnB,OAAuB,EACvB,IAAiB;IAEjB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACnG,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;IACnC,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,IAAI,uEAAuE,CAAC,CAAC;IACvI,CAAC;IAED,0BAA0B;IAC1B,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAuB,OAAO;QAC7C,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;QAC7C,CAAC,CAAC,EAAE,CAAC;IAEN,iDAAiD;IACjD,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,mBAAmB,CACvC,IAAI,CAAC,IAAI,EACT,UAAU,CAAC,KAAK,EAChB,MAAM,CAAC,MAAM,EACb,cAAc,EACd,UAAU,CAAC,gBAAgB,EAC3B,UAAU,CAAC,eAAe,EAC1B,CAAC,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC,CACD,CAAC;IAEF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;IAEnE,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,CAAC;AACF,CAAC;AAED,2CAA2C;AAC3C,SAAS,YAAY,CACpB,MAAmB,EACnB,KAA2B,EAC3B,OAAuB,EACvB,IAAiB;IAEjB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACnG,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,aAAa,GAAuB,EAAE,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC7B,aAAa,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,iDAAiD;IACjD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACnC,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrE,IAAI,CAAC,UAAU;YAAE,SAAS,CAAC,+CAA+C;QAE1E,MAAM,cAAc,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAErD,IAAI,YAAsB,CAAC;QAC3B,IAAI,CAAC;YACJ,YAAY,GAAG,mBAAmB,CACjC,IAAI,CAAC,IAAI,EACT,UAAU,CAAC,KAAK,EAChB,MAAM,CAAC,MAAM,EACb,cAAc,EACd,UAAU,CAAC,gBAAgB,EAC3B,UAAU,CAAC,eAAe,EAC1B,CAAC,KAAK,EAAE,EAAE;gBACT,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;gBACxD,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACnD,CAAC,CACD,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACR,8CAA8C;YAC9C,SAAS;QACV,CAAC;QAED,iEAAiE;QACjE,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC5C,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CACrE,CAAC;QAEF,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,iGAAiG;IACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;QAChE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,UAAU,CAAC;QACxC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,CAAC;AACF,CAAC;AAED,iFAAiF;AACjF,SAAS,aAAa,CACrB,IAAU,EACV,MAAmB,EACnB,KAA6B,EAC7B,IAAiB;IAEjB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;IACnC,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAErE,OAAO,eAAe,CAAC;QACtB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,MAAM;QACb,MAAM,EAAE,UAAU;QAClB,IAAI;QACJ,SAAS;KACT,CAAC,CAAC;AACJ,CAAC;AAED,sDAAsD;AACtD,SAAS,eAAe,CACvB,IAAU,EACV,MAAmB,EACnB,KAA6B,EAC7B,IAAiB;IAEjB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAEjC,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,kFAAkF;AAClF,SAAS,WAAW,CACnB,IAAU,EACV,MAAmB,EACnB,KAA6B,EAC7B,IAAiB;IAEjB,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAE3C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE;YACV,YAAY,EAAE,IAAI,GAAG,EAAU;YAC/B,IAAI,EAAE,aAAa;YACnB,QAAQ;YACR,QAAQ,EAAE,MAAM;SAChB;KACD,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAE3C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACzB,CAAC;AAED,+BAA+B;AAC/B,SAAS,SAAS,CAAC,KAA2B,EAAE,IAAa;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;KACvC,CAAC,CAAC,CAAC;IAEJ,IAAI,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,CAAC;AACF,CAAC;AAED,mCAAmC;AACnC,SAAS,QAAQ,CAAC,IAAY,EAAE,KAA2B;IAC1D,2BAA2B;IAC3B,IAAI,KAAK,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpC,0BAA0B;IAC1B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,2EAA2E;AAC3E,SAAS,cAAc,CAAC,KAA6B,EAAE,QAAkC;IACxF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,KAAK,KAAK,IAAI,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO,GAAG,CAAC;QACZ,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,4CAA4C;AAC5C,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,UAAuB;IACjE,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC;IAExC,4EAA4E;IAC5E,2CAA2C;IAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAChE,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QAC5C,CAAC,CAAC,KAAK,GAAG,YAAY,CAAC;IAExB,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,+BAA+B;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC;QAC5D,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC3E,OAAO,MAAqB,CAAC;QAC9B,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,aAAa,UAAU,6DAA6D,CAAC,CAAC;QACpG,OAAO,UAAU,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,kCAAkC,KAAK,MAAM,UAAU,MAAO,GAAa,CAAC,OAAO,IAAI,CAAC,CAAC;QACvG,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,OAAO,UAAU,CAAC;IACnB,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-css.d.ts","sourceRoot":"","sources":["../../src/commands/scaffold-css.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CACf;AAYD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAyDjE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { generateStructureContract } from '@refrakt-md/transform';
|
|
4
|
+
import { baseConfig } from '@refrakt-md/theme-base';
|
|
5
|
+
export function scaffoldCssCommand(opts) {
|
|
6
|
+
const contract = generateStructureContract(baseConfig);
|
|
7
|
+
const outputDir = resolve(opts.outputDir);
|
|
8
|
+
if (!existsSync(outputDir)) {
|
|
9
|
+
mkdirSync(outputDir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
// Group runes by block name (e.g., Tier and FeaturedTier both use 'tier')
|
|
12
|
+
const blockMap = new Map();
|
|
13
|
+
for (const [runeName, runeContract] of Object.entries(contract.runes)) {
|
|
14
|
+
const existing = blockMap.get(runeContract.block);
|
|
15
|
+
if (existing) {
|
|
16
|
+
existing.runeNames.push(runeName);
|
|
17
|
+
Object.assign(existing.modifiers, runeContract.modifiers ?? {});
|
|
18
|
+
Object.assign(existing.contextModifiers, runeContract.contextModifiers ?? {});
|
|
19
|
+
existing.staticModifiers.push(...(runeContract.staticModifiers ?? []));
|
|
20
|
+
Object.assign(existing.elements, runeContract.elements ?? {});
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
blockMap.set(runeContract.block, {
|
|
24
|
+
runeNames: [runeName],
|
|
25
|
+
block: runeContract.block,
|
|
26
|
+
modifiers: { ...(runeContract.modifiers ?? {}) },
|
|
27
|
+
contextModifiers: { ...(runeContract.contextModifiers ?? {}) },
|
|
28
|
+
staticModifiers: [...(runeContract.staticModifiers ?? [])],
|
|
29
|
+
elements: { ...(runeContract.elements ?? {}) },
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let created = 0;
|
|
34
|
+
let skipped = 0;
|
|
35
|
+
for (const [blockName, merged] of blockMap) {
|
|
36
|
+
const fileName = `${blockName}.css`;
|
|
37
|
+
const filePath = join(outputDir, fileName);
|
|
38
|
+
if (existsSync(filePath) && !opts.force) {
|
|
39
|
+
skipped++;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const css = generateBlockCss(merged, contract.prefix);
|
|
43
|
+
writeFileSync(filePath, css);
|
|
44
|
+
created++;
|
|
45
|
+
}
|
|
46
|
+
console.log(`Scaffold CSS: ${created} files created, ${skipped} skipped (already exist)`);
|
|
47
|
+
if (skipped > 0 && !opts.force) {
|
|
48
|
+
console.log('Use --force to overwrite existing files');
|
|
49
|
+
}
|
|
50
|
+
if (created > 0) {
|
|
51
|
+
console.log(`Output directory: ${outputDir}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function generateBlockCss(merged, prefix) {
|
|
55
|
+
const block = `${prefix}-${merged.block}`;
|
|
56
|
+
const label = merged.runeNames.join(', ');
|
|
57
|
+
const lines = [];
|
|
58
|
+
lines.push(`/* ${label} rune${merged.runeNames.length > 1 ? 's' : ''} */`);
|
|
59
|
+
lines.push('');
|
|
60
|
+
// Root block
|
|
61
|
+
lines.push(`.${block} {`);
|
|
62
|
+
lines.push('');
|
|
63
|
+
lines.push('}');
|
|
64
|
+
// Modifier selectors
|
|
65
|
+
if (Object.keys(merged.modifiers).length > 0) {
|
|
66
|
+
lines.push('');
|
|
67
|
+
lines.push(`/* Modifiers */`);
|
|
68
|
+
for (const [modName, mod] of Object.entries(merged.modifiers)) {
|
|
69
|
+
if (mod.default) {
|
|
70
|
+
lines.push(`.${block}--${mod.default} {`);
|
|
71
|
+
lines.push('');
|
|
72
|
+
lines.push('}');
|
|
73
|
+
}
|
|
74
|
+
lines.push(`/* ${modName}: ${mod.classPattern} [${mod.dataAttribute}] */`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Context modifier selectors
|
|
78
|
+
if (Object.keys(merged.contextModifiers).length > 0) {
|
|
79
|
+
lines.push('');
|
|
80
|
+
lines.push(`/* Context modifiers */`);
|
|
81
|
+
for (const [parent, ctx] of Object.entries(merged.contextModifiers)) {
|
|
82
|
+
lines.push(`/* When inside ${parent}: */`);
|
|
83
|
+
lines.push(`${ctx.selector} {`);
|
|
84
|
+
lines.push('');
|
|
85
|
+
lines.push('}');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Static modifier selectors
|
|
89
|
+
if (merged.staticModifiers.length > 0) {
|
|
90
|
+
lines.push('');
|
|
91
|
+
lines.push(`/* Static modifiers */`);
|
|
92
|
+
for (const mod of merged.staticModifiers) {
|
|
93
|
+
lines.push(`${mod.selector} {`);
|
|
94
|
+
lines.push('');
|
|
95
|
+
lines.push('}');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Element selectors
|
|
99
|
+
if (Object.keys(merged.elements).length > 0) {
|
|
100
|
+
lines.push('');
|
|
101
|
+
lines.push(`/* Elements */`);
|
|
102
|
+
for (const [elName, el] of Object.entries(merged.elements)) {
|
|
103
|
+
const condNote = el.condition ? ` (conditional: ${el.condition})` : '';
|
|
104
|
+
lines.push(`/* ${elName} — <${el.tag}> from ${el.source}${condNote} */`);
|
|
105
|
+
lines.push(`${el.selector} {`);
|
|
106
|
+
lines.push('');
|
|
107
|
+
lines.push('}');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
lines.push('');
|
|
111
|
+
return lines.join('\n');
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=scaffold-css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-css.js","sourceRoot":"","sources":["../../src/commands/scaffold-css.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA4C3D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { resolve } from 'path';
|
|
3
|
+
import { validateThemeConfig, validateManifest } from '@refrakt-md/transform';
|
|
4
|
+
import { baseConfig } from '@refrakt-md/theme-base';
|
|
5
|
+
export function validateCommand(opts) {
|
|
6
|
+
let hasErrors = false;
|
|
7
|
+
// Validate theme config
|
|
8
|
+
if (opts.configPath) {
|
|
9
|
+
const absPath = resolve(opts.configPath);
|
|
10
|
+
if (!existsSync(absPath)) {
|
|
11
|
+
console.error(`Error: Config file not found: ${absPath}`);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
// For now, only JSON configs are supported via CLI.
|
|
15
|
+
// TypeScript configs require dynamic import which needs the module to be built.
|
|
16
|
+
const raw = JSON.parse(readFileSync(absPath, 'utf-8'));
|
|
17
|
+
console.log('Validating theme config...');
|
|
18
|
+
const result = validateThemeConfig(raw);
|
|
19
|
+
printResult('Theme config', result);
|
|
20
|
+
if (!result.valid)
|
|
21
|
+
hasErrors = true;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
// Validate the base config as a sanity check
|
|
25
|
+
console.log('Validating base theme config...');
|
|
26
|
+
const result = validateThemeConfig(baseConfig);
|
|
27
|
+
printResult('Base theme config', result);
|
|
28
|
+
if (!result.valid)
|
|
29
|
+
hasErrors = true;
|
|
30
|
+
}
|
|
31
|
+
// Validate manifest
|
|
32
|
+
if (opts.manifestPath) {
|
|
33
|
+
const absPath = resolve(opts.manifestPath);
|
|
34
|
+
if (!existsSync(absPath)) {
|
|
35
|
+
console.error(`Error: Manifest file not found: ${absPath}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
const raw = JSON.parse(readFileSync(absPath, 'utf-8'));
|
|
39
|
+
console.log('\nValidating manifest...');
|
|
40
|
+
const result = validateManifest(raw);
|
|
41
|
+
printResult('Manifest', result);
|
|
42
|
+
if (!result.valid)
|
|
43
|
+
hasErrors = true;
|
|
44
|
+
}
|
|
45
|
+
if (hasErrors) {
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function printResult(label, result) {
|
|
50
|
+
if (result.valid && result.warnings.length === 0) {
|
|
51
|
+
console.log(` ${label}: OK`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (result.errors.length > 0) {
|
|
55
|
+
console.log(` ${label}: FAIL (${result.errors.length} error${result.errors.length === 1 ? '' : 's'})`);
|
|
56
|
+
for (const err of result.errors) {
|
|
57
|
+
console.log(` ERROR ${err.path}: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.log(` ${label}: OK`);
|
|
62
|
+
}
|
|
63
|
+
if (result.warnings.length > 0) {
|
|
64
|
+
console.log(` ${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'}:`);
|
|
65
|
+
for (const warn of result.warnings) {
|
|
66
|
+
console.log(` WARN ${warn.path}: ${warn.message}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/write.d.ts
CHANGED
|
@@ -2,8 +2,15 @@ import type { AIProvider } from '@refrakt-md/ai';
|
|
|
2
2
|
export interface WriteOptions {
|
|
3
3
|
prompt: string;
|
|
4
4
|
provider: AIProvider;
|
|
5
|
+
providerName: string;
|
|
6
|
+
modelName: string;
|
|
5
7
|
model?: string;
|
|
6
8
|
output?: string;
|
|
9
|
+
outputDir?: string;
|
|
7
10
|
}
|
|
11
|
+
export declare function splitFiles(raw: string): Array<{
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}>;
|
|
8
15
|
export declare function writeCommand(options: WriteOptions): Promise<void>;
|
|
9
16
|
//# sourceMappingURL=write.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAYD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA8BhF;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDvE"}
|
package/dist/commands/write.js
CHANGED
|
@@ -1,25 +1,81 @@
|
|
|
1
|
-
import { writeFileSync } from 'node:fs';
|
|
2
|
-
import
|
|
1
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { generateSystemPrompt, writePrompt } from '@refrakt-md/ai';
|
|
3
4
|
import { runes } from '@refrakt-md/runes';
|
|
5
|
+
function log(message) {
|
|
6
|
+
process.stderr.write(message);
|
|
7
|
+
}
|
|
8
|
+
function wordCount(text) {
|
|
9
|
+
return text.split(/\s+/).filter(Boolean).length;
|
|
10
|
+
}
|
|
11
|
+
const FILE_MARKER = /^--- FILE: (.+) ---$/gm;
|
|
12
|
+
export function splitFiles(raw) {
|
|
13
|
+
const files = [];
|
|
14
|
+
const markers = [];
|
|
15
|
+
let match;
|
|
16
|
+
while ((match = FILE_MARKER.exec(raw)) !== null) {
|
|
17
|
+
markers.push({ path: match[1].trim(), index: match.index + match[0].length });
|
|
18
|
+
}
|
|
19
|
+
if (markers.length === 0) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
for (let i = 0; i < markers.length; i++) {
|
|
23
|
+
const filePath = markers[i].path;
|
|
24
|
+
if (filePath.includes('..')) {
|
|
25
|
+
throw new Error(`Invalid file path "${filePath}": parent traversal is not allowed`);
|
|
26
|
+
}
|
|
27
|
+
const start = markers[i].index;
|
|
28
|
+
const nextMarkerPos = i + 1 < markers.length
|
|
29
|
+
? raw.indexOf(`--- FILE: ${markers[i + 1].path} ---`, start)
|
|
30
|
+
: raw.length;
|
|
31
|
+
const content = raw.slice(start, nextMarkerPos).replace(/^\n/, '').replace(/\n$/, '');
|
|
32
|
+
files.push({ path: filePath, content: content + '\n' });
|
|
33
|
+
}
|
|
34
|
+
return files;
|
|
35
|
+
}
|
|
4
36
|
export async function writeCommand(options) {
|
|
5
|
-
const { prompt, provider, model, output } = options;
|
|
6
|
-
|
|
37
|
+
const { prompt, provider, providerName, modelName, model, output, outputDir } = options;
|
|
38
|
+
log(`Using ${providerName} (${modelName})\n`);
|
|
39
|
+
const multiFile = !!outputDir;
|
|
40
|
+
const systemPrompt = generateSystemPrompt(runes) + writePrompt({ multiFile });
|
|
7
41
|
const messages = [
|
|
8
42
|
{ role: 'system', content: systemPrompt },
|
|
9
43
|
{ role: 'user', content: prompt },
|
|
10
44
|
];
|
|
11
45
|
let content = '';
|
|
46
|
+
if (output || outputDir) {
|
|
47
|
+
log('Generating...');
|
|
48
|
+
}
|
|
12
49
|
for await (const chunk of provider.complete({ messages, model })) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
50
|
+
content += chunk;
|
|
51
|
+
if (!output && !outputDir) {
|
|
17
52
|
process.stdout.write(chunk);
|
|
18
53
|
}
|
|
19
54
|
}
|
|
20
|
-
if (
|
|
55
|
+
if (outputDir) {
|
|
56
|
+
const files = splitFiles(content);
|
|
57
|
+
const words = wordCount(content);
|
|
58
|
+
if (files.length === 0) {
|
|
59
|
+
log(`\rGenerating... done (${words.toLocaleString()} words)\n`);
|
|
60
|
+
const fallbackPath = path.join(outputDir, 'index.md');
|
|
61
|
+
mkdirSync(outputDir, { recursive: true });
|
|
62
|
+
writeFileSync(fallbackPath, content);
|
|
63
|
+
log(`Written to ${fallbackPath}\n`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
log(`\rGenerating... done (${words.toLocaleString()} words, ${files.length} files)\n`);
|
|
67
|
+
for (const file of files) {
|
|
68
|
+
const fullPath = path.join(outputDir, file.path);
|
|
69
|
+
mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
70
|
+
writeFileSync(fullPath, file.content);
|
|
71
|
+
log(` ${fullPath}\n`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (output) {
|
|
75
|
+
const words = wordCount(content);
|
|
76
|
+
log(`\rGenerating... done (${words.toLocaleString()} words)\n`);
|
|
21
77
|
writeFileSync(output, content);
|
|
22
|
-
|
|
78
|
+
log(`Written to ${output}\n`);
|
|
23
79
|
}
|
|
24
80
|
else {
|
|
25
81
|
process.stdout.write('\n');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/commands/write.ts"],"names":[],"mappings":"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"}
|