-
-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add mixins (extends) feature to work with @nestjs/mapped-types
and @nestjs/swagger
#271
Comments
I have some stashed code for this which could give me a headstart. However, I'm thinking of which package we'd want to publish this under:
What do you think? I'm leaning towards |
I've said To me |
@nestjs/mapped-types
and @nestjs/swagger
@nestjs/mapped-types
and @nestjs/swagger
@micalevisk 7.7kb is nothing if used on the server-side (client-side can benefit better with gzipped + minified). And as soon as Nx supports differential build for Node Package then tree-shaking is also available. |
https://automapperts.netlify.app/docs/plugins-system/classes-mapped-types give this a try in v3.3.0. I don't close this issue yet since not sure if it works for you. |
Looks like the mappings are working but it still not inherits the metadata from class Foo {
@AutoMap()
foo: string;
@AutoMap()
@ApiProperty({ description: 'do something' }) // or any other `Api`-like decorators
bar: number;
}
class SubFoo extends MapperOmitType(Foo, ['foo']) {} If you can somehow make this work with the OpenAPI CLI plugin (from Nestjs) as well it would be awesome! |
Since there’re mixins, can you just compose them? Like OmitType(MapperOmitType()) kinda? |
Well, it's probably not possible. I'll give it more thoughts tomorrow. @micalevisk okay, I'm at a roadblock. I'm not sure how to combine these mixins between packages since the typings and the parameters types are all different, and there is also an unknown number of mixins that you'd combine. You have any idea? |
Looking at I've tried the following version of export function MyMapperPickType<T, K extends keyof T>(
classRef: Constructible<T>,
keys: readonly K[]
): MappedType<Pick<T, typeof keys[number]>> {
const isInheritedPredicate = (propertyKey: string) =>
keys.includes(propertyKey as K);
class PickClassType {
constructor() {
inheritPropertyInitializers(
this as Record<string, unknown>,
classRef,
isInheritedPredicate
);
}
}
inheritAutoMapMetadata(classRef, PickClassType, isInheritedPredicate);
// ---------------------------------------------------------------------- //
clonePluginMetadataFactory(
PickClassType,
classRef.prototype,
(metadata: Record<string, any>) => pick(metadata, keys)
);
// ---------------------------------------------------------------------- //
return PickClassType as MappedType<Pick<T, typeof keys[number]>>;
} |
Yeah, that's what I want to avoid, I don't want automapper/classes to depend on nestjs/swagger :( |
I'm with you. |
So can you confirm if something like this would work? export function MyPickType<T, K extends keyof T>(
classRef: Constructible<T>,
keys: readonly K[]
): MappedType<Pick<T, typeof keys[number]>> {
class MappedClass extends MapperPickType(classRef, keys) {}
// ---------------------------------------------------------------------- //
clonePluginMetadataFactory(
MappedClass,
classRef.prototype,
(metadata: Record<string, any>) => pick(metadata, keys)
);
// ---------------------------------------------------------------------- //
return MappedClass as MappedType<Pick<T, typeof keys[number]>>;
} This way, we can reuse |
I'm getting TS error in (alias) MapperPickType<T, K>(classRef: Constructible<T>, keys: readonly K[]): MappedType<Pick<T, K>>
import MapperPickType but it works if I ignore this error. The problem with that is using |
does adding |
hm...so we're using a private API then. I guess I should halt on this since I'm not sure how to move forward. If you think of a stable workaround, please let me know so I can add to the docs. |
@nartc
export class GetOrganizationDto extends OmitType<
Organization,
(typeof GET_ORGANIZATION_OMIT_PROPERTIES)[number]
>(Organization, GET_ORGANIZATION_OMIT_PROPERTIES) {}
class GetOrganizationAutomapperDto extends MapperOmitType<
Organization,
(typeof GET_ORGANIZATION_OMIT_PROPERTIES)[number]
>(Organization, GET_ORGANIZATION_OMIT_PROPERTIES) {}
@Injectable()
export class OrganizationMapper extends AutomapperProfile {
constructor(@InjectMapper() mapper: Mapper) {
super(mapper);
}
override get profile(): MappingProfile {
return (mapper: Mapper) => {
createMap(mapper, Organization, GetOrganizationAutomapperDto);
createMap(
mapper,
Organization,
GetOrganizationDto,
extend<
Organization,
GetOrganizationDto,
Organization,
GetOrganizationDto
>(Organization, GetOrganizationAutomapperDto),
);
};
}
}
@Controller('organizations')
export class OrganizationsController {
constructor(
private readonly organizationsService: OrganizationsService,
@InjectMapper() private readonly mapper: Mapper,
) {}
@Get(':id')
async findById(@Param('id') id: string): Promise<GetOrganizationDto> {
const organization = await this.organizationsService.findById(id);
return this.mapper.map(
organization,
Organization,
GetOrganizationDto,
);
}
} |
Hey!
I want to use
@automapper/nestjs
along with@nestjs/swagger
to be able to generate an OpenAPI spec from my DTOs (or view models).However the mapped types mixins from
@nestjs/swagger
(the same of@nestjs/mapped-types
) do not inherit automapper's metadata, as you already notice here: #173 (comment) thus this following code will not work as expected:ie. when mapping
User
toNonDeletableUserVm
we'll getNonDeletableUserVm {}
Therefore, automapper should have mixins like
PickType
andOmitType
to makemapper.map(user, NonDeletableUserVm, User)
returnNonDeletableUserVm { name: "foo" }
instead ofNonDeletableUserVm {}
without removing metadata that are copied in@nestjs/swagger
Related issue: nestjsx/automapper#254
The text was updated successfully, but these errors were encountered: