gg-express 1.0.79 → 1.0.83
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/dist/main.d.ts +3 -0
- package/dist/main.js +10 -0
- package/dist/run.test.js +14 -6
- package/dist/v2/GGExpressV2.d.ts +38 -0
- package/dist/v2/GGExpressV2.js +76 -0
- package/dist/v2/generateGGApi_v2.d.ts +1 -0
- package/dist/v2/generateGGApi_v2.js +81 -0
- package/dist/v2/generateStaticRouteFileV2.d.ts +19 -0
- package/dist/v2/generateStaticRouteFileV2.js +100 -0
- package/dist/v2/output/apiConnector_hotel_v2.d.ts +8 -0
- package/dist/v2/output/apiConnector_hotel_v2.js +59 -0
- package/dist/v2/output/staticRouteInterface_hotel_v2.d.ts +42 -0
- package/dist/v2/output/staticRouteInterface_hotel_v2.js +2 -0
- package/dist/v2/run_v2.test.d.ts +1 -0
- package/dist/v2/run_v2.test.js +78 -0
- package/dist/v2/typeResolver.d.ts +23 -0
- package/dist/v2/typeResolver.js +15 -0
- package/package.json +3 -3
- package/src/main.ts +3 -0
- package/src/run.test.ts +5 -6
- package/src/v2/GGExpressV2.ts +192 -0
- package/src/v2/generateGGApi_v2.ts +79 -0
- package/src/v2/generateStaticRouteFileV2.ts +127 -0
- package/src/v2/output/apiConnector_hotel_v2.ts +68 -0
- package/src/v2/output/staticRouteInterface_hotel_v2.ts +32 -0
- package/src/v2/run_v2.test.ts +74 -0
- package/src/v2/typeResolver.ts +110 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { NextFunction, Request, Response } from "express"
|
|
2
|
+
import Express from "express-serve-static-core"
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
import { convertRoot, InputParent } from "./typeResolver"
|
|
5
|
+
import { generateStaticRouteFileV2 } from "./generateStaticRouteFileV2"
|
|
6
|
+
import path from "path"
|
|
7
|
+
import { generateGGApi_v2 } from "./generateGGApi_v2"
|
|
8
|
+
|
|
9
|
+
type Unarray<T> = T extends (infer U)[] ? U : T
|
|
10
|
+
export type Method = "get" | "post" | "put" | "delete"
|
|
11
|
+
|
|
12
|
+
type MyRequest<M extends Method, RQ extends InputParent> = M extends "get"
|
|
13
|
+
? //get
|
|
14
|
+
convertRoot<MyRequestQuery<RQ>>
|
|
15
|
+
: // post, put, delete
|
|
16
|
+
convertRoot<MyRequestBody<RQ>>
|
|
17
|
+
|
|
18
|
+
type MyRequestQuery<T extends InputParent> = Request<{}, {}, {}, T, {}>
|
|
19
|
+
type MyRequestBody<T extends InputParent> = Request<{}, {}, T, {}, {}>
|
|
20
|
+
|
|
21
|
+
type MyResponse<T extends InputParent> = Response<{
|
|
22
|
+
status: "SUCCESS" | "ERROR" | "SERVER_ERROR"
|
|
23
|
+
message: string
|
|
24
|
+
data: convertRoot<T>
|
|
25
|
+
}>
|
|
26
|
+
|
|
27
|
+
const myExpressRouteList: {
|
|
28
|
+
method: "get" | "post" | "put" | "delete"
|
|
29
|
+
url: string
|
|
30
|
+
requireParams: InputParent
|
|
31
|
+
responseStructure: InputParent
|
|
32
|
+
}[] = []
|
|
33
|
+
|
|
34
|
+
export default class GGExpressV2<appName extends string> {
|
|
35
|
+
public express: Express.Express
|
|
36
|
+
private outputPath: string[]
|
|
37
|
+
appName: string
|
|
38
|
+
constructor(app: Express.Express, appName: appName, outputPath: string[]) {
|
|
39
|
+
this.express = app
|
|
40
|
+
this.outputPath = outputPath
|
|
41
|
+
this.appName = appName
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private rootMethod<
|
|
45
|
+
M extends Method,
|
|
46
|
+
RQ extends InputParent,
|
|
47
|
+
RS extends InputParent
|
|
48
|
+
>(
|
|
49
|
+
method: M,
|
|
50
|
+
url: string | string[],
|
|
51
|
+
options: {
|
|
52
|
+
requireParams: RQ
|
|
53
|
+
responseStructure: RS
|
|
54
|
+
},
|
|
55
|
+
...middlewares: Array<
|
|
56
|
+
(
|
|
57
|
+
req: MyRequest<M, RQ>,
|
|
58
|
+
res: MyResponse<RS>,
|
|
59
|
+
next: NextFunction
|
|
60
|
+
) => void | Promise<void>
|
|
61
|
+
>
|
|
62
|
+
): Express.Express {
|
|
63
|
+
let tempURL
|
|
64
|
+
if (Array.isArray(url)) {
|
|
65
|
+
tempURL = url
|
|
66
|
+
} else {
|
|
67
|
+
tempURL = [url]
|
|
68
|
+
}
|
|
69
|
+
tempURL.map((url) => {
|
|
70
|
+
myExpressRouteList.push({
|
|
71
|
+
method: method,
|
|
72
|
+
url: url,
|
|
73
|
+
requireParams: options.requireParams,
|
|
74
|
+
responseStructure: {
|
|
75
|
+
...options.responseStructure,
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return this.express[method](
|
|
81
|
+
url,
|
|
82
|
+
// Express handler ต้องกว้าง
|
|
83
|
+
(req: Request, res: Response, next: NextFunction) => next(),
|
|
84
|
+
|
|
85
|
+
// แต่ middleware ของคุณจะถูก wrap ทีละตัว
|
|
86
|
+
...middlewares.map(
|
|
87
|
+
(mw) =>
|
|
88
|
+
((req: Request, res: Response, next: NextFunction) =>
|
|
89
|
+
mw(
|
|
90
|
+
req as unknown as MyRequest<M, RQ>,
|
|
91
|
+
res as MyResponse<RS>,
|
|
92
|
+
next
|
|
93
|
+
)) as Express.RequestHandler
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
get<RQ extends InputParent, RS extends InputParent>(
|
|
98
|
+
url:
|
|
99
|
+
| `/api/${appName | "seed"}/${string}`
|
|
100
|
+
| `/api/${appName | "seed"}/${string}`[],
|
|
101
|
+
options: {
|
|
102
|
+
requireParams: RQ
|
|
103
|
+
responseStructure: RS
|
|
104
|
+
},
|
|
105
|
+
...middlewares: Array<
|
|
106
|
+
(
|
|
107
|
+
req: MyRequest<"get", RQ>,
|
|
108
|
+
res: MyResponse<RS>,
|
|
109
|
+
next: NextFunction
|
|
110
|
+
) => any
|
|
111
|
+
>
|
|
112
|
+
) {
|
|
113
|
+
return this.rootMethod("get", url, options, ...middlewares)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
post<RQ extends InputParent, RS extends InputParent>(
|
|
117
|
+
url:
|
|
118
|
+
| `/api/${appName | "seed"}/${string}`
|
|
119
|
+
| `/api/${appName | "seed"}/${string}`[],
|
|
120
|
+
options: {
|
|
121
|
+
requireParams: RQ
|
|
122
|
+
responseStructure: RS
|
|
123
|
+
},
|
|
124
|
+
...middlewares: Array<
|
|
125
|
+
(
|
|
126
|
+
req: MyRequest<"post", RQ>,
|
|
127
|
+
res: MyResponse<RS>,
|
|
128
|
+
next: NextFunction
|
|
129
|
+
) => any
|
|
130
|
+
>
|
|
131
|
+
) {
|
|
132
|
+
return this.rootMethod("post", url, options, ...middlewares)
|
|
133
|
+
}
|
|
134
|
+
put<RQ extends InputParent, RS extends InputParent>(
|
|
135
|
+
url:
|
|
136
|
+
| `/api/${appName | "seed"}/${string}`
|
|
137
|
+
| `/api/${appName | "seed"}/${string}`[],
|
|
138
|
+
options: {
|
|
139
|
+
requireParams: RQ
|
|
140
|
+
responseStructure: RS
|
|
141
|
+
},
|
|
142
|
+
...middlewares: Array<
|
|
143
|
+
(
|
|
144
|
+
req: MyRequest<"put", RQ>,
|
|
145
|
+
res: MyResponse<RS>,
|
|
146
|
+
next: NextFunction
|
|
147
|
+
) => any
|
|
148
|
+
>
|
|
149
|
+
) {
|
|
150
|
+
return this.rootMethod("put", url, options, ...middlewares)
|
|
151
|
+
}
|
|
152
|
+
delete<RQ extends InputParent, RS extends InputParent>(
|
|
153
|
+
url:
|
|
154
|
+
| `/api/${appName | "seed"}/${string}`
|
|
155
|
+
| `/api/${appName | "seed"}/${string}`[],
|
|
156
|
+
options: {
|
|
157
|
+
requireParams: RQ
|
|
158
|
+
responseStructure: RS
|
|
159
|
+
},
|
|
160
|
+
...middlewares: Array<
|
|
161
|
+
(
|
|
162
|
+
req: MyRequest<"delete", RQ>,
|
|
163
|
+
res: MyResponse<RS>,
|
|
164
|
+
next: NextFunction
|
|
165
|
+
) => any
|
|
166
|
+
>
|
|
167
|
+
) {
|
|
168
|
+
return this.rootMethod("delete", url, options, ...middlewares)
|
|
169
|
+
}
|
|
170
|
+
public async generateAPIFiles() {
|
|
171
|
+
await this.generateStaticRouteFile()
|
|
172
|
+
console.log(`GGExpressV2.ts : ${this.appName} - generate staticRoute done.`)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private async generateStaticRouteFile() {
|
|
176
|
+
const staticRouteCode = generateStaticRouteFileV2(
|
|
177
|
+
this.appName,
|
|
178
|
+
myExpressRouteList
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
for (let row of this.outputPath) {
|
|
182
|
+
fs.writeFileSync(
|
|
183
|
+
path.join(row, `staticRouteInterface_${this.appName}_v2.ts`),
|
|
184
|
+
staticRouteCode
|
|
185
|
+
)
|
|
186
|
+
await generateGGApi_v2(
|
|
187
|
+
this.appName,
|
|
188
|
+
path.join(row, `apiConnector_${this.appName}_v2.ts`)
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from "fs"
|
|
2
|
+
|
|
3
|
+
export function generateGGApi_v2(
|
|
4
|
+
appName: string,
|
|
5
|
+
filePathWithFileName: string
|
|
6
|
+
) {
|
|
7
|
+
const tempInterfaceName = `staticRouteInterface_${appName}_v2`
|
|
8
|
+
const code = `
|
|
9
|
+
import axios from "axios"
|
|
10
|
+
import { ${tempInterfaceName} } from "./${tempInterfaceName}"
|
|
11
|
+
|
|
12
|
+
export class GGApi_v2 {
|
|
13
|
+
constructor() {}
|
|
14
|
+
|
|
15
|
+
get<T extends keyof ${tempInterfaceName}["get"]>(
|
|
16
|
+
url: T,
|
|
17
|
+
requireParams: ${tempInterfaceName}["get"][T]["requireParams"]
|
|
18
|
+
): Promise<${tempInterfaceName}["get"][T]["responseStructure"]> {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
axios
|
|
21
|
+
.get(url as string, { params: requireParams })
|
|
22
|
+
.then((response) => {
|
|
23
|
+
resolve(response.data)
|
|
24
|
+
})
|
|
25
|
+
.catch((error) => {
|
|
26
|
+
reject(error)
|
|
27
|
+
})
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
post<T extends keyof ${tempInterfaceName}["post"]>(
|
|
32
|
+
url: T,
|
|
33
|
+
requireParams: ${tempInterfaceName}["post"][T]["requireParams"]
|
|
34
|
+
): Promise<${tempInterfaceName}["post"][T]["responseStructure"]> {
|
|
35
|
+
return new Promise((resolve, reject) => {
|
|
36
|
+
axios
|
|
37
|
+
.post(url as string, { data: requireParams })
|
|
38
|
+
.then((response) => {
|
|
39
|
+
resolve(response.data)
|
|
40
|
+
})
|
|
41
|
+
.catch((error) => {
|
|
42
|
+
reject(error)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
put<T extends keyof ${tempInterfaceName}["put"]>(
|
|
47
|
+
url: T,
|
|
48
|
+
requireParams: ${tempInterfaceName}["put"][T]["requireParams"]
|
|
49
|
+
): Promise<${tempInterfaceName}["put"][T]["responseStructure"]> {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
axios
|
|
52
|
+
.put(url as string, { data: requireParams })
|
|
53
|
+
.then((response) => {
|
|
54
|
+
resolve(response.data)
|
|
55
|
+
})
|
|
56
|
+
.catch((error) => {
|
|
57
|
+
reject(error)
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
delete<T extends keyof ${tempInterfaceName}["delete"]>(
|
|
62
|
+
url: T,
|
|
63
|
+
requireParams: ${tempInterfaceName}["delete"][T]["requireParams"]
|
|
64
|
+
): Promise<${tempInterfaceName}["delete"][T]["responseStructure"]> {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
axios
|
|
67
|
+
.delete(url as string, { data: { data: requireParams } })
|
|
68
|
+
.then((response) => {
|
|
69
|
+
resolve(response.data)
|
|
70
|
+
})
|
|
71
|
+
.catch((error) => {
|
|
72
|
+
reject(error)
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`
|
|
78
|
+
fs.writeFileSync(filePathWithFileName, code)
|
|
79
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Method } from "./GGExpressV2"
|
|
2
|
+
import { CustomType, InputNest, InputParent, toArray } from "./typeResolver"
|
|
3
|
+
import fs from "fs"
|
|
4
|
+
type routeList = {
|
|
5
|
+
method: Method
|
|
6
|
+
url: string
|
|
7
|
+
requireParams: InputParent
|
|
8
|
+
responseStructure: InputParent
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type PrepareRouteStucture = {
|
|
12
|
+
[K in Method]: {
|
|
13
|
+
[key in string]: {
|
|
14
|
+
requireParams: string
|
|
15
|
+
responseStructure: string
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type MyResponse = {
|
|
21
|
+
[url in string]: {}
|
|
22
|
+
}
|
|
23
|
+
export function prepareExportInterfaceData(data: routeList[]) {
|
|
24
|
+
let prepareRoute: PrepareRouteStucture = {
|
|
25
|
+
get: {},
|
|
26
|
+
post: {},
|
|
27
|
+
put: {},
|
|
28
|
+
delete: {},
|
|
29
|
+
}
|
|
30
|
+
prepareRoute = extract(data, prepareRoute)
|
|
31
|
+
return prepareRoute
|
|
32
|
+
}
|
|
33
|
+
function extract(
|
|
34
|
+
allData: routeList[],
|
|
35
|
+
prepareRoute: PrepareRouteStucture
|
|
36
|
+
): PrepareRouteStucture {
|
|
37
|
+
for (const route of allData) {
|
|
38
|
+
prepareRoute[route.method][route.url] = {
|
|
39
|
+
requireParams: parentInputToCode(route.requireParams),
|
|
40
|
+
responseStructure: parentInputToCode(route.responseStructure),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return prepareRoute
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function parentInputToCode(data: InputParent) {
|
|
48
|
+
const recursiveExtract = (target: InputParent, parentKeyName: string) => {
|
|
49
|
+
let result = ""
|
|
50
|
+
// check nest pimitive -------------------
|
|
51
|
+
if (typeof target === "string") {
|
|
52
|
+
const isUndefinedAble = (target as string).includes("?")
|
|
53
|
+
? "undefined"
|
|
54
|
+
: ""
|
|
55
|
+
const isNullAble = (target as string).includes("~") ? "null" : ""
|
|
56
|
+
const isArray = (target as string).includes("[]") ? "[]" : ""
|
|
57
|
+
const varType = (target as string).replace(/\[\]|\?|\~/g, "")
|
|
58
|
+
let result = [`${varType}`, isUndefinedAble, isNullAble]
|
|
59
|
+
.filter((row) => row !== "")
|
|
60
|
+
.join(" | ")
|
|
61
|
+
if (isArray) result = `(${result})[]`
|
|
62
|
+
else result
|
|
63
|
+
return `${parentKeyName} : ${result}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// check object ---------------------------
|
|
67
|
+
else if (typeof target === "object" && Array.isArray(target) === false) {
|
|
68
|
+
const keyList = Object.keys(target)
|
|
69
|
+
const tempResult = []
|
|
70
|
+
for (const keyName of keyList) {
|
|
71
|
+
//@ts-ignore
|
|
72
|
+
const recusiveResult = recursiveExtract(target[keyName], keyName)
|
|
73
|
+
tempResult.push(recusiveResult)
|
|
74
|
+
}
|
|
75
|
+
result = `${result} \n ${parentKeyName} : { ${tempResult.join(",")} }`
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// check array ---------------------------
|
|
79
|
+
else if (Array.isArray(target)) {
|
|
80
|
+
// enum
|
|
81
|
+
if (
|
|
82
|
+
typeof target[0] === "number" ||
|
|
83
|
+
typeof target[0] === "string" ||
|
|
84
|
+
target[0] === null ||
|
|
85
|
+
target[0] === undefined
|
|
86
|
+
)
|
|
87
|
+
return `${parentKeyName} : [${(target as string[])
|
|
88
|
+
.map((word) => ` "${word}" `)
|
|
89
|
+
.join(",")}] `
|
|
90
|
+
// nest or input nest
|
|
91
|
+
else if (typeof target[0] === "object")
|
|
92
|
+
for (const row of target as InputNest[] | InputParent[]) {
|
|
93
|
+
result = result + " " + recursiveExtract(row, parentKeyName) + "[] "
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return `${result}`
|
|
97
|
+
}
|
|
98
|
+
const result = recursiveExtract(data, "data")
|
|
99
|
+
return `${result} `
|
|
100
|
+
}
|
|
101
|
+
export function generateStaticRouteFileV2(appName: string, data: routeList[]) {
|
|
102
|
+
const interfaceName = `staticRouteInterface_${appName}_v2`
|
|
103
|
+
const generateEachUrl = (data: PrepareRouteStucture[Method]) => {
|
|
104
|
+
const keyName = Object.keys(data)
|
|
105
|
+
return keyName
|
|
106
|
+
.map(
|
|
107
|
+
(keyName) => `
|
|
108
|
+
"${keyName}" : {
|
|
109
|
+
requireParams : { ${data[keyName].requireParams} },
|
|
110
|
+
responseStructure : { ${data[keyName].responseStructure},
|
|
111
|
+
status: "SUCCESS" | "ERROR",
|
|
112
|
+
message: string }
|
|
113
|
+
}`
|
|
114
|
+
)
|
|
115
|
+
.join(", ")
|
|
116
|
+
}
|
|
117
|
+
const preparedData = prepareExportInterfaceData(data)
|
|
118
|
+
let code = `
|
|
119
|
+
export interface ${interfaceName} {
|
|
120
|
+
get : { ${generateEachUrl(preparedData.get)} },
|
|
121
|
+
post : { ${generateEachUrl(preparedData.post)} },
|
|
122
|
+
put : { ${generateEachUrl(preparedData.put)} },
|
|
123
|
+
delete : { ${generateEachUrl(preparedData.delete)} },
|
|
124
|
+
}
|
|
125
|
+
`
|
|
126
|
+
return code
|
|
127
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import axios from "axios"
|
|
2
|
+
import { staticRouteInterface_hotel_v2 } from "./staticRouteInterface_hotel_v2"
|
|
3
|
+
|
|
4
|
+
export class GGApi_v2 {
|
|
5
|
+
constructor() {}
|
|
6
|
+
|
|
7
|
+
get<T extends keyof staticRouteInterface_hotel_v2["get"]>(
|
|
8
|
+
url: T,
|
|
9
|
+
requireParams: staticRouteInterface_hotel_v2["get"][T]["requireParams"]
|
|
10
|
+
): Promise<staticRouteInterface_hotel_v2["get"][T]["responseStructure"]> {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
axios
|
|
13
|
+
.get(url as string, { params: { data: requireParams } })
|
|
14
|
+
.then((response) => {
|
|
15
|
+
resolve(response.data)
|
|
16
|
+
})
|
|
17
|
+
.catch((error) => {
|
|
18
|
+
reject(error)
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
post<T extends keyof staticRouteInterface_hotel_v2["post"]>(
|
|
24
|
+
url: T,
|
|
25
|
+
requireParams: staticRouteInterface_hotel_v2["post"][T]["requireParams"]
|
|
26
|
+
): Promise<staticRouteInterface_hotel_v2["post"][T]["responseStructure"]> {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
axios
|
|
29
|
+
.post(url as string, { data: requireParams })
|
|
30
|
+
.then((response) => {
|
|
31
|
+
resolve(response.data)
|
|
32
|
+
})
|
|
33
|
+
.catch((error) => {
|
|
34
|
+
reject(error)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
put<T extends keyof staticRouteInterface_hotel_v2["put"]>(
|
|
39
|
+
url: T,
|
|
40
|
+
requireParams: staticRouteInterface_hotel_v2["put"][T]["requireParams"]
|
|
41
|
+
): Promise<staticRouteInterface_hotel_v2["put"][T]["responseStructure"]> {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
axios
|
|
44
|
+
.put(url as string, { data: requireParams })
|
|
45
|
+
.then((response) => {
|
|
46
|
+
resolve(response.data)
|
|
47
|
+
})
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
reject(error)
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
delete<T extends keyof staticRouteInterface_hotel_v2["delete"]>(
|
|
54
|
+
url: T,
|
|
55
|
+
requireParams: staticRouteInterface_hotel_v2["delete"][T]["requireParams"]
|
|
56
|
+
): Promise<staticRouteInterface_hotel_v2["delete"][T]["responseStructure"]> {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
axios
|
|
59
|
+
.delete(url as string, { data: { data: requireParams } })
|
|
60
|
+
.then((response) => {
|
|
61
|
+
resolve(response.data)
|
|
62
|
+
})
|
|
63
|
+
.catch((error) => {
|
|
64
|
+
reject(error)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface staticRouteInterface_hotel_v2 {
|
|
2
|
+
get: {
|
|
3
|
+
"/api/hotel/users/id": {
|
|
4
|
+
requireParams: {
|
|
5
|
+
data: { id: number }
|
|
6
|
+
}
|
|
7
|
+
responseStructure: {
|
|
8
|
+
data: {
|
|
9
|
+
userData: { id: number; name: string }[]
|
|
10
|
+
}
|
|
11
|
+
status: "SUCCESS" | "ERROR"
|
|
12
|
+
message: string
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
post: {
|
|
17
|
+
"/api/hotel/booking/id": {
|
|
18
|
+
requireParams: {
|
|
19
|
+
data: { id: number }
|
|
20
|
+
}
|
|
21
|
+
responseStructure: {
|
|
22
|
+
data: {
|
|
23
|
+
bookingData: { id: number; roomNumber: string }
|
|
24
|
+
}
|
|
25
|
+
status: "SUCCESS" | "ERROR"
|
|
26
|
+
message: string
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
put: {}
|
|
31
|
+
delete: {}
|
|
32
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import express, { Express } from "express"
|
|
2
|
+
import GGExpressV2 from "./GGExpressV2"
|
|
3
|
+
import { toArray } from "./typeResolver"
|
|
4
|
+
import { GGApi_v2 } from "./output/apiConnector_hotel_v2"
|
|
5
|
+
// import { GGApi_v2 } from "./output/apiConnector_hotel_v2"
|
|
6
|
+
function run() {
|
|
7
|
+
const app = express()
|
|
8
|
+
const ggapp = new GGExpressV2<"hotel">(app, "hotel", ["./output"])
|
|
9
|
+
ggapp.get(
|
|
10
|
+
"/api/hotel/users/id",
|
|
11
|
+
{
|
|
12
|
+
requireParams: {
|
|
13
|
+
id: "number",
|
|
14
|
+
},
|
|
15
|
+
responseStructure: {
|
|
16
|
+
userData: toArray({
|
|
17
|
+
id: "number",
|
|
18
|
+
name: "string",
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
(req, res, next) => {
|
|
23
|
+
console.log(req.query)
|
|
24
|
+
req.query.id
|
|
25
|
+
return res.json({
|
|
26
|
+
message: "",
|
|
27
|
+
status: "SUCCESS",
|
|
28
|
+
data: { userData: [] },
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
ggapp.post(
|
|
33
|
+
"/api/hotel/booking/id",
|
|
34
|
+
{
|
|
35
|
+
requireParams: {
|
|
36
|
+
id: "number",
|
|
37
|
+
},
|
|
38
|
+
responseStructure: {
|
|
39
|
+
bookingData: {
|
|
40
|
+
id: "number",
|
|
41
|
+
roomNumber: "string",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
(req, res, next) => {
|
|
46
|
+
return res.json({
|
|
47
|
+
message: "",
|
|
48
|
+
status: "SUCCESS",
|
|
49
|
+
data: {
|
|
50
|
+
bookingData: {
|
|
51
|
+
id: 2,
|
|
52
|
+
roomNumber: "dd",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
app.listen(3002, async () => {
|
|
60
|
+
await ggapp.generateAPIFiles()
|
|
61
|
+
console.log("done")
|
|
62
|
+
process.exit(0)
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
run()
|
|
66
|
+
|
|
67
|
+
const x = new GGApi_v2()
|
|
68
|
+
x.post("/api/hotel/booking/id", {
|
|
69
|
+
data: { id: 1 },
|
|
70
|
+
}).then((response) => {
|
|
71
|
+
response.status === "ERROR"
|
|
72
|
+
response.data.bookingData
|
|
73
|
+
response.data.bookingData.roomNumber
|
|
74
|
+
})
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
type BaseType = "string" | "number" | "string[]" | "number[]"
|
|
2
|
+
export type CustomType =
|
|
3
|
+
| BaseType
|
|
4
|
+
| `${BaseType}?`
|
|
5
|
+
| `${BaseType}~`
|
|
6
|
+
| `${BaseType}?~`
|
|
7
|
+
|
|
8
|
+
export type InputNest = { [key in string]: CustomType }
|
|
9
|
+
type InputEnum = string[] | number[]
|
|
10
|
+
export type InputParent = {
|
|
11
|
+
[key in string]:
|
|
12
|
+
| CustomType
|
|
13
|
+
| InputNest
|
|
14
|
+
| InputNest[]
|
|
15
|
+
| InputParent
|
|
16
|
+
| InputParent[]
|
|
17
|
+
| InputEnum
|
|
18
|
+
}
|
|
19
|
+
type ResolveBase<T extends BaseType> = T extends "string"
|
|
20
|
+
? string
|
|
21
|
+
: T extends "string[]"
|
|
22
|
+
? string[]
|
|
23
|
+
: T extends "number"
|
|
24
|
+
? number
|
|
25
|
+
: T extends "number[]"
|
|
26
|
+
? number[]
|
|
27
|
+
: never
|
|
28
|
+
|
|
29
|
+
export const toArray = <T extends InputParent>(input: T) => {
|
|
30
|
+
return [input]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// let req2 = {
|
|
34
|
+
// booking: {
|
|
35
|
+
// id: "number",
|
|
36
|
+
// bookingGroupID: "number",
|
|
37
|
+
// checkInDate: "string",
|
|
38
|
+
// checkOutDate: "string",
|
|
39
|
+
// checkInTime: "string",
|
|
40
|
+
// checkOutTime: "string",
|
|
41
|
+
// roomRate: "number",
|
|
42
|
+
// extraBedRate: "number",
|
|
43
|
+
// roomNumber: "string",
|
|
44
|
+
// editTime: "string",
|
|
45
|
+
// createTime: "string",
|
|
46
|
+
// shiftDate: "string",
|
|
47
|
+
// shiftName: "string",
|
|
48
|
+
// userName: "string",
|
|
49
|
+
// bookingStatus: ["ACTIVE", "CLOSE", "CANCEL", "NO_SHOW"],
|
|
50
|
+
// is_specificRoom: "number",
|
|
51
|
+
// guestCount: "number",
|
|
52
|
+
// reasonToCancel: "string",
|
|
53
|
+
// note: "string",
|
|
54
|
+
// },
|
|
55
|
+
// status: ["ACTIVE", "DISABLE"],
|
|
56
|
+
// rooms: toArray({
|
|
57
|
+
// id: "number",
|
|
58
|
+
// status: ["ON", "OFF"],
|
|
59
|
+
// roomNumber: "string",
|
|
60
|
+
// log: toArray({
|
|
61
|
+
// time: "string",
|
|
62
|
+
// logger: [{ info: "string" }],
|
|
63
|
+
// }),
|
|
64
|
+
// }),
|
|
65
|
+
|
|
66
|
+
// data: {
|
|
67
|
+
// level_1: {
|
|
68
|
+
// title: "string",
|
|
69
|
+
// level_2: {
|
|
70
|
+
// id: "number",
|
|
71
|
+
// name: "string",
|
|
72
|
+
// },
|
|
73
|
+
// },
|
|
74
|
+
// },
|
|
75
|
+
// } as const satisfies InputParent
|
|
76
|
+
|
|
77
|
+
type ResolveType<T> =
|
|
78
|
+
// both null + undefined
|
|
79
|
+
T extends `${infer B}?~`
|
|
80
|
+
? ResolveBase<B & BaseType> | null | undefined
|
|
81
|
+
: // undefined only
|
|
82
|
+
T extends `${infer B}?`
|
|
83
|
+
? ResolveBase<B & BaseType> | undefined
|
|
84
|
+
: // null only
|
|
85
|
+
T extends `${infer B}~`
|
|
86
|
+
? ResolveBase<B & BaseType> | null
|
|
87
|
+
: // plain primitive
|
|
88
|
+
ResolveBase<T & BaseType>
|
|
89
|
+
|
|
90
|
+
type convertNest<T> = ResolveType<T>
|
|
91
|
+
|
|
92
|
+
type checkEnum<T> = T extends InputEnum ? T[number] : convertNest<T>
|
|
93
|
+
type convertChildObjet<T> = {
|
|
94
|
+
[K in keyof T]: chooseType<T[K]>
|
|
95
|
+
}
|
|
96
|
+
type convertObject<T> = T extends object ? convertChildObjet<T> : checkEnum<T>
|
|
97
|
+
type chooseType<T> = T extends InputEnum ? T[number] : convertObject<T>
|
|
98
|
+
export type convertRoot<T> = {
|
|
99
|
+
[K in keyof T]: chooseType<T[K]>
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// const data = {} as convertRoot<typeof req2>
|
|
103
|
+
|
|
104
|
+
// data.booking.bookingStatus
|
|
105
|
+
// data.status
|
|
106
|
+
// const id = data.booking.id
|
|
107
|
+
// const roomNumber = data.booking.bookingStatus === data.booking.bookingStatus
|
|
108
|
+
// data.rooms.map((row) => row.status === "OFF")
|
|
109
|
+
// data.data.level_1.level_2.id
|
|
110
|
+
// data.booking.createTime
|