@quarklab/rad-ui 0.3.2 → 0.3.3

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.
Files changed (2) hide show
  1. package/dist/index.js +111 -44
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -743,7 +743,6 @@ function getInstallCommand(pm, packages) {
743
743
 
744
744
  // src/commands/add.ts
745
745
  import path4 from "path";
746
- import { fileURLToPath } from "url";
747
746
  import fs4 from "fs-extra";
748
747
  import * as p2 from "@clack/prompts";
749
748
  import chalk3 from "chalk";
@@ -813,9 +812,9 @@ var components = [
813
812
  },
814
813
  {
815
814
  name: "input",
816
- description: "A text input field with multiple variants",
815
+ description: "A text input field with validation, keyboard filtering, and file validation",
817
816
  platform: "web",
818
- files: ["input.tsx"],
817
+ files: ["input/input.tsx", "input/validation.ts"],
819
818
  npmDependencies: {
820
819
  "class-variance-authority": "^0.7.1",
821
820
  "lucide-react": "^0.309.0"
@@ -1007,7 +1006,7 @@ function collectNpmDependencies(names) {
1007
1006
  function transformImports(source, config) {
1008
1007
  const utilsAlias = config.aliases.utils;
1009
1008
  let result = source.replace(
1010
- /from\s+["']\.\.\/lib\/utils["']/g,
1009
+ /from\s+["'](?:\.\.\/)+lib\/utils["']/g,
1011
1010
  `from "${utilsAlias}"`
1012
1011
  );
1013
1012
  result = result.replace(
@@ -1036,46 +1035,19 @@ async function fetchRegistryIndex(registryUrl) {
1036
1035
  }
1037
1036
 
1038
1037
  // src/commands/add.ts
1039
- var __filename = fileURLToPath(import.meta.url);
1040
- var __dirname = path4.dirname(__filename);
1041
- function getTemplatesDir() {
1042
- return path4.resolve(__dirname, "..", "templates");
1043
- }
1044
- async function readBundledTemplate(name, platform) {
1045
- const comp = getComponent(name);
1046
- if (!comp) return null;
1047
- const platformDir = platform === "mobile" ? "mobile" : "web";
1048
- const templatesDir = getTemplatesDir();
1049
- const sourceDir = path4.resolve(templatesDir, platformDir);
1050
- const files = [];
1051
- for (const file of comp.files) {
1052
- const filePath = path4.resolve(sourceDir, file);
1053
- if (await fs4.pathExists(filePath)) {
1054
- const content = await fs4.readFile(filePath, "utf-8");
1055
- files.push({ path: `ui/${file}`, type: "registry:ui", content });
1056
- }
1057
- }
1058
- const utilsPath = path4.resolve(sourceDir, "lib", "utils.ts");
1059
- const utilsContent = await fs4.pathExists(utilsPath) ? await fs4.readFile(utilsPath, "utf-8") : void 0;
1060
- return {
1061
- name: comp.name,
1062
- type: "registry:ui",
1063
- description: comp.description,
1064
- platform: comp.platform,
1065
- dependencies: Object.keys(comp.npmDependencies),
1066
- registryDependencies: comp.internalDependencies,
1067
- files,
1068
- utils: utilsContent ? { path: "lib/utils.ts", content: utilsContent } : void 0
1069
- };
1070
- }
1071
1038
  async function getComponentContent(name, config) {
1072
- if (config.registry) {
1073
- try {
1074
- return await fetchComponent(config.registry, name);
1075
- } catch {
1076
- }
1039
+ if (!config.registry) {
1040
+ throw new Error(
1041
+ "No registry URL configured. Run `rad-ui init` first."
1042
+ );
1043
+ }
1044
+ try {
1045
+ return await fetchComponent(config.registry, name);
1046
+ } catch {
1047
+ throw new Error(
1048
+ `Failed to fetch component "${name}" from ${config.registry}. Is the registry available?`
1049
+ );
1077
1050
  }
1078
- return readBundledTemplate(name, config.platform);
1079
1051
  }
1080
1052
  async function addCommand(componentNames, opts) {
1081
1053
  const cwd = process.cwd();
@@ -1188,8 +1160,8 @@ async function addCommand(componentNames, opts) {
1188
1160
  for (const file of item.files) {
1189
1161
  let content = file.content;
1190
1162
  content = transformImports(content, config);
1191
- const fileName = path4.basename(file.path);
1192
- const destPath = path4.resolve(componentsDir, fileName);
1163
+ const relPath = file.path.replace(/^ui\//, "");
1164
+ const destPath = path4.resolve(componentsDir, relPath);
1193
1165
  await fs4.ensureDir(path4.dirname(destPath));
1194
1166
  await fs4.writeFile(destPath, content, "utf-8");
1195
1167
  copiedCount++;
@@ -1254,6 +1226,100 @@ function getInstallCommand2(pm, packages) {
1254
1226
  }
1255
1227
  }
1256
1228
 
1229
+ // src/commands/build.ts
1230
+ import path5 from "path";
1231
+ import fs5 from "fs-extra";
1232
+ import * as p3 from "@clack/prompts";
1233
+ import chalk4 from "chalk";
1234
+ function parseDep(dep) {
1235
+ const atIndex = dep.lastIndexOf("@");
1236
+ if (atIndex > 0) {
1237
+ return {
1238
+ name: dep.slice(0, atIndex),
1239
+ version: dep.slice(atIndex + 1)
1240
+ };
1241
+ }
1242
+ return { name: dep };
1243
+ }
1244
+ function getRelativePath(registryDir, filePath) {
1245
+ return filePath.replace(`${registryDir}/`, "");
1246
+ }
1247
+ async function buildCommand(registryPath, opts) {
1248
+ const cwd = opts.cwd ? path5.resolve(opts.cwd) : process.cwd();
1249
+ const registryJsonPath = path5.resolve(cwd, registryPath);
1250
+ const outputDir = path5.resolve(cwd, opts.output ?? "./public/r");
1251
+ p3.intro(chalk4.bold("Build Rad UI Registry"));
1252
+ if (!await fs5.pathExists(registryJsonPath)) {
1253
+ p3.log.error(
1254
+ `Registry file not found: ${chalk4.cyan(registryJsonPath)}`
1255
+ );
1256
+ p3.log.info(
1257
+ `Create a ${chalk4.cyan("registry.json")} file or specify a path: ${chalk4.gray("rad-ui build ./path/to/registry.json")}`
1258
+ );
1259
+ process.exit(1);
1260
+ }
1261
+ const s = p3.spinner();
1262
+ s.start("Reading registry.json...");
1263
+ const registry = await fs5.readJson(registryJsonPath);
1264
+ s.message(`Building ${registry.items.length} components...`);
1265
+ await fs5.ensureDir(outputDir);
1266
+ const utilsPath = path5.resolve(cwd, registry.registryDir, "lib", "utils.ts");
1267
+ const utilsContent = await fs5.pathExists(utilsPath) ? await fs5.readFile(utilsPath, "utf-8") : null;
1268
+ let built = 0;
1269
+ const warnings = [];
1270
+ for (const item of registry.items) {
1271
+ const files = [];
1272
+ for (const file of item.files) {
1273
+ const filePath = path5.resolve(cwd, file.path);
1274
+ if (!await fs5.pathExists(filePath)) {
1275
+ warnings.push(`${item.name}: ${file.path} not found, skipped`);
1276
+ continue;
1277
+ }
1278
+ const content = await fs5.readFile(filePath, "utf-8");
1279
+ files.push({
1280
+ path: getRelativePath(registry.registryDir, file.path),
1281
+ type: file.type,
1282
+ content
1283
+ });
1284
+ }
1285
+ const depNames = item.dependencies.map((d) => parseDep(d).name);
1286
+ const registryItem = {
1287
+ name: item.name,
1288
+ type: item.type,
1289
+ description: item.description,
1290
+ platform: item.platform,
1291
+ dependencies: depNames,
1292
+ registryDependencies: item.registryDependencies,
1293
+ files,
1294
+ utils: utilsContent ? { path: "lib/utils.ts", content: utilsContent } : void 0
1295
+ };
1296
+ const outputPath = path5.resolve(outputDir, `${item.name}.json`);
1297
+ await fs5.writeFile(
1298
+ outputPath,
1299
+ JSON.stringify(registryItem, null, 2),
1300
+ "utf-8"
1301
+ );
1302
+ built++;
1303
+ }
1304
+ const index = registry.items.map((item) => ({
1305
+ name: item.name,
1306
+ description: item.description,
1307
+ platform: item.platform,
1308
+ dependencies: item.dependencies.map((d) => parseDep(d).name),
1309
+ registryDependencies: item.registryDependencies
1310
+ }));
1311
+ const indexPath = path5.resolve(outputDir, "index.json");
1312
+ await fs5.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
1313
+ s.stop(`Built ${built} components + index.json`);
1314
+ if (warnings.length > 0) {
1315
+ for (const w of warnings) {
1316
+ p3.log.warn(w);
1317
+ }
1318
+ }
1319
+ p3.log.info(`Output: ${chalk4.cyan(outputDir)}`);
1320
+ p3.outro("Registry built successfully!");
1321
+ }
1322
+
1257
1323
  // src/index.ts
1258
1324
  var program = new Command();
1259
1325
  program.name("rad-ui").description(
@@ -1261,4 +1327,5 @@ program.name("rad-ui").description(
1261
1327
  ).version("0.1.0");
1262
1328
  program.command("init").description("Initialize Rad UI in your project").option("-y, --yes", "Skip confirmation prompts and use defaults").action(initCommand);
1263
1329
  program.command("add").description("Add components to your project").argument("[components...]", "Components to add (space-separated)").option("-a, --all", "Add all available components").option("-o, --overwrite", "Overwrite existing components").option("-p, --path <path>", "Custom path for components").action(addCommand);
1330
+ program.command("build").description("Build registry JSON from registry.json").argument("[registry]", "Path to registry.json", "./registry.json").option("-o, --output <dir>", "Output directory", "./public/r").option("--cwd <path>", "Working directory").action(buildCommand);
1264
1331
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quarklab/rad-ui",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "A CLI for adding Rad UI components to your project. Beautiful Persian-themed React components built on Radix UI and Tailwind CSS.",
5
5
  "license": "MIT",
6
6
  "type": "module",