Skip to content

Commit bb95c94

Browse files
committed
Support passing a transformer function to
1 parent 0ffe6d9 commit bb95c94

File tree

3 files changed

+64
-32
lines changed

3 files changed

+64
-32
lines changed

src/tests/transform.test.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const removeAuthor = async (item: Record<string, unknown>) =>
1414
0,
1515
item.title.length -
1616
6 -
17-
(typeof item.author === 'string' ? item.author.length : 0)
17+
(typeof item.author === 'string' ? item.author.length : 0),
1818
)
1919
: item.title
2020

@@ -174,7 +174,7 @@ test('should reverse map simple object with dedicated rev transform', async (t)
174174
t.deepEqual(ret, expected)
175175
})
176176

177-
test('should transform beofre data is set on outer path', async (t) => {
177+
test('should transform before data is set on outer path', async (t) => {
178178
const def = {
179179
attributes: [
180180
'result.data',
@@ -630,6 +630,28 @@ test('should provide index when iterating in reverse', async (t) => {
630630
t.deepEqual(ret, expected)
631631
})
632632

633+
test('should use transformer function provided directly to $transform', async (t) => {
634+
const def = [
635+
{
636+
title: 'content.heading',
637+
author: 'meta.writer.username',
638+
},
639+
{ $transform: appendAuthorToTitle },
640+
]
641+
const data = {
642+
content: { heading: 'The heading' },
643+
meta: { writer: { username: 'johnf' } },
644+
}
645+
const expected = {
646+
title: 'The heading - by johnf',
647+
author: 'johnf',
648+
}
649+
650+
const ret = await mapTransform(def)(data)
651+
652+
t.deepEqual(ret, expected)
653+
})
654+
633655
test('should support $value shorthand', async (t) => {
634656
const def = [
635657
{
@@ -795,7 +817,7 @@ test('should throw when transform is given an unknown transformer id', (t) => {
795817
t.true(error instanceof Error)
796818
t.is(
797819
error?.message,
798-
"Transform operator was given the unknown transformer id 'unknown'"
820+
"Transform operator was given the unknown transformer id 'unknown'",
799821
)
800822
})
801823

@@ -811,7 +833,7 @@ test('should throw when transform is given an unknown transformer id symbol', (t
811833
t.true(error instanceof Error)
812834
t.is(
813835
error?.message,
814-
"Transform operator was given the unknown transformer id 'Symbol(unknown)'"
836+
"Transform operator was given the unknown transformer id 'Symbol(unknown)'",
815837
)
816838
})
817839

@@ -829,7 +851,7 @@ test('should throw when transform operation is missing a transformer id', (t) =>
829851
t.true(error instanceof Error)
830852
t.is(
831853
error?.message,
832-
'Transform operator was given no transformer id or an invalid transformer id'
854+
'Transform operator was given no transformer id or an invalid transformer id',
833855
)
834856
})
835857

@@ -847,7 +869,7 @@ test('should throw when transform operation has invalid transformer id', async (
847869
t.true(error instanceof Error)
848870
t.is(
849871
error?.message,
850-
'Transform operator was given no transformer id or an invalid transformer id'
872+
'Transform operator was given no transformer id or an invalid transformer id',
851873
)
852874
})
853875

@@ -873,7 +895,7 @@ test('should run operation objects trought modifyOperationObject', async (t) =>
873895
}
874896

875897
const ret = await mapTransform(def, { transformers, modifyOperationObject })(
876-
data
898+
data,
877899
)
878900

879901
t.deepEqual(ret, expected)

src/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export interface Options {
4141
fwdAlias?: string
4242
revAlias?: string
4343
modifyOperationObject?: (
44-
operation: Record<string, unknown>
44+
operation: Record<string, unknown>,
4545
) => Record<string, unknown>
4646
modifyGetValue?: (value: unknown, state: State, options: Options) => unknown
4747
}
@@ -99,7 +99,11 @@ export interface AsyncTransformer<T = TransformerProps> {
9999
export type Path = string
100100

101101
export interface TransformOperation extends TransformerProps {
102-
$transform: string | symbol
102+
$transform:
103+
| string
104+
| symbol
105+
| DataMapperWithOptions
106+
| AsyncDataMapperWithOptions
103107
$iterate?: boolean
104108
$direction?: string
105109
}

src/utils/definitionHelpers.ts

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -123,26 +123,32 @@ const createOperation =
123123
): Operation =>
124124
(options) => {
125125
const { [fnProp]: fnId, ...props } = def
126-
if (typeof fnId !== 'string' && typeof fnId !== 'symbol') {
127-
throw new Error(
128-
`${humanizeOperatorName(
129-
fnProp,
130-
)} operator was given no transformer id or an invalid transformer id`,
131-
)
132-
}
126+
let transformFn
127+
if (typeof fnId === 'function') {
128+
transformFn = fnId as DataMapperWithOptions | AsyncDataMapperWithOptions
129+
} else {
130+
if (typeof fnId !== 'string' && typeof fnId !== 'symbol') {
131+
throw new Error(
132+
`${humanizeOperatorName(
133+
fnProp,
134+
)} operator was given no transformer id or an invalid transformer id`,
135+
)
136+
}
133137

134-
// eslint-disable-next-line security/detect-object-injection
135-
const fn = options.transformers && options.transformers[fnId]
136-
if (typeof fn !== 'function') {
137-
throw new Error(
138-
`${humanizeOperatorName(
139-
fnProp,
140-
)} operator was given the unknown transformer id '${String(fnId)}'`,
141-
)
138+
// eslint-disable-next-line security/detect-object-injection
139+
const fn = options.transformers && options.transformers[fnId]
140+
if (typeof fn !== 'function') {
141+
throw new Error(
142+
`${humanizeOperatorName(
143+
fnProp,
144+
)} operator was given the unknown transformer id '${String(fnId)}'`,
145+
)
146+
}
147+
transformFn = fn(props)
142148
}
143149

144-
return typeof fn === 'function'
145-
? wrapFromDefinition(operationFn(fn(props)), def)(options)
150+
return typeof transformFn === 'function'
151+
? wrapFromDefinition(operationFn(transformFn), def)(options)
146152
: passStateThroughNext
147153
}
148154

@@ -252,12 +258,12 @@ export const defToOperations = (
252258
isPipeline(def)
253259
? def.flatMap((def) => defToOperations(def, options))
254260
: isObject(def)
255-
? operationFromObject(def, options)
256-
: isPath(def)
257-
? get(def)
258-
: isOperation(def)
259-
? def
260-
: () => () => async (value) => value
261+
? operationFromObject(def, options)
262+
: isPath(def)
263+
? get(def)
264+
: isOperation(def)
265+
? def
266+
: () => () => async (value) => value
261267

262268
export function defToOperation(
263269
def: TransformDefinition | undefined,

0 commit comments

Comments
 (0)