ui-thing 0.2.4 → 0.2.6

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.
@@ -0,0 +1,19 @@
1
+ import js from "@eslint/js";
2
+ import { defineConfig } from "eslint/config";
3
+ import globals from "globals";
4
+ import tseslint from "typescript-eslint";
5
+
6
+ export default defineConfig([
7
+ {
8
+ files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
9
+ plugins: { js },
10
+ extends: ["js/recommended"],
11
+ languageOptions: { globals: globals.node },
12
+ },
13
+ tseslint.configs.recommended,
14
+ {
15
+ rules: {
16
+ "@typescript-eslint/no-explicit-any": "off",
17
+ },
18
+ },
19
+ ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-thing",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "CLI used to add Nuxt components to a project",
5
5
  "keywords": [
6
6
  "cli",
@@ -13,6 +13,7 @@
13
13
  "shadcn-ui"
14
14
  ],
15
15
  "repository": {
16
+ "type": "git",
16
17
  "url": "git+https://github.com/BayBreezy/ui-thing-cli.git"
17
18
  },
18
19
  "license": "MIT",
@@ -35,7 +36,9 @@
35
36
  "format": "npx prettier --write .",
36
37
  "knip": "knip",
37
38
  "knip:fix": "knip --fix",
39
+ "lint": "eslint src",
38
40
  "lint-staged": "lint-staged",
41
+ "lint:fix": "eslint src --fix",
39
42
  "prepare": "husky",
40
43
  "release": "npm run build && npx changelogen@latest --release && npm publish && git push --follow-tags",
41
44
  "start": "node dist/index.js",
@@ -47,37 +50,42 @@
47
50
  ]
48
51
  },
49
52
  "dependencies": {
50
- "axios": "^1.11.0",
53
+ "axios": "^1.13.1",
51
54
  "boxen": "^8.0.1",
52
- "c12": "^3.2.0",
53
- "commander": "^14.0.0",
55
+ "c12": "^3.3.1",
56
+ "commander": "^14.0.2",
54
57
  "consola": "^3.4.2",
55
- "dotenv": "^17.2.1",
56
- "es-toolkit": "^1.39.9",
58
+ "dotenv": "^17.2.3",
59
+ "es-toolkit": "^1.41.0",
57
60
  "execa": "^9.6.0",
58
- "figlet": "^1.8.2",
59
- "fs-extra": "^11.3.1",
61
+ "figlet": "^1.9.3",
62
+ "fs-extra": "^11.3.2",
60
63
  "kleur": "^4.1.5",
61
64
  "lodash": "^4.17.21",
62
65
  "magicast": "^0.3.5",
63
- "ora": "^8.2.0",
66
+ "ora": "^9.0.0",
64
67
  "prompts": "^2.4.2"
65
68
  },
66
69
  "devDependencies": {
67
- "@ianvs/prettier-plugin-sort-imports": "^4.6.2",
70
+ "@eslint/js": "^9.38.0",
71
+ "@ianvs/prettier-plugin-sort-imports": "^4.7.0",
68
72
  "@types/figlet": "^1.7.0",
69
73
  "@types/fs-extra": "^11.0.4",
70
74
  "@types/lodash": "^4.17.20",
71
- "@types/node": "^24.2.1",
75
+ "@types/node": "^24.9.2",
72
76
  "@types/prompts": "^2.4.9",
73
- "@vitest/coverage-v8": "^3.2.4",
77
+ "@vitest/coverage-v8": "^4.0.5",
78
+ "eslint": "^9.38.0",
79
+ "globals": "^16.4.0",
74
80
  "husky": "^9.1.7",
75
- "knip": "^5.62.0",
76
- "lint-staged": "^16.1.5",
81
+ "jiti": "^2.6.1",
82
+ "knip": "^5.66.4",
83
+ "lint-staged": "^16.2.6",
77
84
  "prettier": "^3.6.2",
78
85
  "tsup": "^8.5.0",
79
- "typescript": "^5.9.2",
80
- "vitest": "^3.2.4"
86
+ "typescript": "^5.9.3",
87
+ "typescript-eslint": "^8.46.2",
88
+ "vitest": "^4.0.5"
81
89
  },
