bearnie 0.1.5 → 0.1.7

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/README.md CHANGED
@@ -14,13 +14,15 @@ npx bearnie init
14
14
  # 3. Add components
15
15
  npx bearnie add button card input
16
16
 
17
- # 4. Use in your Astro pages
17
+ # 4. Optional: add barrel export for named imports
18
+ npx bearnie add barrel
19
+
20
+ # 5. Use in your Astro pages
18
21
  ```
19
22
 
20
23
  ```astro
21
24
  ---
22
- import Button from "@/components/ui/button/Button.astro";
23
- import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
25
+ import { Button, Card, CardHeader, CardTitle, CardContent } from "@/components/bearnie";
24
26
  ---
25
27
 
26
28
  <Card>
@@ -60,6 +62,8 @@ This will:
60
62
  - Create the `cn()` utility function
61
63
  - Install `clsx`, `tailwind-merge`, and `tailwindcss` dependencies
62
64
 
65
+ Projects created with `create-bearnie` already include `bearnie.json` and can skip init.
66
+
63
67
  **Options:**
64
68
 
65
69
  - `-y, --yes` - Skip confirmation prompts and use defaults
@@ -79,6 +83,9 @@ npx bearnie add button card input
79
83
  # Add all available components
80
84
  npx bearnie add --all
81
85
 
86
+ # Add barrel export (after components are installed)
87
+ npx bearnie add barrel
88
+
82
89
  # Interactive component selection
83
90
  npx bearnie add
84
91
  ```
@@ -101,6 +108,8 @@ npx bearnie list
101
108
  npx bearnie list --json
102
109
  ```
103
110
 
111
+ Components are grouped by category, including **Theme** (`styles`) and **Meta** (`barrel`).
112
+
104
113
  **Options:**
105
114
 
106
115
  - `--json` - Output as JSON
@@ -113,6 +122,7 @@ After running `init`, a `bearnie.json` file is created in your project root:
113
122
  {
114
123
  "componentsDir": "src/components/bearnie",
115
124
  "utilsDir": "src/utils",
125
+ "stylesDir": "src/styles",
116
126
  "typescript": true
117
127
  }
118
128
  ```
@@ -123,6 +133,7 @@ After running `init`, a `bearnie.json` file is created in your project root:
123
133
  | --------------- | --------- | --------------------- | -------------------------------------------- |
124
134
  | `componentsDir` | `string` | `"src/components/bearnie"` | Directory where components will be installed |
125
135
  | `utilsDir` | `string` | `"src/utils"` | Directory for utility functions |
136
+ | `stylesDir` | `string` | `"src/styles"` | Directory for theme styles |
126
137
  | `typescript` | `boolean` | `true` | Whether to use TypeScript |
127
138
 
128
139
  ## Environment Variables
@@ -141,15 +152,14 @@ For local development and testing:
141
152
  git clone https://github.com/michael-andreuzza/bearnie.git
142
153
  cd bearnie
143
154
 
144
- # Install CLI dependencies
145
- cd packages/cli
155
+ # Install dependencies (npm workspaces)
146
156
  npm install
147
157
 
148
- # Build the CLI
149
- npm run build
158
+ # Build packages
159
+ npm run build:packages
150
160
 
151
- # Link for local testing
152
- npm link
161
+ # Link CLI for local testing
162
+ npm run cli:link
153
163
 
154
164
  # Now you can use it
155
165
  bearnie add button
@@ -195,7 +205,7 @@ BEARNIE_REGISTRY_URL=http://localhost:4321/registry bearnie add button
195
205
 
196
206
  ```astro
197
207
  ---
198
- import Button from "@/components/ui/button/Button.astro";
208
+ import Button from "@/components/bearnie/button/Button.astro";
199
209
  ---
200
210
 
201
211
  <Button>Default</Button>
@@ -210,9 +220,9 @@ import Button from "@/components/ui/button/Button.astro";
210
220
 
211
221
  ```astro
212
222
  ---
213
- import Input from "@/components/ui/input/Input.astro";
214
- import Label from "@/components/ui/label/Label.astro";
215
- import Button from "@/components/ui/button/Button.astro";
223
+ import Input from "@/components/bearnie/input/Input.astro";
224
+ import Label from "@/components/bearnie/label/Label.astro";
225
+ import Button from "@/components/bearnie/button/Button.astro";
216
226
  ---
217
227
 
218
228
  <form class="space-y-4">
@@ -232,13 +242,13 @@ import Button from "@/components/ui/button/Button.astro";
232
242
 
233
243
  ```astro
234
244
  ---
