diff --git a/index.d.ts b/index.d.ts index 4f72786b..8806c314 100644 --- a/index.d.ts +++ b/index.d.ts @@ -17,7 +17,7 @@ declare module 'redux-fluent' { P extends object = object, M extends object = object, T extends string = string - >(type: T): I.ActionCreator; + >(type: T, payloadCreator?: (p: any) => P, metaCreator?: (m: any) => M): I.ActionCreator; } declare namespace /* Interfaces */ I { diff --git a/src/Action/Action.js b/src/Action/Action.js index b7511111..32a80ce9 100644 --- a/src/Action/Action.js +++ b/src/Action/Action.js @@ -1,11 +1,16 @@ -export default function ActionCreatorFactory(type) { - function actionCreator(payload, meta) { +const identity = arg => arg; + +export default function ActionCreatorFactory(type, payloadCreator, metaCreator) { + function actionCreator(rawPayload, rawMeta) { const action = Object.create(null); + const payload = (payloadCreator || identity)(rawPayload) || null; + const meta = (metaCreator || identity)(rawMeta) || null; + action.type = type; action.error = payload instanceof Error; - action.meta = meta || null; - action.payload = payload || null; + action.meta = meta; + action.payload = payload; return Object.freeze(action); } diff --git a/src/Action/Action.spec.js b/src/Action/Action.spec.js index 8a74a889..32cd800d 100644 --- a/src/Action/Action.spec.js +++ b/src/Action/Action.spec.js @@ -9,6 +9,28 @@ describe('createAction', () => { expect(createAction('test')).toEqual(jasmine.any(Function)); }); + it('Factory should accept a payloadCreator', () => { + const payloadCreator = jasmine.createSpy('payloadCreator') + .and.callFake(todoId => ({ id: todoId })); + + const deleteTodo = createAction('@@todos/:id | delete', payloadCreator); + const todoId = 12; + + expect(deleteTodo(todoId).payload).toEqual({ id: todoId }); + expect(payloadCreator).toHaveBeenCalledWith(todoId); + }); + + it('Factory should accept a metaCreator', () => { + const metaCreator = jasmine.createSpy('metaCreator') + .and.callFake(metaThing => ({ id: metaThing })); + + const deleteTodo = createAction('@@todos/:id | delete', null, metaCreator); + const metaThing = 'Hello World'; + + expect(deleteTodo(null, metaThing).meta).toEqual({ id: metaThing }); + expect(metaCreator).toHaveBeenCalledWith(metaThing); + }); + describe('actionCreator', () => { it('should have a property type', () => { expect(createAction(type)).toHaveProperty('type', type);