Skip to content

Commit

Permalink
feat(schema): Add resolveAll hook (#2643)
Browse files Browse the repository at this point in the history
  • Loading branch information
daffl authored May 23, 2022
1 parent 43d8a08 commit 85527d7
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 118 deletions.
129 changes: 68 additions & 61 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"dependencies": {
"@feathersjs/errors": "^5.0.0-pre.20",
"@feathersjs/feathers": "^5.0.0-pre.20",
"@feathersjs/hooks": "^0.7.4",
"@types/json-schema": "^7.0.11",
"ajv": "^8.11.0",
"json-schema": "^0.4.0",
Expand Down
2 changes: 2 additions & 0 deletions packages/schema/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './resolve';
export * from './validate';
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HookContext, NextFunction } from '@feathersjs/feathers';
import { BadRequest } from '../../errors/lib';
import { Resolver, ResolverStatus } from './resolver';
import { Schema } from './schema';
import { compose } from '@feathersjs/hooks';
import { Resolver, ResolverStatus } from '../resolver';

const getContext = <H extends HookContext> (context: H) => {
return {
Expand Down Expand Up @@ -55,18 +54,21 @@ export const resolveQuery = <T, H extends HookContext> (...resolvers: Resolver<T

export const resolveData = <T, H extends HookContext> (...resolvers: Resolver<T, H>[]) =>
async (context: H, next?: NextFunction) => {
const ctx = getContext(context);
const data = context.data;
const status = {
originalContext: context
};

if (Array.isArray(data)) {
context.data = await Promise.all(data.map(current =>
runResolvers(resolvers, current, ctx, status)
));
} else {
context.data = await runResolvers(resolvers, data, ctx, status);
if (context.method === 'create' || context.method === 'patch' || context.method === 'update') {
const ctx = getContext(context);
const data = context.data;

const status = {
originalContext: context
};

if (Array.isArray(data)) {
context.data = await Promise.all(data.map(current =>
runResolvers(resolvers, current, ctx, status)
));
} else {
context.data = await runResolvers(resolvers, data, ctx, status);
}
}

if (typeof next === 'function') {
Expand Down Expand Up @@ -144,43 +146,25 @@ export const resolveDispatch = <T, H extends HookContext> (...resolvers: Resolve
});
};

export const validateQuery = <H extends HookContext> (schema: Schema<any>) =>
async (context: H, next?: NextFunction) => {
const data = context?.params?.query || {};

try {
const query = await schema.validate(data);

context.params = {
...context.params,
query
}

if (typeof next === 'function') {
return next();
}
} catch (error: any) {
throw (error.ajv ? new BadRequest(error.message, error.errors) : error);
}
};
export type ResolveAllSettings<H extends HookContext> = {
data?: Resolver<any, H>|Resolver<any, H>[]
query?: Resolver<any, H>|Resolver<any, H>[]
result?: Resolver<any, H>|Resolver<any, H>[]
dispatch?: Resolver<any, H>|Resolver<any, H>[]
}

export const validateData = <H extends HookContext> (schema: Schema<any>) =>
async (context: H, next?: NextFunction) => {
const data = context.data;
const getResolvers = <H extends HookContext> (
map: ResolveAllSettings<H>,
name: keyof ResolveAllSettings<H>
) => {
const value = map[name];

try {
if (Array.isArray(data)) {
context.data = await Promise.all(data.map(current =>
schema.validate(current)
));
} else {
context.data = await schema.validate(data);
}
} catch (error: any) {
throw (error.ajv ? new BadRequest(error.message, error.errors) : error);
}
return Array.isArray(value) ? value : (value !== undefined ? [ value ] : []);
}

if (typeof next === 'function') {
return next();
}
};
export const resolveAll = <H extends HookContext> (map: ResolveAllSettings<H>) => compose([
resolveDispatch(...getResolvers(map, 'dispatch')),
resolveResult(...getResolvers(map, 'result')),
resolveQuery(...getResolvers(map, 'query')),
resolveData(...getResolvers(map, 'data'))
])
Loading

0 comments on commit 85527d7

Please # to comment.