inai-react-components 1.4.1 → 1.5.1
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 +147 -15
- package/dist/commands/init.d.ts +5 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +18 -13
- package/dist/index.js +1 -1
- package/dist/utils/paths.d.ts +34 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +54 -0
- 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;AAwBrB,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;AA2TD,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 } from "../utils/paths.js";
|
|
13
|
+
import { resolveLocalDir, getSourceRoot, rewriteCompanyUiImports, } from "../utils/paths.js";
|
|
14
14
|
/**
|
|
15
15
|
* Parse a component spec into its registry namespace, type prefix and name.
|
|
16
16
|
*
|
|
@@ -107,6 +107,19 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
107
107
|
const baseTargetDir = getTargetDir(component, componentsJson);
|
|
108
108
|
const isMultiFile = component.type === "block" || component.type === "template";
|
|
109
109
|
const targetDir = isMultiFile ? path.join(baseTargetDir, name) : baseTargetDir;
|
|
110
|
+
// Prefixes used by source files. Stripping them preserves each
|
|
111
|
+
// component/block's internal subdirectory structure.
|
|
112
|
+
//
|
|
113
|
+
// Components: `packages/ui/src/<name>.tsx` and
|
|
114
|
+
// `packages/ui/src/<name>/sub.tsx` → strip `packages/ui/src/`
|
|
115
|
+
// so compound subdirs (`data-table/`) land as-is under
|
|
116
|
+
// `<componentDir>/`.
|
|
117
|
+
//
|
|
118
|
+
// Blocks/templates: `apps/docs/src/registry/blocks/<name>/**` → strip
|
|
119
|
+
// `apps/docs/src/registry/blocks/<name>/` so nested `parts/`
|
|
120
|
+
// subfolders are preserved under `<blocksDir>/<name>/`.
|
|
121
|
+
const UI_PREFIX = "packages/ui/src/";
|
|
122
|
+
const BLOCK_PREFIX = `apps/docs/src/registry/blocks/${name}/`;
|
|
110
123
|
const copiedFiles = [];
|
|
111
124
|
const skippedFiles = [];
|
|
112
125
|
// Track captured content for the snapshot (only for files that were
|
|
@@ -114,15 +127,30 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
114
127
|
const capturedFiles = {};
|
|
115
128
|
for (const filePath of component.files) {
|
|
116
129
|
const registryFilePath = path.join(registryDir, filePath);
|
|
117
|
-
|
|
118
|
-
|
|
130
|
+
// Destination path relative to `targetDir`. The prefix stripping
|
|
131
|
+
// preserves intra-component directory structure (compound subdirs,
|
|
132
|
+
// blocks' `parts/` folders, etc.). Flattening to basename here was
|
|
133
|
+
// the cause of broken `./parts/*` and `../data` imports in templates.
|
|
134
|
+
let destRel;
|
|
135
|
+
if (isMultiFile && filePath.startsWith(BLOCK_PREFIX)) {
|
|
136
|
+
destRel = filePath.slice(BLOCK_PREFIX.length);
|
|
137
|
+
}
|
|
138
|
+
else if (!isMultiFile && filePath.startsWith(UI_PREFIX)) {
|
|
139
|
+
destRel = filePath.slice(UI_PREFIX.length);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Fallback for legacy registry entries without the expected prefix.
|
|
143
|
+
destRel = path.basename(filePath);
|
|
144
|
+
}
|
|
145
|
+
const localFilePath = path.join(rootDir, targetDir, destRel);
|
|
146
|
+
const displayName = isMultiFile ? `${name}/${destRel}` : destRel;
|
|
119
147
|
if (!fs.existsSync(registryFilePath)) {
|
|
120
148
|
continue;
|
|
121
149
|
}
|
|
122
150
|
const exists = fs.existsSync(localFilePath);
|
|
123
151
|
if (exists && !options.force) {
|
|
124
152
|
if (options.skipExisting) {
|
|
125
|
-
skippedFiles.push(
|
|
153
|
+
skippedFiles.push(displayName);
|
|
126
154
|
continue;
|
|
127
155
|
}
|
|
128
156
|
if (options.dryRun) {
|
|
@@ -136,7 +164,7 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
136
164
|
initial: false,
|
|
137
165
|
});
|
|
138
166
|
if (!res.overwrite) {
|
|
139
|
-
skippedFiles.push(
|
|
167
|
+
skippedFiles.push(displayName);
|
|
140
168
|
continue;
|
|
141
169
|
}
|
|
142
170
|
}
|
|
@@ -144,7 +172,14 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
144
172
|
throw new Error(`File "${path.relative(rootDir, localFilePath)}" already exists. Use --force to overwrite or --skip-existing to ignore (stdin is not a TTY, cannot prompt).`);
|
|
145
173
|
}
|
|
146
174
|
}
|
|
147
|
-
|
|
175
|
+
let content = fs.readFileSync(registryFilePath, "utf-8");
|
|
176
|
+
// Blocks and templates reference sibling components via
|
|
177
|
+
// `from "@company/ui/<name>"`. Rewrite those to point at the user's
|
|
178
|
+
// locally-installed components using the project's alias prefix, so
|
|
179
|
+
// the block compiles without `@company/ui` being in node_modules.
|
|
180
|
+
if (isMultiFile) {
|
|
181
|
+
content = rewriteCompanyUiImports(content, componentsJson);
|
|
182
|
+
}
|
|
148
183
|
if (options.dryRun) {
|
|
149
184
|
console.log(chalk.dim(` [dry-run] would write ${path.relative(rootDir, localFilePath)}`));
|
|
150
185
|
}
|
|
@@ -158,19 +193,38 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
158
193
|
content,
|
|
159
194
|
};
|
|
160
195
|
}
|
|
161
|
-
copiedFiles.push(
|
|
162
|
-
}
|
|
163
|
-
// Internal deps (lib/cn, lib/animations, ...)
|
|
164
|
-
//
|
|
165
|
-
|
|
196
|
+
copiedFiles.push(displayName);
|
|
197
|
+
}
|
|
198
|
+
// Internal deps (lib/cn, lib/animations, lib/i18n-context, ...).
|
|
199
|
+
//
|
|
200
|
+
// Placement matters: source components import via `./lib/<name>.js`
|
|
201
|
+
// (sibling), so lib files MUST land in `<componentDir>/lib/` — NOT in
|
|
202
|
+
// `<sourceRoot>/lib/`. Otherwise the relative imports break at runtime.
|
|
203
|
+
//
|
|
204
|
+
// Extensions: most lib files are `.ts` but `i18n-context.tsx` contains
|
|
205
|
+
// JSX and must be copied as `.tsx`. We probe both in order.
|
|
206
|
+
const componentsDir = resolveLocalDir(componentsJson.aliases.components, componentsJson);
|
|
166
207
|
const copiedInternalDeps = [];
|
|
167
208
|
for (const dep of component.internalDeps) {
|
|
168
|
-
const
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
|
|
209
|
+
const depBase = dep.split("/").pop();
|
|
210
|
+
const tsSource = path.join(registryDir, "packages", "ui", "src", dep + ".ts");
|
|
211
|
+
const tsxSource = path.join(registryDir, "packages", "ui", "src", dep + ".tsx");
|
|
212
|
+
let depSourcePath;
|
|
213
|
+
let depFileName;
|
|
214
|
+
if (fs.existsSync(tsSource)) {
|
|
215
|
+
depSourcePath = tsSource;
|
|
216
|
+
depFileName = `${depBase}.ts`;
|
|
217
|
+
}
|
|
218
|
+
else if (fs.existsSync(tsxSource)) {
|
|
219
|
+
depSourcePath = tsxSource;
|
|
220
|
+
depFileName = `${depBase}.tsx`;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
172
223
|
continue;
|
|
173
224
|
}
|
|
225
|
+
// e.g. componentsDir = "app/components/ui" → target:
|
|
226
|
+
// "app/components/ui/lib/i18n-context.tsx"
|
|
227
|
+
const depTargetPath = path.join(rootDir, componentsDir, "lib", depFileName);
|
|
174
228
|
const content = fs.readFileSync(depSourcePath, "utf-8");
|
|
175
229
|
if (options.dryRun) {
|
|
176
230
|
console.log(chalk.dim(` [dry-run] would write ${path.relative(rootDir, depTargetPath)}`));
|
|
@@ -181,6 +235,84 @@ async function installOne(component, registry, componentsJson, registryDir, root
|
|
|
181
235
|
}
|
|
182
236
|
copiedInternalDeps.push(dep);
|
|
183
237
|
}
|
|
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
|
+
}
|
|
184
316
|
// Update components.json (skipped in dry-run).
|
|
185
317
|
if (!options.dryRun) {
|
|
186
318
|
const registryVersion = registry.version;
|
package/dist/commands/init.d.ts
CHANGED
|
@@ -273,11 +273,12 @@ export declare function getLegacyTailwindCssTemplate(theme: Theme, fontBody: Fon
|
|
|
273
273
|
export declare function normalizeThemeCss(css: string, theme: string): string;
|
|
274
274
|
/**
|
|
275
275
|
* Copies the i18n base files (context, types, defaults) from the registry
|
|
276
|
-
* to
|
|
277
|
-
* `useUIMessages` from `./lib/i18n-context.js` —
|
|
278
|
-
*
|
|
276
|
+
* to `<componentPath>/lib/`. Required because ~75 components import
|
|
277
|
+
* `useUIMessages` from `./lib/i18n-context.js` — the lib directory must
|
|
278
|
+
* live as a SIBLING of the component `.tsx` files so relative imports
|
|
279
|
+
* resolve correctly.
|
|
279
280
|
*/
|
|
280
|
-
export declare function copyI18nFiles(registryDir: string | undefined, targetDir: string,
|
|
281
|
+
export declare function copyI18nFiles(registryDir: string | undefined, targetDir: string, componentPath: string): string[];
|
|
281
282
|
export declare function runInit(config: InitConfig, targetDir: string, repoUrl?: string): Promise<{
|
|
282
283
|
success: boolean;
|
|
283
284
|
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":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -347,16 +347,17 @@ function copyTokensToProject(registryDir, targetDir, theme, sourceRoot) {
|
|
|
347
347
|
}
|
|
348
348
|
/**
|
|
349
349
|
* Copies the i18n base files (context, types, defaults) from the registry
|
|
350
|
-
* to
|
|
351
|
-
* `useUIMessages` from `./lib/i18n-context.js` —
|
|
352
|
-
*
|
|
350
|
+
* to `<componentPath>/lib/`. Required because ~75 components import
|
|
351
|
+
* `useUIMessages` from `./lib/i18n-context.js` — the lib directory must
|
|
352
|
+
* live as a SIBLING of the component `.tsx` files so relative imports
|
|
353
|
+
* resolve correctly.
|
|
353
354
|
*/
|
|
354
|
-
export function copyI18nFiles(registryDir, targetDir,
|
|
355
|
+
export function copyI18nFiles(registryDir, targetDir, componentPath) {
|
|
355
356
|
if (!registryDir)
|
|
356
357
|
return [];
|
|
357
358
|
const files = ["i18n-context.tsx", "i18n-types.ts", "i18n-defaults.ts"];
|
|
358
359
|
const srcBase = path.join(registryDir, "packages", "ui", "src", "lib");
|
|
359
|
-
const destBase = path.join(targetDir,
|
|
360
|
+
const destBase = path.join(targetDir, componentPath, "lib");
|
|
360
361
|
fs.mkdirSync(destBase, { recursive: true });
|
|
361
362
|
const copied = [];
|
|
362
363
|
for (const file of files) {
|
|
@@ -364,7 +365,7 @@ export function copyI18nFiles(registryDir, targetDir, sourceRoot) {
|
|
|
364
365
|
if (!fs.existsSync(src))
|
|
365
366
|
continue;
|
|
366
367
|
fs.copyFileSync(src, path.join(destBase, file));
|
|
367
|
-
copied.push(`${
|
|
368
|
+
copied.push(`${componentPath}/lib/${file}`);
|
|
368
369
|
}
|
|
369
370
|
return copied;
|
|
370
371
|
}
|
|
@@ -381,12 +382,15 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
381
382
|
fs.mkdirSync(componentDir, { recursive: true });
|
|
382
383
|
const blockDir = path.join(targetDir, config.blockPath);
|
|
383
384
|
fs.mkdirSync(blockDir, { recursive: true });
|
|
384
|
-
// 3. Create cn.ts utility
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
385
|
+
// 3. Create cn.ts utility as a sibling of the components directory.
|
|
386
|
+
// Components import via `./lib/cn.js`, so lib/ MUST live directly
|
|
387
|
+
// next to the installed component files — `<componentPath>/lib/`,
|
|
388
|
+
// not `<sourceRoot>/lib/`.
|
|
389
|
+
const libDir = path.join(targetDir, config.componentPath, "lib");
|
|
390
|
+
fs.mkdirSync(libDir, { recursive: true });
|
|
391
|
+
const cnPath = path.join(libDir, "cn.ts");
|
|
388
392
|
fs.writeFileSync(cnPath, getCnTemplate());
|
|
389
|
-
filesCreated.push(`${
|
|
393
|
+
filesCreated.push(`${config.componentPath}/lib/cn.ts`);
|
|
390
394
|
// 4. Copy tokens and create CSS
|
|
391
395
|
const cssRelPath = config.cssEntryPoint ?? `${sourceRoot}/index.css`;
|
|
392
396
|
const cssPath = path.join(targetDir, cssRelPath);
|
|
@@ -396,8 +400,9 @@ export async function runInit(config, targetDir, repoUrl) {
|
|
|
396
400
|
const registryDir = getCacheDir();
|
|
397
401
|
const tokenFiles = copyTokensToProject(registryDir, targetDir, config.theme, sourceRoot);
|
|
398
402
|
filesCreated.push(...tokenFiles);
|
|
399
|
-
// Copy i18n base files
|
|
400
|
-
|
|
403
|
+
// Copy i18n base files next to the components so their
|
|
404
|
+
// `./lib/i18n-context.js` imports resolve.
|
|
405
|
+
const i18nFiles = copyI18nFiles(registryDir, targetDir, config.componentPath);
|
|
401
406
|
filesCreated.push(...i18nFiles);
|
|
402
407
|
fs.writeFileSync(cssPath, getLocalTailwindCssTemplate(config.theme, config.fontBody, config.fontHeading, config.radius));
|
|
403
408
|
}
|
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.5.1");
|
|
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
|
@@ -23,4 +23,38 @@ export declare function resolveLocalDir(alias: string, componentsJson: Pick<Comp
|
|
|
23
23
|
* `components.json` files without a `layout` field.
|
|
24
24
|
*/
|
|
25
25
|
export declare function getSourceRoot(componentsJson: Pick<ComponentsJsonFile, "layout">): string;
|
|
26
|
+
/**
|
|
27
|
+
* Compute the import-alias form of `aliases.components` for use when
|
|
28
|
+
* rewriting `@company/ui/*` imports in block and template files.
|
|
29
|
+
*
|
|
30
|
+
* Rules:
|
|
31
|
+
* 1. If the stored alias already starts with a known alias prefix
|
|
32
|
+
* (`@/`, `~/`, `$/`), return it as-is. Block imports written with
|
|
33
|
+
* this prefix will resolve through the user's `tsconfig.json` paths.
|
|
34
|
+
* 2. Otherwise it's a raw filesystem path (e.g. `app/components/ui`).
|
|
35
|
+
* Strip `layout.sourceRoot` and prepend `layout.aliasPrefix` to
|
|
36
|
+
* produce an alias form (e.g. `~/components/ui`). This matches what
|
|
37
|
+
* the user's tsconfig `paths` maps, so the rewritten imports resolve
|
|
38
|
+
* without needing the user to configure anything extra.
|
|
39
|
+
* 3. If the stored alias doesn't match the layout's sourceRoot, return
|
|
40
|
+
* it as-is (the user may have chosen a non-standard location and we
|
|
41
|
+
* assume their tsconfig handles it).
|
|
42
|
+
*/
|
|
43
|
+
export declare function getComponentsImportAlias(componentsJson: Pick<ComponentsJsonFile, "aliases" | "layout">): string;
|
|
44
|
+
/**
|
|
45
|
+
* Rewrite `@company/ui/*` imports in a block or template file to point
|
|
46
|
+
* at the user's locally-installed components. Without this, block files
|
|
47
|
+
* that `import { Button } from "@company/ui/button"` would fail at
|
|
48
|
+
* compile time because `@company/ui` doesn't exist in the consumer project.
|
|
49
|
+
*
|
|
50
|
+
* Transformations:
|
|
51
|
+
* - `from "@company/ui/data-table"` → `from "~/components/ui/data-table"`
|
|
52
|
+
* - `from "@company/ui/data-table/sub"` → `from "~/components/ui/data-table/sub"`
|
|
53
|
+
* - `from "@company/ui/lib/animations"` → `from "~/components/ui/lib/animations"`
|
|
54
|
+
* - `from "@company/ui"` (bare barrel) → no rewrite (logged as unsupported)
|
|
55
|
+
*
|
|
56
|
+
* The alias prefix (`~/`, `@/`, etc.) is derived from the project layout
|
|
57
|
+
* so it matches the user's `tsconfig.json` paths.
|
|
58
|
+
*/
|
|
59
|
+
export declare function rewriteCompanyUiImports(source: string, componentsJson: Pick<ComponentsJsonFile, "aliases" | "layout">): string;
|
|
26
60
|
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -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"}
|
|
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"}
|
package/dist/utils/paths.js
CHANGED
|
@@ -33,3 +33,57 @@ export function resolveLocalDir(alias, componentsJson) {
|
|
|
33
33
|
export function getSourceRoot(componentsJson) {
|
|
34
34
|
return componentsJson.layout?.sourceRoot ?? "src";
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute the import-alias form of `aliases.components` for use when
|
|
38
|
+
* rewriting `@company/ui/*` imports in block and template files.
|
|
39
|
+
*
|
|
40
|
+
* Rules:
|
|
41
|
+
* 1. If the stored alias already starts with a known alias prefix
|
|
42
|
+
* (`@/`, `~/`, `$/`), return it as-is. Block imports written with
|
|
43
|
+
* this prefix will resolve through the user's `tsconfig.json` paths.
|
|
44
|
+
* 2. Otherwise it's a raw filesystem path (e.g. `app/components/ui`).
|
|
45
|
+
* Strip `layout.sourceRoot` and prepend `layout.aliasPrefix` to
|
|
46
|
+
* produce an alias form (e.g. `~/components/ui`). This matches what
|
|
47
|
+
* the user's tsconfig `paths` maps, so the rewritten imports resolve
|
|
48
|
+
* without needing the user to configure anything extra.
|
|
49
|
+
* 3. If the stored alias doesn't match the layout's sourceRoot, return
|
|
50
|
+
* it as-is (the user may have chosen a non-standard location and we
|
|
51
|
+
* assume their tsconfig handles it).
|
|
52
|
+
*/
|
|
53
|
+
export function getComponentsImportAlias(componentsJson) {
|
|
54
|
+
const raw = componentsJson.aliases.components;
|
|
55
|
+
// Already in alias form
|
|
56
|
+
for (const prefix of ["@/", "~/", "$/"]) {
|
|
57
|
+
if (raw.startsWith(prefix))
|
|
58
|
+
return raw;
|
|
59
|
+
}
|
|
60
|
+
// Raw path — convert to alias form via layout
|
|
61
|
+
const layout = componentsJson.layout;
|
|
62
|
+
if (layout && raw.startsWith(`${layout.sourceRoot}/`)) {
|
|
63
|
+
return `${layout.aliasPrefix}${raw.slice(layout.sourceRoot.length + 1)}`;
|
|
64
|
+
}
|
|
65
|
+
return raw;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Rewrite `@company/ui/*` imports in a block or template file to point
|
|
69
|
+
* at the user's locally-installed components. Without this, block files
|
|
70
|
+
* that `import { Button } from "@company/ui/button"` would fail at
|
|
71
|
+
* compile time because `@company/ui` doesn't exist in the consumer project.
|
|
72
|
+
*
|
|
73
|
+
* Transformations:
|
|
74
|
+
* - `from "@company/ui/data-table"` → `from "~/components/ui/data-table"`
|
|
75
|
+
* - `from "@company/ui/data-table/sub"` → `from "~/components/ui/data-table/sub"`
|
|
76
|
+
* - `from "@company/ui/lib/animations"` → `from "~/components/ui/lib/animations"`
|
|
77
|
+
* - `from "@company/ui"` (bare barrel) → no rewrite (logged as unsupported)
|
|
78
|
+
*
|
|
79
|
+
* The alias prefix (`~/`, `@/`, etc.) is derived from the project layout
|
|
80
|
+
* so it matches the user's `tsconfig.json` paths.
|
|
81
|
+
*/
|
|
82
|
+
export function rewriteCompanyUiImports(source, componentsJson) {
|
|
83
|
+
const compImport = getComponentsImportAlias(componentsJson);
|
|
84
|
+
// Handle subpath imports (@company/ui/xxx)
|
|
85
|
+
let result = source.replace(/(from\s+["'])@company\/ui\/([^"']+)(["'])/g, (_, pre, sub, post) => `${pre}${compImport}/${sub}${post}`);
|
|
86
|
+
// Handle side-effect imports like `import "@company/ui/xxx"`
|
|
87
|
+
result = result.replace(/(import\s+["'])@company\/ui\/([^"']+)(["'])/g, (_, pre, sub, post) => `${pre}${compImport}/${sub}${post}`);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
package/package.json
CHANGED