Browse Source

Merge pull request #5209 from abpframework/fix/5181

Resolved Dictionary Types and Improved Generics Parsing in Schematics
pull/5240/head
Bunyamin Coskuner 6 years ago
committed by GitHub
parent
commit
8984ffa1ec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      npm/ng-packs/packages/schematics/src/constants/volo.ts
  2. 15
      npm/ng-packs/packages/schematics/src/utils/model.ts
  3. 4
      npm/ng-packs/packages/schematics/src/utils/namespace.ts
  4. 21
      npm/ng-packs/packages/schematics/src/utils/type.ts

21
npm/ng-packs/packages/schematics/src/constants/volo.ts

@ -1 +1,22 @@
import { Interface, Property } from '../models';
export const VOLO_REGEX = /^Volo\.Abp\.(Application\.Dtos|ObjectExtending)/; export const VOLO_REGEX = /^Volo\.Abp\.(Application\.Dtos|ObjectExtending)/;
export const VOLO_NAME_VALUE = new Interface({
base: null,
identifier: 'NameValue<T = string>',
ref: 'Volo.Abp.NameValue',
namespace: 'Volo.Abp',
properties: [
new Property({
name: 'name',
type: 'string',
refs: ['System.String'],
}),
new Property({
name: 'value',
type: 'T',
refs: ['T'],
}),
],
});

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

@ -1,5 +1,5 @@
import { strings } from '@angular-devkit/core'; import { strings } from '@angular-devkit/core';
import { VOLO_REGEX } from '../constants'; import { VOLO_NAME_VALUE, VOLO_REGEX } from '../constants';
import { Interface, Model, Property, Type, TypeWithEnum } from '../models'; import { Interface, Model, Property, Type, TypeWithEnum } from '../models';
import { parseNamespace } from './namespace'; import { parseNamespace } from './namespace';
import { relativePathToModel } from './path'; import { relativePathToModel } from './path';
@ -40,8 +40,12 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) {
const index = models.findIndex(m => m.namespace === _interface.namespace); const index = models.findIndex(m => m.namespace === _interface.namespace);
if (index > -1) { if (index > -1) {
if (models[index].interfaces.some(i => i.identifier === _interface.identifier)) return; if (models[index].interfaces.some(i => i.identifier === _interface.identifier)) return;
if (_interface.ref.startsWith(VOLO_NAME_VALUE.ref)) return;
models[index].interfaces.push(_interface); models[index].interfaces.push(_interface);
} else { } else {
if (_interface.ref.startsWith(VOLO_NAME_VALUE.ref)) _interface = VOLO_NAME_VALUE;
const { namespace } = _interface; const { namespace } = _interface;
models.push( models.push(
@ -59,6 +63,7 @@ export function createImportRefsToModelReducer(params: ModelGeneratorParams) {
model.interfaces.forEach(_interface => { model.interfaces.forEach(_interface => {
const { baseType } = types[_interface.ref]; const { baseType } = types[_interface.ref];
if (baseType && parseNamespace(solution, baseType) !== model.namespace) if (baseType && parseNamespace(solution, baseType) !== model.namespace)
toBeImported.push({ toBeImported.push({
type: baseType.split('<')[0], type: baseType.split('<')[0],
@ -131,13 +136,7 @@ export function createImportRefToInterfaceReducerCreator(params: ModelGeneratorP
prop.refs.forEach(type => !types[type]?.isEnum && refs.push(type)); prop.refs.forEach(type => !types[type]?.isEnum && refs.push(type));
return refs; return refs;
}, []) }, [])
.concat( .concat(base ? parseGenerics(typeDef.baseType!).toGenerics() : [])
base
? parseGenerics(typeDef.baseType!)
.toGenerics()
.join('')
: [],
)
.reduce<Interface[]>(reduceRefsToInterfaces, interfaces); .reduce<Interface[]>(reduceRefsToInterfaces, interfaces);
} }
} }

4
npm/ng-packs/packages/schematics/src/utils/namespace.ts

@ -1,7 +1,7 @@
import { createTypeParser } from './type'; import { createTypeParser, removeGenerics } from './type';
export function parseNamespace(solution: string, type: string) { export function parseNamespace(solution: string, type: string) {
const parseType = createTypeParser(); const parseType = createTypeParser(removeGenerics);
let namespace = parseType(type)[0] let namespace = parseType(type)[0]
.split('.') .split('.')
.slice(0, -1) .slice(0, -1)

21
npm/ng-packs/packages/schematics/src/utils/type.ts

@ -15,13 +15,18 @@ export function createTypeSimplifier() {
); );
return type.split('.').pop()!; return type.split('.').pop()!;
}); });
return (type: string) => parseType(type).join(' | ');
return (type: string) => {
const parsed = parseType(type);
const last = parsed.pop()!;
return parsed.reduceRight((record, tKey) => `Record<${tKey}, ${record}>`, last);
};
} }
export function createTypeParser(replacerFn = (t: string) => t) { export function createTypeParser(replacerFn = (t: string) => t) {
const normalizeType = createTypeNormalizer(replacerFn); const normalizeType = createTypeNormalizer(replacerFn);
return (originalType: string) => flattenUnionTypes([], originalType).map(normalizeType); return (originalType: string) => flattenDictionaryTypes([], originalType).map(normalizeType);
} }
export function createTypeNormalizer(replacerFn = (t: string) => t) { export function createTypeNormalizer(replacerFn = (t: string) => t) {
@ -32,14 +37,10 @@ export function createTypeNormalizer(replacerFn = (t: string) => t) {
}; };
} }
export function flattenUnionTypes(types: string[], type: string) { export function flattenDictionaryTypes(types: string[], type: string) {
type type
.replace(/^{/, '') .replace(/[}{]/g, '')
.replace(/}$/, '')
.replace(/{/, '(')
.replace(/}/, ')')
.split(':') .split(':')
.filter(Boolean)
.forEach(t => types.push(t)); .forEach(t => types.push(t));
return types; return types;
@ -50,6 +51,10 @@ export function normalizeTypeAnnotations(type: string) {
return type.replace(/\?/g, ''); return type.replace(/\?/g, '');
} }
export function removeGenerics(type: string) {
return type.replace(/<.+>/g, '');
}
export function removeTypeModifiers(type: string) { export function removeTypeModifiers(type: string) {
return type.replace(/\[\]/g, ''); return type.replace(/\[\]/g, '');
} }

Loading…
Cancel
Save