vibe-design-system 2.8.38 → 2.8.40

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
@@ -316,6 +316,12 @@ function buildStorybookPreviewTs(framework, projectRoot) {
316
316
  ["src/globals.css", "../src/globals.css"],
317
317
  ["src/styles/globals.css", "../src/styles/globals.css"],
318
318
  ["app/globals.css", "../app/globals.css"],
319
+ // Fullstack / monorepo patterns (client/, frontend/, web/)
320
+ ["client/src/index.css", "../client/src/index.css"],
321
+ ["client/src/globals.css", "../client/src/globals.css"],
322
+ ["frontend/src/index.css", "../frontend/src/index.css"],
323
+ ["frontend/src/globals.css", "../frontend/src/globals.css"],
324
+ ["web/src/index.css", "../web/src/index.css"],
319
325
  ];
320
326
  let cssImport = '// CSS bulunamadı — projenizin global CSS dosyasını buraya ekleyin';
321
327
  for (const [rel, importPath] of cssCandidates) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.8.38",
3
+ "version": "2.8.40",
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");
@@ -206,6 +206,52 @@ function injectAliases(projectRoot, specifiers) {
206
206
 
207
207
  /** Inject resolve.dedupe into .storybook/main.* viteFinal to prevent multiple React instances.
208
208
  * Multiple React instances cause "Cannot read properties of null (reading 'useRef')" at MemoryRouter. */
209
+ /** Read vite.config.ts/js and extract path.resolve alias entries.
210
+ * Injects any missing aliases into .storybook/main.ts viteFinal. */
211
+ function injectViteConfigAliases(projectRoot) {
212
+ const mainPath = getMainPath(projectRoot);
213
+ if (!mainPath) return;
214
+
215
+ // Find the project's vite config
216
+ const viteConfigCandidates = ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"];
217
+ let viteConfigContent = null;
218
+ for (const name of viteConfigCandidates) {
219
+ const p = path.join(projectRoot, name);
220
+ if (fs.existsSync(p)) { viteConfigContent = fs.readFileSync(p, "utf-8"); break; }
221
+ }
222
+ if (!viteConfigContent) return;
223
+
224
+ // Extract alias entries like: "@shared": path.resolve(..., "shared")
225
+ const aliasRe = /["'](@[^"']+)["']\s*:\s*path\.resolve\([^)]*,\s*["']([^"']+)["']\s*\)/g;
226
+ const viteAliases = {};
227
+ let m;
228
+ while ((m = aliasRe.exec(viteConfigContent)) !== null) {
229
+ viteAliases[m[1]] = m[2]; // e.g. "@shared" -> "shared"
230
+ }
231
+ if (Object.keys(viteAliases).length === 0) return;
232
+
233
+ // Read current main.ts
234
+ let mainContent = fs.readFileSync(mainPath, "utf-8");
235
+
236
+ // Find which aliases are missing
237
+ const missingAliases = Object.entries(viteAliases).filter(([key]) => !mainContent.includes(`"${key}"`));
238
+ if (missingAliases.length === 0) return;
239
+
240
+ // Inject missing aliases into the existing alias block
241
+ const aliasBlockRe = /(\balias\s*:\s*\{)([^}]*)(\})/;
242
+ if (!aliasBlockRe.test(mainContent)) return;
243
+
244
+ const additions = missingAliases
245
+ .map(([key, dir]) => `\n "${key}": path.resolve(process.cwd(), "${dir}"),`)
246
+ .join("");
247
+
248
+ mainContent = mainContent.replace(aliasBlockRe, (_, open, body, close) =>
249
+ `${open}${body}${additions}\n ${close}`
250
+ );
251
+ fs.writeFileSync(mainPath, mainContent, "utf-8");
252
+ console.log(`[VDS] Storybook adapt: injected vite aliases: ${missingAliases.map(([k]) => k).join(", ")}`);
253
+ }
254
+
209
255
  function injectDedupe(projectRoot) {
210
256
  const mainPath = getMainPath(projectRoot);
211
257
  if (!mainPath) return;
@@ -231,6 +277,8 @@ function main() {
231
277
  }
232
278
  // Always inject dedupe — prevents "useRef null" crashes from multiple React instances
233
279
  injectDedupe(projectRoot);
280
+ // Propagate aliases from project's vite.config.ts to Storybook
281
+ injectViteConfigAliases(projectRoot);
234
282
  reportUnresolvedImports(projectRoot);
235
283
  const problematic = collectProblematicImports(projectRoot);
236
284
  if (problematic.size === 0) return;