From 460f21717fc7edb84eebca80bbbf304f7ba605e1 Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Wed, 19 Aug 2020 12:50:58 +0300 Subject: [PATCH] refactor: make schematics service imports reducer reusable --- .../packages/schematics/src/utils/path.ts | 4 +- .../packages/schematics/src/utils/service.ts | 74 ++++--------------- .../packages/schematics/src/utils/type.ts | 50 +++++++++++++ 3 files changed, 65 insertions(+), 63 deletions(-) diff --git a/npm/ng-packs/packages/schematics/src/utils/path.ts b/npm/ng-packs/packages/schematics/src/utils/path.ts index a48534c92c..5b84ea168b 100644 --- a/npm/ng-packs/packages/schematics/src/utils/path.ts +++ b/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); } diff --git a/npm/ng-packs/packages/schematics/src/utils/service.ts b/npm/ng-packs/packages/schematics/src/utils/service.ts index bec531de1a..83e8af2235 100644 --- a/npm/ng-packs/packages/schematics/src/utils/service.ts +++ b/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; + }, []), + ); } diff --git a/npm/ng-packs/packages/schematics/src/utils/type.ts b/npm/ng-packs/packages/schematics/src/utils/type.ts index 5af905cabb..18726d0334 100644 --- a/npm/ng-packs/packages/schematics/src/utils/type.ts +++ b/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(); +}