Skip to content

Commit 789d76a

Browse files
committed
Create ListField to DRY deduping items
1 parent 821c60e commit 789d76a

File tree

9 files changed

+52
-38
lines changed

9 files changed

+52
-38
lines changed

src/common/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export * from './fiscal-year';
2424
export * from './generate-id';
2525
export * from './id.arg';
2626
export * from './lazy-ref';
27+
export * from './list-field';
2728
export * from './lazy-record';
2829
export { DateField, DateTimeField } from './luxon.graphql';
2930
export * from './map-or-else';

src/common/list-field.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { applyDecorators } from '@nestjs/common';
2+
import { OptionalField, OptionalFieldOptions } from './optional-field';
3+
4+
export type ListFieldOptions = OptionalFieldOptions;
5+
6+
export const ListField = (typeFn: () => any, options: ListFieldOptions) =>
7+
applyDecorators(
8+
OptionalField(() => [typeFn()], {
9+
optional: false,
10+
...options,
11+
transform: (value) => {
12+
const deduped = value ? [...new Set(value)] : value;
13+
return options.transform ? options.transform(deduped) : value;
14+
},
15+
}),
16+
);

src/components/language/dto/update-language.dto.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Field, InputType, Int, ObjectType } from '@nestjs/graphql';
2-
import { Transform, Type } from 'class-transformer';
2+
import { Type } from 'class-transformer';
33
import {
44
IsAlpha,
55
IsLowercase,
@@ -8,12 +8,12 @@ import {
88
Matches,
99
ValidateNested,
1010
} from 'class-validator';
11-
import { uniq } from 'lodash';
1211
import {
1312
CalendarDate,
1413
DateField,
1514
ID,
1615
IdField,
16+
ListField,
1717
NameField,
1818
OptionalField,
1919
Sensitivity,
@@ -108,9 +108,8 @@ export abstract class UpdateLanguage {
108108
@OptionalField()
109109
readonly hasExternalFirstScripture?: boolean;
110110

111-
@Field(() => [String], { nullable: true })
112-
@Transform(({ value }) => uniq(value))
113-
readonly tags?: string[];
111+
@ListField(() => String, { optional: true })
112+
readonly tags?: readonly string[];
114113
}
115114

116115
@InputType()

src/components/partner/dto/update-partner.dto.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { Field, ID as IDType, InputType, ObjectType } from '@nestjs/graphql';
2-
import { Transform, Type } from 'class-transformer';
2+
import { Type } from 'class-transformer';
33
import { Matches, ValidateNested } from 'class-validator';
4-
import { uniq } from 'lodash';
54
import {
65
CalendarDate,
76
DateField,
87
ID,
98
IdField,
109
IsId,
10+
ListField,
1111
NameField,
1212
} from '~/common';
1313
import { FinanceDepartmentIdBlockInput } from '../../finance/department/dto/id-blocks.input';
@@ -24,12 +24,10 @@ export abstract class UpdatePartner {
2424
@IdField({ nullable: true })
2525
readonly pointOfContactId?: ID<'User'> | null;
2626

27-
@Field(() => [PartnerType], { nullable: true })
28-
@Transform(({ value }) => uniq(value))
27+
@ListField(() => PartnerType, { optional: true })
2928
readonly types?: readonly PartnerType[];
3029

31-
@Field(() => [FinancialReportingType], { nullable: true })
32-
@Transform(({ value }) => uniq(value))
30+
@ListField(() => FinancialReportingType, { optional: true })
3331
readonly financialReportingTypes?: readonly FinancialReportingType[];
3432

3533
@Field(() => String, { nullable: true })
@@ -50,26 +48,23 @@ export abstract class UpdatePartner {
5048
@IdField({ nullable: true })
5149
readonly languageOfWiderCommunicationId?: ID<'Language'> | null;
5250

53-
@Field(() => [IDType], { nullable: true })
51+
@ListField(() => IDType, { optional: true })
5452
@IsId({ each: true })
55-
@Transform(({ value }) => (value ? uniq(value) : undefined))
5653
readonly countries?: ReadonlyArray<ID<'Location'>>;
5754

58-
@Field(() => [IDType], { nullable: true })
55+
@ListField(() => IDType, { optional: true })
5956
@IsId({ each: true })
60-
@Transform(({ value }) => (value ? uniq(value) : undefined))
6157
readonly fieldRegions?: ReadonlyArray<ID<'FieldRegion'>>;
6258

63-
@Field(() => [IDType], { name: 'languagesOfConsulting', nullable: true })
64-
@Transform(({ value }) => (value ? uniq(value) : undefined))
59+
@ListField(() => IDType, { optional: true })
60+
@IsId({ each: true })
6561
readonly languagesOfConsulting?: ReadonlyArray<ID<'Language'>>;
6662

6763
@DateField({ nullable: true })
6864
readonly startDate?: CalendarDate | null;
6965

70-
@Field(() => [ProjectType], { nullable: true })
71-
@Transform(({ value }) => uniq(value))
72-
readonly approvedPrograms?: ProjectType[];
66+
@ListField(() => ProjectType, { optional: true })
67+
readonly approvedPrograms?: readonly ProjectType[];
7368

7469
@Field(() => FinanceDepartmentIdBlockInput, { nullable: true })
7570
@ValidateNested()

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
2-
import { Transform, Type } from 'class-transformer';
2+
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { uniq } from 'lodash';
5-
import { CalendarDate, DateField, ID, IdField, OptionalField } from '~/common';
4+
import {
5+
CalendarDate,
6+
DateField,
7+
ID,
8+
IdField,
9+
ListField,
10+
OptionalField,
11+
} from '~/common';
612
import { ChangesetIdField } from '../../changeset';
713
import { CreateDefinedFileVersionInput } from '../../file/dto';
814
import { PartnerType } from '../../partner/dto';
@@ -37,8 +43,7 @@ export abstract class UpdatePartnership {
3743
@DateField({ nullable: true })
3844
readonly mouEndOverride?: CalendarDate | null;
3945

40-
@Field(() => [PartnerType], { nullable: true })
41-
@Transform(({ value }) => uniq(value))
46+
@ListField(() => PartnerType, { optional: true })
4247
readonly types?: readonly PartnerType[];
4348

4449
@Field(() => FinancialReportingType, { nullable: true })

src/components/project-change-request/dto/update-project-change-request.dto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
22
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { ID, IdField, NameField, OptionalField } from '~/common';
4+
import { ID, IdField, ListField, NameField, OptionalField } from '~/common';
55
import { ProjectChangeRequestStatus } from './project-change-request-status.enum';
66
import { ProjectChangeRequestType } from './project-change-request-type.enum';
77
import { ProjectChangeRequest } from './project-change-request.dto';
@@ -11,8 +11,8 @@ export abstract class UpdateProjectChangeRequest {
1111
@IdField()
1212
readonly id: ID;
1313

14-
@OptionalField(() => [ProjectChangeRequestType])
15-
readonly types?: [ProjectChangeRequestType];
14+
@ListField(() => ProjectChangeRequestType, { optional: true })
15+
readonly types?: readonly ProjectChangeRequestType[];
1616

1717
@NameField({ optional: true })
1818
readonly summary?: string;

src/components/project/dto/update-project.dto.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
2-
import { Transform, Type } from 'class-transformer';
2+
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { uniq } from 'lodash';
54
import { DateTime } from 'luxon';
65
import {
76
CalendarDate,
@@ -10,6 +9,7 @@ import {
109
ID,
1110
IdField,
1211
IdOf,
12+
ListField,
1313
NameField,
1414
OptionalField,
1515
Sensitivity,
@@ -75,8 +75,7 @@ export abstract class UpdateProject {
7575
})
7676
readonly sensitivity?: Sensitivity;
7777

78-
@Field(() => [String], { nullable: true })
79-
@Transform(({ value }) => uniq(value))
78+
@ListField(() => String, { optional: true })
8079
readonly tags?: readonly string[];
8180

8281
@DateTimeField({ nullable: true })

src/components/project/project-member/dto/update-project-member.dto.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
22
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { ID, IdField, OptionalField, Role } from '~/common';
4+
import { ID, IdField, ListField, Role } from '~/common';
55
import { ProjectMember } from './project-member.dto';
66

77
@InputType()
88
export abstract class UpdateProjectMember {
99
@IdField()
1010
readonly id: ID;
1111

12-
@OptionalField(() => [Role])
12+
@ListField(() => Role, { optional: true })
1313
readonly roles?: readonly Role[];
1414
}
1515

src/components/user/dto/update-user.dto.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { Field, InputType, ObjectType } from '@nestjs/graphql';
2-
import { Transform, Type } from 'class-transformer';
2+
import { Type } from 'class-transformer';
33
import { ValidateNested } from 'class-validator';
4-
import { uniq } from 'lodash';
54
import {
65
EmailField,
76
ID,
87
IdField,
98
IsIanaTimezone,
9+
ListField,
1010
NameField,
1111
OptionalField,
1212
Role,
@@ -47,8 +47,7 @@ export abstract class UpdateUser {
4747
@OptionalField(() => UserStatus)
4848
readonly status?: UserStatus;
4949

50-
@Field(() => [Role], { nullable: true })
51-
@Transform(({ value }) => uniq(value))
50+
@ListField(() => Role, { optional: true })
5251
readonly roles?: readonly Role[];
5352

5453
@Field(() => String, { nullable: true })

0 commit comments

Comments
 (0)