create-sprint 0.0.62 → 0.0.64

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,704 +1,2 @@
1
- import * as crypto from "node:crypto";
2
- export function generateJWTKeys() {
3
- const keys = crypto.generateKeyPairSync("rsa", {
4
- modulusLength: 4096,
5
- publicKeyEncoding: { type: "spki", format: "pem" },
6
- privateKeyEncoding: { type: "pkcs8", format: "pem" }
7
- });
8
- return keys;
9
- }
10
- export function getTypeScriptPackageJson(name, telemetry) {
11
- const deps = {
12
- "sprint-es": "^0.0.54"
13
- };
14
- const devDeps = {
15
- "@types/node": "^22.0.0",
16
- "tsx": "^4.19.0",
17
- typescript: "^5.6.0",
18
- };
19
- if (telemetry === "sentry" || telemetry === "glitchtip") {
20
- deps["@sentry/node"] = "^8.0.0";
21
- }
22
- else if (telemetry === "discord") {
23
- deps["axios"] = "^1.6.0";
24
- }
25
- return {
26
- name: name === "." ? "sprint-app" : name,
27
- version: "0.0.1",
28
- description: "Sprint API",
29
- main: "dist/index.js",
30
- scripts: {
31
- build: "sprint-es build",
32
- start: "sprint-es start",
33
- dev: "sprint-es dev",
34
- "generate:keys": "sprint-es generate-keys"
35
- },
36
- dependencies: deps,
37
- devDependencies: devDeps,
38
- };
39
- }
40
- export function getJavaScriptPackageJson(name, telemetry) {
41
- const deps = {
42
- "sprint-es": "^0.0.54"
43
- };
44
- if (telemetry === "sentry" || telemetry === "glitchtip") {
45
- deps["@sentry/node"] = "^8.0.0";
46
- }
47
- else if (telemetry === "discord") {
48
- deps["axios"] = "^1.6.0";
49
- }
50
- return {
51
- name: name === "." ? "sprint-app" : name,
52
- version: "0.0.1",
53
- description: "Sprint API",
54
- main: "src/index.js",
55
- type: "module",
56
- scripts: {
57
- build: "sprint-es build",
58
- start: "sprint-es start",
59
- dev: "sprint-es dev",
60
- "generate:keys": "sprint-es generate-keys"
61
- },
62
- dependencies: deps
63
- };
64
- }
65
- export function getTsConfig() {
66
- return JSON.stringify({
67
- compilerOptions: {
68
- target: "ES2022",
69
- module: "NodeNext",
70
- moduleResolution: "NodeNext",
71
- lib: ["ES2022"],
72
- types: ["node"],
73
- outDir: "./dist",
74
- rootDir: "./src",
75
- strict: true,
76
- esModuleInterop: true,
77
- skipLibCheck: true,
78
- forceConsistentCasingInFileNames: true,
79
- resolveJsonModule: true,
80
- declaration: true,
81
- declarationMap: true,
82
- sourceMap: true,
83
- baseUrl: ".",
84
- paths: {
85
- "@/*": ["./src/*"]
86
- }
87
- },
88
- include: ["src/**/*"],
89
- exclude: ["node_modules", "dist"],
90
- }, null, 2);
91
- }
92
- export function getViteConfig() {
93
- return `import { defineConfig } from "vite";
94
- import { resolve } from "path";
95
-
96
- export default defineConfig({
97
- build: {
98
- lib: {
99
- entry: resolve(__dirname, "src/index.ts"),
100
- formats: ["es"],
101
- fileName: "index",
102
- },
103
- outDir: "dist",
104
- rollupOptions: {
105
- external: ["sprint-es", "express", "cors", "morgan", "serve-favicon", "dotenv"],
106
- },
107
- target: "ES2020",
108
- },
109
- resolve: {
110
- alias: {
111
- "@": resolve(__dirname, "src"),
112
- },
113
- },
114
- });
115
- `;
116
- }
117
- export function getMainFile(language) {
118
- if (language === "typescript") {
119
- return `import Sprint from "sprint-es";
120
-
121
- const app = new Sprint();
122
- `;
123
- }
124
- return `import Sprint from "sprint-es";
125
-
126
- const app = new Sprint();
127
- `;
128
- }
129
- export function getHomeRoute(language) {
130
- if (language === "typescript") {
131
- return `import { Router } from "sprint-es";
132
- import { homeSchema } from "@/schemas/home";
133
- import { homeController, jwtValidateController } from "@/controllers/home";
134
-
135
- const router = Router();
136
-
137
- router.get("/", homeSchema, homeController);
138
- router.post("/me", jwtValidateController);
139
-
140
- export default router;
141
- `;
142
- }
143
- return `import { Router } from "sprint-es";
144
- import { homeSchema } from "../schemas/home.js";
145
- import { homeController, jwtValidateController } from "../controllers/home.js";
146
-
147
- const router = Router();
148
-
149
- router.get("/", homeSchema, homeController);
150
- router.post("/me", jwtValidateController);
151
-
152
- export default router;
153
- `;
154
- }
155
- export function getAdminRoute(language) {
156
- if (language === "typescript") {
157
- return `import { Router } from "sprint-es";
158
- import { adminSchema, jwtGenerateSchema } from "@/schemas/admin";
159
- import { adminController, adminUsersController, jwtGenerateController } from "@/controllers/admin";
160
-
161
- const router = Router();
162
-
163
- router.get("/", adminSchema, adminController);
164
- router.get("/users", adminSchema, adminUsersController);
165
- router.post("/jwt/generate", jwtGenerateSchema, jwtGenerateController);
166
-
167
- export default router;
168
- `;
169
- }
170
- return `import { Router } from "sprint-es";
171
- import { adminSchema, jwtGenerateSchema } from "../schemas/admin.js";
172
- import { adminController, adminUsersController, jwtGenerateController } from "../controllers/admin.js";
173
-
174
- const router = Router();
175
-
176
- router.get("/", adminSchema, adminController);
177
- router.get("/users", adminSchema, adminUsersController);
178
- router.post("/jwt/generate", jwtGenerateSchema, jwtGenerateController);
179
-
180
- export default router;
181
- `;
182
- }
183
- export function getHomeController(language) {
184
- if (language === "typescript") {
185
- return `import { Handler, SprintRequest, SprintResponse } from "sprint-es";
186
- import { verifyEncrypted, getJwtFromEnv } from "sprint-es/jwt";
187
-
188
- export const homeController: Handler = (req: SprintRequest, res: SprintResponse) => {
189
- res.json({
190
- message: "Hello World",
191
- status: "ok"
192
- });
193
- };
194
-
195
- export const jwtValidateController: Handler = (req: SprintRequest, res: SprintResponse) => {
196
- return res.json(req.custom.user);
197
- };
198
- `;
199
- }
200
- return `import { Handler, SprintRequest, SprintResponse } from "sprint-es";
201
- import { verifyEncrypted, getJwtFromEnv } from "sprint-es/jwt";
202
-
203
- export const homeController = (req: SprintRequest, res: SprintResponse) => {
204
- res.json({
205
- message: "Hello World",
206
- status: "ok"
207
- });
208
- };
209
-
210
- export const jwtValidateController = (req: SprintRequest, res: SprintResponse) => {
211
- return res.json(req.custom.user);
212
- };
213
- `;
214
- }
215
- export function getAdminController(language) {
216
- if (language === "typescript") {
217
- return `import { Handler, SprintRequest, SprintResponse } from "sprint-es";
218
- import { signEncrypted, getJwtFromEnv } from "sprint-es/jwt";
219
-
220
- export const adminController: Handler = (req: SprintRequest, res: SprintResponse) => {
221
- res.json({
222
- message: "Admin Dashboard",
223
- status: "ok"
224
- });
225
- };
226
-
227
- export const adminUsersController: Handler = (req: SprintRequest, res: SprintResponse) => {
228
- res.json({
229
- users: [
230
- { id: 1, name: "John Doe", role: "admin" },
231
- { id: 2, name: "Jane Smith", role: "user" }
232
- ]
233
- });
234
- };
235
-
236
- const { privateKey, encryptionSecret } = getJwtFromEnv();
237
-
238
- export const jwtGenerateController: Handler = (req: SprintRequest, res: SprintResponse) => {
239
- const { userId, role } = req.body || {};
240
-
241
- try {
242
- const payload = { userId, role: role || "user" };
243
- const token = signEncrypted(payload, privateKey, encryptionSecret, { expiresIn: "1h" });
244
- res.json({ token });
245
- } catch (error) {
246
- return res.status(500).json({ error: "JWT not configured" });
247
- }
248
- };
249
- `;
250
- }
251
- else {
252
- return `import { Handler, SprintRequest, SprintResponse } from "sprint-es";
253
- import { signEncrypted, getJwtFromEnv } from "sprint-es/jwt";
254
-
255
- export const adminController = (req: SprintRequest, res: SprintResponse) => {
256
- res.json({
257
- message: "Admin Dashboard",
258
- status: "ok"
259
- });
260
- };
261
-
262
- export const adminUsersController = (req: SprintRequest, res: SprintResponse) => {
263
- res.json({
264
- users: [
265
- { id: 1, name: "John Doe", role: "admin" },
266
- { id: 2, name: "Jane Smith", role: "user" }
267
- ]
268
- });
269
- };
270
-
271
- const { privateKey, encryptionSecret } = getJwtFromEnv();
272
-
273
- export const jwtGenerateController = (req: SprintRequest, res: SprintResponse) => {
274
- const { userId, role } = req.body || {};
275
-
276
- try {
277
- const payload = { userId, role: role || "user" };
278
- const token = signEncrypted(payload, privateKey, encryptionSecret, { expiresIn: "1h" });
279
- res.json({ token });
280
- } catch (error) {
281
- return res.status(500).json({ error: "JWT not configured" });
282
- }
283
- };
284
- `;
285
- }
286
- }
287
- export function getHomeSchema(language) {
288
- if (language === "typescript") {
289
- return `import { z, defineRouteSchema } from "sprint-es/schemas";
290
-
291
- export const homeSchema = defineRouteSchema({});
292
- `;
293
- }
294
- return `import { z, defineRouteSchema } from "sprint-es/schemas";
295
-
296
- export const homeSchema = defineRouteSchema({});
297
- `;
298
- }
299
- export function getAdminSchema(language) {
300
- if (language === "typescript") {
301
- return `import { z, defineRouteSchema } from "sprint-es/schemas";
302
-
303
- export const adminSchema = defineRouteSchema({
304
- queryParams: z.object({
305
- id: z.string().uuid()
306
- }),
307
- body: z.object({
308
- name: z.string().min(1),
309
- email: z.string().email().optional()
310
- })
311
- });
312
-
313
- export const jwtGenerateSchema = defineRouteSchema({
314
- body: z.object({
315
- userId: z.string().min(1),
316
- role: z.string().optional()
317
- })
318
- });
319
- `;
320
- }
321
- return `import { z, defineRouteSchema } from "sprint-es/schemas";
322
-
323
- export const adminSchema = defineRouteSchema({
324
- queryParams: z.object({
325
- id: z.string().uuid()
326
- }),
327
- body: z.object({
328
- name: z.string().min(1),
329
- email: z.string().email().optional()
330
- })
331
- });
332
-
333
- export const jwtGenerateSchema = defineRouteSchema({
334
- body: z.object({
335
- userId: z.string().min(1),
336
- role: z.string().optional()
337
- })
338
- });
339
- `;
340
- }
341
- export function getInternalAuthMiddleware(language) {
342
- if (language === "typescript") {
343
- return `import { defineMiddleware, SprintRequest, SprintResponse, NextFunction } from "sprint-es";
344
-
345
- export default defineMiddleware({
346
- name: "adminAuth",
347
- priority: 10,
348
- include: "/admin/**",
349
- handler: (req: SprintRequest, res: SprintResponse, next: NextFunction) => {
350
- const auth = req.sprint.getAuthorization();
351
- if (!auth) return res.status(401).json({ error: "No authorization header" });
352
-
353
- const token = auth.replace("Bearer ", "");
354
-
355
- if (token !== "admin-token") return res.status(403).json({ error: "Invalid token" });
356
-
357
- next();
358
- }
359
- });
360
- `;
361
- }
362
- return `import { defineMiddleware } from "sprint-es";
363
-
364
- export default defineMiddleware({
365
- name: "adminAuth",
366
- priority: 10,
367
- include: "/admin/**",
368
- handler: (req, res, next) => {
369
- const auth = req.sprint.getAuthorization();
370
- if (!auth) return res.status(401).json({ error: "No authorization header" });
371
-
372
- const token = auth.replace("Bearer ", "");
373
-
374
- if (token !== "admin-token") return res.status(403).json({ error: "Invalid token" });
375
-
376
- next();
377
- }
378
- });
379
- `;
380
- }
381
- export function getUserAuthMiddleware(language) {
382
- if (language === "typescript") {
383
- return `import { defineMiddleware, SprintRequest, SprintResponse, NextFunction } from "sprint-es";
384
- import { verifyEncrypted, getJwtFromEnv } from "sprint-es/jwt";
385
-
386
- const { publicKey, encryptionSecret } = getJwtFromEnv();
387
-
388
- export default defineMiddleware({
389
- name: "userAuth",
390
- priority: 10,
391
- include: "/**",
392
- exclude: "/admin/**",
393
- handler: (req: SprintRequest, res: SprintResponse, next: NextFunction) => {
394
- const auth = req.sprint.getAuthorization();
395
- if (!auth) return res.status(401).json({ error: "No authorization header" });
396
-
397
- const token = auth.replace("Bearer ", "");
398
-
399
- const decoded = verifyEncrypted(token, publicKey, encryptionSecret);
400
-
401
- if (!decoded) return res.status(403).json({ error: "Invalid token" });
402
-
403
- req.custom.user = decoded;
404
-
405
- next();
406
- }
407
- });
408
- `;
409
- }
410
- return `import { defineMiddleware } from "sprint-es";
411
- import { verifyEncrypted, getJwtFromEnv } from "sprint-es/jwt";
412
-
413
- const { publicKey, encryptionSecret } = getJwtFromEnv();
414
-
415
- export default defineMiddleware({
416
- name: "userAuth",
417
- priority: 10,
418
- include: "/**",
419
- exclude: "/admin/**",
420
- handler: (req, res, next) => {
421
- const auth = req.sprint.getAuthorization();
422
- if (!auth) return res.status(401).json({ error: "No authorization header" });
423
-
424
- const token = auth.replace("Bearer ", "");
425
-
426
- const decoded = verifyEncrypted(token, publicKey, encryptionSecret);
427
-
428
- if (!decoded) return res.status(403).json({ error: "Invalid token" });
429
-
430
- req.custom.user = decoded;
431
-
432
- next();
433
- }
434
- });
435
- `;
436
- }
437
- export function getDockerfile(language) {
438
- if (language === "typescript") {
439
- return `FROM node:20-alpine
440
-
441
- WORKDIR /app
442
-
443
- COPY package*.json ./
444
-
445
- RUN npm ci
446
-
447
- COPY . .
448
-
449
- RUN npm run build
450
-
451
- EXPOSE 3000
452
-
453
- CMD ["npm", "start"]
454
- `;
455
- }
456
- return `FROM node:20-alpine
457
-
458
- WORKDIR /app
459
-
460
- COPY package*.json ./
461
-
462
- RUN npm ci
463
-
464
- COPY . .
465
-
466
- EXPOSE 3000
467
-
468
- CMD ["npm", "start"]
469
- `;
470
- }
471
- export function getDockerCompose(language) {
472
- return `
473
- services:
474
- app:
475
- build: .
476
- ports:
477
- - "3000:3000"
478
- environment:
479
- - NODE_ENV=production
480
- - PORT=5000
481
- restart: unless-stopped
482
- `;
483
- }
484
- export function getGitignore() {
485
- return `# Dependencies
486
- node_modules/
487
- npm-debug.log*
488
- yarn-debug.log*
489
- yarn-error.log*
490
-
491
- # Build
492
- dist/
493
- build/
494
- *.tsbuildinfo
495
-
496
- # Environment
497
- .env.development
498
- .env.production
499
- .env.local
500
- .env.*.local
501
-
502
- # IDE
503
- .vscode/
504
- .idea/
505
- *.swp
506
- *.swo
507
- *~
508
-
509
- # OS
510
- .DS_Store
511
- Thumbs.db
512
-
513
- # Logs
514
- logs/
515
- *.log
516
-
517
- # Test
518
- coverage/
519
-
520
- # Temporary
521
- tmp/
522
- temp/
523
- `;
524
- }
525
- export function getDockerIgnore() {
526
- return `node_modules
527
- npm-debug.log
528
- .env
529
- .env.*
530
- .git
531
- .gitignore
532
- README.md
533
- dist
534
- build
535
- coverage
536
- .vscode
537
- .idea
538
- *.log
539
- tmp
540
- temp
541
- `;
542
- }
543
- export function getSprintConfigFile(language, telemetry) {
544
- if (language === "typescript") {
545
- let config = `import type { SprintOptions } from "sprint-es";
546
-
547
- export const config: SprintOptions = {
548
- openapi: {
549
- /* Generate OpenAPI spec on build - Coming Soon */
550
- generateOnBuild: false
551
- }
552
- };
553
-
554
- // Add Vite config here if needed
555
- // export const vite = {
556
- // build: { ... }
557
- // };
558
- `;
559
- if (telemetry === "sentry" || telemetry === "glitchtip") {
560
- config += `import { initTelemetry } from "sprint-es/telemetry";
561
-
562
- initTelemetry({
563
- provider: "${telemetry}",
564
- dsn: process.env.SENTRY_DSN || "",
565
- environment: process.env.NODE_ENV || "development"
566
- });
567
- `;
568
- }
569
- else if (telemetry === "discord") {
570
- config += `import { initTelemetry } from "sprint-es/telemetry";
571
-
572
- initTelemetry({
573
- provider: "discord",
574
- webhookUrl: process.env.DISCORD_TELEMETRY_WEBHOOK_URL || ""
575
- });
576
- `;
577
- }
578
- return config;
579
- }
580
- let config = `export const config = {
581
- openapi: {
582
- /* Generate OpenAPI spec on build - Coming Soon */
583
- generateOnBuild: false
584
- }
585
- };
586
- `;
587
- if (telemetry === "sentry" || telemetry === "glitchtip") {
588
- config += `
589
- import { initTelemetry } from "sprint-es/telemetry";
590
-
591
- initTelemetry({
592
- provider: "${telemetry}",
593
- dsn: process.env.SENTRY_DSN || "",
594
- environment: process.env.NODE_ENV || "development"
595
- });
596
- `;
597
- }
598
- else if (telemetry === "discord") {
599
- config += `
600
- import { initTelemetry } from "sprint-es/telemetry";
601
-
602
- initTelemetry({
603
- provider: "discord",
604
- webhookUrl: process.env.DISCORD_TELEMETRY_WEBHOOK_URL || ""
605
- });
606
- `;
607
- }
608
- return config;
609
- }
610
- export function getEnvExample(telemetry) {
611
- let env = `PORT=5000
612
-
613
- JWT_PUBLIC_KEY=""
614
- JWT_PRIVATE_KEY=""
615
- JWT_ENCRYPTION_SECRET=""
616
-
617
- # Development: npm run dev (NODE_ENV=development)
618
- # Production: npm start (NODE_ENV=production)
619
- `;
620
- if (telemetry === "sentry" || telemetry === "glitchtip") {
621
- env += `
622
- # Sentry / GlitchTip (use GlitchTip DSN for self-hosted)
623
- SENTRY_DSN=""
624
- `;
625
- }
626
- else if (telemetry === "discord") {
627
- env += `
628
- # Discord Webhook URL for error notifications
629
- DISCORD_TELEMETRY_WEBHOOK_URL=""
630
- `;
631
- }
632
- return env;
633
- }
634
- function envKey(key) {
635
- return key;
636
- }
637
- export function getEnvDevelopment(telemetry) {
638
- const keys = generateJWTKeys();
639
- let env = `NODE_ENV=development
640
- PORT=5000
641
- JWT_PUBLIC_KEY='${keys.publicKey}'
642
- JWT_PRIVATE_KEY='${keys.privateKey}'
643
- JWT_ENCRYPTION_SECRET='${crypto.randomBytes(32).toString("hex")}'
644
- `;
645
- if (telemetry === "sentry" || telemetry === "glitchtip") {
646
- env += `
647
- # Sentry / GlitchTip
648
- SENTRY_DSN=""
649
- `;
650
- }
651
- else if (telemetry === "discord") {
652
- env += `
653
- # Discord Webhook URL
654
- DISCORD_TELEMETRY_WEBHOOK_URL=""
655
- `;
656
- }
657
- return env;
658
- }
659
- export function getEnvProduction(telemetry) {
660
- const keys = generateJWTKeys();
661
- let env = `NODE_ENV=production
662
- PORT=5000
663
- JWT_PUBLIC_KEY='${keys.publicKey}'
664
- JWT_PRIVATE_KEY='${keys.privateKey}'
665
- JWT_ENCRYPTION_SECRET='${crypto.randomBytes(32).toString("hex")}'
666
- `;
667
- if (telemetry === "sentry" || telemetry === "glitchtip") {
668
- env += `
669
- # Sentry / GlitchTip
670
- SENTRY_DSN=
671
- `;
672
- }
673
- else if (telemetry === "discord") {
674
- env += `
675
- # Discord Webhook URL
676
- DISCORD_TELEMETRY_WEBHOOK_URL=
677
- `;
678
- }
679
- return env;
680
- }
681
- export function getExampleCronJob(language) {
682
- if (language === "typescript") {
683
- return `import { defineCronJob } from "sprint-es/cronjobs";
684
-
685
- export default defineCronJob({
686
- name: "daily-task",
687
- cronExpression: "0 21 * * *",
688
- handler: () => {
689
- console.log("Hello World from cronjob!");
690
- }
691
- });
692
- `;
693
- }
694
- return `import { defineCronJob } from "sprint-es/cronjobs";
695
-
696
- export default defineCronJob({
697
- name: "daily-task",
698
- cronExpression: "0 21 * * *",
699
- handler: () => {
700
- console.log("Hello World from cronjob!");
701
- }
702
- });
703
- `;
704
- }
1
+ // Re-export all templates for backward compatibility.
2
+ export * from "./templates/index.js";