create-sprint 0.0.6 → 0.0.8

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.
@@ -1,13 +1,13 @@
1
1
  export function getTypeScriptPackageJson(name, telemetry) {
2
2
  const deps = {
3
- "sprint-es": "^0.0.24",
3
+ "sprint-es": "^0.0.28",
4
+ "sprint": "^0.0.1",
4
5
  dotenv: "^17.0.0",
5
6
  };
6
7
  const devDeps = {
7
8
  "@types/node": "^22.0.0",
8
9
  "tsx": "^4.19.0",
9
10
  typescript: "^5.6.0",
10
- vite: "^6.0.0",
11
11
  };
12
12
  if (telemetry === "sentry" || telemetry === "glitchtip") {
13
13
  deps["@sentry/node"] = "^8.0.0";
@@ -21,9 +21,9 @@ export function getTypeScriptPackageJson(name, telemetry) {
21
21
  description: "Sprint API",
22
22
  main: "dist/index.js",
23
23
  scripts: {
24
- build: "vite build",
25
- start: "NODE_ENV=production node dist/index.js",
26
- dev: "NODE_ENV=development tsx src/index.ts",
24
+ build: "sprint build",
25
+ start: "sprint start",
26
+ dev: "sprint dev",
27
27
  },
28
28
  dependencies: deps,
29
29
  devDependencies: devDeps,
@@ -31,7 +31,8 @@ export function getTypeScriptPackageJson(name, telemetry) {
31
31
  }
32
32
  export function getJavaScriptPackageJson(name, telemetry) {
33
33
  const deps = {
34
- "sprint-es": "^0.0.24",
34
+ "sprint-es": "^0.0.28",
35
+ "sprint": "^0.0.1",
35
36
  dotenv: "^17.0.0",
36
37
  };
37
38
  if (telemetry === "sentry" || telemetry === "glitchtip") {
@@ -47,8 +48,9 @@ export function getJavaScriptPackageJson(name, telemetry) {
47
48
  main: "src/index.js",
48
49
  type: "module",
49
50
  scripts: {
50
- start: "NODE_ENV=production node src/index.js",
51
- dev: "NODE_ENV=development node --watch src/index.js",
51
+ build: "sprint build",
52
+ start: "sprint start",
53
+ dev: "sprint dev",
52
54
  },
53
55
  dependencies: deps,
54
56
  };
@@ -71,6 +73,10 @@ export function getTsConfig() {
71
73
  declarationMap: true,
72
74
  sourceMap: true,
73
75
  tabWidth: 4,
76
+ baseUrl: ".",
77
+ paths: {
78
+ "@/*": ["./src/*"]
79
+ }
74
80
  },
75
81
  include: ["src/**/*"],
76
82
  exclude: ["node_modules", "dist"],
@@ -104,51 +110,235 @@ export default defineConfig({
104
110
  export function getMainFile(language) {
105
111
  if (language === "typescript") {
106
112
  return `import Sprint from "sprint-es";
107
- import { config } from "./sprint.config";
108
- import homeRouter from "./routes/home";
109
113
 
110
- const app = new Sprint(config);
111
-
112
- app.use(homeRouter);
114
+ const app = new Sprint();
113
115
  `;
114
116
  }
115
117
  return `import Sprint from "sprint-es";
116
- import { config } from "./sprint.config.js";
117
- import homeRouter from "./routes/home.js";
118
-
119
- const app = new Sprint(config);
120
118
 
121
- app.use(homeRouter);
119
+ const app = new Sprint();
122
120
  `;
123
121
  }
124
122
  export function getHomeRoute(language) {
125
123
  if (language === "typescript") {
126
124
  return `import { Router } from "sprint-es";
125
+ import { homeSchema } from "@/schemas/home";
126
+ import { homeController } from "@/controllers/home";
127
127
 
128
128
  const router = Router();
129
129
 
130
- router.get("/", (req, res) => {
131
- res.json({
132
- message: "Hello World",
133
- status: "ok"
134
- });
135
- });
130
+ router.get("/", homeSchema, homeController);
131
+
132
+ export default router;
133
+ `;
134
+ }
135
+ return `import { Router } from "sprint-es";
136
+ import { homeSchema } from "../schemas/home.js";
137
+ import { homeController } from "../controllers/home.js";
138
+
139
+ const router = Router();
140
+
141
+ router.get("/", homeSchema, homeController);
142
+
143
+ export default router;
144
+ `;
145
+ }
146
+ export function getAdminRoute(language) {
147
+ if (language === "typescript") {
148
+ return `import { Router } from "sprint-es";
149
+ import { adminSchema } from "@/schemas/admin";
150
+ import { adminController, adminUsersController } from "@/controllers/admin";
151
+
152
+ const router = Router();
153
+
154
+ router.get("/", adminSchema, adminController);
155
+ router.get("/users", adminSchema, adminUsersController);
136
156
 
137
157
  export default router;
138
158
  `;
139
159
  }
140
160
  return `import { Router } from "sprint-es";
161
+ import { adminSchema } from "../schemas/admin.js";
162
+ import { adminController, adminUsersController } from "../controllers/admin.js";
141
163
 
142
164
  const router = Router();
143
165
 
144
- router.get("/", (req, res) => {
166
+ router.get("/", adminSchema, adminController);
167
+ router.get("/users", adminSchema, adminUsersController);
168
+
169
+ export default router;
170
+ `;
171
+ }
172
+ export function getHomeController(language) {
173
+ if (language === "typescript") {
174
+ return `import { Handler } from "sprint-es";
175
+
176
+ export const homeController: Handler = (req, res) => {
145
177
  res.json({
146
178
  message: "Hello World",
147
179
  status: "ok"
148
180
  });
181
+ };
182
+ `;
183
+ }
184
+ return `import { Handler } from "sprint-es";
185
+
186
+ export const homeController = (req, res) => {
187
+ res.json({
188
+ message: "Hello World",
189
+ status: "ok"
190
+ });
191
+ };
192
+ `;
193
+ }
194
+ export function getAdminController(language) {
195
+ if (language === "typescript") {
196
+ return `import { Handler } from "sprint-es";
197
+
198
+ export const adminController: Handler = (req, res) => {
199
+ res.json({
200
+ message: "Admin Dashboard",
201
+ status: "ok"
202
+ });
203
+ };
204
+
205
+ export const adminUsersController: Handler = (req, res) => {
206
+ res.json({
207
+ users: [
208
+ { id: 1, name: "John Doe", role: "admin" },
209
+ { id: 2, name: "Jane Smith", role: "user" }
210
+ ]
211
+ });
212
+ };
213
+ `;
214
+ }
215
+ return `import { Handler } from "sprint-es";
216
+
217
+ export const adminController = (req, res) => {
218
+ res.json({
219
+ message: "Admin Dashboard",
220
+ status: "ok"
221
+ });
222
+ };
223
+
224
+ export const adminUsersController = (req, res) => {
225
+ res.json({
226
+ users: [
227
+ { id: 1, name: "John Doe", role: "admin" },
228
+ { id: 2, name: "Jane Smith", role: "user" }
229
+ ]
230
+ });
231
+ };
232
+ `;
233
+ }
234
+ export function getHomeSchema(language) {
235
+ if (language === "typescript") {
236
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
237
+
238
+ export const homeSchema = defineRouteSchema({
239
+ input: z.object({
240
+ message: z.string(),
241
+ status: z.string()
242
+ })
149
243
  });
244
+ `;
245
+ }
246
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
150
247
 
151
- export default router;
248
+ export const homeSchema = defineRouteSchema({
249
+ input: z.object({
250
+ message: z.string(),
251
+ status: z.string()
252
+ })
253
+ });
254
+ `;
255
+ }
256
+ export function getAdminSchema(language) {
257
+ if (language === "typescript") {
258
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
259
+
260
+ export const adminSchema = defineRouteSchema({
261
+ params: z.object({
262
+ id: z.string().uuid()
263
+ }),
264
+ body: z.object({
265
+ name: z.string().min(1),
266
+ email: z.email().optional()
267
+ }),
268
+ input: z.object({
269
+ id: z.string().uuid(),
270
+ name: z.string(),
271
+ email: z.string().email().optional()
272
+ })
273
+ });
274
+ `;
275
+ }
276
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
277
+
278
+ export const adminSchema = defineRouteSchema({
279
+ params: z.object({
280
+ id: z.string().uuid()
281
+ }),
282
+ body: z.object({
283
+ name: z.string().min(1),
284
+ email: z.email().optional()
285
+ }),
286
+ input: z.object({
287
+ id: z.string().uuid(),
288
+ name: z.string(),
289
+ email: z.string().email().optional()
290
+ })
291
+ });
292
+ `;
293
+ }
294
+ export function getAuthMiddleware(language) {
295
+ if (language === "typescript") {
296
+ return `import { defineMiddleware } from "sprint-es";
297
+
298
+ export default defineMiddleware({
299
+ name: "auth",
300
+ priority: 10,
301
+ include: "/admin/**",
302
+ handler: (req, res, next) => {
303
+ const authHeader = req.headers.authorization;
304
+
305
+ if (!authHeader) {
306
+ return res.status(401).json({ error: "No authorization header" });
307
+ }
308
+
309
+ const token = authHeader.replace("Bearer ", "");
310
+
311
+ if (token !== "admin-token") {
312
+ return res.status(403).json({ error: "Invalid token" });
313
+ }
314
+
315
+ next();
316
+ }
317
+ });
318
+ `;
319
+ }
320
+ return `import { defineMiddleware } from "sprint-es";
321
+
322
+ export default defineMiddleware({
323
+ name: "auth",
324
+ priority: 10,
325
+ include: "/admin/**",
326
+ handler: (req, res, next) => {
327
+ const authHeader = req.headers.authorization;
328
+
329
+ if (!authHeader) {
330
+ return res.status(401).json({ error: "No authorization header" });
331
+ }
332
+
333
+ const token = authHeader.replace("Bearer ", "");
334
+
335
+ if (token !== "admin-token") {
336
+ return res.status(403).json({ error: "Invalid token" });
337
+ }
338
+
339
+ next();
340
+ }
341
+ });
152
342
  `;
153
343
  }
154
344
  export function getDockerfile(language) {
@@ -266,6 +456,11 @@ export const config: SprintOptions = {
266
456
  port: process.env.PORT ? parseInt(process.env.PORT) : 3000
267
457
  };
268
458
 
459
+ // Add Vite config here if needed
460
+ // export const vite = {
461
+ // build: { ... }
462
+ // };
463
+
269
464
  `;
270
465
  if (telemetry === "sentry" || telemetry === "glitchtip") {
271
466
  config += `import { initTelemetry } from "sprint-es/telemetry";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { mkdir, writeFile } from "fs/promises";
4
4
  import { join } from "path";
5
5
  import { input, select, confirm } from "@inquirer/prompts";
6
6
  import { validateProjectName } from "./validators.js";
7
- import { getTypeScriptPackageJson, getJavaScriptPackageJson, getTsConfig, getViteConfig, getMainFile, getHomeRoute, getDockerfile, getDockerCompose, getGitignore, getDockerIgnore, getSprintConfigFile, getEnvExample, getEnvDevelopment, getEnvProduction } from "./generators.js";
7
+ import { getTypeScriptPackageJson, getJavaScriptPackageJson, getTsConfig, getViteConfig, getMainFile, getHomeRoute, getAdminRoute, getHomeController, getAdminController, getAuthMiddleware, getHomeSchema, getAdminSchema, getDockerfile, getDockerCompose, getGitignore, getDockerIgnore, getSprintConfigFile, getEnvDevelopment, getEnvProduction } from "./generators.js";
8
8
  export async function runCLI(args) {
9
9
  const options = parseArgs(args);
10
10
  console.log("\n🚀 Welcome to Sprint - Quickly API Framework\n");
@@ -30,7 +30,7 @@ export async function runCLI(args) {
30
30
  if (options.skipInstall) {
31
31
  installDeps = false;
32
32
  }
33
- else if (!options.skipPrompts) {
33
+ else {
34
34
  installDeps = await confirm({
35
35
  message: "Do you want to install dependencies now?",
36
36
  default: true,
@@ -63,13 +63,17 @@ function parseArgs(args) {
63
63
  const telemetryArg = args.includes("--telemetry") ? args[args.indexOf("--telemetry") + 1] : null;
64
64
  if (args.includes("--yes") || args.includes("-y")) {
65
65
  options.skipPrompts = true;
66
- options.language = "typescript";
67
66
  }
68
- else if (hasTs) {
69
- options.language = "typescript";
67
+ if (!options.skipPrompts) {
68
+ if (hasTs) {
69
+ options.language = "typescript";
70
+ }
71
+ else if (hasJs) {
72
+ options.language = "javascript";
73
+ }
70
74
  }
71
- else if (hasJs) {
72
- options.language = "javascript";
75
+ else {
76
+ options.language = "typescript";
73
77
  }
74
78
  if (hasName !== -1 && args[hasName + 1]) {
75
79
  options.projectName = args[hasName + 1];
@@ -185,13 +189,20 @@ async function createProject(projectName, language, telemetryArg, useDockerArg)
185
189
  await mkdir(join(srcDir, "middlewares"), { recursive: true });
186
190
  await mkdir(join(srcDir, "routes"), { recursive: true });
187
191
  await mkdir(join(srcDir, "controllers"), { recursive: true });
192
+ await mkdir(join(srcDir, "schemas"), { recursive: true });
188
193
  await writeFile(join(srcDir, "middlewares", ".gitkeep"), "");
189
- await writeFile(join(srcDir, "controllers", ".gitkeep"), "");
190
194
  await writeFile(join(srcDir, "app." + (language === "typescript" ? "ts" : "js")), getMainFile(language));
191
195
  await writeFile(join(srcDir, "routes", "home." + (language === "typescript" ? "ts" : "js")), getHomeRoute(language));
192
- await writeFile(join(targetDir, ".env.example"), getEnvExample(telemetry));
193
- await writeFile(join(targetDir, ".env.development"), getEnvDevelopment(telemetry));
194
- await writeFile(join(targetDir, ".env.production"), getEnvProduction(telemetry));
196
+ await writeFile(join(srcDir, "routes", "admin." + (language === "typescript" ? "ts" : "js")), getAdminRoute(language));
197
+ await writeFile(join(srcDir, "controllers", "home." + (language === "typescript" ? "ts" : "js")), getHomeController(language));
198
+ await writeFile(join(srcDir, "controllers", "admin." + (language === "typescript" ? "ts" : "js")), getAdminController(language));
199
+ await writeFile(join(srcDir, "middlewares", "auth." + (language === "typescript" ? "ts" : "js")), getAuthMiddleware(language));
200
+ await writeFile(join(srcDir, "schemas", "home." + (language === "typescript" ? "ts" : "js")), getHomeSchema(language));
201
+ await writeFile(join(srcDir, "schemas", "admin." + (language === "typescript" ? "ts" : "js")), getAdminSchema(language));
202
+ await writeFile(join(targetDir, ".env.development.example"), getEnvDevelopment(telemetry));
203
+ await writeFile(join(targetDir, ".env.production.example"), getEnvProduction(telemetry));
204
+ await writeFile(join(targetDir, ".env.development"), "");
205
+ await writeFile(join(targetDir, ".env.production"), "");
195
206
  await writeFile(join(targetDir, ".gitignore"), getGitignore());
196
207
  if (useDocker) {
197
208
  await writeFile(join(targetDir, "Dockerfile"), getDockerfile(language));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sprint",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Create a new Sprint API project",
5
5
  "type": "module",
6
6
  "bin": {
package/src/generators.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export function getTypeScriptPackageJson(name: string, telemetry: string) {
2
2
  const deps: Record<string, string> = {
3
- "sprint-es": "^0.0.24",
3
+ "sprint-es": "^0.0.28",
4
+ "sprint": "^0.0.1",
4
5
  dotenv: "^17.0.0",
5
6
  };
6
7
 
@@ -8,7 +9,6 @@ export function getTypeScriptPackageJson(name: string, telemetry: string) {
8
9
  "@types/node": "^22.0.0",
9
10
  "tsx": "^4.19.0",
10
11
  typescript: "^5.6.0",
11
- vite: "^6.0.0",
12
12
  };
13
13
 
14
14
  if (telemetry === "sentry" || telemetry === "glitchtip") {
@@ -23,9 +23,9 @@ export function getTypeScriptPackageJson(name: string, telemetry: string) {
23
23
  description: "Sprint API",
24
24
  main: "dist/index.js",
25
25
  scripts: {
26
- build: "vite build",
27
- start: "NODE_ENV=production node dist/index.js",
28
- dev: "NODE_ENV=development tsx src/index.ts",
26
+ build: "sprint build",
27
+ start: "sprint start",
28
+ dev: "sprint dev",
29
29
  },
30
30
  dependencies: deps,
31
31
  devDependencies: devDeps,
@@ -34,7 +34,8 @@ export function getTypeScriptPackageJson(name: string, telemetry: string) {
34
34
 
35
35
  export function getJavaScriptPackageJson(name: string, telemetry: string) {
36
36
  const deps: Record<string, string> = {
37
- "sprint-es": "^0.0.24",
37
+ "sprint-es": "^0.0.28",
38
+ "sprint": "^0.0.1",
38
39
  dotenv: "^17.0.0",
39
40
  };
40
41
 
@@ -51,8 +52,9 @@ export function getJavaScriptPackageJson(name: string, telemetry: string) {
51
52
  main: "src/index.js",
52
53
  type: "module",
53
54
  scripts: {
54
- start: "NODE_ENV=production node src/index.js",
55
- dev: "NODE_ENV=development node --watch src/index.js",
55
+ build: "sprint build",
56
+ start: "sprint start",
57
+ dev: "sprint dev",
56
58
  },
57
59
  dependencies: deps,
58
60
  };
@@ -76,6 +78,10 @@ export function getTsConfig() {
76
78
  declarationMap: true,
77
79
  sourceMap: true,
78
80
  tabWidth: 4,
81
+ baseUrl: ".",
82
+ paths: {
83
+ "@/*": ["./src/*"]
84
+ }
79
85
  },
80
86
  include: ["src/**/*"],
81
87
  exclude: ["node_modules", "dist"],
@@ -111,53 +117,243 @@ export default defineConfig({
111
117
  export function getMainFile(language: string) {
112
118
  if (language === "typescript") {
113
119
  return `import Sprint from "sprint-es";
114
- import { config } from "./sprint.config";
115
- import homeRouter from "./routes/home";
116
120
 
117
- const app = new Sprint(config);
118
-
119
- app.use(homeRouter);
121
+ const app = new Sprint();
120
122
  `;
121
123
  }
122
124
 
123
125
  return `import Sprint from "sprint-es";
124
- import { config } from "./sprint.config.js";
125
- import homeRouter from "./routes/home.js";
126
-
127
- const app = new Sprint(config);
128
126
 
129
- app.use(homeRouter);
127
+ const app = new Sprint();
130
128
  `;
131
129
  }
132
130
 
133
131
  export function getHomeRoute(language: string) {
134
132
  if (language === "typescript") {
135
133
  return `import { Router } from "sprint-es";
134
+ import { homeSchema } from "@/schemas/home";
135
+ import { homeController } from "@/controllers/home";
136
136
 
137
137
  const router = Router();
138
138
 
139
- router.get("/", (req, res) => {
140
- res.json({
141
- message: "Hello World",
142
- status: "ok"
143
- });
144
- });
139
+ router.get("/", homeSchema, homeController);
145
140
 
146
141
  export default router;
147
142
  `;
148
143
  }
149
144
  return `import { Router } from "sprint-es";
145
+ import { homeSchema } from "../schemas/home.js";
146
+ import { homeController } from "../controllers/home.js";
150
147
 
151
148
  const router = Router();
152
149
 
153
- router.get("/", (req, res) => {
150
+ router.get("/", homeSchema, homeController);
151
+
152
+ export default router;
153
+ `;
154
+ }
155
+
156
+ export function getAdminRoute(language: string) {
157
+ if (language === "typescript") {
158
+ return `import { Router } from "sprint-es";
159
+ import { adminSchema } from "@/schemas/admin";
160
+ import { adminController, adminUsersController } from "@/controllers/admin";
161
+
162
+ const router = Router();
163
+
164
+ router.get("/", adminSchema, adminController);
165
+ router.get("/users", adminSchema, adminUsersController);
166
+
167
+ export default router;
168
+ `;
169
+ }
170
+ return `import { Router } from "sprint-es";
171
+ import { adminSchema } from "../schemas/admin.js";
172
+ import { adminController, adminUsersController } from "../controllers/admin.js";
173
+
174
+ const router = Router();
175
+
176
+ router.get("/", adminSchema, adminController);
177
+ router.get("/users", adminSchema, adminUsersController);
178
+
179
+ export default router;
180
+ `;
181
+ }
182
+
183
+ export function getHomeController(language: string) {
184
+ if (language === "typescript") {
185
+ return `import { Handler } from "sprint-es";
186
+
187
+ export const homeController: Handler = (req, res) => {
188
+ res.json({
189
+ message: "Hello World",
190
+ status: "ok"
191
+ });
192
+ };
193
+ `;
194
+ }
195
+ return `import { Handler } from "sprint-es";
196
+
197
+ export const homeController = (req, res) => {
154
198
  res.json({
155
199
  message: "Hello World",
156
200
  status: "ok"
157
201
  });
202
+ };
203
+ `;
204
+ }
205
+
206
+ export function getAdminController(language: string) {
207
+ if (language === "typescript") {
208
+ return `import { Handler } from "sprint-es";
209
+
210
+ export const adminController: Handler = (req, res) => {
211
+ res.json({
212
+ message: "Admin Dashboard",
213
+ status: "ok"
214
+ });
215
+ };
216
+
217
+ export const adminUsersController: Handler = (req, res) => {
218
+ res.json({
219
+ users: [
220
+ { id: 1, name: "John Doe", role: "admin" },
221
+ { id: 2, name: "Jane Smith", role: "user" }
222
+ ]
223
+ });
224
+ };
225
+ `;
226
+ }
227
+ return `import { Handler } from "sprint-es";
228
+
229
+ export const adminController = (req, res) => {
230
+ res.json({
231
+ message: "Admin Dashboard",
232
+ status: "ok"
233
+ });
234
+ };
235
+
236
+ export const adminUsersController = (req, res) => {
237
+ res.json({
238
+ users: [
239
+ { id: 1, name: "John Doe", role: "admin" },
240
+ { id: 2, name: "Jane Smith", role: "user" }
241
+ ]
242
+ });
243
+ };
244
+ `;
245
+ }
246
+
247
+ export function getHomeSchema(language: string) {
248
+ if (language === "typescript") {
249
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
250
+
251
+ export const homeSchema = defineRouteSchema({
252
+ input: z.object({
253
+ message: z.string(),
254
+ status: z.string()
255
+ })
158
256
  });
257
+ `;
258
+ }
259
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
159
260
 
160
- export default router;
261
+ export const homeSchema = defineRouteSchema({
262
+ input: z.object({
263
+ message: z.string(),
264
+ status: z.string()
265
+ })
266
+ });
267
+ `;
268
+ }
269
+
270
+ export function getAdminSchema(language: string) {
271
+ if (language === "typescript") {
272
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
273
+
274
+ export const adminSchema = defineRouteSchema({
275
+ params: z.object({
276
+ id: z.string().uuid()
277
+ }),
278
+ body: z.object({
279
+ name: z.string().min(1),
280
+ email: z.email().optional()
281
+ }),
282
+ input: z.object({
283
+ id: z.string().uuid(),
284
+ name: z.string(),
285
+ email: z.string().email().optional()
286
+ })
287
+ });
288
+ `;
289
+ }
290
+ return `import { z, defineRouteSchema } from "sprint-es/schemas";
291
+
292
+ export const adminSchema = defineRouteSchema({
293
+ params: z.object({
294
+ id: z.string().uuid()
295
+ }),
296
+ body: z.object({
297
+ name: z.string().min(1),
298
+ email: z.email().optional()
299
+ }),
300
+ input: z.object({
301
+ id: z.string().uuid(),
302
+ name: z.string(),
303
+ email: z.string().email().optional()
304
+ })
305
+ });
306
+ `;
307
+ }
308
+
309
+ export function getAuthMiddleware(language: string) {
310
+ if (language === "typescript") {
311
+ return `import { defineMiddleware } from "sprint-es";
312
+
313
+ export default defineMiddleware({
314
+ name: "auth",
315
+ priority: 10,
316
+ include: "/admin/**",
317
+ handler: (req, res, next) => {
318
+ const authHeader = req.headers.authorization;
319
+
320
+ if (!authHeader) {
321
+ return res.status(401).json({ error: "No authorization header" });
322
+ }
323
+
324
+ const token = authHeader.replace("Bearer ", "");
325
+
326
+ if (token !== "admin-token") {
327
+ return res.status(403).json({ error: "Invalid token" });
328
+ }
329
+
330
+ next();
331
+ }
332
+ });
333
+ `;
334
+ }
335
+ return `import { defineMiddleware } from "sprint-es";
336
+
337
+ export default defineMiddleware({
338
+ name: "auth",
339
+ priority: 10,
340
+ include: "/admin/**",
341
+ handler: (req, res, next) => {
342
+ const authHeader = req.headers.authorization;
343
+
344
+ if (!authHeader) {
345
+ return res.status(401).json({ error: "No authorization header" });
346
+ }
347
+
348
+ const token = authHeader.replace("Bearer ", "");
349
+
350
+ if (token !== "admin-token") {
351
+ return res.status(403).json({ error: "Invalid token" });
352
+ }
353
+
354
+ next();
355
+ }
356
+ });
161
357
  `;
162
358
  }
163
359
 
@@ -280,6 +476,11 @@ export const config: SprintOptions = {
280
476
  port: process.env.PORT ? parseInt(process.env.PORT) : 3000
281
477
  };
282
478
 
479
+ // Add Vite config here if needed
480
+ // export const vite = {
481
+ // build: { ... }
482
+ // };
483
+
283
484
  `;
284
485
 
285
486
  if (telemetry === "sentry" || telemetry === "glitchtip") {
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ import { mkdir, writeFile } from "fs/promises";
4
4
  import { join } from "path";
5
5
  import { input, select, confirm } from "@inquirer/prompts";
6
6
  import { validateProjectName } from "./validators.js";
7
- import { getTypeScriptPackageJson, getJavaScriptPackageJson, getTsConfig, getViteConfig, getMainFile, getHomeRoute, getDockerfile, getDockerCompose, getGitignore, getDockerIgnore, getSprintConfigFile, getEnvExample, getEnvDevelopment, getEnvProduction } from "./generators.js";
7
+ import { getTypeScriptPackageJson, getJavaScriptPackageJson, getTsConfig, getViteConfig, getMainFile, getHomeRoute, getAdminRoute, getHomeController, getAdminController, getAuthMiddleware, getHomeSchema, getAdminSchema, getDockerfile, getDockerCompose, getGitignore, getDockerIgnore, getSprintConfigFile, getEnvDevelopment, getEnvProduction } from "./generators.js";
8
8
 
9
9
  export interface CLIOptions {
10
10
  projectName?: string;
@@ -48,7 +48,7 @@ export async function runCLI(args: string[]) {
48
48
  let installDeps = true;
49
49
  if (options.skipInstall) {
50
50
  installDeps = false;
51
- } else if (!options.skipPrompts) {
51
+ } else {
52
52
  installDeps = await confirm({
53
53
  message: "Do you want to install dependencies now?",
54
54
  default: true,
@@ -85,11 +85,16 @@ function parseArgs(args: string[]): CLIOptions {
85
85
 
86
86
  if (args.includes("--yes") || args.includes("-y")) {
87
87
  options.skipPrompts = true;
88
+ }
89
+
90
+ if (!options.skipPrompts) {
91
+ if (hasTs) {
92
+ options.language = "typescript";
93
+ } else if (hasJs) {
94
+ options.language = "javascript";
95
+ }
96
+ } else {
88
97
  options.language = "typescript";
89
- } else if (hasTs) {
90
- options.language = "typescript";
91
- } else if (hasJs) {
92
- options.language = "javascript";
93
98
  }
94
99
 
95
100
  if (hasName !== -1 && args[hasName + 1]) {
@@ -230,17 +235,28 @@ async function createProject(
230
235
  await mkdir(join(srcDir, "middlewares"), { recursive: true });
231
236
  await mkdir(join(srcDir, "routes"), { recursive: true });
232
237
  await mkdir(join(srcDir, "controllers"), { recursive: true });
238
+ await mkdir(join(srcDir, "schemas"), { recursive: true });
233
239
 
234
240
  await writeFile(join(srcDir, "middlewares", ".gitkeep"), "");
235
- await writeFile(join(srcDir, "controllers", ".gitkeep"), "");
236
241
 
237
242
  await writeFile(join(srcDir, "app." + (language === "typescript" ? "ts" : "js")), getMainFile(language));
238
243
 
239
244
  await writeFile(join(srcDir, "routes", "home." + (language === "typescript" ? "ts" : "js")), getHomeRoute(language));
245
+ await writeFile(join(srcDir, "routes", "admin." + (language === "typescript" ? "ts" : "js")), getAdminRoute(language));
246
+
247
+ await writeFile(join(srcDir, "controllers", "home." + (language === "typescript" ? "ts" : "js")), getHomeController(language));
248
+ await writeFile(join(srcDir, "controllers", "admin." + (language === "typescript" ? "ts" : "js")), getAdminController(language));
249
+
250
+ await writeFile(join(srcDir, "middlewares", "auth." + (language === "typescript" ? "ts" : "js")), getAuthMiddleware(language));
251
+
252
+ await writeFile(join(srcDir, "schemas", "home." + (language === "typescript" ? "ts" : "js")), getHomeSchema(language));
253
+ await writeFile(join(srcDir, "schemas", "admin." + (language === "typescript" ? "ts" : "js")), getAdminSchema(language));
254
+
255
+ await writeFile(join(targetDir, ".env.development.example"), getEnvDevelopment(telemetry));
256
+ await writeFile(join(targetDir, ".env.production.example"), getEnvProduction(telemetry));
240
257
 
241
- await writeFile(join(targetDir, ".env.example"), getEnvExample(telemetry));
242
- await writeFile(join(targetDir, ".env.development"), getEnvDevelopment(telemetry));
243
- await writeFile(join(targetDir, ".env.production"), getEnvProduction(telemetry));
258
+ await writeFile(join(targetDir, ".env.development"), "");
259
+ await writeFile(join(targetDir, ".env.production"), "");
244
260
 
245
261
  await writeFile(join(targetDir, ".gitignore"), getGitignore());
246
262