├── .eslintrc.js ├── .github └── workflows │ └── node.js.yml ├── .gitignore ├── .nycrc.yml ├── CHANGELOG.md ├── LICENSE ├── NOTES.md ├── README.md ├── README_fr_FR.md ├── base ├── fixtures │ ├── docs │ │ ├── a.js │ │ └── b.ngdoc │ └── src │ │ ├── f1 │ │ └── a.js │ │ └── f2 │ │ └── b.js ├── index.js ├── index.spec.js ├── mocks │ └── mockPackage.js ├── processors │ ├── checkAnchorLinks.js │ ├── checkAnchorLinks.spec.js │ ├── computeIds.js │ ├── computeIds.spec.js │ ├── computePaths.js │ ├── computePaths.spec.js │ ├── debugDumpProcessor.js │ ├── debugDumpProcessor.spec.js │ ├── read-files.js │ ├── read-files.spec.js │ ├── render-docs.js │ ├── render-docs.spec.js │ ├── unescape-comments.js │ ├── unescape-comments.spec.js │ ├── write-files.js │ └── write-files.spec.js └── services │ ├── aliasMap.js │ ├── aliasMap.spec.js │ ├── createDocMessage.js │ ├── createDocMessage.spec.js │ ├── encodeCodeBlock.js │ ├── encodeCodeBlock.spec.js │ ├── extractLinks.js │ ├── extractLinks.spec.js │ ├── resolveUrl.js │ ├── resolveUrl.spec.js │ ├── templateFinder.js │ ├── templateFinder.spec.js │ ├── trimIndentation.js │ ├── trimIndentation.spec.js │ └── writeFile.js ├── dgeni ├── index.js ├── mocks │ ├── mockPackage.js │ ├── testPackage.js │ ├── testPackage2.js │ └── testProcessor.js ├── processors │ ├── checkDocsHavePackage.js │ ├── computeProcessorPipeline.js │ ├── filterJSFileDocs.js │ ├── generateIndex.js │ ├── readPackageInfo.js │ ├── readPackageInfo.spec.js │ └── wireUpServicesToPackages.js ├── tag-defs │ ├── dgPackage.js │ ├── dgProcessor.js │ └── dgService.js └── templates │ ├── dgPackage.template.md │ ├── dgProcessor.template.md │ └── dgService.template.md ├── docs ├── README.md ├── RELEASE.md ├── index.js └── templates │ ├── dgPackage.template.md │ ├── dgProcessor.template.md │ ├── dgService.template.md │ ├── indexPage.template.md │ └── partials │ └── header.template.md ├── examples ├── index.js ├── index.spec.js ├── inline-tag-defs │ ├── runnableExample.js │ └── runnableExample.spec.js ├── mocks │ └── mockPackage.js ├── processors │ ├── examples-generate.js │ ├── examples-generate.spec.js │ ├── examples-parse.js │ ├── examples-parse.spec.js │ ├── protractor-generate.js │ └── protractor-generate.spec.js ├── services │ └── exampleMap.js └── templates │ ├── index.template.html │ ├── manifest.template.json │ ├── protractorTests.template.js │ ├── runnableExample.template.html │ ├── template.css │ ├── template.html │ ├── template.js │ ├── template.json │ ├── template.protractor │ ├── template.scenario │ └── template.spec ├── git ├── index.js ├── index.spec.js ├── mocks │ ├── mockPackage.js │ └── mocks.js ├── services │ ├── decorateVersion.js │ ├── decorateVersion.spec.js │ ├── getPreviousVersions.js │ ├── getPreviousVersions.spec.js │ ├── gitData.js │ ├── gitData.spec.js │ ├── gitRepoInfo.js │ ├── gitRepoInfo.spec.js │ ├── packageInfo.js │ ├── packageInfo.spec.js │ ├── versionInfo.js │ └── versionInfo.spec.js └── templates │ ├── api │ └── api.template.html │ └── base.template.html ├── jsdoc ├── file-readers │ ├── jsdoc.js │ └── jsdoc.spec.js ├── index.js ├── index.spec.js ├── lib │ ├── Tag.js │ ├── Tag.spec.js │ ├── TagCollection.js │ └── TagCollection.spec.js ├── mocks │ ├── _test-data │ │ ├── docsFromJsFile.js │ │ └── srcJsFile.js │ └── mockPackage.js ├── processors │ ├── code-name.js │ ├── code-name.spec.js │ ├── extract-tags.js │ ├── extract-tags.spec.js │ ├── extractJSDocComments.js │ ├── extractJSDocComments.spec.js │ ├── inline-tags.js │ ├── inline-tags.spec.js │ ├── parse-tags.js │ └── parse-tags.spec.js ├── services │ ├── code-name-map.js │ ├── code-name-matchers │ │ ├── array-expression.js │ │ ├── array-expression.spec.js │ │ ├── arrow-function-expression.js │ │ ├── arrow-function-expression.spec.js │ │ ├── assignment-expression.js │ │ ├── assignment-expression.spec.js │ │ ├── call-expression.js │ │ ├── call-expression.spec.js │ │ ├── class-declaration.js │ │ ├── class-declaration.spec.js │ │ ├── export-default-declaration.js │ │ ├── export-default-declaration.spec.js │ │ ├── export-named-declaration.js │ │ ├── export-named-declaration.spec.js │ │ ├── expression-statement.js │ │ ├── expression-statement.spec.js │ │ ├── function-declaration.js │ │ ├── function-declaration.spec.js │ │ ├── function-expression.js │ │ ├── function-expression.spec.js │ │ ├── identifier.js │ │ ├── identifier.spec.js │ │ ├── import-declaration.js │ │ ├── import-declaration.spec.js │ │ ├── index.js │ │ ├── literal.js │ │ ├── literal.spec.js │ │ ├── member-expression.js │ │ ├── member-expression.spec.js │ │ ├── method-definition.js │ │ ├── method-definition.spec.js │ │ ├── new-expression.js │ │ ├── new-expression.spec.js │ │ ├── object-expression.js │ │ ├── object-expression.spec.js │ │ ├── program.js │ │ ├── program.spec.js │ │ ├── property.js │ │ ├── property.spec.js │ │ ├── return-statement.js │ │ ├── return-statement.spec.js │ │ ├── throw-statement.js │ │ ├── throw-statement.spec.js │ │ ├── variable-declaration.js │ │ ├── variable-declaration.spec.js │ │ ├── variable-declarator.js │ │ └── variable-declarator.spec.js │ ├── code-name.js │ ├── code-name.spec.js │ ├── jsParser-config.js │ ├── jsParser-config.spec.js │ ├── jsParser.js │ ├── parser-adapters │ │ ├── backtick-parser-adapter.js │ │ ├── backtick-parser-adapter.spec.js │ │ ├── html-block-parser-adapter.js │ │ └── html-block-parser-adapter.spec.js │ └── transforms │ │ ├── boolean-tag.js │ │ ├── boolean-tag.spec.js │ │ ├── extract-access.js │ │ ├── extract-access.spec.js │ │ ├── extract-name.js │ │ ├── extract-name.spec.js │ │ ├── extract-type.js │ │ ├── extract-type.spec.js │ │ ├── trim-whitespace.js │ │ ├── trim-whitespace.spec.js │ │ ├── unknown-tag.js │ │ ├── unknown-tag.spec.js │ │ ├── whole-tag.js │ │ └── whole-tag.spec.js └── tag-defs │ ├── access.js │ ├── access.spec.js │ ├── animations.js │ ├── async.js │ ├── class.js │ ├── classdesc.js │ ├── constant.js │ ├── constructor.js │ ├── deprecated.js │ ├── description.js │ ├── description.spec.js │ ├── enum.js │ ├── function.js │ ├── global.js │ ├── index.js │ ├── index.spec.js │ ├── kind.js │ ├── license.js │ ├── license.spec.js │ ├── memberof.js │ ├── memberof.spec.js │ ├── method.js │ ├── module.js │ ├── name.js │ ├── namespace.js │ ├── param.js │ ├── param.spec.js │ ├── private.js │ ├── private.spec.js │ ├── property.js │ ├── property.spec.js │ ├── propertyof.js │ ├── propertyof.spec.js │ ├── protected.js │ ├── protected.spec.js │ ├── public.js │ ├── public.spec.js │ ├── requires.js │ ├── returns.js │ ├── returns.spec.js │ ├── see.js │ ├── since.js │ ├── type.js │ ├── type.spec.js │ ├── usage.js │ └── version.js ├── links ├── index.js ├── inline-tag-defs │ ├── link.js │ └── link.spec.js ├── mocks │ └── mockPackage.js └── services │ ├── getAliases.js │ ├── getAliases.spec.js │ ├── getDocFromAlias.js │ ├── getDocFromAlias.spec.js │ └── getLinkInfo.js ├── ngdoc ├── file-readers │ ├── ngdoc.js │ └── ngdoc.spec.js ├── index.js ├── index.spec.js ├── mocks │ └── mockPackage.js ├── processors │ ├── collectKnownIssues.js │ ├── collectKnownIssues.spec.js │ ├── filterNgdocs.js │ ├── filterNgdocs.spec.js │ ├── generateComponentGroups.js │ ├── generateComponentGroups.spec.js │ ├── memberDocs.js │ ├── memberDocs.spec.js │ ├── moduleDocs.js │ ├── moduleDocs.spec.js │ ├── providerDocs.js │ └── providerDocs.spec.js ├── rendering │ ├── filters │ │ ├── code.js │ │ ├── code.spec.js │ │ ├── link.js │ │ ├── link.spec.js │ │ ├── type-class.js │ │ └── type-class.spec.js │ └── tags │ │ ├── code.js │ │ └── code.spec.js ├── services │ ├── getTypeClass.js │ ├── getTypeClass.spec.js │ └── moduleMap.js ├── tag-defs │ ├── area.js │ ├── area.spec.js │ ├── element.js │ ├── element.spec.js │ ├── eventType.js │ ├── eventType.spec.js │ ├── example.js │ ├── fullName.js │ ├── id.js │ ├── index.js │ ├── knownIssue.js │ ├── module.js │ ├── module.spec.js │ ├── multiElement.js │ ├── multiElement.spec.js │ ├── name.js │ ├── name.spec.js │ ├── ngdoc.js │ ├── packageName.js │ ├── parent.js │ ├── priority.js │ ├── priority.spec.js │ ├── restrict.js │ ├── restrict.spec.js │ ├── scope.js │ ├── scope.spec.js │ └── title.js └── templates │ ├── api │ ├── api.template.html │ ├── componentGroup.template.html │ ├── directive.template.html │ ├── filter.template.html │ ├── function.template.html │ ├── input.template.html │ ├── module.template.html │ ├── object.template.html │ ├── provider.template.html │ ├── service.template.html │ └── type.template.html │ ├── base.template.html │ ├── lib │ ├── events.template.html │ ├── macros.html │ ├── methods.template.html │ ├── params.template.html │ ├── properties.template.html │ ├── returns.template.html │ └── this.template.html │ └── overview.template.html ├── nunjucks ├── index.js ├── index.spec.js ├── mocks │ └── mockPackage.js ├── rendering │ ├── filters │ │ ├── change-case.js │ │ ├── change-case.spec.js │ │ ├── first-line.js │ │ ├── first-line.spec.js │ │ ├── first-paragraph.js │ │ ├── first-paragraph.spec.js │ │ ├── json.js │ │ ├── json.spec.js │ │ ├── marked.js │ │ └── marked.spec.js │ └── tags │ │ ├── marked.js │ │ └── marked.spec.js └── services │ ├── nunjucks-template-engine.js │ ├── nunjucks-template-engine.spec.js │ ├── renderMarkdown.js │ └── renderMarkdown.spec.js ├── package.json ├── post-process-html ├── .gitignore ├── .npmignore ├── src │ ├── api-doc-types │ │ └── ApiDoc.ts │ ├── index.spec.ts │ ├── index.ts │ ├── mocks │ │ └── mockPackage.ts │ └── processors │ │ ├── postProcessHtml.spec.ts │ │ └── postProcessHtml.ts ├── tsconfig.json └── types │ └── rehype.d.ts ├── test.js ├── tsconfig.json ├── typescript ├── .gitignore ├── .npmignore ├── mocks │ ├── linkInheritedDocs │ │ ├── deps.ts │ │ └── index.ts │ ├── mockPackage.js │ ├── readTypeScriptModules │ │ ├── commentContent.ts │ │ ├── consts.ts │ │ ├── exportAliases.ts │ │ ├── functions.ts │ │ ├── gettersAndSetters.ts │ │ ├── ignoreExportsMatching.ts │ │ ├── imports.ts │ │ ├── interfaces.ts │ │ ├── memberAliases.ts │ │ ├── memberModifiers.ts │ │ ├── methodParameters.ts │ │ ├── modules.ts │ │ ├── multipleDeclarations.ts │ │ ├── orderingOfMembers.ts │ │ ├── overloadedMembers.ts │ │ ├── privateMembers.ts │ │ ├── privateModule.ts │ │ ├── publicModule.ts │ │ ├── returnTypes.ts │ │ ├── spreadParams.ts │ │ ├── staticMembers.ts │ │ ├── stripNamespaces.ts │ │ ├── test │ │ │ └── folder │ │ │ │ └── index.ts │ │ └── type-aliases.ts │ └── tsParser │ │ ├── Location.test.ts │ │ ├── getAccessibility.test.ts │ │ ├── getContent.test.ts │ │ ├── getDeclarationTypeText.test.ts │ │ ├── getDecorators.test.ts │ │ ├── getExportDocType.test.ts │ │ ├── getHeritageClause.test.ts │ │ ├── getParameters.test.ts │ │ ├── getTypeParametersText.test.ts │ │ ├── getTypeText.test.ts │ │ ├── importedSrc.ts │ │ ├── multipleLeadingComments.ts │ │ ├── nodeToString.test.ts │ │ ├── testSrc.ts │ │ ├── typeToString.ts │ │ └── zone.js │ │ └── index.ts ├── src │ ├── api-doc-types │ │ ├── AccessorInfoDoc.ts │ │ ├── ApiDoc.ts │ │ ├── ClassExportDoc.ts │ │ ├── ClassLikeExportDoc.ts │ │ ├── ConstExportDoc.ts │ │ ├── ContainerExportDoc.ts │ │ ├── EnumExportDoc.ts │ │ ├── ExportDoc.ts │ │ ├── FunctionExportDoc.ts │ │ ├── InterfaceExportDoc.ts │ │ ├── MemberDoc.ts │ │ ├── MethodMemberDoc.ts │ │ ├── ModuleDoc.ts │ │ ├── OverloadInfo.ts │ │ ├── ParameterContainer.ts │ │ ├── ParameterDoc.ts │ │ ├── ParameterizedExportDoc.ts │ │ ├── PropertyMemberDoc.ts │ │ └── TypeAliasExportDoc.ts │ ├── index.ts │ ├── processors │ │ ├── linkInheritedDocs.spec.ts │ │ ├── linkInheritedDocs.ts │ │ ├── mergeParameterInfo.spec.ts │ │ ├── mergeParameterInfo.ts │ │ └── readTypeScriptModules │ │ │ ├── SourcePattern.ts │ │ │ ├── index.spec.ts │ │ │ └── index.ts │ └── services │ │ ├── TsParser │ │ ├── CustomCompilerHost.spec.ts │ │ ├── CustomCompilerHost.ts │ │ ├── FileInfo.spec.ts │ │ ├── FileInfo.ts │ │ ├── LineFeedPrinter.ts │ │ ├── Location.spec.ts │ │ ├── Location.ts │ │ ├── getAccessibility.spec.ts │ │ ├── getAccessibility.ts │ │ ├── getContent.spec.ts │ │ ├── getContent.ts │ │ ├── getDeclarationTypeText.spec.ts │ │ ├── getDeclarationTypeText.ts │ │ ├── getDecorators.spec.ts │ │ ├── getDecorators.ts │ │ ├── getExportDocType.spec.ts │ │ ├── getExportDocType.ts │ │ ├── getHeritageClause.spec.ts │ │ ├── getHeritageClause.ts │ │ ├── getTypeParametersText.spec.ts │ │ ├── getTypeParametersText.ts │ │ ├── getTypeText.spec.ts │ │ ├── getTypeText.ts │ │ ├── index.spec.ts │ │ ├── index.ts │ │ ├── nodeToString.spec.ts │ │ └── nodeToString.ts │ │ ├── convertPrivateClassesToInterfaces.spec.ts │ │ ├── convertPrivateClassesToInterfaces.ts │ │ ├── exportSymbolsToDocsMap.ts │ │ ├── modules.ts │ │ └── ts-host │ │ ├── host.spec.ts │ │ └── host.ts └── tsconfig.json └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | jasmine: true, 5 | es2020: true, 6 | }, 7 | extends: 'eslint:recommended', 8 | rules: { 9 | 'no-unused-vars': 'off', 10 | 'no-prototype-builtins': 'off', 11 | }, 12 | ignorePatterns: [ 13 | 'typescript/**/*.js', 14 | 'examples/templates/**/*.js' 15 | ], 16 | }; -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [14.x, 16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v1 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - run: yarn 29 | - run: yarn test 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.DS_Store 10 | 11 | pids 12 | logs 13 | results 14 | 15 | npm-debug.log 16 | node_modules 17 | .idea/ 18 | 19 | .agignore 20 | 21 | coverage 22 | .nyc_output 23 | 24 | .tmp 25 | 26 | debug-dump.txt 27 | -------------------------------------------------------------------------------- /.nycrc.yml: -------------------------------------------------------------------------------- 1 | exclude: ['**/*.spec.js', '**/mocks/**'] 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 Google, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /base/fixtures/docs/a.js: -------------------------------------------------------------------------------- 1 | // Mock code file -------------------------------------------------------------------------------- /base/fixtures/docs/b.ngdoc: -------------------------------------------------------------------------------- 1 | mock documentation file -------------------------------------------------------------------------------- /base/fixtures/src/f1/a.js: -------------------------------------------------------------------------------- 1 | // Mock code file -------------------------------------------------------------------------------- /base/fixtures/src/f2/b.js: -------------------------------------------------------------------------------- 1 | // Other mock code file -------------------------------------------------------------------------------- /base/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }) 9 | 10 | // provide a mock template engine for the tests 11 | .factory('templateEngine', function dummyTemplateEngine() { 12 | const renderSpy = jasmine.createSpy('templateEngine'); 13 | return { 14 | getRenderer() { return renderSpy; } 15 | }; 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /base/processors/debugDumpProcessor.js: -------------------------------------------------------------------------------- 1 | const path = require('canonical-path'); 2 | var util = require("util"); 3 | 4 | /** 5 | * @dgProcessor debugDumpProcessor 6 | * @description 7 | * This processor dumps docs that match a filter to a file 8 | */ 9 | module.exports = function debugDumpProcessor(log, readFilesProcessor, writeFile) { 10 | return { 11 | filterFn(docs) { return docs; }, 12 | outputPath: 'debug-dump.txt', 13 | depth: 2, 14 | 15 | $enabled: false, 16 | 17 | $validate: { 18 | filterFn: { presence: true }, 19 | outputPath: { presence: true }, 20 | depth: { presence: true } 21 | }, 22 | 23 | $runBefore: ['writing-files'], 24 | 25 | $process(docs) { 26 | log.info('Dumping docs:', this.filterFn, this.outputPath); 27 | const filteredDocs = this.filterFn(docs); 28 | const dumpedDocs = util.inspect(filteredDocs, this.depth); 29 | const outputPath = path.resolve(readFilesProcessor.basePath, this.outputPath); 30 | return writeFile(outputPath, dumpedDocs).then(() => docs); 31 | } 32 | }; 33 | 34 | }; -------------------------------------------------------------------------------- /base/processors/debugDumpProcessor.spec.js: -------------------------------------------------------------------------------- 1 | const path = require('canonical-path'); 2 | 3 | const mockPackage = require('../mocks/mockPackage'); 4 | const Dgeni = require('dgeni'); 5 | 6 | 7 | describe("debugDumpProcessor", () => { 8 | it("should write out the docs to a file", () => { 9 | 10 | const writeFileSpy = jasmine.createSpy('writeFile').and.returnValue(Promise.resolve()); 11 | const testPackage = mockPackage().factory('writeFile', function writeFile() { return writeFileSpy; }); 12 | 13 | const dgeni = new Dgeni([testPackage]); 14 | const injector = dgeni.configureInjector(); 15 | 16 | const readFilesProcessor = injector.get('readFilesProcessor'); 17 | readFilesProcessor.basePath = path.resolve('some/path'); 18 | 19 | const processor = injector.get('debugDumpProcessor'); 20 | 21 | processor.outputPath = 'build/dump.txt'; 22 | processor.$process([{ val: 'a' }, { val: 'b' }]); 23 | expect(writeFileSpy).toHaveBeenCalledWith(path.resolve('some/path/build/dump.txt'), "[ { val: 'a' }, { val: 'b' } ]"); 24 | }); 25 | }); -------------------------------------------------------------------------------- /base/processors/unescape-comments.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @dgProcessor unescapeCommentsProcessor 4 | * @description 5 | * Some files (like CSS) use the same comment markers as the jsdoc comments, such as /*. 6 | * To get around this we HTML encode them in the source. 7 | * This processor unescapes them back to normal comment markers 8 | */ 9 | module.exports = function unescapeCommentsProcessor() { 10 | return { 11 | $runAfter: ['docs-rendered'], 12 | $runBefore: ['writing-files'], 13 | $process(docs) { 14 | docs.forEach(doc => doc.renderedContent = doc.renderedContent.replace(/\/*/g, '/*').replace(/*\//g, '*/')); 15 | } 16 | }; 17 | }; -------------------------------------------------------------------------------- /base/processors/unescape-comments.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | describe("unescapeCommentsProcessor", () => { 5 | it("should convert HTML encoded comments back to their original form", () => { 6 | 7 | const dgeni = new Dgeni([mockPackage()]); 8 | const injector = dgeni.configureInjector(); 9 | const processor = injector.get('unescapeCommentsProcessor'); 10 | 11 | const doc = { 12 | renderedContent: 'Some text containing /* a comment */\nSome text containing /* a comment */' 13 | }; 14 | processor.$process([doc]); 15 | expect(doc.renderedContent).toEqual('Some text containing /* a comment */\nSome text containing /* a comment */'); 16 | }); 17 | }); -------------------------------------------------------------------------------- /base/processors/write-files.js: -------------------------------------------------------------------------------- 1 | const path = require('canonical-path'); 2 | 3 | /** 4 | * @dgProcessor writeFilesProcessor 5 | * @param {Object} log A service that provides logging 6 | * @description Write the value of `doc.renderedContent` to a file a `doc.outputPath`. 7 | * @property {String} outputFolder The base path to the folder where files are outputted 8 | */ 9 | module.exports = function writeFilesProcessor(log, readFilesProcessor, writeFile) { 10 | return { 11 | outputFolder: null, 12 | $validate: { 13 | outputFolder: { presence: true }, 14 | }, 15 | $runAfter:['writing-files'], 16 | $runBefore: ['files-written'], 17 | $process(docs) { 18 | const outputFolder = this.outputFolder; 19 | return Promise.all(docs.map(doc => { 20 | 21 | if ( !doc.outputPath ) { 22 | log.debug('Document "' + doc.id + ', ' + doc.docType + '" has no outputPath.'); 23 | } else { 24 | 25 | const outputFile = path.resolve(readFilesProcessor.basePath, outputFolder, doc.outputPath); 26 | 27 | log.silly('writing file', outputFile); 28 | return writeFile(outputFile, doc.renderedContent).then(() => { 29 | log.debug('written file', outputFile); 30 | return outputFile; 31 | }); 32 | 33 | } 34 | })).then(() => docs); 35 | } 36 | }; 37 | }; -------------------------------------------------------------------------------- /base/services/createDocMessage.js: -------------------------------------------------------------------------------- 1 | module.exports = function createDocMessage() { 2 | return (message, doc, error) => { 3 | message = message || ''; 4 | if ( doc ) { 5 | message += ' - doc'; 6 | const docIdentifier = doc.id || doc.name || doc.path; 7 | if ( docIdentifier ) { 8 | message += ' "' + docIdentifier + '"'; 9 | } 10 | if ( doc.docType ) { 11 | message += ' (' + doc.docType + ') '; 12 | } 13 | const filePath = doc.fileInfo && doc.fileInfo.relativePath; 14 | if ( filePath ) { 15 | message += ' - from file "' + filePath + '"'; 16 | if ( typeof doc.startingLine === 'number' ) { 17 | message += ' - starting at line ' + doc.startingLine; 18 | } 19 | if ( typeof doc.endingLine === 'number' ) { 20 | message += ', ending at line ' + doc.endingLine; 21 | } 22 | } 23 | } 24 | if ( error ) { 25 | message += '\n\nOriginal Error: \n\n' + error.stack; 26 | } 27 | return message; 28 | }; 29 | }; -------------------------------------------------------------------------------- /base/services/encodeCodeBlock.js: -------------------------------------------------------------------------------- 1 | const htmlEncode = require('htmlencode').htmlEncode; 2 | 3 | module.exports = function encodeCodeBlock() { 4 | return (str, inline, lang) => { 5 | 6 | // Encode any HTML entities in the code string 7 | str = htmlEncode(str, true); 8 | 9 | // If a language is provided then attach a CSS class to the code element 10 | lang = lang ? ' class="lang-' + lang + '"' : ''; 11 | 12 | str = '' + str + ''; 13 | 14 | // If not inline then wrap the code element in a pre element 15 | if ( !inline ) { 16 | str = '
' + str + '
'; 17 | } 18 | 19 | return str; 20 | }; 21 | }; -------------------------------------------------------------------------------- /base/services/encodeCodeBlock.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | describe("code utility", () => { 5 | let encodeCodeBlock; 6 | 7 | beforeEach(() => { 8 | const dgeni = new Dgeni([mockPackage()]); 9 | const injector = dgeni.configureInjector(); 10 | encodeCodeBlock = injector.get('encodeCodeBlock'); 11 | }); 12 | 13 | it("should wrap the string in code and pre tags", () => { 14 | expect(encodeCodeBlock('abc')).toEqual('
abc
'); 15 | }); 16 | 17 | it("should HTML encode the string", () => { 18 | expect(encodeCodeBlock('
&
')).toEqual('
<div>&</div>
'); 19 | }); 20 | 21 | it("should encode HTML entities", () => { 22 | expect(encodeCodeBlock('
')).toEqual('
<div>&#10;</div>
'); 23 | }); 24 | 25 | describe("inline", () => { 26 | it("should only wrap in a code tag", () => { 27 | expect(encodeCodeBlock('abc', true)).toEqual('abc'); 28 | }); 29 | }); 30 | 31 | describe("language", () => { 32 | it("should add a CSS class if a language is specified", () => { 33 | expect(encodeCodeBlock('abc', true, 'js')).toEqual('abc'); 34 | }); 35 | }); 36 | }); -------------------------------------------------------------------------------- /base/services/extractLinks.js: -------------------------------------------------------------------------------- 1 | var htmlparser = require("htmlparser2"); 2 | 3 | /** 4 | * @dgService extractLinks 5 | * @description 6 | * Extracts the links and references from a given html 7 | * @param {String} html The html 8 | */ 9 | module.exports = function extractLinks() { 10 | return html => { 11 | const result = {hrefs: [], names: []}; 12 | const parser = new htmlparser.Parser({ 13 | onopentag(name, attribs) { 14 | 15 | // Parse anchor elements, extracting href and name 16 | if (name === 'a') { 17 | if (attribs.href) { 18 | result.hrefs.push(attribs.href); 19 | } 20 | if (attribs.name) { 21 | result.names.push(attribs.name); 22 | } 23 | } 24 | 25 | // Extract id from other elements 26 | if(attribs.id) { 27 | result.names.push(attribs.id); 28 | } 29 | } 30 | }, { 31 | decodeEntities: true 32 | }); 33 | parser.write(html); 34 | parser.end(); 35 | return result; 36 | }; 37 | }; 38 | -------------------------------------------------------------------------------- /base/services/extractLinks.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | describe("extractLinks", () => { 5 | let extractLinks; 6 | 7 | beforeEach(() => { 8 | const dgeni = new Dgeni([mockPackage()]); 9 | const injector = dgeni.configureInjector(); 10 | extractLinks = injector.get('extractLinks'); 11 | }); 12 | 13 | it("should extract the hrefs from anchors", () => { 14 | expect(extractLinks('bar').hrefs).toEqual(['foo']); 15 | expect(extractLinks('barshell').hrefs).toEqual(['foo', 'man']); 16 | expect(extractLinks('
bar
').hrefs).toEqual([]); 17 | }); 18 | 19 | it("should extract the names from anchors", () => { 20 | expect(extractLinks('barshell').names).toEqual(['foo']); 21 | expect(extractLinks('
bar
').names).toEqual([]); 22 | }); 23 | 24 | it("should extract the ids from elements", () => { 25 | expect(extractLinks('barshell').names).toEqual(['foo']); 26 | expect(extractLinks('
bar
').names).toEqual(['foo']); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /base/services/resolveUrl.js: -------------------------------------------------------------------------------- 1 | const url = require('url'); 2 | const path = require('canonical-path'); 3 | 4 | /** 5 | * @dgService resolveUrl 6 | * @description 7 | * Calculates the absolute path of the url from the current path, 8 | * the relative path and the base 9 | * @param {String=} currentPath The current path 10 | * @param {String} newPath The new path 11 | * @param {String=} base The base path 12 | */ 13 | module.exports = function resolveUrl() { 14 | return (currentPath, newPath, base) => { 15 | 16 | // Extract only the path and the hash from the newPath 17 | const parsedUrl = url.parse(newPath); 18 | parsedUrl.search = null; 19 | newPath = url.format(parsedUrl); 20 | 21 | if ( base && newPath.charAt(0) !== '/' ) { 22 | // Resolve against the base url if there is a base and the new path is not absolute 23 | newPath = path.resolve(base, newPath).replace(/^(\w:)?\//,''); 24 | } else { 25 | // Otherwise resolve against the current path 26 | newPath = url.resolve(currentPath || '', newPath); 27 | } 28 | 29 | return newPath; 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /base/services/writeFile.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('canonical-path'); 3 | /** 4 | * @dgService writeFile 5 | * @description 6 | * Write the given contents to a file, ensuring the path to the file exists 7 | */ 8 | module.exports = function writeFile() { 9 | return async (file, content) => { 10 | await fs.promises.mkdir(path.dirname(file), {recursive: true}); 11 | await fs.promises.writeFile(file, content); 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /dgeni/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }); 9 | }; 10 | -------------------------------------------------------------------------------- /dgeni/mocks/testPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | const somePackage = new Package('somePackage'); 4 | 5 | /** 6 | * @dgPackage testPackage 7 | */ 8 | module.exports = new Package('testPackage', [require('./testPackage2'), somePackage]) 9 | .processor(require('./testProcessor')) 10 | .processor({ name: 'pseudo', $runAfter: ['testProcessor'] }); -------------------------------------------------------------------------------- /dgeni/mocks/testPackage2.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | /** 4 | * @dgPackage testPackage2 5 | */ 6 | module.exports = new Package('testPackage2', []); -------------------------------------------------------------------------------- /dgeni/mocks/testProcessor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgProcessor testProcessor 3 | */ 4 | module.exports = function testProcessor() { 5 | return { 6 | $runAfter: ['a', 'b'], 7 | $runBefore: ['c','d'], 8 | $validate: { 9 | requiredProp: { presence: true } 10 | }, 11 | $process(docs) {} 12 | }; 13 | }; -------------------------------------------------------------------------------- /dgeni/processors/checkDocsHavePackage.js: -------------------------------------------------------------------------------- 1 | module.exports = function checkDocsHavePackage(createDocMessage) { 2 | return { 3 | $runAfter: ['readPackageInfo'], 4 | $runBefore: ['computing-ids'], 5 | docTypes: ['dgProcessor', 'dgService'], 6 | $process(docs) { 7 | const docTypes = this.docTypes; 8 | docs.forEach(doc => { 9 | if (!doc.packageDoc && docTypes.indexOf(doc.docType) !== -1) { 10 | throw new Error(createDocMessage('Failed to find package for ' + doc.codeName, doc)); 11 | } 12 | }); 13 | } 14 | }; 15 | }; -------------------------------------------------------------------------------- /dgeni/processors/computeProcessorPipeline.js: -------------------------------------------------------------------------------- 1 | const sortByDependency = require('dgeni/lib/util/dependency-sort').sortByDependency; 2 | 3 | module.exports = function computeProcessorPipeline() { 4 | return { 5 | $runAfter: ['readPackageInfo'], 6 | $runBefore: ['rendering-docs'], 7 | $process(docs) { 8 | docs.forEach(doc => { 9 | if (doc.docType === 'dgPackage') { 10 | const processors = collectProcessors(doc); 11 | doc.pipeline = sortByDependency(processors, '$runAfter', '$runBefore'); 12 | } 13 | }); 14 | } 15 | }; 16 | }; 17 | 18 | function collectProcessors(doc) { 19 | const processors = [...doc.processors]; 20 | doc.dependencies.forEach(dependency => { 21 | processors.push(...collectProcessors(dependency)); 22 | }); 23 | return processors; 24 | } 25 | -------------------------------------------------------------------------------- /dgeni/processors/filterJSFileDocs.js: -------------------------------------------------------------------------------- 1 | module.exports = function filterJSFileDocs() { 2 | return { 3 | $runAfter: ['readPackageInfo'], 4 | $runBefore: ['rendering-docs'], 5 | $process(docs) { 6 | return docs.filter(doc => doc.docType !== 'js'); 7 | } 8 | }; 9 | }; -------------------------------------------------------------------------------- /dgeni/processors/generateIndex.js: -------------------------------------------------------------------------------- 1 | module.exports = function generateIndex() { 2 | return { 3 | $runAfter: ['adding-extra-docs'], 4 | $runBefore: ['extra-docs-added'], 5 | $process(docs) { 6 | const indexDoc = { 7 | docType: 'indexPage', 8 | name: 'index', 9 | packages: [] 10 | }; 11 | docs.forEach(doc => { 12 | if (doc.docType === 'dgPackage') { 13 | indexDoc.packages.push(doc); 14 | } 15 | }); 16 | docs.push(indexDoc); 17 | } 18 | }; 19 | }; -------------------------------------------------------------------------------- /dgeni/processors/wireUpServicesToPackages.js: -------------------------------------------------------------------------------- 1 | module.exports = function wireUpServicesToPackages() { 2 | return { 3 | $runAfter: ['readPackageInfo'], 4 | $runBefore: ['checkDocsHavePackage'], 5 | $process(docs) { 6 | 7 | // Build a map of the service name to package doc 8 | const services = {}; 9 | docs.forEach(doc => { 10 | if(doc.docType === 'dgPackage') { 11 | for(const serviceName in doc.package.module) { 12 | services[serviceName] = doc; 13 | } 14 | } 15 | }); 16 | 17 | docs.forEach(doc => { 18 | if(doc.docType === 'dgService' || doc.docType === 'dgProcessor') { 19 | doc.name = doc.name || doc.codeName; 20 | doc.packageDoc = services[doc.name]; 21 | doc.packageDoc.services.push(doc); 22 | } 23 | }); 24 | } 25 | }; 26 | }; 27 | -------------------------------------------------------------------------------- /dgeni/tag-defs/dgPackage.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'dgPackage', 4 | docProperty: 'name', 5 | transforms(doc, tag, value) { 6 | doc.docType = 'dgPackage'; 7 | return value; 8 | } 9 | }; 10 | }; -------------------------------------------------------------------------------- /dgeni/tag-defs/dgProcessor.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'dgProcessor', 4 | docProperty: 'name', 5 | transforms(doc, tag, value) { 6 | doc.docType = 'dgProcessor'; 7 | return value; 8 | } 9 | }; 10 | }; -------------------------------------------------------------------------------- /dgeni/tag-defs/dgService.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'dgService', 4 | docProperty: 'name', 5 | transforms(doc, tag, value) { 6 | doc.docType = 'dgService'; 7 | return value; 8 | } 9 | }; 10 | }; -------------------------------------------------------------------------------- /dgeni/templates/dgPackage.template.md: -------------------------------------------------------------------------------- 1 | # {$ doc.name $} package 2 | 3 | {$ doc.description | marked $} 4 | 5 | ## Dependencies 6 | 7 | {% for dependency in doc.dependencies %} 8 | * {@link {$ dependency.name $} } 9 | {% endfor %} 10 | 11 | 12 | ## Processors 13 | 14 | {% for processor in doc.processors %} 15 | * {@link {$ processor.id $} } 16 | {% endfor %} 17 | 18 | ### Services 19 | 20 | {% for service in doc.services %} 21 | * {$ service.name $} 22 | {% endfor %} 23 | -------------------------------------------------------------------------------- /dgeni/templates/dgProcessor.template.md: -------------------------------------------------------------------------------- 1 | # {$ doc.name $} processor {% if not doc.$process %}*(pseudo)*{% endif %} 2 | ## from {$ doc.packageDoc.name $} package 3 | 4 | {$ doc.description | marked $} 5 | 6 | ## Properties 7 | 8 | {% if doc.$runAfter %} 9 | ### Run After 10 | 11 | {% for processor in doc.$runAfter %} 12 | * {$ processor $} 13 | {% endfor %} 14 | {% endif %} 15 | 16 | {% if doc.$runBefore %} 17 | ### Run Before 18 | 19 | {% for processor in doc.$runBefore %} 20 | * {$ processor $} 21 | {% endfor %} 22 | {% endif %} 23 | 24 | {% if doc.$validate %} 25 | ### Validation 26 | 27 | {% for key, value in doc.$validate %} 28 | * {$ key $} - {$ value | json $} 29 | {% endfor %} 30 | {% endif %} 31 | -------------------------------------------------------------------------------- /dgeni/templates/dgService.template.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular/dgeni-packages/4fac18fb8e03265718a11b52cdcb05e72e9fba0c/dgeni/templates/dgService.template.md -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # docs package 2 | 3 | This package contains templates and configuration to generate some basic API 4 | documentation pages for the dgeni-packages project. 5 | 6 | ## Usage 7 | 8 | Simply ensure that the npm dependencies have been installed: 9 | 10 | ```bash 11 | yarn 12 | ``` 13 | 14 | and then run the docs script in package.json: 15 | 16 | ```bash 17 | yarn docs 18 | ``` 19 | 20 | (behind the scenes this is running `dgeni ./docs`) 21 | 22 | ## Output 23 | 24 | The output of running this package is a set of MarkDown files that 25 | could be pushed to GitHub Pages. The files are save to 26 | 27 | ``` 28 | dgeni-packages/.tmp/docs/... 29 | ``` -------------------------------------------------------------------------------- /docs/RELEASE.md: -------------------------------------------------------------------------------- 1 | # Releasing 2 | 3 | ## Steps 4 | 5 | 1. `npm login https://wombat-dressing-room.appspot.com` 6 | 2. `GITHUB_TOKEN=<..> yarn semantic-release --ci=false` 7 | 3. Push up the changes 8 | -------------------------------------------------------------------------------- /docs/templates/dgPackage.template.md: -------------------------------------------------------------------------------- 1 | {% include 'partials/header.template.md' %} 2 | ## {$ doc.name $} package 3 | 4 | {$ doc.description $} 5 | 6 | ### Dependencies 7 | 8 | {% if doc.dependencies.length %} 9 | This package depends upon: 10 | {% else %} 11 | This package has no dependencies. 12 | {% endif %} 13 | {% for dependency in doc.dependencies %} 14 | * {@link {$ dependency.name $} } 15 | {% endfor %} 16 | 17 | ### Processors 18 | 19 | {% if doc.processors.length %} 20 | Processors that are defined in this package: 21 | {% else %} 22 | There are no processors defined in this package. 23 | {% endif %} 24 | {% for processor in doc.processors %} 25 | * **{@link {$ processor.id $} }** 26 | {$ processor.description $} 27 | {% endfor %} 28 | 29 | ### Services 30 | 31 | {% if doc.services.length %} 32 | Services that are defined in this package: 33 | {% else %} 34 | There are no services defined in this package. 35 | {% endif %} 36 | {% for service in doc.services %} 37 | * **{@link {$ service.id $} }** 38 | {$ service.description $} 39 | {% endfor %} 40 | 41 | ### Pipeline 42 | 43 | The full pipeline of processors for this package: 44 | 45 | {% for p in doc.pipeline %} 46 | * {% if p.$process %}**{% endif %}{@link {$ p.id $} {$ p.name $} }{% if p.$process %}**{% endif %} 47 | ({@link {$ p.packageDoc.id $} {$ p.packageDoc.name $} }){% endfor %} 48 | 49 | -------------------------------------------------------------------------------- /docs/templates/dgProcessor.template.md: -------------------------------------------------------------------------------- 1 | {% include 'partials/header.template.md' %} 2 | ## {$ doc.name $} processor {% if not doc.$process %}*(pseudo)*{% endif %} 3 | **from {@link {$ doc.packageDoc.id $} } package** 4 | 5 | {$ doc.description $} 6 | 7 | ## Properties 8 | 9 | {% if doc.$runAfter %} 10 | ### Run After 11 | 12 | {% for processor in doc.$runAfter %} 13 | * {@link {$ processor $} } 14 | {% endfor %} 15 | {% endif %} 16 | 17 | {% if doc.$runBefore %} 18 | ### Run Before 19 | 20 | {% for processor in doc.$runBefore %} 21 | * {@link {$ processor $} } 22 | {% endfor %} 23 | {% endif %} 24 | 25 | {% if doc.$validate %} 26 | ### Validation 27 | 28 | {% for key, value in doc.$validate %} 29 | * {$ key $} - {$ value | json $} 30 | {% endfor %} 31 | {% endif %} 32 | -------------------------------------------------------------------------------- /docs/templates/dgService.template.md: -------------------------------------------------------------------------------- 1 | {% include 'partials/header.template.md' %} 2 | ## {$ doc.name $} service 3 | **from {@link {$ doc.packageDoc.id $} } package** 4 | 5 | {$ doc.description $} 6 | 7 | -------------------------------------------------------------------------------- /docs/templates/indexPage.template.md: -------------------------------------------------------------------------------- 1 | {% include 'partials/header.template.md' %} 2 | 3 | These docs describe the packages stored in the dgeni-packages project 4 | 5 | ## Packages 6 | 7 | {% for p in doc.packages %} 8 | * {@link {$ p.id $} }
{$ p.description $} 9 | {% endfor %} -------------------------------------------------------------------------------- /docs/templates/partials/header.template.md: -------------------------------------------------------------------------------- 1 | # Dgeni Packages Documentation 2 | 3 | -------------------------------------------------------------------------------- /examples/inline-tag-defs/runnableExample.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService runnableExampleInlineTagDef 3 | * @description 4 | * Inject the specified runnable example into the doc 5 | */ 6 | module.exports = function runnableExampleInlineTagDef(exampleMap, createDocMessage) { 7 | return { 8 | name: 'runnableExample', 9 | 10 | handler(doc, tagName, description) { 11 | 12 | // The tag description should contain the id of the runnable example doc 13 | const example = exampleMap.get(description); 14 | if ( !example ) { 15 | throw new Error(createDocMessage('No example exists with id "' + description + '".', doc)); 16 | } 17 | if ( !example.runnableExampleDoc ) { 18 | throw new Error(createDocMessage('Example "' + description + '" does not have an associated runnableExampleDoc. Are you missing a processor (examples-generate)?"', doc)); 19 | } 20 | 21 | return example.runnableExampleDoc.renderedContent; 22 | } 23 | }; 24 | }; -------------------------------------------------------------------------------- /examples/inline-tag-defs/runnableExample.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | describe("runnableExampleInlineTagDef", () => { 5 | 6 | let exampleMap, tagDef; 7 | 8 | beforeEach(() => { 9 | const dgeni = new Dgeni([mockPackage()]); 10 | const injector = dgeni.configureInjector(); 11 | 12 | exampleMap = injector.get('exampleMap'); 13 | exampleMap.set('some-example', { 14 | runnableExampleDoc: { 15 | renderedContent: 'The rendered content of the some-example example' 16 | } 17 | }); 18 | tagDef = injector.get('runnableExampleInlineTagDef'); 19 | }); 20 | 21 | it("should have the correct name", () => { 22 | expect(tagDef.name).toEqual('runnableExample'); 23 | }); 24 | 25 | it("should lookup the runnableExampleDoc identified in the tag description and return its renderedContent", () => { 26 | expect(tagDef.handler({}, 'runnableExample', 'some-example')).toEqual('The rendered content of the some-example example'); 27 | }); 28 | }); -------------------------------------------------------------------------------- /examples/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../'), require('../../jsdoc')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }) 9 | 10 | // provide a mock template engine for the tests 11 | .factory('templateEngine', function dummyTemplateEngine() {}); 12 | }; 13 | -------------------------------------------------------------------------------- /examples/processors/protractor-generate.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @dgProcessor generateProtractorTestsProcessor 5 | * @description 6 | * Generate a protractor test files from the e2e tests in the examples 7 | */ 8 | module.exports = function generateProtractorTestsProcessor(exampleMap) { 9 | return { 10 | deployments: [], 11 | basePath: '', 12 | $validate: { 13 | deployments: { presence: true }, 14 | }, 15 | $runAfter: ['adding-extra-docs'], 16 | $runBefore: ['extra-docs-added'], 17 | $process(docs) { 18 | 19 | const deployments = this.deployments; 20 | const basePath = this.basePath; 21 | 22 | exampleMap.forEach(example => { 23 | Object.values(example.files || {}).forEach(file => { 24 | // Check if it's a Protractor test. 25 | if (file.type === 'protractor') { 26 | deployments.forEach(deployment => docs.push(createProtractorDoc(example, deployment, file, basePath))); 27 | } 28 | }); 29 | }); 30 | } 31 | }; 32 | }; 33 | 34 | function createProtractorDoc(example, deployment, file, basePath) { 35 | return { 36 | docType: 'e2e-test', 37 | id: 'protractorTest' + '-' + example.id + '-' + deployment.name, 38 | example: example, 39 | deployment: deployment, 40 | template: 'protractorTests.template.js', 41 | innerTest: file.fileContents, 42 | 'ng-app-included': example['ng-app-included'], 43 | basePath: basePath 44 | }; 45 | } -------------------------------------------------------------------------------- /examples/services/exampleMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService exampleMap 3 | * @description 4 | * A map of examples parsed out of the doc content, keyed on 5 | */ 6 | module.exports = function exampleMap() { 7 | return new Map(); 8 | }; -------------------------------------------------------------------------------- /examples/templates/index.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example - {$ doc.id $} 6 | {% for stylesheet in doc.stylesheets %} 7 | {% endfor %} 8 | 9 | {% for script in doc.scripts %} 10 | {% endfor %} 11 | 12 | {% if doc.example.fixBase -%} 13 | 16 | {%- endif %} 17 | 18 | 19 | {$ doc.fileContents $} 20 | 21 | -------------------------------------------------------------------------------- /examples/templates/manifest.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "{$ doc.example.id $}", 3 | "files": [ 4 | "index-production.html" 5 | {%- for file in doc.files %}, 6 | "{$ file $}"{% endfor %} 7 | ] 8 | } -------------------------------------------------------------------------------- /examples/templates/protractorTests.template.js: -------------------------------------------------------------------------------- 1 | describe("{$ doc.description $}", () => { 2 | let rootEl; 3 | beforeEach(() => { 4 | rootEl = browser.rootEl;{% if doc['ng-app-included'] %} 5 | browser.rootEl = '[ng-app]';{% endif %} 6 | browser.get("{$ doc.basePath $}{$ doc.example.deployments[doc.deployment.name].outputPath $}"); 7 | }); 8 | {% if doc['ng-app-included'] %}afterEach(() => { browser.rootEl = rootEl; });{% endif %} 9 | {$ doc.innerTest $} 10 | }); -------------------------------------------------------------------------------- /examples/templates/runnableExample.template.html: -------------------------------------------------------------------------------- 1 | {# Be aware that we need these extra new lines here or marked will not realise that the
2 | is HTML and wrap each line in a

- thus breaking the HTML #} 3 | 4 | 5 |

9 | 10 | {% for fileName, file in doc.example.files %} 11 |
13 | {% code -%} 14 | {$ file.fileContents $} 15 | {%- endcode %} 16 |
17 | {% endfor %} 18 | 19 | 20 |
21 | 22 | 23 | {# Be aware that we need these extra new lines here or marked will not realise that the
24 | above is HTML and wrap each line in a

- thus breaking the HTML #} -------------------------------------------------------------------------------- /examples/templates/template.css: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /examples/templates/template.html: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /examples/templates/template.js: -------------------------------------------------------------------------------- 1 | (function(angular) { 2 | 'use strict'; 3 | {$ doc.fileContents $} 4 | })(window.angular); -------------------------------------------------------------------------------- /examples/templates/template.json: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /examples/templates/template.protractor: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /examples/templates/template.scenario: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /examples/templates/template.spec: -------------------------------------------------------------------------------- 1 | {$ doc.fileContents $} -------------------------------------------------------------------------------- /git/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const path = require('canonical-path'); 4 | const Package = require('dgeni').Package; 5 | 6 | /** 7 | * @dgPackage git 8 | * @description 9 | * Create and export a new Dgeni package called git which provides 10 | * some git and version information to the `extraData` for the 11 | * `renderDocsProcessor`. 12 | */ 13 | module.exports = new Package('git', ['base']) 14 | 15 | .factory(require('./services/decorateVersion')) 16 | .factory(require('./services/getPreviousVersions')) 17 | .factory(require('./services/gitData')) 18 | .factory(require('./services/gitRepoInfo')) 19 | .factory(require('./services/packageInfo')) 20 | .factory(require('./services/versionInfo')) 21 | 22 | .config(function(renderDocsProcessor, gitData) { 23 | renderDocsProcessor.extraData.git = gitData; 24 | }) 25 | 26 | 27 | .config(function(templateFinder) { 28 | templateFinder.templateFolders.unshift(path.resolve(__dirname, 'templates')); 29 | }); 30 | 31 | -------------------------------------------------------------------------------- /git/index.spec.js: -------------------------------------------------------------------------------- 1 | const gitPackage = require('./mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | const mocks = require('./mocks/mocks'); 4 | 5 | describe('git package', () => { 6 | let extraData, dgeni; 7 | beforeEach(() => { 8 | dgeni = new Dgeni([gitPackage()]); 9 | }); 10 | 11 | it("should be instance of Package", () => { 12 | expect(require('./') instanceof Dgeni.Package).toBeTruthy(); 13 | }); 14 | 15 | it("should have factories set", () => { 16 | const injector = dgeni.configureInjector(); 17 | 18 | expect(injector.get('gitData')).toBeDefined(); 19 | expect(injector.get('packageInfo')).toBeDefined(); 20 | expect(injector.get('decorateVersion')).toBeDefined(); 21 | expect(injector.get('versionInfo')).toBeDefined(); 22 | expect(injector.get('gitRepoInfo')).toBeDefined(); 23 | }); 24 | 25 | it("should set extraData.git to gitData", () => { 26 | const injector = dgeni.configureInjector(); 27 | const renderDocsProcessor = injector.get('renderDocsProcessor'); 28 | expect(renderDocsProcessor.extraData.git).toBe(mocks.gitData); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /git/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | const mocks = require('./mocks.js'); 3 | 4 | module.exports = function mockPackage() { 5 | 6 | return new Package('mockPackage', [require('../'), require('../../base')]) 7 | 8 | .factory('decorateVersion', function decorateVersion() { return mocks.decorateVersion; }) 9 | .factory('getPreviousVersions', function getPreviousVersions() { return mocks.getPreviousVersions; }) 10 | .factory('gitData', function gitData() { return mocks.gitData; }) 11 | .factory('gitRepoInfo', function gitRepoInfo() { return mocks.gitRepoInfo; }) 12 | .factory('packageInfo', function packageInfo() { return mocks.packageWithVersion; }) 13 | .factory('versionInfo', function versionInfo() { return mocks.versionInfo; }) 14 | 15 | // provide a mock log service 16 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }) 17 | 18 | // provide a mock template engine for the tests 19 | .factory('templateEngine', function dummyTemplateEngine() {}); 20 | }; 21 | -------------------------------------------------------------------------------- /git/services/decorateVersion.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @dgService decorateVersion 5 | * @description 6 | * A function that decorates the semver with custom properties. 7 | * This version sets some defaults used by the angular.js project. 8 | */ 9 | module.exports = function decorateVersion() { 10 | 11 | /** 12 | * Decorate version with custom properties 13 | * @param {SemVer} version should be a semver version. 14 | */ 15 | return version => { 16 | // angular.js didn't follow semantic version until after 1.2.0rc1 17 | if ((version.major === 1 && version.minor === 0 && version.prerelease.length > 0) || (version.major === 1 && version.minor === 2 && version.prerelease[0] === 'rc1')) { 18 | version.version = [version.major, version.minor, version.patch].join('.') + version.prerelease.join(''); 19 | version.raw = 'v' + version.version; 20 | } 21 | 22 | version.docsUrl = 'http://code.angularjs.org/' + version.version + '/docs'; 23 | 24 | // Versions before 1.0.2 had a different docs folder name 25 | if (version.major < 1 || (version.major === 1 && version.minor === 0 && version.patch < 2)) { 26 | version.docsUrl += '-' + version.version; 27 | version.isOldDocsUrl = true; 28 | } 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /git/services/gitData.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | /** 4 | * @dgService gitData 5 | * @description 6 | * Information from the local git repository 7 | */ 8 | module.exports = function gitData(versionInfo) { 9 | return { 10 | version: versionInfo.currentVersion, 11 | versions: versionInfo.previousVersions, 12 | info: versionInfo.gitRepoInfo 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /git/services/gitData.spec.js: -------------------------------------------------------------------------------- 1 | const mocks = require('../mocks/mocks'); 2 | const mockPackageFactory = require('../mocks/mockPackage'); 3 | const Dgeni = require('dgeni'); 4 | const gitDataFactory = require('./gitData'); 5 | 6 | 7 | 8 | describe("gitData", () => { 9 | let gitData, mockPackage; 10 | 11 | beforeEach(() => { 12 | mockPackage = mockPackageFactory() 13 | .factory(gitDataFactory); 14 | 15 | const dgeni = new Dgeni([mockPackage]); 16 | 17 | const injector = dgeni.configureInjector(); 18 | gitData = injector.get('gitData'); 19 | 20 | }); 21 | 22 | describe("version", () => { 23 | it("should be set to currentVersion of versionInfo", () => { 24 | expect(gitData.version).toEqual(mocks.versionInfo.currentVersion); 25 | }); 26 | }); 27 | 28 | describe("versions", () => { 29 | it("should be set to previousVersions of versionInfo", () => { 30 | expect(gitData.versions).toEqual(mocks.versionInfo.previousVersions); 31 | }); 32 | }); 33 | 34 | describe("info", () => { 35 | it("should be set to gitRepoInfo of versionInfo", () => { 36 | expect(gitData.info).toEqual(mocks.versionInfo.gitRepoInfo); 37 | }); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /git/services/gitRepoInfo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Parse the github URL for useful information 5 | * @return {Object} An object containing the github owner and repository name 6 | */ 7 | module.exports = function gitRepoInfo(packageInfo) { 8 | const GITURL_REGEX = /^(?:git\+https|https?):\/\/[^/]+\/([^/]+)\/(.+).git$/; 9 | const match = GITURL_REGEX.exec(packageInfo.repository.url); 10 | return { 11 | owner: match[1], 12 | repo: match[2] 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /git/services/gitRepoInfo.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackageFactory = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | const gitRepoInfoFactory = require('./gitRepoInfo'); 4 | 5 | describe("gitRepoInfo", () => { 6 | let gitRepoInfo, mockPackage; 7 | 8 | beforeEach(() => { 9 | mockPackage = mockPackageFactory() 10 | .factory(gitRepoInfoFactory); 11 | 12 | const dgeni = new Dgeni([mockPackage]); 13 | 14 | const injector = dgeni.configureInjector(); 15 | gitRepoInfo = injector.get('gitRepoInfo'); 16 | }); 17 | 18 | it("should be set", () => { 19 | expect(gitRepoInfo).not.toBe(null); 20 | }); 21 | 22 | it("should have owner set from package repository url", () => { 23 | expect(gitRepoInfo.owner).toBe('owner'); 24 | }); 25 | 26 | it("should have repo set from package repository url", () => { 27 | expect(gitRepoInfo.repo).toBe('repo'); 28 | }); 29 | 30 | it("should throw an error if packageInfo is empty", () => { 31 | mockPackage.factory(function packageInfo() { 32 | return {}; 33 | }); 34 | const dgeni = new Dgeni([mockPackage]); 35 | const injector = dgeni.configureInjector(); 36 | 37 | expect(() => injector.get('gitRepoInfo')).toThrow(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /git/services/packageInfo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('canonical-path'); 5 | 6 | /** 7 | * Load information about this project from the package.json 8 | * @return {Object} The package information 9 | */ 10 | module.exports = function packageInfo() { 11 | // Search up the folder hierarchy for the first package.json 12 | let packageFolder = path.resolve('.'); 13 | while (!fs.existsSync(path.join(packageFolder, 'package.json'))) { 14 | const parent = path.dirname(packageFolder); 15 | if (parent === packageFolder) { break; } 16 | packageFolder = parent; 17 | } 18 | 19 | return JSON.parse(fs.readFileSync(path.join(packageFolder,'package.json'), 'UTF-8')); 20 | }; 21 | 22 | -------------------------------------------------------------------------------- /git/services/packageInfo.spec.js: -------------------------------------------------------------------------------- 1 | const rewire = require('rewire'); 2 | var packageInfoFactory = rewire('./packageInfo.js'); 3 | 4 | 5 | describe("packageInfo", () => { 6 | let fs, path; 7 | 8 | beforeEach(() => { 9 | fs = packageInfoFactory.__get__('fs'); 10 | path = packageInfoFactory.__get__('path'); 11 | spyOn(path, 'resolve').and.returnValue(''); 12 | spyOn(fs, 'existsSync').and.returnValue(true); 13 | }); 14 | 15 | it('should read package.json as UTF-8', () => { 16 | spyOn(fs, 'readFileSync').and.returnValue('{}'); 17 | 18 | packageInfoFactory(); 19 | 20 | expect(fs.readFileSync).toHaveBeenCalledWith('package.json', 'UTF-8'); 21 | }); 22 | it('should return parsed file contents', () => { 23 | fs.existsSync.and.returnValue(true); 24 | spyOn(fs, 'readFileSync').and.returnValue('{"foo":"bar"}'); 25 | 26 | const packageInfo = packageInfoFactory(); 27 | 28 | expect(packageInfo).toEqual({foo: "bar"}); 29 | }); 30 | 31 | it('should walk up the tree looking for jasmine', () => { 32 | fs.existsSync.and.callFake(file => { 33 | if (file == 'package.json') { 34 | return false; 35 | } else { 36 | return true; 37 | } 38 | }); 39 | 40 | spyOn(fs, 'readFileSync').and.returnValue('{}'); 41 | spyOn(path, 'dirname').and.returnValue('../'); 42 | 43 | packageInfoFactory(); 44 | 45 | expect(fs.readFileSync).toHaveBeenCalledWith('../package.json', 'UTF-8'); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /git/templates/base.template.html: -------------------------------------------------------------------------------- 1 |  Improve this Doc 2 | 3 | {% block content %} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /jsdoc/file-readers/jsdoc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService jsdocFileReader 3 | * @description 4 | * This file reader will create a simple doc for each js 5 | * file including a code AST of the JavaScript in the file. 6 | */ 7 | module.exports = function jsdocFileReader(log, jsParser) { 8 | return { 9 | name: 'jsdocFileReader', 10 | defaultPattern: /\.js$/, 11 | getDocs(fileInfo) { 12 | 13 | try { 14 | fileInfo.ast = jsParser(fileInfo.content); 15 | } catch(ex) { 16 | ex.file = fileInfo.filePath; 17 | throw new Error(`JavaScript error in file "${ex.file}" [line ${ex.lineNumber}, column ${ex.column}]`); 18 | } 19 | 20 | return [{ 21 | docType: 'jsFile' 22 | }]; 23 | } 24 | }; 25 | }; -------------------------------------------------------------------------------- /jsdoc/lib/Tag.js: -------------------------------------------------------------------------------- 1 | function Tag(tagDef, tagName, description, lineNumber) { 2 | this.tagDef = tagDef; 3 | this.tagName = tagName; 4 | this.description = description; 5 | this.startingLine = lineNumber; 6 | } 7 | 8 | module.exports = Tag; -------------------------------------------------------------------------------- /jsdoc/lib/Tag.spec.js: -------------------------------------------------------------------------------- 1 | const Tag = require('./Tag'); 2 | 3 | describe("Tag", () => { 4 | it("should put constructor parameters into member properties", () => { 5 | const tagDef = {}; 6 | const tag = new Tag(tagDef, 'someName', 'a load of content', 12); 7 | expect(tag.tagDef).toBe(tagDef); 8 | expect(tag.tagName).toEqual('someName'); 9 | expect(tag.description).toEqual('a load of content'); 10 | expect(tag.startingLine).toEqual(12); 11 | }); 12 | }); -------------------------------------------------------------------------------- /jsdoc/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }) 9 | 10 | // provide a mock template engine for the tests 11 | .factory('templateEngine', function dummyTemplateEngine() {}); 12 | }; 13 | -------------------------------------------------------------------------------- /jsdoc/processors/code-name.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgProcessor codeNameProcessor 3 | * @description Infer the name of the document from name of the following code 4 | */ 5 | module.exports = function codeNameProcessor(log, codeNameService) { 6 | return { 7 | $runAfter: ['files-read'], 8 | $runBefore: ['processing-docs'], 9 | $process(docs) { 10 | docs.forEach(doc => { 11 | doc.codeName = doc.codeName || (doc.codeNode && codeNameService.find(doc.codeNode)) || null; 12 | if ( doc.codeName ) { 13 | log.silly('found codeName: ', doc.codeName); 14 | } 15 | }); 16 | return docs; 17 | } 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-map.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService codeNameMap 3 | * @description 4 | * A map of AST codeName matchers 5 | */ 6 | module.exports = function codeNameMap() { 7 | return new Map(); 8 | }; -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/array-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ArrayExpressionNodeMatcher 3 | * @description Creates code name matcher for AST entry 4 | */ 5 | module.exports = function ArrayExpressionNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ArrayExpressionNodeMatcher (node) { 11 | return null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/array-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./array-expression'); 2 | 3 | describe('ArrayExpression matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for any argument", () => { 12 | expect(matcher()).toBeNull(); 13 | expect(matcher(null)).toBeNull(); 14 | expect(matcher({})).toBeNull(); 15 | }); 16 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/arrow-function-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ArrowFunctionExpressionNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function ArrowFunctionExpressionNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ArrowFunctionExpressionNodeMatcher (node) { 11 | return null; 12 | }; 13 | }; -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/arrow-function-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./arrow-function-expression'); 2 | 3 | describe('ArrowFunctionExpression matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for any argument", () => { 12 | expect(matcher()).toBeNull(); 13 | expect(matcher(null)).toBeNull(); 14 | expect(matcher({})).toBeNull(); 15 | }); 16 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/assignment-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService AssignmentExpressionNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function AssignmentExpressionNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function AssignmentExpressionNodeMatcher (node) { 11 | return codeNameService.find(node.right) || codeNameService.find(node.left) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/call-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService CallExpressionNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function CallExpressionNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function CallExpressionNodeMatcher (node) { 11 | return codeNameService.find(node.callee) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/call-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./call-expression'); 2 | 3 | describe('CallExpression matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({callee: null})).toBeNull(); 21 | expect(codeNameServiceMock.find.calls.count()).toEqual(2); 22 | }); 23 | 24 | it("should return name for supported node", () => { 25 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 26 | 27 | expect(matcher({callee: 'test'})).toEqual('test'); 28 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 29 | }); 30 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/class-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ClassDeclarationNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function FunctionDeclarationNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ClassDeclarationNodeMatcher (node) { 11 | return node.id && node.id.name || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/class-declaration.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./class-declaration'); 2 | 3 | describe('ClassDeclaration matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({id: null})).toBeNull(); 13 | expect(matcher({id: {}})).toBeNull(); 14 | expect(matcher({id: {name: null}})).toBeNull(); 15 | expect(matcher({id: {name: ""}})).toBeNull(); 16 | }); 17 | 18 | it("should return name for supported node", () => { 19 | expect(matcher({id: {name: "test"}})).toEqual("test"); 20 | }); 21 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/export-default-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ExportDefaultDeclarationNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function ExportDefaultDeclarationNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ExportDefaultDeclarationNodeMatcher (node) { 11 | return codeNameService.find(node.right) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/export-named-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ExportNamedDeclarationNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function ExportNamedDeclarationNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ExportNamedDeclarationNodeMatcher (node) { 11 | return codeNameService.find(node.right) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/expression-statement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ExpressionStatementNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function ExpressionStatementNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ExpressionStatementNodeMatcher (node) { 11 | return codeNameService.find(node.expression) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/expression-statement.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./expression-statement'); 2 | 3 | describe('ExpressionStatement matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({expression: null})).toBeNull(); 21 | expect(codeNameServiceMock.find.calls.count()).toEqual(2); 22 | }); 23 | 24 | it("should return name for supported node", () => { 25 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 26 | 27 | expect(matcher({expression: 'test'})).toEqual('test'); 28 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 29 | }); 30 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/function-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService FunctionDeclarationNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function FunctionDeclarationNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function FunctionDeclarationNodeMatcher (node) { 11 | return node.id && node.id.name || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/function-declaration.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./function-declaration'); 2 | 3 | describe('FunctionDeclaration matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({id: null})).toBeNull(); 13 | expect(matcher({id: {}})).toBeNull(); 14 | expect(matcher({id: {name: null}})).toBeNull(); 15 | expect(matcher({id: {name: ""}})).toBeNull(); 16 | }); 17 | 18 | it("should return name for supported node", () => { 19 | expect(matcher({id: {name: "test"}})).toEqual("test"); 20 | }); 21 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/function-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService FunctionExpressionNodeMatcher 3 | * @returns {String|Null} code name from node 4 | */ 5 | module.exports = function FunctionExpressionNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function FunctionExpressionNodeMatcher (node) { 11 | return node.id && node.id.name || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/function-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./function-expression'); 2 | 3 | describe('FunctionExpression matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({id: null})).toBeNull(); 13 | expect(matcher({id: {}})).toBeNull(); 14 | expect(matcher({id: {name: null}})).toBeNull(); 15 | expect(matcher({id: {name: ""}})).toBeNull(); 16 | }); 17 | 18 | it("should return name for supported node", () => { 19 | expect(matcher({id: {name: "test"}})).toEqual("test"); 20 | }); 21 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/identifier.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService IdentifierNodeMatcher 3 | * @description Creates code name matcher for AST entry 4 | */ 5 | module.exports = function IdentifierNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function IdentifierNodeMatcher (node) { 11 | return node.name || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/identifier.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./identifier'); 2 | 3 | describe('Identifier matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({})).toBeNull(); 13 | expect(matcher({foo: "bar"})).toBeNull(); 14 | }); 15 | 16 | it("should return name for supported node", () => { 17 | expect(matcher({name: "test"})).toEqual("test"); 18 | }); 19 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/import-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ImportDeclarationNodeMatcher 3 | * @description Creates code name matcher for AST entry 4 | */ 5 | module.exports = function ImportDeclarationNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ImportDeclarationNodeMatcher (node) { 11 | return node.source && node.source.value || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/import-declaration.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./import-declaration'); 2 | 3 | describe('ImportDeclaration matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported nodes", () => { 12 | expect(matcher({})).toBeNull(); 13 | expect(matcher({ source: {} })).toBeNull(); 14 | }); 15 | 16 | it("should return a name for supported nodes", () => { 17 | expect(matcher({ source: { value: './file' } })).toBe('./file'); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | require('./array-expression.js'), 3 | require('./arrow-function-expression.js'), 4 | require('./assignment-expression.js'), 5 | require('./call-expression.js'), 6 | require('./class-declaration.js'), 7 | require('./export-default-declaration.js'), 8 | require('./export-named-declaration.js'), 9 | require('./expression-statement.js'), 10 | require('./function-declaration.js'), 11 | require('./function-expression.js'), 12 | require('./identifier.js'), 13 | require('./import-declaration'), 14 | require('./literal.js'), 15 | require('./member-expression.js'), 16 | require('./method-definition.js'), 17 | require('./new-expression.js'), 18 | require('./object-expression.js'), 19 | require('./program.js'), 20 | require('./property.js'), 21 | require('./return-statement.js'), 22 | require('./throw-statement.js'), 23 | require('./variable-declaration.js'), 24 | require('./variable-declarator.js') 25 | ]; 26 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/literal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService LiteralNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function LiteralNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function LiteralNodeMatcher (node) { 11 | return node.value || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/literal.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./literal'); 2 | 3 | describe('Literal matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({})).toBeNull(); 13 | expect(matcher({value: null})).toBeNull(); 14 | expect(matcher({value: ""})).toBeNull(); 15 | }); 16 | 17 | it("should return name for supported node", () => { 18 | expect(matcher({value: "test"})).toEqual("test"); 19 | }); 20 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/member-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService MemberExpressionNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function MemberExpressionNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function MemberExpressionNodeMatcher (node) { 11 | return codeNameService.find(node.property) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/member-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./member-expression'); 2 | 3 | describe('MemberExpression matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 21 | }); 22 | 23 | it("should return name for supported node", () => { 24 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 25 | 26 | expect(matcher({property: 'test'})).toEqual('test'); 27 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 28 | }); 29 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/method-definition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService MethodDefinitionNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function MethodDefinitionNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function MethodDefinitionNodeMatcher (node) { 11 | return codeNameService.find(node.key) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/method-definition.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./method-definition'); 2 | 3 | describe('MethodDefinition matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 21 | }); 22 | 23 | it("should return name for supported node", () => { 24 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 25 | 26 | expect(matcher({key: 'test'})).toEqual('test'); 27 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 28 | }); 29 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/new-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService NewExpressionNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function NewExpressionNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function NewExpressionNodeMatcher (node) { 11 | return codeNameService.find(node.callee) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/new-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./new-expression'); 2 | 3 | describe('NewExpression matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 21 | }); 22 | 23 | it("should return name for supported node", () => { 24 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 25 | 26 | expect(matcher({callee: 'test'})).toEqual('test'); 27 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 28 | }); 29 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/object-expression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ObjectExpressionNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function ObjectExpressionNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ObjectExpressionNodeMatcher (node) { 11 | return null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/object-expression.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./object-expression'); 2 | 3 | describe('ObjectExpression matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for any argument", () => { 12 | expect(matcher()).toBeNull(); 13 | expect(matcher(null)).toBeNull(); 14 | expect(matcher({})).toBeNull(); 15 | }); 16 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/program.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ProgramNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function ProgramNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ProgramNodeMatcher (node) { 11 | return node.body && node.body[0] && codeNameService.find(node.body[0]) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/program.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./program'); 2 | 3 | describe('Program matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({body: null})).toBeNull(); 21 | expect(matcher({body: []})).toBeNull(); 22 | expect(matcher({body: [null, "test"]})).toBeNull(); 23 | expect(codeNameServiceMock.find.calls.count()).toEqual(0); 24 | }); 25 | 26 | it("should return name for supported node", () => { 27 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 28 | 29 | expect(matcher({body: ["test"]})).toEqual("test"); 30 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 31 | }); 32 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/property.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService PropertyNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function PropertyNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function PropertyNodeMatcher (node) { 11 | return codeNameService.find(node.value) || codeNameService.find(node.key); 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/return-statement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ReturnStatementNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function ReturnStatementNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ReturnStatementNodeMatcher (node) { 11 | return codeNameService.find(node.argument) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/return-statement.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./return-statement'); 2 | 3 | describe('ReturnStatement matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({argument: null})).toBeNull(); 21 | expect(codeNameServiceMock.find.calls.count()).toEqual(2); 22 | }); 23 | 24 | it("should return name for supported node", () => { 25 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 26 | 27 | expect(matcher({argument: 'test'})).toEqual('test'); 28 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 29 | }); 30 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/throw-statement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ThrowStatementNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function ThrowStatementNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function ThrowStatementNodeMatcher (node) { 11 | return codeNameService.find(node.argument) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/throw-statement.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./throw-statement'); 2 | 3 | describe('ThrowStatement matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({argument: null})).toBeNull(); 21 | expect(codeNameServiceMock.find.calls.count()).toEqual(2); 22 | }); 23 | 24 | it("should return name for supported node", () => { 25 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 26 | 27 | expect(matcher({argument: 'test'})).toEqual('test'); 28 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 29 | }); 30 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/variable-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService VariableDeclarationNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function VariableDeclarationNodeMatcherFactory (codeNameService) { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function VariableDeclarationNodeMatcher (node) { 11 | return node.declarations && node.declarations[0] && codeNameService.find(node.declarations[0]) || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/variable-declaration.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./variable-declaration'); 2 | 3 | describe('VariableDeclaration matcher', () => { 4 | 5 | let matcher, codeNameServiceMock; 6 | 7 | beforeEach(() => { 8 | codeNameServiceMock = { 9 | find(arg) { 10 | return arg; 11 | } 12 | }; 13 | matcher = matcherFactory(codeNameServiceMock); 14 | }); 15 | 16 | it("should return null for unsupported node", () => { 17 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 18 | 19 | expect(matcher({})).toBeNull(); 20 | expect(matcher({declarations: null})).toBeNull(); 21 | expect(matcher({declarations: []})).toBeNull(); 22 | expect(matcher({declarations: [null, "test"]})).toBeNull(); 23 | expect(codeNameServiceMock.find.calls.count()).toEqual(0); 24 | }); 25 | 26 | it("should return name for supported node", () => { 27 | spyOn(codeNameServiceMock, 'find').and.callThrough(); 28 | 29 | expect(matcher({declarations: ["test"]})).toEqual("test"); 30 | expect(codeNameServiceMock.find.calls.count()).toEqual(1); 31 | }); 32 | }); -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/variable-declarator.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService VariableDeclaratorNodeMatcher 3 | * @description Returns code name from node 4 | */ 5 | module.exports = function VariableDeclaratorNodeMatcherFactory () { 6 | /** 7 | * @param {Node} node AST node to process 8 | * @returns {String|Null} code name from node 9 | */ 10 | return function VariableDeclaratorNodeMatcher (node) { 11 | return node.id && node.id.name || null; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /jsdoc/services/code-name-matchers/variable-declarator.spec.js: -------------------------------------------------------------------------------- 1 | const matcherFactory = require('./variable-declarator'); 2 | 3 | describe('VariableDeclarator matcher', () => { 4 | 5 | let matcher; 6 | 7 | beforeEach(() => { 8 | matcher = matcherFactory(); 9 | }); 10 | 11 | it("should return null for unsupported node", () => { 12 | expect(matcher({id: null})).toBeNull(); 13 | expect(matcher({id: {}})).toBeNull(); 14 | expect(matcher({id: {name: null}})).toBeNull(); 15 | expect(matcher({id: {name: ""}})).toBeNull(); 16 | }); 17 | 18 | it("should return name for supported node", () => { 19 | expect(matcher({id: {name: "test"}})).toEqual("test"); 20 | }); 21 | }); -------------------------------------------------------------------------------- /jsdoc/services/jsParser-config.js: -------------------------------------------------------------------------------- 1 | module.exports = function jsParserConfig() { 2 | return { 3 | 4 | // attach range information to each node 5 | range: true, 6 | 7 | // attach line/column location information to each node 8 | loc: true, 9 | 10 | // create a top-level comments array containing all comments 11 | comment: true, 12 | 13 | // create a top-level tokens array containing all tokens 14 | tokens: true, 15 | 16 | // Set to 3, 5 (default), 6, 7, 8, 9, 10, 11, or 12 to specify the version of ECMAScript syntax you want to use. 17 | // You can also set to 2015 (same as 6), 2016 (same as 7), 2017 (same as 8), 2018 (same as 9), 2019 (same as 10), 2020 (same as 11), or 2021 (same as 12) to use the year-based naming. 18 | ecmaVersion: 8, 19 | 20 | // specify which type of script you're parsing ("script" or "module") 21 | sourceType: "script", 22 | 23 | // specify additional language features 24 | ecmaFeatures: { 25 | 26 | // enable React JSX parsing 27 | jsx: true, 28 | 29 | // enable return in global scope 30 | globalReturn: true, 31 | 32 | // enable implied strict mode (if ecmaVersion >= 5) 33 | impliedStrict: false 34 | } 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /jsdoc/services/jsParser-config.spec.js: -------------------------------------------------------------------------------- 1 | var Dgeni = require('dgeni'); 2 | var mockPackage = require('../mocks/mockPackage'); 3 | 4 | describe('jsParserConfig service', function() { 5 | 6 | var jsParserConfig; 7 | 8 | beforeEach(function() { 9 | var dgeni = new Dgeni([mockPackage()]) 10 | var injector = dgeni.configureInjector(); 11 | jsParserConfig = injector.get('jsParserConfig'); 12 | }); 13 | 14 | it("checks options required by this implementaion", function() { 15 | expect(jsParserConfig.comment).toBe(true); 16 | expect(jsParserConfig.loc).toBe(true); 17 | expect(jsParserConfig.range).toBe(true); 18 | expect(jsParserConfig.tokens).toBe(true); 19 | expect(jsParserConfig.ecmaVersion).toBe(8); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /jsdoc/services/jsParser.js: -------------------------------------------------------------------------------- 1 | var jsParserImpl = require('espree'); 2 | 3 | module.exports = function jsParser(jsParserConfig) { 4 | return code => jsParserImpl.parse(code, jsParserConfig); 5 | }; 6 | -------------------------------------------------------------------------------- /jsdoc/services/parser-adapters/backtick-parser-adapter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A ParserAdapter adapter that ignores tags between triple backtick blocks 3 | */ 4 | module.exports = function backTickParserAdapter() { 5 | return { 6 | init() { 7 | this.inCode = false; 8 | }, 9 | nextLine(line, lineNumber) { 10 | const CODE_FENCE = /^\s*```(?!.*```)/; 11 | if ( CODE_FENCE.test(line) ) { 12 | this.inCode = !this.inCode; 13 | } 14 | }, 15 | parseForTags() { 16 | return !this.inCode; 17 | } 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /jsdoc/services/transforms/boolean-tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Change the value of a tag to a boolean value (used by jsdoc tags like `@async`). 3 | * @param {Tag} tag The tag to process 4 | */ 5 | module.exports = function booleanTagTransform() { 6 | return function(doc, tag, value) { 7 | return value !== null && value !== undefined; 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /jsdoc/services/transforms/boolean-tag.spec.js: -------------------------------------------------------------------------------- 1 | var transformFactory = require('./boolean-tag'); 2 | 3 | describe("boolean-tag transform", function() { 4 | var transform; 5 | 6 | beforeEach(function() { 7 | transform = transformFactory(); 8 | }); 9 | 10 | it("should transform non-null and non-undefined values to `true`", function() { 11 | var doc = {}, tag = {}; 12 | 13 | var value = '', newValue = transform(doc, tag, value); 14 | expect(newValue).toEqual(true); 15 | 16 | var value = 'some text', newValue = transform(doc, tag, value); 17 | expect(newValue).toEqual(true); 18 | 19 | var value = {}, newValue = transform(doc, tag, value); 20 | expect(newValue).toEqual(true); 21 | }); 22 | 23 | it("should transform null and undefined values to `false`", function() { 24 | var doc = {}, tag = {}; 25 | 26 | var value = null, newValue = transform(doc, tag, value); 27 | expect(newValue).toEqual(false); 28 | 29 | var value = undefined, newValue = transform(doc, tag, value); 30 | expect(newValue).toEqual(false); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /jsdoc/services/transforms/extract-name.js: -------------------------------------------------------------------------------- 1 | // Matches: 2 | // name, [name], [name=default], name text, [name] text, [name=default] text, name - text, [name] - text or [name=default] - text 3 | var NAME_AND_DESCRIPTION = /^\s*(\[([^\]=]+)(?:=([^\]]+))?\]|\S+)((?:[ \t]*-\s*|\s+)(\S[\s\S]*))?\s*$/; 4 | 5 | /** 6 | * Extract the name information from a tag 7 | * @param {Tag} tag The tag to process 8 | */ 9 | module.exports = function extractNameTransform() { 10 | return (doc, tag, value) => { 11 | 12 | tag.description = value.replace(NAME_AND_DESCRIPTION, (match, name, optionalName, defaultValue, description, dashDescription) => { 13 | tag.name = optionalName || name; 14 | 15 | if ( optionalName ) { 16 | tag.optional = true; 17 | } 18 | 19 | if ( defaultValue ) { 20 | tag.defaultValue = defaultValue; 21 | } 22 | 23 | const aliasParts = tag.name.split('|'); 24 | tag.name = aliasParts[0]; 25 | tag.alias = aliasParts[1]; 26 | return dashDescription || description || ''; 27 | }); 28 | 29 | return tag.description; 30 | 31 | }; 32 | }; -------------------------------------------------------------------------------- /jsdoc/services/transforms/trim-whitespace.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Trim excess whitespace from the value 3 | */ 4 | module.exports = function trimWhitespaceTransform() { 5 | return (doc, tag, value) => typeof value === 'string' ? value.trim() : value; 6 | }; -------------------------------------------------------------------------------- /jsdoc/services/transforms/trim-whitespace.spec.js: -------------------------------------------------------------------------------- 1 | const transformFactory = require('./trim-whitespace'); 2 | 3 | describe("trim-whitespace", () => { 4 | 5 | let transform; 6 | 7 | beforeEach(() => { 8 | transform = transformFactory(); 9 | }); 10 | 11 | it("should trim newlines and whitespace from the end of the description", () => { 12 | expect(transform({}, {}, 'myId\n\nsome other text \n \n')).toEqual('myId\n\nsome other text'); 13 | }); 14 | 15 | it("should not do anything if the value is not a string", () => { 16 | const someNonStringObject = {}; 17 | expect(transform({}, {}, someNonStringObject)).toEqual(someNonStringObject); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /jsdoc/services/transforms/unknown-tag.js: -------------------------------------------------------------------------------- 1 | module.exports = function unknownTagTransform() { 2 | return (doc, tag, value) => { 3 | if ( !tag.tagDef ) { 4 | tag.errors = tag.errors || []; 5 | tag.errors.push('Unknown tag: ' + tag.tagName); 6 | } 7 | }; 8 | }; -------------------------------------------------------------------------------- /jsdoc/services/transforms/unknown-tag.spec.js: -------------------------------------------------------------------------------- 1 | const transformFactory = require('./unknown-tag'); 2 | 3 | describe("unknown-tag transform", () => { 4 | it("should add an error to the tag if it has no tagDef", () => { 5 | const doc = {}, tag = { tagName: 'bad-tag'}; 6 | const transform = transformFactory(); 7 | transform(doc, tag); 8 | expect(tag.errors).toEqual(['Unknown tag: bad-tag']); 9 | }); 10 | }); -------------------------------------------------------------------------------- /jsdoc/services/transforms/whole-tag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use the whole tag as the value rather than using a tag property, such as `description` 3 | * @param {Tag} tag The tag to process 4 | */ 5 | module.exports = function wholeTagTransform() { 6 | return (doc, tag, value) => { 7 | return tag; 8 | }; 9 | }; -------------------------------------------------------------------------------- /jsdoc/services/transforms/whole-tag.spec.js: -------------------------------------------------------------------------------- 1 | const transformFactory = require('./whole-tag'); 2 | 3 | describe("whole-tag transform", () => { 4 | it("should return the whole tag", () => { 5 | const transform = transformFactory(); 6 | const doc = {}, tag = {}, value = {}; 7 | expect(transform(doc, tag, value)).toBe(tag); 8 | }); 9 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/access.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractAccessTransform) { 2 | extractAccessTransform.accessProperty = 'access'; 3 | extractAccessTransform.accessTagName = 'access'; 4 | return { 5 | name: 'access', 6 | transforms: extractAccessTransform 7 | }; 8 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/access.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./access'); 2 | 3 | describe("access tagDef", () => { 4 | let extractAccessTransform; 5 | 6 | beforeEach(() => { 7 | extractAccessTransform = () => {}; 8 | }); 9 | 10 | it("should have the correct name", () => { 11 | const tagDef = tagDefFactory(extractAccessTransform); 12 | expect(tagDef.name).toEqual('access'); 13 | }); 14 | 15 | it("should add the injected transforms to the transforms property", () => { 16 | const tagDef = tagDefFactory(extractAccessTransform); 17 | expect(tagDef.transforms).toEqual(extractAccessTransform); 18 | }); 19 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/animations.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'animations' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/async.js: -------------------------------------------------------------------------------- 1 | module.exports = function(booleanTagTransform) { 2 | return { 3 | name: 'async', 4 | transforms: [ booleanTagTransform ] 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/class.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'class' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/classdesc.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'classdesc' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/constant.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractNameTransform, wholeTagTransform) { 2 | return { 3 | name: 'constant', 4 | aliases: ['const'], 5 | transforms: [ extractTypeTransform, extractNameTransform, wholeTagTransform ] 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/constructor.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'constructor' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/deprecated.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'deprecated' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/description.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'description', 4 | transforms(doc, tag, value) { 5 | if ( doc.tags.description ) { 6 | value = doc.tags.description + '\n' + value; 7 | } 8 | return value; 9 | }, 10 | defaultFn(doc) { 11 | return doc.tags.description; 12 | } 13 | }; 14 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/description.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./description'); 2 | 3 | describe("description tag-def", () => { 4 | let tagDef; 5 | 6 | beforeEach(() => { 7 | tagDef = tagDefFactory(); 8 | }); 9 | 10 | describe('transforms', () => { 11 | it("should prepend any non-tag specific description found in the jsdoc comment", () => { 12 | const doc = { tags: { description: 'general description'} }; 13 | const tag = {}; 14 | const value = "tag specific description"; 15 | expect(tagDef.transforms(doc, tag, value)).toEqual('general description\ntag specific description'); 16 | }); 17 | }); 18 | 19 | 20 | describe("defaultFn", () => { 21 | it("should get the contents of the non-tag specific description", () => { 22 | const doc = { tags: { description: 'general description'} }; 23 | expect(tagDef.defaultFn(doc)).toEqual('general description'); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/enum.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform) { 2 | return { 3 | name: 'enum', 4 | transforms: [ extractTypeTransform ] 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/function.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'function' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/global.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'global' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = [ 3 | require('./access'), 4 | require('./animations'), 5 | require('./async'), 6 | require('./class'), 7 | require('./classdesc'), 8 | require('./constant'), 9 | require('./constructor'), 10 | require('./deprecated'), 11 | require('./description'), 12 | require('./enum'), 13 | require('./function'), 14 | require('./global'), 15 | require('./kind'), 16 | require('./license'), 17 | require('./memberof'), 18 | require('./method'), 19 | require('./module'), 20 | require('./name'), 21 | require('./namespace'), 22 | require('./param'), 23 | require('./private'), 24 | require('./property'), 25 | require('./propertyof'), 26 | require('./protected'), 27 | require('./public'), 28 | require('./requires'), 29 | require('./returns'), 30 | require('./see'), 31 | require('./since'), 32 | require('./type'), 33 | require('./usage'), 34 | require('./version') 35 | ]; 36 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/index.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactories = require('./'); 2 | 3 | describe("jsdoc tagdefs", () => { 4 | it("should contain an array of tagDef factory functions", () => { 5 | expect(tagDefFactories).toEqual(jasmine.any(Array)); 6 | expect(tagDefFactories.length).toEqual(32); 7 | tagDefFactories.forEach(factory => expect(factory).toEqual(jasmine.any(Function))); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/kind.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'kind' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/license.js: -------------------------------------------------------------------------------- 1 | const spdxLicenseList = require('spdx-license-list/spdx-full'); 2 | 3 | module.exports = function() { 4 | return { 5 | name: 'license', 6 | transforms(doc, tagName, value) { 7 | if (spdxLicenseList[value]) { 8 | doc.licenseDescription = spdxLicenseList[value]; 9 | } 10 | return value; 11 | } 12 | }; 13 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/license.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./license'); 2 | 3 | describe("license tag-def", () => { 4 | let tagDef; 5 | 6 | beforeEach(() => { 7 | tagDef = tagDefFactory(); 8 | }); 9 | 10 | it('should pull in the license detail if it matches the SPDX License List', () => { 11 | const doc = {}; 12 | const result = tagDef.transforms(doc, 'license', 'Apache-2.0'); 13 | expect(result).toEqual('Apache-2.0'); 14 | expect(doc.licenseDescription).toEqual(jasmine.objectContaining({ 15 | "name": "Apache License 2.0", 16 | "url": "http://www.apache.org/licenses/LICENSE-2.0\nhttp://www.opensource.org/licenses/Apache-2.0", 17 | "osiApproved": true 18 | })); 19 | 20 | expect(doc.licenseDescription.license).toContain('Apache License\nVersion 2.0, January 2004'); 21 | }); 22 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/memberof.js: -------------------------------------------------------------------------------- 1 | module.exports = function(createDocMessage) { 2 | return { 3 | name: 'memberof', 4 | defaultFn(doc) { 5 | if ( doc.docType === 'event' || doc.docType === 'property' || doc.docType === 'method' ) { 6 | throw new Error(createDocMessage('Missing tag "@memberof" for doc of type "'+ doc.docType, doc)); 7 | } 8 | }, 9 | transforms(doc, tag, value) { 10 | if ( !(doc.docType === 'event' || doc.docType === 'property' || doc.docType === 'method') ) { 11 | throw new Error(createDocMessage('"@'+ tag.name +'" tag found on non-'+ doc.docType +' document', doc)); 12 | } 13 | return value; 14 | } 15 | }; 16 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/memberof.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | const tagDefFactory = require('./memberof'); 4 | 5 | describe("memberof tag-def", () => { 6 | let tagDef; 7 | 8 | beforeEach(() => { 9 | const dgeni = new Dgeni([mockPackage()]); 10 | const injector = dgeni.configureInjector(); 11 | tagDef = injector.invoke(tagDefFactory); 12 | }); 13 | 14 | describe('transforms', () => { 15 | it("should throw an exception if the docType is not 'event', 'method' or 'property'", () => { 16 | expect(() => tagDef.transforms({ docType: 'unknown'})).toThrowError(); 17 | expect(() => tagDef.transforms({ docType: 'event'})).not.toThrowError(); 18 | expect(() => tagDef.transforms({ docType: 'method'})).not.toThrowError(); 19 | expect(() => tagDef.transforms({ docType: 'property'})).not.toThrowError(); 20 | }); 21 | }); 22 | 23 | 24 | describe("defaultFn", () => { 25 | it("should throw an exception if the docType is 'event', 'method' or 'property'", () => { 26 | expect(() => tagDef.defaultFn({ docType: 'unknown'})).not.toThrowError(); 27 | expect(() => tagDef.defaultFn({ docType: 'event'})).toThrowError(); 28 | expect(() => tagDef.defaultFn({ docType: 'method'})).toThrowError(); 29 | expect(() => tagDef.defaultFn({ docType: 'property'})).toThrowError(); 30 | }); 31 | }); 32 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/method.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'method' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/module.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'module' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/name.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'name' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/namespace.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'namespace' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/param.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractNameTransform, wholeTagTransform) { 2 | return { 3 | name: 'param', 4 | multi: true, 5 | docProperty: 'params', 6 | transforms: [ extractTypeTransform, extractNameTransform, wholeTagTransform ] 7 | }; 8 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/param.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./param'); 2 | 3 | describe('param tagDef', () => { 4 | it("should add the injected transforms to the transforms property", () => { 5 | const extractNameTransform = () => {}; 6 | const extractTypeTransform = () => {}; 7 | const wholeTagTransform = () => {}; 8 | 9 | const tagDef = tagDefFactory(extractTypeTransform, extractNameTransform, wholeTagTransform); 10 | expect(tagDef.transforms).toEqual([extractTypeTransform, extractNameTransform, wholeTagTransform]); 11 | }); 12 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/private.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractAccessTransform) { 2 | extractAccessTransform.allowedTags.set('private'); 3 | return { 4 | name: 'private', 5 | transforms: [extractTypeTransform, extractAccessTransform] 6 | }; 7 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/private.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./private'); 2 | 3 | describe("private tagDef", () => { 4 | let extractAccessTransform, extractTypeTransform, tagDef; 5 | 6 | beforeEach(() => { 7 | extractTypeTransform = () => {}; 8 | extractAccessTransform = () => {}; 9 | extractAccessTransform.allowedTags = new Map(); 10 | tagDef = tagDefFactory(extractTypeTransform, extractAccessTransform); 11 | }); 12 | 13 | it("should have correct name and property", () => { 14 | expect(tagDef.name).toEqual('private'); 15 | }); 16 | 17 | it("should add the injected transforms to the transforms property", () => { 18 | expect(tagDef.transforms).toEqual([extractTypeTransform, extractAccessTransform]); 19 | }); 20 | 21 | it("should record itself in extractAccessTransform service", () => { 22 | expect(extractAccessTransform.allowedTags.has('private')).toBe(true); 23 | expect(extractAccessTransform.allowedTags.get('private')).toBeUndefined(); 24 | }); 25 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/property.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractNameTransform, wholeTagTransform) { 2 | return { 3 | name: 'property', 4 | multi: true, 5 | docProperty: 'properties', 6 | transforms: [ extractTypeTransform, extractNameTransform, wholeTagTransform ] 7 | }; 8 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/property.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./property'); 2 | 3 | describe("property tagDef", () => { 4 | it("should add the injected transforms to the transforms property", () => { 5 | const extractNameTransform = () => {}; 6 | const extractTypeTransform = () => {}; 7 | const wholeTagTransform = () => {}; 8 | 9 | const tagDef = tagDefFactory(extractTypeTransform, extractNameTransform, wholeTagTransform); 10 | expect(tagDef.transforms).toEqual([extractTypeTransform, extractNameTransform, wholeTagTransform]); 11 | }); 12 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/propertyof.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, wholeTagTransform) { 2 | return { 3 | name: 'propertyof', 4 | transforms: [ extractTypeTransform, wholeTagTransform ] 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/propertyof.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./propertyof'); 2 | 3 | describe("propertyof tagDef", () => { 4 | it("should add the injected transforms to the transforms property", () => { 5 | const extractTypeTransform = () => {}; 6 | const wholeTagTransform = () => {}; 7 | 8 | const tagDef = tagDefFactory(extractTypeTransform, wholeTagTransform); 9 | expect(tagDef.transforms).toEqual([extractTypeTransform, wholeTagTransform]); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/protected.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractAccessTransform) { 2 | extractAccessTransform.allowedTags.set('protected'); 3 | return { 4 | name: 'protected', 5 | transforms: [extractTypeTransform, extractAccessTransform] 6 | }; 7 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/protected.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./protected'); 2 | 3 | describe("protected tagDef", () => { 4 | let extractAccessTransform, extractTypeTransform, tagDef; 5 | 6 | beforeEach(() => { 7 | extractTypeTransform = () => {}; 8 | extractAccessTransform = () => {}; 9 | extractAccessTransform.allowedTags = new Map(); 10 | tagDef = tagDefFactory(extractTypeTransform, extractAccessTransform); 11 | }); 12 | 13 | it("should have correct name and property", () => { 14 | expect(tagDef.name).toEqual('protected'); 15 | }); 16 | 17 | it("should add the injected transforms to the transforms property", () => { 18 | expect(tagDef.transforms).toEqual([extractTypeTransform, extractAccessTransform]); 19 | }); 20 | 21 | it("should record itself in extractAccessTransform service", () => { 22 | expect(extractAccessTransform.allowedTags.has('protected')).toBe(true); 23 | expect(extractAccessTransform.allowedTags.get('protected')).toBeUndefined(); 24 | }); 25 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/public.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, extractAccessTransform) { 2 | extractAccessTransform.allowedTags.set('public'); 3 | return { 4 | name: 'public', 5 | transforms: [extractTypeTransform, extractAccessTransform] 6 | }; 7 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/public.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./public'); 2 | 3 | describe("public tagDef", () => { 4 | let extractAccessTransform, extractTypeTransform, tagDef; 5 | 6 | beforeEach(() => { 7 | extractTypeTransform = () => {}; 8 | extractAccessTransform = () => {}; 9 | extractAccessTransform.allowedTags = new Map(); 10 | tagDef = tagDefFactory(extractTypeTransform, extractAccessTransform); 11 | }); 12 | 13 | it("should have correct name and property", () => { 14 | expect(tagDef.name).toEqual('public'); 15 | }); 16 | 17 | it("should add the injected transforms to the transforms property", () => { 18 | expect(tagDef.transforms).toEqual([extractTypeTransform, extractAccessTransform]); 19 | }); 20 | 21 | it("should record itself in extractAccessTransform service", () => { 22 | expect(extractAccessTransform.allowedTags.has('public')).toBe(true); 23 | expect(extractAccessTransform.allowedTags.get('public')).toBeUndefined(); 24 | }); 25 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/requires.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'requires', 4 | multi: true 5 | }; 6 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/returns.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, wholeTagTransform) { 2 | return { 3 | name: 'returns', 4 | aliases: ['return'], 5 | transforms: [ extractTypeTransform, wholeTagTransform ] 6 | }; 7 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/returns.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./returns'); 2 | 3 | describe("returns tagDef", () => { 4 | it("should add the injected transforms to the transforms property", () => { 5 | const extractTypeTransform = () => {}; 6 | const wholeTagTransform = () => {}; 7 | 8 | const tagDef = tagDefFactory(extractTypeTransform, wholeTagTransform); 9 | expect(tagDef.transforms).toEqual([extractTypeTransform, wholeTagTransform]); 10 | }); 11 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/see.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'see', 4 | multi: true 5 | }; 6 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/since.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'since' }; 3 | }; 4 | -------------------------------------------------------------------------------- /jsdoc/tag-defs/type.js: -------------------------------------------------------------------------------- 1 | module.exports = function(extractTypeTransform, wholeTagTransform) { 2 | return { 3 | name: 'type', 4 | transforms: [ extractTypeTransform, wholeTagTransform ] 5 | }; 6 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/type.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./type'); 2 | 3 | describe("type tagDef", () => { 4 | it("should add the injected transforms to the transforms property", () => { 5 | const extractTypeTransform = () => {}; 6 | const wholeTagTransform = () => {}; 7 | 8 | const tagDef = tagDefFactory(extractTypeTransform, wholeTagTransform); 9 | expect(tagDef.transforms).toEqual([extractTypeTransform, wholeTagTransform]); 10 | }); 11 | }); -------------------------------------------------------------------------------- /jsdoc/tag-defs/usage.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'usage' }; 3 | }; -------------------------------------------------------------------------------- /jsdoc/tag-defs/version.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'version' }; 3 | }; 4 | -------------------------------------------------------------------------------- /links/index.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | /** 4 | * @dgPackage links 5 | */ 6 | module.exports = new Package('links', [require('../jsdoc')]) 7 | 8 | .factory(require('./inline-tag-defs/link')) 9 | .factory(require('./services/getAliases')) 10 | .factory(require('./services/getDocFromAlias')) 11 | .factory(require('./services/getLinkInfo')) 12 | 13 | .config(function(inlineTagProcessor, linkInlineTagDef) { 14 | inlineTagProcessor.inlineTagDefinitions.push(linkInlineTagDef); 15 | }); 16 | -------------------------------------------------------------------------------- /links/inline-tag-defs/link.js: -------------------------------------------------------------------------------- 1 | var INLINE_LINK = /(\S+)(?:\s+([\s\S]+))?/; 2 | 3 | /** 4 | * @dgService linkInlineTagDef 5 | * @description 6 | * Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors 7 | * @kind function 8 | * @param {Object} url The url to match 9 | * @param {Function} docs error message 10 | * @return {String} The html link information 11 | * 12 | * @property {boolean} relativeLinks Whether we expect the links to be relative to the originating doc 13 | */ 14 | module.exports = function linkInlineTagDef(getLinkInfo, createDocMessage, log) { 15 | return { 16 | name: 'link', 17 | description: 'Process inline link tags (of the form {@link some/uri Some Title}), replacing them with HTML anchors', 18 | handler(doc, tagName, tagDescription) { 19 | 20 | // Parse out the uri and title 21 | return tagDescription.replace(INLINE_LINK, (match, uri, title) => { 22 | 23 | const linkInfo = getLinkInfo(uri, title, doc); 24 | 25 | if ( !linkInfo.valid ) { 26 | log.warn(createDocMessage(linkInfo.error, doc)); 27 | } 28 | 29 | return '' + linkInfo.title + ''; 30 | }); 31 | } 32 | }; 33 | }; -------------------------------------------------------------------------------- /links/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }) 9 | 10 | // provide a mock template engine for the tests 11 | .factory('templateEngine', function dummyTemplateEngine() {}); 12 | }; 13 | -------------------------------------------------------------------------------- /links/services/getAliases.spec.js: -------------------------------------------------------------------------------- 1 | const getAliasesFactory = require('./getAliases'); 2 | 3 | describe("getAliases", () => { 4 | 5 | it("should extract all the parts from a code name", () => { 6 | 7 | const getAliases = getAliasesFactory(); 8 | 9 | expect(getAliases({ id: 'module:ng.service:$http#get'})).toEqual([ 10 | '$http#get', 11 | 'service:$http#get', 12 | 'ng.$http#get', 13 | 'module:ng.$http#get', 14 | 'ng.service:$http#get', 15 | 'module:ng.service:$http#get', 16 | 'get' 17 | ]); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /links/services/getDocFromAlias.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService getDocFromAlias 3 | * @description Get an array of docs that match this alias, relative to the originating doc. 4 | */ 5 | module.exports = function getDocFromAlias(aliasMap, log) { 6 | 7 | return function getDocFromAlias(alias, originatingDoc) { 8 | let docs = aliasMap.getDocs(alias); 9 | 10 | // If there is more than one item with this name then try to filter them by the originatingDoc's area 11 | if ( docs.length > 1 && originatingDoc && originatingDoc.area) { 12 | docs = docs.filter(doc => doc.area === originatingDoc.area); 13 | } 14 | 15 | // If filtering by area left us with none then let's start again 16 | if ( docs.length === 0 ) { 17 | docs = aliasMap.getDocs(alias); 18 | } 19 | 20 | // If there is more than one item with this name then try to filter them by the originatingDoc's module 21 | if ( docs.length > 1 && originatingDoc && originatingDoc.module ) { 22 | docs = docs.filter(doc => doc.module === originatingDoc.module); 23 | } 24 | 25 | return docs; 26 | }; 27 | }; -------------------------------------------------------------------------------- /ngdoc/file-readers/ngdoc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService ngdocFileReader 3 | * @description 4 | * This file reader will pull the contents from a text file (by default .ngdoc) 5 | * 6 | * The doc will initially have the form: 7 | * ``` 8 | * { 9 | * content: 'the content of the file', 10 | * startingLine: 1 11 | * } 12 | * ``` 13 | */ 14 | module.exports = function ngdocFileReader() { 15 | return { 16 | name: 'ngdocFileReader', 17 | defaultPattern: /\.ngdoc$/, 18 | getDocs(fileInfo) { 19 | // We return a single element array because ngdoc files only contain one document 20 | return [{ 21 | content: fileInfo.content, 22 | startingLine: 1 23 | }]; 24 | } 25 | }; 26 | }; -------------------------------------------------------------------------------- /ngdoc/file-readers/ngdoc.spec.js: -------------------------------------------------------------------------------- 1 | const ngdocFileReaderFactory = require('./ngdoc'); 2 | const path = require('canonical-path'); 3 | 4 | describe("ngdocFileReader", () => { 5 | 6 | let fileReader; 7 | 8 | function createFileInfo(file, content, basePath) { 9 | return { 10 | fileReader: fileReader.name, 11 | filePath: file, 12 | baseName: path.basename(file, path.extname(file)), 13 | extension: path.extname(file).replace(/^\./, ''), 14 | basePath: basePath, 15 | relativePath: path.relative(basePath, file), 16 | content: content 17 | }; 18 | } 19 | 20 | 21 | beforeEach(() => { 22 | fileReader = ngdocFileReaderFactory(); 23 | }); 24 | 25 | 26 | describe("defaultPattern", () => { 27 | it("should match .ngdoc files", () => { 28 | expect(fileReader.defaultPattern.test('abc.ngdoc')).toBeTruthy(); 29 | expect(fileReader.defaultPattern.test('abc.js')).toBeFalsy(); 30 | }); 31 | }); 32 | 33 | 34 | describe("getDocs", () => { 35 | it('should return an object containing info about the file and its contents', () => { 36 | const fileInfo = createFileInfo('foo/bar.ngdoc', 'A load of content', 'base/path'); 37 | expect(fileReader.getDocs(fileInfo)).toEqual([{ 38 | content: 'A load of content', 39 | startingLine: 1 40 | }]); 41 | }); 42 | }); 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /ngdoc/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }); 9 | }; 10 | -------------------------------------------------------------------------------- /ngdoc/processors/collectKnownIssues.js: -------------------------------------------------------------------------------- 1 | module.exports = function collectKnownIssuesProcessor() { 2 | return { 3 | $runAfter: ['moduleDocsProcessor'], 4 | $runBefore: ['computing-paths'], 5 | $process(docs) { 6 | docs 7 | .filter(doc => doc.knownIssues && doc.knownIssues.length) 8 | .forEach(doc => { 9 | const moduleDoc = doc.moduleDoc; 10 | moduleDoc.knownIssueDocs = moduleDoc.knownIssueDocs || []; 11 | moduleDoc.knownIssueDocs.push(doc); 12 | }); 13 | } 14 | }; 15 | }; -------------------------------------------------------------------------------- /ngdoc/processors/collectKnownIssues.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | describe("collectKnownIssuesProcessor", () => { 5 | let processor, moduleMap; 6 | 7 | beforeEach(() => { 8 | const dgeni = new Dgeni([mockPackage()]); 9 | const injector = dgeni.configureInjector(); 10 | processor = injector.get('collectKnownIssuesProcessor'); 11 | }); 12 | 13 | it("should add API docs that have known issues to their module doc", () => { 14 | const module1 = {}; 15 | const module2 = {}; 16 | const docs = [ 17 | { id: 'doc-with-issues-1', moduleDoc: module1, knownIssues: [ 'issue 1', 'issue 2' ] }, 18 | { id: 'doc-with-empty-issues', moduleDoc: module1, knownIssues: [] }, 19 | { id: 'doc-with-no-issues', moduleDoc: module2 }, 20 | { id: 'doc-with-issues-1', moduleDoc: module2, knownIssues: [ 'issue 3', 'issue 4' ] } 21 | ]; 22 | processor.$process(docs); 23 | expect(module1).toEqual({ knownIssueDocs: [docs[0]] }); 24 | expect(module2).toEqual({ knownIssueDocs: [docs[3]] }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /ngdoc/processors/filterNgdocs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgProcessor filterNgDocsProcessor 3 | * @description 4 | * Remove docs that do not contain the ngdoc tag 5 | */ 6 | module.exports = function filterNgDocsProcessor(log) { 7 | return { 8 | $runAfter: ['tags-parsed'], 9 | $runBefore: ['extracting-tags'], 10 | $process(docs) { 11 | const docCount = docs.length; 12 | docs = docs.filter(doc => doc.tags.getTag('ngdoc')); 13 | log.debug('filtered ' + (docCount - docs.length) + ' docs'); 14 | return docs; 15 | } 16 | }; 17 | }; -------------------------------------------------------------------------------- /ngdoc/processors/filterNgdocs.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | function createMockTagCollection(tags) { 5 | return { 6 | getTag(value) { 7 | return tags[value]; 8 | } 9 | }; 10 | } 11 | 12 | 13 | describe("filter-ngdocs doc-processor plugin", () => { 14 | let processor; 15 | 16 | beforeEach(() => { 17 | const dgeni = new Dgeni([mockPackage()]); 18 | const injector = dgeni.configureInjector(); 19 | processor = injector.get('filterNgDocsProcessor'); 20 | }); 21 | 22 | it("should only return docs that have the ngdoc tag", () => { 23 | 24 | const doc1 = { tags: createMockTagCollection({ngdoc: 'a'}) }; 25 | 26 | const doc2 = { tags: createMockTagCollection({other: 'b'}) }; 27 | 28 | const doc3 = { tags: createMockTagCollection({ngdoc: 'c', other: 'd'}) }; 29 | 30 | const doc4 = { tags: createMockTagCollection({}) }; 31 | 32 | const docs = [ doc1, doc2, doc3, doc4 ]; 33 | 34 | const filteredDocs = processor.$process(docs); 35 | 36 | expect(filteredDocs).toEqual([doc1, doc3]); 37 | }); 38 | }); -------------------------------------------------------------------------------- /ngdoc/processors/providerDocs.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgProcessor providerDocsProcessor 3 | * @description 4 | * Connect docs for services to docs for their providers 5 | */ 6 | module.exports = function providerDocsProcessor(log, aliasMap, createDocMessage) { 7 | return { 8 | $runAfter: ['ids-computed', 'memberDocsProcessor'], 9 | $runBefore: ['computing-paths'], 10 | $process(docs) { 11 | 12 | // Map services to their providers 13 | docs.forEach(doc => { 14 | if ( doc.docType === 'provider' ) { 15 | const serviceId = doc.id.replace(/provider:/, 'service:').replace(/Provider$/, ''); 16 | const serviceDocs = aliasMap.getDocs(serviceId); 17 | 18 | if ( serviceDocs.length === 1 ) { 19 | const serviceDoc = serviceDocs[0]; 20 | doc.serviceDoc = serviceDoc; 21 | serviceDoc.providerDoc = doc; 22 | } else if ( serviceDocs.length === 0 ) { 23 | log.warn(createDocMessage('Missing service "' + serviceId + '" for provider', doc)); 24 | } else { 25 | log.warn(createDocMessage('Ambiguous service name "' + serviceId + '" for provider', doc) + '\n' + 26 | serviceDocs.reduce((msg, doc) => `${msg}\n "${doc.id}"`, 'Matching docs: ')); 27 | } 28 | } 29 | }); 30 | } 31 | }; 32 | }; -------------------------------------------------------------------------------- /ngdoc/rendering/filters/code.js: -------------------------------------------------------------------------------- 1 | module.exports = function(encodeCodeBlock) { 2 | return { 3 | name: 'code', 4 | process(str, lang) { 5 | return encodeCodeBlock(str, true, lang); 6 | } 7 | }; 8 | }; -------------------------------------------------------------------------------- /ngdoc/rendering/filters/code.spec.js: -------------------------------------------------------------------------------- 1 | const codeFilterFactory = require('./code'); 2 | 3 | describe("code custom filter", () => { 4 | 5 | let codeFilter, codeSpy; 6 | 7 | beforeEach(() => { 8 | codeSpy = jasmine.createSpy('code').and.callFake(value => '' + value + ''); 9 | codeFilter = codeFilterFactory(codeSpy); 10 | }); 11 | 12 | it("should have the name 'code'", () => { 13 | expect(codeFilter.name).toEqual('code'); 14 | }); 15 | 16 | 17 | it("should call the code utility", () => { 18 | codeFilter.process('function foo() { }'); 19 | expect(codeSpy).toHaveBeenCalledWith('function foo() { }', true, undefined); 20 | }); 21 | 22 | 23 | it("should pass the language to the code utility", () => { 24 | codeFilter.process('function foo() { }', 'js'); 25 | expect(codeSpy).toHaveBeenCalledWith('function foo() { }', true, 'js'); 26 | }); 27 | }); -------------------------------------------------------------------------------- /ngdoc/rendering/filters/link.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'link', 4 | process(url, title, doc) { 5 | return `{@link ${url} ${title || ''} }`; 6 | } 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /ngdoc/rendering/filters/link.spec.js: -------------------------------------------------------------------------------- 1 | const filterFactory = require('./link'); 2 | 3 | describe("link filter", () => { 4 | let filter; 5 | 6 | beforeEach(() => { 7 | filter = filterFactory(); 8 | }); 9 | 10 | it("should have the name 'link'", () => { 11 | expect(filter.name).toEqual('link'); 12 | }); 13 | 14 | it("should inject an inline link tag", () => { 15 | expect(filter.process('URL', 'TITLE')).toEqual('{@link URL TITLE }'); 16 | }); 17 | 18 | it("should omit title when it is undefined", () => { 19 | expect(filter.process('URL', undefined)).toEqual('{@link URL }'); 20 | }); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /ngdoc/rendering/filters/type-class.js: -------------------------------------------------------------------------------- 1 | module.exports = function(getTypeClass) { 2 | return { 3 | name: 'typeClass', 4 | process: getTypeClass 5 | }; 6 | }; -------------------------------------------------------------------------------- /ngdoc/rendering/filters/type-class.spec.js: -------------------------------------------------------------------------------- 1 | const filterFactory = require('./type-class'); 2 | 3 | describe("type-class filter", () => { 4 | it("should call getTypeClass", () => { 5 | const getTypeClassSpy = jasmine.createSpy('getTypeClass'); 6 | const filter = filterFactory(getTypeClassSpy); 7 | 8 | filter.process('object'); 9 | expect(getTypeClassSpy).toHaveBeenCalled(); 10 | }); 11 | }); -------------------------------------------------------------------------------- /ngdoc/rendering/tags/code.js: -------------------------------------------------------------------------------- 1 | module.exports = function(trimIndentation, encodeCodeBlock) { 2 | return { 3 | tags: ['code'], 4 | 5 | parse(parser, nodes) { 6 | const tok = parser.nextToken(); 7 | const args = parser.parseSignature(null, true); 8 | parser.advanceAfterBlockEnd(tok.value); 9 | 10 | const content = parser.parseUntilBlocks("endcode"); 11 | const tag = new nodes.CallExtension(this, 'process', args, [content]); 12 | parser.advanceAfterBlockEnd(); 13 | 14 | return tag; 15 | }, 16 | 17 | process(context, lang, content) { 18 | if ( !content ) { 19 | content = lang; 20 | lang = undefined; 21 | } 22 | const trimmedString = trimIndentation(content()); 23 | const codeString = encodeCodeBlock(trimmedString, false, lang); 24 | return codeString; 25 | } 26 | }; 27 | }; -------------------------------------------------------------------------------- /ngdoc/rendering/tags/code.spec.js: -------------------------------------------------------------------------------- 1 | const codeTagFactory = require('./code'); 2 | const nunjucks = require('nunjucks'); 3 | 4 | describe("code custom tag", () => { 5 | let codeTag, trimIndentationSpy, codeSpy, env; 6 | 7 | beforeEach(() => { 8 | trimIndentationSpy = jasmine.createSpy('trimIndentation').and.callFake(value => value.trim()); 9 | codeSpy = jasmine.createSpy('code'); 10 | codeTag = codeTagFactory(trimIndentationSpy, codeSpy); 11 | 12 | env = nunjucks.configure('views'); 13 | env.addExtension(codeTag.tags[0], codeTag); 14 | }); 15 | 16 | it("should pass the content to the code utility", () => { 17 | env.renderString('\n{% code %}\nfunction() {}\n{% endcode %}\n'); 18 | expect(codeSpy).toHaveBeenCalledWith('function() {}', false, undefined); 19 | }); 20 | 21 | it("should pass the language if provided to the code utility", () => { 22 | env.renderString('\n{% code lang %}\nfunction() {}\n{% endcode %}\n', { lang: 'js' }); 23 | expect(codeSpy).toHaveBeenCalledWith('function() {}', false, 'js'); 24 | }); 25 | }); -------------------------------------------------------------------------------- /ngdoc/services/getTypeClass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService getTypeClass 3 | * @description 4 | * Get a CSS class string for the given type string 5 | */ 6 | module.exports = function getTypeClass() { 7 | return typeStr => { 8 | let typeClass = typeStr.toLowerCase().match(/^[-\w]+/) || []; 9 | typeClass = typeClass[0] ? typeClass[0] : 'object'; 10 | return 'label type-hint type-hint-' + typeClass; 11 | }; 12 | }; -------------------------------------------------------------------------------- /ngdoc/services/getTypeClass.spec.js: -------------------------------------------------------------------------------- 1 | const getTypeClassFactory = require('./getTypeClass'); 2 | 3 | describe("getTypeClass", () => { 4 | it("should convert the type name to a css string", () => { 5 | const getTypeClass = getTypeClassFactory(); 6 | expect(getTypeClass('string')).toEqual('label type-hint type-hint-string'); 7 | expect(getTypeClass('Object')).toEqual('label type-hint type-hint-object'); 8 | expect(getTypeClass('')).toEqual('label type-hint type-hint-object'); 9 | expect(getTypeClass('function() {}')).toEqual('label type-hint type-hint-function'); 10 | expect(getTypeClass('array.')).toEqual('label type-hint type-hint-array'); 11 | }); 12 | }); -------------------------------------------------------------------------------- /ngdoc/services/moduleMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgService moduleMap 3 | * @description 4 | * A collection of modules keyed on the module name 5 | */ 6 | module.exports = function moduleMap() { 7 | return new Map(); 8 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/area.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'area', 4 | defaultFn(doc) { 5 | // Code files are put in the 'api' area 6 | // Other files compute their area from the first path segment 7 | return (doc.fileInfo.extension === 'js') ? 'api' : doc.fileInfo.relativePath.split('/')[0]; 8 | } 9 | }; 10 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/area.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./area'); 2 | 3 | describe("area tag-def", () => { 4 | it("should set default based on fileType", () => { 5 | const tagDef = tagDefFactory(); 6 | expect(tagDef.defaultFn({ fileInfo: { extension: 'js' } })).toEqual('api'); 7 | expect(tagDef.defaultFn({ fileInfo: { relativePath: 'guide/concepts.ngdoc' } })).toEqual('guide'); 8 | }); 9 | }); -------------------------------------------------------------------------------- /ngdoc/tag-defs/element.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'element', 4 | defaultFn(doc) { 5 | if ( doc.docType === 'directive' || doc.docType === 'input') { 6 | return'ANY'; 7 | } 8 | } 9 | }; 10 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/element.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./element'); 2 | 3 | describe("element tag-def", () => { 4 | it("should set default based on docType", () => { 5 | 6 | const tagDef = tagDefFactory(); 7 | expect(tagDef.defaultFn({ docType: 'directive' })).toEqual('ANY'); 8 | expect(tagDef.defaultFn({ docType: 'input' })).toEqual('ANY'); 9 | expect(tagDef.defaultFn({ docType: 'service' })).toBeUndefined(); 10 | 11 | }); 12 | }); -------------------------------------------------------------------------------- /ngdoc/tag-defs/eventType.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'eventType', 4 | transforms(doc, tag, value) { 5 | const EVENTTYPE_REGEX = /^([^\s]*)\s+on\s+([\S\s]*)/; 6 | const match = EVENTTYPE_REGEX.exec(value); 7 | // Attach the target to the doc 8 | doc.eventTarget = match[2]; 9 | // And return the type 10 | return match[1]; 11 | } 12 | }; 13 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/eventType.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./eventType'); 2 | 3 | describe("eventType tag-def", () => { 4 | it("should split into eventType and eventTarget", () => { 5 | const doc = {}, tag = {}; 6 | const tagDef = tagDefFactory(); 7 | const value = tagDef.transforms(doc, tag, 'broadcast on module:ng.directive:ngInclude'); 8 | expect(value).toEqual('broadcast'); 9 | expect(doc.eventTarget).toEqual('module:ng.directive:ngInclude'); 10 | }); 11 | }); -------------------------------------------------------------------------------- /ngdoc/tag-defs/example.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'example', 4 | multi: true, 5 | docProperty: 'examples' 6 | }; 7 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/fullName.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'fullName' }; 3 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/id.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'id' }; 3 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/index.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | require('./ngdoc'), 3 | require('./name'), 4 | require('./area'), 5 | require('./module'), 6 | require('./id'), 7 | require('./restrict'), 8 | require('./eventType'), 9 | require('./example'), 10 | require('./element'), 11 | require('./fullName'), 12 | require('./priority'), 13 | require('./title'), 14 | require('./parent'), 15 | require('./packageName'), 16 | require('./scope'), 17 | require('./multiElement'), 18 | require('./knownIssue') 19 | ]; -------------------------------------------------------------------------------- /ngdoc/tag-defs/knownIssue.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'knownIssue', 4 | multi: true, 5 | docProperty: 'knownIssues' 6 | }; 7 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/module.js: -------------------------------------------------------------------------------- 1 | const path = require('canonical-path'); 2 | 3 | module.exports = function() { 4 | return { 5 | name: 'module', 6 | defaultFn(doc) { 7 | if ( doc.area === 'api' && doc.docType !== 'overview' ) { 8 | return path.dirname(doc.fileInfo.relativePath).split('/')[0]; 9 | } 10 | } 11 | }; 12 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/module.spec.js: -------------------------------------------------------------------------------- 1 | const path = require('canonical-path'); 2 | const tagDefFactory = require('./module'); 3 | 4 | describe("module tag-def", () => { 5 | it("should calculate the module from the second segment of the file path", () => { 6 | const tagDef = tagDefFactory(); 7 | expect(tagDef.defaultFn({ area: 'api', fileInfo: { relativePath: 'ng/service/$http.js' } })).toEqual('ng'); 8 | }); 9 | 10 | it("should use the relative file path", () => { 11 | const tagDef = tagDefFactory(); 12 | const relativePath = 'ng/service/$http.js'; 13 | expect(tagDef.defaultFn({ area: 'api', fileInfo: { filePath: path.resolve(relativePath), relativePath: relativePath } })).toEqual('ng'); 14 | }); 15 | 16 | it("should not calculate module if the doc is not in 'api' area", () => { 17 | const tagDef = tagDefFactory(); 18 | const relativePath = 'guide/concepts.ngdoc'; 19 | expect(tagDef.defaultFn({ area: 'guide', fileInfo: { filePath: path.resolve(relativePath), relativePath: relativePath } })).toBeUndefined(); 20 | }); 21 | 22 | it("should not calculate module if the doc has docType 'overview'", () => { 23 | const tagDef = tagDefFactory(); 24 | const relativePath = 'api/index.ngdoc'; 25 | expect(tagDef.defaultFn({ docType: 'overview', area: 'api', fileInfo: { filePath: path.resolve(relativePath), relativePath: relativePath } })).toBeUndefined(); 26 | }); 27 | }); -------------------------------------------------------------------------------- /ngdoc/tag-defs/multiElement.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'multiElement', 4 | transforms(doc, tag) { return true; } 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /ngdoc/tag-defs/multiElement.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./multiElement'); 2 | 3 | describe("scope tag-def", () => { 4 | it("should transform the value to true", () => { 5 | const tagDef = tagDefFactory(); 6 | expect(tagDef.transforms()).toEqual(true); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /ngdoc/tag-defs/name.js: -------------------------------------------------------------------------------- 1 | module.exports = function(createDocMessage) { 2 | return { 3 | name: 'name', 4 | required: true, 5 | transforms(doc, tag, value) { 6 | const INPUT_TYPE = /input\[(.+)\]/; 7 | if ( doc.docType === 'input' ) { 8 | const match = INPUT_TYPE.exec(value); 9 | if ( !match ) { 10 | throw new Error(createDocMessage('Invalid input directive name. It should be of the form: "input[inputType]" but was "' + value + '"', doc)); 11 | } 12 | doc.inputType = match[1]; 13 | } 14 | return value; 15 | } 16 | }; 17 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/name.spec.js: -------------------------------------------------------------------------------- 1 | const mockPackage = require('../mocks/mockPackage'); 2 | const Dgeni = require('dgeni'); 3 | 4 | const tagDefFactory = require('./name'); 5 | 6 | describe("name tag-def", () => { 7 | let tagDef; 8 | 9 | beforeEach(() => { 10 | const dgeni = new Dgeni([mockPackage()]); 11 | const injector = dgeni.configureInjector(); 12 | tagDef = injector.invoke(tagDefFactory); 13 | }); 14 | 15 | it("should update the inputType if docType is input", () => { 16 | const doc = { docType: 'input' }; 17 | const tag = {}; 18 | const value = tagDef.transforms(doc, tag, 'input[checkbox]'); 19 | expect(value).toEqual('input[checkbox]'); 20 | expect(doc.inputType).toEqual('checkbox'); 21 | }); 22 | 23 | it("should not update the inputType if docType is not input", () => { 24 | const doc = { docType: 'directive' }; 25 | const tag = {}; 26 | const value = tagDef.transforms(doc, tag, 'input[checkbox]'); 27 | expect(value).toEqual('input[checkbox]'); 28 | expect(doc.inputType).toBeUndefined(); 29 | }); 30 | 31 | it("should throw error if the docType is 'input' and the name is not a valid format", () => { 32 | const doc = { docType: 'input' }; 33 | const tag = {}; 34 | expect(() => tagDef.transforms(doc, tag, 'invalidInputName')).toThrow(); 35 | }); 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /ngdoc/tag-defs/ngdoc.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'ngdoc', 4 | required: true, 5 | docProperty: 'docType' 6 | }; 7 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/packageName.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'packageName' }; 3 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/parent.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'parent' }; 3 | }; 4 | -------------------------------------------------------------------------------- /ngdoc/tag-defs/priority.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'priority', 4 | defaultFn(doc) { return 0; } 5 | }; 6 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/priority.spec.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular/dgeni-packages/4fac18fb8e03265718a11b52cdcb05e72e9fba0c/ngdoc/tag-defs/priority.spec.js -------------------------------------------------------------------------------- /ngdoc/tag-defs/restrict.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'restrict', 4 | defaultFn(doc) { 5 | if ( doc.docType === 'directive' || doc.docType === 'input' ) { 6 | return { element: true, attribute: true, cssClass: false, comment: false }; 7 | } 8 | }, 9 | transforms(doc, tag, value) { 10 | value = value || ''; 11 | return { 12 | element: value.indexOf('E') !== -1, 13 | attribute: value.indexOf('A') !== -1, 14 | cssClass: value.indexOf('C') !== -1, 15 | comment: value.indexOf('M') !== -1 16 | }; 17 | } 18 | }; 19 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/scope.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { 3 | name: 'scope', 4 | transforms(doc, tag) { return true; } 5 | }; 6 | }; -------------------------------------------------------------------------------- /ngdoc/tag-defs/scope.spec.js: -------------------------------------------------------------------------------- 1 | const tagDefFactory = require('./scope'); 2 | 3 | describe("scope tag-def", () => { 4 | it("should transform the value to true", () => { 5 | const tagDef = tagDefFactory(); 6 | expect(tagDef.transforms()).toEqual(true); 7 | }); 8 | }); -------------------------------------------------------------------------------- /ngdoc/tag-defs/title.js: -------------------------------------------------------------------------------- 1 | module.exports = function() { 2 | return { name: 'title' }; 3 | }; -------------------------------------------------------------------------------- /ngdoc/templates/api/componentGroup.template.html: -------------------------------------------------------------------------------- 1 | {% block content %} 2 |

3 | {%- if doc.title -%} 4 | {$ doc.title $} 5 | {%- elif doc.moduleName -%} 6 | {$ doc.groupType | title $} components in {$ doc.moduleName | code $} 7 | {%- else -%} 8 | Pages 9 | {%- endif -%} 10 |

11 | 12 | {$ doc.description | marked $} 13 | 14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | {% for page in doc.components %} 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 |
NameDescription
{$ page.id | link(page.name, page) $}{$ page.description | firstParagraph | marked $}
28 |
29 |
30 | 31 | {% endblock %} -------------------------------------------------------------------------------- /ngdoc/templates/api/filter.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {% extends "api/api.template.html" %} 3 | 4 | {% block additional %} 5 |

Usage

6 |

In HTML Template Binding

7 | {% if doc.usage %} 8 | {$ doc.usage | code $} 9 | {% else %} 10 | {% code -%} 11 | {{ {$ doc.name $}_expression | {$ doc.name $} 12 | {%- for param in doc.params %}{% if not loop.first %} : {$ param.name $}{% endif %}{% endfor -%} 13 | }} 14 | {%- endcode %} 15 | {% endif %} 16 | 17 |

In JavaScript

18 | {% code -%} 19 | {%- set sep = joiner(', ') -%} 20 | $filter('{$ doc.name $}')({% for param in doc.params %}{$ sep() $}{$ param.name $}{% endfor -%}) 21 | {%- endcode %} 22 | 23 | {% include "lib/params.template.html" %} 24 | {% include "lib/this.template.html" %} 25 | {% include "lib/returns.template.html" %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /ngdoc/templates/api/function.template.html: -------------------------------------------------------------------------------- 1 | {% extends "api/object.template.html" %} 2 | -------------------------------------------------------------------------------- /ngdoc/templates/api/input.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {% extends "api/directive.template.html" %} 3 | 4 | {% block usage %} 5 |

Usage

6 | {% code %} 7 | 11 | {% endcode %} 12 | {% endblock %} -------------------------------------------------------------------------------- /ngdoc/templates/api/object.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib %} 2 | {% extends "api/api.template.html" %} 3 | 4 | {% block additional %} 5 | 6 | {% if doc.params or doc.returns or doc.this or doc.kind == 'function' -%} 7 |

Usage

8 | {% if doc.usage %} 9 | {$ doc.usage | code $} 10 | {% else %} 11 | {$ lib.functionSyntax(doc) $} 12 | {% endif %} 13 | 14 | {% include "lib/params.template.html" %} 15 | {% include "lib/this.template.html" %} 16 | {% include "lib/returns.template.html" %} 17 | {%- endif %} 18 | 19 | {% include "lib/methods.template.html" %} 20 | {% include "lib/events.template.html" %} 21 | {% include "lib/properties.template.html" %} 22 | 23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /ngdoc/templates/api/provider.template.html: -------------------------------------------------------------------------------- 1 | {% extends "api/object.template.html" %} 2 | 3 | {% block related_components %} 4 | {% if doc.serviceDoc -%} 5 |
  • 6 | - {$ doc.serviceDoc.name $} 7 |
  • 8 | {%- endif %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /ngdoc/templates/api/service.template.html: -------------------------------------------------------------------------------- 1 | {% extends "api/object.template.html" %} 2 | 3 | {% block related_components %} 4 | {% if doc.providerDoc -%} 5 |
  • 6 | - {$ doc.providerDoc.name $} 7 |
  • 8 | {%- endif %} 9 | {% endblock %} 10 | -------------------------------------------------------------------------------- /ngdoc/templates/api/type.template.html: -------------------------------------------------------------------------------- 1 | {% extends "api/object.template.html" %} 2 | -------------------------------------------------------------------------------- /ngdoc/templates/base.template.html: -------------------------------------------------------------------------------- 1 | {% block content %} 2 | {% endblock %} 3 | -------------------------------------------------------------------------------- /ngdoc/templates/lib/events.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {%- if doc.events %} 3 |

    Events

    4 |
      5 | {%- for event in doc.events %} 6 |
    • 7 |

      {$ event.name $}

      8 |
      {$ event.description | marked $}
      9 | {%- if event.eventType == 'listen' %} 10 |
      11 |

      Listen on: {$ event.eventTarget $}

      12 |
      13 | {%- else %} 14 |
      15 |

      Type:

      16 |
      {$ event.eventType $}
      17 |
      18 |
      19 |

      Target:

      20 |
      {$ event.eventTarget $}
      21 |
      22 | {% endif -%} 23 | {%- if event.params %} 24 |
      25 |

      Parameters

      26 | {$ lib.paramTable(event.params) $} 27 |
      28 | {%- endif -%} 29 |
    • 30 | {% endfor -%} 31 |
    32 | {% endif -%} 33 | -------------------------------------------------------------------------------- /ngdoc/templates/lib/methods.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {%- if doc.methods %} 3 |

    Methods

    4 |
      5 | {%- for method in doc.methods %} 6 |
    • 7 |

      {$ lib.functionSyntax(method) $}

      8 |
      {$ method.description | marked $}
      9 | 10 | {% if method.params %} 11 |

      Parameters

      12 | {$ lib.paramTable(method.params) $} 13 | {% endif %} 14 | 15 | {% if method.this %} 16 |

      Method's {% code %}this{% endcode %}

      17 | {$ method.this | marked $} 18 | {% endif %} 19 | 20 | {% if method.returns %} 21 |

      Returns

      22 | {$ lib.typeInfo(method.returns) $} 23 | {% endif %} 24 | 25 |
    • 26 | {% endfor -%} 27 |
    28 | {%- endif -%} 29 | -------------------------------------------------------------------------------- /ngdoc/templates/lib/params.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {%- if doc.params %} 3 |
    4 |

    Arguments

    5 | {$ lib.paramTable(doc.params) $} 6 |
    7 | {%- endif -%} 8 | -------------------------------------------------------------------------------- /ngdoc/templates/lib/properties.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {%- if doc.properties %} 3 |

    Properties

    4 |
      5 | {%- for property in doc.properties %} 6 |
    • 7 |

      {$ property.name | code $}

      8 | {$ lib.typeInfo(property) $} 9 |
    • 10 | {% endfor -%} 11 |
    12 | {%- endif -%} 13 | -------------------------------------------------------------------------------- /ngdoc/templates/lib/returns.template.html: -------------------------------------------------------------------------------- 1 | {% import "lib/macros.html" as lib -%} 2 | {% if doc.returns -%} 3 |

    Returns

    4 | {$ lib.typeInfo(doc.returns) $} 5 | {%- endif %} -------------------------------------------------------------------------------- /ngdoc/templates/lib/this.template.html: -------------------------------------------------------------------------------- 1 | {% if doc.this %} 2 |

    Method's {% code %}this{% endcode %}

    3 | {$ doc.this | marked $} 4 | {% endif %} -------------------------------------------------------------------------------- /ngdoc/templates/overview.template.html: -------------------------------------------------------------------------------- 1 | {% extends "base.template.html" %} 2 | 3 | {% block content %} 4 | {$ doc.description | marked $} 5 | {% endblock %} -------------------------------------------------------------------------------- /nunjucks/index.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | /** 4 | * @dgPackage nunjucks 5 | * @description Provides a template engine powered by Nunjucks 6 | */ 7 | module.exports = new Package('nunjucks', ['base']) 8 | 9 | .factory(require('./services/renderMarkdown')) 10 | .factory(require('./services/nunjucks-template-engine')) 11 | .factory(require('./rendering/tags/marked')) 12 | .factory(require('./rendering/filters/marked')) 13 | 14 | .config(function(templateEngine, markedNunjucksTag, markedNunjucksFilter) { 15 | templateEngine.tags.push(markedNunjucksTag); 16 | templateEngine.filters = templateEngine.filters 17 | .concat(require('./rendering/filters/change-case')) 18 | .concat([ 19 | require('./rendering/filters/first-line'), 20 | require('./rendering/filters/first-paragraph'), 21 | require('./rendering/filters/json'), 22 | markedNunjucksFilter 23 | ]); 24 | }); 25 | -------------------------------------------------------------------------------- /nunjucks/index.spec.js: -------------------------------------------------------------------------------- 1 | const package = require('./'); 2 | 3 | describe('nunjucks package', () => { 4 | 5 | }); -------------------------------------------------------------------------------- /nunjucks/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | const Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../'), require('../../base')]); 6 | 7 | }; 8 | -------------------------------------------------------------------------------- /nunjucks/rendering/filters/change-case.spec.js: -------------------------------------------------------------------------------- 1 | const filters = require('./change-case'); 2 | 3 | const dashCase = filters.find(filter => filter.name === 'dashCase'); 4 | 5 | describe("dashCase custom filter", () => { 6 | it("should have the name 'dashCase'", () => { 7 | expect(dashCase.name).toEqual('dashCase'); 8 | }); 9 | it("should transform the content to dash-case", () => { 10 | expect(dashCase.process('fooBar')).toEqual('foo-bar'); 11 | }); 12 | }); 13 | 14 | -------------------------------------------------------------------------------- /nunjucks/rendering/filters/first-line.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgRenderFilter firstLine 3 | * @description Extract the first line from the value 4 | */ 5 | module.exports = { 6 | name: 'firstLine', 7 | process(str) { 8 | if (!str) return str; 9 | 10 | return str.match(/([^$]*\{@[^}]+\})|.*$/m)[0]; 11 | } 12 | }; -------------------------------------------------------------------------------- /nunjucks/rendering/filters/first-line.spec.js: -------------------------------------------------------------------------------- 1 | const filter = require('./first-line'); 2 | 3 | describe("firstLine filter", () => { 4 | 5 | it("should have the name 'firstLine'", () => { 6 | expect(filter.name).toEqual('firstLine'); 7 | }); 8 | 9 | 10 | it("should return the whole string if it contains only one line", () => { 11 | expect(filter.process('this is a line')).toEqual('this is a line'); 12 | }); 13 | 14 | 15 | it("should return the content up to the first newline", () => { 16 | expect(filter.process('this is a line\nthis is another line')).toEqual('this is a line'); 17 | }); 18 | 19 | 20 | it("should return the contents until inline-tag closes", () => { 21 | expect(filter.process( 22 | 'this is a {@otherTag first line\n' + 23 | 'second line\n'+ 24 | 'third line} more stuff on the third line\n' + 25 | 'this is another line')) 26 | .toEqual( 27 | 'this is a {@otherTag first line\n' + 28 | 'second line\n'+ 29 | 'third line}' 30 | ); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /nunjucks/rendering/filters/first-paragraph.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgRenderFilter firstParagraph 3 | * @description Extract the first paragraph from the value, breaking on the first double newline 4 | */ 5 | module.exports = { 6 | name: 'firstParagraph', 7 | process(str) { 8 | if (!str) return str; 9 | 10 | str = str 11 | .split("\n\n")[0]; 12 | return str; 13 | } 14 | }; -------------------------------------------------------------------------------- /nunjucks/rendering/filters/first-paragraph.spec.js: -------------------------------------------------------------------------------- 1 | const filter = require('./first-paragraph'); 2 | 3 | describe("firstParagraph filter", () => { 4 | it("should have the name 'firstParagraph'", () => { 5 | expect(filter.name).toEqual('firstParagraph'); 6 | }); 7 | it("should return the content up to end of the first paragraph", () => { 8 | expect(filter.process('this is a line\nthis is another line\n\nthis is new paragraph')) 9 | .toEqual('this is a line\nthis is another line'); 10 | }); 11 | }); 12 | 13 | -------------------------------------------------------------------------------- /nunjucks/rendering/filters/json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgRenderFilter json 3 | * @description Convert the object to a JSON string 4 | */ 5 | module.exports = { 6 | name: 'json', 7 | process(obj) { 8 | return JSON.stringify(obj, null, ' '); 9 | } 10 | }; -------------------------------------------------------------------------------- /nunjucks/rendering/filters/json.spec.js: -------------------------------------------------------------------------------- 1 | const filter = require('./json'); 2 | 3 | describe("json filter", () => { 4 | it("should have the name 'json'", () => { 5 | expect(filter.name).toEqual('json'); 6 | }); 7 | it("should return the value stringified into JSON", () => { 8 | expect(filter.process({ prop1: 'val1', prop2: [1,2,3] })) 9 | .toEqual('{\n'+ 10 | ' "prop1": "val1",\n'+ 11 | ' "prop2": [\n' + 12 | ' 1,\n'+ 13 | ' 2,\n'+ 14 | ' 3\n'+ 15 | ' ]\n'+ 16 | '}'); 17 | }); 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /nunjucks/rendering/filters/marked.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgRenderFilter marked 3 | * @description Convert the value, as markdown, into HTML using the marked library 4 | */ 5 | module.exports = function markedNunjucksFilter(renderMarkdown) { 6 | return { 7 | name: 'marked', 8 | process(str) { 9 | const output = str && renderMarkdown(str); 10 | return output; 11 | } 12 | }; 13 | }; -------------------------------------------------------------------------------- /nunjucks/rendering/filters/marked.spec.js: -------------------------------------------------------------------------------- 1 | const Dgeni = require('dgeni'); 2 | const mockPackage = require('../../mocks/mockPackage'); 3 | 4 | describe("marked custom filter", () => { 5 | let filter; 6 | 7 | beforeEach(() => { 8 | const dgeni = new Dgeni([mockPackage()]); 9 | const injector = dgeni.configureInjector(); 10 | 11 | filter = injector.get('markedNunjucksFilter'); 12 | }); 13 | 14 | it("should have the name 'marked'", () => { 15 | expect(filter.name).toEqual('marked'); 16 | }); 17 | 18 | it("should transform the content as markdown trimming excess code indentation", () => { 19 | const result = filter.process( 20 | '## heading 2\n\n' + 21 | 'some paragraph\n\n' + 22 | ' * a bullet point\n\n' + 23 | '```\n' + 24 | ' code\n' + 25 | ' indented code\n' + 26 | ' code\n' + 27 | '```' 28 | ); 29 | expect(result).toEqual( 30 | '

    heading 2

    \n' + 31 | '

    some paragraph

    \n' + 32 | '
      \n' + 33 | '
    • a bullet point
    • \n' + 34 | '
    \n' + 35 | '
    code\n' +
    36 |         '  indented code\n' +
    37 |         'code
    \n' + 38 | '' 39 | ); 40 | }); 41 | }); -------------------------------------------------------------------------------- /nunjucks/rendering/tags/marked.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @dgRenderTag marked 3 | * @description Convert a block of template text from markdown to HTML 4 | */ 5 | module.exports = function markedNunjucksTag(trimIndentation, renderMarkdown) { 6 | return { 7 | tags: ['marked'], 8 | 9 | /** Disable autoescape for this tag because the markdown tag renders HTML that shouldn't be escaped. */ 10 | autoescape: false, 11 | 12 | parse(parser, nodes) { 13 | parser.advanceAfterBlockEnd(); 14 | 15 | const content = parser.parseUntilBlocks("endmarked"); 16 | const tag = new nodes.CallExtension(this, 'process', null, [content]); 17 | parser.advanceAfterBlockEnd(); 18 | 19 | return tag; 20 | }, 21 | 22 | process(context, content) { 23 | const contentString = content(); 24 | const indent = trimIndentation.calcIndent(contentString); 25 | const trimmedString = trimIndentation.trimIndent(contentString, indent); 26 | const markedString = renderMarkdown(trimmedString); 27 | 28 | return trimIndentation.reindent(markedString, indent); 29 | } 30 | }; 31 | }; 32 | -------------------------------------------------------------------------------- /nunjucks/services/nunjucks-template-engine.js: -------------------------------------------------------------------------------- 1 | const nunjucks = require('nunjucks'); 2 | 3 | /** 4 | * @dgService templateEngine 5 | * @description A nunjucks powered template rendering engine 6 | */ 7 | module.exports = function templateEngine(templateFinder) { 8 | 9 | return { 10 | 11 | /** 12 | * Nunjucks specific options, such as using `{$ $}` for nunjucks interpolation 13 | * rather than `{{ }}`, which conflicts with AngularJS 14 | */ 15 | config: {autoescape: false}, 16 | 17 | filters: [], 18 | tags: [], 19 | 20 | getRenderer() { 21 | const loader = new nunjucks.FileSystemLoader(templateFinder.templateFolders, {watch: false, noCache: false}); 22 | const engine = new nunjucks.Environment(loader, this.config); 23 | 24 | // Configure nunjucks with the custom filters 25 | this.filters.forEach(filter => engine.addFilter(filter.name, filter.process)); 26 | 27 | // Configure nunjucks with the custom tags 28 | this.tags.forEach(tag => engine.addExtension(tag.tags[0], tag)); 29 | 30 | return function render(template, data) { 31 | return engine.render(template, data); 32 | }; 33 | } 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /nunjucks/services/renderMarkdown.js: -------------------------------------------------------------------------------- 1 | const marked = require('marked'); 2 | 3 | /** 4 | * @dgService renderMarkdown 5 | * @description 6 | * Render the markdown in the given string as HTML. 7 | */ 8 | module.exports = function renderMarkdown(trimIndentation) { 9 | 10 | const renderer = new marked.Renderer(); 11 | 12 | // Remove the leading whitespace from the code block before it gets to the 13 | // markdown code render function 14 | renderer.code = (code, string, language) => { 15 | 16 | const trimmedCode = trimIndentation(code); 17 | let renderedCode = marked.Renderer.prototype.code.call(renderer, trimmedCode, string, language); 18 | 19 | // Bug in marked - forgets to add a final newline sometimes 20 | if ( !/\n$/.test(renderedCode) ) { 21 | renderedCode += '\n'; 22 | } 23 | 24 | return renderedCode; 25 | }; 26 | 27 | return content => marked(content, { renderer: renderer }); 28 | }; -------------------------------------------------------------------------------- /nunjucks/services/renderMarkdown.spec.js: -------------------------------------------------------------------------------- 1 | const Dgeni = require('dgeni'); 2 | const mockPackage = require('../mocks/mockPackage'); 3 | 4 | describe("renderMarkdown", () => { 5 | 6 | let renderMarkdown, trimIndentation; 7 | 8 | beforeEach(() => { 9 | const dgeni = new Dgeni([mockPackage()]); 10 | const injector = dgeni.configureInjector(); 11 | trimIndentation = injector.get('trimIndentation'); 12 | renderMarkdown = injector.get('renderMarkdown'); 13 | }); 14 | 15 | it("should render the given markdown content as HTML", () => { 16 | const html = renderMarkdown( 17 | '## heading 2\n\n' + 18 | 'some paragraph\n\n' + 19 | '* a bullet point'); 20 | expect(html).toEqual( 21 | '

    heading 2

    \n' + 22 | '

    some paragraph

    \n' + 23 | '
      \n' + 24 | '
    • a bullet point
    • \n' + 25 | '
    \n' 26 | ); 27 | }); 28 | 29 | it("should trim leading whitespace from code blocks", () => { 30 | const html = renderMarkdown( 31 | 'some test\n\n' + 32 | '```\n' + 33 | ' code\n' + 34 | ' indented code\n' + 35 | ' more code\n' + 36 | '```\n\n' + 37 | 'more text' 38 | ); 39 | expect(html).toEqual( 40 | '

    some test

    \n' + 41 | '
    code\n' +
    42 |       '  indented code\n' +
    43 |       'more code
    \n' + 44 | '

    more text

    \n' 45 | ); 46 | 47 | }); 48 | 49 | }); -------------------------------------------------------------------------------- /post-process-html/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.js 2 | **/*.d.ts 3 | **/*.js.map 4 | !types/*.d.ts -------------------------------------------------------------------------------- /post-process-html/.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular/dgeni-packages/4fac18fb8e03265718a11b52cdcb05e72e9fba0c/post-process-html/.npmignore -------------------------------------------------------------------------------- /post-process-html/src/api-doc-types/ApiDoc.ts: -------------------------------------------------------------------------------- 1 | export interface ApiDoc { 2 | docType: string; 3 | renderedContent: string; 4 | vFile: any; 5 | } 6 | -------------------------------------------------------------------------------- /post-process-html/src/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { Package } from 'dgeni'; 2 | 3 | describe('post-process-html package', () => { 4 | it('should be instance of Package', () => { 5 | expect(require('./') instanceof Package).toBeTruthy(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /post-process-html/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Package } from 'dgeni'; 2 | import { postProcessHtml } from './processors/postProcessHtml'; 3 | 4 | /** 5 | * @dgPackage post-process-package 6 | */ 7 | module.exports = new Package('post-process-package', [require('../base')]) 8 | .processor(postProcessHtml); 9 | -------------------------------------------------------------------------------- /post-process-html/src/mocks/mockPackage.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'canonical-path'; 2 | import { Package } from 'dgeni'; 3 | 4 | export function mockPackage(mockTemplateEngine: boolean): Package { 5 | const pkg = new Package('mockPackage', [require('../')]); 6 | 7 | // provide a mock log service 8 | pkg.factory('log', function log() { return require('dgeni/lib/mocks/log')(false); }); 9 | 10 | // overrides base packageInfo and returns the one for the 'angular/dgeni-packages' repo. 11 | const PROJECT_ROOT = path.resolve(__dirname, '../../'); 12 | pkg.factory('packageInfo', function packageInfo() { return require(path.resolve(PROJECT_ROOT, 'package.json')); }); 13 | 14 | if (mockTemplateEngine) { 15 | pkg.factory('templateEngine', function templateEngine() { return {}; }); 16 | } 17 | 18 | return pkg; 19 | } 20 | -------------------------------------------------------------------------------- /post-process-html/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./", /* Redirect output structure to the directory. */ 5 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 6 | "paths": { 7 | "*": [ 8 | "types/*" 9 | ] 10 | }, 11 | "baseUrl": "./", 12 | }, 13 | "include": [ 14 | "src" 15 | ], 16 | "exclude": [ 17 | "mocks" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /post-process-html/types/rehype.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rehype'; 2 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Use this script to run the tests 3 | * We cannot use the Jasmine CLI directly because it doesn't seem to 4 | * understand the glob and only runs one spec file. 5 | * 6 | * Equally we cannot use a jasmine.json config file because it doesn't 7 | * allow us to set the projectBaseDir, which means that you have to run 8 | * jasmine CLI from this directory. 9 | * 10 | * Using a file like this gives us full control and keeps the package.json 11 | * file clean and simple. 12 | */ 13 | 14 | require('source-map-support').install(); 15 | const Jasmine = require('jasmine'); 16 | const jasmine = new Jasmine({ projectBaseDir: __dirname }); 17 | jasmine.loadConfig({ spec_files: ['!(node_modules)/**/*.spec.js'] }); 18 | jasmine.execute(); 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ 4 | "module": "commonjs", /* Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'. */ 5 | "lib": [ /* Specify library files to be included in the compilation: */ 6 | "es2017" 7 | ], 8 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 9 | "sourceMap": true, /* Generates corresponding '.map' file. */ 10 | "strict": true, /* Enable all strict type-checking options. */ 11 | "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 12 | "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 13 | "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */ 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /typescript/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.js 2 | **/*.d.ts 3 | **/*.js.map -------------------------------------------------------------------------------- /typescript/.npmignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angular/dgeni-packages/4fac18fb8e03265718a11b52cdcb05e72e9fba0c/typescript/.npmignore -------------------------------------------------------------------------------- /typescript/mocks/linkInheritedDocs/deps.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:variable-name 2 | import { LastParent, TestInterface } from './index'; 3 | 4 | export class FirstParent extends LastParent implements TestInterface { 5 | firstParentProp: string = 'Works'; 6 | private privateProp: string = 'Private'; 7 | } 8 | -------------------------------------------------------------------------------- /typescript/mocks/linkInheritedDocs/index.ts: -------------------------------------------------------------------------------- 1 | // tslint:disable:no-empty-interface 2 | // tslint:disable:max-classes-per-file 3 | 4 | import { FirstParent } from './deps'; 5 | 6 | /** 7 | * This is just a test interface that has been added to ensure that Dgeni only recognizes 8 | * extends heritages. 9 | */ 10 | export interface TestInterface {} 11 | 12 | export class LastParent implements TestInterface { 13 | lastParentProp: number = 0; 14 | } 15 | 16 | export class Child extends FirstParent implements TestInterface { 17 | childProp: boolean = false; 18 | } 19 | -------------------------------------------------------------------------------- /typescript/mocks/mockPackage.js: -------------------------------------------------------------------------------- 1 | var Package = require('dgeni').Package; 2 | 3 | module.exports = function mockPackage() { 4 | 5 | return new Package('mockPackage', [require('../')]) 6 | 7 | // provide a mock log service 8 | .factory('log', function() { return require('dgeni/lib/mocks/log')(false); }) 9 | .factory('templateEngine', function() { return {}; }); 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/commentContent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @empty 3 | */ 4 | export class SomeClass { 5 | /** 6 | * The description 7 | * @tag1 8 | * tag info 9 | */ 10 | foo: string; 11 | 12 | /** 13 | * @name bar 14 | * @description 15 | * description of bar {@inline-tag} more content 16 | */ 17 | bar(value: any): string; 18 | } 19 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/consts.ts: -------------------------------------------------------------------------------- 1 | class CLASS {} 2 | export const X = 'x'; 3 | export const fun = (foo: string) => true; 4 | export const OBJ = { prop1: true, prop2: 'string' }; 5 | export const INSTANCE = new CLASS(); 6 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/exportAliases.ts: -------------------------------------------------------------------------------- 1 | export class OriginalExport { 2 | sayHello() { 3 | // 4 | } 5 | } 6 | 7 | export {OriginalExport as AliasedExport}; 8 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/functions.ts: -------------------------------------------------------------------------------- 1 | export function foo(val: T): R { 2 | return val as any as R; 3 | } 4 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/gettersAndSetters.ts: -------------------------------------------------------------------------------- 1 | export class Test { 2 | get foo1(): string { return null; } 3 | /** foo1 setter */ 4 | set foo1(value: string) { /* do nothing */} 5 | 6 | set foo2(value: string) { /* do nothing */} 7 | /** foo2 getter */ 8 | get foo2(): string { return null; } 9 | 10 | /** bar getter */ 11 | get bar(): number { return null; } 12 | 13 | /** qux setter */ 14 | set qux(value: object) { /* do nothing */ } 15 | 16 | /** This has no explicit getter return type */ 17 | get noType() { return 'x'; } 18 | /** So we get it from the setter instead */ 19 | set noType(value: string) { /**/ } 20 | 21 | /** Description of myProperty. */ 22 | @SomeDecorator() 23 | set decoratorProp(value: string) {} 24 | get decoratorProp() { return 'Hello'; } 25 | } 26 | 27 | export function SomeDecorator() { 28 | return (target: any, args: any) => {} 29 | } -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/ignoreExportsMatching.ts: -------------------------------------------------------------------------------- 1 | export var __esModule = true; 2 | export class OKToExport {} 3 | export function _thisIsPrivate() {} 4 | export var thisIsOK = '!'; -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/imports.ts: -------------------------------------------------------------------------------- 1 | import { X } from './modules'; 2 | 3 | export const Y = !X; 4 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/interfaces.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | interface Findable {} 3 | export interface MyInterface { 4 | optionalProperty? : string 5 | >(param: T) : U 6 | new (param: number) : MyInterface 7 | } -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/memberAliases.ts: -------------------------------------------------------------------------------- 1 | export class MyClass { 2 | bar: string; 3 | fn() { /* */ } 4 | foo(a: string); 5 | foo(a: number, b: string); 6 | foo(a: string|number, b?: string) { /* empty */} 7 | } 8 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/memberModifiers.ts: -------------------------------------------------------------------------------- 1 | export class ModifierClass { 2 | foo: string; 3 | readonly bar: number; 4 | } 5 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/methodParameters.ts: -------------------------------------------------------------------------------- 1 | export class TestClass { 2 | method1( 3 | /** description of param1 */ param1: number, 4 | /** description of param2 */ param2?: string, 5 | /** description of param3 */ param3: object = {}, 6 | /** description of param4 */ param4 = 'default string', 7 | ) { 8 | /// 9 | } 10 | 11 | /** 12 | * Some description of method 2 13 | * @param param5 description of param5 14 | * @param param6 description of param6 15 | * @param param7 description of param7 16 | */ 17 | method2(param5: string, param6: number, param7 = 42) { 18 | // 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/modules.ts: -------------------------------------------------------------------------------- 1 | export class X { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/multipleDeclarations.ts: -------------------------------------------------------------------------------- 1 | export interface SomeThingConstructor { 2 | (name: string): any; 3 | x?: number; 4 | } 5 | 6 | /** 7 | * the interface doc 8 | */ 9 | export interface SomeThing { 10 | name: string; 11 | count: number; 12 | } 13 | 14 | /** 15 | * the constant doc 16 | */ 17 | export const SomeThing: SomeThingConstructor = (name) => ({ name }); 18 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/orderingOfMembers.ts: -------------------------------------------------------------------------------- 1 | export class Test { 2 | firstItem; 3 | constructor() { this.doStuff(); } 4 | otherMethod() {} 5 | doStuff() {} 6 | } -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/overloadedMembers.ts: -------------------------------------------------------------------------------- 1 | export abstract class TestClass { 2 | constructor(x: string, y: number); 3 | constructor(x: string, y: string, z: number); 4 | constructor(x: string, y: number|string, z?: number) { 5 | // do nothing 6 | } 7 | /** 8 | * String foo 9 | * @other foo 10 | */ 11 | foo(str: string): number; 12 | /** 13 | * Number foo 14 | */ 15 | foo(num1: number, num2: number): number; 16 | 17 | /** 18 | * Actual implementation 19 | */ 20 | foo(num1: number|string, num2?: number) { 21 | return 100; 22 | } 23 | 24 | abstract bar(str: string): number; 25 | abstract bar(): string; 26 | } 27 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/privateMembers.ts: -------------------------------------------------------------------------------- 1 | export class Test { 2 | private privateProperty: any; 3 | protected protectedProperty: any; 4 | public publicProperty: any; 5 | } -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/privateModule.ts: -------------------------------------------------------------------------------- 1 | export var x = 10; -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/publicModule.ts: -------------------------------------------------------------------------------- 1 | export { x as y} from './privateModule'; 2 | 3 | export abstract class AbstractClass {} -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/returnTypes.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | export class Parent { 3 | someProp = { 4 | foo: 'bar', 5 | }; 6 | } 7 | 8 | export class Child extends Parent { 9 | someProp = Object.assign(this.someProp, { 10 | bar: 'baz' 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/spreadParams.ts: -------------------------------------------------------------------------------- 1 | export function test(...args: Array): void {} 2 | 3 | export interface Test { 4 | foo(...args: Array): void; 5 | foo2: (...args: Array) => void; 6 | } 7 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/staticMembers.ts: -------------------------------------------------------------------------------- 1 | export class StaticExports { 2 | /** 3 | * This is the doc for `staticA`. 4 | */ 5 | static staticA(param1: string) { return param1 } 6 | 7 | /** 8 | * This is the doc for `num`. 9 | */ 10 | static num: number; 11 | } -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/stripNamespaces.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-namespace */ 2 | export namespace angular { 3 | export interface IDirective { 4 | name: string; 5 | } 6 | } 7 | 8 | export function someFunctionWithNamespacedReturnValue(x: angular.IDirective): angular.IDirective { 9 | return { 10 | name: 'hello', 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/test/folder/index.ts: -------------------------------------------------------------------------------- 1 | export class TestClass {} 2 | -------------------------------------------------------------------------------- /typescript/mocks/readTypeScriptModules/type-aliases.ts: -------------------------------------------------------------------------------- 1 | export class X { 2 | 3 | } 4 | 5 | export const X2 = X; 6 | export type X2 = X; 7 | 8 | export type Parameterized = X; 9 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/Location.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Some jsdoc comment 3 | */ 4 | export class TestClass { 5 | /** 6 | * A property 7 | */ 8 | property1: string; 9 | /** 10 | * A method 11 | */ 12 | method1() { 13 | // 14 | } 15 | } 16 | 17 | /** 18 | * More comments 19 | */ 20 | export function testFunction() { 21 | return ''; 22 | } 23 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getAccessibility.test.ts: -------------------------------------------------------------------------------- 1 | export class TestClass { 2 | public xee: string; 3 | yuu: string; 4 | protected bar: string; 5 | private foo: string; 6 | } 7 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getContent.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Description of TestClass 3 | * @deprecated warning 4 | */ 5 | export class TestClass { 6 | /** 7 | * Some property 8 | */ 9 | property: string; 10 | 11 | /** 12 | * Some method 13 | */ 14 | method(/** param 1 */ param1: string, param2: number) { 15 | // do nothing 16 | } 17 | } 18 | 19 | // Some non-jsdoc comment 20 | 21 | /* Some other non-jsdoc comment */ 22 | 23 | /** 24 | * Description of function 25 | */ 26 | export function testFunction() { 27 | // do nothing 28 | } 29 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getDeclarationTypeText.test.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:max-classes-per-file */ 2 | 3 | export const testConst = 42; 4 | 5 | export function testFunction(param1: T[]): number { 6 | return 0; 7 | } 8 | 9 | export class TestClass { 10 | prop1: T[]; 11 | prop2 = new OtherClass(); 12 | prop3: OtherClass = new OtherClass(); 13 | method(x: T): T { return x; } 14 | } 15 | 16 | export class OtherClass { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getDecorators.test.ts: -------------------------------------------------------------------------------- 1 | function classDecorator(target: any) { 2 | // do nothing 3 | } 4 | function classDecoratorFactory(foo: string, bar: string, x: Object) { 5 | return classDecorator; 6 | } 7 | function propertyDecorator(target: any, propertyKey: string) { 8 | // do nothing 9 | } 10 | function propertyDecoratorFactory(foo: string, bar: string) { 11 | return propertyDecorator; 12 | } 13 | function methodDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) { 14 | // do nothing 15 | } 16 | function methodDecoratorFactory(foo: string, bar: string) { 17 | return methodDecorator; 18 | } 19 | function paramDecorator(target: any, propertyKey: string | symbol, parameterIndex: number) { 20 | // do nothing 21 | } 22 | function paramDecoratorFactory(foo: string, bar: string) { 23 | return paramDecorator; 24 | } 25 | 26 | /** 27 | * A class "decorated" class 28 | */ 29 | @classDecorator 30 | @classDecoratorFactory('foo', 'bar', { 31 | // some comment that should be ignored 32 | value: 'xxx', 33 | }) 34 | export class TestClass { 35 | /** 36 | * Some property 37 | */ 38 | @propertyDecorator 39 | @propertyDecoratorFactory('foo', /* ignore me */ 'bar') 40 | property: string; 41 | /** 42 | * Some method 43 | */ 44 | @methodDecorator 45 | @methodDecoratorFactory('foo', 'bar') 46 | method(@paramDecorator param1: string, @paramDecoratorFactory('foo','bar') param2: number) { 47 | // do nothing 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getExportDocType.test.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-empty-interface */ 2 | export interface TestInterface { } 3 | export class TestClass {} 4 | /* tslint:disable:no-empty */ 5 | export function testFunction() { } 6 | export enum testEnum {} 7 | export let testLet: string; 8 | export const testConst = 'testConstValue'; 9 | export type TestType = number; 10 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getHeritageClause.test.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-empty-interface */ 2 | /* tslint:disable:max-classes-per-file */ 3 | 4 | export interface Base1 {} 5 | export interface Base2 {} 6 | export interface Test1 extends Base1 {} 7 | export interface Test2 extends Base1, Base2 {} 8 | 9 | export class Base3 {} 10 | export class Test3 extends Base3 {} 11 | export class Test4 implements Base1 {} 12 | export class Test5 implements Base1, Base2 {} 13 | export class Test6 extends Base3 implements Base1 {} 14 | export class Test7 extends Base3 implements Base1, Base2 {} 15 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getParameters.test.ts: -------------------------------------------------------------------------------- 1 | export function testFunction( 2 | a: string, 3 | b: () => number, 4 | c?: Date, 5 | d = 45, 6 | e: string = 'moo', 7 | ...args: string[]) { 8 | // 9 | } 10 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getTypeParametersText.test.ts: -------------------------------------------------------------------------------- 1 | export function testFunction(t: T, u: U, v: V) { 2 | // 3 | } 4 | export class TestClass { 5 | method() { 6 | // 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/getTypeText.test.ts: -------------------------------------------------------------------------------- 1 | export class TestClass {} 2 | export type TestType = TestClass; 3 | export function testFunction(): string { return ''; } 4 | export const testConst: number = 12; 5 | export let testLet: TestType; 6 | export type TestUnion = TestClass | string; 7 | /* tslint:disable:interface-over-type-literal */ 8 | export type TestLiteral = { x: number, y: string }; 9 | /* tslint:disable:array-type */ 10 | export type TestGeneric1 = Array; 11 | export type TestGeneric2 = Array; 12 | 13 | export function function1(): angular.IDirective { 14 | return { name: 'hello' }; 15 | } 16 | 17 | /* tslint:disable:array-type */ 18 | export function function2(): Array { 19 | return [{ name: 'hello' }]; 20 | } 21 | 22 | /* tslint:disable:no-namespace */ 23 | export namespace angular { 24 | export interface IDirective { name: string; } 25 | } 26 | 27 | export type TestType2 = { 28 | a: number; // line comment 29 | /* block comment before */ 30 | b: string; 31 | /* block comment after */ 32 | } & { 33 | a: string; 34 | }; 35 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/importedSrc.ts: -------------------------------------------------------------------------------- 1 | import { MyClass } from './testSrc'; 2 | 3 | export const x = 100; 4 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/multipleLeadingComments.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Not a license comment. 3 | */ 4 | 5 | /** 6 | * This is a test function 7 | */ 8 | export function test(a: string) { 9 | return a; 10 | } 11 | 12 | export function withNoComment(b: string) { 13 | return b; 14 | } 15 | 16 | /** This is the real comment. */ 17 | // This is a comment that shouldn't be documented. 18 | export function withLeadingSingleLineComment(c: string) { 19 | return c; 20 | } 21 | 22 | /** This JSDoc comment should be ignored. */ 23 | /** First real comment. */ 24 | // Non js single line document 25 | /* Non JS-doc document. */ 26 | export function withLeadingNonJsDocComment(c: string) { 27 | return c; 28 | } 29 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/nodeToString.test.ts: -------------------------------------------------------------------------------- 1 | export class TestClass { 2 | // this is a single line comment 3 | someProp: number; 4 | /** This is a jsdoc style comment */ 5 | constructor() { 6 | /* This is a block comment */ 7 | } 8 | foo(/* inline comment */ param1: string) {} 9 | } 10 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/testSrc.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @module 3 | * @description 4 | * This is the module description 5 | */ 6 | 7 | export * from './importedSrc'; 8 | 9 | /** 10 | * This is some random other comment 11 | */ 12 | 13 | /** 14 | * This is MyClass 15 | */ 16 | export class MyClass { 17 | message: String; 18 | 19 | /** 20 | * Create a new MyClass 21 | * @param {String} name The name to say hello to 22 | */ 23 | constructor(name) { this.message = 'hello ' + name; } 24 | 25 | /** 26 | * Return a greeting message 27 | */ 28 | greet() { return this.message; } 29 | } 30 | 31 | /** 32 | * An exported function 33 | */ 34 | export let myFn = (val: number) => val * 2; 35 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/typeToString.ts: -------------------------------------------------------------------------------- 1 | export const a = 'someString'; 2 | 3 | export const b: number = -1; 4 | 5 | export const c = { 6 | LongTypePropA: 'a', 7 | LongTypePropB: 'b', 8 | LongTypePropC: 'c', 9 | LongTypePropD: 'd', 10 | LongTypePropE: 'e', 11 | LongTypePropF: 'f', 12 | LongTypePropG: 'g', 13 | LongTypePropH: 'h', 14 | LongTypePropI: 'i', 15 | LongTypePropJ: 'j', 16 | LongTypePropK: 'k', 17 | LongTypePropL: 'l', 18 | LongTypePropM: 'm', 19 | LongTypePropN: 'n', 20 | }; 21 | -------------------------------------------------------------------------------- /typescript/mocks/tsParser/zone.js/index.ts: -------------------------------------------------------------------------------- 1 | export function test() { 2 | // 3 | } 4 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/AccessorInfoDoc.ts: -------------------------------------------------------------------------------- 1 | import { Declaration } from 'typescript'; 2 | import { Host } from '../services/ts-host/host'; 3 | import { MethodMemberDoc } from './MethodMemberDoc'; 4 | import { PropertyMemberDoc } from './PropertyMemberDoc'; 5 | 6 | /** 7 | * This represents a getter or setter overload of an accessor property. 8 | * There will be a PropertyMemberDoc that contains these docs. 9 | */ 10 | export class AccessorInfoDoc extends MethodMemberDoc { 11 | docType = `${this.accessorType}-accessor-info`; 12 | name = `${this.propertyDoc.name}:${this.accessorType}`; 13 | id = `${this.propertyDoc.id}:${this.accessorType}`; 14 | aliases = this.propertyDoc.aliases.map(alias => `${alias}:${this.accessorType}`); 15 | anchor = this.name; 16 | 17 | constructor(host: Host, 18 | public accessorType: 'get'|'set', 19 | public propertyDoc: PropertyMemberDoc, 20 | declaration: Declaration) { 21 | super(host, propertyDoc.containerDoc, propertyDoc.symbol, declaration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/ConstExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { Symbol, VariableDeclaration } from 'typescript'; 2 | import { Host } from '../services/ts-host/host'; 3 | import { ExportDoc } from './ExportDoc'; 4 | import { ModuleDoc } from './ModuleDoc'; 5 | 6 | export class ConstExportDoc extends ExportDoc { 7 | docType = 'const'; 8 | variableDeclaration = this.declaration as VariableDeclaration; 9 | type = this.getTypeString(this.declaration); 10 | 11 | constructor(host: Host, 12 | moduleDoc: ModuleDoc, 13 | symbol: Symbol, 14 | aliasSymbol?: Symbol) { 15 | super(host, moduleDoc, symbol, symbol.valueDeclaration!, aliasSymbol); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/EnumExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { Declaration, Symbol } from 'typescript'; 2 | import { Host } from '../services/ts-host/host'; 3 | import { ContainerExportDoc } from './ContainerExportDoc'; 4 | import { ModuleDoc } from './ModuleDoc'; 5 | 6 | /** 7 | * Enum docs contain members and can have multiple declaration, which are merged, 8 | * but they cannot have decorators or type parameters 9 | */ 10 | export class EnumExportDoc extends ContainerExportDoc { 11 | docType = 'enum'; 12 | additionalDeclarations: Declaration[] = []; 13 | constructor(host: Host, 14 | moduleDoc: ModuleDoc, 15 | symbol: Symbol, 16 | aliasSymbol?: Symbol) { 17 | super(host, moduleDoc, symbol, symbol.valueDeclaration!, aliasSymbol); 18 | 19 | this.additionalDeclarations = symbol.getDeclarations()!.filter(declaration => declaration !== this.declaration); 20 | if (symbol.exports) { 21 | this.members = this.getMemberDocs(symbol.exports, true); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/ExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { BaseApiDoc } from './ApiDoc'; 2 | 3 | /** 4 | * An export document is an abstraction somewhere between a TypeScript symbol and a declaration 5 | * depending upon the underlying type. 6 | * 7 | * Exported functions can be overloaded and so have one doc per declaration 8 | * Exported interfaces can have multiple declarations, they would be merged together 9 | */ 10 | export abstract class ExportDoc extends BaseApiDoc {} 11 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/InterfaceExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { Declaration, Symbol } from 'typescript'; 2 | import { ClassLikeExportDoc } from '../api-doc-types/ClassLikeExportDoc'; 3 | import { ModuleDoc } from '../api-doc-types/ModuleDoc'; 4 | import { Host } from '../services/ts-host/host'; 5 | 6 | /** 7 | * Interfaces are class-like but can also have multiple declarations that are merged together 8 | */ 9 | export class InterfaceExportDoc extends ClassLikeExportDoc { 10 | docType = 'interface'; 11 | additionalDeclarations: Declaration[] = []; 12 | 13 | constructor(host: Host, 14 | moduleDoc: ModuleDoc, 15 | symbol: Symbol, 16 | aliasSymbol?: Symbol) { 17 | 18 | super(host, moduleDoc, symbol, symbol.valueDeclaration || symbol.getDeclarations()![0]!, 19 | aliasSymbol); 20 | 21 | if (symbol.members) { 22 | this.members = this.getMemberDocs(symbol.members, true); 23 | } 24 | 25 | this.additionalDeclarations = symbol.getDeclarations()! 26 | .filter(declaration => declaration !== this.declaration); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/OverloadInfo.ts: -------------------------------------------------------------------------------- 1 | import { Declaration } from 'typescript'; 2 | import { getDeclarationTypeText } from '../services/TsParser/getDeclarationTypeText'; 3 | import { BaseApiDoc } from './ApiDoc'; 4 | import { FunctionExportDoc } from './FunctionExportDoc'; 5 | import { ModuleDoc } from './ModuleDoc'; 6 | import { getParameters, ParameterContainer } from './ParameterContainer'; 7 | import { ParameterDoc } from './ParameterDoc'; 8 | 9 | /** 10 | * This represents a single overload of an exported function. 11 | * There will be a FunctionExportDoc that contains these overloads 12 | */ 13 | export class OverloadInfo extends BaseApiDoc implements ParameterContainer { 14 | docType = 'function-overload'; 15 | 16 | readonly parameterDocs: ParameterDoc[] = getParameters(this); 17 | readonly parameters = this.parameterDocs.map(p => p.paramText); 18 | 19 | type = getDeclarationTypeText(this.declaration); 20 | containerDoc: ModuleDoc = this.functionDoc.containerDoc; 21 | 22 | constructor(public functionDoc: FunctionExportDoc, declaration: Declaration) { 23 | super(functionDoc.host, functionDoc.moduleDoc, functionDoc.symbol, declaration); 24 | 25 | // Give this overload doc a more specific id and aliases than it's container doc 26 | const paramString = `(${this.parameters.join(', ')})`; 27 | this.id += paramString; 28 | this.aliases = this.aliases.map(alias => alias + paramString); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/ParameterizedExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { Declaration, Symbol } from 'typescript'; 2 | import { Host } from '../services/ts-host/host'; 3 | import { getTypeParametersText } from '../services/TsParser/getTypeParametersText'; 4 | import { ExportDoc } from './ExportDoc'; 5 | import { ModuleDoc } from './ModuleDoc'; 6 | 7 | export abstract class ParameterizedExportDoc extends ExportDoc { 8 | typeParameters = getTypeParametersText(this.declaration); 9 | 10 | constructor(host: Host, 11 | moduleDoc: ModuleDoc, 12 | symbol: Symbol, 13 | declaration: Declaration, 14 | aliasSymbol?: Symbol) { 15 | 16 | super(host, moduleDoc, symbol, declaration, aliasSymbol); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typescript/src/api-doc-types/TypeAliasExportDoc.ts: -------------------------------------------------------------------------------- 1 | import { Declaration, Symbol, SyntaxKind } from 'typescript'; 2 | import { Host } from '../services/ts-host/host'; 3 | import { getDeclarationTypeText } from '../services/TsParser/getDeclarationTypeText'; 4 | import { ModuleDoc } from './ModuleDoc'; 5 | import { ParameterizedExportDoc } from './ParameterizedExportDoc'; 6 | 7 | export class TypeAliasExportDoc extends ParameterizedExportDoc { 8 | docType = 'type-alias'; 9 | typeDefinition = getDeclarationTypeText(this.declaration); 10 | 11 | constructor(host: Host, 12 | moduleDoc: ModuleDoc, 13 | exportSymbol: Symbol, 14 | aliasSymbol?: Symbol) { 15 | 16 | super(host, moduleDoc, exportSymbol, getTypeAliasDeclaration(exportSymbol.getDeclarations()!), 17 | aliasSymbol); 18 | } 19 | } 20 | 21 | function getTypeAliasDeclaration(declarations: Declaration[]) { 22 | return declarations.find(declaration => declaration.kind === SyntaxKind.TypeAliasDeclaration)!; 23 | } 24 | -------------------------------------------------------------------------------- /typescript/src/processors/mergeParameterInfo.ts: -------------------------------------------------------------------------------- 1 | import { DocCollection, Processor } from 'dgeni'; 2 | import { ParameterDoc } from '../api-doc-types/ParameterDoc'; 3 | 4 | /** 5 | * @dgProcessor 6 | * 7 | * @description 8 | * Merge the description from `@param` tags into the parameter docs 9 | * extracted from the TypeScript 10 | */ 11 | export function mergeParameterInfo() { 12 | return new MergeParameterInfoProcessor(); 13 | } 14 | 15 | export class MergeParameterInfoProcessor implements Processor { 16 | $runAfter = ['readTypeScriptModules', 'tags-extracted']; 17 | $runBefore = ['extra-docs-added']; 18 | 19 | $process(docs: DocCollection) { 20 | docs.forEach((doc: ParameterDoc) => { 21 | if (doc.docType === 'parameter') { 22 | // The `params` property comes from parsing the `@param` jsdoc tags on the container doc 23 | const paramTag = doc.container.params && doc.container.params.find((param: any) => param.name === doc.name); 24 | if (paramTag && paramTag.description) { 25 | doc.description = paramTag.description; 26 | } 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /typescript/src/processors/readTypeScriptModules/SourcePattern.ts: -------------------------------------------------------------------------------- 1 | import {sync as globSync} from 'glob'; 2 | // Note that we have to use `require()` here because the `lodash.difference` 3 | // has a `module.exports = difference` style export. 4 | import difference = require('lodash.difference'); 5 | 6 | export interface SourcePattern { 7 | include: string; 8 | exclude?: string; 9 | } 10 | 11 | export function expandSourceFiles(sourceFiles: Array, basePath: string) { 12 | let filePaths: string[] = []; 13 | sourceFiles.forEach(sourcePattern => { 14 | if (isSourcePattern(sourcePattern)) { 15 | const include = globSync(sourcePattern.include, {cwd: basePath}); 16 | const exclude = sourcePattern.exclude ? globSync(sourcePattern.exclude, {cwd: basePath}) : []; 17 | filePaths = filePaths.concat(difference(include, exclude)); 18 | } else { 19 | filePaths = filePaths.concat(globSync(sourcePattern, {cwd: basePath})); 20 | } 21 | }); 22 | return filePaths; 23 | } 24 | 25 | function isSourcePattern(pattern: any): pattern is SourcePattern { 26 | return !!pattern.include; 27 | } 28 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/FileInfo.ts: -------------------------------------------------------------------------------- 1 | import { Declaration } from 'typescript'; 2 | import { Location } from './Location'; 3 | import { realpathSync } from 'fs'; 4 | const path = require('canonical-path'); 5 | 6 | /** 7 | * The file (and the location in the file) from where an API doc element was sourced. 8 | */ 9 | export class FileInfo { 10 | location = new Location(this.declaration); 11 | filePath = path.resolve(this.basePath, this.declaration.getSourceFile().fileName); 12 | baseName = path.basename(this.filePath, path.extname(this.filePath)); 13 | extension = path.extname(this.filePath).replace(/^\./, ''); 14 | relativePath = path.relative(this.basePath, this.filePath); 15 | projectRelativePath = this.relativePath; 16 | realFilePath = this.getRealFilePath(this.filePath); 17 | realProjectRelativePath = path.relative(this.basePath, this.realFilePath); 18 | 19 | constructor( 20 | private declaration: Declaration, 21 | public basePath: string) { 22 | } 23 | 24 | getRealFilePath(filePath: string): string { 25 | return realpathSync(filePath).replace(RegExp('\\' + path.sep, 'g'), '/'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/LineFeedPrinter.ts: -------------------------------------------------------------------------------- 1 | import { createPrinter, NewLineKind, Printer } from 'typescript'; 2 | 3 | /** 4 | * Platform consistent TypeScript printer instance. By default, TypeScript will use the 5 | * new-line kind based on the operating system (e.g. Windows will use CRLF). 6 | */ 7 | export const lineFeedPrinter: Printer = createPrinter({ 8 | newLine: NewLineKind.LineFeed, 9 | removeComments: true, 10 | }); 11 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/Location.ts: -------------------------------------------------------------------------------- 1 | import { getLineAndCharacterOfPosition, LineAndCharacter, Node } from 'typescript'; 2 | 3 | export class Location { 4 | start: LineAndCharacter; 5 | end: LineAndCharacter; 6 | 7 | constructor(declaration: Node) { 8 | const sourceFile = declaration.getSourceFile(); 9 | this.start = getLineAndCharacterOfPosition(sourceFile, declaration.pos); 10 | this.end = getLineAndCharacterOfPosition(sourceFile, declaration.end); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getAccessibility.spec.ts: -------------------------------------------------------------------------------- 1 | import { __String } from 'typescript'; 2 | import { TsParser } from '.'; 3 | import { getAccessibility } from './getAccessibility'; 4 | const path = require('canonical-path'); 5 | 6 | describe('getAccessibility', () => { 7 | let parser: TsParser; 8 | let basePath: string; 9 | beforeEach(() => { 10 | parser = new TsParser(require('dgeni/lib/mocks/log')(false)); 11 | basePath = path.resolve(__dirname, '../../mocks'); 12 | }); 13 | 14 | it('should return the accessibility of class members', () => { 15 | const parseInfo = parser.parse(['tsParser/getAccessibility.test.ts'], basePath); 16 | 17 | const module = parseInfo.moduleSymbols[0]; 18 | const testClassMembers = module.exportArray[0].members!; 19 | 20 | const xee = testClassMembers.get('xee' as __String)!; 21 | expect(getAccessibility(xee.declarations![0])).toEqual('public'); 22 | const yuu = testClassMembers.get('yuu' as __String)!; 23 | expect(getAccessibility(yuu.declarations![0])).toEqual('public'); 24 | const bar = testClassMembers.get('bar' as __String)!; 25 | expect(getAccessibility(bar.declarations![0])).toEqual('protected'); 26 | const foo = testClassMembers.get('foo' as __String)!; 27 | expect(getAccessibility(foo.declarations![0])).toEqual('private'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getAccessibility.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-bitwise */ 2 | import { Declaration, getCombinedModifierFlags, ModifierFlags } from 'typescript'; 3 | 4 | export function getAccessibility(declaration?: Declaration) { 5 | if (declaration) { 6 | const flags = getCombinedModifierFlags(declaration); 7 | if (flags & ModifierFlags.Private) { 8 | return 'private'; 9 | } 10 | if (flags & ModifierFlags.Protected) { 11 | return 'protected'; 12 | } 13 | } 14 | return 'public'; 15 | } 16 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getExportDocType.spec.ts: -------------------------------------------------------------------------------- 1 | import { TsParser } from '.'; 2 | import { getExportDocType } from './getExportDocType'; 3 | const path = require('canonical-path'); 4 | 5 | describe('getExportDocType', () => { 6 | let parser: TsParser; 7 | let basePath: string; 8 | beforeEach(() => { 9 | parser = new TsParser(require('dgeni/lib/mocks/log')(false)); 10 | basePath = path.resolve(__dirname, '../../mocks'); 11 | }); 12 | 13 | it('should return the accessibility of class members', () => { 14 | const parseInfo = parser.parse(['tsParser/getExportDocType.test.ts'], basePath); 15 | 16 | const moduleExports = parseInfo.moduleSymbols[0].exportArray; 17 | expect(moduleExports.length).toEqual(7); 18 | 19 | const docTypes = moduleExports.map(e => getExportDocType(e)); 20 | expect(docTypes).toContain('interface'); 21 | expect(docTypes).toContain('class'); 22 | expect(docTypes).toContain('function'); 23 | expect(docTypes).toContain('enum'); 24 | expect(docTypes).toContain('let'); 25 | expect(docTypes).toContain('const'); 26 | expect(docTypes).toContain('type-alias'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getHeritageClause.ts: -------------------------------------------------------------------------------- 1 | import { ClassDeclaration, InterfaceDeclaration, SyntaxKind } from 'typescript'; 2 | import { nodeToString } from './nodeToString'; 3 | 4 | export function getHeritageClause(declaration: ClassDeclaration | InterfaceDeclaration) { 5 | let heritageString = ''; 6 | if (declaration.heritageClauses) { 7 | declaration.heritageClauses.forEach(heritage => { 8 | if (heritage.token === SyntaxKind.ExtendsKeyword) heritageString += ' extends'; 9 | if (heritage.token === SyntaxKind.ImplementsKeyword) heritageString += ' implements'; 10 | heritageString += heritage.types.map(typ => ' ' + nodeToString(typ)).join(','); 11 | }); 12 | } 13 | return heritageString; 14 | } 15 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getTypeParametersText.spec.ts: -------------------------------------------------------------------------------- 1 | import { __String } from 'typescript'; 2 | import { TsParser } from '.'; 3 | import { getTypeParametersText } from './getTypeParametersText'; 4 | const path = require('canonical-path'); 5 | 6 | describe('getTypeParametersText', () => { 7 | let parser: TsParser; 8 | let basePath: string; 9 | beforeEach(() => { 10 | parser = new TsParser(require('dgeni/lib/mocks/log')(false)); 11 | basePath = path.resolve(__dirname, '../../mocks'); 12 | }); 13 | 14 | it('should return text representation of types', () => { 15 | const parseInfo = parser.parse(['tsParser/getTypeParametersText.test.ts'], basePath); 16 | const moduleExports = parseInfo.moduleSymbols[0].exportArray; 17 | 18 | const testFunction = moduleExports[0].getDeclarations()![0]; 19 | expect(getTypeParametersText(testFunction)).toEqual(''); 20 | 21 | const testClass = moduleExports[1]; 22 | expect(getTypeParametersText(testClass.getDeclarations()![0])).toEqual(''); 23 | expect(getTypeParametersText(testClass.members!.get('method' as __String)!.getDeclarations()![0])).toEqual(''); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getTypeParametersText.ts: -------------------------------------------------------------------------------- 1 | import { Declaration, TypeParameterDeclaration } from 'typescript'; 2 | import { getDeclarationTypeText } from './getDeclarationTypeText'; 3 | 4 | export function getTypeParameters(declaration: Declaration) { 5 | const typeParameters = (declaration as any).typeParameters as TypeParameterDeclaration[]|undefined; 6 | return typeParameters && typeParameters.map(typeParameter => getDeclarationTypeText(typeParameter)); 7 | } 8 | 9 | export function getTypeParametersText(declaration: Declaration) { 10 | const typeParameters = getTypeParameters(declaration); 11 | return typeParameters ? `<${typeParameters.join(', ')}>` : ''; 12 | } 13 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/getTypeText.ts: -------------------------------------------------------------------------------- 1 | import { createPrinter, EmitHint, NewLineKind, TypeNode } from 'typescript'; 2 | import { nodeToString } from './nodeToString'; 3 | 4 | const printerOptions = {removeComments: true, newLine: NewLineKind.LineFeed}; 5 | const printer = createPrinter(printerOptions); 6 | 7 | export function getTypeText(type: TypeNode): string { 8 | return printer.printNode(EmitHint.Unspecified, type, type.getSourceFile()); 9 | } -------------------------------------------------------------------------------- /typescript/src/services/TsParser/index.spec.ts: -------------------------------------------------------------------------------- 1 | import { TsParser } from './index'; 2 | const path = require('canonical-path'); 3 | 4 | describe('tsParser', () => { 5 | let log: any; 6 | let parser: TsParser; 7 | 8 | beforeEach(() => { 9 | log = require('dgeni/lib/mocks/log')(false); 10 | parser = new TsParser(log); 11 | }); 12 | 13 | it("should parse a TS file", () => { 14 | const parseInfo = parser.parse(['testSrc.ts'], path.resolve(__dirname, '../../mocks/tsParser')); 15 | const tsModules = parseInfo.moduleSymbols; 16 | expect(tsModules.length).toEqual(1); 17 | expect(tsModules[0].exportArray.length).toEqual(3); 18 | expect(tsModules[0].exportArray.map(i => i.name)).toEqual(['MyClass', 'myFn', 'x']); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/nodeToString.spec.ts: -------------------------------------------------------------------------------- 1 | import { TsParser } from '.'; 2 | import { nodeToString } from './nodeToString'; 3 | const path = require('canonical-path'); 4 | 5 | describe('nodeToString', () => { 6 | let parser: TsParser; 7 | let basePath: string; 8 | beforeEach(() => { 9 | parser = new TsParser(require('dgeni/lib/mocks/log')(false)); 10 | basePath = path.resolve(__dirname, '../../mocks'); 11 | }); 12 | 13 | it('should return text representation of a node, with the comments stripped out', () => { 14 | const parseInfo = parser.parse(['tsParser/nodeToString.test.ts'], basePath); 15 | const moduleExports = parseInfo.moduleSymbols[0].exportArray; 16 | expect(nodeToString(moduleExports[0].declarations![0])).toEqual([ 17 | 'export class TestClass {', 18 | ' someProp: number;', 19 | ' constructor() {', 20 | ' }', 21 | ' foo(param1: string) { }', 22 | '}', 23 | ].join('\n')); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /typescript/src/services/TsParser/nodeToString.ts: -------------------------------------------------------------------------------- 1 | import { EmitHint, Node } from 'typescript'; 2 | import { lineFeedPrinter } from './LineFeedPrinter'; 3 | 4 | /** 5 | * Use a preconfigured TypeScript "printer" to render the text of a node, without comments. 6 | */ 7 | export function nodeToString(typeNode: Node) { 8 | return lineFeedPrinter.printNode(EmitHint.Unspecified, typeNode, typeNode.getSourceFile()); 9 | } 10 | -------------------------------------------------------------------------------- /typescript/src/services/exportSymbolsToDocsMap.ts: -------------------------------------------------------------------------------- 1 | export function exportSymbolsToDocsMap() { 2 | return new Map(); 3 | } 4 | -------------------------------------------------------------------------------- /typescript/src/services/modules.ts: -------------------------------------------------------------------------------- 1 | export function modules() { 2 | return {}; 3 | } 4 | -------------------------------------------------------------------------------- /typescript/src/services/ts-host/host.ts: -------------------------------------------------------------------------------- 1 | import {Declaration, Type, TypeChecker, TypeFormatFlags} from 'typescript'; 2 | import {getContent} from '../TsParser'; 3 | 4 | /** 5 | * Host that will be used for TypeScript AST operations that should be configurable or shared 6 | * across multiple doc types. 7 | */ 8 | export class Host { 9 | 10 | /** Whether multiple leading comments for a TypeScript node should be concatenated. */ 11 | concatMultipleLeadingComments: boolean = true; 12 | 13 | /** Flags that will be used to format a Type into a string representation. */ 14 | typeFormatFlags: TypeFormatFlags = TypeFormatFlags.None; 15 | 16 | getContent(declaration: Declaration): string { 17 | return getContent(declaration, this.concatMultipleLeadingComments); 18 | } 19 | 20 | typeToString(typeChecker: TypeChecker, type: Type): string { 21 | return typeChecker.typeToString(type, undefined, this.typeFormatFlags); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./", /* Redirect output structure to the directory. */ 5 | "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 6 | }, 7 | "include": [ 8 | "src" 9 | ], 10 | "exclude": [ 11 | "mocks" 12 | ] 13 | } 14 | --------------------------------------------------------------------------------