From bd23ec897e27039177ae7f69de93ad7fce38de03 Mon Sep 17 00:00:00 2001 From: Vincent Ogloblinsky Date: Wed, 17 Oct 2018 13:48:26 +0200 Subject: [PATCH] feat(deps): decorators arguments listing fix #630 fix #640 --- src/app/application.ts | 126 +++++++-------- .../angular/deps/helpers/class-helper.ts | 150 ++++++++++++++---- src/app/engines/dependencies.engine.ts | 42 +++-- src/app/engines/export-json.engine.ts | 5 +- src/app/engines/export.engine.ts | 4 +- .../element-alone.helper.ts | 6 +- .../function-decorator.helper.ts | 114 ------------- .../function-signature.helper.ts | 11 +- .../html-engine-helpers/link-type.helper.ts | 10 +- .../parse-description.helper.ts | 8 +- src/app/engines/html.engine.helpers.ts | 15 +- src/app/engines/html.engine.ts | 5 +- src/app/engines/ngd.engine.ts | 7 +- src/templates/partials/block-method.hbs | 6 +- src/templates/partials/block-property.hbs | 6 +- src/utils/object-literal-expression.util.ts | 24 ++- test/src/cli/cli-generation-big-app.spec.ts | 2 +- test/src/cli/cli-nest.spec.ts | 17 +- test/src/nest-app/src/app.controller.ts | 6 +- test/src/nest-app/src/user.entity.ts | 39 +++++ tools/tests-angularexpo.js | 10 ++ 21 files changed, 326 insertions(+), 287 deletions(-) delete mode 100644 src/app/engines/html-engine-helpers/function-decorator.helper.ts create mode 100644 test/src/nest-app/src/user.entity.ts diff --git a/src/app/application.ts b/src/app/application.ts index eb4a8300..3b4c2efd 100644 --- a/src/app/application.ts +++ b/src/app/application.ts @@ -31,7 +31,7 @@ import { cleanSourcesForWatch } from '../utils/utils'; import { cleanNameWithoutSpaceAndToLowerCase, findMainSourceFolder } from '../utilities'; import { promiseSequential } from '../utils/promise-sequential'; -import { DependenciesEngine } from './engines/dependencies.engine'; +import DependenciesEngine from './engines/dependencies.engine'; import { AngularVersionUtil, RouterParserUtil } from '../utils'; let cwd = process.cwd(); @@ -73,7 +73,6 @@ export class Application { private packageJsonData = {}; private angularVersionUtil = new AngularVersionUtil(); - private dependenciesEngine: DependenciesEngine; private ngdEngine: NgdEngine; private htmlEngine: HtmlEngine; private searchEngine: SearchEngine; @@ -88,17 +87,14 @@ export class Application { */ constructor(options?: Object) { this.configuration = new Configuration(); - this.dependenciesEngine = new DependenciesEngine(); - this.ngdEngine = new NgdEngine(this.dependenciesEngine); + this.ngdEngine = new NgdEngine(); this.htmlEngine = new HtmlEngine( this.configuration, - this.dependenciesEngine, this.fileEngine ); this.searchEngine = new SearchEngine(this.configuration, this.fileEngine); this.exportEngine = new ExportEngine( this.configuration, - this.dependenciesEngine, this.fileEngine ); @@ -420,7 +416,7 @@ export class Application { let dependenciesData = crawler.getDependencies(); - this.dependenciesEngine.update(dependenciesData); + DependenciesEngine.update(dependenciesData); this.prepareJustAFewThings(dependenciesData); } @@ -501,7 +497,7 @@ export class Application { let dependenciesData = crawler.getDependencies(); - this.dependenciesEngine.init(dependenciesData); + DependenciesEngine.init(dependenciesData); this.configuration.mainData.routesLength = this.routerParser.routesLength(); @@ -583,38 +579,38 @@ export class Application { private printStatistics() { logger.info('-------------------'); logger.info('Project statistics '); - if (this.dependenciesEngine.modules.length > 0) { + if (DependenciesEngine.modules.length > 0) { logger.info(`- files : ${this.files.length}`); } - if (this.dependenciesEngine.modules.length > 0) { - logger.info(`- module : ${this.dependenciesEngine.modules.length}`); + if (DependenciesEngine.modules.length > 0) { + logger.info(`- module : ${DependenciesEngine.modules.length}`); } - if (this.dependenciesEngine.components.length > 0) { - logger.info(`- component : ${this.dependenciesEngine.components.length}`); + if (DependenciesEngine.components.length > 0) { + logger.info(`- component : ${DependenciesEngine.components.length}`); } - if (this.dependenciesEngine.controllers.length > 0) { - logger.info(`- controller : ${this.dependenciesEngine.controllers.length}`); + if (DependenciesEngine.controllers.length > 0) { + logger.info(`- controller : ${DependenciesEngine.controllers.length}`); } - if (this.dependenciesEngine.directives.length > 0) { - logger.info(`- directive : ${this.dependenciesEngine.directives.length}`); + if (DependenciesEngine.directives.length > 0) { + logger.info(`- directive : ${DependenciesEngine.directives.length}`); } - if (this.dependenciesEngine.injectables.length > 0) { - logger.info(`- injectable : ${this.dependenciesEngine.injectables.length}`); + if (DependenciesEngine.injectables.length > 0) { + logger.info(`- injectable : ${DependenciesEngine.injectables.length}`); } - if (this.dependenciesEngine.interceptors.length > 0) { - logger.info(`- injector : ${this.dependenciesEngine.interceptors.length}`); + if (DependenciesEngine.interceptors.length > 0) { + logger.info(`- injector : ${DependenciesEngine.interceptors.length}`); } - if (this.dependenciesEngine.guards.length > 0) { - logger.info(`- guard : ${this.dependenciesEngine.guards.length}`); + if (DependenciesEngine.guards.length > 0) { + logger.info(`- guard : ${DependenciesEngine.guards.length}`); } - if (this.dependenciesEngine.pipes.length > 0) { - logger.info(`- pipe : ${this.dependenciesEngine.pipes.length}`); + if (DependenciesEngine.pipes.length > 0) { + logger.info(`- pipe : ${DependenciesEngine.pipes.length}`); } - if (this.dependenciesEngine.classes.length > 0) { - logger.info(`- class : ${this.dependenciesEngine.classes.length}`); + if (DependenciesEngine.classes.length > 0) { + logger.info(`- class : ${DependenciesEngine.classes.length}`); } - if (this.dependenciesEngine.interfaces.length > 0) { - logger.info(`- interface : ${this.dependenciesEngine.interfaces.length}`); + if (DependenciesEngine.interfaces.length > 0) { + logger.info(`- interface : ${DependenciesEngine.interfaces.length}`); } if (this.configuration.mainData.routesLength > 0) { logger.info(`- route : ${this.configuration.mainData.routesLength}`); @@ -632,39 +628,39 @@ export class Application { return this.prepareModules(); }); - if (this.dependenciesEngine.directives.length > 0) { + if (DependenciesEngine.directives.length > 0) { actions.push(() => { return this.prepareDirectives(); }); } - if (this.dependenciesEngine.controllers.length > 0) { + if (DependenciesEngine.controllers.length > 0) { actions.push(() => { return this.prepareControllers(); }); } - if (this.dependenciesEngine.injectables.length > 0) { + if (DependenciesEngine.injectables.length > 0) { actions.push(() => { return this.prepareInjectables(); }); } - if (this.dependenciesEngine.interceptors.length > 0) { + if (DependenciesEngine.interceptors.length > 0) { actions.push(() => { return this.prepareInterceptors(); }); } - if (this.dependenciesEngine.guards.length > 0) { + if (DependenciesEngine.guards.length > 0) { actions.push(() => { return this.prepareGuards(); }); } if ( - this.dependenciesEngine.routes && - this.dependenciesEngine.routes.children.length > 0 && + DependenciesEngine.routes && + DependenciesEngine.routes.children.length > 0 && !this.configuration.mainData.disableRoutesGraph ) { actions.push(() => { @@ -672,29 +668,29 @@ export class Application { }); } - if (this.dependenciesEngine.pipes.length > 0) { + if (DependenciesEngine.pipes.length > 0) { actions.push(() => { return this.preparePipes(); }); } - if (this.dependenciesEngine.classes.length > 0) { + if (DependenciesEngine.classes.length > 0) { actions.push(() => { return this.prepareClasses(); }); } - if (this.dependenciesEngine.interfaces.length > 0) { + if (DependenciesEngine.interfaces.length > 0) { actions.push(() => { return this.prepareInterfaces(); }); } if ( - this.dependenciesEngine.miscellaneous.variables.length > 0 || - this.dependenciesEngine.miscellaneous.functions.length > 0 || - this.dependenciesEngine.miscellaneous.typealiases.length > 0 || - this.dependenciesEngine.miscellaneous.enumerations.length > 0 + DependenciesEngine.miscellaneous.variables.length > 0 || + DependenciesEngine.miscellaneous.functions.length > 0 || + DependenciesEngine.miscellaneous.typealiases.length > 0 || + DependenciesEngine.miscellaneous.enumerations.length > 0 ) { actions.push(() => { return this.prepareMiscellaneous(); @@ -843,7 +839,7 @@ export class Application { public prepareModules(someModules?): Promise { logger.info('Prepare modules'); let i = 0; - let _modules = someModules ? someModules : this.dependenciesEngine.getModules(); + let _modules = someModules ? someModules : DependenciesEngine.getModules(); return new Promise((resolve, reject) => { this.configuration.mainData.modules = _modules.map(ngModule => { @@ -858,7 +854,7 @@ export class Application { ngModule[metadataType] = ngModule[metadataType].filter(metaDataItem => { switch (metaDataItem.type) { case 'directive': - return this.dependenciesEngine.getDirectives().some(directive => { + return DependenciesEngine.getDirectives().some(directive => { let selectedDirective; if (typeof metaDataItem.id !== 'undefined') { selectedDirective = @@ -877,7 +873,7 @@ export class Application { }); case 'component': - return this.dependenciesEngine.getComponents().some(component => { + return DependenciesEngine.getComponents().some(component => { let selectedComponent; if (typeof metaDataItem.id !== 'undefined') { selectedComponent = @@ -896,7 +892,7 @@ export class Application { }); case 'controller': - return this.dependenciesEngine.getControllers().some(controller => { + return DependenciesEngine.getControllers().some(controller => { let selectedController; if (typeof metaDataItem.id !== 'undefined') { selectedController = @@ -915,12 +911,12 @@ export class Application { }); case 'module': - return this.dependenciesEngine + return DependenciesEngine .getModules() .some(module => (module as any).name === metaDataItem.name); case 'pipe': - return this.dependenciesEngine.getPipes().some(pipe => { + return DependenciesEngine.getPipes().some(pipe => { let selectedPipe; if (typeof metaDataItem.id !== 'undefined') { selectedPipe = (pipe as any).id === metaDataItem.id; @@ -943,7 +939,7 @@ export class Application { }); ngModule.providers = ngModule.providers.filter(provider => { return ( - this.dependenciesEngine.getInjectables().some(injectable => { + DependenciesEngine.getInjectables().some(injectable => { let selectedInjectable = (injectable as any).name === provider.name; if ( selectedInjectable && @@ -953,7 +949,7 @@ export class Application { } return selectedInjectable; }) || - this.dependenciesEngine + DependenciesEngine .getInterceptors() .some(interceptor => (interceptor as any).name === provider.name) ); @@ -961,14 +957,14 @@ export class Application { // Try fixing type undefined for each providers _.forEach(ngModule.providers, provider => { if ( - this.dependenciesEngine + DependenciesEngine .getInjectables() .find(injectable => (injectable as any).name === provider.name) ) { provider.type = 'injectable'; } if ( - this.dependenciesEngine + DependenciesEngine .getInterceptors() .find(interceptor => (interceptor as any).name === provider.name) ) { @@ -1049,7 +1045,7 @@ export class Application { logger.info('Prepare pipes'); this.configuration.mainData.pipes = somePipes ? somePipes - : this.dependenciesEngine.getPipes(); + : DependenciesEngine.getPipes(); return new Promise((resolve, reject) => { let i = 0; @@ -1090,7 +1086,7 @@ export class Application { logger.info('Prepare classes'); this.configuration.mainData.classes = someClasses ? someClasses - : this.dependenciesEngine.getClasses(); + : DependenciesEngine.getClasses(); return new Promise((resolve, reject) => { let i = 0; @@ -1131,7 +1127,7 @@ export class Application { logger.info('Prepare interfaces'); this.configuration.mainData.interfaces = someInterfaces ? someInterfaces - : this.dependenciesEngine.getInterfaces(); + : DependenciesEngine.getInterfaces(); return new Promise((resolve, reject) => { let i = 0; @@ -1172,7 +1168,7 @@ export class Application { logger.info('Prepare miscellaneous'); this.configuration.mainData.miscellaneous = someMisc ? someMisc - : this.dependenciesEngine.getMiscellaneous(); + : DependenciesEngine.getMiscellaneous(); return new Promise((resolve, reject) => { if (this.configuration.mainData.miscellaneous.functions.length > 0) { @@ -1329,7 +1325,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); logger.info('Prepare controllers'); this.configuration.mainData.controllers = someControllers ? someControllers - : this.dependenciesEngine.getControllers(); + : DependenciesEngine.getControllers(); return new Promise((resolve, reject) => { let i = 0; @@ -1365,7 +1361,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); logger.info('Prepare components'); this.configuration.mainData.components = someComponents ? someComponents - : this.dependenciesEngine.getComponents(); + : DependenciesEngine.getComponents(); return new Promise((mainPrepareComponentResolve, mainPrepareComponentReject) => { let i = 0; @@ -1474,7 +1470,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); this.configuration.mainData.directives = someDirectives ? someDirectives - : this.dependenciesEngine.getDirectives(); + : DependenciesEngine.getDirectives(); return new Promise((resolve, reject) => { let i = 0; @@ -1516,7 +1512,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); this.configuration.mainData.injectables = someInjectables ? someInjectables - : this.dependenciesEngine.getInjectables(); + : DependenciesEngine.getInjectables(); return new Promise((resolve, reject) => { let i = 0; @@ -1558,7 +1554,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); this.configuration.mainData.interceptors = someInterceptors ? someInterceptors - : this.dependenciesEngine.getInterceptors(); + : DependenciesEngine.getInterceptors(); return new Promise((resolve, reject) => { let i = 0; @@ -1600,7 +1596,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); this.configuration.mainData.guards = someGuards ? someGuards - : this.dependenciesEngine.getGuards(); + : DependenciesEngine.getGuards(); return new Promise((resolve, reject) => { let i = 0; @@ -1639,7 +1635,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); public prepareRoutes(): Promise { logger.info('Process routes'); - this.configuration.mainData.routes = this.dependenciesEngine.getRoutes(); + this.configuration.mainData.routes = DependenciesEngine.getRoutes(); return new Promise((resolve, reject) => { this.configuration.addPage({ @@ -2738,7 +2734,7 @@ at least one config for the 'info' or 'source' tab in --navTabConfig.`); finalPath += '/'; } finalPath += 'modules/' + modules[i].name; - let _rawModule = this.dependenciesEngine.getRawModule(modules[i].name); + let _rawModule = DependenciesEngine.getRawModule(modules[i].name); if ( _rawModule.declarations.length > 0 || _rawModule.bootstrap.length > 0 || diff --git a/src/app/compiler/angular/deps/helpers/class-helper.ts b/src/app/compiler/angular/deps/helpers/class-helper.ts index 996b164a..1db0a94a 100644 --- a/src/app/compiler/angular/deps/helpers/class-helper.ts +++ b/src/app/compiler/angular/deps/helpers/class-helper.ts @@ -10,7 +10,10 @@ import { ConfigurationInterface } from '../../../../interfaces/configuration.int import { JsdocParserUtil } from '../../../../../utils/jsdoc-parser.util'; import { ImportsUtil } from '../../../../../utils/imports.util'; import { logger } from '../../../../../logger'; -import { isIgnore } from '../../../../../utils'; +import { isIgnore, AngularVersionUtil, BasicTypeUtil } from '../../../../../utils'; +import { StringifyObjectLiteralExpression } from '../../../../../utils/object-literal-expression.util'; + +import DependenciesEngine from '../../../../engines/dependencies.engine'; const crypto = require('crypto'); const marked = require('marked'); @@ -18,6 +21,8 @@ const marked = require('marked'); export class ClassHelper { private jsdocParserUtil = new JsdocParserUtil(); private importsUtil = new ImportsUtil(); + private angularVersionUtil = new AngularVersionUtil(); + private basicTypeUtil = new BasicTypeUtil(); constructor( private typeChecker: ts.TypeChecker, @@ -61,18 +66,12 @@ export class ClassHelper { _.forEach(decorators, (decorator: any) => { if (decorator.expression) { if (decorator.expression.text) { - _decorators.push({ - name: decorator.expression.text - }); + _decorators.push({ name: decorator.expression.text }); } if (decorator.expression.expression) { - let info: any = { - name: decorator.expression.expression.text - }; + let info: any = { name: decorator.expression.expression.text }; if (decorator.expression.arguments) { - if (decorator.expression.arguments.length > 0) { - info.args = decorator.expression.arguments; - } + info.stringifiedArguments = this.stringifyArguments(decorator.expression.arguments); } _decorators.push(info); } @@ -82,6 +81,111 @@ export class ClassHelper { return _decorators; } + private handleFunction(arg): string { + if (arg.function.length === 0) { + return `${arg.name}${this.getOptionalString(arg)}: () => void`; + } + + let argums = arg.function.map(argu => { + let _result = DependenciesEngine.find(argu.type); + if (_result) { + if (_result.source === 'internal') { + let path = _result.data.type; + if (_result.data.type === 'class') { + path = 'classe'; + } + return `${argu.name}${this.getOptionalString(arg)}: ${argu.type}`; + } else { + let path = this.angularVersionUtil.getApiLink( + _result.data, + this.configuration.mainData.angularVersion + ); + return `${argu.name}${this.getOptionalString( + arg + )}: ${argu.type}`; + } + } else if (this.basicTypeUtil.isKnownType(argu.type)) { + let path = this.basicTypeUtil.getTypeUrl(argu.type); + return `${argu.name}${this.getOptionalString( + arg + )}: ${argu.type}`; + } else { + if (argu.name && argu.type) { + return `${argu.name}${this.getOptionalString(arg)}: ${argu.type}`; + } else { + if (argu.name) { + return `${argu.name.text}`; + } else { + return ''; + } + } + } + }); + return `${arg.name}${this.getOptionalString(arg)}: (${argums}) => void`; + } + + private getOptionalString(arg): string { + return arg.optional ? '?' : ''; + } + + private stringifyArguments(args) { + let stringifyArgs = []; + + stringifyArgs = args + .map(arg => { + let _result = DependenciesEngine.find(arg.type); + if (_result) { + if (_result.source === 'internal') { + let path = _result.data.type; + if (_result.data.type === 'class') { + path = 'classe'; + } + return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; + } else { + let path = this.angularVersionUtil.getApiLink( + _result.data, + this.configuration.mainData.angularVersion + ); + return `${arg.name}${this.getOptionalString( + arg + )}: ${arg.type}`; + } + } else if (arg.dotDotDotToken) { + return `...${arg.name}: ${arg.type}`; + } else if (arg.function) { + return this.handleFunction(arg); + } else if (arg.expression && arg.name) { + return arg.expression.text + '.' + arg.name.text; + } else if (arg.expression && arg.kind === SyntaxKind.NewExpression) { + return 'new ' + arg.expression.text + '()'; + } else if (arg.kind && arg.kind === SyntaxKind.StringLiteral) { + return `'` + arg.text + `'`; + } else if (arg.kind && arg.kind === SyntaxKind.ObjectLiteralExpression) { + return StringifyObjectLiteralExpression(arg); + } else if (this.basicTypeUtil.isKnownType(arg.type)) { + let path = this.basicTypeUtil.getTypeUrl(arg.type); + return `${arg.name}${this.getOptionalString( + arg + )}: ${arg.type}`; + } else { + if (arg.type) { + return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; + } else if (arg.text) { + return `${arg.text}`; + } else { + return `${arg.name}${this.getOptionalString(arg)}`; + } + } + }) + .join(', '); + + return stringifyArgs; + } + private getPosition(node: ts.Node, sourceFile: ts.SourceFile): ts.LineAndCharacter { let position: ts.LineAndCharacter; if (node.name && node.name.end) { @@ -289,19 +393,11 @@ export class ClassHelper { if (symbol) { description = marked(this.jsdocParserUtil.getMainCommentOfNode(classDeclaration)); if (symbol.valueDeclaration && isIgnore(symbol.valueDeclaration)) { - return [ - { - ignore: true - } - ]; + return [{ ignore: true }]; } if (symbol.declarations && symbol.declarations.length > 0) { if (isIgnore(symbol.declarations[0])) { - return [ - { - ignore: true - } - ]; + return [{ ignore: true }]; } } } @@ -389,14 +485,7 @@ export class ClassHelper { } ]; } else if (this.isModuleDecorator(classDeclaration.decorators[i])) { - return [ - { - fileName, - className, - description, - jsdoctags: jsdoctags - } - ]; + return [{ fileName, className, description, jsdoctags: jsdoctags }]; } else { return [ { @@ -1065,10 +1154,7 @@ export class ClassHelper { } private visitArgument(arg: ts.ParameterDeclaration) { - let _result: any = { - name: arg.name.text, - type: this.visitType(arg) - }; + let _result: any = { name: arg.name.text, type: this.visitType(arg) }; if (arg.dotDotDotToken) { _result.dotDotDotToken = true; } diff --git a/src/app/engines/dependencies.engine.ts b/src/app/engines/dependencies.engine.ts index 8b74754f..f75fb105 100644 --- a/src/app/engines/dependencies.engine.ts +++ b/src/app/engines/dependencies.engine.ts @@ -39,10 +39,28 @@ export class DependenciesEngine { public routes: RouteInterface; public pipes: Object[]; public classes: Object[]; - public miscellaneous: MiscellaneousData; + public miscellaneous: MiscellaneousData = { + variables: [], + functions:[], + typealiases:[], + enumerations:[], + groupedVariables: [], + groupedFunctions: [], + groupedEnumerations: [], + groupedTypeAliases: [], + }; private angularApiUtil: AngularApiUtil = new AngularApiUtil(); + private static instance: DependenciesEngine; + private constructor() { } + public static getInstance() { + if (!DependenciesEngine.instance) { + DependenciesEngine.instance = new DependenciesEngine(); + } + return DependenciesEngine.instance; + } + private updateModulesDeclarationsExportsTypes() { let _m = this.modules, i = 0, @@ -119,15 +137,17 @@ export class DependenciesEngine { source: 'internal', data: undefined }; - for (let i = 0; i < data.length; i++) { - if (typeof name !== 'undefined') { - if (typeof file !== 'undefined') { - if (name.indexOf(data[i].name) !== -1 && file.replace(/\\/g, '/').indexOf(data[i].file) !== -1) { - _result.data = data[i]; - } - } else { - if (name.indexOf(data[i].name) !== -1) { - _result.data = data[i]; + if (data && data.length > 0) { + for (let i = 0; i < data.length; i++) { + if (typeof name !== 'undefined') { + if (typeof file !== 'undefined') { + if (name.indexOf(data[i].name) !== -1 && file.replace(/\\/g, '/').indexOf(data[i].file) !== -1) { + _result.data = data[i]; + } + } else { + if (name.indexOf(data[i].name) !== -1) { + _result.data = data[i]; + } } } } @@ -386,3 +406,5 @@ export class DependenciesEngine { return this.miscellaneous; } } + +export default DependenciesEngine.getInstance(); \ No newline at end of file diff --git a/src/app/engines/export-json.engine.ts b/src/app/engines/export-json.engine.ts index 48f0c93b..e946d225 100644 --- a/src/app/engines/export-json.engine.ts +++ b/src/app/engines/export-json.engine.ts @@ -1,7 +1,7 @@ import * as path from 'path'; import { logger } from '../../logger'; -import { DependenciesEngine } from './dependencies.engine'; +import DependenciesEngine from './dependencies.engine'; import { ConfigurationInterface } from '../interfaces/configuration.interface'; import { FileEngine } from './file.engine'; @@ -14,7 +14,6 @@ const traverse = require('traverse'); export class ExportJsonEngine { constructor( private configuration: ConfigurationInterface, - private dependenciesEngine: DependenciesEngine, private fileEngine: FileEngine = new FileEngine() ) {} @@ -51,7 +50,7 @@ export class ExportJsonEngine { } processModules() { - const modules: AngularNgModuleNode[] = this.dependenciesEngine.getModules(); + const modules: AngularNgModuleNode[] = DependenciesEngine.getModules(); let _resultedModules = []; diff --git a/src/app/engines/export.engine.ts b/src/app/engines/export.engine.ts index b3679ab2..ccd94240 100644 --- a/src/app/engines/export.engine.ts +++ b/src/app/engines/export.engine.ts @@ -1,4 +1,4 @@ -import { DependenciesEngine } from './dependencies.engine'; +import DependenciesEngine from './dependencies.engine'; import { ConfigurationInterface } from '../interfaces/configuration.interface'; import { FileEngine } from './file.engine'; @@ -9,7 +9,6 @@ export class ExportEngine { constructor( private configuration: ConfigurationInterface, - private dependenciesEngine: DependenciesEngine, private fileEngine: FileEngine = new FileEngine() ) {} @@ -18,7 +17,6 @@ export class ExportEngine { case 'json': this._engine = new ExportJsonEngine( this.configuration, - this.dependenciesEngine, this.fileEngine ); return this._engine.export(outputFolder, data); diff --git a/src/app/engines/html-engine-helpers/element-alone.helper.ts b/src/app/engines/html-engine-helpers/element-alone.helper.ts index 130e59ae..ce86c32c 100644 --- a/src/app/engines/html-engine-helpers/element-alone.helper.ts +++ b/src/app/engines/html-engine-helpers/element-alone.helper.ts @@ -1,13 +1,13 @@ import { IHtmlEngineHelper, IHandlebarsOptions } from './html-engine-helper.interface'; import { extractLeadingText, splitLinkText } from '../../../utils/link-parser'; -import { DependenciesEngine } from '../dependencies.engine'; +import DependenciesEngine from '../dependencies.engine'; export class ElementAloneHelper implements IHtmlEngineHelper { - constructor(private dependenciesEngine: DependenciesEngine) {} + constructor() {} public helperFunc(context: any, elements, elementType: string, options: IHandlebarsOptions) { let alones = []; - let modules = this.dependenciesEngine.modules; + let modules = DependenciesEngine.modules; elements.forEach(element => { let foundInOneModule = false; diff --git a/src/app/engines/html-engine-helpers/function-decorator.helper.ts b/src/app/engines/html-engine-helpers/function-decorator.helper.ts deleted file mode 100644 index d34642ef..00000000 --- a/src/app/engines/html-engine-helpers/function-decorator.helper.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { IHtmlEngineHelper } from './html-engine-helper.interface'; - -import { DependenciesEngine } from '../dependencies.engine'; -import { AngularVersionUtil, BasicTypeUtil } from '../../../utils'; -import { StringifyObjectLiteralExpression } from '.././../../utils/object-literal-expression.util'; -import { ConfigurationInterface } from '../../interfaces/configuration.interface'; - -import { ts, SyntaxKind } from 'ts-simple-ast'; - -export class FunctionDecoratorHelper implements IHtmlEngineHelper { - private angularVersionUtil = new AngularVersionUtil(); - private basicTypeUtil = new BasicTypeUtil(); - - constructor( - private configuration: ConfigurationInterface, - private dependenciesEngine: DependenciesEngine - ) {} - - private handleFunction(arg): string { - if (arg.function.length === 0) { - return `${arg.name}${this.getOptionalString(arg)}: () => void`; - } - - let argums = arg.function.map(argu => { - let _result = this.dependenciesEngine.find(argu.type); - if (_result) { - if (_result.source === 'internal') { - let path = _result.data.type; - if (_result.data.type === 'class') { - path = 'classe'; - } - return `${argu.name}${this.getOptionalString(arg)}: ${argu.type}`; - } else { - let path = this.angularVersionUtil.getApiLink( - _result.data, - this.configuration.mainData.angularVersion - ); - return `${argu.name}${this.getOptionalString( - arg - )}: ${argu.type}`; - } - } else if (this.basicTypeUtil.isKnownType(argu.type)) { - let path = this.basicTypeUtil.getTypeUrl(argu.type); - return `${argu.name}${this.getOptionalString( - arg - )}: ${argu.type}`; - } else { - if (argu.name && argu.type) { - return `${argu.name}${this.getOptionalString(arg)}: ${argu.type}`; - } else { - if (argu.name) { - return `${argu.name.text}`; - } else { - return ''; - } - } - } - }); - return `${arg.name}${this.getOptionalString(arg)}: (${argums}) => void`; - } - - private getOptionalString(arg): string { - return arg.optional ? '?' : ''; - } - - public helperFunc(context: any, decorator) { - let args = []; - - if (decorator.args) { - args = decorator.args - .map(arg => { - let _result = this.dependenciesEngine.find(arg.type); - if (_result) { - if (_result.source === 'internal') { - let path = _result.data.type; - if (_result.data.type === 'class') { - path = 'classe'; - } - return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; - } else { - let path = this.angularVersionUtil.getApiLink(_result.data, this.configuration.mainData.angularVersion); - return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; - } - } else if (arg.dotDotDotToken) { - return `...${arg.name}: ${arg.type}`; - } else if (arg.function) { - return this.handleFunction(arg); - } else if (arg.expression && arg.name) { - return arg.expression.text + '.' + arg.name.text; - } else if (arg.kind && arg.kind === SyntaxKind.StringLiteral) { - return `'` + arg.text + `'`; - } else if (arg.kind && arg.kind === SyntaxKind.ObjectLiteralExpression) { - return StringifyObjectLiteralExpression(arg); - } else if (this.basicTypeUtil.isKnownType(arg.type)) { - let path = this.basicTypeUtil.getTypeUrl(arg.type); - return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; - } else { - if (arg.type) { - return `${arg.name}${this.getOptionalString(arg)}: ${arg.type}`; - } else if (arg.text) { - return `${arg.text}`; - }else { - return `${arg.name}${this.getOptionalString(arg)}`; - } - } - }) - .join(', '); - } - - return `@${decorator.name}(${args}) `; - } -} diff --git a/src/app/engines/html-engine-helpers/function-signature.helper.ts b/src/app/engines/html-engine-helpers/function-signature.helper.ts index eb986ebd..60aff17f 100644 --- a/src/app/engines/html-engine-helpers/function-signature.helper.ts +++ b/src/app/engines/html-engine-helpers/function-signature.helper.ts @@ -1,6 +1,6 @@ import { IHtmlEngineHelper } from './html-engine-helper.interface'; -import { DependenciesEngine } from '../dependencies.engine'; +import DependenciesEngine from '../dependencies.engine'; import { AngularVersionUtil, BasicTypeUtil } from '../../../utils'; import { ConfigurationInterface } from '../../interfaces/configuration.interface'; @@ -10,10 +10,7 @@ export class FunctionSignatureHelper implements IHtmlEngineHelper { private angularVersionUtil = new AngularVersionUtil(); private basicTypeUtil = new BasicTypeUtil(); - constructor( - private configuration: ConfigurationInterface, - private dependenciesEngine: DependenciesEngine - ) {} + constructor(private configuration: ConfigurationInterface) {} private handleFunction(arg): string { if (arg.function.length === 0) { @@ -21,7 +18,7 @@ export class FunctionSignatureHelper implements IHtmlEngineHelper { } let argums = arg.function.map(argu => { - let _result = this.dependenciesEngine.find(argu.type); + let _result = DependenciesEngine.find(argu.type); if (_result) { if (_result.source === 'internal') { let path = _result.data.type; @@ -70,7 +67,7 @@ export class FunctionSignatureHelper implements IHtmlEngineHelper { if (method.args) { args = method.args .map(arg => { - let _result = this.dependenciesEngine.find(arg.type); + let _result = DependenciesEngine.find(arg.type); if (_result) { if (_result.source === 'internal') { let path = _result.data.type; diff --git a/src/app/engines/html-engine-helpers/link-type.helper.ts b/src/app/engines/html-engine-helpers/link-type.helper.ts index b775d57a..2d8f31cf 100644 --- a/src/app/engines/html-engine-helpers/link-type.helper.ts +++ b/src/app/engines/html-engine-helpers/link-type.helper.ts @@ -1,5 +1,5 @@ import { IHtmlEngineHelper, IHandlebarsOptions } from './html-engine-helper.interface'; -import { DependenciesEngine } from '../dependencies.engine'; +import DependenciesEngine from '../dependencies.engine'; import { ConfigurationInterface } from '../../interfaces/configuration.interface'; import { AngularVersionUtil, BasicTypeUtil } from '../../../utils'; @@ -7,14 +7,10 @@ export class LinkTypeHelper implements IHtmlEngineHelper { private angularVersionUtil = new AngularVersionUtil(); private basicTypeUtil = new BasicTypeUtil(); - constructor( - private configuration: ConfigurationInterface, - private dependenciesEngine: DependenciesEngine) { - - } + constructor(private configuration: ConfigurationInterface) {} public helperFunc(context: any, name: string, options: IHandlebarsOptions) { - let _result = this.dependenciesEngine.find(name); + let _result = DependenciesEngine.find(name); let angularDocPrefix = this.angularVersionUtil.prefixOfficialDoc(this.configuration.mainData.angularVersion); if (_result) { context.type = { diff --git a/src/app/engines/html-engine-helpers/parse-description.helper.ts b/src/app/engines/html-engine-helpers/parse-description.helper.ts index a66712dd..565e4fa8 100644 --- a/src/app/engines/html-engine-helpers/parse-description.helper.ts +++ b/src/app/engines/html-engine-helpers/parse-description.helper.ts @@ -1,9 +1,9 @@ import { IHtmlEngineHelper } from './html-engine-helper.interface'; import { extractLeadingText, splitLinkText } from '../../../utils/link-parser'; -import { DependenciesEngine } from '../dependencies.engine'; +import DependenciesEngine from '../dependencies.engine'; export class ParseDescriptionHelper implements IHtmlEngineHelper { - constructor(private dependenciesEngine: DependenciesEngine) {} + constructor() {} public helperFunc(context: any, description: string, depth: number) { let tagRegExpLight = new RegExp('\\{@link\\s+((?:.|\n)+?)\\}', 'i'); @@ -29,14 +29,14 @@ export class ParseDescriptionHelper implements IHtmlEngineHelper { split = splitLinkText(matchedTag.text); if (typeof split.linkText !== 'undefined') { - resultInCompodoc = this.dependenciesEngine.findInCompodoc(split.target); + resultInCompodoc = DependenciesEngine.findInCompodoc(split.target); } else { let info = matchedTag.text; if (matchedTag.text.indexOf('#') !== -1) { anchor = matchedTag.text.substr(matchedTag.text.indexOf('#'), matchedTag.text.length); info = matchedTag.text.substr(0, matchedTag.text.indexOf('#')); } - resultInCompodoc = this.dependenciesEngine.findInCompodoc(info); + resultInCompodoc = DependenciesEngine.findInCompodoc(info); } if (resultInCompodoc) { diff --git a/src/app/engines/html.engine.helpers.ts b/src/app/engines/html.engine.helpers.ts index fd62c1b3..d4732fcb 100644 --- a/src/app/engines/html.engine.helpers.ts +++ b/src/app/engines/html.engine.helpers.ts @@ -1,7 +1,7 @@ import * as Handlebars from 'handlebars'; import * as _ from 'lodash'; -import { DependenciesEngine } from './dependencies.engine'; +import DependenciesEngine from './dependencies.engine'; import { IHtmlEngineHelper } from './html-engine-helpers/html-engine-helper.interface'; import { CompareHelper } from './html-engine-helpers/compare.helper'; import { OrHelper } from './html-engine-helpers/or.helper'; @@ -37,22 +37,19 @@ import { ElementAloneHelper } from './html-engine-helpers/element-alone.helper'; import { HasOwnHelper } from './html-engine-helpers/has-own.helper'; import { ShortURLHelper } from './html-engine-helpers/short-url.helper'; import { I18nHelper } from './html-engine-helpers/i18n.helper'; -import { FunctionDecoratorHelper } from './html-engine-helpers/function-decorator.helper'; export class HtmlEngineHelpers { public registerHelpers( bars, - configuration: ConfigurationInterface, - dependenciesEngine: DependenciesEngine + configuration: ConfigurationInterface ): void { this.registerHelper(bars, 'compare', new CompareHelper()); this.registerHelper(bars, 'or', new OrHelper()); this.registerHelper( bars, 'functionSignature', - new FunctionSignatureHelper(configuration, dependenciesEngine) + new FunctionSignatureHelper(configuration) ); - this.registerHelper(bars, 'functionDecorator', new FunctionDecoratorHelper(configuration, dependenciesEngine)); this.registerHelper(bars, 'isNotToggle', new IsNotToggleHelper(configuration)); this.registerHelper(bars, 'isInitialTab', new IsInitialTabHelper()); this.registerHelper(bars, 'isTabEnabled', new IsTabEnabledHelper()); @@ -76,7 +73,7 @@ export class HtmlEngineHelpers { this.registerHelper( bars, 'linkType', - new LinkTypeHelper(configuration, dependenciesEngine) + new LinkTypeHelper(configuration) ); this.registerHelper(bars, 'indexableSignature', new IndexableSignatureHelper()); this.registerHelper(bars, 'object', new ObjectHelper()); @@ -84,10 +81,10 @@ export class HtmlEngineHelpers { this.registerHelper( bars, 'parseDescription', - new ParseDescriptionHelper(dependenciesEngine) + new ParseDescriptionHelper() ); this.registerHelper(bars, 'one-parameter-has', new OneParameterHasHelper()); - this.registerHelper(bars, 'element-alone', new ElementAloneHelper(dependenciesEngine)); + this.registerHelper(bars, 'element-alone', new ElementAloneHelper()); this.registerHelper(bars, 'hasOwn', new HasOwnHelper()); this.registerHelper(bars, 'short-url', new ShortURLHelper()); this.registerHelper(bars, 't', new I18nHelper()); diff --git a/src/app/engines/html.engine.ts b/src/app/engines/html.engine.ts index 30500c3b..5ff28e69 100644 --- a/src/app/engines/html.engine.ts +++ b/src/app/engines/html.engine.ts @@ -3,7 +3,7 @@ import * as Handlebars from 'handlebars'; import { logger } from '../../logger'; import { HtmlEngineHelpers } from './html.engine.helpers'; -import { DependenciesEngine } from './dependencies.engine'; +import DependenciesEngine from './dependencies.engine'; import { ConfigurationInterface } from '../interfaces/configuration.interface'; import { FileEngine } from './file.engine'; @@ -17,11 +17,10 @@ export class HtmlEngine { constructor( configuration: ConfigurationInterface, - dependenciesEngine: DependenciesEngine, private fileEngine: FileEngine = new FileEngine() ) { const helper = new HtmlEngineHelpers(); - helper.registerHelpers(Handlebars, configuration, dependenciesEngine); + helper.registerHelpers(Handlebars, configuration); } public init(templatePath: string): Promise { diff --git a/src/app/engines/ngd.engine.ts b/src/app/engines/ngd.engine.ts index 7b39293b..9b87e261 100644 --- a/src/app/engines/ngd.engine.ts +++ b/src/app/engines/ngd.engine.ts @@ -1,4 +1,4 @@ -import { DependenciesEngine } from './dependencies.engine'; +import DependenciesEngine from './dependencies.engine'; import { FileEngine } from './file.engine'; const ngdT = require('@compodoc/ngd-transformer'); @@ -7,7 +7,6 @@ export class NgdEngine { public engine; constructor( - private dependenciesEngine: DependenciesEngine, private fileEngine: FileEngine = new FileEngine() ) {} @@ -24,9 +23,9 @@ export class NgdEngine { this.engine.updateOutput(outputpath); if (type === 'f') { - return this.engine.generateGraph([this.dependenciesEngine.getRawModule(name)]); + return this.engine.generateGraph([DependenciesEngine.getRawModule(name)]); } else { - return this.engine.generateGraph(this.dependenciesEngine.rawModulesForOverview); + return this.engine.generateGraph(DependenciesEngine.rawModulesForOverview); } } diff --git a/src/templates/partials/block-method.hbs b/src/templates/partials/block-method.hbs index 21e00aad..0d1090fa 100644 --- a/src/templates/partials/block-method.hbs +++ b/src/templates/partials/block-method.hbs @@ -49,7 +49,11 @@ {{#if decorators}} - {{t "decorators" }} : {{#each decorators}}{{{functionDecorator this}}}{{/each}} + {{t "decorators" }} : +
+ + {{#each decorators}}{{#if stringifiedArguments}}@{{name}}({{stringifiedArguments}}){{else}}@{{name}}(){{/if}}
{{/each}} +
{{/if}} diff --git a/src/templates/partials/block-property.hbs b/src/templates/partials/block-property.hbs index ad393b54..0b444b7b 100644 --- a/src/templates/partials/block-property.hbs +++ b/src/templates/partials/block-property.hbs @@ -53,7 +53,11 @@ {{#if decorators}} - {{t "decorators" }} : {{#each decorators}}@{{name}}() {{/each}} + {{t "decorators" }} : +
+ + {{#each decorators}}{{#if stringifiedArguments}}@{{name}}({{stringifiedArguments}}){{else}}@{{name}}(){{/if}}
{{/each}} +
{{/if}} diff --git a/src/utils/object-literal-expression.util.ts b/src/utils/object-literal-expression.util.ts index 8c1b33ed..fc7f5028 100644 --- a/src/utils/object-literal-expression.util.ts +++ b/src/utils/object-literal-expression.util.ts @@ -1,27 +1,25 @@ const util = require('util'); -import { SyntaxKind } from "ts-simple-ast"; +import { SyntaxKind } from 'ts-simple-ast'; export function StringifyObjectLiteralExpression(ole) { let returnedString = '{'; - // console.log(util.inspect(ole, { showHidden: true, depth: 10 })); - if (ole.properties && ole.properties.length > 0) { - ole.properties.forEach(property => { - // console.log(util.inspect(property, { showHidden: true, depth: 20 })); + ole.properties.forEach((property, index) => { if (property.name) { - returnedString += property.name.text + ':'; + returnedString += property.name.text + ': '; } - if (property.symbol) { - if (property.symbol.declarations && property.symbol.declarations.length > 0) { - property.symbol.declarations.forEach(declaration => { - if (declaration.kind === SyntaxKind.PropertyAssignment) { - returnedString += declaration.name.text + ':'; - } - }); + if (property.initializer) { + if (property.initializer.kind === SyntaxKind.StringLiteral) { + returnedString += `'` + property.initializer.text + `'`; + } else { + returnedString += property.initializer.text; } } + if (index < ole.properties.length - 1) { + returnedString += ', '; + } }); } diff --git a/test/src/cli/cli-generation-big-app.spec.ts b/test/src/cli/cli-generation-big-app.spec.ts index e831ca3f..1d5e7dfa 100644 --- a/test/src/cli/cli-generation-big-app.spec.ts +++ b/test/src/cli/cli-generation-big-app.spec.ts @@ -117,7 +117,7 @@ describe('CLI simple generation - big app', () => { }); it('should have a decorator listed', () => { - expect(footerComponentFile).to.contain('Decorators : @LogProperty()'); + expect(footerComponentFile).to.contain('@LogProperty() { }); it('it should contain a controller page with prefix', () => { - let file = read(`${distFolder}/controllers/AuthController.html`); - expect(file).to.contain('code>auth@Auth(Roles.User) @Post() @Post('multiple') { @@ -44,5 +46,12 @@ describe('CLI nest projects support', () => { expect(file).to.contain('AppController'); }); + it('it should contain an entity', () => { + let isFileExists = exists(`${distFolder}/classes/UserEntity.html`); + expect(isFileExists).to.be.true; + let file = read(`${distFolder}/classes/UserEntity.html`); + expect(file).to.contain('@Column({default: ''}) ArticleEntity) + @JoinTable() + favorites: ArticleEntity[]; + + @OneToMany(type => ArticleEntity, article => article.author) + articles: ArticleEntity[]; +} \ No newline at end of file diff --git a/tools/tests-angularexpo.js b/tools/tests-angularexpo.js index aad921d2..a5c8fb57 100755 --- a/tools/tests-angularexpo.js +++ b/tools/tests-angularexpo.js @@ -329,6 +329,16 @@ const TEST_FOLDER = 'angularexpo-tests', maintainer: 'vmware', tsconfig_path: './src/dev/', tsconfig_file: 'tsconfig.dev.json' + }, + { + name: 'simple-todos', + maintainer: 'chanlito', + tsconfig_path: './server/', + tsconfig_file: 'tsconfig.json' + }, { + name: 'nestjs-realworld-example-app', + maintainer: 'lujakob', + tsconfig_path: './' } ], len = GIT_REPOSITORIES.length;