@oscarpalmer/jhunal 0.11.0 → 0.13.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.
@@ -1,233 +0,0 @@
1
- import {isConstructor, isPlainObject} from '@oscarpalmer/atoms/is';
2
- import type {PlainObject} from '@oscarpalmer/atoms/models';
3
- import {smush} from '@oscarpalmer/atoms/value/misc';
4
- import {
5
- EXPRESSION_HAS_NUMBER,
6
- EXPRESSION_INDEX,
7
- EXPRESSION_PROPERTY,
8
- MESSAGE_SCHEMA_INVALID_EMPTY,
9
- MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED,
10
- MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE,
11
- MESSAGE_VALIDATOR_INVALID_KEY,
12
- MESSAGE_VALIDATOR_INVALID_TYPE,
13
- MESSAGE_VALIDATOR_INVALID_VALUE,
14
- PROPERTY_REQUIRED,
15
- PROPERTY_TYPE,
16
- PROPERTY_VALIDATORS,
17
- TEMPLATE_PATTERN,
18
- TYPE_ALL,
19
- TYPE_OBJECT,
20
- TYPE_UNDEFINED,
21
- VALIDATABLE_TYPES,
22
- } from '../constants';
23
- import {isInstance, isSchematic} from '../is';
24
- import {
25
- SchematicError,
26
- type Schema,
27
- type ValidatedPropertyType,
28
- type ValidatedPropertyValidators,
29
- type ValidatedSchema,
30
- type ValueName,
31
- } from '../models';
32
-
33
- function addPropertyType(
34
- to: ValidatedSchema,
35
- key: string,
36
- values: ValidatedPropertyType[],
37
- validators: ValidatedPropertyValidators,
38
- required: boolean,
39
- ): void {
40
- if (to.keys.set.has(key)) {
41
- const property = to.properties[key];
42
-
43
- for (const type of values) {
44
- property.types.push(type);
45
- }
46
- } else {
47
- to.keys.array.push(key);
48
- to.keys.set.add(key);
49
-
50
- to.properties[key] = {
51
- required,
52
- types: values,
53
- validators: {},
54
- };
55
- }
56
-
57
- if (!required && !to.properties[key].types.includes(TYPE_UNDEFINED)) {
58
- to.properties[key].types.push(TYPE_UNDEFINED);
59
- }
60
-
61
- to.properties[key].validators = validators;
62
- }
63
-
64
- export function getSchema(schema: Schema): ValidatedSchema {
65
- return getValidatedSchema(schema, {
66
- keys: {
67
- array: [],
68
- set: new Set<string>(),
69
- },
70
- properties: {},
71
- });
72
- }
73
-
74
- function getTypes(
75
- value: unknown,
76
- validated: ValidatedSchema,
77
- prefix: string,
78
- ): ValidatedPropertyType[] {
79
- const propertyTypes: ValidatedPropertyType[] = [];
80
-
81
- const values = Array.isArray(value) ? value : [value];
82
- const {length} = values;
83
-
84
- for (let index = 0; index < length; index += 1) {
85
- const type = values[index];
86
-
87
- if (isSchematic(type) || TYPE_ALL.has(type as never)) {
88
- propertyTypes.push(type);
89
-
90
- continue;
91
- }
92
-
93
- if (typeof type === 'function') {
94
- propertyTypes.push(isConstructor(type) ? isInstance(type) : type);
95
-
96
- continue;
97
- }
98
-
99
- if (!isPlainObject(type)) {
100
- throw new SchematicError(
101
- MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace(TEMPLATE_PATTERN, prefix),
102
- );
103
- }
104
-
105
- if (PROPERTY_TYPE in type) {
106
- propertyTypes.push(...getTypes(type[PROPERTY_TYPE], validated, prefix));
107
-
108
- continue;
109
- }
110
-
111
- const {[PROPERTY_REQUIRED]: required, ...nested} = type;
112
-
113
- if (PROPERTY_REQUIRED in type && typeof required !== 'boolean') {
114
- throw new SchematicError(
115
- MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace(TEMPLATE_PATTERN, prefix),
116
- );
117
- }
118
-
119
- addPropertyType(validated, prefix, [TYPE_OBJECT], {}, required !== false);
120
-
121
- propertyTypes.push(TYPE_OBJECT);
122
-
123
- getValidatedSchema(nested as Schema, validated, prefix);
124
- }
125
-
126
- return propertyTypes;
127
- }
128
-
129
- function getValidatedSchema(
130
- schema: Schema,
131
- validated: ValidatedSchema,
132
- prefix?: string,
133
- ): ValidatedSchema {
134
- const smushed = smush(schema as PlainObject);
135
- const keys = Object.keys(smushed);
136
- const {length} = keys;
137
-
138
- const arrayKeys = new Set<string>();
139
- const noPrefix = prefix == null;
140
-
141
- prefix = noPrefix ? '' : `${prefix}.`;
142
-
143
- for (let index = 0; index < length; index += 1) {
144
- const key = keys[index];
145
- const value = smushed[key];
146
-
147
- if (Array.isArray(value)) {
148
- arrayKeys.add(key);
149
- }
150
-
151
- if (EXPRESSION_PROPERTY.test(key)) {
152
- continue;
153
- }
154
-
155
- if (EXPRESSION_HAS_NUMBER.test(key) && arrayKeys.has(key.replace(EXPRESSION_INDEX, ''))) {
156
- continue;
157
- }
158
-
159
- let required = true;
160
- let validators: ValidatedPropertyValidators = {};
161
-
162
- const isObject = isPlainObject(value);
163
-
164
- if (isObject && PROPERTY_REQUIRED in value) {
165
- if (typeof value[PROPERTY_REQUIRED] !== 'boolean') {
166
- throw new SchematicError(
167
- MESSAGE_SCHEMA_INVALID_PROPERTY_REQUIRED.replace(TEMPLATE_PATTERN, key),
168
- );
169
- }
170
-
171
- required = value[PROPERTY_REQUIRED] === true;
172
- }
173
-
174
- if (isObject && PROPERTY_VALIDATORS in value) {
175
- validators = getValidators(value[PROPERTY_VALIDATORS]);
176
- }
177
-
178
- const prefixedKey = `${prefix}${key}`;
179
-
180
- const types = getTypes(value, validated, prefixedKey);
181
-
182
- if (types.length === 0) {
183
- throw new SchematicError(MESSAGE_SCHEMA_INVALID_PROPERTY_TYPE.replace(TEMPLATE_PATTERN, key));
184
- }
185
-
186
- addPropertyType(validated, prefixedKey, types, validators, required);
187
- }
188
-
189
- if (noPrefix) {
190
- validated.keys.array.sort();
191
- }
192
-
193
- if (noPrefix && validated.keys.array.length === 0) {
194
- throw new SchematicError(MESSAGE_SCHEMA_INVALID_EMPTY);
195
- }
196
-
197
- return validated;
198
- }
199
-
200
- function getValidators(original: unknown): ValidatedPropertyValidators {
201
- const validators: ValidatedPropertyValidators = {};
202
-
203
- if (original == null) {
204
- return validators;
205
- }
206
-
207
- if (!isPlainObject(original)) {
208
- throw new TypeError(MESSAGE_VALIDATOR_INVALID_TYPE);
209
- }
210
-
211
- const keys = Object.keys(original);
212
- const {length} = keys;
213
-
214
- for (let index = 0; index < length; index += 1) {
215
- const key = keys[index];
216
-
217
- if (!VALIDATABLE_TYPES.has(key as never)) {
218
- throw new TypeError(MESSAGE_VALIDATOR_INVALID_KEY.replace(TEMPLATE_PATTERN, key));
219
- }
220
-
221
- const value = (original as PlainObject)[key];
222
-
223
- validators[key as ValueName] = (Array.isArray(value) ? value : [value]).filter(item => {
224
- if (typeof item !== 'function') {
225
- throw new TypeError(MESSAGE_VALIDATOR_INVALID_VALUE.replace(TEMPLATE_PATTERN, key));
226
- }
227
-
228
- return true;
229
- });
230
- }
231
-
232
- return validators;
233
- }
@@ -1,2 +0,0 @@
1
- import { type Schema, type ValidatedSchema } from '../models';
2
- export declare function getSchema(schema: Schema): ValidatedSchema;