Commit f8a20598 authored by nanahira's avatar nanahira

add @NotInResult()

parent 0d6dac65
import { NotWritable } from '../decorators'; import { NotInResult, NotWritable } from '../decorators';
import { SelectQueryBuilder } from 'typeorm'; import { SelectQueryBuilder } from 'typeorm';
import { IsInt, IsPositive } from 'class-validator'; import { IsInt, IsPositive } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
...@@ -32,6 +32,7 @@ export class PageSettingsDto ...@@ -32,6 +32,7 @@ export class PageSettingsDto
type: Number, type: Number,
minimum: 1, minimum: 1,
}) })
@NotInResult()
pageCount: number; pageCount: number;
@NotWritable() @NotWritable()
...@@ -43,6 +44,7 @@ export class PageSettingsDto ...@@ -43,6 +44,7 @@ export class PageSettingsDto
type: Number, type: Number,
minimum: 1, minimum: 1,
}) })
@NotInResult()
recordsPerPage: number; recordsPerPage: number;
getActualPageSettings(): PageSettingsWise { getActualPageSettings(): PageSettingsWise {
......
...@@ -4,7 +4,7 @@ import { ...@@ -4,7 +4,7 @@ import {
SelectQueryBuilder, SelectQueryBuilder,
UpdateDateColumn, UpdateDateColumn,
} from 'typeorm'; } from 'typeorm';
import { NotColumn } from '../decorators'; import { NotColumn, NotInResult } from '../decorators';
import { PageSettingsDto } from './page-settings'; import { PageSettingsDto } from './page-settings';
export interface DeletionWise { export interface DeletionWise {
...@@ -27,14 +27,17 @@ export class TimeBase ...@@ -27,14 +27,17 @@ export class TimeBase
{ {
@CreateDateColumn({ select: false }) @CreateDateColumn({ select: false })
@NotColumn() @NotColumn()
@NotInResult({ entityVersioningDate: true })
createTime: Date; createTime: Date;
@UpdateDateColumn({ select: false }) @UpdateDateColumn({ select: false })
@NotColumn() @NotColumn()
@NotInResult({ entityVersioningDate: true })
updateTime: Date; updateTime: Date;
@DeleteDateColumn({ select: false }) @DeleteDateColumn({ select: false })
@NotColumn() @NotColumn()
@NotInResult({ entityVersioningDate: true })
deleteTime: Date; deleteTime: Date;
isValidInCreate(): string | undefined { isValidInCreate(): string | undefined {
......
...@@ -17,12 +17,13 @@ import { ...@@ -17,12 +17,13 @@ import {
import { ConsoleLogger } from '@nestjs/common'; import { ConsoleLogger } from '@nestjs/common';
import { camelCase } from 'typeorm/util/StringUtils'; import { camelCase } from 'typeorm/util/StringUtils';
import _ from 'lodash'; import _ from 'lodash';
import { ClassType } from './utility/insert-field';
import { import {
BlankReturnMessageDto, BlankReturnMessageDto,
ClassType,
PaginatedReturnMessageDto, PaginatedReturnMessageDto,
ReturnMessageDto, ReturnMessageDto,
} from 'nesties'; } from 'nesties';
import { getNotInResultFields } from './utility/metadata';
export type EntityId<T extends { id: any }> = T['id']; export type EntityId<T extends { id: any }> = T['id'];
export interface RelationDef { export interface RelationDef {
...@@ -56,6 +57,7 @@ export interface CrudOptions<T extends ValidCrudEntity<T>> { ...@@ -56,6 +57,7 @@ export interface CrudOptions<T extends ValidCrudEntity<T>> {
extraGetQuery?: (qb: SelectQueryBuilder<T>) => void; extraGetQuery?: (qb: SelectQueryBuilder<T>) => void;
hardDelete?: boolean; hardDelete?: boolean;
createOrUpdate?: boolean; createOrUpdate?: boolean;
keepEntityVersioningDates?: boolean;
} }
export class CrudBase<T extends ValidCrudEntity<T>> { export class CrudBase<T extends ValidCrudEntity<T>> {
...@@ -80,6 +82,26 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -80,6 +82,26 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
this.extraGetQuery = crudOptions.extraGetQuery || ((qb) => {}); this.extraGetQuery = crudOptions.extraGetQuery || ((qb) => {});
} }
_cleanEntityNotInResultFields(ent: T): T {
const fields = getNotInResultFields(
this.entityClass,
this.crudOptions.keepEntityVersioningDates,
);
for (const field of fields) {
delete (ent as any)[field];
}
return ent;
}
cleanEntityNotInResultFields<E extends T | T[]>(ents: E): E {
if (Array.isArray(ents)) {
return ents.map((ent) => this._cleanEntityNotInResultFields(ent)) as E;
} else {
return this._cleanEntityNotInResultFields(ents as T) as E;
}
}
async _batchCreate( async _batchCreate(
ents: T[], ents: T[],
beforeCreate?: (repo: Repository<T>) => Promise<void>, beforeCreate?: (repo: Repository<T>) => Promise<void>,
...@@ -181,8 +203,11 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -181,8 +203,11 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
results = results.concat(savedChunk); results = results.concat(savedChunk);
} }
return { return {
results, results: this.cleanEntityNotInResultFields(results),
skipped, skipped: skipped.map((e) => ({
...e,
entry: this.cleanEntityNotInResultFields(e.entry),
})),
}; };
} catch (e) { } catch (e) {
this.log.error( this.log.error(
...@@ -237,7 +262,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -237,7 +262,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
try { try {
const savedEnt = await repo.save(ent as DeepPartial<T>); const savedEnt = await repo.save(ent as DeepPartial<T>);
await savedEnt.afterCreate(); await savedEnt.afterCreate();
return savedEnt; return this.cleanEntityNotInResultFields(savedEnt);
} catch (e) { } catch (e) {
this.log.error( this.log.error(
`Failed to create entity ${JSON.stringify(ent)}: ${e.toString()}`, `Failed to create entity ${JSON.stringify(ent)}: ${e.toString()}`,
...@@ -318,7 +343,11 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -318,7 +343,11 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
).toException(); ).toException();
} }
await ent.afterGet(); await ent.afterGet();
return new this.entityReturnMessageDto(200, 'success', ent); return new this.entityReturnMessageDto(
200,
'success',
this.cleanEntityNotInResultFields(ent),
);
} }
async findAll( async findAll(
...@@ -342,7 +371,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> { ...@@ -342,7 +371,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
return new this.entityPaginatedReturnMessageDto( return new this.entityPaginatedReturnMessageDto(
200, 200,
'success', 'success',
ents, this.cleanEntityNotInResultFields(ents),
count, count,
newEnt.getActualPageSettings(), newEnt.getActualPageSettings(),
); );
......
...@@ -18,3 +18,8 @@ export const NotChangeable = () => ...@@ -18,3 +18,8 @@ export const NotChangeable = () =>
export const NotQueryable = () => export const NotQueryable = () =>
Metadata.set('notQueryable', true, 'notQueryableFields'); Metadata.set('notQueryable', true, 'notQueryableFields');
export const NotInResult = (options: { entityVersioningDate?: boolean } = {}) =>
options.entityVersioningDate
? Metadata.set('entityVersioningDate', true, 'entityVersioningDateFields')
: Metadata.set('notInResult', true, 'notInResultFields');
...@@ -23,11 +23,7 @@ import { ColumnNumericOptions } from 'typeorm/decorator/options/ColumnNumericOpt ...@@ -23,11 +23,7 @@ import { ColumnNumericOptions } from 'typeorm/decorator/options/ColumnNumericOpt
import { Exclude, Transform, Type } from 'class-transformer'; import { Exclude, Transform, Type } from 'class-transformer';
import { BigintTransformer } from '../utility/bigint'; import { BigintTransformer } from '../utility/bigint';
import { Metadata } from '../utility/metadata'; import { Metadata } from '../utility/metadata';
import { import { ClassOrArray, getClassFromClassOrArray, ParseType } from 'nesties';
ClassOrArray,
getClassFromClassOrArray,
ParseType,
} from '../utility/insert-field';
import { TypeTransformer } from '../utility/type-transformer'; import { TypeTransformer } from '../utility/type-transformer';
import { NotQueryable } from './access'; import { NotQueryable } from './access';
......
...@@ -11,12 +11,14 @@ import { ...@@ -11,12 +11,14 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { ImportDataDto, ImportEntryDto } from '../dto'; import { ImportDataDto, ImportEntryDto } from '../dto';
import { import {
AnyClass,
BlankReturnMessageDto, BlankReturnMessageDto,
InsertField,
MergeMethodDecorators, MergeMethodDecorators,
PaginatedReturnMessageDto, PaginatedReturnMessageDto,
ReturnMessageDto, ReturnMessageDto,
ClassType,
} from 'nesties'; } from 'nesties';
import { ClassType } from '../utility/insert-field';
import { import {
ApiBadRequestResponse, ApiBadRequestResponse,
ApiBody, ApiBody,
...@@ -31,33 +33,39 @@ import { ...@@ -31,33 +33,39 @@ import {
import { CreatePipe, GetPipe, UpdatePipe } from './pipes'; import { CreatePipe, GetPipe, UpdatePipe } from './pipes';
import { OperationObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface'; import { OperationObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
import _ from 'lodash'; import _ from 'lodash';
import { getSpecificFields } from '../utility/metadata'; import { getNotInResultFields, getSpecificFields } from '../utility/metadata';
import { RenameClass } from '../utility/rename-class'; import { RenameClass } from '../utility/rename-class';
import { getMetadataArgsStorage } from 'typeorm';
import { DECORATORS } from '@nestjs/swagger/dist/constants';
export interface RestfulFactoryOptions<T> { export interface RestfulFactoryOptions<T> {
fieldsToOmit?: (keyof T)[]; fieldsToOmit?: (keyof T)[];
prefix?: string; prefix?: string;
keepEntityVersioningDates?: boolean;
outputFieldsToOmit?: (keyof T)[];
entityClassName?: string;
} }
export class RestfulFactory<T> { export class RestfulFactory<T> {
readonly entityReturnMessageDto = ReturnMessageDto(this.entityClass); private getEntityClassName() {
readonly entityArrayReturnMessageDto = PaginatedReturnMessageDto( return this.options.entityClassName || this.entityClass.name;
this.entityClass, }
);
readonly importReturnMessageDto = ReturnMessageDto([
ImportEntryDto(this.entityClass),
]);
readonly fieldsToOmit = _.uniq([ readonly fieldsToOmit = _.uniq([
...(getSpecificFields(this.entityClass, 'notColumn') as (keyof T)[]), ...(getSpecificFields(this.entityClass, 'notColumn') as (keyof T)[]),
...(this.options.fieldsToOmit || []), ...(this.options.fieldsToOmit || []),
...getMetadataArgsStorage()
.relations.filter((r) => r.target === this.entityClass)
.map((r) => r.propertyName as keyof T),
]); ]);
private readonly basicDto = OmitType( private readonly basicInputDto = OmitType(
this.entityClass, this.entityClass,
this.fieldsToOmit, this.fieldsToOmit,
) as ClassType<T>; ) as ClassType<T>;
readonly createDto = RenameClass( readonly createDto = RenameClass(
OmitType( OmitType(
this.basicDto, this.basicInputDto,
getSpecificFields(this.entityClass, 'notWritable') as (keyof T)[], getSpecificFields(this.entityClass, 'notWritable') as (keyof T)[],
), ),
`Create${this.entityClass.name}Dto`, `Create${this.entityClass.name}Dto`,
...@@ -66,7 +74,7 @@ export class RestfulFactory<T> { ...@@ -66,7 +74,7 @@ export class RestfulFactory<T> {
readonly findAllDto = RenameClass( readonly findAllDto = RenameClass(
PartialType( PartialType(
OmitType( OmitType(
this.basicDto, this.basicInputDto,
getSpecificFields(this.entityClass, 'notQueryable') as (keyof T)[], getSpecificFields(this.entityClass, 'notQueryable') as (keyof T)[],
), ),
), ),
...@@ -81,6 +89,77 @@ export class RestfulFactory<T> { ...@@ -81,6 +89,77 @@ export class RestfulFactory<T> {
), ),
`Update${this.entityClass.name}Dto`, `Update${this.entityClass.name}Dto`,
) as ClassType<T>; ) as ClassType<T>;
private resolveEntityResultDto() {
const outputFieldsToOmit = new Set([
...(getNotInResultFields(
this.entityClass,
this.options.keepEntityVersioningDates,
) as (keyof T)[]),
...(this.options.outputFieldsToOmit || []),
]);
let resultDto = OmitType(this.entityClass, [...outputFieldsToOmit]);
const { relations } = getMetadataArgsStorage();
for (const relation of relations) {
if (
outputFieldsToOmit.has(relation.propertyName as keyof T) ||
relation.target !== this.entityClass
)
continue;
const relationClassFactory = relation.type;
// check if it's a callable function
if (typeof relationClassFactory !== 'function') continue;
const relationClass = (relationClassFactory as () => AnyClass)();
if (typeof relationClass !== 'function') continue;
const oldApiProperty =
Reflect.getMetadata(
DECORATORS.API_MODEL_PROPERTIES,
this.entityClass.prototype,
relation.propertyName,
) || {};
const replace = (useClass) => {
resultDto = InsertField(resultDto, {
[relation.propertyName]: {
required: false,
...oldApiProperty,
type: relation.relationType.endsWith('-many')
? [useClass]
: useClass,
},
});
};
const existing = this.__resolveVisited.get(relationClass);
if (existing) {
replace(existing);
} else {
if (!this.__resolveVisited.has(this.entityClass)) {
this.__resolveVisited.set(this.entityClass, Object);
}
const relationFactory = new RestfulFactory(
relationClass,
{},
this.__resolveVisited,
);
const relationResultDto = relationFactory.resolveEntityResultDto();
replace(relationResultDto);
this.__resolveVisited.set(relationClass, relationResultDto);
}
}
return RenameClass(
resultDto,
`${this.getEntityClassName()}ResultDto`,
) as ClassType<T>;
}
readonly entityResultDto = this.resolveEntityResultDto();
readonly entityReturnMessageDto = ReturnMessageDto(this.entityResultDto);
readonly entityArrayReturnMessageDto = PaginatedReturnMessageDto(
this.entityResultDto,
);
readonly importReturnMessageDto = ReturnMessageDto([
ImportEntryDto(this.entityResultDto),
]);
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
readonly idType: Function = Reflect.getMetadata( readonly idType: Function = Reflect.getMetadata(
'design:type', 'design:type',
...@@ -91,6 +170,7 @@ export class RestfulFactory<T> { ...@@ -91,6 +170,7 @@ export class RestfulFactory<T> {
constructor( constructor(
public readonly entityClass: ClassType<T>, public readonly entityClass: ClassType<T>,
private options: RestfulFactoryOptions<T> = {}, private options: RestfulFactoryOptions<T> = {},
private __resolveVisited = new Map<AnyClass, AnyClass>(),
) {} ) {}
private usePrefix( private usePrefix(
...@@ -117,14 +197,14 @@ export class RestfulFactory<T> { ...@@ -117,14 +197,14 @@ export class RestfulFactory<T> {
this.usePrefix(Post), this.usePrefix(Post),
HttpCode(200), HttpCode(200),
ApiOperation({ ApiOperation({
summary: `Create a new ${this.entityClass.name}`, summary: `Create a new ${this.getEntityClassName()}`,
...extras, ...extras,
}), }),
ApiBody({ type: this.createDto }), ApiBody({ type: this.createDto }),
ApiOkResponse({ type: this.entityReturnMessageDto }), ApiOkResponse({ type: this.entityReturnMessageDto }),
ApiBadRequestResponse({ ApiBadRequestResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
description: `The ${this.entityClass.name} is not valid`, description: `The ${this.getEntityClassName()} is not valid`,
}), }),
]); ]);
} }
...@@ -137,14 +217,14 @@ export class RestfulFactory<T> { ...@@ -137,14 +217,14 @@ export class RestfulFactory<T> {
return MergeMethodDecorators([ return MergeMethodDecorators([
this.usePrefix(Get, ':id'), this.usePrefix(Get, ':id'),
ApiOperation({ ApiOperation({
summary: `Find a ${this.entityClass.name} by id`, summary: `Find a ${this.getEntityClassName()} by id`,
...extras, ...extras,
}), }),
ApiParam({ name: 'id', type: this.idType, required: true }), ApiParam({ name: 'id', type: this.idType, required: true }),
ApiOkResponse({ type: this.entityReturnMessageDto }), ApiOkResponse({ type: this.entityReturnMessageDto }),
ApiNotFoundResponse({ ApiNotFoundResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
description: `The ${this.entityClass.name} with the given id was not found`, description: `The ${this.getEntityClassName()} with the given id was not found`,
}), }),
]); ]);
} }
...@@ -160,7 +240,10 @@ export class RestfulFactory<T> { ...@@ -160,7 +240,10 @@ export class RestfulFactory<T> {
findAll(extras: Partial<OperationObject> = {}): MethodDecorator { findAll(extras: Partial<OperationObject> = {}): MethodDecorator {
return MergeMethodDecorators([ return MergeMethodDecorators([
this.usePrefix(Get), this.usePrefix(Get),
ApiOperation({ summary: `Find all ${this.entityClass.name}`, ...extras }), ApiOperation({
summary: `Find all ${this.getEntityClassName()}`,
...extras,
}),
ApiOkResponse({ type: this.entityArrayReturnMessageDto }), ApiOkResponse({ type: this.entityArrayReturnMessageDto }),
]); ]);
} }
...@@ -174,7 +257,7 @@ export class RestfulFactory<T> { ...@@ -174,7 +257,7 @@ export class RestfulFactory<T> {
this.usePrefix(Patch, ':id'), this.usePrefix(Patch, ':id'),
HttpCode(200), HttpCode(200),
ApiOperation({ ApiOperation({
summary: `Update a ${this.entityClass.name} by id`, summary: `Update a ${this.getEntityClassName()} by id`,
...extras, ...extras,
}), }),
ApiParam({ name: 'id', type: this.idType, required: true }), ApiParam({ name: 'id', type: this.idType, required: true }),
...@@ -182,11 +265,11 @@ export class RestfulFactory<T> { ...@@ -182,11 +265,11 @@ export class RestfulFactory<T> {
ApiOkResponse({ type: BlankReturnMessageDto }), ApiOkResponse({ type: BlankReturnMessageDto }),
ApiNotFoundResponse({ ApiNotFoundResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
description: `The ${this.entityClass.name} with the given id was not found`, description: `The ${this.getEntityClassName()} with the given id was not found`,
}), }),
ApiBadRequestResponse({ ApiBadRequestResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
description: `The ${this.entityClass.name} is not valid`, description: `The ${this.getEntityClassName()} is not valid`,
}), }),
ApiInternalServerErrorResponse({ ApiInternalServerErrorResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
...@@ -204,14 +287,14 @@ export class RestfulFactory<T> { ...@@ -204,14 +287,14 @@ export class RestfulFactory<T> {
this.usePrefix(Delete, ':id'), this.usePrefix(Delete, ':id'),
HttpCode(200), HttpCode(200),
ApiOperation({ ApiOperation({
summary: `Delete a ${this.entityClass.name} by id`, summary: `Delete a ${this.getEntityClassName()} by id`,
...extras, ...extras,
}), }),
ApiParam({ name: 'id', type: this.idType, required: true }), ApiParam({ name: 'id', type: this.idType, required: true }),
ApiOkResponse({ type: BlankReturnMessageDto }), ApiOkResponse({ type: BlankReturnMessageDto }),
ApiNotFoundResponse({ ApiNotFoundResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
description: `The ${this.entityClass.name} with the given id was not found`, description: `The ${this.getEntityClassName()} with the given id was not found`,
}), }),
ApiInternalServerErrorResponse({ ApiInternalServerErrorResponse({
type: BlankReturnMessageDto, type: BlankReturnMessageDto,
...@@ -224,7 +307,7 @@ export class RestfulFactory<T> { ...@@ -224,7 +307,7 @@ export class RestfulFactory<T> {
return MergeMethodDecorators([ return MergeMethodDecorators([
Post('import'), Post('import'),
ApiOperation({ ApiOperation({
summary: `Import ${this.entityClass.name}`, summary: `Import ${this.getEntityClassName()}`,
...extras, ...extras,
}), }),
ApiBody({ type: ImportDataDto(this.createDto) }), ApiBody({ type: ImportDataDto(this.createDto) }),
......
...@@ -6,7 +6,7 @@ import { ...@@ -6,7 +6,7 @@ import {
ClassOrArray, ClassOrArray,
getClassFromClassOrArray, getClassFromClassOrArray,
InsertField, InsertField,
} from '../utility/insert-field'; } from 'nesties';
export class ImportEntryBaseDto { export class ImportEntryBaseDto {
@ApiProperty({ description: 'Import result', type: String }) @ApiProperty({ description: 'Import result', type: String })
......
import { ApiProperty, ApiPropertyOptions } from '@nestjs/swagger';
export type AnyClass = new (...args: any[]) => any;
export type ClassOrArray = AnyClass | [AnyClass];
export type ClassType<T> = new (...args: any[]) => T;
export type TypeFromClass<T> = T extends new (...args: any[]) => infer U
? U
: never;
export type ParamsFromClass<T> = T extends new (...args: infer U) => any
? U
: never;
export type ParseType<IC extends ClassOrArray> = IC extends [infer U]
? TypeFromClass<U>[]
: TypeFromClass<IC>;
export function getClassFromClassOrArray(o: ClassOrArray) {
return o instanceof Array ? o[0] : o;
}
export interface InsertOptions<C extends ClassOrArray = ClassOrArray> {
type: C;
options?: ApiPropertyOptions;
}
type TypeFromInsertOptions<O extends InsertOptions> = O extends InsertOptions<
infer C
>
?
| ParseType<C>
| (O extends { options: { required: true } } ? never : undefined)
: never;
type Merge<T, U> = {
[K in keyof T | keyof U]: K extends keyof T
? T[K]
: K extends keyof U
? U[K]
: never;
};
export function InsertField<
C extends AnyClass,
M extends Record<string, InsertOptions>,
>(
cl: C,
map: M,
newName?: string,
): new (...args: ParamsFromClass<C>) => Merge<
{
[F in keyof M]: TypeFromInsertOptions<M[F]>;
},
TypeFromClass<C>
> {
const extendedCl = class extends cl {};
for (const key in map) {
ApiProperty({
type: map[key].type,
...(map[key].options || {}),
})(extendedCl.prototype, key);
}
Object.defineProperty(extendedCl, 'name', {
value: newName || cl.name,
});
return extendedCl;
}
...@@ -6,6 +6,8 @@ interface SpecificFields { ...@@ -6,6 +6,8 @@ interface SpecificFields {
notWritable: boolean; notWritable: boolean;
notChangeable: boolean; notChangeable: boolean;
notQueryable: boolean; notQueryable: boolean;
notInResult: boolean;
entityVersioningDate: boolean;
} }
interface MetadataMap extends SpecificFields { interface MetadataMap extends SpecificFields {
...@@ -26,3 +28,17 @@ export function getSpecificFields(obj: any, type: keyof SpecificFields) { ...@@ -26,3 +28,17 @@ export function getSpecificFields(obj: any, type: keyof SpecificFields) {
.getArray(`${type}Fields`, obj) .getArray(`${type}Fields`, obj)
.filter((field) => reflector.get(type, obj, field)); .filter((field) => reflector.get(type, obj, field));
} }
export function getNotInResultFields(
obj: any,
keepEntityVersioningDates = false,
) {
const notInResultFields = getSpecificFields(obj, 'notInResult');
if (keepEntityVersioningDates) {
return notInResultFields;
}
return [
...notInResultFields,
...getSpecificFields(obj, 'entityVersioningDate'),
];
}
import { ClassOrArray } from './insert-field';
import { ValueTransformer } from 'typeorm'; import { ValueTransformer } from 'typeorm';
import { ClassOrArray } from 'nesties';
export class TypeTransformer implements ValueTransformer { export class TypeTransformer implements ValueTransformer {
constructor(private definition: ClassOrArray) {} constructor(private definition: ClassOrArray) {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment