tspace-spear 1.2.6 โ†’ 1.2.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.
Files changed (81) hide show
  1. package/README.md +101 -105
  2. package/dist/cli/app.d.ts +1 -1
  3. package/dist/cli/app.js +12 -4
  4. package/dist/cli/app.js.map +1 -1
  5. package/dist/cli/client.d.ts +1 -0
  6. package/dist/cli/client.js +30 -0
  7. package/dist/cli/client.js.map +1 -0
  8. package/dist/cli/controller.d.ts +1 -1
  9. package/dist/cli/controller.js +12 -1
  10. package/dist/cli/controller.js.map +1 -1
  11. package/dist/cli/generators/app/index.d.ts +1 -0
  12. package/dist/cli/generators/app/index.js +124 -0
  13. package/dist/cli/generators/app/index.js.map +1 -0
  14. package/dist/cli/generators/app/template.d.ts +1 -0
  15. package/dist/cli/generators/app/template.js +42 -0
  16. package/dist/cli/generators/app/template.js.map +1 -0
  17. package/dist/cli/generators/client/template.d.ts +1 -0
  18. package/dist/cli/generators/client/template.js +30 -0
  19. package/dist/cli/generators/client/template.js.map +1 -0
  20. package/dist/cli/generators/controller/index.d.ts +1 -0
  21. package/dist/cli/generators/controller/index.js +78 -0
  22. package/dist/cli/generators/controller/index.js.map +1 -0
  23. package/dist/cli/generators/controller/template.d.ts +1 -0
  24. package/dist/cli/generators/controller/template.js +99 -0
  25. package/dist/cli/generators/controller/template.js.map +1 -0
  26. package/dist/cli/generators/dto/index.d.ts +1 -0
  27. package/dist/cli/generators/dto/index.js +55 -0
  28. package/dist/cli/generators/dto/index.js.map +1 -0
  29. package/dist/cli/generators/dto/template.d.ts +1 -0
  30. package/dist/cli/generators/dto/template.js +32 -0
  31. package/dist/cli/generators/dto/template.js.map +1 -0
  32. package/dist/cli/generators/middleware/index.d.ts +1 -0
  33. package/dist/cli/generators/middleware/index.js +38 -0
  34. package/dist/cli/generators/middleware/index.js.map +1 -0
  35. package/dist/cli/generators/middleware/template.d.ts +1 -0
  36. package/dist/cli/generators/middleware/template.js +16 -0
  37. package/dist/cli/generators/middleware/template.js.map +1 -0
  38. package/dist/cli/generators/module/index.d.ts +1 -0
  39. package/dist/cli/generators/module/index.js +173 -0
  40. package/dist/cli/generators/module/index.js.map +1 -0
  41. package/dist/cli/generators/service/index.d.ts +1 -0
  42. package/dist/cli/generators/service/index.js +53 -0
  43. package/dist/cli/generators/service/index.js.map +1 -0
  44. package/dist/cli/generators/service/template.d.ts +1 -0
  45. package/dist/cli/generators/service/template.js +74 -0
  46. package/dist/cli/generators/service/template.js.map +1 -0
  47. package/dist/cli/generators/shared/index.d.ts +3 -0
  48. package/dist/cli/generators/shared/index.js +22 -0
  49. package/dist/cli/generators/shared/index.js.map +1 -0
  50. package/dist/cli/index.js +52 -125
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/cli/middleware.d.ts +1 -0
  53. package/dist/cli/middleware.js +16 -0
  54. package/dist/cli/middleware.js.map +1 -0
  55. package/dist/client.d.ts +1 -0
  56. package/dist/client.js +17 -0
  57. package/dist/client.js.map +1 -0
  58. package/dist/common/middlewares/log.middleware.d.ts +2 -0
  59. package/dist/common/middlewares/log.middleware.js +12 -0
  60. package/dist/common/middlewares/log.middleware.js.map +1 -0
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.js +32 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/lib/core/compiler/generator.js +37 -1
  65. package/dist/lib/core/compiler/generator.js.map +1 -1
  66. package/dist/lib/core/decorators/context.d.ts +78 -8
  67. package/dist/lib/core/decorators/context.js +74 -7
  68. package/dist/lib/core/decorators/context.js.map +1 -1
  69. package/dist/lib/core/package/index.d.ts +11 -0
  70. package/dist/lib/core/package/index.js +42 -0
  71. package/dist/lib/core/package/index.js.map +1 -0
  72. package/dist/modules/cats/cat.controller.d.ts +58 -0
  73. package/dist/modules/cats/cat.controller.js +90 -0
  74. package/dist/modules/cats/cat.controller.js.map +1 -0
  75. package/dist/modules/cats/cat.dto.d.ts +8 -0
  76. package/dist/modules/cats/cat.dto.js +44 -0
  77. package/dist/modules/cats/cat.dto.js.map +1 -0
  78. package/dist/modules/cats/cat.service.d.ts +23 -0
  79. package/dist/modules/cats/cat.service.js +56 -0
  80. package/dist/modules/cats/cat.service.js.map +1 -0
  81. package/package.json +2 -2
