create-bearnie 0.4.1 → 0.4.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.
package/README.md CHANGED
@@ -22,19 +22,22 @@ Include all components from the start:
22
22
  npx create-bearnie my-app --full
23
23
  ```
24
24
 
25
- This fetches all components from the registry and installs them in your project.
25
+ This fetches all components from the registry, installs them in `src/components/bearnie/`, and adds a barrel export at `src/components/bearnie/index.ts`.
26
26
 
27
27
  ## What's included
28
28
 
29
- - Astro 5 with TypeScript
29
+ - Astro 7 with TypeScript
30
30
  - Tailwind CSS v4 (via `@tailwindcss/vite`)
31
31
  - Bearnie CSS variables and theme
32
+ - `bearnie.json` CLI config at the project root
32
33
  - Simple landing page to get started
33
34
  - Ready for components via `npx bearnie add`
34
35
 
35
36
  With `--full` flag:
36
- - All Bearnie UI components
37
- - Utility functions (`cn`, `focus-trap`)
37
+
38
+ - All Bearnie UI components in `src/components/bearnie/`
39
+ - Barrel export (`src/components/bearnie/index.ts`) for named imports
40
+ - Utility functions (`cn`, runtime helpers, `focus-trap`)
38
41
  - Additional dependencies (`clsx`, `tailwind-merge`)
39
42
 
40
43
  ## After creating your project
@@ -49,6 +52,15 @@ Without `--full`, add components as needed:
49
52
 
50
53
  ```bash
51
54
  npx bearnie add button card dialog
55
+ npx bearnie add barrel
56
+ ```
57
+
58
+ Import from the barrel after adding it:
59
+
60
+ ```astro
61
+ ---
62
+ import { Button, Card } from "@/components/bearnie";
63
+ ---
52
64
  ```
53
65
 
54
66
  ## Learn more
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  #!/usr/bin/env node
2
+ export {};
package/dist/index.js CHANGED
@@ -13,67 +13,42 @@ var link = (text, url) => `\x1B]8;;${url}\x07${pc.cyan(text)}\x1B]8;;\x07`;
13
13
  function parseFullArg() {
14
14
  return process.argv.includes("--full");
15
15
  }
16
- var REGISTRY_URL = "https://bearnie.dev/registry";
17
- var COMPONENT_NAMES = [
18
- "accordion",
19
- "alert",
20
- "alert-dialog",
21
- "aspect-ratio",
22
- "avatar",
23
- "badge",
24
- "breadcrumb",
25
- "button",
26
- "button-group",
27
- "card",
28
- "carousel",
29
- "checkbox",
30
- "collapsible",
31
- "command",
32
- "context-menu",
33
- "dialog",
34
- "dropdown-menu",
35
- "empty",
36
- "file-upload",
37
- "hover-card",
38
- "input",
39
- "input-group",
40
- "input-otp",
41
- "kbd",
42
- "label",
43
- "menubar",
44
- "pagination",
45
- "popover",
46
- "progress",
47
- "radio",
48
- "scroll-area",
49
- "select",
50
- "separator",
51
- "sheet",
52
- "sidebar",
53
- "skeleton",
54
- "slider",
55
- "spinner",
56
- "stepper",
57
- "switch",
58
- "table",
59
- "tabs",
60
- "textarea",
61
- "toast",
62
- "toggle",
63
- "tooltip",
64
- "tree"
16
+ var REGISTRY_URL = process.env.BEARNIE_REGISTRY_URL || "https://bearnie.dev/registry";
17
+ var REGISTRY_PATH = process.env.BEARNIE_REGISTRY_PATH;
18
+ var BEARNIE_CONFIG = {
19
+ componentsDir: "src/components/bearnie",
20
+ utilsDir: "src/utils",
21
+ stylesDir: "src/styles",
22
+ tailwindConfig: "tailwind.config.mjs",
23
+ typescript: true
24
+ };
25
+ var UTILITY_NAMES = [
26
+ "focus-trap",
27
+ "ui-runtime-loader",
28
+ "ui-runtime-boot",
29
+ "ui-runtime-disclosure-triggers",
30
+ "ui-runtime-popover",
31
+ "ui-runtime-command",
32
+ "ui-runtime-combobox"
65
33
  ];
66
- async function fetchComponent(name) {
67
- try {
68
- const response = await fetch(`${REGISTRY_URL}/${name}.json`);
69
- if (!response.ok) return null;
70
- return await response.json();
71
- } catch {
72
- return null;
34
+ function resolveInstallPath(targetDir, filePath, type) {
35
+ if (type === "utility" || filePath.startsWith("utils/")) {
36
+ return path.join(targetDir, "src/utils", filePath.replace(/^utils\//, ""));
37
+ }
38
+ if (type === "styles" || filePath.startsWith("styles/")) {
39
+ return path.join(targetDir, "src/styles", filePath.replace(/^styles\//, ""));
73
40
  }
41
+ return path.join(targetDir, "src/components/bearnie", filePath);
74
42
  }
75
- async function fetchUtility(name) {
43
+ async function fetchRegistryEntry(name) {
76
44
  try {
45
+ if (REGISTRY_PATH) {
46
+ const entryPath = path.join(REGISTRY_PATH, `${name}.json`);
47
+ if (await fs.pathExists(entryPath)) {
48
+ return await fs.readJson(entryPath);
49
+ }
50
+ return null;
51
+ }
77
52
  const response = await fetch(`${REGISTRY_URL}/${name}.json`);
78
53
  if (!response.ok) return null;
79
54
  return await response.json();
@@ -81,6 +56,32 @@ async function fetchUtility(name) {
81
56
  return null;
82
57
  }
83
58
  }
59
+ async function fetchRegistryIndex() {
60
+ if (REGISTRY_PATH) {
61
+ const indexPath = path.join(REGISTRY_PATH, "index.json");
62
+ if (await fs.pathExists(indexPath)) {
63
+ return await fs.readJson(indexPath);
64
+ }
65
+ throw new Error(`Failed to fetch registry index at ${indexPath}`);
66
+ }
67
+ const response = await fetch(`${REGISTRY_URL}/index.json`);
68
+ if (!response.ok) {
69
+ throw new Error("Failed to fetch registry index");
70
+ }
71
+ return await response.json();
72
+ }
73
+ async function writeBearnieConfig(targetDir) {
74
+ await fs.writeJson(path.join(targetDir, "bearnie.json"), BEARNIE_CONFIG, {
75
+ spaces: 2
76
+ });
77
+ }
78
+ async function writeRegistryFiles(targetDir, entry) {
79
+ for (const file of entry.files) {
80
+ const filePath = resolveInstallPath(targetDir, file.path, entry.type);
81
+ await fs.ensureDir(path.dirname(filePath));
82
+ await fs.writeFile(filePath, file.content);
83
+ }
84
+ }
84
85
  async function main() {
85
86
  const fullInstall = parseFullArg();
86
87
  console.log(`
