scaffy-tool 0.2.0 → 1.0.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.
Files changed (45) hide show
  1. package/README.md +21 -26
  2. package/cli.js +18 -41
  3. package/core/detector.js +5 -31
  4. package/core/executor.js +5 -27
  5. package/core/interviewer.js +15 -19
  6. package/core/plugin-validator.js +1 -1
  7. package/core/registry.js +47 -28
  8. package/core/utils.js +2 -19
  9. package/package.json +11 -11
  10. package/registry/go/gin/plugin.json +23 -0
  11. package/registry/go/gin/v1/questions.js +19 -0
  12. package/registry/go/gin/v1/scaffold.js +196 -0
  13. package/registry/index.json +4 -4
  14. package/registry/javascript/expressjs/plugin.json +44 -0
  15. package/registry/javascript/expressjs/v4/questions.js +43 -0
  16. package/registry/javascript/expressjs/v4/scaffold.js +236 -0
  17. package/registry/javascript/nestjs/plugin.json +2 -2
  18. package/registry/javascript/nestjs/v10/questions.js +6 -4
  19. package/registry/javascript/nestjs/v10/scaffold.js +1 -1
  20. package/registry/javascript/nestjs/v11/questions.js +61 -0
  21. package/registry/javascript/nestjs/v11/scaffold.js +94 -0
  22. package/registry/javascript/nextjs/plugin.json +44 -0
  23. package/registry/javascript/nextjs/v14/questions.js +44 -0
  24. package/registry/javascript/nextjs/v14/scaffold.js +57 -0
  25. package/registry/javascript/vuejs/v3/questions.js +5 -3
  26. package/registry/javascript/vuejs/v3/scaffold.js +3 -10
  27. package/registry/php/laravel/plugin.json +2 -2
  28. package/registry/php/laravel/v11/questions.js +3 -3
  29. package/registry/php/laravel/v11/scaffold.js +1 -1
  30. package/registry/php/laravel/v12/questions.js +45 -0
  31. package/registry/php/laravel/v12/scaffold.js +46 -0
  32. package/registry/php/laravel/v13/questions.js +28 -0
  33. package/registry/php/laravel/v13/scaffold.js +46 -0
  34. package/registry/php/laravel/v13/test/.gitkeep +0 -0
  35. package/registry/php/laravel/v13/test/questions.test.js +48 -0
  36. package/registry/php/laravel/v13/test/scaffold.test.js +105 -0
  37. package/registry/php/symfony/plugin.json +35 -0
  38. package/registry/php/symfony/v7/questions.js +19 -0
  39. package/registry/php/symfony/v7/scaffold.js +74 -0
  40. package/registry/python/django/plugin.json +35 -0
  41. package/registry/python/django/v5/questions.js +24 -0
  42. package/registry/python/django/v5/scaffold.js +107 -0
  43. package/registry/python/fastapi/plugin.json +35 -0
  44. package/registry/python/fastapi/v1/questions.js +25 -0
  45. package/registry/python/fastapi/v1/scaffold.js +180 -0