package/README.md CHANGED
@@ -17,7 +17,7 @@ It is designed with a strong focus on developer experience and provides end-to-e
17
17
  - ๐Ÿงช Built-in testing support for E2E validation
18
18
  - ๐Ÿงฉ Simple and intuitive developer experience
19
19
  - ๐Ÿ”Œ Flexible architecture for plugins and extensions
20
- - ๐Ÿ“˜ Auto-generated Swagger documentation via `@Swagger()` decorator (zero manual configuration required)
20
+ - ๐Ÿ“˜ Auto-generated Swagger documentation via `app.useSwagger()` (zero manual configuration required)
21
21
 
22
22
  ---
23
23
 
@@ -27,7 +27,7 @@ Install with [npm](https://www.npmjs.com/):
27
27
 
28
28
  ```sh
29
29
  npm install tspace-spear --save
30
-
30
+ npm install tspace-spear -g
31
31
  ```
32
32
 
33
33
  ## Documentation
@@ -35,7 +35,8 @@ npm install tspace-spear --save
35
35
  See the [`docs`](https://thanathip41.github.io/tspace-spear) directory for full documentation.
36
36
 
37
37
  ## Basic Usage
38
- - [Start Server](#start-server)
38
+ - [Getting Started](#getting-started)
39
+ - [Cli](#cli)
39
40
  - [Adapter](#adapter)
40
41
  - [Cluster](#cluster)
41
42
  - [Global Prefix](#global-prefix)
@@ -57,7 +58,7 @@ See the [`docs`](https://thanathip41.github.io/tspace-spear) directory for full
57
58
  - [E2E](#e2e)
58
59
  - [Example CRUD](#example-crud)
59
60
 
60
- ## Start Server
61
+ ## Getting Started
61
62
  ```js
62
63
  import { Spear } from "tspace-spear";
63
64
 
@@ -68,8 +69,52 @@ new Spear()
68
69
  message : 'Hello world!'
69
70
  }
70
71
  })
71
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
72
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
73
+ ```
74
+
75
+ ## Cli
76
+ Generate applications, modules, controllers, services, and middleware with the Spear CLI.
77
+ ```sh
78
+ # Install CLI globally
79
+ npm install -g tspace-spear
80
+
81
+ # Create a new application structure
82
+ spear create new my-app
83
+
84
+ โœ” Successfully created project "my-app"
85
+
86
+ ๐Ÿ“ฆ Project Structure
87
+
88
+ src/
89
+ โ”œโ”€โ”€ common/
90
+ โ”‚ โ””โ”€โ”€ middlewares/
91
+ โ”‚ โ””โ”€โ”€ log.middleware.ts
92
+ โ”‚
93
+ โ”œโ”€โ”€ modules/
94
+ โ”‚ โ””โ”€โ”€ cats/
95
+ โ”‚ โ”œโ”€โ”€ cat.controller.ts
96
+ โ”‚ โ”œโ”€โ”€ cat.service.ts
97
+ โ”‚ โ””โ”€โ”€ cat.dto.ts
98
+ โ”‚
99
+ โ”œโ”€โ”€ client.ts
100
+ โ””โ”€โ”€ index.ts
101
+
102
+ ๐Ÿš€ Next Steps
103
+
104
+ cd my-app
105
+
106
+ npm run dev
107
+
108
+ โœ” Server is running at:
109
+ http://localhost:8000
110
+
111
+ โœ” Swagger Docs:
112
+ http://localhost:8000/api/docs
72
113
 
114
+ โœ” Run E2E client:
115
+ ts-node src/client.ts
116
+
117
+ ts-node src/client.ts // for E2E
73
118
  ```
74
119
 
75
120
  ## Adapter
@@ -96,8 +141,8 @@ new Spear({ adapter: uWS })
96
141
  message: "Hello world!",
97
142
  };
98
143
  })
99
- .listen(3000, () =>
100
- console.log("uWS server is running at http://localhost:3000")
144
+ .listen(8000, () =>
145
+ console.log("uWS server is running at http://localhost:8000")
101
146
  );
102
147
  ```
103
148
 
@@ -114,7 +159,7 @@ new Spear({
114
159
  message : 'Hello world!'
115
160
  }
116
161
  })
117
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
162
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
118
163
 
119
164
  ```
120
165
 
@@ -127,9 +172,9 @@ const app = new Spear({
127
172
  globalPrefix : '/api' // prefix all routes
128
173
  })
129
174
  .get('/' , () => 'Hello world!')
130
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
175
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
131
176
 
132
- // http://localhost:3000/api => 'Hello world!'
177
+ // http://localhost:8000/api => 'Hello world!'
133
178
  ```
134
179
 
135
180
  ## Logger
@@ -153,7 +198,7 @@ const app = new Spear({
153
198
  exceptPath : /\/benchmark(\/|$)|\/favicon\.ico(\/|$)/ // or use Array ['/']
154
199
  })
155
200
  .get('/' , () => 'Hello world!')
156
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
201
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
157
202
 
158
203
  ```
159
204
 
@@ -179,8 +224,8 @@ const app = new Spear()
179
224
  .notfound(({ res } : T.Context) => {
180
225
  return res.notFound('Not found!')
181
226
  })
182
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
183
- // http://localhost:3000/notfound => { success: false , message : 'Not found!' , statusCode: 404 }
227
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
228
+ // http://localhost:8000/notfound => { success: false , message : 'Not found!' , statusCode: 404 }
184
229
 
185
230
  ```
186
231
 
@@ -227,8 +272,8 @@ const app = new Spear()
227
272
  statusCode
228
273
  }
229
274
  })
230
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
231
- // http://localhost:3000 => { success: true , message : 'Hello World' , statusCode: 200 }
275
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
276
+ // http://localhost:8000 => { success: true , message : 'Hello World' , statusCode: 200 }
232
277
 
233
278
  ```
234
279
 
@@ -265,8 +310,8 @@ const app = new Spear()
265
310
  statusCode : 500
266
311
  });
267
312
  })
268
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
269
- // http://localhost:3000 => { success: false , message : 'Catching failed' , statusCode: 500 }
313
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
314
+ // http://localhost:8000 => { success: false , message : 'Catching failed' , statusCode: 500 }
270
315
 
271
316
  ```
272
317
 
@@ -301,7 +346,7 @@ new Spear()
301
346
  yourBody : body
302
347
  }
303
348
  })
304
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
349
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
305
350
 
306
351
  ```
307
352
 
@@ -345,7 +390,7 @@ new Spear()
345
390
  files
346
391
  }
347
392
  })
348
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
393
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
349
394
 
350
395
  ```
351
396
 
@@ -367,7 +412,7 @@ new Spear()
367
412
  yourCookies : cookies
368
413
  }
369
414
  })
370
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
415
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
371
416
  ```
372
417
 
373
418
  ## Middleware
@@ -389,7 +434,7 @@ import Spear { Router, type T } from "tspace-spear";
389
434
  import CatMiddleware from './cat-middleware.ts'
390
435
 
391
436
  (async () => {
392
- const port = Number(process.env.PORT ?? 3000)
437
+ const port = Number(process.env.PORT ?? 8000)
393
438
  const app = new Spear({
394
439
  middlewares: [ CatMiddleware ]
395
440
  // if you want to import middlewares with a directory can you follow the example
@@ -420,9 +465,9 @@ import CatMiddleware from './cat-middleware.ts'
420
465
  });
421
466
  })
422
467
 
423
- app.listen(port , () => console.log(`Server is now listening http://localhost:3000`))
468
+ app.listen(port , () => console.log(`Server is now listening http://localhost:8000`))
424
469
 
425
- // localhost:3000
470
+ // localhost:8000
426
471
 
427
472
  })()
