rn-shadcn 0.1.0

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 ADDED
@@ -0,0 +1,74 @@
1
+ # react-native-windcn
2
+
3
+ A shadcn-style CLI for React Native UI components. Install pre-built components directly into your project — no wrapper library, full ownership.
4
+
5
+ ```bash
6
+ npx react-native-windcn init
7
+ npx react-native-windcn add button
8
+ npx react-native-windcn add card modal
9
+ ```
10
+
11
+ ## Prerequisites
12
+
13
+ - Node.js 20+
14
+ - Expo SDK 56+ / React Native 0.85.3+
15
+ - Uniwind 1.9.0+
16
+ - Tailwind CSS v4
17
+
18
+ ## Getting Started
19
+
20
+ ```bash
21
+ npx react-native-windcn init
22
+ ```
23
+
24
+ This creates:
25
+ - `components.json` — configuration file with registry URL and components directory
26
+ - `src/lib/cn.ts` — utility for merging Tailwind CSS classes
27
+ - Installs `clsx` and `tailwind-merge`
28
+
29
+ ## Commands
30
+
31
+ ### `add`
32
+
33
+ Install one or more components:
34
+
35
+ ```bash
36
+ npx react-native-windcn add button
37
+ npx react-native-windcn add card modal
38
+ npx react-native-windcn add accordion dialog sheet
39
+ ```
40
+
41
+ Automatically installs required npm dependencies.
42
+
43
+ ### `list`
44
+
45
+ Show all available components:
46
+
47
+ ```bash
48
+ npx react-native-windcn list
49
+ ```
50
+
51
+ ### `info`
52
+
53
+ View component metadata:
54
+
55
+ ```bash
56
+ npx react-native-windcn info button
57
+ ```
58
+
59
+ ## How It Works
60
+
61
+ Components are downloaded from a remote GitHub Pages registry and copied into your project's `src/components/ui/` directory. You own the files — modify them freely.
62
+
63
+ ## Available Components
64
+
65
+ Layout: Accordion, Card, Carousel, Collapsible, Resizable, ScrollArea, Separator, Sheet, Tabs
66
+ Forms: Button, Checkbox, Combobox, DatePicker, Form, Input, InputOTP, Label, RadioGroup, Select, Slider, Switch, Textarea, Toggle, ToggleGroup
67
+ Overlays: AlertDialog, ContextMenu, Dialog, Drawer, DropdownMenu, HoverCard, Menubar, NavigationMenu, Popover, Tooltip
68
+ Data: Avatar, Badge, Breadcrumb, Calendar, Chart, DataTable, Pagination, Table
69
+ Feedback: Alert, Progress, Skeleton, Sonner, Toast
70
+ Typography: Text, Typography
71
+
72
+ ## License
73
+
74
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/init.ts
7
+ import { mkdirp, pathExists as pathExists3, writeFile as writeFile2 } from "fs-extra";
8
+ import { resolve as resolve3 } from "path";
9
+
10
+ // src/utils/config.ts
11
+ import { readFile, writeFile, pathExists } from "fs-extra";
12
+ import { resolve } from "path";
13
+
14
+ // src/utils/logger.ts
15
+ import chalk from "chalk";
16
+ import ora from "ora";
17
+ function info(message) {
18
+ console.log(chalk.blue("\u2139"), message);
19
+ }
20
+ function success(message) {
21
+ console.log(chalk.green("\u2714"), message);
22
+ }
23
+ function warning(message) {
24
+ console.log(chalk.yellow("\u26A0"), message);
25
+ }
26
+ function error(message) {
27
+ console.log(chalk.red("\u2716"), message);
28
+ }
29
+ function spinner(message) {
30
+ return ora({ text: message, color: "blue" });
31
+ }
32
+
33
+ // src/utils/config.ts
34
+ var CONFIG_FILE = "components.json";
35
+ async function readConfig(cwd) {
36
+ const configPath = resolve(cwd, CONFIG_FILE);
37
+ const exists = await pathExists(configPath);
38
+ if (!exists) {
39
+ error(`components.json not found.`);
40
+ console.log("Run:");
41
+ console.log(" npx react-native-windcn init");
42
+ process.exit(1);
43
+ }
44
+ const content = await readFile(configPath, "utf-8");
45
+ return JSON.parse(content);
46
+ }
47
+ async function writeConfig(cwd, config) {
48
+ const configPath = resolve(cwd, CONFIG_FILE);
49
+ await writeFile(configPath, JSON.stringify(config, null, 2));
50
+ }
51
+ async function configExists(cwd) {
52
+ return pathExists(resolve(cwd, CONFIG_FILE));
53
+ }
54
+
55
+ // src/utils/registry.ts
56
+ function registryUrl(base, path) {
57
+ const baseUrl = base.replace(/\/+$/, "");
58
+ const cleanPath = path.startsWith("/") ? path.slice(1) : path;
59
+ return `${baseUrl}/${cleanPath}`;
60
+ }
61
+ async function fetchJson(url) {
62
+ const response = await fetch(url);
63
+ if (!response.ok) {
64
+ throw new Error(`Registry returned ${response.status}`);
65
+ }
66
+ return response.json();
67
+ }
68
+ async function fetchRegistryIndex(baseUrl) {
69
+ const url = registryUrl(baseUrl, "registry/index.json");
70
+ return fetchJson(url);
71
+ }
72
+ async function fetchComponentRegistry(baseUrl, name) {
73
+ const url = registryUrl(baseUrl, `registry/${name}.json`);
74
+ return fetchJson(url);
75
+ }
76
+ async function downloadComponentFile(baseUrl, sourcePath) {
77
+ const url = registryUrl(baseUrl, sourcePath);
78
+ const response = await fetch(url);
79
+ if (!response.ok) {
80
+ throw new Error(`Failed to download file: ${response.status}`);
81
+ }
82
+ return response.text();
83
+ }
84
+ function validateComponentName(name, available) {
85
+ const match = available.find((c) => c === name);
86
+ return match ?? null;
87
+ }
88
+
89
+ // src/utils/packageManager.ts
90
+ import { pathExists as pathExists2 } from "fs-extra";
91
+ import { resolve as resolve2 } from "path";
92
+ import { execSync } from "child_process";
93
+ async function detectPackageManager(cwd) {
94
+ if (await pathExists2(resolve2(cwd, "pnpm-lock.yaml"))) return "pnpm";
95
+ if (await pathExists2(resolve2(cwd, "yarn.lock"))) return "yarn";
96
+ if (await pathExists2(resolve2(cwd, "bun.lockb"))) return "bun";
97
+ return "npm";
98
+ }
99
+ function pmInstallCmd(pm) {
100
+ switch (pm) {
101
+ case "pnpm":
102
+ return "pnpm add";
103
+ case "yarn":
104
+ return "yarn add";
105
+ case "bun":
106
+ return "bun add";
107
+ default:
108
+ return "npm install";
109
+ }
110
+ }
111
+ function installDependencies(deps, pm, cwd) {
112
+ if (deps.length === 0) return;
113
+ const cmd = `${pmInstallCmd(pm)} ${deps.join(" ")}`;
114
+ execSync(cmd, { cwd, stdio: "inherit" });
115
+ }
116
+
117
+ // src/commands/init.ts
118
+ function defaultRegistry() {
119
+ return "https://username.github.io/react-native-windcn-registry";
120
+ }
121
+ function defaultComponentsDir() {
122
+ return "src/components/ui";
123
+ }
124
+ async function init(cwd) {
125
+ const spinner2 = spinner("Initializing...");
126
+ spinner2.start();
127
+ try {
128
+ if (await configExists(cwd)) {
129
+ spinner2.fail("components.json already exists.");
130
+ return;
131
+ }
132
+ const pkgPath = resolve3(cwd, "package.json");
133
+ if (!await pathExists3(pkgPath)) {
134
+ spinner2.fail("package.json not found. Are you in a project directory?");
135
+ return;
136
+ }
137
+ const componentsDir = defaultComponentsDir();
138
+ const registry = defaultRegistry();
139
+ await mkdirp(resolve3(cwd, componentsDir));
140
+ const config = {
141
+ registry,
142
+ componentsDir
143
+ };
144
+ await writeConfig(cwd, config);
145
+ try {
146
+ const cnMeta = await fetchComponentRegistry(registry, "cn");
147
+ const libDir = resolve3(cwd, "src", "lib");
148
+ await mkdirp(libDir);
149
+ for (const file of cnMeta.files) {
150
+ const content = await downloadComponentFile(registry, file.source);
151
+ await writeFile2(resolve3(cwd, file.target), content, "utf-8");
152
+ }
153
+ const pm = await detectPackageManager(cwd);
154
+ if (cnMeta.dependencies.length > 0) {
155
+ installDependencies(cnMeta.dependencies, pm, cwd);
156
+ }
157
+ } catch {
158
+ warning("Could not install base dependencies. Run `npm install clsx tailwind-merge` manually.");
159
+ }
160
+ spinner2.succeed("Initialized project.");
161
+ info(`Components directory: ${componentsDir}`);
162
+ info(`Registry: ${registry}`);
163
+ } catch (err) {
164
+ spinner2.fail("Initialization failed.");
165
+ throw err;
166
+ }
167
+ }
168
+
169
+ // src/commands/add.ts
170
+ import { mkdirp as mkdirp2, writeFile as writeFile3 } from "fs-extra";
171
+ import { resolve as resolve4 } from "path";
172
+ async function add(names, cwd) {
173
+ const config = await readConfig(cwd);
174
+ const spinner2 = spinner("Fetching registry index...");
175
+ spinner2.start();
176
+ let index;
177
+ try {
178
+ index = await fetchRegistryIndex(config.registry);
179
+ } catch {
180
+ spinner2.fail("Unable to connect to registry.");
181
+ return;
182
+ }
183
+ spinner2.succeed("Registry index loaded.");
184
+ const notFound = [];
185
+ const toInstall = [];
186
+ const componentDeps = /* @__PURE__ */ new Set();
187
+ for (const name of names) {
188
+ const valid = validateComponentName(name, index.components);
189
+ if (!valid) {
190
+ notFound.push(name);
191
+ continue;
192
+ }
193
+ toInstall.push(name);
194
+ }
195
+ if (notFound.length > 0) {
196
+ for (const name of notFound) {
197
+ error(`Component "${name}" does not exist.`);
198
+ }
199
+ }
200
+ if (toInstall.length === 0) {
201
+ return;
202
+ }
203
+ const pm = await detectPackageManager(cwd);
204
+ for (const name of toInstall) {
205
+ const step = spinner(`Installing ${name}...`);
206
+ step.start();
207
+ try {
208
+ const meta = await fetchComponentRegistry(config.registry, name);
209
+ for (const dep of meta.dependencies) {
210
+ componentDeps.add(dep);
211
+ }
212
+ for (const file of meta.files) {
213
+ const content = await downloadComponentFile(config.registry, file.source);
214
+ const targetPath = resolve4(cwd, file.target);
215
+ await mkdirp2(resolve4(targetPath, ".."));
216
+ await writeFile3(targetPath, content, "utf-8");
217
+ }
218
+ step.succeed(`Installed ${name}.`);
219
+ } catch {
220
+ step.fail(`Failed to install ${name}.`);
221
+ }
222
+ }
223
+ if (componentDeps.size > 0) {
224
+ const depSpinner = spinner("Installing npm dependencies...");
225
+ depSpinner.start();
226
+ try {
227
+ installDependencies([...componentDeps], pm, cwd);
228
+ depSpinner.succeed("npm dependencies installed.");
229
+ } catch {
230
+ depSpinner.fail("Failed to install some dependencies.");
231
+ }
232
+ }
233
+ success("Done.");
234
+ }
235
+
236
+ // src/commands/list.ts
237
+ async function listComponents(cwd) {
238
+ const config = await readConfig(cwd);
239
+ const spinner2 = spinner("Fetching registry index...");
240
+ spinner2.start();
241
+ let index;
242
+ try {
243
+ index = await fetchRegistryIndex(config.registry);
244
+ } catch {
245
+ spinner2.fail("Unable to connect to registry.");
246
+ return;
247
+ }
248
+ spinner2.succeed("Available components:");
249
+ for (const name of index.components) {
250
+ console.log(` ${name}`);
251
+ }
252
+ }
253
+
254
+ // src/commands/info.ts
255
+ async function info2(name, cwd) {
256
+ const config = await readConfig(cwd);
257
+ const spinner2 = spinner(`Fetching ${name}...`);
258
+ spinner2.start();
259
+ let meta;
260
+ try {
261
+ meta = await fetchComponentRegistry(config.registry, name);
262
+ } catch {
263
+ spinner2.fail(`Component "${name}" does not exist.`);
264
+ return;
265
+ }
266
+ spinner2.stop();
267
+ console.log(`
268
+ name: ${meta.name}`);
269
+ console.log(` description: ${meta.description}`);
270
+ if (meta.dependencies.length > 0) {
271
+ console.log(` dependencies:`);
272
+ for (const dep of meta.dependencies) {
273
+ console.log(` - ${dep}`);
274
+ }
275
+ }
276
+ if (meta.files.length > 0) {
277
+ console.log(` files:`);
278
+ for (const file of meta.files) {
279
+ console.log(` - ${file.source} \u2192 ${file.target}`);
280
+ }
281
+ }
282
+ console.log("");
283
+ }
284
+
285
+ // src/index.ts
286
+ var program = new Command();
287
+ program.name("react-native-windcn").description("shadcn-style CLI for React Native UI components").version("0.1.0");
288
+ program.command("init").description("Initialize configuration").action(() => {
289
+ init(process.cwd());
290
+ });
291
+ program.command("add").description("Install components").argument("<names...>", "component names").action((names) => {
292
+ add(names, process.cwd());
293
+ });
294
+ program.command("list").description("Show all available components").action(() => {
295
+ listComponents(process.cwd());
296
+ });
297
+ program.command("info").description("Show component metadata").argument("<name>", "component name").action((name) => {
298
+ info2(name, process.cwd());
299
+ });
300
+ program.parse();
301
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/config.ts","../src/utils/logger.ts","../src/utils/registry.ts","../src/utils/packageManager.ts","../src/commands/add.ts","../src/commands/list.ts","../src/commands/info.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { init } from './commands/init.js'\nimport { add } from './commands/add.js'\nimport { listComponents } from './commands/list.js'\nimport { info } from './commands/info.js'\n\nconst program = new Command()\n\nprogram\n .name('react-native-windcn')\n .description('shadcn-style CLI for React Native UI components')\n .version('0.1.0')\n\nprogram\n .command('init')\n .description('Initialize configuration')\n .action(() => {\n init(process.cwd())\n })\n\nprogram\n .command('add')\n .description('Install components')\n .argument('<names...>', 'component names')\n .action((names: string[]) => {\n add(names, process.cwd())\n })\n\nprogram\n .command('list')\n .description('Show all available components')\n .action(() => {\n listComponents(process.cwd())\n })\n\nprogram\n .command('info')\n .description('Show component metadata')\n .argument('<name>', 'component name')\n .action((name: string) => {\n info(name, process.cwd())\n })\n\nprogram.parse()\n","import { mkdirp, pathExists, writeFile } from 'fs-extra'\nimport { resolve } from 'node:path'\nimport { writeConfig, configExists } from '../utils/config.js'\nimport { fetchComponentRegistry, downloadComponentFile } from '../utils/registry.js'\nimport { detectPackageManager, installDependencies } from '../utils/packageManager.js'\nimport type { Config } from '../types/registry.js'\nimport * as logger from '../utils/logger.js'\n\nfunction defaultRegistry(): string {\n return 'https://username.github.io/react-native-windcn-registry'\n}\n\nfunction defaultComponentsDir(): string {\n return 'src/components/ui'\n}\n\nexport async function init(cwd: string): Promise<void> {\n const spinner = logger.spinner('Initializing...')\n spinner.start()\n\n try {\n if (await configExists(cwd)) {\n spinner.fail('components.json already exists.')\n return\n }\n\n const pkgPath = resolve(cwd, 'package.json')\n if (!(await pathExists(pkgPath))) {\n spinner.fail('package.json not found. Are you in a project directory?')\n return\n }\n\n const componentsDir = defaultComponentsDir()\n const registry = defaultRegistry()\n\n await mkdirp(resolve(cwd, componentsDir))\n\n const config: Config = {\n registry,\n componentsDir,\n }\n\n await writeConfig(cwd, config)\n\n // Install cn utility and base deps\n try {\n const cnMeta = await fetchComponentRegistry(registry, 'cn')\n const libDir = resolve(cwd, 'src', 'lib')\n await mkdirp(libDir)\n\n for (const file of cnMeta.files) {\n const content = await downloadComponentFile(registry, file.source)\n await writeFile(resolve(cwd, file.target), content, 'utf-8')\n }\n\n const pm = await detectPackageManager(cwd)\n if (cnMeta.dependencies.length > 0) {\n installDependencies(cnMeta.dependencies, pm, cwd)\n }\n } catch {\n logger.warning('Could not install base dependencies. Run `npm install clsx tailwind-merge` manually.')\n }\n\n spinner.succeed('Initialized project.')\n logger.info(`Components directory: ${componentsDir}`)\n logger.info(`Registry: ${registry}`)\n } catch (err) {\n spinner.fail('Initialization failed.')\n throw err\n }\n}\n","import { readFile, writeFile, pathExists } from 'fs-extra'\nimport { resolve } from 'node:path'\nimport type { Config } from '../types/registry.js'\nimport * as logger from './logger.js'\n\nconst CONFIG_FILE = 'components.json'\n\nexport async function readConfig(cwd: string): Promise<Config> {\n const configPath = resolve(cwd, CONFIG_FILE)\n const exists = await pathExists(configPath)\n\n if (!exists) {\n logger.error(`components.json not found.`)\n console.log('Run:')\n console.log(' npx react-native-windcn init')\n process.exit(1)\n }\n\n const content = await readFile(configPath, 'utf-8')\n return JSON.parse(content) as Config\n}\n\nexport async function writeConfig(cwd: string, config: Config): Promise<void> {\n const configPath = resolve(cwd, CONFIG_FILE)\n await writeFile(configPath, JSON.stringify(config, null, 2))\n}\n\nexport async function configExists(cwd: string): Promise<boolean> {\n return pathExists(resolve(cwd, CONFIG_FILE))\n}\n","import chalk from 'chalk'\nimport ora from 'ora'\n\nexport function info(message: string): void {\n console.log(chalk.blue('ℹ'), message)\n}\n\nexport function success(message: string): void {\n console.log(chalk.green('✔'), message)\n}\n\nexport function warning(message: string): void {\n console.log(chalk.yellow('⚠'), message)\n}\n\nexport function error(message: string): void {\n console.log(chalk.red('✖'), message)\n}\n\nexport function spinner(message: string) {\n return ora({ text: message, color: 'blue' })\n}\n","import type { ComponentRegistry, RegistryIndex } from '../types/registry.js'\n\nfunction registryUrl(base: string, path: string): string {\n const baseUrl = base.replace(/\\/+$/, '')\n const cleanPath = path.startsWith('/') ? path.slice(1) : path\n return `${baseUrl}/${cleanPath}`\n}\n\nasync function fetchJson<T>(url: string): Promise<T> {\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(`Registry returned ${response.status}`)\n }\n\n return response.json() as Promise<T>\n}\n\nexport async function fetchRegistryIndex(baseUrl: string): Promise<RegistryIndex> {\n const url = registryUrl(baseUrl, 'registry/index.json')\n return fetchJson<RegistryIndex>(url)\n}\n\nexport async function fetchComponentRegistry(\n baseUrl: string,\n name: string,\n): Promise<ComponentRegistry> {\n const url = registryUrl(baseUrl, `registry/${name}.json`)\n return fetchJson<ComponentRegistry>(url)\n}\n\nexport async function downloadComponentFile(\n baseUrl: string,\n sourcePath: string,\n): Promise<string> {\n const url = registryUrl(baseUrl, sourcePath)\n const response = await fetch(url)\n\n if (!response.ok) {\n throw new Error(`Failed to download file: ${response.status}`)\n }\n\n return response.text()\n}\n\nexport function validateComponentName(\n name: string,\n available: string[],\n): string | null {\n const match = available.find((c) => c === name)\n return match ?? null\n}\n","import { pathExists } from 'fs-extra'\nimport { resolve } from 'node:path'\nimport { execSync } from 'node:child_process'\nimport type { PackageManager } from '../types/registry.js'\n\nexport async function detectPackageManager(cwd: string): Promise<PackageManager> {\n if (await pathExists(resolve(cwd, 'pnpm-lock.yaml'))) return 'pnpm'\n if (await pathExists(resolve(cwd, 'yarn.lock'))) return 'yarn'\n if (await pathExists(resolve(cwd, 'bun.lockb'))) return 'bun'\n return 'npm'\n}\n\nfunction pmInstallCmd(pm: PackageManager): string {\n switch (pm) {\n case 'pnpm': return 'pnpm add'\n case 'yarn': return 'yarn add'\n case 'bun': return 'bun add'\n default: return 'npm install'\n }\n}\n\nexport function installDependencies(\n deps: string[],\n pm: PackageManager,\n cwd: string,\n): void {\n if (deps.length === 0) return\n\n const cmd = `${pmInstallCmd(pm)} ${deps.join(' ')}`\n execSync(cmd, { cwd, stdio: 'inherit' })\n}\n","import { mkdirp, writeFile } from 'fs-extra'\nimport { resolve } from 'node:path'\nimport { readConfig } from '../utils/config.js'\nimport {\n fetchRegistryIndex,\n fetchComponentRegistry,\n downloadComponentFile,\n validateComponentName,\n} from '../utils/registry.js'\nimport { detectPackageManager, installDependencies } from '../utils/packageManager.js'\nimport * as logger from '../utils/logger.js'\n\nexport async function add(names: string[], cwd: string): Promise<void> {\n const config = await readConfig(cwd)\n\n const spinner = logger.spinner('Fetching registry index...')\n spinner.start()\n\n let index\n try {\n index = await fetchRegistryIndex(config.registry)\n } catch {\n spinner.fail('Unable to connect to registry.')\n return\n }\n\n spinner.succeed('Registry index loaded.')\n\n const notFound: string[] = []\n const toInstall: string[] = []\n const componentDeps = new Set<string>()\n\n for (const name of names) {\n const valid = validateComponentName(name, index.components)\n if (!valid) {\n notFound.push(name)\n continue\n }\n toInstall.push(name)\n }\n\n if (notFound.length > 0) {\n for (const name of notFound) {\n logger.error(`Component \"${name}\" does not exist.`)\n }\n }\n\n if (toInstall.length === 0) {\n return\n }\n\n const pm = await detectPackageManager(cwd)\n\n for (const name of toInstall) {\n const step = logger.spinner(`Installing ${name}...`)\n step.start()\n\n try {\n const meta = await fetchComponentRegistry(config.registry, name)\n\n for (const dep of meta.dependencies) {\n componentDeps.add(dep)\n }\n\n for (const file of meta.files) {\n const content = await downloadComponentFile(config.registry, file.source)\n const targetPath = resolve(cwd, file.target)\n await mkdirp(resolve(targetPath, '..'))\n await writeFile(targetPath, content, 'utf-8')\n }\n\n step.succeed(`Installed ${name}.`)\n } catch {\n step.fail(`Failed to install ${name}.`)\n }\n }\n\n if (componentDeps.size > 0) {\n const depSpinner = logger.spinner('Installing npm dependencies...')\n depSpinner.start()\n\n try {\n installDependencies([...componentDeps], pm, cwd)\n depSpinner.succeed('npm dependencies installed.')\n } catch {\n depSpinner.fail('Failed to install some dependencies.')\n }\n }\n\n logger.success('Done.')\n}\n","import { readConfig } from '../utils/config.js'\nimport { fetchRegistryIndex } from '../utils/registry.js'\nimport * as logger from '../utils/logger.js'\n\nexport async function listComponents(cwd: string): Promise<void> {\n const config = await readConfig(cwd)\n\n const spinner = logger.spinner('Fetching registry index...')\n spinner.start()\n\n let index\n try {\n index = await fetchRegistryIndex(config.registry)\n } catch {\n spinner.fail('Unable to connect to registry.')\n return\n }\n\n spinner.succeed('Available components:')\n for (const name of index.components) {\n console.log(` ${name}`)\n }\n}\n","import { readConfig } from '../utils/config.js'\nimport { fetchComponentRegistry } from '../utils/registry.js'\nimport * as logger from '../utils/logger.js'\n\nexport async function info(name: string, cwd: string): Promise<void> {\n const config = await readConfig(cwd)\n\n const spinner = logger.spinner(`Fetching ${name}...`)\n spinner.start()\n\n let meta\n try {\n meta = await fetchComponentRegistry(config.registry, name)\n } catch {\n spinner.fail(`Component \"${name}\" does not exist.`)\n return\n }\n\n spinner.stop()\n console.log(`\\n name: ${meta.name}`)\n console.log(` description: ${meta.description}`)\n\n if (meta.dependencies.length > 0) {\n console.log(` dependencies:`)\n for (const dep of meta.dependencies) {\n console.log(` - ${dep}`)\n }\n }\n\n if (meta.files.length > 0) {\n console.log(` files:`)\n for (const file of meta.files) {\n console.log(` - ${file.source} → ${file.target}`)\n }\n }\n\n console.log('')\n}\n"],"mappings":"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","names":["pathExists","writeFile","resolve","pathExists","resolve","spinner","resolve","pathExists","writeFile","mkdirp","writeFile","resolve","spinner","resolve","mkdirp","writeFile","spinner","info","spinner","info"]}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "rn-shadcn",
3
+ "version": "0.1.0",
4
+ "description": "shadcn-style CLI for React Native UI components",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "react-native-windcn": "./dist/index.js"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "typecheck": "tsc --noEmit"
19
+ },
20
+ "dependencies": {
21
+ "chalk": "^5.4.1",
22
+ "commander": "^13.1.0",
23
+ "fs-extra": "^11.3.0",
24
+ "ora": "^8.2.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/fs-extra": "^11.0.4",
28
+ "@types/node": "^22.13.0",
29
+ "tsup": "^8.3.6",
30
+ "typescript": "^5.7.3"
31
+ },
32
+ "engines": {
33
+ "node": ">=20"
34
+ }
35
+ }