feat: handle enum imports in schematics

pull/5137/head
Arman Ozak 5 years ago
parent 7d272958ba
commit 198ea436af

@ -15,10 +15,11 @@ export default function(params: GenerateProxySchema) {
const targetPath = buildDefaultPath(target.definition);
const readApiDefinition = createApiDefinitionReader(`${targetPath}/shared/api-definition.json`);
const data = readApiDefinition(tree);
const types = data.types;
const definition = data.modules[moduleName];
if (!definition) throw new SchematicsException(interpolate(Exception.InvalidModule, moduleName));
const mapControllerToService = createControllerToServiceMapper(solution, definition.remoteServiceName);
const mapControllerToService = createControllerToServiceMapper(solution, types, definition.remoteServiceName);
const controllers = Object.values(definition.controllers || {});
const serviceImports: Record<string, string[]> = {};
@ -43,7 +44,7 @@ export default function(params: GenerateProxySchema) {
),
);
const mapImportRefsToModel = createImportRefsToModelMapper(solution, data.types);
const mapImportRefsToModel = createImportRefsToModelMapper(solution, types);
const createModelFiles = chain(
Object.values(serviceImports).map(refs => {

@ -73,3 +73,8 @@ export interface TypeDef {
type: string;
typeSimple: string;
}
export interface TypeWithEnum {
isEnum: boolean;
type: string;
}

@ -1,5 +1,5 @@
import { strings } from '@angular-devkit/core';
import { Import, Interface, Model, Property, Type } from '../models';
import { Import, Interface, Model, Property, Type, TypeWithEnum } from '../models';
import { sortImports } from './import';
import { parseNamespace } from './namespace';
import { relativePathToModel } from './path';
@ -73,12 +73,12 @@ export function createImportRefToImportReducerCreator(
return (imports: Import[], importRef: string) =>
reduceTypesToImport(
imports,
mergeBaseTypeWithProperties(types[importRef]).reduce((typeNames: string[], type) => {
parseGenerics(type)
mergeBaseTypeWithProperties(types[importRef]).reduce((acc: TypeWithEnum[], typeName) => {
parseGenerics(typeName)
.toGenerics()
.forEach(t => typeNames.push(t));
.forEach(type => acc.push({ type, isEnum: types[type]?.isEnum }));
return typeNames;
return acc;
}, []),
);
};

@ -1,4 +1,10 @@
import { dir } from './text';
import { dir, kebab } from './text';
export function relativePathToEnum(namespace: string, enumNamespace: string, enumName: string) {
const repeats = namespace ? namespace.split('.').length : 0;
const path = '..' + '/..'.repeat(repeats) + '/enums/' + dir(enumNamespace) + kebab(enumName);
return removeDoubleSlash(path);
}
export function relativePathToModel(namespace: string, modelNamespace: string) {
const repeats = namespace ? namespace.split('.').length : 0;
@ -6,6 +12,10 @@ export function relativePathToModel(namespace: string, modelNamespace: string) {
return removeTrailingSlash(path);
}
function removeDoubleSlash(path: string) {
return path.replace(/\/{2,}/g, '');
}
function removeTrailingSlash(path: string) {
return path.replace(/\/+$/, '');
}

@ -1,4 +1,15 @@
import { Action, Body, Controller, Import, Method, Property, Service, Signature } from '../models';
import {
Action,
Body,
Controller,
Import,
Method,
Property,
Service,
Signature,
Type,
TypeWithEnum,
} from '../models';
import { sortImports } from './import';
import { parseNamespace } from './namespace';
import { parseGenerics } from './tree';
@ -8,14 +19,18 @@ export function serializeParameters(parameters: Property[]) {
return parameters.map(p => p.name + p.optional + ': ' + p.type + p.default, '').join(', ');
}
export function createControllerToServiceMapper(solution: string, apiName: string) {
export function createControllerToServiceMapper(
solution: string,
types: Record<string, Type>,
apiName: string,
) {
const mapActionToMethod = createActionToMethodMapper(solution);
return (controller: Controller) => {
const name = controller.controllerName;
const namespace = parseNamespace(solution, controller.type);
const actions = Object.values(controller.actions);
const imports = actions.reduce(createActionToImportsReducer(solution, namespace), []);
const imports = actions.reduce(createActionToImportsReducer(solution, types, namespace), []);
imports.push(new Import({ path: '@abp/ng.core', specifiers: ['RestService'] }));
imports.push(new Import({ path: '@angular/core', specifiers: ['Injectable'] }));
sortImports(imports);
@ -75,18 +90,22 @@ function getMethodNameFromAction(action: Action): string {
return action.uniqueName.split('Async')[0];
}
function createActionToImportsReducer(solution: string, namespace: string) {
function createActionToImportsReducer(
solution: string,
types: Record<string, Type>,
namespace: string,
) {
const mapTypesToImports = createTypesToImportsReducer(solution, namespace);
return (imports: Import[], { parametersOnMethod, returnValue }: Action) =>
mapTypesToImports(
imports,
[returnValue, ...parametersOnMethod].reduce((types: string[], { type }) => {
parseGenerics(type)
[returnValue, ...parametersOnMethod].reduce((acc: TypeWithEnum[], param) => {
parseGenerics(param.type)
.toGenerics()
.forEach(t => types.push(t));
.forEach(type => acc.push({ type, isEnum: types[type]?.isEnum }));
return types;
return acc;
}, []),
);
}

@ -1,9 +1,9 @@
import { strings } from '@angular-devkit/core';
import { SYSTEM_TYPES } from '../constants';
import { eImportKeyword } from '../enums';
import { Import } from '../models';
import { Import, TypeWithEnum } from '../models';
import { parseNamespace } from './namespace';
import { relativePathToModel } from './path';
import { relativePathToEnum, relativePathToModel } from './path';
import { parseGenerics } from './tree';
export function createTypeSimplifier(solution: string) {
@ -53,9 +53,9 @@ export function removeTypeModifiers(type: string) {
export function createTypesToImportsReducer(solution: string, namespace: string) {
const mapTypeToImport = createTypeToImportMapper(solution, namespace);
return (imports: Import[], types: string[]) => {
types.forEach(type => {
const newImport = mapTypeToImport(type);
return (imports: Import[], types: TypeWithEnum[]) => {
types.forEach(({ type, isEnum }) => {
const newImport = mapTypeToImport(type, isEnum);
if (!newImport) return;
const existingImport = imports.find(
@ -76,15 +76,17 @@ export function createTypesToImportsReducer(solution: string, namespace: string)
export function createTypeToImportMapper(solution: string, namespace: string) {
const adaptType = createTypeAdapter(solution);
return (type: string) => {
return (type: string, isEnum: boolean) => {
if (!type || type.startsWith('System')) return;
const modelNamespace = parseNamespace(solution, type);
const refs = [type];
const specifiers = [adaptType(type.split('<')[0])];
const path = type.startsWith('Volo.Abp.Application.Dtos')
? '@abp/ng.core'
: isEnum
? relativePathToEnum(namespace, modelNamespace, specifiers[0])
: relativePathToModel(namespace, modelNamespace);
const refs = [type];
const specifiers = [adaptType(type.split('<')[0])];
return new Import({ keyword: eImportKeyword.Type, path, refs, specifiers });
};

Loading…
Cancel
Save