From a8c1a49148759444bb7c92cdcc920b2e0b608c1a Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 20 Aug 2020 11:35:11 +0300 Subject: [PATCH] feat: create enums and enum options with schematics --- .../__name@kebab__.ts.template | 8 +++++ .../schematics/src/commands/api/index.ts | 32 +++++++++++++++++-- .../schematics/src/enums/exception.ts | 1 + .../packages/schematics/src/utils/enum.ts | 31 ++++++++++++++++++ .../packages/schematics/src/utils/index.ts | 1 + 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 npm/ng-packs/packages/schematics/src/utils/enum.ts diff --git a/npm/ng-packs/packages/schematics/src/commands/api/files-enum/shared/enums/__namespace@dir__/__name@kebab__.ts.template b/npm/ng-packs/packages/schematics/src/commands/api/files-enum/shared/enums/__namespace@dir__/__name@kebab__.ts.template index e69de29bb2..795ec2bbf6 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/files-enum/shared/enums/__namespace@dir__/__name@kebab__.ts.template +++ b/npm/ng-packs/packages/schematics/src/commands/api/files-enum/shared/enums/__namespace@dir__/__name@kebab__.ts.template @@ -0,0 +1,8 @@ +import { mapEnumToOptions } from '@abp/ng.core'; + +export enum <%= name %> {<% + for (let member of members) { %> + <%= member.key %> = <%= member.value %>,<% } %> +} + +export const <%= camel(name) %>Options = mapEnumToOptions(<%= name %>); diff --git a/npm/ng-packs/packages/schematics/src/commands/api/index.ts b/npm/ng-packs/packages/schematics/src/commands/api/index.ts index f18ee5985d..d6c01373e0 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/api/index.ts @@ -1,7 +1,7 @@ import { normalize, strings } from '@angular-devkit/core'; import { applyTemplates, branchAndMerge, chain, move, SchematicContext, SchematicsException, Tree, url } from '@angular-devkit/schematics'; import { Exception } from '../../enums'; -import { applyWithOverwrite, buildDefaultPath, createApiDefinitionReader, createControllerToServiceMapper, createImportRefsToModelMapper, interpolate, resolveProject, serializeParameters } from '../../utils'; +import { applyWithOverwrite, buildDefaultPath, createApiDefinitionReader, createControllerToServiceMapper, createImportRefsToModelMapper, createImportRefToEnumMapper, getEnumNamesFromImports, interpolate, resolveProject, serializeParameters } from '../../utils'; import * as cases from '../../utils/text'; import type { Schema as GenerateProxySchema } from './schema'; @@ -45,20 +45,46 @@ export default function(params: GenerateProxySchema) { ); const mapImportRefsToModel = createImportRefsToModelMapper(solution, types); + const modelImports: Record = {}; 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])]; + })); + return applyWithOverwrite(url('./files-model'), [ applyTemplates({ ...cases, - ...mapImportRefsToModel(refs), + ...model, + }), + move(normalize(targetPath)), + ]); + }), + ); + + const mapImportRefToEnum = createImportRefToEnumMapper(solution, types); + const enumRefs = [...new Set([ + ...getEnumNamesFromImports(serviceImports), + ...getEnumNamesFromImports(modelImports), + ])]; + + const createEnumFiles = chain( + enumRefs.map(ref => { + return applyWithOverwrite(url('./files-enum'), [ + applyTemplates({ + ...cases, + ...mapImportRefToEnum(ref), }), move(normalize(targetPath)), ]); }), ); - return branchAndMerge(chain([createServiceFiles, createModelFiles])); + return branchAndMerge(chain([createServiceFiles, createModelFiles, createEnumFiles])); }, ]); } diff --git a/npm/ng-packs/packages/schematics/src/enums/exception.ts b/npm/ng-packs/packages/schematics/src/enums/exception.ts index 70d74a832f..b1402daf5c 100644 --- a/npm/ng-packs/packages/schematics/src/enums/exception.ts +++ b/npm/ng-packs/packages/schematics/src/enums/exception.ts @@ -5,6 +5,7 @@ export const enum Exception { NoApi = '[API Not Available] Please double-check the URL in the source project environment and make sure your application is up and running.', NoApiDefinition = '[API Definition Not Found] There is no valid API definition file at "{0}".', NoProject = '[Project Not Found] Either define a default project in your workspace or specify the project name in schematics options.', + NoTypeDefinition = '[Type Definition Not Found] There is no type definition for "{0}".', NoWorkspace = '[Workspace Not Found] Make sure you are running schematics at the root directory of your workspace and it has an angular.json file.', NoEnvironment = '[Environment Not Found] An environment file cannot be located in "{0}" project.', NoApiUrl = '[API URL Not Found] Cannot resolve API URL for "{1}" module from "{0}" project.', diff --git a/npm/ng-packs/packages/schematics/src/utils/enum.ts b/npm/ng-packs/packages/schematics/src/utils/enum.ts new file mode 100644 index 0000000000..d58ed23a36 --- /dev/null +++ b/npm/ng-packs/packages/schematics/src/utils/enum.ts @@ -0,0 +1,31 @@ +import { SchematicsException } from '@angular-devkit/schematics'; +import { Exception } from '../enums'; +import { Type } from '../models'; +import { interpolate } from './common'; +import { parseNamespace } from './namespace'; + +export function getEnumNamesFromImports(serviceImports: Record) { + return Object.keys(serviceImports) + .filter(path => path.includes('/enums/')) + .reduce((acc: string[], path) => { + serviceImports[path].forEach(_import => acc.push(_import)); + return acc; + }, []); +} + +export function createImportRefToEnumMapper(solution: string, types: Record) { + return (ref: string) => { + const { enumNames, enumValues } = types[ref]; + if (!enumNames || !enumValues) + throw new SchematicsException(interpolate(Exception.NoTypeDefinition, ref)); + + const namespace = parseNamespace(solution, ref); + const members = enumNames!.map((key, i) => ({ key, value: enumValues[i] })); + + return { + namespace, + name: ref.split('.').pop()!, + members, + }; + }; +} diff --git a/npm/ng-packs/packages/schematics/src/utils/index.ts b/npm/ng-packs/packages/schematics/src/utils/index.ts index fc6c973b81..badfaa79ee 100644 --- a/npm/ng-packs/packages/schematics/src/utils/index.ts +++ b/npm/ng-packs/packages/schematics/src/utils/index.ts @@ -1,6 +1,7 @@ export * from './angular'; export * from './ast'; export * from './common'; +export * from './enum'; export * from './import'; export * from './model'; export * from './namespace';