Browse Source

Merge pull request #17804 from abpframework/fix-audit-dto-generic-prop-order

Refactor(dtos.ts): improve generic type naming and ordering
pull/17978/head
Mahmut Gundogdu 3 years ago
committed by GitHub
parent
commit
ab03a57f34
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      npm/ng-packs/packages/core/src/lib/models/dtos.ts
  2. 129
      npm/ng-packs/packages/schematics/src/tests/parse-generic-type.spec.ts
  3. 35
      npm/ng-packs/packages/schematics/src/utils/model.ts
  4. 31
      npm/ng-packs/packages/schematics/src/utils/tree.ts

15
npm/ng-packs/packages/core/src/lib/models/dtos.ts

@ -114,14 +114,14 @@ export class CreationAuditedEntityDto<TPrimaryKey = string> extends EntityDto<TP
}
}
export class CreationAuditedEntityWithUserDto<
TUserDto,
export class CreationAuditedEntityWithUserDto<
TPrimaryKey = string,
TUserDto = any
> extends CreationAuditedEntityDto<TPrimaryKey> {
creator?: TUserDto;
constructor(
initialValues: Partial<CreationAuditedEntityWithUserDto<TUserDto, TPrimaryKey>> = {},
initialValues: Partial<CreationAuditedEntityWithUserDto<TPrimaryKey,TUserDto>> = {},
) {
super(initialValues);
}
@ -136,14 +136,15 @@ export class AuditedEntityDto<TPrimaryKey = string> extends CreationAuditedEntit
}
}
export class AuditedEntityWithUserDto<
TUserDto,
TPrimaryKey = string,
TUserDto = any,
> extends AuditedEntityDto<TPrimaryKey> {
creator?: TUserDto;
lastModifier?: TUserDto;
constructor(initialValues: Partial<AuditedEntityWithUserDto<TUserDto, TPrimaryKey>> = {}) {
constructor(initialValues: Partial<AuditedEntityWithUserDto< TPrimaryKey,TUserDto>> = {}) {
super(initialValues);
}
}
@ -159,14 +160,14 @@ export class FullAuditedEntityDto<TPrimaryKey = string> extends AuditedEntityDto
}
export class FullAuditedEntityWithUserDto<
TUserDto,
TPrimaryKey = string,
TUserDto = any
> extends FullAuditedEntityDto<TPrimaryKey> {
creator?: TUserDto;
lastModifier?: TUserDto;
deleter?: TUserDto;
constructor(initialValues: Partial<FullAuditedEntityWithUserDto<TUserDto, TPrimaryKey>> = {}) {
constructor(initialValues: Partial<FullAuditedEntityWithUserDto< TPrimaryKey,TUserDto>> = {}) {
super(initialValues);
}
}

129
npm/ng-packs/packages/schematics/src/tests/parse-generic-type.spec.ts

@ -0,0 +1,129 @@
import { parseBaseTypeWithGenericTypes } from '../utils/model';
import { parseGenerics } from '../utils/tree';
import {test} from '@jest/globals';
const cases: Array<[string, string[]]> = [
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto',
['Volo.Abp.Application.Dtos.AuditedEntityWithUserDto'],
],
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<Volo.Abp.Identity.IdentityUserDto>',
['Volo.Abp.Application.Dtos.AuditedEntityWithUserDto', 'Volo.Abp.Identity.IdentityUserDto'],
],
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<string,Volo.Abp.Identity.IdentityUserDto>',
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto',
'string',
'Volo.Abp.Identity.IdentityUserDto'
],
],
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<string,Volo.Abp.Identity.IdentityUserDto<number>>',
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto',
'string',
'Volo.Abp.Identity.IdentityUserDto',
'number',
],
],
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<string,Volo.Abp.Identity.IdentityUserDto<Volo.Abp.Core.Dummy<System.String>>>',
[
'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto',
'string',
'Volo.Abp.Identity.IdentityUserDto',
'Volo.Abp.Core.Dummy',
'System.String',
],
],
[
'AuditedEntityWithUserDto',
['AuditedEntityWithUserDto'],
],
];
test.each(cases)('should parse %s', (inputStr, expected) => {
const parsed = parseBaseTypeWithGenericTypes(inputStr);
expect(parsed).toEqual(expected);
})
describe('parseGenerics', () => {
it('should work with simple type', function() {
const node = parseGenerics('System.String');
expect(node.data).toEqual('System.String');
expect(node.index).toBe(0);
expect(node.parent).toBe(null);
});
it('should work with simple Array type', function() {
const node = parseGenerics('System.String[]');
expect(node.data).toEqual('System.String[]');
expect(node.index).toBe(0);
expect(node.parent).toBe(null);
});
it('should work with simple', function() {
const node = parseGenerics('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.data).toEqual('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.index).toBe(0);
expect(node.parent).toBe(null);
});
it('should work with `Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<Volo.Abp.Identity.IdentityUserDto>`', function() {
const type = 'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<Volo.Abp.Identity.IdentityUserDto>';
const node = parseGenerics(type);
expect(node.data).toEqual('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.children.length).toBe(1);
const child = node.children[0];
expect(node.children[0].data).toEqual('Volo.Abp.Identity.IdentityUserDto');
expect(child.parent).toBe(node);
});
it('should work with `Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<System.string,Volo.Abp.Identity.IdentityUserDto>`', function() {
const type = 'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<System.string,Volo.Abp.Identity.IdentityUserDto>';
const node = parseGenerics(type);
expect(node.data).toEqual('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.children.length).toBe(2);
expect(node.children[0].data).toEqual('System.string');
expect(node.children[0].index).toBe(0)
expect(node.children[1].data).toEqual('Volo.Abp.Identity.IdentityUserDto');
expect(node.children[1].index).toBe(1);
});
it('should Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<System.string,Volo.Abp.Identity.IdentityUserDto<System.Int>>', function() {
const type = 'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<System.string,Volo.Abp.Identity.IdentityUserDto<System.Int>>';
const node = parseGenerics(type);
expect(node.data).toEqual('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.children.length).toBe(2);
expect(node.children[0].data).toEqual('System.string');
expect((node.children[0]).parent).toBe(node);
expect(node.children[1].data).toEqual('Volo.Abp.Identity.IdentityUserDto');
expect(node.children[1].children.length).toBe(1);
expect(node.children[1].children[0].data).toEqual('System.Int');
expect(node.children[1].children[0].parent).toBe(node.children[1])
expect(node.children[1].children[0].index).toBe(0)
});
it('should Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<Volo.Abp.Identity.IdentityUserDto<System.Int>,System.string>', function() {
const type = 'Volo.Abp.Application.Dtos.AuditedEntityWithUserDto<Volo.Abp.Identity.IdentityUserDto<System.Int>,System.string>';
const node = parseGenerics(type);
expect(node.data).toEqual('Volo.Abp.Application.Dtos.AuditedEntityWithUserDto');
expect(node.children.length).toBe(2);
expect(node.children[0].data).toEqual('Volo.Abp.Identity.IdentityUserDto');
expect(node.children[0].children.length).toBe(1);
expect(node.children[0].children[0].data).toEqual('System.Int');
expect(node.children[1].data).toEqual('System.string');
});
});

35
npm/ng-packs/packages/schematics/src/utils/model.ts

@ -9,7 +9,7 @@ import {
import { parseNamespace } from './namespace';
import { relativePathToModel } from './path';
import { camel } from './text';
import { parseGenerics } from './tree';
import { parseGenerics, TypeNode } from './tree';
import {
createTypeParser,
createTypeSimplifier,
@ -71,12 +71,16 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) {
model.interfaces.forEach(_interface => {
const { baseType } = types[_interface.ref];
if (baseType && parseNamespace(solution, baseType) !== model.namespace)
toBeImported.push({
type: baseType.split('<')[0],
isEnum: false,
});
if (baseType && parseNamespace(solution, baseType) !== model.namespace){
const baseTypeWithGenericParams = parseBaseTypeWithGenericTypes(baseType);
baseTypeWithGenericParams.forEach(t => {
toBeImported.push({
type: t,
isEnum: false,
});
})
}
[..._interface.properties, ..._interface.generics].forEach(prop => {
prop.refs.forEach(ref => {
const propType = types[ref];
@ -172,7 +176,20 @@ export function createRefToImportReducerCreator(params: ModelGeneratorParams) {
}
function isOptionalProperty(prop: PropertyDef) {
return (
prop.typeSimple.endsWith('?') || (prop.typeSimple === 'string' && prop.isRequired === false)
);
return (prop.typeSimple.endsWith('?') || (prop.typeSimple === 'string' && !prop.isRequired));
}
export function parseBaseTypeWithGenericTypes(type: string): string[] {
const parsedTypeNode = parseGenerics(type);
const nodeToText = (node: TypeNode,acc:string[] = []): string[] => {
acc.push(node.data);
if(node.children && node.children.length > 0){
node.children.forEach(child => {
nodeToText(child,acc);
})
}
return acc;
}
return nodeToText(parsedTypeNode);
}

31
npm/ng-packs/packages/schematics/src/utils/tree.ts

@ -39,7 +39,7 @@ export class TypeNode {
}
}
export function parseGenerics(type: string, mapperFn?: TypeNodeMapperFn) {
export function parseGenericsOld(type: string, mapperFn?: TypeNodeMapperFn) {
const [rootType, ...types] = type.split('<');
const root = new TypeNode(rootType, null, mapperFn);
@ -68,4 +68,33 @@ export function parseGenerics(type: string, mapperFn?: TypeNodeMapperFn) {
return root;
}
export function parseGenerics(type: string, mapperFn?: TypeNodeMapperFn, parent?: TypeNode | null): TypeNode {
const regex = /(?<MainType>[\w.]+)<(?<GenericType>.*)>/;
const match = type.match(regex);
if (!match) {
return new TypeNode(type, null, mapperFn);
}
const mainType = match.groups?.MainType || '';
const genericType = match.groups?.GenericType || '';
const root = new TypeNode(mainType, parent ?? null, mapperFn);
if (genericType.includes(',')) {
const genericTypes = genericType.split(',');
genericTypes.forEach((genericType, index) => {
const child = parseGenerics(genericType, mapperFn, root);
child.index = index;
root.children.push(child);
child.parent = root;
});
} else {
const child = parseGenerics(genericType, mapperFn, root);
child.index = root.children.length;
root.children.push(child);
child.parent = root;
}
return root;
}
export type TypeNodeMapperFn = (node: TypeNode) => string;

Loading…
Cancel
Save