├── .gitattributes ├── .github ├── CODEOWNERS ├── CODE_OF_CONDUCT.md └── workflows │ └── ci.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.js ├── LICENSE ├── README.md ├── SECURITY.md ├── api-demo ├── .eslintrc.js ├── LICENSE ├── README.md ├── assets │ ├── advanced-input.ts │ └── simple-input.ts ├── config │ ├── jest.config.json │ └── rig.json ├── package.json ├── src │ ├── Formatter.ts │ ├── advancedDemo.ts │ ├── simpleDemo.ts │ └── start.ts └── tsconfig.json ├── common ├── autoinstallers │ └── rush-prettier │ │ ├── package.json │ │ └── pnpm-lock.yaml ├── changes │ ├── @microsoft │ │ ├── tsdoc-config │ │ │ └── bump-rs-deps_2024-12-10-19-18.json │ │ └── tsdoc │ │ │ ├── bump-rs-deps_2024-12-10-19-18.json │ │ │ └── default-value-inline-content_2024-09-12-09-25.json │ └── eslint-plugin-tsdoc │ │ └── bump-rs-deps_2024-12-10-19-18.json ├── config │ ├── azure-pipelines │ │ ├── npm-publish.yaml │ │ ├── playground-build.yaml │ │ └── templates │ │ │ ├── build.yaml │ │ │ ├── configure-git.yaml │ │ │ ├── install-node.yaml │ │ │ ├── publish.yaml │ │ │ └── record-published-versions.yaml │ └── rush │ │ ├── .npmrc │ │ ├── .npmrc-publish │ │ ├── .pnpmfile.cjs │ │ ├── artifactory.json │ │ ├── build-cache.json │ │ ├── cobuild.json │ │ ├── command-line.json │ │ ├── common-versions.json │ │ ├── custom-tips.json │ │ ├── experiments.json │ │ ├── pnpm-config.json │ │ ├── pnpm-lock.yaml │ │ ├── repo-state.json │ │ ├── rush-plugins.json │ │ ├── subspaces.json │ │ └── version-policies.json ├── git-hooks │ ├── commit-msg.sample │ └── pre-commit └── scripts │ ├── install-run-rush-pnpm.js │ ├── install-run-rush.js │ ├── install-run-rushx.js │ └── install-run.js ├── eslint-plugin ├── .eslintrc.js ├── .npmignore ├── CHANGELOG.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── config │ ├── jest.config.json │ └── rig.json ├── package.json ├── src │ ├── ConfigCache.ts │ ├── Debug.ts │ ├── index.ts │ └── tests │ │ └── plugin.test.ts └── tsconfig.json ├── playground ├── .eslintignore ├── .eslintrc.js ├── LICENSE ├── config │ ├── heft.json │ ├── rig.json │ └── typescript.json ├── package.json ├── public │ └── index.hbs ├── src │ ├── App.tsx │ ├── CodeEditor.tsx │ ├── DocAstView.tsx │ ├── DocDomView.tsx │ ├── DocHtmlView.tsx │ ├── FlexDivs.tsx │ ├── PlaygroundView.module.scss │ ├── PlaygroundView.tsx │ ├── SyntaxStyler │ │ ├── DocNodeSyntaxStyler.ts │ │ ├── DocNodeSyntaxStylerTheme.ts │ │ └── syntaxStyles.css │ ├── TabPane.tsx │ ├── samples │ │ ├── SampleInputs.ts │ │ ├── advancedSample.ts │ │ ├── basicSample.ts │ │ └── hyperlinkSample.ts │ ├── start.css │ └── start.tsx ├── tsconfig.json └── webpack.config.js ├── rush.json ├── spec └── code-snippets │ └── DeclarationReferences.ts ├── tsdoc-config ├── .eslintrc.js ├── .npmignore ├── .vscode │ └── launch.json ├── CHANGELOG.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── config │ ├── jest.config.json │ └── rig.json ├── package.json ├── src │ ├── TSDocConfigFile.ts │ ├── __tests__ │ │ ├── ErrorHandling.test.ts │ │ ├── TSDocConfigFile.test.ts │ │ └── assets │ │ │ ├── .gitignore │ │ │ ├── e1 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── e2 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── e3 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── e4 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── e5 │ │ │ ├── package.json │ │ │ ├── tsdoc-a.json │ │ │ ├── tsdoc-b.json │ │ │ ├── tsdoc-c.json │ │ │ └── tsdoc.json │ │ │ ├── e6 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── e7 │ │ │ ├── package.json │ │ │ └── tsdoc.json │ │ │ ├── p1 │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p10 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p11 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── base2 │ │ │ │ └── tsdoc-base2.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p12 │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p2 │ │ │ └── tsconfig.json │ │ │ ├── p3 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── base2 │ │ │ │ └── tsdoc-base2.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p4 │ │ │ ├── node_modules │ │ │ │ └── example-lib │ │ │ │ │ ├── dist │ │ │ │ │ └── tsdoc-example.json │ │ │ │ │ └── package.json │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p5 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── base2 │ │ │ │ └── tsdoc-base2.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p6 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p7 │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ ├── p8 │ │ │ ├── base1 │ │ │ │ └── tsdoc-base1.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ │ │ └── p9 │ │ │ ├── base1 │ │ │ └── tsdoc-base1.json │ │ │ ├── tsconfig.json │ │ │ └── tsdoc.json │ └── index.ts └── tsconfig.json └── tsdoc ├── .eslintrc.js ├── .npmignore ├── .vscode └── launch.json ├── CHANGELOG.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── config ├── api-extractor.json ├── heft.json ├── jest.config.json └── rig.json ├── etc └── tsdoc.api.md ├── package.json ├── schemas └── tsdoc.schema.json ├── src ├── __tests__ │ ├── DocNodeTransforms.test.ts │ ├── ParagraphSplitter.test.ts │ ├── ParsingBasics.test.ts │ └── __snapshots__ │ │ ├── DocNodeTransforms.test.ts.snap │ │ ├── ParagraphSplitter.test.ts.snap │ │ └── ParsingBasics.test.ts.snap ├── beta │ ├── DeclarationReference.grammarkdown │ ├── DeclarationReference.ts │ ├── __tests__ │ │ └── DeclarationReference.test.ts │ └── declaration-reference.rule ├── configuration │ ├── DocNodeManager.ts │ ├── TSDocConfiguration.ts │ ├── TSDocTagDefinition.ts │ └── TSDocValidationConfiguration.ts ├── details │ ├── ModifierTagSet.ts │ ├── StandardModifierTagSet.ts │ ├── StandardTags.ts │ └── Standardization.ts ├── emitters │ ├── PlainTextEmitter.ts │ ├── StringBuilder.ts │ ├── TSDocEmitter.ts │ └── __tests__ │ │ └── TSDocEmitter.test.ts ├── index.ts ├── nodes │ ├── BuiltInDocNodes.ts │ ├── DocBlock.ts │ ├── DocBlockTag.ts │ ├── DocCodeSpan.ts │ ├── DocComment.ts │ ├── DocDeclarationReference.ts │ ├── DocErrorText.ts │ ├── DocEscapedText.ts │ ├── DocExcerpt.ts │ ├── DocFencedCode.ts │ ├── DocHtmlAttribute.ts │ ├── DocHtmlEndTag.ts │ ├── DocHtmlStartTag.ts │ ├── DocInheritDocTag.ts │ ├── DocInlineTag.ts │ ├── DocInlineTagBase.ts │ ├── DocLinkTag.ts │ ├── DocMemberIdentifier.ts │ ├── DocMemberReference.ts │ ├── DocMemberSelector.ts │ ├── DocMemberSymbol.ts │ ├── DocNode.ts │ ├── DocNodeContainer.ts │ ├── DocParagraph.ts │ ├── DocParamBlock.ts │ ├── DocParamCollection.ts │ ├── DocPlainText.ts │ ├── DocSection.ts │ ├── DocSoftBreak.ts │ └── index.ts ├── parser │ ├── LineExtractor.ts │ ├── NodeParser.ts │ ├── ParagraphSplitter.ts │ ├── ParserContext.ts │ ├── ParserMessage.ts │ ├── ParserMessageLog.ts │ ├── StringChecks.ts │ ├── TSDocMessageId.ts │ ├── TSDocParser.ts │ ├── TextRange.ts │ ├── Token.ts │ ├── TokenReader.ts │ ├── TokenSequence.ts │ ├── Tokenizer.ts │ └── __tests__ │ │ ├── LineExtractor.test.ts │ │ ├── NodeParserBasics.test.ts │ │ ├── NodeParserCode.test.ts │ │ ├── NodeParserHtml.test.ts │ │ ├── NodeParserInheritDocTag.test.ts │ │ ├── NodeParserLinkTag.test.ts │ │ ├── NodeParserLinkTag2.test.ts │ │ ├── NodeParserLinkTag3.test.ts │ │ ├── NodeParserTags.test.ts │ │ ├── NodeParserValidationChecks.test.ts │ │ ├── TestHelpers.ts │ │ ├── TextRange.test.ts │ │ ├── TokenCoverageChecker.ts │ │ ├── Tokenizer.test.ts │ │ └── __snapshots__ │ │ ├── LineExtractor.test.ts.snap │ │ ├── NodeParserBasics.test.ts.snap │ │ ├── NodeParserCode.test.ts.snap │ │ ├── NodeParserHtml.test.ts.snap │ │ ├── NodeParserInheritDocTag.test.ts.snap │ │ ├── NodeParserLinkTag.test.ts.snap │ │ ├── NodeParserLinkTag2.test.ts.snap │ │ ├── NodeParserLinkTag3.test.ts.snap │ │ ├── NodeParserTags.test.ts.snap │ │ ├── NodeParserValidationChecks.test.ts.snap │ │ ├── TextRange.test.ts.snap │ │ └── Tokenizer.test.ts.snap └── transforms │ ├── DocNodeTransforms.ts │ └── TrimSpacesTransform.ts └── tsconfig.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Prevent Git to auto detect text files and perform LF normalization. 2 | * -text 3 | 4 | # The item with `binary` is treated as binary file. 5 | # The item with `eol=lf` is converted to LF on checkin, back to LF on checkout. 6 | # The item with `eol=crlf` is converted to LF on checkin, back to CRLF on checkout. 7 | 8 | # To get full extension list in the repo, remove the node_modules folder and run the following PowerShell cmdlet. 9 | # PS> Get-ChildItem . -Recurse | Where-Object { -not $_.PSIsContainer } | ForEach-Object { $_.Extension.ToLower() } | Sort-Object | Get-Unique 10 | 11 | # If new extensions are added, please refresh the repo with the following commands. 12 | # Reference: https://git-scm.com/docs/gitattributes 13 | # > rm .git/index # Remove the index to force Git to 14 | # > git reset # re-scan the working directory 15 | # > git status # Show files that will be normalized 16 | # > git add -u 17 | # > git add .gitattributes 18 | # > git commit -m "Apply end-of-line normalization based on updated .gitattributes file" 19 | 20 | *.aspx text eol=crlf 21 | *.bowerrc text eol=lf 22 | *.cmd text eol=crlf 23 | *.command text eol=lf 24 | *.config text eol=crlf 25 | *.cs text eol=crlf 26 | *.csproj text eol=crlf 27 | *.css text eol=crlf 28 | *.dll binary 29 | *.editorconfig text eol=lf 30 | *.eot binary 31 | *.example text eol=crlf 32 | *.exe binary 33 | *.gif binary 34 | *.gitattributes text eol=lf 35 | *.gitignore text eol=lf 36 | *.gitmodules text eol=lf 37 | *.html text eol=crlf 38 | *.ico binary 39 | *.jpg binary 40 | *.js text eol=crlf 41 | *.json text eol=crlf 42 | *.less text eol=crlf 43 | *.map text eol=lf 44 | *.md text eol=crlf 45 | *.npmignore text eol=lf 46 | *.png binary 47 | *.ps1 text eol=crlf 48 | *.rels text eol=crlf 49 | *.resx text eol=crlf 50 | *.scss text eol=crlf 51 | *.sln text eol=crlf 52 | *.svg text elf=lf 53 | *.ts text eol=crlf 54 | *.tsx text eol=crlf 55 | *.ttf binary 56 | *.woff binary 57 | *.wsp binary 58 | *.xml text eol=crlf 59 | 60 | # NPM "bin" scripts MUST have LF, or else the executable fails to run on Mac. 61 | # This fnmatch expression only matches files in a "bin" folder and without 62 | # a period in the filename. 63 | /*/*/bin/+([!.]) -text 64 | 65 | # Don't allow people to merge changes to these generated files, because the result 66 | # may be invalid. You need to run "rush update" again. 67 | pnpm-lock.yaml merge=text 68 | shrinkwrap.yaml merge=binary 69 | npm-shrinkwrap.json merge=binary 70 | yarn.lock merge=binary 71 | 72 | # Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic 73 | # syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor 74 | # may also require a special configuration to allow comments in JSON. 75 | # 76 | # For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088 77 | # 78 | *.json linguist-language=JSON-with-Comments 79 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | .github/CODEOWNERS @iclanton @octogonz @apostolisms @D4N14L @dmichon-msft @patmill 2 | common/config/**/* @iclanton @octogonz @apostolisms @D4N14L @dmichon-msft @patmill 3 | 4 | **/* @iclanton @octogonz @apostolisms @D4N14L @dmichon-msft @patmill 5 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | This project has adopted the [Microsoft Open Source Code of 2 | Conduct](https://opensource.microsoft.com/codeofconduct/). 3 | For more information see the [Code of Conduct 4 | FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 5 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) 6 | with any additional questions or comments. 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: ['main'] 5 | pull_request: 6 | branches: ['main'] 7 | # Allows you to run this workflow manually from the Actions tab 8 | workflow_dispatch: 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | include: 14 | - NodeVersion: 18.20.x 15 | NodeVersionDisplayName: 18 16 | OS: ubuntu-latest 17 | - NodeVersion: 20.18.x 18 | NodeVersionDisplayName: 20 19 | OS: ubuntu-latest 20 | - NodeVersion: 22.12.x 21 | NodeVersionDisplayName: 22 22 | OS: ubuntu-latest 23 | - NodeVersion: 22.12.x 24 | NodeVersionDisplayName: 22 25 | OS: windows-latest 26 | name: Node.js v${{ matrix.NodeVersionDisplayName }} (${{ matrix.OS }}) 27 | runs-on: ${{ matrix.OS }} 28 | steps: 29 | - uses: actions/checkout@v3 30 | with: 31 | fetch-depth: 2 32 | 33 | - name: Git config user 34 | run: | 35 | git config --local user.name "Rushbot" 36 | git config --local user.email "rushbot@users.noreply.github.com" 37 | 38 | - uses: actions/setup-node@v3 39 | with: 40 | node-version: ${{ matrix.NodeVersion }} 41 | 42 | - name: Verify Change Logs 43 | run: node common/scripts/install-run-rush.js change --verify 44 | 45 | - name: Rush Install 46 | run: node common/scripts/install-run-rush.js install 47 | 48 | - name: Rush retest 49 | run: node common/scripts/install-run-rush.js retest --verbose --production 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | *.log 3 | npm-debug.log* 4 | yarn-debug.log* 5 | yarn-error.log* 6 | 7 | # Runtime data 8 | *.pid 9 | *.seed 10 | *.pid.lock 11 | 12 | # Directory for instrumented libs generated by jscoverage/JSCover 13 | lib-cov 14 | 15 | # Coverage directory used by tools like istanbul 16 | coverage 17 | 18 | # nyc test coverage 19 | .nyc_output 20 | 21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 22 | .grunt 23 | 24 | # Bower dependency directory (https://bower.io/) 25 | bower_components 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (https://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional eslint cache 41 | .eslintcache 42 | 43 | # Optional REPL history 44 | .node_repl_history 45 | 46 | # Output of 'npm pack' 47 | *.tgz 48 | 49 | # Yarn Integrity file 50 | .yarn-integrity 51 | 52 | # dotenv environment variables file 53 | .env 54 | 55 | # next.js build output 56 | .next 57 | 58 | # OS X temporary files 59 | .DS_Store 60 | 61 | # IntelliJ IDEA project files; if you want to commit IntelliJ settings, this recipe may be helpful: 62 | # https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 63 | .idea/ 64 | *.iml 65 | 66 | # Rush temporary files 67 | common/deploy/ 68 | common/temp/ 69 | common/autoinstallers/*/.npmrc 70 | **/.rush/temp/ 71 | *.lock 72 | 73 | # Heft temporary files 74 | .cache 75 | .heft 76 | 77 | # Common toolchain intermediate files 78 | temp 79 | lib 80 | lib-amd 81 | lib-es6 82 | lib-esnext 83 | lib-commonjs 84 | dist 85 | *.scss.ts 86 | *.sass.ts 87 | 88 | # Visual Studio Code 89 | .vscode 90 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------------------------------------------- 2 | # Keep this section in sync with .gitignore 3 | #------------------------------------------------------------------------------------------------------------------- 4 | 5 | # Logs 6 | *.log 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | # Runtime data 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # Optional npm cache directory 42 | .npm 43 | 44 | # Optional eslint cache 45 | .eslintcache 46 | 47 | # Optional REPL history 48 | .node_repl_history 49 | 50 | # Output of 'npm pack' 51 | *.tgz 52 | 53 | # Yarn Integrity file 54 | .yarn-integrity 55 | 56 | # dotenv environment variables file 57 | .env 58 | 59 | # next.js build output 60 | .next 61 | 62 | # OS X temporary files 63 | .DS_Store 64 | 65 | # Rush temporary files 66 | common/deploy/ 67 | common/temp/ 68 | common/autoinstallers/*/.npmrc 69 | **/.rush/temp/ 70 | 71 | # Common toolchain intermediate files 72 | temp 73 | lib 74 | lib-amd 75 | lib-es6 76 | lib-esnext 77 | lib-commonjs 78 | dist 79 | *.scss.ts 80 | *.sass.ts 81 | 82 | # Visual Studio Code 83 | .vscode 84 | 85 | # Heft 86 | */.heft/build-cache/** 87 | */.heft/temp/** 88 | 89 | #------------------------------------------------------------------------------------------------------------------- 90 | # Prettier-specific overrides 91 | #------------------------------------------------------------------------------------------------------------------- 92 | 93 | # Machine-egnerated files 94 | common/reviews 95 | common/changes 96 | common/scripts 97 | common/config/rush/browser-approved-packages.json 98 | common/config/rush/nonbrowser-approved-packages.json 99 | CHANGELOG.* 100 | pnpm-lock.yaml 101 | build-tests/*/etc 102 | dist-dev 103 | dist-prod 104 | 105 | # We'll consider enabling this later; Prettier reformats code blocks, which affects end-user content 106 | *.md 107 | 108 | # Ignore .json files which may contain intentional syntax errors 109 | **/__tests__/assets/**/*.json 110 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Documentation for this file: https://prettier.io/docs/en/configuration.html 2 | module.exports = { 3 | // We use a larger print width because Prettier's word-wrapping seems to be tuned 4 | // for plain JavaScript without type annotations 5 | printWidth: 110, 6 | 7 | // Use .gitattributes to manage newlines 8 | endOfLine: 'auto', 9 | 10 | // Use single quotes instead of double quotes 11 | singleQuote: true, 12 | 13 | // For ES5, trailing commas cannot be used in function parameters; it is counterintuitive 14 | // to use them for arrays only 15 | trailingComma: 'none' 16 | }; 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /api-demo/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458 2 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/modern-module-resolution'); 3 | // This is a workaround for https://github.com/microsoft/rushstack/issues/3021 4 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/custom-config-package-names'); 5 | 6 | module.exports = { 7 | extends: [ 8 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/profile/node', 9 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/mixins/friendly-locals' 10 | ], 11 | parserOptions: { tsconfigRootDir: __dirname }, 12 | 13 | plugins: ['eslint-plugin-header'], 14 | overrides: [ 15 | { 16 | files: ['*.ts', '*.tsx'], 17 | rules: { 18 | // Rationale: Including the `type` annotation in the import statement for imports 19 | // only used as types prevents the import from being emitted in the compiled output. 20 | '@typescript-eslint/consistent-type-imports': [ 21 | 'warn', 22 | { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 23 | ], 24 | 25 | // Rationale: If all imports in an import statement are only used as types, 26 | // then the import statement should be omitted in the compiled JS output. 27 | '@typescript-eslint/no-import-type-side-effects': 'warn', 28 | 29 | 'header/header': [ 30 | 'warn', 31 | 'line', 32 | [ 33 | ' Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.', 34 | ' See LICENSE in the project root for license information.' 35 | ] 36 | ] 37 | } 38 | } 39 | ] 40 | }; 41 | -------------------------------------------------------------------------------- /api-demo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /api-demo/README.md: -------------------------------------------------------------------------------- 1 | # api-demo 2 | 3 | This is a simple code sample that illustrates how to invoke the API for the 4 | **@microsoft/tsdoc** library. There are two options for installing. Option 1 5 | is easiest. Option 2 is for contributors. 6 | 7 | 8 | ### Option 1: Building and running the demo using NPM 9 | 10 | > 👉 IF YOU ARE CONTRIBUTING A FIX, PLEASE USE OPTION 2 INSTEAD. 11 | 12 | Here's quick instructions to try out the **api-demo**. Option 1 will use the **latest official release** of 13 | the **@microsoft/tsdoc** library. It will NOT symlink to your local build of the library. 14 | 15 | 1. Install the NPM dependencies for the **api-demo** project: 16 | 17 | ```shell 18 | $ cd ./api-demo 19 | # Note: Be sure to specify "--no-package-lock" to avoid conflicts with Rush 20 | $ npm install --no-package-lock 21 | ``` 22 | 23 | 2. Build the **api-demo** project like this: 24 | 25 | ```shell 26 | $ npm run build 27 | ``` 28 | 29 | 3. Run the **api-demo** project: 30 | 31 | The simple demo does not rely on the TypeScript compiler API; instead, it parses the 32 | source file directly. It uses the default parser configuration. 33 | 34 | ```shell 35 | $ npm run simple 36 | ``` 37 | 38 | The advanced demo invokes the TypeScript compiler and extracts the comment from the AST. 39 | It also illustrates how to define custom TSDoc tags using `TSDocParserConfiguration`. 40 | 41 | ```shell 42 | $ npm run advanced 43 | ``` 44 | 45 | 46 | ### Option 2: Building and running the demo using Rush 47 | 48 | If you're going to submit a pull request for TSDoc, you will need to use the Rush monorepo 49 | manager tool. See [Contributing.md](../Contributing.md) for more information. 50 | 51 | Option 2 will link **api-demo** to use your local build of the **@microsoft/tsdoc** library, 52 | for easy testing/validation. 53 | 54 | 1. Install the [Rush](https://rushjs.io/pages/developer/new_developer/) software: 55 | 56 | ```shell 57 | $ npm install -g @microsoft/rush 58 | ``` 59 | 60 | *NOTE: If this command fails because your user account does not have permissions to 61 | access NPM's global folder, you may need to 62 | [fix your NPM configuration](https://docs.npmjs.com/getting-started/fixing-npm-permissions).* 63 | 64 | 2. Install dependencies for all projects in the monorepo: 65 | 66 | ```shell 67 | # Run this command in the folder where you cloned the TSDoc repo from GitHub 68 | $ rush install 69 | ``` 70 | 71 | 3. Build all the projects in the monorepo: 72 | 73 | ```shell 74 | $ rush build 75 | ``` 76 | 77 | You can also build just the **api-demo** project like this: 78 | 79 | ```shell 80 | $ cd ./api-demo 81 | $ npm run build 82 | ``` 83 | 84 | 4. Run the **api-demo** project (see above notes for more details): 85 | 86 | ```shell 87 | $ npm run simple 88 | $ npm run advanced 89 | ``` 90 | 91 | *IMPORTANT: After you run `rush install`, your repo will be in a "Rush-linked" state, 92 | with special symlinks in the node_modules folders. DO NOT run `npm install` in this state. 93 | If you want to go back to working in standalone mode, first run `rush unlink && rush purge`.* 94 | -------------------------------------------------------------------------------- /api-demo/assets/advanced-input.ts: -------------------------------------------------------------------------------- 1 | export class Statistics { 2 | /** 3 | * Returns the average of two numbers. 4 | * This incomplete HTML tag should be reported as an error: ): string { 24 | let result: string = ''; 25 | for (const docNode of docNodes) { 26 | result += Formatter.renderDocNode(docNode); 27 | } 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /api-demo/src/simpleDemo.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import colors from 'colors'; 5 | import * as fs from 'fs'; 6 | import * as path from 'path'; 7 | import * as os from 'os'; 8 | import { TSDocParser, type ParserContext, type DocComment } from '@microsoft/tsdoc'; 9 | import { Formatter } from './Formatter'; 10 | 11 | /** 12 | * The simple demo does not rely on the TypeScript compiler API; instead, it parses the 13 | * source file directly. It uses the default parser configuration. 14 | */ 15 | export function simpleDemo(): void { 16 | console.log(colors.yellow('*** TSDoc API demo: Simple Scenario ***') + os.EOL); 17 | 18 | const inputFilename: string = path.resolve(path.join(__dirname, '..', 'assets', 'simple-input.ts')); 19 | console.log('Reading assets/simple-input.ts...'); 20 | 21 | const inputBuffer: string = fs.readFileSync(inputFilename).toString(); 22 | 23 | // NOTE: Optionally, can provide a TSDocConfiguration here 24 | const tsdocParser: TSDocParser = new TSDocParser(); 25 | const parserContext: ParserContext = tsdocParser.parseString(inputBuffer); 26 | 27 | console.log(os.EOL + colors.green('Input Buffer:') + os.EOL); 28 | console.log(colors.gray('<<<<<<')); 29 | console.log(inputBuffer); 30 | console.log(colors.gray('>>>>>>')); 31 | 32 | console.log(os.EOL + colors.green('Extracted Lines:') + os.EOL); 33 | console.log( 34 | JSON.stringify( 35 | parserContext.lines.map((x) => x.toString()), 36 | undefined, 37 | ' ' 38 | ) 39 | ); 40 | 41 | console.log(os.EOL + colors.green('Parser Log Messages:') + os.EOL); 42 | 43 | if (parserContext.log.messages.length === 0) { 44 | console.log('No errors or warnings.'); 45 | } else { 46 | for (const message of parserContext.log.messages) { 47 | console.log(inputFilename + message.toString()); 48 | } 49 | } 50 | 51 | console.log(os.EOL + colors.green('DocComment parts:') + os.EOL); 52 | 53 | const docComment: DocComment = parserContext.docComment; 54 | 55 | console.log(colors.cyan('Summary: ') + JSON.stringify(Formatter.renderDocNode(docComment.summarySection))); 56 | 57 | if (docComment.remarksBlock) { 58 | console.log( 59 | colors.cyan('Remarks: ') + JSON.stringify(Formatter.renderDocNode(docComment.remarksBlock.content)) 60 | ); 61 | } 62 | 63 | for (const paramBlock of docComment.params.blocks) { 64 | console.log( 65 | colors.cyan(`Parameter "${paramBlock.parameterName}": `) + 66 | JSON.stringify(Formatter.renderDocNode(paramBlock.content)) 67 | ); 68 | } 69 | 70 | if (docComment.returnsBlock) { 71 | console.log( 72 | colors.cyan('Returns: ') + JSON.stringify(Formatter.renderDocNode(docComment.returnsBlock.content)) 73 | ); 74 | } 75 | 76 | console.log(colors.cyan('Modifiers: ') + docComment.modifierTagSet.nodes.map((x) => x.tagName).join(', ')); 77 | } 78 | -------------------------------------------------------------------------------- /api-demo/src/start.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import * as colors from 'colors'; 5 | import * as os from 'os'; 6 | import { simpleDemo } from './simpleDemo'; 7 | import { advancedDemo } from './advancedDemo'; 8 | 9 | function main(args: string[]): void { 10 | if (args.length >= 1) { 11 | switch (args[0].toUpperCase()) { 12 | case 'SIMPLE': 13 | simpleDemo(); 14 | return; 15 | case 'ADVANCED': 16 | advancedDemo(); 17 | return; 18 | case '--HELP': 19 | case '-H': 20 | break; 21 | default: 22 | console.log(colors.red('Unsupported option: ' + JSON.stringify(args[0])) + os.EOL); 23 | break; 24 | } 25 | } 26 | 27 | console.log(colors.yellow('*** TSDoc API demo ***') + os.EOL); 28 | 29 | console.log('usage: ' + colors.green('npm run start simple')); 30 | console.log(' ' + colors.green('npm run start advanced')); 31 | console.log(os.EOL + 'Invokes the simple or advanced API demo for TSDoc.'); 32 | } 33 | 34 | main(process.argv.slice(2)); 35 | -------------------------------------------------------------------------------- /api-demo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "./node_modules/@rushstack/heft-node-rig/profiles/default/tsconfig-base.json", 4 | "compilerOptions": { 5 | "isolatedModules": true, 6 | "types": ["heft-jest", "node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /common/autoinstallers/rush-prettier/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rush-prettier", 3 | "version": "1.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "pretty-quick": "4.0.0", 7 | "prettier": "3.2.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /common/changes/@microsoft/tsdoc-config/bump-rs-deps_2024-12-10-19-18.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": [ 3 | { 4 | "comment": "", 5 | "type": "none", 6 | "packageName": "@microsoft/tsdoc-config" 7 | } 8 | ], 9 | "packageName": "@microsoft/tsdoc-config", 10 | "email": "iclanton@users.noreply.github.com" 11 | } -------------------------------------------------------------------------------- /common/changes/@microsoft/tsdoc/bump-rs-deps_2024-12-10-19-18.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": [ 3 | { 4 | "comment": "", 5 | "type": "none", 6 | "packageName": "@microsoft/tsdoc" 7 | } 8 | ], 9 | "packageName": "@microsoft/tsdoc", 10 | "email": "iclanton@users.noreply.github.com" 11 | } -------------------------------------------------------------------------------- /common/changes/@microsoft/tsdoc/default-value-inline-content_2024-09-12-09-25.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": [ 3 | { 4 | "packageName": "@microsoft/tsdoc", 5 | "comment": "Ensure TSDocEmitter does not emit a newline for the text after `@defaultValue` tags.", 6 | "type": "patch" 7 | } 8 | ], 9 | "packageName": "@microsoft/tsdoc" 10 | } -------------------------------------------------------------------------------- /common/changes/eslint-plugin-tsdoc/bump-rs-deps_2024-12-10-19-18.json: -------------------------------------------------------------------------------- 1 | { 2 | "changes": [ 3 | { 4 | "comment": "", 5 | "type": "none", 6 | "packageName": "eslint-plugin-tsdoc" 7 | } 8 | ], 9 | "packageName": "eslint-plugin-tsdoc", 10 | "email": "iclanton@users.noreply.github.com" 11 | } -------------------------------------------------------------------------------- /common/config/azure-pipelines/npm-publish.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | repositories: 3 | - repository: RushstackMainRepo 4 | type: github 5 | name: Microsoft/rushstack 6 | endpoint: 'GitHub (Rushbot)' 7 | - repository: 1esPipelines 8 | type: git 9 | name: 1ESPipelineTemplates/1ESPipelineTemplates 10 | ref: refs/tags/release 11 | 12 | extends: 13 | template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines 14 | parameters: 15 | pool: 16 | name: Azure-Pipelines-1ESPT-ExDShared 17 | os: windows 18 | sdl: 19 | sourceRepositoriesToScan: 20 | include: 21 | - repository: RushstackMainRepo 22 | stages: 23 | - stage: 24 | jobs: 25 | - job: 26 | pool: 27 | name: publish-rushstack 28 | os: linux 29 | templateContext: 30 | outputs: 31 | - output: pipelineArtifact 32 | targetPath: $(Build.ArtifactStagingDirectory)/published-versions 33 | artifactName: published-versions 34 | steps: 35 | - checkout: self 36 | persistCredentials: true 37 | path: tsdoc 38 | 39 | - template: /common/config/azure-pipelines/templates/install-node.yaml@self 40 | 41 | - template: /common/config/azure-pipelines/templates/build.yaml@self 42 | 43 | - template: /common/config/azure-pipelines/templates/publish.yaml@self 44 | 45 | - template: /common/config/azure-pipelines/templates/record-published-versions.yaml@self 46 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/playground-build.yaml: -------------------------------------------------------------------------------- 1 | pool: 2 | vmImage: 'ubuntu-latest' 3 | resources: 4 | repositories: 5 | - repository: pagesBranch 6 | endpoint: 'GitHub (Rushbot)' 7 | type: github 8 | name: microsoft/tsdoc 9 | ref: refs/heads/gh-pages 10 | trigger: none 11 | variables: 12 | NodeVersion: 18 13 | FORCE_COLOR: 1 14 | jobs: 15 | - job: build 16 | displayName: Build 17 | steps: 18 | - checkout: self 19 | path: tsdoc 20 | 21 | - template: /common/config/azure-pipelines/templates/install-node.yaml@self 22 | 23 | - template: /common/config/azure-pipelines/templates/build.yaml@self 24 | 25 | - publish: playground/dist 26 | artifact: 'playground' 27 | displayName: 'Publish Playground Artifacts' 28 | 29 | - job: publish 30 | displayName: Publish 31 | dependsOn: build 32 | steps: 33 | - checkout: pagesBranch 34 | persistCredentials: true 35 | path: tsdoc 36 | 37 | - script: git checkout gh-pages 38 | displayName: 'Checkout gh-pages Branch' 39 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 40 | 41 | - script: rm -r $(Build.SourcesDirectory)/* 42 | displayName: 'Clean Pages Branch' 43 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 44 | 45 | - task: DownloadPipelineArtifact@2 46 | displayName: 'Download Playground Artifacts' 47 | inputs: 48 | artifact: playground 49 | targetPath: $(Agent.BuildDirectory)/tsdoc 50 | 51 | - template: /common/config/azure-pipelines/templates/configure-git.yaml@self 52 | 53 | - script: | 54 | git add -A 55 | if [ -n "$(git diff --name-only --staged HEAD --)" ] 56 | then 57 | echo "Committing changes" 58 | git commit -m "Update playground artifacts" 59 | git push 60 | else 61 | echo "No changes" 62 | fi 63 | displayName: 'Commit and push playground artifacts' 64 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 65 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/templates/build.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - template: /common/config/azure-pipelines/templates/configure-git.yaml@self 3 | 4 | - script: 'node common/scripts/install-run-rush.js change --verify' 5 | displayName: 'Verify Change Logs' 6 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 7 | 8 | - script: 'node common/scripts/install-run-rush.js install' 9 | displayName: 'Rush Install' 10 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 11 | 12 | - script: 'node common/scripts/install-run-rush.js retest --verbose --production' 13 | displayName: 'Rush retest' 14 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 15 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/templates/configure-git.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - script: 'git config --local user.email rushbot@users.noreply.github.com' 3 | displayName: 'git config email' 4 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 5 | 6 | - script: 'git config --local user.name Rushbot' 7 | displayName: 'git config name' 8 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 9 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/templates/install-node.yaml: -------------------------------------------------------------------------------- 1 | parameters: 2 | - name: NodeMajorVersion 3 | type: number 4 | default: 20 5 | 6 | steps: 7 | - task: NodeTool@0 8 | inputs: 9 | versionSpec: '${{ parameters.NodeMajorVersion }}.x' 10 | displayName: 'Install Node.js ${{ parameters.NodeMajorVersion }}' 11 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/templates/publish.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - script: 'node common/scripts/install-run-rush.js version --bump --version-policy tsdoc --target-branch $(Build.SourceBranchName)' 3 | displayName: 'Rush Version' 4 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 5 | 6 | - script: 'node common/scripts/install-run-rush.js publish --apply --publish --include-all --target-branch $(Build.SourceBranchName) --add-commit-details --set-access-level public' 7 | displayName: 'Rush Publish' 8 | env: 9 | NPM_AUTH_TOKEN: $(npmToken) 10 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 11 | -------------------------------------------------------------------------------- /common/config/azure-pipelines/templates/record-published-versions.yaml: -------------------------------------------------------------------------------- 1 | steps: 2 | - checkout: RushstackMainRepo 3 | path: rushstack 4 | 5 | - script: 'git config --local user.email rushbot@users.noreply.github.com' 6 | displayName: 'git config email' 7 | workingDirectory: '$(Agent.BuildDirectory)/rushstack' 8 | 9 | - script: 'git config --local user.name Rushbot' 10 | displayName: 'git config name' 11 | workingDirectory: '$(Agent.BuildDirectory)/rushstack' 12 | 13 | - script: 'node common/scripts/install-run-rush.js install --to repo-toolbox' 14 | displayName: 'Rush Install (rushstack)' 15 | workingDirectory: '$(Agent.BuildDirectory)/rushstack' 16 | 17 | - script: 'node common/scripts/install-run-rush.js build --verbose --production --to repo-toolbox' 18 | displayName: 'Rush Rebuild (rushstack)' 19 | workingDirectory: '$(Agent.BuildDirectory)/rushstack' 20 | 21 | - script: 'node $(Agent.BuildDirectory)/rushstack/repo-scripts/repo-toolbox/lib/start.js record-versions --out-file $(Build.ArtifactStagingDirectory)/published-versions/published-versions.json' 22 | displayName: 'Record Published Versions' 23 | workingDirectory: '$(Agent.BuildDirectory)/tsdoc' 24 | 25 | # Published by the 1ES template 26 | # - publish: $(Build.ArtifactStagingDirectory)/published-versions 27 | # artifact: published-versions 28 | # displayName: 'Publish Artifact: published-versions' 29 | -------------------------------------------------------------------------------- /common/config/rush/.npmrc: -------------------------------------------------------------------------------- 1 | # Rush uses this file to configure the NPM package registry during installation. It is applicable 2 | # to PNPM, NPM, and Yarn package managers. It is used by operations such as "rush install", 3 | # "rush update", and the "install-run.js" scripts. 4 | # 5 | # NOTE: The "rush publish" command uses .npmrc-publish instead. 6 | # 7 | # Before invoking the package manager, Rush will generate an .npmrc in the folder where installation 8 | # is performed. This generated file will omit any config lines that reference environment variables 9 | # that are undefined in that session; this avoids problems that would otherwise result due to 10 | # a missing variable being replaced by an empty string. 11 | # 12 | # If "subspacesEnabled" is true in subspaces.json, the generated file will merge settings from 13 | # "common/config/rush/.npmrc" and "common/config/subspaces//.npmrc", with the latter taking 14 | # precedence. 15 | # 16 | # * * * SECURITY WARNING * * * 17 | # 18 | # It is NOT recommended to store authentication tokens in a text file on a lab machine, because 19 | # other unrelated processes may be able to read that file. Also, the file may persist indefinitely, 20 | # for example if the machine loses power. A safer practice is to pass the token via an 21 | # environment variable, which can be referenced from .npmrc using ${} expansion. For example: 22 | # 23 | # //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} 24 | # 25 | registry=https://registry.npmjs.org/ 26 | 27 | # This seemed to interfere with authentication for publishing: 28 | # always-auth=false 29 | -------------------------------------------------------------------------------- /common/config/rush/.npmrc-publish: -------------------------------------------------------------------------------- 1 | # This config file is very similar to common/config/rush/.npmrc, except that .npmrc-publish 2 | # is used by the "rush publish" command, as publishing often involves different credentials 3 | # and registries than other operations. 4 | # 5 | # Before invoking the package manager, Rush will copy this file to "common/temp/publish-home/.npmrc" 6 | # and then temporarily map that folder as the "home directory" for the current user account. 7 | # This enables the same settings to apply for each project folder that gets published. The copied file 8 | # will omit any config lines that reference environment variables that are undefined in that session; 9 | # this avoids problems that would otherwise result due to a missing variable being replaced by 10 | # an empty string. 11 | # 12 | # * * * SECURITY WARNING * * * 13 | # 14 | # It is NOT recommended to store authentication tokens in a text file on a lab machine, because 15 | # other unrelated processes may be able to read the file. Also, the file may persist indefinitely, 16 | # for example if the machine loses power. A safer practice is to pass the token via an 17 | # environment variable, which can be referenced from .npmrc using ${} expansion. For example: 18 | # 19 | # //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} 20 | # 21 | 22 | registry=https://registry.npmjs.org/ 23 | always-auth=true 24 | //registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN} 25 | -------------------------------------------------------------------------------- /common/config/rush/.pnpmfile.cjs: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * When using the PNPM package manager, you can use pnpmfile.js to workaround 5 | * dependencies that have mistakes in their package.json file. (This feature is 6 | * functionally similar to Yarn's "resolutions".) 7 | * 8 | * For details, see the PNPM documentation: 9 | * https://pnpm.js.org/docs/en/hooks.html 10 | * 11 | * IMPORTANT: SINCE THIS FILE CONTAINS EXECUTABLE CODE, MODIFYING IT IS LIKELY TO INVALIDATE 12 | * ANY CACHED DEPENDENCY ANALYSIS. After any modification to pnpmfile.js, it's recommended to run 13 | * "rush update --full" so that PNPM will recalculate all version selections. 14 | */ 15 | module.exports = { 16 | hooks: { 17 | readPackage 18 | } 19 | }; 20 | 21 | /** 22 | * This hook is invoked during installation before a package's dependencies 23 | * are selected. 24 | * The `packageJson` parameter is the deserialized package.json 25 | * contents for the package that is about to be installed. 26 | * The `context` parameter provides a log() function. 27 | * The return value is the updated object. 28 | */ 29 | function readPackage(packageJson, context) { 30 | // // The karma types have a missing dependency on typings from the log4js package. 31 | // if (packageJson.name === '@types/karma') { 32 | // context.log('Fixed up dependencies for @types/karma'); 33 | // packageJson.dependencies['log4js'] = '0.6.38'; 34 | // } 35 | 36 | return packageJson; 37 | } 38 | -------------------------------------------------------------------------------- /common/config/rush/cobuild.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This configuration file manages Rush's cobuild feature. 3 | * More documentation is available on the Rush website: https://rushjs.io 4 | */ 5 | { 6 | "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/cobuild.schema.json", 7 | 8 | /** 9 | * (Required) EXPERIMENTAL - Set this to true to enable the cobuild feature. 10 | * RUSH_COBUILD_CONTEXT_ID should always be specified as an environment variable with an non-empty string, 11 | * otherwise the cobuild feature will be disabled. 12 | */ 13 | "cobuildFeatureEnabled": false, 14 | 15 | /** 16 | * (Required) Choose where cobuild lock will be acquired. 17 | * 18 | * The lock provider is registered by the rush plugins. 19 | * For example, @rushstack/rush-redis-cobuild-plugin registers the "redis" lock provider. 20 | */ 21 | "cobuildLockProvider": "redis" 22 | } 23 | -------------------------------------------------------------------------------- /common/config/rush/common-versions.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This configuration file specifies NPM dependency version selections that affect all projects 3 | * in a Rush repo. More documentation is available on the Rush website: https://rushjs.io 4 | */ 5 | { 6 | "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json", 7 | 8 | /** 9 | * A table that specifies a "preferred version" for a given NPM package. This feature is typically used 10 | * to hold back an indirect dependency to a specific older version, or to reduce duplication of indirect dependencies. 11 | * 12 | * The "preferredVersions" value can be any SemVer range specifier (e.g. "~1.2.3"). Rush injects these values into 13 | * the "dependencies" field of the top-level common/temp/package.json, which influences how the package manager 14 | * will calculate versions. The specific effect depends on your package manager. Generally it will have no 15 | * effect on an incompatible or already constrained SemVer range. If you are using PNPM, similar effects can be 16 | * achieved using the pnpmfile.js hook. See the Rush documentation for more details. 17 | * 18 | * After modifying this field, it's recommended to run "rush update --full" so that the package manager 19 | * will recalculate all version selections. 20 | */ 21 | "preferredVersions": { 22 | /** 23 | * When someone asks for "^1.0.0" make sure they get "1.2.3" when working in this repo, 24 | * instead of the latest version. 25 | */ 26 | // "some-library": "1.2.3" 27 | }, 28 | 29 | /** 30 | * When set to true, for all projects in the repo, all dependencies will be automatically added as preferredVersions, 31 | * except in cases where different projects specify different version ranges for a given dependency. For older 32 | * package managers, this tended to reduce duplication of indirect dependencies. However, it can sometimes cause 33 | * trouble for indirect dependencies with incompatible peerDependencies ranges. 34 | * 35 | * The default value is true. If you're encountering installation errors related to peer dependencies, 36 | * it's recommended to set this to false. 37 | * 38 | * After modifying this field, it's recommended to run "rush update --full" so that the package manager 39 | * will recalculate all version selections. 40 | */ 41 | // "implicitlyPreferredVersions": false, 42 | 43 | /** 44 | * The "rush check" command can be used to enforce that every project in the repo must specify 45 | * the same SemVer range for a given dependency. However, sometimes exceptions are needed. 46 | * The allowedAlternativeVersions table allows you to list other SemVer ranges that will be 47 | * accepted by "rush check" for a given dependency. 48 | * 49 | * IMPORTANT: THIS TABLE IS FOR *ADDITIONAL* VERSION RANGES THAT ARE ALTERNATIVES TO THE 50 | * USUAL VERSION (WHICH IS INFERRED BY LOOKING AT ALL PROJECTS IN THE REPO). 51 | * This design avoids unnecessary churn in this file. 52 | */ 53 | "allowedAlternativeVersions": { 54 | /** 55 | * For example, allow some projects to use an older TypeScript compiler 56 | * (in addition to whatever "usual" version is being used by other projects in the repo): 57 | */ 58 | // "typescript": [ 59 | // "~2.4.0" 60 | // ] 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /common/config/rush/custom-tips.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This configuration file allows repo maintainers to configure extra details to be 3 | * printed alongside certain Rush messages. More documentation is available on the 4 | * Rush website: https://rushjs.io 5 | */ 6 | { 7 | "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/custom-tips.schema.json", 8 | 9 | /** 10 | * Custom tips allow you to annotate Rush's console messages with advice tailored for 11 | * your specific monorepo. 12 | */ 13 | "customTips": [ 14 | // { 15 | // /** 16 | // * (REQUIRED) An identifier indicating a message that may be printed by Rush. 17 | // * If that message is printed, then this custom tip will be shown. 18 | // * The list of available tip identifiers can be found on this page: 19 | // * https://rushjs.io/pages/maintainer/custom_tips/ 20 | // */ 21 | // "tipId": "TIP_RUSH_INCONSISTENT_VERSIONS", 22 | // 23 | // /** 24 | // * (REQUIRED) The message text to be displayed for this tip. 25 | // */ 26 | // "message": "For additional troubleshooting information, refer this wiki article:\n\nhttps://intranet.contoso.com/docs/pnpm-mismatch" 27 | // } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /common/config/rush/repo-state.json: -------------------------------------------------------------------------------- 1 | // DO NOT MODIFY THIS FILE MANUALLY BUT DO COMMIT IT. It is generated and used by Rush. 2 | { 3 | "preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f" 4 | } 5 | -------------------------------------------------------------------------------- /common/config/rush/rush-plugins.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This configuration file manages Rush's plugin feature. 3 | */ 4 | { 5 | "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush-plugins.schema.json", 6 | "plugins": [ 7 | /** 8 | * Each item configures a plugin to be loaded by Rush. 9 | */ 10 | // { 11 | // /** 12 | // * The name of the NPM package that provides the plugin. 13 | // */ 14 | // "packageName": "@scope/my-rush-plugin", 15 | // /** 16 | // * The name of the plugin. This can be found in the "pluginName" 17 | // * field of the "rush-plugin-manifest.json" file in the NPM package folder. 18 | // */ 19 | // "pluginName": "my-plugin-name", 20 | // /** 21 | // * The name of a Rush autoinstaller that will be used for installation, which 22 | // * can be created using "rush init-autoinstaller". Add the plugin's NPM package 23 | // * to the package.json "dependencies" of your autoinstaller, then run 24 | // * "rush update-autoinstaller". 25 | // */ 26 | // "autoinstallerName": "rush-plugins" 27 | // } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /common/config/rush/subspaces.json: -------------------------------------------------------------------------------- 1 | /** 2 | * This configuration file manages the experimental "subspaces" feature for Rush, 3 | * which allows multiple PNPM lockfiles to be used in a single Rush workspace. 4 | * For full documentation, please see https://rushjs.io 5 | */ 6 | { 7 | "$schema": "https://developer.microsoft.com/json-schemas/rush/v5/subspaces.schema.json", 8 | 9 | /** 10 | * Set this flag to "true" to enable usage of subspaces. 11 | */ 12 | "subspacesEnabled": false, 13 | 14 | /** 15 | * (DEPRECATED) This is a temporary workaround for migrating from an earlier prototype 16 | * of this feature: https://github.com/microsoft/rushstack/pull/3481 17 | * It allows subspaces with only one project to store their config files in the project folder. 18 | */ 19 | "splitWorkspaceCompatibility": false, 20 | 21 | /** 22 | * When a command such as "rush update" is invoked without the "--subspace" or "--to" 23 | * parameters, Rush will install all subspaces. In a huge monorepo with numerous subspaces, 24 | * this would be extremely slow. Set "preventSelectingAllSubspaces" to true to avoid this 25 | * mistake by always requiring selection parameters for commands such as "rush update". 26 | */ 27 | "preventSelectingAllSubspaces": false, 28 | 29 | /** 30 | * The list of subspace names, which should be lowercase alphanumeric words separated by 31 | * hyphens, for example "my-subspace". The corresponding config files will have paths 32 | * such as "common/config/subspaces/my-subspace/package-lock.yaml". 33 | */ 34 | "subspaceNames": [] 35 | } 36 | -------------------------------------------------------------------------------- /common/git-hooks/commit-msg.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # This is an example Git hook for use with Rush. To enable this hook, rename this file 4 | # to "commit-msg" and then run "rush install", which will copy it from common/git-hooks 5 | # to the .git/hooks folder. 6 | # 7 | # TO LEARN MORE ABOUT GIT HOOKS 8 | # 9 | # The Git documentation is here: https://git-scm.com/docs/githooks 10 | # Some helpful resources: https://githooks.com 11 | # 12 | # ABOUT THIS EXAMPLE 13 | # 14 | # The commit-msg hook is called by "git commit" with one argument, the name of the file 15 | # that has the commit message. The hook should exit with non-zero status after issuing 16 | # an appropriate message if it wants to stop the commit. The hook is allowed to edit 17 | # the commit message file. 18 | 19 | # This example enforces that commit message should contain a minimum amount of 20 | # description text. 21 | if [ `cat $1 | wc -w` -lt 3 ]; then 22 | echo "" 23 | echo "Invalid commit message: The message must contain at least 3 words." 24 | exit 1 25 | fi 26 | -------------------------------------------------------------------------------- /common/git-hooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Called by "git commit" with no arguments. The hook should 3 | # exit with non-zero status after issuing an appropriate message if 4 | # it wants to stop the commit. 5 | 6 | # Invoke the "rush prettier" custom command to reformat files whenever they 7 | # are committed. The command is defined in common/config/rush/command-line.json 8 | # and uses the "rush-prettier" autoinstaller. 9 | node common/scripts/install-run-rush.js prettier || exit $? 10 | -------------------------------------------------------------------------------- /common/scripts/install-run-rush-pnpm.js: -------------------------------------------------------------------------------- 1 | // THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED. 2 | // 3 | // This script is intended for usage in an automated build environment where the Rush command may not have 4 | // been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush 5 | // specified in the rush.json configuration file (if not already installed), and then pass a command-line to the 6 | // rush-pnpm command. 7 | // 8 | // An example usage would be: 9 | // 10 | // node common/scripts/install-run-rush-pnpm.js pnpm-command 11 | // 12 | // For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/ 13 | // 14 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 15 | // See the @microsoft/rush package's LICENSE file for details. 16 | 17 | /******/ (() => { // webpackBootstrap 18 | /******/ "use strict"; 19 | var __webpack_exports__ = {}; 20 | /*!*****************************************************!*\ 21 | !*** ./lib-esnext/scripts/install-run-rush-pnpm.js ***! 22 | \*****************************************************/ 23 | 24 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 25 | // See LICENSE in the project root for license information. 26 | require('./install-run-rush'); 27 | //# sourceMappingURL=install-run-rush-pnpm.js.map 28 | module.exports = __webpack_exports__; 29 | /******/ })() 30 | ; 31 | //# sourceMappingURL=install-run-rush-pnpm.js.map -------------------------------------------------------------------------------- /common/scripts/install-run-rushx.js: -------------------------------------------------------------------------------- 1 | // THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED. 2 | // 3 | // This script is intended for usage in an automated build environment where the Rush command may not have 4 | // been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush 5 | // specified in the rush.json configuration file (if not already installed), and then pass a command-line to the 6 | // rushx command. 7 | // 8 | // An example usage would be: 9 | // 10 | // node common/scripts/install-run-rushx.js custom-command 11 | // 12 | // For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/ 13 | // 14 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 15 | // See the @microsoft/rush package's LICENSE file for details. 16 | 17 | /******/ (() => { // webpackBootstrap 18 | /******/ "use strict"; 19 | var __webpack_exports__ = {}; 20 | /*!*************************************************!*\ 21 | !*** ./lib-esnext/scripts/install-run-rushx.js ***! 22 | \*************************************************/ 23 | 24 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 25 | // See LICENSE in the project root for license information. 26 | require('./install-run-rush'); 27 | //# sourceMappingURL=install-run-rushx.js.map 28 | module.exports = __webpack_exports__; 29 | /******/ })() 30 | ; 31 | //# sourceMappingURL=install-run-rushx.js.map -------------------------------------------------------------------------------- /eslint-plugin/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458 2 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/modern-module-resolution'); 3 | // This is a workaround for https://github.com/microsoft/rushstack/issues/3021 4 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/custom-config-package-names'); 5 | 6 | module.exports = { 7 | extends: [ 8 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/profile/node', 9 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/mixins/friendly-locals' 10 | ], 11 | parserOptions: { tsconfigRootDir: __dirname }, 12 | 13 | plugins: ['eslint-plugin-header'], 14 | overrides: [ 15 | { 16 | files: ['*.ts', '*.tsx'], 17 | rules: { 18 | // Rationale: Including the `type` annotation in the import statement for imports 19 | // only used as types prevents the import from being emitted in the compiled output. 20 | '@typescript-eslint/consistent-type-imports': [ 21 | 'warn', 22 | { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 23 | ], 24 | 25 | // Rationale: If all imports in an import statement are only used as types, 26 | // then the import statement should be omitted in the compiled JS output. 27 | '@typescript-eslint/no-import-type-side-effects': 'warn', 28 | 29 | 'header/header': [ 30 | 'warn', 31 | 'line', 32 | [ 33 | ' Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.', 34 | ' See LICENSE in the project root for license information.' 35 | ] 36 | ] 37 | } 38 | } 39 | ] 40 | }; 41 | -------------------------------------------------------------------------------- /eslint-plugin/.npmignore: -------------------------------------------------------------------------------- 1 | # THIS IS A STANDARD TEMPLATE FOR .npmignore FILES IN THIS REPO. 2 | 3 | # Ignore all files by default, to avoid accidentally publishing unintended files. 4 | * 5 | 6 | # Use negative patterns to bring back the specific things we want to publish. 7 | !/bin/** 8 | !/lib/** 9 | !/lib-*/** 10 | !/dist/** 11 | 12 | !CHANGELOG.md 13 | !CHANGELOG.json 14 | !heft-plugin.json 15 | !rush-plugin-manifest.json 16 | !ThirdPartyNotice.txt 17 | 18 | # Ignore certain patterns that should not get published. 19 | /dist/*.stats.* 20 | /lib/**/test/ 21 | /lib-*/**/test/ 22 | *.test.js 23 | 24 | # NOTE: These don't need to be specified, because NPM includes them automatically. 25 | # 26 | # package.json 27 | # README.md 28 | # LICENSE 29 | 30 | # --------------------------------------------------------------------------- 31 | # DO NOT MODIFY ABOVE THIS LINE! Add any project-specific overrides below. 32 | # --------------------------------------------------------------------------- 33 | -------------------------------------------------------------------------------- /eslint-plugin/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log - eslint-plugin-tsdoc 2 | 3 | This log was last generated on Sat, 23 Nov 2024 00:23:35 GMT and should not be manually modified. 4 | 5 | ## 0.4.0 6 | Sat, 23 Nov 2024 00:23:35 GMT 7 | 8 | ### Minor changes 9 | 10 | - Leverage `parserOptions.tsConfigRootDir` to reduce file system probing. This field is commonly used when eslint is configured with `@typescript-eslint/parser`. 11 | 12 | ### Patches 13 | 14 | - Include CHANGELOG.md in published releases again 15 | 16 | ## 0.3.0 17 | Tue, 28 May 2024 21:34:19 GMT 18 | 19 | ### Minor changes 20 | 21 | - Minor package cleanup. 22 | 23 | ### Patches 24 | 25 | - Upgrade dev toolchain (Heft, Webpack, TypeScript, ESLint) 26 | 27 | ## 0.2.17 28 | Wed, 14 Sep 2022 02:55:06 GMT 29 | 30 | _Version update only_ 31 | 32 | ## 0.2.16 33 | Sat, 09 Apr 2022 02:28:41 GMT 34 | 35 | ### Patches 36 | 37 | - Rename the "master" branch to "main." 38 | 39 | ## 0.2.15 40 | Thu, 07 Apr 2022 22:51:07 GMT 41 | 42 | _Version update only_ 43 | 44 | ## 0.2.14 45 | Tue, 20 Apr 2021 04:25:13 GMT 46 | 47 | _Version update only_ 48 | 49 | ## 0.2.13 50 | Mon, 19 Apr 2021 21:22:32 GMT 51 | 52 | _Version update only_ 53 | 54 | ## 0.2.12 55 | Fri, 16 Apr 2021 23:22:26 GMT 56 | 57 | _Version update only_ 58 | 59 | ## 0.2.11 60 | Fri, 22 Jan 2021 18:07:19 GMT 61 | 62 | _Version update only_ 63 | 64 | ## 0.2.10 65 | Thu, 03 Dec 2020 08:07:55 GMT 66 | 67 | _Version update only_ 68 | 69 | ## 0.2.9 70 | Thu, 03 Dec 2020 04:31:52 GMT 71 | 72 | _Version update only_ 73 | 74 | ## 0.2.8 75 | Mon, 30 Nov 2020 06:16:21 GMT 76 | 77 | ### Patches 78 | 79 | - Update documentation to reference the new website URL 80 | - Upgrade build tools and configuration 81 | 82 | ## 0.2.7 83 | Fri, 04 Sep 2020 15:53:27 GMT 84 | 85 | ### Patches 86 | 87 | - Update build system 88 | 89 | ## 0.2.6 90 | Sun, 19 Jul 2020 01:22:35 GMT 91 | 92 | _Version update only_ 93 | 94 | ## 0.2.5 95 | Wed, 20 May 2020 22:33:27 GMT 96 | 97 | _Version update only_ 98 | 99 | ## 0.2.4 100 | Fri, 27 Mar 2020 23:14:53 GMT 101 | 102 | ### Patches 103 | 104 | - Improve plugin documentation URL in ESLint metadata 105 | 106 | ## 0.2.3 107 | Sat, 22 Feb 2020 20:44:16 GMT 108 | 109 | _Version update only_ 110 | 111 | ## 0.2.2 112 | Sat, 22 Feb 2020 02:55:07 GMT 113 | 114 | _Version update only_ 115 | 116 | ## 0.2.1 117 | Tue, 21 Jan 2020 21:26:36 GMT 118 | 119 | ### Patches 120 | 121 | - Use a cache to avoid repeatedly reloading tsdoc.json during linting 122 | 123 | ## 0.2.0 124 | Tue, 19 Nov 2019 22:01:56 GMT 125 | 126 | ### Minor changes 127 | 128 | - Add support for defining your own custom tags using tsdoc.json 129 | 130 | ## 0.1.2 131 | Sat, 09 Nov 2019 05:55:42 GMT 132 | 133 | ### Patches 134 | 135 | - Improve lint rule to check every doc comment in a source file 136 | 137 | ## 0.1.1 138 | Sat, 09 Nov 2019 04:57:59 GMT 139 | 140 | ### Patches 141 | 142 | - Improve error location accuracy 143 | - Generalize the TSDoc parser configuration to allow any standard tag 144 | 145 | ## 0.1.0 146 | Wed, 06 Nov 2019 00:40:51 GMT 147 | 148 | ### Minor changes 149 | 150 | - Initial release of plugin 151 | 152 | -------------------------------------------------------------------------------- /eslint-plugin/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /eslint-plugin/README.md: -------------------------------------------------------------------------------- 1 | # eslint-plugin-tsdoc 2 | 3 | This ESLint plugin provides a rule for validating that TypeScript doc comments conform to the 4 | [TSDoc specification](https://tsdoc.org/). 5 | 6 | ## Usage 7 | 8 | 1. Configure ESLint for your TypeScript project. See the instructions provided by the 9 | [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint) project. 10 | You will end up with some dependencies like this: 11 | 12 | **my-project/package.json** (example) 13 | ```ts 14 | { 15 | "name": "my-project", 16 | "version": "1.0.0", 17 | "dependencies": {}, 18 | "devDependencies": { 19 | "@typescript-eslint/eslint-plugin": "~2.6.1", 20 | "@typescript-eslint/parser": "~2.6.1", 21 | "eslint": "~6.6.0", 22 | "typescript": "~3.7.2" 23 | }, 24 | "scripts": { 25 | "lint": "eslint -f unix \"src/**/*.{ts,tsx}\"" 26 | } 27 | } 28 | ``` 29 | 30 | 2. Add the `eslint-plugin-tsdoc` dependency to your project: 31 | 32 | ```bash 33 | $ cd my-project 34 | $ npm install --save-dev eslint-plugin-tsdoc 35 | ``` 36 | 37 | 3. In your ESLint config file, add the `"eslint-plugin-tsdoc"` package to your `plugins` field, 38 | and enable the `"tsdoc/syntax"` rule. For example: 39 | 40 | **my-project/.eslintrc.js** (example) 41 | ```ts 42 | module.exports = { 43 | plugins: [ 44 | "@typescript-eslint/eslint-plugin", 45 | "eslint-plugin-tsdoc" 46 | ], 47 | extends: [ 48 | 'plugin:@typescript-eslint/recommended' 49 | ], 50 | parser: '@typescript-eslint/parser', 51 | parserOptions: { 52 | project: "./tsconfig.json", 53 | tsconfigRootDir: __dirname, 54 | ecmaVersion: 2018, 55 | sourceType: "module" 56 | }, 57 | rules: { 58 | "tsdoc/syntax": "warn" 59 | } 60 | }; 61 | ``` 62 | 63 | This package is maintained by the TSDoc project. If you have questions or feedback, please 64 | [let us know](https://tsdoc.org/pages/resources/help)! 65 | -------------------------------------------------------------------------------- /eslint-plugin/config/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@rushstack/heft-node-rig/profiles/default/config/jest.config.json" 3 | } 4 | -------------------------------------------------------------------------------- /eslint-plugin/config/rig.json: -------------------------------------------------------------------------------- 1 | // The "rig.json" file directs tools to look for their config files in an external package. 2 | // Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package 3 | { 4 | "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", 5 | 6 | /** 7 | * (Required) The name of the rig package to inherit from. 8 | * It should be an NPM package name with the "-rig" suffix. 9 | */ 10 | "rigPackageName": "@rushstack/heft-node-rig" 11 | 12 | /** 13 | * (Optional) Selects a config profile from the rig package. The name must consist of 14 | * lowercase alphanumeric words separated by hyphens, for example "sample-profile". 15 | * If omitted, then the "default" profile will be used." 16 | */ 17 | // "rigProfile": "your-profile-name" 18 | } 19 | -------------------------------------------------------------------------------- /eslint-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-tsdoc", 3 | "version": "0.4.0", 4 | "description": "An ESLint plugin that validates TypeScript doc comments", 5 | "keywords": [ 6 | "TypeScript", 7 | "documentation", 8 | "doc", 9 | "comments", 10 | "JSDoc", 11 | "TSDoc", 12 | "ESLint", 13 | "plugin" 14 | ], 15 | "license": "MIT", 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/microsoft/tsdoc", 19 | "directory": "eslint-plugin" 20 | }, 21 | "homepage": "https://tsdoc.org/", 22 | "main": "lib/index.js", 23 | "typings": "lib/index.d.ts", 24 | "scripts": { 25 | "build": "heft test --clean", 26 | "_phase:build": "heft run --only build -- --clean", 27 | "_phase:test": "heft run --only test -- --clean" 28 | }, 29 | "dependencies": { 30 | "@microsoft/tsdoc": "workspace:*", 31 | "@microsoft/tsdoc-config": "workspace:*" 32 | }, 33 | "devDependencies": { 34 | "@rushstack/heft-node-rig": "~2.6.45", 35 | "@rushstack/heft": "^0.68.10", 36 | "@types/eslint": "8.40.1", 37 | "@types/estree": "1.0.1", 38 | "@types/heft-jest": "1.0.3", 39 | "@types/node": "14.18.36", 40 | "eslint": "~8.57.0", 41 | "eslint-plugin-header": "~3.1.1" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /eslint-plugin/src/Debug.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | export class Debug { 5 | // To debug the plugin, temporarily uncomment the body of this function 6 | public static log(message: string): void { 7 | // message = require("process").pid + ": " + message; 8 | // console.log(message); 9 | // require('fs').writeFileSync('C:\\Git\\log.txt', message + '\r\n', { flag: 'as' }); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /eslint-plugin/src/tests/plugin.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { RuleTester } from 'eslint'; 5 | import * as plugin from '../index'; 6 | 7 | const ruleTester: RuleTester = new RuleTester({ 8 | env: { 9 | es6: true 10 | } 11 | }); 12 | ruleTester.run('"tsdoc/syntax" rule', plugin.rules.syntax, { 13 | valid: [ 14 | '/**\nA great function!\n */\nfunction foobar() {}\n', 15 | '/**\nA great class!\n */\nclass FooBar {}\n' 16 | ], 17 | invalid: [ 18 | { 19 | code: '/**\n * This `is wrong\n */\nfunction foobar() {}\n', 20 | errors: [ 21 | { 22 | messageId: 'tsdoc-code-span-missing-delimiter' 23 | } 24 | ] 25 | }, 26 | { 27 | code: '/**\n * This `is wrong\n */\nclass FooBar {}\n', 28 | errors: [ 29 | { 30 | messageId: 'tsdoc-code-span-missing-delimiter' 31 | } 32 | ] 33 | } 34 | ] 35 | }); 36 | -------------------------------------------------------------------------------- /eslint-plugin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "./node_modules/@rushstack/heft-node-rig/profiles/default/tsconfig-base.json", 4 | "compilerOptions": { 5 | "isolatedModules": true, 6 | "types": ["heft-jest", "node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /playground/.eslintignore: -------------------------------------------------------------------------------- 1 | src/samples/ 2 | -------------------------------------------------------------------------------- /playground/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458 2 | require('@rushstack/heft-web-rig/profiles/library/includes/eslint/patch/modern-module-resolution'); 3 | // This is a workaround for https://github.com/microsoft/rushstack/issues/3021 4 | require('@rushstack/heft-web-rig/profiles/library/includes/eslint/patch/custom-config-package-names'); 5 | 6 | module.exports = { 7 | extends: [ 8 | '@rushstack/heft-web-rig/profiles/library/includes/eslint/profile/web-app', 9 | '@rushstack/heft-web-rig/profiles/library/includes/eslint/mixins/friendly-locals', 10 | '@rushstack/heft-web-rig/profiles/library/includes/eslint/mixins/react' 11 | ], 12 | 13 | settings: { 14 | react: { 15 | version: '16.9' 16 | } 17 | }, 18 | 19 | parserOptions: { tsconfigRootDir: __dirname }, 20 | 21 | plugins: ['eslint-plugin-header'], 22 | overrides: [ 23 | { 24 | files: ['*.ts', '*.tsx'], 25 | rules: { 26 | // Rationale: Including the `type` annotation in the import statement for imports 27 | // only used as types prevents the import from being emitted in the compiled output. 28 | '@typescript-eslint/consistent-type-imports': [ 29 | 'warn', 30 | { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 31 | ], 32 | 33 | // Rationale: If all imports in an import statement are only used as types, 34 | // then the import statement should be omitted in the compiled JS output. 35 | '@typescript-eslint/no-import-type-side-effects': 'warn', 36 | 37 | 'header/header': [ 38 | 'warn', 39 | 'line', 40 | [ 41 | ' Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.', 42 | ' See LICENSE in the project root for license information.' 43 | ] 44 | ] 45 | } 46 | } 47 | ] 48 | }; 49 | -------------------------------------------------------------------------------- /playground/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /playground/config/heft.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", 3 | 4 | "extends": "@rushstack/heft-web-rig/profiles/library/config/heft.json", 5 | 6 | "phasesByName": { 7 | "build": { 8 | "tasksByName": { 9 | "post-compile-copy": { 10 | // The "post-compile-copy" task should not run until after "typescript" completes 11 | "taskDependencies": ["typescript"], 12 | 13 | "taskPlugin": { 14 | "pluginName": "copy-files-plugin", 15 | "pluginPackage": "@rushstack/heft", 16 | "options": { 17 | "copyOperations": [ 18 | { 19 | "sourcePath": "..", 20 | "destinationFolders": ["./dist"], 21 | "includeGlobs": ["LICENSE"] 22 | } 23 | ] 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /playground/config/rig.json: -------------------------------------------------------------------------------- 1 | // The "rig.json" file directs tools to look for their config files in an external package. 2 | // Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package 3 | { 4 | "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", 5 | 6 | /** 7 | * (Required) The name of the rig package to inherit from. 8 | * It should be an NPM package name with the "-rig" suffix. 9 | */ 10 | "rigPackageName": "@rushstack/heft-web-rig", 11 | 12 | /** 13 | * (Optional) Selects a config profile from the rig package. The name must consist of 14 | * lowercase alphanumeric words separated by hyphens, for example "sample-profile". 15 | * If omitted, then the "default" profile will be used." 16 | */ 17 | "rigProfile": "library" 18 | } 19 | -------------------------------------------------------------------------------- /playground/config/typescript.json: -------------------------------------------------------------------------------- 1 | /** 2 | * Configures the TypeScript plugin for Heft. This plugin also manages linting. 3 | */ 4 | { 5 | "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/typescript.schema.json", 6 | 7 | "extends": "@rushstack/heft-web-rig/profiles/library/config/typescript.json", 8 | 9 | "staticAssetsToCopy": { 10 | "fileExtensions": [".json", ".css", ".scss"], 11 | "includeGlobs": ["samples/*.ts"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsdoc-playground", 3 | "version": "0.0.0", 4 | "description": "An interactive web application for experimenting with TSDoc syntax", 5 | "private": true, 6 | "license": "MIT", 7 | "scripts": { 8 | "build": "heft build --clean", 9 | "start": "heft start", 10 | "_phase:build": "heft run --only build -- --clean" 11 | }, 12 | "dependencies": { 13 | "@microsoft/tsdoc": "workspace:*", 14 | "@types/react": "16.9.11", 15 | "@types/react-dom": "16.9.3", 16 | "monaco-editor": "~0.50.0", 17 | "promise": "~8.0.3", 18 | "react": "~16.14.0", 19 | "react-dom": "~16.14.0", 20 | "tslib": "~2.5.3" 21 | }, 22 | "devDependencies": { 23 | "@rushstack/heft": "^0.68.10", 24 | "@rushstack/heft-web-rig": "~0.25.12", 25 | "@types/webpack-env": "1.18.0", 26 | "eslint": "~8.57.0", 27 | "eslint-plugin-header": "~3.1.1", 28 | "handlebars": "~4.7.7", 29 | "handlebars-loader": "~1.7.3", 30 | "monaco-editor-webpack-plugin": "~7.1.0", 31 | "webpack": "~5.92.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /playground/public/index.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | TSDoc Playground 9 | 10 | 11 | 16 | 20 | 25 | 26 | 27 | 28 |
29 | 30 | -------------------------------------------------------------------------------- /playground/src/App.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import * as React from 'react'; 5 | import { PlaygroundView } from './PlaygroundView'; 6 | 7 | export default function App(): JSX.Element { 8 | return ( 9 | <> 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /playground/src/DocAstView.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import * as React from 'react'; 5 | import * as tsdoc from '@microsoft/tsdoc'; 6 | import { CodeEditor } from './CodeEditor'; 7 | 8 | export interface IDocAstViewProps { 9 | style?: React.CSSProperties; 10 | parserContext: tsdoc.ParserContext | undefined; 11 | theme?: string; 12 | } 13 | 14 | export function DocAstView(props: IDocAstViewProps): JSX.Element { 15 | const parserContext: tsdoc.ParserContext | undefined = props.parserContext; 16 | const outputLines: string[] = []; 17 | 18 | if (parserContext && parserContext.docComment) { 19 | _dumpTSDocTree(outputLines, parserContext.docComment); 20 | } 21 | 22 | return ( 23 | 30 | ); 31 | } 32 | 33 | function _dumpTSDocTree(outputLines: string[], docNode: tsdoc.DocNode, indent: string = ''): void { 34 | let dumpText: string = ''; 35 | if (docNode instanceof tsdoc.DocExcerpt) { 36 | const content: string = docNode.content.toString(); 37 | dumpText += `${indent}* ${docNode.excerptKind}=` + JSON.stringify(content); 38 | } else { 39 | dumpText += `${indent}- ${docNode.kind}`; 40 | } 41 | outputLines.push(dumpText); 42 | 43 | for (const child of docNode.getChildNodes()) { 44 | _dumpTSDocTree(outputLines, child, indent + ' '); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /playground/src/FlexDivs.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import * as React from 'react'; 5 | 6 | export interface IFlexDivProps 7 | extends React.DetailedHTMLProps, HTMLDivElement> {} 8 | 9 | export function FlexRowDiv(props: IFlexDivProps): JSX.Element { 10 | const mergedProps: IFlexDivProps = { 11 | ...props, 12 | style: { 13 | display: 'flex', 14 | flexDirection: 'row', 15 | ...props.style 16 | } 17 | }; 18 | 19 | return React.createElement('div', mergedProps); 20 | } 21 | 22 | export function FlexColDiv(props: IFlexDivProps): JSX.Element { 23 | const mergedProps: IFlexDivProps = { 24 | ...props, 25 | style: { 26 | display: 'flex', 27 | flexDirection: 'column', 28 | ...props.style 29 | } 30 | }; 31 | 32 | return React.createElement('div', mergedProps); 33 | } 34 | -------------------------------------------------------------------------------- /playground/src/PlaygroundView.module.scss: -------------------------------------------------------------------------------- 1 | .playgroundMainRow { 2 | align-items: stretch; 3 | flex: 1; 4 | } 5 | 6 | @media screen and (max-width: 700px) { 7 | .playgroundMainRow { 8 | align-items: stretch; 9 | flex: 1; 10 | flex-direction: column !important; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /playground/src/SyntaxStyler/DocNodeSyntaxStylerTheme.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | export interface IThemeRule { 5 | foreground?: string; 6 | background?: string; 7 | fontWeight?: string; 8 | className?: string; 9 | } 10 | 11 | export interface IDocNodeSyntaxStylerTheme { 12 | [styleTokens: string]: IThemeRule; 13 | } 14 | 15 | export class MonacoTSDocTheme { 16 | public static readonly vs: IDocNodeSyntaxStylerTheme = { 17 | 'tsdoc.delimiter': { foreground: 'a6a6a6' }, 18 | 'tsdoc.tag.block': { foreground: '003399', fontWeight: 'bold', className: 'tsdoc-blocktag' }, 19 | 'tsdoc.tag.inline': { foreground: '003399', fontWeight: 'bold' }, 20 | 'tsdoc.tag.modifier': { foreground: 'C55411', fontWeight: 'bold' }, 21 | 'tsdoc.tag.undefined': { foreground: 'a6a6a6' }, 22 | 'tsdoc.member.selector': { foreground: 'C55411' }, 23 | 'tsdoc.member.identifier': { foreground: '3D7CAA' }, 24 | 'tsdoc.packageName': { foreground: '003399' }, 25 | 'tsdoc.importPath': { foreground: '003399' }, 26 | 'tsdoc.element.name': { foreground: '003399' }, 27 | 'tsdoc.element.attribute.name': { foreground: '003399' }, 28 | 'tsdoc.element.attribute.value': { foreground: '000000' }, 29 | 'tsdoc.url': { foreground: '3D7CAA', className: 'tsdoc-underline' }, 30 | 'tsdoc.code': { foreground: '000000' }, 31 | 'tsdoc.language': { foreground: 'C55411' }, 32 | 'tsdoc.error': { foreground: 'FFFFFF', background: 'c00000' }, 33 | 'tsdoc.escaped': { background: 'e0e0e0' } 34 | }; 35 | 36 | public static readonly vsDark: IDocNodeSyntaxStylerTheme = { 37 | 'tsdoc.delimiter': { foreground: 'a6a6a6' }, 38 | 'tsdoc.tag.block': { foreground: '646fd1', fontWeight: 'bold', className: 'tsdoc-blocktag' }, 39 | 'tsdoc.tag.inline': { foreground: '646fd1', fontWeight: 'bold' }, 40 | 'tsdoc.tag.modifier': { foreground: 'b46695', fontWeight: 'bold' }, 41 | 'tsdoc.tag.undefined': { foreground: 'a6a6a6' }, 42 | 'tsdoc.member.selector': { foreground: 'b46695' }, 43 | 'tsdoc.member.identifier': { foreground: '64b0d2' }, 44 | 'tsdoc.packageName': { foreground: '646fd1' }, 45 | 'tsdoc.importPath': { foreground: '646fd1' }, 46 | 'tsdoc.element.name': { foreground: '646fd1' }, 47 | 'tsdoc.element.attribute.name': { foreground: '646fd1' }, 48 | 'tsdoc.element.attribute.value': { foreground: 'd4d4d4' }, 49 | 'tsdoc.url': { foreground: '64b0d2', className: 'tsdoc-underline' }, 50 | 'tsdoc.code': { foreground: 'd4d4d4' }, 51 | 'tsdoc.language': { foreground: 'b46695' }, 52 | 'tsdoc.error': { foreground: 'd4d4d4', background: 'c00000' }, 53 | 'tsdoc.escaped': { background: '333333' } 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /playground/src/SyntaxStyler/syntaxStyles.css: -------------------------------------------------------------------------------- 1 | .tsdoc-underline { 2 | text-decoration: underline !important; 3 | } 4 | 5 | .tsdoc-blocktag { 6 | border-color: #a6a6a6; 7 | border-width: 1px; 8 | border-top-style: solid; 9 | border-left-style: solid; 10 | border-right-style: none; 11 | border-bottom-style: none; 12 | border-top-left-radius: 4px; 13 | padding-left: 1px; 14 | margin-left: -1px; 15 | } 16 | 17 | .tsdoc-blocktag + .tsdoc-blocktag { 18 | border-left-style: none; 19 | border-top-left-radius: 0px; 20 | } 21 | -------------------------------------------------------------------------------- /playground/src/samples/SampleInputs.ts: -------------------------------------------------------------------------------- 1 | export namespace SampleInputs { 2 | export const advanced: string = require('./advancedSample.ts'); 3 | export const basic: string = require('./basicSample.ts'); 4 | export const hyperlink: string = require('./hyperlinkSample.ts'); 5 | } 6 | -------------------------------------------------------------------------------- /playground/src/samples/advancedSample.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The summary section should be brief. On a documentation web site, 3 | * it will be shown on a page that lists summaries for many different 4 | * API items. On a detail page for a single item, the summary will be 5 | * shown followed by the remarks section (if any). 6 | * 7 | * @remarks 8 | * 9 | * The main documentation for an API item is separated into a brief 10 | * "summary" section optionally followed by an `@remarks` block containing 11 | * additional details. 12 | * 13 | * Unlike the summary, the remarks block may contain lengthy documentation 14 | * content. The remarks should not restate information from the summary, 15 | * since the summary section will always be displayed wherever the remarks 16 | * section appears. Other sections (e.g. an `@example` block) if shown 17 | * will usually appear after the remarks section. 18 | * 19 | * Code samples can be enclosed in a Markdown code fence: 20 | * ```ts 21 | * function getAverage(x, y) { 22 | * return (x + y) / 2.0; 23 | * } 24 | * ``` 25 | * 26 | * If you use special symbols and don't want to use a code span, you can 27 | * escape them using backslashes: \{\@inheritDoc Button.render\} 28 | * 29 | * @sampleCustomBlockTag 30 | * 31 | * You can define your own custom block tags and tell the parser about them. 32 | * The playground doesn't render this block, but your own tooling could do that. 33 | * 34 | * @privateRemarks 35 | * 36 | * The `@privateRemarks` tag starts a block of additional commentary that is not meant 37 | * for an external audience. A documentation tool must omit this content from an 38 | * API reference web site. It should also be omitted when generating a normalized 39 | * *.d.ts file. 40 | * 41 | * Modifiers look like block tags, but they do not start a documentation block. 42 | * For example this `@sealed` tag tells us that nobody should inherit from the 43 | * class. But if text appeared after it, that text would get attached to the 44 | * previous block. 45 | * 46 | * @sealed 47 | */ 48 | -------------------------------------------------------------------------------- /playground/src/samples/basicSample.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns the average of two numbers. 3 | * 4 | * @remarks 5 | * This method is part of the {@link core-library#Statistics | Statistics subsystem}. 6 | * 7 | * @param x - The first input number 8 | * @param y - The second input number 9 | * @returns The arithmetic mean of `x` and `y` 10 | * 11 | * @beta 12 | */ 13 | function getAverage(x: number, y: number): number { 14 | return (x + y) / 2.0; 15 | } 16 | 17 | // The TypeScript function is included for illustrative purposes. 18 | // It is not processed by the TSDoc parser. 19 | -------------------------------------------------------------------------------- /playground/src/samples/hyperlinkSample.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Let's learn about the `{@link}` tag. 3 | * 4 | * @remarks 5 | * 6 | * Links can point to a URL: {@link https://github.com/microsoft/tsdoc} 7 | * 8 | * Links can point to an API item: {@link Button} 9 | * 10 | * You can optionally include custom link text: {@link Button | the Button class} 11 | * 12 | * Suppose the `Button` class is part of an external package. In that case, we 13 | * can include the package name when referring to it: 14 | * 15 | * {@link my-control-library#Button | the Button class} 16 | * 17 | * The package name can include an NPM scope and import path: 18 | * 19 | * {@link @microsoft/my-control-library/lib/Button#Button | the Button class} 20 | * 21 | * The TSDoc standard calls this notation a "declaration reference". The notation supports 22 | * references to many different kinds of TypeScript declarations. This notation was originally 23 | * designed for use in `{@link}` and `{@inheritDoc}` tags, but you can also use it in your 24 | * own custom tags. 25 | * 26 | * For example, the `Button` can be part of a TypeScript namespace: 27 | * 28 | * {@link my-control-library#controls.Button | the Button class} 29 | * 30 | * We can refer to a member of the class: 31 | * 32 | * {@link controls.Button.render | the render() method} 33 | * 34 | * If a static and instance member have the same name, we can use a selector to distinguish them: 35 | * 36 | * {@link controls.Button.(render:instance) | the render() method} 37 | * 38 | * {@link controls.Button.(render:static) | the render() static member} 39 | * 40 | * This is also how we refer to the class's constructor: 41 | * 42 | * {@link controls.(Button:constructor) | the class constructor} 43 | * 44 | * Sometimes a name has special characters that are not a legal TypeScript identifier: 45 | * 46 | * {@link restProtocol.IServerResponse."first-name" | the first name property} 47 | * 48 | * Here is a fairly elaborate example where the function name is an ECMAScript 6 symbol, 49 | * and it's an overloaded function that uses a label selector (defined using the `{@label}` 50 | * TSDoc tag): 51 | * 52 | * {@link my-control-library#Button.([UISymbols.toNumberPrimitive]:OVERLOAD_1) 53 | * | the toNumberPrimitive() static member} 54 | * 55 | * See the TSDoc spec for more details about the "declaration reference" notation. 56 | */ 57 | -------------------------------------------------------------------------------- /playground/src/start.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | min-height: 100%; 7 | display: flex; 8 | flex-direction: column; 9 | flex-wrap: nowrap; 10 | margin: 0; 11 | 12 | flex-grow: 1; 13 | flex-shrink: 1; 14 | flex-basis: 100%; 15 | } 16 | 17 | #root { 18 | margin: 0; 19 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif, 20 | 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; 21 | font-size: 1rem; 22 | font-weight: 400; 23 | line-height: 1.5; 24 | color: #212529; 25 | text-align: left; 26 | background-color: #fff; 27 | 28 | flex-grow: 1; 29 | flex-shrink: 1; 30 | flex-basis: 100%; 31 | } 32 | 33 | input, 34 | button, 35 | select, 36 | optgroup, 37 | textarea { 38 | margin: 0; 39 | font-family: inherit; 40 | font-size: inherit; 41 | line-height: inherit; 42 | } 43 | 44 | .doc-section { 45 | font-family: Tahoma, sans-serif; 46 | font-size: 16px; 47 | } 48 | 49 | .doc-heading { 50 | color: #2f5496; 51 | font-size: 24px; 52 | font-weight: 400; 53 | 54 | margin-block-start: 1.2em; 55 | margin-block-end: 0.4em; 56 | } 57 | 58 | .doc-table { 59 | margin: 0; 60 | font-size: 16px; 61 | border: none; 62 | border-collapse: collapse; 63 | } 64 | 65 | .doc-table th, 66 | td { 67 | text-align: left; 68 | padding: 5px 10px; 69 | border-bottom: 2px solid #e0e0e0; 70 | } 71 | 72 | .doc-fenced-code { 73 | background-color: #f0f0f0; 74 | border: 1px solid #ccc; 75 | padding: 6px 10px; 76 | border-radius: 3px; 77 | overflow: auto; 78 | } 79 | 80 | .doc-code-span { 81 | background-color: #f0f0f0; 82 | color: #000; 83 | border-radius: 2pt; 84 | border: 1px solid #ccc; 85 | padding: 1pt; 86 | } 87 | -------------------------------------------------------------------------------- /playground/src/start.tsx: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import * as React from 'react'; 5 | import * as ReactDOM from 'react-dom'; 6 | import App from './App'; 7 | import './start.css'; 8 | 9 | // Ensure that this file changes each time it builds so deployment always works 10 | declare const COMMIT_ID: string; 11 | console.log(COMMIT_ID); 12 | 13 | const rootDiv: HTMLElement = document.getElementById('root') as HTMLElement; 14 | 15 | rootDiv.style.margin = '0'; 16 | rootDiv.style.height = '100%'; 17 | rootDiv.style.display = 'flex'; 18 | rootDiv.style.flexDirection = 'column'; 19 | 20 | ReactDOM.render(, rootDiv); 21 | -------------------------------------------------------------------------------- /playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "./node_modules/@rushstack/heft-web-rig/profiles/library/tsconfig-base.json", 4 | "compilerOptions": { 5 | "isolatedModules": true, 6 | "types": ["webpack-env"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /playground/webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); 5 | 6 | const RIG_BASE_PATH = path.dirname(require.resolve('@rushstack/heft-web-rig/package.json')); 7 | 8 | /** 9 | * require.resolve() an importPath using another NPM package's folder as 10 | * the base directory for module resolution 11 | */ 12 | function getPackagePathRelativeToRig(importPath) { 13 | const targetPath = require.resolve(importPath, { paths: [RIG_BASE_PATH] }); 14 | return targetPath; 15 | } 16 | 17 | /** 18 | * require() an importPath using another NPM package's folder as 19 | * the base directory for module resolution 20 | */ 21 | function requireRelativeToRig(importPath) { 22 | const targetPath = getPackagePathRelativeToRig(importPath); 23 | return require(targetPath); 24 | } 25 | 26 | const createWebpackConfig = require('@rushstack/heft-web-rig/profiles/app/webpack-base.config'); 27 | 28 | const webpack = requireRelativeToRig('webpack'); 29 | const HtmlWebpackPlugin = requireRelativeToRig('html-webpack-plugin'); 30 | 31 | module.exports = function createConfig(env, argv) { 32 | return createWebpackConfig({ 33 | env: env, 34 | argv: argv, 35 | projectRoot: __dirname, 36 | // Documentation: https://webpack.js.org/configuration/ 37 | configOverride: { 38 | module: { 39 | rules: [ 40 | { 41 | // For the lib/samples files which are imported as source code 42 | test: /\.ts$/, 43 | type: 'asset/source' 44 | }, 45 | // The following rules are needed to support the Monaco Editor 46 | { 47 | test: /\.css$/, 48 | use: [getPackagePathRelativeToRig('style-loader'), getPackagePathRelativeToRig('css-loader')], 49 | include: /node_modules[\/\\]monaco-editor/ 50 | }, 51 | { 52 | test: /\.ttf$/, 53 | type: 'asset/resource', 54 | include: /node_modules[\/\\]monaco-editor/ 55 | } 56 | ] 57 | }, 58 | plugins: [ 59 | new HtmlWebpackPlugin({ 60 | inject: true, 61 | template: `handlebars-loader!${__dirname}/public/index.hbs`, 62 | chunks: {} 63 | }), 64 | new webpack.optimize.ModuleConcatenationPlugin(), 65 | new webpack.DefinePlugin({ 66 | COMMIT_ID: `'${process.env['BUILD_SOURCEVERSION'] || 'COMMIT_SHA'}'` 67 | }), 68 | new MonacoWebpackPlugin() 69 | ], 70 | performance: { 71 | hints: false 72 | } 73 | } 74 | }); 75 | }; 76 | -------------------------------------------------------------------------------- /tsdoc-config/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458 2 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/modern-module-resolution'); 3 | // This is a workaround for https://github.com/microsoft/rushstack/issues/3021 4 | require('@rushstack/heft-node-rig/profiles/default/includes/eslint/patch/custom-config-package-names'); 5 | 6 | module.exports = { 7 | extends: [ 8 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/profile/node', 9 | '@rushstack/heft-node-rig/profiles/default/includes/eslint/mixins/friendly-locals' 10 | ], 11 | parserOptions: { tsconfigRootDir: __dirname }, 12 | 13 | plugins: ['eslint-plugin-header'], 14 | overrides: [ 15 | { 16 | files: ['*.ts', '*.tsx'], 17 | rules: { 18 | // Rationale: Including the `type` annotation in the import statement for imports 19 | // only used as types prevents the import from being emitted in the compiled output. 20 | '@typescript-eslint/consistent-type-imports': [ 21 | 'warn', 22 | { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 23 | ], 24 | 25 | // Rationale: If all imports in an import statement are only used as types, 26 | // then the import statement should be omitted in the compiled JS output. 27 | '@typescript-eslint/no-import-type-side-effects': 'warn', 28 | 29 | 'header/header': [ 30 | 'warn', 31 | 'line', 32 | [ 33 | ' Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.', 34 | ' See LICENSE in the project root for license information.' 35 | ] 36 | ] 37 | } 38 | } 39 | ] 40 | }; 41 | -------------------------------------------------------------------------------- /tsdoc-config/.npmignore: -------------------------------------------------------------------------------- 1 | # THIS IS A STANDARD TEMPLATE FOR .npmignore FILES IN THIS REPO. 2 | 3 | # Ignore all files by default, to avoid accidentally publishing unintended files. 4 | * 5 | 6 | # Use negative patterns to bring back the specific things we want to publish. 7 | !/bin/** 8 | !/lib/** 9 | !/lib-*/** 10 | !/dist/** 11 | 12 | !CHANGELOG.md 13 | !CHANGELOG.json 14 | !heft-plugin.json 15 | !rush-plugin-manifest.json 16 | !ThirdPartyNotice.txt 17 | 18 | # Ignore certain patterns that should not get published. 19 | /dist/*.stats.* 20 | /lib/**/test/ 21 | /lib-*/**/test/ 22 | *.test.js 23 | 24 | # NOTE: These don't need to be specified, because NPM includes them automatically. 25 | # 26 | # package.json 27 | # README.md 28 | # LICENSE 29 | 30 | # --------------------------------------------------------------------------- 31 | # DO NOT MODIFY ABOVE THIS LINE! Add any project-specific overrides below. 32 | # --------------------------------------------------------------------------- 33 | -------------------------------------------------------------------------------- /tsdoc-config/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Debug Jest tests", 11 | "program": "${workspaceFolder}/node_modules/@rushstack/heft/lib/start.js", 12 | "cwd": "${workspaceFolder}", 13 | "args": ["--debug", "test", "--clean"], 14 | "console": "integratedTerminal", 15 | "sourceMaps": true 16 | }, 17 | ] 18 | } -------------------------------------------------------------------------------- /tsdoc-config/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tsdoc-config/config/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@rushstack/heft-node-rig/profiles/default/config/jest.config.json" 3 | } 4 | -------------------------------------------------------------------------------- /tsdoc-config/config/rig.json: -------------------------------------------------------------------------------- 1 | // The "rig.json" file directs tools to look for their config files in an external package. 2 | // Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package 3 | { 4 | "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", 5 | 6 | /** 7 | * (Required) The name of the rig package to inherit from. 8 | * It should be an NPM package name with the "-rig" suffix. 9 | */ 10 | "rigPackageName": "@rushstack/heft-node-rig" 11 | 12 | /** 13 | * (Optional) Selects a config profile from the rig package. The name must consist of 14 | * lowercase alphanumeric words separated by hyphens, for example "sample-profile". 15 | * If omitted, then the "default" profile will be used." 16 | */ 17 | // "rigProfile": "your-profile-name" 18 | } 19 | -------------------------------------------------------------------------------- /tsdoc-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microsoft/tsdoc-config", 3 | "version": "0.17.1", 4 | "description": "A loader for the tsdoc.json file", 5 | "keywords": [ 6 | "TypeScript", 7 | "documentation", 8 | "doc", 9 | "comments", 10 | "JSDoc", 11 | "parser", 12 | "standard" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/microsoft/tsdoc", 17 | "directory": "tsdoc-config" 18 | }, 19 | "homepage": "https://tsdoc.org/", 20 | "main": "lib/index.js", 21 | "typings": "lib/index.d.ts", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@microsoft/tsdoc": "workspace:*", 25 | "ajv": "~8.12.0", 26 | "jju": "~1.4.0", 27 | "resolve": "~1.22.2" 28 | }, 29 | "devDependencies": { 30 | "@rushstack/heft-node-rig": "~2.6.45", 31 | "@rushstack/heft": "^0.68.10", 32 | "@types/heft-jest": "1.0.3", 33 | "@types/jju": "1.4.2", 34 | "@types/node": "14.18.36", 35 | "@types/resolve": "1.20.2", 36 | "eslint": "~8.57.0", 37 | "eslint-plugin-header": "~3.1.1" 38 | }, 39 | "scripts": { 40 | "build": "heft test --clean", 41 | "watch": "heft test --clean --watch", 42 | "_phase:build": "heft run --only build -- --clean", 43 | "_phase:test": "heft run --only test -- --clean" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules 2 | !dist 3 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e1/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e1/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "invalidSetting": false 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e2/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e2/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "invalid 4 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e3/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e3/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/invalid.json" 3 | } 4 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e4/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e4/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | 4 | "tagDefinitions": [ 5 | { 6 | "tagName": "@dupe", 7 | "syntaxKind": "modifier" 8 | }, 9 | { 10 | "tagName": "@dupe", 11 | "syntaxKind": "modifier" 12 | } 13 | ], 14 | 15 | "supportForTags": { 16 | "@undefinedTag": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e5/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e5/tsdoc-a.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": [ "./tsdoc-b.json", "./tsdoc-c.json" ] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e5/tsdoc-b.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": [ "./tsdoc-a.json" ] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e5/tsdoc-c.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "unknownSetting": 123 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e5/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": [ "./tsdoc-a.json" ] 4 | 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e6/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e6/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": [ "@rushstack/nonexistent-package/tsdoc.json" ] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e7/package.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/e7/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | 4 | "supportForTags": { 5 | "@nonExistentTag": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p1/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p1/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json" 3 | } 4 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p10/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": ["span", "p"], 4 | "reportUnsupportedHtmlElements": false 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p10/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p10/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json"], 4 | "reportUnsupportedHtmlElements": true 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p11/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "reportUnsupportedHtmlElements": false 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p11/base2/tsdoc-base2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": [] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p11/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p11/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json"], 4 | "reportUnsupportedHtmlElements": true 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p12/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p12/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": [], 4 | "reportUnsupportedHtmlElements": false 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p2/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p3/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "tagDefinitions": [ 4 | { 5 | "tagName": "@base1", 6 | "syntaxKind": "modifier" 7 | } 8 | ], 9 | "supportForTags": { 10 | "@base1": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p3/base2/tsdoc-base2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "tagDefinitions": [ 4 | { 5 | "tagName": "@base2", 6 | "syntaxKind": "modifier" 7 | } 8 | ], 9 | "supportForTags": { 10 | "@base2": false 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p3/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p3/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json", "./base2/tsdoc-base2.json"], 4 | "tagDefinitions": [ 5 | { 6 | "tagName": "@root", 7 | "syntaxKind": "modifier" 8 | } 9 | ], 10 | "supportForTags": { 11 | "@base2": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p4/node_modules/example-lib/dist/tsdoc-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "tagDefinitions": [ 4 | { 5 | "tagName": "@example", 6 | "syntaxKind": "modifier" 7 | } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p4/node_modules/example-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-lib", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "p4", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "example-lib": "1.0.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p4/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p4/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["example-lib/dist/tsdoc-example.json"], 4 | "tagDefinitions": [ 5 | { 6 | "tagName": "@root", 7 | "syntaxKind": "modifier" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p5/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "noStandardTags": false 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p5/base2/tsdoc-base2.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "noStandardTags": true 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p5/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p5/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json", "./base2/tsdoc-base2.json"] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p6/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "noStandardTags": true 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p6/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p6/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json"], 4 | "noStandardTags": false 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p7/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p7/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": ["b", "u"] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p8/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": ["span", "p"] 4 | } 5 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p8/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p8/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json"], 4 | "supportedHtmlElements": [] 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p9/base1/tsdoc-base1.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "supportedHtmlElements": ["span", "p"], 4 | "reportUnsupportedHtmlElements": true 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p9/tsconfig.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tsdoc-config/src/__tests__/assets/p9/tsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", 3 | "extends": ["./base1/tsdoc-base1.json"], 4 | "reportUnsupportedHtmlElements": false 5 | } 6 | -------------------------------------------------------------------------------- /tsdoc-config/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | export { TSDocConfigFile } from './TSDocConfigFile'; 5 | -------------------------------------------------------------------------------- /tsdoc-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "./node_modules/@rushstack/heft-node-rig/profiles/default/tsconfig-base.json", 4 | "compilerOptions": { 5 | "isolatedModules": true, 6 | "types": ["heft-jest", "node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsdoc/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458 2 | require('@rushstack/heft-web-rig/profiles/library/includes/eslint/patch/modern-module-resolution'); 3 | // This is a workaround for https://github.com/microsoft/rushstack/issues/3021 4 | require('@rushstack/heft-web-rig/profiles/library/includes/eslint/patch/custom-config-package-names'); 5 | 6 | module.exports = { 7 | extends: [ 8 | '@rushstack/heft-web-rig/profiles/library/includes/eslint/profile/web-app', 9 | '@rushstack/heft-web-rig/profiles/library/includes/eslint/mixins/friendly-locals' 10 | ], 11 | parserOptions: { tsconfigRootDir: __dirname }, 12 | 13 | plugins: ['eslint-plugin-header'], 14 | overrides: [ 15 | { 16 | files: ['*.ts', '*.tsx'], 17 | rules: { 18 | // Rationale: Including the `type` annotation in the import statement for imports 19 | // only used as types prevents the import from being emitted in the compiled output. 20 | '@typescript-eslint/consistent-type-imports': [ 21 | 'warn', 22 | { prefer: 'type-imports', disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' } 23 | ], 24 | 25 | // Rationale: If all imports in an import statement are only used as types, 26 | // then the import statement should be omitted in the compiled JS output. 27 | '@typescript-eslint/no-import-type-side-effects': 'warn', 28 | 29 | 'header/header': [ 30 | 'warn', 31 | 'line', 32 | [ 33 | ' Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.', 34 | ' See LICENSE in the project root for license information.' 35 | ] 36 | ] 37 | } 38 | } 39 | ] 40 | }; 41 | -------------------------------------------------------------------------------- /tsdoc/.npmignore: -------------------------------------------------------------------------------- 1 | # THIS IS A STANDARD TEMPLATE FOR .npmignore FILES IN THIS REPO. 2 | 3 | # Ignore all files by default, to avoid accidentally publishing unintended files. 4 | * 5 | 6 | # Use negative patterns to bring back the specific things we want to publish. 7 | !/bin/** 8 | !/lib/** 9 | !/lib-*/** 10 | !/dist/** 11 | 12 | !CHANGELOG.md 13 | !CHANGELOG.json 14 | !heft-plugin.json 15 | !rush-plugin-manifest.json 16 | !ThirdPartyNotice.txt 17 | 18 | # Ignore certain patterns that should not get published. 19 | /dist/*.stats.* 20 | /lib/**/test/ 21 | /lib-*/**/test/ 22 | *.test.js 23 | 24 | # NOTE: These don't need to be specified, because NPM includes them automatically. 25 | # 26 | # package.json 27 | # README.md 28 | # LICENSE 29 | 30 | # --------------------------------------------------------------------------- 31 | # DO NOT MODIFY ABOVE THIS LINE! Add any project-specific overrides below. 32 | # --------------------------------------------------------------------------- 33 | 34 | !/schemas/** 35 | -------------------------------------------------------------------------------- /tsdoc/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Debug Jest tests", 11 | "program": "${workspaceFolder}/node_modules/@rushstack/heft/lib/start.js", 12 | "cwd": "${workspaceFolder}", 13 | "args": ["--debug", "test", "--clean"], 14 | "console": "integratedTerminal", 15 | "sourceMaps": true 16 | }, 17 | ] 18 | } -------------------------------------------------------------------------------- /tsdoc/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tsdoc/README.md: -------------------------------------------------------------------------------- 1 | # @microsoft/tsdoc 2 | 3 |
4 |
5 | 6 | 7 | 8 |

9 |

10 | 11 | This library is the reference implementation of a parser for the TSDoc syntax. Using this library is an easy way to ensure that your tool is 100% compatible with the standard. 12 | 13 | 14 | ## What is TSDoc? 15 | 16 | **TSDoc** is a proposal to standardize the doc comments used in [TypeScript](http://www.typescriptlang.org/) source files. It allows different tools to extract content from comments without getting confused by each other's syntax. The **TSDoc** notation looks pretty familiar: 17 | 18 | ```typescript 19 | export class Statistics { 20 | /** 21 | * Returns the average of two numbers. 22 | * 23 | * @remarks 24 | * This method is part of the {@link core-library#Statistics | Statistics subsystem}. 25 | * 26 | * @param x - The first input number 27 | * @param y - The second input number 28 | * @returns The arithmetic mean of `x` and `y` 29 | * 30 | * @beta 31 | */ 32 | public static getAverage(x: number, y: number): number { 33 | return (x + y) / 2.0; 34 | } 35 | } 36 | ``` 37 | 38 | ## Give it a try! 39 | 40 | Check out the [TSDoc Playground](https://tsdoc.org/play) for a cool live demo of our parser! 41 | 42 | 43 | ## API Usage 44 | 45 | The [api-demo](https://github.com/microsoft/tsdoc/tree/main/api-demo) folder on GitHub illustrates how 46 | to invoke the TSDoc parser. 47 | 48 | A separate NPM package [`@microsoft/tsdoc-config`](https://www.npmjs.com/package/@microsoft/tsdoc-config) 49 | is used for loading the **tsdoc.json** file. 50 | 51 | 52 | ## Get involved 53 | 54 | The **TSDoc** project is actively evolving. Please visit the website for the latest documentation, instructions for building/debugging the projects, and other resources: 55 | 56 | https://tsdoc.org/ 57 | -------------------------------------------------------------------------------- /tsdoc/config/heft.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", 3 | 4 | "extends": "@rushstack/heft-web-rig/profiles/library/config/heft.json", 5 | 6 | "phasesByName": { 7 | "build": { 8 | "tasksByName": { 9 | "post-compile-copy": { 10 | // The "post-compile-copy" task should not run until after "typescript" completes 11 | "taskDependencies": ["typescript"], 12 | 13 | "taskPlugin": { 14 | "pluginName": "copy-files-plugin", 15 | "pluginPackage": "@rushstack/heft", 16 | "options": { 17 | "copyOperations": [ 18 | { 19 | "sourcePath": "lib/beta", 20 | "destinationFolders": ["lib-commonjs/beta"], 21 | "fileExtensions": [".d.ts"] 22 | } 23 | ] 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tsdoc/config/jest.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@rushstack/heft-web-rig/profiles/library/config/jest.config.json" 3 | } 4 | -------------------------------------------------------------------------------- /tsdoc/config/rig.json: -------------------------------------------------------------------------------- 1 | // The "rig.json" file directs tools to look for their config files in an external package. 2 | // Documentation for this system: https://www.npmjs.com/package/@rushstack/rig-package 3 | { 4 | "$schema": "https://developer.microsoft.com/json-schemas/rig-package/rig.schema.json", 5 | 6 | /** 7 | * (Required) The name of the rig package to inherit from. 8 | * It should be an NPM package name with the "-rig" suffix. 9 | */ 10 | "rigPackageName": "@rushstack/heft-web-rig", 11 | 12 | /** 13 | * (Optional) Selects a config profile from the rig package. The name must consist of 14 | * lowercase alphanumeric words separated by hyphens, for example "sample-profile". 15 | * If omitted, then the "default" profile will be used." 16 | */ 17 | "rigProfile": "library" 18 | } 19 | -------------------------------------------------------------------------------- /tsdoc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@microsoft/tsdoc", 3 | "version": "0.15.1", 4 | "description": "A parser for the TypeScript doc comment syntax", 5 | "keywords": [ 6 | "TypeScript", 7 | "documentation", 8 | "doc", 9 | "comments", 10 | "JSDoc", 11 | "parser", 12 | "standard" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/microsoft/tsdoc", 17 | "directory": "tsdoc" 18 | }, 19 | "homepage": "https://tsdoc.org/", 20 | "main": "lib-commonjs/index.js", 21 | "module": "lib/index.js", 22 | "typings": "lib/index.d.ts", 23 | "license": "MIT", 24 | "devDependencies": { 25 | "@rushstack/heft-web-rig": "~0.25.12", 26 | "@rushstack/heft": "^0.68.10", 27 | "@types/heft-jest": "1.0.3", 28 | "eslint": "~8.57.0", 29 | "eslint-plugin-header": "~3.1.1" 30 | }, 31 | "scripts": { 32 | "build": "heft test --clean", 33 | "watch": "heft test --clean --watch", 34 | "_phase:build": "heft run --only build -- --clean", 35 | "_phase:test": "heft run --only test -- --clean" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tsdoc/src/__tests__/DocNodeTransforms.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { type ParserContext, TSDocParser } from '..'; 5 | import { TestHelpers } from '../parser/__tests__/TestHelpers'; 6 | import { type DocParagraph, type DocNode, DocNodeKind } from '../nodes'; 7 | import { DocNodeTransforms } from '../transforms/DocNodeTransforms'; 8 | 9 | test('01 trimSpacesInParagraphNodes()', () => { 10 | const buffer: string = [ 11 | '/**', 12 | ' *', 13 | ' * This \t is the', 14 | ' * first {@mylink}sentence.', 15 | ' * This is another', 16 | ' *sentence. ', 17 | ' */' 18 | ].join('\n'); 19 | 20 | const tsdocParser: TSDocParser = new TSDocParser(); 21 | const parserContext: ParserContext = tsdocParser.parseString(buffer); 22 | const firstNode: DocNode = parserContext.docComment.summarySection.nodes[0]; 23 | expect(firstNode.kind).toEqual(DocNodeKind.Paragraph); 24 | const paragraph: DocParagraph = firstNode as DocParagraph; 25 | const transformedParagraph: DocParagraph = DocNodeTransforms.trimSpacesInParagraph(paragraph); 26 | expect(TestHelpers.getDocNodeSnapshot(transformedParagraph)).toMatchSnapshot(); 27 | }); 28 | -------------------------------------------------------------------------------- /tsdoc/src/__tests__/ParagraphSplitter.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from '../parser/__tests__/TestHelpers'; 5 | import { ParagraphSplitter } from '../parser/ParagraphSplitter'; 6 | import { DocSection, DocPlainText, DocSoftBreak, DocParagraph, DocBlockTag } from '../index'; 7 | import { TSDocConfiguration } from '../configuration/TSDocConfiguration'; 8 | 9 | test('01 Basic paragraph splitting', () => { 10 | TestHelpers.parseAndMatchDocCommentSnapshot( 11 | [ 12 | '/**', 13 | ' * ', 14 | ' * This is the', 15 | ' * first paragraph.', 16 | ' * \t ', 17 | ' * ', 18 | ' * \t ', 19 | ' * This is the second paragraph.', 20 | ' *', 21 | ' * This is the third paragraph.', 22 | ' *', 23 | ' * ', 24 | ' */' 25 | ].join('\n') 26 | ); 27 | }); 28 | 29 | test('02 Basic paragraph splitting in blocks', () => { 30 | TestHelpers.parseAndMatchDocCommentSnapshot( 31 | ['/**', ' * P1', ' * @remarks P2', ' *', ' * P3 @deprecated P4', ' *', ' * P5', ' */'].join('\n') 32 | ); 33 | }); 34 | 35 | test('03 Degenerate comment framing', () => { 36 | TestHelpers.parseAndMatchDocCommentSnapshot( 37 | ['/** line 1', ' * line 2', '', ' * @public line 3*/'].join('\n') 38 | ); 39 | }); 40 | 41 | test('04 Degenerate manually constructed nodes', () => { 42 | const configuration: TSDocConfiguration = new TSDocConfiguration(); 43 | 44 | const docSection: DocSection = new DocSection({ configuration }, [ 45 | new DocParagraph({ configuration }, [ 46 | new DocPlainText({ configuration, text: ' para 1 ' }), 47 | new DocSoftBreak({ configuration }), 48 | new DocPlainText({ configuration, text: ' ' }), 49 | new DocSoftBreak({ configuration }), 50 | new DocPlainText({ configuration, text: ' \t ' }), 51 | new DocPlainText({ configuration, text: ' ' }), 52 | new DocBlockTag({ configuration, tagName: '@public' }), 53 | new DocPlainText({ configuration, text: ' para 2 ' }), 54 | new DocSoftBreak({ configuration }), 55 | new DocSoftBreak({ configuration }), 56 | new DocPlainText({ configuration, text: ' para 3 ' }) 57 | ]), 58 | // Currently we do not discard empty paragraphs 59 | new DocParagraph({ configuration }) 60 | ]); 61 | 62 | ParagraphSplitter.splitParagraphsForSection(docSection); 63 | expect(TestHelpers.getDocNodeSnapshot(docSection)).toMatchSnapshot(); 64 | }); 65 | -------------------------------------------------------------------------------- /tsdoc/src/__tests__/__snapshots__/DocNodeTransforms.test.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`01 trimSpacesInParagraphNodes() 1`] = ` 4 | Object { 5 | "kind": "Paragraph", 6 | "nodes": Array [ 7 | Object { 8 | "kind": "PlainText", 9 | "nodePlainText": "This is the first ", 10 | }, 11 | Object { 12 | "kind": "InlineTag", 13 | "nodes": Array [ 14 | Object { 15 | "kind": "Excerpt: InlineTag_OpeningDelimiter", 16 | "nodeExcerpt": "{", 17 | }, 18 | Object { 19 | "kind": "Excerpt: InlineTag_TagName", 20 | "nodeExcerpt": "@mylink", 21 | }, 22 | Object { 23 | "kind": "Excerpt: InlineTag_ClosingDelimiter", 24 | "nodeExcerpt": "}", 25 | }, 26 | ], 27 | }, 28 | Object { 29 | "kind": "PlainText", 30 | "nodePlainText": "sentence. This is another sentence.", 31 | }, 32 | ], 33 | } 34 | `; 35 | -------------------------------------------------------------------------------- /tsdoc/src/configuration/TSDocTagDefinition.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { StringChecks } from '../parser/StringChecks'; 5 | import { Standardization } from '../details/Standardization'; 6 | 7 | /** 8 | * Determines the type of syntax for a TSDocTagDefinition 9 | */ 10 | export enum TSDocTagSyntaxKind { 11 | /** 12 | * The tag is intended to be an inline tag. For example: `{@link}`. 13 | */ 14 | InlineTag, 15 | 16 | /** 17 | * The tag is intended to be a block tag that starts a new documentation 18 | * section. For example: `@remarks` 19 | */ 20 | BlockTag, 21 | 22 | /** 23 | * The tag is intended to be a modifier tag whose presence indicates 24 | * an aspect of the associated API item. For example: `@internal` 25 | */ 26 | ModifierTag 27 | } 28 | 29 | /** 30 | * Constructor parameters for {@link TSDocTagDefinition} 31 | */ 32 | export interface ITSDocTagDefinitionParameters { 33 | tagName: string; 34 | syntaxKind: TSDocTagSyntaxKind; 35 | allowMultiple?: boolean; 36 | } 37 | 38 | /** 39 | * @internal 40 | */ 41 | export interface ITSDocTagDefinitionInternalParameters extends ITSDocTagDefinitionParameters { 42 | standardization: Standardization; 43 | } 44 | 45 | /** 46 | * Defines a TSDoc tag that will be understood by the TSDocParser. 47 | */ 48 | export class TSDocTagDefinition { 49 | /** 50 | * The TSDoc tag name. TSDoc tag names start with an at-sign (`@`) followed 51 | * by ASCII letters using "camelCase" capitalization. 52 | */ 53 | public readonly tagName: string; 54 | 55 | /** 56 | * The TSDoc tag name in all capitals, which is used for performing 57 | * case-insensitive comparisons or lookups. 58 | */ 59 | public readonly tagNameWithUpperCase: string; 60 | 61 | /** 62 | * Specifies the expected syntax for this tag. 63 | */ 64 | public readonly syntaxKind: TSDocTagSyntaxKind; 65 | 66 | /** 67 | * Indicates the level of support expected from documentation tools that implement 68 | * the standard. 69 | */ 70 | public readonly standardization: Standardization; 71 | 72 | /** 73 | * If true, then this TSDoc tag may appear multiple times in a doc comment. 74 | * By default, a tag may only appear once. 75 | */ 76 | public readonly allowMultiple: boolean; 77 | 78 | public constructor(parameters: ITSDocTagDefinitionParameters) { 79 | StringChecks.validateTSDocTagName(parameters.tagName); 80 | this.tagName = parameters.tagName; 81 | this.tagNameWithUpperCase = parameters.tagName.toUpperCase(); 82 | this.syntaxKind = parameters.syntaxKind; 83 | this.standardization = 84 | (parameters as ITSDocTagDefinitionInternalParameters).standardization || Standardization.None; 85 | this.allowMultiple = !!parameters.allowMultiple; 86 | } 87 | 88 | /** 89 | * Throws an exception if `tagName` is not a valid TSDoc tag name. 90 | */ 91 | public static validateTSDocTagName(tagName: string): void { 92 | StringChecks.validateTSDocTagName(tagName); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tsdoc/src/configuration/TSDocValidationConfiguration.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | /** 5 | * Part of the {@link TSDocConfiguration} object. 6 | */ 7 | export class TSDocValidationConfiguration { 8 | /** 9 | * Set `ignoreUndefinedTags` to true to silently ignore unrecognized tags, 10 | * instead of reporting a warning. 11 | * 12 | * @remarks 13 | * Normally the parser will issue errors when it encounters tag names that do not 14 | * have a corresponding definition in {@link TSDocConfiguration.tagDefinitions}. 15 | * This helps to catch common mistakes such as a misspelled tag. 16 | * 17 | * @defaultValue `false` 18 | */ 19 | public ignoreUndefinedTags: boolean = false; 20 | 21 | /** 22 | * Set `reportUnsupportedTags` to true to issue a warning for tags that are not 23 | * supported by your tool. 24 | * 25 | * @remarks 26 | * The TSDoc standard defines may tags. By default it assumes that if your tool does 27 | * not implement one of these tags, then it will simply ignore it. But sometimes this 28 | * may be misleading for developers. (For example, they might write an `@example` block 29 | * and then be surprised if it doesn't appear in the documentation output.). 30 | * 31 | * For a better experience, you can tell the parser which tags you support, and then it 32 | * will issue warnings wherever unsupported tags are used. This is done using 33 | * {@link TSDocConfiguration.setSupportForTag}. Note that calling that function 34 | * automatically sets `reportUnsupportedTags` to true. 35 | * 36 | * @defaultValue `false` 37 | */ 38 | public reportUnsupportedTags: boolean = false; 39 | 40 | /** 41 | * Set `reportUnsupportedHtmlElements` to true to issue a warning for HTML elements which 42 | * are not defined in your TSDoc configuration's `supportedHtmlElements` field. 43 | * 44 | * @defaultValue `false` 45 | */ 46 | public reportUnsupportedHtmlElements: boolean = false; 47 | } 48 | -------------------------------------------------------------------------------- /tsdoc/src/details/ModifierTagSet.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import type { DocBlockTag } from '../nodes/DocBlockTag'; 5 | import { type TSDocTagDefinition, TSDocTagSyntaxKind } from '../configuration/TSDocTagDefinition'; 6 | 7 | /** 8 | * Represents a set of modifier tags that were extracted from a doc comment. 9 | * 10 | * @remarks 11 | * TSDoc modifier tags are block tags that do not have any associated rich text content. 12 | * Instead, their presence or absence acts as an on/off switch, indicating some aspect 13 | * of the underlying API item. For example, the `@internal` modifier indicates that a 14 | * signature is internal (i.e. not part of the public API contract). 15 | */ 16 | export class ModifierTagSet { 17 | private readonly _nodes: DocBlockTag[] = []; 18 | 19 | // NOTE: To implement case insensitivity, the keys in this set are always upper-case. 20 | // This convention makes the normalization more obvious (and as a general practice handles 21 | // the Turkish "i" character correctly). 22 | private readonly _nodesByName: Map = new Map(); 23 | 24 | /** 25 | * The original block tag nodes that defined the modifiers in this set, excluding duplicates. 26 | */ 27 | public get nodes(): ReadonlyArray { 28 | return this._nodes; 29 | } 30 | 31 | /** 32 | * Returns true if the set contains a DocBlockTag with the specified tag name. 33 | * Note that synonyms are not considered. The comparison is case-insensitive. 34 | * @param modifierTagName - The name of the tag, including the `@` prefix For example, `@internal` 35 | */ 36 | public hasTagName(modifierTagName: string): boolean { 37 | return this._nodesByName.has(modifierTagName.toUpperCase()); 38 | } 39 | 40 | /** 41 | * Returns true if the set contains a DocBlockTag matching the specified tag definition. 42 | * Note that synonyms are not considered. The comparison is case-insensitive. 43 | * The TSDocTagDefinition must be a modifier tag. 44 | * @param tagName - The name of the tag, including the `@` prefix For example, `@internal` 45 | */ 46 | public hasTag(modifierTagDefinition: TSDocTagDefinition): boolean { 47 | return !!this.tryGetTag(modifierTagDefinition); 48 | } 49 | 50 | /** 51 | * Returns a DocBlockTag matching the specified tag definition, or undefined if no such 52 | * tag was added to the set. If there were multiple instances, returned object will be 53 | * the first one to be added. 54 | */ 55 | public tryGetTag(modifierTagDefinition: TSDocTagDefinition): DocBlockTag | undefined { 56 | if (modifierTagDefinition.syntaxKind !== TSDocTagSyntaxKind.ModifierTag) { 57 | throw new Error('The tag definition is not a modifier tag'); 58 | } 59 | return this._nodesByName.get(modifierTagDefinition.tagNameWithUpperCase); 60 | } 61 | 62 | /** 63 | * Adds a new modifier tag to the set. If a tag already exists with the same name, 64 | * then no change is made, and the return value is false. 65 | */ 66 | public addTag(blockTag: DocBlockTag): boolean { 67 | if (this._nodesByName.has(blockTag.tagNameWithUpperCase)) { 68 | return false; 69 | } 70 | 71 | this._nodesByName.set(blockTag.tagNameWithUpperCase, blockTag); 72 | this._nodes.push(blockTag); 73 | 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tsdoc/src/details/StandardModifierTagSet.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { ModifierTagSet } from './ModifierTagSet'; 5 | import { StandardTags } from './StandardTags'; 6 | 7 | /** 8 | * Extends the ModifierTagSet base class with getters for modifiers that 9 | * are part of the standardized core tags for TSDoc. 10 | */ 11 | export class StandardModifierTagSet extends ModifierTagSet { 12 | /** 13 | * Returns true if the `@alpha` modifier tag was specified. 14 | */ 15 | public isAlpha(): boolean { 16 | return this.hasTag(StandardTags.alpha); 17 | } 18 | 19 | /** 20 | * Returns true if the `@beta` modifier tag was specified. 21 | */ 22 | public isBeta(): boolean { 23 | return this.hasTag(StandardTags.beta); 24 | } 25 | 26 | /** 27 | * Returns true if the `@eventProperty` modifier tag was specified. 28 | */ 29 | public isEventProperty(): boolean { 30 | return this.hasTag(StandardTags.eventProperty); 31 | } 32 | 33 | /** 34 | * Returns true if the `@experimental` modifier tag was specified. 35 | */ 36 | public isExperimental(): boolean { 37 | return this.hasTag(StandardTags.experimental); 38 | } 39 | 40 | /** 41 | * Returns true if the `@internal` modifier tag was specified. 42 | */ 43 | public isInternal(): boolean { 44 | return this.hasTag(StandardTags.internal); 45 | } 46 | 47 | /** 48 | * Returns true if the `@override` modifier tag was specified. 49 | */ 50 | public isOverride(): boolean { 51 | return this.hasTag(StandardTags.override); 52 | } 53 | 54 | /** 55 | * Returns true if the `@packageDocumentation` modifier tag was specified. 56 | */ 57 | public isPackageDocumentation(): boolean { 58 | return this.hasTag(StandardTags.packageDocumentation); 59 | } 60 | 61 | /** 62 | * Returns true if the `@public` modifier tag was specified. 63 | */ 64 | public isPublic(): boolean { 65 | return this.hasTag(StandardTags.public); 66 | } 67 | 68 | /** 69 | * Returns true if the `@readonly` modifier tag was specified. 70 | */ 71 | public isReadonly(): boolean { 72 | return this.hasTag(StandardTags.readonly); 73 | } 74 | 75 | /** 76 | * Returns true if the `@sealed` modifier tag was specified. 77 | */ 78 | public isSealed(): boolean { 79 | return this.hasTag(StandardTags.sealed); 80 | } 81 | 82 | /** 83 | * Returns true if the `@virtual` modifier tag was specified. 84 | */ 85 | public isVirtual(): boolean { 86 | return this.hasTag(StandardTags.virtual); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tsdoc/src/details/Standardization.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | /** 5 | * Used to group the {@link StandardTags} definitions according to the level of support 6 | * expected from documentation tools that implement the standard. 7 | */ 8 | export enum Standardization { 9 | /** 10 | * TSDoc tags in the "Core" standardization group are considered essential. 11 | * Their meaning is standardized, and every documentation tool is expected 12 | * to recognize them. The TSDoc parser library typically provides dedicated APIs 13 | * for accessing these tags. 14 | */ 15 | Core = 'Core', 16 | 17 | /** 18 | * TSDoc tags in the "Extended" standardization group are optional. Documentation tools 19 | * may or may not support them. If they do, the syntax and semantics should conform to 20 | * the TSDoc standard definitions. 21 | */ 22 | Extended = 'Extended', 23 | 24 | /** 25 | * TSDoc tags in the "Discretionary" standardization group are optional. Although the 26 | * syntax is specified, the semantics for these tags are implementation-specific 27 | * (and sometimes difficult to describe completely without referring to a specific 28 | * implementation). Discretionary tags are included in the TSDoc standard to ensure that 29 | * if two different popular tools use the same tag name, developers can expect the syntax 30 | * to be the same, and the semantics to be somewhat similar. 31 | */ 32 | Discretionary = 'Discretionary', 33 | 34 | /** 35 | * The tag is not part of the TSDoc standard. All used-defined tags are assigned to this group. 36 | */ 37 | None = 'None' 38 | } 39 | -------------------------------------------------------------------------------- /tsdoc/src/emitters/StringBuilder.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | /** 5 | * An interface for a builder object that allows a large text string to be constructed incrementally by appending 6 | * small chunks. 7 | * 8 | * @remarks 9 | * 10 | * {@link StringBuilder} is the default implementation of this contract. 11 | */ 12 | export interface IStringBuilder { 13 | /** 14 | * Append the specified text to the buffer. 15 | */ 16 | append(text: string): void; 17 | 18 | /** 19 | * Returns a single string containing all the text that was appended to the buffer so far. 20 | * 21 | * @remarks 22 | * 23 | * This is a potentially expensive operation. 24 | */ 25 | toString(): string; 26 | } 27 | 28 | /** 29 | * This class allows a large text string to be constructed incrementally by appending small chunks. The final 30 | * string can be obtained by calling StringBuilder.toString(). 31 | * 32 | * @remarks 33 | * A naive approach might use the `+=` operator to append strings: This would have the downside of copying 34 | * the entire string each time a chunk is appended, resulting in `O(n^2)` bytes of memory being allocated 35 | * (and later freed by the garbage collector), and many of the allocations could be very large objects. 36 | * StringBuilder avoids this overhead by accumulating the chunks in an array, and efficiently joining them 37 | * when `getText()` is finally called. 38 | */ 39 | export class StringBuilder implements IStringBuilder { 40 | private _chunks: string[]; 41 | 42 | public constructor() { 43 | this._chunks = []; 44 | } 45 | 46 | /** {@inheritdoc IStringBuilder.append} */ 47 | public append(text: string): void { 48 | this._chunks.push(text); 49 | } 50 | 51 | /** {@inheritdoc IStringBuilder.toString} */ 52 | public toString(): string { 53 | if (this._chunks.length === 0) { 54 | return ''; 55 | } 56 | 57 | if (this._chunks.length > 1) { 58 | const joined: string = this._chunks.join(''); 59 | this._chunks.length = 1; 60 | this._chunks[0] = joined; 61 | } 62 | 63 | return this._chunks[0]; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tsdoc/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | export { 5 | DocNodeManager, 6 | type IDocNodeDefinition, 7 | type DocNodeConstructor 8 | } from './configuration/DocNodeManager'; 9 | export { TSDocConfiguration } from './configuration/TSDocConfiguration'; 10 | export { 11 | type ITSDocTagDefinitionParameters, 12 | TSDocTagSyntaxKind, 13 | TSDocTagDefinition 14 | } from './configuration/TSDocTagDefinition'; 15 | export { TSDocValidationConfiguration } from './configuration/TSDocValidationConfiguration'; 16 | 17 | export { StandardTags } from './details/StandardTags'; 18 | export { Standardization } from './details/Standardization'; 19 | export { StandardModifierTagSet } from './details/StandardModifierTagSet'; 20 | export { ModifierTagSet } from './details/ModifierTagSet'; 21 | 22 | export { PlainTextEmitter } from './emitters/PlainTextEmitter'; 23 | export { StringBuilder, type IStringBuilder } from './emitters/StringBuilder'; 24 | export { TSDocEmitter } from './emitters/TSDocEmitter'; 25 | 26 | export * from './nodes'; 27 | 28 | export { ParserContext } from './parser/ParserContext'; 29 | export { ParserMessage, type IParserMessageParameters } from './parser/ParserMessage'; 30 | export { ParserMessageLog } from './parser/ParserMessageLog'; 31 | export { TextRange, type ITextLocation } from './parser/TextRange'; 32 | export { Token, TokenKind } from './parser/Token'; 33 | export { TokenSequence, type ITokenSequenceParameters } from './parser/TokenSequence'; 34 | export { TSDocMessageId } from './parser/TSDocMessageId'; 35 | export { TSDocParser } from './parser/TSDocParser'; 36 | 37 | export { DocNodeTransforms } from './transforms/DocNodeTransforms'; 38 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/BuiltInDocNodes.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import type { TSDocConfiguration } from '../configuration/TSDocConfiguration'; 5 | import type { DocNodeManager } from '../configuration/DocNodeManager'; 6 | import { DocNodeKind } from './DocNode'; 7 | import * as nodes from '..'; 8 | 9 | export class BuiltInDocNodes { 10 | public static register(configuration: TSDocConfiguration): void { 11 | const docNodeManager: DocNodeManager = configuration.docNodeManager; 12 | 13 | docNodeManager.registerDocNodes('@microsoft/tsdoc', [ 14 | { docNodeKind: DocNodeKind.Block, constructor: nodes.DocBlock }, 15 | { docNodeKind: DocNodeKind.BlockTag, constructor: nodes.DocBlockTag }, 16 | { docNodeKind: DocNodeKind.CodeSpan, constructor: nodes.DocCodeSpan }, 17 | { docNodeKind: DocNodeKind.Comment, constructor: nodes.DocComment }, 18 | { docNodeKind: DocNodeKind.DeclarationReference, constructor: nodes.DocDeclarationReference }, 19 | { docNodeKind: DocNodeKind.ErrorText, constructor: nodes.DocErrorText }, 20 | { docNodeKind: DocNodeKind.EscapedText, constructor: nodes.DocEscapedText }, 21 | { docNodeKind: DocNodeKind.Excerpt, constructor: nodes.DocExcerpt }, 22 | { docNodeKind: DocNodeKind.FencedCode, constructor: nodes.DocFencedCode }, 23 | { docNodeKind: DocNodeKind.HtmlAttribute, constructor: nodes.DocHtmlAttribute }, 24 | { docNodeKind: DocNodeKind.HtmlEndTag, constructor: nodes.DocHtmlEndTag }, 25 | { docNodeKind: DocNodeKind.HtmlStartTag, constructor: nodes.DocHtmlStartTag }, 26 | { docNodeKind: DocNodeKind.InheritDocTag, constructor: nodes.DocInheritDocTag }, 27 | { docNodeKind: DocNodeKind.InlineTag, constructor: nodes.DocInlineTag }, 28 | { docNodeKind: DocNodeKind.LinkTag, constructor: nodes.DocLinkTag }, 29 | { docNodeKind: DocNodeKind.MemberIdentifier, constructor: nodes.DocMemberIdentifier }, 30 | { docNodeKind: DocNodeKind.MemberReference, constructor: nodes.DocMemberReference }, 31 | { docNodeKind: DocNodeKind.MemberSelector, constructor: nodes.DocMemberSelector }, 32 | { docNodeKind: DocNodeKind.MemberSymbol, constructor: nodes.DocMemberSymbol }, 33 | { docNodeKind: DocNodeKind.Paragraph, constructor: nodes.DocParagraph }, 34 | { docNodeKind: DocNodeKind.ParamBlock, constructor: nodes.DocParamBlock }, 35 | { docNodeKind: DocNodeKind.ParamCollection, constructor: nodes.DocParamCollection }, 36 | { docNodeKind: DocNodeKind.PlainText, constructor: nodes.DocPlainText }, 37 | { docNodeKind: DocNodeKind.Section, constructor: nodes.DocSection }, 38 | { docNodeKind: DocNodeKind.SoftBreak, constructor: nodes.DocSoftBreak } 39 | ]); 40 | 41 | docNodeManager.registerAllowableChildren(DocNodeKind.Section, [ 42 | DocNodeKind.FencedCode, 43 | DocNodeKind.Paragraph, 44 | DocNodeKind.HtmlStartTag, 45 | DocNodeKind.HtmlEndTag 46 | ]); 47 | 48 | docNodeManager.registerAllowableChildren(DocNodeKind.Paragraph, [ 49 | DocNodeKind.BlockTag, 50 | DocNodeKind.CodeSpan, 51 | DocNodeKind.ErrorText, 52 | DocNodeKind.EscapedText, 53 | DocNodeKind.HtmlStartTag, 54 | DocNodeKind.HtmlEndTag, 55 | DocNodeKind.InlineTag, 56 | DocNodeKind.LinkTag, 57 | DocNodeKind.PlainText, 58 | DocNodeKind.SoftBreak 59 | ]); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocBlock.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, DocNode, type IDocNodeParameters, type IDocNodeParsedParameters } from './DocNode'; 5 | import { DocSection } from './DocSection'; 6 | import type { DocBlockTag } from './DocBlockTag'; 7 | 8 | /** 9 | * Constructor parameters for {@link DocBlock}. 10 | */ 11 | export interface IDocBlockParameters extends IDocNodeParameters { 12 | blockTag: DocBlockTag; 13 | } 14 | 15 | /** 16 | * Constructor parameters for {@link DocBlock}. 17 | */ 18 | export interface IDocBlockParsedParameters extends IDocNodeParsedParameters { 19 | blockTag: DocBlockTag; 20 | } 21 | 22 | /** 23 | * Represents a section that is introduced by a TSDoc block tag. 24 | * For example, an `@example` block. 25 | */ 26 | export class DocBlock extends DocNode { 27 | private readonly _blockTag: DocBlockTag; 28 | private readonly _content: DocSection; 29 | 30 | /** 31 | * Don't call this directly. Instead use {@link TSDocParser} 32 | * @internal 33 | */ 34 | public constructor(parameters: IDocBlockParameters | IDocBlockParsedParameters) { 35 | super(parameters); 36 | this._blockTag = parameters.blockTag; 37 | this._content = new DocSection({ configuration: this.configuration }); 38 | } 39 | 40 | /** @override */ 41 | public get kind(): DocNodeKind | string { 42 | return DocNodeKind.Block; 43 | } 44 | 45 | /** 46 | * The TSDoc tag that introduces this section. 47 | */ 48 | public get blockTag(): DocBlockTag { 49 | return this._blockTag; 50 | } 51 | 52 | /** 53 | * The TSDoc tag that introduces this section. 54 | */ 55 | public get content(): DocSection { 56 | return this._content; 57 | } 58 | 59 | /** @override */ 60 | protected onGetChildNodes(): ReadonlyArray { 61 | return [this.blockTag, this._content]; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocBlockTag.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, DocNode, type IDocNodeParameters, type IDocNodeParsedParameters } from './DocNode'; 5 | import { StringChecks } from '../parser/StringChecks'; 6 | import type { TokenSequence } from '../parser/TokenSequence'; 7 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 8 | 9 | /** 10 | * Constructor parameters for {@link DocBlockTag}. 11 | */ 12 | export interface IDocBlockTagParameters extends IDocNodeParameters { 13 | tagName: string; 14 | } 15 | 16 | /** 17 | * Constructor parameters for {@link DocBlockTag}. 18 | */ 19 | export interface IDocBlockTagParsedParameters extends IDocNodeParsedParameters { 20 | tagName: string; 21 | tagNameExcerpt: TokenSequence; 22 | } 23 | 24 | /** 25 | * Represents a TSDoc block tag such as `@param` or `@public`. 26 | */ 27 | export class DocBlockTag extends DocNode { 28 | private readonly _tagName: string; 29 | private readonly _tagNameWithUpperCase: string; 30 | private readonly _tagNameExcerpt: DocExcerpt | undefined; 31 | 32 | /** 33 | * Don't call this directly. Instead use {@link TSDocParser} 34 | * @internal 35 | */ 36 | public constructor(parameters: IDocBlockTagParameters | IDocBlockTagParsedParameters) { 37 | super(parameters); 38 | 39 | StringChecks.validateTSDocTagName(parameters.tagName); 40 | this._tagName = parameters.tagName; 41 | this._tagNameWithUpperCase = parameters.tagName.toUpperCase(); 42 | 43 | if (DocNode.isParsedParameters(parameters)) { 44 | this._tagNameExcerpt = new DocExcerpt({ 45 | configuration: this.configuration, 46 | excerptKind: ExcerptKind.BlockTag, 47 | content: parameters.tagNameExcerpt 48 | }); 49 | } 50 | } 51 | 52 | /** @override */ 53 | public get kind(): DocNodeKind | string { 54 | return DocNodeKind.BlockTag; 55 | } 56 | 57 | /** 58 | * The TSDoc tag name. TSDoc tag names start with an at-sign (`@`) followed 59 | * by ASCII letters using "camelCase" capitalization. 60 | */ 61 | public get tagName(): string { 62 | return this._tagName; 63 | } 64 | 65 | /** 66 | * The TSDoc tag name in all capitals, which is used for performing 67 | * case-insensitive comparisons or lookups. 68 | */ 69 | public get tagNameWithUpperCase(): string { 70 | return this._tagNameWithUpperCase; 71 | } 72 | 73 | /** @override */ 74 | protected onGetChildNodes(): ReadonlyArray { 75 | return [this._tagNameExcerpt]; 76 | } 77 | 78 | public getTokenSequence(): TokenSequence { 79 | if (!this._tagNameExcerpt) { 80 | throw new Error( 81 | 'DocBlockTag.getTokenSequence() failed because this object did not originate from a parsed input' 82 | ); 83 | } 84 | return this._tagNameExcerpt.content; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocCodeSpan.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type IDocNodeParameters, DocNode, type IDocNodeParsedParameters } from './DocNode'; 5 | import type { TokenSequence } from '../parser/TokenSequence'; 6 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 7 | 8 | /** 9 | * Constructor parameters for {@link DocCodeSpan}. 10 | */ 11 | export interface IDocCodeSpanParameters extends IDocNodeParameters { 12 | code: string; 13 | } 14 | 15 | /** 16 | * Constructor parameters for {@link DocCodeSpan}. 17 | */ 18 | export interface IDocCodeSpanParsedParameters extends IDocNodeParsedParameters { 19 | openingDelimiterExcerpt: TokenSequence; 20 | 21 | codeExcerpt: TokenSequence; 22 | 23 | closingDelimiterExcerpt: TokenSequence; 24 | } 25 | 26 | /** 27 | * Represents CommonMark-style code span, i.e. code surrounded by 28 | * backtick characters. 29 | */ 30 | export class DocCodeSpan extends DocNode { 31 | // The opening ` delimiter 32 | private readonly _openingDelimiterExcerpt: DocExcerpt | undefined; 33 | 34 | // The code content 35 | private _code: string | undefined; 36 | private readonly _codeExcerpt: DocExcerpt | undefined; 37 | 38 | // The closing ` delimiter 39 | private readonly _closingDelimiterExcerpt: DocExcerpt | undefined; 40 | 41 | /** 42 | * Don't call this directly. Instead use {@link TSDocParser} 43 | * @internal 44 | */ 45 | public constructor(parameters: IDocCodeSpanParameters | IDocCodeSpanParsedParameters) { 46 | super(parameters); 47 | 48 | if (DocNode.isParsedParameters(parameters)) { 49 | this._openingDelimiterExcerpt = new DocExcerpt({ 50 | configuration: this.configuration, 51 | excerptKind: ExcerptKind.CodeSpan_OpeningDelimiter, 52 | content: parameters.openingDelimiterExcerpt 53 | }); 54 | this._codeExcerpt = new DocExcerpt({ 55 | configuration: this.configuration, 56 | excerptKind: ExcerptKind.CodeSpan_Code, 57 | content: parameters.codeExcerpt 58 | }); 59 | this._closingDelimiterExcerpt = new DocExcerpt({ 60 | configuration: this.configuration, 61 | excerptKind: ExcerptKind.CodeSpan_ClosingDelimiter, 62 | content: parameters.closingDelimiterExcerpt 63 | }); 64 | } else { 65 | this._code = parameters.code; 66 | } 67 | } 68 | 69 | /** @override */ 70 | public get kind(): DocNodeKind | string { 71 | return DocNodeKind.CodeSpan; 72 | } 73 | 74 | /** 75 | * The text that should be rendered as code, excluding the backtick delimiters. 76 | */ 77 | public get code(): string { 78 | if (this._code === undefined) { 79 | this._code = this._codeExcerpt!.content.toString(); 80 | } 81 | return this._code; 82 | } 83 | 84 | /** @override */ 85 | protected onGetChildNodes(): ReadonlyArray { 86 | return [this._openingDelimiterExcerpt, this._codeExcerpt, this._closingDelimiterExcerpt]; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocEscapedText.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type IDocNodeParsedParameters, DocNode } from './DocNode'; 5 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 6 | import type { TokenSequence } from '../parser/TokenSequence'; 7 | 8 | /** 9 | * Constructor parameters for {@link DocEscapedText}. 10 | */ 11 | export interface IDocEscapedTextParsedParameters extends IDocNodeParsedParameters { 12 | escapeStyle: EscapeStyle; 13 | encodedTextExcerpt: TokenSequence; 14 | decodedText: string; 15 | } 16 | 17 | /** 18 | * The style of escaping to be used with DocEscapedText. 19 | */ 20 | export enum EscapeStyle { 21 | /** 22 | * Use a backslash symbol to escape the character. 23 | */ 24 | CommonMarkBackslash 25 | } 26 | 27 | /** 28 | * Represents a text character that should be escaped as a TSDoc symbol. 29 | * @remarks 30 | * Note that renders will normally apply appropriate escaping when rendering 31 | * DocPlainText in a format such as HTML or TSDoc. The DocEscapedText node 32 | * forces a specific escaping that may not be the default. 33 | */ 34 | export class DocEscapedText extends DocNode { 35 | private readonly _escapeStyle: EscapeStyle; 36 | 37 | private _encodedText: string | undefined; 38 | private readonly _encodedTextExcerpt: DocExcerpt; 39 | 40 | private readonly _decodedText: string; 41 | 42 | /** 43 | * Don't call this directly. Instead use {@link TSDocParser} 44 | * @internal 45 | */ 46 | public constructor(parameters: IDocEscapedTextParsedParameters) { 47 | super(parameters); 48 | 49 | this._escapeStyle = parameters.escapeStyle; 50 | 51 | this._encodedTextExcerpt = new DocExcerpt({ 52 | configuration: this.configuration, 53 | excerptKind: ExcerptKind.EscapedText, 54 | content: parameters.encodedTextExcerpt 55 | }); 56 | 57 | this._decodedText = parameters.decodedText; 58 | } 59 | 60 | /** @override */ 61 | public get kind(): DocNodeKind | string { 62 | return DocNodeKind.EscapedText; 63 | } 64 | 65 | /** 66 | * The style of escaping to be performed. 67 | */ 68 | public get escapeStyle(): EscapeStyle { 69 | return this._escapeStyle; 70 | } 71 | 72 | /** 73 | * The text sequence including escapes. 74 | */ 75 | public get encodedText(): string { 76 | if (this._encodedText === undefined) { 77 | this._encodedText = this._encodedTextExcerpt.content.toString(); 78 | } 79 | return this._encodedText; 80 | } 81 | 82 | /** 83 | * The text without escaping. 84 | */ 85 | public get decodedText(): string { 86 | return this._decodedText; 87 | } 88 | 89 | /** @override */ 90 | protected onGetChildNodes(): ReadonlyArray { 91 | return [this._encodedTextExcerpt]; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocInheritDocTag.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type DocNode } from './DocNode'; 5 | import type { DocDeclarationReference } from './DocDeclarationReference'; 6 | import { 7 | DocInlineTagBase, 8 | type IDocInlineTagBaseParsedParameters, 9 | type IDocInlineTagBaseParameters 10 | } from './DocInlineTagBase'; 11 | 12 | /** 13 | * Constructor parameters for {@link DocInheritDocTag}. 14 | */ 15 | export interface IDocInheritDocTagParameters extends IDocInlineTagBaseParameters { 16 | declarationReference?: DocDeclarationReference; 17 | } 18 | 19 | /** 20 | * Constructor parameters for {@link DocInheritDocTag}. 21 | */ 22 | export interface IDocInheritDocTagParsedParameters extends IDocInlineTagBaseParsedParameters { 23 | declarationReference?: DocDeclarationReference; 24 | } 25 | 26 | /** 27 | * Represents an `{@inheritDoc}` tag. 28 | */ 29 | export class DocInheritDocTag extends DocInlineTagBase { 30 | private readonly _declarationReference: DocDeclarationReference | undefined; 31 | 32 | /** 33 | * Don't call this directly. Instead use {@link TSDocParser} 34 | * @internal 35 | */ 36 | public constructor(parameters: IDocInheritDocTagParameters | IDocInheritDocTagParsedParameters) { 37 | super(parameters); 38 | 39 | if (this.tagNameWithUpperCase !== '@INHERITDOC') { 40 | throw new Error('DocInheritDocTag requires the tag name to be "{@inheritDoc}"'); 41 | } 42 | 43 | this._declarationReference = parameters.declarationReference; 44 | } 45 | 46 | /** @override */ 47 | public get kind(): DocNodeKind | string { 48 | return DocNodeKind.InheritDocTag; 49 | } 50 | 51 | /** 52 | * The declaration that the documentation will be inherited from. 53 | * If omitted, the documentation will be inherited from the parent class. 54 | */ 55 | public get declarationReference(): DocDeclarationReference | undefined { 56 | return this._declarationReference; 57 | } 58 | 59 | /** @override */ 60 | protected getChildNodesForContent(): ReadonlyArray { 61 | // abstract 62 | return [this._declarationReference]; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocInlineTag.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, DocNode } from './DocNode'; 5 | import type { TokenSequence } from '../parser/TokenSequence'; 6 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 7 | import { 8 | type IDocInlineTagBaseParameters, 9 | type IDocInlineTagBaseParsedParameters, 10 | DocInlineTagBase 11 | } from './DocInlineTagBase'; 12 | 13 | /** 14 | * Constructor parameters for {@link DocInlineTag}. 15 | */ 16 | export interface IDocInlineTagParameters extends IDocInlineTagBaseParameters { 17 | tagContent: string; 18 | } 19 | 20 | /** 21 | * Constructor parameters for {@link DocInlineTag}. 22 | */ 23 | export interface IDocInlineTagParsedParameters extends IDocInlineTagBaseParsedParameters { 24 | tagContentExcerpt?: TokenSequence; 25 | } 26 | 27 | /** 28 | * Represents a generic TSDoc inline tag, including custom tags. 29 | * 30 | * @remarks 31 | * NOTE: Certain tags such as `{@link}` and `{@inheritDoc}` have specialized structures and parser rules, 32 | * and thus are represented using {@link DocLinkTag} or {@link DocInheritDocTag} instead. However, if the 33 | * specialized parser rule encounters a syntax error, but the outer framing is correct, then the parser constructs 34 | * a generic `DocInlineTag` instead of `DocErrorText`. This means, for example, that it is possible sometimes for 35 | * `DocInlineTag.tagName` to be `"@link"`. 36 | */ 37 | export class DocInlineTag extends DocInlineTagBase { 38 | private _tagContent: string | undefined; 39 | private readonly _tagContentExcerpt: DocExcerpt | undefined; 40 | 41 | /** 42 | * Don't call this directly. Instead use {@link TSDocParser} 43 | * @internal 44 | */ 45 | public constructor(parameters: IDocInlineTagParameters | IDocInlineTagParsedParameters) { 46 | super(parameters); 47 | 48 | if (DocNode.isParsedParameters(parameters)) { 49 | if (parameters.tagContentExcerpt) { 50 | this._tagContentExcerpt = new DocExcerpt({ 51 | configuration: this.configuration, 52 | excerptKind: ExcerptKind.InlineTag_TagContent, 53 | content: parameters.tagContentExcerpt 54 | }); 55 | } 56 | } else { 57 | this._tagContent = parameters.tagContent; 58 | } 59 | } 60 | 61 | /** @override */ 62 | public get kind(): DocNodeKind | string { 63 | return DocNodeKind.InlineTag; 64 | } 65 | 66 | /** 67 | * The tag content. 68 | * @remarks 69 | * For example, if the tag is `{@myTag x=12.34 y=56.78 }` then the tag content 70 | * would be `x=12.34 y=56.78 `, including the trailing space but not the leading space. 71 | */ 72 | public get tagContent(): string { 73 | if (this._tagContent === undefined) { 74 | if (this._tagContentExcerpt) { 75 | this._tagContent = this._tagContentExcerpt.content.toString(); 76 | } else { 77 | return ''; 78 | } 79 | } 80 | return this._tagContent; 81 | } 82 | 83 | /** @override */ 84 | protected getChildNodesForContent(): ReadonlyArray { 85 | // abstract 86 | return [this._tagContentExcerpt]; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocNodeContainer.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNode, type IDocNodeParameters, type IDocNodeParsedParameters } from './DocNode'; 5 | 6 | /** 7 | * Constructor parameters for {@link DocNodeContainer}. 8 | */ 9 | export interface IDocNodeContainerParameters extends IDocNodeParameters {} 10 | 11 | /** 12 | * Constructor parameters for {@link DocNodeContainer}. 13 | */ 14 | export interface IDocNodeContainerParsedParameters extends IDocNodeParsedParameters {} 15 | 16 | /** 17 | * DocNodeContainer is the base class for DocNode classes that allow arbitrary child nodes to be added by the consumer. 18 | * The child classes are {@link DocParagraph} and {@link DocSection}. 19 | */ 20 | export abstract class DocNodeContainer extends DocNode { 21 | private readonly _nodes: DocNode[] = []; 22 | 23 | /** 24 | * Don't call this directly. Instead use {@link TSDocParser} 25 | * @internal 26 | */ 27 | public constructor( 28 | parameters: IDocNodeContainerParameters | IDocNodeContainerParsedParameters, 29 | childNodes?: ReadonlyArray 30 | ) { 31 | super(parameters); 32 | 33 | if (childNodes !== undefined && childNodes.length > 0) { 34 | this.appendNodes(childNodes); 35 | } 36 | } 37 | 38 | /** 39 | * The nodes that were added to this container. 40 | */ 41 | public get nodes(): ReadonlyArray { 42 | return this._nodes; 43 | } 44 | 45 | /** 46 | * Append a node to the container. 47 | */ 48 | public appendNode(docNode: DocNode): void { 49 | if (!this.configuration.docNodeManager.isAllowedChild(this.kind, docNode.kind)) { 50 | throw new Error( 51 | `The TSDocConfiguration does not allow a ${this.kind} node to` + 52 | ` contain a node of type ${docNode.kind}` 53 | ); 54 | } 55 | 56 | this._nodes!.push(docNode); 57 | } 58 | 59 | /** 60 | * Append nodes to the container. 61 | */ 62 | public appendNodes(docNodes: ReadonlyArray): void { 63 | for (const docNode of docNodes) { 64 | this.appendNode(docNode); 65 | } 66 | } 67 | 68 | /** 69 | * Remove all nodes from the container. 70 | */ 71 | public clearNodes(): void { 72 | this._nodes!.length = 0; 73 | } 74 | 75 | /** @override */ 76 | protected onGetChildNodes(): ReadonlyArray { 77 | return this._nodes; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocParagraph.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type DocNode } from './DocNode'; 5 | import { DocNodeContainer, type IDocNodeContainerParameters } from './DocNodeContainer'; 6 | 7 | /** 8 | * Constructor parameters for {@link DocParagraph}. 9 | */ 10 | export interface IDocParagraphParameters extends IDocNodeContainerParameters {} 11 | 12 | /** 13 | * Represents a paragraph of text, similar to a `

` element in HTML. 14 | * Like CommonMark, the TSDoc syntax uses blank lines to delineate paragraphs 15 | * instead of explicitly notating them. 16 | */ 17 | export class DocParagraph extends DocNodeContainer { 18 | /** 19 | * Don't call this directly. Instead use {@link TSDocParser} 20 | * @internal 21 | */ 22 | public constructor(parameters: IDocParagraphParameters, childNodes?: ReadonlyArray) { 23 | super(parameters, childNodes); 24 | } 25 | 26 | /** @override */ 27 | public get kind(): DocNodeKind | string { 28 | return DocNodeKind.Paragraph; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocPlainText.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type IDocNodeParameters, type IDocNodeParsedParameters, DocNode } from './DocNode'; 5 | import type { TokenSequence } from '../parser/TokenSequence'; 6 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 7 | 8 | /** 9 | * Constructor parameters for {@link DocPlainText}. 10 | */ 11 | export interface IDocPlainTextParameters extends IDocNodeParameters { 12 | text: string; 13 | } 14 | 15 | /** 16 | * Constructor parameters for {@link DocPlainText}. 17 | */ 18 | export interface IDocPlainTextParsedParameters extends IDocNodeParsedParameters { 19 | textExcerpt: TokenSequence; 20 | } 21 | 22 | /** 23 | * Represents a span of comment text that is considered by the parser 24 | * to contain no special symbols or meaning. 25 | * 26 | * @remarks 27 | * The text content must not contain newline characters. 28 | * Use DocSoftBreak to represent manual line splitting. 29 | */ 30 | export class DocPlainText extends DocNode { 31 | // TODO: We should also prohibit "\r", but this requires updating LineExtractor 32 | // to interpret a lone "\r" as a newline 33 | private static readonly _newlineCharacterRegExp: RegExp = /[\n]/; 34 | 35 | private _text: string | undefined; 36 | private readonly _textExcerpt: DocExcerpt | undefined; 37 | 38 | /** 39 | * Don't call this directly. Instead use {@link TSDocParser} 40 | * @internal 41 | */ 42 | public constructor(parameters: IDocPlainTextParameters | IDocPlainTextParsedParameters) { 43 | super(parameters); 44 | 45 | if (DocNode.isParsedParameters(parameters)) { 46 | this._textExcerpt = new DocExcerpt({ 47 | configuration: this.configuration, 48 | excerptKind: ExcerptKind.PlainText, 49 | content: parameters.textExcerpt 50 | }); 51 | } else { 52 | if (DocPlainText._newlineCharacterRegExp.test(parameters.text)) { 53 | // Use DocSoftBreak to represent manual line splitting 54 | throw new Error('The DocPlainText content must not contain newline characters'); 55 | } 56 | 57 | this._text = parameters.text; 58 | } 59 | } 60 | 61 | /** @override */ 62 | public get kind(): DocNodeKind | string { 63 | return DocNodeKind.PlainText; 64 | } 65 | 66 | /** 67 | * The text content. 68 | */ 69 | public get text(): string { 70 | if (this._text === undefined) { 71 | this._text = this._textExcerpt!.content.toString(); 72 | } 73 | return this._text; 74 | } 75 | 76 | public get textExcerpt(): TokenSequence | undefined { 77 | if (this._textExcerpt) { 78 | return this._textExcerpt.content; 79 | } else { 80 | return undefined; 81 | } 82 | } 83 | 84 | /** @override */ 85 | protected onGetChildNodes(): ReadonlyArray { 86 | return [this._textExcerpt]; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocSection.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { type DocNode, DocNodeKind } from './DocNode'; 5 | import { DocParagraph } from './DocParagraph'; 6 | import { 7 | DocNodeContainer, 8 | type IDocNodeContainerParameters, 9 | type IDocNodeContainerParsedParameters 10 | } from './DocNodeContainer'; 11 | 12 | /** 13 | * Constructor parameters for {@link DocSection}. 14 | */ 15 | export interface IDocSectionParameters extends IDocNodeContainerParameters {} 16 | 17 | /** 18 | * Constructor parameters for {@link DocSection}. 19 | */ 20 | export interface IDocSectionParsedParameters extends IDocNodeContainerParsedParameters {} 21 | 22 | /** 23 | * Represents a general block of rich text. 24 | */ 25 | export class DocSection extends DocNodeContainer { 26 | /** 27 | * Don't call this directly. Instead use {@link TSDocParser} 28 | * @internal 29 | */ 30 | public constructor( 31 | parameters: IDocSectionParameters | IDocSectionParsedParameters, 32 | childNodes?: ReadonlyArray 33 | ) { 34 | super(parameters, childNodes); 35 | } 36 | 37 | /** @override */ 38 | public get kind(): DocNodeKind | string { 39 | return DocNodeKind.Section; 40 | } 41 | 42 | /** 43 | * If the last item in DocSection.nodes is not a DocParagraph, a new paragraph 44 | * is started. Either way, the provided docNode will be appended to the paragraph. 45 | */ 46 | public appendNodeInParagraph(docNode: DocNode): void { 47 | let paragraphNode: DocParagraph | undefined = undefined; 48 | 49 | if (this.nodes.length > 0) { 50 | const lastNode: DocNode = this.nodes[this.nodes.length - 1]; 51 | if (lastNode.kind === DocNodeKind.Paragraph) { 52 | paragraphNode = lastNode as DocParagraph; 53 | } 54 | } 55 | if (!paragraphNode) { 56 | paragraphNode = new DocParagraph({ configuration: this.configuration }); 57 | this.appendNode(paragraphNode); 58 | } 59 | 60 | paragraphNode.appendNode(docNode); 61 | } 62 | 63 | public appendNodesInParagraph(docNodes: ReadonlyArray): void { 64 | for (const docNode of docNodes) { 65 | this.appendNodeInParagraph(docNode); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/DocSoftBreak.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { DocNodeKind, type IDocNodeParameters, DocNode, type IDocNodeParsedParameters } from './DocNode'; 5 | import type { TokenSequence } from '../parser/TokenSequence'; 6 | import { DocExcerpt, ExcerptKind } from './DocExcerpt'; 7 | 8 | /** 9 | * Constructor parameters for {@link DocSoftBreak}. 10 | */ 11 | export interface IDocSoftBreakParameters extends IDocNodeParameters {} 12 | 13 | /** 14 | * Constructor parameters for {@link DocSoftBreak}. 15 | */ 16 | export interface IDocSoftBreakParsedParameters extends IDocNodeParsedParameters { 17 | softBreakExcerpt: TokenSequence; 18 | } 19 | 20 | /** 21 | * Instructs a renderer to insert an explicit newline in the output. 22 | * (Normally the renderer uses a formatting rule to determine where 23 | * lines should wrap.) 24 | * 25 | * @remarks 26 | * In HTML, a soft break is represented as an ASCII newline character (which does not 27 | * affect the web browser's view), whereas the hard break is the `
` element 28 | * (which starts a new line in the web browser's view). 29 | * 30 | * TSDoc follows the same conventions, except the renderer avoids emitting 31 | * two empty lines (because that could start a new CommonMark paragraph). 32 | */ 33 | export class DocSoftBreak extends DocNode { 34 | private readonly _softBreakExcerpt: DocExcerpt | undefined; 35 | 36 | /** 37 | * Don't call this directly. Instead use {@link TSDocParser} 38 | * @internal 39 | */ 40 | public constructor(parameters: IDocSoftBreakParameters | IDocSoftBreakParsedParameters) { 41 | super(parameters); 42 | 43 | if (DocNode.isParsedParameters(parameters)) { 44 | // The type is IDocNodeParsedParameters, which is a base of IDocSoftBreakParsedParameters 45 | // but not a base of IDocSoftBreakParameters. Therefore the type must be IDocSoftBreakParsedParameters. 46 | // TypeScript 4 could infer this, but for some reason TypeScript 5 cannot. 47 | const parsedParameters: IDocSoftBreakParsedParameters = parameters as IDocSoftBreakParsedParameters; 48 | this._softBreakExcerpt = new DocExcerpt({ 49 | configuration: this.configuration, 50 | excerptKind: ExcerptKind.SoftBreak, 51 | content: parsedParameters.softBreakExcerpt 52 | }); 53 | } 54 | } 55 | 56 | /** @override */ 57 | public get kind(): DocNodeKind | string { 58 | return DocNodeKind.SoftBreak; 59 | } 60 | 61 | /** @override */ 62 | protected onGetChildNodes(): ReadonlyArray { 63 | return [this._softBreakExcerpt]; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tsdoc/src/nodes/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | export * from './DocBlock'; 5 | export * from './DocBlockTag'; 6 | export * from './DocCodeSpan'; 7 | export * from './DocComment'; 8 | export * from './DocDeclarationReference'; 9 | export * from './DocErrorText'; 10 | export * from './DocEscapedText'; 11 | export * from './DocExcerpt'; 12 | export * from './DocFencedCode'; 13 | export * from './DocHtmlAttribute'; 14 | export * from './DocHtmlEndTag'; 15 | export * from './DocHtmlStartTag'; 16 | export * from './DocInheritDocTag'; 17 | export * from './DocInlineTag'; 18 | export * from './DocInlineTagBase'; 19 | export * from './DocLinkTag'; 20 | export * from './DocMemberIdentifier'; 21 | export * from './DocMemberReference'; 22 | export * from './DocMemberSelector'; 23 | export * from './DocMemberSymbol'; 24 | export * from './DocNode'; 25 | export * from './DocNodeContainer'; 26 | export * from './DocParagraph'; 27 | export * from './DocParamBlock'; 28 | export * from './DocParamCollection'; 29 | export * from './DocPlainText'; 30 | export * from './DocSection'; 31 | export * from './DocSoftBreak'; 32 | -------------------------------------------------------------------------------- /tsdoc/src/parser/ParserContext.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TextRange } from './TextRange'; 5 | import type { Token } from './Token'; 6 | import { DocComment } from '../nodes'; 7 | import type { TSDocConfiguration } from '../configuration/TSDocConfiguration'; 8 | import { ParserMessageLog } from './ParserMessageLog'; 9 | 10 | /** 11 | * An internal data structure that tracks all the state being built up by the various 12 | * parser stages. 13 | */ 14 | export class ParserContext { 15 | /** 16 | * The configuration that was provided for the TSDocParser. 17 | */ 18 | public readonly configuration: TSDocConfiguration; 19 | 20 | /** 21 | * The `sourceRange` indicates the start and end of the original input that was parsed. 22 | */ 23 | public readonly sourceRange: TextRange; 24 | 25 | /** 26 | * The text range starting from the opening `/**` and ending with 27 | * the closing `*\/` delimiter. 28 | */ 29 | public commentRange: TextRange = TextRange.empty; 30 | 31 | /** 32 | * The text ranges corresponding to the lines of content inside the comment. 33 | */ 34 | public lines: TextRange[] = []; 35 | 36 | /** 37 | * A complete list of all tokens that were extracted from the input lines. 38 | */ 39 | public tokens: Token[] = []; 40 | 41 | /** 42 | * The parsed doc comment object. This is the primary output of the parser. 43 | */ 44 | public readonly docComment: DocComment; 45 | 46 | /** 47 | * A queryable log that reports warnings and error messages that occurred during parsing. 48 | */ 49 | public readonly log: ParserMessageLog; 50 | 51 | public constructor(configuration: TSDocConfiguration, sourceRange: TextRange) { 52 | this.configuration = configuration; 53 | this.sourceRange = sourceRange; 54 | 55 | this.docComment = new DocComment({ configuration: this.configuration }); 56 | 57 | this.log = new ParserMessageLog(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tsdoc/src/parser/ParserMessage.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import type { TextRange, ITextLocation } from './TextRange'; 5 | import type { TokenSequence } from './TokenSequence'; 6 | import type { DocNode } from '../nodes/DocNode'; 7 | import type { TSDocMessageId } from './TSDocMessageId'; 8 | 9 | /** 10 | * Constructor parameters for {@link ParserMessage}. 11 | */ 12 | export interface IParserMessageParameters { 13 | messageId: TSDocMessageId; 14 | messageText: string; 15 | textRange: TextRange; 16 | tokenSequence?: TokenSequence; 17 | docNode?: DocNode; 18 | } 19 | 20 | /** 21 | * Represents an error or warning that occurred during parsing. 22 | */ 23 | export class ParserMessage { 24 | /** 25 | * A string that uniquely identifies the messages reported by the TSDoc parser. 26 | */ 27 | public readonly messageId: TSDocMessageId; 28 | 29 | /** 30 | * The message text without the default prefix that shows line/column information. 31 | */ 32 | public readonly unformattedText: string; 33 | 34 | public readonly textRange: TextRange; 35 | 36 | public readonly tokenSequence: TokenSequence | undefined; 37 | 38 | public readonly docNode: DocNode | undefined; 39 | 40 | private _text: string | undefined; 41 | 42 | public constructor(parameters: IParserMessageParameters) { 43 | this.messageId = parameters.messageId; 44 | this.unformattedText = parameters.messageText; 45 | this.textRange = parameters.textRange; 46 | this.tokenSequence = parameters.tokenSequence; 47 | this.docNode = parameters.docNode; 48 | this._text = undefined; 49 | } 50 | 51 | /** 52 | * Generates a line/column prefix. Example with line=2 and column=5 53 | * and message="An error occurred": 54 | * ``` 55 | * "(2,5): An error occurred" 56 | * ``` 57 | */ 58 | private static _formatMessageText(message: string, range: TextRange): string { 59 | if (!message) { 60 | message = 'An unknown error occurred'; 61 | } 62 | 63 | if (range.pos !== 0 || range.end !== 0) { 64 | // NOTE: This currently a potentially expensive operation, since TSDoc currently doesn't 65 | // have a full newline analysis for the input buffer. 66 | const location: ITextLocation = range.getLocation(range.pos); 67 | if (location.line) { 68 | return `(${location.line},${location.column}): ` + message; 69 | } 70 | } 71 | return message; 72 | } 73 | 74 | /** 75 | * The message text. 76 | */ 77 | public get text(): string { 78 | if (this._text === undefined) { 79 | // NOTE: This currently a potentially expensive operation, since TSDoc currently doesn't 80 | // have a full newline analysis for the input buffer. 81 | this._text = ParserMessage._formatMessageText(this.unformattedText, this.textRange); 82 | } 83 | return this._text; 84 | } 85 | 86 | public toString(): string { 87 | return this.text; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tsdoc/src/parser/ParserMessageLog.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { ParserMessage } from './ParserMessage'; 5 | import type { TextRange } from './TextRange'; 6 | import type { TokenSequence } from './TokenSequence'; 7 | import type { DocNode } from '../nodes/DocNode'; 8 | import type { DocErrorText } from '../nodes/DocErrorText'; 9 | import type { TSDocMessageId } from './TSDocMessageId'; 10 | 11 | /** 12 | * Used to report errors and warnings that occurred during parsing. 13 | */ 14 | export class ParserMessageLog { 15 | private _messages: ParserMessage[] = []; 16 | 17 | /** 18 | * The unfiltered list of all messages. 19 | */ 20 | public get messages(): ReadonlyArray { 21 | return this._messages; 22 | } 23 | 24 | /** 25 | * Append a message to the log. 26 | */ 27 | public addMessage(parserMessage: ParserMessage): void { 28 | this._messages.push(parserMessage); 29 | } 30 | 31 | /** 32 | * Append a message associated with a TextRange. 33 | */ 34 | public addMessageForTextRange(messageId: TSDocMessageId, messageText: string, textRange: TextRange): void { 35 | this.addMessage( 36 | new ParserMessage({ 37 | messageId, 38 | messageText, 39 | textRange 40 | }) 41 | ); 42 | } 43 | 44 | /** 45 | * Append a message associated with a TokenSequence. 46 | */ 47 | public addMessageForTokenSequence( 48 | messageId: TSDocMessageId, 49 | messageText: string, 50 | tokenSequence: TokenSequence, 51 | docNode?: DocNode 52 | ): void { 53 | this.addMessage( 54 | new ParserMessage({ 55 | messageId, 56 | messageText, 57 | textRange: tokenSequence.getContainingTextRange(), 58 | tokenSequence, 59 | docNode 60 | }) 61 | ); 62 | } 63 | 64 | /** 65 | * Append a message associated with a TokenSequence. 66 | */ 67 | public addMessageForDocErrorText(docErrorText: DocErrorText): void { 68 | let tokenSequence: TokenSequence; 69 | 70 | if (docErrorText.textExcerpt) { 71 | // If there is an excerpt directly associated with the DocErrorText, highlight that: 72 | tokenSequence = docErrorText.textExcerpt; 73 | } else { 74 | // Otherwise we can use the errorLocation, but typically that is meant to give additional 75 | // details, not to indicate the primary location of the problem. 76 | tokenSequence = docErrorText.errorLocation; 77 | } 78 | 79 | this.addMessage( 80 | new ParserMessage({ 81 | messageId: docErrorText.messageId, 82 | messageText: docErrorText.errorMessage, 83 | textRange: tokenSequence.getContainingTextRange(), 84 | tokenSequence: tokenSequence, 85 | docNode: docErrorText 86 | }) 87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tsdoc/src/parser/TSDocParser.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TextRange } from './TextRange'; 5 | import { ParserContext } from './ParserContext'; 6 | import { LineExtractor } from './LineExtractor'; 7 | import { Tokenizer } from './Tokenizer'; 8 | import { NodeParser } from './NodeParser'; 9 | import { TSDocConfiguration } from '../configuration/TSDocConfiguration'; 10 | import { ParagraphSplitter } from './ParagraphSplitter'; 11 | 12 | /** 13 | * The main API for parsing TSDoc comments. 14 | */ 15 | export class TSDocParser { 16 | /** 17 | * The configuration that was provided for the TSDocParser. 18 | */ 19 | public readonly configuration: TSDocConfiguration; 20 | 21 | public constructor(configuration?: TSDocConfiguration) { 22 | if (configuration) { 23 | this.configuration = configuration; 24 | } else { 25 | this.configuration = new TSDocConfiguration(); 26 | } 27 | } 28 | 29 | public parseString(text: string): ParserContext { 30 | return this.parseRange(TextRange.fromString(text)); 31 | } 32 | 33 | public parseRange(range: TextRange): ParserContext { 34 | const parserContext: ParserContext = new ParserContext(this.configuration, range); 35 | 36 | if (LineExtractor.extract(parserContext)) { 37 | parserContext.tokens = Tokenizer.readTokens(parserContext.lines); 38 | 39 | const nodeParser: NodeParser = new NodeParser(parserContext); 40 | nodeParser.parse(); 41 | 42 | ParagraphSplitter.splitParagraphs(parserContext.docComment); 43 | } 44 | 45 | return parserContext; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/LineExtractor.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TSDocParser } from '../TSDocParser'; 5 | import { TestHelpers } from './TestHelpers'; 6 | import type { ParserContext } from '../ParserContext'; 7 | 8 | function parseAndMatchSnapshot(buffer: string): void { 9 | const tsdocParser: TSDocParser = new TSDocParser(); 10 | const parserContext: ParserContext = tsdocParser.parseString(buffer); 11 | expect({ 12 | buffer: TestHelpers.getEscaped(buffer), 13 | comment: TestHelpers.getEscaped(parserContext.commentRange.toString()), 14 | lines: parserContext.lines.map((line) => TestHelpers.getEscaped(line.toString())), 15 | logMessages: parserContext.log.messages.map((message) => message.text) 16 | }).toMatchSnapshot(); 17 | } 18 | 19 | test('A. Whitespace variations', () => { 20 | parseAndMatchSnapshot(`/***/`); // 1 21 | parseAndMatchSnapshot(` /***/ `); // 2 22 | parseAndMatchSnapshot(` /** */ `); // 3 23 | parseAndMatchSnapshot(` /**\n\n*/ `); // 4 24 | parseAndMatchSnapshot(` /**L1*/ `); // 5 25 | parseAndMatchSnapshot(` /** L1 */ `); // 6 26 | parseAndMatchSnapshot(` /**L1\n*/ `); // 7 27 | parseAndMatchSnapshot(` /**L1*\n*/ `); // 8 28 | parseAndMatchSnapshot(` /**\nL1*/ `); // 9 29 | parseAndMatchSnapshot(` /**\n L1 */ `); // 10 30 | parseAndMatchSnapshot(` /**\nL1\n*/ `); // 11 31 | parseAndMatchSnapshot(` /**\nL1\n\nL2*/ `); // 12 32 | parseAndMatchSnapshot(` /**\n*L1\n*/ `); // 13 33 | parseAndMatchSnapshot(` /**\n * L1\n*/ `); // 14 34 | parseAndMatchSnapshot(` /**\n * L1\n */ `); // 15 35 | parseAndMatchSnapshot(` /**L1\n *L2\nL3*/ `); // 16 36 | parseAndMatchSnapshot(` /** L1\n * L2\n L3*/ `); // 17 37 | parseAndMatchSnapshot(` /** L1 \n * L2 \n L3 */ `); // 18 38 | parseAndMatchSnapshot( 39 | [ 40 | // 19 41 | '/** L1 ', 42 | ' * L2 ', 43 | ' L3 ', 44 | ' L4 */' 45 | ].join('\r\n') 46 | ); 47 | }); 48 | 49 | // TODO: Special handling for these somewhat common ornamentations 50 | test('B. Extra stars', () => { 51 | parseAndMatchSnapshot(` /****/ `); 52 | parseAndMatchSnapshot(` /**L1**/ `); 53 | parseAndMatchSnapshot(` /***L1*/ `); 54 | parseAndMatchSnapshot(` 55 | /***** 56 | **X** 57 | *****/ `); 58 | }); 59 | 60 | test('C. Missing stars', () => { 61 | parseAndMatchSnapshot(['/**', '```', 'a', ' b', ' c ', ' d', '```', ' */'].join('\n')); 62 | 63 | parseAndMatchSnapshot(['/**', '```', 'ee', ' ff', ' gg ', ' hh', '```', ' */'].join('\n')); 64 | }); 65 | 66 | test('D. Newline styles', () => { 67 | parseAndMatchSnapshot(['', '/**', ' * L1', ' */', ''].join('\r\n')); 68 | parseAndMatchSnapshot(['/**', 'L1', 'L2', '*/'].join('\r\n')); 69 | 70 | // We currently don't support CR or LFCR, so a single "\r" is treated 71 | // as part of the line. 72 | parseAndMatchSnapshot(`/** L \r 1 */`); 73 | }); 74 | 75 | test('E. Parser errors', () => { 76 | parseAndMatchSnapshot(''); 77 | parseAndMatchSnapshot('/*'); 78 | parseAndMatchSnapshot('//'); 79 | parseAndMatchSnapshot('/** L1\n L2'); 80 | parseAndMatchSnapshot('/** L1 *'); 81 | }); 82 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserBasics.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 Tokenizer simple case', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot( 8 | [ 9 | '/**', 10 | ' * line 1 ', // extra space at end of line 11 | ' * line 2', 12 | ' */' 13 | ].join('\n') 14 | ); 15 | }); 16 | 17 | test('01 Tokenizer degenerate cases', () => { 18 | TestHelpers.parseAndMatchNodeParserSnapshot('/***/'); 19 | 20 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' *', ' */'].join('\n')); 21 | 22 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' ', ' ', ' */'].join('\n')); 23 | }); 24 | 25 | test('02 Backslash escapes: positive examples', () => { 26 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * \\$\\@param', ' */'].join('\n')); 27 | }); 28 | 29 | test('03 Backslash escapes: negative examples', () => { 30 | TestHelpers.parseAndMatchNodeParserSnapshot( 31 | ['/**', ' * letter: \\A space: \\ end of line: \\', ' */'].join('\n') 32 | ); 33 | }); 34 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserCode.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 Code span basic, positive', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * line `1`', ' * line ` 2` sdf', ' */'].join('\n')); 8 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * M`&`M', ' */'].join('\n')); 9 | }); 10 | 11 | test('01 Code span basic, negative', () => { 12 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * `multi', ' * line`', ' */'].join('\n')); 13 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * ``', ' */'].join('\n')); 14 | }); 15 | 16 | test('03 Code fence, positive', () => { 17 | TestHelpers.parseAndMatchNodeParserSnapshot( 18 | [ 19 | '/**', 20 | ' * This is a code fence with all parts:', 21 | ' * ```a language! ', 22 | ' * some `code` here', 23 | ' * ``` ', 24 | ' */' 25 | ].join('\n') 26 | ); 27 | TestHelpers.parseAndMatchNodeParserSnapshot( 28 | [ 29 | '/**', 30 | ' * This is a code fence with no language or trailing whitespace:', 31 | ' * ```', 32 | ' * some `code` here', 33 | ' * ```*/' 34 | ].join('\n') 35 | ); 36 | }); 37 | 38 | test('04 Code fence, negative', () => { 39 | TestHelpers.parseAndMatchNodeParserSnapshot( 40 | ['/**', ' * Code fence incorrectly indented:', ' * ```', ' */'].join('\n') 41 | ); 42 | TestHelpers.parseAndMatchNodeParserSnapshot( 43 | ['/**', ' * Code fence not starting the line:', ' *a```', ' */'].join('\n') 44 | ); 45 | TestHelpers.parseAndMatchNodeParserSnapshot( 46 | ['/**', ' * Code fence not being terminated 1:', ' * ```*/'].join('\n') 47 | ); 48 | TestHelpers.parseAndMatchNodeParserSnapshot( 49 | ['/**', ' * Code fence not being terminated 2:', ' * ``` some stuff', ' */'].join('\n') 50 | ); 51 | TestHelpers.parseAndMatchNodeParserSnapshot( 52 | ['/**', ' * Language having backticks:', ' * ``` some stuff ```', ' */'].join('\n') 53 | ); 54 | TestHelpers.parseAndMatchNodeParserSnapshot( 55 | ['/**', ' * Closing delimiter being indented:', ' * ```', ' * code', ' * ```', ' */'].join('\n') 56 | ); 57 | TestHelpers.parseAndMatchNodeParserSnapshot( 58 | [ 59 | '/**', 60 | ' * Closing delimiter not being on a line by itself:', 61 | ' * ```', 62 | ' * code', 63 | ' * ``` a', 64 | ' */' 65 | ].join('\n') 66 | ); 67 | }); 68 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserInheritDocTag.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 InheritDoc tag: positive examples', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@inheritDoc}', ' */'].join('\n')); 8 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@inheritDoc Class.member}', ' */'].join('\n')); 9 | TestHelpers.parseAndMatchNodeParserSnapshot( 10 | ['/**', ' * {@inheritDoc package# Class . member}', ' */'].join('\n') 11 | ); 12 | }); 13 | 14 | test('01 InheritDoc tag: negative examples', () => { 15 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@inheritDoc | link text}', ' */'].join('\n')); 16 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@inheritDoc Class % junk}', ' */'].join('\n')); 17 | TestHelpers.parseAndMatchNodeParserSnapshot( 18 | ['/**', ' * {@inheritDoc}', ' * {@inheritDoc}', ' */'].join('\n') 19 | ); 20 | TestHelpers.parseAndMatchNodeParserSnapshot( 21 | ['/**', ' * summary text', ' * @remarks', ' * {@inheritDoc}', ' */'].join('\n') 22 | ); 23 | 24 | // Old API Extractor syntax 25 | TestHelpers.parseAndMatchNodeParserSnapshot( 26 | ['/**', ' * {@inheritdoc @scope/library:IDisposable.isDisposed}', ' */'].join('\n') 27 | ); 28 | }); 29 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserLinkTag3.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 Symbol references: positive examples', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot( 8 | [ 9 | '/**', 10 | ' * {@link Class1.[WellknownSymbols.toStringPrimitive]}', 11 | ' * {@link Class1 . ( [ WellknownSymbols . toStringPrimitive ] : static) | link text}', 12 | ' */' 13 | ].join('\n') 14 | ); 15 | }); 16 | 17 | test('01 Symbol references: negative examples', () => { 18 | TestHelpers.parseAndMatchNodeParserSnapshot( 19 | ['/**', ' * {@link Class1.[WellknownSymbols.toStringPrimitive}', ' * {@link Class1.[]}', ' */'].join('\n') 20 | ); 21 | }); 22 | 23 | test('02 Complicated examples', () => { 24 | TestHelpers.parseAndMatchNodeParserSnapshot( 25 | [ 26 | '/**', 27 | ' * {@link ./lib/controls/Button#Button.([(WellknownSymbols:namespace).toStringPrimitive]:instance)}', 28 | ' */' 29 | ].join('\n') 30 | ); 31 | }); 32 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserTags.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 Block tags: positive examples', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * @one ', ' * @two', ' */'].join('\n')); 8 | }); 9 | 10 | test('01 Block tags: negative examples', () => { 11 | TestHelpers.parseAndMatchNodeParserSnapshot( 12 | ['/**', ' * @ one ', ' * +@two ', ' * @two+ ', ' */'].join('\n') 13 | ); 14 | }); 15 | 16 | test('02 Inline tags: simple, positive', () => { 17 | TestHelpers.parseAndMatchNodeParserSnapshot( 18 | ['/**', ' * {@one} ', ' * {@two } ', ' * {@three}{@four} ', ' * {@five ', ' * } ', ' */'].join('\n') 19 | ); 20 | }); 21 | 22 | test('03 Inline tags: simple, negative', () => { 23 | TestHelpers.parseAndMatchNodeParserSnapshot( 24 | ['/**', ' * {@ one} ', ' * {@two~} ', ' * { @three} ', ' * {@four', ' */'].join('\n') 25 | ); 26 | }); 27 | 28 | test('04 Inline tags: complex, positive', () => { 29 | TestHelpers.parseAndMatchNodeParserSnapshot( 30 | ['/**', ' * {@one some content}', ' * {@two multi', ' * line}', ' */'].join('\n') 31 | ); 32 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@three @taglike}', ' */'].join('\n')); 33 | }); 34 | 35 | test('05 Inline tags: escaping, positive', () => { 36 | TestHelpers.parseAndMatchNodeParserSnapshot( 37 | ['/**', ' * {@one left \\{ right \\} backslash \\\\ }', ' */'].join('\n') 38 | ); 39 | }); 40 | 41 | test('06 Inline tags: escaping, negative', () => { 42 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@one curly\\}', ' */'].join('\n')); 43 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * {@two curly{}}', ' */'].join('\n')); 44 | TestHelpers.parseAndMatchNodeParserSnapshot(['/**', ' * three: }', ' */'].join('\n')); 45 | }); 46 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/NodeParserValidationChecks.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TestHelpers } from './TestHelpers'; 5 | 6 | test('00 Deprecated block: positive test', () => { 7 | TestHelpers.parseAndMatchNodeParserSnapshot( 8 | ['/**', ' * @deprecated', ' * Use the other thing', ' */'].join('\n') 9 | ); 10 | }); 11 | 12 | test('01 Deprecated block: negative test', () => { 13 | TestHelpers.parseAndMatchNodeParserSnapshot( 14 | ['/**', ' * @deprecated', ' * ', ' * @public', ' */'].join('\n') 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/TextRange.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TextRange } from '../TextRange'; 5 | import { TestHelpers } from './TestHelpers'; 6 | 7 | function matchSnapshot(textRange: TextRange): void { 8 | for (let i: number = -1; i <= textRange.end + 1; ++i) { 9 | // Show the current character 10 | const c: string = TestHelpers.getEscaped(textRange.buffer.substr(Math.max(i, 0), 1)); 11 | 12 | // Show the next 10 characters of context 13 | const context: string = TestHelpers.getEscaped(textRange.buffer.substr(Math.max(i, 0), 10)); 14 | 15 | expect({ 16 | c: c, 17 | context: context, 18 | i: i, 19 | location: textRange.getLocation(i) 20 | }).toMatchSnapshot(); 21 | } 22 | } 23 | 24 | test('construction scenarios', () => { 25 | const buffer: string = '0123456789'; 26 | const textRange: TextRange = TextRange.fromString(buffer); 27 | expect(textRange.toString()).toEqual(buffer); 28 | 29 | const subRange: TextRange = textRange.getNewRange(3, 6); 30 | expect(subRange).toMatchSnapshot('subRange'); 31 | }); 32 | 33 | test('getLocation() basic', () => { 34 | const textRange: TextRange = TextRange.fromString( 35 | [ 36 | 'L1', 37 | 'L2', 38 | '', // (line 3 is blank) 39 | 'L4', 40 | 'L5+CR\rL5+CRLF\r\nL6+LFCR\n\rL7' 41 | ].join('\n') 42 | ); 43 | matchSnapshot(textRange); 44 | }); 45 | 46 | test('getLocation() empty string', () => { 47 | const textRange: TextRange = TextRange.fromString(''); 48 | matchSnapshot(textRange); 49 | }); 50 | 51 | test('getLocation() CR string', () => { 52 | const textRange: TextRange = TextRange.fromString('\r'); 53 | matchSnapshot(textRange); 54 | }); 55 | 56 | test('getLocation() LF string', () => { 57 | const textRange: TextRange = TextRange.fromString('\n'); 58 | matchSnapshot(textRange); 59 | }); 60 | 61 | test('getLocation() tab characters', () => { 62 | // Tab character advances by only one column 63 | const textRange: TextRange = TextRange.fromString('1\t3'); 64 | matchSnapshot(textRange); 65 | }); 66 | -------------------------------------------------------------------------------- /tsdoc/src/parser/__tests__/Tokenizer.test.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TSDocParser } from '../TSDocParser'; 5 | import { Tokenizer } from '../Tokenizer'; 6 | import { type Token, TokenKind } from '../Token'; 7 | import { TestHelpers } from './TestHelpers'; 8 | import type { ParserContext } from '../ParserContext'; 9 | 10 | interface ISnapshotItem { 11 | indexOfLine: number; 12 | line: string; 13 | span: string; 14 | tokenKind: string; 15 | } 16 | 17 | function matchSnapshot(buffer: string): void { 18 | const tsdocParser: TSDocParser = new TSDocParser(); 19 | const parserContext: ParserContext = tsdocParser.parseString(buffer); 20 | const tokens: Token[] = parserContext.tokens; 21 | 22 | const items: ISnapshotItem[] = []; 23 | 24 | for (const token of tokens) { 25 | items.push({ 26 | indexOfLine: parserContext.lines.indexOf(token.line), 27 | line: '>' + TestHelpers.getEscaped(token.line.toString()) + '<', 28 | span: TestHelpers.formatLineSpan(token.line, token.range), 29 | tokenKind: TokenKind[token.kind] 30 | }); 31 | 32 | if (token.kind === TokenKind.EndOfInput) { 33 | break; 34 | } 35 | } 36 | 37 | expect({ 38 | buffer: TestHelpers.getEscaped(buffer), 39 | tokens: items 40 | }).toMatchSnapshot(); 41 | } 42 | 43 | test('Tokenizer.isPunctuation()', () => { 44 | expect(Tokenizer.isPunctuation(TokenKind.OtherPunctuation)).toEqual(true); 45 | expect(Tokenizer.isPunctuation(TokenKind.DoubleQuote)).toEqual(true); 46 | expect(Tokenizer.isPunctuation(TokenKind.Slash)).toEqual(true); 47 | 48 | expect(Tokenizer.isPunctuation(TokenKind.EndOfInput)).toEqual(false); 49 | expect(Tokenizer.isPunctuation(TokenKind.Spacing)).toEqual(false); 50 | expect(Tokenizer.isPunctuation(TokenKind.AsciiWord)).toEqual(false); 51 | }); 52 | 53 | test('00 Tokenizer simple case', () => { 54 | matchSnapshot( 55 | [ 56 | '/**', 57 | ' * line 1 ', // extra space at end of line 58 | ' * line 2', 59 | ' */' 60 | ].join('\n') 61 | ); 62 | }); 63 | 64 | test('01 Tokenizer degenerate cases', () => { 65 | matchSnapshot('/***/'); 66 | 67 | matchSnapshot(['/**', ' *', ' */'].join('\n')); 68 | 69 | matchSnapshot(['/**', ' ', ' ', ' */'].join('\n')); 70 | }); 71 | 72 | test('02 Backslash escapes: positive examples', () => { 73 | matchSnapshot(['/**', ' * \\$\\@param', ' * double-backslash: \\\\', ' */'].join('\n')); 74 | }); 75 | 76 | test('03 Backslash escapes: negative examples', () => { 77 | matchSnapshot(['/**', ' * letter: \\A space: \\ end of line: \\', ' */'].join('\n')); 78 | }); 79 | 80 | test('04 General characters', () => { 81 | matchSnapshot(['/**', ' * !"#$%&\'()*+,-./:;<=>?@[]^_`{|}~', ' */'].join('\n')); 82 | }); 83 | 84 | test('05 Spacing characters', () => { 85 | matchSnapshot(['/**', ' * space: tab: \t form feed: \f end', ' */'].join('\n')); 86 | }); 87 | -------------------------------------------------------------------------------- /tsdoc/src/transforms/DocNodeTransforms.ts: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. 2 | // See LICENSE in the project root for license information. 3 | 4 | import { TrimSpacesTransform } from './TrimSpacesTransform'; 5 | import type { DocParagraph } from '../nodes'; 6 | 7 | /** 8 | * Helper functions that transform DocNode trees. 9 | */ 10 | export class DocNodeTransforms { 11 | /** 12 | * trimSpacesInParagraphNodes() collapses extra spacing characters from plain text nodes. 13 | * 14 | * @remarks 15 | * This is useful when emitting HTML, where any number of spaces are equivalent 16 | * to a single space. It's also useful when emitting Markdown, where spaces 17 | * can be misinterpreted as an indented code block. 18 | * 19 | * For example, we might transform this: 20 | * 21 | * ``` 22 | * nodes: [ 23 | * { kind: PlainText, text: " Here are some " }, 24 | * { kind: SoftBreak } 25 | * { kind: PlainText, text: " words" }, 26 | * { kind: SoftBreak } 27 | * { kind: InlineTag, text: "{\@inheritDoc}" }, 28 | * { kind: PlainText, text: "to process." }, 29 | * { kind: PlainText, text: " " }, 30 | * { kind: PlainText, text: " " } 31 | * ] 32 | * ``` 33 | * 34 | * ...to this: 35 | * 36 | * ``` 37 | * nodes: [ 38 | * { kind: PlainText, text: "Here are some " }, 39 | * { kind: PlainText, text: "words " }, 40 | * { kind: InlineTag, text: "{\@inheritDoc}" }, 41 | * { kind: PlainText, text: "to process." } 42 | * ] 43 | * ``` 44 | * 45 | * Note that in this example, `"words "` is not merged with the preceding node because 46 | * its DocPlainText.excerpt cannot span multiple lines. 47 | * 48 | * @param docParagraph - a DocParagraph containing nodes to be transformed 49 | * @returns The transformed child nodes. 50 | */ 51 | public static trimSpacesInParagraph(docParagraph: DocParagraph): DocParagraph { 52 | return TrimSpacesTransform.transform(docParagraph); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tsdoc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "./node_modules/@rushstack/heft-web-rig/profiles/library/tsconfig-base.json", 4 | "compilerOptions": { 5 | "isolatedModules": true, 6 | "types": ["heft-jest"], 7 | "importHelpers": false 8 | } 9 | } 10 | --------------------------------------------------------------------------------