myoperator-ui 0.0.42 → 0.0.44

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 +143 -73
  2. package/package.json +10 -4
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ import { createRequire } from "module";
6
6
 
7
7
  // src/commands/add.ts
8
8
  import chalk from "chalk";
9
- import fs from "fs-extra";
10
- import path from "path";
9
+ import fs2 from "fs-extra";
10
+ import path2 from "path";
11
11
  import prompts from "prompts";
12
12
  import ora from "ora";
13
13
 
@@ -875,17 +875,73 @@ export { Tag, tagVariants }
875
875
  };
876
876
  }
877
877
 
878
+ // src/utils/config.ts
879
+ import fs from "fs-extra";
880
+ import path from "path";
881
+ var DEFAULT_CONFIG = {
882
+ $schema: "https://myoperator.com/schema.json",
883
+ style: "default",
884
+ tailwind: {
885
+ config: "tailwind.config.js",
886
+ css: "src/index.css",
887
+ baseColor: "slate",
888
+ cssVariables: true,
889
+ prefix: ""
890
+ },
891
+ aliases: {
892
+ components: "@/components",
893
+ utils: "@/lib/utils",
894
+ ui: "@/components/ui"
895
+ }
896
+ };
897
+ function getConfigPath(cwd = process.cwd()) {
898
+ return path.join(cwd, "components.json");
899
+ }
900
+ async function configExists(cwd = process.cwd()) {
901
+ return await fs.pathExists(getConfigPath(cwd));
902
+ }
903
+ async function readConfig(cwd = process.cwd()) {
904
+ const configPath = getConfigPath(cwd);
905
+ if (!await fs.pathExists(configPath)) {
906
+ return null;
907
+ }
908
+ try {
909
+ return await fs.readJson(configPath);
910
+ } catch (error) {
911
+ console.error("Error reading components.json:", error);
912
+ return null;
913
+ }
914
+ }
915
+ async function getTailwindPrefix(cwd = process.cwd()) {
916
+ const config = await readConfig(cwd);
917
+ return config?.tailwind?.prefix || "";
918
+ }
919
+ async function detectTailwindPrefix(configFile, cwd = process.cwd()) {
920
+ const configPath = path.join(cwd, configFile);
921
+ if (await fs.pathExists(configPath)) {
922
+ const content = await fs.readFile(configPath, "utf-8");
923
+ const prefixMatch = content.match(/prefix:\s*['"]([^'"]+)['"]/);
924
+ if (prefixMatch) {
925
+ return prefixMatch[1];
926
+ }
927
+ }
928
+ return "";
929
+ }
930
+
878
931
  // src/commands/add.ts
