blacksmith-cli 0.1.1
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 +210 -0
- package/bin/blacksmith.js +20 -0
- package/dist/index.js +4404 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
- package/src/templates/backend/.env.example.hbs +10 -0
- package/src/templates/backend/apps/__init__.py.hbs +0 -0
- package/src/templates/backend/apps/users/__init__.py.hbs +0 -0
- package/src/templates/backend/apps/users/admin.py.hbs +26 -0
- package/src/templates/backend/apps/users/managers.py.hbs +25 -0
- package/src/templates/backend/apps/users/models.py.hbs +25 -0
- package/src/templates/backend/apps/users/serializers.py.hbs +94 -0
- package/src/templates/backend/apps/users/tests.py.hbs +47 -0
- package/src/templates/backend/apps/users/urls.py.hbs +10 -0
- package/src/templates/backend/apps/users/views.py.hbs +175 -0
- package/src/templates/backend/config/__init__.py.hbs +0 -0
- package/src/templates/backend/config/asgi.py.hbs +9 -0
- package/src/templates/backend/config/settings/__init__.py.hbs +13 -0
- package/src/templates/backend/config/settings/base.py.hbs +117 -0
- package/src/templates/backend/config/settings/development.py.hbs +19 -0
- package/src/templates/backend/config/settings/production.py.hbs +31 -0
- package/src/templates/backend/config/urls.py.hbs +26 -0
- package/src/templates/backend/config/wsgi.py.hbs +9 -0
- package/src/templates/backend/manage.py.hbs +22 -0
- package/src/templates/backend/requirements.txt.hbs +7 -0
- package/src/templates/frontend/.env.hbs +1 -0
- package/src/templates/frontend/index.html.hbs +13 -0
- package/src/templates/frontend/openapi-ts.config.ts.hbs +29 -0
- package/src/templates/frontend/package.json.hbs +44 -0
- package/src/templates/frontend/postcss.config.js.hbs +6 -0
- package/src/templates/frontend/src/api/client.ts.hbs +110 -0
- package/src/templates/frontend/src/api/generated/.gitkeep +0 -0
- package/src/templates/frontend/src/api/generated/client.gen.ts +13 -0
- package/src/templates/frontend/src/api/query-client.ts.hbs +22 -0
- package/src/templates/frontend/src/app.tsx.hbs +30 -0
- package/src/templates/frontend/src/features/auth/adapter.ts.hbs +198 -0
- package/src/templates/frontend/src/features/auth/components/auth-provider.tsx.hbs +32 -0
- package/src/templates/frontend/src/features/auth/hooks/use-auth.ts.hbs +27 -0
- package/src/templates/frontend/src/features/auth/index.ts.hbs +3 -0
- package/src/templates/frontend/src/features/auth/pages/forgot-password-page.tsx.hbs +37 -0
- package/src/templates/frontend/src/features/auth/pages/login-page.tsx.hbs +36 -0
- package/src/templates/frontend/src/features/auth/pages/register-page.tsx.hbs +36 -0
- package/src/templates/frontend/src/features/auth/pages/reset-password-page.tsx.hbs +41 -0
- package/src/templates/frontend/src/features/auth/routes.tsx.hbs +13 -0
- package/src/templates/frontend/src/main.tsx.hbs +10 -0
- package/src/templates/frontend/src/pages/dashboard/components/quick-start-card.tsx.hbs +36 -0
- package/src/templates/frontend/src/pages/dashboard/components/stack-cards.tsx.hbs +69 -0
- package/src/templates/frontend/src/pages/dashboard/components/welcome-header.tsx.hbs +14 -0
- package/src/templates/frontend/src/pages/dashboard/dashboard.tsx.hbs +21 -0
- package/src/templates/frontend/src/pages/dashboard/index.ts.hbs +1 -0
- package/src/templates/frontend/src/pages/dashboard/routes.tsx.hbs +7 -0
- package/src/templates/frontend/src/pages/home/components/features-grid.tsx.hbs +88 -0
- package/src/templates/frontend/src/pages/home/components/getting-started.tsx.hbs +88 -0
- package/src/templates/frontend/src/pages/home/components/hero-section.tsx.hbs +47 -0
- package/src/templates/frontend/src/pages/home/components/resources-section.tsx.hbs +34 -0
- package/src/templates/frontend/src/pages/home/home.tsx.hbs +20 -0
- package/src/templates/frontend/src/pages/home/index.ts.hbs +1 -0
- package/src/templates/frontend/src/pages/home/routes.tsx.hbs +7 -0
- package/src/templates/frontend/src/router/auth-guard.tsx.hbs +57 -0
- package/src/templates/frontend/src/router/error-boundary.tsx.hbs +61 -0
- package/src/templates/frontend/src/router/index.tsx.hbs +12 -0
- package/src/templates/frontend/src/router/layouts/auth-layout.tsx.hbs +68 -0
- package/src/templates/frontend/src/router/layouts/main-layout.tsx.hbs +137 -0
- package/src/templates/frontend/src/router/paths.ts.hbs +38 -0
- package/src/templates/frontend/src/router/routes.tsx.hbs +64 -0
- package/src/templates/frontend/src/shared/components/loading-spinner.tsx.hbs +20 -0
- package/src/templates/frontend/src/shared/components/not-found-page.tsx.hbs +31 -0
- package/src/templates/frontend/src/shared/hooks/api-error.ts.hbs +147 -0
- package/src/templates/frontend/src/shared/hooks/use-api-mutation.ts.hbs +88 -0
- package/src/templates/frontend/src/shared/hooks/use-api-query.ts.hbs +66 -0
- package/src/templates/frontend/src/shared/hooks/use-debounce.ts.hbs +10 -0
- package/src/templates/frontend/src/styles/globals.css.hbs +62 -0
- package/src/templates/frontend/src/vite-env.d.ts.hbs +1 -0
- package/src/templates/frontend/tailwind.config.js.hbs +73 -0
- package/src/templates/frontend/tsconfig.app.json.hbs +25 -0
- package/src/templates/frontend/tsconfig.json.hbs +7 -0
- package/src/templates/frontend/tsconfig.node.json.hbs +18 -0
- package/src/templates/frontend/vite.config.ts.hbs +21 -0
- package/src/templates/resource/backend/__init__.py.hbs +0 -0
- package/src/templates/resource/backend/admin.py.hbs +10 -0
- package/src/templates/resource/backend/models.py.hbs +24 -0
- package/src/templates/resource/backend/serializers.py.hbs +21 -0
- package/src/templates/resource/backend/tests.py.hbs +35 -0
- package/src/templates/resource/backend/urls.py.hbs +10 -0
- package/src/templates/resource/backend/views.py.hbs +32 -0
- package/src/templates/resource/frontend/components/{{kebab}}-card.tsx.hbs +39 -0
- package/src/templates/resource/frontend/components/{{kebab}}-form.tsx.hbs +106 -0
- package/src/templates/resource/frontend/components/{{kebab}}-list.tsx.hbs +49 -0
- package/src/templates/resource/frontend/hooks/use-{{kebabs}}-query.ts.hbs +35 -0
- package/src/templates/resource/frontend/hooks/use-{{kebab}}-mutations.ts.hbs +39 -0
- package/src/templates/resource/frontend/index.ts.hbs +6 -0
- package/src/templates/resource/frontend/pages/{{kebabs}}-page.tsx.hbs +33 -0
- package/src/templates/resource/frontend/pages/{{kebab}}-detail-page.tsx.hbs +96 -0
- package/src/templates/resource/frontend/routes.tsx.hbs +15 -0
- package/src/templates/resource/pages/components/{{kebab}}-card.tsx.hbs +39 -0
- package/src/templates/resource/pages/components/{{kebab}}-form.tsx.hbs +106 -0
- package/src/templates/resource/pages/components/{{kebab}}-list.tsx.hbs +49 -0
- package/src/templates/resource/pages/hooks/use-{{kebabs}}-query.ts.hbs +35 -0
- package/src/templates/resource/pages/hooks/use-{{kebab}}-mutations.ts.hbs +39 -0
- package/src/templates/resource/pages/index.ts.hbs +6 -0
- package/src/templates/resource/pages/routes.tsx.hbs +15 -0
- package/src/templates/resource/pages/{{kebabs}}-page.tsx.hbs +33 -0
- package/src/templates/resource/pages/{{kebab}}-detail-page.tsx.hbs +96 -0
package/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Blacksmith CLI
|
|
2
|
+
|
|
3
|
+
**Fullstack Django + React framework — one command, one codebase, one mental model.**
|
|
4
|
+
|
|
5
|
+
Blacksmith scaffolds production-ready web applications with a Django REST backend and a React frontend, wired together through automatic OpenAPI synchronization. Define your API in Django, and Blacksmith generates the TypeScript client, types, and hooks for you.
|
|
6
|
+
|
|
7
|
+
## Why Blacksmith?
|
|
8
|
+
|
|
9
|
+
Building fullstack apps usually means gluing together two separate projects, manually keeping types in sync, and writing boilerplate on both sides of the stack. Blacksmith eliminates that friction:
|
|
10
|
+
|
|
11
|
+
- **One command to scaffold** a complete project with authentication, routing, and API layer already wired up
|
|
12
|
+
- **Automatic API sync** — change a Django serializer, get updated TypeScript types and API client instantly
|
|
13
|
+
- **Full-stack resource scaffolding** — `make:resource BlogPost` creates the model, serializer, viewset, URLs, hooks, components, and pages
|
|
14
|
+
- **AI-ready** — generates a `CLAUDE.md` and skill files so AI coding assistants understand your entire stack
|
|
15
|
+
- **Clean ejection** — remove Blacksmith at any time and keep a standard Django + React project
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
### Prerequisites
|
|
20
|
+
|
|
21
|
+
- **Node.js** >= 20.5.0
|
|
22
|
+
- **Python 3**
|
|
23
|
+
- **npm**
|
|
24
|
+
|
|
25
|
+
### Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g blacksmith-cli
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Create a Project
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
blacksmith init my-app
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
You'll be prompted for configuration (or pass flags to skip prompts):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
blacksmith init my-app \
|
|
41
|
+
--backend-port 8000 \
|
|
42
|
+
--frontend-port 5173 \
|
|
43
|
+
--theme-color blue \
|
|
44
|
+
--ai
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Start Developing
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
cd my-app
|
|
51
|
+
blacksmith dev
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This starts three processes in parallel:
|
|
55
|
+
1. **Django** development server
|
|
56
|
+
2. **Vite** dev server with HMR
|
|
57
|
+
3. **OpenAPI watcher** that auto-syncs types when backend files change
|
|
58
|
+
|
|
59
|
+
## Commands
|
|
60
|
+
|
|
61
|
+
| Command | Description |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `blacksmith init [name]` | Create a new project (interactive or via flags) |
|
|
64
|
+
| `blacksmith dev` | Start Django + Vite + OpenAPI watcher |
|
|
65
|
+
| `blacksmith sync` | Regenerate frontend API client from Django schema |
|
|
66
|
+
| `blacksmith make:resource <Name>` | Scaffold a CRUD resource across the full stack |
|
|
67
|
+
| `blacksmith build` | Production build (Vite + collectstatic) |
|
|
68
|
+
| `blacksmith eject` | Remove Blacksmith, keep a clean project |
|
|
69
|
+
| `blacksmith setup:ai` | Generate CLAUDE.md with AI development skills |
|
|
70
|
+
| `blacksmith skills` | List available AI skills |
|
|
71
|
+
| `blacksmith backend <cmd>` | Run a Django management command |
|
|
72
|
+
| `blacksmith frontend <cmd>` | Run an npm command in the frontend |
|
|
73
|
+
|
|
74
|
+
## Generated Project Structure
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
my-app/
|
|
78
|
+
├── backend/ # Django project
|
|
79
|
+
│ ├── config/ # Settings, URLs, WSGI/ASGI
|
|
80
|
+
│ │ └── settings/ # Split settings (base, development, production)
|
|
81
|
+
│ ├── apps/ # Django apps (one per resource)
|
|
82
|
+
│ │ └── users/ # Built-in user app with JWT auth
|
|
83
|
+
│ ├── manage.py
|
|
84
|
+
│ ├── requirements.txt
|
|
85
|
+
│ └── venv/ # Python virtual environment
|
|
86
|
+
├── frontend/ # React + Vite project
|
|
87
|
+
│ ├── src/
|
|
88
|
+
│ │ ├── api/ # Auto-generated API client (via OpenAPI)
|
|
89
|
+
│ │ ├── features/ # Feature modules (auth, etc.)
|
|
90
|
+
│ │ ├── pages/ # Top-level page components
|
|
91
|
+
│ │ ├── router/ # React Router with auth guards
|
|
92
|
+
│ │ ├── shared/ # Shared components and hooks
|
|
93
|
+
│ │ └── styles/ # Global styles (Tailwind CSS)
|
|
94
|
+
│ └── package.json
|
|
95
|
+
├── blacksmith.config.json # Project configuration
|
|
96
|
+
└── CLAUDE.md # AI development guide (with --ai)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Tech Stack
|
|
100
|
+
|
|
101
|
+
### Backend
|
|
102
|
+
- **Django** with split settings (base/development/production)
|
|
103
|
+
- **Django REST Framework** for API endpoints
|
|
104
|
+
- **drf-spectacular** for OpenAPI schema generation
|
|
105
|
+
- **SimpleJWT** for token-based authentication
|
|
106
|
+
- **django-environ** for environment variable management
|
|
107
|
+
|
|
108
|
+
### Frontend
|
|
109
|
+
- **React 19** with TypeScript (strict mode)
|
|
110
|
+
- **Vite** for fast builds and HMR
|
|
111
|
+
- **React Router v7** for client-side routing
|
|
112
|
+
- **TanStack React Query** for server state management
|
|
113
|
+
- **React Hook Form** + **Zod** for forms and validation
|
|
114
|
+
- **Tailwind CSS** for styling
|
|
115
|
+
- **@hey-api/openapi-ts** for API client generation
|
|
116
|
+
|
|
117
|
+
## Resource Scaffolding
|
|
118
|
+
|
|
119
|
+
The `make:resource` command generates a complete CRUD feature across both backend and frontend:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
blacksmith make:resource BlogPost
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Backend** (in `backend/apps/blog_posts/`):
|
|
126
|
+
- `models.py` — Django model
|
|
127
|
+
- `serializers.py` — DRF serializer
|
|
128
|
+
- `views.py` — DRF viewset
|
|
129
|
+
- `urls.py` — URL configuration
|
|
130
|
+
- `admin.py` — Admin registration
|
|
131
|
+
- `tests.py` — Test scaffold
|
|
132
|
+
|
|
133
|
+
**Frontend** (in `frontend/src/features/blog-posts/`):
|
|
134
|
+
- API hooks for list, detail, create, update, delete
|
|
135
|
+
- List and detail page components
|
|
136
|
+
- Create and edit form components
|
|
137
|
+
|
|
138
|
+
After scaffolding, run `blacksmith sync` to generate the TypeScript types.
|
|
139
|
+
|
|
140
|
+
## OpenAPI Sync
|
|
141
|
+
|
|
142
|
+
Blacksmith bridges Django and React through OpenAPI:
|
|
143
|
+
|
|
144
|
+
1. Django serves an OpenAPI schema via `drf-spectacular`
|
|
145
|
+
2. `@hey-api/openapi-ts` generates a typed API client from that schema
|
|
146
|
+
3. During `blacksmith dev`, a file watcher detects backend changes and re-syncs automatically
|
|
147
|
+
|
|
148
|
+
You never manually write API client code — it's always generated from your Django serializers and viewsets.
|
|
149
|
+
|
|
150
|
+
## AI Development Support
|
|
151
|
+
|
|
152
|
+
With the `--ai` flag, Blacksmith generates documentation that helps AI coding assistants (like Claude Code) understand your project:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
blacksmith init my-app --ai
|
|
156
|
+
# or add it later:
|
|
157
|
+
blacksmith setup:ai
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This creates:
|
|
161
|
+
- **CLAUDE.md** — project overview, commands, workflow, and conventions
|
|
162
|
+
- **.claude/skills/** — detailed skill files covering Django, DRF, React, React Query, forms, authentication, and more
|
|
163
|
+
|
|
164
|
+
## Theme Presets
|
|
165
|
+
|
|
166
|
+
Choose a theme color during project creation:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
blacksmith init my-app --theme-color violet
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Available presets: `default`, `blue`, `green`, `violet`, `red`, `neutral`
|
|
173
|
+
|
|
174
|
+
## Ejecting
|
|
175
|
+
|
|
176
|
+
If you outgrow Blacksmith or want full control, eject cleanly:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
blacksmith eject
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
This removes the Blacksmith dependency and configuration, leaving you with a standard Django + React project that runs independently.
|
|
183
|
+
|
|
184
|
+
## Development Workflow
|
|
185
|
+
|
|
186
|
+
A typical workflow looks like:
|
|
187
|
+
|
|
188
|
+
1. Create a resource: `blacksmith make:resource Product`
|
|
189
|
+
2. Customize the Django model in `backend/apps/products/models.py`
|
|
190
|
+
3. Update the serializer in `backend/apps/products/serializers.py`
|
|
191
|
+
4. Run `blacksmith sync` to regenerate the frontend API client
|
|
192
|
+
5. Build the UI in `frontend/src/features/products/`
|
|
193
|
+
6. Check the API docs at `http://localhost:8000/api/docs/`
|
|
194
|
+
|
|
195
|
+
## Configuration
|
|
196
|
+
|
|
197
|
+
Project settings live in `blacksmith.config.json`:
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"name": "my-app",
|
|
202
|
+
"version": "0.1.0",
|
|
203
|
+
"backend": { "port": 8000 },
|
|
204
|
+
"frontend": { "port": 5173 }
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const requiredMajor = 20;
|
|
4
|
+
const requiredMinor = 5;
|
|
5
|
+
const requiredVersion = `${requiredMajor}.${requiredMinor}.0`;
|
|
6
|
+
|
|
7
|
+
const [major, minor] = process.version.slice(1).split('.').map(Number);
|
|
8
|
+
|
|
9
|
+
if (major < requiredMajor || (major === requiredMajor && minor < requiredMinor)) {
|
|
10
|
+
console.error(
|
|
11
|
+
`\nBlacksmith requires Node.js v${requiredVersion} or later.\n` +
|
|
12
|
+
`You are running ${process.version}.\n\n` +
|
|
13
|
+
`Please upgrade Node.js:\n` +
|
|
14
|
+
` nvm install ${requiredMajor} && nvm use ${requiredMajor}\n` +
|
|
15
|
+
` or visit https://nodejs.org\n`
|
|
16
|
+
);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
import('../dist/index.js');
|