Commit 6520b26f authored by nanahira's avatar nanahira

better typing for relation

parent 70c8e590
......@@ -23,14 +23,15 @@ import { ConsoleLogger } from '@nestjs/common';
import { camelCase } from 'typeorm/util/StringUtils';
import _ from 'lodash';
import { ClassType } from './utility/insert-field';
import { RecursiveKeyOf } from './utility/recursive-key-of';
export type EntityId<T extends { id: any }> = T['id'];
export interface RelationDef {
name: string;
export interface RelationDef<T> {
name: T;
inner?: boolean;
}
export const Inner = (name: string): RelationDef => {
export const Inner = <T>(name: T): RelationDef<T> => {
return { name, inner: true };
};
......@@ -39,7 +40,7 @@ export type ValidCrudEntity<T> = Record<string, any> & {
} & Partial<QueryWise<T> & DeletionWise & EntityHooks & PageSettingsFactory>;
export interface CrudOptions<T extends ValidCrudEntity<T>> {
relations?: (string | RelationDef)[];
relations?: (RecursiveKeyOf<T> | RelationDef<RecursiveKeyOf<T>>)[];
extraGetQuery?: (qb: SelectQueryBuilder<T>) => void;
hardDelete?: boolean;
}
......@@ -52,7 +53,10 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
readonly entityPaginatedReturnMessageDto = PaginatedReturnMessageDto(
this.entityClass,
);
readonly entityRelations: (string | RelationDef)[];
readonly entityRelations: (
| RecursiveKeyOf<T>
| RelationDef<RecursiveKeyOf<T>>
)[];
readonly extraGetQuery: (qb: SelectQueryBuilder<T>) => void;
readonly log = new ConsoleLogger(`${this.entityClass.name}Service`);
......@@ -191,7 +195,10 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
return camelCase(this.entityName);
}
_applyRelationToQuery(qb: SelectQueryBuilder<T>, relation: RelationDef) {
_applyRelationToQuery(
qb: SelectQueryBuilder<T>,
relation: RelationDef<RecursiveKeyOf<T>>,
) {
const { name } = relation;
const relationUnit = name.split('.');
const base =
......@@ -209,7 +216,7 @@ export class CrudBase<T extends ValidCrudEntity<T>> {
_applyRelationsToQuery(qb: SelectQueryBuilder<T>) {
for (const relation of this.entityRelations) {
if (typeof relation === 'string') {
this._applyRelationToQuery(qb, { name: relation });
this._applyRelationToQuery(qb, { name: relation as any });
} else {
this._applyRelationToQuery(qb, relation);
}
......
/* eslint-disable @typescript-eslint/ban-types */
export type RecursiveKeyOf<TObj extends Record<string, any>> = {
[TKey in keyof TObj & string]: RecursiveKeyOfHandleValue<
TObj[TKey],
`${TKey}`
>;
}[keyof TObj & string];
type RecursiveKeyOfInner<TObj extends Record<string, any>> = {
[TKey in keyof TObj & string]: RecursiveKeyOfHandleValue<
TObj[TKey],
`.${TKey}`
>;
}[keyof TObj & string];
type RecursiveKeyOfHandleValue<TValue, Text extends string> = TValue extends
| Function
| ((...args: any[]) => any)
| (new (...args: any[]) => any)
? never
: TValue extends Date | string | number | boolean
? never // Text
: TValue extends (infer TItem)[]
? Text | `${Text}${RecursiveKeyOfInner<TItem>}`
: TValue extends Record<string, any>
? Text | `${Text}${RecursiveKeyOfInner<TValue>}`
: never; // Text;
import { NestExpressApplication } from '@nestjs/platform-express';
import { Controller, Injectable } from '@nestjs/common';
import { CrudService } from '../src/crud-base';
import { Gender, User } from './utility/user';
import { User } from './utility/user';
import { RestfulFactory } from '../src/decorators';
import { Test } from '@nestjs/testing';
import { InjectDataSource, TypeOrmModule } from '@nestjs/typeorm';
import { InjectDataSource } from '@nestjs/typeorm';
import { DataSource } from 'typeorm';
import request from 'supertest';
@Injectable()
class UserService extends CrudService(User) {
......
import { Entity, Index } from 'typeorm';
import { DateColumn, EnumColumn, IntColumn, NotChangeable, NotColumn, NotWritable, StringColumn } from '../../src/decorators';
import {
DateColumn,
EnumColumn,
IntColumn,
NotChangeable,
NotColumn,
NotWritable,
StringColumn,
} from '../../src/decorators';
import { IdBase, StringIdBase } from '../../src/bases';
export enum Gender {
......@@ -7,6 +15,11 @@ export enum Gender {
M = 'M',
}
export class Book {
id: number;
name: string;
}
@Entity()
export class User extends IdBase() {
@Index()
......@@ -28,6 +41,8 @@ export class User extends IdBase() {
@NotColumn()
birthday: Date;
books: Book[];
}
@Entity()
......
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