Skip to content

Commit 11c8b31

Browse files
committed
Adjust OptionalField transformers to be passed the original/previous transformer
This allows them to transform the value _before_ passing it to the original/previous transformer.
1 parent d202975 commit 11c8b31

File tree

5 files changed

+54
-32
lines changed

5 files changed

+54
-32
lines changed

src/common/list-field.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { applyDecorators } from '@nestjs/common';
22
import { ArrayNotEmpty } from 'class-validator';
3-
import { OptionalField, type OptionalFieldOptions } from './optional-field';
3+
import {
4+
OptionalField,
5+
type OptionalFieldOptions,
6+
withDefaultTransform,
7+
} from './optional-field';
48

59
export type ListFieldOptions = OptionalFieldOptions & {
610
/**
@@ -14,11 +18,12 @@ export const ListField = (typeFn: () => any, options: ListFieldOptions) =>
1418
OptionalField(() => [typeFn()], {
1519
optional: false,
1620
...options,
17-
transform: (value) => {
21+
transform: withDefaultTransform(options.transform, (prev) => (raw) => {
22+
const value = prev(raw);
1823
let out = value ? [...new Set(value)] : value;
1924
out = options.empty === 'omit' && out.length === 0 ? undefined : out;
20-
return options.transform ? options.transform(out) : out;
21-
},
25+
return out;
26+
}),
2227
}),
2328
...(options.empty === 'deny' ? [ArrayNotEmpty()] : []),
2429
);

src/common/optional-field.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,19 @@ export type OptionalFieldOptions = FieldOptions & {
1313
* If true, values can be omitted/undefined but not null.
1414
*/
1515
optional?: boolean;
16-
transform?: (value: any) => unknown;
16+
transform?: TransformerLink;
1717
};
1818

19+
type TransformerLink = (prev: Transformer) => Transformer;
20+
type Transformer<I = any, O = any> = (value: I) => O;
21+
export const withDefaultTransform =
22+
(
23+
input: TransformerLink | undefined,
24+
wrapping: TransformerLink,
25+
): TransformerLink =>
26+
(base) =>
27+
input?.(wrapping(base)) ?? wrapping(base);
28+
1929
/**
2030
* A field that is optional/omissible/can be undefined.
2131
* Whether it can be explicitly null is based on `nullable`.
@@ -38,13 +48,16 @@ export function OptionalField(...args: any) {
3848
...options,
3949
nullable: nilIn,
4050
};
51+
const defaultTransformer: Transformer = (value) => {
52+
if (value === null && !nullOut) {
53+
return undefined;
54+
}
55+
return value;
56+
};
57+
const finalTransformer =
58+
options.transform?.(defaultTransformer) ?? defaultTransformer;
4159
return applyDecorators(
4260
typeFn ? Field(typeFn, schemaOptions) : Field(schemaOptions),
43-
Transform(({ value }) => {
44-
if (value === null && !nullOut) {
45-
return undefined;
46-
}
47-
return options.transform ? options.transform(value) : value;
48-
}),
61+
Transform(({ value }) => finalTransformer(value)),
4962
);
5063
}

src/common/rich-text.scalar.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { applyDecorators } from '@nestjs/common';
22
import { ObjectType } from '@nestjs/graphql';
3-
import { setToStringTag } from '@seedcompany/common';
3+
import { type Nil, setToStringTag } from '@seedcompany/common';
44
import { markSkipClassTransformation } from '@seedcompany/nest';
55
import { IsObject } from 'class-validator';
66
import { createHash } from 'crypto';
@@ -82,23 +82,19 @@ export const RichTextField = (options?: OptionalFieldOptions) =>
8282
OptionalField(() => RichTextScalar, {
8383
optional: false,
8484
...options,
85-
transform: (value) => {
86-
const doc = RichTextDocument.fromMaybe(value);
87-
if (doc) {
88-
return doc;
85+
transform: (prev) => (value) => {
86+
const doc: RichTextDocument | Nil = prev(
87+
RichTextDocument.fromMaybe(value),
88+
);
89+
if (doc == null && !options?.nullable && !options?.optional) {
90+
// Should never _really_ get here.
91+
// UI should understand & send null instead of an empty document.
92+
// Would prefer this to be done with validators.
93+
// But I believe this needs `null`s to be validated.
94+
// skipMissingProperties -> skipUndefinedProperties
95+
throw new InputException('RichText must be given');
8996
}
90-
if (options?.nullable) {
91-
return null;
92-
}
93-
if (options?.optional) {
94-
return undefined;
95-
}
96-
// Should never _really_ get here.
97-
// UI should understand & send null instead of an empty document.
98-
// Would prefer this to be done with validators.
99-
// But I believe this needs to `null`s to be validated.
100-
// skipMissingProperties -> skipUndefinedProperties
101-
throw new InputException('RichText must be given');
97+
return doc;
10298
},
10399
}),
104100
IsObject(),

src/common/sensitivity.enum.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ export const SensitivitiesFilterField = (options?: ListFieldOptions) =>
2727
...options,
2828
optional: true,
2929
empty: 'omit',
30-
transform: (value) =>
30+
transform: (prev) => (raw) => {
31+
const value = prev(raw);
3132
// If given all options, there is no need to filter
32-
!value || value.length === Sensitivity.values.size ? undefined : value,
33+
return !value || value.length === Sensitivity.values.size
34+
? undefined
35+
: value;
36+
},
3337
});

src/components/partnership/dto/list-partnership.dto.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ export abstract class PartnershipFilters {
2020
@ListField(() => PartnerType, {
2121
optional: true,
2222
empty: 'omit',
23-
transform: (value) =>
23+
transform: (prev) => (raw) => {
24+
const value = prev(raw);
2425
// If given all options, there is no need to filter
25-
!value || value.length === PartnerType.values.size ? undefined : value,
26+
return !value || value.length === PartnerType.values.size
27+
? undefined
28+
: value;
29+
},
2630
})
2731
readonly types?: readonly PartnerType[];
2832
}

0 commit comments

Comments
 (0)