|
|
|
|
@ -1,9 +1,33 @@
|
|
|
|
|
import { normalize, strings } from '@angular-devkit/core';
|
|
|
|
|
import { applyTemplates, branchAndMerge, chain, move, SchematicContext, SchematicsException, Tree, url } from '@angular-devkit/schematics';
|
|
|
|
|
import {
|
|
|
|
|
applyTemplates,
|
|
|
|
|
branchAndMerge,
|
|
|
|
|
chain,
|
|
|
|
|
move,
|
|
|
|
|
Rule,
|
|
|
|
|
SchematicContext,
|
|
|
|
|
SchematicsException,
|
|
|
|
|
Tree,
|
|
|
|
|
url,
|
|
|
|
|
} from '@angular-devkit/schematics';
|
|
|
|
|
import { Exception } from '../../enums';
|
|
|
|
|
import { applyWithOverwrite, buildDefaultPath, createApiDefinitionReader, createControllerToServiceMapper, createImportRefsToModelMapper, createImportRefToEnumMapper, getEnumNamesFromImports, interpolate, resolveProject, serializeParameters } from '../../utils';
|
|
|
|
|
import { ServiceGeneratorParams } from '../../models';
|
|
|
|
|
import {
|
|
|
|
|
applyWithOverwrite,
|
|
|
|
|
buildDefaultPath,
|
|
|
|
|
createApiDefinitionReader,
|
|
|
|
|
createControllerToServiceMapper,
|
|
|
|
|
createImportRefsToModelMapper,
|
|
|
|
|
createImportRefToEnumMapper,
|
|
|
|
|
EnumGeneratorParams,
|
|
|
|
|
getEnumNamesFromImports,
|
|
|
|
|
interpolate,
|
|
|
|
|
ModelGeneratorParams,
|
|
|
|
|
resolveProject,
|
|
|
|
|
serializeParameters,
|
|
|
|
|
} from '../../utils';
|
|
|
|
|
import * as cases from '../../utils/text';
|
|
|
|
|
import type { Schema as GenerateProxySchema } from './schema';
|
|
|
|
|
import { Schema as GenerateProxySchema } from './schema';
|
|
|
|
|
|
|
|
|
|
export default function(params: GenerateProxySchema) {
|
|
|
|
|
const solution = params.solution;
|
|
|
|
|
@ -13,79 +37,124 @@ export default function(params: GenerateProxySchema) {
|
|
|
|
|
async (tree: Tree, _context: SchematicContext) => {
|
|
|
|
|
const target = await resolveProject(tree, params.target!);
|
|
|
|
|
const targetPath = buildDefaultPath(target.definition);
|
|
|
|
|
const readApiDefinition = createApiDefinitionReader(`${targetPath}/shared/api-definition.json`);
|
|
|
|
|
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));
|
|
|
|
|
if (!definition)
|
|
|
|
|
throw new SchematicsException(interpolate(Exception.InvalidModule, moduleName));
|
|
|
|
|
|
|
|
|
|
const mapControllerToService = createControllerToServiceMapper(solution, types, definition.remoteServiceName);
|
|
|
|
|
const apiName = definition.remoteServiceName;
|
|
|
|
|
const controllers = Object.values(definition.controllers || {});
|
|
|
|
|
const serviceImports: Record<string, string[]> = {};
|
|
|
|
|
const generateServices = createServiceGenerator({
|
|
|
|
|
targetPath,
|
|
|
|
|
solution,
|
|
|
|
|
types,
|
|
|
|
|
apiName,
|
|
|
|
|
controllers,
|
|
|
|
|
serviceImports,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const createServiceFiles = chain(
|
|
|
|
|
controllers.map(controller => {
|
|
|
|
|
const service = mapControllerToService(controller);
|
|
|
|
|
service.imports.forEach(({refs, path}) => refs.forEach(ref => {
|
|
|
|
|
if (path === '@abp/ng.core') return;
|
|
|
|
|
if (!serviceImports[path]) return (serviceImports[path] = [ref]);
|
|
|
|
|
serviceImports[path] = [...new Set([...serviceImports[path], ref])];
|
|
|
|
|
}));
|
|
|
|
|
const modelImports: Record<string, string[]> = {};
|
|
|
|
|
const generateModels = createModelGenerator({
|
|
|
|
|
targetPath,
|
|
|
|
|
solution,
|
|
|
|
|
types,
|
|
|
|
|
serviceImports,
|
|
|
|
|
modelImports,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return applyWithOverwrite(url('./files-service'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
serializeParameters,
|
|
|
|
|
...service,
|
|
|
|
|
}),
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
const generateEnums = createEnumGenerator({
|
|
|
|
|
targetPath,
|
|
|
|
|
solution,
|
|
|
|
|
types,
|
|
|
|
|
serviceImports,
|
|
|
|
|
modelImports,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const mapImportRefsToModel = createImportRefsToModelMapper(solution, types);
|
|
|
|
|
const modelImports: Record<string, string[]> = {};
|
|
|
|
|
return branchAndMerge(chain([generateServices, generateModels, generateEnums]));
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const createModelFiles = chain(
|
|
|
|
|
Object.values(serviceImports).map(refs => {
|
|
|
|
|
const model = mapImportRefsToModel(refs);
|
|
|
|
|
model.imports.forEach(({refs, path}) => refs.forEach(ref => {
|
|
|
|
|
if (path === '@abp/ng.core') return;
|
|
|
|
|
if (!modelImports[path]) return (modelImports[path] = [ref]);
|
|
|
|
|
modelImports[path] = [...new Set([...modelImports[path], ref])];
|
|
|
|
|
}));
|
|
|
|
|
function createEnumGenerator(params: EnumGeneratorParams) {
|
|
|
|
|
const { targetPath, serviceImports, modelImports } = params;
|
|
|
|
|
const mapImportRefToEnum = createImportRefToEnumMapper(params);
|
|
|
|
|
const enumRefs = [
|
|
|
|
|
...new Set([
|
|
|
|
|
...getEnumNamesFromImports(serviceImports),
|
|
|
|
|
...getEnumNamesFromImports(modelImports),
|
|
|
|
|
]),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return applyWithOverwrite(url('./files-model'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
...model,
|
|
|
|
|
}),
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
return chain(
|
|
|
|
|
enumRefs.map(ref => {
|
|
|
|
|
return applyWithOverwrite(url('./files-enum'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
...mapImportRefToEnum(ref),
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapImportRefToEnum = createImportRefToEnumMapper(solution, types);
|
|
|
|
|
const enumRefs = [...new Set([
|
|
|
|
|
...getEnumNamesFromImports(serviceImports),
|
|
|
|
|
...getEnumNamesFromImports(modelImports),
|
|
|
|
|
])];
|
|
|
|
|
function createModelGenerator(params: ModelGeneratorParams) {
|
|
|
|
|
const { targetPath, serviceImports, modelImports } = params;
|
|
|
|
|
const mapImportRefsToModel = createImportRefsToModelMapper(params);
|
|
|
|
|
|
|
|
|
|
const createEnumFiles = chain(
|
|
|
|
|
enumRefs.map(ref => {
|
|
|
|
|
return applyWithOverwrite(url('./files-enum'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
...mapImportRefToEnum(ref),
|
|
|
|
|
}),
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
return chain(
|
|
|
|
|
Object.values(serviceImports).reduce((rules: Rule[], refs) => {
|
|
|
|
|
const model = mapImportRefsToModel(refs);
|
|
|
|
|
model.imports.forEach(({ refs, path }) =>
|
|
|
|
|
refs.forEach(ref => {
|
|
|
|
|
if (path === '@abp/ng.core') return;
|
|
|
|
|
if (!modelImports[path]) return (modelImports[path] = [ref]);
|
|
|
|
|
modelImports[path] = [...new Set([...modelImports[path], ref])];
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return branchAndMerge(chain([createServiceFiles, createModelFiles, createEnumFiles]));
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
const rule = applyWithOverwrite(url('./files-model'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
...model,
|
|
|
|
|
}),
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
rules.push(rule);
|
|
|
|
|
|
|
|
|
|
return rules;
|
|
|
|
|
}, []),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createServiceGenerator(params: ServiceGeneratorParams) {
|
|
|
|
|
const { targetPath, controllers, serviceImports } = params;
|
|
|
|
|
const mapControllerToService = createControllerToServiceMapper(params);
|
|
|
|
|
|
|
|
|
|
return chain(
|
|
|
|
|
controllers.map(controller => {
|
|
|
|
|
const service = mapControllerToService(controller);
|
|
|
|
|
service.imports.forEach(({ refs, path }) =>
|
|
|
|
|
refs.forEach(ref => {
|
|
|
|
|
if (path === '@abp/ng.core') return;
|
|
|
|
|
if (!serviceImports[path]) return (serviceImports[path] = [ref]);
|
|
|
|
|
serviceImports[path] = [...new Set([...serviceImports[path], ref])];
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return applyWithOverwrite(url('./files-service'), [
|
|
|
|
|
applyTemplates({
|
|
|
|
|
...cases,
|
|
|
|
|
serializeParameters,
|
|
|
|
|
...service,
|
|
|
|
|
}),
|
|
|
|
|
move(normalize(targetPath)),
|
|
|
|
|
]);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|