Skip to content

Commit

Permalink
Added the ability to nest schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
GrzegorzManiak committed Jun 18, 2024
1 parent e1e512e commit 11cbb54
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 43 deletions.
35 changes: 31 additions & 4 deletions src/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,16 @@ export default class Schema<

public static async _validate_value(
instance: Schema<SchemaNamespace.NestedSchema | SchemaNamespace.FlatSchema, unknown>,
validator: SchemaNamespace.NestedSchema | SchemaNamespace.GenericTypeConstructor<unknown, unknown>,
validator: SchemaNamespace.NestedSchema | SchemaNamespace.GenericTypeConstructor<unknown, unknown> | SchemaNamespace.SchemaLike,
new_data: unknown,
new_path: string[]
): Promise<unknown> {

switch (typeof validator) {
const type: 'function' | 'object' | 'class' =
validator instanceof Schema ? 'class' :
typeof validator === 'object' ? 'object' : 'function';

switch (type) {
// -- Function, execute it
case 'function': {
const walk_result = await Schema._execute_validator(
Expand All @@ -111,11 +115,34 @@ export default class Schema<



// -- Nested schema
case 'class': {

const schema = validator as SchemaNamespace.SchemaLike;
let result: unknown;

try { result = await schema.validate(new_data); }
catch (unknown_error) {
const error = GenericError.from_unknown(unknown_error);
error.hint = 'Error occurred while validating the schema';
error.data = {
path: new_path,
expected: validator.constructor.name
};
instance.push_error(error);
throw error;
}

return result;
}



// -- Object, walk it
case 'object': {
const walk_result = await Schema._walk_object(
const walk_result = await Schema._walk_object(
instance,
validator,
validator as SchemaNamespace.NestedSchema,
new_data,
new_path
);
Expand Down
7 changes: 5 additions & 2 deletions src/schema/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export namespace SchemaNamespace {


export type NestedSchema = {
[key: string]: GenericTypeConstructor<any> | NestedSchema;
[key: string]: GenericTypeConstructor<any> | NestedSchema | SchemaLike | NestedSchemaLike;
}

export type FlatSchema = {
Expand Down Expand Up @@ -97,7 +97,10 @@ export namespace SchemaNamespace {
// -- Run it trough the ExtractParamaterReturnType to get the return type
Schema[K] extends GenericTypeConstructor<any>
? ExtractParamaterReturnType<Schema[K]>


: Schema[K] extends SchemaLike
? ReturnType<Schema[K]>

: Schema[K] extends NestedSchema
? ParsedSchema<Schema[K]>

Expand Down
87 changes: 50 additions & 37 deletions tests.ts
Original file line number Diff line number Diff line change
@@ -1,68 +1,81 @@
import * as nv from './src';



class MiddlewareExecutionError extends nv.GenericError {
public constructor(
message: string
) {
super(message, 500);
const testschema = new nv.Schema({
a: nv.String,
c: {
balls: nv.String
}
}
});


const testschema2 = new nv.Schema({
a: nv.String,
b: testschema
});



console.log(await testschema2.validate({ a: '', b: { a: 'sdfsd', c:{o:'ck'} }}))

// class MiddlewareExecutionError extends nv.GenericError {
// public constructor(
// message: string
// ) {
// super(message, 500);
// }
// }



const server = new nv.Server();
const route = new nv.Route(server, '/contacts/email/check/:code');

class MW extends nv.GenericMiddleware {
protected handler = async () => {
console.log('Middleware executed');
return { 'a': 'test' }
}
}
// class MW extends nv.GenericMiddleware {
// protected handler = async () => {
// console.log('Middleware executed');
// return { 'a': 'test' }
// }
// }


const testschema = new nv.Schema({
a: nv.String
});

nv.Binder(route, 'GET', {
middleware: {
test: MW,
},

schemas: {
input: {
query: [testschema]
body: [testschema2]
}
}
}, async ({
middleware,
url
url,
body
}) => {
console.log(url);
console.log(body.b.c.balls);
});




server.start();
// server.start();



const test = nv.register_api_route('localhost:8080', 'contacts/email/check/:code', 'GET', {
input: {
query: [testschema]
}
});
// const test = nv.register_api_route('localhost:8080', 'contacts/email/check/:code', 'GET', {
// input: {
// query: [testschema]
// }
// });

const res = await test({
route: {
code: '1'
},
query: {
a: 'test'
}
})
// const res = await test({
// route: {
// code: '1'
// },
// query: {
// a: 'test'
// }
// })

// console.log(res.success, res.error.message);
// // console.log(res.success, res.error.message);

0 comments on commit 11cbb54

Please sign in to comment.