@@ -0,0 +1,180 @@
1
+ export default async (answers, utils) => {
2
+ const { projectName, database, async: useAsync, docker } = answers;
3
+
4
+ utils.title('Creating FastAPI Project');
5
+
6
+ // ─── Step 1: Create project folder ────────────────────
7
+ utils.step(1, 'Creating project structure');
8
+ await utils.run(`mkdir ${projectName}`);
9
+ await utils.run(`mkdir ${projectName}/app`);
10
+
11
+ // ─── Step 2: Create virtual environment ───────────────
12
+ utils.step(2, 'Creating virtual environment');
13
+ await utils.runInProject(projectName, 'python3 -m venv venv');
14
+
15
+ // ─── Step 3: Install FastAPI + Uvicorn ────────────────
16
+ utils.step(3, 'Installing FastAPI and Uvicorn');
17
+ await utils.runInProject(
18
+ projectName,
19
+ 'venv/bin/pip install "fastapi>=0.100.0" "uvicorn[standard]"'
20
+ );
21
+
22
+ // ─── Step 4: Database drivers ─────────────────────────
23
+ if (database !== 'none') {
24
+ utils.step(4, 'Installing database dependencies');
25
+ await utils.runInProject(
26
+ projectName,
27
+ 'venv/bin/pip install sqlalchemy alembic'
28
+ );
29
+
30
+ if (database === 'postgresql') {
31
+ const driver = useAsync ? 'asyncpg' : 'psycopg2-binary';
32
+ await utils.runInProject(projectName, `venv/bin/pip install ${driver}`);
33
+ }
34
+
35
+ if (database === 'mysql') {
36
+ const driver = useAsync ? 'aiomysql' : 'mysqlclient';
37
+ await utils.runInProject(projectName, `venv/bin/pip install ${driver}`);
38
+ }
39
+
40
+ if (database === 'sqlite' && useAsync) {
41
+ await utils.runInProject(projectName, 'venv/bin/pip install aiosqlite');
42
+ }
43
+ }
44
+
45
+ // ─── Step 5: Generate main.py ─────────────────────────
46
+ utils.step(5, 'Generating application files');
47
+
48
+ const mainPy = `from fastapi import FastAPI
49
+
50
+ app = FastAPI(title="${projectName}", version="0.1.0")
51
+
52
+
53
+ @app.get("/")
54
+ ${useAsync ? 'async ' : ''}def root():
55
+ return {"message": "Hello from ${projectName}"}
56
+
57
+
58
+ @app.get("/health")
59
+ ${useAsync ? 'async ' : ''}def health():
60
+ return {"status": "ok"}
61
+ `;
62
+
63
+ await utils.createFile(`${projectName}/app/main.py`, mainPy);
64
+
65
+ // ─── Step 6: Generate database.py if needed ───────────
66
+ if (database !== 'none') {
67
+ const dsnMap = {
68
+ postgresql: useAsync
69
+ ? `postgresql+asyncpg://user:password@localhost/${projectName}`
70
+ : `postgresql+psycopg2://user:password@localhost/${projectName}`,
71
+ mysql: useAsync
72
+ ? `mysql+aiomysql://user:password@localhost/${projectName}`
73
+ : `mysql+mysqlclient://user:password@localhost/${projectName}`,
74
+ sqlite: useAsync
75
+ ? `sqlite+aiosqlite:///./data.db`
76
+ : `sqlite:///./data.db`,
77
+ };
78
+
79
+ const databasePy = `from sqlalchemy${useAsync ? '.ext.asyncio' : ''} import create_engine${useAsync ? ', AsyncSession' : ''}, sessionmaker
80
+ from sqlalchemy.orm import DeclarativeBase
81
+
82
+ DATABASE_URL = "${dsnMap[database]}"
83
+
84
+ ${
85
+ useAsync
86
+ ? `engine = create_engine(DATABASE_URL)
87
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)`
88
+ : `engine = create_engine(DATABASE_URL)
89
+ SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)`
90
+ }
91
+
92
+
93
+ class Base(DeclarativeBase):
94
+ pass
95
+ `;
96
+ await utils.createFile(`${projectName}/app/database.py`, databasePy);
97
+ }
98
+
99
+ // ─── Step 7: Generate __init__.py ─────────────────────
100
+ await utils.createFile(`${projectName}/app/__init__.py`, '');
101
+
102
+ // ─── Step 8: requirements.txt ─────────────────────────
103
+ utils.step(6, 'Generating requirements.txt');
104
+
105
+ const requirements = ['fastapi>=0.100.0', 'uvicorn[standard]'];
106
+
107
+ if (database !== 'none') {
108
+ requirements.push('sqlalchemy');
109
+ requirements.push('alembic');
110
+ if (database === 'postgresql')
111
+ requirements.push(useAsync ? 'asyncpg' : 'psycopg2-binary');
112
+ if (database === 'mysql')
113
+ requirements.push(useAsync ? 'aiomysql' : 'mysqlclient');
114
+ if (database === 'sqlite' && useAsync) requirements.push('aiosqlite');
115
+ }
116
+
117
+ await utils.createFile(
118
+ `${projectName}/requirements.txt`,
119
+ requirements.join('\n') + '\n'
120
+ );
121
+
122
+ // ─── Step 9: Docker ───────────────────────────────────
123
+ if (docker) {
124
+ utils.step(7, 'Creating Docker config');
125
+
126
+ const dockerfile = `FROM python:3.12-slim
127
+
128
+ WORKDIR /app
129
+
130
+ COPY requirements.txt .
131
+ RUN pip install --no-cache-dir -r requirements.txt
132
+
133
+ COPY . .
134
+
135
+ EXPOSE 8000
136
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
137
+ `;
138
+
139
+ const dockerCompose = `version: '3.8'
140
+ services:
141
+ web:
142
+ build: .
143
+ ports:
144
+ - "8000:8000"
145
+ volumes:
146
+ - .:/app
147
+ ${
148
+ database === 'postgresql'
149
+ ? ` db:
150
+ image: postgres:15
151
+ environment:
152
+ POSTGRES_PASSWORD: password
153
+ POSTGRES_DB: ${projectName}
154
+ ports:
155
+ - "5432:5432"`
156
+ : ''
157
+ }
158
+ ${
159
+ database === 'mysql'
160
+ ? ` db:
161
+ image: mysql:8.0
162
+ environment:
163
+ MYSQL_ROOT_PASSWORD: password
164
+ MYSQL_DATABASE: ${projectName}
165
+ ports:
166
+ - "3306:3306"`
167
+ : ''
168
+ }
169
+ `;
170
+
171
+ await utils.createFile(`${projectName}/Dockerfile`, dockerfile);
172
+ await utils.createFile(`${projectName}/docker-compose.yml`, dockerCompose);
173
+ }
174
+
175
+ utils.success(`FastAPI project "${projectName}" created successfully!`);
176
+ utils.log(` cd ${projectName}`);
177
+ utils.log(` source venv/bin/activate`);
178
+ utils.log(` uvicorn app.main:app --reload`);
179
+ utils.log(` Docs: http://localhost:8000/docs`);
180
+ };