draft-cli 0.0.2 → 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/CHANGELOG.md +6 -0
- package/README.md +8 -12
- package/package.json +4 -5
- package/src/bin/index.ts +60 -0
- package/dist/chunk-TY6E2FMX.js +0 -191
- package/dist/react.d.ts +0 -2
- package/dist/react.js +0 -16
- package/dist/vue.d.ts +0 -2
- package/dist/vue.js +0 -16
- package/src/bin/react.ts +0 -28
- package/src/bin/vue.ts +0 -28
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -14,29 +14,25 @@ You can install the CLI globally or use it with your favorite package manager:
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
# Global installation
|
|
17
|
-
npm install -g draft-
|
|
17
|
+
npm install -g draft-cli
|
|
18
18
|
# or
|
|
19
|
-
pnpm add -g draft-
|
|
19
|
+
pnpm add -g draft-cli
|
|
20
20
|
|
|
21
21
|
# Or use it directly without installation
|
|
22
|
-
pnpm dlx draft-
|
|
23
|
-
npx draft-
|
|
22
|
+
pnpm dlx draft-cli init
|
|
23
|
+
npx draft-cli init
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
28
|
-
The CLI provides
|
|
28
|
+
The CLI provides a unified entry point `draft-cli` for all operations.
|
|
29
29
|
|
|
30
30
|
### Initialize
|
|
31
31
|
|
|
32
32
|
Initialize your project and create a `components.json` file:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
|
|
36
|
-
pnpm draft-vue init
|
|
37
|
-
|
|
38
|
-
# For React projects
|
|
39
|
-
pnpm draft-react init
|
|
35
|
+
draft-cli init
|
|
40
36
|
```
|
|
41
37
|
|
|
42
38
|
### Add Components
|
|
@@ -45,10 +41,10 @@ Add a component to your project:
|
|
|
45
41
|
|
|
46
42
|
```bash
|
|
47
43
|
# For Vue
|
|
48
|
-
|
|
44
|
+
draft-cli vue add button
|
|
49
45
|
|
|
50
46
|
# For React
|
|
51
|
-
|
|
47
|
+
draft-cli react add button
|
|
52
48
|
```
|
|
53
49
|
|
|
54
50
|
## Configuration
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "draft-cli",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A command-line tool for adding components to your Vue and React projects. Inspired by shadcn/ui.",
|
|
6
6
|
"type": "module",
|
|
@@ -19,8 +19,7 @@
|
|
|
19
19
|
"directory": "packages/cli"
|
|
20
20
|
},
|
|
21
21
|
"bin": {
|
|
22
|
-
"draft-
|
|
23
|
-
"draft-react": "./dist/react.js"
|
|
22
|
+
"draft-cli": "./dist/index.js"
|
|
24
23
|
},
|
|
25
24
|
"publishConfig": {
|
|
26
25
|
"access": "public",
|
|
@@ -44,7 +43,7 @@
|
|
|
44
43
|
},
|
|
45
44
|
"register": "https://raw.githubusercontent.com/preflower/draft-ui/main",
|
|
46
45
|
"scripts": {
|
|
47
|
-
"build": "tsup src/bin/
|
|
48
|
-
"dev": "tsup src/bin/
|
|
46
|
+
"build": "tsup src/bin/index.ts --format esm --clean --dts",
|
|
47
|
+
"dev": "tsup src/bin/index.ts --format esm --watch --clean"
|
|
49
48
|
}
|
|
50
49
|
}
|
package/src/bin/index.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createRequire } from 'module'
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander'
|
|
4
|
+
|
|
5
|
+
import { addComponent } from '../commands/add.js'
|
|
6
|
+
import { initProject } from '../commands/init.js'
|
|
7
|
+
|
|
8
|
+
const require = createRequire(import.meta.url)
|
|
9
|
+
interface PackageJson {
|
|
10
|
+
version: string
|
|
11
|
+
[key: string]: unknown
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let pkg: PackageJson = { version: '0.0.1' }
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
pkg = require('../../package.json')
|
|
18
|
+
} catch {
|
|
19
|
+
try {
|
|
20
|
+
pkg = require('../package.json')
|
|
21
|
+
} catch {
|
|
22
|
+
pkg = { version: '0.0.1' }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const program = new Command()
|
|
27
|
+
|
|
28
|
+
program
|
|
29
|
+
.name('draft-cli')
|
|
30
|
+
.description('CLI for adding components to your projects')
|
|
31
|
+
.version(pkg.version)
|
|
32
|
+
|
|
33
|
+
program
|
|
34
|
+
.command('init')
|
|
35
|
+
.description('initialize your project and create a components.json file')
|
|
36
|
+
.action(async () => {
|
|
37
|
+
await initProject()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
const vue = program.command('vue').description('Vue components commands')
|
|
41
|
+
|
|
42
|
+
vue
|
|
43
|
+
.command('add')
|
|
44
|
+
.description('add a Vue component to your project')
|
|
45
|
+
.argument('<component>', 'the component to add')
|
|
46
|
+
.action(async (component) => {
|
|
47
|
+
await addComponent(component, 'vue')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const react = program.command('react').description('React components commands')
|
|
51
|
+
|
|
52
|
+
react
|
|
53
|
+
.command('add')
|
|
54
|
+
.description('add a React component to your project')
|
|
55
|
+
.argument('<component>', 'the component to add')
|
|
56
|
+
.action(async (component) => {
|
|
57
|
+
await addComponent(component, 'react')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
program.parse()
|
package/dist/chunk-TY6E2FMX.js
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
// src/commands/add.ts
|
|
2
|
-
import { createRequire } from "module";
|
|
3
|
-
import path2 from "path";
|
|
4
|
-
import chalk from "chalk";
|
|
5
|
-
import fs2 from "fs-extra";
|
|
6
|
-
import ora from "ora";
|
|
7
|
-
|
|
8
|
-
// src/utils/config.ts
|
|
9
|
-
import path from "path";
|
|
10
|
-
import fs from "fs-extra";
|
|
11
|
-
import { z } from "zod";
|
|
12
|
-
var configSchema = z.object({
|
|
13
|
-
style: z.string(),
|
|
14
|
-
rsc: z.boolean(),
|
|
15
|
-
tsx: z.boolean(),
|
|
16
|
-
tailwind: z.object({
|
|
17
|
-
config: z.string(),
|
|
18
|
-
css: z.string(),
|
|
19
|
-
baseColor: z.string(),
|
|
20
|
-
cssVariables: z.boolean()
|
|
21
|
-
}),
|
|
22
|
-
aliases: z.object({
|
|
23
|
-
components: z.string(),
|
|
24
|
-
utils: z.string(),
|
|
25
|
-
ui: z.string().optional(),
|
|
26
|
-
draft: z.string().optional()
|
|
27
|
-
})
|
|
28
|
-
});
|
|
29
|
-
async function getConfig(cwd) {
|
|
30
|
-
const configPath = path.resolve(cwd, "components.json");
|
|
31
|
-
if (!await fs.pathExists(configPath)) {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
try {
|
|
35
|
-
const config = await fs.readJson(configPath);
|
|
36
|
-
return configSchema.parse(config);
|
|
37
|
-
} catch (error) {
|
|
38
|
-
throw new Error(`Invalid configuration: ${error}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// src/commands/add.ts
|
|
43
|
-
var require2 = createRequire(import.meta.url);
|
|
44
|
-
var pkg = {};
|
|
45
|
-
try {
|
|
46
|
-
pkg = require2("../../package.json");
|
|
47
|
-
} catch {
|
|
48
|
-
try {
|
|
49
|
-
pkg = require2("../package.json");
|
|
50
|
-
} catch {
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
async function addComponent(componentName, type) {
|
|
54
|
-
const cwd = process.cwd();
|
|
55
|
-
const config = await getConfig(cwd);
|
|
56
|
-
if (!config) {
|
|
57
|
-
console.log(chalk.red("\nNo components.json found. Please run init first (simulated).\n"));
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const spinner = ora(`Adding ${componentName}...`).start();
|
|
61
|
-
try {
|
|
62
|
-
const monorepoRoot = path2.resolve(import.meta.url.replace("file://", ""), "../../../../");
|
|
63
|
-
const sourceDir = path2.resolve(
|
|
64
|
-
monorepoRoot,
|
|
65
|
-
"packages",
|
|
66
|
-
type,
|
|
67
|
-
"src",
|
|
68
|
-
"components",
|
|
69
|
-
componentName
|
|
70
|
-
);
|
|
71
|
-
if (!await fs2.pathExists(sourceDir)) {
|
|
72
|
-
if (typeof pkg.register === "string") {
|
|
73
|
-
spinner.text = `Checking registry ${pkg.register}...`;
|
|
74
|
-
try {
|
|
75
|
-
const registryUrl = `${pkg.register}/packages/${type}/src/registry.json`;
|
|
76
|
-
const registryRes = await fetch(registryUrl);
|
|
77
|
-
if (!registryRes.ok) {
|
|
78
|
-
throw new Error(`Failed to fetch registry from ${registryUrl}: ${registryRes.statusText}`);
|
|
79
|
-
}
|
|
80
|
-
const registry = await registryRes.json();
|
|
81
|
-
const componentMeta = registry.components[componentName];
|
|
82
|
-
if (componentMeta == null) {
|
|
83
|
-
spinner.fail(chalk.red(`Component ${componentName} not found in registry.`));
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (!componentMeta.files || !Array.isArray(componentMeta.files)) {
|
|
87
|
-
spinner.fail(chalk.red(`Component ${componentName} has no files listed in registry.`));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
spinner.text = `Fetching ${componentName} files...`;
|
|
91
|
-
const titleCaseComponentName = componentName.charAt(0).toUpperCase() + componentName.slice(1);
|
|
92
|
-
const targetBase2 = (config.aliases.draft ?? config.aliases.ui ?? config.aliases.components).replace("@/", "src/");
|
|
93
|
-
const targetDir2 = path2.resolve(cwd, targetBase2, titleCaseComponentName);
|
|
94
|
-
await fs2.ensureDir(targetDir2);
|
|
95
|
-
for (const file of componentMeta.files) {
|
|
96
|
-
const fileUrl = `${pkg.register}/packages/${type}/src/components/${componentName}/${file}`;
|
|
97
|
-
const fileRes = await fetch(fileUrl);
|
|
98
|
-
if (!fileRes.ok) {
|
|
99
|
-
throw new Error(`Failed to fetch file ${file}: ${fileRes.statusText}`);
|
|
100
|
-
}
|
|
101
|
-
const content = await fileRes.text();
|
|
102
|
-
await fs2.writeFile(path2.resolve(targetDir2, file), content);
|
|
103
|
-
}
|
|
104
|
-
if (componentMeta.dependencies != null && componentMeta.dependencies.length > 0) {
|
|
105
|
-
spinner.text = `Installing dependencies for ${componentName}: ${componentMeta.dependencies.join(", ")}...`;
|
|
106
|
-
const { execa } = await import("execa");
|
|
107
|
-
try {
|
|
108
|
-
await execa("pnpm", ["add", ...componentMeta.dependencies], { cwd });
|
|
109
|
-
} catch (err) {
|
|
110
|
-
spinner.warn(chalk.yellow(`Component added, but failed to install dependencies: ${err.message}`));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
spinner.succeed(chalk.green(`Component ${componentName} added from registry.`));
|
|
114
|
-
return;
|
|
115
|
-
} catch (error) {
|
|
116
|
-
spinner.fail(chalk.red(`Failed to fetch from registry: ${error.message}`));
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
spinner.fail(chalk.red(`Component ${componentName} not found for ${type}.`));
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const targetBase = (config.aliases.draft ?? config.aliases.ui ?? config.aliases.components).replace("@/", "src/");
|
|
124
|
-
const targetDir = path2.resolve(cwd, targetBase, componentName);
|
|
125
|
-
await fs2.ensureDir(targetDir);
|
|
126
|
-
await fs2.copy(sourceDir, targetDir);
|
|
127
|
-
const registryPath = path2.resolve(monorepoRoot, "packages", type, "src", "registry.json");
|
|
128
|
-
if (await fs2.pathExists(registryPath)) {
|
|
129
|
-
const registry = await fs2.readJson(registryPath);
|
|
130
|
-
const componentMeta = registry.components[componentName];
|
|
131
|
-
if (componentMeta?.dependencies?.length > 0) {
|
|
132
|
-
spinner.text = `Installing dependencies for ${componentName}: ${componentMeta.dependencies.join(", ")}...`;
|
|
133
|
-
const { execa } = await import("execa");
|
|
134
|
-
try {
|
|
135
|
-
await execa("pnpm", ["add", ...componentMeta.dependencies], { cwd });
|
|
136
|
-
spinner.succeed(chalk.green(`Component ${componentName} and its dependencies added successfully.`));
|
|
137
|
-
return;
|
|
138
|
-
} catch (err) {
|
|
139
|
-
spinner.warn(chalk.yellow(`Component copied, but failed to install dependencies: ${err.message}`));
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
spinner.succeed(chalk.green(`Component ${componentName} added successfully to ${targetDir}`));
|
|
145
|
-
} catch (error) {
|
|
146
|
-
spinner.fail(chalk.red(`Failed to add component: ${error}`));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// src/commands/init.ts
|
|
151
|
-
import path3 from "path";
|
|
152
|
-
import chalk2 from "chalk";
|
|
153
|
-
import fs3 from "fs-extra";
|
|
154
|
-
import ora2 from "ora";
|
|
155
|
-
var DEFAULT_CONFIG = {
|
|
156
|
-
style: "default",
|
|
157
|
-
rsc: false,
|
|
158
|
-
tsx: true,
|
|
159
|
-
tailwind: {
|
|
160
|
-
config: "tailwind.config.js",
|
|
161
|
-
css: "src/index.css",
|
|
162
|
-
baseColor: "slate",
|
|
163
|
-
cssVariables: true
|
|
164
|
-
},
|
|
165
|
-
aliases: {
|
|
166
|
-
components: "@/components",
|
|
167
|
-
utils: "@/lib/utils",
|
|
168
|
-
ui: "@/components/ui",
|
|
169
|
-
draft: "@/components/draft"
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
async function initProject() {
|
|
173
|
-
const cwd = process.cwd();
|
|
174
|
-
const configPath = path3.resolve(cwd, "components.json");
|
|
175
|
-
if (await fs3.pathExists(configPath)) {
|
|
176
|
-
console.log(chalk2.yellow("\ncomponents.json already exists.\n"));
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
const spinner = ora2("Initializing project...").start();
|
|
180
|
-
try {
|
|
181
|
-
await fs3.writeJson(configPath, DEFAULT_CONFIG, { spaces: 2 });
|
|
182
|
-
spinner.succeed(chalk2.green("Initialized components.json successfully!"));
|
|
183
|
-
} catch (error) {
|
|
184
|
-
spinner.fail(chalk2.red(`Failed to initialize project: ${error}`));
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export {
|
|
189
|
-
addComponent,
|
|
190
|
-
initProject
|
|
191
|
-
};
|
package/dist/react.d.ts
DELETED
package/dist/react.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addComponent,
|
|
3
|
-
initProject
|
|
4
|
-
} from "./chunk-TY6E2FMX.js";
|
|
5
|
-
|
|
6
|
-
// src/bin/react.ts
|
|
7
|
-
import { Command } from "commander";
|
|
8
|
-
var program = new Command();
|
|
9
|
-
program.name("draft-react").description("CLI for adding React components").version("0.0.1");
|
|
10
|
-
program.command("add").description("add a component to your project").argument("<component>", "the component to add").action(async (component) => {
|
|
11
|
-
await addComponent(component, "react");
|
|
12
|
-
});
|
|
13
|
-
program.command("init").description("initialize your project and create a components.json file").action(async () => {
|
|
14
|
-
await initProject();
|
|
15
|
-
});
|
|
16
|
-
program.parse();
|
package/dist/vue.d.ts
DELETED
package/dist/vue.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
addComponent,
|
|
3
|
-
initProject
|
|
4
|
-
} from "./chunk-TY6E2FMX.js";
|
|
5
|
-
|
|
6
|
-
// src/bin/vue.ts
|
|
7
|
-
import { Command } from "commander";
|
|
8
|
-
var program = new Command();
|
|
9
|
-
program.name("draft-vue").description("CLI for adding Vue components").version("0.0.1");
|
|
10
|
-
program.command("add").description("add a component to your project").argument("<component>", "the component to add").action(async (component) => {
|
|
11
|
-
await addComponent(component, "vue");
|
|
12
|
-
});
|
|
13
|
-
program.command("init").description("initialize your project and create a components.json file").action(async () => {
|
|
14
|
-
await initProject();
|
|
15
|
-
});
|
|
16
|
-
program.parse();
|
package/src/bin/react.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander'
|
|
2
|
-
|
|
3
|
-
import { addComponent } from '../commands/add.js'
|
|
4
|
-
import { initProject } from '../commands/init.js'
|
|
5
|
-
|
|
6
|
-
const program = new Command()
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
.name('draft-react')
|
|
10
|
-
.description('CLI for adding React components')
|
|
11
|
-
.version('0.0.1')
|
|
12
|
-
|
|
13
|
-
program
|
|
14
|
-
.command('add')
|
|
15
|
-
.description('add a component to your project')
|
|
16
|
-
.argument('<component>', 'the component to add')
|
|
17
|
-
.action(async (component) => {
|
|
18
|
-
await addComponent(component, 'react')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
program
|
|
22
|
-
.command('init')
|
|
23
|
-
.description('initialize your project and create a components.json file')
|
|
24
|
-
.action(async () => {
|
|
25
|
-
await initProject()
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
program.parse()
|
package/src/bin/vue.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander'
|
|
2
|
-
|
|
3
|
-
import { addComponent } from '../commands/add.js'
|
|
4
|
-
import { initProject } from '../commands/init.js'
|
|
5
|
-
|
|
6
|
-
const program = new Command()
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
.name('draft-vue')
|
|
10
|
-
.description('CLI for adding Vue components')
|
|
11
|
-
.version('0.0.1')
|
|
12
|
-
|
|
13
|
-
program
|
|
14
|
-
.command('add')
|
|
15
|
-
.description('add a component to your project')
|
|
16
|
-
.argument('<component>', 'the component to add')
|
|
17
|
-
.action(async (component) => {
|
|
18
|
-
await addComponent(component, 'vue')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
program
|
|
22
|
-
.command('init')
|
|
23
|
-
.description('initialize your project and create a components.json file')
|
|
24
|
-
.action(async () => {
|
|
25
|
-
await initProject()
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
program.parse()
|