@oscarpalmer/jhunal 0.22.0 → 0.24.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/constants.d.mts +11 -4
- package/dist/constants.mjs +27 -8
- package/dist/helpers/message.helper.d.mts +17 -0
- package/dist/helpers/message.helper.mjs +92 -0
- package/dist/helpers/misc.helper.d.mts +22 -0
- package/dist/helpers/misc.helper.mjs +56 -0
- package/dist/index.d.mts +309 -292
- package/dist/index.mjs +237 -166
- package/dist/models/schema.plain.model.d.mts +2 -0
- package/dist/models/schema.typed.model.d.mts +3 -17
- package/dist/models/validation.model.d.mts +28 -7
- package/dist/schematic.d.mts +25 -7
- package/dist/schematic.mjs +6 -4
- package/dist/validator/base.validator.d.mts +6 -0
- package/dist/validator/base.validator.mjs +19 -0
- package/dist/validator/function.validator.d.mts +6 -0
- package/dist/validator/function.validator.mjs +9 -0
- package/dist/validator/named.handler.d.mts +6 -0
- package/dist/validator/named.handler.mjs +23 -0
- package/dist/validator/named.validator.d.mts +7 -0
- package/dist/validator/named.validator.mjs +38 -0
- package/dist/validator/object.validator.d.mts +7 -0
- package/dist/validator/object.validator.mjs +185 -0
- package/dist/validator/schematic.validator.d.mts +7 -0
- package/dist/validator/schematic.validator.mjs +16 -0
- package/package.json +1 -1
- package/src/constants.ts +34 -6
- package/src/helpers/message.helper.ts +217 -0
- package/src/helpers/misc.helper.ts +92 -0
- package/src/index.ts +3 -3
- package/src/models/schema.plain.model.ts +2 -0
- package/src/models/schema.typed.model.ts +4 -22
- package/src/models/validation.model.ts +31 -6
- package/src/schematic.ts +43 -16
- package/src/validator/base.validator.ts +31 -0
- package/src/validator/function.validator.ts +9 -0
- package/src/validator/named.handler.ts +65 -0
- package/src/validator/named.validator.ts +61 -0
- package/src/validator/object.validator.ts +366 -0
- package/src/validator/schematic.validator.ts +25 -0
- package/dist/helpers.d.mts +0 -28
- package/dist/helpers.mjs +0 -120
- package/dist/validation.d.mts +0 -7
- package/dist/validation.mjs +0 -245
- package/src/helpers.ts +0 -249
- package/src/validation.ts +0 -498
package/dist/validation.mjs
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { PROPERTY_REQUIRED, PROPERTY_TYPE, PROPERTY_VALIDATORS, SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED, SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE, SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE, TYPE_ALL } from "./constants.mjs";
|
|
2
|
-
import { getInvalidInputMessage, getInvalidMissingMessage, getInvalidTypeMessage, getInvalidValidatorMessage, getUnknownKeysMessage, instanceOf, isSchematic } from "./helpers.mjs";
|
|
3
|
-
import { SchematicError, ValidationError } from "./models/validation.model.mjs";
|
|
4
|
-
import { schematicValidator } from "./schematic.mjs";
|
|
5
|
-
import { isConstructor, isPlainObject } from "@oscarpalmer/atoms/is";
|
|
6
|
-
import { join } from "@oscarpalmer/atoms";
|
|
7
|
-
import { clone } from "@oscarpalmer/atoms/value/clone";
|
|
8
|
-
//#region src/validation.ts
|
|
9
|
-
function getDisallowedProperty(obj) {
|
|
10
|
-
if ("$required" in obj) return PROPERTY_REQUIRED;
|
|
11
|
-
if ("$type" in obj) return PROPERTY_TYPE;
|
|
12
|
-
if ("$validators" in obj) return PROPERTY_VALIDATORS;
|
|
13
|
-
}
|
|
14
|
-
function getFunctionValidator(fn) {
|
|
15
|
-
const validator = isConstructor(fn) ? instanceOf(fn) : fn;
|
|
16
|
-
return (input) => validator(input) === true;
|
|
17
|
-
}
|
|
18
|
-
function getNamedValidator(key, name, handlers) {
|
|
19
|
-
const validator = namedValidators[name];
|
|
20
|
-
const named = handlers[name] ?? [];
|
|
21
|
-
const { length } = named;
|
|
22
|
-
return (input, parameters) => {
|
|
23
|
-
if (!validator(input)) return false;
|
|
24
|
-
for (let index = 0; index < length; index += 1) {
|
|
25
|
-
const handler = named[index];
|
|
26
|
-
if (handler(input) === true) continue;
|
|
27
|
-
const information = {
|
|
28
|
-
key,
|
|
29
|
-
validator,
|
|
30
|
-
message: getInvalidValidatorMessage(key.full, name, index, length),
|
|
31
|
-
value: input
|
|
32
|
-
};
|
|
33
|
-
parameters.information?.push(information);
|
|
34
|
-
return parameters.reporting.none ? false : [information];
|
|
35
|
-
}
|
|
36
|
-
return true;
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function getNamedHandlers(original, prefix) {
|
|
40
|
-
const handlers = {};
|
|
41
|
-
if (original == null) return handlers;
|
|
42
|
-
if (!isPlainObject(original)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_TYPE);
|
|
43
|
-
const keys = Object.keys(original);
|
|
44
|
-
const { length } = keys;
|
|
45
|
-
for (let index = 0; index < length; index += 1) {
|
|
46
|
-
const key = keys[index];
|
|
47
|
-
if (!TYPE_ALL.has(key)) throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_KEY.replace("<>", key));
|
|
48
|
-
const value = original[key];
|
|
49
|
-
handlers[key] = (Array.isArray(value) ? value : [value]).map((item) => {
|
|
50
|
-
if (typeof item !== "function") throw new TypeError(SCHEMATIC_MESSAGE_VALIDATOR_INVALID_VALUE.replace("<>", key).replace("<>", prefix));
|
|
51
|
-
return item;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
return handlers;
|
|
55
|
-
}
|
|
56
|
-
function getObjectValidator(original, origin, fromType) {
|
|
57
|
-
const keys = Object.keys(original);
|
|
58
|
-
const keysLength = keys.length;
|
|
59
|
-
if (keysLength === 0) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_EMPTY);
|
|
60
|
-
if (fromType ?? false) {
|
|
61
|
-
const property = getDisallowedProperty(original);
|
|
62
|
-
if (property != null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_DISALLOWED.replace("<>", origin.full).replace("<>", property));
|
|
63
|
-
}
|
|
64
|
-
const set = /* @__PURE__ */ new Set();
|
|
65
|
-
const items = [];
|
|
66
|
-
for (let keyIndex = 0; keyIndex < keysLength; keyIndex += 1) {
|
|
67
|
-
const key = keys[keyIndex];
|
|
68
|
-
const value = original[key];
|
|
69
|
-
if (value == null) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_NULLABLE.replace("<>", join([origin?.full, key], ".")));
|
|
70
|
-
const prefixedKey = origin == null ? key : join([origin.full, key], ".");
|
|
71
|
-
const fullKey = {
|
|
72
|
-
full: prefixedKey,
|
|
73
|
-
short: key
|
|
74
|
-
};
|
|
75
|
-
let handlers = {};
|
|
76
|
-
let required = true;
|
|
77
|
-
let typed = false;
|
|
78
|
-
let types;
|
|
79
|
-
const validators = [];
|
|
80
|
-
if (isPlainObject(value)) {
|
|
81
|
-
typed = PROPERTY_TYPE in value;
|
|
82
|
-
const type = typed ? value[PROPERTY_TYPE] : value;
|
|
83
|
-
handlers = getNamedHandlers(value[PROPERTY_VALIDATORS], prefixedKey);
|
|
84
|
-
required = getRequired(key, value) ?? required;
|
|
85
|
-
types = Array.isArray(type) ? type : [type];
|
|
86
|
-
} else types = Array.isArray(value) ? value : [value];
|
|
87
|
-
if (types.length === 0) throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace("<>", prefixedKey).replace("<>", String(value)));
|
|
88
|
-
const typesLength = types.length;
|
|
89
|
-
for (let typeIndex = 0; typeIndex < typesLength; typeIndex += 1) {
|
|
90
|
-
const type = types[typeIndex];
|
|
91
|
-
let validator;
|
|
92
|
-
switch (true) {
|
|
93
|
-
case typeof type === "function":
|
|
94
|
-
validator = getFunctionValidator(type);
|
|
95
|
-
break;
|
|
96
|
-
case isPlainObject(type):
|
|
97
|
-
validator = getObjectValidator(type, fullKey, typed);
|
|
98
|
-
break;
|
|
99
|
-
case isSchematic(type):
|
|
100
|
-
validator = getSchematicValidator(type);
|
|
101
|
-
break;
|
|
102
|
-
case TYPE_ALL.has(type):
|
|
103
|
-
validator = getNamedValidator(fullKey, type, handlers);
|
|
104
|
-
break;
|
|
105
|
-
default: throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace("<>", prefixedKey).replace("<>", String(type)));
|
|
106
|
-
}
|
|
107
|
-
validators.push(validator);
|
|
108
|
-
}
|
|
109
|
-
set.add(key);
|
|
110
|
-
items.push({
|
|
111
|
-
types,
|
|
112
|
-
key: fullKey,
|
|
113
|
-
required: required && !types.includes("undefined"),
|
|
114
|
-
validator: getValidator(validators)
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
const validatorsLength = items.length;
|
|
118
|
-
return (input, parameters, get) => {
|
|
119
|
-
if (!isPlainObject(input)) {
|
|
120
|
-
if (origin != null) return false;
|
|
121
|
-
const information = {
|
|
122
|
-
key: {
|
|
123
|
-
full: "",
|
|
124
|
-
short: ""
|
|
125
|
-
},
|
|
126
|
-
value: input,
|
|
127
|
-
message: getInvalidInputMessage(input)
|
|
128
|
-
};
|
|
129
|
-
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
130
|
-
parameters.information?.push(information);
|
|
131
|
-
return parameters.reporting.none ? false : [information];
|
|
132
|
-
}
|
|
133
|
-
if (parameters.strict) {
|
|
134
|
-
const unknownKeys = Object.keys(input).filter((key) => !set.has(key));
|
|
135
|
-
if (unknownKeys.length > 0) {
|
|
136
|
-
const information = {
|
|
137
|
-
key: origin ?? {
|
|
138
|
-
full: "",
|
|
139
|
-
short: ""
|
|
140
|
-
},
|
|
141
|
-
message: getUnknownKeysMessage(unknownKeys),
|
|
142
|
-
value: input
|
|
143
|
-
};
|
|
144
|
-
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
145
|
-
parameters.information?.push(information);
|
|
146
|
-
return parameters.reporting.none ? false : [information];
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const allInformation = [];
|
|
150
|
-
const output = {};
|
|
151
|
-
for (let validatorIndex = 0; validatorIndex < validatorsLength; validatorIndex += 1) {
|
|
152
|
-
const { key, required, types, validator } = items[validatorIndex];
|
|
153
|
-
const value = input[key.short];
|
|
154
|
-
if (value === void 0) {
|
|
155
|
-
if (required) {
|
|
156
|
-
if (parameters.reporting.none) return false;
|
|
157
|
-
const information = {
|
|
158
|
-
key,
|
|
159
|
-
value,
|
|
160
|
-
message: getInvalidMissingMessage(key.full, types)
|
|
161
|
-
};
|
|
162
|
-
if (parameters.reporting.throw) throw new ValidationError([information]);
|
|
163
|
-
parameters.information?.push(information);
|
|
164
|
-
if (parameters.reporting.all) {
|
|
165
|
-
allInformation.push(information);
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
return [information];
|
|
169
|
-
}
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
const previousOutput = parameters.output;
|
|
173
|
-
parameters.output = output;
|
|
174
|
-
const result = validator(value, parameters, get);
|
|
175
|
-
parameters.output = previousOutput;
|
|
176
|
-
if (result === false) continue;
|
|
177
|
-
if (result === true) {
|
|
178
|
-
if (get) output[key.short] = clone(value);
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (parameters.reporting.none) return false;
|
|
182
|
-
const information = typeof result !== "boolean" && result.length > 0 ? result : [{
|
|
183
|
-
key,
|
|
184
|
-
value,
|
|
185
|
-
message: getInvalidTypeMessage(key.full, types, value)
|
|
186
|
-
}];
|
|
187
|
-
if (parameters.reporting.throw) throw new ValidationError(information);
|
|
188
|
-
if (parameters.reporting.all) {
|
|
189
|
-
allInformation.push(...information);
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
return information;
|
|
193
|
-
}
|
|
194
|
-
if (get) if (origin == null) parameters.output = output;
|
|
195
|
-
else parameters.output[origin.short] = output;
|
|
196
|
-
return parameters.reporting.none || allInformation.length === 0 ? true : allInformation;
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
function getRequired(key, obj) {
|
|
200
|
-
if (!("$required" in obj)) return;
|
|
201
|
-
if (typeof obj["$required"] !== "boolean") throw new SchematicError(SCHEMATIC_MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace("<>", key));
|
|
202
|
-
return obj[PROPERTY_REQUIRED];
|
|
203
|
-
}
|
|
204
|
-
function getSchematicValidator(schematic) {
|
|
205
|
-
const validator = schematicValidator.get(schematic);
|
|
206
|
-
return (input, parameters, get) => {
|
|
207
|
-
let result = false;
|
|
208
|
-
if (isPlainObject(input)) result = validator(input, parameters, get);
|
|
209
|
-
if (typeof result === "boolean") return result;
|
|
210
|
-
parameters.information?.push(...result);
|
|
211
|
-
return result.length === 0 ? true : result;
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
function getValidator(validators) {
|
|
215
|
-
const { length } = validators;
|
|
216
|
-
return (input, parameters, get) => {
|
|
217
|
-
const allInformation = [];
|
|
218
|
-
for (let index = 0; index < length; index += 1) {
|
|
219
|
-
const previousInformation = parameters.information;
|
|
220
|
-
parameters.information = [];
|
|
221
|
-
const result = validators[index](input, parameters, get);
|
|
222
|
-
parameters.information = previousInformation;
|
|
223
|
-
if (result === false) continue;
|
|
224
|
-
if (result === true) return true;
|
|
225
|
-
parameters.information?.push(...result);
|
|
226
|
-
allInformation.push(...result);
|
|
227
|
-
}
|
|
228
|
-
return allInformation;
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
const namedValidators = {
|
|
232
|
-
array: Array.isArray,
|
|
233
|
-
bigint: (value) => typeof value === "bigint",
|
|
234
|
-
boolean: (value) => typeof value === "boolean",
|
|
235
|
-
date: (value) => value instanceof Date,
|
|
236
|
-
function: (value) => typeof value === "function",
|
|
237
|
-
null: (value) => value === null,
|
|
238
|
-
number: (value) => typeof value === "number",
|
|
239
|
-
object: (value) => typeof value === "object" && value !== null,
|
|
240
|
-
string: (value) => typeof value === "string",
|
|
241
|
-
symbol: (value) => typeof value === "symbol",
|
|
242
|
-
undefined: (value) => value === void 0
|
|
243
|
-
};
|
|
244
|
-
//#endregion
|
|
245
|
-
export { getObjectValidator };
|
package/src/helpers.ts
DELETED
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
import {isConstructor, isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
|
-
import type {Constructor} from '@oscarpalmer/atoms/models';
|
|
3
|
-
import {
|
|
4
|
-
COMMA,
|
|
5
|
-
CONJUNCTION_AND,
|
|
6
|
-
CONJUNCTION_AND_COMMA,
|
|
7
|
-
CONJUNCTION_OR,
|
|
8
|
-
CONJUNCTION_OR_COMMA,
|
|
9
|
-
MESSAGE_CONSTRUCTOR,
|
|
10
|
-
NAME_SCHEMATIC,
|
|
11
|
-
PROPERTY_SCHEMATIC,
|
|
12
|
-
REPORTING_ALL,
|
|
13
|
-
REPORTING_FIRST,
|
|
14
|
-
REPORTING_NONE,
|
|
15
|
-
REPORTING_THROW,
|
|
16
|
-
REPORTING_TYPES,
|
|
17
|
-
TEMPLATE_PATTERN,
|
|
18
|
-
TYPE_ARRAY,
|
|
19
|
-
TYPE_NULL,
|
|
20
|
-
TYPE_OBJECT,
|
|
21
|
-
TYPE_UNDEFINED,
|
|
22
|
-
VALIDATION_MESSAGE_INVALID_INPUT,
|
|
23
|
-
VALIDATION_MESSAGE_INVALID_REQUIRED,
|
|
24
|
-
VALIDATION_MESSAGE_INVALID_TYPE,
|
|
25
|
-
VALIDATION_MESSAGE_INVALID_VALUE,
|
|
26
|
-
VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX,
|
|
27
|
-
VALIDATION_MESSAGE_UNKNOWN_KEYS,
|
|
28
|
-
} from './constants';
|
|
29
|
-
import type {ValueName} from './models/misc.model';
|
|
30
|
-
import type {
|
|
31
|
-
ReportingInformation,
|
|
32
|
-
ReportingType,
|
|
33
|
-
ValidatorParameters,
|
|
34
|
-
ValidatorType,
|
|
35
|
-
} from './models/validation.model';
|
|
36
|
-
import type {Schematic} from './schematic';
|
|
37
|
-
|
|
38
|
-
export function getInvalidInputMessage(actual: unknown): string {
|
|
39
|
-
return VALIDATION_MESSAGE_INVALID_INPUT.replace(TEMPLATE_PATTERN, getValueType(actual));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function getInvalidMissingMessage(key: string, types: ValidatorType[]): string {
|
|
43
|
-
let message = VALIDATION_MESSAGE_INVALID_REQUIRED.replace(TEMPLATE_PATTERN, renderTypes(types));
|
|
44
|
-
|
|
45
|
-
message = message.replace(TEMPLATE_PATTERN, key);
|
|
46
|
-
|
|
47
|
-
return message;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export function getInvalidTypeMessage(
|
|
51
|
-
key: string,
|
|
52
|
-
types: ValidatorType[],
|
|
53
|
-
actual: unknown,
|
|
54
|
-
): string {
|
|
55
|
-
let message = VALIDATION_MESSAGE_INVALID_TYPE.replace(TEMPLATE_PATTERN, renderTypes(types));
|
|
56
|
-
|
|
57
|
-
message = message.replace(TEMPLATE_PATTERN, key);
|
|
58
|
-
message = message.replace(TEMPLATE_PATTERN, getValueType(actual));
|
|
59
|
-
|
|
60
|
-
return message;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function getInvalidValidatorMessage(
|
|
64
|
-
key: string,
|
|
65
|
-
type: ValueName,
|
|
66
|
-
index: number,
|
|
67
|
-
length: number,
|
|
68
|
-
): string {
|
|
69
|
-
let message = VALIDATION_MESSAGE_INVALID_VALUE.replace(TEMPLATE_PATTERN, key);
|
|
70
|
-
|
|
71
|
-
message = message.replace(TEMPLATE_PATTERN, type);
|
|
72
|
-
|
|
73
|
-
if (length > 1) {
|
|
74
|
-
message += VALIDATION_MESSAGE_INVALID_VALUE_SUFFIX.replace(TEMPLATE_PATTERN, String(index));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return message;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export function getParameters(input?: unknown): ValidatorParameters {
|
|
81
|
-
if (typeof input === 'boolean') {
|
|
82
|
-
return {
|
|
83
|
-
output: {},
|
|
84
|
-
reporting: getReporting(REPORTING_NONE),
|
|
85
|
-
strict: input,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (REPORTING_TYPES.has(input as ReportingType)) {
|
|
90
|
-
return {
|
|
91
|
-
output: {},
|
|
92
|
-
reporting: getReporting(input as ReportingType),
|
|
93
|
-
strict: false,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const options = isPlainObject(input) ? input : {};
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
output: {},
|
|
101
|
-
reporting: getReporting(options.errors),
|
|
102
|
-
strict: typeof options.strict === 'boolean' ? options.strict : false,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function getPropertyType(original: ValidatorType): string {
|
|
107
|
-
if (typeof original === 'function') {
|
|
108
|
-
return 'a validated value';
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (Array.isArray(original)) {
|
|
112
|
-
return `'array'`;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (isPlainObject(original)) {
|
|
116
|
-
return `'${TYPE_OBJECT}'`;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (isSchematic(original)) {
|
|
120
|
-
return `a ${NAME_SCHEMATIC}`;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return `'${String(original)}'`;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function getReporting(value: unknown): ReportingInformation {
|
|
127
|
-
const type = REPORTING_TYPES.has(value as ReportingType)
|
|
128
|
-
? (value as ReportingType)
|
|
129
|
-
: REPORTING_NONE;
|
|
130
|
-
|
|
131
|
-
return {
|
|
132
|
-
type,
|
|
133
|
-
[REPORTING_ALL]: type === REPORTING_ALL,
|
|
134
|
-
[REPORTING_FIRST]: type === REPORTING_FIRST,
|
|
135
|
-
[REPORTING_NONE]: type === REPORTING_NONE,
|
|
136
|
-
[REPORTING_THROW]: type === REPORTING_THROW,
|
|
137
|
-
} as ReportingInformation;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function getUnknownKeysMessage(keys: string[]): string {
|
|
141
|
-
return VALIDATION_MESSAGE_UNKNOWN_KEYS.replace(TEMPLATE_PATTERN, renderKeys(keys));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function getValueType(value: unknown): string {
|
|
145
|
-
const valueType = typeof value;
|
|
146
|
-
|
|
147
|
-
switch (true) {
|
|
148
|
-
case value === null:
|
|
149
|
-
return `'${TYPE_NULL}'`;
|
|
150
|
-
|
|
151
|
-
case value === undefined:
|
|
152
|
-
return `'${TYPE_UNDEFINED}'`;
|
|
153
|
-
|
|
154
|
-
case valueType !== TYPE_OBJECT:
|
|
155
|
-
return `'${valueType}'`;
|
|
156
|
-
|
|
157
|
-
case Array.isArray(value):
|
|
158
|
-
return `'${TYPE_ARRAY}'`;
|
|
159
|
-
|
|
160
|
-
case isPlainObject(value):
|
|
161
|
-
return `'${TYPE_OBJECT}'`;
|
|
162
|
-
|
|
163
|
-
case isSchematic(value):
|
|
164
|
-
return `a ${NAME_SCHEMATIC}`;
|
|
165
|
-
|
|
166
|
-
default:
|
|
167
|
-
return value.constructor.name;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Creates a validator function for a given constructor
|
|
173
|
-
* @param constructor - Constructor to check against
|
|
174
|
-
* @throws Will throw a `TypeError` if the provided argument is not a valid constructor
|
|
175
|
-
* @returns Validator function that checks if a value is an instance of the constructor
|
|
176
|
-
*/
|
|
177
|
-
export function instanceOf<Instance>(
|
|
178
|
-
constructor: Constructor<Instance>,
|
|
179
|
-
): (value: unknown) => value is Instance {
|
|
180
|
-
if (!isConstructor(constructor)) {
|
|
181
|
-
throw new TypeError(MESSAGE_CONSTRUCTOR);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return (value: unknown): value is Instance => {
|
|
185
|
-
return value instanceof constructor;
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Is the value a schematic?
|
|
191
|
-
* @param value Value to check
|
|
192
|
-
* @returns `true` if the value is a schematic, `false` otherwise
|
|
193
|
-
*/
|
|
194
|
-
export function isSchematic(value: unknown): value is Schematic<never> {
|
|
195
|
-
return (
|
|
196
|
-
typeof value === 'object' &&
|
|
197
|
-
value !== null &&
|
|
198
|
-
PROPERTY_SCHEMATIC in value &&
|
|
199
|
-
value[PROPERTY_SCHEMATIC] === true
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function renderKeys(keys: string[]): string {
|
|
204
|
-
return renderParts(
|
|
205
|
-
keys.map(key => `'${key}'`),
|
|
206
|
-
CONJUNCTION_AND,
|
|
207
|
-
CONJUNCTION_AND_COMMA,
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function renderParts(parts: string[], delimiterShort: string, delimiterLong: string): string {
|
|
212
|
-
const {length} = parts;
|
|
213
|
-
|
|
214
|
-
if (length === 1) {
|
|
215
|
-
return parts[0];
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
let rendered = '';
|
|
219
|
-
|
|
220
|
-
for (let index = 0; index < length; index += 1) {
|
|
221
|
-
rendered += parts[index];
|
|
222
|
-
|
|
223
|
-
if (index < length - 2) {
|
|
224
|
-
rendered += COMMA;
|
|
225
|
-
} else if (index === length - 2) {
|
|
226
|
-
rendered += parts.length > 2 ? delimiterLong : delimiterShort;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return rendered;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
function renderTypes(types: ValidatorType[]): string {
|
|
234
|
-
const unique = new Set<string>();
|
|
235
|
-
const parts: string[] = [];
|
|
236
|
-
|
|
237
|
-
for (let index = 0; index < types.length; index += 1) {
|
|
238
|
-
const rendered = getPropertyType(types[index]);
|
|
239
|
-
|
|
240
|
-
if (unique.has(rendered)) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
unique.add(rendered);
|
|
245
|
-
parts.push(rendered);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return renderParts(parts, CONJUNCTION_OR, CONJUNCTION_OR_COMMA);
|
|
249
|
-
}
|