Commit 4de16764 authored by nanahira's avatar nanahira

auto set omit fields by @NotColumn()

parent 72a68e24
......@@ -9,7 +9,8 @@
"version": "1.0.18",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.21"
"lodash": "^4.17.21",
"typed-reflector": "^1.0.11"
},
"devDependencies": {
"@nestjs/platform-express": "^9.0.3",
......@@ -5429,8 +5430,7 @@
"node_modules/reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
"peer": true
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
},
"node_modules/regexpp": {
"version": "3.2.0",
......@@ -6260,6 +6260,14 @@
"node": ">= 0.6"
}
},
"node_modules/typed-reflector": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.11.tgz",
"integrity": "sha512-OhryVYaR+tBEW9Yt2PsPqAniNfbVk1idKbnLxBCBPUSHVRm+Ajik/QxifoJUuGoaXAZDLW9JlJTO6ctXGZX9gQ==",
"dependencies": {
"reflect-metadata": "^0.1.13"
}
},
"node_modules/typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
......@@ -10710,8 +10718,7 @@
"reflect-metadata": {
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
"peer": true
"integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg=="
},
"regexpp": {
"version": "3.2.0",
......@@ -11329,6 +11336,14 @@
"mime-types": "~2.1.24"
}
},
"typed-reflector": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/typed-reflector/-/typed-reflector-1.0.11.tgz",
"integrity": "sha512-OhryVYaR+tBEW9Yt2PsPqAniNfbVk1idKbnLxBCBPUSHVRm+Ajik/QxifoJUuGoaXAZDLW9JlJTO6ctXGZX9gQ==",
"requires": {
"reflect-metadata": "^0.1.13"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
......
......@@ -67,6 +67,7 @@
"typeorm": "^0.3.10"
},
"dependencies": {
"lodash": "^4.17.21"
"lodash": "^4.17.21",
"typed-reflector": "^1.0.11"
}
}
......@@ -55,9 +55,3 @@ export class TimeBase
// eslint-disable-next-line @typescript-eslint/no-empty-function
async beforeUpdate(): Promise<void> {}
}
export const TimeBaseFields: (keyof TimeBase)[] = [
'createTime',
'updateTime',
'deleteTime',
];
......@@ -21,6 +21,7 @@ import { ColumnWithWidthOptions } from 'typeorm/decorator/options/ColumnWithWidt
import { ColumnNumericOptions } from 'typeorm/decorator/options/ColumnNumericOptions';
import { Exclude } from 'class-transformer';
import { BigintTransformer } from '../utility/bigint';
import { Metadata } from '../utility/metadata';
export interface OpenAPIOptions<T> {
description?: string;
......@@ -171,4 +172,8 @@ export const BoolColumn = (
export const NotColumn = (
options: OpenAPIOptions<any> = {},
): PropertyDecorator =>
MergePropertyDecorators([Exclude(), swaggerDecorator(options)]);
MergePropertyDecorators([
Exclude(),
swaggerDecorator(options),
Metadata.set('notColumn', true, 'notColumnFields'),
]);
......@@ -15,7 +15,6 @@ import {
} from '../dto';
import { MergeMethodDecorators } from './merge';
import { ClassType } from '../utility/insert-field';
import { TimeBase, TimeBaseFields } from '../bases';
import {
ApiBody,
ApiCreatedResponse,
......@@ -28,36 +27,39 @@ import {
} from '@nestjs/swagger';
import { CreatePipe, GetPipe, UpdatePipe } from './pipes';
import { OperationObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
import _ from 'lodash';
import { reflector } from '../utility/metadata';
export interface RestfulFactoryOptions<T> {
fieldsToOmit?: (keyof T)[];
}
export class RestfulFactory<T> {
readonly createDto: ClassType<Omit<T, keyof T>>;
readonly updateDto: ClassType<Partial<Omit<T, keyof T>>>;
readonly entityReturnMessageDto = ReturnMessageDto(this.entityClass);
readonly entityArrayReturnMessageDto = PaginatedReturnMessageDto(
this.entityClass,
);
readonly fieldsToOmit: (keyof T)[] = _.uniq([
...(reflector
.getArray('notColumnFields', this.entityClass)
.filter((field) =>
reflector.get('notColumn', this.entityClass, field),
) as (keyof T)[]),
...(this.options.fieldsToOmit || []),
]);
readonly createDto = OmitType(this.entityClass, this.fieldsToOmit);
readonly updateDto = PartialType(this.createDto);
// eslint-disable-next-line @typescript-eslint/ban-types
readonly idType: Function;
readonly idType: Function = Reflect.getMetadata(
'design:type',
this.entityClass.prototype,
'id',
);
constructor(
public readonly entityClass: ClassType<T>,
private options: RestfulFactoryOptions<T> = {},
) {
this.createDto = OmitType(this.entityClass, [
...(TimeBaseFields as (keyof T)[]),
...(options.fieldsToOmit || []),
]);
this.updateDto = PartialType(this.createDto);
this.idType = Reflect.getMetadata(
'design:type',
this.entityClass.prototype,
'id',
);
}
) {}
create(extras: Partial<OperationObject> = {}): MethodDecorator {
return MergeMethodDecorators([
......
import { MetadataSetter, Reflector } from "typed-reflector";
export interface MetadataArrayMap {
notColumnFields: string;
}
export interface MetadataMap {
notColumn: boolean;
}
export const Metadata = new MetadataSetter<MetadataMap, MetadataArrayMap>();
export const reflector = new Reflector<MetadataMap, MetadataArrayMap>();
import { plainToInstance } from 'class-transformer';
import { validateSync } from 'class-validator';
import { RestfulFactory } from '../src/decorators';
import { Gender, User, User2 } from './utility/user';
describe('entity', () => {
......@@ -40,4 +41,9 @@ describe('entity', () => {
),
).not.toEqual([]);
});
it('should set omit fields', () => {
const factory = new RestfulFactory(User);
expect(factory.fieldsToOmit.includes('createTime')).toBe(true);
});
});
......@@ -48,6 +48,12 @@ class UserController {
}
}
describe('app', () => {
it('should pass', () => {
expect(true).toBe(true);
});
});
/*
describe('app', () => {
let app: NestExpressApplication;
......
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