Skip to content
This repository has been archived by the owner on Oct 10, 2022. It is now read-only.

Commit

Permalink
Merge cd5841f into 4ec06cf
Browse files Browse the repository at this point in the history
  • Loading branch information
smolijar committed May 13, 2019
2 parents 4ec06cf + cd5841f commit b73de5d
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `postprocessData` function to transform all possible return values

### Changed
- `processData` now called even on list

## [0.4.3] - 2019-04-30
### Fixed
Expand Down
6 changes: 1 addition & 5 deletions src/lib/context/crudContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,4 @@ export type CrudContext<T, C> =
| DeleteContext<T, C>
| ListContext<T, C>;

export type DataContext<T, C> = Pick<
CreateContext<T, C> | UpdateContext<T, C>,
// tslint:disable-next-line max-union-size
'data' | 'context' | 'options' | 'type'
>;
export type DataContext<T, C> = UpdateContext<T, C> | CreateContext<T, C> | ListContext<T, C>;
1 change: 1 addition & 0 deletions src/lib/service/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const createDefaultImplementation = <T, C>(): Omit<Required<Definitions<T>>, 're
list: () => Promise.reject(new Error('"list" not implemented')),
authorize: () => Promise.resolve(true),
processData: ({ data }: DataContext<T, C>) => data,
postprocessData: (returnValue: any) => returnValue,
createNotFoundError: () => new Error('Requested resource not found'),
getOptions: () => ({}),
controller: getDefaultController(),
Expand Down
27 changes: 18 additions & 9 deletions src/lib/service/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,33 +53,38 @@ export const createHandlers = <T extends { id: any }, C extends object>(
options,
});
await implementation.authorize(ctx);
return ctx.entity;
const result = ctx.entity;
return implementation.postprocessData(result, ctx);
};
const createHandler = (options: any = {}): CreateHandler<T, C> => async (data: any, context: C) => {
options = await bootstrapOption(Operation.CREATE, options, context);
const processedData = await implementation.processData({ data, context, options, type: Operation.CREATE });
const ctx: CreateContext<T, C> = forgeCreateContext({
data,
context,
options,
data: processedData,
bareData: data,
});
const processedData = await implementation.processData(ctx);
ctx.data = processedData;
await implementation.authorize(ctx);
return implementation.create(ctx);
const result = implementation.create(ctx);
return implementation.postprocessData(result, ctx);
};
const updateHandler = (options: any = {}): UpdateHandler<T, C> => async (id: number, data: any, context: C) => {
options = await bootstrapOption(Operation.UPDATE, options, context);
const processedData = await implementation.processData({ data, context, options, type: Operation.UPDATE });
const entity = await safeDetail({ id, context, options });
const ctx: UpdateContext<T, C> = forgeUpdateContext({
data,
context,
entity,
options,
data: processedData,
bareData: data,
});
const processedData = await implementation.processData(ctx);
ctx.data = processedData;
await implementation.authorize(ctx);
return implementation.update(ctx);
const result = implementation.update(ctx);
return implementation.postprocessData(result, ctx);
};

const deleteHandler = (options: any = {}): DeleteHandler<T, C> => async (id: number, context: C) => {
Expand All @@ -92,7 +97,8 @@ export const createHandlers = <T extends { id: any }, C extends object>(
options,
});
await implementation.authorize(ctx);
return implementation.delete(ctx);
const result = implementation.delete(ctx);
return implementation.postprocessData(result, ctx);
};

const listHandler = (options: any = {}): ListHandler<T, C> => async (filters: any, context: C) => {
Expand All @@ -102,8 +108,11 @@ export const createHandlers = <T extends { id: any }, C extends object>(
options,
filters,
});
const processedData = await implementation.processData(ctx);
ctx.data = processedData;
await implementation.authorize(ctx);
return implementation.list(ctx);
const result = implementation.list(ctx);
return implementation.postprocessData(result, ctx);
};

return {
Expand Down
7 changes: 6 additions & 1 deletion src/lib/settings/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,15 @@ export interface Definitions<T, C = any> {
repository?: CrudRepository<T>;
/**
* This method processes any incoming data coming from user.
* Data processing is called for Create and Update.
* Data processing is called for Create, Update and List (filters).
* Override the method for custom data transformation.
*/
processData?: (ctx: DataContext<T, C>) => PromiseLike<any> | any;

/**
* Process data coming from the service.
*/
postprocessData?: (returnValue: any, context: CrudContext<T, C>) => PromiseLike<any> | any;
/**
* Reject access to any given handler based on CrudContext.
* This method is called before each handler is finished. To reject access, throw Error.
Expand Down
1 change: 1 addition & 0 deletions src/test/__snapshots__/crudella.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Object {
"q": "dalmatians",
"user": "Crudella de Vile",
},
"data": undefined,
"filters": Object {
"nice": true,
},
Expand Down

0 comments on commit b73de5d

Please sign in to comment.