tss-stack 1.0.0 → 1.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.
Files changed (3) hide show
  1. package/README.md +257 -0
  2. package/bin/cli.js +22 -5
  3. package/package.json +7 -2
package/README.md ADDED
@@ -0,0 +1,257 @@
1
+ # tss-stack
2
+
3
+ > Interactive full-stack project generator for Node.js + React + MySQL — built for TSS students and developers who are tired of rewriting the same boilerplate.
4
+
5
+ ![npm version](https://img.shields.io/npm/v/tss-stack)
6
+ ![license](https://img.shields.io/npm/l/tss-stack)
7
+ ![node](https://img.shields.io/node/v/tss-stack)
8
+
9
+ ---
10
+
11
+ ## What It Does
12
+
13
+ Run one command, answer a few questions, and get a fully wired full-stack project — no manual setup, no copy-pasting, no forgetting to install cors.
14
+
15
+ ```bash
16
+ npx tss-stack my-app
17
+ ```
18
+
19
+ It asks you:
20
+ - Your project name and database name
21
+ - How many tables you need and what fields they have
22
+ - Which CRUD operations each table needs
23
+ - Whether to include login/register and a Reports page
24
+
25
+ Then it generates everything, installs all dependencies, and prints your next steps.
26
+
27
+ ---
28
+
29
+ ## Demo
30
+
31
+ ```
32
+ 🚀 TSS Stack Generator
33
+
34
+ [1] Project display name: SmartPark
35
+ [2] MySQL database name: smartpark_db
36
+ [3] Backend port number: 5000
37
+ [4] How many tables? 3
38
+ Table 1 name: spare_parts
39
+ Fields: name, category, quantity, unit_price
40
+ Operations: INSERT, SELECT
41
+ Table 2 name: stock_in
42
+ Fields: spare_part_id, quantity, date
43
+ Operations: INSERT, SELECT
44
+ Table 3 name: stock_out
45
+ Fields: spare_part_id, quantity, unit_price, total_price, date
46
+ Operations: INSERT, SELECT, UPDATE, DELETE
47
+ [5] Add login/register system? Yes
48
+ [6] Add a Reports page? Yes
49
+
50
+ ⚙️ Generating SmartPark...
51
+
52
+ SmartPark/
53
+ ├── backend-project/
54
+ │ ├── config/
55
+ │ │ ├── db.js
56
+ │ │ └── database.sql
57
+ │ ├── middleware/
58
+ │ │ └── auth.js
59
+ │ ├── routes/
60
+ │ │ ├── auth.js
61
+ │ │ ├── spare_parts.js
62
+ │ │ ├── stock_in.js
63
+ │ │ └── stock_out.js
64
+ │ ├── server.js
65
+ │ ├── .env.example
66
+ │ └── package.json
67
+
68
+ └── frontend-project/
69
+ ├── src/
70
+ │ ├── api/
71
+ │ │ └── axios.js
72
+ │ ├── pages/
73
+ │ │ ├── Login.jsx
74
+ │ │ ├── SpareParts.jsx
75
+ │ │ ├── StockIn.jsx
76
+ │ │ ├── StockOut.jsx
77
+ │ │ └── Reports.jsx
78
+ │ ├── App.jsx
79
+ │ └── main.jsx
80
+ └── package.json
81
+
82
+ ⠸ Installing backend dependencies...
83
+ ✔ Backend dependencies installed
84
+ ✔ Frontend dependencies installed
85
+
86
+ ✅ Done! SmartPark is ready.
87
+ ```
88
+
89
+ ---
90
+
91
+ ## Generated Stack
92
+
93
+ | Layer | Technology |
94
+ |---|---|
95
+ | Runtime | Node.js |
96
+ | Backend framework | Express.js |
97
+ | Database | MySQL (mysql2) |
98
+ | Auth | express-session + bcryptjs |
99
+ | Frontend | React + Vite |
100
+ | Styling | Tailwind CSS |
101
+ | HTTP client | Axios (pre-configured) |
102
+ | Routing | React Router v6 |
103
+
104
+ ---
105
+
106
+ ## What Gets Generated
107
+
108
+ ### Backend (`backend-project/`)
109
+
110
+ - **`server.js`** — Express server with CORS, sessions, and all routes wired
111
+ - **`config/db.js`** — MySQL connection using your `.env` credentials
112
+ - **`config/database.sql`** — Ready-to-import SQL with `CREATE DATABASE`, `CREATE TABLE`, primary keys and foreign keys
113
+ - **`routes/*.js`** — One route file per table, with only the operations you selected (INSERT / SELECT / UPDATE / DELETE)
114
+ - **`middleware/auth.js`** — Session protection middleware, attach to any route
115
+ - **`routes/auth.js`** — Register, login, logout endpoints (if auth selected)
116
+ - **`.env.example`** — Template for your database credentials
117
+
118
+ ### Frontend (`frontend-project/`)
119
+
120
+ - **`src/api/axios.js`** — Pre-configured Axios instance pointed at your backend, `withCredentials` enabled
121
+ - **`src/pages/*.jsx`** — One page per table with form, table display, and only the action buttons matching your selected operations
122
+ - **`src/pages/Login.jsx`** — Login form wired to `/auth/login` (if auth selected)
123
+ - **`src/pages/Reports.jsx`** — Reports page scaffold (if selected)
124
+ - **`src/App.jsx`** — React Router setup with Navbar and all routes configured
125
+
126
+ ---
127
+
128
+ ## Getting Started After Generation
129
+
130
+ ### 1. Import the database
131
+
132
+ ```bash
133
+ mysql -u root -p < my-app/backend-project/config/database.sql
134
+ ```
135
+
136
+ ### 2. Configure environment
137
+
138
+ ```bash
139
+ cd my-app/backend-project
140
+ cp .env.example .env
141
+ ```
142
+
143
+ Open `.env` and fill in your MySQL credentials:
144
+
145
+ ```env
146
+ DB_HOST=localhost
147
+ DB_USER=root
148
+ DB_PASSWORD=your_password
149
+ DB_NAME=smartpark_db
150
+ PORT=5000
151
+ SESSION_SECRET=any_random_string_here
152
+ ```
153
+
154
+ ### 3. Start the backend
155
+
156
+ ```bash
157
+ npm run dev
158
+ ```
159
+
160
+ ### 4. Start the frontend
161
+
162
+ ```bash
163
+ cd ../frontend-project
164
+ npm run dev
165
+ ```
166
+
167
+ ### 5. Open the app
168
+
169
+ ```
170
+ http://localhost:5173
171
+ ```
172
+
173
+ ---
174
+
175
+ ## Requirements
176
+
177
+ - Node.js 16 or higher
178
+ - npm 7 or higher
179
+ - MySQL installed and running
180
+
181
+ ---
182
+
183
+ ## Project Structure (Source)
184
+
185
+ ```
186
+ tss-stack/
187
+ ├── bin/
188
+ │ └── cli.js ← CLI entry point and interview logic
189
+ ├── src/
190
+ │ └── generators/
191
+ │ ├── backend.js ← generates all backend files
192
+ │ ├── frontend.js ← generates all frontend files
193
+ │ ├── database.js ← generates the .sql file
194
+ │ └── utils.js ← shared helpers (toPascal, toRoute, toCamel)
195
+ └── package.json
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Local Development
201
+
202
+ Clone the repo and link it globally to test before publishing:
203
+
204
+ ```bash
205
+ git clone https://github.com/your-username/tss-stack.git
206
+ cd tss-stack
207
+ npm install
208
+ npm link
209
+ ```
210
+
211
+ Now test it like a real user:
212
+
213
+ ```bash
214
+ tss-stack test-project
215
+ ```
216
+
217
+ When done testing:
218
+
219
+ ```bash
220
+ npm unlink -g tss-stack
221
+ ```
222
+
223
+ ---
224
+
225
+ ## Publishing a New Version
226
+
227
+ ```bash
228
+ npm version patch # bug fix: 1.0.0 → 1.0.1
229
+ npm version minor # new feature: 1.0.0 → 1.1.0
230
+ npm version major # breaking: 1.0.0 → 2.0.0
231
+
232
+ npm publish
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Roadmap
238
+
239
+ - [ ] MongoDB support
240
+ - [ ] JWT auth option alongside session auth
241
+ - [ ] Role-based access (admin / user)
242
+ - [ ] Dark mode Tailwind theme
243
+ - [ ] `--yes` flag to skip prompts with defaults
244
+
245
+ ---
246
+
247
+ ## Author
248
+
249
+ **Mugisha Brian**
250
+ - GitHub: [Kevin](https://github.com/mugishabrian202-rgb/tss-stack.git)
251
+ - npm: [tss-stack](https://npmjs.com/package/tss-stack)
252
+
253
+ ---
254
+
255
+ ## License
256
+
257
+ ISC © Mugisha Brian
package/bin/cli.js CHANGED
@@ -100,19 +100,36 @@ function validatePort(value) {
100
100
  return true;
101
101
  }
102
102
 
103
- function validateFields(fields) {
104
- if (!fields || fields.trim() === "") return "At least one field is required.";
105
- const parsed = fields.split(",").map((f) => f.trim()).filter(Boolean);
106
- if (parsed.length === 0) return "At least one field is required.";
107
- if (parsed.length > 50) return "Maximum 50 fields per table allowed.";
103
+ function validateFields(value) {
104
+ const raw = Array.isArray(value) ? value.join(",") : String(value ?? "");
105
+
106
+ if (raw.trim() === "") {
107
+ return "At least one field is required.";
108
+ }
109
+
110
+ const parsed = raw
111
+ .split(",")
112
+ .map((f) => f.trim())
113
+ .filter(Boolean);
114
+
115
+ if (parsed.length === 0) {
116
+ return "At least one field is required.";
117
+ }
118
+
119
+ if (parsed.length > 50) {
120
+ return "Maximum 50 fields per table allowed.";
121
+ }
122
+
108
123
  const invalid = parsed.find((field) => {
109
124
  if (!/^[a-z][a-z0-9_]*$/.test(field)) return true;
110
125
  const reserved = ["id", "created_at", "updated_at"];
111
126
  return reserved.includes(field.toLowerCase());
112
127
  });
128
+
113
129
  if (invalid) {
114
130
  return `Invalid field name "${invalid}". Use lowercase snake_case starting with a letter.`;
115
131
  }
132
+
116
133
  return true;
117
134
  }
118
135
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tss-stack",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Interactive full-stack Node.js + React + MySQL project generator",
5
5
  "bin": {
6
6
  "tss-stack": "bin/cli.js"
@@ -25,7 +25,12 @@
25
25
  "mysql",
26
26
  "scaffold"
27
27
  ],
28
- "author": "Mugisha Brian",
28
+ "author": "mugishabrian202-rgb",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/mugishabrian202-rgb/tss-stack.git"
32
+ },
33
+ "homepage": "https://github.com/mugishabrian202-rgb/tss-stack#readme",
29
34
  "license": "ISC",
30
35
  "type": "commonjs"
31
36
  }