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'; import { dir } from './text';
export function relativePathFromServiceToModel(serviceNamespace: string, modelNamespace: string) { export function relativePathToModel(namespace: string, modelNamespace: string) {
const repeats = serviceNamespace ? serviceNamespace.split('.').length : 0; const repeats = namespace ? namespace.split('.').length : 0;
const path = '..' + '/..'.repeat(repeats) + '/models/' + dir(modelNamespace); const path = '..' + '/..'.repeat(repeats) + '/models/' + dir(modelNamespace);
return removeTrailingSlash(path); 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 { Action, Body, Controller, Import, Method, Property, Service, Signature } from '../models';
import { parseNamespace } from './namespace'; import { parseNamespace } from './namespace';
import { relativePathFromServiceToModel } from './path';
import { parseGenerics } from './tree'; import { parseGenerics } from './tree';
import { createTypeSimplifier } from './type'; import { createTypeAdapter, createTypesToImportsReducer } from './type';
export function serializeParameters(parameters: Property[]) { export function serializeParameters(parameters: Property[]) {
return parameters.map(p => p.name + p.optional + ': ' + p.type + p.default, '').join(', '); 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)); 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) { export function createActionToMethodMapper(solution: string) {
const mapActionToBody = createActionToBodyMapper(solution); const mapActionToBody = createActionToBodyMapper(solution);
const mapActionToSignature = createActionToSignatureMapper(solution); const mapActionToSignature = createActionToSignatureMapper(solution);
@ -128,22 +84,18 @@ function getMethodNameFromAction(action: Action): string {
return action.uniqueName.split('Async')[0]; return action.uniqueName.split('Async')[0];
} }
function createTypeAdapter(solution: string) { function createActionToImportsReducer(solution: string, namespace: string) {
const simplifyType = createTypeSimplifier(solution); const mapTypesToImports = createTypesToImportsReducer(solution, namespace);
return (typeSimple: string) => {
if (typeSimple === 'System.Void') return 'void';
return parseGenerics(typeSimple, node => simplifyType(node.data)).toString();
};
}
function getTypesFromAction({ parametersOnMethod, returnValue }: Action) { return (imports: Import[], { parametersOnMethod, returnValue }: Action) =>
return [returnValue, ...parametersOnMethod].reduce((types: string[], { type }) => { mapTypesToImports(
parseGenerics(type) imports,
.toGenerics() [returnValue, ...parametersOnMethod].reduce((types: string[], { type }) => {
.forEach(t => types.push(t)); 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 { strings } from '@angular-devkit/core';
import { SYSTEM_TYPES } from '../constants'; 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) { export function createTypeSimplifier(solution: string) {
const optionalRegex = /\?/g; const optionalRegex = /\?/g;
@ -19,3 +24,48 @@ export function createTypeSimplifier(solution: string) {
return type; 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