@@ -140,20 +141,21 @@ ${fullInstall ? ` ${pc.dim("Full install: including all components")}
140
141
  const pkg = await fs.readJson(pkgPath);
141
142
  pkg.name = finalName;
142
143
  await fs.writeJson(pkgPath, pkg, { spaces: 2 });
144
+ await writeBearnieConfig(targetDir);
143
145
  if (fullInstall) {
144
146
  console.log(`
145
147
  ${pc.dim("Fetching components from registry...")}
146
148
  `);
147
- await fs.ensureDir(path.join(targetDir, "src", "components", "ui"));
149
+ await fs.ensureDir(path.join(targetDir, "src", "components", "bearnie"));
148
150
  await fs.ensureDir(path.join(targetDir, "src", "utils"));
149
- const focusTrap = await fetchUtility("focus-trap");
150
- if (focusTrap?.files) {
151
- for (const file of focusTrap.files) {
152
- const filePath = path.join(targetDir, "src", file.name);
153
- await fs.ensureDir(path.dirname(filePath));
154
- await fs.writeFile(filePath, file.content);
151
+ for (const utilityName of UTILITY_NAMES) {
152
+ const utility = await fetchRegistryEntry(utilityName);
153
+ if (utility?.files) {
154
+ await writeRegistryFiles(targetDir, utility);
155
+ console.log(` ${pc.green("\u2713")} Added ${utilityName} utility`);
156
+ } else {
157
+ console.log(` ${pc.yellow("!")} Failed to fetch ${utilityName} utility`);
155
158
  }
156
- console.log(` ${pc.green("\u2713")} Added focus-trap utility`);
157
159
  }
158
160
  const cnContent = `import { clsx, type ClassValue } from "clsx";
159
161
  import { twMerge } from "tailwind-merge";
@@ -164,23 +166,30 @@ export function cn(...inputs: ClassValue[]) {
164
166
  `;
165
167
  await fs.writeFile(path.join(targetDir, "src", "utils", "cn.ts"), cnContent);
166
168
  console.log(` ${pc.green("\u2713")} Added cn utility`);
169
+ const registryIndex = await fetchRegistryIndex();
170
+ const componentNames = registryIndex.components.map((component) => component.name).filter((name) => name !== "styles" && name !== "barrel");
167
171
  let installed = 0;
168
172
  let failed = 0;
169
- for (const componentName of COMPONENT_NAMES) {
170
- const component = await fetchComponent(componentName);
173
+ for (const componentName of componentNames) {
174
+ const component = await fetchRegistryEntry(componentName);
171
175
  if (component?.files) {
172
- for (const file of component.files) {
173
- const filePath = path.join(targetDir, "src", file.name);
174
- await fs.ensureDir(path.dirname(filePath));
175
- await fs.writeFile(filePath, file.content);
176
- }
176
+ await writeRegistryFiles(targetDir, component);
177
177
  installed++;
178
- process.stdout.write(`\r ${pc.green("\u2713")} Installed ${installed}/${COMPONENT_NAMES.length} components`);
178
+ process.stdout.write(
179
+ `\r ${pc.green("\u2713")} Installed ${installed}/${componentNames.length} components`
180
+ );
179
181
  } else {
180
182
  failed++;
181
183
  }
182
184
  }
183
185
  console.log("");
186
+ const barrel = await fetchRegistryEntry("barrel");
187
+ if (barrel?.files) {
188
+ await writeRegistryFiles(targetDir, barrel);
189
+ console.log(` ${pc.green("\u2713")} Added barrel export`);
190
+ } else {
191
+ console.log(` ${pc.yellow("!")} Failed to fetch barrel export`);
192
+ }
184
193
  if (failed > 0) {
185
194
  console.log(` ${pc.yellow("!")} ${failed} components failed to fetch`);
186
195
  }
@@ -188,7 +197,7 @@ export function cn(...inputs: ClassValue[]) {
188
197
  const pkg2 = await fs.readJson(pkgPath2);
189
198
  pkg2.dependencies = {
190
199
  ...pkg2.dependencies,
191
- "clsx": "^2.1.1",
200
+ clsx: "^2.1.1",
192
201
  "tailwind-merge": "^3.3.0"
193
202
  };
194
203
  await fs.writeJson(pkgPath2, pkg2, { spaces: 2 });
@@ -230,7 +239,8 @@ Thumbs.db
230
239
  ${pc.dim("2.")} npm install
231
240
  ${pc.dim("3.")} npm run dev
232
241
 
233
- ${pc.dim("All components are in")} ${pc.cyan("src/components/ui/")}
242
+ ${pc.dim("All components are in")} ${pc.cyan("src/components/bearnie/")}
243
+ ${pc.dim("Import from")} ${pc.cyan("@/components/bearnie")} ${pc.dim("via")} ${pc.cyan("index.ts")}
234
244
 
235
245
  ${pc.dim("Browse components at")} ${link("bearnie.dev/docs/components", "https://bearnie.dev/docs/components")}
236
246
 
package/package.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "name": "create-bearnie",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Create a new Astro project with Bearnie UI components",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "bin": {
8
8
  "create-bearnie": "dist/index.js"
9
9
  },
10
+ "types": "dist/index.d.ts",
10
11
  "files": [
11
12
  "dist",
12
13
  "template"
13
14
  ],
14
15
  "scripts": {
15
- "build": "tsup src/index.ts --format esm --dts --clean",
16
+ "build": "tsup src/index.ts --format esm --clean && tsc --emitDeclarationOnly",
16
17
  "dev": "tsup src/index.ts --format esm --watch"
17
18
  },
18
19
  "dependencies": {
@@ -25,7 +26,7 @@
25
26
  "@types/node": "^20.14.9",
26
27
  "@types/prompts": "^2.4.9",
27
28
  "tsup": "^8.1.0",
28
- "typescript": "^5.5.3"
29
+ "typescript": "^5.7.3"
29
30
  },
30
31
  "engines": {
31
32
  "node": ">=18"
@@ -8,11 +8,11 @@
8
8
  "preview": "astro preview"
9
9
  },
10
10
  "dependencies": {
11
- "astro": "^5.16.15"
11
+ "astro": "^7.1.6"
12
12
  },
13
13
  "devDependencies": {
14
- "@tailwindcss/vite": "^4.1.18",
14
+ "@tailwindcss/vite": "^4.3.3",
15
15
  "@tailwindcss/forms": "^0.5.11",
16
- "tailwindcss": "^4.1.18"
16
+ "tailwindcss": "^4.3.3"
17
17
  }
18
18
  }