428
473
  ```
@@ -541,10 +586,10 @@ import CatController from './cat-controller.ts'
541
586
  });
542
587
  })
543
588
 
544
- app.listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
589
+ app.listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
545
590
 
546
- // localhost:3000/cats
547
- // localhost:3000/cats/41
591
+ // localhost:8000/cats
592
+ // localhost:8000/cats/41
548
593
 
549
594
  })()
550
595
  ```
@@ -555,8 +600,9 @@ DTO (Data Transfer Object) is used to validate and transform incoming request da
555
600
  import {
556
601
  Controller ,
557
602
  Post,
558
- createDtoDecorator,
559
603
  Validate,
604
+ ValidateDto,
605
+ createDtoDecorator,
560
606
  type T
561
607
  } from 'tspace-spear';
562
608
 
@@ -568,8 +614,6 @@ import {
568
614
  validate
569
615
  } from "class-validator";
570
616
 
571
- import { ClassConstructor, plainToInstance } from 'class-transformer';
572
-
573
617
  const ValidateDtoCustomBody = (keys: string[]) => {
574
618
  return createDtoDecorator((ctx) => {
575
619
  const body = ctx.body ?? {};
@@ -595,13 +639,6 @@ const ValidateDtoCustomBody = (keys: string[]) => {
595
639
  });
596
640
  }
597
641
 
598
- const ValidateDtoZodBody = (schema: z.ZodTypeAny) => {
599
- return createDtoDecorator((ctx) => {
600
- const result = schema.parse(ctx.body);
601
- ctx.body = result as T.Body;
602
- });
603
- }
604
-
605
642
  const ValidateDtoPromiseBody = (keys: string[]) => {
606
643
  return createDtoDecorator(async (ctx) => {
607
644
  await new Promise(resolve => setTimeout(resolve,500));
@@ -621,39 +658,6 @@ const ValidateDtoPromiseBody = (keys: string[]) => {
621
658
  });
622
659
  }
623
660
 
624
- const ValidateDtoClsBody = <T extends object>(
625
- cls: ClassConstructor<T>
626
- ) => {
627
- return createDtoDecorator(async (ctx) => {
628
-
629
- const dto = plainToInstance(
630
- cls,
631
- ctx.body
632
- );
633
-
634
- const errors = await validate(dto);
635
-
636
- if (errors.length > 0) {
637
- throw {
638
- message: "Validation failed",
639
- issues: errors.flatMap((error) => {
640
- const constraints = error.constraints ?? {};
641
-
642
- const firstError = Object.values(constraints)[0] ?? "Validation error";
643
-
644
- return {
645
- path: error.property,
646
- message: firstError,
647
- };
648
- })
649
- };
650
- }
651
-
652
- ctx.body = dto;
653
- }
654
- );
655
- };
656
-
657
661
  const catSchema = z.object({
658
662
  name: z.string(),
659
663
  age: z.number(),
@@ -667,7 +671,6 @@ class CreateCatDto {
667
671
  age!: number;
668
672
  }
669
673
 
670
-
671
674
  // file cat-controller.ts
672
675
  @Controller('/cats')
673
676
  export class CatController {
@@ -676,47 +679,40 @@ export class CatController {
676
679
  // only required validation without type checking
677
680
  @Validate(["name", "age"], { required: { allowEmptyString: false, allowNull: false } })
678
681
  public async basic(ctx : T.Context<{ body : { name : any , age : any }}>) {
679
- const body = ctx.body;
680
682
  return {
681
- body
683
+ body : ctx.body
682
684
  }
683
685
  }
684
686
 
685
- @Post('/')
687
+ @Post('/custom')
686
688
  @ValidateDtoCustomBody(["name", "age"])
687
689
  public async custom(ctx : T.Context<{ body : { name : string , age : number }}>) {
688
- const body = ctx.body;
689
690
  return {
690
- body
691
- }
692
- }
693
-
694
- @Post('/zod')
695
- @ValidateDtoZodBody(catSchema)
696
- public async zod(ctx : T.Context<z.infer<typeof catSchema>>) {
697
- const body = ctx.body;
698
- return {
699
- body
691
+ body : ctx.body
700
692
  }
701
693
  }
702
694
 
703
695
  @Post('/promise')
704
696
  @ValidateDtoPromiseBody(['name'])
705
697
  public async promise(ctx : T.Context<{ body : { name : string }}>) {
706
- const body = ctx.body;
698
+ return {
699
+ body : ctx.body
700
+ }
701
+ }
707
702
 
703
+ @Post('/zod')
704
+ @ValidateDto(catSchema, { adaptor : "zod" })
705
+ public async zod(ctx : T.Context<{ body : z.infer<typeof catSchema>}>) {
708
706
  return {
709
- body
707
+ body : ctx.body
710
708
  }
711
709
  }
712
710
 
713
711
  @Post('/cls')
714
- @ValidateDtoClsBody(CreateCatDto)
712
+ @ValidateDto(CreateCatDto)
715
713
  public async cls(ctx : T.Context<{ body : CreateCatDto }>) {
716
- const body = ctx.body;
717
-
718
714
  return {
719
- body
715
+ body : ctx.body
720
716
  }
721
717
  }
722
718
  }
@@ -731,11 +727,11 @@ import CatController from './cat-controller.ts'
731
727
  controllers: [ CatController ]
732
728
  })
733
729
  .useBodyParser()
734
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
730
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
735
731
 
736
- // localhost:3000/cats // basic implete
737
- // localhost:3000/cats/zod // zod implete
738
- // localhost:3000/cats/promise // promise implete
732
+ // localhost:8000/cats // basic implete
733
+ // localhost:8000/cats/zod // zod implete
734
+ // localhost:8000/cats/promise // promise implete
739
735
 
740
736
  })()
741
737
  ```
@@ -782,12 +778,12 @@ app.get('/' , ({ res } : T.Context) => {
782
778
  });
783
779
  })
784
780
 
785
- let port = 3000
781
+ let port = 8000
786
782
 
787
- app.listen(port , () => console.log(`Server is now listening http://localhost:3000`))
783
+ app.listen(port , () => console.log(`Server is now listening http://localhost:8000`))
788
784
 
789
- // localhost:3000/my/cats
790
- // localhost:3000/cats
785
+ // localhost:8000/my/cats
786
+ // localhost:8000/cats
791
787
 
792
788
  ```
793
789
 
@@ -991,7 +987,7 @@ class CatController {
991
987
  .useSwagger({
992
988
  path : "/docs",
993
989
  servers : [
994
- { url : "http://localhost:3000" , description : "development"},
990
+ { url : "http://localhost:8000" , description : "development"},
995
991
  { url : "http://localhost:8000" , description : "production"}
996
992
  ],
997
993
  info : {
@@ -999,9 +995,9 @@ class CatController {
999
995
  "description" : "This is the documentation"
1000
996
  }
1001
997
  })
1002
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
998
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
1003
999
 
1004
- // localhost:3000/docs
1000
+ // localhost:8000/docs
1005
1001
  })()
1006
1002
 
1007
1003
  ```
@@ -1080,7 +1076,7 @@ new Spear()
1080
1076
  }
