From d4044c657220ca1dd5011d0e74868ed11040771c Mon Sep 17 00:00:00 2001 From: Arman Ozak Date: Thu, 20 Aug 2020 16:23:22 +0300 Subject: [PATCH] feat: generate referred models recursively in schematics --- .../schematics/src/commands/api/index.ts | 21 ++++++++++++---- .../packages/schematics/src/models/model.ts | 1 + .../packages/schematics/src/utils/enum.ts | 6 ++++- .../packages/schematics/src/utils/model.ts | 24 ++++++++++++++----- 4 files changed, 40 insertions(+), 12 deletions(-) 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 bf2922dc25..1d19c8e777 100644 --- a/npm/ng-packs/packages/schematics/src/commands/api/index.ts +++ b/npm/ng-packs/packages/schematics/src/commands/api/index.ts @@ -11,7 +11,7 @@ import { url, } from '@angular-devkit/schematics'; import { Exception } from '../../enums'; -import { ServiceGeneratorParams } from '../../models'; +import { Model, ServiceGeneratorParams } from '../../models'; import { applyWithOverwrite, buildDefaultPath, @@ -20,6 +20,7 @@ import { createImportRefsToModelMapper, createImportRefToEnumMapper, EnumGeneratorParams, + filterModelRefsToGenerate, getEnumNamesFromImports, interpolate, ModelGeneratorParams, @@ -107,8 +108,12 @@ function createModelGenerator(params: ModelGeneratorParams) { const { targetPath, serviceImports, modelImports } = params; const mapImportRefsToModel = createImportRefsToModelMapper(params); - return chain( - Object.values(serviceImports).reduce((rules: Rule[], refs) => { + return chain(reduceImportRefsToRules(Object.values(serviceImports))); + + function reduceImportRefsToRules(importRefs: string[][], models: Model[] = []): Rule[] { + if (!importRefs.length) return []; + + const accumulatedRules = importRefs.reduce((rules: Rule[], refs) => { const model = mapImportRefsToModel(refs); model.imports.forEach(({ refs, path }) => refs.forEach(ref => { @@ -117,6 +122,7 @@ function createModelGenerator(params: ModelGeneratorParams) { modelImports[path] = [...new Set([...modelImports[path], ref])]; }), ); + models.push(model); const rule = applyWithOverwrite(url('./files-model'), [ applyTemplates({ @@ -128,8 +134,13 @@ function createModelGenerator(params: ModelGeneratorParams) { rules.push(rule); return rules; - }, []), - ); + }, []); + + const refsToGenerate = filterModelRefsToGenerate(modelImports, models); + reduceImportRefsToRules(refsToGenerate).forEach(rule => accumulatedRules.push(rule)); + + return accumulatedRules; + } } function createServiceGenerator(params: ServiceGeneratorParams) { diff --git a/npm/ng-packs/packages/schematics/src/models/model.ts b/npm/ng-packs/packages/schematics/src/models/model.ts index 2318d6c181..76289ef2ca 100644 --- a/npm/ng-packs/packages/schematics/src/models/model.ts +++ b/npm/ng-packs/packages/schematics/src/models/model.ts @@ -5,6 +5,7 @@ export class Model { imports: Import[] = []; interfaces: Interface[] = []; namespace: string; + path: string; constructor(options: ModelOptions) { Object.assign(this, options); diff --git a/npm/ng-packs/packages/schematics/src/utils/enum.ts b/npm/ng-packs/packages/schematics/src/utils/enum.ts index 3b6de0134a..818a1a089b 100644 --- a/npm/ng-packs/packages/schematics/src/utils/enum.ts +++ b/npm/ng-packs/packages/schematics/src/utils/enum.ts @@ -12,9 +12,13 @@ export interface EnumGeneratorParams { modelImports: Record; } +export function isEnumImport(path: string) { + return path.includes('/enums/'); +} + export function getEnumNamesFromImports(serviceImports: Record) { return Object.keys(serviceImports) - .filter(path => path.includes('/enums/')) + .filter(isEnumImport) .reduce((acc: string[], path) => { serviceImports[path].forEach(_import => acc.push(_import)); return acc; diff --git a/npm/ng-packs/packages/schematics/src/utils/model.ts b/npm/ng-packs/packages/schematics/src/utils/model.ts index 89de6e3888..b46cf3a017 100644 --- a/npm/ng-packs/packages/schematics/src/utils/model.ts +++ b/npm/ng-packs/packages/schematics/src/utils/model.ts @@ -1,6 +1,6 @@ import { strings } from '@angular-devkit/core'; import { Import, Interface, Model, Property, Type, TypeWithEnum } from '../models'; -import { sortImports } from './import'; +import { isEnumImport } from './enum'; import { parseNamespace } from './namespace'; import { relativePathToModel } from './path'; import { parseGenerics } from './tree'; @@ -26,7 +26,8 @@ export function createImportRefsToModelMapper({ solution, types }: ModelGenerato return (importRefs: string[]) => { const namespace = parseNamespace(solution, importRefs[0]); - const model = new Model({ namespace }); + const path = relativePathToModel(namespace, namespace); + const model = new Model({ namespace, path }); const reduceImportRefToImport = createImportRefToImportReducer(namespace); const imports = importRefs.reduce((accumulatedImports, ref) => { @@ -36,11 +37,8 @@ export function createImportRefsToModelMapper({ solution, types }: ModelGenerato return reduceImportRefToImport(accumulatedImports, ref); }, []); - sortImports(imports); - - const selfPath = relativePathToModel(namespace, namespace); imports.forEach(_import => { - if (_import.path === selfPath) + if (_import.path === model.path) return _import.refs.forEach(ref => { if (model.interfaces.some(i => i.ref === ref)) return; @@ -133,3 +131,17 @@ export function createGenericRemover(genericArguments: string[] | null) { .join(','); }); } + +export function filterModelRefsToGenerate( + modelImports: Record, + modelsCreated: Model[], +) { + const created = modelsCreated.map(m => m.path); + + return Object.entries(modelImports).reduce((acc: string[][], [path, refs]) => { + if (isEnumImport(path)) return acc; + if (created.includes(path)) return acc; + acc.push(refs); + return acc; + }, []); +}