scaffy-tool 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/LICENSE +21 -0
- package/README.md +392 -0
- package/cli.js +143 -0
- package/core/.gitkeep +0 -0
- package/core/detector.js +198 -0
- package/core/executor.js +105 -0
- package/core/interviewer.js +140 -0
- package/core/plugin-validator.js +2 -0
- package/core/registry.js +128 -0
- package/core/utils.js +63 -0
- package/package.json +82 -0
- package/registry/index.json +85 -0
- package/registry/javascript/nestjs/plugin.json +44 -0
- package/registry/javascript/nestjs/v10/questions.js +59 -0
- package/registry/javascript/nestjs/v10/scaffold.js +94 -0
- package/registry/javascript/vuejs/plugin.json +44 -0
- package/registry/javascript/vuejs/v3/questions.js +64 -0
- package/registry/javascript/vuejs/v3/scaffold.js +53 -0
- package/registry/php/laravel/plugin.json +34 -0
- package/registry/php/laravel/v11/questions.js +44 -0
- package/registry/php/laravel/v11/scaffold.js +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Your Name
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="https://readme-typing-svg.demolab.com?font=Fira+Code&weight=700&size=40&pause=1000&color=00D4FF¢er=true&vCenter=true&width=600&lines=Scaffy+%F0%9F%9A%80;One+Command.+Any+Framework." alt="Scaffy" />
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<strong>The universal CLI scaffolding tool for modern developers.</strong><br/>
|
|
7
|
+
Set up any framework project in seconds — using official installers,<br/>driven by a community-powered plugin system.
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/TanvirHossen112/scaffy/actions/workflows/ci.yml">
|
|
12
|
+
<img src="https://github.com/TanvirHossen112/scaffy/actions/workflows/ci.yml/badge.svg" alt="CI" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/scaffy-tool">
|
|
15
|
+
<img src="https://img.shields.io/npm/v/scaffy-tool?color=cb3837&logo=npm" alt="npm version" />
|
|
16
|
+
</a>
|
|
17
|
+
<a href="https://www.npmjs.com/package/scaffy-tool">
|
|
18
|
+
<img src="https://img.shields.io/npm/dm/scaffy-tool?color=cb3837&logo=npm" alt="npm downloads" />
|
|
19
|
+
</a>
|
|
20
|
+
<a href="https://nodejs.org">
|
|
21
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?logo=node.js" alt="Node" />
|
|
22
|
+
</a>
|
|
23
|
+
<a href="LICENSE">
|
|
24
|
+
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" />
|
|
25
|
+
</a>
|
|
26
|
+
<a href="CONTRIBUTING.md">
|
|
27
|
+
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome" />
|
|
28
|
+
</a>
|
|
29
|
+
<a href="https://buymeacoffee.com/TanvirHossen112">
|
|
30
|
+
<img src="https://img.shields.io/badge/☕-buy%20me%20a%20coffee-yellow" alt="Buy Me A Coffee" />
|
|
31
|
+
</a>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<p align="center">
|
|
35
|
+
<a href="#the-solution">Quick Start</a> ·
|
|
36
|
+
<a href="#-available-frameworks">Frameworks</a> ·
|
|
37
|
+
<a href="#-plugin-system">Plugin System</a> ·
|
|
38
|
+
<a href="#-contributing">Contributing</a> ·
|
|
39
|
+
<a href="#️-roadmap">Roadmap</a>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## The Problem
|
|
47
|
+
|
|
48
|
+
Every developer knows this pain. You want to start a new project. Instead of coding, you spend the next hour:
|
|
49
|
+
|
|
50
|
+
- Googling the exact install command for the framework
|
|
51
|
+
- Figuring out which version is currently stable
|
|
52
|
+
- Installing dependencies one by one
|
|
53
|
+
- Configuring Docker, databases, auth — all manually
|
|
54
|
+
- Realizing you missed a step halfway through
|
|
55
|
+
|
|
56
|
+
**Scaffy eliminates all of that.**
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## The Solution
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
$ scaffy laravel
|
|
64
|
+
|
|
65
|
+
🔍 Checking requirements...
|
|
66
|
+
✅ php — found
|
|
67
|
+
✅ composer — found
|
|
68
|
+
|
|
69
|
+
✅ All requirements met!
|
|
70
|
+
|
|
71
|
+
? Project name: my-blog
|
|
72
|
+
? Starter kit: Breeze
|
|
73
|
+
? Database: PostgreSQL
|
|
74
|
+
? Docker (Sail): Yes
|
|
75
|
+
|
|
76
|
+
⠸ Scaffolding your Laravel project...
|
|
77
|
+
|
|
78
|
+
✅ Done! Your project is ready.
|
|
79
|
+
📁 cd my-blog
|
|
80
|
+
🚀 php artisan serve
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
One command. A few questions. Ready to code.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## ✨ Why Scaffy?
|
|
88
|
+
|
|
89
|
+
Existing scaffolding tools are framework-specific, opinionated, and go stale fast. Scaffy takes a fundamentally different approach.
|
|
90
|
+
|
|
91
|
+
| | Traditional Scaffolding | Scaffy |
|
|
92
|
+
|-----------------------------|-------------------------------|-------------------------------------|
|
|
93
|
+
| **Multi-framework support** | ❌ One tool per framework | ✅ Every framework, one tool |
|
|
94
|
+
| **Always up to date** | ❌ Stores stale templates | ✅ Uses official CLI commands |
|
|
95
|
+
| **Requirement checking** | ❌ Breaks halfway through | ✅ Validates before starting |
|
|
96
|
+
| **Community extensible** | ❌ Closed, maintainer-only | ✅ Add any framework in 3 files |
|
|
97
|
+
| **Version management** | ❌ Usually locked to one | ✅ Multiple versions per framework |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## ⚡ Quick Start
|
|
102
|
+
|
|
103
|
+
**Install**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm install -g scaffy-tool
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Run**
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Interactive mode — Scaffy guides you through everything
|
|
113
|
+
scaffy
|
|
114
|
+
|
|
115
|
+
# Direct mode — jump straight to your framework
|
|
116
|
+
scaffy laravel
|
|
117
|
+
scaffy nestjs
|
|
118
|
+
scaffy django
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Other Commands**
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
scaffy list # Browse all available frameworks
|
|
125
|
+
scaffy search <query> # Search by name or language
|
|
126
|
+
scaffy --version # Current version
|
|
127
|
+
scaffy --help # Help
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 📋 Available Frameworks
|
|
133
|
+
|
|
134
|
+
<table>
|
|
135
|
+
<tr>
|
|
136
|
+
<th>Language</th>
|
|
137
|
+
<th>Framework</th>
|
|
138
|
+
<th>Command</th>
|
|
139
|
+
<th>Supported Versions</th>
|
|
140
|
+
</tr>
|
|
141
|
+
<tr>
|
|
142
|
+
<td rowspan="2"><strong>PHP</strong></td>
|
|
143
|
+
<td>Laravel</td>
|
|
144
|
+
<td><code>scaffy laravel</code></td>
|
|
145
|
+
<td>v10, v11</td>
|
|
146
|
+
</tr>
|
|
147
|
+
<tr>
|
|
148
|
+
<td>Symfony</td>
|
|
149
|
+
<td><code>scaffy symfony</code></td>
|
|
150
|
+
<td>v7</td>
|
|
151
|
+
</tr>
|
|
152
|
+
<tr>
|
|
153
|
+
<td rowspan="4"><strong>JavaScript</strong></td>
|
|
154
|
+
<td>NestJS</td>
|
|
155
|
+
<td><code>scaffy nestjs</code></td>
|
|
156
|
+
<td>v10</td>
|
|
157
|
+
</tr>
|
|
158
|
+
<tr>
|
|
159
|
+
<td>VueJS</td>
|
|
160
|
+
<td><code>scaffy vue</code></td>
|
|
161
|
+
<td>v3</td>
|
|
162
|
+
</tr>
|
|
163
|
+
<tr>
|
|
164
|
+
<td>NextJS</td>
|
|
165
|
+
<td><code>scaffy nextjs</code></td>
|
|
166
|
+
<td>v14</td>
|
|
167
|
+
</tr>
|
|
168
|
+
<tr>
|
|
169
|
+
<td>ExpressJS</td>
|
|
170
|
+
<td><code>scaffy express</code></td>
|
|
171
|
+
<td>v4</td>
|
|
172
|
+
</tr>
|
|
173
|
+
<tr>
|
|
174
|
+
<td rowspan="3"><strong>Python</strong></td>
|
|
175
|
+
<td>Django</td>
|
|
176
|
+
<td><code>scaffy django</code></td>
|
|
177
|
+
<td>v5</td>
|
|
178
|
+
</tr>
|
|
179
|
+
<tr>
|
|
180
|
+
<td>FastAPI</td>
|
|
181
|
+
<td><code>scaffy fastapi</code></td>
|
|
182
|
+
<td>v0.100+</td>
|
|
183
|
+
</tr>
|
|
184
|
+
<tr>
|
|
185
|
+
<td>Flask</td>
|
|
186
|
+
<td><code>scaffy flask</code></td>
|
|
187
|
+
<td>v3</td>
|
|
188
|
+
</tr>
|
|
189
|
+
<tr>
|
|
190
|
+
<td><strong>Go</strong></td>
|
|
191
|
+
<td>Gin</td>
|
|
192
|
+
<td><code>scaffy gin</code></td>
|
|
193
|
+
<td>v1</td>
|
|
194
|
+
</tr>
|
|
195
|
+
</table>
|
|
196
|
+
|
|
197
|
+
> **Missing your framework?** [Add it in 3 files](#-plugin-system) — it takes less than 30 minutes.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 🔌 Plugin System
|
|
202
|
+
|
|
203
|
+
Scaffy's power comes from its plugin architecture. Every framework is a self-contained plugin — just **3 files**:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
registry/
|
|
207
|
+
└── php/
|
|
208
|
+
└── laravel/
|
|
209
|
+
├── plugin.json ← framework metadata & requirements
|
|
210
|
+
└── v11/
|
|
211
|
+
├── questions.js ← what to ask the user
|
|
212
|
+
└── scaffold.js ← which official commands to run
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### How It Works Under The Hood
|
|
216
|
+
|
|
217
|
+
Scaffy does **not** store template files. Instead, `scaffold.js` calls the framework's **own official installer** — ensuring your project is always set up correctly with the latest tooling:
|
|
218
|
+
|
|
219
|
+
```javascript
|
|
220
|
+
// registry/php/laravel/v11/scaffold.js
|
|
221
|
+
module.exports = async (answers, utils) => {
|
|
222
|
+
const { projectName, starterKit, database } = answers
|
|
223
|
+
|
|
224
|
+
// Step 1 — Official Laravel installer
|
|
225
|
+
await utils.run(
|
|
226
|
+
`composer create-project laravel/laravel ${projectName}`
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
// Step 2 — Layered on top with your choices
|
|
230
|
+
if (starterKit === 'Breeze') {
|
|
231
|
+
await utils.runInProject(projectName,
|
|
232
|
+
`php artisan breeze:install`
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
When a new framework version releases tomorrow, a community member can add support in minutes — with zero changes to Scaffy's core.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 🛡️ Requirement Safety
|
|
243
|
+
|
|
244
|
+
Scaffy checks that all required tools are installed **before** running anything. Nothing is worse than a half-created broken project.
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
$ scaffy laravel
|
|
248
|
+
|
|
249
|
+
🔍 Checking requirements...
|
|
250
|
+
✅ php — found
|
|
251
|
+
❌ composer — not found
|
|
252
|
+
💻 Install (mac): brew install composer
|
|
253
|
+
💻 Install (linux): sudo apt install composer
|
|
254
|
+
📖 Docs: https://getcomposer.org/download
|
|
255
|
+
|
|
256
|
+
──────────────────────────────────────────
|
|
257
|
+
❌ Requirements not met.
|
|
258
|
+
Please install missing tools and retry.
|
|
259
|
+
Nothing was created. Your system is clean.
|
|
260
|
+
──────────────────────────────────────────
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
If something is missing, Scaffy tells you exactly how to fix it — for your specific OS.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 🏗️ Architecture
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
scaffy/
|
|
271
|
+
├── cli.js # Entry point & command routing
|
|
272
|
+
├── core/
|
|
273
|
+
│ ├── detector.js # Requirement checking engine
|
|
274
|
+
│ ├── registry.js # Plugin loader & search
|
|
275
|
+
│ ├── interviewer.js # User question engine
|
|
276
|
+
│ ├── executor.js # Command runner
|
|
277
|
+
│ └── utils.js # Shared utilities
|
|
278
|
+
└── registry/
|
|
279
|
+
├── index.json # Master framework registry
|
|
280
|
+
├── php/laravel/ # Framework plugins
|
|
281
|
+
├── javascript/nestjs/
|
|
282
|
+
├── python/django/
|
|
283
|
+
└── ...
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Every core module is written in **functional programming style** — pure functions, no classes, every function independently testable in isolation.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 🧪 Testing
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Run all tests
|
|
294
|
+
npm test
|
|
295
|
+
|
|
296
|
+
# Watch mode during development
|
|
297
|
+
npm run test:watch
|
|
298
|
+
|
|
299
|
+
# Full coverage report
|
|
300
|
+
npm run test:coverage
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Scaffy maintains a minimum **80% test coverage** across all core modules. Every plugin ships with dry-run tests that verify the correct commands are generated — without executing anything on your machine.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## 🛣️ Roadmap
|
|
308
|
+
|
|
309
|
+
**v0.1.0 — Hello World** *(current)*
|
|
310
|
+
- [x] Core engine — detector, registry, interviewer, executor
|
|
311
|
+
- [x] Functional programming architecture
|
|
312
|
+
- [x] Requirement checking with OS-specific install guides
|
|
313
|
+
- [x] Laravel v11, NestJS v10, VueJS v3 plugins
|
|
314
|
+
- [x] GitHub Actions CI pipeline
|
|
315
|
+
- [x] Published on npm
|
|
316
|
+
|
|
317
|
+
**v0.2.0 — Community Ready**
|
|
318
|
+
- [ ] ESM migration — modern JavaScript standard
|
|
319
|
+
- [ ] Plugin contribution system with automated CI validation
|
|
320
|
+
- [ ] Full documentation site
|
|
321
|
+
- [ ] 15+ framework plugins
|
|
322
|
+
|
|
323
|
+
**v0.3.0 — Growth**
|
|
324
|
+
- [ ] AI mode — describe your project in plain English
|
|
325
|
+
- [ ] `scaffy add github:user/plugin` — install external plugins
|
|
326
|
+
- [ ] Discord community
|
|
327
|
+
|
|
328
|
+
**v1.0.0 — Ecosystem**
|
|
329
|
+
- [ ] VS Code extension
|
|
330
|
+
- [ ] Plugin marketplace website
|
|
331
|
+
- [ ] Enterprise adoption
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## 🤝 Contributing
|
|
336
|
+
|
|
337
|
+
Scaffy is built by the community, for the community. There are many ways to get involved:
|
|
338
|
+
|
|
339
|
+
- 🐛 **Report a bug** — open an issue using the bug report template
|
|
340
|
+
- 💡 **Request a feature** — open an issue using the feature request template
|
|
341
|
+
- 🔌 **Add a framework plugin** — the most impactful contribution you can make
|
|
342
|
+
- 📖 **Improve documentation** — fix typos, improve clarity, add examples
|
|
343
|
+
- 🧪 **Write tests** — help reach higher coverage
|
|
344
|
+
|
|
345
|
+
Read [CONTRIBUTING.md](CONTRIBUTING.md) to get started. First time contributing to open source? Scaffy is a great place to begin — adding a framework plugin is self-contained, well-documented, and genuinely useful to thousands of developers.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## 💛 Support The Project
|
|
350
|
+
|
|
351
|
+
Scaffy is completely free and open source, and will always remain so. If it saves you time, consider supporting its development:
|
|
352
|
+
|
|
353
|
+
<a href="https://buymeacoffee.com/TanvirHossen112">
|
|
354
|
+
<img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" />
|
|
355
|
+
</a>
|
|
356
|
+
|
|
357
|
+
Your support helps fund active maintenance, new framework plugins, and the features on the roadmap.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 👥 Contributors
|
|
362
|
+
|
|
363
|
+
Thanks to every person who has contributed to making Scaffy better. 🎉
|
|
364
|
+
|
|
365
|
+
<!-- ALL-CONTRIBUTORS-LIST:START -->
|
|
366
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
367
|
+
|
|
368
|
+
Want to see your name here? Check out [CONTRIBUTING.md](CONTRIBUTING.md) and submit your first PR.
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 📄 License
|
|
373
|
+
|
|
374
|
+
Scaffy is open source software licensed under the [MIT License](LICENSE).
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
<div align="center">
|
|
379
|
+
|
|
380
|
+
Built with dedication by the Scaffy community
|
|
381
|
+
|
|
382
|
+
<br/>
|
|
383
|
+
|
|
384
|
+
<a href="https://buymeacoffee.com/TanvirHossen112">☕ Buy me a coffee</a>
|
|
385
|
+
·
|
|
386
|
+
<a href="https://github.com/TanvirHossen112/scaffy/issues/new?template=bug_report.md">🐛 Report a bug</a>
|
|
387
|
+
·
|
|
388
|
+
<a href="https://github.com/TanvirHossen112/scaffy/issues/new?template=feature_request.md">💡 Request a feature</a>
|
|
389
|
+
·
|
|
390
|
+
<a href="https://github.com/TanvirHossen112/scaffy/discussions">💬 Join the discussion</a>
|
|
391
|
+
|
|
392
|
+
</div>
|
package/cli.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { Command } = require('commander');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const figlet = require('figlet');
|
|
6
|
+
const ora = require('ora');
|
|
7
|
+
const { version } = require('./package.json');
|
|
8
|
+
const detector = require('./core/detector');
|
|
9
|
+
const registry = require('./core/registry');
|
|
10
|
+
const interviewer = require('./core/interviewer');
|
|
11
|
+
const executor = require('./core/executor');
|
|
12
|
+
const { buildPluginUtils, title, error, divider } = require('./core/utils');
|
|
13
|
+
|
|
14
|
+
// ─── Banner ───────────────────────────────────────────
|
|
15
|
+
const showBanner = () => {
|
|
16
|
+
console.log(
|
|
17
|
+
chalk.cyan(
|
|
18
|
+
figlet.textSync('Scaffy', {
|
|
19
|
+
font: 'Big',
|
|
20
|
+
horizontalLayout: 'default',
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
);
|
|
24
|
+
console.log(chalk.gray(' One command. Any framework. Ready to code.\n'));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// ─── Run Full Scaffold Flow ────────────────────────────
|
|
28
|
+
const runScaffold = async framework => {
|
|
29
|
+
try {
|
|
30
|
+
// Step 1 — Load plugin
|
|
31
|
+
const version = await interviewer.askVersion(framework);
|
|
32
|
+
const plugin = registry.loadPlugin(framework, version);
|
|
33
|
+
|
|
34
|
+
// Step 2 — Check requirements
|
|
35
|
+
const requirementsMet = await detector.report(plugin.meta.requires);
|
|
36
|
+
|
|
37
|
+
if (!requirementsMet) {
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Step 3 — Ask questions
|
|
42
|
+
const answers = await interviewer.askFrameworkQuestions(framework, plugin);
|
|
43
|
+
|
|
44
|
+
// Step 4 — Build utils for plugin
|
|
45
|
+
const utils = buildPluginUtils(executor);
|
|
46
|
+
|
|
47
|
+
// Step 5 — Run scaffold
|
|
48
|
+
divider();
|
|
49
|
+
const spinner = ora(
|
|
50
|
+
chalk.cyan(`Scaffolding ${framework.name} project...`)
|
|
51
|
+
).start();
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await plugin.scaffold(answers, utils);
|
|
55
|
+
spinner.succeed(
|
|
56
|
+
chalk.green(`${framework.name} project created successfully!`)
|
|
57
|
+
);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
spinner.fail(chalk.red('Scaffolding failed'));
|
|
60
|
+
error(err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (err.message !== 'cancelled') {
|
|
65
|
+
error(`Unexpected error: ${err.message}`);
|
|
66
|
+
}
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// ─── Program Setup ────────────────────────────────────
|
|
72
|
+
const program = new Command();
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.name('scaffy')
|
|
76
|
+
.description('One command. Any framework. Ready to code.')
|
|
77
|
+
.version(version, '-v, --version', 'Show current version');
|
|
78
|
+
|
|
79
|
+
// ─── Default Command ───────────────────────────────────
|
|
80
|
+
program
|
|
81
|
+
.argument('[framework]', 'Framework name to scaffold directly')
|
|
82
|
+
.action(async frameworkQuery => {
|
|
83
|
+
showBanner();
|
|
84
|
+
|
|
85
|
+
// Direct framework mode
|
|
86
|
+
if (frameworkQuery) {
|
|
87
|
+
const framework = await interviewer.askDirectFramework(frameworkQuery);
|
|
88
|
+
if (!framework) process.exit(1);
|
|
89
|
+
await runScaffold(framework);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Interactive mode
|
|
94
|
+
try {
|
|
95
|
+
title('Select A Framework');
|
|
96
|
+
const framework = await interviewer.askFramework();
|
|
97
|
+
await runScaffold(framework);
|
|
98
|
+
} catch {
|
|
99
|
+
console.log(chalk.yellow('\n 👋 Scaffolding cancelled\n'));
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// ─── List Command ──────────────────────────────────────
|
|
105
|
+
program
|
|
106
|
+
.command('list')
|
|
107
|
+
.description('List all available frameworks')
|
|
108
|
+
.action(() => {
|
|
109
|
+
showBanner();
|
|
110
|
+
registry.displayFrameworks();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// ─── Search Command ────────────────────────────────────
|
|
114
|
+
program
|
|
115
|
+
.command('search <query>')
|
|
116
|
+
.description('Search for a framework by name or language')
|
|
117
|
+
.action(query => {
|
|
118
|
+
showBanner();
|
|
119
|
+
|
|
120
|
+
const results = registry.searchFrameworks(query);
|
|
121
|
+
|
|
122
|
+
if (results.length === 0) {
|
|
123
|
+
console.log(chalk.red(`\n No frameworks found for "${query}"\n`));
|
|
124
|
+
console.log(
|
|
125
|
+
chalk.gray(' Run scaffy list to see all available frameworks\n')
|
|
126
|
+
);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(chalk.bold(`\n 🔍 Results for "${query}":\n`));
|
|
131
|
+
|
|
132
|
+
results.forEach(f => {
|
|
133
|
+
console.log(
|
|
134
|
+
chalk.white(` • ${f.name}`) +
|
|
135
|
+
chalk.gray(` (${f.language}) — scaffy ${f.alias[0]}`)
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
console.log('');
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// ─── Parse ────────────────────────────────────────────
|
|
143
|
+
program.parse(process.argv);
|
package/core/.gitkeep
ADDED
|
File without changes
|