Browse Source

refactor: make schematics service imports reducer reusable

pull/5137/head
Arman Ozak 6 years ago
parent
commit
460f21717f
  1. 4
      npm/ng-packs/packages/schematics/src/utils/path.ts
  2. 74
      npm/ng-packs/packages/schematics/src/utils/service.ts
  3. 50
      npm/ng-packs/packages/schematics/src/utils/type.ts

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

@ -1,7 +1,7 @@
import { dir } from './text';
export function relativePathFromServiceToModel(serviceNamespace: string, modelNamespace: string) {
const repeats = serviceNamespace ? serviceNamespace.split('.').length : 0;
export function relativePathToModel(namespace: string, modelNamespace: string) {
const repeats = namespace ? namespace.split('.').length : 0;
const path = '..' + '/..'.repeat(repeats) + '/models/' + dir(modelNamespace);
return removeTrailingSlash(path);
}

74
npm/ng-packs/packages/schematics/src/utils/service.ts

@ -1,9 +1,7 @@
import { eImportKeyword } from '../enums';
import { Action, Body, Controller, Import, Method, Property, Service, Signature } from '../models';
import { parseNamespace } from './namespace';
import { relativePathFromServiceToModel } from './path';
import { parseGenerics } from './tree';
import { createTypeSimplifier } from './type';
import { createTypeAdapter, createTypesToImportsReducer } from './type';
export function serializeParameters(parameters: Property[]) {
return parameters.map(p => p.name + p.optional + ': ' + p.type + p.default, '').join(', ');
@ -40,48 +38,6 @@ function sortMethods(methods: Method[]) {
methods.sort((a, b) => (a.signature.name > b.signature.name ? 1 : -1));
}
export function createActionToImportsReducer(solution: string, namespace: string) {
const mapTypeToImport = createTypeToImportMapper(solution, namespace);
return (imports: Import[], action: Action) => {
const types = getTypesFromAction(action);
types.forEach(type => {
const def = mapTypeToImport(type);
if (!def) return;
const existingImport = imports.find(
({ keyword, path }) => keyword === def.keyword && path === def.path,
);
if (!existingImport) return imports.push(def);
existingImport.refs = [...new Set([...existingImport.refs, ...def.refs])];
existingImport.specifiers = [
...new Set([...existingImport.specifiers, ...def.specifiers]),
].sort();
});
return imports;
};
}
export function createTypeToImportMapper(solution: string, namespace: string) {
const adaptType = createTypeAdapter(solution);
return (type: string) => {
if (type.startsWith('System')) return;
const modelNamespace = parseNamespace(solution, type);
const path = type.startsWith('Volo.Abp.Application.Dtos')
? '@abp/ng.core'
: relativePathFromServiceToModel(namespace, modelNamespace);
const refs = [type];
const specifiers = [adaptType(type.split('<')[0])];
return new Import({ keyword: eImportKeyword.Type, path, refs, specifiers });
};
}
export function createActionToMethodMapper(solution: string) {
const mapActionToBody = createActionToBodyMapper(solution);
const mapActionToSignature = createActionToSignatureMapper(solution);
@ -128,22 +84,18 @@ function getMethodNameFromAction(action: Action): string {
return action.uniqueName.split('Async')[0];
}
function createTypeAdapter(solution: string) {
const simplifyType = createTypeSimplifier(solution);
return (typeSimple: string) => {
if (typeSimple === 'System.Void') return 'void';
return parseGenerics(typeSimple, node => simplifyType(node.data)).toString();
};
}
function createActionToImportsReducer(solution: string, namespace: string) {
const mapTypesToImports = createTypesToImportsReducer(solution, namespace);
function getTypesFromAction({ parametersOnMethod, returnValue }: Action) {
return [returnValue, ...parametersOnMethod].reduce((types: string[], { type }) => {
parseGenerics(type)
.toGenerics()
.forEach(t => types.push(t));
return (imports: Import[], { parametersOnMethod, returnValue }: Action) =>
mapTypesToImports(
imports,
[returnValue, ...parametersOnMethod].reduce((types: string[], { type }) => {
parseGenerics(type)
.toGenerics()
.forEach(t => types.push(t));
return types;
}, []);
return types;
}, []),
);
}

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

@ -1,5 +1,10 @@
import { strings } from '@angular-devkit/core';
import { SYSTEM_TYPES } from '../constants';
import { eImportKeyword } from '../enums';
import { Import } from '../models';
import { parseNamespace } from './namespace';
import { relativePathToModel } from './path';
import { parseGenerics } from './tree';
export function createTypeSimplifier(solution: string) {
const optionalRegex = /\?/g;
@ -19,3 +24,48 @@ export function createTypeSimplifier(solution: string) {
return type;
};
}
export function createTypesToImportsReducer(solution: string, namespace: string) {
const mapTypeToImport = createTypeToImportMapper(solution, namespace);
return (imports: Import[], types: string[]) => {
types.forEach(type => {
const def = mapTypeToImport(type);
if (!def) return;
const existingImport = imports.find(
({ keyword, path }) => keyword === def.keyword && path === def.path,
);
if (!existingImport) return imports.push(def);
existingImport.refs = [...new Set([...existingImport.refs, ...def.refs])];
existingImport.specifiers = [
...new Set([...existingImport.specifiers, ...def.specifiers]),
].sort();
});
return imports;
};
}
export function createTypeToImportMapper(solution: string, namespace: string) {
const adaptType = createTypeAdapter(solution);
return (type: string) => {
if (type.startsWith('System')) return;
const modelNamespace = parseNamespace(solution, type);
const path = type.startsWith('Volo.Abp.Application.Dtos')
? '@abp/ng.core'
: relativePathToModel(namespace, modelNamespace);
const refs = [type];
const specifiers = [adaptType(type.split('<')[0])];
return new Import({ keyword: eImportKeyword.Type, path, refs, specifiers });
};
}
export function createTypeAdapter(solution: string) {
const simplifyType = createTypeSimplifier(solution);
return (type: string) => parseGenerics(type, node => simplifyType(node.data)).toString();
}

Loading…
Cancel
Save