vibe-design-system 2.8.36 → 2.8.39

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 CHANGED
@@ -223,14 +223,45 @@ function detectFramework(pkg) {
223
223
  return "vite";
224
224
  }
225
225
 
226
+ /** Vite 7+ kullanılıyorsa Storybook 8 peer dep çakışır.
227
+ * .npmrc'ye legacy-peer-deps=true ekleyerek tüm npm komutlarını bağışık hale getirir. */
228
+ function ensureLegacyPeerDepsIfNeeded(projectRoot, pkg) {
229
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
230
+ const viteVersion = allDeps["vite"] || "";
231
+ // "^7.x", "~7.x", "7.x" gibi tüm Vite 7+ versiyonlarını yakala
232
+ const isVite7Plus = /^\^?~?[7-9]\d*\./.test(viteVersion) || /^\^?~?[1-9]\d+\./.test(viteVersion);
233
+ if (!isVite7Plus) return;
234
+ const npmrcPath = path.join(projectRoot, ".npmrc");
235
+ let content = fs.existsSync(npmrcPath) ? fs.readFileSync(npmrcPath, "utf-8") : "";
236
+ if (content.includes("legacy-peer-deps")) return; // idempotent
237
+ content = content ? content.trimEnd() + "\nlegacy-peer-deps=true\n" : "legacy-peer-deps=true\n";
238
+ fs.writeFileSync(npmrcPath, content, "utf-8");
239
+ console.log("📝 .npmrc: legacy-peer-deps=true eklendi (Vite 7+ / Storybook 8 uyumluluk).");
240
+ }
241
+
226
242
  /** Framework'e göre Storybook framework paket adı */
227
243
  function storybookFrameworkPackage(framework) {
228
244
  if (framework === "nextjs") return "@storybook/nextjs";
229
245
  return "@storybook/react-vite"; // vite & remix
230
246
  }
231
247
 
248
+ /** Projenin gerçek frontend src dizinini tespit eder.
249
+ * Fullstack projelerde (client/, frontend/, web/) doğru alias için gerekli. */
250
+ function detectFrontendSrcDir(projectRoot) {
251
+ // Fullstack / monorepo: frontend ayrı bir klasörde olabilir
252
+ const candidates = [
253
+ "client/src",
254
+ "frontend/src",
255
+ "web/src",
256
+ ];
257
+ for (const c of candidates) {
258
+ if (fs.existsSync(path.join(projectRoot, c))) return c;
259
+ }
260
+ return "src"; // varsayılan
261
+ }
262
+
232
263
  /** Framework'e göre .storybook/main.ts içeriği */