82
90
  "publishConfig": {
83
91
  "access": "public"
@@ -109,7 +109,7 @@ const runAddCommand = async (components: string[], options: AddCommand) => {
109
109
  }
110
110
 
111
111
  // Step 5 — Collect found components and their dependencies
112
- let found: Component[] = componentNames
112
+ const found: Component[] = componentNames
113
113
  .map((name) => findComponent(name))
114
114
  .filter(Boolean) as Component[];
115
115
 
@@ -8,11 +8,11 @@ import ora from "ora";
8
8
  import { createCSS } from "../templates/css";
9
9
  import { TW_HELPER } from "../templates/tw-helper";
10
10
  import { InitOptions, UIConfig } from "../types";
11
- import { addPrettierConfig } from "../utils/addPrettierConfig";
11
+ import { addPrettierConfig, askPrettierConfig } from "../utils/addPrettierConfig";
12
12
  import { addTailwindVitePlugin } from "../utils/addTailwindVitePlugin";
13
13
  import { addVSCodeFiles } from "../utils/addVSCodeFiles";
14
14
  import { getUIConfig } from "../utils/config";
15
- import { INIT_DEPS, INIT_DEV_DEPS, INIT_MODULES } from "../utils/constants";
15
+ import { INIT_DEPS, INIT_DEV_DEPS, INIT_DEV_DEPS_PRETTIER, INIT_MODULES } from "../utils/constants";
16
16
  import { installPackages } from "../utils/installPackages";
17
17
  import { printFancyBoxMessage } from "../utils/printFancyBoxMessage";
18
18
 
@@ -21,7 +21,7 @@ import { printFancyBoxMessage } from "../utils/printFancyBoxMessage";
21
21
  */
22
22
  const runInitCommand = async (options: InitOptions) => {
23
23
  // Get or create the initial configuration file
24
- let uiConfig: UIConfig = await getUIConfig(options);
24
+ const uiConfig: UIConfig = await getUIConfig(options);
25
25
  const spinner = ora("Updating nuxt.config...").start();
26
26
  // Get nuxt config
27
27
  await updateConfig({
@@ -103,8 +103,12 @@ const runInitCommand = async (options: InitOptions) => {
103
103
  spinner.succeed("Merged VS Code settings!");
104
104
  // Install deps
105
105
  await installPackages(uiConfig.packageManager, INIT_DEPS, INIT_DEV_DEPS);
106
- // Add prettier config
107
- await addPrettierConfig();
106
+ // Add prettier config if user agrees
107
+ const addPrettier = await askPrettierConfig();
108
+ if (addPrettier) {
109
+ await installPackages(uiConfig.packageManager, [], INIT_DEV_DEPS_PRETTIER);
110
+ await addPrettierConfig();
111
+ }
108
112
  printFancyBoxMessage(
109
113
  "Initialized",
110
114
  `Feel free to start adding components with the ${kleur.bgWhite(" add ")} command.`,
@@ -2,7 +2,7 @@ import { Command } from "commander";
2
2
  import prompts from "prompts";
3
3
 
4
4
  import { addPrettierConfig } from "../utils/addPrettierConfig";
5
- import { PACKAGE_MANAGER_CHOICES } from "../utils/constants";
5
+ import { INIT_DEV_DEPS_PRETTIER, PACKAGE_MANAGER_CHOICES } from "../utils/constants";
6
6
  import { installPackages } from "../utils/installPackages";
7
7
  import { printFancyBoxMessage } from "../utils/printFancyBoxMessage";
8
8
 
@@ -28,11 +28,7 @@ export const addPrettier = new Command()
28
28
  if (!pkgManager) return process.exit(0);
29
29
 
30
30
  // install prettier dep
31
- await installPackages(pkgManager, undefined, [
32
- "prettier",
33
- "prettier-plugin-tailwindcss",
34
- "@ianvs/prettier-plugin-sort-imports",
35
- ]);
31
+ await installPackages(pkgManager, undefined, INIT_DEV_DEPS_PRETTIER);
36
32
  printFancyBoxMessage(
37
33
  "All Done!",
38
34
  `A .prettierrc file has been added to your project and the code formatted. Enjoy!`,
@@ -10,6 +10,13 @@ import { getUIConfig } from "../utils/config";
10
10
  import { CSS_THEME_OPTIONS } from "../utils/constants";
11
11
  import { printFancyBoxMessage } from "../utils/printFancyBoxMessage";
12
12
 
13
+ /**
14
+ * Validates if a theme name exists in the predefined options.
15
+ */
16
+ const validateThemeName = (name: string) => {
17
+ return CSS_THEME_OPTIONS.some((option) => option.value === name?.toLowerCase());
18
+ };
19
+
13
20
  /**
14
21
  * Adds a new theme to the project.
15
22
  */
@@ -17,10 +24,11 @@ export const theme = new Command()
17
24
  .command("theme")
18
25
  .name("theme")
19
26
  .description("Add a new theme to your project.")
20
- .action(async () => {
27
+ .argument("[themeName]", "The name of the theme you would like to add")
28
+ .action(async (themeName?: string) => {
21
29
  // Get ui config
22
30
  let uiConfig = await getUIConfig();
23
- let uiConfigIsCorrect = await compareUIConfig();
31
+ const uiConfigIsCorrect = await compareUIConfig();
24
32
  if (!uiConfigIsCorrect) {
25
33
  uiConfig = await getUIConfig({ force: true });
26
34
  }
@@ -28,25 +36,35 @@ export const theme = new Command()
28
36
  console.log(kleur.red("Config file not set. Exiting..."));
29
37
  process.exit(0);
30
38
  }
31
- const { theme } = await prompts([
32
- {
33
- name: "theme",
34
- type: "autocomplete",
35
- message: "Which theme do you want to add?",
36
- choices: CSS_THEME_OPTIONS,
37
- },
38
- ]);
39
- if (!theme) {
40
- console.log(kleur.red("No theme selected. Exiting..."));
41
- process.exit(0);
39
+
40
+ let selectedTheme =
41
+ themeName && validateThemeName(themeName) ? themeName.toLowerCase() : undefined;
42
+
43
+ if (!selectedTheme) {
44
+ // Prompt for theme if not provided or invalid
45
+ const { theme } = await prompts([
46
+ {
47
+ name: "theme",
48
+ type: "autocomplete",
49
+ message: "Which theme do you want to add?",
50
+ choices: CSS_THEME_OPTIONS,
51
+ },
52
+ ]);
53
+ if (!theme) {
54
+ console.log(kleur.red("No theme selected. Exiting..."));
55
+ process.exit(0);
56
+ }
57
+ selectedTheme = theme;
42
58
  }
59
+
60
+ // Check if the file exists
43
61
  if (fse.existsSync(uiConfig.tailwindCSSLocation)) {
44
62
  const { force } = await prompts([
45
63
  {
46
64
  name: "force",
47
65
  type: "confirm",
48
- message: "Do you want to overwrite your current css file?",
49
- initial: true,
66
+ message: "The Tailwind CSS file already exists. Overwrite?",
67
+ initial: false,
50
68
  },
51
69
  ]);
52
70
  if (!force) {
@@ -54,11 +72,16 @@ export const theme = new Command()
54
72
  return process.exit(0);
55
73
  }
56
74
  }
57
- fse.writeFileSync(uiConfig.tailwindCSSLocation, createCSS(theme.toUpperCase() as any), "utf-8");
75
+
76
+ fse.writeFileSync(
77
+ uiConfig.tailwindCSSLocation,
78
+ createCSS(selectedTheme!.toUpperCase() as any),
79
+ "utf-8"
80
+ );
58
81
 
59
82
  printFancyBoxMessage(
60
- `${_.capitalize(theme)}`,
61
- `${_.capitalize(theme)} theme has been added to ${uiConfig.tailwindCSSLocation}`,
83
+ `${_.capitalize(selectedTheme!)}`,
84
+ `${_.capitalize(selectedTheme!)} theme has been added to ${uiConfig.tailwindCSSLocation}`,
62
85
  { box: { title: "New Theme Added" } }
63
86
  );
64
87
  });
@@ -67,3 +67,16 @@ export const addPrettierConfig = async (cwd = process.cwd(), format: boolean = t
67
67
 
68
68
  return true;
69
69
  };
70
+
71
+ /**
72
+ * Asks the user if they want to add a Prettier configuration.
73
+ */
74
+ export const askPrettierConfig = async (): Promise<boolean> => {
75
+ const { addPrettier } = await prompts({
76
+ name: "addPrettier",
77
+ type: "confirm",
78
+ message: "Would you like to add a Prettier configuration to your project?",
79
+ initial: true,
80
+ });
81
+ return addPrettier;
82
+ };
@@ -10,7 +10,7 @@ import { getUIConfig } from "./config";
10
10
  */
11
11
  export const addShortcutFiles = async (cwd = process.cwd()) => {
12
12
  // get config
13
- let userConfig: UIConfig = await getUIConfig();
13
+ const userConfig: UIConfig = await getUIConfig();
14
14
  const composablesLocation = join(cwd, userConfig.composablesLocation);
15
15
  // ensure that the composable folder exists
16
16
  await fse.ensureDir(composablesLocation);
@@ -7,7 +7,7 @@ import { getUIConfig } from "./config";
7
7
  */
8
8
  export const compareUIConfig = async () => {
9
9
  // Get ui config
10
- let userConfig: UIConfig = await getUIConfig();
10
+ const userConfig: UIConfig = await getUIConfig();
11
11
  const tempConfig: UIConfig = {
12
12
  nuxtVersion: 3,
13
13
  theme: "string",
@@ -70,7 +70,11 @@ export const getUIConfig = async (options?: InitOptions): Promise<UIConfig> => {
70
70
  const createConfigPaths = (uiConfig: UIConfig) => {
71
71
  const ensureFileOrDir = (pathValue?: string, isDir = false) => {
72
72
  if (!pathValue) return;
73
- isDir ? fse.ensureDirSync(pathValue) : fse.ensureFileSync(pathValue);
73
+ if (isDir) {
74
+ fse.ensureDirSync(pathValue);
75
+ } else {
76
+ fse.ensureFileSync(pathValue);
77
+ }
74
78
  };
75
79
 
76
80
  ensureFileOrDir(uiConfig.tailwindCSSLocation);
@@ -58,12 +58,14 @@ export const INIT_DEPS = [
58
58
  /**
59
59
  * The initial development dependencies
60
60
  */
61
- export const INIT_DEV_DEPS = [
62
- "typescript",
61
+ export const INIT_DEV_DEPS = ["typescript", "tw-animate-css"];
62
+ /**
63
+ * The initial development dependencies for prettier stuff
64
+ */
65
+ export const INIT_DEV_DEPS_PRETTIER = [
63
66
  "prettier-plugin-tailwindcss",
64
67
  "prettier",
65
68
  "@ianvs/prettier-plugin-sort-imports",
66
- "tw-animate-css",
67
69
  ];
68
70
 
69
71
  /**
@@ -4,6 +4,7 @@ export const fileExists = async (path: string) => {
4
4
  try {
5
5
  await fs.promises.access(path, fs.constants.F_OK || fs.constants.W_OK);
6
6
  return true;
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7
8
  } catch (error) {
8
9
  return false;
9
10
  }
@@ -1,7 +1,6 @@
1
1
  import prompts from "prompts";
2
2
 
3
3
  import { Component } from "../types";
4
- import { fetchComponents } from "./fetchComponents";
5
4
 
6
5
  /**
7
6
  * Prompts the user to select components to add.
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
1
2
  import kleur from "kleur";
2
3
  import prompts from "prompts";
3
4