@buoy-design/cli 0.1.0 → 0.1.2
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/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +235 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/baseline.d.ts +39 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +298 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/check.d.ts +16 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +168 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/ci.d.ts +2 -2
- package/dist/commands/ci.d.ts.map +1 -1
- package/dist/commands/ci.js +124 -142
- package/dist/commands/ci.js.map +1 -1
- package/dist/commands/compare.d.ts +3 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +170 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/drift.d.ts +1 -1
- package/dist/commands/drift.d.ts.map +1 -1
- package/dist/commands/drift.js +79 -121
- package/dist/commands/drift.js.map +1 -1
- package/dist/commands/explain.d.ts +3 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +212 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/graph.d.ts +3 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +430 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/index.d.ts +14 -8
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +14 -8
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +404 -237
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/plugins.d.ts.map +1 -1
- package/dist/commands/plugins.js +32 -41
- package/dist/commands/plugins.js.map +1 -1
- package/dist/commands/scan.d.ts +1 -1
- package/dist/commands/scan.d.ts.map +1 -1
- package/dist/commands/scan.js +107 -219
- package/dist/commands/scan.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +114 -122
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tokens.d.ts +3 -0
- package/dist/commands/tokens.d.ts.map +1 -0
- package/dist/commands/tokens.js +261 -0
- package/dist/commands/tokens.js.map +1 -0
- package/dist/config/auto-detect.d.ts +21 -0
- package/dist/config/auto-detect.d.ts.map +1 -0
- package/dist/config/auto-detect.js +278 -0
- package/dist/config/auto-detect.js.map +1 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +17 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +63 -63
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +20 -2
- package/dist/config/schema.js.map +1 -1
- package/dist/constants.d.ts +36 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +37 -0
- package/dist/constants.js.map +1 -0
- package/dist/detect/frameworks.d.ts +11 -2
- package/dist/detect/frameworks.d.ts.map +1 -1
- package/dist/detect/frameworks.js +78 -78
- package/dist/detect/frameworks.js.map +1 -1
- package/dist/detect/index.d.ts +1 -0
- package/dist/detect/index.d.ts.map +1 -1
- package/dist/detect/index.js +3 -0
- package/dist/detect/index.js.map +1 -1
- package/dist/detect/monorepo-patterns.d.ts +54 -0
- package/dist/detect/monorepo-patterns.d.ts.map +1 -0
- package/dist/detect/monorepo-patterns.js +209 -0
- package/dist/detect/monorepo-patterns.js.map +1 -0
- package/dist/detect/project-detector.d.ts +1 -1
- package/dist/detect/project-detector.d.ts.map +1 -1
- package/dist/detect/project-detector.js +132 -0
- package/dist/detect/project-detector.js.map +1 -1
- package/dist/explain/agents.d.ts +31 -0
- package/dist/explain/agents.d.ts.map +1 -0
- package/dist/explain/agents.js +507 -0
- package/dist/explain/agents.js.map +1 -0
- package/dist/hooks/index.d.ts +26 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +283 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/dist/integrations/github-formatter.d.ts +55 -0
- package/dist/integrations/github-formatter.d.ts.map +1 -0
- package/dist/integrations/github-formatter.js +391 -0
- package/dist/integrations/github-formatter.js.map +1 -0
- package/dist/integrations/github.d.ts +95 -0
- package/dist/integrations/github.d.ts.map +1 -0
- package/dist/integrations/github.js +281 -0
- package/dist/integrations/github.js.map +1 -0
- package/dist/integrations/index.d.ts +4 -0
- package/dist/integrations/index.d.ts.map +1 -0
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/output/formatters.d.ts.map +1 -1
- package/dist/output/formatters.js +5 -10
- package/dist/output/formatters.js.map +1 -1
- package/dist/scan/orchestrator.d.ts +76 -0
- package/dist/scan/orchestrator.d.ts.map +1 -0
- package/dist/scan/orchestrator.js +247 -0
- package/dist/scan/orchestrator.js.map +1 -0
- package/dist/services/ai-analysis.d.ts +54 -0
- package/dist/services/ai-analysis.d.ts.map +1 -0
- package/dist/services/ai-analysis.js +239 -0
- package/dist/services/ai-analysis.js.map +1 -0
- package/dist/services/drift-analysis.d.ts +77 -0
- package/dist/services/drift-analysis.d.ts.map +1 -0
- package/dist/services/drift-analysis.js +145 -0
- package/dist/services/drift-analysis.js.map +1 -0
- package/package.json +17 -5
- package/dist/commands/__tests__/ci.test.d.ts +0 -2
- package/dist/commands/__tests__/ci.test.d.ts.map +0 -1
- package/dist/commands/__tests__/ci.test.js +0 -33
- package/dist/commands/__tests__/ci.test.js.map +0 -1
- package/dist/commands/bootstrap.d.ts +0 -3
- package/dist/commands/bootstrap.d.ts.map +0 -1
- package/dist/commands/bootstrap.js +0 -458
- package/dist/commands/bootstrap.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -3
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/index.js +0 -3
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/loader.d.ts +0 -11
- package/dist/plugins/loader.d.ts.map +0 -1
- package/dist/plugins/loader.js +0 -77
- package/dist/plugins/loader.js.map +0 -1
- package/dist/plugins/registry.d.ts +0 -15
- package/dist/plugins/registry.d.ts.map +0 -1
- package/dist/plugins/registry.js +0 -32
- package/dist/plugins/registry.js.map +0 -1
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { writeFileSync } from 'fs';
|
|
3
|
+
import { resolve, relative } from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { glob } from 'glob';
|
|
6
|
+
import { readFile } from 'fs/promises';
|
|
7
|
+
import { getConfigPath } from '../config/loader.js';
|
|
8
|
+
import { buildAutoConfig } from '../config/auto-detect.js';
|
|
9
|
+
import { detectFrameworks } from '../detect/frameworks.js';
|
|
10
|
+
import { spinner, success, error, info, header, newline, keyValue, } from '../output/reporters.js';
|
|
11
|
+
import { extractStyles, extractCssFileStyles, } from '@buoy-design/scanners';
|
|
12
|
+
import { parseCssValues, generateTokens, } from '@buoy-design/core';
|
|
13
|
+
export function createTokensCommand() {
|
|
14
|
+
const cmd = new Command('tokens')
|
|
15
|
+
.description('Generate design tokens from your codebase')
|
|
16
|
+
.option('-o, --output <path>', 'Output file path (auto-detected if not specified)')
|
|
17
|
+
.option('--format <format>', 'Output format: css, json, tailwind (auto-detected if not specified)')
|
|
18
|
+
.option('--dry-run', 'Preview without writing files')
|
|
19
|
+
.option('--prefix <prefix>', 'Prefix for CSS custom properties (e.g., "ds-")')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
const spin = spinner('Analyzing codebase...');
|
|
22
|
+
try {
|
|
23
|
+
const cwd = process.cwd();
|
|
24
|
+
// Auto-detect project setup
|
|
25
|
+
const frameworks = await detectFrameworks(cwd);
|
|
26
|
+
const hasTailwind = frameworks.some(f => f.name === 'tailwind');
|
|
27
|
+
// Determine format (auto-detect or user-specified)
|
|
28
|
+
const format = options.format || (hasTailwind ? 'tailwind' : 'css');
|
|
29
|
+
// Determine output path (auto-detect or user-specified)
|
|
30
|
+
const defaultOutput = format === 'tailwind'
|
|
31
|
+
? 'buoy.tokens.js'
|
|
32
|
+
: format === 'json'
|
|
33
|
+
? 'design-tokens.json'
|
|
34
|
+
: 'design-tokens.css';
|
|
35
|
+
const outputPath = resolve(cwd, options.output || defaultOutput);
|
|
36
|
+
// Get config (or auto-detect)
|
|
37
|
+
let config;
|
|
38
|
+
const configPath = getConfigPath();
|
|
39
|
+
if (configPath) {
|
|
40
|
+
const { loadConfig } = await import('../config/loader.js');
|
|
41
|
+
const result = await loadConfig();
|
|
42
|
+
config = result.config;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const autoResult = await buildAutoConfig(cwd);
|
|
46
|
+
config = autoResult.config;
|
|
47
|
+
spin.stop();
|
|
48
|
+
console.log(chalk.cyan.bold('⚡ Zero-config mode'));
|
|
49
|
+
console.log(chalk.dim(' Auto-detected:'));
|
|
50
|
+
for (const d of autoResult.detected) {
|
|
51
|
+
console.log(` ${chalk.green('•')} ${d.name}`);
|
|
52
|
+
}
|
|
53
|
+
console.log('');
|
|
54
|
+
spin.start();
|
|
55
|
+
}
|
|
56
|
+
// Collect files to scan
|
|
57
|
+
spin.text = 'Finding source files...';
|
|
58
|
+
const filesToScan = [];
|
|
59
|
+
const sources = config.sources || {};
|
|
60
|
+
// Component files (React, Vue, Svelte, etc.)
|
|
61
|
+
const componentSources = [
|
|
62
|
+
{ key: 'react', patterns: sources.react?.include || ['src/**/*.tsx', 'src/**/*.jsx'] },
|
|
63
|
+
{ key: 'vue', patterns: sources.vue?.include || ['src/**/*.vue'] },
|
|
64
|
+
{ key: 'svelte', patterns: sources.svelte?.include || ['src/**/*.svelte'] },
|
|
65
|
+
];
|
|
66
|
+
for (const { key, patterns } of componentSources) {
|
|
67
|
+
if (sources[key]?.enabled !== false) {
|
|
68
|
+
for (const pattern of patterns) {
|
|
69
|
+
const files = await glob(pattern, {
|
|
70
|
+
cwd,
|
|
71
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/*.test.*', '**/*.stories.*'],
|
|
72
|
+
absolute: true
|
|
73
|
+
});
|
|
74
|
+
for (const file of files) {
|
|
75
|
+
filesToScan.push({ path: file, type: key });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Template files
|
|
81
|
+
if (sources.templates?.enabled) {
|
|
82
|
+
const patterns = sources.templates.include || [];
|
|
83
|
+
for (const pattern of patterns) {
|
|
84
|
+
const files = await glob(pattern, {
|
|
85
|
+
cwd,
|
|
86
|
+
ignore: sources.templates.exclude || [],
|
|
87
|
+
absolute: true
|
|
88
|
+
});
|
|
89
|
+
for (const file of files) {
|
|
90
|
+
filesToScan.push({ path: file, type: sources.templates.type });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// CSS/SCSS files (always scan)
|
|
95
|
+
const cssPatterns = ['**/*.css', '**/*.scss'];
|
|
96
|
+
const cssIgnore = ['**/node_modules/**', '**/dist/**', '**/build/**', '**/*.min.css'];
|
|
97
|
+
for (const pattern of cssPatterns) {
|
|
98
|
+
const files = await glob(pattern, { cwd, ignore: cssIgnore, absolute: true });
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
filesToScan.push({ path: file, type: 'css' });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (filesToScan.length === 0) {
|
|
104
|
+
spin.stop();
|
|
105
|
+
error('No source files found');
|
|
106
|
+
info('Make sure you have CSS, React, Vue, or other component files in your project.');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// Extract values from all files
|
|
110
|
+
spin.text = `Scanning ${filesToScan.length} files...`;
|
|
111
|
+
const allValues = [];
|
|
112
|
+
for (const { path: filePath, type } of filesToScan) {
|
|
113
|
+
try {
|
|
114
|
+
const content = await readFile(filePath, 'utf-8');
|
|
115
|
+
const styles = type === 'css'
|
|
116
|
+
? extractCssFileStyles(content)
|
|
117
|
+
: extractStyles(content, type);
|
|
118
|
+
for (const style of styles) {
|
|
119
|
+
const { values } = parseCssValues(style.css);
|
|
120
|
+
allValues.push(...values);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// Skip files that can't be read
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (allValues.length === 0) {
|
|
128
|
+
spin.stop();
|
|
129
|
+
info('No hardcoded design values found');
|
|
130
|
+
console.log('');
|
|
131
|
+
info('This could mean:');
|
|
132
|
+
info(' • Your codebase already uses design tokens');
|
|
133
|
+
info(' • Values are using CSS variables or theme objects');
|
|
134
|
+
console.log('');
|
|
135
|
+
success('Your codebase looks clean!');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Generate tokens
|
|
139
|
+
spin.text = 'Generating tokens...';
|
|
140
|
+
const result = generateTokens(allValues, {
|
|
141
|
+
prefix: options.prefix || '',
|
|
142
|
+
});
|
|
143
|
+
spin.stop();
|
|
144
|
+
// Summary
|
|
145
|
+
newline();
|
|
146
|
+
header('Token Generation');
|
|
147
|
+
newline();
|
|
148
|
+
keyValue('Files scanned', String(filesToScan.length));
|
|
149
|
+
keyValue('Values found', String(result.stats.total));
|
|
150
|
+
keyValue('Tokens generated', String(result.tokens.length));
|
|
151
|
+
const { coverage } = result.stats;
|
|
152
|
+
const coverageColor = coverage.percentage >= 80 ? chalk.green :
|
|
153
|
+
coverage.percentage >= 60 ? chalk.yellow :
|
|
154
|
+
chalk.red;
|
|
155
|
+
keyValue('Coverage', `${coverageColor(coverage.percentage + '%')}`);
|
|
156
|
+
newline();
|
|
157
|
+
// Show tokens by category
|
|
158
|
+
const byCategory = {};
|
|
159
|
+
for (const token of result.tokens) {
|
|
160
|
+
if (!byCategory[token.category]) {
|
|
161
|
+
byCategory[token.category] = [];
|
|
162
|
+
}
|
|
163
|
+
byCategory[token.category].push(token);
|
|
164
|
+
}
|
|
165
|
+
for (const [category, tokens] of Object.entries(byCategory)) {
|
|
166
|
+
console.log(` ${chalk.bold(category)}: ${tokens.length} tokens`);
|
|
167
|
+
}
|
|
168
|
+
newline();
|
|
169
|
+
// Write or preview
|
|
170
|
+
if (options.dryRun) {
|
|
171
|
+
info('Dry run - no files written');
|
|
172
|
+
newline();
|
|
173
|
+
header('Preview');
|
|
174
|
+
console.log(chalk.dim(getOutput(result, format).slice(0, 800)));
|
|
175
|
+
if (getOutput(result, format).length > 800) {
|
|
176
|
+
console.log(chalk.dim('...'));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const content = getOutput(result, format);
|
|
181
|
+
writeFileSync(outputPath, content, 'utf-8');
|
|
182
|
+
success(`Created ${chalk.cyan(relative(cwd, outputPath))}`);
|
|
183
|
+
newline();
|
|
184
|
+
// Next steps based on format
|
|
185
|
+
if (format === 'css') {
|
|
186
|
+
info('Next: Import in your CSS:');
|
|
187
|
+
console.log(chalk.cyan(` @import "${relative(cwd, outputPath)}";`));
|
|
188
|
+
}
|
|
189
|
+
else if (format === 'tailwind') {
|
|
190
|
+
info('Next: Add to your tailwind.config.js:');
|
|
191
|
+
console.log(chalk.cyan(` const tokens = require("./${relative(cwd, outputPath)}");`));
|
|
192
|
+
console.log(chalk.cyan(' // Spread into theme.extend'));
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
info('Next: Import tokens in your build system');
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Hint to save config if auto-detected
|
|
199
|
+
if (!configPath) {
|
|
200
|
+
newline();
|
|
201
|
+
console.log(chalk.dim('─'.repeat(50)));
|
|
202
|
+
console.log(chalk.dim('💡 ') +
|
|
203
|
+
'Run ' +
|
|
204
|
+
chalk.cyan('buoy init') +
|
|
205
|
+
' to save configuration');
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
209
|
+
spin.stop();
|
|
210
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
211
|
+
error(`Token generation failed: ${message}`);
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
return cmd;
|
|
216
|
+
}
|
|
217
|
+
function getOutput(result, format) {
|
|
218
|
+
switch (format) {
|
|
219
|
+
case 'json':
|
|
220
|
+
return JSON.stringify(result.json, null, 2);
|
|
221
|
+
case 'tailwind':
|
|
222
|
+
return generateTailwindOutput(result);
|
|
223
|
+
default:
|
|
224
|
+
return result.css;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function generateTailwindOutput(result) {
|
|
228
|
+
const colors = {};
|
|
229
|
+
const spacing = {};
|
|
230
|
+
const fontSize = {};
|
|
231
|
+
const borderRadius = {};
|
|
232
|
+
for (const token of result.tokens) {
|
|
233
|
+
const name = token.name.replace(/^(color|spacing|text|radius)-/, '');
|
|
234
|
+
switch (token.category) {
|
|
235
|
+
case 'color':
|
|
236
|
+
colors[name] = token.value;
|
|
237
|
+
break;
|
|
238
|
+
case 'spacing':
|
|
239
|
+
case 'sizing':
|
|
240
|
+
spacing[name] = token.value;
|
|
241
|
+
break;
|
|
242
|
+
case 'font-size':
|
|
243
|
+
fontSize[name] = token.value;
|
|
244
|
+
break;
|
|
245
|
+
case 'radius':
|
|
246
|
+
borderRadius[name] = token.value;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return `// Generated by buoy tokens
|
|
251
|
+
// Import and spread into your tailwind.config.js theme.extend
|
|
252
|
+
|
|
253
|
+
module.exports = {
|
|
254
|
+
colors: ${JSON.stringify(colors, null, 4)},
|
|
255
|
+
spacing: ${JSON.stringify(spacing, null, 4)},
|
|
256
|
+
fontSize: ${JSON.stringify(fontSize, null, 4)},
|
|
257
|
+
borderRadius: ${JSON.stringify(borderRadius, null, 4)},
|
|
258
|
+
};
|
|
259
|
+
`;
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/commands/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type DetectedFramework } from '../detect/frameworks.js';
|
|
2
|
+
import type { BuoyConfig } from './schema.js';
|
|
3
|
+
export interface MonorepoInfo {
|
|
4
|
+
type: 'pnpm' | 'yarn' | 'npm' | 'lerna' | 'nx' | 'turborepo';
|
|
5
|
+
patterns: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Build a config automatically from detected frameworks.
|
|
9
|
+
* Used when no buoy.config.mjs exists - zero-config mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildAutoConfig(projectRoot?: string): Promise<{
|
|
12
|
+
config: BuoyConfig;
|
|
13
|
+
detected: DetectedFramework[];
|
|
14
|
+
tokenFiles: string[];
|
|
15
|
+
monorepo: MonorepoInfo | null;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Format a summary of what was auto-detected
|
|
19
|
+
*/
|
|
20
|
+
export declare function formatAutoDetectSummary(detected: DetectedFramework[], tokenFiles: string[]): string;
|
|
21
|
+
//# sourceMappingURL=auto-detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-detect.d.ts","sourceRoot":"","sources":["../../src/config/auto-detect.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,WAAW,CAAC;IAC7D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAwID;;;GAGG;AACH,wBAAsB,eAAe,CAAC,WAAW,GAAE,MAAsB,GAAG,OAAO,CAAC;IAClF,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CAC/B,CAAC,CA6FD;AA4CD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,UAAU,EAAE,MAAM,EAAE,GACnB,MAAM,CAqBR"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// apps/cli/src/config/auto-detect.ts
|
|
2
|
+
import { basename, resolve } from 'node:path';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { glob } from 'glob';
|
|
6
|
+
import { detectFrameworks } from '../detect/frameworks.js';
|
|
7
|
+
/**
|
|
8
|
+
* Detect if this is a monorepo and return workspace patterns.
|
|
9
|
+
*/
|
|
10
|
+
async function detectMonorepo(projectRoot) {
|
|
11
|
+
// Check for pnpm-workspace.yaml
|
|
12
|
+
const pnpmWorkspacePath = resolve(projectRoot, 'pnpm-workspace.yaml');
|
|
13
|
+
if (existsSync(pnpmWorkspacePath)) {
|
|
14
|
+
try {
|
|
15
|
+
const content = await readFile(pnpmWorkspacePath, 'utf-8');
|
|
16
|
+
// Simple YAML parsing for packages: array
|
|
17
|
+
const packagesMatch = content.match(/packages:\s*\n((?:\s+-\s+[^\n]+\n?)+)/);
|
|
18
|
+
if (packagesMatch && packagesMatch[1]) {
|
|
19
|
+
const patterns = packagesMatch[1]
|
|
20
|
+
.split('\n')
|
|
21
|
+
.map(line => line.replace(/^\s*-\s*/, '').trim())
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
// Strip single and double quotes from YAML strings
|
|
24
|
+
.map(pattern => pattern.replace(/^["'](.*)["']$/, '$1'))
|
|
25
|
+
// Filter out negation patterns (they start with !)
|
|
26
|
+
.filter(pattern => !pattern.startsWith('!'));
|
|
27
|
+
return { type: 'pnpm', patterns };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// Failed to parse, continue
|
|
32
|
+
}
|
|
33
|
+
return { type: 'pnpm', patterns: ['packages/**', 'apps/**'] }; // Default patterns
|
|
34
|
+
}
|
|
35
|
+
// Check for lerna.json
|
|
36
|
+
const lernaPath = resolve(projectRoot, 'lerna.json');
|
|
37
|
+
if (existsSync(lernaPath)) {
|
|
38
|
+
try {
|
|
39
|
+
const content = JSON.parse(await readFile(lernaPath, 'utf-8'));
|
|
40
|
+
if (content.packages) {
|
|
41
|
+
return { type: 'lerna', patterns: content.packages };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Failed to parse
|
|
46
|
+
}
|
|
47
|
+
return { type: 'lerna', patterns: ['packages/*'] };
|
|
48
|
+
}
|
|
49
|
+
// Check for nx.json
|
|
50
|
+
const nxPath = resolve(projectRoot, 'nx.json');
|
|
51
|
+
if (existsSync(nxPath)) {
|
|
52
|
+
return { type: 'nx', patterns: ['packages/**', 'apps/**', 'libs/**'] };
|
|
53
|
+
}
|
|
54
|
+
// Check for turbo.json
|
|
55
|
+
const turboPath = resolve(projectRoot, 'turbo.json');
|
|
56
|
+
if (existsSync(turboPath)) {
|
|
57
|
+
return { type: 'turborepo', patterns: ['packages/**', 'apps/**'] };
|
|
58
|
+
}
|
|
59
|
+
// Check package.json for workspaces (yarn/npm)
|
|
60
|
+
const pkgPath = resolve(projectRoot, 'package.json');
|
|
61
|
+
if (existsSync(pkgPath)) {
|
|
62
|
+
try {
|
|
63
|
+
const content = JSON.parse(await readFile(pkgPath, 'utf-8'));
|
|
64
|
+
if (content.workspaces) {
|
|
65
|
+
const patterns = Array.isArray(content.workspaces)
|
|
66
|
+
? content.workspaces
|
|
67
|
+
: content.workspaces.packages || [];
|
|
68
|
+
if (patterns.length > 0) {
|
|
69
|
+
// Check if it's yarn (yarn.lock) or npm (package-lock.json)
|
|
70
|
+
const type = existsSync(resolve(projectRoot, 'yarn.lock')) ? 'yarn' : 'npm';
|
|
71
|
+
return { type, patterns };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Failed to parse
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Expand include patterns for monorepo structure.
|
|
83
|
+
* Adds patterns like packages/[star]/src/[star][star]/[star].tsx for monorepos.
|
|
84
|
+
*/
|
|
85
|
+
function expandForMonorepo(basePatterns, monorepo) {
|
|
86
|
+
const expanded = [...basePatterns];
|
|
87
|
+
// Add monorepo-specific patterns based on workspace config
|
|
88
|
+
for (const wsPattern of monorepo.patterns) {
|
|
89
|
+
// Normalize the pattern (remove trailing slashes and **)
|
|
90
|
+
const base = wsPattern.replace(/\/?\*\*?\/?$/, '').replace(/\/$/, '');
|
|
91
|
+
// For each base pattern, add the monorepo equivalent
|
|
92
|
+
for (const pattern of basePatterns) {
|
|
93
|
+
// Extract the core pattern (e.g., '**/*.tsx' from 'src/**/*.tsx')
|
|
94
|
+
const match = pattern.match(/^([^*]+)(\*\*.*)$/);
|
|
95
|
+
if (match) {
|
|
96
|
+
const prefix = match[1]; // e.g., 'src/'
|
|
97
|
+
const suffix = match[2]; // e.g., '**/*.tsx'
|
|
98
|
+
// Add patterns for different monorepo structures:
|
|
99
|
+
// - packages/*/src/**/*.tsx (direct packages)
|
|
100
|
+
// - packages/@scope/*/src/**/*.tsx (scoped packages like @mantine/core)
|
|
101
|
+
if (base.includes('*')) {
|
|
102
|
+
// Already has a wildcard (e.g., 'packages/**')
|
|
103
|
+
expanded.push(`${base}/${prefix}${suffix}`);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
// Need to add wildcards for package directories
|
|
107
|
+
expanded.push(`${base}/*/${prefix}${suffix}`);
|
|
108
|
+
// Also handle scoped packages (packages/@scope/*/src/...)
|
|
109
|
+
expanded.push(`${base}/@*/*/${prefix}${suffix}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Also add common patterns for apps directory (many monorepos have an apps/ folder)
|
|
115
|
+
if (!monorepo.patterns.some(p => p.includes('apps'))) {
|
|
116
|
+
for (const pattern of basePatterns) {
|
|
117
|
+
const match = pattern.match(/^([^*]+)(\*\*.*)$/);
|
|
118
|
+
if (match) {
|
|
119
|
+
expanded.push(`apps/*/${match[1]}${match[2]}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Add registry patterns for shadcn-style repos
|
|
124
|
+
for (const pattern of basePatterns) {
|
|
125
|
+
if (pattern.includes('*.tsx') || pattern.includes('*.jsx')) {
|
|
126
|
+
expanded.push(`**/registry/**/*.tsx`);
|
|
127
|
+
expanded.push(`**/registry/**/*.jsx`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return [...new Set(expanded)]; // Deduplicate
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Build a config automatically from detected frameworks.
|
|
134
|
+
* Used when no buoy.config.mjs exists - zero-config mode.
|
|
135
|
+
*/
|
|
136
|
+
export async function buildAutoConfig(projectRoot = process.cwd()) {
|
|
137
|
+
// Detect monorepo first, then frameworks (passing monorepo info for workspace scanning)
|
|
138
|
+
const monorepo = await detectMonorepo(projectRoot);
|
|
139
|
+
const detected = await detectFrameworks(projectRoot, monorepo);
|
|
140
|
+
// Find token files
|
|
141
|
+
const tokenFiles = await findTokenFiles(projectRoot);
|
|
142
|
+
// Build config from detections
|
|
143
|
+
const config = {
|
|
144
|
+
project: {
|
|
145
|
+
name: basename(projectRoot),
|
|
146
|
+
},
|
|
147
|
+
sources: {},
|
|
148
|
+
drift: { ignore: [], severity: {} },
|
|
149
|
+
claude: { enabled: false, model: 'claude-sonnet-4-20250514' },
|
|
150
|
+
output: { format: 'table', colors: true },
|
|
151
|
+
};
|
|
152
|
+
// Map detected frameworks to source configs
|
|
153
|
+
for (const framework of detected) {
|
|
154
|
+
const scanner = framework.scanner;
|
|
155
|
+
if (!scanner)
|
|
156
|
+
continue;
|
|
157
|
+
switch (scanner) {
|
|
158
|
+
case 'react': {
|
|
159
|
+
const baseInclude = ['src/**/*.tsx', 'src/**/*.jsx', 'app/**/*.tsx', 'app/**/*.jsx', 'components/**/*.tsx', 'components/**/*.jsx'];
|
|
160
|
+
config.sources.react = {
|
|
161
|
+
enabled: true,
|
|
162
|
+
include: monorepo ? expandForMonorepo(baseInclude, monorepo) : baseInclude,
|
|
163
|
+
exclude: ['**/*.test.*', '**/*.spec.*', '**/*.stories.*', '**/node_modules/**'],
|
|
164
|
+
};
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'vue': {
|
|
168
|
+
const baseInclude = ['src/**/*.vue', 'components/**/*.vue'];
|
|
169
|
+
config.sources.vue = {
|
|
170
|
+
enabled: true,
|
|
171
|
+
include: monorepo ? expandForMonorepo(baseInclude, monorepo) : baseInclude,
|
|
172
|
+
exclude: ['**/*.test.*', '**/*.spec.*', '**/*.stories.*', '**/node_modules/**'],
|
|
173
|
+
};
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case 'svelte': {
|
|
177
|
+
const baseInclude = ['src/**/*.svelte', 'lib/**/*.svelte'];
|
|
178
|
+
config.sources.svelte = {
|
|
179
|
+
enabled: true,
|
|
180
|
+
include: monorepo ? expandForMonorepo(baseInclude, monorepo) : baseInclude,
|
|
181
|
+
exclude: ['**/*.test.*', '**/*.spec.*', '**/*.stories.*', '**/node_modules/**'],
|
|
182
|
+
};
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
case 'angular': {
|
|
186
|
+
// Use **/*.ts to catch Angular Material-style naming (e.g., button.ts, tab.ts)
|
|
187
|
+
// as well as standard *.component.ts files
|
|
188
|
+
const baseInclude = ['src/**/*.ts'];
|
|
189
|
+
config.sources.angular = {
|
|
190
|
+
enabled: true,
|
|
191
|
+
include: monorepo ? expandForMonorepo(baseInclude, monorepo) : baseInclude,
|
|
192
|
+
exclude: ['**/*.spec.*', '**/*.test.*', '**/node_modules/**'],
|
|
193
|
+
};
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case 'webcomponents': {
|
|
197
|
+
const baseInclude = ['src/**/*.ts'];
|
|
198
|
+
config.sources.webcomponent = {
|
|
199
|
+
enabled: true,
|
|
200
|
+
include: monorepo ? expandForMonorepo(baseInclude, monorepo) : baseInclude,
|
|
201
|
+
exclude: ['**/*.test.*', '**/*.spec.*', '**/node_modules/**'],
|
|
202
|
+
framework: 'auto',
|
|
203
|
+
};
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case 'tailwind':
|
|
207
|
+
// Tailwind is handled by token scanning, not a separate source
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Add token scanning if we found token files
|
|
212
|
+
if (tokenFiles.length > 0) {
|
|
213
|
+
config.sources.tokens = {
|
|
214
|
+
enabled: true,
|
|
215
|
+
files: tokenFiles,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return { config, detected, tokenFiles, monorepo };
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Find common token file patterns
|
|
222
|
+
*/
|
|
223
|
+
async function findTokenFiles(projectRoot) {
|
|
224
|
+
const patterns = [
|
|
225
|
+
// CSS custom properties
|
|
226
|
+
'**/tokens.css',
|
|
227
|
+
'**/variables.css',
|
|
228
|
+
'**/design-tokens.css',
|
|
229
|
+
'**/theme.css',
|
|
230
|
+
'**/_variables.scss',
|
|
231
|
+
'**/_tokens.scss',
|
|
232
|
+
'**/styles/variables.css',
|
|
233
|
+
'**/styles/tokens.css',
|
|
234
|
+
// JSON tokens
|
|
235
|
+
'**/tokens.json',
|
|
236
|
+
'**/design-tokens.json',
|
|
237
|
+
'**/.tokens.json',
|
|
238
|
+
'**/style-dictionary/**/*.json',
|
|
239
|
+
// Tailwind config (extract theme)
|
|
240
|
+
'tailwind.config.js',
|
|
241
|
+
'tailwind.config.ts',
|
|
242
|
+
'tailwind.config.mjs',
|
|
243
|
+
];
|
|
244
|
+
const found = [];
|
|
245
|
+
for (const pattern of patterns) {
|
|
246
|
+
const matches = await glob(pattern, {
|
|
247
|
+
cwd: projectRoot,
|
|
248
|
+
nodir: true,
|
|
249
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/build/**'],
|
|
250
|
+
});
|
|
251
|
+
found.push(...matches);
|
|
252
|
+
}
|
|
253
|
+
// Deduplicate
|
|
254
|
+
return [...new Set(found)];
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Format a summary of what was auto-detected
|
|
258
|
+
*/
|
|
259
|
+
export function formatAutoDetectSummary(detected, tokenFiles) {
|
|
260
|
+
const lines = [];
|
|
261
|
+
if (detected.length > 0) {
|
|
262
|
+
lines.push('Detected:');
|
|
263
|
+
for (const d of detected) {
|
|
264
|
+
lines.push(` • ${d.name} (${d.evidence})`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (tokenFiles.length > 0) {
|
|
268
|
+
lines.push('Token files:');
|
|
269
|
+
for (const f of tokenFiles.slice(0, 5)) {
|
|
270
|
+
lines.push(` • ${f}`);
|
|
271
|
+
}
|
|
272
|
+
if (tokenFiles.length > 5) {
|
|
273
|
+
lines.push(` ... and ${tokenFiles.length - 5} more`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return lines.join('\n');
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=auto-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-detect.js","sourceRoot":"","sources":["../../src/config/auto-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAC;AAU3D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0EvF;AAED,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAQxE"}
|
package/dist/config/loader.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync } from 'fs';
|
|
2
2
|
import { resolve, basename } from 'path';
|
|
3
3
|
import { pathToFileURL } from 'url';
|
|
4
|
+
import { ZodError } from 'zod';
|
|
5
|
+
import { fromZodError } from 'zod-validation-error';
|
|
4
6
|
import { BuoyConfigSchema } from './schema.js';
|
|
5
7
|
const CONFIG_FILES = [
|
|
6
8
|
'buoy.config.mjs',
|
|
@@ -51,6 +53,21 @@ export async function loadConfig(cwd = process.cwd()) {
|
|
|
51
53
|
};
|
|
52
54
|
}
|
|
53
55
|
catch (error) {
|
|
56
|
+
// Provide helpful error messages for different error types
|
|
57
|
+
if (error instanceof ZodError) {
|
|
58
|
+
const validationError = fromZodError(error, {
|
|
59
|
+
prefix: 'Configuration error',
|
|
60
|
+
prefixSeparator: ': ',
|
|
61
|
+
});
|
|
62
|
+
throw new Error(`Invalid config in ${configPath}:\n\n${validationError.message}\n\nRun 'buoy init' to generate a valid configuration.`);
|
|
63
|
+
}
|
|
64
|
+
if (error instanceof SyntaxError) {
|
|
65
|
+
throw new Error(`Invalid JSON in ${configPath}: ${error.message}\n\nCheck for missing commas, trailing commas, or unquoted keys.`);
|
|
66
|
+
}
|
|
67
|
+
// Handle import errors (for JS/TS config files)
|
|
68
|
+
if (error instanceof Error && error.message.includes('Cannot find module')) {
|
|
69
|
+
throw new Error(`Failed to load config from ${configPath}: Module not found.\n\nIf using TypeScript, ensure tsx or ts-node is installed.`);
|
|
70
|
+
}
|
|
54
71
|
const message = error instanceof Error ? error.message : String(error);
|
|
55
72
|
throw new Error(`Failed to load config from ${configPath}: ${message}`);
|
|
56
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAc,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,YAAY,GAAG;IACnB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB,EAAG,kCAAkC;IACrD,cAAc;IACd,SAAS;CACV,CAAC;AAOF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,mBAAmB;IACnB,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,UAAU,GAAG,QAAQ,CAAC;YACtB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,yCAAyC;QACzC,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC;gBAC7B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;aACjC,CAAC;YACF,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAExC,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO;gBACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC;gBACnC,UAAU;aACX,CAAC;QACJ,CAAC;QAED,0CAA0C;QAC1C,qDAAqD;QACrD,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAE/B,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC;YACnC,UAAU;SACX,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACvD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAc,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,YAAY,GAAG;IACnB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB,EAAG,kCAAkC;IACrD,cAAc;IACd,SAAS;CACV,CAAC;AAOF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAC1D,mBAAmB;IACnB,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,UAAU,GAAG,QAAQ,CAAC;YACtB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,yCAAyC;QACzC,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC;gBAC7B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;aACjC,CAAC;YACF,UAAU,EAAE,IAAI;SACjB,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAExC,IAAI,CAAC;QACH,IAAI,GAAG,KAAK,MAAM,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO;gBACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC;gBACnC,UAAU;aACX,CAAC;QACJ,CAAC;QAED,0CAA0C;QAC1C,qDAAqD;QACrD,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;QAC/C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC;QAE/B,OAAO;YACL,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC;YACnC,UAAU;SACX,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2DAA2D;QAC3D,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,eAAe,GAAG,YAAY,CAAC,KAAY,EAAE;gBACjD,MAAM,EAAE,qBAAqB;gBAC7B,eAAe,EAAE,IAAI;aACtB,CAAC,CAAC;YACH,MAAM,IAAI,KAAK,CACb,qBAAqB,UAAU,QAAQ,eAAe,CAAC,OAAO,wDAAwD,CACvH,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,mBAAmB,UAAU,KAAK,KAAK,CAAC,OAAO,kEAAkE,CAClH,CAAC;QACJ,CAAC;QAED,gDAAgD;QAChD,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CACb,8BAA8B,UAAU,iFAAiF,CAC1H,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,8BAA8B,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACvD,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|