tspace-spear 1.2.7 → 1.2.9
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.
- package/README.md +299 -146
- package/dist/cli/generators/app/index.d.ts +1 -0
- package/dist/cli/generators/app/index.js +124 -0
- package/dist/cli/generators/app/index.js.map +1 -0
- package/dist/cli/generators/app/template.d.ts +1 -0
- package/dist/cli/{app.js → generators/app/template.js} +22 -8
- package/dist/cli/generators/app/template.js.map +1 -0
- package/dist/cli/generators/client/template.d.ts +1 -0
- package/dist/cli/generators/client/template.js +30 -0
- package/dist/cli/generators/client/template.js.map +1 -0
- package/dist/cli/generators/controller/index.d.ts +1 -0
- package/dist/cli/generators/controller/index.js +78 -0
- package/dist/cli/generators/controller/index.js.map +1 -0
- package/dist/cli/generators/controller/template.d.ts +1 -0
- package/dist/cli/generators/controller/template.js +106 -0
- package/dist/cli/generators/controller/template.js.map +1 -0
- package/dist/cli/generators/dto/index.d.ts +1 -0
- package/dist/cli/generators/dto/index.js +57 -0
- package/dist/cli/generators/dto/index.js.map +1 -0
- package/dist/cli/generators/dto/template.d.ts +1 -0
- package/dist/cli/generators/dto/template.js +32 -0
- package/dist/cli/generators/dto/template.js.map +1 -0
- package/dist/cli/generators/middleware/index.d.ts +1 -0
- package/dist/cli/generators/middleware/index.js +38 -0
- package/dist/cli/generators/middleware/index.js.map +1 -0
- package/dist/cli/generators/middleware/template.d.ts +1 -0
- package/dist/cli/generators/middleware/template.js +16 -0
- package/dist/cli/generators/middleware/template.js.map +1 -0
- package/dist/cli/generators/module/index.d.ts +1 -0
- package/dist/cli/generators/module/index.js +173 -0
- package/dist/cli/generators/module/index.js.map +1 -0
- package/dist/cli/generators/service/index.d.ts +1 -0
- package/dist/cli/generators/service/index.js +53 -0
- package/dist/cli/generators/service/index.js.map +1 -0
- package/dist/cli/generators/service/template.d.ts +1 -0
- package/dist/cli/generators/service/template.js +74 -0
- package/dist/cli/generators/service/template.js.map +1 -0
- package/dist/cli/generators/shared/index.d.ts +3 -0
- package/dist/cli/generators/shared/index.js +22 -0
- package/dist/cli/generators/shared/index.js.map +1 -0
- package/dist/cli/index.js +53 -96
- package/dist/cli/index.js.map +1 -1
- package/dist/lib/core/client/index.d.ts +13 -43
- package/dist/lib/core/client/index.js +47 -26
- package/dist/lib/core/client/index.js.map +1 -1
- package/dist/lib/core/{compiler → client}/types.d.ts +29 -0
- package/dist/lib/core/client/types.js.map +1 -0
- package/dist/lib/core/compiler/generator.d.ts +4 -6
- package/dist/lib/core/compiler/generator.js +186 -39
- package/dist/lib/core/compiler/generator.js.map +1 -1
- package/dist/lib/core/compiler/index.d.ts +2 -2
- package/dist/lib/core/compiler/index.js +2 -2
- package/dist/lib/core/compiler/index.js.map +1 -1
- package/dist/lib/core/compiler/pre-routes.d.ts +170 -34
- package/dist/lib/core/compiler/pre-routes.js +45 -25
- package/dist/lib/core/compiler/pre-routes.js.map +1 -1
- package/dist/lib/core/decorators/context.d.ts +78 -8
- package/dist/lib/core/decorators/context.js +84 -9
- package/dist/lib/core/decorators/context.js.map +1 -1
- package/dist/lib/core/decorators/statusCode.js +3 -1
- package/dist/lib/core/decorators/statusCode.js.map +1 -1
- package/dist/lib/core/package/index.d.ts +11 -0
- package/dist/lib/core/package/index.js +42 -0
- package/dist/lib/core/package/index.js.map +1 -0
- package/dist/lib/core/server/fast-router.d.ts +2 -2
- package/dist/lib/core/server/fast-router.js +17 -3
- package/dist/lib/core/server/fast-router.js.map +1 -1
- package/dist/lib/core/server/index.js +2 -2
- package/dist/lib/core/server/index.js.map +1 -1
- package/dist/lib/core/server/response.js +21 -1
- package/dist/lib/core/server/response.js.map +1 -1
- package/dist/lib/core/types/index.d.ts +32 -27
- package/package.json +7 -4
- package/dist/cli/app.d.ts +0 -1
- package/dist/cli/app.js.map +0 -1
- package/dist/cli/controller.d.ts +0 -1
- package/dist/cli/controller.js +0 -158
- package/dist/cli/controller.js.map +0 -1
- package/dist/lib/core/compiler/types.js.map +0 -1
- /package/dist/lib/core/{compiler → client}/types.js +0 -0
package/README.md
CHANGED
|
@@ -12,12 +12,19 @@ It is designed with a strong focus on developer experience and provides end-to-e
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
14
14
|
- ⚡ High-performance core built on native Node.js HTTP
|
|
15
|
-
- 🚀 Optional uWebSockets.js support
|
|
16
|
-
- 🧠 End-to-end (
|
|
17
|
-
-
|
|
15
|
+
- 🚀 Optional [uWebSockets.js](#adapter) adapter support for ultra-low latency and maximum throughput
|
|
16
|
+
- 🧠 End-to-end [E2E](#e2e) type safety across the entire request → response lifecycle
|
|
17
|
+
- 🎮 Built-in support for [Controllers](#controller) and route-based architecture
|
|
18
|
+
- 🏷️ Powerful Decorator system for routes, middleware, validation, and metadata
|
|
19
|
+
- 📦 [DTO](#dto) (Data Transfer Object) support for structured and type-safe request handling
|
|
20
|
+
- 📂 Built-in [File Upload](#file-upload) support via `useFileUpload()` with zero configuration required
|
|
21
|
+
- 🔌 Native [WebSocket](#web-socket) support for real-time applications and event-driven systems
|
|
22
|
+
- ⚛️ [GraphQL](#graphql) support with flexible schema integration and HTTP adapters
|
|
23
|
+
- 🖥️ Built-in [cluster mode](#cluster) support for multi-core scalability and higher throughput
|
|
24
|
+
- 🧪 Built-in testing utilities for [E2E](#e2e) validation
|
|
18
25
|
- 🧩 Simple and intuitive developer experience
|
|
19
|
-
-
|
|
20
|
-
-
|
|
26
|
+
- 📘 Auto-generated [Swagger](#swagger) documentation via `app.useSwagger()` with zero manual configuration
|
|
27
|
+
- 🔥 Lightweight and optimized for high-performance APIs and microservices
|
|
21
28
|
|
|
22
29
|
---
|
|
23
30
|
|
|
@@ -36,7 +43,7 @@ See the [`docs`](https://thanathip41.github.io/tspace-spear) directory for full
|
|
|
36
43
|
|
|
37
44
|
## Basic Usage
|
|
38
45
|
- [Getting Started](#getting-started)
|
|
39
|
-
- [
|
|
46
|
+
- [Quick Started](#quick-started)
|
|
40
47
|
- [Adapter](#adapter)
|
|
41
48
|
- [Cluster](#cluster)
|
|
42
49
|
- [Global Prefix](#global-prefix)
|
|
@@ -55,8 +62,8 @@ See the [`docs`](https://thanathip41.github.io/tspace-spear) directory for full
|
|
|
55
62
|
- [Router](#router)
|
|
56
63
|
- [Swagger](#swagger)
|
|
57
64
|
- [WebSocket](#websocket)
|
|
65
|
+
- [Graphql](#graphql)
|
|
58
66
|
- [E2E](#e2e)
|
|
59
|
-
- [Example CRUD](#example-crud)
|
|
60
67
|
|
|
61
68
|
## Getting Started
|
|
62
69
|
```js
|
|
@@ -72,29 +79,49 @@ new Spear()
|
|
|
72
79
|
.listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
|
|
73
80
|
```
|
|
74
81
|
|
|
75
|
-
##
|
|
82
|
+
## Quick Started
|
|
83
|
+
Generate applications, modules, controllers, services, and middleware with the Spear CLI.
|
|
76
84
|
```sh
|
|
77
85
|
# Install CLI globally
|
|
78
86
|
npm install -g tspace-spear
|
|
79
87
|
|
|
80
88
|
# Create a new application structure
|
|
81
|
-
|
|
89
|
+
spear create new my-app
|
|
82
90
|
|
|
83
|
-
|
|
84
|
-
|
|
91
|
+
✔ Successfully created project "my-app"
|
|
92
|
+
|
|
93
|
+
📦 Project Structure
|
|
85
94
|
|
|
86
|
-
# Generated structure
|
|
87
95
|
src/
|
|
88
|
-
├──
|
|
89
|
-
│ └──
|
|
90
|
-
│
|
|
96
|
+
├── common/
|
|
97
|
+
│ └── middlewares/
|
|
98
|
+
│ └── log.middleware.ts
|
|
99
|
+
│
|
|
100
|
+
├── modules/
|
|
101
|
+
│ └── cats/
|
|
102
|
+
│ ├── cat.controller.ts
|
|
103
|
+
│ ├── cat.service.ts
|
|
104
|
+
│ └── cat.dto.ts
|
|
105
|
+
│
|
|
106
|
+
├── client.ts
|
|
91
107
|
└── index.ts
|
|
92
108
|
|
|
93
|
-
|
|
109
|
+
🚀 Next Steps
|
|
110
|
+
|
|
111
|
+
cd my-app
|
|
112
|
+
|
|
113
|
+
npm run dev
|
|
114
|
+
|
|
115
|
+
✔ Server is running at:
|
|
116
|
+
http://localhost:8000
|
|
117
|
+
|
|
118
|
+
✔ Swagger Docs:
|
|
119
|
+
http://localhost:8000/api/docs
|
|
94
120
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
✔ Run E2E client:
|
|
122
|
+
ts-node src/client.ts
|
|
123
|
+
|
|
124
|
+
ts-node src/client.ts // for E2E
|
|
98
125
|
```
|
|
99
126
|
|
|
100
127
|
## Adapter
|
|
@@ -580,8 +607,9 @@ DTO (Data Transfer Object) is used to validate and transform incoming request da
|
|
|
580
607
|
import {
|
|
581
608
|
Controller ,
|
|
582
609
|
Post,
|
|
583
|
-
createDtoDecorator,
|
|
584
610
|
Validate,
|
|
611
|
+
ValidateDto,
|
|
612
|
+
createDtoDecorator,
|
|
585
613
|
type T
|
|
586
614
|
} from 'tspace-spear';
|
|
587
615
|
|
|
@@ -593,8 +621,6 @@ import {
|
|
|
593
621
|
validate
|
|
594
622
|
} from "class-validator";
|
|
595
623
|
|
|
596
|
-
import { ClassConstructor, plainToInstance } from 'class-transformer';
|
|
597
|
-
|
|
598
624
|
const ValidateDtoCustomBody = (keys: string[]) => {
|
|
599
625
|
return createDtoDecorator((ctx) => {
|
|
600
626
|
const body = ctx.body ?? {};
|
|
@@ -620,13 +646,6 @@ const ValidateDtoCustomBody = (keys: string[]) => {
|
|
|
620
646
|
});
|
|
621
647
|
}
|
|
622
648
|
|
|
623
|
-
const ValidateDtoZodBody = (schema: z.ZodTypeAny) => {
|
|
624
|
-
return createDtoDecorator((ctx) => {
|
|
625
|
-
const result = schema.parse(ctx.body);
|
|
626
|
-
ctx.body = result as T.Body;
|
|
627
|
-
});
|
|
628
|
-
}
|
|
629
|
-
|
|
630
649
|
const ValidateDtoPromiseBody = (keys: string[]) => {
|
|
631
650
|
return createDtoDecorator(async (ctx) => {
|
|
632
651
|
await new Promise(resolve => setTimeout(resolve,500));
|
|
@@ -646,39 +665,6 @@ const ValidateDtoPromiseBody = (keys: string[]) => {
|
|
|
646
665
|
});
|
|
647
666
|
}
|
|
648
667
|
|
|
649
|
-
const ValidateDtoClsBody = <T extends object>(
|
|
650
|
-
cls: ClassConstructor<T>
|
|
651
|
-
) => {
|
|
652
|
-
return createDtoDecorator(async (ctx) => {
|
|
653
|
-
|
|
654
|
-
const dto = plainToInstance(
|
|
655
|
-
cls,
|
|
656
|
-
ctx.body
|
|
657
|
-
);
|
|
658
|
-
|
|
659
|
-
const errors = await validate(dto);
|
|
660
|
-
|
|
661
|
-
if (errors.length > 0) {
|
|
662
|
-
throw {
|
|
663
|
-
message: "Validation failed",
|
|
664
|
-
issues: errors.flatMap((error) => {
|
|
665
|
-
const constraints = error.constraints ?? {};
|
|
666
|
-
|
|
667
|
-
const firstError = Object.values(constraints)[0] ?? "Validation error";
|
|
668
|
-
|
|
669
|
-
return {
|
|
670
|
-
path: error.property,
|
|
671
|
-
message: firstError,
|
|
672
|
-
};
|
|
673
|
-
})
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
ctx.body = dto;
|
|
678
|
-
}
|
|
679
|
-
);
|
|
680
|
-
};
|
|
681
|
-
|
|
682
668
|
const catSchema = z.object({
|
|
683
669
|
name: z.string(),
|
|
684
670
|
age: z.number(),
|
|
@@ -692,7 +678,6 @@ class CreateCatDto {
|
|
|
692
678
|
age!: number;
|
|
693
679
|
}
|
|
694
680
|
|
|
695
|
-
|
|
696
681
|
// file cat-controller.ts
|
|
697
682
|
@Controller('/cats')
|
|
698
683
|
export class CatController {
|
|
@@ -701,47 +686,40 @@ export class CatController {
|
|
|
701
686
|
// only required validation without type checking
|
|
702
687
|
@Validate(["name", "age"], { required: { allowEmptyString: false, allowNull: false } })
|
|
703
688
|
public async basic(ctx : T.Context<{ body : { name : any , age : any }}>) {
|
|
704
|
-
const body = ctx.body;
|
|
705
689
|
return {
|
|
706
|
-
body
|
|
690
|
+
body : ctx.body
|
|
707
691
|
}
|
|
708
692
|
}
|
|
709
693
|
|
|
710
|
-
@Post('/')
|
|
694
|
+
@Post('/custom')
|
|
711
695
|
@ValidateDtoCustomBody(["name", "age"])
|
|
712
696
|
public async custom(ctx : T.Context<{ body : { name : string , age : number }}>) {
|
|
713
|
-
const body = ctx.body;
|
|
714
697
|
return {
|
|
715
|
-
body
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
@Post('/zod')
|
|
720
|
-
@ValidateDtoZodBody(catSchema)
|
|
721
|
-
public async zod(ctx : T.Context<z.infer<typeof catSchema>>) {
|
|
722
|
-
const body = ctx.body;
|
|
723
|
-
return {
|
|
724
|
-
body
|
|
698
|
+
body : ctx.body
|
|
725
699
|
}
|
|
726
700
|
}
|
|
727
701
|
|
|
728
702
|
@Post('/promise')
|
|
729
703
|
@ValidateDtoPromiseBody(['name'])
|
|
730
704
|
public async promise(ctx : T.Context<{ body : { name : string }}>) {
|
|
731
|
-
|
|
705
|
+
return {
|
|
706
|
+
body : ctx.body
|
|
707
|
+
}
|
|
708
|
+
}
|
|
732
709
|
|
|
710
|
+
@Post('/zod')
|
|
711
|
+
@ValidateDto(catSchema, { adaptor : "zod" })
|
|
712
|
+
public async zod(ctx : T.Context<{ body : z.infer<typeof catSchema>}>) {
|
|
733
713
|
return {
|
|
734
|
-
body
|
|
714
|
+
body : ctx.body
|
|
735
715
|
}
|
|
736
716
|
}
|
|
737
717
|
|
|
738
718
|
@Post('/cls')
|
|
739
|
-
@
|
|
719
|
+
@ValidateDto(CreateCatDto)
|
|
740
720
|
public async cls(ctx : T.Context<{ body : CreateCatDto }>) {
|
|
741
|
-
const body = ctx.body;
|
|
742
|
-
|
|
743
721
|
return {
|
|
744
|
-
body
|
|
722
|
+
body : ctx.body
|
|
745
723
|
}
|
|
746
724
|
}
|
|
747
725
|
}
|
|
@@ -1112,6 +1090,244 @@ new Spear()
|
|
|
1112
1090
|
|
|
1113
1091
|
```
|
|
1114
1092
|
|
|
1093
|
+
## Graphql
|
|
1094
|
+
GraphQL CRUD Example with graphql-http + tspace-spear
|
|
1095
|
+
|
|
1096
|
+
This example shows how to build a simple GraphQL CRUD API using graphql-http and tspace-spear.
|
|
1097
|
+
|
|
1098
|
+
It includes:
|
|
1099
|
+
|
|
1100
|
+
- GraphQL schema setup
|
|
1101
|
+
- Query and Mutation examples
|
|
1102
|
+
- Create / Read / Update / Delete operations
|
|
1103
|
+
- HTTP integration with graphql-http
|
|
1104
|
+
- cURL testing examples
|
|
1105
|
+
|
|
1106
|
+
The server uses an in-memory array as a fake database for simplicity.
|
|
1107
|
+
|
|
1108
|
+
Features
|
|
1109
|
+
- High performance HTTP server with tspace-spear
|
|
1110
|
+
- Native GraphQL schema definitions
|
|
1111
|
+
- Full CRUD operations
|
|
1112
|
+
- Simple and dependency-light setup
|
|
1113
|
+
- Works with standard GraphQL clients and tools
|
|
1114
|
+
|
|
1115
|
+
```sh
|
|
1116
|
+
npm install graphql graphql-http
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
```js
|
|
1120
|
+
|
|
1121
|
+
import {
|
|
1122
|
+
GraphQLSchema,
|
|
1123
|
+
GraphQLObjectType,
|
|
1124
|
+
GraphQLString,
|
|
1125
|
+
GraphQLList,
|
|
1126
|
+
GraphQLNonNull,
|
|
1127
|
+
GraphQLID,
|
|
1128
|
+
} from 'graphql';
|
|
1129
|
+
|
|
1130
|
+
import { createHandler } from 'graphql-http/lib/use/http';
|
|
1131
|
+
import { type T, Spear } from "tspace-spear";
|
|
1132
|
+
|
|
1133
|
+
/**
|
|
1134
|
+
* Fake database
|
|
1135
|
+
*/
|
|
1136
|
+
const users : {
|
|
1137
|
+
id : string;
|
|
1138
|
+
name : string;
|
|
1139
|
+
email :string
|
|
1140
|
+
}[] = [];
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* User Type
|
|
1144
|
+
*/
|
|
1145
|
+
const UserType = new GraphQLObjectType({
|
|
1146
|
+
name: 'User',
|
|
1147
|
+
|
|
1148
|
+
fields: {
|
|
1149
|
+
id: { type: GraphQLID },
|
|
1150
|
+
name: { type: GraphQLString },
|
|
1151
|
+
email: { type: GraphQLString },
|
|
1152
|
+
},
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Queries (READ)
|
|
1157
|
+
*/
|
|
1158
|
+
const QueryType = new GraphQLObjectType({
|
|
1159
|
+
name: 'Query',
|
|
1160
|
+
|
|
1161
|
+
fields: {
|
|
1162
|
+
users: {
|
|
1163
|
+
type: new GraphQLList(UserType),
|
|
1164
|
+
|
|
1165
|
+
resolve: () => {
|
|
1166
|
+
return users;
|
|
1167
|
+
},
|
|
1168
|
+
},
|
|
1169
|
+
|
|
1170
|
+
user: {
|
|
1171
|
+
type: UserType,
|
|
1172
|
+
|
|
1173
|
+
args: {
|
|
1174
|
+
id: { type: new GraphQLNonNull(GraphQLID) },
|
|
1175
|
+
},
|
|
1176
|
+
|
|
1177
|
+
resolve: (_, args) => {
|
|
1178
|
+
return users.find((v) => v.id === args.id);
|
|
1179
|
+
},
|
|
1180
|
+
},
|
|
1181
|
+
},
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* Mutations (CREATE UPDATE DELETE)
|
|
1186
|
+
*/
|
|
1187
|
+
const MutationType = new GraphQLObjectType({
|
|
1188
|
+
name: 'Mutation',
|
|
1189
|
+
|
|
1190
|
+
fields: {
|
|
1191
|
+
/**
|
|
1192
|
+
* CREATE
|
|
1193
|
+
*/
|
|
1194
|
+
createUser: {
|
|
1195
|
+
type: UserType,
|
|
1196
|
+
|
|
1197
|
+
args: {
|
|
1198
|
+
name: { type: new GraphQLNonNull(GraphQLString) },
|
|
1199
|
+
email: { type: new GraphQLNonNull(GraphQLString) },
|
|
1200
|
+
},
|
|
1201
|
+
|
|
1202
|
+
resolve: (_, args) => {
|
|
1203
|
+
const user = {
|
|
1204
|
+
id: String(users.length + 1),
|
|
1205
|
+
name: args.name,
|
|
1206
|
+
email: args.email,
|
|
1207
|
+
};
|
|
1208
|
+
|
|
1209
|
+
users.push(user);
|
|
1210
|
+
|
|
1211
|
+
return user;
|
|
1212
|
+
},
|
|
1213
|
+
},
|
|
1214
|
+
|
|
1215
|
+
/**
|
|
1216
|
+
* UPDATE
|
|
1217
|
+
*/
|
|
1218
|
+
updateUser: {
|
|
1219
|
+
type: UserType,
|
|
1220
|
+
|
|
1221
|
+
args: {
|
|
1222
|
+
id: { type: new GraphQLNonNull(GraphQLID) },
|
|
1223
|
+
name: { type: GraphQLString },
|
|
1224
|
+
email: { type: GraphQLString },
|
|
1225
|
+
},
|
|
1226
|
+
|
|
1227
|
+
resolve: (_, args) => {
|
|
1228
|
+
const user = users.find((v) => v.id === args.id);
|
|
1229
|
+
|
|
1230
|
+
if (!user) {
|
|
1231
|
+
throw new Error('User not found');
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
if (args.name !== undefined) {
|
|
1235
|
+
user.name = args.name;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
if (args.email !== undefined) {
|
|
1239
|
+
user.email = args.email;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
return user;
|
|
1243
|
+
},
|
|
1244
|
+
},
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* DELETE
|
|
1248
|
+
*/
|
|
1249
|
+
deleteUser: {
|
|
1250
|
+
type: GraphQLString,
|
|
1251
|
+
|
|
1252
|
+
args: {
|
|
1253
|
+
id: { type: new GraphQLNonNull(GraphQLID) },
|
|
1254
|
+
},
|
|
1255
|
+
|
|
1256
|
+
resolve: (_, args) => {
|
|
1257
|
+
const index = users.findIndex((v) => v.id === args.id);
|
|
1258
|
+
|
|
1259
|
+
if (index === -1) {
|
|
1260
|
+
throw new Error('User not found');
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
users.splice(index, 1);
|
|
1264
|
+
|
|
1265
|
+
return 'Deleted';
|
|
1266
|
+
},
|
|
1267
|
+
},
|
|
1268
|
+
},
|
|
1269
|
+
});
|
|
1270
|
+
|
|
1271
|
+
/**
|
|
1272
|
+
* Schema
|
|
1273
|
+
*/
|
|
1274
|
+
const schema = new GraphQLSchema({
|
|
1275
|
+
query: QueryType,
|
|
1276
|
+
mutation: MutationType,
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
/**
|
|
1280
|
+
* Handler
|
|
1281
|
+
*/
|
|
1282
|
+
const graphqlHandler = createHandler({
|
|
1283
|
+
schema,
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
const app = new Spear()
|
|
1287
|
+
.post('/graphql',({ req , res }) => graphqlHandler(req , res))
|
|
1288
|
+
|
|
1289
|
+
app.listen(4000 , ({ port , server }) => {
|
|
1290
|
+
console.log(`server listening on : http://localhost:${port}/graphql`)
|
|
1291
|
+
})
|
|
1292
|
+
```
|
|
1293
|
+
|
|
1294
|
+
```sh
|
|
1295
|
+
## Create
|
|
1296
|
+
curl -X POST http://localhost:4000/graphql \
|
|
1297
|
+
-H "Content-Type: application/json" \
|
|
1298
|
+
-d '{
|
|
1299
|
+
"query": "mutation { createUser(name:\"John\", email:\"john@example.com\") { id name email } }"
|
|
1300
|
+
}'
|
|
1301
|
+
|
|
1302
|
+
## Read all
|
|
1303
|
+
curl -X POST http://localhost:4000/graphql \
|
|
1304
|
+
-H "Content-Type: application/json" \
|
|
1305
|
+
-d '{
|
|
1306
|
+
"query": "query { users { id name email } }"
|
|
1307
|
+
}'
|
|
1308
|
+
|
|
1309
|
+
## Read one
|
|
1310
|
+
curl -X POST http://localhost:4000/graphql \
|
|
1311
|
+
-H "Content-Type: application/json" \
|
|
1312
|
+
-d '{
|
|
1313
|
+
"query": "query { user(id:\"1\") { id name email } }"
|
|
1314
|
+
}'
|
|
1315
|
+
|
|
1316
|
+
## Update
|
|
1317
|
+
curl -X POST http://localhost:4000/graphql \
|
|
1318
|
+
-H "Content-Type: application/json" \
|
|
1319
|
+
-d '{
|
|
1320
|
+
"query": "mutation { updateUser(id:\"1\", name:\"Johnny\") { id name email } }"
|
|
1321
|
+
}'
|
|
1322
|
+
|
|
1323
|
+
## Delete
|
|
1324
|
+
curl -X POST http://localhost:4000/graphql \
|
|
1325
|
+
-H "Content-Type: application/json" \
|
|
1326
|
+
-d '{
|
|
1327
|
+
"query": "mutation { deleteUser(id:\"1\") }"
|
|
1328
|
+
}'
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1115
1331
|
## E2E
|
|
1116
1332
|
Provides end-to-end type safety and testing support across the full request lifecycle, from request input to
|
|
1117
1333
|
response output. It allows you to:
|
|
@@ -1293,66 +1509,3 @@ const res = await client.get("/cats");
|
|
|
1293
1509
|
|
|
1294
1510
|
```
|
|
1295
1511
|
|
|
1296
|
-
## Example CRUD
|
|
1297
|
-
```js
|
|
1298
|
-
import { Spear } from "tspace-spear";
|
|
1299
|
-
|
|
1300
|
-
const spears = [
|
|
1301
|
-
{
|
|
1302
|
-
id : 1,
|
|
1303
|
-
damage : 100
|
|
1304
|
-
},
|
|
1305
|
-
{
|
|
1306
|
-
id : 2,
|
|
1307
|
-
damage : 75
|
|
1308
|
-
},
|
|
1309
|
-
{
|
|
1310
|
-
id : 3,
|
|
1311
|
-
damage : 50
|
|
1312
|
-
}
|
|
1313
|
-
]
|
|
1314
|
-
|
|
1315
|
-
new Spear()
|
|
1316
|
-
// enable body payload
|
|
1317
|
-
.useBodyParser()
|
|
1318
|
-
.get('/' , () => spears)
|
|
1319
|
-
.get('/:id' , ({ params }) => spears.find(spear => spear.id === Number(params.id ?? 0)))
|
|
1320
|
-
.post('/' , ({ body }) => {
|
|
1321
|
-
// please validation the your body
|
|
1322
|
-
const damage = Number(body.damage ?? (Math.random() * 100).toFixed(0))
|
|
1323
|
-
|
|
1324
|
-
const id = spears.reduce((max, spear) => spear.id > max ? spear.id : max, 0) + 1
|
|
1325
|
-
|
|
1326
|
-
spears.push({ id , damage })
|
|
1327
|
-
|
|
1328
|
-
return spears.find(spear => spear.id === id)
|
|
1329
|
-
})
|
|
1330
|
-
.patch('/:id' , ({ params , body , res }) => {
|
|
1331
|
-
|
|
1332
|
-
const damage = Number(body.damage ?? (Math.random() * 100).toFixed(0))
|
|
1333
|
-
|
|
1334
|
-
const id = Number(params.id)
|
|
1335
|
-
|
|
1336
|
-
const spear = spears.find(spear => spear.id === id)
|
|
1337
|
-
|
|
1338
|
-
if (spear == null) return res.status(404).json({ message : 'Spear not found'})
|
|
1339
|
-
|
|
1340
|
-
spear.damage = damage;
|
|
1341
|
-
|
|
1342
|
-
return spears.find(spear => spear.id === id)
|
|
1343
|
-
})
|
|
1344
|
-
.delete('/:id', ({ params , res }) => {
|
|
1345
|
-
|
|
1346
|
-
const id = Number(params.id)
|
|
1347
|
-
|
|
1348
|
-
const spear = spears.find(spear => spear.id === id)
|
|
1349
|
-
|
|
1350
|
-
if (spear == null) return res.status(404).json({ message : 'Spear not found'})
|
|
1351
|
-
|
|
1352
|
-
spears.splice(spears.findIndex(spear => spear.id === Number(params.id ?? 0)), 1)
|
|
1353
|
-
|
|
1354
|
-
return res.status(204).json()
|
|
1355
|
-
})
|
|
1356
|
-
.listen(8000 , () => console.log(`Server is now listening http://localhost:8000`))
|
|
1357
|
-
|
|
1358
|
-
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createApp(inputPath?: string): Promise<void>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createApp = createApp;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
const template_1 = require("./template");
|
|
11
|
+
const template_2 = require("../client/template");
|
|
12
|
+
const template_3 = require("../middleware/template");
|
|
13
|
+
const template_4 = require("../controller/template");
|
|
14
|
+
const template_5 = require("../service/template");
|
|
15
|
+
const template_6 = require("../dto/template");
|
|
16
|
+
const c = {
|
|
17
|
+
bold: (text) => `\x1b[1m${text}\x1b[0m`,
|
|
18
|
+
dim: (text) => `\x1b[2m${text}\x1b[0m`,
|
|
19
|
+
green: (text) => `\x1b[32m${text}\x1b[0m`,
|
|
20
|
+
cyan: (text) => `\x1b[36m${text}\x1b[0m`,
|
|
21
|
+
underline: (text) => `\x1b[4m${text}\x1b[0m`,
|
|
22
|
+
gray: (text) => `\x1b[90m${text}\x1b[0m`,
|
|
23
|
+
reset: "\x1b[0m"
|
|
24
|
+
};
|
|
25
|
+
async function createApp(inputPath) {
|
|
26
|
+
if (!inputPath) {
|
|
27
|
+
console.log("Missing target path, try: spear g app src");
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
const root = path_1.default.resolve(process.cwd(), inputPath);
|
|
31
|
+
fs_1.default.mkdirSync(root, { recursive: true });
|
|
32
|
+
await fs_1.default.promises.writeFile(path_1.default.join(root, "package.json"), JSON.stringify({
|
|
33
|
+
name: path_1.default.basename(root),
|
|
34
|
+
version: "1.0.0",
|
|
35
|
+
main: "dist/index.js",
|
|
36
|
+
scripts: {
|
|
37
|
+
build: "tsc",
|
|
38
|
+
start: "node dist/index.js",
|
|
39
|
+
dev: "ts-node src/index.ts",
|
|
40
|
+
},
|
|
41
|
+
dependencies: {
|
|
42
|
+
"tspace-spear": "latest",
|
|
43
|
+
"class-transformer": "0.5.1",
|
|
44
|
+
"class-validator": "0.15.1"
|
|
45
|
+
},
|
|
46
|
+
devDependencies: {
|
|
47
|
+
"typescript": "5.6.2",
|
|
48
|
+
"ts-node": "10.9.2",
|
|
49
|
+
"@types/node": "16.18.126"
|
|
50
|
+
},
|
|
51
|
+
}, null, 2));
|
|
52
|
+
await fs_1.default.promises.writeFile(path_1.default.join(root, "tsconfig.json"), JSON.stringify({
|
|
53
|
+
compilerOptions: {
|
|
54
|
+
"target": "esnext",
|
|
55
|
+
"module": "commonjs",
|
|
56
|
+
"lib": ["esnext", "DOM"],
|
|
57
|
+
"types": ["node"],
|
|
58
|
+
"allowJs": true,
|
|
59
|
+
"checkJs": false,
|
|
60
|
+
"outDir": "dist",
|
|
61
|
+
"rootDir": "src",
|
|
62
|
+
"strict": true,
|
|
63
|
+
"esModuleInterop": true,
|
|
64
|
+
"skipLibCheck": true,
|
|
65
|
+
"forceConsistentCasingInFileNames": true,
|
|
66
|
+
"emitDecoratorMetadata": true,
|
|
67
|
+
"experimentalDecorators": true,
|
|
68
|
+
},
|
|
69
|
+
}, null, 2));
|
|
70
|
+
const src = path_1.default.join(root, "src");
|
|
71
|
+
await fs_1.default.promises.mkdir(src, { recursive: true });
|
|
72
|
+
await fs_1.default.promises.mkdir(path_1.default.join(src, "common", "middlewares"), { recursive: true });
|
|
73
|
+
await fs_1.default.promises.mkdir(path_1.default.join(src, "modules", "cats"), { recursive: true });
|
|
74
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "index.ts"), template_1.AppTemplate);
|
|
75
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "client.ts"), template_2.ClientTemplate);
|
|
76
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "common", "middlewares", "log.middleware.ts"), template_3.MiddlewareTemplate);
|
|
77
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "modules", "cats", "cat.controller.ts"), template_4.ControllerTemplate);
|
|
78
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "modules", "cats", "cat.service.ts"), template_5.ServiceTemplate);
|
|
79
|
+
await fs_1.default.promises.writeFile(path_1.default.join(src, "modules", "cats", "cat.dto.ts"), template_6.DtoTemplate);
|
|
80
|
+
console.log(`\n${c.bold("$ npm install")}\n`);
|
|
81
|
+
const startTime = Date.now();
|
|
82
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
83
|
+
let i = 0;
|
|
84
|
+
const spinner = setInterval(() => {
|
|
85
|
+
process.stdout.write(`\r ${c.cyan(frames[i])} Installing dependencies...`);
|
|
86
|
+
i = (i + 1) % frames.length;
|
|
87
|
+
}, 50);
|
|
88
|
+
await new Promise((resolve, reject) => {
|
|
89
|
+
(0, child_process_1.exec)("npm install", { cwd: root }, (error) => {
|
|
90
|
+
if (error)
|
|
91
|
+
return reject(error);
|
|
92
|
+
return resolve();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
96
|
+
const nodeModulesPath = path_1.default.join(root, "node_modules");
|
|
97
|
+
let totalPhysicalPackages = 0;
|
|
98
|
+
if (fs_1.default.existsSync(nodeModulesPath)) {
|
|
99
|
+
const files = await fs_1.default.promises.readdir(nodeModulesPath);
|
|
100
|
+
const packages = files.filter(file => !file.startsWith(".") && !file.startsWith("@"));
|
|
101
|
+
totalPhysicalPackages = packages.length;
|
|
102
|
+
}
|
|
103
|
+
clearInterval(spinner);
|
|
104
|
+
process.stdout.write("\r\x1b[K");
|
|
105
|
+
const endTime = Date.now();
|
|
106
|
+
const elapsedSeconds = ((endTime - startTime) / 1000).toFixed(2);
|
|
107
|
+
console.log(`${c.bold(c.cyan("dependencies"))}`);
|
|
108
|
+
console.log(`${c.gray("├──")} ${c.green("+")} tspace-spear${c.dim("@latest")}`);
|
|
109
|
+
console.log(`${c.gray("├──")} ${c.green("+")} class-transformer${c.dim("@0.5.1")}`);
|
|
110
|
+
console.log(`${c.gray("└──")} ${c.green("+")} class-validator${c.dim("@0.15.1")}`);
|
|
111
|
+
console.log(`${c.gray("│")}`);
|
|
112
|
+
console.log(`${c.bold(c.gray("devDependencies"))}`);
|
|
113
|
+
console.log(`${c.gray("├──")} ${c.green("+")} typescript${c.dim("@5.6.2")}`);
|
|
114
|
+
console.log(`${c.gray("├──")} ${c.green("+")} ts-node${c.dim("@10.9.2")}`);
|
|
115
|
+
console.log(`${c.gray("└──")} ${c.green("+")} @types/node${c.dim("@16.18.126")}\n`);
|
|
116
|
+
console.log(`\n${c.green(`${totalPhysicalPackages} packages installed`)} ${c.dim(`[${elapsedSeconds}s]`)}`);
|
|
117
|
+
console.log(`${c.dim(`[${elapsedSeconds}s] npm install`)}`);
|
|
118
|
+
console.log(`\n--------`);
|
|
119
|
+
console.log("A local project was created for you and dependencies were installed automatically.\n");
|
|
120
|
+
console.log(`${c.green("Created spear project successfully")}\n`);
|
|
121
|
+
console.log(c.bold(c.gray("# To get started, run:")));
|
|
122
|
+
console.log(`\n cd ${inputPath}\n ${c.cyan("npm run dev")}\n`);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cli/generators/app/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AppTemplate = "\nimport Spear from \"tspace-spear\";\n\nconst app = new Spear({\n logger: true,\n controllers: {\n folder: `${__dirname}/modules/*`,\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.cors({\n origins: [ \n /^http:\\/\\/localhost:\\d+$/ \n ],\n credentials: true\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;\n\nexport { AppRouter };\nexport { app };\nexport default app;\n";
|