vibe-design-system 1.2.1 → 1.3.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/bin/init.js +8 -0
- package/package.json +1 -1
- package/vds-core-template/scan.mjs +133 -1
package/bin/init.js
CHANGED
|
@@ -90,6 +90,14 @@ function addVdsRouteToApp(projectRoot) {
|
|
|
90
90
|
console.log("🎨 VDS kuruluyor...");
|
|
91
91
|
|
|
92
92
|
const projectRoot = getProjectRoot();
|
|
93
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
94
|
+
if (!fs.existsSync(pkgPath)) {
|
|
95
|
+
console.error("❌ Bu klasörde package.json bulunamadı.");
|
|
96
|
+
console.error("VDS, mevcut bir React projesine kurulmalıdır.");
|
|
97
|
+
console.error("Cursor'da projenizi açın ve o projenin terminalinde çalıştırın.");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
const vdsCoreDest = path.join(projectRoot, "vds-core");
|
|
94
102
|
|
|
95
103
|
if (!fs.existsSync(vdsCoreDest)) {
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import fs from "fs";
|
|
|
8
8
|
import path from "path";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
import { createRequire } from "module";
|
|
11
|
+
import { execSync } from "child_process";
|
|
11
12
|
|
|
12
13
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
14
|
const PROJECT_ROOT = path.join(__dirname, "..");
|
|
@@ -31,6 +32,22 @@ const OUTPUT_FILE = path.join(PROJECT_ROOT, "vds-output.json");
|
|
|
31
32
|
const PUBLIC_MANIFEST = path.join(PROJECT_ROOT, "public", "vds-output.json");
|
|
32
33
|
const HISTORY_FILE = path.join(PROJECT_ROOT, "vds-history.json");
|
|
33
34
|
|
|
35
|
+
function getGitBranch() {
|
|
36
|
+
try {
|
|
37
|
+
return execSync("git branch --show-current", { cwd: PROJECT_ROOT, encoding: "utf-8" }).trim() || null;
|
|
38
|
+
} catch (_) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getGitEngineer() {
|
|
44
|
+
try {
|
|
45
|
+
return execSync("git config user.name", { cwd: PROJECT_ROOT, encoding: "utf-8" }).trim() || null;
|
|
46
|
+
} catch (_) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
34
51
|
function incPatch(version) {
|
|
35
52
|
const parts = String(version || "1.0.0").split(".");
|
|
36
53
|
const major = parseInt(parts[0], 10) || 1;
|
|
@@ -208,6 +225,44 @@ function getAllTsxJsxInDir(dir) {
|
|
|
208
225
|
return getAllComponentFiles(dir, dir);
|
|
209
226
|
}
|
|
210
227
|
|
|
228
|
+
const BRAND_KEYWORDS = /logo|brand|icon|favicon|emblem|mark/i;
|
|
229
|
+
const BRAND_EXTENSIONS = /\.(svg|png|ico)$/i;
|
|
230
|
+
|
|
231
|
+
function getFilesByExtension(dir, extRe, baseDir = dir) {
|
|
232
|
+
if (!fs.existsSync(dir)) return [];
|
|
233
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
234
|
+
const files = [];
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
const fullPath = path.join(dir, entry.name);
|
|
237
|
+
if (entry.isDirectory()) {
|
|
238
|
+
files.push(...getFilesByExtension(fullPath, extRe, baseDir));
|
|
239
|
+
} else if (entry.isFile() && extRe.test(entry.name)) {
|
|
240
|
+
files.push(path.relative(baseDir, fullPath).replace(/\\/g, "/"));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return files;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Scan public/, src/assets/, src/images/ for .svg, .png, .ico; filter by brand keywords. */
|
|
247
|
+
function extractBrandAssets() {
|
|
248
|
+
const assets = [];
|
|
249
|
+
const dirs = [
|
|
250
|
+
path.join(PROJECT_ROOT, "public"),
|
|
251
|
+
path.join(PROJECT_ROOT, "src", "assets"),
|
|
252
|
+
path.join(PROJECT_ROOT, "src", "images"),
|
|
253
|
+
];
|
|
254
|
+
for (const dir of dirs) {
|
|
255
|
+
const files = getFilesByExtension(dir, BRAND_EXTENSIONS, PROJECT_ROOT);
|
|
256
|
+
for (const filePath of files) {
|
|
257
|
+
const baseName = path.basename(filePath);
|
|
258
|
+
if (!BRAND_KEYWORDS.test(baseName)) continue;
|
|
259
|
+
const type = /favicon|\.ico$/i.test(baseName) ? "favicon" : /logo|brand|emblem|mark/i.test(baseName) ? "logo" : "icon";
|
|
260
|
+
assets.push({ path: filePath, name: baseName, type });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return assets;
|
|
264
|
+
}
|
|
265
|
+
|
|
211
266
|
/** Extract icon names from `import { A, B, C } from "lucide-react"` (or 'lucide-react'). Returns unique list. */
|
|
212
267
|
function extractLucideIconsUsed(srcDir) {
|
|
213
268
|
const files = getAllTsxJsxInDir(srcDir);
|
|
@@ -505,7 +560,10 @@ function scan() {
|
|
|
505
560
|
}
|
|
506
561
|
const foundations = extractFoundations();
|
|
507
562
|
foundations.icons = extractLucideIconsUsed(SRC_DIR);
|
|
563
|
+
foundations.brand = { assets: extractBrandAssets() };
|
|
508
564
|
const output = {
|
|
565
|
+
branch: getGitBranch(),
|
|
566
|
+
engineer: getGitEngineer(),
|
|
509
567
|
scannedAt: new Date().toISOString(),
|
|
510
568
|
totalComponents: results.length,
|
|
511
569
|
components: results,
|
|
@@ -528,6 +586,8 @@ function scan() {
|
|
|
528
586
|
const historyEntry = {
|
|
529
587
|
version: nextVersion,
|
|
530
588
|
timestamp: new Date().toISOString(),
|
|
589
|
+
branch: getGitBranch(),
|
|
590
|
+
engineer: getGitEngineer(),
|
|
531
591
|
changes,
|
|
532
592
|
};
|
|
533
593
|
const entries = readHistoryEntries();
|
|
@@ -540,9 +600,81 @@ function scan() {
|
|
|
540
600
|
}
|
|
541
601
|
}
|
|
542
602
|
|
|
603
|
+
function loadVdsOutputFromBranch(branch) {
|
|
604
|
+
try {
|
|
605
|
+
const raw = execSync(`git show ${branch}:vds-output.json`, { cwd: PROJECT_ROOT, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 });
|
|
606
|
+
return JSON.parse(raw);
|
|
607
|
+
} catch (_) {
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function componentSignature(c) {
|
|
613
|
+
return JSON.stringify({ name: c.name, group: c.group, category: c.category, tokens: (c.tokens || []).slice().sort() });
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function runCompare() {
|
|
617
|
+
const argv = process.argv.slice(2);
|
|
618
|
+
const idx = argv.indexOf("--compare");
|
|
619
|
+
const branch1 = idx >= 0 ? argv[idx + 1] : null;
|
|
620
|
+
const branch2 = idx >= 0 ? argv[idx + 2] : null;
|
|
621
|
+
if (!branch1 || !branch2) {
|
|
622
|
+
console.error("Kullanım: node vds-core/scan.mjs --compare <branch1> <branch2>");
|
|
623
|
+
process.exit(1);
|
|
624
|
+
}
|
|
625
|
+
const data1 = loadVdsOutputFromBranch(branch1);
|
|
626
|
+
const data2 = loadVdsOutputFromBranch(branch2);
|
|
627
|
+
if (!data1 || !data1.components) {
|
|
628
|
+
console.error(`vds-output.json bulunamadı veya geçersiz: ${branch1}. Önce o branch'te 'npm run vds' çalıştırın.`);
|
|
629
|
+
process.exit(1);
|
|
630
|
+
}
|
|
631
|
+
if (!data2 || !data2.components) {
|
|
632
|
+
console.error(`vds-output.json bulunamadı veya geçersiz: ${branch2}. Önce o branch'te 'npm run vds' çalıştırın.`);
|
|
633
|
+
process.exit(1);
|
|
634
|
+
}
|
|
635
|
+
const byFile1 = new Map(data1.components.map((c) => [c.file, c]));
|
|
636
|
+
const byFile2 = new Map(data2.components.map((c) => [c.file, c]));
|
|
637
|
+
const files1 = new Set(byFile1.keys());
|
|
638
|
+
const files2 = new Set(byFile2.keys());
|
|
639
|
+
const commonFiles = [...files1].filter((f) => files2.has(f));
|
|
640
|
+
const only1 = [...files1].filter((f) => !files2.has(f));
|
|
641
|
+
const only2 = [...files2].filter((f) => !files1.has(f));
|
|
642
|
+
const different = commonFiles.filter((f) => componentSignature(byFile1.get(f)) !== componentSignature(byFile2.get(f)));
|
|
643
|
+
const commonCount = commonFiles.length - different.length;
|
|
644
|
+
|
|
645
|
+
const label1 = branch1.length > 20 ? branch1.slice(0, 17) + "…" : branch1;
|
|
646
|
+
const label2 = branch2.length > 20 ? branch2.slice(0, 17) + "…" : branch2;
|
|
647
|
+
console.log(`\n📊 Branch karşılaştırma: ${label1} vs ${label2}\n`);
|
|
648
|
+
console.log(`✅ Ortak: ${commonCount} component`);
|
|
649
|
+
if (different.length > 0) {
|
|
650
|
+
different.forEach((file) => {
|
|
651
|
+
const c = byFile1.get(file);
|
|
652
|
+
console.log(`🟡 Farklılaşan: ${c.name} (token veya meta farkı)`);
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
if (only1.length > 0) {
|
|
656
|
+
only1.forEach((file) => {
|
|
657
|
+
const c = byFile1.get(file);
|
|
658
|
+
const shortBranch = branch1.length > 15 ? branch1.replace(/^[^/]+\//, "").slice(0, 12) : branch1;
|
|
659
|
+
console.log(`🔴 Sadece ${shortBranch}'ta: ${c.name}`);
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
if (only2.length > 0) {
|
|
663
|
+
only2.forEach((file) => {
|
|
664
|
+
const c = byFile2.get(file);
|
|
665
|
+
const shortBranch = branch2.length > 15 ? branch2.replace(/^[^/]+\//, "").slice(0, 12) : branch2;
|
|
666
|
+
console.log(`🔴 Sadece ${shortBranch}'ta: ${c.name}`);
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
console.log("");
|
|
670
|
+
}
|
|
671
|
+
|
|
543
672
|
const isWatch = process.argv.includes("--watch");
|
|
673
|
+
const isCompare = process.argv.includes("--compare");
|
|
544
674
|
|
|
545
|
-
if (
|
|
675
|
+
if (isCompare) {
|
|
676
|
+
runCompare();
|
|
677
|
+
} else if (isWatch) {
|
|
546
678
|
if (!fs.existsSync(COMPONENTS_DIR)) {
|
|
547
679
|
console.error(CLI_LOCALES[CLI_LOCALE].componentsNotFound);
|
|
548
680
|
process.exit(1);
|