vortez 5.0.0-dev.18 → 5.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.
- package/.gitignore +11 -4
- package/README.md +699 -177
- package/build/Template/Compiler.d.ts +70 -0
- package/build/Template/Compiler.js +135 -0
- package/build/Template/Compiler.js.map +1 -0
- package/build/Template/StreamCompiler.d.ts +16 -0
- package/build/Template/StreamCompiler.js +54 -0
- package/build/Template/StreamCompiler.js.map +1 -0
- package/build/Template/Template.d.ts +49 -0
- package/build/Template/Template.js +77 -0
- package/build/Template/Template.js.map +1 -0
- package/build/Vortez.d.ts +2 -1
- package/build/Vortez.js +2 -1
- package/build/Vortez.js.map +1 -1
- package/build/beta/JwtManager/JwtError.d.ts +8 -0
- package/build/beta/JwtManager/JwtError.js +10 -0
- package/build/beta/JwtManager/JwtError.js.map +1 -0
- package/build/beta/JwtManager/JwtManager.d.ts +3 -0
- package/build/beta/JwtManager/JwtManager.js +24 -7
- package/build/beta/JwtManager/JwtManager.js.map +1 -1
- package/build/server/BodyParser.d.ts +6 -0
- package/build/server/BodyParser.js +18 -3
- package/build/server/BodyParser.js.map +1 -1
- package/build/server/Request.d.ts +6 -4
- package/build/server/Request.js +15 -10
- package/build/server/Request.js.map +1 -1
- package/build/server/Response.d.ts +25 -10
- package/build/server/Response.js +161 -75
- package/build/server/Response.js.map +1 -1
- package/build/server/Server.d.ts +4 -4
- package/build/server/Server.js +34 -11
- package/build/server/Server.js.map +1 -1
- package/build/server/ServerDebug.d.ts +10 -1
- package/build/server/ServerDebug.js +85 -17
- package/build/server/ServerDebug.js.map +1 -1
- package/build/server/config/Config.d.ts +276 -47
- package/build/server/config/Config.js +70 -47
- package/build/server/config/Config.js.map +1 -1
- package/build/server/config/{ConfigLoader.d.ts → Loader.d.ts} +4 -5
- package/build/server/config/{ConfigLoader.js → Loader.js} +8 -11
- package/build/server/config/Loader.js.map +1 -0
- package/build/server/router/Router.d.ts +88 -31
- package/build/server/router/Router.js +113 -51
- package/build/server/router/Router.js.map +1 -1
- package/build/server/router/algorithm/Algorithm.d.ts +39 -0
- package/build/server/router/algorithm/Algorithm.js +20 -0
- package/build/server/router/algorithm/Algorithm.js.map +1 -0
- package/build/server/router/algorithm/FIFO.d.ts +15 -0
- package/build/server/router/algorithm/FIFO.js +24 -0
- package/build/server/router/algorithm/FIFO.js.map +1 -0
- package/build/server/router/algorithm/Tree.d.ts +38 -0
- package/build/server/router/algorithm/Tree.js +126 -0
- package/build/server/router/algorithm/Tree.js.map +1 -0
- package/build/server/router/middleware/HttpMiddleware.js +1 -1
- package/build/server/router/middleware/HttpMiddleware.js.map +1 -1
- package/build/server/router/middleware/WsMiddleware.js +1 -1
- package/build/server/router/middleware/WsMiddleware.js.map +1 -1
- package/build/server/security/PathSecurity.d.ts +45 -0
- package/build/server/security/PathSecurity.js +108 -0
- package/build/server/security/PathSecurity.js.map +1 -0
- package/build/server/websocket/Websocket.js +4 -1
- package/build/server/websocket/Websocket.js.map +1 -1
- package/build/utilities/ConsoleUI.d.ts +2 -1
- package/build/utilities/ConsoleUI.js +2 -1
- package/build/utilities/ConsoleUI.js.map +1 -1
- package/build/utilities/DebugUI.d.ts +1 -1
- package/build/utilities/DebugUI.js +1 -1
- package/build/utilities/Encoding.d.ts +22 -0
- package/build/utilities/Encoding.js +26 -0
- package/build/utilities/Encoding.js.map +1 -0
- package/build/utilities/Env.js +7 -2
- package/build/utilities/Env.js.map +1 -1
- package/build/utilities/File.d.ts +10 -0
- package/build/utilities/File.js +19 -0
- package/build/utilities/File.js.map +1 -0
- package/build/utilities/Flatten.d.ts +73 -0
- package/build/utilities/Flatten.js +76 -0
- package/build/utilities/Flatten.js.map +1 -0
- package/build/utilities/Object.d.ts +16 -0
- package/build/utilities/Object.js +48 -0
- package/build/utilities/Object.js.map +1 -0
- package/build/utilities/Path.d.ts +31 -11
- package/build/utilities/Path.js +48 -15
- package/build/utilities/Path.js.map +1 -1
- package/build/utilities/Time.d.ts +21 -0
- package/build/utilities/Time.js +25 -0
- package/build/utilities/Time.js.map +1 -0
- package/build/utilities/Utilities.d.ts +50 -92
- package/build/utilities/Utilities.js +56 -71
- package/build/utilities/Utilities.js.map +1 -1
- package/build/utilities/schema/Introspection.d.ts +24 -0
- package/build/utilities/schema/Introspection.js +87 -0
- package/build/utilities/schema/Introspection.js.map +1 -0
- package/build/utilities/schema/JSONSchema.d.ts +68 -0
- package/build/utilities/schema/JSONSchema.js +13 -0
- package/build/utilities/schema/JSONSchema.js.map +1 -0
- package/build/utilities/schema/Schema.d.ts +253 -0
- package/build/utilities/schema/Schema.js +241 -0
- package/build/utilities/schema/Schema.js.map +1 -0
- package/build/utilities/schema/SchemaError.d.ts +10 -0
- package/build/utilities/schema/SchemaError.js +13 -0
- package/build/utilities/schema/SchemaError.js.map +1 -0
- package/build/utilities/schema/Validator.d.ts +94 -0
- package/build/utilities/schema/Validator.js +246 -0
- package/build/utilities/schema/Validator.js.map +1 -0
- package/changes.md +4 -0
- package/docs/ARCHITECTURE.md +142 -0
- package/global/style/template/error.css +29 -0
- package/global/style/template/folder.css +79 -0
- package/global/{Style/Template/Template.css → style/template/template.css} +60 -68
- package/global/template/error.vhtml +29 -0
- package/global/template/folder.vhtml +54 -0
- package/package.json +2 -2
- package/build/Template.d.ts +0 -46
- package/build/Template.js +0 -81
- package/build/Template.js.map +0 -1
- package/build/server/config/ConfigLoader.js.map +0 -1
- package/build/server/config/ConfigValidator.d.ts +0 -71
- package/build/server/config/ConfigValidator.js +0 -131
- package/build/server/config/ConfigValidator.js.map +0 -1
- package/examples/in-docs.js +0 -96
- package/global/Style/Template/Error.css +0 -30
- package/global/Style/Template/Folder.css +0 -77
- package/global/Template/Error.vhtml +0 -29
- package/global/Template/Folder.vhtml +0 -41
- package/tests/Template/template.js +0 -18
- package/tests/Template/template.txt +0 -13
- package/tests/Template/template.vhtml +0 -23
- package/tests/debug.js +0 -34
- package/tests/jwtManager/jwtManager.js +0 -342
- package/tests/test.js +0 -131
- package/tests/test.vhtml +0 -14
- package/tests/utilities.js +0 -28
- package/tests/websocket.vhtml +0 -86
- /package/global/{Source/Logo_960.png → source/logo_960.png} +0 -0
- /package/global/{Source/Logo_SM_960.png → source/logo_SM_960.png} +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
+
* @description Provides a comprehensive schema validation and processing system, allowing developers to define complex data structures.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import _SchemaError from './SchemaError.js';
|
|
7
|
+
import _JSONSchema from './JSONSchema.js';
|
|
8
|
+
import _Introspection from './Introspection.js';
|
|
9
|
+
import _Validator from './Validator.js';
|
|
10
|
+
export { SchemaError } from './SchemaError.js';
|
|
11
|
+
export { JSONSchema } from './JSONSchema.js';
|
|
12
|
+
export { Introspection } from './Introspection.js';
|
|
13
|
+
export { Validator } from './Validator.js';
|
|
14
|
+
export class Schema {
|
|
15
|
+
schema;
|
|
16
|
+
constructor(schema) {
|
|
17
|
+
this.schema = schema;
|
|
18
|
+
Schema.Validator.validateStructure(schema);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the inferred type of the schema.
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ IMPORTANT: This getter returns an EMPTY object. It is designed ONLY for type inference.
|
|
24
|
+
*
|
|
25
|
+
* Usage: Use with `typeof` to extract the inferred type:
|
|
26
|
+
* ```typescript
|
|
27
|
+
* type infered = typeof schemaInstance.infer;
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* DO NOT use the returned value at runtime - it's always an empty object.
|
|
31
|
+
* This is purely a TypeScript type utility.
|
|
32
|
+
*
|
|
33
|
+
* @returns An empty object with the inferred type
|
|
34
|
+
*/
|
|
35
|
+
get infer() {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get the inferred type of the schema for processing (i.e., before applying defaults and handling optional properties).
|
|
40
|
+
*
|
|
41
|
+
* ⚠️ IMPORTANT: This getter returns an EMPTY object. It is designed ONLY for type inference.
|
|
42
|
+
*
|
|
43
|
+
* Usage: Use with `typeof` to extract the inferred type for processing:
|
|
44
|
+
* ```typescript
|
|
45
|
+
* type inferedToProcess = typeof schemaInstance.inferToProcess;
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* DO NOT use the returned value at runtime - it's always an empty object.
|
|
49
|
+
* This is purely a TypeScript type utility.
|
|
50
|
+
*/
|
|
51
|
+
get inferToProcess() {
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* get the json schema as an object
|
|
56
|
+
* @returns the json schema
|
|
57
|
+
*/
|
|
58
|
+
get jsonSchema() { return this.toJsonSchema(); }
|
|
59
|
+
/**
|
|
60
|
+
* get the json schema as a JSON string
|
|
61
|
+
* @returns the json schema as a string
|
|
62
|
+
*/
|
|
63
|
+
get jsonSchemaJSON() { return JSON.stringify(this.jsonSchema); }
|
|
64
|
+
/**
|
|
65
|
+
* get the list of unique keys
|
|
66
|
+
* @returns the list of unique keys
|
|
67
|
+
*/
|
|
68
|
+
get uniques() { return this.listUniques(); }
|
|
69
|
+
processData(data, partial = false) {
|
|
70
|
+
const result = {};
|
|
71
|
+
const iterable = partial ? data : this.schema;
|
|
72
|
+
for (const key in iterable) {
|
|
73
|
+
if (!this.isKeyOf(this.schema, key))
|
|
74
|
+
throw new Schema.SchemaError(`Unknown property ${String(key)}`);
|
|
75
|
+
const prop = this.schema[key];
|
|
76
|
+
const value = this.isKeyOf(data, key) ? data[key] : undefined;
|
|
77
|
+
result[key] = this.processProperty(value, prop, key, partial);
|
|
78
|
+
if (result[key] === undefined)
|
|
79
|
+
delete result[key];
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
processPartialData(data) {
|
|
84
|
+
const result = {};
|
|
85
|
+
let currentProp;
|
|
86
|
+
for (const key in data) {
|
|
87
|
+
const value = this.isKeyOf(data, key) ? data[key] : undefined;
|
|
88
|
+
const subKeys = key.split('.');
|
|
89
|
+
const firstKey = subKeys.shift();
|
|
90
|
+
if (!firstKey || !(firstKey in this.schema))
|
|
91
|
+
throw new Schema.SchemaError(`Unknown property ${firstKey}`);
|
|
92
|
+
currentProp = this.schema[firstKey];
|
|
93
|
+
if (subKeys.length === 0)
|
|
94
|
+
result[key] = this.processProperty(value, currentProp, key);
|
|
95
|
+
else {
|
|
96
|
+
if (currentProp.type !== 'object')
|
|
97
|
+
throw new Schema.SchemaError(`Property ${key} is not an object`);
|
|
98
|
+
let objectProp = currentProp;
|
|
99
|
+
let usedKeys = [];
|
|
100
|
+
for (const subKey of subKeys) {
|
|
101
|
+
usedKeys.push(subKey);
|
|
102
|
+
if (!(subKey in objectProp.schema))
|
|
103
|
+
throw new Schema.SchemaError(`Unknown property ${firstKey}.${usedKeys.join('.')}`);
|
|
104
|
+
currentProp = objectProp.schema[subKey];
|
|
105
|
+
if (currentProp.type === 'object')
|
|
106
|
+
objectProp = currentProp;
|
|
107
|
+
}
|
|
108
|
+
result[key] = this.processProperty(value, currentProp, key);
|
|
109
|
+
}
|
|
110
|
+
if (result[key] === undefined)
|
|
111
|
+
delete result[key];
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* process a property
|
|
117
|
+
* @param data the data to process
|
|
118
|
+
* @param prop the property to process
|
|
119
|
+
* @param key the key of the property
|
|
120
|
+
* @param partial if the data is partial
|
|
121
|
+
* @returns the processed data
|
|
122
|
+
* @throws schemaError if the data is not valid
|
|
123
|
+
*/
|
|
124
|
+
processProperty(data, prop, key, partial = false) {
|
|
125
|
+
if (data === undefined || data === null) {
|
|
126
|
+
if ('default' in prop)
|
|
127
|
+
return prop.default;
|
|
128
|
+
if (prop.nullable && prop.nullable === true)
|
|
129
|
+
return null;
|
|
130
|
+
if (prop.required && prop.required === true)
|
|
131
|
+
throw new Schema.SchemaError(`Property ${key} is required but not provided`);
|
|
132
|
+
else
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
switch (prop.type) {
|
|
136
|
+
case 'string':
|
|
137
|
+
Schema.Validator.validateString(data, prop, key);
|
|
138
|
+
return data;
|
|
139
|
+
case 'number':
|
|
140
|
+
Schema.Validator.validateNumber(data, prop, key);
|
|
141
|
+
return data;
|
|
142
|
+
case 'boolean':
|
|
143
|
+
Schema.Validator.validateBoolean(data, prop, key);
|
|
144
|
+
return data;
|
|
145
|
+
case 'array':
|
|
146
|
+
Schema.Validator.validateArray(data, prop, key);
|
|
147
|
+
return this.processArray(data, prop, key);
|
|
148
|
+
case 'object':
|
|
149
|
+
Schema.Validator.validateObject(data, prop, key);
|
|
150
|
+
return this.processObject(data, prop, key, partial);
|
|
151
|
+
default: throw new Schema.SchemaError(`Unknown type in property ${key}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* validate a array
|
|
156
|
+
* @param value the value to validate
|
|
157
|
+
* @param prop the property to validate
|
|
158
|
+
* @param key the key of the property
|
|
159
|
+
* @returns the data
|
|
160
|
+
* @throws schemaError if the data is not valid
|
|
161
|
+
*/
|
|
162
|
+
processArray(value, prop, key) {
|
|
163
|
+
try {
|
|
164
|
+
return value.map((item, index) => this.processProperty(item, prop.property, `${key}[${index}]`));
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
throw new Schema.SchemaError(`Property ${key} is not valid: ${error}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* validate a object
|
|
172
|
+
* @param value the value to validate
|
|
173
|
+
* @param prop the property to validate
|
|
174
|
+
* @param key the key of the property
|
|
175
|
+
* @returns the data
|
|
176
|
+
* @throws schemaError if the data is not valid
|
|
177
|
+
*/
|
|
178
|
+
processObject(value, prop, key, partial = false) {
|
|
179
|
+
const handler = new Schema(prop.schema);
|
|
180
|
+
try {
|
|
181
|
+
return handler.processData(value, partial);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
throw new Schema.SchemaError(`Property ${key} is not valid: ${error}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* validate a array
|
|
189
|
+
* @param value the value to validate
|
|
190
|
+
* @param prop the property to validate
|
|
191
|
+
* @param key the key of the property
|
|
192
|
+
* @throws schemaError if the data is not valid
|
|
193
|
+
*/
|
|
194
|
+
validateArray(value, prop, key) {
|
|
195
|
+
if (value == null && prop.nullable === true)
|
|
196
|
+
return;
|
|
197
|
+
if (!Array.isArray(value))
|
|
198
|
+
throw new Schema.SchemaError(`Property ${key} must be an array`);
|
|
199
|
+
if (prop.minimum !== undefined && value.length < prop.minimum) {
|
|
200
|
+
throw new Schema.SchemaError(`Property ${key} must have at least ${prop.minimum} items`);
|
|
201
|
+
}
|
|
202
|
+
if (prop.maximum !== undefined && value.length > prop.maximum) {
|
|
203
|
+
throw new Schema.SchemaError(`Property ${key} must have at most ${prop.maximum} items`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* generate a list of unique keys
|
|
208
|
+
* @param doc the schema to validate
|
|
209
|
+
* @param parentKey the parent key of the schema
|
|
210
|
+
* @returns a list of unique keys
|
|
211
|
+
*/
|
|
212
|
+
listUniques(doc, parentKey) {
|
|
213
|
+
const useDoc = doc ?? this.schema;
|
|
214
|
+
return Schema.Introspection.listUniques(useDoc, parentKey);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* convert a schema to a JSON schema
|
|
218
|
+
* @param schema the schema to convert
|
|
219
|
+
* @returns the JSON schema
|
|
220
|
+
*/
|
|
221
|
+
toJsonSchema(schema) {
|
|
222
|
+
const useSchema = schema ?? this.schema;
|
|
223
|
+
return Schema.Introspection.toJsonSchema(useSchema);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* -- TYPE GUARD --
|
|
227
|
+
* verify if the key is in the schema
|
|
228
|
+
* @param doc the object to verify
|
|
229
|
+
* @param key the key to verify
|
|
230
|
+
* @returns true if the key is in the schema
|
|
231
|
+
*/
|
|
232
|
+
isKeyOf(doc, key) { return key in doc; }
|
|
233
|
+
}
|
|
234
|
+
(function (Schema) {
|
|
235
|
+
Schema.SchemaError = _SchemaError;
|
|
236
|
+
Schema.JSONSchema = _JSONSchema;
|
|
237
|
+
Schema.Introspection = _Introspection;
|
|
238
|
+
Schema.Validator = _Validator;
|
|
239
|
+
})(Schema || (Schema = {}));
|
|
240
|
+
export default Schema;
|
|
241
|
+
//# sourceMappingURL=Schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Schema.js","sourceRoot":"","sources":["../../../src/utilities/schema/Schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
+
* @description Defines a custom error class for handling schema-related errors in the schema validation and processing system.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export declare class SchemaError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
export declare namespace SchemaError { }
|
|
10
|
+
export default SchemaError;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
+
* @description Defines a custom error class for handling schema-related errors in the schema validation and processing system.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
export class SchemaError extends Error {
|
|
7
|
+
constructor(message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = 'schemaError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export default SchemaError;
|
|
13
|
+
//# sourceMappingURL=SchemaError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaError.js","sourceRoot":"","sources":["../../../src/utilities/schema/SchemaError.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAClC,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC9B,CAAC;CACJ;AAED,eAAe,WAAW,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
+
* @description Provides utilities for validating the structure of a schema, ensuring that property definitions are consistent and valid according to their types and constraints.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import type { Schema } from './Schema.js';
|
|
7
|
+
export declare class Validator {
|
|
8
|
+
/**
|
|
9
|
+
* Validates the structure of a schema, used for validating the structure of a schema and nested objects.
|
|
10
|
+
* @param schema The schema to validate
|
|
11
|
+
* @param parentKey The parent key of the schema, used for error messages
|
|
12
|
+
*/
|
|
13
|
+
static validateStructure(schema: Schema.Schema, parentKey?: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Validates a property definition, used for validating the structure of a schema and nested objects.
|
|
16
|
+
* @param prop The property definition to validate
|
|
17
|
+
* @param key The key of the property, used for error messages
|
|
18
|
+
*/
|
|
19
|
+
static validateProperty(prop: Schema.property, key: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Validates a default value against a property definition, used for validating default values.
|
|
22
|
+
* @param prop The property definition to validate against
|
|
23
|
+
* @param key The key of the property, used for error messages
|
|
24
|
+
*/
|
|
25
|
+
static validateDefaultValue(prop: Schema.property, key: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Validates a string property definition, used for validating nested objects.
|
|
28
|
+
* @param prop The string property definition to validate
|
|
29
|
+
* @param key The key of the property, used for error messages
|
|
30
|
+
*/
|
|
31
|
+
static validateStringProperty(prop: Schema.Property.String, key: string): void;
|
|
32
|
+
/**
|
|
33
|
+
* Validates a number property definition, used for validating nested objects.
|
|
34
|
+
* @param prop The number property definition to validate
|
|
35
|
+
* @param key The key of the property, used for error messages
|
|
36
|
+
*/
|
|
37
|
+
static validateNumberProperty(prop: Schema.Property.Number, key: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Validates an array property definition, used for validating nested arrays.
|
|
40
|
+
* @param prop The array property definition to validate
|
|
41
|
+
* @param key The key of the property, used for error messages
|
|
42
|
+
*/
|
|
43
|
+
static validateArrayProperty(prop: Schema.Property.Array, key: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Validates an object property definition, used for validating nested objects.
|
|
46
|
+
* @param prop The object property definition to validate
|
|
47
|
+
* @param key The key of the property, used for error messages
|
|
48
|
+
*/
|
|
49
|
+
static validateObjectProperty(prop: Schema.Property.Object, key: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Validates a string value against a string property definition, used for validating default values and nested objects.
|
|
52
|
+
* @param value The value to validate
|
|
53
|
+
* @param prop The string property definition to validate against
|
|
54
|
+
* @param key The key of the property, used for error messages
|
|
55
|
+
*/
|
|
56
|
+
static validateString(value: string, prop: Schema.Property.String, key: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Validates a number value against a number property definition, used for validating default values.
|
|
59
|
+
* @param value The value to validate
|
|
60
|
+
* @param prop The number property definition to validate against
|
|
61
|
+
* @param key The key of the property, used for error messages
|
|
62
|
+
*/
|
|
63
|
+
static validateNumber(value: number, prop: Schema.Property.Number, key: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Validates a boolean value against a boolean property definition, used for validating default values.
|
|
66
|
+
* @param value The value to validate
|
|
67
|
+
* @param prop The boolean property definition to validate against
|
|
68
|
+
* @param key The key of the property, used for error messages
|
|
69
|
+
*/
|
|
70
|
+
static validateBoolean(value: boolean, prop: Schema.Property.Boolean, key: string): void;
|
|
71
|
+
/**
|
|
72
|
+
* Validates an object value against an object property definition, used for validating default values and nested objects.
|
|
73
|
+
* @param value The value to validate
|
|
74
|
+
* @param prop The object property definition to validate against
|
|
75
|
+
* @param key The key of the property, used for error messages
|
|
76
|
+
*/
|
|
77
|
+
static validateObject(value: any, prop: Schema.Property.Object, key: string): void;
|
|
78
|
+
/**
|
|
79
|
+
* Validates an array value against an array property definition, used for validating default values and array items.
|
|
80
|
+
* @param value The value to validate
|
|
81
|
+
* @param prop The array property definition to validate against
|
|
82
|
+
* @param key The key of the property, used for error messages
|
|
83
|
+
*/
|
|
84
|
+
static validateArray(value: any, prop: Schema.Property.Array, key: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* Validates a value against a property definition, used for validating default values and array items.
|
|
87
|
+
* @param value The value to validate
|
|
88
|
+
* @param prop The property definition to validate against
|
|
89
|
+
* @param key The key of the property, used for error messages
|
|
90
|
+
*/
|
|
91
|
+
static validateValue(value: any, prop: Schema.property, key: string): void;
|
|
92
|
+
}
|
|
93
|
+
export declare namespace Validator { }
|
|
94
|
+
export default Validator;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author NetFeez <netfeez.dev@gmail.com>
|
|
3
|
+
* @description Provides utilities for validating the structure of a schema, ensuring that property definitions are consistent and valid according to their types and constraints.
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { SchemaError } from './SchemaError.js';
|
|
7
|
+
export class Validator {
|
|
8
|
+
/**
|
|
9
|
+
* Validates the structure of a schema, used for validating the structure of a schema and nested objects.
|
|
10
|
+
* @param schema The schema to validate
|
|
11
|
+
* @param parentKey The parent key of the schema, used for error messages
|
|
12
|
+
*/
|
|
13
|
+
static validateStructure(schema, parentKey) {
|
|
14
|
+
for (const key in schema) {
|
|
15
|
+
const prop = schema[key];
|
|
16
|
+
this.validateProperty(prop, parentKey ? `${parentKey}.${key}` : key);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Validates a property definition, used for validating the structure of a schema and nested objects.
|
|
21
|
+
* @param prop The property definition to validate
|
|
22
|
+
* @param key The key of the property, used for error messages
|
|
23
|
+
*/
|
|
24
|
+
static validateProperty(prop, key) {
|
|
25
|
+
switch (prop.type) {
|
|
26
|
+
case 'string':
|
|
27
|
+
this.validateStringProperty(prop, key);
|
|
28
|
+
break;
|
|
29
|
+
case 'number':
|
|
30
|
+
this.validateNumberProperty(prop, key);
|
|
31
|
+
break;
|
|
32
|
+
case 'boolean': break;
|
|
33
|
+
case 'array':
|
|
34
|
+
this.validateArrayProperty(prop, key);
|
|
35
|
+
break;
|
|
36
|
+
case 'object':
|
|
37
|
+
this.validateObjectProperty(prop, key);
|
|
38
|
+
break;
|
|
39
|
+
default: throw new SchemaError(`Unknown type for property '${key}'`);
|
|
40
|
+
}
|
|
41
|
+
if ('default' in prop)
|
|
42
|
+
this.validateDefaultValue(prop, key);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validates a default value against a property definition, used for validating default values.
|
|
46
|
+
* @param prop The property definition to validate against
|
|
47
|
+
* @param key The key of the property, used for error messages
|
|
48
|
+
*/
|
|
49
|
+
static validateDefaultValue(prop, key) {
|
|
50
|
+
if (prop.default === undefined) {
|
|
51
|
+
if (!prop.required)
|
|
52
|
+
return;
|
|
53
|
+
throw new SchemaError(`Property '${key}' default value cannot be undefined`);
|
|
54
|
+
}
|
|
55
|
+
if (prop.default === null) {
|
|
56
|
+
if (prop.nullable)
|
|
57
|
+
return;
|
|
58
|
+
throw new SchemaError(`Property '${key}' default value cannot be null`);
|
|
59
|
+
}
|
|
60
|
+
switch (prop.type) {
|
|
61
|
+
case 'string':
|
|
62
|
+
this.validateString(prop.default, prop, key);
|
|
63
|
+
break;
|
|
64
|
+
case 'number':
|
|
65
|
+
this.validateNumber(prop.default, prop, key);
|
|
66
|
+
break;
|
|
67
|
+
case 'boolean':
|
|
68
|
+
this.validateBoolean(prop.default, prop, key);
|
|
69
|
+
break;
|
|
70
|
+
case 'array':
|
|
71
|
+
this.validateArray(prop.default, prop, key);
|
|
72
|
+
break;
|
|
73
|
+
case 'object':
|
|
74
|
+
this.validateObject(prop.default, prop, key);
|
|
75
|
+
break;
|
|
76
|
+
default: throw new SchemaError(`Unknown type for property '${key}'`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validates a string property definition, used for validating nested objects.
|
|
81
|
+
* @param prop The string property definition to validate
|
|
82
|
+
* @param key The key of the property, used for error messages
|
|
83
|
+
*/
|
|
84
|
+
static validateStringProperty(prop, key) {
|
|
85
|
+
if (prop.enum !== undefined) {
|
|
86
|
+
if (!Array.isArray(prop.enum) || prop.enum.length === 0) {
|
|
87
|
+
throw new SchemaError(`Property '${key}' enum must be a non-empty array`);
|
|
88
|
+
}
|
|
89
|
+
if (prop.enum.some((value) => typeof value !== 'string')) {
|
|
90
|
+
throw new SchemaError(`Property '${key}' enum values must be strings`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (prop.maxLength !== undefined && prop.minLength !== undefined && prop.maxLength < prop.minLength) {
|
|
94
|
+
throw new SchemaError(`Property '${key}' maxLength must be greater than or equal to minLength`);
|
|
95
|
+
}
|
|
96
|
+
if (prop.pattern !== undefined && !(prop.pattern instanceof RegExp)) {
|
|
97
|
+
throw new SchemaError(`Property '${key}' pattern must be a RegExp`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Validates a number property definition, used for validating nested objects.
|
|
102
|
+
* @param prop The number property definition to validate
|
|
103
|
+
* @param key The key of the property, used for error messages
|
|
104
|
+
*/
|
|
105
|
+
static validateNumberProperty(prop, key) {
|
|
106
|
+
if (prop.maximum !== undefined && prop.minimum !== undefined && prop.maximum < prop.minimum) {
|
|
107
|
+
throw new SchemaError(`Property '${key}' maximum must be greater than or equal to minimum`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validates an array property definition, used for validating nested arrays.
|
|
112
|
+
* @param prop The array property definition to validate
|
|
113
|
+
* @param key The key of the property, used for error messages
|
|
114
|
+
*/
|
|
115
|
+
static validateArrayProperty(prop, key) {
|
|
116
|
+
if (prop.maximum !== undefined && prop.minimum !== undefined && prop.maximum < prop.minimum) {
|
|
117
|
+
throw new SchemaError(`Property '${key}' maximum must be greater than or equal to minimum`);
|
|
118
|
+
}
|
|
119
|
+
this.validateProperty(prop.property, `${key}[]`);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validates an object property definition, used for validating nested objects.
|
|
123
|
+
* @param prop The object property definition to validate
|
|
124
|
+
* @param key The key of the property, used for error messages
|
|
125
|
+
*/
|
|
126
|
+
static validateObjectProperty(prop, key) {
|
|
127
|
+
this.validateStructure(prop.schema, key);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Validates a string value against a string property definition, used for validating default values and nested objects.
|
|
131
|
+
* @param value The value to validate
|
|
132
|
+
* @param prop The string property definition to validate against
|
|
133
|
+
* @param key The key of the property, used for error messages
|
|
134
|
+
*/
|
|
135
|
+
static validateString(value, prop, key) {
|
|
136
|
+
if (value == null && prop.nullable === true)
|
|
137
|
+
return;
|
|
138
|
+
if (typeof value !== 'string')
|
|
139
|
+
throw new SchemaError(`Property ${key} must be a string`);
|
|
140
|
+
if (prop.enum !== undefined && !prop.enum.includes(value)) {
|
|
141
|
+
throw new SchemaError(`Property ${key} must be one of: ${prop.enum.join(', ')}`);
|
|
142
|
+
}
|
|
143
|
+
if (prop.minLength !== undefined && value.length < prop.minLength) {
|
|
144
|
+
throw new SchemaError(`Property ${key} must have a minimum length of ${prop.minLength}`);
|
|
145
|
+
}
|
|
146
|
+
if (prop.maxLength !== undefined && value.length > prop.maxLength) {
|
|
147
|
+
throw new SchemaError(`Property ${key} must have a maximum length of ${prop.maxLength}`);
|
|
148
|
+
}
|
|
149
|
+
if (prop.pattern && !prop.pattern.test(value)) {
|
|
150
|
+
throw new SchemaError(`Property ${key} must match the pattern ${prop.pattern}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Validates a number value against a number property definition, used for validating default values.
|
|
155
|
+
* @param value The value to validate
|
|
156
|
+
* @param prop The number property definition to validate against
|
|
157
|
+
* @param key The key of the property, used for error messages
|
|
158
|
+
*/
|
|
159
|
+
static validateNumber(value, prop, key) {
|
|
160
|
+
if (value == null && prop.nullable === true)
|
|
161
|
+
return;
|
|
162
|
+
if (typeof value !== 'number')
|
|
163
|
+
throw new SchemaError(`Property ${key} must be a number`);
|
|
164
|
+
if (prop.minimum !== undefined && value < prop.minimum) {
|
|
165
|
+
throw new SchemaError(`Property ${key} must be greater than or equal to ${prop.minimum}`);
|
|
166
|
+
}
|
|
167
|
+
if (prop.maximum !== undefined && value > prop.maximum) {
|
|
168
|
+
throw new SchemaError(`Property ${key} must be less than or equal to ${prop.maximum}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validates a boolean value against a boolean property definition, used for validating default values.
|
|
173
|
+
* @param value The value to validate
|
|
174
|
+
* @param prop The boolean property definition to validate against
|
|
175
|
+
* @param key The key of the property, used for error messages
|
|
176
|
+
*/
|
|
177
|
+
static validateBoolean(value, prop, key) {
|
|
178
|
+
if (value == null && prop.nullable === true)
|
|
179
|
+
return;
|
|
180
|
+
if (typeof value !== 'boolean')
|
|
181
|
+
throw new SchemaError(`Property ${key} must be a boolean`);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Validates an object value against an object property definition, used for validating default values and nested objects.
|
|
185
|
+
* @param value The value to validate
|
|
186
|
+
* @param prop The object property definition to validate against
|
|
187
|
+
* @param key The key of the property, used for error messages
|
|
188
|
+
*/
|
|
189
|
+
static validateObject(value, prop, key) {
|
|
190
|
+
if (value == null && prop.nullable === true)
|
|
191
|
+
return;
|
|
192
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
193
|
+
throw new SchemaError(`Property ${key} must be an object`);
|
|
194
|
+
}
|
|
195
|
+
this.validateStructure(prop.schema, key);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Validates an array value against an array property definition, used for validating default values and array items.
|
|
199
|
+
* @param value The value to validate
|
|
200
|
+
* @param prop The array property definition to validate against
|
|
201
|
+
* @param key The key of the property, used for error messages
|
|
202
|
+
*/
|
|
203
|
+
static validateArray(value, prop, key) {
|
|
204
|
+
if (value == null && prop.nullable === true)
|
|
205
|
+
return;
|
|
206
|
+
if (!Array.isArray(value))
|
|
207
|
+
throw new SchemaError(`Property ${key} must be an array`);
|
|
208
|
+
if (prop.minimum !== undefined && value.length < prop.minimum) {
|
|
209
|
+
throw new SchemaError(`Property ${key} must have at least ${prop.minimum} items`);
|
|
210
|
+
}
|
|
211
|
+
if (prop.maximum !== undefined && value.length > prop.maximum) {
|
|
212
|
+
throw new SchemaError(`Property ${key} must have at most ${prop.maximum} items`);
|
|
213
|
+
}
|
|
214
|
+
value.forEach((item, index) => {
|
|
215
|
+
this.validateValue(item, prop.property, `${key}[${index}]`);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Validates a value against a property definition, used for validating default values and array items.
|
|
220
|
+
* @param value The value to validate
|
|
221
|
+
* @param prop The property definition to validate against
|
|
222
|
+
* @param key The key of the property, used for error messages
|
|
223
|
+
*/
|
|
224
|
+
static validateValue(value, prop, key) {
|
|
225
|
+
switch (prop.type) {
|
|
226
|
+
case 'string':
|
|
227
|
+
this.validateString(value, prop, key);
|
|
228
|
+
break;
|
|
229
|
+
case 'number':
|
|
230
|
+
this.validateNumber(value, prop, key);
|
|
231
|
+
break;
|
|
232
|
+
case 'boolean':
|
|
233
|
+
this.validateBoolean(value, prop, key);
|
|
234
|
+
break;
|
|
235
|
+
case 'array':
|
|
236
|
+
this.validateArray(value, prop, key);
|
|
237
|
+
break;
|
|
238
|
+
case 'object':
|
|
239
|
+
this.validateObject(value, prop, key);
|
|
240
|
+
break;
|
|
241
|
+
default: throw new SchemaError(`Unknown type for property '${key}'`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
export default Validator;
|
|
246
|
+
//# sourceMappingURL=Validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validator.js","sourceRoot":"","sources":["../../../src/utilities/schema/Validator.ts"],"names":[],"mappings":"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"}
|
package/changes.md
CHANGED
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
- **(Server/WebSocket)**: Overhauled the WebSocket connection lifecycle for improved security and developer experience.
|
|
33
33
|
- The `WebSocket` class no longer accepts connections in its constructor. Instead, it waits in a `pending` state.
|
|
34
34
|
- Added `accept()` and `reject()` methods to give the framework full control over the connection handshake.
|
|
35
|
+
- **(Server/Response)**: The `send()`, `sendJson()`, `sendFile()`, `sendFolder()`, and `sendTemplate()` methods are now **async** and return `Promise<void>`. **This is a breaking change.**
|
|
36
|
+
- All response methods now require `await` in calling code for proper error handling.
|
|
37
|
+
- Added `sendReadable()` for streaming responses with backpressure support via `stream/promises`.
|
|
38
|
+
- HTTP range requests (206 Partial Content) are now properly handled in streaming contexts.
|
|
35
39
|
|
|
36
40
|
# version (4.1.0)
|
|
37
41
|
## ➕ Added
|