1081
1077
  };
1082
1078
  })
1083
- .listen(3000 , ({ port , server }) => {
1079
+ .listen(8000 , ({ port , server }) => {
1084
1080
  console.log(`server listening on : http://localhost:${port}`)
1085
1081
  })
1086
1082
 
@@ -1241,7 +1237,7 @@ const app = new Spear({
1241
1237
 
1242
1238
  app.useGlobalPrefix('api');
1243
1239
  app.useBodyParser();
1244
- app.listen(3000 , () => console.log(`Server is now listening http://localhost:3000`));
1240
+ app.listen(8000 , () => console.log(`Server is now listening http://localhost:8000`));
1245
1241
 
1246
1242
  type AppRouter = typeof app.contract;
1247
1243
  export { AppRouter }
@@ -1252,7 +1248,7 @@ import { AppRouter } from "./server/app";
1252
1248
  import { ApiClient } from "tspace-spear/client";
1253
1249
 
1254
1250
  const client: ApiClient<AppRouter> = new ApiClient(
1255
- `http://localhost:3000/api`
1251
+ `http://localhost:8000/api`
1256
1252
  );
1257
1253
 
1258
1254
  const test = await client.get("/catsq"); // Type error: Argument of type '"/catsq"' is not assignable to parameter of type '"/cats" | "/cats/:id" | ... 3 more
@@ -1328,6 +1324,6 @@ new Spear()
1328
1324
 
1329
1325
  return res.status(204).json()
1330
1326
  })
1331
- .listen(3000 , () => console.log(`Server is now listening http://localhost:3000`))
1327
+ .listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
1332
1328
 
1333
1329
  ```
package/dist/cli/app.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const app = "\nimport Spear from \"tspace-spear\";\n\nexport const app = new Spear({\n logger: true,\n controllers: {\n folder: `${__dirname}/controllers`,\n name: /controller\\\\.(ts|js)$/i,\n preRouteTypes: true\n }\n})\n\napp.useGlobalPrefix(\"api\");\n\napp.useBodyParser();\n\napp.listen(8000 , ({ port , server }) => {\n console.log(`server listening on : http://localhost:${port}`)\n})\n";
1
+ export declare const app = "\nimport Spear from \"tspace-spear\";\n\nconst app = new Spear({\n logger: true,\n controllers: {\n folder: `${__dirname}/controllers`,\n name: /controller\\.(ts|js)$/i,\n\n // don't forget to set this option for auto-generate route metadata for type-safe E2E usage, \n // and swagger documentation. By default if use .useSwagger() in app no need to set any description\n preRouteTypes: true\n }\n})\n\napp.useGlobalPrefix(\"api\");\napp.useSwagger();\napp.useBodyParser();\n\napp.listen(8000 , ({ port , server }) => {\n console.log(`Server listening on : http://localhost:${port}`)\n console.log(`Docs listening on : http://localhost:${port}/api/docs`)\n})\n\ntype AppRouter = typeof app.contract;\nexport { AppRouter };\nexport { app };\n";
package/dist/cli/app.js CHANGED
@@ -4,21 +4,29 @@ exports.app = void 0;
4
4
  exports.app = `
5
5
  import Spear from "tspace-spear";
6
6
 
7
- export const app = new Spear({
7
+ const app = new Spear({
8
8
  logger: true,
9
9
  controllers: {
10
10
  folder: \`\${__dirname}/controllers\`,
11
- name: /controller\\\\.(ts|js)$/i,
11
+ name: /controller\\\.(ts|js)$/i,
12
+
13
+ // don't forget to set this option for auto-generate route metadata for type-safe E2E usage,
14
+ // and swagger documentation. By default if use .useSwagger() in app no need to set any description
12
15
  preRouteTypes: true
13
16
  }
14
17
  })
15
18
 
16
19
  app.useGlobalPrefix("api");
17
-
20
+ app.useSwagger();
18
21
  app.useBodyParser();
19
22
 
20
23
  app.listen(8000 , ({ port , server }) => {
21
- console.log(\`server listening on : http://localhost:\${port}\`)
24
+ console.log(\`Server listening on : http://localhost:\${port}\`)
25
+ console.log(\`Docs listening on : http://localhost:\${port}/api/docs\`)
22
26
  })
27
+
28
+ type AppRouter = typeof app.contract;
29
+ export { AppRouter };
30
+ export { app };
23
31
  `;
24
32
  //# sourceMappingURL=app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.ts"],"names":[],"mappings":";;;AAAa,QAAA,GAAG,GAAG;;;;;;;;;;;;;;;;;;;CAmBlB,CAAC"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.ts"],"names":[],"mappings":";;;AAAa,QAAA,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BlB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare const client = "\n// for example E2E\nimport { AppRouter } from \".\";\nimport { ApiClient } from \"tspace-spear/client\";\n\nconst client: ApiClient<AppRouter> = new ApiClient(\n \"http://localhost:8000/api\"\n);\n\nasync function main() { \n \n const res = await client.get(\"/cats\");\n res.data.cats = 1 // Type error: Type 'number' is not assignable to type '{ id: number; name: string; age: number; }[]'\n res.data.cats[0].name = 1 // Type error: Type 'number' is not assignable to type 'string'\n res.data.cats[0].age = \"1.6\" // Type error: Type 'string' is not assignable to type 'number'\n\n console.log(res) \n // res.ok -> boolean\n // res.status -> number\n // res.data -> { cats: [{ id: 1, name: 'cat1', age: 1.6 },{ id: 2, name: 'cat2', age: 1.8 }] }\n\n await client.get(\"/catsq\"); // Type error: Argument of type '\"/catsq\"' is not assignable to parameter of type '\"/cats\" | \"/cats/:id\" | ... 3 more\n \n}\nmain()\n";
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.client = void 0;
4
+ exports.client = `
5
+ // for example E2E
6
+ import { AppRouter } from ".";
7
+ import { ApiClient } from "tspace-spear/client";
8
+
9
+ const client: ApiClient<AppRouter> = new ApiClient(
10
+ "http://localhost:8000/api"
11
+ );
12
+
13
+ async function main() {
14
+
15
+ const res = await client.get("/cats");
16
+ res.data.cats = 1 // Type error: Type 'number' is not assignable to type '{ id: number; name: string; age: number; }[]'
17
+ res.data.cats[0].name = 1 // Type error: Type 'number' is not assignable to type 'string'
18
+ res.data.cats[0].age = "1.6" // Type error: Type 'string' is not assignable to type 'number'
19
+
20
+ console.log(res)
21
+ // res.ok -> boolean
22
+ // res.status -> number
23
+ // res.data -> { cats: [{ id: 1, name: 'cat1', age: 1.6 },{ id: 2, name: 'cat2', age: 1.8 }] }
24
+
25
+ await client.get("/catsq"); // Type error: Argument of type '"/catsq"' is not assignable to parameter of type '"/cats" | "/cats/:id" | ... 3 more
26
+
27
+ }
28
+ main()
29
+ `;
30
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":";;;AACa,QAAA,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBrB,CAAA"}
@@ -1 +1 @@
1
- export declare const CatController = "\nimport {\n type T,\n Controller,\n Get,\n Post,\n Put,\n Delete\n} from \"tspace-spear\";\n\ntype Cat = {\n id: number;\n name: string;\n age: number;\n};\n\nlet cats: Cat[] = [\n {\n id: 1,\n name: \"cat 1\",\n age: 2\n },\n {\n id: 2,\n name: \"cat 2\",\n age: 4\n }\n];\n\n@Controller(\"/cats\")\nexport default class CatController {\n\n @Get(\"/\")\n async index() {\n return {\n cats\n };\n }\n\n @Get(\"/:id\")\n async show({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const cat = cats.find(\n d => d.id === Number(params.id)\n );\n\n if (!cat) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n return {\n cat\n };\n }\n\n @Post(\"/\")\n async create({\n body\n }: T.Context<{\n body: {\n name: string;\n age: number;\n };\n }>) {\n\n const cat: Cat = {\n id: cats.length + 1,\n name: body.name,\n age: body.age\n };\n\n cats.push(cat);\n\n return {\n message: \"Created\",\n cat\n };\n }\n\n @Put(\"/:id\")\n async update({\n res,\n params,\n body\n }: T.Context<{\n params: {\n id: number;\n };\n body: Partial<{\n name: string;\n age: number;\n }>;\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats[index] = {\n ...cats[index],\n ...body\n };\n\n return {\n message: \"Updated\",\n cat: cats[index]\n };\n }\n\n @Delete(\"/:id\")\n async remove({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats = cats.filter(\n d => d.id !== Number(params.id)\n );\n\n return {\n message: \"Deleted\"\n };\n }\n}\n";
1
+ export declare const CatController = "\nimport {\n type T,\n Controller,\n Middleware,\n Get,\n Post,\n Put,\n Delete\n} from \"tspace-spear\";\n\nimport { CatMiddleware } from \"../middlewares/cat.middleware\";\n\ntype Cat = {\n id: number;\n name: string;\n age: number;\n};\n\nlet cats: Cat[] = [\n {\n id: 1,\n name: \"cat 1\",\n age: 2\n },\n {\n id: 2,\n name: \"cat 2\",\n age: 4\n }\n];\n\n@Controller(\"/cats\")\nclass CatController {\n\n @Get(\"/\")\n @Middleware(CatMiddleware)\n async index() {\n return {\n cats\n };\n }\n\n @Get(\"/:id\")\n @Middleware(CatMiddleware)\n async show({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const cat = cats.find(\n d => d.id === Number(params.id)\n );\n\n if (!cat) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n return {\n cat\n };\n }\n\n @Post(\"/\")\n @Middleware(CatMiddleware)\n async create({\n body\n }: T.Context<{\n body: {\n name: string;\n age: number;\n };\n }>) {\n\n const cat: Cat = {\n id: cats.length + 1,\n name: body.name,\n age: body.age\n };\n\n cats.push(cat);\n\n return {\n message: \"Created\",\n cat\n };\n }\n\n @Put(\"/:id\")\n @Middleware(CatMiddleware)\n async update({\n res,\n params,\n body\n }: T.Context<{\n params: {\n id: number;\n };\n body: Partial<{\n name: string;\n age: number;\n }>;\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats[index] = {\n ...cats[index],\n ...body\n };\n\n return {\n message: \"Updated\",\n cat: cats[index]\n };\n }\n\n @Delete(\"/:id\")\n @Middleware(CatMiddleware)\n async remove({\n res,\n params\n }: T.Context<{\n params: {\n id: number;\n };\n }>) {\n\n const index = cats.findIndex(\n d => d.id === Number(params.id)\n );\n\n if (index === -1) {\n throw res.notFound(\n \"Cat not found\"\n );\n }\n\n cats = cats.filter(\n d => d.id !== Number(params.id)\n );\n\n return {\n message: \"Deleted\"\n };\n }\n}\n\nexport { CatController };\nexport default CatController;\n";
@@ -5,12 +5,15 @@ exports.CatController = `
5
5
  import {
6
6
  type T,
7
7
  Controller,
8
+ Middleware,
8
9
  Get,
9
10
  Post,
10
11
  Put,
11
12
  Delete
12
13
  } from "tspace-spear";
13
14
 
15
+ import { CatMiddleware } from "../middlewares/cat.middleware";
16
+
14
17
  type Cat = {
15
18
  id: number;
16
19
  name: string;
@@ -31,9 +34,10 @@ let cats: Cat[] = [
31
34
  ];
32
35
 
33
36
  @Controller("/cats")
34
- export default class CatController {
37
+ class CatController {
35
38
 
36
39
  @Get("/")
40
+ @Middleware(CatMiddleware)
37
41
  async index() {
38
42
  return {
39
43
  cats
@@ -41,6 +45,7 @@ export default class CatController {
41
45
  }
42
46
 
43
47
  @Get("/:id")
48
+ @Middleware(CatMiddleware)
44
49
  async show({
45
50
  res,
46
51
  params
@@ -66,6 +71,7 @@ export default class CatController {
66
71
  }
67
72
 
68
73
  @Post("/")
74
+ @Middleware(CatMiddleware)
69
75
  async create({
70
76
  body
71
77
  }: T.Context<{
@@ -90,6 +96,7 @@ export default class CatController {
90
96
  }
91
97
 
92
98
  @Put("/:id")
99
+ @Middleware(CatMiddleware)
93
100
  async update({
94
101
  res,
95
102
  params,
@@ -126,6 +133,7 @@ export default class CatController {
126
133
  }
127
134
 
128
135
  @Delete("/:id")
136
+ @Middleware(CatMiddleware)
129
137
  async remove({
130
138
  res,
131
139
  params
@@ -154,5 +162,8 @@ export default class CatController {
154
162
  };
155
163
  }
156
164
  }
165
+
166
+ export { CatController };
167
+ export default CatController;
157
168
  `;
158
169
  //# sourceMappingURL=controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/cli/controller.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyJ5B,CAAC"}
1
+ {"version":3,"file":"controller.js","sourceRoot":"","sources":["../../src/cli/controller.ts"],"names":[],"mappings":";;;AAAa,QAAA,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoK5B,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function createApp(inputPath?: string): Promise<void>;