@hapiboo/server 2.0.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.
@@ -0,0 +1,4 @@
1
+ import { IRoutingItem, routingProvider } from './routing';
2
+ import { server } from './server';
3
+ import { validator } from './validator';
4
+ export { IRoutingItem, routingProvider, server, validator };
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validator = exports.server = exports.routingProvider = void 0;
4
+ const routing_1 = require("./routing");
5
+ Object.defineProperty(exports, "routingProvider", { enumerable: true, get: function () { return routing_1.routingProvider; } });
6
+ const server_1 = require("./server");
7
+ Object.defineProperty(exports, "server", { enumerable: true, get: function () { return server_1.server; } });
8
+ const validator_1 = require("./validator");
9
+ Object.defineProperty(exports, "validator", { enumerable: true, get: function () { return validator_1.validator; } });
@@ -0,0 +1,12 @@
1
+ import { Application, Router } from 'express';
2
+ export interface IRoutingItem {
3
+ mount: string | undefined;
4
+ children: IRoutingItem[];
5
+ router: Router;
6
+ }
7
+ export declare namespace routingProvider {
8
+ function printMap(routes: IRoutingItem[]): void;
9
+ function createRoutingItem(mount: string | undefined, router: Router): IRoutingItem;
10
+ function createRouter(mount: string | undefined, routes: IRoutingItem[]): IRoutingItem;
11
+ function processApp(expressApp: Application, routers: IRoutingItem[]): void;
12
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.routingProvider = void 0;
4
+ const express_1 = require("express");
5
+ function parseItem(path, item) {
6
+ if (item.children.length === 0) {
7
+ return parseRouter(`${path}${item.mount ?? ''}`, item.router);
8
+ }
9
+ else {
10
+ const ret = [];
11
+ item.children.forEach((child) => {
12
+ ret.push(...parseItem(`${path}${item.mount ?? ''}`, child));
13
+ });
14
+ return ret;
15
+ }
16
+ }
17
+ function parseRouter(path, item) {
18
+ const ret = [];
19
+ item.stack.forEach((layer) => {
20
+ if (layer.route && layer.name === 'handle') {
21
+ layer.route.stack.forEach((details) => {
22
+ if (details.name === '<anonymous>') {
23
+ ret.push({ method: details.method, url: `${path}${layer.route?.path}` });
24
+ }
25
+ });
26
+ }
27
+ });
28
+ return ret;
29
+ }
30
+ var routingProvider;
31
+ (function (routingProvider) {
32
+ function printMap(routes) {
33
+ console.info('Method Routes:');
34
+ console.info('------------------');
35
+ routes.forEach((route) => {
36
+ parseItem('', route).forEach((detail) => {
37
+ console.info(`${detail.method.toUpperCase().padEnd(10)} ${detail.url}`);
38
+ });
39
+ });
40
+ }
41
+ routingProvider.printMap = printMap;
42
+ function createRoutingItem(mount, router) {
43
+ return { mount: mount, children: [], router: router };
44
+ }
45
+ routingProvider.createRoutingItem = createRoutingItem;
46
+ function createRouter(mount, routes) {
47
+ const router = (0, express_1.Router)({ mergeParams: true });
48
+ routes.forEach((item) => {
49
+ if (item.mount && item.mount !== '') {
50
+ router.use(item.mount, item.router);
51
+ }
52
+ else {
53
+ router.use(item.router);
54
+ }
55
+ });
56
+ return { mount: mount, children: routes, router: router };
57
+ }
58
+ routingProvider.createRouter = createRouter;
59
+ function processApp(expressApp, routers) {
60
+ routers.forEach((item) => {
61
+ if (item.mount && item.mount !== '') {
62
+ expressApp.use(item.mount, item.router);
63
+ }
64
+ else {
65
+ expressApp.use(item.router);
66
+ }
67
+ });
68
+ }
69
+ routingProvider.processApp = processApp;
70
+ })(routingProvider || (exports.routingProvider = routingProvider = {}));
@@ -0,0 +1,19 @@
1
+ import { Response, Request } from 'express';
2
+ import { ResponseError, IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
3
+ export declare namespace server {
4
+ function prepareJsonResponse<T>(response: Response, data: T, err?: ResponseError, non200Status?: number): void;
5
+ function prepareStringResponse(response: Response, data: string, err?: ResponseError): void;
6
+ function prepareBinaryResponse(response: Response, data: Buffer, err?: ResponseError): void;
7
+ function prepareMimeResponse(response: Response, data: Buffer, mime: string, err?: ResponseError, non200Status?: number): void;
8
+ function prepareJsonPromiseResponse<T>(response: Response, promise: IResponsePromise<T>, non200Status?: number): void;
9
+ function prepareStringPromiseResponse(response: Response, promise: IResponsePromise<string>, non200Status?: number): void;
10
+ function prepareEmptyPromiseResponse(response: Response, promise: IResponsePromiseVoid, non200Status?: number): void;
11
+ function prepareMimePromiseResponse(response: Response, mime: string, promise: IResponsePromise<Buffer>, non200Status?: number): void;
12
+ function prepareMimeBinaryPromiseResponse(response: Response, promise: IResponsePromise<{
13
+ mime: string;
14
+ binary: Buffer;
15
+ }>, non200Status?: number): void;
16
+ function prepareCustomPromiseResponse<T>(response: Response, promise: IResponsePromiseVoid, successContent: T, non200Status?: number): void;
17
+ function createValidatedPromise<T>(request: Request, validator: (request: Request) => boolean, delayedPromise: IResponsePromise<T>): IResponsePromise<T>;
18
+ function createValidatedVoidPromise(request: Request, validator: (request: Request) => boolean, delayedPromise: IResponsePromiseVoid): IResponsePromiseVoid;
19
+ }
package/dist/server.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.server = void 0;
4
+ const core_1 = require("@hapiboo/core");
5
+ function prepareResponse(response, responseSender, err, non200Status) {
6
+ if (err) {
7
+ response.status(err.status);
8
+ if (err.code) {
9
+ if (err.error) {
10
+ response.json({ code: err.code, error: err.message, original: err.error.name, stack: err.error.stack });
11
+ }
12
+ else {
13
+ response.json({ code: err.code, error: err.message });
14
+ }
15
+ }
16
+ else {
17
+ if (err.error) {
18
+ response.json({ error: err.message, original: err.error.name, stack: err.error.stack });
19
+ }
20
+ else {
21
+ response.json({ error: err.message });
22
+ }
23
+ }
24
+ }
25
+ else {
26
+ if (responseSender) {
27
+ response.status(non200Status ?? 200);
28
+ responseSender();
29
+ }
30
+ else {
31
+ response.status(non200Status ?? 204);
32
+ response.send();
33
+ }
34
+ }
35
+ }
36
+ var server;
37
+ (function (server) {
38
+ function prepareJsonResponse(response, data, err, non200Status) {
39
+ prepareResponse(response, () => {
40
+ response.json(data);
41
+ }, err, non200Status);
42
+ }
43
+ server.prepareJsonResponse = prepareJsonResponse;
44
+ function prepareStringResponse(response, data, err) {
45
+ prepareResponse(response, () => {
46
+ response.send(data);
47
+ }, err);
48
+ }
49
+ server.prepareStringResponse = prepareStringResponse;
50
+ function prepareBinaryResponse(response, data, err) {
51
+ prepareResponse(response, () => {
52
+ response.send(data);
53
+ }, err);
54
+ }
55
+ server.prepareBinaryResponse = prepareBinaryResponse;
56
+ function prepareMimeResponse(response, data, mime, err, non200Status) {
57
+ prepareResponse(response, () => {
58
+ if (mime != undefined && data != undefined) {
59
+ response.contentType(mime);
60
+ response.send(data);
61
+ }
62
+ else {
63
+ response.json({});
64
+ }
65
+ }, err, non200Status);
66
+ }
67
+ server.prepareMimeResponse = prepareMimeResponse;
68
+ function prepareJsonPromiseResponse(response, promise, non200Status) {
69
+ promise
70
+ .then((data) => {
71
+ prepareResponse(response, () => {
72
+ response.json(data);
73
+ }, undefined, non200Status);
74
+ })
75
+ .catch((error) => {
76
+ prepareResponse(response, undefined, error, non200Status);
77
+ });
78
+ }
79
+ server.prepareJsonPromiseResponse = prepareJsonPromiseResponse;
80
+ function prepareStringPromiseResponse(response, promise, non200Status) {
81
+ promise
82
+ .then((value) => {
83
+ prepareStringResponse(response, value);
84
+ })
85
+ .catch((error) => {
86
+ prepareResponse(response, undefined, error, non200Status);
87
+ });
88
+ }
89
+ server.prepareStringPromiseResponse = prepareStringPromiseResponse;
90
+ function prepareEmptyPromiseResponse(response, promise, non200Status) {
91
+ promise
92
+ .then(() => {
93
+ prepareResponse(response, undefined, undefined, non200Status);
94
+ })
95
+ .catch((error) => {
96
+ prepareResponse(response, undefined, error, non200Status);
97
+ });
98
+ }
99
+ server.prepareEmptyPromiseResponse = prepareEmptyPromiseResponse;
100
+ function prepareMimePromiseResponse(response, mime, promise, non200Status) {
101
+ promise
102
+ .then((data) => {
103
+ prepareMimeResponse(response, data, mime, undefined, non200Status);
104
+ })
105
+ .catch((error) => {
106
+ prepareResponse(response, undefined, error, non200Status);
107
+ });
108
+ }
109
+ server.prepareMimePromiseResponse = prepareMimePromiseResponse;
110
+ function prepareMimeBinaryPromiseResponse(response, promise, non200Status) {
111
+ promise
112
+ .then((data) => {
113
+ prepareMimeResponse(response, data.binary, data.mime, undefined, non200Status);
114
+ })
115
+ .catch((error) => {
116
+ prepareResponse(response, undefined, error, non200Status);
117
+ });
118
+ }
119
+ server.prepareMimeBinaryPromiseResponse = prepareMimeBinaryPromiseResponse;
120
+ function prepareCustomPromiseResponse(response, promise, successContent, non200Status) {
121
+ promise
122
+ .then(() => {
123
+ prepareResponse(response, () => { response.send(successContent); }, undefined, non200Status);
124
+ })
125
+ .catch((error) => {
126
+ prepareResponse(response, undefined, error, non200Status);
127
+ });
128
+ }
129
+ server.prepareCustomPromiseResponse = prepareCustomPromiseResponse;
130
+ function createValidatedPromise(request, validator, delayedPromise) {
131
+ if (validator(request)) {
132
+ return delayedPromise.start();
133
+ }
134
+ else {
135
+ return core_1.promise.createFailedPromise(core_1.ResponseError.getMessageResponse(400, 'malformed request'));
136
+ }
137
+ }
138
+ server.createValidatedPromise = createValidatedPromise;
139
+ function createValidatedVoidPromise(request, validator, delayedPromise) {
140
+ if (validator(request)) {
141
+ return delayedPromise.start();
142
+ }
143
+ else {
144
+ return core_1.promise.createFailedVoidPromise(core_1.ResponseError.getMessageResponse(400, 'malformed request'));
145
+ }
146
+ }
147
+ server.createValidatedVoidPromise = createValidatedVoidPromise;
148
+ })(server || (exports.server = server = {}));
@@ -0,0 +1,20 @@
1
+ import { Request } from 'express';
2
+ import { IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
3
+ export declare namespace validator {
4
+ function createValidatedPromise<T>(validator: () => boolean, delayedPromise: IResponsePromise<T>): IResponsePromise<T>;
5
+ function createValidatedVoidPromise(validator: () => boolean, delayedPromise: IResponsePromiseVoid): IResponsePromiseVoid;
6
+ function validateString(toValidate: string): boolean;
7
+ function validatePattern(toValidate: string, pattern: string[]): boolean;
8
+ function validateStringArray(toValidate: string[]): boolean;
9
+ function validateNotEmptyStringArray(toValidate: string[]): boolean;
10
+ function validateInteger(toValidate: number): boolean;
11
+ function validateBody(request: Request): boolean;
12
+ function validateHeader(request: Request, headerKey: string): {
13
+ isValid: boolean;
14
+ value: string;
15
+ };
16
+ function validateQuery(request: Request, queryKey: string): {
17
+ isValid: boolean;
18
+ value: string;
19
+ };
20
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validator = void 0;
4
+ const core_1 = require("@hapiboo/core");
5
+ var validator;
6
+ (function (validator_1) {
7
+ function createValidatedPromise(validator, delayedPromise) {
8
+ if (validator()) {
9
+ return delayedPromise.start();
10
+ }
11
+ else {
12
+ return core_1.promise.createFailedPromise(core_1.ResponseError.getMessageResponse(400, 'malformed request'));
13
+ }
14
+ }
15
+ validator_1.createValidatedPromise = createValidatedPromise;
16
+ function createValidatedVoidPromise(validator, delayedPromise) {
17
+ if (validator()) {
18
+ return delayedPromise.start();
19
+ }
20
+ else {
21
+ return core_1.promise.createFailedVoidPromise(core_1.ResponseError.getMessageResponse(400, 'malformed request'));
22
+ }
23
+ }
24
+ validator_1.createValidatedVoidPromise = createValidatedVoidPromise;
25
+ function validateString(toValidate) {
26
+ return toValidate != undefined && toValidate != '';
27
+ }
28
+ validator_1.validateString = validateString;
29
+ function validatePattern(toValidate, pattern) {
30
+ return validateString(toValidate) &&
31
+ pattern.some((val) => {
32
+ return val == toValidate;
33
+ });
34
+ }
35
+ validator_1.validatePattern = validatePattern;
36
+ function validateStringArray(toValidate) {
37
+ return toValidate != undefined;
38
+ }
39
+ validator_1.validateStringArray = validateStringArray;
40
+ function validateNotEmptyStringArray(toValidate) {
41
+ return toValidate != undefined && toValidate.length > 0 && toValidate.every((item) => { return validateString(item); });
42
+ }
43
+ validator_1.validateNotEmptyStringArray = validateNotEmptyStringArray;
44
+ function validateInteger(toValidate) {
45
+ return toValidate != undefined && (Math.floor(toValidate) == toValidate);
46
+ }
47
+ validator_1.validateInteger = validateInteger;
48
+ function validateBody(request) {
49
+ return request.body !== undefined;
50
+ }
51
+ validator_1.validateBody = validateBody;
52
+ function validateHeader(request, headerKey) {
53
+ const headerValue = request.headers[headerKey.toLowerCase()];
54
+ if (headerValue && typeof (headerValue) === 'string' && headerValue.trim() !== '') {
55
+ return { isValid: true, value: headerValue };
56
+ }
57
+ else {
58
+ return { isValid: false, value: '' };
59
+ }
60
+ }
61
+ validator_1.validateHeader = validateHeader;
62
+ function validateQuery(request, queryKey) {
63
+ const queryValue = request.query[queryKey];
64
+ if (queryValue && typeof (queryValue) === 'string' && queryValue.trim() !== '') {
65
+ return { isValid: true, value: queryValue };
66
+ }
67
+ else {
68
+ return { isValid: false, value: '' };
69
+ }
70
+ }
71
+ validator_1.validateQuery = validateQuery;
72
+ })(validator || (exports.validator = validator = {}));
@@ -0,0 +1,16 @@
1
+ import tseslint from "typescript-eslint";
2
+ import { defineConfig } from "eslint/config";
3
+
4
+ export default defineConfig([
5
+ ...tseslint.configs.recommended,
6
+ {
7
+ files: ["**/*.{ts,mts,cts}"],
8
+ rules: {
9
+ "@typescript-eslint/no-namespace": "off",
10
+ indent: ['error', 4],
11
+ 'linebreak-style': ['error', 'unix'],
12
+ quotes: ['error', 'single'],
13
+ semi: ['error', 'always'],
14
+ },
15
+ },
16
+ ]);
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@hapiboo/server",
3
+ "version": "2.0.1-dev",
4
+ "description": "MK13 Studio Hapiboo - API server services",
5
+ "author": "MK13 Studio",
6
+ "license": "ISC",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "scripts": {
10
+ "s_public": "cp package.public.json package.json",
11
+ "s_dev": "cp package.dev.json package.json",
12
+ "s_clean": "rm -f pnpm-lock.yaml && rm -rf node_modules dist",
13
+ "s_dependency": "cd .. && cd __core && pnpm s_build",
14
+ "s_build": "tsc --project tsconfig.dev.json",
15
+ "s_lint": "eslint 'src/*.ts'",
16
+ "s_lint_fix": "eslint 'src/*.ts' --fix",
17
+ "s_prepare": "pnpm s_clean && pnpm i && pnpm s_lint && pnpm s_build"
18
+ },
19
+ "dependencies": {
20
+ "@hapiboo/core": "workspace:*",
21
+ "express": "^5.1.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/express": "^5.0.3",
25
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
26
+ "@typescript-eslint/parser": "^8.38.0",
27
+ "eslint": "^9.32.0",
28
+ "typescript": "5.8.3",
29
+ "typescript-eslint": "^8.38.0"
30
+ }
31
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@hapiboo/server",
3
+ "version": "2.0.0",
4
+ "description": "MK13 Studio Hapiboo - API server services",
5
+ "author": "MK13 Studio",
6
+ "license": "ISC",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "dependencies": {
10
+ "@hapiboo/core": "^2.0.0",
11
+ "express": "^5.1.0"
12
+ },
13
+ "devDependencies": {
14
+ "@types/express": "^5.0.3",
15
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
16
+ "@typescript-eslint/parser": "^8.38.0",
17
+ "eslint": "^9.32.0",
18
+ "typescript": "5.8.3",
19
+ "typescript-eslint": "^8.38.0"
20
+ },
21
+ "scripts": {
22
+ "s_public": "cp package.public.json package.json",
23
+ "s_dev": "cp package.dev.json package.json",
24
+ "s_clean": "rm -f pnpm-lock.yaml && rm -rf node_modules dist",
25
+ "s_build": "tsc --project tsconfig.public.json",
26
+ "s_lint": "eslint 'src/*.ts'",
27
+ "s_check": "bash ../../scripts/publish.sh ./",
28
+ "s_publish": "pnpm s_clean && pnpm i -w=false && pnpm s_lint && pnpm s_build && pnpm s_check && pnpm s_dev"
29
+ }
30
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@hapiboo/server",
3
+ "version": "2.0.0",
4
+ "description": "MK13 Studio Hapiboo - API server services",
5
+ "author": "MK13 Studio",
6
+ "license": "ISC",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "scripts": {
10
+ "s_public": "cp package.public.json package.json",
11
+ "s_dev": "cp package.dev.json package.json",
12
+ "s_clean": "rm -f pnpm-lock.yaml && rm -rf node_modules dist",
13
+ "s_build": "tsc --project tsconfig.public.json",
14
+ "s_lint": "eslint 'src/*.ts'",
15
+ "s_check": "bash ../../scripts/publish.sh ./",
16
+ "s_publish": "pnpm s_clean && pnpm i -w=false && pnpm s_lint && pnpm s_build && pnpm s_check && pnpm s_dev"
17
+ },
18
+ "dependencies": {
19
+ "@hapiboo/core": "^2.0.0",
20
+ "express": "^5.1.0"
21
+ },
22
+ "devDependencies": {
23
+ "@types/express": "^5.0.3",
24
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
25
+ "@typescript-eslint/parser": "^8.38.0",
26
+ "eslint": "^9.32.0",
27
+ "typescript": "5.8.3",
28
+ "typescript-eslint": "^8.38.0"
29
+ }
30
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { IRoutingItem, routingProvider } from './routing';
2
+ import { server } from './server';
3
+ import { validator } from './validator';
4
+
5
+ export { IRoutingItem, routingProvider, server, validator };
package/src/routing.ts ADDED
@@ -0,0 +1,77 @@
1
+ import { Application, Router, IRouter } from 'express';
2
+
3
+ interface IRouteDetails{
4
+ method: string;
5
+ url: string;
6
+ }
7
+
8
+ function parseItem(path: string, item: IRoutingItem): IRouteDetails[]{
9
+ if (item.children.length === 0) {
10
+ return parseRouter(`${path}${item.mount ?? ''}`, item.router);
11
+ } else {
12
+ const ret: IRouteDetails[] = [];
13
+ item.children.forEach((child) => {
14
+ ret.push(...parseItem(`${path}${item.mount ?? ''}`, child));
15
+ });
16
+
17
+ return ret;
18
+ }
19
+ }
20
+ function parseRouter(path: string, item: IRouter): IRouteDetails[]{
21
+ const ret: IRouteDetails[] = [];
22
+ item.stack.forEach((layer) => {
23
+ if (layer.route && layer.name === 'handle') {
24
+ layer.route.stack.forEach((details) => {
25
+ if (details.name === '<anonymous>'){
26
+ ret.push({ method: details.method, url: `${path}${layer.route?.path }` });
27
+ }
28
+ });
29
+ }
30
+ });
31
+
32
+ return ret;
33
+ }
34
+
35
+ export interface IRoutingItem{
36
+ mount: string | undefined;
37
+ children: IRoutingItem[];
38
+ router: Router;
39
+ }
40
+
41
+ export namespace routingProvider{
42
+ export function printMap(routes: IRoutingItem[]){
43
+ console.info('Method Routes:');
44
+ console.info('------------------');
45
+
46
+ routes.forEach((route) => {
47
+ parseItem('', route).forEach((detail) => {
48
+ console.info(`${detail.method.toUpperCase().padEnd(10)} ${detail.url}`);
49
+ });
50
+ });
51
+ }
52
+ export function createRoutingItem(mount: string | undefined, router: Router): IRoutingItem{
53
+ return { mount: mount, children: [], router: router };
54
+ }
55
+ export function createRouter(mount: string | undefined, routes: IRoutingItem[]): IRoutingItem{
56
+ const router = Router({ mergeParams: true });
57
+
58
+ routes.forEach((item) => {
59
+ if (item.mount && item.mount !== ''){
60
+ router.use(item.mount, item.router);
61
+ } else {
62
+ router.use(item.router);
63
+ }
64
+ });
65
+
66
+ return { mount: mount, children: routes, router: router };
67
+ }
68
+ export function processApp(expressApp: Application, routers: IRoutingItem[]){
69
+ routers.forEach((item) => {
70
+ if (item.mount && item.mount !== ''){
71
+ expressApp.use(item.mount, item.router);
72
+ } else {
73
+ expressApp.use(item.router);
74
+ }
75
+ });
76
+ }
77
+ }
package/src/server.ts ADDED
@@ -0,0 +1,129 @@
1
+ import { Response, Request } from 'express';
2
+ import { promise, ResponseError, IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
3
+
4
+ function prepareResponse(response: Response, responseSender?: () => void, err?: ResponseError, non200Status?: number) {
5
+ if (err) {
6
+ response.status(err.status);
7
+ if (err.code) {
8
+ if (err.error) {
9
+ response.json({ code: err.code, error: err.message, original: err.error.name, stack: err.error.stack });
10
+ } else {
11
+ response.json({ code: err.code, error: err.message});
12
+ }
13
+ } else {
14
+ if (err.error) {
15
+ response.json({ error: err.message, original: err.error.name, stack: err.error.stack });
16
+ } else {
17
+ response.json({ error: err.message});
18
+ }
19
+ }
20
+ } else {
21
+ if (responseSender) {
22
+ response.status(non200Status ?? 200);
23
+ responseSender();
24
+ } else {
25
+ response.status(non200Status ?? 204);
26
+ response.send();
27
+ }
28
+ }
29
+ }
30
+
31
+ export namespace server {
32
+ export function prepareJsonResponse<T>(response: Response, data: T, err?: ResponseError, non200Status?: number) {
33
+ prepareResponse(response, () => {
34
+ response.json(data);
35
+ }, err, non200Status);
36
+ }
37
+ export function prepareStringResponse(response: Response, data: string, err?: ResponseError) {
38
+ prepareResponse(response, () => {
39
+ response.send(data);
40
+ }, err);
41
+ }
42
+ export function prepareBinaryResponse(response: Response, data: Buffer, err?: ResponseError) {
43
+ prepareResponse(response, () => {
44
+ response.send(data);
45
+ }, err);
46
+ }
47
+ export function prepareMimeResponse(response: Response, data: Buffer, mime: string, err?: ResponseError, non200Status?: number) {
48
+ prepareResponse(response, () => {
49
+ if (mime != undefined && data != undefined) {
50
+ response.contentType(mime);
51
+ response.send(data);
52
+ } else {
53
+ response.json({});
54
+ }
55
+ }, err, non200Status);
56
+ }
57
+
58
+ export function prepareJsonPromiseResponse<T>(response: Response, promise: IResponsePromise<T>, non200Status?: number) {
59
+ promise
60
+ .then((data) => {
61
+ prepareResponse(response, () => {
62
+ response.json(data);
63
+ }, undefined, non200Status);
64
+ })
65
+ .catch((error) => {
66
+ prepareResponse(response, undefined, error, non200Status);
67
+ });
68
+ }
69
+ export function prepareStringPromiseResponse(response: Response, promise: IResponsePromise<string>, non200Status?: number) {
70
+ promise
71
+ .then((value) => {
72
+ prepareStringResponse(response, value);
73
+ })
74
+ .catch((error) => {
75
+ prepareResponse(response, undefined, error, non200Status);
76
+ });
77
+ }
78
+ export function prepareEmptyPromiseResponse(response: Response, promise: IResponsePromiseVoid, non200Status?: number) {
79
+ promise
80
+ .then(() => {
81
+ prepareResponse(response, undefined, undefined, non200Status);
82
+ })
83
+ .catch((error) => {
84
+ prepareResponse(response, undefined, error, non200Status);
85
+ });
86
+ }
87
+ export function prepareMimePromiseResponse(response: Response, mime: string, promise: IResponsePromise<Buffer>, non200Status?: number) {
88
+ promise
89
+ .then((data) => {
90
+ prepareMimeResponse(response, data, mime, undefined, non200Status);
91
+ })
92
+ .catch((error) => {
93
+ prepareResponse(response, undefined, error, non200Status);
94
+ });
95
+ }
96
+ export function prepareMimeBinaryPromiseResponse(response: Response, promise: IResponsePromise<{mime: string, binary: Buffer}>, non200Status?: number) {
97
+ promise
98
+ .then((data) => {
99
+ prepareMimeResponse(response, data.binary, data.mime, undefined, non200Status);
100
+ })
101
+ .catch((error) => {
102
+ prepareResponse(response, undefined, error, non200Status);
103
+ });
104
+ }
105
+ export function prepareCustomPromiseResponse<T>(response: Response, promise: IResponsePromiseVoid, successContent: T, non200Status?: number) {
106
+ promise
107
+ .then(() => {
108
+ prepareResponse(response, () => { response.send(successContent); }, undefined, non200Status);
109
+ })
110
+ .catch((error) => {
111
+ prepareResponse(response, undefined, error, non200Status);
112
+ });
113
+ }
114
+
115
+ export function createValidatedPromise<T>(request: Request, validator: (request: Request) => boolean, delayedPromise: IResponsePromise<T>): IResponsePromise<T> {
116
+ if (validator(request)) {
117
+ return delayedPromise.start();
118
+ } else {
119
+ return promise.createFailedPromise(ResponseError.getMessageResponse(400, 'malformed request'));
120
+ }
121
+ }
122
+ export function createValidatedVoidPromise(request: Request, validator: (request: Request) => boolean, delayedPromise: IResponsePromiseVoid): IResponsePromiseVoid {
123
+ if (validator(request)) {
124
+ return delayedPromise.start();
125
+ } else {
126
+ return promise.createFailedVoidPromise(ResponseError.getMessageResponse(400, 'malformed request'));
127
+ }
128
+ }
129
+ }
@@ -0,0 +1,63 @@
1
+ import { Request } from 'express';
2
+ import { promise, ResponseError, IResponsePromise, IResponsePromiseVoid } from '@hapiboo/core';
3
+
4
+ export namespace validator {
5
+
6
+ export function createValidatedPromise<T>(validator: () => boolean, delayedPromise: IResponsePromise<T>): IResponsePromise<T> {
7
+ if (validator()) {
8
+ return delayedPromise.start();
9
+ } else {
10
+ return promise.createFailedPromise(ResponseError.getMessageResponse(400, 'malformed request'));
11
+ }
12
+ }
13
+ export function createValidatedVoidPromise(validator: () => boolean, delayedPromise: IResponsePromiseVoid): IResponsePromiseVoid {
14
+ if (validator()) {
15
+ return delayedPromise.start();
16
+ } else {
17
+ return promise.createFailedVoidPromise(ResponseError.getMessageResponse(400, 'malformed request'));
18
+ }
19
+ }
20
+
21
+ export function validateString(toValidate: string): boolean {
22
+ return toValidate != undefined && toValidate != '';
23
+ }
24
+ export function validatePattern(toValidate: string, pattern: string[]): boolean {
25
+ return validateString(toValidate) &&
26
+ pattern.some((val) => {
27
+ return val == toValidate;
28
+ });
29
+ }
30
+ export function validateStringArray(toValidate: string[]): boolean {
31
+ return toValidate != undefined;
32
+ }
33
+ export function validateNotEmptyStringArray(toValidate: string[]): boolean {
34
+ return toValidate != undefined && toValidate.length > 0 && toValidate.every((item) => { return validateString(item); });
35
+ }
36
+ export function validateInteger(toValidate: number): boolean {
37
+ return toValidate != undefined && (Math.floor(toValidate) == toValidate);
38
+ }
39
+
40
+ export function validateBody(request: Request): boolean{
41
+ return request.body !== undefined;
42
+ }
43
+
44
+ export function validateHeader(request: Request, headerKey: string): { isValid: boolean, value: string }{
45
+ const headerValue = request.headers[headerKey.toLowerCase()];
46
+
47
+ if (headerValue && typeof(headerValue) === 'string' && headerValue.trim() !== '') {
48
+ return { isValid: true, value: headerValue };
49
+ } else {
50
+ return { isValid: false, value: '' };
51
+ }
52
+ }
53
+
54
+ export function validateQuery(request: Request, queryKey: string): { isValid: boolean, value: string }{
55
+ const queryValue = request.query[queryKey];
56
+
57
+ if (queryValue && typeof(queryValue) === 'string' && queryValue.trim() !== '') {
58
+ return { isValid: true, value: queryValue };
59
+ } else {
60
+ return { isValid: false, value: '' };
61
+ }
62
+ }
63
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "moduleResolution": "node",
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ },
16
+ "include": ["src/**/*"],
17
+ "exclude": ["node_modules", "dist"]
18
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "sourceMap": true,
5
+ "declarationMap": true
6
+ }
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "./tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "sourceMap": false,
5
+ "declarationMap": false
6
+ }
7
+ }