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 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&center=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
+ &nbsp;·&nbsp;
386
+ <a href="https://github.com/TanvirHossen112/scaffy/issues/new?template=bug_report.md">🐛 Report a bug</a>
387
+ &nbsp;·&nbsp;
388
+ <a href="https://github.com/TanvirHossen112/scaffy/issues/new?template=feature_request.md">💡 Request a feature</a>
389
+ &nbsp;·&nbsp;
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