233
- function buildStorybookMainTs(framework) {
264
+ function buildStorybookMainTs(framework, projectRoot) {
234
265
  if (framework === "nextjs") {
235
266
  return `import type { StorybookConfig } from "@storybook/nextjs";
236
267
 
@@ -250,6 +281,7 @@ export default config;
250
281
  `;
251
282
  }
252
283
  // vite (default) & remix
284
+ const srcDir = detectFrontendSrcDir(projectRoot || process.cwd());
253
285
  return `import type { StorybookConfig } from "@storybook/react-vite";
254
286
  import { mergeConfig } from "vite";
255
287
  import path from "path";
@@ -265,7 +297,7 @@ const config: StorybookConfig = {
265
297
  return mergeConfig(config, {
266
298
  resolve: {
267
299
  alias: {
268
- "@": path.resolve(process.cwd(), "src"),
300
+ "@": path.resolve(process.cwd(), "${srcDir}"),
269
301
  },
270
302
  },
271
303
  });
@@ -365,10 +397,11 @@ function ensureStorybook(projectRoot, framework) {
365
397
  console.log("📁 .storybook/ oluşturuldu.");
366
398
  }
367
399
 
368
- const mainTs = buildStorybookMainTs(framework);
400
+ const mainTs = buildStorybookMainTs(framework, projectRoot);
369
401
  const mainPath = path.join(storybookDir, "main.ts");
370
402
  fs.writeFileSync(mainPath, mainTs, "utf-8");
371
- console.log(`📝 .storybook/main.ts yazıldı (framework: ${framework}).`);
403
+ const detectedSrc = detectFrontendSrcDir(projectRoot);
404
+ console.log(`📝 .storybook/main.ts yazıldı (framework: ${framework}, @ alias: ${detectedSrc}).`);
372
405
 
373
406
  const previewTs = buildStorybookPreviewTs(framework, projectRoot);
374
407
 
@@ -612,6 +645,9 @@ if (monorepoPackages.length > 0 && pkg.workspaces) {
612
645
  const framework = detectFramework(pkg);
613
646
  console.log(`🔍 Framework tespit edildi: ${framework}\n`);
614
647
 
648
+ // Vite 7+ projelerinde Storybook 8 peer dep çakışmasını önle
649
+ ensureLegacyPeerDepsIfNeeded(projectRoot, pkg);
650
+
615
651
  // ADIM 1
616
652
  if (needsStorybook(projectRoot, framework)) {
617
653
  installStorybook(projectRoot, framework);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.8.36",
3
+ "version": "2.8.39",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "homepage": "https://vibedesign.tech",
6
6
  "repository": {
@@ -14,9 +14,18 @@ import { fileURLToPath } from "url";
14
14
 
15
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
16
  const PROJECT_ROOT = path.join(__dirname, "..");
17
- const SRC_DIR = path.join(PROJECT_ROOT, "src");
18
17
  const STORYBOOK_DIR = path.join(PROJECT_ROOT, ".storybook");
19
18
 
19
+ /** Projenin gerçek frontend src dizinini tespit eder (fullstack/monorepo desteği). */
20
+ function detectSrcDir(root) {
21
+ for (const candidate of ["client/src", "frontend/src", "web/src"]) {
22
+ if (fs.existsSync(path.join(root, candidate))) return path.join(root, candidate);
23
+ }
24
+ return path.join(root, "src");
25
+ }
26
+
27
+ const SRC_DIR = detectSrcDir(PROJECT_ROOT);
28
+
20
29
  // ── vds.config.js loader ──────────────────────────────────────────────────────
21
30
  function loadVdsConfig() {
22
31
  const configPath = path.join(PROJECT_ROOT, "vds.config.js");
@@ -119,8 +128,9 @@ function detectHooksInFile(content) {
119
128
 
120
129
  /** Map: relative path (src/...) -> Set of hook names */
121
130
  function detectHooksUsedInProject(projectRoot) {
122
- const srcDir = path.join(projectRoot, "src");
123
- const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join("src", r));
131
+ const srcDir = detectSrcDir(projectRoot);
132
+ const srcRel = path.relative(projectRoot, srcDir).replace(/\\/g, "/");
133
+ const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(srcRel, r));
124
134
  const byFile = new Map();
125
135
  for (const rel of files) {
126
136
  const full = path.join(projectRoot, rel);
@@ -135,8 +145,9 @@ function detectHooksUsedInProject(projectRoot) {
135
145
 
136
146
  /** Find file that exports providerName (e.g. TimerProvider). If hookName is given, prefer a file that also contains that hook (e.g. context/SidebarContext.tsx for useSidebar over ui/sidebar). */
137
147
  function findProviderExportPath(projectRoot, providerName, hookName) {
138
- const srcDir = path.join(projectRoot, "src");
139
- const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join("src", r));
148
+ const srcDir = detectSrcDir(projectRoot);
149
+ const srcRel = path.relative(projectRoot, srcDir).replace(/\\/g, "/");
150
+ const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(srcRel, r));
140
151
  const exportRe = new RegExp(
141
152
  "export\\s+(?:default\\s+)?(?:const|function|class)\\s+" + providerName + "\\b|export\\s*\\{[^}]*\\b" + providerName + "\\b[^}]*\\}"
142
153
  );
@@ -146,7 +157,8 @@ function findProviderExportPath(projectRoot, providerName, hookName) {
146
157
  try {
147
158
  const content = fs.readFileSync(full, "utf-8");
148
159
  if (exportRe.test(content)) {
149
- const withoutExt = rel.replace(/\.(tsx?|jsx?)$/i, "").replace(/^src\/?/, "");
160
+ // Strip the src prefix (could be "src", "client/src", "frontend/src", etc.)
161
+ const withoutExt = rel.replace(/\.(tsx?|jsx?)$/i, "").replace(new RegExp("^" + srcRel.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "\\/?"), "");
150
162
  const pathForImport = "@/" + withoutExt;
151
163
  const hasHook = hookName && new RegExp("\\b" + hookName + "\\b").test(content);
152
164
  candidates.push({ pathForImport, hasHook });
@@ -190,9 +202,9 @@ function detectRouterPackage(projectRoot) {
190
202
  }
191
203
 
192
204
  function projectUsesRouterHooks(projectRoot) {
193
- const srcDir = path.join(projectRoot, "src");
205
+ const srcDir = detectSrcDir(projectRoot);
194
206
  if (!fs.existsSync(srcDir)) return false;
195
- const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(projectRoot, "src", r));
207
+ const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(srcDir, r));
196
208
  for (const file of files) {
197
209
  try {
198
210
  const content = fs.readFileSync(file, "utf-8");
@@ -206,8 +218,8 @@ function projectUsesRouterHooks(projectRoot) {
206
218
 
207
219
  /** Detect if project uses react-dnd (useDrag, useDrop, or import from react-dnd). */
208
220
  function detectReactDnd(projectRoot) {
209
- const srcDir = path.join(projectRoot, "src");
210
- const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(projectRoot, "src", r));
221
+ const srcDir = detectSrcDir(projectRoot);
222
+ const files = getAllSourceFiles(srcDir, srcDir).map((r) => path.join(srcDir, r));
211
223
  for (const full of files) {
212
224
  try {
213
225
  const content = fs.readFileSync(full, "utf-8");