235
- import Card from "@/components/ui/card/Card.astro";
236
- import CardHeader from "@/components/ui/card/CardHeader.astro";
237
- import CardTitle from "@/components/ui/card/CardTitle.astro";
238
- import CardDescription from "@/components/ui/card/CardDescription.astro";
239
- import CardContent from "@/components/ui/card/CardContent.astro";
240
- import CardFooter from "@/components/ui/card/CardFooter.astro";
241
- import Button from "@/components/ui/button/Button.astro";
245
+ import Card from "@/components/bearnie/card/Card.astro";
246
+ import CardHeader from "@/components/bearnie/card/CardHeader.astro";
247
+ import CardTitle from "@/components/bearnie/card/CardTitle.astro";
248
+ import CardDescription from "@/components/bearnie/card/CardDescription.astro";
249
+ import CardContent from "@/components/bearnie/card/CardContent.astro";
250
+ import CardFooter from "@/components/bearnie/card/CardFooter.astro";
251
+ import Button from "@/components/bearnie/button/Button.astro";
242
252
  ---
243
253
 
244
254
  <Card class="w-96">
@@ -259,9 +269,9 @@ import Button from "@/components/ui/button/Button.astro";
259
269
 
260
270
  ```astro
261
271
  ---
262
- import Alert from "@/components/ui/alert/Alert.astro";
263
- import AlertTitle from "@/components/ui/alert/AlertTitle.astro";
264
- import AlertDescription from "@/components/ui/alert/AlertDescription.astro";
272
+ import Alert from "@/components/bearnie/alert/Alert.astro";
273
+ import AlertTitle from "@/components/bearnie/alert/AlertTitle.astro";
274
+ import AlertDescription from "@/components/bearnie/alert/AlertDescription.astro";
265
275
  ---
266
276
 
267
277
  <Alert>
@@ -0,0 +1,7 @@
1
+ interface AddOptions {
2
+ yes?: boolean;
3
+ all?: boolean;
4
+ cwd: string;
5
+ }
6
+ export declare function add(components: string[], options: AddOptions): Promise<void>;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ interface InitOptions {
2
+ yes?: boolean;
3
+ cwd: string;
4
+ }
5
+ export declare function init(options: InitOptions): Promise<void>;
6
+ export {};
@@ -0,0 +1,5 @@
1
+ interface ListOptions {
2
+ json?: boolean;
3
+ }
4
+ export declare function list(options: ListOptions): Promise<void>;
5
+ export {};
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  #!/usr/bin/env node
2
+ export {};
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
+ import { readFileSync } from "fs";
5
+ import { dirname, join } from "path";
6
+ import { fileURLToPath } from "url";
4
7
  import { Command } from "commander";
5
8
  import chalk5 from "chalk";
6
9
 
@@ -18,6 +21,7 @@ import fs from "fs-extra";
18
21
  var DEFAULT_CONFIG = {
19
22
  componentsDir: "src/components/bearnie",
20
23
  utilsDir: "src/utils",
24
+ stylesDir: "src/styles",
21
25
  tailwindConfig: "tailwind.config.mjs",
22
26
  typescript: true
23
27
  };
@@ -26,7 +30,7 @@ async function getProjectConfig(cwd) {
26
30
  const configPath = path.join(cwd, CONFIG_FILE);
27
31
  if (await fs.pathExists(configPath)) {
28
32
  const content = await fs.readFile(configPath, "utf-8");
29
- return JSON.parse(content);
33
+ return { ...DEFAULT_CONFIG, ...JSON.parse(content) };
30
34
  }
31
35
  return null;
32
36
  }
@@ -58,6 +62,17 @@ async function hasTailwindInstalled(cwd) {
58
62
  };
59
63
  return "tailwindcss" in deps;
60
64
  }
65
+ function resolveInstallPath(cwd, config, filePath, componentType) {
66
+ const isUtilityFile = componentType === "utility" || filePath.startsWith("utils/");
67
+ const isStylesFile = componentType === "styles" || filePath.startsWith("styles/");
68
+ if (isUtilityFile) {
69
+ return path.join(cwd, config.utilsDir, filePath.replace(/^utils\//, ""));
70
+ }
71
+ if (isStylesFile) {
72
+ return path.join(cwd, config.stylesDir, filePath.replace(/^styles\//, ""));
73
+ }
74
+ return path.join(cwd, config.componentsDir, filePath);
75
+ }
61
76
 
62
77
  // src/utils/ui.ts
63
78
  import chalk from "chalk";
@@ -249,6 +264,7 @@ async function init(options) {
249
264
  try {
250
265
  await fs2.ensureDir(path2.join(cwd, config.componentsDir));
251
266
  await fs2.ensureDir(path2.join(cwd, config.utilsDir));
267
+ await fs2.ensureDir(path2.join(cwd, config.stylesDir));
252
268
  spinner.text = "Creating directories...";
253
269
  } catch (error) {
254
270
  spinner.fail("Couldn't create directories");
@@ -465,10 +481,12 @@ async function add(components, options) {
465
481
  component.dependencies?.forEach((d) => npmDeps.add(d));
466
482
  component.devDependencies?.forEach((d) => npmDevDeps.add(d));
467
483
  for (const file of component.files) {
468
- const isUtilityFile = component.type === "utility" || file.path.startsWith("utils/");
469
- const relativePath = isUtilityFile ? file.path.replace(/^utils\//, "") : file.path;
470
- const baseDir = isUtilityFile ? config.utilsDir : config.componentsDir;
471
- const filePath = path4.join(cwd, baseDir, relativePath);
484
+ const filePath = resolveInstallPath(
485
+ cwd,
486
+ config,
487
+ file.path,
488
+ component.type
489
+ );
472
490
  const exists = await fs4.pathExists(filePath);
473
491
  if (exists && !options.yes) {
474
492
  skippedFiles.push(file.path);
@@ -561,6 +579,8 @@ async function list(options) {
561
579
  categories.get(cat).push(component);
562
580
  }
563
581
  const categoryConfig = {
582
+ theme: { emoji: "\u{1F3A8}", label: "Theme" },
583
+ meta: { emoji: "\u{1F4E6}", label: "Meta" },
564
584
  foundation: { emoji: "\u{1F3A8}", label: "Foundation" },
565
585
  form: { emoji: "\u{1F4DD}", label: "Form" },
566
586
  layout: { emoji: "\u{1F4D0}", label: "Layout" },
@@ -571,6 +591,8 @@ async function list(options) {
571
591
  other: { emoji: "\u{1F4E6}", label: "Other" }
572
592
  };
573
593
  const categoryOrder = [
594
+ "theme",
595
+ "meta",
574
596
  "foundation",
575
597
  "form",
576
598
  "layout",
@@ -599,6 +621,7 @@ async function list(options) {
599
621
  console.log(` ${brand.muted("\u2192")} Add a component: ${chalk4.cyan("npx bearnie add button")}`);
600
622
  console.log(` ${brand.muted("\u2192")} Add everything: ${chalk4.cyan("npx bearnie add --all")}`);
601
623
  console.log(` ${brand.muted("\u2192")} Add CSS variables: ${chalk4.cyan("npx bearnie add styles")}`);
624
+ console.log(` ${brand.muted("\u2192")} Add barrel export: ${chalk4.cyan("npx bearnie add barrel")}`);
602
625
  print.newline();
603
626
  } catch (error) {
604
627
  spinner.fail(messages.networkError());
@@ -608,11 +631,15 @@ async function list(options) {
608
631
  }
609
632
 
610
633
  // src/index.ts
634
+ var __dirname = dirname(fileURLToPath(import.meta.url));
635
+ var pkg = JSON.parse(
636
+ readFileSync(join(__dirname, "../package.json"), "utf-8")
637
+ );
611
638
  var amber = chalk5.hex("#F59E0B");
612
639
  var logo2 = `${amber("\u{1F43B}")} ${chalk5.bold("bearnie")}`;
613
640
  var link = (text, url) => `\x1B]8;;${url}\x07${chalk5.cyan(text)}\x1B]8;;\x07`;
614
641
  var program = new Command();
615
- program.name("bearnie").description("UI components for Astro").version("0.1.0").configureOutput({
642
+ program.name("bearnie").description("UI components for Astro").version(pkg.version).configureOutput({
616
643
  writeOut: (str) => process.stdout.write(str),
617
644
  writeErr: (str) => process.stdout.write(str),
618
645
  outputError: (str, write) => {
@@ -0,0 +1,22 @@
1
+ export interface ProjectConfig {
2
+ componentsDir: string;
3
+ utilsDir: string;
4
+ stylesDir: string;
5
+ tailwindConfig: string;
6
+ typescript: boolean;
7
+ }
8
+ export declare const DEFAULT_CONFIG: ProjectConfig;
9
+ export declare const CONFIG_FILE = "bearnie.json";
10
+ export declare function getProjectConfig(cwd: string): Promise<ProjectConfig | null>;
11
+ export declare function saveProjectConfig(cwd: string, config: ProjectConfig): Promise<void>;
12
+ export declare function isAstroProject(cwd: string): Promise<boolean>;
13
+ export declare function hasTailwindInstalled(cwd: string): Promise<boolean>;
14
+ export declare function writeComponentFile(cwd: string, config: ProjectConfig, componentPath: string, content: string, overwrite?: boolean): Promise<{
15
+ written: boolean;
16
+ path: string;
17
+ }>;
18
+ export declare function resolveInstallPath(cwd: string, config: ProjectConfig, filePath: string, componentType?: string): string;
19
+ export declare function writeUtilFile(cwd: string, config: ProjectConfig, utilPath: string, content: string, overwrite?: boolean): Promise<{
20
+ written: boolean;
21
+ path: string;
22
+ }>;
@@ -0,0 +1,30 @@
1
+ export declare const REGISTRY_URL: string;
2
+ export declare const REGISTRY_PATH: string | undefined;
3
+ export declare const REGISTRY_INDEX_URL: string;
4
+ export interface RegistryComponent {
5
+ name: string;
6
+ type?: "component" | "utility" | "styles";
7
+ description: string;
8
+ category: string;
9
+ dependencies?: string[];
10
+ devDependencies?: string[];
11
+ registryDependencies?: string[];
12
+ files: RegistryFile[];
13
+ }
14
+ export interface RegistryFile {
15
+ name: string;
16
+ path: string;
17
+ content: string;
18
+ }
19
+ export interface RegistryIndex {
20
+ name: string;
21
+ version: string;
22
+ components: {
23
+ name: string;
24
+ description: string;
25
+ category: string;
26
+ }[];
27
+ }
28
+ export declare function getRegistryIndex(): Promise<RegistryIndex>;
29
+ export declare function getComponent(name: string): Promise<RegistryComponent>;
30
+ export declare function resolveComponentDependencies(names: string[], resolved?: Set<string>): Promise<string[]>;
@@ -0,0 +1,57 @@
1
+ export declare const brand: {
2
+ primary: import("chalk").ChalkInstance;
3
+ secondary: import("chalk").ChalkInstance;
4
+ accent: import("chalk").ChalkInstance;
5
+ muted: import("chalk").ChalkInstance;
6
+ success: import("chalk").ChalkInstance;
7
+ warning: import("chalk").ChalkInstance;
8
+ error: import("chalk").ChalkInstance;
9
+ info: import("chalk").ChalkInstance;
10
+ };
11
+ export declare const banner: string;
12
+ export declare const logo: string;
13
+ export declare const messages: {
14
+ greeting: () => string;
15
+ initStart: () => string;
16
+ initSuccess: () => string;
17
+ alreadyInit: () => string;
18
+ addStart: () => string;
19
+ fetching: () => string;
20
+ foundComponents: (count: number) => string;
21
+ resolving: () => string;
22
+ installing: (name: string) => string;
23
+ installed: (name: string) => string;
24
+ installingDeps: () => string;
25
+ listHeader: (version: string) => string;
26
+ listFooter: (count: number) => string;
27
+ success: () => string;
28
+ notAstro: () => string;
29
+ notAstroHelp: () => string;
30
+ networkError: () => string;
31
+ networkErrorHelp: () => string;
32
+ unknownComponent: (names: string[]) => string;
33
+ hint: (text: string) => string;
34
+ nextStep: (step: string) => string;
35
+ };
36
+ export declare function box(content: string, title?: string): string;
37
+ export declare const newline: () => void;
38
+ export declare const space: (n?: number) => void;
39
+ export declare const print: {
40
+ banner: () => void;
41
+ logo: () => void;
42
+ greeting: () => void;
43
+ success: () => void;
44
+ newline: () => void;
45
+ step: (text: string) => void;
46
+ hint: (text: string) => void;
47
+ error: (text: string) => void;
48
+ warning: (text: string) => void;
49
+ info: (text: string) => void;
50
+ nextSteps: (steps: string[]) => void;
51
+ footer: () => void;
52
+ };
53
+ export declare const promptsTheme: {
54
+ prefix: string;
55
+ highlight: import("chalk").ChalkInstance;
56
+ submit: string;
57
+ };
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "bearnie",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "CLI for installing Bearnie UI components",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "bin": "dist/index.js",
8
+ "types": "dist/index.d.ts",
8
9
  "files": [
9
10
  "dist"
10
11
  ],
11
12
  "scripts": {
12
- "build": "tsup src/index.ts --format esm --dts --clean",
13
+ "build": "tsup src/index.ts --format esm --clean && tsc --emitDeclarationOnly",
13
14
  "dev": "tsup src/index.ts --format esm --watch",
14
15
  "typecheck": "tsc --noEmit"
15
16
  },
@@ -27,7 +28,7 @@
27
28
  "@types/node": "^20.14.9",
28
29
  "@types/prompts": "^2.4.9",
29
30
  "tsup": "^8.1.0",
30
- "typescript": "^5.5.3"
31
+ "typescript": "^5.7.3"
31
32
  },
32
33
  "engines": {
33
34
  "node": ">=18"