bootpress 4.1.1 → 5.0.1
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 +1 -2
- package/helpers/index.d.ts +21 -6
- package/helpers/index.js +55 -16
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
#### Basic usage:
|
|
9
9
|
```ts
|
|
10
10
|
import express from "express";
|
|
11
|
-
import bodyparser from "body-parser";
|
|
12
11
|
import { HttpError, PassParams, RestService } from "bootpress";
|
|
13
12
|
import { asInteger, getOrThrow } from "bootpress/helpers";
|
|
14
13
|
|
|
15
14
|
const app = express();
|
|
16
|
-
app.use(
|
|
15
|
+
app.use(express.json());
|
|
17
16
|
|
|
18
17
|
const UserServiceImpl = {
|
|
19
18
|
users: [1, 2, 3, 4],
|
package/helpers/index.d.ts
CHANGED
|
@@ -2,22 +2,37 @@ import { HttpError } from "..";
|
|
|
2
2
|
|
|
3
3
|
type TypeMap = {
|
|
4
4
|
"string": string,
|
|
5
|
-
"string
|
|
5
|
+
"string[]": string[],
|
|
6
6
|
"boolean": boolean,
|
|
7
|
-
"boolean
|
|
7
|
+
"boolean[]": boolean[],
|
|
8
8
|
"number": number,
|
|
9
|
-
"number
|
|
9
|
+
"number[]": number[],
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
type ValidTypeKeys = keyof TypeMap;
|
|
13
|
+
type ValOf<T extends keyof TypeMap> = TypeMap[T]
|
|
14
|
+
|
|
15
|
+
type StringEndsWithQm = `${string}?`;
|
|
16
|
+
|
|
12
17
|
type JsSchema = {
|
|
13
|
-
[key:
|
|
18
|
+
[key: PropertyKey]: ValidTypeKeys | JsSchema | ArraySchema
|
|
14
19
|
}
|
|
15
20
|
|
|
16
|
-
type
|
|
21
|
+
type ArraySchema = [JsSchema]
|
|
22
|
+
|
|
23
|
+
type RemoveQuestionMark<T extends string> = T extends `${infer Prefix}?` ? Prefix : T;
|
|
24
|
+
|
|
25
|
+
type TypedSchema<T> = {
|
|
26
|
+
[key in keyof T as `${RemoveQuestionMark<string & key>}`]:
|
|
27
|
+
key extends StringEndsWithQm ? T[key] extends ValidTypeKeys ? ValOf<T[key]> | null : T[key] extends ArraySchema ? TypedSchema<T[key][0]>[] | null : TypedSchema<T[key]> | null
|
|
28
|
+
: (T[key] extends ValidTypeKeys ? ValOf<T[key]> : T[key] extends ArraySchema ? TypedSchema<T[key][0]>[] : TypedSchema<T[key]>)
|
|
29
|
+
}
|
|
17
30
|
|
|
18
31
|
export function getOrThrow<T, E extends HttpError>(data: T, error: E): T;
|
|
19
32
|
export function getOrElse<T, E>(data: T, defaultValue: E): T | E;
|
|
20
33
|
export function asBoolean(o: any): boolean;
|
|
21
34
|
export function asNumber(o: any): number;
|
|
22
35
|
export function asInteger(o: any): number;
|
|
23
|
-
export function
|
|
36
|
+
export function asString(o: any): string;
|
|
37
|
+
export function asSchema<T extends JsSchema>(o: any, jsSchema: T): TypedSchema<T>;
|
|
38
|
+
export function schema<T extends JsSchema>(schema: T): T;
|
package/helpers/index.js
CHANGED
|
@@ -17,7 +17,7 @@ function getOrElse(data, defaultValue) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
function asBoolean(o, errorMessage = undefined, errorStatus = 400) {
|
|
20
|
-
errorMessage = errorMessage ?? `Value ${o} should have been a boolean but it's
|
|
20
|
+
errorMessage = errorMessage ?? `Value ${o} should have been a boolean but it's ${typeof o}`;
|
|
21
21
|
if (typeof o === "string") {
|
|
22
22
|
const lowercased = o.toLowerCase();
|
|
23
23
|
const validBooleanStrings = new Map(Object.entries({
|
|
@@ -39,7 +39,7 @@ function asBoolean(o, errorMessage = undefined, errorStatus = 400) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function asNumber(o, errorMessage = undefined, errorStatus = 400) {
|
|
42
|
-
errorMessage = errorMessage ?? `Value ${o} should have been a number but it's
|
|
42
|
+
errorMessage = errorMessage ?? `Value ${o} should have been a number but it's ${typeof o}`
|
|
43
43
|
if (typeof o === "number") {
|
|
44
44
|
return o;
|
|
45
45
|
}
|
|
@@ -53,7 +53,7 @@ function asNumber(o, errorMessage = undefined, errorStatus = 400) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function asInteger(o, errorMessage = undefined, errorStatus = 400) {
|
|
56
|
-
errorMessage = errorMessage ?? `Value ${o} should have been a integer but it's
|
|
56
|
+
errorMessage = errorMessage ?? `Value ${o} should have been a integer but it's ${typeof o}`;
|
|
57
57
|
let value = o;
|
|
58
58
|
if (typeof o === "string") {
|
|
59
59
|
value = Number(o);
|
|
@@ -64,22 +64,54 @@ function asInteger(o, errorMessage = undefined, errorStatus = 400) {
|
|
|
64
64
|
return value;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function
|
|
67
|
+
function asString(o, errorMessage = undefined, errorStatus = 400) {
|
|
68
|
+
errorMessage = errorMessage ?? `Value ${o} should have been a string but it's not`;
|
|
69
|
+
const validTypes = ["string", "number"];
|
|
70
|
+
if (validTypes.includes(typeof o)) {
|
|
71
|
+
return '' + o;
|
|
72
|
+
} else {
|
|
73
|
+
throw new HttpError(errorStatus, errorMessage);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function asSchema(o, schema) {
|
|
68
78
|
const schemaKeyValues = Object.entries(schema);
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
let result = {};
|
|
80
|
+
for (let i = 0; i < schemaKeyValues.length; i++) {
|
|
81
|
+
let key = schemaKeyValues[i][0];
|
|
82
|
+
if (key.endsWith("?")) {
|
|
83
|
+
key = key.substring(0, key.length - 1);
|
|
84
|
+
if (o[key] == null) {
|
|
85
|
+
result[key] = null;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
71
89
|
const expectedType = schemaKeyValues[i][1];
|
|
72
|
-
const errorMessage = `Value of ${key} should have been a ${expectedType} but it's a ${typeof o[key]}`;
|
|
90
|
+
const errorMessage = o[key] == null ? `Value of ${key} should have been a ${expectedType} but it's null` : `Value of ${key} should have been a ${expectedType} but it's a ${typeof o[key]}`;
|
|
73
91
|
|
|
74
|
-
if(typeof expectedType === "object"){
|
|
75
|
-
|
|
92
|
+
if (typeof expectedType === "object") {
|
|
93
|
+
if (Array.isArray(expectedType)) {
|
|
94
|
+
result[key] = [];
|
|
95
|
+
for (let j = 0; j < o[key].length; j++) {
|
|
96
|
+
result[key][j] = asSchema(o[key][j], expectedType[0])
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
result[key] = asSchema(o[key], expectedType);
|
|
100
|
+
}
|
|
76
101
|
}
|
|
77
|
-
else if(typeof expectedType === "string"){
|
|
78
|
-
if(expectedType.endsWith("
|
|
79
|
-
|
|
102
|
+
else if (typeof expectedType === "string") {
|
|
103
|
+
if (expectedType.endsWith("[]")) {
|
|
104
|
+
const elementType = expectedType.replace("[]", "");
|
|
105
|
+
for (let j = 0; j < o[key].length; j++){
|
|
106
|
+
if(typeof o[key][j] !== elementType){
|
|
107
|
+
throw new HttpError(400, `Each element of ${key} should have been a ${elementType} but a ${typeof o[key][j]} is present (${o[key][j]})`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
result[key] = o[key];
|
|
80
111
|
}
|
|
81
|
-
|
|
82
|
-
|
|
112
|
+
else if (typeof o[key] === expectedType) {
|
|
113
|
+
result[key] = o[key];
|
|
114
|
+
} else {
|
|
83
115
|
throw new HttpError(400, errorMessage);
|
|
84
116
|
}
|
|
85
117
|
}
|
|
@@ -87,7 +119,12 @@ function asSchema(o, schema){
|
|
|
87
119
|
throw new HttpError(500, `Type of a schema key should be a primitive type or another schema`);
|
|
88
120
|
}
|
|
89
121
|
}
|
|
90
|
-
return
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
function schema(schema) {
|
|
127
|
+
return schema;
|
|
91
128
|
}
|
|
92
129
|
|
|
93
130
|
module.exports = {
|
|
@@ -96,5 +133,7 @@ module.exports = {
|
|
|
96
133
|
asBoolean,
|
|
97
134
|
asNumber,
|
|
98
135
|
asInteger,
|
|
99
|
-
|
|
136
|
+
asString,
|
|
137
|
+
asSchema,
|
|
138
|
+
schema
|
|
100
139
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bootpress",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "REST service methods for express",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {},
|
|
@@ -25,9 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/ufukbakan/bootpress#readme",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@types/body-parser": "^1.19.2",
|
|
29
|
-
"@types/express": "^4.17.17",
|
|
30
|
-
"body-parser": "^1.20.2",
|
|
31
28
|
"express": "^4.18.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/body-parser": "^1.19.2",
|
|
32
|
+
"@types/express": "^4.17.17"
|
|
32
33
|
}
|
|
33
34
|
}
|