879
932
  async function add(components, options) {
880
933
  const cwd = process.cwd();
881
- const configPath = path.join(cwd, "components.json");
882
- if (!await fs.pathExists(configPath)) {
934
+ if (!await configExists(cwd)) {
883
935
  console.log(chalk.red("\n Error: Project not initialized."));
884
936
  console.log(chalk.yellow(" Run `npx myoperator-ui init` first.\n"));
885
937
  process.exit(1);
886
938
  }
887
- const config = await fs.readJson(configPath);
888
- const prefix = config.tailwind?.prefix || "";
939
+ const prefix = await getTailwindPrefix(cwd);
940
+ if (prefix) {
941
+ console.log(chalk.blue(`
942
+ \u2139 Applying Tailwind prefix: "${prefix}"
943
+ `));
944
+ }
889
945
  const registry = await getRegistry(prefix);
890
946
  const availableComponents = Object.keys(registry);
891
947
  if (!components || components.length === 0) {
@@ -914,7 +970,7 @@ async function add(components, options) {
914
970
  `));
915
971
  process.exit(1);
916
972
  }
917
- const componentsDir = path.join(cwd, options.path);
973
+ const componentsDir = path2.join(cwd, options.path);
918
974
  if (!options.yes) {
919
975
  const { confirm } = await prompts({
920
976
  type: "confirm",
@@ -935,15 +991,15 @@ async function add(components, options) {
935
991
  for (const componentName of components) {
936
992
  const component = registry[componentName];
937
993
  for (const file of component.files) {
938
- const filePath = path.join(componentsDir, file.name);
939
- if (await fs.pathExists(filePath)) {
994
+ const filePath = path2.join(componentsDir, file.name);
995
+ if (await fs2.pathExists(filePath)) {
940
996
  if (!options.overwrite) {
941
997
  spinner.warn(`${file.name} already exists. Use --overwrite to replace.`);
942
998
  continue;
943
999
  }
944
1000
  }
945
- await fs.ensureDir(path.dirname(filePath));
946
- await fs.writeFile(filePath, file.content);
1001
+ await fs2.ensureDir(path2.dirname(filePath));
1002
+ await fs2.writeFile(filePath, file.content);
947
1003
  installed.push(file.name);
948
1004
  }
949
1005
  if (component.dependencies) {
@@ -971,8 +1027,8 @@ async function add(components, options) {
971
1027
 
972
1028
  // src/commands/init.ts
973
1029
  import chalk2 from "chalk";
974
- import fs2 from "fs-extra";
975
- import path2 from "path";
1030
+ import fs3 from "fs-extra";
1031
+ import path3 from "path";
976
1032
  import prompts2 from "prompts";
977
1033
  import ora2 from "ora";
978
1034
  import { execSync } from "child_process";
@@ -1200,26 +1256,11 @@ export default {
1200
1256
  plugins: [require("tailwindcss-animate")],
1201
1257
  }
1202
1258
  `;
1203
- var DEFAULT_CONFIG = {
1204
- $schema: "https://myoperator.com/schema.json",
1205
- style: "default",
1206
- tailwind: {
1207
- config: "tailwind.config.js",
1208
- css: "src/index.css",
1209
- baseColor: "slate",
1210
- cssVariables: true
1211
- },
1212
- aliases: {
1213
- components: "@/components",
1214
- utils: "@/lib/utils",
1215
- ui: "@/components/ui"
1216
- }
1217
- };
1218
1259
  async function init() {
1219
1260
  console.log(chalk2.bold("\n Welcome to myOperator UI!\n"));
1220
1261
  const cwd = process.cwd();
1221
- const configPath = path2.join(cwd, "components.json");
1222
- if (await fs2.pathExists(configPath)) {
1262
+ const configPath = path3.join(cwd, "components.json");
1263
+ if (await fs3.pathExists(configPath)) {
1223
1264
  const { overwrite } = await prompts2({
1224
1265
  type: "confirm",
1225
1266
  name: "overwrite",
@@ -1231,12 +1272,12 @@ async function init() {
1231
1272
  process.exit(0);
1232
1273
  }
1233
1274
  }
1234
- const packageJsonPath = path2.join(cwd, "package.json");
1275
+ const packageJsonPath = path3.join(cwd, "package.json");
1235
1276
  let hasBootstrap = false;
1236
1277
  let isESM = false;
1237
1278
  let detectedTailwindVersion = null;
1238
- if (await fs2.pathExists(packageJsonPath)) {
1239
- const packageJson2 = await fs2.readJson(packageJsonPath);
1279
+ if (await fs3.pathExists(packageJsonPath)) {
1280
+ const packageJson2 = await fs3.readJson(packageJsonPath);
1240
1281
  hasBootstrap = !!(packageJson2.dependencies?.bootstrap || packageJson2.devDependencies?.bootstrap);
1241
1282
  isESM = packageJson2.type === "module";
1242
1283
  const tailwindDep = packageJson2.dependencies?.tailwindcss || packageJson2.devDependencies?.tailwindcss;
@@ -1268,7 +1309,7 @@ async function init() {
1268
1309
  "styles/globals.css"
1269
1310
  ];
1270
1311
  for (const css of cssOptions) {
1271
- if (await fs2.pathExists(path2.join(cwd, css))) {
1312
+ if (await fs3.pathExists(path3.join(cwd, css))) {
1272
1313
  return css;
1273
1314
  }
1274
1315
  }
@@ -1282,7 +1323,7 @@ async function init() {
1282
1323
  "tailwind.config.cjs"
1283
1324
  ];
1284
1325
  for (const config of configOptions) {
1285
- if (await fs2.pathExists(path2.join(cwd, config))) {
1326
+ if (await fs3.pathExists(path3.join(cwd, config))) {
1286
1327
  return config;
1287
1328
  }
1288
1329
  }
@@ -1290,21 +1331,44 @@ async function init() {
1290
1331
  };
1291
1332
  const detectedCss = await detectGlobalCss();
1292
1333
  const detectedTailwindConfig = await detectTailwindConfig();
1334
+ const detectedPrefix = await detectTailwindPrefix(detectedTailwindConfig, cwd);
1335
+ if (detectedPrefix) {
1336
+ console.log(chalk2.blue(` \u2139 Tailwind prefix "${detectedPrefix}" detected - components will use prefixed classes
1337
+ `));
1338
+ }
1293
1339
  let tailwindVersion = detectedTailwindVersion;
1340
+ let userPrefix = detectedPrefix;
1341
+ const questions = [];
1294
1342
  if (!tailwindVersion) {
1295
- const response = await prompts2([
1296
- {
1297
- type: "select",
1298
- name: "tailwindVersion",
1299
- message: "Which Tailwind CSS version are you using?",
1300
- choices: [
1301
- { title: "Tailwind CSS v4 (latest)", value: "v4" },
1302
- { title: "Tailwind CSS v3", value: "v3" }
1303
- ],
1304
- initial: 0
1343
+ questions.push({
1344
+ type: "select",
1345
+ name: "tailwindVersion",
1346
+ message: "Which Tailwind CSS version are you using?",
1347
+ choices: [
1348
+ { title: "Tailwind CSS v4 (latest)", value: "v4" },
1349
+ { title: "Tailwind CSS v3", value: "v3" }
1350
+ ],
1351
+ initial: 0
1352
+ });
1353
+ }
1354
+ questions.push({
1355
+ type: "text",
1356
+ name: "prefix",
1357
+ message: detectedPrefix ? `Confirm Tailwind prefix (detected: "${detectedPrefix}"):` : "Enter Tailwind CSS prefix (leave empty for none):",
1358
+ initial: detectedPrefix,
1359
+ validate: (value) => {
1360
+ if (value === "" || /^[a-zA-Z_-][a-zA-Z0-9_-]*$/.test(value)) {
1361
+ return true;
1305
1362
  }
1306
- ]);
1307
- tailwindVersion = response.tailwindVersion;
1363
+ return "Prefix must be a valid CSS identifier (letters, numbers, hyphens, underscores)";
1364
+ }
1365
+ });
1366
+ if (questions.length > 0) {
1367
+ const response = await prompts2(questions);
1368
+ if (!tailwindVersion) {
1369
+ tailwindVersion = response.tailwindVersion;
1370
+ }
1371
+ userPrefix = response.prefix || "";
1308
1372
  }
1309
1373
  const componentsPath = "src/components/ui";
1310
1374
  const utilsPath = "src/lib/utils.ts";
@@ -1318,15 +1382,16 @@ async function init() {
1318
1382
  tailwind: {
1319
1383
  ...DEFAULT_CONFIG.tailwind,
1320
1384
  config: tailwindConfig,
1321
- css: globalCss
1385
+ css: globalCss,
1386
+ prefix: userPrefix
1322
1387
  },
1323
1388
  aliases: {
1324
1389
  ...DEFAULT_CONFIG.aliases,
1325
1390
  ui: `@/${componentsPath.replace("src/", "")}`
1326
1391
  }
1327
1392
  };
1328
- await fs2.writeJson(configPath, config, { spaces: 2 });
1329
- const utilsFullPath = path2.join(cwd, utilsPath);
1393
+ await fs3.writeJson(configPath, config, { spaces: 2 });
1394
+ const utilsFullPath = path3.join(cwd, utilsPath);
1330
1395
  const cnUtilsContent = `import { type ClassValue, clsx } from "clsx"
1331
1396
  import { twMerge } from "tailwind-merge"
1332
1397
 
@@ -1336,12 +1401,12 @@ export function cn(...inputs: ClassValue[]) {
1336
1401
  `;
1337
1402
  let utilsCreated = false;
1338
1403
  let utilsUpdated = false;
1339
- if (!await fs2.pathExists(utilsFullPath)) {
1340
- await fs2.ensureDir(path2.dirname(utilsFullPath));
1341
- await fs2.writeFile(utilsFullPath, cnUtilsContent);
1404
+ if (!await fs3.pathExists(utilsFullPath)) {
1405
+ await fs3.ensureDir(path3.dirname(utilsFullPath));
1406
+ await fs3.writeFile(utilsFullPath, cnUtilsContent);
1342
1407
  utilsCreated = true;
1343
1408
  } else {
1344
- const existingUtils = await fs2.readFile(utilsFullPath, "utf-8");
1409
+ const existingUtils = await fs3.readFile(utilsFullPath, "utf-8");
1345
1410
  if (!existingUtils.includes("export function cn") && !existingUtils.includes("export const cn")) {
1346
1411
  let updatedContent = existingUtils;
1347
1412
  const hasClsxImport = existingUtils.includes('from "clsx"') || existingUtils.includes("from 'clsx'");
@@ -1364,13 +1429,13 @@ export function cn(...inputs: ClassValue[]) {
1364
1429
  }
1365
1430
  `;
1366
1431
  updatedContent = updatedContent.trimEnd() + "\n" + cnFunction;
1367
- await fs2.writeFile(utilsFullPath, updatedContent);
1432
+ await fs3.writeFile(utilsFullPath, updatedContent);
1368
1433
  utilsUpdated = true;
1369
1434
  }
1370
1435
  }
1371
- const componentsFullPath = path2.join(cwd, componentsPath);
1372
- await fs2.ensureDir(componentsFullPath);
1373
- const globalCssPath = path2.join(cwd, globalCss);
1436
+ const componentsFullPath = path3.join(cwd, componentsPath);
1437
+ await fs3.ensureDir(componentsFullPath);
1438
+ const globalCssPath = path3.join(cwd, globalCss);
1374
1439
  let cssContent;
1375
1440
  if (tailwindVersion === "v4") {
1376
1441
  cssContent = hasBootstrap ? CSS_VARIABLES_V4_BOOTSTRAP : CSS_VARIABLES_V4;
@@ -1378,12 +1443,12 @@ export function cn(...inputs: ClassValue[]) {
1378
1443
  cssContent = CSS_VARIABLES_V3;
1379
1444
  }
1380
1445
  let cssUpdated = false;
1381
- if (!await fs2.pathExists(globalCssPath)) {
1382
- await fs2.ensureDir(path2.dirname(globalCssPath));
1383
- await fs2.writeFile(globalCssPath, cssContent);
1446
+ if (!await fs3.pathExists(globalCssPath)) {
1447
+ await fs3.ensureDir(path3.dirname(globalCssPath));
1448
+ await fs3.writeFile(globalCssPath, cssContent);
1384
1449
  cssUpdated = true;
1385
1450
  } else {
1386
- const existingCss = await fs2.readFile(globalCssPath, "utf-8");
1451
+ const existingCss = await fs3.readFile(globalCssPath, "utf-8");
1387
1452
  if (!existingCss.includes("myOperator UI") && !existingCss.includes("--mo-background:")) {
1388
1453
  let updateCss = tailwindVersion === "v3";
1389
1454
  if (!updateCss) {
@@ -1399,9 +1464,9 @@ export function cn(...inputs: ClassValue[]) {
1399
1464
  }
1400
1465
  if (updateCss) {
1401
1466
  if (hasBootstrap) {
1402
- await fs2.writeFile(globalCssPath, cssContent + existingCss);
1467
+ await fs3.writeFile(globalCssPath, cssContent + existingCss);
1403
1468
  } else {
1404
- await fs2.writeFile(globalCssPath, cssContent);
1469
+ await fs3.writeFile(globalCssPath, cssContent);
1405
1470
  }
1406
1471
  cssUpdated = true;
1407
1472
  }
@@ -1409,19 +1474,19 @@ export function cn(...inputs: ClassValue[]) {
1409
1474
  }
1410
1475
  let tailwindUpdated = false;
1411
1476
  if (tailwindVersion === "v3" && tailwindConfig) {
1412
- const tailwindConfigPath = path2.join(cwd, tailwindConfig);
1413
- if (!await fs2.pathExists(tailwindConfigPath)) {
1414
- await fs2.writeFile(tailwindConfigPath, getTailwindConfig(disablePreflight));
1477
+ const tailwindConfigPath = path3.join(cwd, tailwindConfig);
1478
+ if (!await fs3.pathExists(tailwindConfigPath)) {
1479
+ await fs3.writeFile(tailwindConfigPath, getTailwindConfig(disablePreflight));
1415
1480
  tailwindUpdated = true;
1416
1481
  } else {
1417
- const existingConfig = await fs2.readFile(tailwindConfigPath, "utf-8");
1482
+ const existingConfig = await fs3.readFile(tailwindConfigPath, "utf-8");
1418
1483
  if (!existingConfig.includes("hsl(var(--destructive))") && !existingConfig.includes("hsl(var(--ring))")) {
1419
- await fs2.writeFile(tailwindConfigPath, getTailwindConfig(disablePreflight));
1484
+ await fs3.writeFile(tailwindConfigPath, getTailwindConfig(disablePreflight));
1420
1485
  tailwindUpdated = true;
1421
1486
  }
1422
1487
  }
1423
1488
  }
1424
- const postcssConfigPath = path2.join(cwd, "postcss.config.js");
1489
+ const postcssConfigPath = path3.join(cwd, "postcss.config.js");
1425
1490
  let postcssConfigContent;
1426
1491
  if (tailwindVersion === "v4") {
1427
1492
  postcssConfigContent = isESM ? `export default {
@@ -1451,8 +1516,8 @@ export function cn(...inputs: ClassValue[]) {
1451
1516
  `;
1452
1517
  }
1453
1518
  let postcssCreated = false;
1454
- if (!await fs2.pathExists(postcssConfigPath)) {
1455
- await fs2.writeFile(postcssConfigPath, postcssConfigContent);
1519
+ if (!await fs3.pathExists(postcssConfigPath)) {
1520
+ await fs3.writeFile(postcssConfigPath, postcssConfigContent);
1456
1521
  postcssCreated = true;
1457
1522
  } else {
1458
1523
  spinner.stop();
@@ -1464,7 +1529,7 @@ export function cn(...inputs: ClassValue[]) {
1464
1529
  });
1465
1530
  spinner.start("Initializing project...");
1466
1531
  if (updatePostcss) {
1467
- await fs2.writeFile(postcssConfigPath, postcssConfigContent);
1532
+ await fs3.writeFile(postcssConfigPath, postcssConfigContent);
1468
1533
  postcssCreated = true;
1469
1534
  }
1470
1535
  }
@@ -1482,6 +1547,11 @@ export function cn(...inputs: ClassValue[]) {
1482
1547
  }
1483
1548
  spinner.succeed("Project initialized successfully!");
1484
1549
  console.log(chalk2.green("\n \u2713 Created components.json"));
1550
+ if (userPrefix) {
1551
+ console.log(chalk2.blue(` \u2139 Components will use prefix: "${userPrefix}"`));
1552
+ } else {
1553
+ console.log(chalk2.blue(` \u2139 Components will use no prefix`));
1554
+ }
1485
1555
  if (utilsCreated) {
1486
1556
  console.log(chalk2.green(` \u2713 Created ${utilsPath}`));
1487
1557
  } else if (utilsUpdated) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-ui",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "description": "CLI for adding myOperator UI components to your project",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",
@@ -12,9 +12,14 @@
12
12
  ],
13
13
  "scripts": {
14
14
  "generate-registry": "node scripts/generate-registry.js",
15
- "build": "npm run generate-registry && tsup src/index.ts --format esm --dts",
15
+ "validate-registry": "node scripts/validate-registry.js",
16
+ "verify-build": "node scripts/verify-build.js",
17
+ "build": "npm run generate-registry && tsup src/index.ts --format esm --dts && npm run verify-build",
16
18
  "dev": "tsup src/index.ts --format esm --watch",
17
- "typecheck": "tsc --noEmit"
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "prepublishOnly": "npm run build && npm run validate-registry"
18
23
  },
19
24
  "dependencies": {
20
25
  "chalk": "^5.3.0",
@@ -28,7 +33,8 @@
28
33
  "@types/node": "^20.11.0",
29
34
  "@types/prompts": "^2.4.9",
30
35
  "tsup": "^8.0.1",
31
- "typescript": "^5.3.3"
36
+ "typescript": "^5.3.3",
37
+ "vitest": "^1.0.0"
32
38
  },
33
39
  "keywords": [
34
40
  "myoperator",