Commit 4de16764 authored by nanahira's avatar nanahira

auto set omit fields by @NotColumn()

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