inai-react-components 1.6.1 → 1.6.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.
@@ -274,14 +274,24 @@ export declare function getLegacyTailwindCssTemplate(theme: Theme, fontBody: Fon
274
274
  export declare function normalizeThemeCss(css: string, theme: string): string;
275
275
  /**
276
276
  * Copies the i18n base files (context, types, defaults) from the registry
277
- * to `<sourceRoot>/lib/`. ~75 components import `useUIMessages` from the
278
- * i18n context; the CLI rewrites those imports at install-time to the
279
- * unified `aliases.lib` directory, so the files must land there.
277
+ * to the unified lib directory. ~75 components import `useUIMessages`
278
+ * from the i18n context; the CLI rewrites those imports at install-time
279
+ * to the `aliases.lib` directory, so the files must land there.
280
280
  *
281
- * Never overwrites pre-existing files so a user's custom i18n provider
282
- * stays intact across re-runs.
281
+ * Normalizes `.js` import suffixes in the process (so the copied
282
+ * `i18n-context.tsx` reads without bundler-incompatible extensions) and
283
+ * never overwrites pre-existing files.
283
284
  */
284
285
  export declare function copyI18nFiles(registryDir: string | undefined, targetDir: string, libDirRelative: string): string[];
286
+ /**
287
+ * Copies the canonical `cn.ts` from the cached registry to the user's
288
+ * lib directory. We copy the REAL source file (not a hardcoded template)
289
+ * because components import extra type exports like `ClassNames` that
290
+ * any minimal template would miss. Returns `true` if the file was
291
+ * written, `false` if the registry copy was missing or a user file was
292
+ * already present.
293
+ */
294
+ export declare function copyCnFile(registryDir: string | undefined, targetDir: string, libDirRelative: string): boolean;
285
295
  export declare function runInit(config: InitConfig, targetDir: string, repoUrl?: string): Promise<{
286
296
  success: boolean;
287
297
  filesCreated: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAOA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAIrC,KAAK,KAAK,GAAG,MAAM,CAAC;AAEpB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DR,CAAC;AACX,KAAK,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAUxD,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;IACrB,WAAW,EAAE,UAAU,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE;QACJ,IAAI,EAAE,UAAU,CAAC;QACjB,OAAO,EAAE,UAAU,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;QACf,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;CACH;AAgBD,wBAAsB,gBAAgB,CACpC,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,SAAS,EACrB,MAAM,CAAC,EAAE,aAAa,GACrB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA0F5B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,cAAc,CA8ChB;AAED,wBAAgB,aAAa,IAAI,MAAM,CAQtC;AAOD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAc/H;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAahI;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAoBpE;AAsHD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,MAAM,EAAE,CAeV;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,OAAO,CAKT;AAED,wBAAsB,OAAO,CAC3B,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA0FvD;AAED,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EjE"}
@@ -7,6 +7,7 @@ import { cloneRegistry, getCacheDir } from "../utils/registry-resolver.js";
7
7
  import { THEME_NAMES } from "../utils/themes.js";
8
8
  import { detectFramework, frameworkLabel, getCssEntryPoint, } from "../utils/framework-detect.js";
9
9
  import { detectProjectLayout, } from "../utils/tsconfig-detect.js";
10
+ import { stripRelativeJsExtensions } from "../utils/paths.js";
10
11
  const AVAILABLE_THEMES = THEME_NAMES;
11
12
  const FONT_PRESETS = [
12
13
  // Sans-serif — geometric & modern
@@ -351,14 +352,41 @@ function copyTokensToProject(registryDir, targetDir, theme, sourceRoot) {
351
352
  }
352
353
  return copied;
353
354
  }
355
+ /**
356
+ * Read a source file from the registry and write it to the user's lib
357
+ * directory with imports normalized — `.js` suffixes stripped so the
358
+ * installed code reads naturally under bundler-style resolution (Vite,
359
+ * Next.js, TanStack Start, …). Never overwrites a pre-existing file so
360
+ * user customizations stay intact across re-runs.
361
+ *
362
+ * Returns the relative destination path if written, or `null` if skipped
363
+ * (file missing in registry, or already present in the user project).
364
+ */
365
+ function copyLibFileNormalized(srcPath, destPath) {
366
+ if (!fs.existsSync(srcPath))
367
+ return false;
368
+ if (fs.existsSync(destPath))
369
+ return false; // don't clobber user files
370
+ const raw = fs.readFileSync(srcPath, "utf-8");
371
+ // Strip `.js` from relative sibling imports so `i18n-context.tsx`'s
372
+ // `./i18n-types.js` becomes `./i18n-types`. We intentionally DON'T
373
+ // apply `rewriteLibImports` here — these files live inside the lib
374
+ // directory already, so their sibling imports are correctly relative
375
+ // and shouldn't be rerouted through the `@/lib/*` alias.
376
+ const normalized = stripRelativeJsExtensions(raw);
377
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
378
+ fs.writeFileSync(destPath, normalized);
379
+ return true;
380
+ }
354
381
  /**
355
382
  * Copies the i18n base files (context, types, defaults) from the registry
356
- * to `<sourceRoot>/lib/`. ~75 components import `useUIMessages` from the
357
- * i18n context; the CLI rewrites those imports at install-time to the
358
- * unified `aliases.lib` directory, so the files must land there.
383
+ * to the unified lib directory. ~75 components import `useUIMessages`
384
+ * from the i18n context; the CLI rewrites those imports at install-time
385
+ * to the `aliases.lib` directory, so the files must land there.
359
386
  *
360
- * Never overwrites pre-existing files so a user's custom i18n provider
361
- * stays intact across re-runs.
387
+ * Normalizes `.js` import suffixes in the process (so the copied
388
+ * `i18n-context.tsx` reads without bundler-incompatible extensions) and
389
+ * never overwrites pre-existing files.
362
390
  */
363
391
  export function copyI18nFiles(registryDir, targetDir, libDirRelative) {
364
392
  if (!registryDir)
@@ -366,20 +394,31 @@ export function copyI18nFiles(registryDir, targetDir, libDirRelative) {
366
394
  const files = ["i18n-context.tsx", "i18n-types.ts", "i18n-defaults.ts"];
367
395
  const srcBase = path.join(registryDir, "packages", "ui", "src", "lib");
368
396
  const destBase = path.join(targetDir, libDirRelative);
369
- fs.mkdirSync(destBase, { recursive: true });
370
397
  const copied = [];
371
398
  for (const file of files) {
372
399
  const src = path.join(srcBase, file);
373
- if (!fs.existsSync(src))
374
- continue;
375
400
  const dest = path.join(destBase, file);
376
- if (fs.existsSync(dest))
377
- continue; // don't clobber user files
378
- fs.copyFileSync(src, dest);
379
- copied.push(`${libDirRelative}/${file}`);
401
+ if (copyLibFileNormalized(src, dest)) {
402
+ copied.push(`${libDirRelative}/${file}`);
403
+ }
380
404
  }
381
405
  return copied;
382
406
  }
407
+ /**
408
+ * Copies the canonical `cn.ts` from the cached registry to the user's
409
+ * lib directory. We copy the REAL source file (not a hardcoded template)
410
+ * because components import extra type exports like `ClassNames` that
411
+ * any minimal template would miss. Returns `true` if the file was
412
+ * written, `false` if the registry copy was missing or a user file was
413
+ * already present.
414
+ */
415
+ export function copyCnFile(registryDir, targetDir, libDirRelative) {
416
+ if (!registryDir)
417
+ return false;
418
+ const src = path.join(registryDir, "packages", "ui", "src", "lib", "cn.ts");
419
+ const dest = path.join(targetDir, libDirRelative, "cn.ts");
420
+ return copyLibFileNormalized(src, dest);
421
+ }
383
422
  export async function runInit(config, targetDir, repoUrl) {
384
423
  const filesCreated = [];
385
424
  const sourceRoot = config.layout?.sourceRoot ?? "src";
@@ -393,27 +432,30 @@ export async function runInit(config, targetDir, repoUrl) {
393
432
  fs.mkdirSync(componentDir, { recursive: true });
394
433
  const blockDir = path.join(targetDir, config.blockPath);
395
434
  fs.mkdirSync(blockDir, { recursive: true });
396
- // 3. Create the unified lib directory under `<sourceRoot>/lib/` and
397
- // seed it with `cn.ts`. Every component/block lib file ships here;
398
- // the CLI rewrites all imports at install-time to point at the
399
- // `aliases.lib` alias so there's a single source of truth.
400
- //
401
- // Never overwrite an existing `cn.ts` the user may have their own.
435
+ // 3. Create the unified lib directory under `<sourceRoot>/lib/`. Every
436
+ // component/block lib file ships here; the CLI rewrites all imports
437
+ // at install-time to point at the `aliases.lib` alias so there's a
438
+ // single source of truth. `cn.ts` is seeded here so `init` users
439
+ // can start writing app code immediately — the real file (not a
440
+ // hardcoded template) is copied from the registry so secondary
441
+ // exports like `ClassNames` stay available to components. Never
442
+ // overwrite existing user files.
402
443
  const libDirRelative = `${sourceRoot}/lib`;
403
444
  const libDir = path.join(targetDir, libDirRelative);
404
445
  fs.mkdirSync(libDir, { recursive: true });
405
- const cnPath = path.join(libDir, "cn.ts");
406
- if (!fs.existsSync(cnPath)) {
407
- fs.writeFileSync(cnPath, getCnTemplate());
408
- filesCreated.push(`${libDirRelative}/cn.ts`);
409
- }
410
446
  // 4. Copy tokens and create CSS
411
447
  const cssRelPath = config.cssEntryPoint ?? `${sourceRoot}/index.css`;
412
448
  const cssPath = path.join(targetDir, cssRelPath);
413
449
  fs.mkdirSync(path.dirname(cssPath), { recursive: true });
414
450
  if (repoUrl) {
415
- // Remote mode: copy tokens from cached registry
451
+ // Remote mode: copy tokens and canonical lib files from the cached
452
+ // registry so users get the real `cn.ts` (including type exports
453
+ // like `ClassNames` that downstream components import) rather than
454
+ // a minimal hardcoded template.
416
455
  const registryDir = getCacheDir();
456
+ if (copyCnFile(registryDir, targetDir, libDirRelative)) {
457
+ filesCreated.push(`${libDirRelative}/cn.ts`);
458
+ }
417
459
  const tokenFiles = copyTokensToProject(registryDir, targetDir, config.theme, sourceRoot);
418
460
  filesCreated.push(...tokenFiles);
419
461
  // Copy i18n base files to the unified lib directory so that components'
@@ -424,7 +466,15 @@ export async function runInit(config, targetDir, repoUrl) {
424
466
  fs.writeFileSync(cssPath, getLocalTailwindCssTemplate(config.theme, config.fontBody, config.fontHeading, config.radius));
425
467
  }
426
468
  else {
427
- // Local mode: reference @company/tokens package
469
+ // Local mode: reference @company/tokens package. Without a registry
470
+ // to read from, we seed `cn.ts` with a minimal template — users in
471
+ // this mode are almost always developing the monorepo itself, where
472
+ // the real `@company/ui` package is resolvable via workspace links.
473
+ const cnPath = path.join(libDir, "cn.ts");
474
+ if (!fs.existsSync(cnPath)) {
475
+ fs.writeFileSync(cnPath, getCnTemplate());
476
+ filesCreated.push(`${libDirRelative}/cn.ts`);
477
+ }
428
478
  fs.writeFileSync(cssPath, getLegacyTailwindCssTemplate(config.theme, config.fontBody, config.fontHeading, config.radius));
429
479
  }
430
480
  filesCreated.push(cssRelPath);
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ const program = new Command();
17
17
  program
18
18
  .name("inai-ui")
19
19
  .description("CLI for InAI UI component library")
20
- .version("1.6.1");
20
+ .version("1.6.2");
21
21
  program
22
22
  .command("init [repo-url]")
23
23
  .description("Initialize InAI UI in your project. Optionally pass a Git repo URL to fetch components remotely.")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inai-react-components",
3
- "version": "1.6.1",
3
+ "version": "1.6.2",
4
4
  "description": "CLI for InAI UI component library — install components from a private registry into your React project",
5
5
  "private": false,
6
6
  "type": "module",