vibe-design-system 2.5.49 → 2.5.51
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 +24 -2
- package/package.json +1 -1
- package/vds-core-template/scan.mjs +71 -1
package/bin/init.js
CHANGED
|
@@ -194,12 +194,34 @@ function ensureStorybook(projectRoot) {
|
|
|
194
194
|
fs.writeFileSync(mainPath, STORYBOOK_MAIN_TS, "utf-8");
|
|
195
195
|
console.log("📝 .storybook/main.ts yazıldı.");
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
// preview.ts / preview.tsx — eski VDS template'lerini otomatik olarak yeni router'sız template'e migrate et.
|
|
198
|
+
const previewCandidates = ["preview.tsx", "preview.ts", "preview.jsx", "preview.js"];
|
|
199
|
+
const existingPreview = previewCandidates.find((name) =>
|
|
198
200
|
fs.existsSync(path.join(storybookDir, name))
|
|
199
201
|
);
|
|
200
|
-
|
|
202
|
+
const previewPath = existingPreview ? path.join(storybookDir, existingPreview) : null;
|
|
203
|
+
|
|
204
|
+
if (!previewPath) {
|
|
205
|
+
// Daha önce hiç preview yoksa, yeni template'i yaz.
|
|
201
206
|
fs.writeFileSync(path.join(storybookDir, "preview.ts"), STORYBOOK_PREVIEW_TS, "utf-8");
|
|
202
207
|
console.log("📝 .storybook/preview.ts yazıldı.");
|
|
208
|
+
} else {
|
|
209
|
+
// Eski VDS preview'lerini tespit edip otomatik migrate et; kullanıcıya ait preview'lere dokunma.
|
|
210
|
+
try {
|
|
211
|
+
const content = fs.readFileSync(previewPath, "utf-8");
|
|
212
|
+
const looksLikeOldVdsPreview =
|
|
213
|
+
content.includes('MemoryRouter from "react-router-dom"') ||
|
|
214
|
+
content.includes("const withRouter") ||
|
|
215
|
+
content.includes("decorators: [withRouter");
|
|
216
|
+
if (looksLikeOldVdsPreview) {
|
|
217
|
+
fs.writeFileSync(previewPath, STORYBOOK_PREVIEW_TS, "utf-8");
|
|
218
|
+
console.log("📝 .storybook/preview.* eski VDS şablonundan yeni router'sız şablona güncellendi.");
|
|
219
|
+
} else {
|
|
220
|
+
console.log("ℹ️ .storybook/preview.* bulundu, kullanıcıya ait görünüyor; değiştirilmedi.");
|
|
221
|
+
}
|
|
222
|
+
} catch {
|
|
223
|
+
console.log("⚠️ .storybook/preview.* okunamadı; değiştirilmedi.");
|
|
224
|
+
}
|
|
203
225
|
}
|
|
204
226
|
}
|
|
205
227
|
|
package/package.json
CHANGED
|
@@ -621,7 +621,77 @@ function extractComponentSuggestions() {
|
|
|
621
621
|
reason: `Visual section candidate: same className cluster ${count}×, ${directChildren} child elements`,
|
|
622
622
|
});
|
|
623
623
|
}
|
|
624
|
-
|
|
624
|
+
|
|
625
|
+
// Ek: Tekil büyük bloklar (single large blocks) — tekrar etmese bile component adayı
|
|
626
|
+
const LARGE_BLOCK_MIN_CHILDREN = 5; // en az 5 direkt child
|
|
627
|
+
const LARGE_BLOCK_MIN_CLASS_TOKENS = 4; // className’de en az 4 token
|
|
628
|
+
const MAX_SINGLE_BLOCKS_PER_FILE = 3; // her dosyadan en fazla 3 aday
|
|
629
|
+
|
|
630
|
+
const singleBlockCandidates = [];
|
|
631
|
+
|
|
632
|
+
for (const { fullPath, srcRel } of allPageFiles) {
|
|
633
|
+
let content;
|
|
634
|
+
try {
|
|
635
|
+
content = fs.readFileSync(fullPath, "utf-8");
|
|
636
|
+
} catch {
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
const fileCandidates = [];
|
|
640
|
+
const reSingle = /className\s*=\s*["']([^"']+)["']|className\s*=\s*\{\s*["']([^"']+)["']\s*\}/g;
|
|
641
|
+
let m;
|
|
642
|
+
while ((m = reSingle.exec(content)) !== null) {
|
|
643
|
+
const raw = (m[1] ?? m[2] ?? "").trim().replace(/\s+/g, " ").trim();
|
|
644
|
+
if (!raw) continue;
|
|
645
|
+
const classCount = raw.split(/\s+/).filter(Boolean).length;
|
|
646
|
+
if (classCount < LARGE_BLOCK_MIN_CLASS_TOKENS) continue;
|
|
647
|
+
|
|
648
|
+
const before = content.substring(0, m.index);
|
|
649
|
+
const lastOpen = before.lastIndexOf("<");
|
|
650
|
+
const tagMatch = lastOpen >= 0 ? content.slice(lastOpen).match(/<(\w+)/) : null;
|
|
651
|
+
const tagName = tagMatch ? tagMatch[1] : "div";
|
|
652
|
+
|
|
653
|
+
let fullJsx = null;
|
|
654
|
+
let innerContent = "";
|
|
655
|
+
const extracted = extractFullElement(content, m.index, tagName);
|
|
656
|
+
if (extracted) {
|
|
657
|
+
fullJsx = extracted.fullJsx;
|
|
658
|
+
innerContent = extracted.innerContent || "";
|
|
659
|
+
}
|
|
660
|
+
const directChildren = countDirectChildren(innerContent);
|
|
661
|
+
if (directChildren < LARGE_BLOCK_MIN_CHILDREN) continue;
|
|
662
|
+
|
|
663
|
+
fileCandidates.push({
|
|
664
|
+
tagName,
|
|
665
|
+
pattern: raw,
|
|
666
|
+
fullJsx,
|
|
667
|
+
innerContent,
|
|
668
|
+
directChildren,
|
|
669
|
+
srcRel,
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
fileCandidates
|
|
674
|
+
.sort((a, b) => b.directChildren - a.directChildren)
|
|
675
|
+
.slice(0, MAX_SINGLE_BLOCKS_PER_FILE)
|
|
676
|
+
.forEach((c) => {
|
|
677
|
+
singleBlockCandidates.push({
|
|
678
|
+
suggestedName: sanitizeComponentName(
|
|
679
|
+
(suggestNameFromContent(c.innerContent) ||
|
|
680
|
+
suggestNameFromPattern(c.pattern) ||
|
|
681
|
+
"Section").replace(/\s+/g, "")
|
|
682
|
+
),
|
|
683
|
+
tagName: c.tagName,
|
|
684
|
+
pattern: c.pattern,
|
|
685
|
+
fullJsx: c.fullJsx,
|
|
686
|
+
occurrences: 1,
|
|
687
|
+
foundIn: [c.srcRel],
|
|
688
|
+
snippet: `<${c.tagName} className="${c.pattern}">...</${c.tagName}>`,
|
|
689
|
+
reason: `Large visual block candidate: ${c.directChildren} direct children, rich className`,
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
return suggestions.concat(singleBlockCandidates);
|
|
625
695
|
}
|
|
626
696
|
|
|
627
697
|
/** src/pages/ içinde tanımlı ama src/components'a çıkarılmamış visual section'ları listele (component adayı raporu). */
|