schema-shield 0.0.3 → 0.0.4
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 +68 -45
- package/dist/formats.d.ts +1 -1
- package/dist/formats.d.ts.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +197 -176
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +197 -189
- package/dist/keywords/string-keywords.d.ts.map +1 -1
- package/lib/formats.ts +191 -49
- package/lib/index.ts +49 -29
- package/lib/keywords/array-keywords.ts +1 -1
- package/lib/keywords/string-keywords.ts +6 -12
- package/package.json +3 -3
package/lib/formats.ts
CHANGED
|
@@ -1,62 +1,190 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { FormatFunction } from './index';
|
|
3
|
-
import { ValidationError } from './utils';
|
|
4
|
-
|
|
5
|
-
// The datetime 1990-02-31T15:59:60.123-08:00 must be rejected.
|
|
6
|
-
const RegExps = {
|
|
7
|
-
'date-time': /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(Z|([+-])(\d{2}):(\d{2}))$/,
|
|
8
|
-
time: /^(\d{2}):(\d{2}):(\d{2})(\.\d+)?(Z|([+-])(\d{2}):(\d{2}))$/,
|
|
9
|
-
uri: /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/,
|
|
10
|
-
email:
|
|
11
|
-
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
|
|
12
|
-
hostname: /^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}(\.[a-zA-Z0-9][a-zA-Z0-9-]{0,62})*[a-zA-Z0-9]$/,
|
|
13
|
-
date: /^(\d{4})-(\d{2})-(\d{2})$/,
|
|
14
|
-
'json-pointer': /^\/(?:[^~]|~0|~1)*$/,
|
|
15
|
-
'relative-json-pointer': /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/,
|
|
16
|
-
};
|
|
1
|
+
import { FormatFunction } from "./index";
|
|
17
2
|
|
|
18
3
|
export const Formats: Record<string, FormatFunction | false> = {
|
|
19
|
-
[
|
|
20
|
-
const
|
|
21
|
-
|
|
4
|
+
["date-time"](data) {
|
|
5
|
+
const match = data.match(
|
|
6
|
+
/^(\d{4})-(0[0-9]|1[0-2])-(\d{2})T(0[0-9]|1\d|2[0-3]):([0-5]\d):((?:[0-5]\d|60))(?:.\d+)?(?:([+-])(0[0-9]|1\d|2[0-3]):([0-5]\d)|Z)?$/i
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
if (!match) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let day = Number(match[3]);
|
|
14
|
+
|
|
15
|
+
if (match[2] === "02" && day > 29) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const [
|
|
20
|
+
,
|
|
21
|
+
yearStr,
|
|
22
|
+
monthStr,
|
|
23
|
+
,
|
|
24
|
+
hourStr,
|
|
25
|
+
minuteStr,
|
|
26
|
+
secondStr,
|
|
27
|
+
timezoneSign,
|
|
28
|
+
timezoneHourStr,
|
|
29
|
+
timezoneMinuteStr
|
|
30
|
+
] = match;
|
|
31
|
+
|
|
32
|
+
let year = Number(yearStr);
|
|
33
|
+
let month = Number(monthStr);
|
|
34
|
+
let hour = Number(hourStr);
|
|
35
|
+
let minute = Number(minuteStr);
|
|
36
|
+
let second = Number(secondStr);
|
|
37
|
+
|
|
38
|
+
if (timezoneSign === "-" || timezoneSign === "+") {
|
|
39
|
+
const timezoneHour = Number(timezoneHourStr);
|
|
40
|
+
const timezoneMinute = Number(timezoneMinuteStr);
|
|
41
|
+
|
|
42
|
+
if (timezoneSign === "-") {
|
|
43
|
+
hour += timezoneHour;
|
|
44
|
+
minute += timezoneMinute;
|
|
45
|
+
} else if (timezoneSign === "+") {
|
|
46
|
+
hour -= timezoneHour;
|
|
47
|
+
minute -= timezoneMinute;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (minute > 59) {
|
|
51
|
+
hour += 1;
|
|
52
|
+
minute -= 60;
|
|
53
|
+
} else if (minute < 0) {
|
|
54
|
+
hour -= 1;
|
|
55
|
+
minute += 60;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (hour > 23) {
|
|
59
|
+
day += 1;
|
|
60
|
+
hour -= 24;
|
|
61
|
+
} else if (hour < 0) {
|
|
62
|
+
day -= 1;
|
|
63
|
+
hour += 24;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (day > 31) {
|
|
67
|
+
month += 1;
|
|
68
|
+
day -= 31;
|
|
69
|
+
} else if (day < 1) {
|
|
70
|
+
month -= 1;
|
|
71
|
+
day += 31;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (month > 12) {
|
|
75
|
+
year += 1;
|
|
76
|
+
month -= 12;
|
|
77
|
+
} else if (month < 1) {
|
|
78
|
+
year -= 1;
|
|
79
|
+
month += 12;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (year < 0) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const daysInMonth = [31, , 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
88
|
+
const maxDays =
|
|
89
|
+
month === 2
|
|
90
|
+
? year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
|
|
91
|
+
? 29
|
|
92
|
+
: 28
|
|
93
|
+
: daysInMonth[month - 1];
|
|
94
|
+
|
|
95
|
+
if (day > maxDays) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Leap seconds
|
|
100
|
+
if (second === 60 && (minute !== 59 || hour !== 23)) {
|
|
22
101
|
return false;
|
|
23
102
|
}
|
|
24
103
|
|
|
25
|
-
|
|
26
|
-
return !isNaN(date.getTime());
|
|
104
|
+
return true;
|
|
27
105
|
},
|
|
28
106
|
uri(data) {
|
|
29
|
-
return
|
|
107
|
+
return /^[a-zA-Z][a-zA-Z0-9+\-.]*:[^\s]*$/.test(data);
|
|
30
108
|
},
|
|
31
109
|
email(data) {
|
|
32
|
-
|
|
110
|
+
return /^(?!\.)(?!.*\.$)[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,20}(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]{1,21}){0,2}@[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,60}[a-z0-9])?){0,3}$/i.test(
|
|
111
|
+
data
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
ipv4(data) {
|
|
115
|
+
// Matches a string formed by 4 numbers between 0 and 255 separated by dots without leading zeros
|
|
116
|
+
// /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$/
|
|
117
|
+
return /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$/.test(
|
|
118
|
+
data
|
|
119
|
+
);
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
// ipv6: isMyIpValid({ version: 6 }),
|
|
123
|
+
ipv6(data) {
|
|
124
|
+
if (data === "::") {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (
|
|
129
|
+
data.indexOf(":") === -1 ||
|
|
130
|
+
/(?:\s+|:::+|^\w{5,}|\w{5}$|^:{1}\w|\w:{1}$)/.test(data)
|
|
131
|
+
) {
|
|
33
132
|
return false;
|
|
34
133
|
}
|
|
35
134
|
|
|
36
|
-
const
|
|
135
|
+
const hasIpv4 = data.indexOf(".") !== -1;
|
|
136
|
+
let addressParts = data;
|
|
37
137
|
|
|
38
|
-
if (
|
|
39
|
-
|
|
138
|
+
if (hasIpv4) {
|
|
139
|
+
addressParts = data.split(":");
|
|
140
|
+
const ipv4Part = addressParts.pop();
|
|
141
|
+
if (
|
|
142
|
+
!/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])$/.test(
|
|
143
|
+
ipv4Part
|
|
144
|
+
)
|
|
145
|
+
) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
40
148
|
}
|
|
41
149
|
|
|
42
|
-
|
|
43
|
-
|
|
150
|
+
const isShortened = data.indexOf("::") !== -1;
|
|
151
|
+
const ipv6Part = hasIpv4 ? addressParts.join(":") : data;
|
|
152
|
+
|
|
153
|
+
if (isShortened) {
|
|
154
|
+
if (ipv6Part.split("::").length - 1 > 1) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (!/^[0-9a-fA-F:.]*$/.test(ipv6Part)) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return /^(?:(?:(?:[0-9a-fA-F]{1,4}(?::|$)){1,6}))|(?:::(?:[0-9a-fA-F]{1,4})){0,5}$/.test(
|
|
163
|
+
ipv6Part
|
|
164
|
+
);
|
|
44
165
|
}
|
|
45
166
|
|
|
46
|
-
|
|
167
|
+
const isIpv6Valid =
|
|
168
|
+
/^(?:(?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:))$/.test(ipv6Part);
|
|
169
|
+
|
|
170
|
+
const hasInvalidChar = /(?:[0-9a-fA-F]{5,}|\D[0-9a-fA-F]{3}:)/.test(
|
|
171
|
+
ipv6Part
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
if (hasIpv4) {
|
|
175
|
+
return isIpv6Valid || !hasInvalidChar;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return isIpv6Valid && !hasInvalidChar;
|
|
47
179
|
},
|
|
48
|
-
ipv4: isMyIpValid({ version: 4 }),
|
|
49
|
-
ipv6: isMyIpValid({ version: 6 }),
|
|
50
180
|
|
|
51
181
|
hostname(data) {
|
|
52
|
-
return
|
|
182
|
+
return /^[a-z0-9][a-z0-9-]{0,62}(?:\.[a-z0-9][a-z0-9-]{0,62})*[a-z0-9]$/i.test(
|
|
183
|
+
data
|
|
184
|
+
);
|
|
53
185
|
},
|
|
54
186
|
date(data) {
|
|
55
|
-
if (
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (RegExps.date.test(data) === false) {
|
|
187
|
+
if (/^(\d{4})-(\d{2})-(\d{2})$/.test(data) === false) {
|
|
60
188
|
return false;
|
|
61
189
|
}
|
|
62
190
|
|
|
@@ -70,31 +198,45 @@ export const Formats: Record<string, FormatFunction | false> = {
|
|
|
70
198
|
return false;
|
|
71
199
|
}
|
|
72
200
|
},
|
|
73
|
-
|
|
74
|
-
if (data ===
|
|
201
|
+
"json-pointer"(data) {
|
|
202
|
+
if (data === "") {
|
|
75
203
|
return true;
|
|
76
204
|
}
|
|
77
205
|
|
|
78
|
-
return
|
|
206
|
+
return /^\/(?:[^~]|~0|~1)*$/.test(data);
|
|
79
207
|
},
|
|
80
|
-
|
|
81
|
-
if (data ===
|
|
208
|
+
"relative-json-pointer"(data) {
|
|
209
|
+
if (data === "") {
|
|
82
210
|
return true;
|
|
83
211
|
}
|
|
84
212
|
|
|
85
|
-
return
|
|
213
|
+
return /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/.test(data);
|
|
86
214
|
},
|
|
87
215
|
time(data) {
|
|
88
|
-
return
|
|
216
|
+
return /^(\d{2}):(\d{2}):(\d{2})(\.\d+)?(Z|([+-])(\d{2}):(\d{2}))$/.test(
|
|
217
|
+
data
|
|
218
|
+
);
|
|
219
|
+
},
|
|
220
|
+
"uri-reference"(data) {
|
|
221
|
+
if (/\\/.test(data)) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return /^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#((?![^#]*\\)[^#]*))?/i.test(
|
|
226
|
+
data
|
|
227
|
+
);
|
|
228
|
+
},
|
|
229
|
+
"uri-template"(data) {
|
|
230
|
+
return /^(?:(?:https?:\/\/[\w.-]+)?\/?)?[\w- ;,.\/?%&=]*(?:\{[\w-]+(?::\d+)?\}[\w- ;,.\/?%&=]*)*\/?$/.test(
|
|
231
|
+
data
|
|
232
|
+
);
|
|
89
233
|
},
|
|
90
234
|
|
|
91
235
|
// Not supported yet
|
|
92
236
|
duration: false,
|
|
93
|
-
'idn-email': false,
|
|
94
|
-
'idn-hostname': false,
|
|
95
237
|
uuid: false,
|
|
96
|
-
|
|
238
|
+
"idn-email": false,
|
|
239
|
+
"idn-hostname": false,
|
|
97
240
|
iri: false,
|
|
98
|
-
|
|
99
|
-
'uri-template': false,
|
|
241
|
+
"iri-reference": false
|
|
100
242
|
};
|
package/lib/index.ts
CHANGED
|
@@ -45,10 +45,10 @@ export interface Validator {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export class SchemaShield {
|
|
48
|
-
types
|
|
49
|
-
formats
|
|
50
|
-
keywords
|
|
51
|
-
immutable = false;
|
|
48
|
+
private types: Record<string, TypeFunction | false> = {};
|
|
49
|
+
private formats: Record<string, FormatFunction | false> = {};
|
|
50
|
+
private keywords: Record<string, KeywordFunction | false> = {};
|
|
51
|
+
private immutable = false;
|
|
52
52
|
|
|
53
53
|
constructor({
|
|
54
54
|
immutable = false
|
|
@@ -74,16 +74,37 @@ export class SchemaShield {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
addType(name: string, validator: TypeFunction) {
|
|
78
|
-
this.types
|
|
77
|
+
addType(name: string, validator: TypeFunction, overwrite = false) {
|
|
78
|
+
if (this.types[name] && !overwrite) {
|
|
79
|
+
throw new ValidationError(`Type "${name}" already exists`);
|
|
80
|
+
}
|
|
81
|
+
this.types[name] = validator;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
getType(type: string): TypeFunction | false {
|
|
85
|
+
return this.types[type];
|
|
79
86
|
}
|
|
80
87
|
|
|
81
|
-
addFormat(name: string, validator: FormatFunction) {
|
|
82
|
-
this.formats
|
|
88
|
+
addFormat(name: string, validator: FormatFunction, overwrite = false) {
|
|
89
|
+
if (this.formats[name] && !overwrite) {
|
|
90
|
+
throw new ValidationError(`Format "${name}" already exists`);
|
|
91
|
+
}
|
|
92
|
+
this.formats[name] = validator;
|
|
83
93
|
}
|
|
84
94
|
|
|
85
|
-
|
|
86
|
-
this.
|
|
95
|
+
getFormat(format: string): FormatFunction | false {
|
|
96
|
+
return this.formats[format];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
addKeyword(name: string, validator: KeywordFunction, overwrite = false) {
|
|
100
|
+
if (this.keywords[name] && !overwrite) {
|
|
101
|
+
throw new ValidationError(`Keyword "${name}" already exists`);
|
|
102
|
+
}
|
|
103
|
+
this.keywords[name] = validator;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
getKeyword(keyword: string): KeywordFunction | false {
|
|
107
|
+
return this.keywords[keyword];
|
|
87
108
|
}
|
|
88
109
|
|
|
89
110
|
compile(schema: any): Validator {
|
|
@@ -144,7 +165,7 @@ export class SchemaShield {
|
|
|
144
165
|
: schema.type.split(",").map((t) => t.trim());
|
|
145
166
|
|
|
146
167
|
for (const type of types) {
|
|
147
|
-
const validator = this.
|
|
168
|
+
const validator = this.getType(type);
|
|
148
169
|
if (validator) {
|
|
149
170
|
typeValidations.push(validator);
|
|
150
171
|
methodName += (methodName ? "_OR_" : "") + validator.name;
|
|
@@ -162,10 +183,9 @@ export class SchemaShield {
|
|
|
162
183
|
compiledSchema.$validate = getNamedFunction<ValidateFunction>(
|
|
163
184
|
methodName,
|
|
164
185
|
(data) => {
|
|
165
|
-
if (typeValidation(data)) {
|
|
166
|
-
return;
|
|
186
|
+
if (!typeValidation(data)) {
|
|
187
|
+
return defineTypeError("Invalid type", { data });
|
|
167
188
|
}
|
|
168
|
-
return defineTypeError("Invalid type", { data });
|
|
169
189
|
}
|
|
170
190
|
);
|
|
171
191
|
} else if (typeValidationsLength > 1) {
|
|
@@ -189,17 +209,9 @@ export class SchemaShield {
|
|
|
189
209
|
continue;
|
|
190
210
|
}
|
|
191
211
|
|
|
192
|
-
const keywordValidator = this.
|
|
212
|
+
const keywordValidator = this.getKeyword(key);
|
|
193
213
|
if (keywordValidator) {
|
|
194
214
|
const defineError = getDefinedErrorFunctionForKey(key, schema[key]);
|
|
195
|
-
const executeKeywordValidator = (data: any) =>
|
|
196
|
-
(keywordValidator as KeywordFunction)(
|
|
197
|
-
compiledSchema,
|
|
198
|
-
data,
|
|
199
|
-
defineError,
|
|
200
|
-
this
|
|
201
|
-
);
|
|
202
|
-
|
|
203
215
|
if (compiledSchema.$validate) {
|
|
204
216
|
const prevValidator = compiledSchema.$validate;
|
|
205
217
|
methodName += `_AND_${keywordValidator.name}`;
|
|
@@ -210,17 +222,25 @@ export class SchemaShield {
|
|
|
210
222
|
if (error) {
|
|
211
223
|
return error;
|
|
212
224
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
return (keywordValidator as KeywordFunction)(
|
|
226
|
+
compiledSchema,
|
|
227
|
+
data,
|
|
228
|
+
defineError,
|
|
229
|
+
this
|
|
230
|
+
);
|
|
217
231
|
}
|
|
218
232
|
);
|
|
219
233
|
} else {
|
|
220
234
|
methodName = keywordValidator.name;
|
|
221
235
|
compiledSchema.$validate = getNamedFunction<ValidateFunction>(
|
|
222
236
|
methodName,
|
|
223
|
-
|
|
237
|
+
(data) =>
|
|
238
|
+
(keywordValidator as KeywordFunction)(
|
|
239
|
+
compiledSchema,
|
|
240
|
+
data,
|
|
241
|
+
defineError,
|
|
242
|
+
this
|
|
243
|
+
)
|
|
224
244
|
);
|
|
225
245
|
}
|
|
226
246
|
}
|
|
@@ -252,7 +272,7 @@ export class SchemaShield {
|
|
|
252
272
|
}
|
|
253
273
|
|
|
254
274
|
for (let subKey in subSchema) {
|
|
255
|
-
if (this.keywords
|
|
275
|
+
if (subKey in this.keywords) {
|
|
256
276
|
return true;
|
|
257
277
|
}
|
|
258
278
|
}
|
|
@@ -101,7 +101,7 @@ export const ArrayKeywords: Record<string, KeywordFunction> = {
|
|
|
101
101
|
},
|
|
102
102
|
|
|
103
103
|
additionalItems(schema, data, defineError) {
|
|
104
|
-
if (!
|
|
104
|
+
if (!schema.items || isObject(schema.items)) {
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -35,24 +35,18 @@ export const StringKeywords: Record<string, KeywordFunction> = {
|
|
|
35
35
|
return defineError("Value does not match the pattern", { data });
|
|
36
36
|
},
|
|
37
37
|
|
|
38
|
-
format
|
|
38
|
+
// Take into account that if we receive a format that is not defined, we
|
|
39
|
+
// will not throw an error, we just ignore it.
|
|
40
|
+
format(schema, data, defineError, instance) {
|
|
39
41
|
if (typeof data !== "string") {
|
|
40
42
|
return;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
const formatValidate =
|
|
44
|
-
if (formatValidate
|
|
45
|
+
const formatValidate = instance.getFormat(schema.format);
|
|
46
|
+
if (!formatValidate || formatValidate(data)) {
|
|
45
47
|
return;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
if (formatValidate(data)) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return defineError("Value does not match the format", { data });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return defineError("Format is not supported", { data });
|
|
50
|
+
return defineError("Value does not match the format", { data });
|
|
57
51
|
}
|
|
58
52
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "schema-shield",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "A fast library that protects your JSON schema from invalid data.",
|
|
5
5
|
"repository": "git@github.com:Masquerade-Circus/schema-shield.git",
|
|
6
6
|
"author": "Masquerade <christian@masquerade-circus.net>",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
72
|
"test": "mocha --bail --recursive --no-timeouts --forbid-only --exit --require ts-node/register --enable-source-maps tests/**/*.test.ts",
|
|
73
|
-
"dev:test": "nodemon -e ts,js -w ./tests -w ./lib --exec
|
|
73
|
+
"dev:test": "nodemon -e ts,js -w ./tests -w ./lib --exec mocha --bail --recursive --no-timeouts --exit --require ts-node/register --enable-source-maps tests/**/*.test.ts",
|
|
74
74
|
"dev:source": "NODE_ENV=development nodemon --enable-source-maps -e tsx,ts,json,css -w ./lib -w ./www source.js",
|
|
75
75
|
"build": "node source.js",
|
|
76
76
|
"coverage": "nyc report --reporter=lcov",
|
|
@@ -79,13 +79,13 @@
|
|
|
79
79
|
"release-test": "release-it --dry-run --verbose"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
|
-
"is-my-ip-valid": "^1.0.1",
|
|
83
82
|
"ts-node": "^10.9.1",
|
|
84
83
|
"tsc-prog": "^2.2.1",
|
|
85
84
|
"tslib": "^2.5.0",
|
|
86
85
|
"typescript": "^5.0.2"
|
|
87
86
|
},
|
|
88
87
|
"devDependencies": {
|
|
88
|
+
"@exodus/schemasafe": "^1.0.0",
|
|
89
89
|
"@release-it/conventional-changelog": "^5.1.1",
|
|
90
90
|
"@typescript-eslint/eslint-plugin": "^5.56.0",
|
|
91
91
|
"@typescript-eslint/parser": "^5.56.0",
|