@lucaapp/service-utils 1.26.0 → 1.27.0
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/lib/api/endpoint.js +102 -23
- package/dist/lib/api/response.d.ts +8 -8
- package/package.json +1 -1
package/dist/lib/api/endpoint.js
CHANGED
|
@@ -6,12 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.registerEndpoint = exports.mountEndpoint = void 0;
|
|
7
7
|
const zod_1 = require("zod");
|
|
8
8
|
const assert_1 = __importDefault(require("assert"));
|
|
9
|
+
const boom_1 = require("@hapi/boom");
|
|
9
10
|
const buildResponseConfig = (responseOptions) => {
|
|
10
11
|
const responses = {};
|
|
11
12
|
responseOptions.forEach(response => {
|
|
12
13
|
responses[String(response.status)] = {
|
|
13
14
|
description: response.description,
|
|
14
|
-
...(!(response.schema instanceof zod_1.ZodVoid) && {
|
|
15
|
+
...(!(response.schema instanceof zod_1.z.ZodVoid) && {
|
|
15
16
|
content: {
|
|
16
17
|
'application/json': {
|
|
17
18
|
schema: response.schema,
|
|
@@ -22,36 +23,114 @@ const buildResponseConfig = (responseOptions) => {
|
|
|
22
23
|
});
|
|
23
24
|
return responses;
|
|
24
25
|
};
|
|
25
|
-
const
|
|
26
|
-
(0, assert_1.default)(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
const validateAndSendResponse = async (expressResponse, response, validResponses) => {
|
|
27
|
+
(0, assert_1.default)(typeof response.status === 'number');
|
|
28
|
+
// get schema respective to status code
|
|
29
|
+
const responseSchema = validResponses.find(responseSchema => responseSchema.status === response.status);
|
|
30
|
+
const schema = responseSchema?.schema;
|
|
31
|
+
const isZodSchema = schema instanceof zod_1.z.ZodSchema;
|
|
32
|
+
const isZodVoid = schema instanceof zod_1.z.ZodVoid;
|
|
33
|
+
(0, assert_1.default)(isZodSchema || isZodVoid);
|
|
34
|
+
// validate response schema
|
|
35
|
+
const validatedResponseBody = await schema.parseAsync(response.body);
|
|
36
|
+
if (validatedResponseBody === undefined) {
|
|
37
|
+
// No Content Response
|
|
38
|
+
return expressResponse.status(response.status).end();
|
|
39
|
+
}
|
|
40
|
+
expressResponse.status(response.status).send(validatedResponseBody);
|
|
41
|
+
};
|
|
42
|
+
const handleMiddleware = async (middleware, context, request, response) => new Promise(async (resolve, reject) => {
|
|
43
|
+
try {
|
|
44
|
+
const handlerRequestBody = ((await middleware.options.schemas?.body?.parseAsync(request.body)) ||
|
|
45
|
+
undefined);
|
|
46
|
+
const handlerRequestParams = ((await middleware.options.schemas?.params?.parseAsync(request.params)) || undefined);
|
|
47
|
+
const handlerRequestQuery = ((await middleware.options.schemas?.query?.parseAsync(request.query)) ||
|
|
48
|
+
undefined);
|
|
49
|
+
const handlerRequestHeaders = ((await middleware.options.schemas?.headers?.parseAsync(request.headers)) || undefined);
|
|
33
50
|
const handlerRequest = {
|
|
34
51
|
body: handlerRequestBody,
|
|
35
52
|
params: handlerRequestParams,
|
|
36
53
|
query: handlerRequestQuery,
|
|
37
54
|
headers: handlerRequestHeaders,
|
|
38
55
|
};
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
56
|
+
await middleware.handler(handlerRequest, async (middlewareResponse) => {
|
|
57
|
+
try {
|
|
58
|
+
await validateAndSendResponse(response, middlewareResponse, middleware.options.responses);
|
|
59
|
+
resolve(false);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
(0, boom_1.boomify)(error, {
|
|
64
|
+
statusCode: 500,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
reject(error);
|
|
68
|
+
}
|
|
69
|
+
}, async (returnedContext) => {
|
|
70
|
+
try {
|
|
71
|
+
const validatedContext = await middleware.options.schemas?.context?.parseAsync(returnedContext);
|
|
72
|
+
Object.assign(context, validatedContext);
|
|
73
|
+
resolve(true);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error instanceof Error) {
|
|
77
|
+
(0, boom_1.boomify)(error, {
|
|
78
|
+
statusCode: 500,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
reject(error);
|
|
52
82
|
}
|
|
53
|
-
response.status(controllerResponse.status).send(validatedResponseBody);
|
|
54
83
|
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
reject(error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const mountEndpoint = (router, method, path, options, handler) => {
|
|
90
|
+
(0, assert_1.default)(options.responses.length > 0, 'You need to specify at least one response');
|
|
91
|
+
router[method](path, async (request, response, next) => {
|
|
92
|
+
try {
|
|
93
|
+
// parse request schemas
|
|
94
|
+
const handlerRequestBody = ((await options.schemas?.body?.parseAsync(request.body)) || undefined);
|
|
95
|
+
const handlerRequestParams = ((await options.schemas?.params?.parseAsync(request.params)) ||
|
|
96
|
+
undefined);
|
|
97
|
+
const handlerRequestQuery = ((await options.schemas?.query?.parseAsync(request.query)) || undefined);
|
|
98
|
+
const handlerRequestHeaders = ((await options.schemas?.headers?.parseAsync(request.headers)) ||
|
|
99
|
+
undefined);
|
|
100
|
+
const handlerRequest = {
|
|
101
|
+
body: handlerRequestBody,
|
|
102
|
+
params: handlerRequestParams,
|
|
103
|
+
query: handlerRequestQuery,
|
|
104
|
+
headers: handlerRequestHeaders,
|
|
105
|
+
};
|
|
106
|
+
const ctx = {};
|
|
107
|
+
if (options.middlewares instanceof Array) {
|
|
108
|
+
for (const middleware of options.middlewares) {
|
|
109
|
+
const shouldContinue = await handleMiddleware(middleware, ctx, request, response);
|
|
110
|
+
if (!shouldContinue)
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
await handler(handlerRequest, ctx, async (controllerResponse) => {
|
|
115
|
+
try {
|
|
116
|
+
await validateAndSendResponse(response, controllerResponse, options.responses);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
if (error instanceof Error) {
|
|
120
|
+
(0, boom_1.boomify)(error, {
|
|
121
|
+
statusCode: 500,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
next(error);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
if (error instanceof zod_1.z.ZodError && !(0, boom_1.isBoom)(error)) {
|
|
130
|
+
return response.status(400).send({ issues: error.issues });
|
|
131
|
+
}
|
|
132
|
+
next(error);
|
|
133
|
+
}
|
|
55
134
|
});
|
|
56
135
|
};
|
|
57
136
|
exports.mountEndpoint = mountEndpoint;
|
|
@@ -5,12 +5,12 @@ declare const badRequestErrorSchema: z.ZodObject<{
|
|
|
5
5
|
error: z.ZodString;
|
|
6
6
|
message: z.ZodString;
|
|
7
7
|
}, "strip", z.ZodTypeAny, {
|
|
8
|
-
error: string;
|
|
9
8
|
message: string;
|
|
9
|
+
error: string;
|
|
10
10
|
statusCode: 400;
|
|
11
11
|
}, {
|
|
12
|
-
error: string;
|
|
13
12
|
message: string;
|
|
13
|
+
error: string;
|
|
14
14
|
statusCode: 400;
|
|
15
15
|
}>;
|
|
16
16
|
declare const unauthorizedErrorSchema: z.ZodObject<{
|
|
@@ -18,12 +18,12 @@ declare const unauthorizedErrorSchema: z.ZodObject<{
|
|
|
18
18
|
error: z.ZodString;
|
|
19
19
|
message: z.ZodString;
|
|
20
20
|
}, "strip", z.ZodTypeAny, {
|
|
21
|
-
error: string;
|
|
22
21
|
message: string;
|
|
22
|
+
error: string;
|
|
23
23
|
statusCode: 401;
|
|
24
24
|
}, {
|
|
25
|
-
error: string;
|
|
26
25
|
message: string;
|
|
26
|
+
error: string;
|
|
27
27
|
statusCode: 401;
|
|
28
28
|
}>;
|
|
29
29
|
declare const forbiddenErrorSchema: z.ZodObject<{
|
|
@@ -31,12 +31,12 @@ declare const forbiddenErrorSchema: z.ZodObject<{
|
|
|
31
31
|
error: z.ZodString;
|
|
32
32
|
message: z.ZodString;
|
|
33
33
|
}, "strip", z.ZodTypeAny, {
|
|
34
|
-
error: string;
|
|
35
34
|
message: string;
|
|
35
|
+
error: string;
|
|
36
36
|
statusCode: 403;
|
|
37
37
|
}, {
|
|
38
|
-
error: string;
|
|
39
38
|
message: string;
|
|
39
|
+
error: string;
|
|
40
40
|
statusCode: 403;
|
|
41
41
|
}>;
|
|
42
42
|
declare const notFoundErrorSchema: z.ZodObject<{
|
|
@@ -44,12 +44,12 @@ declare const notFoundErrorSchema: z.ZodObject<{
|
|
|
44
44
|
error: z.ZodString;
|
|
45
45
|
message: z.ZodString;
|
|
46
46
|
}, "strip", z.ZodTypeAny, {
|
|
47
|
-
error: string;
|
|
48
47
|
message: string;
|
|
48
|
+
error: string;
|
|
49
49
|
statusCode: 404;
|
|
50
50
|
}, {
|
|
51
|
-
error: string;
|
|
52
51
|
message: string;
|
|
52
|
+
error: string;
|
|
53
53
|
statusCode: 404;
|
|
54
54
|
}>;
|
|
55
55
|
export declare const okResponse: <T>(schema: z.ZodType<T, z.ZodTypeDef, T>) => {
|