inai-react-components 1.5.1 → 1.6.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/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +81 -96
- package/dist/commands/init.d.ts +8 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +35 -18
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/paths.d.ts +50 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +87 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EAExB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAKA,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,kBAAkB,EAExB,MAAM,aAAa,CAAC;AA0BrB,MAAM,WAAW,UAAU;IACzB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oDAAoD;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kEAAkE;IAClE,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd,CAsCA;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE;IAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,iBAAiB,EAAE,CAAA;CAAE,EAC1G,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,iBAAiB,GAAG,IAAI,CAc1B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,iBAAiB,EAC5B,cAAc,EAAE,kBAAkB,GACjC,MAAM,CAiBR;AAgRD,wBAAsB,MAAM,CAC1B,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,UAAe,GACvB,OAAO,CAAC,SAAS,CAAC,CAmMpB;AAqCD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,UAAU,CAC9B,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqIf"}
|
package/dist/commands/add.js
CHANGED
|
@@ -10,7 +10,7 @@ import { saveSnapshot, sha256, } from "../utils/snapshot.js";
|
|
|
10
10
|
import { fuzzySearchNames } from "../utils/fuzzy-search.js";
|
|
11
11
|
import { normalizeThemeCss, getLocalTailwindCssTemplate, getLegacyTailwindCssTemplate, } from "./init.js";
|
|
12
12
|
import { autoInstallDeps } from "../utils/auto-install.js";
|
|
13
|
-
import { resolveLocalDir, getSourceRoot, rewriteCompanyUiImports, } from "../utils/paths.js";
|
|
13
|
+
import { resolveLocalDir, getSourceRoot, rewriteCompanyUiImports, rewriteLibImports, stripRelativeJsExtensions, } from "../utils/paths.js";
|
|
14
14
|
/**
|
|
15
15
|
* Parse a component spec into its registry namespace, type prefix and name.
|
|
16
16
|
*
|
|
@@ -173,13 +173,25 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
let content = fs.readFileSync(registryFilePath, "utf-8");
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
176
|
+
// Normalize every import in the copied file so the installed code
|
|
177
|
+
// reads consistently regardless of where it came from:
|
|
178
|
+
//
|
|
179
|
+
// 1. `rewriteLibImports` — unifies `./lib/cn.js`, `../lib/cn.js`,
|
|
180
|
+
// and `@company/ui/lib/cn` onto the single `aliases.lib` alias.
|
|
181
|
+
// Runs first so `@company/ui/lib/*` is routed to `lib/`, not
|
|
182
|
+
// rewritten to `aliases.components/lib/` by the next step.
|
|
183
|
+
// 2. `rewriteCompanyUiImports` — blocks/templates reference sibling
|
|
184
|
+
// components via `from "@company/ui/<name>"`; rewrite those to
|
|
185
|
+
// the user's alias (`@/components/ui/<name>`). Components never
|
|
186
|
+
// use this pattern, but running it on everything is a no-op
|
|
187
|
+
// and keeps the pipeline uniform.
|
|
188
|
+
// 3. `stripRelativeJsExtensions` — the source uses `.js` suffixes
|
|
189
|
+
// for `moduleResolution: NodeNext`; consumer projects use
|
|
190
|
+
// bundler resolution so the suffix is unnecessary and visually
|
|
191
|
+
// confusing in `.tsx` files. Strip it from relative/alias specs.
|
|
192
|
+
content = rewriteLibImports(content, componentsJson);
|
|
193
|
+
content = rewriteCompanyUiImports(content, componentsJson);
|
|
194
|
+
content = stripRelativeJsExtensions(content);
|
|
183
195
|
if (options.dryRun) {
|
|
184
196
|
console.log(chalk.dim(` [dry-run] would write ${path.relative(rootDir, localFilePath)}`));
|
|
185
197
|
}
|
|
@@ -195,15 +207,26 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
195
207
|
}
|
|
196
208
|
copiedFiles.push(displayName);
|
|
197
209
|
}
|
|
198
|
-
// Internal deps (lib/cn, lib/animations, lib/i18n-context,
|
|
210
|
+
// Internal deps (lib/cn, lib/animations, lib/i18n-context, lib/api-client, …).
|
|
211
|
+
//
|
|
212
|
+
// Destination: the unified `aliases.lib` directory (falls back to
|
|
213
|
+
// `<sourceRoot>/lib/` for legacy `components.json` files without the
|
|
214
|
+
// field). Every component, block, and template shares this one lib
|
|
215
|
+
// tree; their imports are rewritten above via `rewriteLibImports` to
|
|
216
|
+
// point at `aliases.lib`, so placement here must match that alias.
|
|
199
217
|
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
//
|
|
218
|
+
// Collision policy: if a file already exists AND its content matches
|
|
219
|
+
// something the CLI previously wrote (or it's about to be overwritten
|
|
220
|
+
// with the exact same bytes), we treat it as a no-op. Otherwise we
|
|
221
|
+
// respect `force` / `skipExisting` / prompt like any other file — this
|
|
222
|
+
// protects the user's own `lib/utils.ts`, custom `api-client.ts`, etc.
|
|
203
223
|
//
|
|
204
224
|
// Extensions: most lib files are `.ts` but `i18n-context.tsx` contains
|
|
205
225
|
// JSX and must be copied as `.tsx`. We probe both in order.
|
|
206
|
-
const
|
|
226
|
+
const libDirRaw = componentsJson.aliases.lib;
|
|
227
|
+
const libDir = libDirRaw
|
|
228
|
+
? resolveLocalDir(libDirRaw, componentsJson)
|
|
229
|
+
: `${getSourceRoot(componentsJson)}/lib`;
|
|
207
230
|
const copiedInternalDeps = [];
|
|
208
231
|
for (const dep of component.internalDeps) {
|
|
209
232
|
const depBase = dep.split("/").pop();
|
|
@@ -222,97 +245,59 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
222
245
|
else {
|
|
223
246
|
continue;
|
|
224
247
|
}
|
|
225
|
-
// e.g.
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
// e.g. libDir = "src/lib" → target: "src/lib/i18n-context.tsx"
|
|
249
|
+
const depTargetPath = path.join(rootDir, libDir, depFileName);
|
|
250
|
+
// Lib files must go through the same import normalization as
|
|
251
|
+
// everything else — otherwise `i18n-context.tsx` would still
|
|
252
|
+
// contain `from "./i18n-types.js"` (relative-sibling) which breaks
|
|
253
|
+
// under the unified layout if the user's tsconfig ever shifts.
|
|
254
|
+
let depContent = fs.readFileSync(depSourcePath, "utf-8");
|
|
255
|
+
depContent = rewriteLibImports(depContent, componentsJson);
|
|
256
|
+
depContent = rewriteCompanyUiImports(depContent, componentsJson);
|
|
257
|
+
depContent = stripRelativeJsExtensions(depContent);
|
|
258
|
+
// Protect the user's pre-existing lib files. If the destination
|
|
259
|
+
// exists and its content differs from what we're about to write,
|
|
260
|
+
// respect `force`/`skipExisting`/prompt like the main copy loop.
|
|
261
|
+
if (fs.existsSync(depTargetPath)) {
|
|
262
|
+
const existing = fs.readFileSync(depTargetPath, "utf-8");
|
|
263
|
+
if (existing === depContent) {
|
|
264
|
+
// Identical — no work to do.
|
|
265
|
+
copiedInternalDeps.push(dep);
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (!options.force) {
|
|
269
|
+
if (options.skipExisting) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (options.dryRun) {
|
|
273
|
+
// Treat as would-overwrite for dry-run logging.
|
|
274
|
+
}
|
|
275
|
+
else if (process.stdin.isTTY) {
|
|
276
|
+
const res = await prompts({
|
|
277
|
+
type: "confirm",
|
|
278
|
+
name: "overwrite",
|
|
279
|
+
message: `Lib file "${path.relative(rootDir, depTargetPath)}" already exists. Overwrite?`,
|
|
280
|
+
initial: false,
|
|
281
|
+
});
|
|
282
|
+
if (!res.overwrite)
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
// Non-interactive and not forced — skip silently to avoid
|
|
287
|
+
// clobbering the user's own implementation (e.g. api-client).
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
229
292
|
if (options.dryRun) {
|
|
230
293
|
console.log(chalk.dim(` [dry-run] would write ${path.relative(rootDir, depTargetPath)}`));
|
|
231
294
|
}
|
|
232
295
|
else {
|
|
233
296
|
fs.mkdirSync(path.dirname(depTargetPath), { recursive: true });
|
|
234
|
-
fs.writeFileSync(depTargetPath,
|
|
297
|
+
fs.writeFileSync(depTargetPath, depContent);
|
|
235
298
|
}
|
|
236
299
|
copiedInternalDeps.push(dep);
|
|
237
300
|
}
|
|
238
|
-
// Block/template lib: blocks import via `../../lib/animations` and
|
|
239
|
-
// `../../lib/styles` relative to `<blocksDir>/<blockName>/page.tsx`,
|
|
240
|
-
// which resolves two levels up to `path.dirname(blocksDir)/lib/`.
|
|
241
|
-
// Copy the global block lib from `apps/docs/src/registry/lib/` there.
|
|
242
|
-
if (isMultiFile) {
|
|
243
|
-
const blocksDir = resolveLocalDir(componentsJson.aliases.blocks, componentsJson);
|
|
244
|
-
const blockLibDest = path.join(rootDir, path.dirname(blocksDir), "lib");
|
|
245
|
-
for (const libFile of ["animations.ts", "styles.ts"]) {
|
|
246
|
-
const src = path.join(registryDir, "apps", "docs", "src", "registry", "lib", libFile);
|
|
247
|
-
if (!fs.existsSync(src))
|
|
248
|
-
continue;
|
|
249
|
-
const dest = path.join(blockLibDest, libFile);
|
|
250
|
-
if (fs.existsSync(dest) && !options.force)
|
|
251
|
-
continue;
|
|
252
|
-
if (options.dryRun) {
|
|
253
|
-
console.log(chalk.dim(` [dry-run] would write ${path.relative(rootDir, dest)}`));
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
fs.mkdirSync(blockLibDest, { recursive: true });
|
|
257
|
-
fs.copyFileSync(src, dest);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// Some data-heavy blocks (data-table-full, template-admin-dashboard,
|
|
261
|
-
// detail-panel-table, etc.) import from `../../../lib/api-client` and
|
|
262
|
-
// `../../../lib/api-types`, which resolves to `<sourceRoot>/lib/`.
|
|
263
|
-
// These are integration points with the user's backend that can't be
|
|
264
|
-
// shipped as real code — but we can write minimal stubs so the project
|
|
265
|
-
// compiles out of the box. Stubs are only written if the file doesn't
|
|
266
|
-
// already exist; if the user has a real implementation it stays intact.
|
|
267
|
-
const sourceRoot = getSourceRoot(componentsJson);
|
|
268
|
-
const userLibDir = path.join(rootDir, sourceRoot, "lib");
|
|
269
|
-
const stubApiTypes = path.join(userLibDir, "api-types.ts");
|
|
270
|
-
const stubApiClient = path.join(userLibDir, "api-client.ts");
|
|
271
|
-
if (!fs.existsSync(stubApiTypes) && !options.dryRun) {
|
|
272
|
-
fs.mkdirSync(userLibDir, { recursive: true });
|
|
273
|
-
fs.writeFileSync(stubApiTypes, `// Stub generated by inai-react-components. Replace with your real API types.
|
|
274
|
-
// These types satisfy the shape expected by data-heavy blocks
|
|
275
|
-
// (data-table-full, template-admin-dashboard, detail-panel-table, ...).
|
|
276
|
-
// If you already have a typed API layer, delete this file and point the
|
|
277
|
-
// block imports at your own module instead.
|
|
278
|
-
|
|
279
|
-
export interface PaginatedResponse<T> {
|
|
280
|
-
data: T[];
|
|
281
|
-
total: number;
|
|
282
|
-
page: number;
|
|
283
|
-
pageSize: number;
|
|
284
|
-
}
|
|
285
|
-
`);
|
|
286
|
-
}
|
|
287
|
-
if (!fs.existsSync(stubApiClient) && !options.dryRun) {
|
|
288
|
-
fs.mkdirSync(userLibDir, { recursive: true });
|
|
289
|
-
fs.writeFileSync(stubApiClient, `// Stub generated by inai-react-components. Replace with your real API client.
|
|
290
|
-
// Data-heavy blocks call \`fetchPaginated\` and \`downloadCsv\` at runtime.
|
|
291
|
-
// Without a real implementation the app will throw when you interact with
|
|
292
|
-
// those features — wire these up to your backend (fetch, tRPC, REST, etc.).
|
|
293
|
-
|
|
294
|
-
import type { PaginatedResponse } from "./api-types.js";
|
|
295
|
-
|
|
296
|
-
export async function fetchPaginated<T>(
|
|
297
|
-
endpoint: string,
|
|
298
|
-
_params: Record<string, unknown>
|
|
299
|
-
): Promise<PaginatedResponse<T>> {
|
|
300
|
-
throw new Error(
|
|
301
|
-
\`fetchPaginated stub called for "\${endpoint}". Replace <sourceRoot>/lib/api-client.ts with your real API client.\`
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export async function downloadCsv(
|
|
306
|
-
endpoint: string,
|
|
307
|
-
_params: Record<string, unknown>
|
|
308
|
-
): Promise<void> {
|
|
309
|
-
throw new Error(
|
|
310
|
-
\`downloadCsv stub called for "\${endpoint}". Replace <sourceRoot>/lib/api-client.ts with your real CSV exporter.\`
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
`);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
301
|
// Update components.json (skipped in dry-run).
|
|
317
302
|
if (!options.dryRun) {
|
|
318
303
|
const registryVersion = registry.version;
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -245,6 +245,7 @@ export interface ComponentsJson {
|
|
|
245
245
|
components: string;
|
|
246
246
|
blocks: string;
|
|
247
247
|
utils: string;
|
|
248
|
+
lib?: string;
|
|
248
249
|
};
|
|
249
250
|
theme: Theme;
|
|
250
251
|
font: {
|
|
@@ -273,12 +274,14 @@ export declare function getLegacyTailwindCssTemplate(theme: Theme, fontBody: Fon
|
|
|
273
274
|
export declare function normalizeThemeCss(css: string, theme: string): string;
|
|
274
275
|
/**
|
|
275
276
|
* Copies the i18n base files (context, types, defaults) from the registry
|
|
276
|
-
* to `<
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
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.
|
|
280
|
+
*
|
|
281
|
+
* Never overwrites pre-existing files so a user's custom i18n provider
|
|
282
|
+
* stays intact across re-runs.
|
|
280
283
|
*/
|
|
281
|
-
export declare function copyI18nFiles(registryDir: string | undefined, targetDir: string,
|
|
284
|
+
export declare function copyI18nFiles(registryDir: string | undefined, targetDir: string, libDirRelative: string): string[];
|
|
282
285
|
export declare function runInit(config: InitConfig, targetDir: string, repoUrl?: string): Promise<{
|
|
283
286
|
success: boolean;
|
|
284
287
|
filesCreated: string[];
|
|
@@ -1 +1 @@
|
|
|
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;AAGrC,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;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -180,6 +180,11 @@ export function buildComponentsJson(config, repoUrl) {
|
|
|
180
180
|
aliasPrefix: "@/",
|
|
181
181
|
};
|
|
182
182
|
const utilsAlias = `${layout.aliasPrefix}lib/utils`;
|
|
183
|
+
// Unified destination for every shared lib file shipped by the CLI
|
|
184
|
+
// (cn, animations, i18n context, api stubs, ...). Stored in alias form
|
|
185
|
+
// so it can be used as an import specifier verbatim and also resolved
|
|
186
|
+
// back to a filesystem path via `resolveLocalDir`.
|
|
187
|
+
const libAlias = `${layout.aliasPrefix}lib`;
|
|
183
188
|
const json = {
|
|
184
189
|
$schema: "https://inai-ui.dev/schema.json",
|
|
185
190
|
style: "default",
|
|
@@ -193,6 +198,7 @@ export function buildComponentsJson(config, repoUrl) {
|
|
|
193
198
|
components: config.componentPath,
|
|
194
199
|
blocks: config.blockPath,
|
|
195
200
|
utils: utilsAlias,
|
|
201
|
+
lib: libAlias,
|
|
196
202
|
},
|
|
197
203
|
theme: config.theme,
|
|
198
204
|
font: {
|
|
@@ -347,25 +353,30 @@ function copyTokensToProject(registryDir, targetDir, theme, sourceRoot) {
|
|
|
347
353
|
}
|
|
348
354
|
/**
|
|
349
355
|
* Copies the i18n base files (context, types, defaults) from the registry
|
|
350
|
-
* to `<
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
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.
|
|
359
|
+
*
|
|
360
|
+
* Never overwrites pre-existing files so a user's custom i18n provider
|
|
361
|
+
* stays intact across re-runs.
|
|
354
362
|
*/
|
|
355
|
-
export function copyI18nFiles(registryDir, targetDir,
|
|
363
|
+
export function copyI18nFiles(registryDir, targetDir, libDirRelative) {
|
|
356
364
|
if (!registryDir)
|
|
357
365
|
return [];
|
|
358
366
|
const files = ["i18n-context.tsx", "i18n-types.ts", "i18n-defaults.ts"];
|
|
359
367
|
const srcBase = path.join(registryDir, "packages", "ui", "src", "lib");
|
|
360
|
-
const destBase = path.join(targetDir,
|
|
368
|
+
const destBase = path.join(targetDir, libDirRelative);
|
|
361
369
|
fs.mkdirSync(destBase, { recursive: true });
|
|
362
370
|
const copied = [];
|
|
363
371
|
for (const file of files) {
|
|
364
372
|
const src = path.join(srcBase, file);
|
|
365
373
|
if (!fs.existsSync(src))
|
|
366
374
|
continue;
|
|
367
|
-
|
|
368
|
-
|
|
375
|
+
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}`);
|
|
369
380
|
}
|
|
370
381
|
return copied;
|
|
371
382
|
}
|
|
@@ -382,15 +393,20 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
382
393
|
fs.mkdirSync(componentDir, { recursive: true });
|
|
383
394
|
const blockDir = path.join(targetDir, config.blockPath);
|
|
384
395
|
fs.mkdirSync(blockDir, { recursive: true });
|
|
385
|
-
// 3. Create
|
|
386
|
-
//
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
|
|
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.
|
|
402
|
+
const libDirRelative = `${sourceRoot}/lib`;
|
|
403
|
+
const libDir = path.join(targetDir, libDirRelative);
|
|
390
404
|
fs.mkdirSync(libDir, { recursive: true });
|
|
391
405
|
const cnPath = path.join(libDir, "cn.ts");
|
|
392
|
-
fs.
|
|
393
|
-
|
|
406
|
+
if (!fs.existsSync(cnPath)) {
|
|
407
|
+
fs.writeFileSync(cnPath, getCnTemplate());
|
|
408
|
+
filesCreated.push(`${libDirRelative}/cn.ts`);
|
|
409
|
+
}
|
|
394
410
|
// 4. Copy tokens and create CSS
|
|
395
411
|
const cssRelPath = config.cssEntryPoint ?? `${sourceRoot}/index.css`;
|
|
396
412
|
const cssPath = path.join(targetDir, cssRelPath);
|
|
@@ -400,9 +416,10 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
400
416
|
const registryDir = getCacheDir();
|
|
401
417
|
const tokenFiles = copyTokensToProject(registryDir, targetDir, config.theme, sourceRoot);
|
|
402
418
|
filesCreated.push(...tokenFiles);
|
|
403
|
-
// Copy i18n base files
|
|
404
|
-
// `./lib/i18n-context.js` imports
|
|
405
|
-
|
|
419
|
+
// Copy i18n base files to the unified lib directory so that components'
|
|
420
|
+
// `./lib/i18n-context.js` imports (rewritten at install-time to the
|
|
421
|
+
// `aliases.lib` alias) resolve.
|
|
422
|
+
const i18nFiles = copyI18nFiles(registryDir, targetDir, libDirRelative);
|
|
406
423
|
filesCreated.push(...i18nFiles);
|
|
407
424
|
fs.writeFileSync(cssPath, getLocalTailwindCssTemplate(config.theme, config.fontBody, config.fontHeading, config.radius));
|
|
408
425
|
}
|
|
@@ -17,6 +17,17 @@ export interface ComponentsJsonFile {
|
|
|
17
17
|
blocks: string;
|
|
18
18
|
templates?: string;
|
|
19
19
|
utils: string;
|
|
20
|
+
/**
|
|
21
|
+
* Destination directory for shared library utilities (`cn`, animation
|
|
22
|
+
* helpers, i18n context, API client stubs, …). When set, all lib files
|
|
23
|
+
* copied by `add` land here and imports inside components/blocks are
|
|
24
|
+
* rewritten to use this alias uniformly.
|
|
25
|
+
*
|
|
26
|
+
* Stored in alias form (e.g. `"@/lib"`) so it can be used directly as
|
|
27
|
+
* an import specifier. Falls back to `"${layout.aliasPrefix}lib"` when
|
|
28
|
+
* absent (legacy pre-1.6 configs).
|
|
29
|
+
*/
|
|
30
|
+
lib?: string;
|
|
20
31
|
};
|
|
21
32
|
theme: string;
|
|
22
33
|
font?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,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,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
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.
|
|
20
|
+
.version("1.6.0");
|
|
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/dist/utils/paths.d.ts
CHANGED
|
@@ -41,16 +41,65 @@ export declare function getSourceRoot(componentsJson: Pick<ComponentsJsonFile, "
|
|
|
41
41
|
* assume their tsconfig handles it).
|
|
42
42
|
*/
|
|
43
43
|
export declare function getComponentsImportAlias(componentsJson: Pick<ComponentsJsonFile, "aliases" | "layout">): string;
|
|
44
|
+
/**
|
|
45
|
+
* Compute the import-alias form of `aliases.lib`. Used when rewriting
|
|
46
|
+
* every lib import (relative `./lib/cn.js`, compound `../lib/cn.js`, and
|
|
47
|
+
* package `@company/ui/lib/cn`) to a single, consistent alias so the
|
|
48
|
+
* installed code never depends on a particular on-disk layout.
|
|
49
|
+
*
|
|
50
|
+
* Falls back to `${aliasPrefix}lib` when `aliases.lib` is missing — this
|
|
51
|
+
* keeps the CLI compatible with pre-1.6 `components.json` files that
|
|
52
|
+
* don't yet declare the field.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getLibImportAlias(componentsJson: Pick<ComponentsJsonFile, "aliases" | "layout">): string;
|
|
55
|
+
/**
|
|
56
|
+
* Rewrite every lib import in a copied source file to the unified
|
|
57
|
+
* `aliases.lib` alias. This handles:
|
|
58
|
+
* - Component sibling imports: `./lib/cn.js` → `@/lib/cn`
|
|
59
|
+
* - Compound-component imports: `../lib/cn.js` → `@/lib/cn`
|
|
60
|
+
* - Package imports: `@company/ui/lib/cn` → `@/lib/cn`
|
|
61
|
+
*
|
|
62
|
+
* The `.js` suffix (required in the source for `moduleResolution: NodeNext`)
|
|
63
|
+
* is stripped in the process so the resulting code reads naturally in a
|
|
64
|
+
* consumer project using bundler-style resolution (Vite, Next, TanStack
|
|
65
|
+
* Start, Webpack).
|
|
66
|
+
*
|
|
67
|
+
* Side-effect imports (`import "@company/ui/lib/xxx"`) get the same
|
|
68
|
+
* treatment.
|
|
69
|
+
*/
|
|
70
|
+
export declare function rewriteLibImports(source: string, componentsJson: Pick<ComponentsJsonFile, "aliases" | "layout">): string;
|
|
71
|
+
/**
|
|
72
|
+
* Strip `.js` extensions from relative and alias-prefixed imports in a
|
|
73
|
+
* copied source file. This is safe for consumer projects because they
|
|
74
|
+
* almost always use bundler-style module resolution (Vite, Next.js,
|
|
75
|
+
* TanStack Start, Webpack, esbuild), which resolves extensionless
|
|
76
|
+
* imports directly.
|
|
77
|
+
*
|
|
78
|
+
* Handles every common module reference form:
|
|
79
|
+
* - Static: `from "./x.js"`, `import "./x.js"` (side-effect)
|
|
80
|
+
* - Dynamic: `import("./x.js")` and `import(\`./x.js\`)`
|
|
81
|
+
* - Type-only: `typeof import("./x.js")`, `import("./x.js").Foo` (TS
|
|
82
|
+
* inline import types appearing mid-line, not at statement start)
|
|
83
|
+
*
|
|
84
|
+
* Only touches specifiers that start with `./`, `../`, `@/`, `~/`, or
|
|
85
|
+
* `$/` — package specifiers (`react`, `motion/react`, ...) and URLs are
|
|
86
|
+
* left untouched because they might legitimately end in `.js`.
|
|
87
|
+
*/
|
|
88
|
+
export declare function stripRelativeJsExtensions(source: string): string;
|
|
44
89
|
/**
|
|
45
90
|
* Rewrite `@company/ui/*` imports in a block or template file to point
|
|
46
91
|
* at the user's locally-installed components. Without this, block files
|
|
47
92
|
* that `import { Button } from "@company/ui/button"` would fail at
|
|
48
93
|
* compile time because `@company/ui` doesn't exist in the consumer project.
|
|
49
94
|
*
|
|
95
|
+
* Note: `@company/ui/lib/*` is handled separately by `rewriteLibImports`
|
|
96
|
+
* (which must run BEFORE this function) so lib files route to
|
|
97
|
+
* `aliases.lib` instead of `aliases.components/lib`. This function only
|
|
98
|
+
* rewrites the non-lib specifiers that remain.
|
|
99
|
+
*
|
|
50
100
|
* Transformations:
|
|
51
101
|
* - `from "@company/ui/data-table"` → `from "~/components/ui/data-table"`
|
|
52
102
|
* - `from "@company/ui/data-table/sub"` → `from "~/components/ui/data-table/sub"`
|
|
53
|
-
* - `from "@company/ui/lib/animations"` → `from "~/components/ui/lib/animations"`
|
|
54
103
|
* - `from "@company/ui"` (bare barrel) → no rewrite (logged as unsupported)
|
|
55
104
|
*
|
|
56
105
|
* The alias prefix (`~/`, `@/`, etc.) is derived from the project layout
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAIhE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACjD,MAAM,CAQR;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACjD,MAAM,CAER;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAYR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAaR"}
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAIhE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACjD,MAAM,CAQR;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GACjD,MAAM,CAER;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAYR;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAiBR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAqBR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYhE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,QAAQ,CAAC,GAC7D,MAAM,CAaR"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -64,16 +64,102 @@ export function getComponentsImportAlias(componentsJson) {
|
|
|
64
64
|
}
|
|
65
65
|
return raw;
|
|
66
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Compute the import-alias form of `aliases.lib`. Used when rewriting
|
|
69
|
+
* every lib import (relative `./lib/cn.js`, compound `../lib/cn.js`, and
|
|
70
|
+
* package `@company/ui/lib/cn`) to a single, consistent alias so the
|
|
71
|
+
* installed code never depends on a particular on-disk layout.
|
|
72
|
+
*
|
|
73
|
+
* Falls back to `${aliasPrefix}lib` when `aliases.lib` is missing — this
|
|
74
|
+
* keeps the CLI compatible with pre-1.6 `components.json` files that
|
|
75
|
+
* don't yet declare the field.
|
|
76
|
+
*/
|
|
77
|
+
export function getLibImportAlias(componentsJson) {
|
|
78
|
+
const raw = componentsJson.aliases.lib;
|
|
79
|
+
if (raw) {
|
|
80
|
+
// Already in alias form — return verbatim.
|
|
81
|
+
for (const prefix of KNOWN_PREFIXES) {
|
|
82
|
+
if (raw.startsWith(prefix))
|
|
83
|
+
return raw;
|
|
84
|
+
}
|
|
85
|
+
// Raw path — try to convert via layout.
|
|
86
|
+
const layout = componentsJson.layout;
|
|
87
|
+
if (layout && raw.startsWith(`${layout.sourceRoot}/`)) {
|
|
88
|
+
return `${layout.aliasPrefix}${raw.slice(layout.sourceRoot.length + 1)}`;
|
|
89
|
+
}
|
|
90
|
+
return raw;
|
|
91
|
+
}
|
|
92
|
+
// Fallback for legacy configs: derive from layout.
|
|
93
|
+
const prefix = componentsJson.layout?.aliasPrefix ?? "@/";
|
|
94
|
+
return `${prefix}lib`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Rewrite every lib import in a copied source file to the unified
|
|
98
|
+
* `aliases.lib` alias. This handles:
|
|
99
|
+
* - Component sibling imports: `./lib/cn.js` → `@/lib/cn`
|
|
100
|
+
* - Compound-component imports: `../lib/cn.js` → `@/lib/cn`
|
|
101
|
+
* - Package imports: `@company/ui/lib/cn` → `@/lib/cn`
|
|
102
|
+
*
|
|
103
|
+
* The `.js` suffix (required in the source for `moduleResolution: NodeNext`)
|
|
104
|
+
* is stripped in the process so the resulting code reads naturally in a
|
|
105
|
+
* consumer project using bundler-style resolution (Vite, Next, TanStack
|
|
106
|
+
* Start, Webpack).
|
|
107
|
+
*
|
|
108
|
+
* Side-effect imports (`import "@company/ui/lib/xxx"`) get the same
|
|
109
|
+
* treatment.
|
|
110
|
+
*/
|
|
111
|
+
export function rewriteLibImports(source, componentsJson) {
|
|
112
|
+
const libAlias = getLibImportAlias(componentsJson);
|
|
113
|
+
// 1) Relative imports: `./lib/foo.js`, `../lib/foo.js`, `../../lib/foo.js`
|
|
114
|
+
let result = source.replace(/(from\s+["'])(?:\.\.?\/)+lib\/([a-zA-Z0-9_-]+)(?:\.js)?(["'])/g, (_, pre, name, post) => `${pre}${libAlias}/${name}${post}`);
|
|
115
|
+
result = result.replace(/(import\s+["'])(?:\.\.?\/)+lib\/([a-zA-Z0-9_-]+)(?:\.js)?(["'])/g, (_, pre, name, post) => `${pre}${libAlias}/${name}${post}`);
|
|
116
|
+
// 2) Package imports: `@company/ui/lib/foo`
|
|
117
|
+
result = result.replace(/(from\s+["'])@company\/ui\/lib\/([a-zA-Z0-9_-]+)(?:\.js)?(["'])/g, (_, pre, name, post) => `${pre}${libAlias}/${name}${post}`);
|
|
118
|
+
result = result.replace(/(import\s+["'])@company\/ui\/lib\/([a-zA-Z0-9_-]+)(?:\.js)?(["'])/g, (_, pre, name, post) => `${pre}${libAlias}/${name}${post}`);
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Strip `.js` extensions from relative and alias-prefixed imports in a
|
|
123
|
+
* copied source file. This is safe for consumer projects because they
|
|
124
|
+
* almost always use bundler-style module resolution (Vite, Next.js,
|
|
125
|
+
* TanStack Start, Webpack, esbuild), which resolves extensionless
|
|
126
|
+
* imports directly.
|
|
127
|
+
*
|
|
128
|
+
* Handles every common module reference form:
|
|
129
|
+
* - Static: `from "./x.js"`, `import "./x.js"` (side-effect)
|
|
130
|
+
* - Dynamic: `import("./x.js")` and `import(\`./x.js\`)`
|
|
131
|
+
* - Type-only: `typeof import("./x.js")`, `import("./x.js").Foo` (TS
|
|
132
|
+
* inline import types appearing mid-line, not at statement start)
|
|
133
|
+
*
|
|
134
|
+
* Only touches specifiers that start with `./`, `../`, `@/`, `~/`, or
|
|
135
|
+
* `$/` — package specifiers (`react`, `motion/react`, ...) and URLs are
|
|
136
|
+
* left untouched because they might legitimately end in `.js`.
|
|
137
|
+
*/
|
|
138
|
+
export function stripRelativeJsExtensions(source) {
|
|
139
|
+
// 1) Static `from "..."` and `import "..."` statements.
|
|
140
|
+
const statement = /((?:from|import)\s+[^"'`]*["'`])((?:\.{1,2}\/|[@~$]\/)[^"'`]*)\.js(["'`])/g;
|
|
141
|
+
// 2) Dynamic / inline type `import("...")` calls. These can appear
|
|
142
|
+
// anywhere in a type position, so the preceding keyword isn't
|
|
143
|
+
// constrained to start of a statement.
|
|
144
|
+
const dynamic = /(import\s*\(\s*["'`])((?:\.{1,2}\/|[@~$]\/)[^"'`]*)\.js(["'`])/g;
|
|
145
|
+
return source
|
|
146
|
+
.replace(statement, (_, pre, spec, post) => `${pre}${spec}${post}`)
|
|
147
|
+
.replace(dynamic, (_, pre, spec, post) => `${pre}${spec}${post}`);
|
|
148
|
+
}
|
|
67
149
|
/**
|
|
68
150
|
* Rewrite `@company/ui/*` imports in a block or template file to point
|
|
69
151
|
* at the user's locally-installed components. Without this, block files
|
|
70
152
|
* that `import { Button } from "@company/ui/button"` would fail at
|
|
71
153
|
* compile time because `@company/ui` doesn't exist in the consumer project.
|
|
72
154
|
*
|
|
155
|
+
* Note: `@company/ui/lib/*` is handled separately by `rewriteLibImports`
|
|
156
|
+
* (which must run BEFORE this function) so lib files route to
|
|
157
|
+
* `aliases.lib` instead of `aliases.components/lib`. This function only
|
|
158
|
+
* rewrites the non-lib specifiers that remain.
|
|
159
|
+
*
|
|
73
160
|
* Transformations:
|
|
74
161
|
* - `from "@company/ui/data-table"` → `from "~/components/ui/data-table"`
|
|
75
162
|
* - `from "@company/ui/data-table/sub"` → `from "~/components/ui/data-table/sub"`
|
|
76
|
-
* - `from "@company/ui/lib/animations"` → `from "~/components/ui/lib/animations"`
|
|
77
163
|
* - `from "@company/ui"` (bare barrel) → no rewrite (logged as unsupported)
|
|
78
164
|
*
|
|
79
165
|
* The alias prefix (`~/`, `@/`, etc.) is derived from the project layout
|
package/package.json
CHANGED