From 27b03c5fc44598e359a16cb41617baca1419580a Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 28 Apr 2024 09:23:39 -0600 Subject: [PATCH 001/219] WIP ESM migration TypeDoc cannot yet migrate to ESM due to a lack of support for transpilers supporting JS decorators, and due to not wanting to deal with warnings from trying to use ts-node on esm. --- .config/.prettierignore | 1 + .config/mocha.fast.json | 6 +- bin/package.json | 3 + bin/typedoc | 2 +- package-lock.json | 447 ++++++++++++++++++ package.json | 2 + scripts/build_themes.js | 39 +- scripts/rebuild_specs.js | 18 +- src/index.ts | 26 +- src/lib/application.ts | 61 ++- src/lib/cli.ts | 2 +- src/lib/converter/comments/blockLexer.ts | 6 +- .../comments/declarationReference.ts | 2 +- .../comments/declarationReferenceResolver.ts | 6 +- src/lib/converter/comments/discovery.ts | 8 +- src/lib/converter/comments/index.ts | 16 +- src/lib/converter/comments/lexer.ts | 2 +- src/lib/converter/comments/lineLexer.ts | 2 +- src/lib/converter/comments/linkResolver.ts | 12 +- src/lib/converter/comments/parser.ts | 20 +- src/lib/converter/comments/rawLexer.ts | 2 +- src/lib/converter/components.ts | 4 +- src/lib/converter/context.ts | 16 +- src/lib/converter/converter.ts | 44 +- .../converter/factories/index-signature.ts | 6 +- src/lib/converter/factories/signature.ts | 12 +- src/lib/converter/index.ts | 17 +- src/lib/converter/jsdoc.ts | 10 +- src/lib/converter/plugins/CategoryPlugin.ts | 12 +- src/lib/converter/plugins/CommentPlugin.ts | 14 +- src/lib/converter/plugins/GroupPlugin.ts | 16 +- src/lib/converter/plugins/ImplementsPlugin.ts | 18 +- src/lib/converter/plugins/InheritDocPlugin.ts | 24 +- .../converter/plugins/LinkResolverPlugin.ts | 14 +- src/lib/converter/plugins/PackagePlugin.ts | 18 +- src/lib/converter/plugins/SourcePlugin.ts | 24 +- src/lib/converter/plugins/TypePlugin.ts | 14 +- src/lib/converter/plugins/index.ts | 18 +- src/lib/converter/symbols.ts | 18 +- src/lib/converter/types.ts | 24 +- src/lib/converter/utils/reflections.ts | 2 +- src/lib/converter/utils/repository.ts | 4 +- .../internationalization.ts | 23 +- src/lib/internationalization/locale-utils.cts | 15 + src/lib/internationalization/locales/en.cts | 431 ++++++++++++++++- src/lib/internationalization/locales/test.cts | 4 +- src/lib/internationalization/translatable.ts | 443 +---------------- src/lib/models/ReflectionCategory.ts | 13 +- src/lib/models/ReflectionGroup.ts | 16 +- src/lib/models/comments/comment.ts | 16 +- src/lib/models/comments/index.ts | 4 +- src/lib/models/index.ts | 12 +- .../models/reflections/ReflectionSymbolId.ts | 10 +- src/lib/models/reflections/abstract.ts | 22 +- src/lib/models/reflections/container.ts | 20 +- src/lib/models/reflections/declaration.ts | 29 +- src/lib/models/reflections/index.ts | 28 +- src/lib/models/reflections/kind.ts | 2 +- src/lib/models/reflections/parameter.ts | 18 +- src/lib/models/reflections/project.ts | 30 +- src/lib/models/reflections/reference.ts | 12 +- src/lib/models/reflections/signature.ts | 24 +- src/lib/models/reflections/type-parameter.ts | 16 +- src/lib/models/reflections/variant.ts | 12 +- src/lib/models/sources/file.ts | 4 +- src/lib/models/sources/index.ts | 2 +- src/lib/models/types.ts | 26 +- src/lib/output/components.ts | 8 +- src/lib/output/events.ts | 8 +- src/lib/output/index.ts | 23 +- src/lib/output/models/UrlMapping.ts | 4 +- src/lib/output/plugins/AssetsPlugin.ts | 18 +- src/lib/output/plugins/IconsPlugin.tsx | 10 +- .../output/plugins/JavascriptIndexPlugin.ts | 16 +- src/lib/output/plugins/NavigationPlugin.ts | 8 +- src/lib/output/plugins/SitemapPlugin.ts | 14 +- src/lib/output/plugins/index.ts | 12 +- src/lib/output/renderer.ts | 34 +- src/lib/output/theme.ts | 14 +- src/lib/output/themes/MarkedPlugin.tsx | 13 +- .../output/themes/default/DefaultTheme.tsx | 20 +- .../default/DefaultThemeRenderContext.ts | 70 +-- .../output/themes/default/assets/bootstrap.ts | 14 +- .../default/assets/typedoc/Application.ts | 2 +- .../default/assets/typedoc/Component.ts | 2 +- .../themes/default/assets/typedoc/Theme.ts | 2 +- .../assets/typedoc/components/Accordion.ts | 4 +- .../assets/typedoc/components/Filter.ts | 4 +- .../assets/typedoc/components/Search.ts | 2 +- .../assets/typedoc/components/Toggle.ts | 4 +- .../output/themes/default/layouts/default.tsx | 12 +- .../themes/default/partials/analytics.tsx | 4 +- .../themes/default/partials/anchor-icon.tsx | 4 +- .../themes/default/partials/breadcrumb.tsx | 6 +- .../themes/default/partials/comment.tsx | 8 +- .../output/themes/default/partials/footer.tsx | 4 +- .../output/themes/default/partials/header.tsx | 10 +- .../themes/default/partials/hierarchy.tsx | 6 +- .../output/themes/default/partials/icon.tsx | 6 +- .../output/themes/default/partials/index.tsx | 8 +- .../default/partials/member.declaration.tsx | 8 +- .../default/partials/member.getterSetter.tsx | 8 +- .../default/partials/member.reference.tsx | 6 +- .../partials/member.signature.body.tsx | 8 +- .../partials/member.signature.title.tsx | 8 +- .../default/partials/member.signatures.tsx | 10 +- .../default/partials/member.sources.tsx | 6 +- .../output/themes/default/partials/member.tsx | 10 +- .../themes/default/partials/members.group.tsx | 6 +- .../themes/default/partials/members.tsx | 8 +- .../themes/default/partials/navigation.tsx | 10 +- .../themes/default/partials/parameter.tsx | 8 +- .../default/partials/reflectionPreview.tsx | 8 +- .../themes/default/partials/toolbar.tsx | 10 +- .../output/themes/default/partials/type.tsx | 10 +- .../themes/default/partials/typeAndParent.tsx | 6 +- .../default/partials/typeParameters.tsx | 6 +- .../themes/default/templates/hierarchy.tsx | 10 +- .../output/themes/default/templates/index.tsx | 8 +- .../themes/default/templates/reflection.tsx | 10 +- src/lib/output/themes/lib.tsx | 6 +- src/lib/serialization/components.ts | 4 +- src/lib/serialization/deserializer.ts | 16 +- src/lib/serialization/events.ts | 6 +- src/lib/serialization/index.ts | 10 +- src/lib/serialization/schema.ts | 2 +- src/lib/serialization/serializer.ts | 12 +- src/lib/utils/component.ts | 4 +- src/lib/utils/entry-point.ts | 17 +- src/lib/utils/fs.ts | 6 +- src/lib/utils/general.ts | 5 +- src/lib/utils/highlighter.tsx | 6 +- src/lib/utils/hooks.ts | 2 +- src/lib/utils/{html.ts => html.cts} | 10 +- src/lib/utils/index.ts | 48 +- src/lib/utils/jsx.ts | 11 +- src/lib/utils/loggers.ts | 8 +- src/lib/utils/minimalSourceFile.ts | 2 +- src/lib/utils/options/declaration.ts | 12 +- src/lib/utils/options/help.ts | 12 +- src/lib/utils/options/index.ts | 10 +- src/lib/utils/options/options.ts | 28 +- src/lib/utils/options/readers/arguments.ts | 8 +- src/lib/utils/options/readers/index.ts | 8 +- src/lib/utils/options/readers/package-json.ts | 12 +- src/lib/utils/options/readers/tsconfig.ts | 20 +- src/lib/utils/options/readers/typedoc.ts | 29 +- src/lib/utils/options/sources/index.ts | 2 +- src/lib/utils/options/sources/typedoc.ts | 20 +- src/lib/utils/package-manifest.ts | 6 +- src/lib/utils/plugins.ts | 30 +- src/lib/utils/reflections.ts | 2 +- src/lib/utils/sort.ts | 8 +- src/lib/utils/tsconfig.ts | 4 +- src/lib/utils/tsutils.ts | 2 +- src/lib/validation/documentation.ts | 8 +- src/lib/validation/exports.ts | 8 +- src/lib/validation/links.ts | 8 +- src/test/Repository.test.ts | 2 +- src/test/TestLogger.ts | 4 +- src/test/behavior.c2.test.ts | 14 +- src/test/capture-screenshots.ts | 4 +- src/test/comments.test.ts | 25 +- src/test/converter.test.ts | 10 +- src/test/converter/alias/alias.ts | 2 +- src/test/converter/exports/export.ts | 10 +- src/test/converter/exports/mod.ts | 4 +- .../converter2/behavior/linkResolutionTs.ts | 4 +- src/test/converter2/issues/gh1578/index.ts | 2 +- src/test/converter2/issues/gh2044/index.js | 12 +- src/test/converter2/issues/gh2150/index.ts | 2 +- src/test/converter2/issues/gh2207/index.ts | 2 +- src/test/declarationReference.test.ts | 2 +- src/test/events.test.ts | 2 +- src/test/internationalization.test.ts | 12 +- src/test/issues.c2.test.ts | 14 +- src/test/merge.test.ts | 6 +- src/test/models/comment.test.ts | 2 +- src/test/models/types.test.ts | 4 +- src/test/module/a.ts | 2 +- src/test/packages.test.ts | 8 +- src/test/programs.ts | 6 +- src/test/project.test.ts | 2 +- src/test/renderer/testProject/src/mod2.ts | 2 +- src/test/slow/entry-point.test.ts | 2 +- .../slow/internationalization-usage.test.ts | 9 +- src/test/utils.ts | 4 +- src/test/utils/array.test.ts | 2 +- src/test/utils/enum.test.ts | 4 +- src/test/utils/fs.test.ts | 4 +- src/test/utils/hooks.test.ts | 2 +- src/test/utils/html.test.ts | 3 +- src/test/utils/jsx.test.tsx | 2 +- src/test/utils/languageAliases.test.ts | 2 +- src/test/utils/minimalSourceFile.test.ts | 2 +- src/test/utils/options/declaration.test.ts | 18 +- .../utils/options/default-options.test.ts | 4 +- src/test/utils/options/help.test.ts | 10 +- src/test/utils/options/options.test.ts | 12 +- .../utils/options/readers/arguments.test.ts | 14 +- .../options/readers/package-json.test.ts | 8 +- .../utils/options/readers/tsconfig.test.ts | 13 +- .../utils/options/readers/typedoc.test.ts | 27 +- src/test/utils/plugins.test.ts | 12 +- src/test/utils/sort.test.ts | 10 +- src/test/utils/validation.test.ts | 4 +- src/test/validation.test.ts | 18 +- tsconfig.json | 7 +- 208 files changed, 2064 insertions(+), 1482 deletions(-) create mode 100644 bin/package.json create mode 100644 src/lib/internationalization/locale-utils.cts rename src/lib/utils/{html.ts => html.cts} (81%) diff --git a/.config/.prettierignore b/.config/.prettierignore index 9245daa3e..b56af1dca 100644 --- a/.config/.prettierignore +++ b/.config/.prettierignore @@ -14,4 +14,5 @@ **/.vs # Remove once Prettier has support +../src/lib/internationalization/locale-utils.cts ../src/test/converter2/behavior/resolutionMode.ts diff --git a/.config/mocha.fast.json b/.config/mocha.fast.json index bc6b6d20f..f9bf1e1aa 100644 --- a/.config/mocha.fast.json +++ b/.config/mocha.fast.json @@ -1,9 +1,9 @@ { "$schema": "https://json.schemastore.org/mocharc.json", "exclude": ["src/test/packages/**", "src/test/slow/**"], - "extension": ["ts", "tsx"], - "require": ["ts-node/register"], + "extension": ["ts", "cts", "mts", "tsx"], "spec": ["src/test/**/*.test.ts", "src/test/**/*.test.tsx"], "timeout": 5000, - "watch-files": ["src/**/*.ts", "src/**/*.tsx"] + "watch-files": ["src/**/*.ts", "src/**/*.tsx"], + "node-option": ["import=tsx"] } diff --git a/bin/package.json b/bin/package.json new file mode 100644 index 000000000..5bbefffba --- /dev/null +++ b/bin/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/bin/typedoc b/bin/typedoc index 221181e72..8d7018402 100755 --- a/bin/typedoc +++ b/bin/typedoc @@ -2,4 +2,4 @@ //@ts-check /* eslint-disable @typescript-eslint/no-var-requires */ -require("../dist/lib/cli"); +import("../dist/lib/cli.js"); diff --git a/package-lock.json b/package-lock.json index 29bb38576..13b0e87d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,6 +32,7 @@ "prettier": "3.0.3", "puppeteer": "^13.5.2", "ts-node": "^10.9.2", + "tsx": "^4.7.3", "typescript": "5.4.2" }, "engines": { @@ -1865,6 +1866,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-tsconfig": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -2862,6 +2875,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3286,6 +3308,431 @@ "node": ">=0.3.1" } }, + "node_modules/tsx": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.3.tgz", + "integrity": "sha512-+fQnMqIp/jxZEXLcj6WzYy9FhcS5/Dfk8y4AtzJ6ejKcKqmfTF8Gso/jtrzDggCF2zTU20gJa6n8XqPYwDAUYQ==", + "dev": true, + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/tsx/node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index 6adc07a9c..cc4885a00 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "description": "Create api documentation for TypeScript projects.", "version": "0.25.12", "homepage": "https://typedoc.org", + "type": "module", "exports": { ".": "./dist/index.js", "./tsdoc.json": "./tsdoc.json", @@ -47,6 +48,7 @@ "prettier": "3.0.3", "puppeteer": "^13.5.2", "ts-node": "^10.9.2", + "tsx": "^4.7.3", "typescript": "5.4.2" }, "files": [ diff --git a/scripts/build_themes.js b/scripts/build_themes.js index 3083e66ae..5a0e15aa9 100644 --- a/scripts/build_themes.js +++ b/scripts/build_themes.js @@ -1,28 +1,21 @@ // @ts-check -const esbuild = require("esbuild"); +import esbuild from "esbuild"; -async function main() { - const context = await esbuild.context({ - entryPoints: ["src/lib/output/themes/default/assets/bootstrap.ts"], - bundle: true, - minify: true, - outfile: "static/main.js", - banner: { - js: '"use strict";', - }, - logLevel: "info", - }); +const context = await esbuild.context({ + entryPoints: ["src/lib/output/themes/default/assets/bootstrap.ts"], + bundle: true, + minify: true, + outfile: "static/main.js", + banner: { + js: '"use strict";', + }, + logLevel: "info", +}); - await context.rebuild(); +await context.rebuild(); - if (process.argv.slice(2).includes("--watch")) { - await context.watch(); - } else { - await context.dispose(); - } +if (process.argv.slice(2).includes("--watch")) { + await context.watch(); +} else { + await context.dispose(); } - -main().catch((err) => { - console.error(err); - process.exitCode = 1; -}); diff --git a/scripts/rebuild_specs.js b/scripts/rebuild_specs.js index 43b7cf461..fe0d2a3f3 100644 --- a/scripts/rebuild_specs.js +++ b/scripts/rebuild_specs.js @@ -1,18 +1,16 @@ // @ts-check "use strict"; -require("ts-node/register"); - Error.stackTraceLimit = 50; -const ts = require("typescript"); -const fs = require("fs"); -const path = require("path"); -const td = require("../src"); -const { getExpandedEntryPointsForPaths } = require("../src/lib/utils"); -const { ok } = require("assert"); -const { basename } = require("path"); +import ts from "typescript"; +import fs from "fs"; +import path, { basename } from "path"; +import * as td from "../dist/index.js"; +import { getExpandedEntryPointsForPaths } from "../dist/lib/utils/index.js"; +import { ok } from "assert"; +import { fileURLToPath } from "url"; -const base = path.join(__dirname, "../src/test/converter"); +const base = path.join(fileURLToPath(import.meta.url), "../../src/test/converter"); async function getApp() { const app = await td.Application.bootstrap( diff --git a/src/index.ts b/src/index.ts index ed1969820..b0d0f28ad 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export { Application } from "./lib/application"; +export { Application } from "./lib/application.js"; -export { EventDispatcher, Event } from "./lib/utils/events"; -export { resetReflectionID } from "./lib/models/reflections/abstract"; +export { EventDispatcher, Event } from "./lib/utils/events.js"; +export { resetReflectionID } from "./lib/models/reflections/abstract.js"; /** * All symbols documented under the Models namespace are also available in the root import. * @@ -12,12 +12,12 @@ export { resetReflectionID } from "./lib/models/reflections/abstract"; * Describes a documentation entry. The root entry is a {@link ProjectReflection} * and contains {@link DeclarationReflection} instances. */ -export * as Models from "./lib/models"; +export * as Models from "./lib/models/index.js"; /** * All symbols documented under the Configuration namespace are also available in the root import. */ -export * as Configuration from "./lib/utils/options"; -export * from "./lib/models"; +export * as Configuration from "./lib/utils/options/index.js"; +export * from "./lib/models/index.js"; export { Converter, Context, @@ -29,7 +29,7 @@ export { type MeaningKeyword, type ExternalResolveResult, type ExternalSymbolResolver, -} from "./lib/converter"; +} from "./lib/converter/index.js"; export { Renderer, @@ -41,12 +41,12 @@ export { RendererEvent, MarkdownEvent, IndexEvent, -} from "./lib/output"; +} from "./lib/output/index.js"; export type { RenderTemplate, RendererHooks, NavigationElement, -} from "./lib/output"; +} from "./lib/output/index.js"; export { ArgumentsReader, @@ -65,7 +65,7 @@ export { EventHooks, MinimalSourceFile, normalizePath, -} from "./lib/utils"; +} from "./lib/utils/index.js"; export type { OptionsReader, @@ -91,9 +91,9 @@ export type { ManuallyValidatedOption, EnumKeys, JsDocCompatibility, -} from "./lib/utils"; +} from "./lib/utils/index.js"; -export type { EventMap, EventCallback } from "./lib/utils/events"; +export type { EventMap, EventCallback } from "./lib/utils/events.js"; export { JSONOutput, @@ -103,7 +103,7 @@ export { type DeserializerComponent, type SerializerComponent, SerializeEvent, -} from "./lib/serialization"; +} from "./lib/serialization/index.js"; import TypeScript from "typescript"; export { TypeScript }; diff --git a/src/lib/application.ts b/src/lib/application.ts index bdc2535dc..0d3605eef 100644 --- a/src/lib/application.ts +++ b/src/lib/application.ts @@ -1,54 +1,62 @@ import * as Path from "path"; import ts from "typescript"; -import { Converter } from "./converter/index"; -import { Renderer } from "./output/renderer"; -import { Deserializer, JSONOutput, Serializer } from "./serialization"; -import type { ProjectReflection } from "./models/index"; +import { Converter } from "./converter/index.js"; +import { Renderer } from "./output/renderer.js"; +import { Deserializer, JSONOutput, Serializer } from "./serialization/index.js"; +import type { ProjectReflection } from "./models/index.js"; import { Logger, ConsoleLogger, loadPlugins, writeFile, - OptionsReader, + type OptionsReader, TSConfigReader, TypeDocReader, PackageJsonReader, -} from "./utils/index"; +} from "./utils/index.js"; import { AbstractComponent, ChildableComponent, Component, -} from "./utils/component"; -import { Options, Option } from "./utils"; -import type { TypeDocOptions } from "./utils/options/declaration"; -import { unique } from "./utils/array"; +} from "./utils/component.js"; +import { Options, Option } from "./utils/index.js"; +import type { TypeDocOptions } from "./utils/options/declaration.js"; +import { unique } from "./utils/array.js"; import { ok } from "assert"; import { - DocumentationEntryPoint, + type DocumentationEntryPoint, EntryPointStrategy, getEntryPoints, getPackageDirectories, getWatchEntryPoints, -} from "./utils/entry-point"; -import { nicePath } from "./utils/paths"; -import { getLoadedPaths, hasBeenLoadedMultipleTimes } from "./utils/general"; -import { validateExports } from "./validation/exports"; -import { validateDocumentation } from "./validation/documentation"; -import { validateLinks } from "./validation/links"; -import { ApplicationEvents } from "./application-events"; -import { findTsConfigFile } from "./utils/tsconfig"; -import { deriveRootDir, glob, readFile } from "./utils/fs"; -import { resetReflectionID } from "./models/reflections/abstract"; -import { addInferredDeclarationMapPaths } from "./models/reflections/ReflectionSymbolId"; +} from "./utils/entry-point.js"; +import { nicePath } from "./utils/paths.js"; +import { getLoadedPaths, hasBeenLoadedMultipleTimes } from "./utils/general.js"; +import { validateExports } from "./validation/exports.js"; +import { validateDocumentation } from "./validation/documentation.js"; +import { validateLinks } from "./validation/links.js"; +import { ApplicationEvents } from "./application-events.js"; +import { findTsConfigFile } from "./utils/tsconfig.js"; +import { deriveRootDir, glob, readFile } from "./utils/fs.js"; +import { resetReflectionID } from "./models/reflections/abstract.js"; +import { addInferredDeclarationMapPaths } from "./models/reflections/ReflectionSymbolId.js"; import { Internationalization, - TranslatedString, -} from "./internationalization/internationalization"; + type TranslatedString, +} from "./internationalization/internationalization.js"; +import { readFileSync } from "fs"; +import { fileURLToPath } from "url"; +import { createRequire } from "module"; // eslint-disable-next-line @typescript-eslint/no-var-requires -const packageInfo = require("../../package.json") as { +const packageInfo = JSON.parse( + readFileSync( + Path.join(fileURLToPath(import.meta.url), "../../../package.json"), + "utf8", + ), +) as { version: string; peerDependencies: { typescript: string }; }; @@ -278,7 +286,8 @@ export class Application extends ChildableComponent< * Return the path to the TypeScript compiler. */ public getTypeScriptPath(): string { - return nicePath(Path.dirname(require.resolve("typescript"))); + const req = createRequire(import.meta.url); + return nicePath(Path.dirname(req.resolve("typescript"))); } public getTypeScriptVersion(): string { diff --git a/src/lib/cli.ts b/src/lib/cli.ts index b408c9b35..8c713da7b 100644 --- a/src/lib/cli.ts +++ b/src/lib/cli.ts @@ -10,7 +10,7 @@ const ExitCodes = { Watching: 7, }; -import * as td from "typedoc"; +import * as td from "../index.js"; void main(); diff --git a/src/lib/converter/comments/blockLexer.ts b/src/lib/converter/comments/blockLexer.ts index 39d627679..4c7b0a095 100644 --- a/src/lib/converter/comments/blockLexer.ts +++ b/src/lib/converter/comments/blockLexer.ts @@ -1,7 +1,7 @@ import ts from "typescript"; -import { Token, TokenSyntaxKind } from "./lexer"; -import { ReflectionSymbolId } from "../../models/reflections/ReflectionSymbolId"; -import { resolveAliasedSymbol } from "../utils/symbols"; +import { type Token, TokenSyntaxKind } from "./lexer.js"; +import { ReflectionSymbolId } from "../../models/reflections/ReflectionSymbolId.js"; +import { resolveAliasedSymbol } from "../utils/symbols.js"; export function* lexBlockComment( file: string, diff --git a/src/lib/converter/comments/declarationReference.ts b/src/lib/converter/comments/declarationReference.ts index 9a2575a27..0cb747e46 100644 --- a/src/lib/converter/comments/declarationReference.ts +++ b/src/lib/converter/comments/declarationReference.ts @@ -6,7 +6,7 @@ * @module */ -import type { Chars } from "../../utils"; +import type { Chars } from "../../utils/index.js"; export const MeaningKeywords = [ "class", // SymbolFlags.Class diff --git a/src/lib/converter/comments/declarationReferenceResolver.ts b/src/lib/converter/comments/declarationReferenceResolver.ts index 8ab91db77..a5741300f 100644 --- a/src/lib/converter/comments/declarationReferenceResolver.ts +++ b/src/lib/converter/comments/declarationReferenceResolver.ts @@ -5,14 +5,14 @@ import { ReferenceReflection, Reflection, ReflectionKind, -} from "../../models"; -import { assertNever, filterMap } from "../../utils"; +} from "../../models/index.js"; +import { assertNever, filterMap } from "../../utils/index.js"; import type { ComponentPath, DeclarationReference, Meaning, MeaningKeyword, -} from "./declarationReference"; +} from "./declarationReference.js"; function resolveReferenceReflection(ref: Reflection): Reflection { if (ref instanceof ReferenceReflection) { diff --git a/src/lib/converter/comments/discovery.ts b/src/lib/converter/comments/discovery.ts index bf0d20c50..eb0d38461 100644 --- a/src/lib/converter/comments/discovery.ts +++ b/src/lib/converter/comments/discovery.ts @@ -1,8 +1,8 @@ import ts from "typescript"; -import { ReflectionKind } from "../../models"; -import { assertNever, Logger } from "../../utils"; -import { CommentStyle } from "../../utils/options/declaration"; -import { nicePath } from "../../utils/paths"; +import { ReflectionKind } from "../../models/index.js"; +import { assertNever, Logger } from "../../utils/index.js"; +import { CommentStyle } from "../../utils/options/declaration.js"; +import { nicePath } from "../../utils/paths.js"; import { ok } from "assert"; const variablePropertyKinds = [ diff --git a/src/lib/converter/comments/index.ts b/src/lib/converter/comments/index.ts index 4fecade37..6ce3339bb 100644 --- a/src/lib/converter/comments/index.ts +++ b/src/lib/converter/comments/index.ts @@ -1,20 +1,20 @@ import ts from "typescript"; -import { Comment, ReflectionKind } from "../../models"; -import { assertNever, Logger } from "../../utils"; +import { Comment, ReflectionKind } from "../../models/index.js"; +import { assertNever, Logger } from "../../utils/index.js"; import type { CommentStyle, JsDocCompatibility, -} from "../../utils/options/declaration"; -import { lexBlockComment } from "./blockLexer"; +} from "../../utils/options/declaration.js"; +import { lexBlockComment } from "./blockLexer.js"; import { - DiscoveredComment, + type DiscoveredComment, discoverComment, discoverFileComment, discoverNodeComment, discoverSignatureComment, -} from "./discovery"; -import { lexLineComments } from "./lineLexer"; -import { parseComment } from "./parser"; +} from "./discovery.js"; +import { lexLineComments } from "./lineLexer.js"; +import { parseComment } from "./parser.js"; export interface CommentParserConfig { blockTags: Set; diff --git a/src/lib/converter/comments/lexer.ts b/src/lib/converter/comments/lexer.ts index 8905d87ec..98e3dbb97 100644 --- a/src/lib/converter/comments/lexer.ts +++ b/src/lib/converter/comments/lexer.ts @@ -1,4 +1,4 @@ -import type { ReflectionSymbolId } from "../../models"; +import type { ReflectionSymbolId } from "../../models/index.js"; export enum TokenSyntaxKind { Text = "text", diff --git a/src/lib/converter/comments/lineLexer.ts b/src/lib/converter/comments/lineLexer.ts index 1a197f962..4a2fff84d 100644 --- a/src/lib/converter/comments/lineLexer.ts +++ b/src/lib/converter/comments/lineLexer.ts @@ -1,5 +1,5 @@ import type * as ts from "typescript"; -import { Token, TokenSyntaxKind } from "./lexer"; +import { type Token, TokenSyntaxKind } from "./lexer.js"; export function* lexLineComments( file: string, diff --git a/src/lib/converter/comments/linkResolver.ts b/src/lib/converter/comments/linkResolver.ts index ea43f65ce..f29bb1790 100644 --- a/src/lib/converter/comments/linkResolver.ts +++ b/src/lib/converter/comments/linkResolver.ts @@ -1,17 +1,17 @@ import ts from "typescript"; import { Comment, - CommentDisplayPart, + type CommentDisplayPart, DeclarationReflection, - InlineTagDisplayPart, + type InlineTagDisplayPart, Reflection, ReflectionSymbolId, -} from "../../models"; +} from "../../models/index.js"; import { - DeclarationReference, + type DeclarationReference, parseDeclarationReference, -} from "./declarationReference"; -import { resolveDeclarationReference } from "./declarationReferenceResolver"; +} from "./declarationReference.js"; +import { resolveDeclarationReference } from "./declarationReferenceResolver.js"; const urlPrefix = /^(http|ftp)s?:\/\//; diff --git a/src/lib/converter/comments/parser.ts b/src/lib/converter/comments/parser.ts index f20a868a6..41cb4df26 100644 --- a/src/lib/converter/comments/parser.ts +++ b/src/lib/converter/comments/parser.ts @@ -1,20 +1,20 @@ import { ok } from "assert"; -import type { CommentParserConfig } from "."; +import type { CommentParserConfig } from "../index.js"; import { Comment, - CommentDisplayPart, + type CommentDisplayPart, CommentTag, - InlineTagDisplayPart, -} from "../../models"; -import { assertNever, Logger, removeIf } from "../../utils"; -import type { MinimalSourceFile } from "../../utils/minimalSourceFile"; -import { nicePath } from "../../utils/paths"; -import { Token, TokenSyntaxKind } from "./lexer"; -import { extractTagName } from "./tagName"; + type InlineTagDisplayPart, +} from "../../models/index.js"; +import { assertNever, Logger, removeIf } from "../../utils/index.js"; +import type { MinimalSourceFile } from "../../utils/minimalSourceFile.js"; +import { nicePath } from "../../utils/paths.js"; +import { type Token, TokenSyntaxKind } from "./lexer.js"; +import { extractTagName } from "./tagName.js"; import type { TranslatedString, TranslationProxy, -} from "../../internationalization/internationalization"; +} from "../../internationalization/internationalization.js"; interface LookaheadGenerator { done(): boolean; diff --git a/src/lib/converter/comments/rawLexer.ts b/src/lib/converter/comments/rawLexer.ts index 7b7eb8a93..533c000c4 100644 --- a/src/lib/converter/comments/rawLexer.ts +++ b/src/lib/converter/comments/rawLexer.ts @@ -1,4 +1,4 @@ -import { Token, TokenSyntaxKind } from "./lexer"; +import { type Token, TokenSyntaxKind } from "./lexer.js"; export function* lexCommentString( file: string, diff --git a/src/lib/converter/components.ts b/src/lib/converter/components.ts index 65dfba437..07fa2502b 100644 --- a/src/lib/converter/components.ts +++ b/src/lib/converter/components.ts @@ -1,5 +1,5 @@ -import { Component, AbstractComponent } from "../utils/component"; -import type { Converter } from "./converter"; +import { Component, AbstractComponent } from "../utils/component.js"; +import type { Converter } from "./converter.js"; export { Component }; diff --git a/src/lib/converter/context.ts b/src/lib/converter/context.ts index fab0a307c..c395add56 100644 --- a/src/lib/converter/context.ts +++ b/src/lib/converter/context.ts @@ -8,21 +8,21 @@ import { DeclarationReflection, ReflectionKind, ReflectionFlag, -} from "../models/index"; +} from "../models/index.js"; -import type { Converter } from "./converter"; -import { isNamedNode } from "./utils/nodes"; -import { ConverterEvents } from "./converter-events"; -import { resolveAliasedSymbol } from "./utils/symbols"; +import type { Converter } from "./converter.js"; +import { isNamedNode } from "./utils/nodes.js"; +import { ConverterEvents } from "./converter-events.js"; +import { resolveAliasedSymbol } from "./utils/symbols.js"; import { getComment, getFileComment, getJsDocComment, getNodeComment, getSignatureComment, -} from "./comments"; -import { getHumanName } from "../utils/tsutils"; -import type { TranslationProxy } from "../internationalization/internationalization"; +} from "./comments/index.js"; +import { getHumanName } from "../utils/tsutils.js"; +import type { TranslationProxy } from "../internationalization/internationalization.js"; /** * The context describes the current state the converter is in. diff --git a/src/lib/converter/converter.ts b/src/lib/converter/converter.ts index 0f5ec6201..14036a31e 100644 --- a/src/lib/converter/converter.ts +++ b/src/lib/converter/converter.ts @@ -1,40 +1,40 @@ import ts from "typescript"; -import type { Application } from "../application"; +import type { Application } from "../application.js"; import { Comment, - CommentDisplayPart, + type CommentDisplayPart, ProjectReflection, Reflection, ReflectionKind, ReflectionSymbolId, - SomeType, -} from "../models/index"; -import { Context } from "./context"; -import { ConverterComponent } from "./components"; -import { Component, ChildableComponent } from "../utils/component"; -import { Option, MinimalSourceFile, readFile, unique } from "../utils"; -import { convertType } from "./types"; -import { ConverterEvents } from "./converter-events"; -import { convertSymbol } from "./symbols"; -import { createMinimatch, matchesAny } from "../utils/paths"; + type SomeType, +} from "../models/index.js"; +import { Context } from "./context.js"; +import { ConverterComponent } from "./components.js"; +import { Component, ChildableComponent } from "../utils/component.js"; +import { Option, MinimalSourceFile, readFile, unique } from "../utils/index.js"; +import { convertType } from "./types.js"; +import { ConverterEvents } from "./converter-events.js"; +import { convertSymbol } from "./symbols.js"; +import { createMinimatch, matchesAny } from "../utils/paths.js"; import type { Minimatch } from "minimatch"; -import { hasAllFlags, hasAnyFlag } from "../utils/enum"; -import type { DocumentationEntryPoint } from "../utils/entry-point"; -import type { CommentParserConfig } from "./comments"; +import { hasAllFlags, hasAnyFlag } from "../utils/enum.js"; +import type { DocumentationEntryPoint } from "../utils/entry-point.js"; +import type { CommentParserConfig } from "./comments/index.js"; import type { CommentStyle, ValidationOptions, -} from "../utils/options/declaration"; -import { parseComment } from "./comments/parser"; -import { lexCommentString } from "./comments/rawLexer"; +} from "../utils/options/declaration.js"; +import { parseComment } from "./comments/parser.js"; +import { lexCommentString } from "./comments/rawLexer.js"; import { resolvePartLinks, resolveLinks, - ExternalSymbolResolver, - ExternalResolveResult, -} from "./comments/linkResolver"; -import type { DeclarationReference } from "./comments/declarationReference"; + type ExternalSymbolResolver, + type ExternalResolveResult, +} from "./comments/linkResolver.js"; +import type { DeclarationReference } from "./comments/declarationReference.js"; /** * Compiles source files using TypeScript and converts compiler symbols to reflections. diff --git a/src/lib/converter/factories/index-signature.ts b/src/lib/converter/factories/index-signature.ts index 5b1106e57..5530a5efd 100644 --- a/src/lib/converter/factories/index-signature.ts +++ b/src/lib/converter/factories/index-signature.ts @@ -5,9 +5,9 @@ import { ParameterReflection, ReflectionKind, SignatureReflection, -} from "../../models"; -import type { Context } from "../context"; -import { ConverterEvents } from "../converter-events"; +} from "../../models/index.js"; +import type { Context } from "../context.js"; +import { ConverterEvents } from "../converter-events.js"; export function convertIndexSignatures(context: Context, symbol: ts.Symbol) { assert(context.scope instanceof DeclarationReflection); diff --git a/src/lib/converter/factories/signature.ts b/src/lib/converter/factories/signature.ts index 97490fa1c..c87c9564e 100644 --- a/src/lib/converter/factories/signature.ts +++ b/src/lib/converter/factories/signature.ts @@ -13,12 +13,12 @@ import { SignatureReflection, TypeParameterReflection, VarianceModifier, -} from "../../models"; -import type { Context } from "../context"; -import { ConverterEvents } from "../converter-events"; -import { convertDefaultValue } from "../convert-expression"; -import { removeUndefined } from "../utils/reflections"; -import { ReflectionSymbolId } from "../../models/reflections/ReflectionSymbolId"; +} from "../../models/index.js"; +import type { Context } from "../context.js"; +import { ConverterEvents } from "../converter-events.js"; +import { convertDefaultValue } from "../convert-expression.js"; +import { removeUndefined } from "../utils/reflections.js"; +import { ReflectionSymbolId } from "../../models/reflections/ReflectionSymbolId.js"; export function createSignature( context: Context, diff --git a/src/lib/converter/index.ts b/src/lib/converter/index.ts index c8ab59175..2989cd6c5 100644 --- a/src/lib/converter/index.ts +++ b/src/lib/converter/index.ts @@ -1,17 +1,20 @@ -export { Context } from "./context"; -export { Converter } from "./converter"; -export type { CommentParserConfig } from "./comments/index"; -export { convertDefaultValue, convertExpression } from "./convert-expression"; +export { Context } from "./context.js"; +export { Converter } from "./converter.js"; +export type { CommentParserConfig } from "./comments/index.js"; +export { + convertDefaultValue, + convertExpression, +} from "./convert-expression.js"; export type { DeclarationReference, SymbolReference, ComponentPath, Meaning, MeaningKeyword, -} from "./comments/declarationReference"; +} from "./comments/declarationReference.js"; export type { ExternalSymbolResolver, ExternalResolveResult, -} from "./comments/linkResolver"; +} from "./comments/linkResolver.js"; -import "./plugins/index"; +import "./plugins/index.js"; diff --git a/src/lib/converter/jsdoc.ts b/src/lib/converter/jsdoc.ts index da5b38c8a..295d8af7d 100644 --- a/src/lib/converter/jsdoc.ts +++ b/src/lib/converter/jsdoc.ts @@ -10,14 +10,14 @@ import { ReflectionKind, ReflectionType, SignatureReflection, -} from "../models"; -import { ReflectionSymbolId } from "../models/reflections/ReflectionSymbolId"; -import type { Context } from "./context"; -import { ConverterEvents } from "./converter-events"; +} from "../models/index.js"; +import { ReflectionSymbolId } from "../models/reflections/ReflectionSymbolId.js"; +import type { Context } from "./context.js"; +import { ConverterEvents } from "./converter-events.js"; import { convertParameterNodes, convertTemplateParameterNodes, -} from "./factories/signature"; +} from "./factories/signature.js"; export function convertJsDocAlias( context: Context, diff --git a/src/lib/converter/plugins/CategoryPlugin.ts b/src/lib/converter/plugins/CategoryPlugin.ts index cb2ef1dd0..3f1bde4d1 100644 --- a/src/lib/converter/plugins/CategoryPlugin.ts +++ b/src/lib/converter/plugins/CategoryPlugin.ts @@ -2,12 +2,12 @@ import { ContainerReflection, DeclarationReflection, Comment, -} from "../../models"; -import { ReflectionCategory } from "../../models"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import { Option, getSortFunction, removeIf } from "../../utils"; +} from "../../models/index.js"; +import { ReflectionCategory } from "../../models/index.js"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import { Option, getSortFunction, removeIf } from "../../utils/index.js"; /** * A handler that sorts and categorizes the found reflections in the resolving phase. diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index fdf7cff85..76b66e8db 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -1,6 +1,6 @@ -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; import { Reflection, ReflectionFlag, @@ -12,9 +12,9 @@ import { Comment, ReflectionType, SourceReference, - TypeVisitor, + type TypeVisitor, CommentTag, -} from "../../models"; +} from "../../models/index.js"; import { Option, filterMap, @@ -22,8 +22,8 @@ import { unique, partition, removeIf, -} from "../../utils"; -import { CategoryPlugin } from "./CategoryPlugin"; +} from "../../utils/index.js"; +import { CategoryPlugin } from "./CategoryPlugin.js"; /** * These tags are not useful to display in the generated documentation. diff --git a/src/lib/converter/plugins/GroupPlugin.ts b/src/lib/converter/plugins/GroupPlugin.ts index ea429ed54..b1399e516 100644 --- a/src/lib/converter/plugins/GroupPlugin.ts +++ b/src/lib/converter/plugins/GroupPlugin.ts @@ -2,14 +2,14 @@ import { ReflectionKind, ContainerReflection, DeclarationReflection, -} from "../../models/reflections/index"; -import { ReflectionGroup } from "../../models/ReflectionGroup"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import { getSortFunction } from "../../utils/sort"; -import { Option, removeIf } from "../../utils"; -import { Comment } from "../../models"; +} from "../../models/reflections/index.js"; +import { ReflectionGroup } from "../../models/ReflectionGroup.js"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import { getSortFunction } from "../../utils/sort.js"; +import { Option, removeIf } from "../../utils/index.js"; +import { Comment } from "../../models/index.js"; // Same as the defaultKindSortOrder in sort.ts const defaultGroupOrder = [ diff --git a/src/lib/converter/plugins/ImplementsPlugin.ts b/src/lib/converter/plugins/ImplementsPlugin.ts index 57224bd01..f59c031bf 100644 --- a/src/lib/converter/plugins/ImplementsPlugin.ts +++ b/src/lib/converter/plugins/ImplementsPlugin.ts @@ -1,5 +1,5 @@ import ts from "typescript"; -import { ApplicationEvents } from "../../application-events"; +import { ApplicationEvents } from "../../application-events.js"; import { ContainerReflection, DeclarationReflection, @@ -7,14 +7,14 @@ import { Reflection, ReflectionKind, SignatureReflection, -} from "../../models/reflections/index"; -import { ReferenceType, ReflectionType, Type } from "../../models/types"; -import { filterMap, zip } from "../../utils/array"; -import { Component, ConverterComponent } from "../components"; -import type { Context } from "../context"; -import { Converter } from "../converter"; -import { getHumanName } from "../../utils"; -import type { TranslatedString } from "../../internationalization/internationalization"; +} from "../../models/reflections/index.js"; +import { ReferenceType, ReflectionType, Type } from "../../models/types.js"; +import { filterMap, zip } from "../../utils/array.js"; +import { Component, ConverterComponent } from "../components.js"; +import type { Context } from "../context.js"; +import { Converter } from "../converter.js"; +import { getHumanName } from "../../utils/index.js"; +import type { TranslatedString } from "../../internationalization/internationalization.js"; /** * A plugin that detects interface implementations of functions and diff --git a/src/lib/converter/plugins/InheritDocPlugin.ts b/src/lib/converter/plugins/InheritDocPlugin.ts index 04c1844a6..2f8c734da 100644 --- a/src/lib/converter/plugins/InheritDocPlugin.ts +++ b/src/lib/converter/plugins/InheritDocPlugin.ts @@ -5,16 +5,20 @@ import { ReflectionKind, ReflectionType, SignatureReflection, -} from "../../models"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import type { Reflection } from "../../models/reflections/abstract"; -import { Option, DefaultMap, ValidationOptions } from "../../utils"; -import { zip } from "../../utils/array"; -import { parseDeclarationReference } from "../comments/declarationReference"; -import { resolveDeclarationReference } from "../comments/declarationReferenceResolver"; -import { ApplicationEvents } from "../../application-events"; +} from "../../models/index.js"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import type { Reflection } from "../../models/reflections/abstract.js"; +import { + Option, + DefaultMap, + type ValidationOptions, +} from "../../utils/index.js"; +import { zip } from "../../utils/array.js"; +import { parseDeclarationReference } from "../comments/declarationReference.js"; +import { resolveDeclarationReference } from "../comments/declarationReferenceResolver.js"; +import { ApplicationEvents } from "../../application-events.js"; /** * A plugin that handles `@inheritDoc` tags by copying documentation from another API item. diff --git a/src/lib/converter/plugins/LinkResolverPlugin.ts b/src/lib/converter/plugins/LinkResolverPlugin.ts index 85ba48b88..7c38733d7 100644 --- a/src/lib/converter/plugins/LinkResolverPlugin.ts +++ b/src/lib/converter/plugins/LinkResolverPlugin.ts @@ -1,16 +1,16 @@ -import { Component, ConverterComponent } from "../components"; -import type { Context, ExternalResolveResult } from "../../converter"; -import { ConverterEvents } from "../converter-events"; -import { Option, ValidationOptions } from "../../utils"; +import { Component, ConverterComponent } from "../components.js"; +import type { Context, ExternalResolveResult } from "../../converter/index.js"; +import { ConverterEvents } from "../converter-events.js"; +import { Option, type ValidationOptions } from "../../utils/index.js"; import { ContainerReflection, DeclarationReflection, ProjectReflection, Reflection, ReflectionCategory, -} from "../../models"; -import { discoverAllReferenceTypes } from "../../utils/reflections"; -import { ApplicationEvents } from "../../application-events"; +} from "../../models/index.js"; +import { discoverAllReferenceTypes } from "../../utils/reflections.js"; +import { ApplicationEvents } from "../../application-events.js"; /** * A plugin that resolves `{@link Foo}` tags. diff --git a/src/lib/converter/plugins/PackagePlugin.ts b/src/lib/converter/plugins/PackagePlugin.ts index f3255ca17..67ba094ed 100644 --- a/src/lib/converter/plugins/PackagePlugin.ts +++ b/src/lib/converter/plugins/PackagePlugin.ts @@ -1,18 +1,18 @@ import * as Path from "path"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import { Option, EntryPointStrategy, readFile } from "../../utils"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import { Option, EntryPointStrategy, readFile } from "../../utils/index.js"; import { deriveRootDir, discoverInParentDir, discoverPackageJson, -} from "../../utils/fs"; -import { nicePath } from "../../utils/paths"; -import { MinimalSourceFile } from "../../utils/minimalSourceFile"; -import type { ProjectReflection } from "../../models/index"; -import { ApplicationEvents } from "../../application-events"; +} from "../../utils/fs.js"; +import { nicePath } from "../../utils/paths.js"; +import { MinimalSourceFile } from "../../utils/minimalSourceFile.js"; +import type { ProjectReflection } from "../../models/index.js"; +import { ApplicationEvents } from "../../application-events.js"; import { join } from "path"; /** diff --git a/src/lib/converter/plugins/SourcePlugin.ts b/src/lib/converter/plugins/SourcePlugin.ts index 50b5ab540..4998ecda2 100644 --- a/src/lib/converter/plugins/SourcePlugin.ts +++ b/src/lib/converter/plugins/SourcePlugin.ts @@ -3,21 +3,25 @@ import ts from "typescript"; import { DeclarationReflection, SignatureReflection, -} from "../../models/reflections/index"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import { Option, normalizePath, getCommonDirectory } from "../../utils"; -import { isNamedNode } from "../utils/nodes"; +} from "../../models/reflections/index.js"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import { + Option, + normalizePath, + getCommonDirectory, +} from "../../utils/index.js"; +import { isNamedNode } from "../utils/nodes.js"; import { dirname, relative } from "path"; -import { SourceReference } from "../../models"; +import { SourceReference } from "../../models/index.js"; import { AssumedRepository, gitIsInstalled, GitRepository, - Repository, -} from "../utils/repository"; -import { BasePath } from "../utils/base-path"; + type Repository, +} from "../utils/repository.js"; +import { BasePath } from "../utils/base-path.js"; /** * A handler that attaches source file information to reflections. diff --git a/src/lib/converter/plugins/TypePlugin.ts b/src/lib/converter/plugins/TypePlugin.ts index 13c946978..4e8350c7a 100644 --- a/src/lib/converter/plugins/TypePlugin.ts +++ b/src/lib/converter/plugins/TypePlugin.ts @@ -1,15 +1,15 @@ import { ReflectionKind, DeclarationReflection, - DeclarationHierarchy, + type DeclarationHierarchy, ProjectReflection, Reflection, -} from "../../models/reflections/index"; -import { Type, ReferenceType } from "../../models/types"; -import { Component, ConverterComponent } from "../components"; -import { Converter } from "../converter"; -import type { Context } from "../context"; -import { ApplicationEvents } from "../../application-events"; +} from "../../models/reflections/index.js"; +import { Type, ReferenceType } from "../../models/types.js"; +import { Component, ConverterComponent } from "../components.js"; +import { Converter } from "../converter.js"; +import type { Context } from "../context.js"; +import { ApplicationEvents } from "../../application-events.js"; /** * Responsible for adding `implementedBy` / `implementedFrom` diff --git a/src/lib/converter/plugins/index.ts b/src/lib/converter/plugins/index.ts index 29564d1f4..c8b27d76e 100644 --- a/src/lib/converter/plugins/index.ts +++ b/src/lib/converter/plugins/index.ts @@ -1,9 +1,9 @@ -export { CategoryPlugin } from "./CategoryPlugin"; -export { CommentPlugin } from "./CommentPlugin"; -export { GroupPlugin } from "./GroupPlugin"; -export { ImplementsPlugin } from "./ImplementsPlugin"; -export { InheritDocPlugin } from "./InheritDocPlugin"; -export { LinkResolverPlugin } from "./LinkResolverPlugin"; -export { PackagePlugin } from "./PackagePlugin"; -export { SourcePlugin } from "./SourcePlugin"; -export { TypePlugin } from "./TypePlugin"; +export { CategoryPlugin } from "./CategoryPlugin.js"; +export { CommentPlugin } from "./CommentPlugin.js"; +export { GroupPlugin } from "./GroupPlugin.js"; +export { ImplementsPlugin } from "./ImplementsPlugin.js"; +export { InheritDocPlugin } from "./InheritDocPlugin.js"; +export { LinkResolverPlugin } from "./LinkResolverPlugin.js"; +export { PackagePlugin } from "./PackagePlugin.js"; +export { SourcePlugin } from "./SourcePlugin.js"; +export { TypePlugin } from "./TypePlugin.js"; diff --git a/src/lib/converter/symbols.ts b/src/lib/converter/symbols.ts index 54a236b6c..69d2578ee 100644 --- a/src/lib/converter/symbols.ts +++ b/src/lib/converter/symbols.ts @@ -9,24 +9,24 @@ import { ReflectionFlag, ReflectionKind, ConversionFlags, -} from "../models"; +} from "../models/index.js"; import { getEnumFlags, hasAllFlags, hasAnyFlag, removeFlag, -} from "../utils/enum"; -import type { Context } from "./context"; -import { convertDefaultValue } from "./convert-expression"; -import { convertIndexSignatures } from "./factories/index-signature"; +} from "../utils/enum.js"; +import type { Context } from "./context.js"; +import { convertDefaultValue } from "./convert-expression.js"; +import { convertIndexSignatures } from "./factories/index-signature.js"; import { createConstructSignatureWithType, createSignature, createTypeParamReflection, -} from "./factories/signature"; -import { convertJsDocAlias, convertJsDocCallback } from "./jsdoc"; -import { getHeritageTypes } from "./utils/nodes"; -import { removeUndefined } from "./utils/reflections"; +} from "./factories/signature.js"; +import { convertJsDocAlias, convertJsDocCallback } from "./jsdoc.js"; +import { getHeritageTypes } from "./utils/nodes.js"; +import { removeUndefined } from "./utils/reflections.js"; const symbolConverters: { [K in ts.SymbolFlags]?: ( diff --git a/src/lib/converter/types.ts b/src/lib/converter/types.ts index 53c644f21..729196614 100644 --- a/src/lib/converter/types.ts +++ b/src/lib/converter/types.ts @@ -25,22 +25,22 @@ import { OptionalType, RestType, TemplateLiteralType, - SomeType, -} from "../models"; -import { ReflectionSymbolId } from "../models/reflections/ReflectionSymbolId"; -import { zip } from "../utils/array"; -import type { Context } from "./context"; -import { ConverterEvents } from "./converter-events"; -import { convertIndexSignatures } from "./factories/index-signature"; + type SomeType, +} from "../models/index.js"; +import { ReflectionSymbolId } from "../models/reflections/ReflectionSymbolId.js"; +import { zip } from "../utils/array.js"; +import type { Context } from "./context.js"; +import { ConverterEvents } from "./converter-events.js"; +import { convertIndexSignatures } from "./factories/index-signature.js"; import { convertParameterNodes, convertTypeParameterNodes, createSignature, -} from "./factories/signature"; -import { convertSymbol } from "./symbols"; -import { isObjectType } from "./utils/nodes"; -import { removeUndefined } from "./utils/reflections"; -import type { TranslatedString } from "../internationalization/internationalization"; +} from "./factories/signature.js"; +import { convertSymbol } from "./symbols.js"; +import { isObjectType } from "./utils/nodes.js"; +import { removeUndefined } from "./utils/reflections.js"; +import type { TranslatedString } from "../internationalization/internationalization.js"; export interface TypeConverter< TNode extends ts.TypeNode = ts.TypeNode, diff --git a/src/lib/converter/utils/reflections.ts b/src/lib/converter/utils/reflections.ts index 91f12165b..8b3ee9e59 100644 --- a/src/lib/converter/utils/reflections.ts +++ b/src/lib/converter/utils/reflections.ts @@ -1,4 +1,4 @@ -import { IntrinsicType, SomeType, UnionType } from "../../models"; +import { IntrinsicType, type SomeType, UnionType } from "../../models/index.js"; export function removeUndefined(type: SomeType): SomeType { if (type instanceof UnionType) { diff --git a/src/lib/converter/utils/repository.ts b/src/lib/converter/utils/repository.ts index 408268821..162da25f3 100644 --- a/src/lib/converter/utils/repository.ts +++ b/src/lib/converter/utils/repository.ts @@ -1,6 +1,6 @@ import { spawnSync } from "child_process"; -import type { Logger } from "../../utils"; -import { BasePath } from "../utils/base-path"; +import type { Logger } from "../../utils/index.js"; +import { BasePath } from "../utils/base-path.js"; const TEN_MEGABYTES = 1024 * 10000; diff --git a/src/lib/internationalization/internationalization.ts b/src/lib/internationalization/internationalization.ts index 6641edeff..7f29ebc27 100644 --- a/src/lib/internationalization/internationalization.ts +++ b/src/lib/internationalization/internationalization.ts @@ -1,13 +1,13 @@ import { ok } from "assert"; -import type { Application } from "../application"; -import { DefaultMap, unique } from "../utils"; -import { - translatable, - type BuiltinTranslatableStringArgs, -} from "./translatable"; +import type { Application } from "../application.js"; +import { DefaultMap, unique } from "../utils/index.js"; import { readdirSync } from "fs"; import { join } from "path"; -import { ReflectionKind } from "../models/reflections/kind"; +import { ReflectionKind } from "../models/reflections/kind.js"; +import type { BuiltinTranslatableStringArgs } from "./translatable.js"; +import translatable from "./locales/en.cjs"; +import { fileURLToPath } from "url"; +import { createRequire } from "module"; /** * ### What is translatable? @@ -72,6 +72,7 @@ const ext = process[Symbol.for("ts-node.register.instance") as never] export class Internationalization { private allTranslations = new DefaultMap>( (lang) => { + const req = createRequire(fileURLToPath(import.meta.url)); // Make sure this isn't abused to load some random file by mistake ok( /^[A-Za-z-]+$/.test(lang), @@ -80,7 +81,7 @@ export class Internationalization { try { return new Map( // eslint-disable-next-line @typescript-eslint/no-var-requires - Object.entries(require(`./locales/${lang}.${ext}`)), + Object.entries(req(`./locales/${lang}.${ext}`)), ); } catch { return new Map(); @@ -258,9 +259,9 @@ export class Internationalization { */ getSupportedLanguages(): string[] { return unique([ - ...readdirSync(join(__dirname, "locales")).map((x) => - x.substring(0, x.indexOf(".")), - ), + ...readdirSync( + join(fileURLToPath(import.meta.url), "../locales"), + ).map((x) => x.substring(0, x.indexOf("."))), ...this.allTranslations.keys(), ]).sort(); } diff --git a/src/lib/internationalization/locale-utils.cts b/src/lib/internationalization/locale-utils.cts new file mode 100644 index 000000000..c9cf87ae1 --- /dev/null +++ b/src/lib/internationalization/locale-utils.cts @@ -0,0 +1,15 @@ +import type { BuiltinTranslatableStringConstraints } from "./translatable.js" with { "resolution-mode": "import" } + +function buildTranslation( + translations: T, +) { + return translations; +} + +function buildIncompleteTranslation< + T extends Partial, +>(translations: T) { + return translations; +} + +export = { buildTranslation, buildIncompleteTranslation }; diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 828bea505..102c7a415 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -1,3 +1,430 @@ -import { translatable } from "../translatable"; +export = { + loaded_multiple_times_0: + "TypeDoc has been loaded multiple times. This is commonly caused by plugins which have their own installation of TypeDoc. The loaded paths are:\n\t{0}", + unsupported_ts_version_0: + "You are running with an unsupported TypeScript version! If TypeDoc crashes, this is why. TypeDoc supports {0}", + no_compiler_options_set: + "No compiler options set. This likely means that TypeDoc did not find your tsconfig.json. Generated documentation will probably be empty.", -export = translatable; + loaded_plugin_0: `Loaded plugin {0}`, + + solution_not_supported_in_watch_mode: + "The provided tsconfig file looks like a solution style tsconfig, which is not supported in watch mode.", + strategy_not_supported_in_watch_mode: + "entryPointStrategy must be set to either resolve or expand for watch mode.", + + docs_could_not_be_generated: + "Documentation could not be generated due to the errors above.", + docs_generated_at_0: "Documentation generated at {0}", + json_written_to_0: "JSON written to {0}", + + no_entry_points_for_packages: + "No entry points provided to packages mode, documentation cannot be generated.", + failed_to_find_packages: + "Failed to find any packages, ensure you have provided at least one directory as an entry point containing package.json", + nested_packages_unsupported_0: + "Project at {0} has entryPointStrategy set to packages, but nested packages are not supported.", + converting_project_at_0: "Converting project at {0}", + failed_to_convert_packages: + "Failed to convert one or more packages, result will not be merged together.", + merging_converted_projects: "Merging converted projects", + + no_entry_points_to_merge: "No entry points provided to merge.", + entrypoint_did_not_match_files_0: + "The entrypoint glob {0} did not match any files.", + failed_to_parse_json_0: `Failed to parse file at {0} as json.`, + + block_and_modifier_tags_ignored_within_readme_0: `Block and modifier tags will be ignored within the readme:\n\t{0}`, + + converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code.`, + converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value.`, + converting_0_as_class_without_construct_signatures: `{0} is being converted as a class, but does not have any construct signatures`, + + symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used.`, + comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`, + + // comments/parser.ts + multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment.`, + failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report.`, + + inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: + "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}", + at_most_one_remarks_tag_expected_in_comment_at_0: + "At most one @remarks tag is expected in a comment, ignoring all but the first in comment at {0}", + at_most_one_returns_tag_expected_in_comment_at_0: + "At most one @returns tag is expected in a comment, ignoring all but the first in comment at {0}", + at_most_one_inheritdoc_tag_expected_in_comment_at_0: + "At most one @inheritDoc tag is expected in a comment, ignoring all but the first in comment at {0}", + content_in_summary_overwritten_by_inheritdoc_in_comment_at_0: + "Content in the summary section will be overwritten by the @inheritDoc tag in comment at {0}", + content_in_remarks_block_overwritten_by_inheritdoc_in_comment_at_0: + "Content in the @remarks block will be overwritten by the @inheritDoc tag in comment at {0}", + example_tag_literal_name: + "The first line of an example tag will be taken literally as the example name, and should only contain text.", + inheritdoc_tag_properly_capitalized: + "The @inheritDoc tag should be properly capitalized.", + treating_unrecognized_tag_0_as_modifier: `Treating unrecognized tag {0} as a modifier tag.`, + unmatched_closing_brace: `Unmatched closing brace.`, + unescaped_open_brace_without_inline_tag: `Encountered an unescaped open brace without an inline tag.`, + unknown_inline_tag_0: `Encountered an unknown inline tag {0}.`, + open_brace_within_inline_tag: `Encountered an open brace within an inline tag, this is likely a mistake.`, + inline_tag_not_closed: `Inline tag is not closed.`, + + // validation + failed_to_resolve_link_to_0_in_comment_for_1: `Failed to resolve link to "{0}" in comment for {1}`, + type_0_defined_in_1_is_referenced_by_2_but_not_included_in_docs: `{0}, defined in {1}, is referenced by {2} but not included in the documentation.`, + reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation.`, + invalid_intentionally_not_exported_symbols_0: + "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}", + + // conversion plugins + not_all_search_category_boosts_used_0: `Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}`, + not_all_search_group_boosts_used_0: `Not all groups specified in searchGroupBoosts were used in the documentation. The unused groups were:\n\t{0}`, + comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category.`, + comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group.`, + label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number.`, + signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used.`, + declaration_reference_in_inheritdoc_for_0_not_fully_parsed: `Declaration reference in @inheritDoc for {0} was not fully parsed and may resolve incorrectly.`, + failed_to_find_0_to_inherit_comment_from_in_1: `Failed to find "{0}" to inherit the comment from in the comment for {1}`, + reflection_0_tried_to_copy_comment_from_1_but_source_had_no_comment: `{0} tried to copy a comment from {1} with @inheritDoc, but the source has no associated comment.`, + inheritdoc_circular_inheritance_chain_0: `@inheritDoc specifies a circular inheritance chain: {0}`, + provided_readme_at_0_could_not_be_read: `Provided README path, {0} could not be read.`, + defaulting_project_name: + 'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation".', + disable_git_set_but_not_source_link_template: `disableGit is set, but sourceLinkTemplate is not, so source links cannot be produced. Set a sourceLinkTemplate or disableSources to prevent source tracking.`, + disable_git_set_and_git_revision_used: `disableGit is set and sourceLinkTemplate contains {gitRevision}, which will be replaced with an empty string as no revision was provided.`, + git_remote_0_not_valid: `The provided git remote "{0}" was not valid. Source links will be broken.`, + + // output plugins + custom_css_file_0_does_not_exist: `Custom CSS file at {0} does not exist.`, + unsupported_highlight_language_0_not_highlighted_in_comment_for_1: `Unsupported highlight language {0} will not be highlighted in comment for {1}.`, + could_not_find_file_to_include_0: `Could not find file to include: {0}`, + could_not_find_media_file_0: `Could not find media file: {0}`, + could_not_find_includes_directory_0: + "Could not find provided includes directory: {0}", + could_not_find_media_directory_0: + "Could not find provided media directory: {0}", + + // renderer + could_not_write_0: `Could not write {0}`, + could_not_empty_output_directory_0: `Could not empty the output directory {0}`, + could_not_create_output_directory_0: `Could not create the output directory {0}`, + theme_0_is_not_defined_available_are_1: `The theme '{0}' is not defined. The available themes are: {1}`, + + // entry points + no_entry_points_provided: + "No entry points were provided, this is likely a misconfiguration.", + unable_to_find_any_entry_points: + "Unable to find any entry points. See previous warnings.", + watch_does_not_support_packages_mode: + "Watch mode does not support 'packages' style entry points.", + watch_does_not_support_merge_mode: + "Watch mode does not support 'merge' style entry points.", + entry_point_0_not_in_program: `The entry point {0} is not referenced by the 'files' or 'include' option in your tsconfig.`, + use_expand_or_glob_for_files_in_dir: `If you wanted to include files inside this directory, set --entryPointStrategy to expand or specify a glob.`, + entry_point_0_did_not_match_any_files: `The entry point glob {0} did not match any files.`, + entry_point_0_did_not_match_any_files_after_exclude: `The entry point glob {0} did not match any files after applying exclude patterns.`, + entry_point_0_did_not_exist: `Provided entry point {0} does not exist.`, + entry_point_0_did_not_match_any_packages: `The entry point glob {0} did not match any directories containing package.json.`, + file_0_not_an_object: `The file {0} is not an object.`, + + // deserialization + serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project.`, + + // options + circular_reference_extends_0: `Circular reference encountered for "extends" field of {0}`, + failed_resolve_0_to_file_in_1: `Failed to resolve {0} to a file in {1}`, + + option_0_can_only_be_specified_by_config_file: `The '{0}' option can only be specified via a config file.`, + option_0_expected_a_value_but_none_provided: `--{0} expected a value, but none was given as an argument.`, + unknown_option_0_may_have_meant_1: `Unknown option: {0}, you may have meant:\n\t{1}`, + + typedoc_key_in_0_ignored: `The 'typedoc' key in {0} was used by the legacy-packages entryPointStrategy and will be ignored.`, + typedoc_options_must_be_object_in_0: `Failed to parse the "typedocOptions" field in {0}, ensure it exists and contains an object.`, + tsconfig_file_0_does_not_exist: `The tsconfig file {0} does not exist`, + tsconfig_file_specifies_options_file: `"typedocOptions" in tsconfig file specifies an option file to read but the option file has already been read. This is likely a misconfiguration.`, + tsconfig_file_specifies_tsconfig_file: `"typedocOptions" in tsconfig file may not specify a tsconfig file to read.`, + tags_0_defined_in_typedoc_json_overwritten_by_tsdoc_json: `The {0} defined in typedoc.json will be overwritten by configuration in tsdoc.json.`, + failed_read_tsdoc_json_0: `Failed to read tsdoc.json file at {0}.`, + invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file.`, + + options_file_0_does_not_exist: `The options file {0} does not exist.`, + failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object.`, + + // plugins + invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found.`, + plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded.`, + + // option declarations help + help_options: + "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory.", + help_tsconfig: + "Specify a TypeScript config file that should be loaded. If not specified TypeDoc will look for 'tsconfig.json' in the current directory.", + help_compilerOptions: + "Selectively override the TypeScript compiler options used by TypeDoc.", + help_lang: + "Sets the language to be used in generation and in TypeDoc's messages.", + help_locales: + "Add translations for a specified locale. This option is primarily intended to be used as a stopgap while waiting for official locale support to be added to TypeDoc.", + + help_entryPoints: "The entry points of your documentation.", + help_entryPointStrategy: + "The strategy to be used to convert entry points into documentation modules.", + help_exclude: + "Define patterns to be excluded when expanding a directory that was specified as an entry point.", + help_externalPattern: + "Define patterns for files that should be considered being external.", + help_excludeExternals: + "Prevent externally resolved symbols from being documented.", + help_excludeNotDocumented: + "Prevent symbols that are not explicitly documented from appearing in the results.", + help_excludeNotDocumentedKinds: + "Specify the type of reflections that can be removed by excludeNotDocumented.", + help_excludeInternal: + "Prevent symbols that are marked with @internal from being documented.", + help_excludeCategories: + "Exclude symbols within this category from the documentation.", + help_excludePrivate: "Ignore private variables and methods.", + help_excludeProtected: "Ignore protected variables and methods.", + help_excludeReferences: + "If a symbol is exported multiple times, ignore all but the first export.", + help_externalSymbolLinkMappings: + "Define custom links for symbols not included in the documentation.", + help_media: + "Specify the location with media files that should be copied to the output directory.", + help_includes: + "Specify the location to look for included documents (use [[include:FILENAME]] in comments).", + help_out: "Specify the location the documentation should be written to.", + help_json: + "Specify the location and filename a JSON file describing the project is written to.", + help_pretty: + "Specify whether the output JSON should be formatted with tabs.", + help_emit: "Specify what TypeDoc should emit, 'docs', 'both', or 'none'.", + help_theme: "Specify the theme name to render the documentation with", + help_lightHighlightTheme: + "Specify the code highlighting theme in light mode.", + help_darkHighlightTheme: + "Specify the code highlighting theme in dark mode.", + help_customCss: "Path to a custom CSS file to for the theme to import.", + help_markedOptions: + "Specify the options passed to Marked, the Markdown parser used by TypeDoc.", + help_maxTypeConversionDepth: + "Set the maximum depth of types to be converted.", + help_name: + "Set the name of the project that will be used in the header of the template.", + help_includeVersion: "Add the package version to the project name.", + help_disableSources: + "Disable setting the source of a reflection when documenting it.", + help_sourceLinkTemplate: + "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders.", + help_gitRevision: + "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files. Has no effect if disableSources is set.", + help_gitRemote: + "Use the specified remote for linking to GitHub/Bitbucket source files. Has no effect if disableGit or disableSources is set.", + help_disableGit: + "Assume that all can be linked to with the sourceLinkTemplate, sourceLinkTemplate must be set if this is enabled. {path} will be rooted at basePath", + help_basePath: + "Specifies the base path to be used when displaying file paths.", + help_excludeTags: + "Remove the listed block/modifier tags from doc comments.", + help_readme: + "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page.", + help_stripYamlFrontmatter: "Strip YAML frontmatter from markdown files.", + help_cname: + "Set the CNAME file text, it's useful for custom domains on GitHub Pages.", + help_sourceLinkExternal: + "Specifies that source links should be treated as external links to be opened in a new tab.", + help_githubPages: + "Generate a .nojekyll file to prevent 404 errors in GitHub Pages. Defaults to `true`.", + help_sitemapBaseUrl: + "Specify a base URL to be used in generating a sitemap.xml in our output folder. If not specified, no sitemap will be generated.", + help_gaID: + "Set the Google Analytics tracking ID and activate tracking code.", + help_hideGenerator: "Do not print the TypeDoc link at the end of the page.", + help_hideParameterTypesInTitle: + "Hides parameter types in signature titles for easier scanning.", + help_cacheBust: "Include the generation time in links to static assets.", + help_searchInComments: + "If set, the search index will also include comments. This will greatly increase the size of the search index.", + help_cleanOutputDir: + "If set, TypeDoc will remove the output directory before writing output.", + help_titleLink: + "Set the link the title in the header points to. Defaults to the documentation homepage.", + help_navigationLinks: "Defines links to be included in the header.", + help_sidebarLinks: "Defines links to be included in the sidebar.", + help_navigationLeaves: + "Branches of the navigation tree which should not be expanded.", + help_navigation: "Determines how the navigation sidebar is organized.", + help_visibilityFilters: + "Specify the default visibility for builtin filters and additional filters according to modifier tags.", + help_searchCategoryBoosts: + "Configure search to give a relevance boost to selected categories", + help_searchGroupBoosts: + 'Configure search to give a relevance boost to selected kinds (eg "class")', + help_jsDocCompatibility: + "Sets compatibility options for comment parsing that increase similarity with JSDoc comments.", + help_commentStyle: "Determines how TypeDoc searches for comments.", + help_useTsLinkResolution: + "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments.", + help_preserveLinkText: + "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name.", + help_blockTags: + "Block tags which TypeDoc should recognize when parsing comments.", + help_inlineTags: + "Inline tags which TypeDoc should recognize when parsing comments.", + help_modifierTags: + "Modifier tags which TypeDoc should recognize when parsing comments.", + help_categorizeByGroup: + "Specify whether categorization will be done at the group level.", + help_defaultCategory: + "Specify the default category for reflections without a category.", + help_categoryOrder: + "Specify the order in which categories appear. * indicates the relative order for categories not in the list.", + help_groupOrder: + "Specify the order in which groups appear. * indicates the relative order for groups not in the list.", + help_sort: "Specify the sort strategy for documented values.", + help_sortEntryPoints: + "If set, entry points will be subject to the same sorting rules as other reflections.", + help_kindSortOrder: + "Specify the sort order for reflections when 'kind' is specified.", + help_watch: "Watch files for changes and rebuild docs on change.", + help_preserveWatchOutput: + "If set, TypeDoc will not clear the screen between compilation runs.", + help_skipErrorChecking: + "Do not run TypeScript's type checking before generating docs.", + help_help: "Print this message.", + help_version: "Print TypeDoc's version.", + help_showConfig: "Print the resolved configuration and exit.", + help_plugin: + "Specify the npm plugins that should be loaded. Omit to load all installed plugins.", + help_logLevel: "Specify what level of logging should be used.", + help_treatWarningsAsErrors: + "If set, all warnings will be treated as errors.", + help_treatValidationWarningsAsErrors: + "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings.", + help_intentionallyNotExported: + "A list of types which should not produce 'referenced but not documented' warnings.", + help_requiredToBeDocumented: + "A list of reflection kinds that must be documented", + help_validation: + "Specify which validation steps TypeDoc should perform on your generated documentation.", + + // ================================================================== + // Option validation + // ================================================================== + unknown_option_0_you_may_have_meant_1: `Unknown option '{0}' You may have meant:\n\t{1}`, + option_0_must_be_between_1_and_2: "{0} must be between {1} and {2}", + option_0_must_be_equal_to_or_greater_than_1: + "{0} must be equal to or greater than {1}", + option_0_must_be_less_than_or_equal_to_1: + "{0} must be less than or equal to {1}", + option_0_must_be_one_of_1: "{0} must be one of {1}", + flag_0_is_not_valid_for_1_expected_2: + "The flag '{0}' is not valid for {1}, expected one of {2}", + expected_object_with_flag_values_for_0: + "Expected an object with flag values for {0} or true/false", + flag_values_for_0_must_be_booleans: + "Flag values for {0} must be a boolean.", + locales_must_be_an_object: + "The 'locales' option must be set to an object which resembles: { en: { theme_implements: \"Implements\" }}", + exclude_not_documented_specified_0_valid_values_are_1: `excludeNotDocumentedKinds may only specify known values, and invalid values were provided ({0}). The valid kinds are:\n{1}`, + external_symbol_link_mappings_must_be_object: + "externalSymbolLinkMappings must be a Record>", + highlight_theme_0_must_be_one_of_1: "{0} must be one of the following: {1}", + sitemap_must_start_with_http: + "sitemapBaseUrl must start with http:// or https://", + option_0_must_be_an_object: "The '{0}' option must be a non-array object.", + option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values.`, + visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`, + visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans.`, + option_0_values_must_be_numbers: "All values of {0} must be numbers", + option_0_values_must_be_array_of_tags: + "{0} must be an array of valid tag names.", + option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({0}). The valid sort strategies are:\n{1}`, + + // ReflectionKind singular translations + kind_project: "Project", + kind_module: "Module", + kind_namespace: "Namespace", + kind_enum: "Enumeration", + kind_enum_member: "Enumeration Member", + kind_variable: "Variable", + kind_function: "Function", + kind_class: "Class", + kind_interface: "Interface", + kind_constructor: "Constructor", + kind_property: "Property", + kind_method: "Method", + kind_call_signature: "Call Signature", + kind_index_signature: "Index Signature", + kind_constructor_signature: "Constructor Signature", + kind_parameter: "Parameter", + kind_type_literal: "Type Literal", + kind_type_parameter: "Type Parameter", + kind_accessor: "Accessor", + kind_get_signature: "Get Signature", + kind_set_signature: "Set Signature", + kind_type_alias: "Type Alias", + kind_reference: "Reference", + + // ReflectionKind plural translations + kind_plural_project: "Projects", + kind_plural_module: "Modules", + kind_plural_namespace: "Namespaces", + kind_plural_enum: "Enumerations", + kind_plural_enum_member: "Enumeration Members", + kind_plural_variable: "Variables", + kind_plural_function: "Functions", + kind_plural_class: "Classes", + kind_plural_interface: "Interfaces", + kind_plural_constructor: "Constructors", + kind_plural_property: "Properties", + kind_plural_method: "Methods", + kind_plural_call_signature: "Call Signatures", + kind_plural_index_signature: "Index Signatures", + kind_plural_constructor_signature: "Constructor Signatures", + kind_plural_parameter: "Parameters", + kind_plural_type_literal: "Type Literals", + kind_plural_type_parameter: "Type Parameters", + kind_plural_accessor: "Accessors", + kind_plural_get_signature: "Get Signatures", + kind_plural_set_signature: "Set Signatures", + kind_plural_type_alias: "Type Aliases", + kind_plural_reference: "References", + + // ================================================================== + // Strings that show up in the default theme + // ================================================================== + // Page headings/labels + theme_implements: "Implements", + theme_indexable: "Indexable", + theme_type_declaration: "Type declaration", + theme_index: "Index", + theme_hierarchy: "Hierarchy", + theme_hierarchy_view_full: "view full", + theme_implemented_by: "Implemented by", + theme_defined_in: "Defined in", + theme_implementation_of: "Implementation of", + theme_inherited_from: "Inherited from", + theme_overrides: "Overrides", + theme_returns: "Returns", + theme_re_exports: "Re-exports", + theme_renames_and_re_exports: "Renames and re-exports", + theme_generated_using_typedoc: "Generated using TypeDoc", // If this includes "TypeDoc", theme will insert a link at that location. + // Search + theme_preparing_search_index: "Preparing search index...", + theme_search_index_not_available: "The search index is not available", + // Right nav bar + theme_settings: "Settings", + theme_member_visibility: "Member Visibility", + theme_theme: "Theme", + theme_os: "OS", + theme_light: "Light", + theme_dark: "Dark", + theme_on_this_page: "On This Page", + + // aria-label + theme_search: "Search", + theme_menu: "Menu", + theme_permalink: "Permalink", +} as const; diff --git a/src/lib/internationalization/locales/test.cts b/src/lib/internationalization/locales/test.cts index 63e164e33..ea9352a29 100644 --- a/src/lib/internationalization/locales/test.cts +++ b/src/lib/internationalization/locales/test.cts @@ -1,8 +1,8 @@ // This should go away once we have a second language in TypeDoc to use // in unit tests. It's here for now so that we have *something* to test with. -import { buildIncompleteTranslation } from "../translatable"; +import utils = require("../locale-utils.cjs"); -export = buildIncompleteTranslation({ +export = utils.buildIncompleteTranslation({ no_entry_points_to_merge: "no_entry_points_to_merge", docs_generated_at_0: "docs_generated_at_0 {0}", }); diff --git a/src/lib/internationalization/translatable.ts b/src/lib/internationalization/translatable.ts index 16188df0c..49517dfab 100644 --- a/src/lib/internationalization/translatable.ts +++ b/src/lib/internationalization/translatable.ts @@ -1,445 +1,4 @@ -export function buildTranslation< - T extends BuiltinTranslatableStringConstraints, ->(translations: T) { - return translations; -} - -export function buildIncompleteTranslation< - T extends Partial, ->(translations: T) { - return translations; -} - -export const translatable = { - loaded_multiple_times_0: - "TypeDoc has been loaded multiple times. This is commonly caused by plugins which have their own installation of TypeDoc. The loaded paths are:\n\t{0}", - unsupported_ts_version_0: - "You are running with an unsupported TypeScript version! If TypeDoc crashes, this is why. TypeDoc supports {0}", - no_compiler_options_set: - "No compiler options set. This likely means that TypeDoc did not find your tsconfig.json. Generated documentation will probably be empty.", - - loaded_plugin_0: `Loaded plugin {0}`, - - solution_not_supported_in_watch_mode: - "The provided tsconfig file looks like a solution style tsconfig, which is not supported in watch mode.", - strategy_not_supported_in_watch_mode: - "entryPointStrategy must be set to either resolve or expand for watch mode.", - - docs_could_not_be_generated: - "Documentation could not be generated due to the errors above.", - docs_generated_at_0: "Documentation generated at {0}", - json_written_to_0: "JSON written to {0}", - - no_entry_points_for_packages: - "No entry points provided to packages mode, documentation cannot be generated.", - failed_to_find_packages: - "Failed to find any packages, ensure you have provided at least one directory as an entry point containing package.json", - nested_packages_unsupported_0: - "Project at {0} has entryPointStrategy set to packages, but nested packages are not supported.", - converting_project_at_0: "Converting project at {0}", - failed_to_convert_packages: - "Failed to convert one or more packages, result will not be merged together.", - merging_converted_projects: "Merging converted projects", - - no_entry_points_to_merge: "No entry points provided to merge.", - entrypoint_did_not_match_files_0: - "The entrypoint glob {0} did not match any files.", - failed_to_parse_json_0: `Failed to parse file at {0} as json.`, - - block_and_modifier_tags_ignored_within_readme_0: `Block and modifier tags will be ignored within the readme:\n\t{0}`, - - converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code.`, - converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value.`, - converting_0_as_class_without_construct_signatures: `{0} is being converted as a class, but does not have any construct signatures`, - - symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used.`, - comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`, - - // comments/parser.ts - multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment.`, - failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report.`, - - inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: - "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}", - at_most_one_remarks_tag_expected_in_comment_at_0: - "At most one @remarks tag is expected in a comment, ignoring all but the first in comment at {0}", - at_most_one_returns_tag_expected_in_comment_at_0: - "At most one @returns tag is expected in a comment, ignoring all but the first in comment at {0}", - at_most_one_inheritdoc_tag_expected_in_comment_at_0: - "At most one @inheritDoc tag is expected in a comment, ignoring all but the first in comment at {0}", - content_in_summary_overwritten_by_inheritdoc_in_comment_at_0: - "Content in the summary section will be overwritten by the @inheritDoc tag in comment at {0}", - content_in_remarks_block_overwritten_by_inheritdoc_in_comment_at_0: - "Content in the @remarks block will be overwritten by the @inheritDoc tag in comment at {0}", - example_tag_literal_name: - "The first line of an example tag will be taken literally as the example name, and should only contain text.", - inheritdoc_tag_properly_capitalized: - "The @inheritDoc tag should be properly capitalized.", - treating_unrecognized_tag_0_as_modifier: `Treating unrecognized tag {0} as a modifier tag.`, - unmatched_closing_brace: `Unmatched closing brace.`, - unescaped_open_brace_without_inline_tag: `Encountered an unescaped open brace without an inline tag.`, - unknown_inline_tag_0: `Encountered an unknown inline tag {0}.`, - open_brace_within_inline_tag: `Encountered an open brace within an inline tag, this is likely a mistake.`, - inline_tag_not_closed: `Inline tag is not closed.`, - - // validation - failed_to_resolve_link_to_0_in_comment_for_1: `Failed to resolve link to "{0}" in comment for {1}`, - type_0_defined_in_1_is_referenced_by_2_but_not_included_in_docs: `{0}, defined in {1}, is referenced by {2} but not included in the documentation.`, - reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation.`, - invalid_intentionally_not_exported_symbols_0: - "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}", - - // conversion plugins - not_all_search_category_boosts_used_0: `Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}`, - not_all_search_group_boosts_used_0: `Not all groups specified in searchGroupBoosts were used in the documentation. The unused groups were:\n\t{0}`, - comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category.`, - comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group.`, - label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number.`, - signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used.`, - declaration_reference_in_inheritdoc_for_0_not_fully_parsed: `Declaration reference in @inheritDoc for {0} was not fully parsed and may resolve incorrectly.`, - failed_to_find_0_to_inherit_comment_from_in_1: `Failed to find "{0}" to inherit the comment from in the comment for {1}`, - reflection_0_tried_to_copy_comment_from_1_but_source_had_no_comment: `{0} tried to copy a comment from {1} with @inheritDoc, but the source has no associated comment.`, - inheritdoc_circular_inheritance_chain_0: `@inheritDoc specifies a circular inheritance chain: {0}`, - provided_readme_at_0_could_not_be_read: `Provided README path, {0} could not be read.`, - defaulting_project_name: - 'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation".', - disable_git_set_but_not_source_link_template: `disableGit is set, but sourceLinkTemplate is not, so source links cannot be produced. Set a sourceLinkTemplate or disableSources to prevent source tracking.`, - disable_git_set_and_git_revision_used: `disableGit is set and sourceLinkTemplate contains {gitRevision}, which will be replaced with an empty string as no revision was provided.`, - git_remote_0_not_valid: `The provided git remote "{0}" was not valid. Source links will be broken.`, - - // output plugins - custom_css_file_0_does_not_exist: `Custom CSS file at {0} does not exist.`, - unsupported_highlight_language_0_not_highlighted_in_comment_for_1: `Unsupported highlight language {0} will not be highlighted in comment for {1}.`, - could_not_find_file_to_include_0: `Could not find file to include: {0}`, - could_not_find_media_file_0: `Could not find media file: {0}`, - could_not_find_includes_directory_0: - "Could not find provided includes directory: {0}", - could_not_find_media_directory_0: - "Could not find provided media directory: {0}", - - // renderer - could_not_write_0: `Could not write {0}`, - could_not_empty_output_directory_0: `Could not empty the output directory {0}`, - could_not_create_output_directory_0: `Could not create the output directory {0}`, - theme_0_is_not_defined_available_are_1: `The theme '{0}' is not defined. The available themes are: {1}`, - - // entry points - no_entry_points_provided: - "No entry points were provided, this is likely a misconfiguration.", - unable_to_find_any_entry_points: - "Unable to find any entry points. See previous warnings.", - watch_does_not_support_packages_mode: - "Watch mode does not support 'packages' style entry points.", - watch_does_not_support_merge_mode: - "Watch mode does not support 'merge' style entry points.", - entry_point_0_not_in_program: `The entry point {0} is not referenced by the 'files' or 'include' option in your tsconfig.`, - use_expand_or_glob_for_files_in_dir: `If you wanted to include files inside this directory, set --entryPointStrategy to expand or specify a glob.`, - entry_point_0_did_not_match_any_files: `The entry point glob {0} did not match any files.`, - entry_point_0_did_not_match_any_files_after_exclude: `The entry point glob {0} did not match any files after applying exclude patterns.`, - entry_point_0_did_not_exist: `Provided entry point {0} does not exist.`, - entry_point_0_did_not_match_any_packages: `The entry point glob {0} did not match any directories containing package.json.`, - file_0_not_an_object: `The file {0} is not an object.`, - - // deserialization - serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project.`, - - // options - circular_reference_extends_0: `Circular reference encountered for "extends" field of {0}`, - failed_resolve_0_to_file_in_1: `Failed to resolve {0} to a file in {1}`, - - option_0_can_only_be_specified_by_config_file: `The '{0}' option can only be specified via a config file.`, - option_0_expected_a_value_but_none_provided: `--{0} expected a value, but none was given as an argument.`, - unknown_option_0_may_have_meant_1: `Unknown option: {0}, you may have meant:\n\t{1}`, - - typedoc_key_in_0_ignored: `The 'typedoc' key in {0} was used by the legacy-packages entryPointStrategy and will be ignored.`, - typedoc_options_must_be_object_in_0: `Failed to parse the "typedocOptions" field in {0}, ensure it exists and contains an object.`, - tsconfig_file_0_does_not_exist: `The tsconfig file {0} does not exist`, - tsconfig_file_specifies_options_file: `"typedocOptions" in tsconfig file specifies an option file to read but the option file has already been read. This is likely a misconfiguration.`, - tsconfig_file_specifies_tsconfig_file: `"typedocOptions" in tsconfig file may not specify a tsconfig file to read.`, - tags_0_defined_in_typedoc_json_overwritten_by_tsdoc_json: `The {0} defined in typedoc.json will be overwritten by configuration in tsdoc.json.`, - failed_read_tsdoc_json_0: `Failed to read tsdoc.json file at {0}.`, - invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file.`, - - options_file_0_does_not_exist: `The options file {0} does not exist.`, - failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object.`, - - // plugins - invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found.`, - plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded.`, - - // option declarations help - help_options: - "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory.", - help_tsconfig: - "Specify a TypeScript config file that should be loaded. If not specified TypeDoc will look for 'tsconfig.json' in the current directory.", - help_compilerOptions: - "Selectively override the TypeScript compiler options used by TypeDoc.", - help_lang: - "Sets the language to be used in generation and in TypeDoc's messages.", - help_locales: - "Add translations for a specified locale. This option is primarily intended to be used as a stopgap while waiting for official locale support to be added to TypeDoc.", - - help_entryPoints: "The entry points of your documentation.", - help_entryPointStrategy: - "The strategy to be used to convert entry points into documentation modules.", - help_exclude: - "Define patterns to be excluded when expanding a directory that was specified as an entry point.", - help_externalPattern: - "Define patterns for files that should be considered being external.", - help_excludeExternals: - "Prevent externally resolved symbols from being documented.", - help_excludeNotDocumented: - "Prevent symbols that are not explicitly documented from appearing in the results.", - help_excludeNotDocumentedKinds: - "Specify the type of reflections that can be removed by excludeNotDocumented.", - help_excludeInternal: - "Prevent symbols that are marked with @internal from being documented.", - help_excludeCategories: - "Exclude symbols within this category from the documentation.", - help_excludePrivate: "Ignore private variables and methods.", - help_excludeProtected: "Ignore protected variables and methods.", - help_excludeReferences: - "If a symbol is exported multiple times, ignore all but the first export.", - help_externalSymbolLinkMappings: - "Define custom links for symbols not included in the documentation.", - help_media: - "Specify the location with media files that should be copied to the output directory.", - help_includes: - "Specify the location to look for included documents (use [[include:FILENAME]] in comments).", - help_out: "Specify the location the documentation should be written to.", - help_json: - "Specify the location and filename a JSON file describing the project is written to.", - help_pretty: - "Specify whether the output JSON should be formatted with tabs.", - help_emit: "Specify what TypeDoc should emit, 'docs', 'both', or 'none'.", - help_theme: "Specify the theme name to render the documentation with", - help_lightHighlightTheme: - "Specify the code highlighting theme in light mode.", - help_darkHighlightTheme: - "Specify the code highlighting theme in dark mode.", - help_customCss: "Path to a custom CSS file to for the theme to import.", - help_markedOptions: - "Specify the options passed to Marked, the Markdown parser used by TypeDoc.", - help_maxTypeConversionDepth: - "Set the maximum depth of types to be converted.", - help_name: - "Set the name of the project that will be used in the header of the template.", - help_includeVersion: "Add the package version to the project name.", - help_disableSources: - "Disable setting the source of a reflection when documenting it.", - help_sourceLinkTemplate: - "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders.", - help_gitRevision: - "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files. Has no effect if disableSources is set.", - help_gitRemote: - "Use the specified remote for linking to GitHub/Bitbucket source files. Has no effect if disableGit or disableSources is set.", - help_disableGit: - "Assume that all can be linked to with the sourceLinkTemplate, sourceLinkTemplate must be set if this is enabled. {path} will be rooted at basePath", - help_basePath: - "Specifies the base path to be used when displaying file paths.", - help_excludeTags: - "Remove the listed block/modifier tags from doc comments.", - help_readme: - "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page.", - help_stripYamlFrontmatter: "Strip YAML frontmatter from markdown files.", - help_cname: - "Set the CNAME file text, it's useful for custom domains on GitHub Pages.", - help_sourceLinkExternal: - "Specifies that source links should be treated as external links to be opened in a new tab.", - help_githubPages: - "Generate a .nojekyll file to prevent 404 errors in GitHub Pages. Defaults to `true`.", - help_sitemapBaseUrl: - "Specify a base URL to be used in generating a sitemap.xml in our output folder. If not specified, no sitemap will be generated.", - help_gaID: - "Set the Google Analytics tracking ID and activate tracking code.", - help_hideGenerator: "Do not print the TypeDoc link at the end of the page.", - help_hideParameterTypesInTitle: - "Hides parameter types in signature titles for easier scanning.", - help_cacheBust: "Include the generation time in links to static assets.", - help_searchInComments: - "If set, the search index will also include comments. This will greatly increase the size of the search index.", - help_cleanOutputDir: - "If set, TypeDoc will remove the output directory before writing output.", - help_titleLink: - "Set the link the title in the header points to. Defaults to the documentation homepage.", - help_navigationLinks: "Defines links to be included in the header.", - help_sidebarLinks: "Defines links to be included in the sidebar.", - help_navigationLeaves: - "Branches of the navigation tree which should not be expanded.", - help_navigation: "Determines how the navigation sidebar is organized.", - help_visibilityFilters: - "Specify the default visibility for builtin filters and additional filters according to modifier tags.", - help_searchCategoryBoosts: - "Configure search to give a relevance boost to selected categories", - help_searchGroupBoosts: - 'Configure search to give a relevance boost to selected kinds (eg "class")', - help_jsDocCompatibility: - "Sets compatibility options for comment parsing that increase similarity with JSDoc comments.", - help_commentStyle: "Determines how TypeDoc searches for comments.", - help_useTsLinkResolution: - "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments.", - help_preserveLinkText: - "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name.", - help_blockTags: - "Block tags which TypeDoc should recognize when parsing comments.", - help_inlineTags: - "Inline tags which TypeDoc should recognize when parsing comments.", - help_modifierTags: - "Modifier tags which TypeDoc should recognize when parsing comments.", - help_categorizeByGroup: - "Specify whether categorization will be done at the group level.", - help_defaultCategory: - "Specify the default category for reflections without a category.", - help_categoryOrder: - "Specify the order in which categories appear. * indicates the relative order for categories not in the list.", - help_groupOrder: - "Specify the order in which groups appear. * indicates the relative order for groups not in the list.", - help_sort: "Specify the sort strategy for documented values.", - help_sortEntryPoints: - "If set, entry points will be subject to the same sorting rules as other reflections.", - help_kindSortOrder: - "Specify the sort order for reflections when 'kind' is specified.", - help_watch: "Watch files for changes and rebuild docs on change.", - help_preserveWatchOutput: - "If set, TypeDoc will not clear the screen between compilation runs.", - help_skipErrorChecking: - "Do not run TypeScript's type checking before generating docs.", - help_help: "Print this message.", - help_version: "Print TypeDoc's version.", - help_showConfig: "Print the resolved configuration and exit.", - help_plugin: - "Specify the npm plugins that should be loaded. Omit to load all installed plugins.", - help_logLevel: "Specify what level of logging should be used.", - help_treatWarningsAsErrors: - "If set, all warnings will be treated as errors.", - help_treatValidationWarningsAsErrors: - "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings.", - help_intentionallyNotExported: - "A list of types which should not produce 'referenced but not documented' warnings.", - help_requiredToBeDocumented: - "A list of reflection kinds that must be documented", - help_validation: - "Specify which validation steps TypeDoc should perform on your generated documentation.", - - // ================================================================== - // Option validation - // ================================================================== - unknown_option_0_you_may_have_meant_1: `Unknown option '{0}' You may have meant:\n\t{1}`, - option_0_must_be_between_1_and_2: "{0} must be between {1} and {2}", - option_0_must_be_equal_to_or_greater_than_1: - "{0} must be equal to or greater than {1}", - option_0_must_be_less_than_or_equal_to_1: - "{0} must be less than or equal to {1}", - option_0_must_be_one_of_1: "{0} must be one of {1}", - flag_0_is_not_valid_for_1_expected_2: - "The flag '{0}' is not valid for {1}, expected one of {2}", - expected_object_with_flag_values_for_0: - "Expected an object with flag values for {0} or true/false", - flag_values_for_0_must_be_booleans: - "Flag values for {0} must be a boolean.", - locales_must_be_an_object: - "The 'locales' option must be set to an object which resembles: { en: { theme_implements: \"Implements\" }}", - exclude_not_documented_specified_0_valid_values_are_1: `excludeNotDocumentedKinds may only specify known values, and invalid values were provided ({0}). The valid kinds are:\n{1}`, - external_symbol_link_mappings_must_be_object: - "externalSymbolLinkMappings must be a Record>", - highlight_theme_0_must_be_one_of_1: "{0} must be one of the following: {1}", - sitemap_must_start_with_http: - "sitemapBaseUrl must start with http:// or https://", - option_0_must_be_an_object: "The '{0}' option must be a non-array object.", - option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values.`, - visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`, - visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans.`, - option_0_values_must_be_numbers: "All values of {0} must be numbers", - option_0_values_must_be_array_of_tags: - "{0} must be an array of valid tag names.", - option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({0}). The valid sort strategies are:\n{1}`, - - // ReflectionKind singular translations - kind_project: "Project", - kind_module: "Module", - kind_namespace: "Namespace", - kind_enum: "Enumeration", - kind_enum_member: "Enumeration Member", - kind_variable: "Variable", - kind_function: "Function", - kind_class: "Class", - kind_interface: "Interface", - kind_constructor: "Constructor", - kind_property: "Property", - kind_method: "Method", - kind_call_signature: "Call Signature", - kind_index_signature: "Index Signature", - kind_constructor_signature: "Constructor Signature", - kind_parameter: "Parameter", - kind_type_literal: "Type Literal", - kind_type_parameter: "Type Parameter", - kind_accessor: "Accessor", - kind_get_signature: "Get Signature", - kind_set_signature: "Set Signature", - kind_type_alias: "Type Alias", - kind_reference: "Reference", - - // ReflectionKind plural translations - kind_plural_project: "Projects", - kind_plural_module: "Modules", - kind_plural_namespace: "Namespaces", - kind_plural_enum: "Enumerations", - kind_plural_enum_member: "Enumeration Members", - kind_plural_variable: "Variables", - kind_plural_function: "Functions", - kind_plural_class: "Classes", - kind_plural_interface: "Interfaces", - kind_plural_constructor: "Constructors", - kind_plural_property: "Properties", - kind_plural_method: "Methods", - kind_plural_call_signature: "Call Signatures", - kind_plural_index_signature: "Index Signatures", - kind_plural_constructor_signature: "Constructor Signatures", - kind_plural_parameter: "Parameters", - kind_plural_type_literal: "Type Literals", - kind_plural_type_parameter: "Type Parameters", - kind_plural_accessor: "Accessors", - kind_plural_get_signature: "Get Signatures", - kind_plural_set_signature: "Set Signatures", - kind_plural_type_alias: "Type Aliases", - kind_plural_reference: "References", - - // ================================================================== - // Strings that show up in the default theme - // ================================================================== - // Page headings/labels - theme_implements: "Implements", - theme_indexable: "Indexable", - theme_type_declaration: "Type declaration", - theme_index: "Index", - theme_hierarchy: "Hierarchy", - theme_hierarchy_view_full: "view full", - theme_implemented_by: "Implemented by", - theme_defined_in: "Defined in", - theme_implementation_of: "Implementation of", - theme_inherited_from: "Inherited from", - theme_overrides: "Overrides", - theme_returns: "Returns", - theme_re_exports: "Re-exports", - theme_renames_and_re_exports: "Renames and re-exports", - theme_generated_using_typedoc: "Generated using TypeDoc", // If this includes "TypeDoc", theme will insert a link at that location. - // Search - theme_preparing_search_index: "Preparing search index...", - theme_search_index_not_available: "The search index is not available", - // Right nav bar - theme_settings: "Settings", - theme_member_visibility: "Member Visibility", - theme_theme: "Theme", - theme_os: "OS", - theme_light: "Light", - theme_dark: "Dark", - theme_on_this_page: "On This Page", - - // aria-label - theme_search: "Search", - theme_menu: "Menu", - theme_permalink: "Permalink", -} as const; +import translatable from "./locales/en.cjs"; export type BuiltinTranslatableStringArgs = { [K in keyof typeof translatable]: BuildTranslationArguments< diff --git a/src/lib/models/ReflectionCategory.ts b/src/lib/models/ReflectionCategory.ts index ae07a5fe5..61347d85f 100644 --- a/src/lib/models/ReflectionCategory.ts +++ b/src/lib/models/ReflectionCategory.ts @@ -1,6 +1,13 @@ -import { Comment } from "./comments"; -import type { CommentDisplayPart, DeclarationReflection } from "."; -import type { Serializer, JSONOutput, Deserializer } from "../serialization"; +import { Comment } from "./comments/index.js"; +import type { + CommentDisplayPart, + DeclarationReflection, +} from "../models/index.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../serialization/index.js"; /** * A category of reflections. diff --git a/src/lib/models/ReflectionGroup.ts b/src/lib/models/ReflectionGroup.ts index 2f56d164d..6bf8c6b6f 100644 --- a/src/lib/models/ReflectionGroup.ts +++ b/src/lib/models/ReflectionGroup.ts @@ -1,7 +1,15 @@ -import { ReflectionCategory } from "./ReflectionCategory"; -import { Comment } from "./comments"; -import type { CommentDisplayPart, DeclarationReflection, Reflection } from "."; -import type { Serializer, JSONOutput, Deserializer } from "../serialization"; +import { ReflectionCategory } from "./ReflectionCategory.js"; +import { Comment } from "./comments/index.js"; +import type { + CommentDisplayPart, + DeclarationReflection, + Reflection, +} from "../models/index.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../serialization/index.js"; /** * A group of reflections. All reflections in a group are of the same kind. diff --git a/src/lib/models/comments/comment.ts b/src/lib/models/comments/comment.ts index b3528ac12..849beff24 100644 --- a/src/lib/models/comments/comment.ts +++ b/src/lib/models/comments/comment.ts @@ -1,9 +1,13 @@ -import { assertNever, removeIf } from "../../utils"; -import type { Reflection } from "../reflections"; -import { ReflectionKind } from "../reflections/kind"; -import { ReflectionSymbolId } from "../reflections/ReflectionSymbolId"; - -import type { Serializer, Deserializer, JSONOutput } from "../../serialization"; +import { assertNever, removeIf } from "../../utils/index.js"; +import type { Reflection } from "../reflections/index.js"; +import { ReflectionKind } from "../reflections/kind.js"; +import { ReflectionSymbolId } from "../reflections/ReflectionSymbolId.js"; + +import type { + Serializer, + Deserializer, + JSONOutput, +} from "../../serialization/index.js"; /** * Represents a parsed piece of a comment. diff --git a/src/lib/models/comments/index.ts b/src/lib/models/comments/index.ts index 15dc5eeb4..299c9ea8e 100644 --- a/src/lib/models/comments/index.ts +++ b/src/lib/models/comments/index.ts @@ -1,2 +1,2 @@ -export { Comment, CommentTag } from "./comment"; -export type { CommentDisplayPart, InlineTagDisplayPart } from "./comment"; +export { Comment, CommentTag } from "./comment.js"; +export type { CommentDisplayPart, InlineTagDisplayPart } from "./comment.js"; diff --git a/src/lib/models/index.ts b/src/lib/models/index.ts index 7d31fb07d..e9ea9b028 100644 --- a/src/lib/models/index.ts +++ b/src/lib/models/index.ts @@ -1,6 +1,6 @@ -export * from "./reflections/index"; -export * from "./types"; -export * from "./comments/index"; -export * from "./sources/index"; -export * from "./ReflectionGroup"; -export * from "./ReflectionCategory"; +export * from "./reflections/index.js"; +export * from "./types.js"; +export * from "./comments/index.js"; +export * from "./sources/index.js"; +export * from "./ReflectionGroup.js"; +export * from "./ReflectionCategory.js"; diff --git a/src/lib/models/reflections/ReflectionSymbolId.ts b/src/lib/models/reflections/ReflectionSymbolId.ts index ee2728179..b6d9dc7f1 100644 --- a/src/lib/models/reflections/ReflectionSymbolId.ts +++ b/src/lib/models/reflections/ReflectionSymbolId.ts @@ -1,11 +1,11 @@ import { existsSync } from "fs"; import { isAbsolute, join, relative, resolve } from "path"; import ts from "typescript"; -import type { JSONOutput, Serializer } from "../../serialization/index"; -import { getCommonDirectory, readFile } from "../../utils/fs"; -import { normalizePath } from "../../utils/paths"; -import { getQualifiedName } from "../../utils/tsutils"; -import { optional, validate } from "../../utils/validation"; +import type { JSONOutput, Serializer } from "../../serialization/index.js"; +import { getCommonDirectory, readFile } from "../../utils/fs.js"; +import { normalizePath } from "../../utils/paths.js"; +import { getQualifiedName } from "../../utils/tsutils.js"; +import { optional, validate } from "../../utils/validation.js"; /** * See {@link ReflectionSymbolId} diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index 5f027b0ea..26398c389 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -1,12 +1,16 @@ -import { Comment } from "../comments/comment"; -import { splitUnquotedString } from "./utils"; -import type { ProjectReflection } from "./project"; -import type { NeverIfInternal } from "../../utils"; -import { ReflectionKind } from "./kind"; -import type { Serializer, Deserializer, JSONOutput } from "../../serialization"; -import type { ReflectionVariant } from "./variant"; -import type { DeclarationReflection } from "./declaration"; -import { NonEnumerable } from "../../utils/general"; +import { Comment } from "../comments/comment.js"; +import { splitUnquotedString } from "./utils.js"; +import type { ProjectReflection } from "./project.js"; +import type { NeverIfInternal } from "../../utils/index.js"; +import { ReflectionKind } from "./kind.js"; +import type { + Serializer, + Deserializer, + JSONOutput, +} from "../../serialization/index.js"; +import type { ReflectionVariant } from "./variant.js"; +import type { DeclarationReflection } from "./declaration.js"; +import { NonEnumerable } from "../../utils/general.js"; /** * Current reflection id. diff --git a/src/lib/models/reflections/container.ts b/src/lib/models/reflections/container.ts index b58a428db..f3422ba36 100644 --- a/src/lib/models/reflections/container.ts +++ b/src/lib/models/reflections/container.ts @@ -1,9 +1,17 @@ -import { Reflection, TraverseCallback, TraverseProperty } from "./abstract"; -import { ReflectionCategory } from "../ReflectionCategory"; -import { ReflectionGroup } from "../ReflectionGroup"; -import type { ReflectionKind } from "./kind"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; -import type { DeclarationReflection } from "./declaration"; +import { + Reflection, + type TraverseCallback, + TraverseProperty, +} from "./abstract.js"; +import { ReflectionCategory } from "../ReflectionCategory.js"; +import { ReflectionGroup } from "../ReflectionGroup.js"; +import type { ReflectionKind } from "./kind.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; +import type { DeclarationReflection } from "./declaration.js"; /** * @category Reflections diff --git a/src/lib/models/reflections/declaration.ts b/src/lib/models/reflections/declaration.ts index 7f8910298..2c0d1b799 100644 --- a/src/lib/models/reflections/declaration.ts +++ b/src/lib/models/reflections/declaration.ts @@ -1,14 +1,23 @@ import type * as ts from "typescript"; -import { ReferenceType, ReflectionType, Type, type SomeType } from "../types"; -import { type TraverseCallback, TraverseProperty } from "./abstract"; -import { ContainerReflection } from "./container"; -import type { SignatureReflection } from "./signature"; -import type { TypeParameterReflection } from "./type-parameter"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; -import { Comment, CommentDisplayPart } from "../comments"; -import { SourceReference } from "../sources/file"; -import { ReflectionSymbolId } from "./ReflectionSymbolId"; -import { ReflectionKind } from "./kind"; +import { + ReferenceType, + ReflectionType, + Type, + type SomeType, +} from "../types.js"; +import { type TraverseCallback, TraverseProperty } from "./abstract.js"; +import { ContainerReflection } from "./container.js"; +import type { SignatureReflection } from "./signature.js"; +import type { TypeParameterReflection } from "./type-parameter.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; +import { Comment, type CommentDisplayPart } from "../comments/index.js"; +import { SourceReference } from "../sources/file.js"; +import { ReflectionSymbolId } from "./ReflectionSymbolId.js"; +import { ReflectionKind } from "./kind.js"; /** * Stores hierarchical type data. diff --git a/src/lib/models/reflections/index.ts b/src/lib/models/reflections/index.ts index 28cce65fe..6a1d5eee1 100644 --- a/src/lib/models/reflections/index.ts +++ b/src/lib/models/reflections/index.ts @@ -3,20 +3,20 @@ export { ReflectionFlag, ReflectionFlags, TraverseProperty, -} from "./abstract"; -export type { TraverseCallback, ReflectionVisitor } from "./abstract"; -export { ContainerReflection } from "./container"; -export { DeclarationReflection, ConversionFlags } from "./declaration"; -export type { DeclarationHierarchy } from "./declaration"; -export { ReflectionKind } from "./kind"; -export { ParameterReflection } from "./parameter"; -export { ProjectReflection } from "./project"; -export { ReferenceReflection } from "./reference"; -export { SignatureReflection } from "./signature"; -export { TypeParameterReflection, VarianceModifier } from "./type-parameter"; -export { splitUnquotedString } from "./utils"; -export type { ReflectionVariant } from "./variant"; +} from "./abstract.js"; +export type { TraverseCallback, ReflectionVisitor } from "./abstract.js"; +export { ContainerReflection } from "./container.js"; +export { DeclarationReflection, ConversionFlags } from "./declaration.js"; +export type { DeclarationHierarchy } from "./declaration.js"; +export { ReflectionKind } from "./kind.js"; +export { ParameterReflection } from "./parameter.js"; +export { ProjectReflection } from "./project.js"; +export { ReferenceReflection } from "./reference.js"; +export { SignatureReflection } from "./signature.js"; +export { TypeParameterReflection, VarianceModifier } from "./type-parameter.js"; +export { splitUnquotedString } from "./utils.js"; +export type { ReflectionVariant } from "./variant.js"; export { ReflectionSymbolId, type ReflectionSymbolIdString, -} from "./ReflectionSymbolId"; +} from "./ReflectionSymbolId.js"; diff --git a/src/lib/models/reflections/kind.ts b/src/lib/models/reflections/kind.ts index 161689961..22dbcba95 100644 --- a/src/lib/models/reflections/kind.ts +++ b/src/lib/models/reflections/kind.ts @@ -1,4 +1,4 @@ -import type { EnumKeys } from "../../utils"; +import type { EnumKeys } from "../../utils/index.js"; /** * Defines the available reflection kinds. diff --git a/src/lib/models/reflections/parameter.ts b/src/lib/models/reflections/parameter.ts index 42087e19b..43b8ab0e0 100644 --- a/src/lib/models/reflections/parameter.ts +++ b/src/lib/models/reflections/parameter.ts @@ -1,8 +1,16 @@ -import type { SomeType } from ".."; -import { ReflectionType } from "../types"; -import { Reflection, TraverseCallback, TraverseProperty } from "./abstract"; -import type { SignatureReflection } from "./signature"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; +import type { SomeType } from "../index.js"; +import { ReflectionType } from "../types.js"; +import { + Reflection, + type TraverseCallback, + TraverseProperty, +} from "./abstract.js"; +import type { SignatureReflection } from "./signature.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; /** * @category Reflections diff --git a/src/lib/models/reflections/project.ts b/src/lib/models/reflections/project.ts index c4d845e02..d6319557f 100644 --- a/src/lib/models/reflections/project.ts +++ b/src/lib/models/reflections/project.ts @@ -1,19 +1,19 @@ -import { Reflection, TraverseProperty } from "./abstract"; -import { ContainerReflection } from "./container"; -import { ReferenceReflection } from "./reference"; -import type { DeclarationReflection } from "./declaration"; -import type { SignatureReflection } from "./signature"; -import type { ParameterReflection } from "./parameter"; -import { IntrinsicType } from "../types"; -import type { TypeParameterReflection } from "./type-parameter"; -import { removeIf, removeIfPresent } from "../../utils"; +import { Reflection, TraverseProperty } from "./abstract.js"; +import { ContainerReflection } from "./container.js"; +import { ReferenceReflection } from "./reference.js"; +import type { DeclarationReflection } from "./declaration.js"; +import type { SignatureReflection } from "./signature.js"; +import type { ParameterReflection } from "./parameter.js"; +import { IntrinsicType } from "../types.js"; +import type { TypeParameterReflection } from "./type-parameter.js"; +import { removeIf, removeIfPresent } from "../../utils/index.js"; import type * as ts from "typescript"; -import { ReflectionKind } from "./kind"; -import { Comment, CommentDisplayPart } from "../comments"; -import { ReflectionSymbolId } from "./ReflectionSymbolId"; -import type { Serializer } from "../../serialization/serializer"; -import type { Deserializer, JSONOutput } from "../../serialization/index"; -import { DefaultMap, StableKeyMap } from "../../utils/map"; +import { ReflectionKind } from "./kind.js"; +import { Comment, type CommentDisplayPart } from "../comments/index.js"; +import { ReflectionSymbolId } from "./ReflectionSymbolId.js"; +import type { Serializer } from "../../serialization/serializer.js"; +import type { Deserializer, JSONOutput } from "../../serialization/index.js"; +import { DefaultMap, StableKeyMap } from "../../utils/map.js"; /** * A reflection that represents the root of the project. diff --git a/src/lib/models/reflections/reference.ts b/src/lib/models/reflections/reference.ts index 8f3fdb1ee..95b98cf14 100644 --- a/src/lib/models/reflections/reference.ts +++ b/src/lib/models/reflections/reference.ts @@ -1,7 +1,11 @@ -import { DeclarationReflection } from "./declaration"; -import { ReflectionKind } from "./kind"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; -import type { Reflection } from "./abstract"; +import { DeclarationReflection } from "./declaration.js"; +import { ReflectionKind } from "./kind.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; +import type { Reflection } from "./abstract.js"; /** * Describes a reflection which does not exist at this location, but is referenced. Used for imported reflections. diff --git a/src/lib/models/reflections/signature.ts b/src/lib/models/reflections/signature.ts index ec4178c6b..6f29c1658 100644 --- a/src/lib/models/reflections/signature.ts +++ b/src/lib/models/reflections/signature.ts @@ -1,11 +1,19 @@ -import { SomeType, ReflectionType, ReferenceType } from "../types"; -import { Reflection, TraverseProperty, TraverseCallback } from "./abstract"; -import type { ParameterReflection } from "./parameter"; -import type { TypeParameterReflection } from "./type-parameter"; -import type { DeclarationReflection } from "./declaration"; -import type { ReflectionKind } from "./kind"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; -import { SourceReference } from "../sources/file"; +import { type SomeType, ReflectionType, ReferenceType } from "../types.js"; +import { + Reflection, + TraverseProperty, + type TraverseCallback, +} from "./abstract.js"; +import type { ParameterReflection } from "./parameter.js"; +import type { TypeParameterReflection } from "./type-parameter.js"; +import type { DeclarationReflection } from "./declaration.js"; +import type { ReflectionKind } from "./kind.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; +import { SourceReference } from "../sources/file.js"; /** * @category Reflections diff --git a/src/lib/models/reflections/type-parameter.ts b/src/lib/models/reflections/type-parameter.ts index ad5ab8d24..6a56e214a 100644 --- a/src/lib/models/reflections/type-parameter.ts +++ b/src/lib/models/reflections/type-parameter.ts @@ -1,9 +1,13 @@ -import type { SomeType } from "../types"; -import { Reflection, TraverseCallback } from "./abstract"; -import type { DeclarationReflection } from "./declaration"; -import { ReflectionKind } from "./kind"; -import type { Serializer, JSONOutput, Deserializer } from "../../serialization"; -import type { SignatureReflection } from "./signature"; +import type { SomeType } from "../types.js"; +import { Reflection, type TraverseCallback } from "./abstract.js"; +import type { DeclarationReflection } from "./declaration.js"; +import { ReflectionKind } from "./kind.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../../serialization/index.js"; +import type { SignatureReflection } from "./signature.js"; /** * Modifier flags for type parameters, added in TS 4.7 diff --git a/src/lib/models/reflections/variant.ts b/src/lib/models/reflections/variant.ts index 361a855db..3cecae30a 100644 --- a/src/lib/models/reflections/variant.ts +++ b/src/lib/models/reflections/variant.ts @@ -1,9 +1,9 @@ -import type { DeclarationReflection } from "./declaration"; -import type { ParameterReflection } from "./parameter"; -import type { ProjectReflection } from "./project"; -import type { ReferenceReflection } from "./reference"; -import type { SignatureReflection } from "./signature"; -import type { TypeParameterReflection } from "./type-parameter"; +import type { DeclarationReflection } from "./declaration.js"; +import type { ParameterReflection } from "./parameter.js"; +import type { ProjectReflection } from "./project.js"; +import type { ReferenceReflection } from "./reference.js"; +import type { SignatureReflection } from "./signature.js"; +import type { TypeParameterReflection } from "./type-parameter.js"; /** * A map of known {@link Reflection} concrete subclasses. diff --git a/src/lib/models/sources/file.ts b/src/lib/models/sources/file.ts index 188faef4d..51c41480d 100644 --- a/src/lib/models/sources/file.ts +++ b/src/lib/models/sources/file.ts @@ -1,5 +1,5 @@ -import type { Deserializer } from "../../serialization/deserializer"; -import type { SourceReference as JSONSourceReference } from "../../serialization/schema"; +import type { Deserializer } from "../../serialization/deserializer.js"; +import type { SourceReference as JSONSourceReference } from "../../serialization/schema.js"; /** * Represents references of reflections to their defining source files. diff --git a/src/lib/models/sources/index.ts b/src/lib/models/sources/index.ts index c6bd6dd3b..e21aaba90 100644 --- a/src/lib/models/sources/index.ts +++ b/src/lib/models/sources/index.ts @@ -1 +1 @@ -export { SourceReference } from "./file"; +export { SourceReference } from "./file.js"; diff --git a/src/lib/models/types.ts b/src/lib/models/types.ts index e42960702..31999aa08 100644 --- a/src/lib/models/types.ts +++ b/src/lib/models/types.ts @@ -1,14 +1,18 @@ -import * as ts from "typescript"; -import type { Context } from "../converter"; -import type { Reflection } from "./reflections/abstract"; -import type { DeclarationReflection } from "./reflections/declaration"; -import type { ProjectReflection } from "./reflections/project"; -import type { Serializer, JSONOutput, Deserializer } from "../serialization"; -import { getQualifiedName } from "../utils/tsutils"; -import { ReflectionSymbolId } from "./reflections/ReflectionSymbolId"; -import type { DeclarationReference } from "../converter/comments/declarationReference"; -import { findPackageForPath } from "../utils/fs"; -import { ReflectionKind } from "./reflections/kind"; +import ts from "typescript"; +import type { Context } from "../converter/index.js"; +import type { Reflection } from "./reflections/abstract.js"; +import type { DeclarationReflection } from "./reflections/declaration.js"; +import type { ProjectReflection } from "./reflections/project.js"; +import type { + Serializer, + JSONOutput, + Deserializer, +} from "../serialization/index.js"; +import { getQualifiedName } from "../utils/tsutils.js"; +import { ReflectionSymbolId } from "./reflections/ReflectionSymbolId.js"; +import type { DeclarationReference } from "../converter/comments/declarationReference.js"; +import { findPackageForPath } from "../utils/fs.js"; +import { ReflectionKind } from "./reflections/kind.js"; /** * Base class of all type definitions. diff --git a/src/lib/output/components.ts b/src/lib/output/components.ts index d69087a44..cd87399c1 100644 --- a/src/lib/output/components.ts +++ b/src/lib/output/components.ts @@ -1,12 +1,12 @@ import * as Path from "path"; -import { Component, AbstractComponent } from "../utils/component"; +import { Component, AbstractComponent } from "../utils/component.js"; import type { ProjectReflection, Reflection, -} from "../models/reflections/index"; -import type { Renderer } from "./renderer"; -import { RendererEvent, PageEvent } from "./events"; +} from "../models/reflections/index.js"; +import type { Renderer } from "./renderer.js"; +import { RendererEvent, PageEvent } from "./events.js"; export { Component }; diff --git a/src/lib/output/events.ts b/src/lib/output/events.ts index 8ab246b86..100501c5a 100644 --- a/src/lib/output/events.ts +++ b/src/lib/output/events.ts @@ -1,13 +1,13 @@ import * as Path from "path"; -import { Event } from "../utils/events"; -import type { ProjectReflection } from "../models/reflections/project"; -import type { RenderTemplate, UrlMapping } from "./models/UrlMapping"; +import { Event } from "../utils/events.js"; +import type { ProjectReflection } from "../models/reflections/project.js"; +import type { RenderTemplate, UrlMapping } from "./models/UrlMapping.js"; import type { DeclarationReflection, Reflection, ReflectionKind, -} from "../models"; +} from "../models/index.js"; /** * An event emitted by the {@link Renderer} class at the very beginning and diff --git a/src/lib/output/index.ts b/src/lib/output/index.ts index 9e63faa68..54758df23 100644 --- a/src/lib/output/index.ts +++ b/src/lib/output/index.ts @@ -1,11 +1,18 @@ -export { PageEvent, RendererEvent, MarkdownEvent, IndexEvent } from "./events"; -export { UrlMapping } from "./models/UrlMapping"; -export type { RenderTemplate } from "./models/UrlMapping"; -export { Renderer } from "./renderer"; -export type { RendererHooks } from "./renderer"; -export { Theme } from "./theme"; +export { + PageEvent, + RendererEvent, + MarkdownEvent, + IndexEvent, +} from "./events.js"; +export { UrlMapping } from "./models/UrlMapping.js"; +export type { RenderTemplate } from "./models/UrlMapping.js"; +export { Renderer } from "./renderer.js"; +export type { RendererHooks } from "./renderer.js"; +export { Theme } from "./theme.js"; export { DefaultTheme, type NavigationElement, -} from "./themes/default/DefaultTheme"; -export { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext"; +} from "./themes/default/DefaultTheme.js"; +export { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext.js"; + +import "./plugins/index.js" diff --git a/src/lib/output/models/UrlMapping.ts b/src/lib/output/models/UrlMapping.ts index 3d75b152c..f3af5f4e3 100644 --- a/src/lib/output/models/UrlMapping.ts +++ b/src/lib/output/models/UrlMapping.ts @@ -1,5 +1,5 @@ -import type { JSX } from "../../utils"; -import type { PageEvent } from "../events"; +import type { JSX } from "../../utils/index.js"; +import type { PageEvent } from "../events.js"; export class UrlMapping { url: string; diff --git a/src/lib/output/plugins/AssetsPlugin.ts b/src/lib/output/plugins/AssetsPlugin.ts index 531b55ea9..7ec891bbb 100644 --- a/src/lib/output/plugins/AssetsPlugin.ts +++ b/src/lib/output/plugins/AssetsPlugin.ts @@ -1,11 +1,12 @@ -import { Component, RendererComponent } from "../components"; -import { RendererEvent } from "../events"; -import { copySync, writeFileSync } from "../../utils/fs"; -import { DefaultTheme } from "../themes/default/DefaultTheme"; -import { getStyles } from "../../utils/highlighter"; -import { Option } from "../../utils"; +import { Component, RendererComponent } from "../components.js"; +import { RendererEvent } from "../events.js"; +import { copySync, writeFileSync } from "../../utils/fs.js"; +import { DefaultTheme } from "../themes/default/DefaultTheme.js"; +import { getStyles } from "../../utils/highlighter.js"; +import { Option } from "../../utils/index.js"; import { existsSync } from "fs"; import { join } from "path"; +import { fileURLToPath } from "url"; /** * A plugin that copies the subdirectory ´assets´ from the current themes @@ -49,7 +50,10 @@ export class AssetsPlugin extends RendererComponent { */ private onRenderEnd(event: RendererEvent) { if (this.owner.theme instanceof DefaultTheme) { - const src = join(__dirname, "..", "..", "..", "..", "static"); + const src = join( + fileURLToPath(import.meta.url), + "../../../../../static", + ); const dest = join(event.outputDirectory, "assets"); copySync(src, dest); diff --git a/src/lib/output/plugins/IconsPlugin.tsx b/src/lib/output/plugins/IconsPlugin.tsx index 93fe66674..f3e3ae8d1 100644 --- a/src/lib/output/plugins/IconsPlugin.tsx +++ b/src/lib/output/plugins/IconsPlugin.tsx @@ -1,9 +1,9 @@ -import { Component, RendererComponent } from "../components"; -import { RendererEvent } from "../events"; -import { writeFile } from "../../utils/fs"; -import { DefaultTheme } from "../themes/default/DefaultTheme"; +import { Component, RendererComponent } from "../components.js"; +import { RendererEvent } from "../events.js"; +import { writeFile } from "../../utils/fs.js"; +import { DefaultTheme } from "../themes/default/DefaultTheme.js"; import { join } from "path"; -import { JSX, renderElement } from "../../utils"; +import { JSX, renderElement } from "../../utils/index.js"; /** * Plugin which is responsible for creating an icons.js file that embeds the icon SVGs diff --git a/src/lib/output/plugins/JavascriptIndexPlugin.ts b/src/lib/output/plugins/JavascriptIndexPlugin.ts index 027dc3ea2..b8468b19d 100644 --- a/src/lib/output/plugins/JavascriptIndexPlugin.ts +++ b/src/lib/output/plugins/JavascriptIndexPlugin.ts @@ -1,15 +1,15 @@ import * as Path from "path"; -import { Builder, trimmer } from "lunr"; +import lunr from "lunr"; import { Comment, DeclarationReflection, ProjectReflection, -} from "../../models"; -import { Component, RendererComponent } from "../components"; -import { IndexEvent, RendererEvent } from "../events"; -import { Option, writeFile } from "../../utils"; -import { DefaultTheme } from "../themes/default/DefaultTheme"; +} from "../../models/index.js"; +import { Component, RendererComponent } from "../components.js"; +import { IndexEvent, RendererEvent } from "../events.js"; +import { Option, writeFile } from "../../utils/index.js"; +import { DefaultTheme } from "../themes/default/DefaultTheme.js"; import { gzip } from "zlib"; import { promisify } from "util"; @@ -88,8 +88,8 @@ export class JavascriptIndexPlugin extends RendererComponent { return; } - const builder = new Builder(); - builder.pipeline.add(trimmer); + const builder = new lunr.Builder(); + builder.pipeline.add(lunr.trimmer); builder.ref("id"); for (const [key, boost] of Object.entries( diff --git a/src/lib/output/plugins/NavigationPlugin.ts b/src/lib/output/plugins/NavigationPlugin.ts index 595110da0..a7d856815 100644 --- a/src/lib/output/plugins/NavigationPlugin.ts +++ b/src/lib/output/plugins/NavigationPlugin.ts @@ -1,8 +1,8 @@ import * as Path from "path"; -import { Component, RendererComponent } from "../components"; -import { RendererEvent } from "../events"; -import { writeFile } from "../../utils"; -import { DefaultTheme } from "../themes/default/DefaultTheme"; +import { Component, RendererComponent } from "../components.js"; +import { RendererEvent } from "../events.js"; +import { writeFile } from "../../utils/index.js"; +import { DefaultTheme } from "../themes/default/DefaultTheme.js"; import { gzip } from "zlib"; import { promisify } from "util"; diff --git a/src/lib/output/plugins/SitemapPlugin.ts b/src/lib/output/plugins/SitemapPlugin.ts index dff37af31..d68b19401 100644 --- a/src/lib/output/plugins/SitemapPlugin.ts +++ b/src/lib/output/plugins/SitemapPlugin.ts @@ -1,9 +1,9 @@ import Path from "path"; -import { Component, RendererComponent } from "../components"; -import { RendererEvent } from "../events"; -import { DefaultTheme } from "../themes/default/DefaultTheme"; -import { Option, writeFile } from "../../utils"; -import { escapeHtml } from "../../utils/html"; +import { Component, RendererComponent } from "../components.js"; +import { RendererEvent } from "../events.js"; +import { DefaultTheme } from "../themes/default/DefaultTheme.js"; +import { Option, writeFile } from "../../utils/index.js"; +import html from "../../utils/html.cjs"; @Component({ name: "sitemap" }) export class SitemapPlugin extends RendererComponent { @@ -73,13 +73,13 @@ function stringifyXml(xml: XmlElementData, indent = 0) { const parts = ["\t".repeat(indent), "<", xml.tag]; for (const [key, val] of Object.entries(xml.attr || {})) { - parts.push(" ", key, '="', escapeHtml(val), '"'); + parts.push(" ", key, '="', html.escapeHtml(val), '"'); } parts.push(">"); if (typeof xml.children === "string") { - parts.push(escapeHtml(xml.children)); + parts.push(html.escapeHtml(xml.children)); } else { for (const child of xml.children) { parts.push("\n"); diff --git a/src/lib/output/plugins/index.ts b/src/lib/output/plugins/index.ts index b2435aaaa..72a0d2e15 100644 --- a/src/lib/output/plugins/index.ts +++ b/src/lib/output/plugins/index.ts @@ -1,6 +1,6 @@ -export { MarkedPlugin } from "../themes/MarkedPlugin"; -export { AssetsPlugin } from "./AssetsPlugin"; -export { IconsPlugin } from "./IconsPlugin"; -export { JavascriptIndexPlugin } from "./JavascriptIndexPlugin"; -export { NavigationPlugin } from "./NavigationPlugin"; -export { SitemapPlugin } from "./SitemapPlugin"; +export { MarkedPlugin } from "../themes/MarkedPlugin.js"; +export { AssetsPlugin } from "./AssetsPlugin.js"; +export { IconsPlugin } from "./IconsPlugin.js"; +export { JavascriptIndexPlugin } from "./JavascriptIndexPlugin.js"; +export { NavigationPlugin } from "./NavigationPlugin.js"; +export { SitemapPlugin } from "./SitemapPlugin.js"; diff --git a/src/lib/output/renderer.ts b/src/lib/output/renderer.ts index 3f8b65d6d..5c2e927bb 100644 --- a/src/lib/output/renderer.ts +++ b/src/lib/output/renderer.ts @@ -9,23 +9,23 @@ import * as fs from "fs"; import * as path from "path"; -import type { Application } from "../application"; -import type { Theme } from "./theme"; -import { RendererEvent, PageEvent, IndexEvent } from "./events"; -import type { ProjectReflection } from "../models/reflections/project"; -import type { RenderTemplate } from "./models/UrlMapping"; -import { writeFileSync } from "../utils/fs"; -import { DefaultTheme } from "./themes/default/DefaultTheme"; -import { RendererComponent } from "./components"; -import { Component, ChildableComponent } from "../utils/component"; -import { Option, EventHooks } from "../utils"; -import { loadHighlighter } from "../utils/highlighter"; +import type { Application } from "../application.js"; +import type { Theme } from "./theme.js"; +import { RendererEvent, PageEvent, IndexEvent } from "./events.js"; +import type { ProjectReflection } from "../models/reflections/project.js"; +import type { RenderTemplate } from "./models/UrlMapping.js"; +import { writeFileSync } from "../utils/fs.js"; +import { DefaultTheme } from "./themes/default/DefaultTheme.js"; +import { RendererComponent } from "./components.js"; +import { Component, ChildableComponent } from "../utils/component.js"; +import { Option, EventHooks } from "../utils/index.js"; +import { loadHighlighter } from "../utils/highlighter.js"; import type { Theme as ShikiTheme } from "shiki"; -import { Reflection } from "../models"; -import type { JsxElement } from "../utils/jsx.elements"; -import type { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext"; -import { validateStateIsClean } from "./themes/default/partials/type"; -import { setRenderSettings } from "../utils/jsx"; +import { Reflection } from "../models/index.js"; +import type { JsxElement } from "../utils/jsx.elements.js"; +import type { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext.js"; +import { validateStateIsClean } from "./themes/default/partials/type.js"; +import { setRenderSettings } from "../utils/jsx.js"; /** * Describes the hooks available to inject output in the default theme. @@ -419,4 +419,4 @@ export class Renderer extends ChildableComponent< // HACK: THIS HAS TO STAY DOWN HERE // if you try to move it up to the top of the file, then you'll run into stuff being used before it has been defined. -import "./plugins"; +await import("./plugins/index.js"); diff --git a/src/lib/output/theme.ts b/src/lib/output/theme.ts index 1f9324512..73b1ddc8c 100644 --- a/src/lib/output/theme.ts +++ b/src/lib/output/theme.ts @@ -1,10 +1,10 @@ -import type { Renderer } from "./renderer"; -import type { ProjectReflection } from "../models/reflections/project"; -import type { RenderTemplate, UrlMapping } from "./models/UrlMapping"; -import { RendererComponent } from "./components"; -import { Component } from "../utils/component"; -import type { PageEvent } from "./events"; -import type { Reflection } from "../models"; +import type { Renderer } from "./renderer.js"; +import type { ProjectReflection } from "../models/reflections/project.js"; +import type { RenderTemplate, UrlMapping } from "./models/UrlMapping.js"; +import { RendererComponent } from "./components.js"; +import { Component } from "../utils/component.js"; +import type { PageEvent } from "./events.js"; +import type { Reflection } from "../models/index.js"; /** * Base class of all themes. diff --git a/src/lib/output/themes/MarkedPlugin.tsx b/src/lib/output/themes/MarkedPlugin.tsx index 1330ac4e9..9b6c749ea 100644 --- a/src/lib/output/themes/MarkedPlugin.tsx +++ b/src/lib/output/themes/MarkedPlugin.tsx @@ -2,12 +2,13 @@ import * as fs from "fs"; import * as Path from "path"; import * as Marked from "marked"; -import { Component, ContextAwareRendererComponent } from "../components"; -import { RendererEvent, MarkdownEvent, PageEvent } from "../events"; -import { Option, readFile, copySync, isFile, JSX, renderElement } from "../../utils"; -import { highlight, isSupportedLanguage } from "../../utils/highlighter"; +import { Component, ContextAwareRendererComponent } from "../components.js"; +import { RendererEvent, MarkdownEvent, PageEvent } from "../events.js"; +import { Option, readFile, copySync, isFile, JSX, renderElement } from "../../utils/index.js"; +import { highlight, isSupportedLanguage } from "../../utils/highlighter.js"; import type { Theme } from "shiki"; -import { escapeHtml, getTextContent } from "../../utils/html"; +import html from "../../utils/html.cjs"; +const { escapeHtml, getTextContent } = html; /** * Implements markdown and relativeURL helpers for templates. @@ -56,7 +57,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent { } /** - * Highlight the syntax of the given text using HighlightJS. + * Highlight the syntax of the given text using Shiki. * * @param text The text that should be highlighted. * @param lang The language that should be used to highlight the string. diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index f1ba239be..8aac4d4fb 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -1,5 +1,5 @@ -import { Theme } from "../../theme"; -import type { Renderer } from "../../renderer"; +import { Theme } from "../../theme.js"; +import type { Renderer } from "../../renderer.js"; import { Reflection, ReflectionKind, @@ -10,14 +10,14 @@ import { ReflectionCategory, ReflectionGroup, TypeParameterReflection, -} from "../../../models"; -import { RenderTemplate, UrlMapping } from "../../models/UrlMapping"; -import type { PageEvent } from "../../events"; -import type { MarkedPlugin } from "../../plugins"; -import { DefaultThemeRenderContext } from "./DefaultThemeRenderContext"; -import { JSX } from "../../../utils"; -import { classNames, getDisplayName, getHierarchyRoots, toStyleClass } from "../lib"; -import { icons } from "./partials/icon"; +} from "../../../models/index.js"; +import { type RenderTemplate, UrlMapping } from "../../models/UrlMapping.js"; +import type { PageEvent } from "../../events.js"; +import type { MarkedPlugin } from "../../plugins/index.js"; +import { DefaultThemeRenderContext } from "./DefaultThemeRenderContext.js"; +import { JSX } from "../../../utils/index.js"; +import { classNames, getDisplayName, getHierarchyRoots, toStyleClass } from "../lib.js"; +import { icons } from "./partials/icon.js"; /** * Defines a mapping of a {@link Models.Kind} to a template file. diff --git a/src/lib/output/themes/default/DefaultThemeRenderContext.ts b/src/lib/output/themes/default/DefaultThemeRenderContext.ts index 7febb51d8..9657f4f8f 100644 --- a/src/lib/output/themes/default/DefaultThemeRenderContext.ts +++ b/src/lib/output/themes/default/DefaultThemeRenderContext.ts @@ -1,39 +1,39 @@ -import type { PageEvent, RendererHooks } from "../.."; +import type { PageEvent, RendererHooks } from "../../index.js"; import type { Internationalization, TranslationProxy, -} from "../../../internationalization/internationalization"; +} from "../../../internationalization/internationalization.js"; import { Comment, - CommentDisplayPart, + type CommentDisplayPart, DeclarationReflection, Reflection, -} from "../../../models"; -import { JSX, NeverIfInternal, Options } from "../../../utils"; -import type { DefaultTheme } from "./DefaultTheme"; -import { defaultLayout } from "./layouts/default"; -import { index } from "./partials"; -import { analytics } from "./partials/analytics"; -import { breadcrumb } from "./partials/breadcrumb"; +} from "../../../models/index.js"; +import { JSX, type NeverIfInternal, Options } from "../../../utils/index.js"; +import type { DefaultTheme } from "./DefaultTheme.js"; +import { defaultLayout } from "./layouts/default.js"; +import { index } from "./partials/index.js"; +import { analytics } from "./partials/analytics.js"; +import { breadcrumb } from "./partials/breadcrumb.js"; import { commentSummary, commentTags, reflectionFlags, -} from "./partials/comment"; -import { footer } from "./partials/footer"; -import { header } from "./partials/header"; -import { hierarchy } from "./partials/hierarchy"; -import { buildRefIcons, icons } from "./partials/icon"; -import { member } from "./partials/member"; -import { memberDeclaration } from "./partials/member.declaration"; -import { memberGetterSetter } from "./partials/member.getterSetter"; -import { memberReference } from "./partials/member.reference"; -import { memberSignatureBody } from "./partials/member.signature.body"; -import { memberSignatureTitle } from "./partials/member.signature.title"; -import { memberSignatures } from "./partials/member.signatures"; -import { memberSources } from "./partials/member.sources"; -import { members } from "./partials/members"; -import { membersGroup } from "./partials/members.group"; +} from "./partials/comment.js"; +import { footer } from "./partials/footer.js"; +import { header } from "./partials/header.js"; +import { hierarchy } from "./partials/hierarchy.js"; +import { buildRefIcons, icons } from "./partials/icon.js"; +import { member } from "./partials/member.js"; +import { memberDeclaration } from "./partials/member.declaration.js"; +import { memberGetterSetter } from "./partials/member.getterSetter.js"; +import { memberReference } from "./partials/member.reference.js"; +import { memberSignatureBody } from "./partials/member.signature.body.js"; +import { memberSignatureTitle } from "./partials/member.signature.title.js"; +import { memberSignatures } from "./partials/member.signatures.js"; +import { memberSources } from "./partials/member.sources.js"; +import { members } from "./partials/members.js"; +import { membersGroup } from "./partials/members.group.js"; import { sidebar, pageSidebar, @@ -41,16 +41,16 @@ import { pageNavigation, settings, sidebarLinks, -} from "./partials/navigation"; -import { parameter } from "./partials/parameter"; -import { reflectionPreview } from "./partials/reflectionPreview"; -import { toolbar } from "./partials/toolbar"; -import { type } from "./partials/type"; -import { typeAndParent } from "./partials/typeAndParent"; -import { typeParameters } from "./partials/typeParameters"; -import { indexTemplate } from "./templates"; -import { hierarchyTemplate } from "./templates/hierarchy"; -import { reflectionTemplate } from "./templates/reflection"; +} from "./partials/navigation.js"; +import { parameter } from "./partials/parameter.js"; +import { reflectionPreview } from "./partials/reflectionPreview.js"; +import { toolbar } from "./partials/toolbar.js"; +import { type } from "./partials/type.js"; +import { typeAndParent } from "./partials/typeAndParent.js"; +import { typeParameters } from "./partials/typeParameters.js"; +import { indexTemplate } from "./templates/index.js"; +import { hierarchyTemplate } from "./templates/hierarchy.js"; +import { reflectionTemplate } from "./templates/reflection.js"; function bind(fn: (f: F, ...a: L) => R, first: F) { return (...r: L) => fn(first, ...r); diff --git a/src/lib/output/themes/default/assets/bootstrap.ts b/src/lib/output/themes/default/assets/bootstrap.ts index 5184eb086..91f794521 100644 --- a/src/lib/output/themes/default/assets/bootstrap.ts +++ b/src/lib/output/themes/default/assets/bootstrap.ts @@ -1,10 +1,10 @@ -import { Application, registerComponent } from "./typedoc/Application"; -import { initSearch } from "./typedoc/components/Search"; -import { Toggle } from "./typedoc/components/Toggle"; -import { Filter } from "./typedoc/components/Filter"; -import { Accordion } from "./typedoc/components/Accordion"; -import { initTheme } from "./typedoc/Theme"; -import { initNav } from "./typedoc/Navigation"; +import { Application, registerComponent } from "./typedoc/Application.js"; +import { initSearch } from "./typedoc/components/Search.js"; +import { Toggle } from "./typedoc/components/Toggle.js"; +import { Filter } from "./typedoc/components/Filter.js"; +import { Accordion } from "./typedoc/components/Accordion.js"; +import { initTheme } from "./typedoc/Theme.js"; +import { initNav } from "./typedoc/Navigation.js"; registerComponent(Toggle, "a[data-toggle]"); registerComponent(Accordion, ".tsd-index-accordion"); diff --git a/src/lib/output/themes/default/assets/typedoc/Application.ts b/src/lib/output/themes/default/assets/typedoc/Application.ts index 4d1e4a1d8..e28cbb29e 100644 --- a/src/lib/output/themes/default/assets/typedoc/Application.ts +++ b/src/lib/output/themes/default/assets/typedoc/Application.ts @@ -1,4 +1,4 @@ -import type { IComponentOptions } from "./Component"; +import type { IComponentOptions } from "./Component.js"; /** * Component definition. diff --git a/src/lib/output/themes/default/assets/typedoc/Component.ts b/src/lib/output/themes/default/assets/typedoc/Component.ts index aec1672f5..b8238bfb2 100644 --- a/src/lib/output/themes/default/assets/typedoc/Component.ts +++ b/src/lib/output/themes/default/assets/typedoc/Component.ts @@ -1,4 +1,4 @@ -import { Application } from "./Application"; +import { Application } from "./Application.js"; export interface IComponentOptions { app: Application; diff --git a/src/lib/output/themes/default/assets/typedoc/Theme.ts b/src/lib/output/themes/default/assets/typedoc/Theme.ts index 270a1818a..e320b6f55 100644 --- a/src/lib/output/themes/default/assets/typedoc/Theme.ts +++ b/src/lib/output/themes/default/assets/typedoc/Theme.ts @@ -1,4 +1,4 @@ -import { storage } from "./utils/storage"; +import { storage } from "./utils/storage.js"; type ThemeChoice = "os" | "light" | "dark"; diff --git a/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts b/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts index ed8df8b7e..815fd026c 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts @@ -1,5 +1,5 @@ -import { Component, IComponentOptions } from "../Component"; -import { storage } from "../utils/storage"; +import { Component, IComponentOptions } from "../Component.js"; +import { storage } from "../utils/storage.js"; /** * Handles accordion dropdown behavior. diff --git a/src/lib/output/themes/default/assets/typedoc/components/Filter.ts b/src/lib/output/themes/default/assets/typedoc/components/Filter.ts index cfda54cc1..f4874a2b4 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Filter.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Filter.ts @@ -1,5 +1,5 @@ -import { Component, IComponentOptions } from "../Component"; -import { storage } from "../utils/storage"; +import { Component, IComponentOptions } from "../Component.js"; +import { storage } from "../utils/storage.js"; const style = document.head.appendChild(document.createElement("style")); style.dataset.for = "filters"; diff --git a/src/lib/output/themes/default/assets/typedoc/components/Search.ts b/src/lib/output/themes/default/assets/typedoc/components/Search.ts index 9e7f282fb..1c7194a5c 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Search.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Search.ts @@ -1,4 +1,4 @@ -import { debounce } from "../utils/debounce"; +import { debounce } from "../utils/debounce.js"; import { Index } from "lunr"; /** diff --git a/src/lib/output/themes/default/assets/typedoc/components/Toggle.ts b/src/lib/output/themes/default/assets/typedoc/components/Toggle.ts index 8f8d57d7d..4d479215b 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Toggle.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Toggle.ts @@ -1,5 +1,5 @@ -import { Component, IComponentOptions } from "../Component"; -import { hasPointerMoved, pointerDown, pointerUp } from "../utils/pointer"; +import { Component, IComponentOptions } from "../Component.js"; +import { hasPointerMoved, pointerDown, pointerUp } from "../utils/pointer.js"; export class Toggle extends Component { active?: boolean; diff --git a/src/lib/output/themes/default/layouts/default.tsx b/src/lib/output/themes/default/layouts/default.tsx index a2fd109cc..556ab4c33 100644 --- a/src/lib/output/themes/default/layouts/default.tsx +++ b/src/lib/output/themes/default/layouts/default.tsx @@ -1,9 +1,9 @@ -import type { RenderTemplate } from "../../.."; -import type { Reflection } from "../../../../models"; -import { JSX, Raw } from "../../../../utils"; -import type { PageEvent } from "../../../events"; -import { getDisplayName } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import type { RenderTemplate } from "../../../index.js"; +import type { Reflection } from "../../../../models/index.js"; +import { JSX, Raw } from "../../../../utils/index.js"; +import type { PageEvent } from "../../../events.js"; +import { getDisplayName } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export const defaultLayout = ( context: DefaultThemeRenderContext, diff --git a/src/lib/output/themes/default/partials/analytics.tsx b/src/lib/output/themes/default/partials/analytics.tsx index afcf8fbbd..76d2bda96 100644 --- a/src/lib/output/themes/default/partials/analytics.tsx +++ b/src/lib/output/themes/default/partials/analytics.tsx @@ -1,5 +1,5 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; export function analytics(context: DefaultThemeRenderContext) { const gaID = context.options.getValue("gaID"); diff --git a/src/lib/output/themes/default/partials/anchor-icon.tsx b/src/lib/output/themes/default/partials/anchor-icon.tsx index 72a546925..d6ff3fed0 100644 --- a/src/lib/output/themes/default/partials/anchor-icon.tsx +++ b/src/lib/output/themes/default/partials/anchor-icon.tsx @@ -1,5 +1,5 @@ -import { JSX } from "../../../../utils"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import { JSX } from "../../../../utils/index.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export function anchorIcon(context: DefaultThemeRenderContext, anchor: string | undefined) { if (!anchor) return <>; diff --git a/src/lib/output/themes/default/partials/breadcrumb.tsx b/src/lib/output/themes/default/partials/breadcrumb.tsx index 00a37e7d5..42130e568 100644 --- a/src/lib/output/themes/default/partials/breadcrumb.tsx +++ b/src/lib/output/themes/default/partials/breadcrumb.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { Reflection } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { Reflection } from "../../../../models/index.js"; export const breadcrumb = (context: DefaultThemeRenderContext, props: Reflection): JSX.Element | undefined => props.parent ? ( diff --git a/src/lib/output/themes/default/partials/comment.tsx b/src/lib/output/themes/default/partials/comment.tsx index 768b70469..d38b6c0c8 100644 --- a/src/lib/output/themes/default/partials/comment.tsx +++ b/src/lib/output/themes/default/partials/comment.tsx @@ -1,7 +1,7 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX, Raw } from "../../../../utils"; -import { Reflection, ReflectionKind } from "../../../../models"; -import { camelToTitleCase } from "../../lib"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX, Raw } from "../../../../utils/index.js"; +import { Reflection, ReflectionKind } from "../../../../models/index.js"; +import { camelToTitleCase } from "../../lib.js"; // Note: Comment modifiers are handled in `renderFlags` diff --git a/src/lib/output/themes/default/partials/footer.tsx b/src/lib/output/themes/default/partials/footer.tsx index 0be9a80c7..58a19d169 100644 --- a/src/lib/output/themes/default/partials/footer.tsx +++ b/src/lib/output/themes/default/partials/footer.tsx @@ -1,5 +1,5 @@ -import { JSX } from "../../../../utils"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import { JSX } from "../../../../utils/index.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export function footer(context: DefaultThemeRenderContext) { const hideGenerator = context.options.getValue("hideGenerator"); diff --git a/src/lib/output/themes/default/partials/header.tsx b/src/lib/output/themes/default/partials/header.tsx index 31fe3d21a..3c8c55000 100644 --- a/src/lib/output/themes/default/partials/header.tsx +++ b/src/lib/output/themes/default/partials/header.tsx @@ -1,8 +1,8 @@ -import { classNames, getDisplayName, hasTypeParameters, join } from "../../lib"; -import { JSX } from "../../../../utils"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { PageEvent } from "../../../events"; -import { Reflection, ReflectionKind } from "../../../../models"; +import { classNames, getDisplayName, hasTypeParameters, join } from "../../lib.js"; +import { JSX } from "../../../../utils/index.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { PageEvent } from "../../../events.js"; +import { Reflection, ReflectionKind } from "../../../../models/index.js"; export const header = (context: DefaultThemeRenderContext, props: PageEvent) => { const HeadingLevel = props.model.isProject() ? "h2" : "h1"; diff --git a/src/lib/output/themes/default/partials/hierarchy.tsx b/src/lib/output/themes/default/partials/hierarchy.tsx index 6c01ffe95..0a545d8d1 100644 --- a/src/lib/output/themes/default/partials/hierarchy.tsx +++ b/src/lib/output/themes/default/partials/hierarchy.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { DeclarationHierarchy, Type } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { DeclarationHierarchy, Type } from "../../../../models/index.js"; const isLinkedReferenceType = (type: Type) => type.visit({ diff --git a/src/lib/output/themes/default/partials/icon.tsx b/src/lib/output/themes/default/partials/icon.tsx index c899cf5cb..548e24dff 100644 --- a/src/lib/output/themes/default/partials/icon.tsx +++ b/src/lib/output/themes/default/partials/icon.tsx @@ -1,7 +1,7 @@ import assert from "assert"; -import { ReflectionKind } from "../../../../models"; -import { JSX } from "../../../../utils"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import { ReflectionKind } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; const kindIcon = (letterPath: JSX.Element, color: string, circular = false) => ( diff --git a/src/lib/output/themes/default/partials/index.tsx b/src/lib/output/themes/default/partials/index.tsx index 6da2d66da..0265ee418 100644 --- a/src/lib/output/themes/default/partials/index.tsx +++ b/src/lib/output/themes/default/partials/index.tsx @@ -1,7 +1,7 @@ -import { classNames, renderName } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX, Raw } from "../../../../utils"; -import type { ContainerReflection, ReflectionCategory, ReflectionGroup } from "../../../../models"; +import { classNames, renderName } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX, Raw } from "../../../../utils/index.js"; +import type { ContainerReflection, ReflectionCategory, ReflectionGroup } from "../../../../models/index.js"; function renderCategory( { urlTo, icons, getReflectionClasses, markdown }: DefaultThemeRenderContext, diff --git a/src/lib/output/themes/default/partials/member.declaration.tsx b/src/lib/output/themes/default/partials/member.declaration.tsx index dc35a62d5..1c9296930 100644 --- a/src/lib/output/themes/default/partials/member.declaration.tsx +++ b/src/lib/output/themes/default/partials/member.declaration.tsx @@ -1,7 +1,7 @@ -import type { DeclarationReflection, ReflectionType } from "../../../../models"; -import { JSX } from "../../../../utils"; -import { getKindClass, hasTypeParameters, renderTypeParametersSignature, wbr } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import type { DeclarationReflection, ReflectionType } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import { getKindClass, hasTypeParameters, renderTypeParametersSignature, wbr } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection) { function renderTypeDeclaration(type: ReflectionType) { diff --git a/src/lib/output/themes/default/partials/member.getterSetter.tsx b/src/lib/output/themes/default/partials/member.getterSetter.tsx index f02aa4bbc..7825eb62e 100644 --- a/src/lib/output/themes/default/partials/member.getterSetter.tsx +++ b/src/lib/output/themes/default/partials/member.getterSetter.tsx @@ -1,7 +1,7 @@ -import type { DeclarationReflection } from "../../../../models"; -import { JSX } from "../../../../utils"; -import { classNames } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import type { DeclarationReflection } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import { classNames } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export const memberGetterSetter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <> diff --git a/src/lib/output/themes/default/partials/member.reference.tsx b/src/lib/output/themes/default/partials/member.reference.tsx index 709ec1388..abc1e5cd0 100644 --- a/src/lib/output/themes/default/partials/member.reference.tsx +++ b/src/lib/output/themes/default/partials/member.reference.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { ReferenceReflection } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { ReferenceReflection } from "../../../../models/index.js"; export const memberReference = ({ urlTo, i18n }: DefaultThemeRenderContext, props: ReferenceReflection) => { const referenced = props.tryGetTargetReflectionDeep(); diff --git a/src/lib/output/themes/default/partials/member.signature.body.tsx b/src/lib/output/themes/default/partials/member.signature.body.tsx index 4ddcf9254..a20494903 100644 --- a/src/lib/output/themes/default/partials/member.signature.body.tsx +++ b/src/lib/output/themes/default/partials/member.signature.body.tsx @@ -1,7 +1,7 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX, Raw } from "../../../../utils"; -import { ReflectionType, SignatureReflection } from "../../../../models"; -import { hasTypeParameters } from "../../lib"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX, Raw } from "../../../../utils/index.js"; +import { ReflectionType, SignatureReflection } from "../../../../models/index.js"; +import { hasTypeParameters } from "../../lib.js"; export function memberSignatureBody( context: DefaultThemeRenderContext, diff --git a/src/lib/output/themes/default/partials/member.signature.title.tsx b/src/lib/output/themes/default/partials/member.signature.title.tsx index 659e2f0fa..3dd3f42ad 100644 --- a/src/lib/output/themes/default/partials/member.signature.title.tsx +++ b/src/lib/output/themes/default/partials/member.signature.title.tsx @@ -1,7 +1,7 @@ -import { getKindClass, join, renderTypeParametersSignature, wbr } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import { ParameterReflection, ReflectionKind, SignatureReflection } from "../../../../models"; +import { getKindClass, join, renderTypeParametersSignature, wbr } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import { ParameterReflection, ReflectionKind, SignatureReflection } from "../../../../models/index.js"; function renderParameterWithType(context: DefaultThemeRenderContext, item: ParameterReflection) { return ( diff --git a/src/lib/output/themes/default/partials/member.signatures.tsx b/src/lib/output/themes/default/partials/member.signatures.tsx index d4e39cefe..99e9bff3c 100644 --- a/src/lib/output/themes/default/partials/member.signatures.tsx +++ b/src/lib/output/themes/default/partials/member.signatures.tsx @@ -1,8 +1,8 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { DeclarationReflection } from "../../../../models"; -import { anchorIcon } from "./anchor-icon"; -import { classNames } from "../../lib"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { DeclarationReflection } from "../../../../models/index.js"; +import { anchorIcon } from "./anchor-icon.js"; +import { classNames } from "../../lib.js"; export const memberSignatures = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <> diff --git a/src/lib/output/themes/default/partials/member.sources.tsx b/src/lib/output/themes/default/partials/member.sources.tsx index cb842b098..843d9f7f1 100644 --- a/src/lib/output/themes/default/partials/member.sources.tsx +++ b/src/lib/output/themes/default/partials/member.sources.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { DeclarationReflection, SignatureReflection, SourceReference } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { DeclarationReflection, SignatureReflection, SourceReference } from "../../../../models/index.js"; function sourceLink(context: DefaultThemeRenderContext, item: SourceReference) { if (!item.url) { diff --git a/src/lib/output/themes/default/partials/member.tsx b/src/lib/output/themes/default/partials/member.tsx index 6e189d8a5..a53493554 100644 --- a/src/lib/output/themes/default/partials/member.tsx +++ b/src/lib/output/themes/default/partials/member.tsx @@ -1,8 +1,8 @@ -import { classNames, getDisplayName, wbr } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import { DeclarationReflection, ReferenceReflection } from "../../../../models"; -import { anchorIcon } from "./anchor-icon"; +import { classNames, getDisplayName, wbr } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import { DeclarationReflection, ReferenceReflection } from "../../../../models/index.js"; +import { anchorIcon } from "./anchor-icon.js"; export function member(context: DefaultThemeRenderContext, props: DeclarationReflection) { context.page.pageHeadings.push({ diff --git a/src/lib/output/themes/default/partials/members.group.tsx b/src/lib/output/themes/default/partials/members.group.tsx index cfbad3885..cd7a213af 100644 --- a/src/lib/output/themes/default/partials/members.group.tsx +++ b/src/lib/output/themes/default/partials/members.group.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import type { ReflectionGroup } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import type { ReflectionGroup } from "../../../../models/index.js"; export function membersGroup(context: DefaultThemeRenderContext, group: ReflectionGroup) { if (group.categories) { diff --git a/src/lib/output/themes/default/partials/members.tsx b/src/lib/output/themes/default/partials/members.tsx index 9cb0f0f06..a1069c883 100644 --- a/src/lib/output/themes/default/partials/members.tsx +++ b/src/lib/output/themes/default/partials/members.tsx @@ -1,7 +1,7 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import { ContainerReflection, DeclarationReflection } from "../../../../models"; -import { classNames } from "../../lib"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import { ContainerReflection, DeclarationReflection } from "../../../../models/index.js"; +import { classNames } from "../../lib.js"; export function members(context: DefaultThemeRenderContext, props: ContainerReflection) { if (props.categories && props.categories.length) { diff --git a/src/lib/output/themes/default/partials/navigation.tsx b/src/lib/output/themes/default/partials/navigation.tsx index 9a6d39574..4d623ed53 100644 --- a/src/lib/output/themes/default/partials/navigation.tsx +++ b/src/lib/output/themes/default/partials/navigation.tsx @@ -1,8 +1,8 @@ -import { Reflection, ReflectionKind } from "../../../../models"; -import { JSX } from "../../../../utils"; -import type { PageEvent } from "../../../events"; -import { camelToTitleCase, classNames, getDisplayName, wbr } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import { Reflection, ReflectionKind } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import type { PageEvent } from "../../../events.js"; +import { camelToTitleCase, classNames, getDisplayName, wbr } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export function sidebar(context: DefaultThemeRenderContext, props: PageEvent) { return ( diff --git a/src/lib/output/themes/default/partials/parameter.tsx b/src/lib/output/themes/default/partials/parameter.tsx index f34a8a72c..f54c153f7 100644 --- a/src/lib/output/themes/default/partials/parameter.tsx +++ b/src/lib/output/themes/default/partials/parameter.tsx @@ -1,7 +1,7 @@ -import { classNames, getKindClass, wbr } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { JSX } from "../../../../utils"; -import { DeclarationReflection, ReflectionType, SignatureReflection } from "../../../../models"; +import { classNames, getKindClass, wbr } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { JSX } from "../../../../utils/index.js"; +import { DeclarationReflection, ReflectionType, SignatureReflection } from "../../../../models/index.js"; export const parameter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <> diff --git a/src/lib/output/themes/default/partials/reflectionPreview.tsx b/src/lib/output/themes/default/partials/reflectionPreview.tsx index 95df3b4f6..c4e519789 100644 --- a/src/lib/output/themes/default/partials/reflectionPreview.tsx +++ b/src/lib/output/themes/default/partials/reflectionPreview.tsx @@ -1,7 +1,7 @@ -import { DeclarationReflection, ReflectionKind, type Reflection, ReflectionType } from "../../../../models"; -import { JSX } from "../../../../utils"; -import { getKindClass, renderTypeParametersSignature } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import { DeclarationReflection, ReflectionKind, type Reflection, ReflectionType } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import { getKindClass, renderTypeParametersSignature } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export function reflectionPreview(context: DefaultThemeRenderContext, props: Reflection) { if (!(props instanceof DeclarationReflection)) return; diff --git a/src/lib/output/themes/default/partials/toolbar.tsx b/src/lib/output/themes/default/partials/toolbar.tsx index 03240d323..1920f6964 100644 --- a/src/lib/output/themes/default/partials/toolbar.tsx +++ b/src/lib/output/themes/default/partials/toolbar.tsx @@ -1,8 +1,8 @@ -import type { Reflection } from "../../../../models"; -import { JSX } from "../../../../utils"; -import type { PageEvent } from "../../../events"; -import { getDisplayName } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import type { Reflection } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import type { PageEvent } from "../../../events.js"; +import { getDisplayName } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; export const toolbar = (context: DefaultThemeRenderContext, props: PageEvent) => (
diff --git a/src/lib/output/themes/default/partials/type.tsx b/src/lib/output/themes/default/partials/type.tsx index 37340afee..0081f4a0c 100644 --- a/src/lib/output/themes/default/partials/type.tsx +++ b/src/lib/output/themes/default/partials/type.tsx @@ -1,4 +1,4 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; import { DeclarationReflection, LiteralType, @@ -8,10 +8,10 @@ import { ReflectionKind, Type, TypeContext, - TypeKindMap, -} from "../../../../models"; -import { JSX } from "../../../../utils"; -import { getKindClass, join, stringify } from "../../lib"; + type TypeKindMap, +} from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; +import { getKindClass, join, stringify } from "../../lib.js"; import { ok } from "assert"; const EXPORTABLE: ReflectionKind = diff --git a/src/lib/output/themes/default/partials/typeAndParent.tsx b/src/lib/output/themes/default/partials/typeAndParent.tsx index e776c3c04..c69f7caef 100644 --- a/src/lib/output/themes/default/partials/typeAndParent.tsx +++ b/src/lib/output/themes/default/partials/typeAndParent.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import { ArrayType, ReferenceType, SignatureReflection, Type } from "../../../../models"; -import { JSX } from "../../../../utils"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import { ArrayType, ReferenceType, SignatureReflection, Type } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; export const typeAndParent = (context: DefaultThemeRenderContext, props: Type): JSX.Element => { if (!props) return <>void; diff --git a/src/lib/output/themes/default/partials/typeParameters.tsx b/src/lib/output/themes/default/partials/typeParameters.tsx index cb6295095..6926be5f5 100644 --- a/src/lib/output/themes/default/partials/typeParameters.tsx +++ b/src/lib/output/themes/default/partials/typeParameters.tsx @@ -1,6 +1,6 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { TypeParameterReflection } from "../../../../models"; -import { JSX } from "../../../../utils"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { TypeParameterReflection } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; export function typeParameters(context: DefaultThemeRenderContext, typeParameters: TypeParameterReflection[]) { return ( diff --git a/src/lib/output/themes/default/templates/hierarchy.tsx b/src/lib/output/themes/default/templates/hierarchy.tsx index ee8fbcb1c..55c08e8a3 100644 --- a/src/lib/output/themes/default/templates/hierarchy.tsx +++ b/src/lib/output/themes/default/templates/hierarchy.tsx @@ -1,8 +1,8 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { PageEvent } from "../../../events"; -import { JSX } from "../../../../utils"; -import { getHierarchyRoots } from "../../lib"; -import type { DeclarationReflection, ProjectReflection } from "../../../../models"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { PageEvent } from "../../../events.js"; +import { JSX } from "../../../../utils/index.js"; +import { getHierarchyRoots } from "../../lib.js"; +import type { DeclarationReflection, ProjectReflection } from "../../../../models/index.js"; function fullHierarchy( context: DefaultThemeRenderContext, diff --git a/src/lib/output/themes/default/templates/index.tsx b/src/lib/output/themes/default/templates/index.tsx index 65ad88748..b33b99425 100644 --- a/src/lib/output/themes/default/templates/index.tsx +++ b/src/lib/output/themes/default/templates/index.tsx @@ -1,7 +1,7 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { ProjectReflection } from "../../../../models"; -import type { PageEvent } from "../../../events"; -import { JSX, Raw } from "../../../../utils"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { ProjectReflection } from "../../../../models/index.js"; +import type { PageEvent } from "../../../events.js"; +import { JSX, Raw } from "../../../../utils/index.js"; export const indexTemplate = ({ markdown }: DefaultThemeRenderContext, props: PageEvent) => (
diff --git a/src/lib/output/themes/default/templates/reflection.tsx b/src/lib/output/themes/default/templates/reflection.tsx index 573a0965c..993bcead6 100644 --- a/src/lib/output/themes/default/templates/reflection.tsx +++ b/src/lib/output/themes/default/templates/reflection.tsx @@ -1,14 +1,14 @@ -import { classNames, getKindClass, hasTypeParameters } from "../../lib"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { PageEvent } from "../../../events"; +import { classNames, getKindClass, hasTypeParameters } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { PageEvent } from "../../../events.js"; import { ContainerReflection, DeclarationReflection, ReflectionKind, ReflectionType, SignatureReflection, -} from "../../../../models"; -import { JSX, Raw } from "../../../../utils"; +} from "../../../../models/index.js"; +import { JSX, Raw } from "../../../../utils/index.js"; export function reflectionTemplate(context: DefaultThemeRenderContext, props: PageEvent) { if ( diff --git a/src/lib/output/themes/lib.tsx b/src/lib/output/themes/lib.tsx index 1c39b1832..7c526fbae 100644 --- a/src/lib/output/themes/lib.tsx +++ b/src/lib/output/themes/lib.tsx @@ -1,4 +1,4 @@ -import type { DefaultThemeRenderContext } from ".."; +import type { DefaultThemeRenderContext } from "../index.js"; import { DeclarationReflection, ProjectReflection, @@ -7,8 +7,8 @@ import { ReflectionKind, SignatureReflection, TypeParameterReflection, -} from "../../models"; -import { JSX } from "../../utils"; +} from "../../models/index.js"; +import { JSX } from "../../utils/index.js"; export function stringify(data: unknown) { if (typeof data === "bigint") { diff --git a/src/lib/serialization/components.ts b/src/lib/serialization/components.ts index e73c8003b..d8f7cf13f 100644 --- a/src/lib/serialization/components.ts +++ b/src/lib/serialization/components.ts @@ -1,5 +1,5 @@ -import type { Serializer } from "./serializer"; -import type { ModelToObject } from "./schema"; +import type { Serializer } from "./serializer.js"; +import type { ModelToObject } from "./schema.js"; /** * Represents Serializer plugin component. diff --git a/src/lib/serialization/deserializer.ts b/src/lib/serialization/deserializer.ts index 63d63cfcb..3bf443ee7 100644 --- a/src/lib/serialization/deserializer.ts +++ b/src/lib/serialization/deserializer.ts @@ -1,5 +1,5 @@ import { ok } from "assert"; -import type { Application } from "../application"; +import type { Application } from "../application.js"; import { ArrayType, ConditionalType, @@ -21,21 +21,21 @@ import { Reflection, ReflectionKind, ReflectionType, - ReflectionVariant, + type ReflectionVariant, RestType, SignatureReflection, - SomeType, + type SomeType, TemplateLiteralType, TupleType, - TypeKindMap, + type TypeKindMap, TypeOperatorType, TypeParameterReflection, UnionType, UnknownType, -} from "../models/index"; -import { insertPrioritySorted } from "../utils/array"; -import type { Logger } from "../utils/loggers"; -import type { JSONOutput } from "./index"; +} from "../models/index.js"; +import { insertPrioritySorted } from "../utils/array.js"; +import type { Logger } from "../utils/loggers.js"; +import type { JSONOutput } from "./index.js"; export interface DeserializerComponent { priority: number; diff --git a/src/lib/serialization/events.ts b/src/lib/serialization/events.ts index d0090dcd5..467e9de51 100644 --- a/src/lib/serialization/events.ts +++ b/src/lib/serialization/events.ts @@ -1,6 +1,6 @@ -import { Event } from "../utils/events"; -import type { ProjectReflection } from "../models"; -import type { ProjectReflection as JSONProjectReflection } from "./schema"; +import { Event } from "../utils/events.js"; +import type { ProjectReflection } from "../models/index.js"; +import type { ProjectReflection as JSONProjectReflection } from "./schema.js"; /** * An event emitted by the {@link Serializer} class at the very beginning and diff --git a/src/lib/serialization/index.ts b/src/lib/serialization/index.ts index 6b91292ee..9362d5d59 100644 --- a/src/lib/serialization/index.ts +++ b/src/lib/serialization/index.ts @@ -1,9 +1,9 @@ -export type { SerializerComponent } from "./components"; +export type { SerializerComponent } from "./components.js"; export { Deserializer, type Deserializable, type DeserializerComponent, -} from "./deserializer"; -export { SerializeEvent } from "./events"; -export * as JSONOutput from "./schema"; -export { Serializer } from "./serializer"; +} from "./deserializer.js"; +export { SerializeEvent } from "./events.js"; +export * as JSONOutput from "./schema.js"; +export { Serializer } from "./serializer.js"; diff --git a/src/lib/serialization/schema.ts b/src/lib/serialization/schema.ts index 8e0db492b..f1af5c62f 100644 --- a/src/lib/serialization/schema.ts +++ b/src/lib/serialization/schema.ts @@ -28,7 +28,7 @@ * @module */ -import type * as M from "../models"; +import type * as M from "../models/index.js"; /** * Describes the mapping from Model types to the corresponding JSON output type. diff --git a/src/lib/serialization/serializer.ts b/src/lib/serialization/serializer.ts index 9b4998a0f..e34927b9d 100644 --- a/src/lib/serialization/serializer.ts +++ b/src/lib/serialization/serializer.ts @@ -1,10 +1,10 @@ -import { EventDispatcher } from "../utils"; -import type { ProjectReflection } from "../models"; +import { EventDispatcher } from "../utils/index.js"; +import type { ProjectReflection } from "../models/index.js"; -import { SerializeEvent } from "./events"; -import type { ModelToObject } from "./schema"; -import type { SerializerComponent } from "./components"; -import { insertPrioritySorted } from "../utils/array"; +import { SerializeEvent } from "./events.js"; +import type { ModelToObject } from "./schema.js"; +import type { SerializerComponent } from "./components.js"; +import { insertPrioritySorted } from "../utils/array.js"; export class Serializer extends EventDispatcher { /** diff --git a/src/lib/utils/component.ts b/src/lib/utils/component.ts index 4c84a55a3..0273f6ecc 100644 --- a/src/lib/utils/component.ts +++ b/src/lib/utils/component.ts @@ -1,5 +1,5 @@ -import type { Application } from "../application"; -import { EventDispatcher, Event, EventMap } from "./events"; +import type { Application } from "../application.js"; +import { EventDispatcher, Event, type EventMap } from "./events.js"; /** * Exposes a reference to the root Application component. diff --git a/src/lib/utils/entry-point.ts b/src/lib/utils/entry-point.ts index 32104807a..52772baf7 100644 --- a/src/lib/utils/entry-point.ts +++ b/src/lib/utils/entry-point.ts @@ -1,12 +1,17 @@ import { join, relative, resolve } from "path"; import ts from "typescript"; import * as FS from "fs"; -import { expandPackages } from "./package-manifest"; -import { createMinimatch, matchesAny, nicePath, normalizePath } from "./paths"; -import type { Logger } from "./loggers"; -import type { Options } from "./options"; -import { deriveRootDir, glob, isDir } from "./fs"; -import { assertNever } from "./general"; +import { expandPackages } from "./package-manifest.js"; +import { + createMinimatch, + matchesAny, + nicePath, + normalizePath, +} from "./paths.js"; +import type { Logger } from "./loggers.js"; +import type { Options } from "./options/index.js"; +import { deriveRootDir, glob, isDir } from "./fs.js"; +import { assertNever } from "./general.js"; /** * Defines how entry points are interpreted. diff --git a/src/lib/utils/fs.ts b/src/lib/utils/fs.ts index f21cea7e3..a48c32de4 100644 --- a/src/lib/utils/fs.ts +++ b/src/lib/utils/fs.ts @@ -2,9 +2,9 @@ import * as fs from "fs"; import { promises as fsp } from "fs"; import { Minimatch } from "minimatch"; import { dirname, join, relative, resolve } from "path"; -import { optional, validate } from "./validation"; -import { createMinimatch, normalizePath } from "./paths"; -import { filterMap } from "./array"; +import { optional, validate } from "./validation.js"; +import { createMinimatch, normalizePath } from "./paths.js"; +import { filterMap } from "./array.js"; export function isFile(file: string) { try { diff --git a/src/lib/utils/general.ts b/src/lib/utils/general.ts index 7e6af56c4..36afc335a 100644 --- a/src/lib/utils/general.ts +++ b/src/lib/utils/general.ts @@ -1,5 +1,6 @@ import { dirname } from "path"; import * as Util from "util"; +import url from "url"; /** * This type provides a flag that can be used to turn off more lax overloads intended for @@ -85,7 +86,9 @@ const g = globalThis as TypeDocGlobals; g[loadSymbol] = (g[loadSymbol] || 0) + 1; g[pathSymbol] ||= []; // transform /abs/path/to/typedoc/dist/lib/utils/general -> /abs/path/to/typedoc -g[pathSymbol].push(dirname(dirname(dirname(__dirname)))); +g[pathSymbol].push( + dirname(dirname(dirname(dirname(url.fileURLToPath(import.meta.url))))), +); export function hasBeenLoadedMultipleTimes() { return g[loadSymbol] !== 1; diff --git a/src/lib/utils/highlighter.tsx b/src/lib/utils/highlighter.tsx index 5dda79043..06cb4abda 100644 --- a/src/lib/utils/highlighter.tsx +++ b/src/lib/utils/highlighter.tsx @@ -1,7 +1,7 @@ import { ok as assert } from "assert"; -import { BUNDLED_LANGUAGES, getHighlighter, Highlighter, Theme } from "shiki"; -import { unique, zip } from "./array"; -import * as JSX from "./jsx"; +import { BUNDLED_LANGUAGES, getHighlighter, type Highlighter, type Theme } from "shiki"; +import { unique, zip } from "./array.js"; +import * as JSX from "./jsx.js"; const aliases = new Map(); for (const lang of BUNDLED_LANGUAGES) { diff --git a/src/lib/utils/hooks.ts b/src/lib/utils/hooks.ts index 53a79865f..534f7e92a 100644 --- a/src/lib/utils/hooks.ts +++ b/src/lib/utils/hooks.ts @@ -1,4 +1,4 @@ -import { insertOrderSorted } from "./array"; +import { insertOrderSorted } from "./array.js"; const momentos = new WeakMap< EventHooksMomento, diff --git a/src/lib/utils/html.ts b/src/lib/utils/html.cts similarity index 81% rename from src/lib/utils/html.ts rename to src/lib/utils/html.cts index 42582524e..27b5418d5 100644 --- a/src/lib/utils/html.ts +++ b/src/lib/utils/html.cts @@ -1,7 +1,7 @@ // There is a fixed list of named character references which will not be expanded in the future. // This json file is based on https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references // with some modifications to reduce the file size of the original JSON since we just need. -import htmlEntities from "./html-entities.json"; +const htmlEntities = require("./html-entities.json") as Record; // Three cases: // { - numeric escape @@ -18,12 +18,12 @@ function unescapeEntities(html: string) { : parseInt(n.substring(1), 10), ); } - return htmlEntities[n as never] || ""; + return htmlEntities[n] || ""; }, ); } -export function getTextContent(text: string) { +function getTextContent(text: string) { return unescapeEntities(text.replace(/<.*?(?:>|$)/g, "")); } @@ -35,6 +35,8 @@ const htmlEscapes: Record = { "'": "'", }; -export function escapeHtml(html: string) { +function escapeHtml(html: string) { return html.replace(/[&<>'"]/g, (c) => htmlEscapes[c as never]); } + +export = { getTextContent, escapeHtml }; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index fbd81a85e..3006ad6cb 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -5,10 +5,14 @@ export { removeIf, removeIfPresent, unique, -} from "./array"; -export { AbstractComponent, ChildableComponent, Component } from "./component"; -export * from "./enum"; -export { Event, EventDispatcher } from "./events"; +} from "./array.js"; +export { + AbstractComponent, + ChildableComponent, + Component, +} from "./component.js"; +export * from "./enum.js"; +export { Event, EventDispatcher } from "./events.js"; export { isFile, copy, @@ -19,12 +23,12 @@ export { writeFileSync, discoverInParentDir, discoverPackageJson, -} from "./fs"; -export { normalizePath } from "./paths"; -export type { IfInternal, NeverIfInternal, Chars } from "./general"; -export { assertNever } from "./general"; -export { ConsoleLogger, Logger, LogLevel } from "./loggers"; -export { DefaultMap } from "./map"; +} from "./fs.js"; +export { normalizePath } from "./paths.js"; +export type { IfInternal, NeverIfInternal, Chars } from "./general.js"; +export { assertNever } from "./general.js"; +export { ConsoleLogger, Logger, LogLevel } from "./loggers.js"; +export { DefaultMap } from "./map.js"; export { ArgumentsReader, Option, @@ -35,7 +39,7 @@ export { ParameterType, TSConfigReader, TypeDocReader, -} from "./options"; +} from "./options/index.js"; export type { ArrayDeclarationOption, BooleanDeclarationOption, @@ -57,21 +61,21 @@ export type { ParameterTypeToOptionTypeMap, ManuallyValidatedOption, JsDocCompatibility, -} from "./options"; -export { loadPlugins } from "./plugins"; -export { getSortFunction } from "./sort"; -export type { SortStrategy } from "./sort"; +} from "./options/index.js"; +export { loadPlugins } from "./plugins.js"; +export { getSortFunction } from "./sort.js"; +export type { SortStrategy } from "./sort.js"; -export { EventHooks } from "./hooks"; +export { EventHooks } from "./hooks.js"; -export * from "./entry-point"; +export * from "./entry-point.js"; -import * as JSX from "./jsx"; +import * as JSX from "./jsx.js"; export { JSX }; -export { Fragment, Raw, renderElement } from "./jsx"; +export { Fragment, Raw, renderElement } from "./jsx.js"; -export * as Validation from "./validation"; +export * as Validation from "./validation.js"; -export * from "./tsutils"; +export * from "./tsutils.js"; -export { MinimalSourceFile } from "./minimalSourceFile"; +export { MinimalSourceFile } from "./minimalSourceFile.js"; diff --git a/src/lib/utils/jsx.ts b/src/lib/utils/jsx.ts index 019ea39bf..10e467d58 100644 --- a/src/lib/utils/jsx.ts +++ b/src/lib/utils/jsx.ts @@ -13,21 +13,22 @@ * @module */ -import { escapeHtml } from "./html"; +import html from "./html.cjs"; +const { escapeHtml } = html; import type { IntrinsicElements, JsxElement, JsxChildren, JsxComponent, -} from "./jsx.elements"; -import { JsxFragment as Fragment } from "./jsx.elements"; +} from "./jsx.elements.js"; +import { JsxFragment as Fragment } from "./jsx.elements.js"; export type { JsxElement as Element, JsxChildren as Children, JsxComponent, -} from "./jsx.elements"; -export { JsxFragment as Fragment } from "./jsx.elements"; +} from "./jsx.elements.js"; +export { JsxFragment as Fragment } from "./jsx.elements.js"; /** * Used to inject HTML directly into the document. diff --git a/src/lib/utils/loggers.ts b/src/lib/utils/loggers.ts index fc09c110f..d072e719b 100644 --- a/src/lib/utils/loggers.ts +++ b/src/lib/utils/loggers.ts @@ -1,13 +1,13 @@ import ts from "typescript"; import { url } from "inspector"; import { resolve } from "path"; -import { nicePath } from "./paths"; -import type { MinimalSourceFile } from "./minimalSourceFile"; +import { nicePath } from "./paths.js"; +import type { MinimalSourceFile } from "./minimalSourceFile.js"; import type { TranslatedString, TranslationProxy, -} from "../internationalization/internationalization"; -import type { IfInternal } from "."; +} from "../internationalization/internationalization.js"; +import type { IfInternal } from "./index.js"; const isDebugging = () => !!url(); diff --git a/src/lib/utils/minimalSourceFile.ts b/src/lib/utils/minimalSourceFile.ts index 18d821f19..7155441bd 100644 --- a/src/lib/utils/minimalSourceFile.ts +++ b/src/lib/utils/minimalSourceFile.ts @@ -1,5 +1,5 @@ import type { LineAndCharacter, SourceFileLike } from "typescript"; -import { binaryFindPartition } from "./array"; +import { binaryFindPartition } from "./array.js"; // I don't like this, but it's necessary so that the lineStarts property isn't // visible in the `MinimalSourceFile` type. Even when private it causes compilation diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index 9ccc6d8e7..b4b242792 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -1,14 +1,14 @@ import type { Theme as ShikiTheme } from "shiki"; -import type { LogLevel } from "../loggers"; -import type { SortStrategy } from "../sort"; +import type { LogLevel } from "../loggers.js"; +import type { SortStrategy } from "../sort.js"; import { isAbsolute, join, resolve } from "path"; -import type { EntryPointStrategy } from "../entry-point"; -import type { ReflectionKind } from "../../models/reflections/kind"; -import type { NeverIfInternal } from ".."; +import type { EntryPointStrategy } from "../entry-point.js"; +import type { ReflectionKind } from "../../models/reflections/kind.js"; +import type { NeverIfInternal } from "../index.js"; import type { TranslatedString, TranslationProxy, -} from "../../internationalization/internationalization"; +} from "../../internationalization/internationalization.js"; /** @enum */ export const EmitStrategy = { diff --git a/src/lib/utils/options/help.ts b/src/lib/utils/options/help.ts index 993bf1370..de0ae813f 100644 --- a/src/lib/utils/options/help.ts +++ b/src/lib/utils/options/help.ts @@ -1,13 +1,13 @@ -import type { Options } from "./options"; +import type { Options } from "./options.js"; import { ParameterHint, - StringDeclarationOption, + type StringDeclarationOption, ParameterType, - DeclarationOption, -} from "./declaration"; -import { getSupportedLanguages } from "../highlighter"; + type DeclarationOption, +} from "./declaration.js"; +import { getSupportedLanguages } from "../highlighter.js"; import { BUNDLED_THEMES } from "shiki"; -import type { TranslationProxy } from "../../internationalization/internationalization"; +import type { TranslationProxy } from "../../internationalization/internationalization.js"; export interface ParameterHelp { names: string[]; diff --git a/src/lib/utils/options/index.ts b/src/lib/utils/options/index.ts index 8f5308f5d..bcd0465e7 100644 --- a/src/lib/utils/options/index.ts +++ b/src/lib/utils/options/index.ts @@ -1,17 +1,17 @@ -export { Options, Option } from "./options"; -export type { OptionsReader } from "./options"; +export { Options, Option } from "./options.js"; +export type { OptionsReader } from "./options.js"; export { ArgumentsReader, PackageJsonReader, TypeDocReader, TSConfigReader, -} from "./readers"; +} from "./readers/index.js"; export { CommentStyle, EmitStrategy, ParameterType, ParameterHint, -} from "./declaration"; +} from "./declaration.js"; export type { TypeDocOptions, @@ -33,4 +33,4 @@ export type { ParameterTypeToOptionTypeMap, ManuallyValidatedOption, JsDocCompatibility, -} from "./declaration"; +} from "./declaration.js"; diff --git a/src/lib/utils/options/options.ts b/src/lib/utils/options/options.ts index 69becb7b8..1bb2ae72b 100644 --- a/src/lib/utils/options/options.ts +++ b/src/lib/utils/options/options.ts @@ -1,21 +1,21 @@ import type * as ts from "typescript"; -import { ParameterType } from "./declaration"; -import type { NeverIfInternal } from ".."; -import type { Application } from "../../.."; -import { insertOrderSorted, unique } from "../array"; -import type { Logger } from "../loggers"; +import { ParameterType } from "./declaration.js"; +import type { NeverIfInternal } from "../index.js"; +import type { Application } from "../../../index.js"; +import { insertOrderSorted, unique } from "../array.js"; +import type { Logger } from "../loggers.js"; import { convert, - DeclarationOption, + type DeclarationOption, getDefaultValue, - KeyToDeclaration, - TypeDocOptionMap, - TypeDocOptions, - TypeDocOptionValues, -} from "./declaration"; -import { addTypeDocOptions } from "./sources"; -import { getOptionsHelp } from "./help"; -import type { TranslationProxy } from "../../internationalization/internationalization"; + type KeyToDeclaration, + type TypeDocOptionMap, + type TypeDocOptions, + type TypeDocOptionValues, +} from "./declaration.js"; +import { addTypeDocOptions } from "./sources/index.js"; +import { getOptionsHelp } from "./help.js"; +import type { TranslationProxy } from "../../internationalization/internationalization.js"; /** * Describes an option reader that discovers user configuration and converts it to the diff --git a/src/lib/utils/options/readers/arguments.ts b/src/lib/utils/options/readers/arguments.ts index dc5845a45..f6a9c703e 100644 --- a/src/lib/utils/options/readers/arguments.ts +++ b/src/lib/utils/options/readers/arguments.ts @@ -1,8 +1,8 @@ import { ok } from "assert"; -import type { OptionsReader, Options } from ".."; -import type { Logger } from "../../loggers"; -import { ParameterType } from "../declaration"; -import type { TranslatedString } from "../../../internationalization/internationalization"; +import type { OptionsReader, Options } from "../index.js"; +import type { Logger } from "../../loggers.js"; +import { ParameterType } from "../declaration.js"; +import type { TranslatedString } from "../../../internationalization/internationalization.js"; const ARRAY_OPTION_TYPES = new Set([ ParameterType.Array, diff --git a/src/lib/utils/options/readers/index.ts b/src/lib/utils/options/readers/index.ts index e77703533..2142e0d19 100644 --- a/src/lib/utils/options/readers/index.ts +++ b/src/lib/utils/options/readers/index.ts @@ -1,4 +1,4 @@ -export { ArgumentsReader } from "./arguments"; -export { PackageJsonReader } from "./package-json"; -export { TSConfigReader } from "./tsconfig"; -export { TypeDocReader } from "./typedoc"; +export { ArgumentsReader } from "./arguments.js"; +export { PackageJsonReader } from "./package-json.js"; +export { TSConfigReader } from "./tsconfig.js"; +export { TypeDocReader } from "./typedoc.js"; diff --git a/src/lib/utils/options/readers/package-json.ts b/src/lib/utils/options/readers/package-json.ts index b4d5c2296..3447c3312 100644 --- a/src/lib/utils/options/readers/package-json.ts +++ b/src/lib/utils/options/readers/package-json.ts @@ -1,11 +1,11 @@ -import type { OptionsReader } from ".."; -import type { Logger } from "../../loggers"; -import type { Options } from "../options"; +import type { OptionsReader } from "../index.js"; +import type { Logger } from "../../loggers.js"; +import type { Options } from "../options.js"; import { ok } from "assert"; -import { nicePath } from "../../paths"; -import { discoverPackageJson } from "../../fs"; +import { nicePath } from "../../paths.js"; +import { discoverPackageJson } from "../../fs.js"; import { dirname } from "path"; -import type { TranslatedString } from "../../../internationalization/internationalization"; +import type { TranslatedString } from "../../../internationalization/internationalization.js"; export class PackageJsonReader implements OptionsReader { // Should run after the TypeDoc config reader but before the TS config diff --git a/src/lib/utils/options/readers/tsconfig.ts b/src/lib/utils/options/readers/tsconfig.ts index e89125ccd..e45e2867e 100644 --- a/src/lib/utils/options/readers/tsconfig.ts +++ b/src/lib/utils/options/readers/tsconfig.ts @@ -2,31 +2,31 @@ import { resolve, join, dirname } from "path"; import ts from "typescript"; -import type { Options, OptionsReader } from "../options"; -import type { Logger } from "../../loggers"; -import { isFile } from "../../fs"; +import type { Options, OptionsReader } from "../options.js"; +import type { Logger } from "../../loggers.js"; +import { isFile } from "../../fs.js"; import { ok } from "assert"; import { additionalProperties, - Infer, + type Infer, isTagString, optional, validate, -} from "../../validation"; -import { nicePath, normalizePath } from "../../paths"; +} from "../../validation.js"; +import { nicePath, normalizePath } from "../../paths.js"; import { createRequire } from "module"; import { tsdocBlockTags, tsdocInlineTags, tsdocModifierTags, -} from "../tsdoc-defaults"; -import { unique } from "../../array"; +} from "../tsdoc-defaults.js"; +import { unique } from "../../array.js"; import { findTsConfigFile, getTypeDocOptionsFromTsConfig, readTsConfig, -} from "../../tsconfig"; -import type { TranslatedString } from "../../../internationalization/internationalization"; +} from "../../tsconfig.js"; +import type { TranslatedString } from "../../../internationalization/internationalization.js"; function isSupportForTags(obj: unknown): obj is Record<`@${string}`, boolean> { return ( diff --git a/src/lib/utils/options/readers/typedoc.ts b/src/lib/utils/options/readers/typedoc.ts index aa5b0bb77..0e0b5afa1 100644 --- a/src/lib/utils/options/readers/typedoc.ts +++ b/src/lib/utils/options/readers/typedoc.ts @@ -2,15 +2,15 @@ import { join, dirname, resolve } from "path"; import * as FS from "fs"; import ts from "typescript"; -import type { OptionsReader } from ".."; -import type { Logger } from "../../loggers"; -import type { Options } from "../options"; +import type { OptionsReader } from "../options.js"; +import type { Logger } from "../../loggers.js"; +import type { Options } from "../options.js"; import { ok } from "assert"; -import { nicePath, normalizePath } from "../../paths"; -import { isFile } from "../../fs"; +import { nicePath, normalizePath } from "../../paths.js"; +import { isFile } from "../../fs.js"; import { createRequire } from "module"; import { pathToFileURL } from "url"; -import type { TranslatedString } from "../../../internationalization/internationalization"; +import type { TranslatedString } from "../../../internationalization/internationalization.js"; /** * Obtains option values from typedoc.json @@ -84,19 +84,10 @@ export class TypeDocReader implements OptionsReader { } } else { try { - try { - // eslint-disable-next-line @typescript-eslint/no-var-requires - fileContent = await require(file); - } catch (error: any) { - if (error?.code === "ERR_REQUIRE_ESM") { - // On Windows, we need to ensure this path is a file path. - // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME - const esmPath = pathToFileURL(file).toString(); - fileContent = await (await import(esmPath)).default; - } else { - throw error; - } - } + // On Windows, we need to ensure this path is a file path. + // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME + const esmPath = pathToFileURL(file).toString(); + fileContent = await (await import(esmPath)).default; } catch (error) { logger.error( logger.i18n.failed_read_options_file_0(nicePath(file)), diff --git a/src/lib/utils/options/sources/index.ts b/src/lib/utils/options/sources/index.ts index fdbdea86d..eb7a40be5 100644 --- a/src/lib/utils/options/sources/index.ts +++ b/src/lib/utils/options/sources/index.ts @@ -1 +1 @@ -export { addTypeDocOptions } from "./typedoc"; +export { addTypeDocOptions } from "./typedoc.js"; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index 303ac1321..f45738404 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -1,18 +1,18 @@ -import type { Options } from ".."; -import { LogLevel } from "../../loggers"; +import type { Options } from "../index.js"; +import { LogLevel } from "../../loggers.js"; import { ParameterType, ParameterHint, EmitStrategy, CommentStyle, -} from "../declaration"; -import { BUNDLED_THEMES, Theme } from "shiki"; -import { SORT_STRATEGIES } from "../../sort"; -import { EntryPointStrategy } from "../../entry-point"; -import { ReflectionKind } from "../../../models/reflections/kind"; -import * as Validation from "../../validation"; -import { blockTags, inlineTags, modifierTags } from "../tsdoc-defaults"; -import { getEnumKeys } from "../../enum"; +} from "../declaration.js"; +import { BUNDLED_THEMES, type Theme } from "shiki"; +import { SORT_STRATEGIES } from "../../sort.js"; +import { EntryPointStrategy } from "../../entry-point.js"; +import { ReflectionKind } from "../../../models/reflections/kind.js"; +import * as Validation from "../../validation.js"; +import { blockTags, inlineTags, modifierTags } from "../tsdoc-defaults.js"; +import { getEnumKeys } from "../../enum.js"; // For convenience, added in the same order as they are documented on the website. export function addTypeDocOptions(options: Pick) { diff --git a/src/lib/utils/package-manifest.ts b/src/lib/utils/package-manifest.ts index bd390acc3..c562c8c12 100644 --- a/src/lib/utils/package-manifest.ts +++ b/src/lib/utils/package-manifest.ts @@ -2,10 +2,10 @@ import { dirname, resolve } from "path"; -import { readFile, glob } from "./fs"; -import type { Logger } from "./loggers"; +import { readFile, glob } from "./fs.js"; +import type { Logger } from "./loggers.js"; import type { Minimatch } from "minimatch"; -import { matchesAny, nicePath } from "./paths"; +import { matchesAny, nicePath } from "./paths.js"; /** * Helper for the TS type system to understand hasOwnProperty diff --git a/src/lib/utils/plugins.ts b/src/lib/utils/plugins.ts index 62a65d7ce..38da2518e 100644 --- a/src/lib/utils/plugins.ts +++ b/src/lib/utils/plugins.ts @@ -1,9 +1,9 @@ import { isAbsolute } from "path"; import { pathToFileURL } from "url"; -import type { Application } from "../application"; -import { nicePath } from "./paths"; -import type { TranslatedString } from "../internationalization/internationalization"; +import type { Application } from "../application.js"; +import { nicePath } from "./paths.js"; +import type { TranslatedString } from "../internationalization/internationalization.js"; export async function loadPlugins( app: Application, @@ -13,23 +13,13 @@ export async function loadPlugins( const pluginDisplay = getPluginDisplayName(plugin); try { - // eslint-disable-next-line @typescript-eslint/no-var-requires - let instance: any; - try { - instance = require(plugin); - } catch (error: any) { - if (error.code === "ERR_REQUIRE_ESM") { - // On Windows, we need to ensure this path is a file path. - // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME - const esmPath = isAbsolute(plugin) - ? pathToFileURL(plugin).toString() - : plugin; - instance = await import(esmPath); - } else { - throw error; - } - } - const initFunction = instance.load; + // On Windows, we need to ensure this path is a file path. + // Or we'll get ERR_UNSUPPORTED_ESM_URL_SCHEME + const esmPath = isAbsolute(plugin) + ? pathToFileURL(plugin).toString() + : plugin; + const instance = await import(esmPath); + const initFunction = instance.load ?? instance.default.load; if (typeof initFunction === "function") { await initFunction(app); diff --git a/src/lib/utils/reflections.ts b/src/lib/utils/reflections.ts index fd471568c..088551c45 100644 --- a/src/lib/utils/reflections.ts +++ b/src/lib/utils/reflections.ts @@ -8,7 +8,7 @@ import { Reflection, SignatureReflection, TypeParameterReflection, -} from "../models"; +} from "../models/index.js"; export function discoverAllReferenceTypes( project: ProjectReflection, diff --git a/src/lib/utils/sort.ts b/src/lib/utils/sort.ts index 476fb65fd..4cf79c5d4 100644 --- a/src/lib/utils/sort.ts +++ b/src/lib/utils/sort.ts @@ -3,10 +3,10 @@ * @module */ -import { ReflectionKind } from "../models/reflections/kind"; -import type { DeclarationReflection } from "../models/reflections/declaration"; -import { LiteralType } from "../models/types"; -import type { Options } from "./options"; +import { ReflectionKind } from "../models/reflections/kind.js"; +import type { DeclarationReflection } from "../models/reflections/declaration.js"; +import { LiteralType } from "../models/types.js"; +import type { Options } from "./options/index.js"; export const SORT_STRATEGIES = [ "source-order", diff --git a/src/lib/utils/tsconfig.ts b/src/lib/utils/tsconfig.ts index f25bd41bf..ce9e8cb15 100644 --- a/src/lib/utils/tsconfig.ts +++ b/src/lib/utils/tsconfig.ts @@ -1,6 +1,6 @@ import ts from "typescript"; -import { isFile, isDir, readFile } from "./fs"; -import type { Logger } from "./loggers"; +import { isFile, isDir, readFile } from "./fs.js"; +import type { Logger } from "./loggers.js"; import { createRequire } from "module"; export function findTsConfigFile(path: string): string | undefined { diff --git a/src/lib/utils/tsutils.ts b/src/lib/utils/tsutils.ts index c3e6c8da7..a668f3b88 100644 --- a/src/lib/utils/tsutils.ts +++ b/src/lib/utils/tsutils.ts @@ -1,4 +1,4 @@ -import * as ts from "typescript"; +import ts from "typescript"; export function getQualifiedName(symbol: ts.Symbol, defaultName: string) { // Two implementation options for this one: diff --git a/src/lib/validation/documentation.ts b/src/lib/validation/documentation.ts index 636e8f1e8..3363f02c8 100644 --- a/src/lib/validation/documentation.ts +++ b/src/lib/validation/documentation.ts @@ -4,10 +4,10 @@ import { Reflection, ReflectionKind, ReflectionType, -} from "../models"; -import type { Logger } from "../utils"; -import { removeFlag } from "../utils/enum"; -import { nicePath } from "../utils/paths"; +} from "../models/index.js"; +import type { Logger } from "../utils/index.js"; +import { removeFlag } from "../utils/enum.js"; +import { nicePath } from "../utils/paths.js"; export function validateDocumentation( project: ProjectReflection, diff --git a/src/lib/validation/exports.ts b/src/lib/validation/exports.ts index b439f0db3..5a76bb09e 100644 --- a/src/lib/validation/exports.ts +++ b/src/lib/validation/exports.ts @@ -1,8 +1,8 @@ import { ok } from "assert"; -import type { ProjectReflection, ReferenceType } from "../models"; -import type { Logger } from "../utils"; -import { nicePath } from "../utils/paths"; -import { discoverAllReferenceTypes } from "../utils/reflections"; +import type { ProjectReflection, ReferenceType } from "../models/index.js"; +import type { Logger } from "../utils/index.js"; +import { nicePath } from "../utils/paths.js"; +import { discoverAllReferenceTypes } from "../utils/reflections.js"; function makeIntentionallyExportedHelper( project: ProjectReflection, diff --git a/src/lib/validation/links.ts b/src/lib/validation/links.ts index a98146fa5..577c1c620 100644 --- a/src/lib/validation/links.ts +++ b/src/lib/validation/links.ts @@ -1,5 +1,9 @@ -import type { Comment, CommentDisplayPart, ProjectReflection } from "../models"; -import type { Logger } from "../utils"; +import type { + Comment, + CommentDisplayPart, + ProjectReflection, +} from "../models/index.js"; +import type { Logger } from "../utils/index.js"; const linkTags = ["@link", "@linkcode", "@linkplain"]; diff --git a/src/test/Repository.test.ts b/src/test/Repository.test.ts index c68821fd0..be3be7db2 100644 --- a/src/test/Repository.test.ts +++ b/src/test/Repository.test.ts @@ -1,4 +1,4 @@ -import { guessSourceUrlTemplate } from "../lib/converter/utils/repository"; +import { guessSourceUrlTemplate } from "../lib/converter/utils/repository.js"; import { strictEqual as equal } from "assert"; describe("Repository", function () { diff --git a/src/test/TestLogger.ts b/src/test/TestLogger.ts index cde695170..3383780b1 100644 --- a/src/test/TestLogger.ts +++ b/src/test/TestLogger.ts @@ -1,11 +1,11 @@ -import { Logger, LogLevel } from "../lib/utils"; +import { Logger, LogLevel } from "../lib/utils/index.js"; import { fail, ok } from "assert"; import ts from "typescript"; import { resolve } from "path"; import { Internationalization, type TranslationProxy, -} from "../lib/internationalization/internationalization"; +} from "../lib/internationalization/internationalization.js"; const levelMap: Record = { [LogLevel.None]: "none: ", diff --git a/src/test/behavior.c2.test.ts b/src/test/behavior.c2.test.ts index b20e1f926..bdc40c42c 100644 --- a/src/test/behavior.c2.test.ts +++ b/src/test/behavior.c2.test.ts @@ -7,19 +7,19 @@ import { Reflection, SignatureReflection, ContainerReflection, -} from "../lib/models"; -import { filterMap } from "../lib/utils"; -import { CommentStyle } from "../lib/utils/options/declaration"; -import { TestLogger } from "./TestLogger"; +} from "../lib/models/index.js"; +import { filterMap } from "../lib/utils/index.js"; +import { CommentStyle } from "../lib/utils/options/declaration.js"; +import { TestLogger } from "./TestLogger.js"; import { getConverter2App, getConverter2Base, getConverter2Program, -} from "./programs"; +} from "./programs.js"; import { join } from "path"; import { existsSync } from "fs"; -import { clearCommentCache } from "../lib/converter/comments"; -import { getComment, query, querySig } from "./utils"; +import { clearCommentCache } from "../lib/converter/comments/index.js"; +import { getComment, query, querySig } from "./utils.js"; type NameTree = { [name: string]: NameTree }; diff --git a/src/test/capture-screenshots.ts b/src/test/capture-screenshots.ts index e46b4e0b8..0f9caee97 100644 --- a/src/test/capture-screenshots.ts +++ b/src/test/capture-screenshots.ts @@ -1,8 +1,8 @@ import * as fs from "fs"; import { platform } from "os"; import { resolve, join, dirname, relative } from "path"; -import { Application, EntryPointStrategy } from ".."; -import { glob } from "../lib/utils/fs"; +import { Application, EntryPointStrategy } from "../index.js"; +import { glob } from "../lib/utils/fs.js"; // The @types package plays badly with non-dom packages. // eslint-disable-next-line @typescript-eslint/no-var-requires diff --git a/src/test/comments.test.ts b/src/test/comments.test.ts index 7337c1d26..6cdbb0d8c 100644 --- a/src/test/comments.test.ts +++ b/src/test/comments.test.ts @@ -1,16 +1,19 @@ import { deepStrictEqual as equal } from "assert"; import ts from "typescript"; -import type { CommentParserConfig } from "../lib/converter/comments"; - -import { lexBlockComment } from "../lib/converter/comments/blockLexer"; -import { lexLineComments } from "../lib/converter/comments/lineLexer"; -import { Token, TokenSyntaxKind } from "../lib/converter/comments/lexer"; -import { parseComment } from "../lib/converter/comments/parser"; -import { lexCommentString } from "../lib/converter/comments/rawLexer"; -import { Comment, CommentTag } from "../lib/models"; -import { MinimalSourceFile } from "../lib/utils/minimalSourceFile"; -import { TestLogger } from "./TestLogger"; -import { extractTagName } from "../lib/converter/comments/tagName"; +import type { CommentParserConfig } from "../lib/converter/comments/index.js"; + +import { lexBlockComment } from "../lib/converter/comments/blockLexer.js"; +import { lexLineComments } from "../lib/converter/comments/lineLexer.js"; +import { + type Token, + TokenSyntaxKind, +} from "../lib/converter/comments/lexer.js"; +import { parseComment } from "../lib/converter/comments/parser.js"; +import { lexCommentString } from "../lib/converter/comments/rawLexer.js"; +import { Comment, CommentTag } from "../lib/models/index.js"; +import { MinimalSourceFile } from "../lib/utils/minimalSourceFile.js"; +import { TestLogger } from "./TestLogger.js"; +import { extractTagName } from "../lib/converter/comments/tagName.js"; function dedent(text: string) { const lines = text.split(/\r?\n/); diff --git a/src/test/converter.test.ts b/src/test/converter.test.ts index cecbc29a3..6304459bd 100644 --- a/src/test/converter.test.ts +++ b/src/test/converter.test.ts @@ -12,17 +12,17 @@ import { CommentTag, ReferenceType, Comment, - CommentDisplayPart, + type CommentDisplayPart, SourceReference, ReferenceReflection, -} from ".."; -import type { ModelToObject } from "../lib/serialization/schema"; -import { getExpandedEntryPointsForPaths } from "../lib/utils"; +} from "../index.js"; +import type { ModelToObject } from "../lib/serialization/schema.js"; +import { getExpandedEntryPointsForPaths } from "../lib/utils/index.js"; import { getConverterApp, getConverterBase, getConverterProgram, -} from "./programs"; +} from "./programs.js"; const comparisonSerializer = new Serializer(); comparisonSerializer.addSerializer({ diff --git a/src/test/converter/alias/alias.ts b/src/test/converter/alias/alias.ts index 3acd812bf..681a0878a 100644 --- a/src/test/converter/alias/alias.ts +++ b/src/test/converter/alias/alias.ts @@ -1,4 +1,4 @@ -import { TestClass } from "../class/class"; +import { TestClass } from "../class/class.js"; /** * A type that describes a compare function, e.g. for array.sort(). diff --git a/src/test/converter/exports/export.ts b/src/test/converter/exports/export.ts index 6b4d65124..ca9ed3b0e 100644 --- a/src/test/converter/exports/export.ts +++ b/src/test/converter/exports/export.ts @@ -1,6 +1,6 @@ -import ModDefault, { a as b } from "./mod"; -import * as Mod from "./mod"; -export * from "./mod"; +import ModDefault, { a as b } from "./mod.js"; +import * as Mod from "./mod.js"; +export * from "./mod.js"; export { b as c, add, Mod, ModDefault }; @@ -11,10 +11,10 @@ function add(x: number, y: number) { /** * This is a comment for Mod that overwrites the one specified in "mod" */ -export * as Mod2 from "./mod"; +export * as Mod2 from "./mod.js"; // Note that this will show up in the docs, not the default function from mod. -// export * from "./mod" does *not* re-export the default function. +// export * from "./mod.js" does *not* re-export the default function. export default function (a: number) {} import * as x from "./test.json"; diff --git a/src/test/converter/exports/mod.ts b/src/test/converter/exports/mod.ts index 9781d2919..2a6bc109b 100644 --- a/src/test/converter/exports/mod.ts +++ b/src/test/converter/exports/mod.ts @@ -15,7 +15,7 @@ export { a as b }; /** * An export with a module specifier that comes from this file. */ -export { a as c } from "./mod"; +export { a as c } from "./mod.js"; /** * Will not be re-exported from export.ts using export * from... @@ -37,6 +37,6 @@ export const hidden = true; export { Node } from "typescript"; // TS 3.8 namespace exports -export * as ThisModule from "./mod"; +export * as ThisModule from "./mod.js"; export type GH1453Helper = `1`; diff --git a/src/test/converter2/behavior/linkResolutionTs.ts b/src/test/converter2/behavior/linkResolutionTs.ts index 1c7748f6d..06a297f89 100644 --- a/src/test/converter2/behavior/linkResolutionTs.ts +++ b/src/test/converter2/behavior/linkResolutionTs.ts @@ -1,6 +1,6 @@ -export * from "./linkResolution"; +export * from "./linkResolution.js"; -import { A as AnotherName, Meanings } from "./linkResolution"; +import { A as AnotherName, Meanings } from "./linkResolution.js"; /** {@link AnotherName | A!}{@link AnotherName A2!}{@link AnotherName} */ export const localSymbolRef = 1; diff --git a/src/test/converter2/issues/gh1578/index.ts b/src/test/converter2/issues/gh1578/index.ts index c003a7b47..79bb01663 100644 --- a/src/test/converter2/issues/gh1578/index.ts +++ b/src/test/converter2/issues/gh1578/index.ts @@ -1,2 +1,2 @@ -export { ignored } from "./ignored"; +export { ignored } from "./ignored.js"; export const notIgnored = true; diff --git a/src/test/converter2/issues/gh2044/index.js b/src/test/converter2/issues/gh2044/index.js index d73fa2861..5f4d68abd 100644 --- a/src/test/converter2/issues/gh2044/index.js +++ b/src/test/converter2/issues/gh2044/index.js @@ -1,18 +1,18 @@ -export { other } from "./other"; +export { other } from "./other.js"; -/** @typedef {import("./other").Foo} Foo */ -/** @typedef {import("./other").Foo} RenamedFoo */ +/** @typedef {import("./other.js").Foo} Foo */ +/** @typedef {import("./other.js").Foo} RenamedFoo */ /** - * @typedef {import("./other").Generic} Generic + * @typedef {import("./other.js").Generic} Generic * @template {string} T */ /** - * @typedef {import("./other").Generic} RenamedGeneric + * @typedef {import("./other.js").Generic} RenamedGeneric * @template {string} U */ /** - * @typedef {import("./other").Generic} NonGeneric + * @typedef {import("./other.js").Generic} NonGeneric */ diff --git a/src/test/converter2/issues/gh2150/index.ts b/src/test/converter2/issues/gh2150/index.ts index 6c670df54..199324486 100644 --- a/src/test/converter2/issues/gh2150/index.ts +++ b/src/test/converter2/issues/gh2150/index.ts @@ -1,4 +1,4 @@ -import * as Int from "./int"; +import * as Int from "./int.js"; type Int = typeof Int; diff --git a/src/test/converter2/issues/gh2207/index.ts b/src/test/converter2/issues/gh2207/index.ts index 31a47857e..3ef7357c9 100644 --- a/src/test/converter2/issues/gh2207/index.ts +++ b/src/test/converter2/issues/gh2207/index.ts @@ -1,2 +1,2 @@ -export * as Mod from "./mod"; +export * as Mod from "./mod.js"; export const a = 1; diff --git a/src/test/declarationReference.test.ts b/src/test/declarationReference.test.ts index cd8a5997f..578654cb6 100644 --- a/src/test/declarationReference.test.ts +++ b/src/test/declarationReference.test.ts @@ -7,7 +7,7 @@ import { parseModuleSource, parseString, parseSymbolReference, -} from "../lib/converter/comments/declarationReference"; +} from "../lib/converter/comments/declarationReference.js"; describe("Declaration References", () => { describe("String parsing", () => { diff --git a/src/test/events.test.ts b/src/test/events.test.ts index 4e74b18dd..9e1b29bc4 100644 --- a/src/test/events.test.ts +++ b/src/test/events.test.ts @@ -8,7 +8,7 @@ // https://github.com/jashkenas/backbone/blob/6b927eb5e7081af16f97d9c15e34b030624a68f9/test/events.js import Assert = require("assert"); -import { EventDispatcher, Event } from "../lib/utils/events"; +import { EventDispatcher, Event } from "../lib/utils/events.js"; function size(thing: any): number { if (!thing) return 0; diff --git a/src/test/internationalization.test.ts b/src/test/internationalization.test.ts index a46de0c62..616f9a2ef 100644 --- a/src/test/internationalization.test.ts +++ b/src/test/internationalization.test.ts @@ -1,7 +1,9 @@ import { deepEqual as equal, ok } from "assert/strict"; -import { Application } from ".."; +import { Application } from "../index.js"; import { readdirSync } from "fs"; import { join } from "path"; +import { fileURLToPath } from "url"; +import { createRequire } from "module"; describe("Internationalization", async () => { const app = await Application.bootstrap({}, []); @@ -34,12 +36,16 @@ describe("Internationalization", async () => { }); describe("Locales", () => { - const localeRoot = join(__dirname, "../lib/internationalization/locales"); + const localeRoot = join( + fileURLToPath(import.meta.url), + "../../lib/internationalization/locales", + ); for (const locale of readdirSync(localeRoot)) { it(`${locale} defines a valid locale`, () => { + const req = createRequire(fileURLToPath(import.meta.url)); // eslint-disable-next-line @typescript-eslint/no-var-requires - const translations = require(join(localeRoot, locale)) as Record< + const translations = req(join(localeRoot, locale)) as Record< string, string >; diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 3662ba758..b30d6783e 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -5,7 +5,7 @@ import { } from "assert"; import { existsSync } from "fs"; import { join } from "path"; -import { clearCommentCache } from "../lib/converter/comments"; +import { clearCommentCache } from "../lib/converter/comments/index.js"; import { Comment, CommentTag, @@ -19,16 +19,16 @@ import { ReflectionType, SignatureReflection, UnionType, -} from "../lib/models"; -import type { InlineTagDisplayPart } from "../lib/models/comments/comment"; +} from "../lib/models/index.js"; +import type { InlineTagDisplayPart } from "../lib/models/comments/comment.js"; import { getConverter2App, getConverter2Base, getConverter2Program, -} from "./programs"; -import { TestLogger } from "./TestLogger"; -import { getComment, getLinks, query, querySig } from "./utils"; -import { DefaultTheme, PageEvent } from ".."; +} from "./programs.js"; +import { TestLogger } from "./TestLogger.js"; +import { getComment, getLinks, query, querySig } from "./utils.js"; +import { DefaultTheme, PageEvent } from "../index.js"; const base = getConverter2Base(); const app = getConverter2App(); diff --git a/src/test/merge.test.ts b/src/test/merge.test.ts index e4c023564..5b0c582c1 100644 --- a/src/test/merge.test.ts +++ b/src/test/merge.test.ts @@ -5,9 +5,9 @@ import { DeclarationReflection, EntryPointStrategy, ReferenceType, -} from "../index"; -import { getConverterBase } from "./programs"; -import { TestLogger } from "./TestLogger"; +} from "../index.js"; +import { getConverterBase } from "./programs.js"; +import { TestLogger } from "./TestLogger.js"; const base = getConverterBase(); diff --git a/src/test/models/comment.test.ts b/src/test/models/comment.test.ts index 3cbdb735a..142894eca 100644 --- a/src/test/models/comment.test.ts +++ b/src/test/models/comment.test.ts @@ -1,5 +1,5 @@ import { deepStrictEqual as equal } from "assert"; -import { Comment, CommentDisplayPart } from "../../index"; +import { Comment, type CommentDisplayPart } from "../../index.js"; describe("Comment.combineDisplayParts", () => { it("Handles text and code", () => { diff --git a/src/test/models/types.test.ts b/src/test/models/types.test.ts index 21c1dff5b..23e79801d 100644 --- a/src/test/models/types.test.ts +++ b/src/test/models/types.test.ts @@ -1,8 +1,8 @@ // Tests the `toString` functionality of the type models -import * as T from "../../lib/models/types"; +import * as T from "../../lib/models/types.js"; import { strictEqual as equal } from "assert"; -import { ProjectReflection } from "../../lib/models"; +import { ProjectReflection } from "../../lib/models/index.js"; describe("Type.toString", () => { describe("Union types", () => { diff --git a/src/test/module/a.ts b/src/test/module/a.ts index 0ff251064..a6a87fa9c 100644 --- a/src/test/module/a.ts +++ b/src/test/module/a.ts @@ -1,4 +1,4 @@ -import { multiply } from "./b"; +import { multiply } from "./b.js"; export function add(a: number, b: number) { return a + multiply(b, 1); diff --git a/src/test/packages.test.ts b/src/test/packages.test.ts index e40a568a3..f99401099 100644 --- a/src/test/packages.test.ts +++ b/src/test/packages.test.ts @@ -1,11 +1,11 @@ import { deepStrictEqual as equal } from "assert"; import { join } from "path"; -import { normalizePath } from "../lib/utils"; -import { expandPackages } from "../lib/utils/package-manifest"; +import { normalizePath } from "../lib/utils/index.js"; +import { expandPackages } from "../lib/utils/package-manifest.js"; import { tempdirProject } from "@typestrong/fs-fixture-builder"; -import { TestLogger } from "./TestLogger"; -import { createMinimatch } from "../lib/utils/paths"; +import { TestLogger } from "./TestLogger.js"; +import { createMinimatch } from "../lib/utils/paths.js"; describe("Packages support", () => { let project: ReturnType; diff --git a/src/test/programs.ts b/src/test/programs.ts index 63055f0ea..21e4d753c 100644 --- a/src/test/programs.ts +++ b/src/test/programs.ts @@ -8,9 +8,9 @@ import { ProjectReflection, SourceReference, TSConfigReader, -} from ".."; -import type { ModelToObject } from "../lib/serialization/schema"; -import { createAppForTesting } from "../lib/application"; +} from "../index.js"; +import type { ModelToObject } from "../lib/serialization/schema.js"; +import { createAppForTesting } from "../lib/application.js"; let converterApp: Application | undefined; let converterProgram: ts.Program | undefined; diff --git a/src/test/project.test.ts b/src/test/project.test.ts index 7a40447db..6a1f6b893 100644 --- a/src/test/project.test.ts +++ b/src/test/project.test.ts @@ -1,4 +1,4 @@ -import { splitUnquotedString } from ".."; +import { splitUnquotedString } from "../index.js"; import Assert = require("assert"); describe("Project", function () { diff --git a/src/test/renderer/testProject/src/mod2.ts b/src/test/renderer/testProject/src/mod2.ts index c3cd0d5e3..5c243d153 100644 --- a/src/test/renderer/testProject/src/mod2.ts +++ b/src/test/renderer/testProject/src/mod2.ts @@ -1,4 +1,4 @@ -export * from "./mod"; +export * from "./mod.js"; /** * Will be exported from mod2, unlike the default function in mod diff --git a/src/test/slow/entry-point.test.ts b/src/test/slow/entry-point.test.ts index 14b7837ea..556d97e1e 100644 --- a/src/test/slow/entry-point.test.ts +++ b/src/test/slow/entry-point.test.ts @@ -1,7 +1,7 @@ import { tempdirProject } from "@typestrong/fs-fixture-builder"; import { deepStrictEqual as equal, ok } from "assert"; import { join } from "path"; -import { Application, EntryPointStrategy } from "../.."; +import { Application, EntryPointStrategy } from "../../index.js"; const fixture = tempdirProject(); fixture.addJsonFile("tsconfig.json", { diff --git a/src/test/slow/internationalization-usage.test.ts b/src/test/slow/internationalization-usage.test.ts index 76a87521b..528452ec6 100644 --- a/src/test/slow/internationalization-usage.test.ts +++ b/src/test/slow/internationalization-usage.test.ts @@ -1,9 +1,10 @@ import ts from "typescript"; import { ok } from "assert/strict"; -import { Logger, Options, TSConfigReader } from "../.."; +import { Logger, Options, TSConfigReader } from "../../index.js"; import { join } from "path"; import { existsSync, readFileSync } from "fs"; -import { Internationalization } from "../../lib/internationalization/internationalization"; +import { Internationalization } from "../../lib/internationalization/internationalization.js"; +import { fileURLToPath } from "url"; describe("Internationalization", () => { it("Does not include strings in translatable object which are unused", () => { @@ -12,8 +13,8 @@ describe("Internationalization", () => { tsconfigReader.read(options, new Logger(), process.cwd()); const translatableTs = join( - __dirname, - "../../lib/internationalization/translatable.ts", + fileURLToPath(import.meta.url), + "../../../lib/internationalization/translatable.ts", ); const host: ts.LanguageServiceHost = { diff --git a/src/test/utils.ts b/src/test/utils.ts index 53a630372..15d52bd3c 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -6,8 +6,8 @@ import { Reflection, ReflectionKind, SignatureReflection, -} from ".."; -import { filterMap } from "../lib/utils"; +} from "../index.js"; +import { filterMap } from "../lib/utils/index.js"; export function query( project: ProjectReflection, diff --git a/src/test/utils/array.test.ts b/src/test/utils/array.test.ts index e7bf939d4..83e486a8f 100644 --- a/src/test/utils/array.test.ts +++ b/src/test/utils/array.test.ts @@ -4,7 +4,7 @@ import { insertOrderSorted, insertPrioritySorted, removeIfPresent, -} from "../../lib/utils/array"; +} from "../../lib/utils/array.js"; describe("Array utils", () => { describe("insertPrioritySorted", () => { diff --git a/src/test/utils/enum.test.ts b/src/test/utils/enum.test.ts index 4dfde4052..515c608ee 100644 --- a/src/test/utils/enum.test.ts +++ b/src/test/utils/enum.test.ts @@ -1,6 +1,6 @@ import { ok } from "assert"; -import { ReflectionKind } from "../../lib/models"; -import { getEnumKeys } from "../../lib/utils/enum"; +import { ReflectionKind } from "../../lib/models/index.js"; +import { getEnumKeys } from "../../lib/utils/enum.js"; describe("Enum utils", () => { it("Should be able to get enum keys", () => { diff --git a/src/test/utils/fs.test.ts b/src/test/utils/fs.test.ts index 3c517c6e8..387adef15 100644 --- a/src/test/utils/fs.test.ts +++ b/src/test/utils/fs.test.ts @@ -1,9 +1,9 @@ import * as fs from "fs"; import { createServer } from "net"; -import { Project, tempdirProject } from "@typestrong/fs-fixture-builder"; +import { type Project, tempdirProject } from "@typestrong/fs-fixture-builder"; import { AssertionError, deepStrictEqual as equal } from "assert"; import { basename, dirname, resolve, normalize } from "path"; -import { getCommonDirectory, glob } from "../../lib/utils/fs"; +import { getCommonDirectory, glob } from "../../lib/utils/fs.js"; describe("fs.ts", () => { let fix: Project; diff --git a/src/test/utils/hooks.test.ts b/src/test/utils/hooks.test.ts index 180b44624..6a682e55e 100644 --- a/src/test/utils/hooks.test.ts +++ b/src/test/utils/hooks.test.ts @@ -1,5 +1,5 @@ import { deepStrictEqual as equal } from "assert"; -import { EventHooks } from "../../lib/utils/hooks"; +import { EventHooks } from "../../lib/utils/hooks.js"; describe("EventHooks", () => { it("Works in simple cases", () => { diff --git a/src/test/utils/html.test.ts b/src/test/utils/html.test.ts index af0180f77..64506db38 100644 --- a/src/test/utils/html.test.ts +++ b/src/test/utils/html.test.ts @@ -1,5 +1,6 @@ import { strictEqual as equal } from "assert"; -import { getTextContent } from "../../lib/utils/html"; +import html from "../../lib/utils/html.cjs"; +const { getTextContent } = html; describe("getTextContent", () => { it("Handles simple text", () => { diff --git a/src/test/utils/jsx.test.tsx b/src/test/utils/jsx.test.tsx index 214521a6f..31a7083a0 100644 --- a/src/test/utils/jsx.test.tsx +++ b/src/test/utils/jsx.test.tsx @@ -1,5 +1,5 @@ import { deepStrictEqual as equal } from "assert"; -import { JSX, renderElement, Raw } from "../../lib/utils"; +import { JSX, renderElement, Raw } from "../../lib/utils/index.js"; describe("JSX", () => { it("Works with basic case", () => { diff --git a/src/test/utils/languageAliases.test.ts b/src/test/utils/languageAliases.test.ts index e1f13adca..b4bdc380f 100644 --- a/src/test/utils/languageAliases.test.ts +++ b/src/test/utils/languageAliases.test.ts @@ -1,5 +1,5 @@ import { deepStrictEqual as equal } from "assert"; -import { isSupportedLanguage } from "../../lib/utils/highlighter"; +import { isSupportedLanguage } from "../../lib/utils/highlighter.js"; describe("Language aliases", () => { describe("Original language aliases", () => { diff --git a/src/test/utils/minimalSourceFile.test.ts b/src/test/utils/minimalSourceFile.test.ts index a45c07d3a..74ce4833d 100644 --- a/src/test/utils/minimalSourceFile.test.ts +++ b/src/test/utils/minimalSourceFile.test.ts @@ -1,6 +1,6 @@ import { deepStrictEqual as equal, throws } from "assert"; import type { LineAndCharacter } from "typescript"; -import { MinimalSourceFile } from "../../lib/utils/minimalSourceFile"; +import { MinimalSourceFile } from "../../lib/utils/minimalSourceFile.js"; describe("MinimalSourceFile", () => { it("Should do bounds checking", () => { diff --git a/src/test/utils/options/declaration.test.ts b/src/test/utils/options/declaration.test.ts index 71a86375c..0ce79f752 100644 --- a/src/test/utils/options/declaration.test.ts +++ b/src/test/utils/options/declaration.test.ts @@ -1,18 +1,18 @@ import { deepStrictEqual as equal, ok, throws } from "assert"; import { join, resolve } from "path"; import { - ArrayDeclarationOption, + type ArrayDeclarationOption, convert, - DeclarationOption, + type DeclarationOption, getDefaultValue, - MapDeclarationOption, - MixedDeclarationOption, - ObjectDeclarationOption, - NumberDeclarationOption, + type MapDeclarationOption, + type MixedDeclarationOption, + type ObjectDeclarationOption, + type NumberDeclarationOption, ParameterType, - StringDeclarationOption, -} from "../../../lib/utils/options/declaration"; -import { Internationalization } from "../../../lib/internationalization/internationalization"; + type StringDeclarationOption, +} from "../../../lib/utils/options/declaration.js"; +import { Internationalization } from "../../../lib/internationalization/internationalization.js"; const emptyHelp = () => ""; diff --git a/src/test/utils/options/default-options.test.ts b/src/test/utils/options/default-options.test.ts index 9d3604845..4463aec3f 100644 --- a/src/test/utils/options/default-options.test.ts +++ b/src/test/utils/options/default-options.test.ts @@ -1,7 +1,7 @@ import { ok, throws, strictEqual, doesNotThrow } from "assert"; import { BUNDLED_THEMES } from "shiki"; -import { Options } from "../../../lib/utils"; -import { Internationalization } from "../../../lib/internationalization/internationalization"; +import { Options } from "../../../lib/utils/index.js"; +import { Internationalization } from "../../../lib/internationalization/internationalization.js"; describe("Default Options", () => { const opts = new Options(new Internationalization(null).proxy); diff --git a/src/test/utils/options/help.test.ts b/src/test/utils/options/help.test.ts index b57e2bb2a..fcc2a6e8a 100644 --- a/src/test/utils/options/help.test.ts +++ b/src/test/utils/options/help.test.ts @@ -1,8 +1,12 @@ import { ok } from "assert"; -import { Options, ParameterType, ParameterHint } from "../../../lib/utils"; -import { getOptionsHelp } from "../../../lib/utils/options/help"; -import { Internationalization } from "../../../lib/internationalization/internationalization"; +import { + Options, + ParameterType, + ParameterHint, +} from "../../../lib/utils/index.js"; +import { getOptionsHelp } from "../../../lib/utils/options/help.js"; +import { Internationalization } from "../../../lib/internationalization/internationalization.js"; describe("Options - help", () => { const i18n = new Internationalization(null).proxy; diff --git a/src/test/utils/options/options.test.ts b/src/test/utils/options/options.test.ts index 1144006f9..d1cc791f5 100644 --- a/src/test/utils/options/options.test.ts +++ b/src/test/utils/options/options.test.ts @@ -1,15 +1,15 @@ -import { LogLevel, Options, ParameterType } from "../../../lib/utils"; +import { LogLevel, Options, ParameterType } from "../../../lib/utils/index.js"; import { Option, - MapDeclarationOption, - NumberDeclarationOption, -} from "../../../lib/utils"; + type MapDeclarationOption, + type NumberDeclarationOption, +} from "../../../lib/utils/index.js"; import { deepStrictEqual as equal, throws } from "assert"; import type { DeclarationOption, EmitStrategy, -} from "../../../lib/utils/options"; -import { Internationalization } from "../../../lib/internationalization/internationalization"; +} from "../../../lib/utils/options/index.js"; +import { Internationalization } from "../../../lib/internationalization/internationalization.js"; describe("Options", () => { let options: Options & { diff --git a/src/test/utils/options/readers/arguments.test.ts b/src/test/utils/options/readers/arguments.test.ts index 41d3af22f..fc2be4fdf 100644 --- a/src/test/utils/options/readers/arguments.test.ts +++ b/src/test/utils/options/readers/arguments.test.ts @@ -1,15 +1,15 @@ import { deepStrictEqual as equal } from "assert"; -import { Options } from "../../../../lib/utils"; -import { ArgumentsReader } from "../../../../lib/utils/options/readers"; +import { Options } from "../../../../lib/utils/index.js"; +import { ArgumentsReader } from "../../../../lib/utils/options/readers/index.js"; import { ParameterType, - NumberDeclarationOption, - MapDeclarationOption, -} from "../../../../lib/utils/options"; + type NumberDeclarationOption, + type MapDeclarationOption, +} from "../../../../lib/utils/options/index.js"; import { join, resolve } from "path"; -import { TestLogger } from "../../../TestLogger"; -import { Internationalization } from "../../../../lib/internationalization/internationalization"; +import { TestLogger } from "../../../TestLogger.js"; +import { Internationalization } from "../../../../lib/internationalization/internationalization.js"; const emptyHelp = () => ""; diff --git a/src/test/utils/options/readers/package-json.test.ts b/src/test/utils/options/readers/package-json.test.ts index 6cf45a188..7b19573d8 100644 --- a/src/test/utils/options/readers/package-json.test.ts +++ b/src/test/utils/options/readers/package-json.test.ts @@ -1,9 +1,9 @@ import { project } from "@typestrong/fs-fixture-builder"; -import { PackageJsonReader } from "../../../../lib/utils/options/readers"; -import { Options } from "../../../../lib/utils"; -import { TestLogger } from "../../../TestLogger"; -import { Internationalization } from "../../../../lib/internationalization/internationalization"; +import { PackageJsonReader } from "../../../../lib/utils/options/readers/index.js"; +import { Options } from "../../../../lib/utils/index.js"; +import { TestLogger } from "../../../TestLogger.js"; +import { Internationalization } from "../../../../lib/internationalization/internationalization.js"; describe("Options - PackageJsonReader", () => { let optsContainer: Options; diff --git a/src/test/utils/options/readers/tsconfig.test.ts b/src/test/utils/options/readers/tsconfig.test.ts index cd1334dd2..71b6ddb68 100644 --- a/src/test/utils/options/readers/tsconfig.test.ts +++ b/src/test/utils/options/readers/tsconfig.test.ts @@ -1,12 +1,13 @@ import { basename, join } from "path"; import { deepStrictEqual as equal } from "assert"; -import { TSConfigReader } from "../../../../lib/utils/options/readers"; -import { Logger, Options } from "../../../../lib/utils"; -import { TestLogger } from "../../../TestLogger"; -import { tempdirProject, Project } from "@typestrong/fs-fixture-builder"; +import { TSConfigReader } from "../../../../lib/utils/options/readers/index.js"; +import { Logger, Options } from "../../../../lib/utils/index.js"; +import { TestLogger } from "../../../TestLogger.js"; +import { tempdirProject, type Project } from "@typestrong/fs-fixture-builder"; import { tmpdir } from "os"; -import { Internationalization } from "../../../../lib/internationalization/internationalization"; +import { Internationalization } from "../../../../lib/internationalization/internationalization.js"; +import { fileURLToPath } from "url"; describe("Options - TSConfigReader", () => { const options = new Options(new Internationalization(null).proxy); @@ -93,7 +94,7 @@ describe("Options - TSConfigReader", () => { options.setValue( "tsconfig", - join(__dirname, "data/does_not_exist.json"), + join(fileURLToPath(import.meta.url), "../data/does_not_exist.json"), ); options.addReader(new TSConfigReader()); await options.read(logger); diff --git a/src/test/utils/options/readers/typedoc.test.ts b/src/test/utils/options/readers/typedoc.test.ts index 0fbe9f3c2..1ba6230e3 100644 --- a/src/test/utils/options/readers/typedoc.test.ts +++ b/src/test/utils/options/readers/typedoc.test.ts @@ -1,11 +1,11 @@ import { deepStrictEqual as equal } from "assert"; import { project as fsProject } from "@typestrong/fs-fixture-builder"; -import { TypeDocReader } from "../../../../lib/utils/options/readers"; -import { Logger, Options } from "../../../../lib/utils"; -import { TestLogger } from "../../../TestLogger"; +import { TypeDocReader } from "../../../../lib/utils/options/readers/index.js"; +import { Logger, Options } from "../../../../lib/utils/index.js"; +import { TestLogger } from "../../../TestLogger.js"; import { join } from "path"; -import { Internationalization } from "../../../../lib/internationalization/internationalization"; +import { Internationalization } from "../../../../lib/internationalization/internationalization.js"; describe("Options - TypeDocReader", () => { const options = new Options(new Internationalization(null).proxy); @@ -48,9 +48,24 @@ describe("Options - TypeDocReader", () => { equal(options.getValue("gitRevision"), "master"); }); - it("Supports js files", async () => { + it("Supports CommonJS files", async () => { const project = fsProject("js"); - project.addFile("typedoc.js", "module.exports = { name: 'js' }"); + project.addFile("typedoc.cjs", "module.exports = { name: 'js' }"); + const logger = new TestLogger(); + + project.write(); + options.reset(); + options.setValue("options", project.cwd); + await options.read(logger); + project.rm(); + + logger.expectNoOtherMessages(); + equal(options.getValue("name"), "js"); + }); + + it("Supports ESM files", async () => { + const project = fsProject("js"); + project.addFile("typedoc.mjs", "export default { name: 'js' }"); const logger = new TestLogger(); project.write(); diff --git a/src/test/utils/plugins.test.ts b/src/test/utils/plugins.test.ts index 32ef16bf3..15834f1f9 100644 --- a/src/test/utils/plugins.test.ts +++ b/src/test/utils/plugins.test.ts @@ -1,9 +1,9 @@ -import { Project, tempdirProject } from "@typestrong/fs-fixture-builder"; -import type { Application } from "../../index"; -import { loadPlugins } from "../../lib/utils/plugins"; -import { TestLogger } from "../TestLogger"; +import { type Project, tempdirProject } from "@typestrong/fs-fixture-builder"; +import type { Application } from "../../index.js"; +import { loadPlugins } from "../../lib/utils/plugins.js"; +import { TestLogger } from "../TestLogger.js"; import { join, resolve } from "path"; -import { Internationalization } from "../../lib/internationalization/internationalization"; +import { Internationalization } from "../../lib/internationalization/internationalization.js"; describe("loadPlugins", () => { let project: Project; @@ -28,7 +28,7 @@ describe("loadPlugins", () => { project.addFile("index.js", "exports.load = function load() {}"); project.write(); - const plugin = resolve(project.cwd); + const plugin = resolve(project.cwd, "index.js"); await loadPlugins(fakeApp, [plugin]); logger.expectMessage(`info: Loaded plugin ${plugin}`); }); diff --git a/src/test/utils/sort.test.ts b/src/test/utils/sort.test.ts index 16a4f4126..e8a29ec56 100644 --- a/src/test/utils/sort.test.ts +++ b/src/test/utils/sort.test.ts @@ -6,11 +6,11 @@ import { ReflectionFlag, ReflectionKind, ReflectionSymbolId, -} from "../../lib/models"; -import { resetReflectionID } from "../../lib/models/reflections/abstract"; -import { Options } from "../../lib/utils"; -import { getSortFunction, SortStrategy } from "../../lib/utils/sort"; -import { Internationalization } from "../../lib/internationalization/internationalization"; +} from "../../lib/models/index.js"; +import { resetReflectionID } from "../../lib/models/reflections/abstract.js"; +import { Options } from "../../lib/utils/index.js"; +import { getSortFunction, type SortStrategy } from "../../lib/utils/sort.js"; +import { Internationalization } from "../../lib/internationalization/internationalization.js"; describe("Sort", () => { function sortReflections( diff --git a/src/test/utils/validation.test.ts b/src/test/utils/validation.test.ts index 046f61d56..da2a2b45f 100644 --- a/src/test/utils/validation.test.ts +++ b/src/test/utils/validation.test.ts @@ -1,6 +1,6 @@ import { ok } from "assert"; -import { Validation } from "../../lib/utils"; -import { additionalProperties } from "../../lib/utils/validation"; +import { Validation } from "../../lib/utils/index.js"; +import { additionalProperties } from "../../lib/utils/validation.js"; describe("Validation Utils", () => { it("Should be able to validate optional values", () => { diff --git a/src/test/validation.test.ts b/src/test/validation.test.ts index bab7e4b02..f82ce9877 100644 --- a/src/test/validation.test.ts +++ b/src/test/validation.test.ts @@ -1,15 +1,16 @@ import { ok } from "assert"; import { join } from "path"; -import { validateDocumentation } from "../lib/validation/documentation"; -import { validateExports } from "../lib/validation/exports"; -import { getConverter2App, getConverter2Program } from "./programs"; -import { TestLogger } from "./TestLogger"; +import { validateDocumentation } from "../lib/validation/documentation.js"; +import { validateExports } from "../lib/validation/exports.js"; +import { getConverter2App, getConverter2Program } from "./programs.js"; +import { TestLogger } from "./TestLogger.js"; +import { fileURLToPath } from "url"; function convertValidationFile(file: string) { const app = getConverter2App(); const program = getConverter2Program(); const sourceFile = program.getSourceFile( - join(__dirname, "converter2/validation", file), + join(fileURLToPath(import.meta.url), "../converter2/validation", file), ); ok(sourceFile, "Specified source file does not exist."); @@ -48,7 +49,7 @@ function expectNoWarning( const app = getConverter2App(); const program = getConverter2Program(); const sourceFile = program.getSourceFile( - join(__dirname, "converter2/validation", file), + join(fileURLToPath(import.meta.url), "../converter2/validation", file), ); ok(sourceFile, "Specified source file does not exist."); @@ -126,7 +127,10 @@ describe("validateExports", () => { const app = getConverter2App(); const program = getConverter2Program(); const sourceFile = program.getSourceFile( - join(__dirname, "converter2/validation/variable.ts"), + join( + fileURLToPath(import.meta.url), + "../converter2/validation/variable.ts", + ), ); ok(sourceFile, "Specified source file does not exist."); diff --git a/tsconfig.json b/tsconfig.json index 5de076553..20f9b51e9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,8 +38,7 @@ // TS 5 introduced verbatimModuleSyntax and deprecated importsNotUsedAsValues // But that flag is intentionally very unfriendly to projects emitting CommonJS // so for now, we're going to ignore that deprecation. - "ignoreDeprecations": "5.0", - "importsNotUsedAsValues": "error", + "verbatimModuleSyntax": true, "isolatedModules": true }, "include": ["src"], @@ -56,6 +55,8 @@ ], // We use ts-node to support mocha runner directly on files "ts-node": { - "transpileOnly": true + "transpileOnly": true, + "esm": true, + "preferTsExts": true } } From b2c6b236d7e4f10e1fe6e84aada5dd30d2d99102 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 15:02:31 -0600 Subject: [PATCH 002/219] Update tsx --- package-lock.json | 235 ++++++++++++++++++++++----------------- package.json | 2 +- src/test/events.test.ts | 2 +- src/test/project.test.ts | 2 +- 4 files changed, 134 insertions(+), 107 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13b0e87d0..9ea88db4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "prettier": "3.0.3", "puppeteer": "^13.5.2", "ts-node": "^10.9.2", - "tsx": "^4.7.3", + "tsx": "^4.15.7", "typescript": "5.4.2" }, "engines": { @@ -1867,10 +1867,11 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", - "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", + "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", "dev": true, + "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -2880,6 +2881,7 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -3309,13 +3311,14 @@ } }, "node_modules/tsx": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.3.tgz", - "integrity": "sha512-+fQnMqIp/jxZEXLcj6WzYy9FhcS5/Dfk8y4AtzJ6ejKcKqmfTF8Gso/jtrzDggCF2zTU20gJa6n8XqPYwDAUYQ==", + "version": "4.15.7", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.15.7.tgz", + "integrity": "sha512-u3H0iSFDZM3za+VxkZ1kywdCeHCn+8/qHQS1MNoO2sONDgD95HlWtt8aB23OzeTmFP9IU4/8bZUdg58Uu5J4cg==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "~0.19.10", - "get-tsconfig": "^4.7.2" + "esbuild": "~0.21.4", + "get-tsconfig": "^4.7.5" }, "bin": { "tsx": "dist/cli.mjs" @@ -3328,13 +3331,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", - "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -3344,13 +3348,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", - "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -3360,13 +3365,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", - "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -3376,13 +3382,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", - "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -3392,13 +3399,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3408,13 +3416,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", - "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3424,13 +3433,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", - "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3440,13 +3450,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", - "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -3456,13 +3467,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", - "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3472,13 +3484,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", - "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3488,13 +3501,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", - "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3504,13 +3518,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", - "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3520,13 +3535,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", - "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3536,13 +3552,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", - "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3552,13 +3569,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", - "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3568,13 +3586,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", - "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3584,13 +3603,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", - "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -3600,13 +3620,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", - "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -3616,13 +3637,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", - "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -3632,13 +3654,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", - "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -3648,13 +3671,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", - "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3664,13 +3688,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", - "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3680,13 +3705,14 @@ } }, "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", - "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -3696,11 +3722,12 @@ } }, "node_modules/tsx/node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -3708,29 +3735,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/type-check": { diff --git a/package.json b/package.json index cc4885a00..b96b126f8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "prettier": "3.0.3", "puppeteer": "^13.5.2", "ts-node": "^10.9.2", - "tsx": "^4.7.3", + "tsx": "^4.15.7", "typescript": "5.4.2" }, "files": [ diff --git a/src/test/events.test.ts b/src/test/events.test.ts index 9e1b29bc4..2d2a930ad 100644 --- a/src/test/events.test.ts +++ b/src/test/events.test.ts @@ -7,7 +7,7 @@ // This test case was taken from // https://github.com/jashkenas/backbone/blob/6b927eb5e7081af16f97d9c15e34b030624a68f9/test/events.js -import Assert = require("assert"); +import Assert from "assert"; import { EventDispatcher, Event } from "../lib/utils/events.js"; function size(thing: any): number { diff --git a/src/test/project.test.ts b/src/test/project.test.ts index 6a1f6b893..9fc79ba33 100644 --- a/src/test/project.test.ts +++ b/src/test/project.test.ts @@ -1,5 +1,5 @@ import { splitUnquotedString } from "../index.js"; -import Assert = require("assert"); +import Assert from "assert"; describe("Project", function () { describe("splitUnquotedString", () => { From da4497fa6a05070a00e4c4217067b495ffb7f8f6 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 16:46:58 -0600 Subject: [PATCH 003/219] Fix most compiler errors --- src/lib/application.ts | 1 - src/lib/converter/comments/textParser.ts | 10 +- src/lib/internationalization/index.ts | 2 +- .../internationalization.ts | 9 +- src/lib/internationalization/locale-utils.cts | 2 +- src/lib/internationalization/locales/en.cts | 388 ++++++++------ src/lib/internationalization/locales/jp.cts | 4 +- src/lib/internationalization/locales/ko.cts | 4 +- src/lib/internationalization/locales/zh.cts | 6 +- src/lib/internationalization/translatable.ts | 493 +----------------- src/lib/models/FileRegistry.ts | 8 +- src/lib/models/reflections/document.ts | 12 +- src/lib/output/plugins/SitemapPlugin.ts | 4 +- .../themes/default/templates/document.tsx | 8 +- src/lib/utils/events.ts | 2 +- src/lib/utils/jsx.ts | 3 +- src/test/internationalization.test.ts | 5 +- src/test/utils/options/tsdoc-defaults.test.ts | 2 +- src/test/utils/path.test.ts | 2 +- 19 files changed, 265 insertions(+), 700 deletions(-) diff --git a/src/lib/application.ts b/src/lib/application.ts index c5023d67b..580b0e334 100644 --- a/src/lib/application.ts +++ b/src/lib/application.ts @@ -56,7 +56,6 @@ import { readFileSync } from "fs"; import { fileURLToPath } from "url"; import { createRequire } from "module"; -// eslint-disable-next-line @typescript-eslint/no-var-requires const packageInfo = JSON.parse( readFileSync( Path.join(fileURLToPath(import.meta.url), "../../../package.json"), diff --git a/src/lib/converter/comments/textParser.ts b/src/lib/converter/comments/textParser.ts index 24dea70a4..bde33428d 100644 --- a/src/lib/converter/comments/textParser.ts +++ b/src/lib/converter/comments/textParser.ts @@ -8,11 +8,11 @@ import type { TranslationProxy, TranslatedString, -} from "../../internationalization"; -import type { CommentDisplayPart } from "../../models"; -import type { FileRegistry } from "../../models/FileRegistry"; -import { HtmlAttributeParser, ParserState } from "../../utils/html"; -import { type Token, TokenSyntaxKind } from "./lexer"; +} from "../../internationalization/index.js"; +import type { CommentDisplayPart } from "../../models/index.js"; +import type { FileRegistry } from "../../models/FileRegistry.js"; +import { HtmlAttributeParser, ParserState } from "../../utils/html.js"; +import { type Token, TokenSyntaxKind } from "./lexer.js"; import MarkdownIt from "markdown-it"; const MdHelpers = new MarkdownIt().helpers; diff --git a/src/lib/internationalization/index.ts b/src/lib/internationalization/index.ts index c9a6f3d4e..3c0430d11 100644 --- a/src/lib/internationalization/index.ts +++ b/src/lib/internationalization/index.ts @@ -9,4 +9,4 @@ export { Internationalization, type TranslatedString, type TranslationProxy, -} from "./internationalization"; +} from "./internationalization.js"; diff --git a/src/lib/internationalization/internationalization.ts b/src/lib/internationalization/internationalization.ts index 547d04a50..ffb5a856c 100644 --- a/src/lib/internationalization/internationalization.ts +++ b/src/lib/internationalization/internationalization.ts @@ -5,6 +5,10 @@ import { readdirSync } from "fs"; import { join } from "path"; import { ReflectionKind } from "../models/reflections/kind.js"; import { ReflectionFlag } from "../models/index.js"; +import { type BuiltinTranslatableStringArgs } from "./translatable.js"; +import translatable from "./locales/en.cjs"; +import { createRequire } from "node:module"; +import { fileURLToPath } from "node:url"; /** * ### What is translatable? @@ -76,10 +80,7 @@ export class Internationalization { "Locale names may only contain letters and dashes", ); try { - return new Map( - // eslint-disable-next-line @typescript-eslint/no-var-requires - Object.entries(req(`./locales/${lang}.${ext}`)), - ); + return new Map(Object.entries(req(`./locales/${lang}.${ext}`))); } catch { return new Map(); } diff --git a/src/lib/internationalization/locale-utils.cts b/src/lib/internationalization/locale-utils.cts index c9cf87ae1..13ce78441 100644 --- a/src/lib/internationalization/locale-utils.cts +++ b/src/lib/internationalization/locale-utils.cts @@ -1,4 +1,4 @@ -import type { BuiltinTranslatableStringConstraints } from "./translatable.js" with { "resolution-mode": "import" } +import type { BuiltinTranslatableStringConstraints } from "./translatable.js" with { "resolution-mode": "import" }; function buildTranslation( translations: T, diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 102c7a415..1e2dace58 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -1,51 +1,63 @@ +// This one is the source of truth, so looks a bit different from the other locales, look at another one +// for a template to follow. + export = { loaded_multiple_times_0: "TypeDoc has been loaded multiple times. This is commonly caused by plugins which have their own installation of TypeDoc. The loaded paths are:\n\t{0}", unsupported_ts_version_0: "You are running with an unsupported TypeScript version! If TypeDoc crashes, this is why. TypeDoc supports {0}", no_compiler_options_set: - "No compiler options set. This likely means that TypeDoc did not find your tsconfig.json. Generated documentation will probably be empty.", + "No compiler options set. This likely means that TypeDoc did not find your tsconfig.json. Generated documentation will probably be empty", loaded_plugin_0: `Loaded plugin {0}`, solution_not_supported_in_watch_mode: - "The provided tsconfig file looks like a solution style tsconfig, which is not supported in watch mode.", + "The provided tsconfig file looks like a solution style tsconfig, which is not supported in watch mode", strategy_not_supported_in_watch_mode: - "entryPointStrategy must be set to either resolve or expand for watch mode.", + "entryPointStrategy must be set to either resolve or expand for watch mode", + found_0_errors_and_1_warnings: "Found {0} errors and {1} warnings", docs_could_not_be_generated: - "Documentation could not be generated due to the errors above.", + "Documentation could not be generated due to the errors above", docs_generated_at_0: "Documentation generated at {0}", json_written_to_0: "JSON written to {0}", no_entry_points_for_packages: - "No entry points provided to packages mode, documentation cannot be generated.", + "No entry points provided to packages mode, documentation cannot be generated", failed_to_find_packages: "Failed to find any packages, ensure you have provided at least one directory as an entry point containing package.json", nested_packages_unsupported_0: - "Project at {0} has entryPointStrategy set to packages, but nested packages are not supported.", + "Project at {0} has entryPointStrategy set to packages, but nested packages are not supported", + previous_error_occurred_when_reading_options_for_0: + "The previous error occurred when reading options for the package at {0}", converting_project_at_0: "Converting project at {0}", failed_to_convert_packages: - "Failed to convert one or more packages, result will not be merged together.", + "Failed to convert one or more packages, result will not be merged together", merging_converted_projects: "Merging converted projects", - no_entry_points_to_merge: "No entry points provided to merge.", + no_entry_points_to_merge: "No entry points provided to merge", entrypoint_did_not_match_files_0: - "The entrypoint glob {0} did not match any files.", - failed_to_parse_json_0: `Failed to parse file at {0} as json.`, - - block_and_modifier_tags_ignored_within_readme_0: `Block and modifier tags will be ignored within the readme:\n\t{0}`, + "The entrypoint glob {0} did not match any files", + failed_to_parse_json_0: `Failed to parse file at {0} as json`, - converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code.`, - converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value.`, + failed_to_read_0_when_processing_document_tag_in_1: `Failed to read file {0} when processing @document tag for comment in {1}`, + failed_to_read_0_when_processing_project_document: `Failed to read file {0} when adding project document`, + failed_to_read_0_when_processing_document_child_in_1: `Failed to read file {0} when processing document children in {1}`, + frontmatter_children_0_should_be_an_array_of_strings_or_object_with_string_values: + "Frontmatter children in {0} should be an array of strings or an object with string values", + converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code`, + converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value`, converting_0_as_class_without_construct_signatures: `{0} is being converted as a class, but does not have any construct signatures`, - symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used.`, + comment_for_0_should_not_contain_block_or_modifier_tags: `The comment for {0} should not contain any block or modifier tags`, + + symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used`, comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`, // comments/parser.ts - multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment.`, - failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report.`, + multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment`, + failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report`, + relative_path_0_does_not_exist: `The relative path {0} does not exist`, inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}", @@ -60,254 +72,266 @@ export = { content_in_remarks_block_overwritten_by_inheritdoc_in_comment_at_0: "Content in the @remarks block will be overwritten by the @inheritDoc tag in comment at {0}", example_tag_literal_name: - "The first line of an example tag will be taken literally as the example name, and should only contain text.", + "The first line of an example tag will be taken literally as the example name, and should only contain text", inheritdoc_tag_properly_capitalized: - "The @inheritDoc tag should be properly capitalized.", - treating_unrecognized_tag_0_as_modifier: `Treating unrecognized tag {0} as a modifier tag.`, - unmatched_closing_brace: `Unmatched closing brace.`, - unescaped_open_brace_without_inline_tag: `Encountered an unescaped open brace without an inline tag.`, - unknown_inline_tag_0: `Encountered an unknown inline tag {0}.`, - open_brace_within_inline_tag: `Encountered an open brace within an inline tag, this is likely a mistake.`, - inline_tag_not_closed: `Inline tag is not closed.`, + "The @inheritDoc tag should be properly capitalized", + treating_unrecognized_tag_0_as_modifier: `Treating unrecognized tag {0} as a modifier tag`, + unmatched_closing_brace: `Unmatched closing brace`, + unescaped_open_brace_without_inline_tag: `Encountered an unescaped open brace without an inline tag`, + unknown_block_tag_0: `Encountered an unknown block tag {0}`, + unknown_inline_tag_0: `Encountered an unknown inline tag {0}`, + open_brace_within_inline_tag: `Encountered an open brace within an inline tag, this is likely a mistake`, + inline_tag_not_closed: `Inline tag is not closed`, // validation failed_to_resolve_link_to_0_in_comment_for_1: `Failed to resolve link to "{0}" in comment for {1}`, - type_0_defined_in_1_is_referenced_by_2_but_not_included_in_docs: `{0}, defined in {1}, is referenced by {2} but not included in the documentation.`, - reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation.`, + failed_to_resolve_link_to_0_in_comment_for_1_may_have_meant_2: `Failed to resolve link to "{0}" in comment for {1}. You may have wanted "{2}"`, + failed_to_resolve_link_to_0_in_readme_for_1: `Failed to resolve link to "{0}" in readme for {1}`, + failed_to_resolve_link_to_0_in_readme_for_1_may_have_meant_2: `Failed to resolve link to "{0}" in readme for {1}. You may have wanted "{2}"`, + type_0_defined_in_1_is_referenced_by_2_but_not_included_in_docs: `{0}, defined in {1}, is referenced by {2} but not included in the documentation`, + reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation`, invalid_intentionally_not_exported_symbols_0: "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}", // conversion plugins not_all_search_category_boosts_used_0: `Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}`, not_all_search_group_boosts_used_0: `Not all groups specified in searchGroupBoosts were used in the documentation. The unused groups were:\n\t{0}`, - comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category.`, - comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group.`, - label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number.`, - signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used.`, - declaration_reference_in_inheritdoc_for_0_not_fully_parsed: `Declaration reference in @inheritDoc for {0} was not fully parsed and may resolve incorrectly.`, + comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category`, + comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group`, + label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number`, + modifier_tag_0_is_mutually_exclusive_with_1_in_comment_for_2: `The modifier tag {0} is mutually exclusive with {1} in the comment for {2}`, + signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used`, + declaration_reference_in_inheritdoc_for_0_not_fully_parsed: `Declaration reference in @inheritDoc for {0} was not fully parsed and may resolve incorrectly`, failed_to_find_0_to_inherit_comment_from_in_1: `Failed to find "{0}" to inherit the comment from in the comment for {1}`, - reflection_0_tried_to_copy_comment_from_1_but_source_had_no_comment: `{0} tried to copy a comment from {1} with @inheritDoc, but the source has no associated comment.`, + reflection_0_tried_to_copy_comment_from_1_but_source_had_no_comment: `{0} tried to copy a comment from {1} with @inheritDoc, but the source has no associated comment`, inheritdoc_circular_inheritance_chain_0: `@inheritDoc specifies a circular inheritance chain: {0}`, - provided_readme_at_0_could_not_be_read: `Provided README path, {0} could not be read.`, + provided_readme_at_0_could_not_be_read: `Provided README path, {0} could not be read`, defaulting_project_name: - 'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation".', - disable_git_set_but_not_source_link_template: `disableGit is set, but sourceLinkTemplate is not, so source links cannot be produced. Set a sourceLinkTemplate or disableSources to prevent source tracking.`, - disable_git_set_and_git_revision_used: `disableGit is set and sourceLinkTemplate contains {gitRevision}, which will be replaced with an empty string as no revision was provided.`, - git_remote_0_not_valid: `The provided git remote "{0}" was not valid. Source links will be broken.`, + 'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation"', + disable_git_set_but_not_source_link_template: `disableGit is set, but sourceLinkTemplate is not, so source links cannot be produced. Set a sourceLinkTemplate or disableSources to prevent source tracking`, + disable_git_set_and_git_revision_used: `disableGit is set and sourceLinkTemplate contains {gitRevision}, which will be replaced with an empty string as no revision was provided`, + git_remote_0_not_valid: `The provided git remote "{0}" was not valid. Source links will be broken`, // output plugins - custom_css_file_0_does_not_exist: `Custom CSS file at {0} does not exist.`, - unsupported_highlight_language_0_not_highlighted_in_comment_for_1: `Unsupported highlight language {0} will not be highlighted in comment for {1}.`, - could_not_find_file_to_include_0: `Could not find file to include: {0}`, - could_not_find_media_file_0: `Could not find media file: {0}`, - could_not_find_includes_directory_0: - "Could not find provided includes directory: {0}", - could_not_find_media_directory_0: - "Could not find provided media directory: {0}", + custom_css_file_0_does_not_exist: `Custom CSS file at {0} does not exist`, + unsupported_highlight_language_0_not_highlighted_in_comment_for_1: `Unsupported highlight language {0} will not be highlighted in comment for {1}`, + unloaded_language_0_not_highlighted_in_comment_for_1: `Code block with language {0} will not be highlighted in comment for {1} as it was not included in the highlightLanguages option`, + yaml_frontmatter_not_an_object: `Expected YAML frontmatter to be an object`, // renderer could_not_write_0: `Could not write {0}`, could_not_empty_output_directory_0: `Could not empty the output directory {0}`, could_not_create_output_directory_0: `Could not create the output directory {0}`, theme_0_is_not_defined_available_are_1: `The theme '{0}' is not defined. The available themes are: {1}`, + custom_theme_does_not_define_getSlugger: `Custom theme does not define a getSlugger(reflection) method, but tries to render markdown`, // entry points no_entry_points_provided: - "No entry points were provided, this is likely a misconfiguration.", + "No entry points were provided, this is likely a misconfiguration", unable_to_find_any_entry_points: - "Unable to find any entry points. See previous warnings.", + "Unable to find any entry points. See previous warnings", watch_does_not_support_packages_mode: - "Watch mode does not support 'packages' style entry points.", + "Watch mode does not support 'packages' style entry points", watch_does_not_support_merge_mode: - "Watch mode does not support 'merge' style entry points.", - entry_point_0_not_in_program: `The entry point {0} is not referenced by the 'files' or 'include' option in your tsconfig.`, - use_expand_or_glob_for_files_in_dir: `If you wanted to include files inside this directory, set --entryPointStrategy to expand or specify a glob.`, - entry_point_0_did_not_match_any_files: `The entry point glob {0} did not match any files.`, - entry_point_0_did_not_match_any_files_after_exclude: `The entry point glob {0} did not match any files after applying exclude patterns.`, - entry_point_0_did_not_exist: `Provided entry point {0} does not exist.`, - entry_point_0_did_not_match_any_packages: `The entry point glob {0} did not match any directories containing package.json.`, - file_0_not_an_object: `The file {0} is not an object.`, + "Watch mode does not support 'merge' style entry points", + entry_point_0_not_in_program: `The entry point {0} is not referenced by the 'files' or 'include' option in your tsconfig`, + use_expand_or_glob_for_files_in_dir: `If you wanted to include files inside this directory, set --entryPointStrategy to expand or specify a glob`, + glob_0_did_not_match_any_files: `The glob {0} did not match any files`, + entry_point_0_did_not_match_any_files_after_exclude: `The glob {0} did not match any files after applying exclude patterns`, + entry_point_0_did_not_exist: `Provided entry point {0} does not exist`, + entry_point_0_did_not_match_any_packages: `The entry point glob {0} did not match any directories containing package.json`, + file_0_not_an_object: `The file {0} is not an object`, // deserialization - serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project.`, + serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project`, + saved_relative_path_0_resolved_from_1_does_not_exist: `Serialized project referenced {0}, which does not exist relative to {1}`, // options circular_reference_extends_0: `Circular reference encountered for "extends" field of {0}`, failed_resolve_0_to_file_in_1: `Failed to resolve {0} to a file in {1}`, - option_0_can_only_be_specified_by_config_file: `The '{0}' option can only be specified via a config file.`, - option_0_expected_a_value_but_none_provided: `--{0} expected a value, but none was given as an argument.`, + option_0_can_only_be_specified_by_config_file: `The '{0}' option can only be specified via a config file`, + option_0_expected_a_value_but_none_provided: `--{0} expected a value, but none was given as an argument`, unknown_option_0_may_have_meant_1: `Unknown option: {0}, you may have meant:\n\t{1}`, - typedoc_key_in_0_ignored: `The 'typedoc' key in {0} was used by the legacy-packages entryPointStrategy and will be ignored.`, - typedoc_options_must_be_object_in_0: `Failed to parse the "typedocOptions" field in {0}, ensure it exists and contains an object.`, + typedoc_key_in_0_ignored: `The 'typedoc' key in {0} was used by the legacy-packages entryPointStrategy and will be ignored`, + typedoc_options_must_be_object_in_0: `Failed to parse the "typedocOptions" field in {0}, ensure it exists and contains an object`, tsconfig_file_0_does_not_exist: `The tsconfig file {0} does not exist`, - tsconfig_file_specifies_options_file: `"typedocOptions" in tsconfig file specifies an option file to read but the option file has already been read. This is likely a misconfiguration.`, - tsconfig_file_specifies_tsconfig_file: `"typedocOptions" in tsconfig file may not specify a tsconfig file to read.`, - tags_0_defined_in_typedoc_json_overwritten_by_tsdoc_json: `The {0} defined in typedoc.json will be overwritten by configuration in tsdoc.json.`, - failed_read_tsdoc_json_0: `Failed to read tsdoc.json file at {0}.`, - invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file.`, + tsconfig_file_specifies_options_file: `"typedocOptions" in tsconfig file specifies an option file to read but the option file has already been read. This is likely a misconfiguration`, + tsconfig_file_specifies_tsconfig_file: `"typedocOptions" in tsconfig file may not specify a tsconfig file to read`, + tags_0_defined_in_typedoc_json_overwritten_by_tsdoc_json: `The {0} defined in typedoc.json will be overwritten by configuration in tsdoc.json`, + failed_read_tsdoc_json_0: `Failed to read tsdoc.json file at {0}`, + invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file`, - options_file_0_does_not_exist: `The options file {0} does not exist.`, - failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object.`, + options_file_0_does_not_exist: `The options file {0} does not exist`, + failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object`, // plugins - invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found.`, - plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded.`, + invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found`, + plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded`, // option declarations help help_options: - "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory.", + "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory", help_tsconfig: - "Specify a TypeScript config file that should be loaded. If not specified TypeDoc will look for 'tsconfig.json' in the current directory.", + "Specify a TypeScript config file that should be loaded. If not specified TypeDoc will look for 'tsconfig.json' in the current directory", help_compilerOptions: - "Selectively override the TypeScript compiler options used by TypeDoc.", + "Selectively override the TypeScript compiler options used by TypeDoc", help_lang: - "Sets the language to be used in generation and in TypeDoc's messages.", + "Sets the language to be used in generation and in TypeDoc's messages", help_locales: - "Add translations for a specified locale. This option is primarily intended to be used as a stopgap while waiting for official locale support to be added to TypeDoc.", + "Add translations for a specified locale. This option is primarily intended to be used as a stopgap while waiting for official locale support to be added to TypeDoc", + help_packageOptions: + "Set options which will be set within each package when entryPointStrategy is set to packages", - help_entryPoints: "The entry points of your documentation.", + help_entryPoints: "The entry points of your documentation", help_entryPointStrategy: - "The strategy to be used to convert entry points into documentation modules.", + "The strategy to be used to convert entry points into documentation modules", + help_alwaysCreateEntryPointModule: + "When set, TypeDoc will always create a `Module` for entry points, even if only one is provided", + help_projectDocuments: + "Documents which should be added as children to the root of the generated documentation. Supports globs to match multiple files", help_exclude: - "Define patterns to be excluded when expanding a directory that was specified as an entry point.", + "Define patterns to be excluded when expanding a directory that was specified as an entry point", help_externalPattern: - "Define patterns for files that should be considered being external.", + "Define patterns for files that should be considered being external", help_excludeExternals: - "Prevent externally resolved symbols from being documented.", + "Prevent externally resolved symbols from being documented", help_excludeNotDocumented: - "Prevent symbols that are not explicitly documented from appearing in the results.", + "Prevent symbols that are not explicitly documented from appearing in the results", help_excludeNotDocumentedKinds: - "Specify the type of reflections that can be removed by excludeNotDocumented.", + "Specify the type of reflections that can be removed by excludeNotDocumented", help_excludeInternal: - "Prevent symbols that are marked with @internal from being documented.", + "Prevent symbols that are marked with @internal from being documented", help_excludeCategories: - "Exclude symbols within this category from the documentation.", - help_excludePrivate: "Ignore private variables and methods.", - help_excludeProtected: "Ignore protected variables and methods.", + "Exclude symbols within this category from the documentation", + help_excludePrivate: + "Ignore private variables and methods, defaults to true.", + help_excludeProtected: "Ignore protected variables and methods", help_excludeReferences: - "If a symbol is exported multiple times, ignore all but the first export.", + "If a symbol is exported multiple times, ignore all but the first export", help_externalSymbolLinkMappings: - "Define custom links for symbols not included in the documentation.", - help_media: - "Specify the location with media files that should be copied to the output directory.", - help_includes: - "Specify the location to look for included documents (use [[include:FILENAME]] in comments).", - help_out: "Specify the location the documentation should be written to.", + "Define custom links for symbols not included in the documentation", + help_out: "Specify the location the documentation should be written to", help_json: - "Specify the location and filename a JSON file describing the project is written to.", + "Specify the location and filename a JSON file describing the project is written to", help_pretty: - "Specify whether the output JSON should be formatted with tabs.", - help_emit: "Specify what TypeDoc should emit, 'docs', 'both', or 'none'.", + "Specify whether the output JSON should be formatted with tabs", + help_emit: "Specify what TypeDoc should emit, 'docs', 'both', or 'none'", help_theme: "Specify the theme name to render the documentation with", help_lightHighlightTheme: - "Specify the code highlighting theme in light mode.", - help_darkHighlightTheme: - "Specify the code highlighting theme in dark mode.", - help_customCss: "Path to a custom CSS file to for the theme to import.", - help_markedOptions: - "Specify the options passed to Marked, the Markdown parser used by TypeDoc.", + "Specify the code highlighting theme in light mode", + help_darkHighlightTheme: "Specify the code highlighting theme in dark mode", + help_highlightLanguages: + "Specify the languages which will be loaded to highlight code when rendering", + help_customCss: "Path to a custom CSS file to for the theme to import", + help_markdownItOptions: + "Specify the options passed to markdown-it, the Markdown parser used by TypeDoc", + help_markdownItLoader: + "Specify a callback to be called when loading the markdown-it instance. Will be passed the instance of the parser which TypeDoc will use", help_maxTypeConversionDepth: - "Set the maximum depth of types to be converted.", + "Set the maximum depth of types to be converted", help_name: - "Set the name of the project that will be used in the header of the template.", - help_includeVersion: "Add the package version to the project name.", + "Set the name of the project that will be used in the header of the template", + help_includeVersion: "Add the package version to the project name", help_disableSources: - "Disable setting the source of a reflection when documenting it.", + "Disable setting the source of a reflection when documenting it", help_sourceLinkTemplate: - "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders.", + "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders", help_gitRevision: - "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files. Has no effect if disableSources is set.", + "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files. Has no effect if disableSources is set", help_gitRemote: - "Use the specified remote for linking to GitHub/Bitbucket source files. Has no effect if disableGit or disableSources is set.", + "Use the specified remote for linking to GitHub/Bitbucket source files. Has no effect if disableGit or disableSources is set", help_disableGit: "Assume that all can be linked to with the sourceLinkTemplate, sourceLinkTemplate must be set if this is enabled. {path} will be rooted at basePath", help_basePath: - "Specifies the base path to be used when displaying file paths.", - help_excludeTags: - "Remove the listed block/modifier tags from doc comments.", + "Specifies the base path to be used when displaying file paths", + help_excludeTags: "Remove the listed block/modifier tags from doc comments", help_readme: - "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page.", - help_stripYamlFrontmatter: "Strip YAML frontmatter from markdown files.", + "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page", help_cname: - "Set the CNAME file text, it's useful for custom domains on GitHub Pages.", + "Set the CNAME file text, it's useful for custom domains on GitHub Pages", help_sourceLinkExternal: - "Specifies that source links should be treated as external links to be opened in a new tab.", + "Specifies that source links should be treated as external links to be opened in a new tab", help_githubPages: - "Generate a .nojekyll file to prevent 404 errors in GitHub Pages. Defaults to `true`.", - help_sitemapBaseUrl: - "Specify a base URL to be used in generating a sitemap.xml in our output folder. If not specified, no sitemap will be generated.", - help_gaID: - "Set the Google Analytics tracking ID and activate tracking code.", - help_hideGenerator: "Do not print the TypeDoc link at the end of the page.", + "Generate a .nojekyll file to prevent 404 errors in GitHub Pages. Defaults to `true`", + help_hostedBaseUrl: + "Specify a base URL to be used in generating a sitemap.xml in our output folder and canonical links. If not specified, no sitemap will be generated", + help_useHostedBaseUrlForAbsoluteLinks: + "If set, TypeDoc will produce absolute links to pages on your site using the hostedBaseUrl option", + help_hideGenerator: "Do not print the TypeDoc link at the end of the page", + help_customFooterHtml: "Custom footer after the TypeDoc link", + help_customFooterHtmlDisableWrapper: + "If set, disables the wrapper element for customFooterHtml", help_hideParameterTypesInTitle: - "Hides parameter types in signature titles for easier scanning.", - help_cacheBust: "Include the generation time in links to static assets.", + "Hides parameter types in signature titles for easier scanning", + help_cacheBust: "Include the generation time in links to static assets", help_searchInComments: - "If set, the search index will also include comments. This will greatly increase the size of the search index.", + "If set, the search index will also include comments. This will greatly increase the size of the search index", + help_searchInDocuments: + "If set, the search index will also include documents. This will greatly increase the size of the search index", help_cleanOutputDir: - "If set, TypeDoc will remove the output directory before writing output.", + "If set, TypeDoc will remove the output directory before writing output", help_titleLink: - "Set the link the title in the header points to. Defaults to the documentation homepage.", - help_navigationLinks: "Defines links to be included in the header.", - help_sidebarLinks: "Defines links to be included in the sidebar.", + "Set the link the title in the header points to. Defaults to the documentation homepage", + help_navigationLinks: "Defines links to be included in the header", + help_sidebarLinks: "Defines links to be included in the sidebar", help_navigationLeaves: - "Branches of the navigation tree which should not be expanded.", - help_navigation: "Determines how the navigation sidebar is organized.", + "Branches of the navigation tree which should not be expanded", + help_navigation: "Determines how the navigation sidebar is organized", help_visibilityFilters: - "Specify the default visibility for builtin filters and additional filters according to modifier tags.", + "Specify the default visibility for builtin filters and additional filters according to modifier tags", help_searchCategoryBoosts: "Configure search to give a relevance boost to selected categories", help_searchGroupBoosts: 'Configure search to give a relevance boost to selected kinds (eg "class")', help_jsDocCompatibility: - "Sets compatibility options for comment parsing that increase similarity with JSDoc comments.", - help_commentStyle: "Determines how TypeDoc searches for comments.", + "Sets compatibility options for comment parsing that increase similarity with JSDoc comments", + help_commentStyle: "Determines how TypeDoc searches for comments", help_useTsLinkResolution: - "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments.", + "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments", help_preserveLinkText: - "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name.", + "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name", help_blockTags: - "Block tags which TypeDoc should recognize when parsing comments.", + "Block tags which TypeDoc should recognize when parsing comments", help_inlineTags: - "Inline tags which TypeDoc should recognize when parsing comments.", + "Inline tags which TypeDoc should recognize when parsing comments", help_modifierTags: - "Modifier tags which TypeDoc should recognize when parsing comments.", + "Modifier tags which TypeDoc should recognize when parsing comments", help_categorizeByGroup: - "Specify whether categorization will be done at the group level.", + "Specify whether categorization will be done at the group level", help_defaultCategory: - "Specify the default category for reflections without a category.", + "Specify the default category for reflections without a category", help_categoryOrder: - "Specify the order in which categories appear. * indicates the relative order for categories not in the list.", + "Specify the order in which categories appear. * indicates the relative order for categories not in the list", help_groupOrder: - "Specify the order in which groups appear. * indicates the relative order for groups not in the list.", - help_sort: "Specify the sort strategy for documented values.", + "Specify the order in which groups appear. * indicates the relative order for groups not in the list", + help_sort: "Specify the sort strategy for documented values", help_sortEntryPoints: - "If set, entry points will be subject to the same sorting rules as other reflections.", + "If set, entry points will be subject to the same sorting rules as other reflections", help_kindSortOrder: - "Specify the sort order for reflections when 'kind' is specified.", - help_watch: "Watch files for changes and rebuild docs on change.", + "Specify the sort order for reflections when 'kind' is specified", + help_watch: "Watch files for changes and rebuild docs on change", help_preserveWatchOutput: - "If set, TypeDoc will not clear the screen between compilation runs.", + "If set, TypeDoc will not clear the screen between compilation runs", help_skipErrorChecking: - "Do not run TypeScript's type checking before generating docs.", - help_help: "Print this message.", - help_version: "Print TypeDoc's version.", - help_showConfig: "Print the resolved configuration and exit.", + "Do not run TypeScript's type checking before generating docs", + help_help: "Print this message", + help_version: "Print TypeDoc's version", + help_showConfig: "Print the resolved configuration and exit", help_plugin: - "Specify the npm plugins that should be loaded. Omit to load all installed plugins.", - help_logLevel: "Specify what level of logging should be used.", + "Specify the npm plugins that should be loaded. Omit to load all installed plugins", + help_logLevel: "Specify what level of logging should be used", help_treatWarningsAsErrors: - "If set, all warnings will be treated as errors.", + "If set, all warnings will be treated as errors", help_treatValidationWarningsAsErrors: - "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings.", + "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings", help_intentionallyNotExported: - "A list of types which should not produce 'referenced but not documented' warnings.", + "A list of types which should not produce 'referenced but not documented' warnings", help_requiredToBeDocumented: "A list of reflection kinds that must be documented", help_validation: - "Specify which validation steps TypeDoc should perform on your generated documentation.", + "Specify which validation steps TypeDoc should perform on your generated documentation", // ================================================================== // Option validation @@ -323,24 +347,28 @@ export = { "The flag '{0}' is not valid for {1}, expected one of {2}", expected_object_with_flag_values_for_0: "Expected an object with flag values for {0} or true/false", - flag_values_for_0_must_be_booleans: - "Flag values for {0} must be a boolean.", + flag_values_for_0_must_be_booleans: "Flag values for {0} must be a boolean", locales_must_be_an_object: "The 'locales' option must be set to an object which resembles: { en: { theme_implements: \"Implements\" }}", exclude_not_documented_specified_0_valid_values_are_1: `excludeNotDocumentedKinds may only specify known values, and invalid values were provided ({0}). The valid kinds are:\n{1}`, external_symbol_link_mappings_must_be_object: "externalSymbolLinkMappings must be a Record>", highlight_theme_0_must_be_one_of_1: "{0} must be one of the following: {1}", - sitemap_must_start_with_http: - "sitemapBaseUrl must start with http:// or https://", - option_0_must_be_an_object: "The '{0}' option must be a non-array object.", - option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values.`, + highlightLanguages_contains_invalid_languages_0: + "highlightLanguages contains invalid languages: {0}, run typedoc --help for a list of supported languages", + hostedBaseUrl_must_start_with_http: + "hostedBaseUrl must start with http:// or https://", + useHostedBaseUrlForAbsoluteLinks_requires_hostedBaseUrl: + "The useHostedBaseUrlForAbsoluteLinks option requires that hostedBaseUrl be set", + option_0_must_be_an_object: "The '{0}' option must be a non-array object", + option_0_must_be_a_function: "The '{0}' option must be a function", + option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values`, visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`, - visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans.`, + visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans`, option_0_values_must_be_numbers: "All values of {0} must be numbers", option_0_values_must_be_array_of_tags: - "{0} must be an array of valid tag names.", - option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({0}). The valid sort strategies are:\n{1}`, + "{0} must be an array of valid tag names", + option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({1}). The valid sort strategies are:\n{2}`, // ReflectionKind singular translations kind_project: "Project", @@ -366,6 +394,7 @@ export = { kind_set_signature: "Set Signature", kind_type_alias: "Type Alias", kind_reference: "Reference", + kind_document: "Document", // ReflectionKind plural translations kind_plural_project: "Projects", @@ -391,6 +420,20 @@ export = { kind_plural_set_signature: "Set Signatures", kind_plural_type_alias: "Type Aliases", kind_plural_reference: "References", + kind_plural_document: "Documents", + + // ReflectionFlag translations + flag_private: "Private", + flag_protected: "Protected", + flag_public: "Public", + flag_static: "Static", + flag_external: "External", + flag_optional: "Optional", + flag_rest: "Rest", + flag_abstract: "Abstract", + flag_const: "Const", + flag_readonly: "Readonly", + flag_inherited: "Inherited", // ================================================================== // Strings that show up in the default theme @@ -411,9 +454,12 @@ export = { theme_re_exports: "Re-exports", theme_renames_and_re_exports: "Renames and re-exports", theme_generated_using_typedoc: "Generated using TypeDoc", // If this includes "TypeDoc", theme will insert a link at that location. + theme_class_hierarchy_title: "Class Hierarchy", // Search theme_preparing_search_index: "Preparing search index...", theme_search_index_not_available: "The search index is not available", + // Left nav bar + theme_loading: "Loading...", // Right nav bar theme_settings: "Settings", theme_member_visibility: "Member Visibility", @@ -427,4 +473,10 @@ export = { theme_search: "Search", theme_menu: "Menu", theme_permalink: "Permalink", + + // Used by the frontend JS + theme_copy: "Copy", + theme_copied: "Copied!", + theme_normally_hidden: + "This member is normally hidden due to your filter settings.", } as const; diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 7145893c8..df858dc02 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -1,6 +1,6 @@ -import { buildIncompleteTranslation } from "../translatable"; +import localeUtils = require("../locale-utils.cjs"); -export = buildIncompleteTranslation({ +export = localeUtils.buildIncompleteTranslation({ loaded_multiple_times_0: "TypeDoc が複数回読み込まれました。これは通常、TypeDoc を独自にインストールしたプラグインによって発生します。読み込まれたパスは次のとおりです:\n{0}", unsupported_ts_version_0: diff --git a/src/lib/internationalization/locales/ko.cts b/src/lib/internationalization/locales/ko.cts index 471be8de1..b5952c90e 100644 --- a/src/lib/internationalization/locales/ko.cts +++ b/src/lib/internationalization/locales/ko.cts @@ -1,6 +1,6 @@ -import { buildIncompleteTranslation } from "../translatable"; +import localeUtils = require("../locale-utils.cjs"); -export = buildIncompleteTranslation({ +export = localeUtils.buildIncompleteTranslation({ docs_generated_at_0: "문서가 {0}에 생성되었습니다", json_written_to_0: "{0}에 JSON이 작성되었습니다", diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index fd1e5d51b..a316d284c 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -1,6 +1,6 @@ -import { buildIncompleteTranslation } from "../translatable"; +import localeUtils = require("../locale-utils.cjs"); -export = buildIncompleteTranslation({ +export = localeUtils.buildIncompleteTranslation({ loaded_multiple_times_0: "TypeDoc 已加载多次。这通常是由具有自己的 TypeDoc 安装的插件引起的。加载的路径为:\n{0}", unsupported_ts_version_0: @@ -89,7 +89,7 @@ export = buildIncompleteTranslation({ not_all_search_group_boosts_used_0: "文档中并未使用 searchGroupBoosts 中指定的所有组。未使用的组为:\n{0}", comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: - "{0} 的评论包含“{1}”的 @categoryDe​​scription,但该类别中没有子项", + "{0} 的评论包含“{1}”的 @categoryDescription,但该类别中没有子项", comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: "对 {0} 的评论包含“{1}”的 @groupDescription,但该组中没有子项", label_0_for_1_cannot_be_referenced: diff --git a/src/lib/internationalization/translatable.ts b/src/lib/internationalization/translatable.ts index 5d4eaa628..b7725937e 100644 --- a/src/lib/internationalization/translatable.ts +++ b/src/lib/internationalization/translatable.ts @@ -3,498 +3,7 @@ import type { inlineTags, modifierTags, } from "../utils/options/tsdoc-defaults.js"; - -export function buildTranslation< - T extends BuiltinTranslatableStringConstraints, ->(translations: T) { - return translations; -} - -export function buildIncompleteTranslation< - T extends Partial, ->(translations: T) { - return translations; -} - -export const translatable = { - loaded_multiple_times_0: - "TypeDoc has been loaded multiple times. This is commonly caused by plugins which have their own installation of TypeDoc. The loaded paths are:\n\t{0}", - unsupported_ts_version_0: - "You are running with an unsupported TypeScript version! If TypeDoc crashes, this is why. TypeDoc supports {0}", - no_compiler_options_set: - "No compiler options set. This likely means that TypeDoc did not find your tsconfig.json. Generated documentation will probably be empty", - - loaded_plugin_0: `Loaded plugin {0}`, - - solution_not_supported_in_watch_mode: - "The provided tsconfig file looks like a solution style tsconfig, which is not supported in watch mode", - strategy_not_supported_in_watch_mode: - "entryPointStrategy must be set to either resolve or expand for watch mode", - found_0_errors_and_1_warnings: "Found {0} errors and {1} warnings", - - docs_could_not_be_generated: - "Documentation could not be generated due to the errors above", - docs_generated_at_0: "Documentation generated at {0}", - json_written_to_0: "JSON written to {0}", - - no_entry_points_for_packages: - "No entry points provided to packages mode, documentation cannot be generated", - failed_to_find_packages: - "Failed to find any packages, ensure you have provided at least one directory as an entry point containing package.json", - nested_packages_unsupported_0: - "Project at {0} has entryPointStrategy set to packages, but nested packages are not supported", - previous_error_occurred_when_reading_options_for_0: - "The previous error occurred when reading options for the package at {0}", - converting_project_at_0: "Converting project at {0}", - failed_to_convert_packages: - "Failed to convert one or more packages, result will not be merged together", - merging_converted_projects: "Merging converted projects", - - no_entry_points_to_merge: "No entry points provided to merge", - entrypoint_did_not_match_files_0: - "The entrypoint glob {0} did not match any files", - failed_to_parse_json_0: `Failed to parse file at {0} as json`, - - failed_to_read_0_when_processing_document_tag_in_1: `Failed to read file {0} when processing @document tag for comment in {1}`, - failed_to_read_0_when_processing_project_document: `Failed to read file {0} when adding project document`, - failed_to_read_0_when_processing_document_child_in_1: `Failed to read file {0} when processing document children in {1}`, - frontmatter_children_0_should_be_an_array_of_strings_or_object_with_string_values: - "Frontmatter children in {0} should be an array of strings or an object with string values", - converting_union_as_interface: `Using @interface on a union type will discard properties not present on all branches of the union. TypeDoc's output may not accurately describe your source code`, - converting_0_as_class_requires_value_declaration: `Converting {0} as a class requires a declaration which represents a non-type value`, - converting_0_as_class_without_construct_signatures: `{0} is being converted as a class, but does not have any construct signatures`, - - comment_for_0_should_not_contain_block_or_modifier_tags: `The comment for {0} should not contain any block or modifier tags`, - - symbol_0_has_multiple_declarations_with_comment: `{0} has multiple declarations with a comment. An arbitrary comment will be used`, - comments_for_0_are_declared_at_1: `The comments for {0} are declared at:\n\t{1}`, - - // comments/parser.ts - multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment`, - failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report`, - relative_path_0_does_not_exist: `The relative path {0} does not exist`, - - inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: - "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}", - at_most_one_remarks_tag_expected_in_comment_at_0: - "At most one @remarks tag is expected in a comment, ignoring all but the first in comment at {0}", - at_most_one_returns_tag_expected_in_comment_at_0: - "At most one @returns tag is expected in a comment, ignoring all but the first in comment at {0}", - at_most_one_inheritdoc_tag_expected_in_comment_at_0: - "At most one @inheritDoc tag is expected in a comment, ignoring all but the first in comment at {0}", - content_in_summary_overwritten_by_inheritdoc_in_comment_at_0: - "Content in the summary section will be overwritten by the @inheritDoc tag in comment at {0}", - content_in_remarks_block_overwritten_by_inheritdoc_in_comment_at_0: - "Content in the @remarks block will be overwritten by the @inheritDoc tag in comment at {0}", - example_tag_literal_name: - "The first line of an example tag will be taken literally as the example name, and should only contain text", - inheritdoc_tag_properly_capitalized: - "The @inheritDoc tag should be properly capitalized", - treating_unrecognized_tag_0_as_modifier: `Treating unrecognized tag {0} as a modifier tag`, - unmatched_closing_brace: `Unmatched closing brace`, - unescaped_open_brace_without_inline_tag: `Encountered an unescaped open brace without an inline tag`, - unknown_block_tag_0: `Encountered an unknown block tag {0}`, - unknown_inline_tag_0: `Encountered an unknown inline tag {0}`, - open_brace_within_inline_tag: `Encountered an open brace within an inline tag, this is likely a mistake`, - inline_tag_not_closed: `Inline tag is not closed`, - - // validation - failed_to_resolve_link_to_0_in_comment_for_1: `Failed to resolve link to "{0}" in comment for {1}`, - failed_to_resolve_link_to_0_in_comment_for_1_may_have_meant_2: `Failed to resolve link to "{0}" in comment for {1}. You may have wanted "{2}"`, - failed_to_resolve_link_to_0_in_readme_for_1: `Failed to resolve link to "{0}" in readme for {1}`, - failed_to_resolve_link_to_0_in_readme_for_1_may_have_meant_2: `Failed to resolve link to "{0}" in readme for {1}. You may have wanted "{2}"`, - type_0_defined_in_1_is_referenced_by_2_but_not_included_in_docs: `{0}, defined in {1}, is referenced by {2} but not included in the documentation`, - reflection_0_kind_1_defined_in_2_does_not_have_any_documentation: `{0} ({1}), defined in {2}, does not have any documentation`, - invalid_intentionally_not_exported_symbols_0: - "The following symbols were marked as intentionally not exported, but were either not referenced in the documentation, or were exported:\n\t{0}", - - // conversion plugins - not_all_search_category_boosts_used_0: `Not all categories specified in searchCategoryBoosts were used in the documentation. The unused categories were:\n\t{0}`, - not_all_search_group_boosts_used_0: `Not all groups specified in searchGroupBoosts were used in the documentation. The unused groups were:\n\t{0}`, - comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: `Comment for {0} includes @categoryDescription for "{1}", but no child is placed in that category`, - comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: `Comment for {0} includes @groupDescription for "{1}", but no child is placed in that group`, - label_0_for_1_cannot_be_referenced: `The label "{0}" for {1} cannot be referenced with a declaration reference. Labels may only contain A-Z, 0-9, and _, and may not start with a number`, - modifier_tag_0_is_mutually_exclusive_with_1_in_comment_for_2: `The modifier tag {0} is mutually exclusive with {1} in the comment for {2}`, - signature_0_has_unused_param_with_name_1: `The signature {0} has an @param with name "{1}", which was not used`, - declaration_reference_in_inheritdoc_for_0_not_fully_parsed: `Declaration reference in @inheritDoc for {0} was not fully parsed and may resolve incorrectly`, - failed_to_find_0_to_inherit_comment_from_in_1: `Failed to find "{0}" to inherit the comment from in the comment for {1}`, - reflection_0_tried_to_copy_comment_from_1_but_source_had_no_comment: `{0} tried to copy a comment from {1} with @inheritDoc, but the source has no associated comment`, - inheritdoc_circular_inheritance_chain_0: `@inheritDoc specifies a circular inheritance chain: {0}`, - provided_readme_at_0_could_not_be_read: `Provided README path, {0} could not be read`, - defaulting_project_name: - 'The --name option was not specified, and no package.json was found. Defaulting project name to "Documentation"', - disable_git_set_but_not_source_link_template: `disableGit is set, but sourceLinkTemplate is not, so source links cannot be produced. Set a sourceLinkTemplate or disableSources to prevent source tracking`, - disable_git_set_and_git_revision_used: `disableGit is set and sourceLinkTemplate contains {gitRevision}, which will be replaced with an empty string as no revision was provided`, - git_remote_0_not_valid: `The provided git remote "{0}" was not valid. Source links will be broken`, - - // output plugins - custom_css_file_0_does_not_exist: `Custom CSS file at {0} does not exist`, - unsupported_highlight_language_0_not_highlighted_in_comment_for_1: `Unsupported highlight language {0} will not be highlighted in comment for {1}`, - unloaded_language_0_not_highlighted_in_comment_for_1: `Code block with language {0} will not be highlighted in comment for {1} as it was not included in the highlightLanguages option`, - yaml_frontmatter_not_an_object: `Expected YAML frontmatter to be an object`, - - // renderer - could_not_write_0: `Could not write {0}`, - could_not_empty_output_directory_0: `Could not empty the output directory {0}`, - could_not_create_output_directory_0: `Could not create the output directory {0}`, - theme_0_is_not_defined_available_are_1: `The theme '{0}' is not defined. The available themes are: {1}`, - custom_theme_does_not_define_getSlugger: `Custom theme does not define a getSlugger(reflection) method, but tries to render markdown`, - - // entry points - no_entry_points_provided: - "No entry points were provided, this is likely a misconfiguration", - unable_to_find_any_entry_points: - "Unable to find any entry points. See previous warnings", - watch_does_not_support_packages_mode: - "Watch mode does not support 'packages' style entry points", - watch_does_not_support_merge_mode: - "Watch mode does not support 'merge' style entry points", - entry_point_0_not_in_program: `The entry point {0} is not referenced by the 'files' or 'include' option in your tsconfig`, - use_expand_or_glob_for_files_in_dir: `If you wanted to include files inside this directory, set --entryPointStrategy to expand or specify a glob`, - glob_0_did_not_match_any_files: `The glob {0} did not match any files`, - entry_point_0_did_not_match_any_files_after_exclude: `The glob {0} did not match any files after applying exclude patterns`, - entry_point_0_did_not_exist: `Provided entry point {0} does not exist`, - entry_point_0_did_not_match_any_packages: `The entry point glob {0} did not match any directories containing package.json`, - file_0_not_an_object: `The file {0} is not an object`, - - // deserialization - serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project`, - saved_relative_path_0_resolved_from_1_does_not_exist: `Serialized project referenced {0}, which does not exist relative to {1}`, - - // options - circular_reference_extends_0: `Circular reference encountered for "extends" field of {0}`, - failed_resolve_0_to_file_in_1: `Failed to resolve {0} to a file in {1}`, - - option_0_can_only_be_specified_by_config_file: `The '{0}' option can only be specified via a config file`, - option_0_expected_a_value_but_none_provided: `--{0} expected a value, but none was given as an argument`, - unknown_option_0_may_have_meant_1: `Unknown option: {0}, you may have meant:\n\t{1}`, - - typedoc_key_in_0_ignored: `The 'typedoc' key in {0} was used by the legacy-packages entryPointStrategy and will be ignored`, - typedoc_options_must_be_object_in_0: `Failed to parse the "typedocOptions" field in {0}, ensure it exists and contains an object`, - tsconfig_file_0_does_not_exist: `The tsconfig file {0} does not exist`, - tsconfig_file_specifies_options_file: `"typedocOptions" in tsconfig file specifies an option file to read but the option file has already been read. This is likely a misconfiguration`, - tsconfig_file_specifies_tsconfig_file: `"typedocOptions" in tsconfig file may not specify a tsconfig file to read`, - tags_0_defined_in_typedoc_json_overwritten_by_tsdoc_json: `The {0} defined in typedoc.json will be overwritten by configuration in tsdoc.json`, - failed_read_tsdoc_json_0: `Failed to read tsdoc.json file at {0}`, - invalid_tsdoc_json_0: `The file {0} is not a valid tsdoc.json file`, - - options_file_0_does_not_exist: `The options file {0} does not exist`, - failed_read_options_file_0: `Failed to parse {0}, ensure it exists and exports an object`, - - // plugins - invalid_plugin_0_missing_load_function: `Invalid structure in plugin {0}, no load function found`, - plugin_0_could_not_be_loaded: `The plugin {0} could not be loaded`, - - // option declarations help - help_options: - "Specify a json option file that should be loaded. If not specified TypeDoc will look for 'typedoc.json' in the current directory", - help_tsconfig: - "Specify a TypeScript config file that should be loaded. If not specified TypeDoc will look for 'tsconfig.json' in the current directory", - help_compilerOptions: - "Selectively override the TypeScript compiler options used by TypeDoc", - help_lang: - "Sets the language to be used in generation and in TypeDoc's messages", - help_locales: - "Add translations for a specified locale. This option is primarily intended to be used as a stopgap while waiting for official locale support to be added to TypeDoc", - help_packageOptions: - "Set options which will be set within each package when entryPointStrategy is set to packages", - - help_entryPoints: "The entry points of your documentation", - help_entryPointStrategy: - "The strategy to be used to convert entry points into documentation modules", - help_alwaysCreateEntryPointModule: - "When set, TypeDoc will always create a `Module` for entry points, even if only one is provided", - help_projectDocuments: - "Documents which should be added as children to the root of the generated documentation. Supports globs to match multiple files", - help_exclude: - "Define patterns to be excluded when expanding a directory that was specified as an entry point", - help_externalPattern: - "Define patterns for files that should be considered being external", - help_excludeExternals: - "Prevent externally resolved symbols from being documented", - help_excludeNotDocumented: - "Prevent symbols that are not explicitly documented from appearing in the results", - help_excludeNotDocumentedKinds: - "Specify the type of reflections that can be removed by excludeNotDocumented", - help_excludeInternal: - "Prevent symbols that are marked with @internal from being documented", - help_excludeCategories: - "Exclude symbols within this category from the documentation", - help_excludePrivate: - "Ignore private variables and methods, defaults to true.", - help_excludeProtected: "Ignore protected variables and methods", - help_excludeReferences: - "If a symbol is exported multiple times, ignore all but the first export", - help_externalSymbolLinkMappings: - "Define custom links for symbols not included in the documentation", - help_out: "Specify the location the documentation should be written to", - help_json: - "Specify the location and filename a JSON file describing the project is written to", - help_pretty: - "Specify whether the output JSON should be formatted with tabs", - help_emit: "Specify what TypeDoc should emit, 'docs', 'both', or 'none'", - help_theme: "Specify the theme name to render the documentation with", - help_lightHighlightTheme: - "Specify the code highlighting theme in light mode", - help_darkHighlightTheme: "Specify the code highlighting theme in dark mode", - help_highlightLanguages: - "Specify the languages which will be loaded to highlight code when rendering", - help_customCss: "Path to a custom CSS file to for the theme to import", - help_markdownItOptions: - "Specify the options passed to markdown-it, the Markdown parser used by TypeDoc", - help_markdownItLoader: - "Specify a callback to be called when loading the markdown-it instance. Will be passed the instance of the parser which TypeDoc will use", - help_maxTypeConversionDepth: - "Set the maximum depth of types to be converted", - help_name: - "Set the name of the project that will be used in the header of the template", - help_includeVersion: "Add the package version to the project name", - help_disableSources: - "Disable setting the source of a reflection when documenting it", - help_sourceLinkTemplate: - "Specify a link template to be used when generating source urls. If not set, will be automatically created using the git remote. Supports {path}, {line}, {gitRevision} placeholders", - help_gitRevision: - "Use specified revision instead of the last revision for linking to GitHub/Bitbucket source files. Has no effect if disableSources is set", - help_gitRemote: - "Use the specified remote for linking to GitHub/Bitbucket source files. Has no effect if disableGit or disableSources is set", - help_disableGit: - "Assume that all can be linked to with the sourceLinkTemplate, sourceLinkTemplate must be set if this is enabled. {path} will be rooted at basePath", - help_basePath: - "Specifies the base path to be used when displaying file paths", - help_excludeTags: "Remove the listed block/modifier tags from doc comments", - help_readme: - "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page", - help_cname: - "Set the CNAME file text, it's useful for custom domains on GitHub Pages", - help_sourceLinkExternal: - "Specifies that source links should be treated as external links to be opened in a new tab", - help_githubPages: - "Generate a .nojekyll file to prevent 404 errors in GitHub Pages. Defaults to `true`", - help_hostedBaseUrl: - "Specify a base URL to be used in generating a sitemap.xml in our output folder and canonical links. If not specified, no sitemap will be generated", - help_useHostedBaseUrlForAbsoluteLinks: - "If set, TypeDoc will produce absolute links to pages on your site using the hostedBaseUrl option", - help_hideGenerator: "Do not print the TypeDoc link at the end of the page", - help_customFooterHtml: "Custom footer after the TypeDoc link", - help_customFooterHtmlDisableWrapper: - "If set, disables the wrapper element for customFooterHtml", - help_hideParameterTypesInTitle: - "Hides parameter types in signature titles for easier scanning", - help_cacheBust: "Include the generation time in links to static assets", - help_searchInComments: - "If set, the search index will also include comments. This will greatly increase the size of the search index", - help_searchInDocuments: - "If set, the search index will also include documents. This will greatly increase the size of the search index", - help_cleanOutputDir: - "If set, TypeDoc will remove the output directory before writing output", - help_titleLink: - "Set the link the title in the header points to. Defaults to the documentation homepage", - help_navigationLinks: "Defines links to be included in the header", - help_sidebarLinks: "Defines links to be included in the sidebar", - help_navigationLeaves: - "Branches of the navigation tree which should not be expanded", - help_navigation: "Determines how the navigation sidebar is organized", - help_visibilityFilters: - "Specify the default visibility for builtin filters and additional filters according to modifier tags", - help_searchCategoryBoosts: - "Configure search to give a relevance boost to selected categories", - help_searchGroupBoosts: - 'Configure search to give a relevance boost to selected kinds (eg "class")', - help_jsDocCompatibility: - "Sets compatibility options for comment parsing that increase similarity with JSDoc comments", - help_commentStyle: "Determines how TypeDoc searches for comments", - help_useTsLinkResolution: - "Use TypeScript's link resolution when determining where @link tags point. This only applies to JSDoc style comments", - help_preserveLinkText: - "If set, @link tags without link text will use the text content as the link. If not set, will use the target reflection name", - help_blockTags: - "Block tags which TypeDoc should recognize when parsing comments", - help_inlineTags: - "Inline tags which TypeDoc should recognize when parsing comments", - help_modifierTags: - "Modifier tags which TypeDoc should recognize when parsing comments", - help_categorizeByGroup: - "Specify whether categorization will be done at the group level", - help_defaultCategory: - "Specify the default category for reflections without a category", - help_categoryOrder: - "Specify the order in which categories appear. * indicates the relative order for categories not in the list", - help_groupOrder: - "Specify the order in which groups appear. * indicates the relative order for groups not in the list", - help_sort: "Specify the sort strategy for documented values", - help_sortEntryPoints: - "If set, entry points will be subject to the same sorting rules as other reflections", - help_kindSortOrder: - "Specify the sort order for reflections when 'kind' is specified", - help_watch: "Watch files for changes and rebuild docs on change", - help_preserveWatchOutput: - "If set, TypeDoc will not clear the screen between compilation runs", - help_skipErrorChecking: - "Do not run TypeScript's type checking before generating docs", - help_help: "Print this message", - help_version: "Print TypeDoc's version", - help_showConfig: "Print the resolved configuration and exit", - help_plugin: - "Specify the npm plugins that should be loaded. Omit to load all installed plugins", - help_logLevel: "Specify what level of logging should be used", - help_treatWarningsAsErrors: - "If set, all warnings will be treated as errors", - help_treatValidationWarningsAsErrors: - "If set, warnings emitted during validation will be treated as errors. This option cannot be used to disable treatWarningsAsErrors for validation warnings", - help_intentionallyNotExported: - "A list of types which should not produce 'referenced but not documented' warnings", - help_requiredToBeDocumented: - "A list of reflection kinds that must be documented", - help_validation: - "Specify which validation steps TypeDoc should perform on your generated documentation", - - // ================================================================== - // Option validation - // ================================================================== - unknown_option_0_you_may_have_meant_1: `Unknown option '{0}' You may have meant:\n\t{1}`, - option_0_must_be_between_1_and_2: "{0} must be between {1} and {2}", - option_0_must_be_equal_to_or_greater_than_1: - "{0} must be equal to or greater than {1}", - option_0_must_be_less_than_or_equal_to_1: - "{0} must be less than or equal to {1}", - option_0_must_be_one_of_1: "{0} must be one of {1}", - flag_0_is_not_valid_for_1_expected_2: - "The flag '{0}' is not valid for {1}, expected one of {2}", - expected_object_with_flag_values_for_0: - "Expected an object with flag values for {0} or true/false", - flag_values_for_0_must_be_booleans: "Flag values for {0} must be a boolean", - locales_must_be_an_object: - "The 'locales' option must be set to an object which resembles: { en: { theme_implements: \"Implements\" }}", - exclude_not_documented_specified_0_valid_values_are_1: `excludeNotDocumentedKinds may only specify known values, and invalid values were provided ({0}). The valid kinds are:\n{1}`, - external_symbol_link_mappings_must_be_object: - "externalSymbolLinkMappings must be a Record>", - highlight_theme_0_must_be_one_of_1: "{0} must be one of the following: {1}", - highlightLanguages_contains_invalid_languages_0: - "highlightLanguages contains invalid languages: {0}, run typedoc --help for a list of supported languages", - hostedBaseUrl_must_start_with_http: - "hostedBaseUrl must start with http:// or https://", - useHostedBaseUrlForAbsoluteLinks_requires_hostedBaseUrl: - "The useHostedBaseUrlForAbsoluteLinks option requires that hostedBaseUrl be set", - option_0_must_be_an_object: "The '{0}' option must be a non-array object", - option_0_must_be_a_function: "The '{0}' option must be a function", - option_0_must_be_object_with_urls: `{0} must be an object with string labels as keys and URL values`, - visibility_filters_only_include_0: `visibilityFilters can only include the following non-@ keys: {0}`, - visibility_filters_must_be_booleans: `All values of visibilityFilters must be booleans`, - option_0_values_must_be_numbers: "All values of {0} must be numbers", - option_0_values_must_be_array_of_tags: - "{0} must be an array of valid tag names", - option_0_specified_1_but_only_2_is_valid: `{0} may only specify known values, and invalid values were provided ({1}). The valid sort strategies are:\n{2}`, - - // ReflectionKind singular translations - kind_project: "Project", - kind_module: "Module", - kind_namespace: "Namespace", - kind_enum: "Enumeration", - kind_enum_member: "Enumeration Member", - kind_variable: "Variable", - kind_function: "Function", - kind_class: "Class", - kind_interface: "Interface", - kind_constructor: "Constructor", - kind_property: "Property", - kind_method: "Method", - kind_call_signature: "Call Signature", - kind_index_signature: "Index Signature", - kind_constructor_signature: "Constructor Signature", - kind_parameter: "Parameter", - kind_type_literal: "Type Literal", - kind_type_parameter: "Type Parameter", - kind_accessor: "Accessor", - kind_get_signature: "Get Signature", - kind_set_signature: "Set Signature", - kind_type_alias: "Type Alias", - kind_reference: "Reference", - kind_document: "Document", - - // ReflectionKind plural translations - kind_plural_project: "Projects", - kind_plural_module: "Modules", - kind_plural_namespace: "Namespaces", - kind_plural_enum: "Enumerations", - kind_plural_enum_member: "Enumeration Members", - kind_plural_variable: "Variables", - kind_plural_function: "Functions", - kind_plural_class: "Classes", - kind_plural_interface: "Interfaces", - kind_plural_constructor: "Constructors", - kind_plural_property: "Properties", - kind_plural_method: "Methods", - kind_plural_call_signature: "Call Signatures", - kind_plural_index_signature: "Index Signatures", - kind_plural_constructor_signature: "Constructor Signatures", - kind_plural_parameter: "Parameters", - kind_plural_type_literal: "Type Literals", - kind_plural_type_parameter: "Type Parameters", - kind_plural_accessor: "Accessors", - kind_plural_get_signature: "Get Signatures", - kind_plural_set_signature: "Set Signatures", - kind_plural_type_alias: "Type Aliases", - kind_plural_reference: "References", - kind_plural_document: "Documents", - - // ReflectionFlag translations - flag_private: "Private", - flag_protected: "Protected", - flag_public: "Public", - flag_static: "Static", - flag_external: "External", - flag_optional: "Optional", - flag_rest: "Rest", - flag_abstract: "Abstract", - flag_const: "Const", - flag_readonly: "Readonly", - flag_inherited: "Inherited", - - // ================================================================== - // Strings that show up in the default theme - // ================================================================== - // Page headings/labels - theme_implements: "Implements", - theme_indexable: "Indexable", - theme_type_declaration: "Type declaration", - theme_index: "Index", - theme_hierarchy: "Hierarchy", - theme_hierarchy_view_full: "view full", - theme_implemented_by: "Implemented by", - theme_defined_in: "Defined in", - theme_implementation_of: "Implementation of", - theme_inherited_from: "Inherited from", - theme_overrides: "Overrides", - theme_returns: "Returns", - theme_re_exports: "Re-exports", - theme_renames_and_re_exports: "Renames and re-exports", - theme_generated_using_typedoc: "Generated using TypeDoc", // If this includes "TypeDoc", theme will insert a link at that location. - theme_class_hierarchy_title: "Class Hierarchy", - // Search - theme_preparing_search_index: "Preparing search index...", - theme_search_index_not_available: "The search index is not available", - // Left nav bar - theme_loading: "Loading...", - // Right nav bar - theme_settings: "Settings", - theme_member_visibility: "Member Visibility", - theme_theme: "Theme", - theme_os: "OS", - theme_light: "Light", - theme_dark: "Dark", - theme_on_this_page: "On This Page", - - // aria-label - theme_search: "Search", - theme_menu: "Menu", - theme_permalink: "Permalink", - - // Used by the frontend JS - theme_copy: "Copy", - theme_copied: "Copied!", - theme_normally_hidden: - "This member is normally hidden due to your filter settings.", -} as const; +import translatable from "./locales/en.cjs"; export type BuiltinTranslatableStringArgs = { [K in keyof typeof translatable]: BuildTranslationArguments< diff --git a/src/lib/models/FileRegistry.ts b/src/lib/models/FileRegistry.ts index e6331547f..1b1ea99fc 100644 --- a/src/lib/models/FileRegistry.ts +++ b/src/lib/models/FileRegistry.ts @@ -1,9 +1,9 @@ import { basename, dirname, parse, relative, resolve } from "path"; -import type { Deserializer, Serializer } from "../serialization"; -import type { FileRegistry as JSONFileRegistry } from "../serialization/schema"; -import { normalizePath } from "../utils"; +import type { Deserializer, Serializer } from "../serialization/index.js"; +import type { FileRegistry as JSONFileRegistry } from "../serialization/schema.js"; +import { normalizePath } from "../utils/index.js"; import { existsSync } from "fs"; -import type { Reflection } from "./reflections"; +import type { Reflection } from "./reflections/index.js"; export class FileRegistry { protected nextId = 1; diff --git a/src/lib/models/reflections/document.ts b/src/lib/models/reflections/document.ts index 74c6b54ec..b68c8265e 100644 --- a/src/lib/models/reflections/document.ts +++ b/src/lib/models/reflections/document.ts @@ -1,11 +1,15 @@ -import type { Deserializer, JSONOutput, Serializer } from "../../serialization"; -import { Comment, type CommentDisplayPart } from "../comments"; +import type { + Deserializer, + JSONOutput, + Serializer, +} from "../../serialization/index.js"; +import { Comment, type CommentDisplayPart } from "../comments/index.js"; import { Reflection, TraverseProperty, type TraverseCallback, -} from "./abstract"; -import { ReflectionKind } from "./kind"; +} from "./abstract.js"; +import { ReflectionKind } from "./kind.js"; /** * Non-TS reflection type which is used to represent markdown documents included in the docs. diff --git a/src/lib/output/plugins/SitemapPlugin.ts b/src/lib/output/plugins/SitemapPlugin.ts index c4ffce856..3a9be2afe 100644 --- a/src/lib/output/plugins/SitemapPlugin.ts +++ b/src/lib/output/plugins/SitemapPlugin.ts @@ -87,13 +87,13 @@ function stringifyXml(xml: XmlElementData, indent = 0) { const parts = ["\t".repeat(indent), "<", xml.tag]; for (const [key, val] of Object.entries(xml.attr || {})) { - parts.push(" ", key, '="', html.escapeHtml(val), '"'); + parts.push(" ", key, '="', escapeHtml(val), '"'); } parts.push(">"); if (typeof xml.children === "string") { - parts.push(html.escapeHtml(xml.children)); + parts.push(escapeHtml(xml.children)); } else { for (const child of xml.children) { parts.push("\n"); diff --git a/src/lib/output/themes/default/templates/document.tsx b/src/lib/output/themes/default/templates/document.tsx index 5ea74b5e9..ff414e00e 100644 --- a/src/lib/output/themes/default/templates/document.tsx +++ b/src/lib/output/themes/default/templates/document.tsx @@ -1,7 +1,7 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext"; -import type { DocumentReflection } from "../../../../models"; -import type { PageEvent } from "../../../events"; -import { JSX, Raw } from "../../../../utils"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +import type { DocumentReflection } from "../../../../models/index.js"; +import type { PageEvent } from "../../../events.js"; +import { JSX, Raw } from "../../../../utils/index.js"; export const documentTemplate = ({ markdown }: DefaultThemeRenderContext, props: PageEvent) => (
diff --git a/src/lib/utils/events.ts b/src/lib/utils/events.ts index 0dcce2fa8..0303b6db6 100644 --- a/src/lib/utils/events.ts +++ b/src/lib/utils/events.ts @@ -1,4 +1,4 @@ -import { insertPrioritySorted } from "./array"; +import { insertPrioritySorted } from "./array.js"; /** * Intentionally very simple event emitter. diff --git a/src/lib/utils/jsx.ts b/src/lib/utils/jsx.ts index 10e467d58..c35e6c154 100644 --- a/src/lib/utils/jsx.ts +++ b/src/lib/utils/jsx.ts @@ -13,8 +13,7 @@ * @module */ -import html from "./html.cjs"; -const { escapeHtml } = html; +import { escapeHtml } from "./html.js"; import type { IntrinsicElements, JsxElement, diff --git a/src/test/internationalization.test.ts b/src/test/internationalization.test.ts index 5f6b63dc9..3d621a7f1 100644 --- a/src/test/internationalization.test.ts +++ b/src/test/internationalization.test.ts @@ -2,13 +2,15 @@ import { deepEqual as equal, ok } from "assert/strict"; import { Application } from "../index.js"; import { readdirSync } from "fs"; import { join } from "path"; -import { translatable } from "../lib/internationalization/translatable.js"; +import translatable from "../lib/internationalization/locales/en.cjs"; import { setDifference } from "../lib/utils/set.js"; import { blockTags, inlineTags, modifierTags, } from "../lib/utils/options/tsdoc-defaults.js"; +import { fileURLToPath } from "node:url"; +import { createRequire } from "node:module"; const allValidTranslationKeys = Object.keys(translatable); // The tag names do not actually exist in the default locale, but are valid @@ -64,7 +66,6 @@ describe("Locales", () => { for (const locale of readdirSync(localeRoot)) { it(`${locale} defines a valid locale`, () => { const req = createRequire(fileURLToPath(import.meta.url)); - // eslint-disable-next-line @typescript-eslint/no-var-requires const translations = req(join(localeRoot, locale)) as Record< string, string diff --git a/src/test/utils/options/tsdoc-defaults.test.ts b/src/test/utils/options/tsdoc-defaults.test.ts index 7d636a0bb..474319320 100644 --- a/src/test/utils/options/tsdoc-defaults.test.ts +++ b/src/test/utils/options/tsdoc-defaults.test.ts @@ -1,7 +1,7 @@ import { deepEqual as equal } from "assert/strict"; import { join } from "path"; import ts from "typescript"; -import * as defaults from "../../../lib/utils/options/tsdoc-defaults"; +import * as defaults from "../../../lib/utils/options/tsdoc-defaults.js"; describe("tsdoc-defaults.ts", () => { const tsdoc = ts.readConfigFile( diff --git a/src/test/utils/path.test.ts b/src/test/utils/path.test.ts index 70c84df3d..9159b0ac6 100644 --- a/src/test/utils/path.test.ts +++ b/src/test/utils/path.test.ts @@ -1,5 +1,5 @@ import { equal } from "assert"; -import { normalizePath } from "../../lib/utils"; +import { normalizePath } from "../../lib/utils/index.js"; describe("normalizePath", () => { const winTest = process.platform === "win32" ? it : it.skip; From e2af5c30e98d33a3f38d32a1cd3cadd898904fb6 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 16:58:09 -0600 Subject: [PATCH 004/219] It compiles now, tests are unhappy --- src/lib/output/themes/MarkedPlugin.tsx | 4 +++- src/lib/output/themes/default/partials/anchor-icon.tsx | 2 ++ src/lib/output/themes/default/partials/header.tsx | 2 ++ src/lib/output/themes/default/partials/hierarchy.tsx | 2 ++ .../output/themes/default/partials/member.getterSetter.tsx | 2 ++ src/lib/output/themes/default/partials/member.reference.tsx | 2 ++ .../output/themes/default/partials/member.signature.title.tsx | 2 ++ src/lib/output/themes/default/partials/member.signatures.tsx | 2 ++ src/lib/output/themes/default/partials/members.group.tsx | 2 ++ src/lib/output/themes/default/partials/members.tsx | 2 ++ src/lib/output/themes/default/partials/parameter.tsx | 2 ++ src/lib/output/themes/default/partials/reflectionPreview.tsx | 2 ++ src/lib/output/themes/default/partials/toolbar.tsx | 2 ++ src/lib/output/themes/default/partials/typeParameters.tsx | 2 ++ src/lib/output/themes/default/templates/hierarchy.tsx | 2 ++ src/test/converter2/package.json | 3 +++ src/test/utils/options/tsdoc-defaults.test.ts | 3 ++- 17 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/test/converter2/package.json diff --git a/src/lib/output/themes/MarkedPlugin.tsx b/src/lib/output/themes/MarkedPlugin.tsx index ac5f2c4f5..0a413bf8c 100644 --- a/src/lib/output/themes/MarkedPlugin.tsx +++ b/src/lib/output/themes/MarkedPlugin.tsx @@ -1,4 +1,6 @@ import markdown from "markdown-it"; +// @types/markdown-it is busted, this type isn't exported with ESM. +import type md from "markdown-it" with { "resolution-mode": "require" }; import { Component, ContextAwareRendererComponent } from "../components.js"; import { type RendererEvent, MarkdownEvent, type PageEvent } from "../events.js"; @@ -278,7 +280,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent { } } -function getTokenTextContent(token: markdown.Token): string { +function getTokenTextContent(token: md.Token): string { if (token.children) { return token.children.map(getTokenTextContent).join(""); } diff --git a/src/lib/output/themes/default/partials/anchor-icon.tsx b/src/lib/output/themes/default/partials/anchor-icon.tsx index d6ff3fed0..384265db1 100644 --- a/src/lib/output/themes/default/partials/anchor-icon.tsx +++ b/src/lib/output/themes/default/partials/anchor-icon.tsx @@ -1,6 +1,8 @@ import { JSX } from "../../../../utils/index.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export function anchorIcon(context: DefaultThemeRenderContext, anchor: string | undefined) { if (!anchor) return <>; diff --git a/src/lib/output/themes/default/partials/header.tsx b/src/lib/output/themes/default/partials/header.tsx index a29cd86d7..8a4446d6e 100644 --- a/src/lib/output/themes/default/partials/header.tsx +++ b/src/lib/output/themes/default/partials/header.tsx @@ -4,6 +4,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import type { PageEvent } from "../../../events.js"; import { type Reflection, ReflectionKind } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export const header = (context: DefaultThemeRenderContext, props: PageEvent) => { const HeadingLevel = props.model.isProject() ? "h2" : "h1"; return ( diff --git a/src/lib/output/themes/default/partials/hierarchy.tsx b/src/lib/output/themes/default/partials/hierarchy.tsx index 16c6bda7f..e21c6c4d9 100644 --- a/src/lib/output/themes/default/partials/hierarchy.tsx +++ b/src/lib/output/themes/default/partials/hierarchy.tsx @@ -2,6 +2,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import { JSX } from "../../../../utils/index.js"; import type { DeclarationHierarchy, Type } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + const isLinkedReferenceType = (type: Type) => type.visit({ reference: (ref) => ref.reflection !== undefined, diff --git a/src/lib/output/themes/default/partials/member.getterSetter.tsx b/src/lib/output/themes/default/partials/member.getterSetter.tsx index 7825eb62e..85ff45262 100644 --- a/src/lib/output/themes/default/partials/member.getterSetter.tsx +++ b/src/lib/output/themes/default/partials/member.getterSetter.tsx @@ -3,6 +3,8 @@ import { JSX } from "../../../../utils/index.js"; import { classNames } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export const memberGetterSetter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <>
    { const referenced = props.tryGetTargetReflectionDeep(); diff --git a/src/lib/output/themes/default/partials/member.signature.title.tsx b/src/lib/output/themes/default/partials/member.signature.title.tsx index 9bfca77bf..3bb053063 100644 --- a/src/lib/output/themes/default/partials/member.signature.title.tsx +++ b/src/lib/output/themes/default/partials/member.signature.title.tsx @@ -3,6 +3,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import { JSX } from "../../../../utils/index.js"; import { type ParameterReflection, ReflectionKind, type SignatureReflection } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + function renderParameterWithType(context: DefaultThemeRenderContext, item: ParameterReflection) { return ( <> diff --git a/src/lib/output/themes/default/partials/member.signatures.tsx b/src/lib/output/themes/default/partials/member.signatures.tsx index 99e9bff3c..1b602c7ab 100644 --- a/src/lib/output/themes/default/partials/member.signatures.tsx +++ b/src/lib/output/themes/default/partials/member.signatures.tsx @@ -4,6 +4,8 @@ import type { DeclarationReflection } from "../../../../models/index.js"; import { anchorIcon } from "./anchor-icon.js"; import { classNames } from "../../lib.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export const memberSignatures = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <>
      diff --git a/src/lib/output/themes/default/partials/members.group.tsx b/src/lib/output/themes/default/partials/members.group.tsx index 2f54029ed..c03455e8c 100644 --- a/src/lib/output/themes/default/partials/members.group.tsx +++ b/src/lib/output/themes/default/partials/members.group.tsx @@ -2,6 +2,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import { JSX } from "../../../../utils/index.js"; import type { ReflectionGroup } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export function membersGroup(context: DefaultThemeRenderContext, group: ReflectionGroup) { if (group.categories) { return ( diff --git a/src/lib/output/themes/default/partials/members.tsx b/src/lib/output/themes/default/partials/members.tsx index 5428e7ed0..e5b3d8def 100644 --- a/src/lib/output/themes/default/partials/members.tsx +++ b/src/lib/output/themes/default/partials/members.tsx @@ -3,6 +3,8 @@ import { JSX } from "../../../../utils/index.js"; import { type ContainerReflection, DeclarationReflection } from "../../../../models/index.js"; import { classNames } from "../../lib.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export function members(context: DefaultThemeRenderContext, props: ContainerReflection) { if (props.categories && props.categories.length) { return ( diff --git a/src/lib/output/themes/default/partials/parameter.tsx b/src/lib/output/themes/default/partials/parameter.tsx index 274c05332..a1e392792 100644 --- a/src/lib/output/themes/default/partials/parameter.tsx +++ b/src/lib/output/themes/default/partials/parameter.tsx @@ -3,6 +3,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import { JSX } from "../../../../utils/index.js"; import { type DeclarationReflection, ReflectionType, type SignatureReflection } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export const parameter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <>
        diff --git a/src/lib/output/themes/default/partials/reflectionPreview.tsx b/src/lib/output/themes/default/partials/reflectionPreview.tsx index 1fbd3d502..78b0a4e20 100644 --- a/src/lib/output/themes/default/partials/reflectionPreview.tsx +++ b/src/lib/output/themes/default/partials/reflectionPreview.tsx @@ -3,6 +3,8 @@ import { JSX } from "../../../../utils/index.js"; import { getKindClass, renderTypeParametersSignature } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export function reflectionPreview(context: DefaultThemeRenderContext, props: Reflection) { if (!(props instanceof DeclarationReflection)) return; diff --git a/src/lib/output/themes/default/partials/toolbar.tsx b/src/lib/output/themes/default/partials/toolbar.tsx index 1920f6964..e44b04b99 100644 --- a/src/lib/output/themes/default/partials/toolbar.tsx +++ b/src/lib/output/themes/default/partials/toolbar.tsx @@ -4,6 +4,8 @@ import type { PageEvent } from "../../../events.js"; import { getDisplayName } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export const toolbar = (context: DefaultThemeRenderContext, props: PageEvent) => (
        diff --git a/src/lib/output/themes/default/partials/typeParameters.tsx b/src/lib/output/themes/default/partials/typeParameters.tsx index 3bfb507cb..3ca4373a1 100644 --- a/src/lib/output/themes/default/partials/typeParameters.tsx +++ b/src/lib/output/themes/default/partials/typeParameters.tsx @@ -2,6 +2,8 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import type { TypeParameterReflection } from "../../../../models/index.js"; import { JSX } from "../../../../utils/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + export function typeParameters(context: DefaultThemeRenderContext, typeParameters: TypeParameterReflection[]) { return ( <> diff --git a/src/lib/output/themes/default/templates/hierarchy.tsx b/src/lib/output/themes/default/templates/hierarchy.tsx index 61b3fa4ca..b968627e9 100644 --- a/src/lib/output/themes/default/templates/hierarchy.tsx +++ b/src/lib/output/themes/default/templates/hierarchy.tsx @@ -4,6 +4,8 @@ import { JSX } from "../../../../utils/index.js"; import { getHierarchyRoots } from "../../lib.js"; import type { DeclarationReflection, ProjectReflection } from "../../../../models/index.js"; +void JSX; // Trick TS into seeing this as used, the import is required. + function fullHierarchy( context: DefaultThemeRenderContext, root: DeclarationReflection, diff --git a/src/test/converter2/package.json b/src/test/converter2/package.json new file mode 100644 index 000000000..5bbefffba --- /dev/null +++ b/src/test/converter2/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/src/test/utils/options/tsdoc-defaults.test.ts b/src/test/utils/options/tsdoc-defaults.test.ts index 474319320..79a566c3c 100644 --- a/src/test/utils/options/tsdoc-defaults.test.ts +++ b/src/test/utils/options/tsdoc-defaults.test.ts @@ -2,10 +2,11 @@ import { deepEqual as equal } from "assert/strict"; import { join } from "path"; import ts from "typescript"; import * as defaults from "../../../lib/utils/options/tsdoc-defaults.js"; +import { fileURLToPath } from "url"; describe("tsdoc-defaults.ts", () => { const tsdoc = ts.readConfigFile( - join(__dirname, "../../../../tsdoc.json"), + join(fileURLToPath(import.meta.url), "../../../../../tsdoc.json"), ts.sys.readFile, ); const tagDefinitions = tsdoc.config?.tagDefinitions as Array<{ From 9220785dddcaad644d8d9fb6f44fea1bb29c4447 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 17:44:05 -0600 Subject: [PATCH 005/219] Bump tsconfig version to es2022 to workaround tsx bug https://github.com/privatenumber/tsx/issues/597 --- src/lib/converter/utils/repository.ts | 14 ++++++++------ src/lib/models/reflections/parameter.ts | 2 +- src/lib/models/reflections/signature.ts | 4 ++-- src/lib/models/reflections/type-parameter.ts | 2 +- tsconfig.json | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/lib/converter/utils/repository.ts b/src/lib/converter/utils/repository.ts index e5f813647..1616750aa 100644 --- a/src/lib/converter/utils/repository.ts +++ b/src/lib/converter/utils/repository.ts @@ -175,11 +175,7 @@ export class GitRepository implements Repository { */ export class RepositoryManager { private cache = new Map(); - private assumedRepo = new AssumedRepository( - this.basePath, - this.gitRevision, - this.sourceLinkTemplate, - ); + private assumedRepo: Repository; constructor( private basePath: string, @@ -188,7 +184,13 @@ export class RepositoryManager { private sourceLinkTemplate: string, private disableGit: boolean, private logger: Logger, - ) {} + ) { + this.assumedRepo = new AssumedRepository( + this.basePath, + this.gitRevision, + this.sourceLinkTemplate, + ); + } /** * Check whether the given file is placed inside a repository. diff --git a/src/lib/models/reflections/parameter.ts b/src/lib/models/reflections/parameter.ts index 43b8ab0e0..09f5c8fcf 100644 --- a/src/lib/models/reflections/parameter.ts +++ b/src/lib/models/reflections/parameter.ts @@ -18,7 +18,7 @@ import type { export class ParameterReflection extends Reflection { readonly variant = "param"; - override parent?: SignatureReflection; + declare parent?: SignatureReflection; defaultValue?: string; diff --git a/src/lib/models/reflections/signature.ts b/src/lib/models/reflections/signature.ts index 783fdaf13..56f5a601d 100644 --- a/src/lib/models/reflections/signature.ts +++ b/src/lib/models/reflections/signature.ts @@ -31,14 +31,14 @@ export class SignatureReflection extends Reflection { super(name, kind, parent); } - override kind!: + declare kind: | ReflectionKind.SetSignature | ReflectionKind.GetSignature | ReflectionKind.IndexSignature | ReflectionKind.CallSignature | ReflectionKind.ConstructorSignature; - override parent!: DeclarationReflection; + declare parent: DeclarationReflection; /** * A list of all source files that contributed to this reflection. diff --git a/src/lib/models/reflections/type-parameter.ts b/src/lib/models/reflections/type-parameter.ts index 6a56e214a..9feac59ea 100644 --- a/src/lib/models/reflections/type-parameter.ts +++ b/src/lib/models/reflections/type-parameter.ts @@ -27,7 +27,7 @@ export type VarianceModifier = export class TypeParameterReflection extends Reflection { readonly variant = "typeParam"; - override parent?: DeclarationReflection | SignatureReflection; + declare parent?: DeclarationReflection | SignatureReflection; type?: SomeType; diff --git a/tsconfig.json b/tsconfig.json index 2a8931c3e..e5c1b60f1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,8 @@ { "compilerOptions": { "module": "Node16", - "lib": ["es2021"], - "target": "es2021", + "lib": ["es2022"], + "target": "es2022", // Add our `ts` internal types "typeRoots": ["node_modules/@types", "src/lib/types"], From a789b325301ccfb4eefab94869d1e19d9276ba38 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 18:46:42 -0600 Subject: [PATCH 006/219] Get rid of component nastiness to make ESM work ... this has really highlighted how bad the plugin design is for TypeDoc's internal plugins. They really need to be refactored to look more similar to external plugins. --- .config/typedoc.json | 4 - src/lib/application.ts | 10 +- src/lib/converter/components.ts | 4 +- src/lib/converter/converter.ts | 34 +- src/lib/converter/index.ts | 2 - src/lib/converter/plugins/CategoryPlugin.ts | 3 +- src/lib/converter/plugins/CommentPlugin.ts | 3 +- src/lib/converter/plugins/GroupPlugin.ts | 3 +- src/lib/converter/plugins/ImplementsPlugin.ts | 3 +- src/lib/converter/plugins/InheritDocPlugin.ts | 3 +- .../converter/plugins/LinkResolverPlugin.ts | 3 +- src/lib/converter/plugins/PackagePlugin.ts | 3 +- src/lib/converter/plugins/SourcePlugin.ts | 3 +- src/lib/converter/plugins/TypePlugin.ts | 3 +- src/lib/output/components.ts | 4 +- src/lib/output/index.ts | 2 - src/lib/output/plugins/AssetsPlugin.ts | 3 +- src/lib/output/plugins/IconsPlugin.tsx | 3 +- .../output/plugins/JavascriptIndexPlugin.ts | 3 +- src/lib/output/plugins/NavigationPlugin.ts | 3 +- src/lib/output/plugins/SitemapPlugin.ts | 3 +- src/lib/output/renderer.ts | 37 +- src/lib/output/theme.ts | 2 - src/lib/output/themes/MarkedPlugin.tsx | 3 +- .../output/themes/default/DefaultTheme.tsx | 2 +- src/lib/utils/component.ts | 139 - src/lib/utils/html-entities.json | 2326 ---------------- src/lib/utils/html-entities.ts | 2330 +++++++++++++++++ src/lib/utils/html.ts | 5 +- src/lib/utils/index.ts | 6 +- 30 files changed, 2398 insertions(+), 2554 deletions(-) delete mode 100644 src/lib/utils/html-entities.json create mode 100644 src/lib/utils/html-entities.ts diff --git a/.config/typedoc.json b/.config/typedoc.json index 609bee4b7..1eec70673 100644 --- a/.config/typedoc.json +++ b/.config/typedoc.json @@ -1,10 +1,6 @@ { "$schema": "https://typedoc.org/schema.json", "intentionallyNotExported": [ - "ComponentClass", - "AbstractComponent", - "ConverterComponent", - "RendererComponent", "SORT_STRATEGIES", "_ModelToObject", "EventHooksMomento", diff --git a/src/lib/application.ts b/src/lib/application.ts index 580b0e334..c4316f90e 100644 --- a/src/lib/application.ts +++ b/src/lib/application.ts @@ -18,13 +18,9 @@ import { TSConfigReader, TypeDocReader, PackageJsonReader, + AbstractComponent, } from "./utils/index.js"; -import { - type AbstractComponent, - ChildableComponent, - Component, -} from "./utils/component.js"; import { Options, Option } from "./utils/index.js"; import type { TypeDocOptions } from "./utils/options/declaration.js"; import { unique } from "./utils/array.js"; @@ -109,10 +105,8 @@ export interface ApplicationEvents { * Access to an Application instance can be retrieved with {@link Application.bootstrap} or * {@link Application.bootstrapWithPlugins}. It can not be constructed manually. */ -@Component({ name: "application", internal: true }) -export class Application extends ChildableComponent< +export class Application extends AbstractComponent< Application, - AbstractComponent, ApplicationEvents > { /** diff --git a/src/lib/converter/components.ts b/src/lib/converter/components.ts index d2ac14713..4df0f837c 100644 --- a/src/lib/converter/components.ts +++ b/src/lib/converter/components.ts @@ -1,8 +1,6 @@ -import { Component, AbstractComponent } from "../utils/component.js"; +import { AbstractComponent } from "../utils/component.js"; import type { Converter } from "./converter.js"; -export { Component }; - export abstract class ConverterComponent extends AbstractComponent< Converter, {} diff --git a/src/lib/converter/converter.ts b/src/lib/converter/converter.ts index 64b1315fe..32de75ec9 100644 --- a/src/lib/converter/converter.ts +++ b/src/lib/converter/converter.ts @@ -17,8 +17,7 @@ import { type TypeParameterReflection, } from "../models/index.js"; import { Context } from "./context.js"; -import { ConverterComponent } from "./components.js"; -import { Component, ChildableComponent } from "../utils/component.js"; +import { AbstractComponent } from "../utils/component.js"; import { Option, MinimalSourceFile, @@ -53,6 +52,16 @@ import { import { basename, dirname, resolve } from "path"; import type { FileRegistry } from "../models/FileRegistry.js"; +import { GroupPlugin } from "./plugins/GroupPlugin.js"; +import { CategoryPlugin } from "./plugins/CategoryPlugin.js"; +import { CommentPlugin } from "./plugins/CommentPlugin.js"; +import { ImplementsPlugin } from "./plugins/ImplementsPlugin.js"; +import { InheritDocPlugin } from "./plugins/InheritDocPlugin.js"; +import { LinkResolverPlugin } from "./plugins/LinkResolverPlugin.js"; +import { PackagePlugin } from "./plugins/PackagePlugin.js"; +import { SourcePlugin } from "./plugins/SourcePlugin.js"; +import { TypePlugin } from "./plugins/TypePlugin.js"; + export interface ConverterEvents { begin: [Context]; end: [Context]; @@ -81,16 +90,7 @@ export interface ConverterEvents { /** * Compiles source files using TypeScript and converts compiler symbols to reflections. */ -@Component({ - name: "converter", - internal: true, - childClass: ConverterComponent, -}) -export class Converter extends ChildableComponent< - Application, - ConverterComponent, - ConverterEvents -> { +export class Converter extends AbstractComponent { /** @internal */ @Option("externalPattern") accessor externalPattern!: string[]; @@ -257,6 +257,16 @@ export class Converter extends ChildableComponent< return modLinks["*"]; } }); + + new CategoryPlugin(this); + new CommentPlugin(this); + new GroupPlugin(this); + new ImplementsPlugin(this); + new InheritDocPlugin(this); + new LinkResolverPlugin(this); + new PackagePlugin(this); + new SourcePlugin(this); + new TypePlugin(this); } /** diff --git a/src/lib/converter/index.ts b/src/lib/converter/index.ts index c33a2bae2..480be5eb8 100644 --- a/src/lib/converter/index.ts +++ b/src/lib/converter/index.ts @@ -16,5 +16,3 @@ export type { ExternalSymbolResolver, ExternalResolveResult, } from "./comments/linkResolver.js"; - -import "./plugins/index.js"; diff --git a/src/lib/converter/plugins/CategoryPlugin.ts b/src/lib/converter/plugins/CategoryPlugin.ts index 76e4bffa0..f4b573681 100644 --- a/src/lib/converter/plugins/CategoryPlugin.ts +++ b/src/lib/converter/plugins/CategoryPlugin.ts @@ -5,7 +5,7 @@ import { type DocumentReflection, } from "../../models/index.js"; import { ReflectionCategory } from "../../models/index.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { Option, getSortFunction, removeIf } from "../../utils/index.js"; @@ -15,7 +15,6 @@ import { Option, getSortFunction, removeIf } from "../../utils/index.js"; * * The handler sets the ´category´ property of all reflections. */ -@Component({ name: "category" }) export class CategoryPlugin extends ConverterComponent { sortFunction!: ( reflections: Array, diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index b8a47b400..9f1457e06 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -1,4 +1,4 @@ -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { @@ -117,7 +117,6 @@ const MUTUALLY_EXCLUSIVE_MODIFIERS = [ * - Resolve `@link` tags to point to target reflections * */ -@Component({ name: "comment" }) export class CommentPlugin extends ConverterComponent { @Option("excludeTags") accessor excludeTags!: `@${string}`[]; diff --git a/src/lib/converter/plugins/GroupPlugin.ts b/src/lib/converter/plugins/GroupPlugin.ts index ca7349068..5866aae28 100644 --- a/src/lib/converter/plugins/GroupPlugin.ts +++ b/src/lib/converter/plugins/GroupPlugin.ts @@ -5,7 +5,7 @@ import { type DocumentReflection, } from "../../models/reflections/index.js"; import { ReflectionGroup } from "../../models/ReflectionGroup.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { getSortFunction } from "../../utils/sort.js"; @@ -40,7 +40,6 @@ const defaultGroupOrder = [ * * The handler sets the `groups` property of all container reflections. */ -@Component({ name: "group" }) export class GroupPlugin extends ConverterComponent { sortFunction!: ( reflections: Array, diff --git a/src/lib/converter/plugins/ImplementsPlugin.ts b/src/lib/converter/plugins/ImplementsPlugin.ts index fe473d22d..de2fc41ed 100644 --- a/src/lib/converter/plugins/ImplementsPlugin.ts +++ b/src/lib/converter/plugins/ImplementsPlugin.ts @@ -15,7 +15,7 @@ import { type Type, } from "../../models/types.js"; import { filterMap, zip } from "../../utils/array.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import type { Context } from "../context.js"; import { Converter } from "../converter.js"; import { getHumanName } from "../../utils/index.js"; @@ -25,7 +25,6 @@ import type { TranslatedString } from "../../internationalization/internationali * A plugin that detects interface implementations of functions and * properties on classes and links them. */ -@Component({ name: "implements" }) export class ImplementsPlugin extends ConverterComponent { private resolved = new WeakSet(); private postponed = new WeakMap>(); diff --git a/src/lib/converter/plugins/InheritDocPlugin.ts b/src/lib/converter/plugins/InheritDocPlugin.ts index 63b8ce517..98311045e 100644 --- a/src/lib/converter/plugins/InheritDocPlugin.ts +++ b/src/lib/converter/plugins/InheritDocPlugin.ts @@ -6,7 +6,7 @@ import { ReflectionType, SignatureReflection, } from "../../models/index.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import type { Reflection } from "../../models/reflections/abstract.js"; @@ -33,7 +33,6 @@ import { ApplicationEvents } from "../../application-events.js"; * - `@typeParam` block * - `@return` block */ -@Component({ name: "inheritDoc" }) export class InheritDocPlugin extends ConverterComponent { @Option("validation") accessor validation!: ValidationOptions; diff --git a/src/lib/converter/plugins/LinkResolverPlugin.ts b/src/lib/converter/plugins/LinkResolverPlugin.ts index c0c9c9839..2b3b6ebc8 100644 --- a/src/lib/converter/plugins/LinkResolverPlugin.ts +++ b/src/lib/converter/plugins/LinkResolverPlugin.ts @@ -1,4 +1,4 @@ -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import type { Context } from "../../converter/index.js"; import { ConverterEvents } from "../converter-events.js"; import { Option, type ValidationOptions } from "../../utils/index.js"; @@ -16,7 +16,6 @@ import { ApplicationEvents } from "../../application-events.js"; /** * A plugin that resolves `{@link Foo}` tags. */ -@Component({ name: "link-resolver" }) export class LinkResolverPlugin extends ConverterComponent { @Option("validation") accessor validation!: ValidationOptions; diff --git a/src/lib/converter/plugins/PackagePlugin.ts b/src/lib/converter/plugins/PackagePlugin.ts index 9bc8209f2..56b1a431d 100644 --- a/src/lib/converter/plugins/PackagePlugin.ts +++ b/src/lib/converter/plugins/PackagePlugin.ts @@ -1,6 +1,6 @@ import * as Path from "path"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { Option, EntryPointStrategy, readFile } from "../../utils/index.js"; @@ -19,7 +19,6 @@ import { join } from "path"; * A handler that tries to find the package.json and readme.md files of the * current project. */ -@Component({ name: "package" }) export class PackagePlugin extends ConverterComponent { @Option("readme") accessor readme!: string; diff --git a/src/lib/converter/plugins/SourcePlugin.ts b/src/lib/converter/plugins/SourcePlugin.ts index cd2946974..fff6e4a14 100644 --- a/src/lib/converter/plugins/SourcePlugin.ts +++ b/src/lib/converter/plugins/SourcePlugin.ts @@ -4,7 +4,7 @@ import { DeclarationReflection, SignatureReflection, } from "../../models/reflections/index.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { @@ -20,7 +20,6 @@ import { gitIsInstalled, RepositoryManager } from "../utils/repository.js"; /** * A handler that attaches source file information to reflections. */ -@Component({ name: "source" }) export class SourcePlugin extends ConverterComponent { @Option("disableSources") accessor disableSources!: boolean; diff --git a/src/lib/converter/plugins/TypePlugin.ts b/src/lib/converter/plugins/TypePlugin.ts index 3eddc37f5..ab7505a60 100644 --- a/src/lib/converter/plugins/TypePlugin.ts +++ b/src/lib/converter/plugins/TypePlugin.ts @@ -6,7 +6,7 @@ import { type Reflection, } from "../../models/reflections/index.js"; import { type Type, ReferenceType } from "../../models/types.js"; -import { Component, ConverterComponent } from "../components.js"; +import { ConverterComponent } from "../components.js"; import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { ApplicationEvents } from "../../application-events.js"; @@ -14,7 +14,6 @@ import { ApplicationEvents } from "../../application-events.js"; /** * Responsible for adding `implementedBy` / `implementedFrom` */ -@Component({ name: "type" }) export class TypePlugin extends ConverterComponent { reflections = new Set(); diff --git a/src/lib/output/components.ts b/src/lib/output/components.ts index 4c5100f9c..237169b15 100644 --- a/src/lib/output/components.ts +++ b/src/lib/output/components.ts @@ -1,6 +1,6 @@ import * as Path from "path"; -import { Component, AbstractComponent } from "../utils/component.js"; +import { AbstractComponent } from "../utils/component.js"; import type { ProjectReflection, Reflection, @@ -9,8 +9,6 @@ import type { Renderer } from "./renderer.js"; import { RendererEvent, PageEvent } from "./events.js"; import { Option } from "../utils/index.js"; -export { Component }; - export abstract class RendererComponent extends AbstractComponent< Renderer, {} diff --git a/src/lib/output/index.ts b/src/lib/output/index.ts index 32dac36ac..5a06e17af 100644 --- a/src/lib/output/index.ts +++ b/src/lib/output/index.ts @@ -15,5 +15,3 @@ export { type NavigationElement, } from "./themes/default/DefaultTheme.js"; export { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext.js"; - -import "./plugins/index.js"; diff --git a/src/lib/output/plugins/AssetsPlugin.ts b/src/lib/output/plugins/AssetsPlugin.ts index e55aafe6c..2b168d880 100644 --- a/src/lib/output/plugins/AssetsPlugin.ts +++ b/src/lib/output/plugins/AssetsPlugin.ts @@ -1,4 +1,4 @@ -import { Component, RendererComponent } from "../components.js"; +import { RendererComponent } from "../components.js"; import { RendererEvent } from "../events.js"; import { copySync, readFile, writeFileSync } from "../../utils/fs.js"; import { DefaultTheme } from "../themes/default/DefaultTheme.js"; @@ -12,7 +12,6 @@ import { fileURLToPath } from "url"; * A plugin that copies the subdirectory ´assets´ from the current themes * source folder to the output directory. */ -@Component({ name: "assets" }) export class AssetsPlugin extends RendererComponent { /** @internal */ @Option("customCss") diff --git a/src/lib/output/plugins/IconsPlugin.tsx b/src/lib/output/plugins/IconsPlugin.tsx index c8b0dbc54..7e5a9d047 100644 --- a/src/lib/output/plugins/IconsPlugin.tsx +++ b/src/lib/output/plugins/IconsPlugin.tsx @@ -1,4 +1,4 @@ -import { Component, RendererComponent } from "../components.js"; +import { RendererComponent } from "../components.js"; import { RendererEvent } from "../events.js"; import { writeFile } from "../../utils/fs.js"; import { DefaultTheme } from "../themes/default/DefaultTheme.js"; @@ -30,7 +30,6 @@ const ICONS_JS = ` * Plugin which is responsible for creating an icons.js file that embeds the icon SVGs * within the page on page load to reduce page sizes. */ -@Component({ name: "icons" }) export class IconsPlugin extends RendererComponent { iconHtml?: string; diff --git a/src/lib/output/plugins/JavascriptIndexPlugin.ts b/src/lib/output/plugins/JavascriptIndexPlugin.ts index fc767ae7b..f81a48efc 100644 --- a/src/lib/output/plugins/JavascriptIndexPlugin.ts +++ b/src/lib/output/plugins/JavascriptIndexPlugin.ts @@ -8,7 +8,7 @@ import { ProjectReflection, type Reflection, } from "../../models/index.js"; -import { Component, RendererComponent } from "../components.js"; +import { RendererComponent } from "../components.js"; import { IndexEvent, RendererEvent } from "../events.js"; import { Option, writeFile } from "../../utils/index.js"; import { DefaultTheme } from "../themes/default/DefaultTheme.js"; @@ -33,7 +33,6 @@ interface SearchDocument { * * The resulting javascript file can be used to build a simple search function. */ -@Component({ name: "javascript-index" }) export class JavascriptIndexPlugin extends RendererComponent { @Option("searchInComments") private accessor searchComments!: boolean; diff --git a/src/lib/output/plugins/NavigationPlugin.ts b/src/lib/output/plugins/NavigationPlugin.ts index 51d75d529..ea0d2666a 100644 --- a/src/lib/output/plugins/NavigationPlugin.ts +++ b/src/lib/output/plugins/NavigationPlugin.ts @@ -1,5 +1,5 @@ import * as Path from "path"; -import { Component, RendererComponent } from "../components.js"; +import { RendererComponent } from "../components.js"; import { RendererEvent } from "../events.js"; import { writeFile } from "../../utils/index.js"; import { DefaultTheme } from "../themes/default/DefaultTheme.js"; @@ -8,7 +8,6 @@ import { promisify } from "util"; const gzipP = promisify(gzip); -@Component({ name: "navigation-tree" }) export class NavigationPlugin extends RendererComponent { override initialize() { this.owner.on(RendererEvent.BEGIN, this.onRendererBegin.bind(this)); diff --git a/src/lib/output/plugins/SitemapPlugin.ts b/src/lib/output/plugins/SitemapPlugin.ts index 3a9be2afe..f5bca2abc 100644 --- a/src/lib/output/plugins/SitemapPlugin.ts +++ b/src/lib/output/plugins/SitemapPlugin.ts @@ -1,12 +1,11 @@ import Path from "path"; -import { Component, RendererComponent } from "../components.js"; +import { RendererComponent } from "../components.js"; import { RendererEvent } from "../events.js"; import { DefaultTheme } from "../themes/default/DefaultTheme.js"; import { writeFile } from "../../utils/index.js"; import { escapeHtml } from "../../utils/html.js"; import { Fragment } from "../../utils/jsx.js"; -@Component({ name: "sitemap" }) export class SitemapPlugin extends RendererComponent { private get hostedBaseUrl() { const url = this.application.options.getValue("hostedBaseUrl"); diff --git a/src/lib/output/renderer.ts b/src/lib/output/renderer.ts index bd8140225..14f853fdf 100644 --- a/src/lib/output/renderer.ts +++ b/src/lib/output/renderer.ts @@ -21,9 +21,7 @@ import type { ProjectReflection } from "../models/reflections/project.js"; import type { RenderTemplate } from "./models/UrlMapping.js"; import { writeFileSync } from "../utils/fs.js"; import { DefaultTheme } from "./themes/default/DefaultTheme.js"; -import { RendererComponent } from "./components.js"; -import { Component, ChildableComponent } from "../utils/component.js"; -import { Option, EventHooks } from "../utils/index.js"; +import { Option, EventHooks, AbstractComponent } from "../utils/index.js"; import { loadHighlighter } from "../utils/highlighter.js"; import type { BundledLanguage, @@ -35,6 +33,15 @@ import type { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRen import { validateStateIsClean } from "./themes/default/partials/type.js"; import { setRenderSettings } from "../utils/jsx.js"; +import { + AssetsPlugin, + IconsPlugin, + JavascriptIndexPlugin, + MarkedPlugin, + NavigationPlugin, + SitemapPlugin, +} from "./plugins/index.js"; + /** * Describes the hooks available to inject output in the default theme. * If the available hooks don't let you put something where you'd like, please open an issue! @@ -161,12 +168,7 @@ export interface RendererEvents { * * @document ../../../internal-docs/custom-themes.md */ -@Component({ name: "renderer", internal: true, childClass: RendererComponent }) -export class Renderer extends ChildableComponent< - Application, - RendererComponent, - RendererEvents -> { +export class Renderer extends AbstractComponent { private themes = new Map Theme>([ ["default", DefaultTheme], ]); @@ -251,6 +253,19 @@ export class Renderer extends ChildableComponent< renderStartTime = -1; + markedPlugin: MarkedPlugin; + + constructor(owner: Application) { + super(owner); + + this.markedPlugin = new MarkedPlugin(this); + new AssetsPlugin(this); + new IconsPlugin(this); + new JavascriptIndexPlugin(this); + new NavigationPlugin(this); + new SitemapPlugin(this); + } + /** * Define a new theme that can be used to render output. * This API will likely be changing at some point, to allow more easily overriding parts of the theme without @@ -449,7 +464,3 @@ export class Renderer extends ChildableComponent< return true; } } - -// HACK: THIS HAS TO STAY DOWN HERE -// if you try to move it up to the top of the file, then you'll run into stuff being used before it has been defined. -await import("./plugins/index.js"); diff --git a/src/lib/output/theme.ts b/src/lib/output/theme.ts index 5393d0934..2bfecd3c7 100644 --- a/src/lib/output/theme.ts +++ b/src/lib/output/theme.ts @@ -2,7 +2,6 @@ import type { Renderer } from "./renderer.js"; import type { ProjectReflection } from "../models/reflections/project.js"; import type { RenderTemplate, UrlMapping } from "./models/UrlMapping.js"; import { RendererComponent } from "./components.js"; -import { Component } from "../utils/component.js"; import type { PageEvent } from "./events.js"; import type { Reflection } from "../models/index.js"; @@ -14,7 +13,6 @@ import type { Reflection } from "../models/index.js"; * and templates to use. Additionally themes can subscribe to the events emitted by * {@link Renderer} to control and manipulate the output process. */ -@Component({ name: "theme", internal: true }) export abstract class Theme extends RendererComponent { /** * Map the models of the given project to the desired output files. diff --git a/src/lib/output/themes/MarkedPlugin.tsx b/src/lib/output/themes/MarkedPlugin.tsx index 0a413bf8c..a9de8fe66 100644 --- a/src/lib/output/themes/MarkedPlugin.tsx +++ b/src/lib/output/themes/MarkedPlugin.tsx @@ -2,7 +2,7 @@ import markdown from "markdown-it"; // @types/markdown-it is busted, this type isn't exported with ESM. import type md from "markdown-it" with { "resolution-mode": "require" }; -import { Component, ContextAwareRendererComponent } from "../components.js"; +import { ContextAwareRendererComponent } from "../components.js"; import { type RendererEvent, MarkdownEvent, type PageEvent } from "../events.js"; import { Option, type Logger, renderElement, assertNever } from "../../utils/index.js"; import { highlight, isLoadedLanguage, isSupportedLanguage } from "../../utils/highlighter.js"; @@ -26,7 +26,6 @@ function getDefaultSlugger(logger: Logger) { * Implements markdown and relativeURL helpers for templates. * @internal */ -@Component({ name: "marked" }) export class MarkedPlugin extends ContextAwareRendererComponent { @Option("lightHighlightTheme") accessor lightTheme!: BundledTheme; diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index 4ce89332a..f8a80ddde 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -190,7 +190,7 @@ export class DefaultTheme extends Theme { */ constructor(renderer: Renderer) { super(renderer); - this.markedPlugin = renderer.getComponent("marked") as MarkedPlugin; + this.markedPlugin = renderer.markedPlugin; } /** diff --git a/src/lib/utils/component.ts b/src/lib/utils/component.ts index 058b1f631..a57492ad7 100644 --- a/src/lib/utils/component.ts +++ b/src/lib/utils/component.ts @@ -11,78 +11,6 @@ export interface ComponentHost { export interface Component = {}> extends AbstractComponent {} -export interface ComponentClass< - T extends Component, - O extends ComponentHost = ComponentHost, -> extends Function { - new (owner: O): T; -} - -/** - * Option-bag passed to Component decorator. - */ -export interface ComponentOptions { - name?: string; - /** Specify valid child component class. Used to prove that children are valid via `instanceof` checks */ - childClass?: Function; - internal?: boolean; -} - -const childMappings: { - host: ChildableComponent; - child: Function; -}[] = []; - -/** - * Class decorator applied to Components - */ -export function Component(options: ComponentOptions) { - // _context is ClassDecoratorContext, but that then requires a public constructor - // which Application does not have. - return (target: Function, _context: unknown) => { - const proto = target.prototype; - if (!(proto instanceof AbstractComponent)) { - throw new Error( - "The `Component` decorator can only be used with a subclass of `AbstractComponent`.", - ); - } - - if (options.childClass) { - if (!(proto instanceof ChildableComponent)) { - throw new Error( - "The `Component` decorator accepts the parameter `childClass` only when used with a subclass of `ChildableComponent`.", - ); - } - - childMappings.push({ - host: proto, - child: options.childClass, - }); - } - - const name = options.name; - if (name) { - proto.componentName = name; - } - - // If not marked internal, and if we are a subclass of another component T's declared - // childClass, then register ourselves as a _defaultComponents of T. - const internal = !!options.internal; - if (name && !internal) { - for (const childMapping of childMappings) { - if (!(proto instanceof childMapping.child)) { - continue; - } - - const host = childMapping.host; - host["_defaultComponents"] = host["_defaultComponents"] || {}; - host["_defaultComponents"][name] = target as any; - break; - } - } - }; -} - /** * Component base class. Has an owner (unless it's the application root component), * can dispatch events to its children, and has access to the root Application component. @@ -141,70 +69,3 @@ export abstract class AbstractComponent< : this._componentOwner; } } - -/** - * Component that can have child components. - * - * @template O type of Component's owner - * @template C type of Component's children - */ -export abstract class ChildableComponent< - O extends ComponentHost, - C extends Component, - E extends Record, -> extends AbstractComponent { - private _componentChildren?: { [name: string]: C | undefined }; - - private _defaultComponents?: { [name: string]: ComponentClass }; - - /** - * Create new Component instance. - */ - constructor(owner: O) { - super(owner); - - Object.entries(this._defaultComponents || {}).forEach( - ([name, component]) => { - this.addComponent(name, component); - }, - ); - } - - /** - * Retrieve a plugin instance. - * - * @returns The instance of the plugin or undefined if no plugin with the given class is attached. - */ - getComponent(name: string): C | undefined { - return (this._componentChildren || {})[name]; - } - - getComponents(): C[] { - return Object.values(this._componentChildren || {}) as C[]; - } - - addComponent( - name: string, - componentClass: T | ComponentClass, - ): T { - if (!this._componentChildren) { - this._componentChildren = {}; - } - - if (this._componentChildren[name]) { - // Component already added so we will return the existing component - // TODO: add better logging around this because it could be unexpected but shouldn't be fatal - // See https://github.com/TypeStrong/typedoc/issues/846 - return this._componentChildren[name]; - } else { - const component: T = - typeof componentClass === "function" - ? new (>componentClass)(this) - : componentClass; - - this._componentChildren[name] = component; - - return component; - } - } -} diff --git a/src/lib/utils/html-entities.json b/src/lib/utils/html-entities.json deleted file mode 100644 index de089ea6a..000000000 --- a/src/lib/utils/html-entities.json +++ /dev/null @@ -1,2326 +0,0 @@ -{ - "AElig": { "p": [198], "c": "\u00C6" }, - "AElig;": { "p": [198], "c": "\u00C6" }, - "AMP": { "p": [38], "c": "\u0026" }, - "AMP;": { "p": [38], "c": "\u0026" }, - "Aacute": { "p": [193], "c": "\u00C1" }, - "Aacute;": { "p": [193], "c": "\u00C1" }, - "Abreve;": { "p": [258], "c": "\u0102" }, - "Acirc": { "p": [194], "c": "\u00C2" }, - "Acirc;": { "p": [194], "c": "\u00C2" }, - "Acy;": { "p": [1040], "c": "\u0410" }, - "Afr;": { "p": [120068], "c": "\uD835\uDD04" }, - "Agrave": { "p": [192], "c": "\u00C0" }, - "Agrave;": { "p": [192], "c": "\u00C0" }, - "Alpha;": { "p": [913], "c": "\u0391" }, - "Amacr;": { "p": [256], "c": "\u0100" }, - "And;": { "p": [10835], "c": "\u2A53" }, - "Aogon;": { "p": [260], "c": "\u0104" }, - "Aopf;": { "p": [120120], "c": "\uD835\uDD38" }, - "ApplyFunction;": { "p": [8289], "c": "\u2061" }, - "Aring": { "p": [197], "c": "\u00C5" }, - "Aring;": { "p": [197], "c": "\u00C5" }, - "Ascr;": { "p": [119964], "c": "\uD835\uDC9C" }, - "Assign;": { "p": [8788], "c": "\u2254" }, - "Atilde": { "p": [195], "c": "\u00C3" }, - "Atilde;": { "p": [195], "c": "\u00C3" }, - "Auml": { "p": [196], "c": "\u00C4" }, - "Auml;": { "p": [196], "c": "\u00C4" }, - "Backslash;": { "p": [8726], "c": "\u2216" }, - "Barv;": { "p": [10983], "c": "\u2AE7" }, - "Barwed;": { "p": [8966], "c": "\u2306" }, - "Bcy;": { "p": [1041], "c": "\u0411" }, - "Because;": { "p": [8757], "c": "\u2235" }, - "Bernoullis;": { "p": [8492], "c": "\u212C" }, - "Beta;": { "p": [914], "c": "\u0392" }, - "Bfr;": { "p": [120069], "c": "\uD835\uDD05" }, - "Bopf;": { "p": [120121], "c": "\uD835\uDD39" }, - "Breve;": { "p": [728], "c": "\u02D8" }, - "Bscr;": { "p": [8492], "c": "\u212C" }, - "Bumpeq;": { "p": [8782], "c": "\u224E" }, - "CHcy;": { "p": [1063], "c": "\u0427" }, - "COPY": { "p": [169], "c": "\u00A9" }, - "COPY;": { "p": [169], "c": "\u00A9" }, - "Cacute;": { "p": [262], "c": "\u0106" }, - "Cap;": { "p": [8914], "c": "\u22D2" }, - "CapitalDifferentialD;": { "p": [8517], "c": "\u2145" }, - "Cayleys;": { "p": [8493], "c": "\u212D" }, - "Ccaron;": { "p": [268], "c": "\u010C" }, - "Ccedil": { "p": [199], "c": "\u00C7" }, - "Ccedil;": { "p": [199], "c": "\u00C7" }, - "Ccirc;": { "p": [264], "c": "\u0108" }, - "Cconint;": { "p": [8752], "c": "\u2230" }, - "Cdot;": { "p": [266], "c": "\u010A" }, - "Cedilla;": { "p": [184], "c": "\u00B8" }, - "CenterDot;": { "p": [183], "c": "\u00B7" }, - "Cfr;": { "p": [8493], "c": "\u212D" }, - "Chi;": { "p": [935], "c": "\u03A7" }, - "CircleDot;": { "p": [8857], "c": "\u2299" }, - "CircleMinus;": { "p": [8854], "c": "\u2296" }, - "CirclePlus;": { "p": [8853], "c": "\u2295" }, - "CircleTimes;": { "p": [8855], "c": "\u2297" }, - "ClockwiseContourIntegral;": { - "p": [8754], - "c": "\u2232" - }, - "CloseCurlyDoubleQuote;": { "p": [8221], "c": "\u201D" }, - "CloseCurlyQuote;": { "p": [8217], "c": "\u2019" }, - "Colon;": { "p": [8759], "c": "\u2237" }, - "Colone;": { "p": [10868], "c": "\u2A74" }, - "Congruent;": { "p": [8801], "c": "\u2261" }, - "Conint;": { "p": [8751], "c": "\u222F" }, - "ContourIntegral;": { "p": [8750], "c": "\u222E" }, - "Copf;": { "p": [8450], "c": "\u2102" }, - "Coproduct;": { "p": [8720], "c": "\u2210" }, - "CounterClockwiseContourIntegral;": { - "p": [8755], - "c": "\u2233" - }, - "Cross;": { "p": [10799], "c": "\u2A2F" }, - "Cscr;": { "p": [119966], "c": "\uD835\uDC9E" }, - "Cup;": { "p": [8915], "c": "\u22D3" }, - "CupCap;": { "p": [8781], "c": "\u224D" }, - "DD;": { "p": [8517], "c": "\u2145" }, - "DDotrahd;": { "p": [10513], "c": "\u2911" }, - "DJcy;": { "p": [1026], "c": "\u0402" }, - "DScy;": { "p": [1029], "c": "\u0405" }, - "DZcy;": { "p": [1039], "c": "\u040F" }, - "Dagger;": { "p": [8225], "c": "\u2021" }, - "Darr;": { "p": [8609], "c": "\u21A1" }, - "Dashv;": { "p": [10980], "c": "\u2AE4" }, - "Dcaron;": { "p": [270], "c": "\u010E" }, - "Dcy;": { "p": [1044], "c": "\u0414" }, - "Del;": { "p": [8711], "c": "\u2207" }, - "Delta;": { "p": [916], "c": "\u0394" }, - "Dfr;": { "p": [120071], "c": "\uD835\uDD07" }, - "DiacriticalAcute;": { "p": [180], "c": "\u00B4" }, - "DiacriticalDot;": { "p": [729], "c": "\u02D9" }, - "DiacriticalDoubleAcute;": { "p": [733], "c": "\u02DD" }, - "DiacriticalGrave;": { "p": [96], "c": "\u0060" }, - "DiacriticalTilde;": { "p": [732], "c": "\u02DC" }, - "Diamond;": { "p": [8900], "c": "\u22C4" }, - "DifferentialD;": { "p": [8518], "c": "\u2146" }, - "Dopf;": { "p": [120123], "c": "\uD835\uDD3B" }, - "Dot;": { "p": [168], "c": "\u00A8" }, - "DotDot;": { "p": [8412], "c": "\u20DC" }, - "DotEqual;": { "p": [8784], "c": "\u2250" }, - "DoubleContourIntegral;": { "p": [8751], "c": "\u222F" }, - "DoubleDot;": { "p": [168], "c": "\u00A8" }, - "DoubleDownArrow;": { "p": [8659], "c": "\u21D3" }, - "DoubleLeftArrow;": { "p": [8656], "c": "\u21D0" }, - "DoubleLeftRightArrow;": { "p": [8660], "c": "\u21D4" }, - "DoubleLeftTee;": { "p": [10980], "c": "\u2AE4" }, - "DoubleLongLeftArrow;": { "p": [10232], "c": "\u27F8" }, - "DoubleLongLeftRightArrow;": { - "p": [10234], - "c": "\u27FA" - }, - "DoubleLongRightArrow;": { "p": [10233], "c": "\u27F9" }, - "DoubleRightArrow;": { "p": [8658], "c": "\u21D2" }, - "DoubleRightTee;": { "p": [8872], "c": "\u22A8" }, - "DoubleUpArrow;": { "p": [8657], "c": "\u21D1" }, - "DoubleUpDownArrow;": { "p": [8661], "c": "\u21D5" }, - "DoubleVerticalBar;": { "p": [8741], "c": "\u2225" }, - "DownArrow;": { "p": [8595], "c": "\u2193" }, - "DownArrowBar;": { "p": [10515], "c": "\u2913" }, - "DownArrowUpArrow;": { "p": [8693], "c": "\u21F5" }, - "DownBreve;": { "p": [785], "c": "\u0311" }, - "DownLeftRightVector;": { "p": [10576], "c": "\u2950" }, - "DownLeftTeeVector;": { "p": [10590], "c": "\u295E" }, - "DownLeftVector;": { "p": [8637], "c": "\u21BD" }, - "DownLeftVectorBar;": { "p": [10582], "c": "\u2956" }, - "DownRightTeeVector;": { "p": [10591], "c": "\u295F" }, - "DownRightVector;": { "p": [8641], "c": "\u21C1" }, - "DownRightVectorBar;": { "p": [10583], "c": "\u2957" }, - "DownTee;": { "p": [8868], "c": "\u22A4" }, - "DownTeeArrow;": { "p": [8615], "c": "\u21A7" }, - "Downarrow;": { "p": [8659], "c": "\u21D3" }, - "Dscr;": { "p": [119967], "c": "\uD835\uDC9F" }, - "Dstrok;": { "p": [272], "c": "\u0110" }, - "ENG;": { "p": [330], "c": "\u014A" }, - "ETH": { "p": [208], "c": "\u00D0" }, - "ETH;": { "p": [208], "c": "\u00D0" }, - "Eacute": { "p": [201], "c": "\u00C9" }, - "Eacute;": { "p": [201], "c": "\u00C9" }, - "Ecaron;": { "p": [282], "c": "\u011A" }, - "Ecirc": { "p": [202], "c": "\u00CA" }, - "Ecirc;": { "p": [202], "c": "\u00CA" }, - "Ecy;": { "p": [1069], "c": "\u042D" }, - "Edot;": { "p": [278], "c": "\u0116" }, - "Efr;": { "p": [120072], "c": "\uD835\uDD08" }, - "Egrave": { "p": [200], "c": "\u00C8" }, - "Egrave;": { "p": [200], "c": "\u00C8" }, - "Element;": { "p": [8712], "c": "\u2208" }, - "Emacr;": { "p": [274], "c": "\u0112" }, - "EmptySmallSquare;": { "p": [9723], "c": "\u25FB" }, - "EmptyVerySmallSquare;": { "p": [9643], "c": "\u25AB" }, - "Eogon;": { "p": [280], "c": "\u0118" }, - "Eopf;": { "p": [120124], "c": "\uD835\uDD3C" }, - "Epsilon;": { "p": [917], "c": "\u0395" }, - "Equal;": { "p": [10869], "c": "\u2A75" }, - "EqualTilde;": { "p": [8770], "c": "\u2242" }, - "Equilibrium;": { "p": [8652], "c": "\u21CC" }, - "Escr;": { "p": [8496], "c": "\u2130" }, - "Esim;": { "p": [10867], "c": "\u2A73" }, - "Eta;": { "p": [919], "c": "\u0397" }, - "Euml": { "p": [203], "c": "\u00CB" }, - "Euml;": { "p": [203], "c": "\u00CB" }, - "Exists;": { "p": [8707], "c": "\u2203" }, - "ExponentialE;": { "p": [8519], "c": "\u2147" }, - "Fcy;": { "p": [1060], "c": "\u0424" }, - "Ffr;": { "p": [120073], "c": "\uD835\uDD09" }, - "FilledSmallSquare;": { "p": [9724], "c": "\u25FC" }, - "FilledVerySmallSquare;": { "p": [9642], "c": "\u25AA" }, - "Fopf;": { "p": [120125], "c": "\uD835\uDD3D" }, - "ForAll;": { "p": [8704], "c": "\u2200" }, - "Fouriertrf;": { "p": [8497], "c": "\u2131" }, - "Fscr;": { "p": [8497], "c": "\u2131" }, - "GJcy;": { "p": [1027], "c": "\u0403" }, - "GT": { "p": [62], "c": "\u003E" }, - "GT;": { "p": [62], "c": "\u003E" }, - "Gamma;": { "p": [915], "c": "\u0393" }, - "Gammad;": { "p": [988], "c": "\u03DC" }, - "Gbreve;": { "p": [286], "c": "\u011E" }, - "Gcedil;": { "p": [290], "c": "\u0122" }, - "Gcirc;": { "p": [284], "c": "\u011C" }, - "Gcy;": { "p": [1043], "c": "\u0413" }, - "Gdot;": { "p": [288], "c": "\u0120" }, - "Gfr;": { "p": [120074], "c": "\uD835\uDD0A" }, - "Gg;": { "p": [8921], "c": "\u22D9" }, - "Gopf;": { "p": [120126], "c": "\uD835\uDD3E" }, - "GreaterEqual;": { "p": [8805], "c": "\u2265" }, - "GreaterEqualLess;": { "p": [8923], "c": "\u22DB" }, - "GreaterFullEqual;": { "p": [8807], "c": "\u2267" }, - "GreaterGreater;": { "p": [10914], "c": "\u2AA2" }, - "GreaterLess;": { "p": [8823], "c": "\u2277" }, - "GreaterSlantEqual;": { "p": [10878], "c": "\u2A7E" }, - "GreaterTilde;": { "p": [8819], "c": "\u2273" }, - "Gscr;": { "p": [119970], "c": "\uD835\uDCA2" }, - "Gt;": { "p": [8811], "c": "\u226B" }, - "HARDcy;": { "p": [1066], "c": "\u042A" }, - "Hacek;": { "p": [711], "c": "\u02C7" }, - "Hat;": { "p": [94], "c": "\u005E" }, - "Hcirc;": { "p": [292], "c": "\u0124" }, - "Hfr;": { "p": [8460], "c": "\u210C" }, - "HilbertSpace;": { "p": [8459], "c": "\u210B" }, - "Hopf;": { "p": [8461], "c": "\u210D" }, - "HorizontalLine;": { "p": [9472], "c": "\u2500" }, - "Hscr;": { "p": [8459], "c": "\u210B" }, - "Hstrok;": { "p": [294], "c": "\u0126" }, - "HumpDownHump;": { "p": [8782], "c": "\u224E" }, - "HumpEqual;": { "p": [8783], "c": "\u224F" }, - "IEcy;": { "p": [1045], "c": "\u0415" }, - "IJlig;": { "p": [306], "c": "\u0132" }, - "IOcy;": { "p": [1025], "c": "\u0401" }, - "Iacute": { "p": [205], "c": "\u00CD" }, - "Iacute;": { "p": [205], "c": "\u00CD" }, - "Icirc": { "p": [206], "c": "\u00CE" }, - "Icirc;": { "p": [206], "c": "\u00CE" }, - "Icy;": { "p": [1048], "c": "\u0418" }, - "Idot;": { "p": [304], "c": "\u0130" }, - "Ifr;": { "p": [8465], "c": "\u2111" }, - "Igrave": { "p": [204], "c": "\u00CC" }, - "Igrave;": { "p": [204], "c": "\u00CC" }, - "Im;": { "p": [8465], "c": "\u2111" }, - "Imacr;": { "p": [298], "c": "\u012A" }, - "ImaginaryI;": { "p": [8520], "c": "\u2148" }, - "Implies;": { "p": [8658], "c": "\u21D2" }, - "Int;": { "p": [8748], "c": "\u222C" }, - "Integral;": { "p": [8747], "c": "\u222B" }, - "Intersection;": { "p": [8898], "c": "\u22C2" }, - "InvisibleComma;": { "p": [8291], "c": "\u2063" }, - "InvisibleTimes;": { "p": [8290], "c": "\u2062" }, - "Iogon;": { "p": [302], "c": "\u012E" }, - "Iopf;": { "p": [120128], "c": "\uD835\uDD40" }, - "Iota;": { "p": [921], "c": "\u0399" }, - "Iscr;": { "p": [8464], "c": "\u2110" }, - "Itilde;": { "p": [296], "c": "\u0128" }, - "Iukcy;": { "p": [1030], "c": "\u0406" }, - "Iuml": { "p": [207], "c": "\u00CF" }, - "Iuml;": { "p": [207], "c": "\u00CF" }, - "Jcirc;": { "p": [308], "c": "\u0134" }, - "Jcy;": { "p": [1049], "c": "\u0419" }, - "Jfr;": { "p": [120077], "c": "\uD835\uDD0D" }, - "Jopf;": { "p": [120129], "c": "\uD835\uDD41" }, - "Jscr;": { "p": [119973], "c": "\uD835\uDCA5" }, - "Jsercy;": { "p": [1032], "c": "\u0408" }, - "Jukcy;": { "p": [1028], "c": "\u0404" }, - "KHcy;": { "p": [1061], "c": "\u0425" }, - "KJcy;": { "p": [1036], "c": "\u040C" }, - "Kappa;": { "p": [922], "c": "\u039A" }, - "Kcedil;": { "p": [310], "c": "\u0136" }, - "Kcy;": { "p": [1050], "c": "\u041A" }, - "Kfr;": { "p": [120078], "c": "\uD835\uDD0E" }, - "Kopf;": { "p": [120130], "c": "\uD835\uDD42" }, - "Kscr;": { "p": [119974], "c": "\uD835\uDCA6" }, - "LJcy;": { "p": [1033], "c": "\u0409" }, - "LT": { "p": [60], "c": "\u003C" }, - "LT;": { "p": [60], "c": "\u003C" }, - "Lacute;": { "p": [313], "c": "\u0139" }, - "Lambda;": { "p": [923], "c": "\u039B" }, - "Lang;": { "p": [10218], "c": "\u27EA" }, - "Laplacetrf;": { "p": [8466], "c": "\u2112" }, - "Larr;": { "p": [8606], "c": "\u219E" }, - "Lcaron;": { "p": [317], "c": "\u013D" }, - "Lcedil;": { "p": [315], "c": "\u013B" }, - "Lcy;": { "p": [1051], "c": "\u041B" }, - "LeftAngleBracket;": { "p": [10216], "c": "\u27E8" }, - "LeftArrow;": { "p": [8592], "c": "\u2190" }, - "LeftArrowBar;": { "p": [8676], "c": "\u21E4" }, - "LeftArrowRightArrow;": { "p": [8646], "c": "\u21C6" }, - "LeftCeiling;": { "p": [8968], "c": "\u2308" }, - "LeftDoubleBracket;": { "p": [10214], "c": "\u27E6" }, - "LeftDownTeeVector;": { "p": [10593], "c": "\u2961" }, - "LeftDownVector;": { "p": [8643], "c": "\u21C3" }, - "LeftDownVectorBar;": { "p": [10585], "c": "\u2959" }, - "LeftFloor;": { "p": [8970], "c": "\u230A" }, - "LeftRightArrow;": { "p": [8596], "c": "\u2194" }, - "LeftRightVector;": { "p": [10574], "c": "\u294E" }, - "LeftTee;": { "p": [8867], "c": "\u22A3" }, - "LeftTeeArrow;": { "p": [8612], "c": "\u21A4" }, - "LeftTeeVector;": { "p": [10586], "c": "\u295A" }, - "LeftTriangle;": { "p": [8882], "c": "\u22B2" }, - "LeftTriangleBar;": { "p": [10703], "c": "\u29CF" }, - "LeftTriangleEqual;": { "p": [8884], "c": "\u22B4" }, - "LeftUpDownVector;": { "p": [10577], "c": "\u2951" }, - "LeftUpTeeVector;": { "p": [10592], "c": "\u2960" }, - "LeftUpVector;": { "p": [8639], "c": "\u21BF" }, - "LeftUpVectorBar;": { "p": [10584], "c": "\u2958" }, - "LeftVector;": { "p": [8636], "c": "\u21BC" }, - "LeftVectorBar;": { "p": [10578], "c": "\u2952" }, - "Leftarrow;": { "p": [8656], "c": "\u21D0" }, - "Leftrightarrow;": { "p": [8660], "c": "\u21D4" }, - "LessEqualGreater;": { "p": [8922], "c": "\u22DA" }, - "LessFullEqual;": { "p": [8806], "c": "\u2266" }, - "LessGreater;": { "p": [8822], "c": "\u2276" }, - "LessLess;": { "p": [10913], "c": "\u2AA1" }, - "LessSlantEqual;": { "p": [10877], "c": "\u2A7D" }, - "LessTilde;": { "p": [8818], "c": "\u2272" }, - "Lfr;": { "p": [120079], "c": "\uD835\uDD0F" }, - "Ll;": { "p": [8920], "c": "\u22D8" }, - "Lleftarrow;": { "p": [8666], "c": "\u21DA" }, - "Lmidot;": { "p": [319], "c": "\u013F" }, - "LongLeftArrow;": { "p": [10229], "c": "\u27F5" }, - "LongLeftRightArrow;": { "p": [10231], "c": "\u27F7" }, - "LongRightArrow;": { "p": [10230], "c": "\u27F6" }, - "Longleftarrow;": { "p": [10232], "c": "\u27F8" }, - "Longleftrightarrow;": { "p": [10234], "c": "\u27FA" }, - "Longrightarrow;": { "p": [10233], "c": "\u27F9" }, - "Lopf;": { "p": [120131], "c": "\uD835\uDD43" }, - "LowerLeftArrow;": { "p": [8601], "c": "\u2199" }, - "LowerRightArrow;": { "p": [8600], "c": "\u2198" }, - "Lscr;": { "p": [8466], "c": "\u2112" }, - "Lsh;": { "p": [8624], "c": "\u21B0" }, - "Lstrok;": { "p": [321], "c": "\u0141" }, - "Lt;": { "p": [8810], "c": "\u226A" }, - "Map;": { "p": [10501], "c": "\u2905" }, - "Mcy;": { "p": [1052], "c": "\u041C" }, - "MediumSpace;": { "p": [8287], "c": "\u205F" }, - "Mellintrf;": { "p": [8499], "c": "\u2133" }, - "Mfr;": { "p": [120080], "c": "\uD835\uDD10" }, - "MinusPlus;": { "p": [8723], "c": "\u2213" }, - "Mopf;": { "p": [120132], "c": "\uD835\uDD44" }, - "Mscr;": { "p": [8499], "c": "\u2133" }, - "Mu;": { "p": [924], "c": "\u039C" }, - "NJcy;": { "p": [1034], "c": "\u040A" }, - "Nacute;": { "p": [323], "c": "\u0143" }, - "Ncaron;": { "p": [327], "c": "\u0147" }, - "Ncedil;": { "p": [325], "c": "\u0145" }, - "Ncy;": { "p": [1053], "c": "\u041D" }, - "NegativeMediumSpace;": { "p": [8203], "c": "\u200B" }, - "NegativeThickSpace;": { "p": [8203], "c": "\u200B" }, - "NegativeThinSpace;": { "p": [8203], "c": "\u200B" }, - "NegativeVeryThinSpace;": { "p": [8203], "c": "\u200B" }, - "NestedGreaterGreater;": { "p": [8811], "c": "\u226B" }, - "NestedLessLess;": { "p": [8810], "c": "\u226A" }, - "NewLine;": { "p": [10], "c": "\u000A" }, - "Nfr;": { "p": [120081], "c": "\uD835\uDD11" }, - "NoBreak;": { "p": [8288], "c": "\u2060" }, - "NonBreakingSpace;": { "p": [160], "c": "\u00A0" }, - "Nopf;": { "p": [8469], "c": "\u2115" }, - "Not;": { "p": [10988], "c": "\u2AEC" }, - "NotCongruent;": { "p": [8802], "c": "\u2262" }, - "NotCupCap;": { "p": [8813], "c": "\u226D" }, - "NotDoubleVerticalBar;": { "p": [8742], "c": "\u2226" }, - "NotElement;": { "p": [8713], "c": "\u2209" }, - "NotEqual;": { "p": [8800], "c": "\u2260" }, - "NotEqualTilde;": { - "p": [8770, 824], - "c": "\u2242\u0338" - }, - "NotExists;": { "p": [8708], "c": "\u2204" }, - "NotGreater;": { "p": [8815], "c": "\u226F" }, - "NotGreaterEqual;": { "p": [8817], "c": "\u2271" }, - "NotGreaterFullEqual;": { - "p": [8807, 824], - "c": "\u2267\u0338" - }, - "NotGreaterGreater;": { - "p": [8811, 824], - "c": "\u226B\u0338" - }, - "NotGreaterLess;": { "p": [8825], "c": "\u2279" }, - "NotGreaterSlantEqual;": { - "p": [10878, 824], - "c": "\u2A7E\u0338" - }, - "NotGreaterTilde;": { "p": [8821], "c": "\u2275" }, - "NotHumpDownHump;": { - "p": [8782, 824], - "c": "\u224E\u0338" - }, - "NotHumpEqual;": { - "p": [8783, 824], - "c": "\u224F\u0338" - }, - "NotLeftTriangle;": { "p": [8938], "c": "\u22EA" }, - "NotLeftTriangleBar;": { - "p": [10703, 824], - "c": "\u29CF\u0338" - }, - "NotLeftTriangleEqual;": { "p": [8940], "c": "\u22EC" }, - "NotLess;": { "p": [8814], "c": "\u226E" }, - "NotLessEqual;": { "p": [8816], "c": "\u2270" }, - "NotLessGreater;": { "p": [8824], "c": "\u2278" }, - "NotLessLess;": { - "p": [8810, 824], - "c": "\u226A\u0338" - }, - "NotLessSlantEqual;": { - "p": [10877, 824], - "c": "\u2A7D\u0338" - }, - "NotLessTilde;": { "p": [8820], "c": "\u2274" }, - "NotNestedGreaterGreater;": { - "p": [10914, 824], - "c": "\u2AA2\u0338" - }, - "NotNestedLessLess;": { - "p": [10913, 824], - "c": "\u2AA1\u0338" - }, - "NotPrecedes;": { "p": [8832], "c": "\u2280" }, - "NotPrecedesEqual;": { - "p": [10927, 824], - "c": "\u2AAF\u0338" - }, - "NotPrecedesSlantEqual;": { "p": [8928], "c": "\u22E0" }, - "NotReverseElement;": { "p": [8716], "c": "\u220C" }, - "NotRightTriangle;": { "p": [8939], "c": "\u22EB" }, - "NotRightTriangleBar;": { - "p": [10704, 824], - "c": "\u29D0\u0338" - }, - "NotRightTriangleEqual;": { "p": [8941], "c": "\u22ED" }, - "NotSquareSubset;": { - "p": [8847, 824], - "c": "\u228F\u0338" - }, - "NotSquareSubsetEqual;": { "p": [8930], "c": "\u22E2" }, - "NotSquareSuperset;": { - "p": [8848, 824], - "c": "\u2290\u0338" - }, - "NotSquareSupersetEqual;": { - "p": [8931], - "c": "\u22E3" - }, - "NotSubset;": { "p": [8834, 8402], "c": "\u2282\u20D2" }, - "NotSubsetEqual;": { "p": [8840], "c": "\u2288" }, - "NotSucceeds;": { "p": [8833], "c": "\u2281" }, - "NotSucceedsEqual;": { - "p": [10928, 824], - "c": "\u2AB0\u0338" - }, - "NotSucceedsSlantEqual;": { "p": [8929], "c": "\u22E1" }, - "NotSucceedsTilde;": { - "p": [8831, 824], - "c": "\u227F\u0338" - }, - "NotSuperset;": { - "p": [8835, 8402], - "c": "\u2283\u20D2" - }, - "NotSupersetEqual;": { "p": [8841], "c": "\u2289" }, - "NotTilde;": { "p": [8769], "c": "\u2241" }, - "NotTildeEqual;": { "p": [8772], "c": "\u2244" }, - "NotTildeFullEqual;": { "p": [8775], "c": "\u2247" }, - "NotTildeTilde;": { "p": [8777], "c": "\u2249" }, - "NotVerticalBar;": { "p": [8740], "c": "\u2224" }, - "Nscr;": { "p": [119977], "c": "\uD835\uDCA9" }, - "Ntilde": { "p": [209], "c": "\u00D1" }, - "Ntilde;": { "p": [209], "c": "\u00D1" }, - "Nu;": { "p": [925], "c": "\u039D" }, - "OElig;": { "p": [338], "c": "\u0152" }, - "Oacute": { "p": [211], "c": "\u00D3" }, - "Oacute;": { "p": [211], "c": "\u00D3" }, - "Ocirc": { "p": [212], "c": "\u00D4" }, - "Ocirc;": { "p": [212], "c": "\u00D4" }, - "Ocy;": { "p": [1054], "c": "\u041E" }, - "Odblac;": { "p": [336], "c": "\u0150" }, - "Ofr;": { "p": [120082], "c": "\uD835\uDD12" }, - "Ograve": { "p": [210], "c": "\u00D2" }, - "Ograve;": { "p": [210], "c": "\u00D2" }, - "Omacr;": { "p": [332], "c": "\u014C" }, - "Omega;": { "p": [937], "c": "\u03A9" }, - "Omicron;": { "p": [927], "c": "\u039F" }, - "Oopf;": { "p": [120134], "c": "\uD835\uDD46" }, - "OpenCurlyDoubleQuote;": { "p": [8220], "c": "\u201C" }, - "OpenCurlyQuote;": { "p": [8216], "c": "\u2018" }, - "Or;": { "p": [10836], "c": "\u2A54" }, - "Oscr;": { "p": [119978], "c": "\uD835\uDCAA" }, - "Oslash": { "p": [216], "c": "\u00D8" }, - "Oslash;": { "p": [216], "c": "\u00D8" }, - "Otilde": { "p": [213], "c": "\u00D5" }, - "Otilde;": { "p": [213], "c": "\u00D5" }, - "Otimes;": { "p": [10807], "c": "\u2A37" }, - "Ouml": { "p": [214], "c": "\u00D6" }, - "Ouml;": { "p": [214], "c": "\u00D6" }, - "OverBar;": { "p": [8254], "c": "\u203E" }, - "OverBrace;": { "p": [9182], "c": "\u23DE" }, - "OverBracket;": { "p": [9140], "c": "\u23B4" }, - "OverParenthesis;": { "p": [9180], "c": "\u23DC" }, - "PartialD;": { "p": [8706], "c": "\u2202" }, - "Pcy;": { "p": [1055], "c": "\u041F" }, - "Pfr;": { "p": [120083], "c": "\uD835\uDD13" }, - "Phi;": { "p": [934], "c": "\u03A6" }, - "Pi;": { "p": [928], "c": "\u03A0" }, - "PlusMinus;": { "p": [177], "c": "\u00B1" }, - "Poincareplane;": { "p": [8460], "c": "\u210C" }, - "Popf;": { "p": [8473], "c": "\u2119" }, - "Pr;": { "p": [10939], "c": "\u2ABB" }, - "Precedes;": { "p": [8826], "c": "\u227A" }, - "PrecedesEqual;": { "p": [10927], "c": "\u2AAF" }, - "PrecedesSlantEqual;": { "p": [8828], "c": "\u227C" }, - "PrecedesTilde;": { "p": [8830], "c": "\u227E" }, - "Prime;": { "p": [8243], "c": "\u2033" }, - "Product;": { "p": [8719], "c": "\u220F" }, - "Proportion;": { "p": [8759], "c": "\u2237" }, - "Proportional;": { "p": [8733], "c": "\u221D" }, - "Pscr;": { "p": [119979], "c": "\uD835\uDCAB" }, - "Psi;": { "p": [936], "c": "\u03A8" }, - "QUOT": { "p": [34], "c": "\u0022" }, - "QUOT;": { "p": [34], "c": "\u0022" }, - "Qfr;": { "p": [120084], "c": "\uD835\uDD14" }, - "Qopf;": { "p": [8474], "c": "\u211A" }, - "Qscr;": { "p": [119980], "c": "\uD835\uDCAC" }, - "RBarr;": { "p": [10512], "c": "\u2910" }, - "REG": { "p": [174], "c": "\u00AE" }, - "REG;": { "p": [174], "c": "\u00AE" }, - "Racute;": { "p": [340], "c": "\u0154" }, - "Rang;": { "p": [10219], "c": "\u27EB" }, - "Rarr;": { "p": [8608], "c": "\u21A0" }, - "Rarrtl;": { "p": [10518], "c": "\u2916" }, - "Rcaron;": { "p": [344], "c": "\u0158" }, - "Rcedil;": { "p": [342], "c": "\u0156" }, - "Rcy;": { "p": [1056], "c": "\u0420" }, - "Re;": { "p": [8476], "c": "\u211C" }, - "ReverseElement;": { "p": [8715], "c": "\u220B" }, - "ReverseEquilibrium;": { "p": [8651], "c": "\u21CB" }, - "ReverseUpEquilibrium;": { "p": [10607], "c": "\u296F" }, - "Rfr;": { "p": [8476], "c": "\u211C" }, - "Rho;": { "p": [929], "c": "\u03A1" }, - "RightAngleBracket;": { "p": [10217], "c": "\u27E9" }, - "RightArrow;": { "p": [8594], "c": "\u2192" }, - "RightArrowBar;": { "p": [8677], "c": "\u21E5" }, - "RightArrowLeftArrow;": { "p": [8644], "c": "\u21C4" }, - "RightCeiling;": { "p": [8969], "c": "\u2309" }, - "RightDoubleBracket;": { "p": [10215], "c": "\u27E7" }, - "RightDownTeeVector;": { "p": [10589], "c": "\u295D" }, - "RightDownVector;": { "p": [8642], "c": "\u21C2" }, - "RightDownVectorBar;": { "p": [10581], "c": "\u2955" }, - "RightFloor;": { "p": [8971], "c": "\u230B" }, - "RightTee;": { "p": [8866], "c": "\u22A2" }, - "RightTeeArrow;": { "p": [8614], "c": "\u21A6" }, - "RightTeeVector;": { "p": [10587], "c": "\u295B" }, - "RightTriangle;": { "p": [8883], "c": "\u22B3" }, - "RightTriangleBar;": { "p": [10704], "c": "\u29D0" }, - "RightTriangleEqual;": { "p": [8885], "c": "\u22B5" }, - "RightUpDownVector;": { "p": [10575], "c": "\u294F" }, - "RightUpTeeVector;": { "p": [10588], "c": "\u295C" }, - "RightUpVector;": { "p": [8638], "c": "\u21BE" }, - "RightUpVectorBar;": { "p": [10580], "c": "\u2954" }, - "RightVector;": { "p": [8640], "c": "\u21C0" }, - "RightVectorBar;": { "p": [10579], "c": "\u2953" }, - "Rightarrow;": { "p": [8658], "c": "\u21D2" }, - "Ropf;": { "p": [8477], "c": "\u211D" }, - "RoundImplies;": { "p": [10608], "c": "\u2970" }, - "Rrightarrow;": { "p": [8667], "c": "\u21DB" }, - "Rscr;": { "p": [8475], "c": "\u211B" }, - "Rsh;": { "p": [8625], "c": "\u21B1" }, - "RuleDelayed;": { "p": [10740], "c": "\u29F4" }, - "SHCHcy;": { "p": [1065], "c": "\u0429" }, - "SHcy;": { "p": [1064], "c": "\u0428" }, - "SOFTcy;": { "p": [1068], "c": "\u042C" }, - "Sacute;": { "p": [346], "c": "\u015A" }, - "Sc;": { "p": [10940], "c": "\u2ABC" }, - "Scaron;": { "p": [352], "c": "\u0160" }, - "Scedil;": { "p": [350], "c": "\u015E" }, - "Scirc;": { "p": [348], "c": "\u015C" }, - "Scy;": { "p": [1057], "c": "\u0421" }, - "Sfr;": { "p": [120086], "c": "\uD835\uDD16" }, - "ShortDownArrow;": { "p": [8595], "c": "\u2193" }, - "ShortLeftArrow;": { "p": [8592], "c": "\u2190" }, - "ShortRightArrow;": { "p": [8594], "c": "\u2192" }, - "ShortUpArrow;": { "p": [8593], "c": "\u2191" }, - "Sigma;": { "p": [931], "c": "\u03A3" }, - "SmallCircle;": { "p": [8728], "c": "\u2218" }, - "Sopf;": { "p": [120138], "c": "\uD835\uDD4A" }, - "Sqrt;": { "p": [8730], "c": "\u221A" }, - "Square;": { "p": [9633], "c": "\u25A1" }, - "SquareIntersection;": { "p": [8851], "c": "\u2293" }, - "SquareSubset;": { "p": [8847], "c": "\u228F" }, - "SquareSubsetEqual;": { "p": [8849], "c": "\u2291" }, - "SquareSuperset;": { "p": [8848], "c": "\u2290" }, - "SquareSupersetEqual;": { "p": [8850], "c": "\u2292" }, - "SquareUnion;": { "p": [8852], "c": "\u2294" }, - "Sscr;": { "p": [119982], "c": "\uD835\uDCAE" }, - "Star;": { "p": [8902], "c": "\u22C6" }, - "Sub;": { "p": [8912], "c": "\u22D0" }, - "Subset;": { "p": [8912], "c": "\u22D0" }, - "SubsetEqual;": { "p": [8838], "c": "\u2286" }, - "Succeeds;": { "p": [8827], "c": "\u227B" }, - "SucceedsEqual;": { "p": [10928], "c": "\u2AB0" }, - "SucceedsSlantEqual;": { "p": [8829], "c": "\u227D" }, - "SucceedsTilde;": { "p": [8831], "c": "\u227F" }, - "SuchThat;": { "p": [8715], "c": "\u220B" }, - "Sum;": { "p": [8721], "c": "\u2211" }, - "Sup;": { "p": [8913], "c": "\u22D1" }, - "Superset;": { "p": [8835], "c": "\u2283" }, - "SupersetEqual;": { "p": [8839], "c": "\u2287" }, - "Supset;": { "p": [8913], "c": "\u22D1" }, - "THORN": { "p": [222], "c": "\u00DE" }, - "THORN;": { "p": [222], "c": "\u00DE" }, - "TRADE;": { "p": [8482], "c": "\u2122" }, - "TSHcy;": { "p": [1035], "c": "\u040B" }, - "TScy;": { "p": [1062], "c": "\u0426" }, - "Tab;": { "p": [9], "c": "\u0009" }, - "Tau;": { "p": [932], "c": "\u03A4" }, - "Tcaron;": { "p": [356], "c": "\u0164" }, - "Tcedil;": { "p": [354], "c": "\u0162" }, - "Tcy;": { "p": [1058], "c": "\u0422" }, - "Tfr;": { "p": [120087], "c": "\uD835\uDD17" }, - "Therefore;": { "p": [8756], "c": "\u2234" }, - "Theta;": { "p": [920], "c": "\u0398" }, - "ThickSpace;": { - "p": [8287, 8202], - "c": "\u205F\u200A" - }, - "ThinSpace;": { "p": [8201], "c": "\u2009" }, - "Tilde;": { "p": [8764], "c": "\u223C" }, - "TildeEqual;": { "p": [8771], "c": "\u2243" }, - "TildeFullEqual;": { "p": [8773], "c": "\u2245" }, - "TildeTilde;": { "p": [8776], "c": "\u2248" }, - "Topf;": { "p": [120139], "c": "\uD835\uDD4B" }, - "TripleDot;": { "p": [8411], "c": "\u20DB" }, - "Tscr;": { "p": [119983], "c": "\uD835\uDCAF" }, - "Tstrok;": { "p": [358], "c": "\u0166" }, - "Uacute": { "p": [218], "c": "\u00DA" }, - "Uacute;": { "p": [218], "c": "\u00DA" }, - "Uarr;": { "p": [8607], "c": "\u219F" }, - "Uarrocir;": { "p": [10569], "c": "\u2949" }, - "Ubrcy;": { "p": [1038], "c": "\u040E" }, - "Ubreve;": { "p": [364], "c": "\u016C" }, - "Ucirc": { "p": [219], "c": "\u00DB" }, - "Ucirc;": { "p": [219], "c": "\u00DB" }, - "Ucy;": { "p": [1059], "c": "\u0423" }, - "Udblac;": { "p": [368], "c": "\u0170" }, - "Ufr;": { "p": [120088], "c": "\uD835\uDD18" }, - "Ugrave": { "p": [217], "c": "\u00D9" }, - "Ugrave;": { "p": [217], "c": "\u00D9" }, - "Umacr;": { "p": [362], "c": "\u016A" }, - "UnderBar;": { "p": [95], "c": "\u005F" }, - "UnderBrace;": { "p": [9183], "c": "\u23DF" }, - "UnderBracket;": { "p": [9141], "c": "\u23B5" }, - "UnderParenthesis;": { "p": [9181], "c": "\u23DD" }, - "Union;": { "p": [8899], "c": "\u22C3" }, - "UnionPlus;": { "p": [8846], "c": "\u228E" }, - "Uogon;": { "p": [370], "c": "\u0172" }, - "Uopf;": { "p": [120140], "c": "\uD835\uDD4C" }, - "UpArrow;": { "p": [8593], "c": "\u2191" }, - "UpArrowBar;": { "p": [10514], "c": "\u2912" }, - "UpArrowDownArrow;": { "p": [8645], "c": "\u21C5" }, - "UpDownArrow;": { "p": [8597], "c": "\u2195" }, - "UpEquilibrium;": { "p": [10606], "c": "\u296E" }, - "UpTee;": { "p": [8869], "c": "\u22A5" }, - "UpTeeArrow;": { "p": [8613], "c": "\u21A5" }, - "Uparrow;": { "p": [8657], "c": "\u21D1" }, - "Updownarrow;": { "p": [8661], "c": "\u21D5" }, - "UpperLeftArrow;": { "p": [8598], "c": "\u2196" }, - "UpperRightArrow;": { "p": [8599], "c": "\u2197" }, - "Upsi;": { "p": [978], "c": "\u03D2" }, - "Upsilon;": { "p": [933], "c": "\u03A5" }, - "Uring;": { "p": [366], "c": "\u016E" }, - "Uscr;": { "p": [119984], "c": "\uD835\uDCB0" }, - "Utilde;": { "p": [360], "c": "\u0168" }, - "Uuml": { "p": [220], "c": "\u00DC" }, - "Uuml;": { "p": [220], "c": "\u00DC" }, - "VDash;": { "p": [8875], "c": "\u22AB" }, - "Vbar;": { "p": [10987], "c": "\u2AEB" }, - "Vcy;": { "p": [1042], "c": "\u0412" }, - "Vdash;": { "p": [8873], "c": "\u22A9" }, - "Vdashl;": { "p": [10982], "c": "\u2AE6" }, - "Vee;": { "p": [8897], "c": "\u22C1" }, - "Verbar;": { "p": [8214], "c": "\u2016" }, - "Vert;": { "p": [8214], "c": "\u2016" }, - "VerticalBar;": { "p": [8739], "c": "\u2223" }, - "VerticalLine;": { "p": [124], "c": "\u007C" }, - "VerticalSeparator;": { "p": [10072], "c": "\u2758" }, - "VerticalTilde;": { "p": [8768], "c": "\u2240" }, - "VeryThinSpace;": { "p": [8202], "c": "\u200A" }, - "Vfr;": { "p": [120089], "c": "\uD835\uDD19" }, - "Vopf;": { "p": [120141], "c": "\uD835\uDD4D" }, - "Vscr;": { "p": [119985], "c": "\uD835\uDCB1" }, - "Vvdash;": { "p": [8874], "c": "\u22AA" }, - "Wcirc;": { "p": [372], "c": "\u0174" }, - "Wedge;": { "p": [8896], "c": "\u22C0" }, - "Wfr;": { "p": [120090], "c": "\uD835\uDD1A" }, - "Wopf;": { "p": [120142], "c": "\uD835\uDD4E" }, - "Wscr;": { "p": [119986], "c": "\uD835\uDCB2" }, - "Xfr;": { "p": [120091], "c": "\uD835\uDD1B" }, - "Xi;": { "p": [926], "c": "\u039E" }, - "Xopf;": { "p": [120143], "c": "\uD835\uDD4F" }, - "Xscr;": { "p": [119987], "c": "\uD835\uDCB3" }, - "YAcy;": { "p": [1071], "c": "\u042F" }, - "YIcy;": { "p": [1031], "c": "\u0407" }, - "YUcy;": { "p": [1070], "c": "\u042E" }, - "Yacute": { "p": [221], "c": "\u00DD" }, - "Yacute;": { "p": [221], "c": "\u00DD" }, - "Ycirc;": { "p": [374], "c": "\u0176" }, - "Ycy;": { "p": [1067], "c": "\u042B" }, - "Yfr;": { "p": [120092], "c": "\uD835\uDD1C" }, - "Yopf;": { "p": [120144], "c": "\uD835\uDD50" }, - "Yscr;": { "p": [119988], "c": "\uD835\uDCB4" }, - "Yuml;": { "p": [376], "c": "\u0178" }, - "ZHcy;": { "p": [1046], "c": "\u0416" }, - "Zacute;": { "p": [377], "c": "\u0179" }, - "Zcaron;": { "p": [381], "c": "\u017D" }, - "Zcy;": { "p": [1047], "c": "\u0417" }, - "Zdot;": { "p": [379], "c": "\u017B" }, - "ZeroWidthSpace;": { "p": [8203], "c": "\u200B" }, - "Zeta;": { "p": [918], "c": "\u0396" }, - "Zfr;": { "p": [8488], "c": "\u2128" }, - "Zopf;": { "p": [8484], "c": "\u2124" }, - "Zscr;": { "p": [119989], "c": "\uD835\uDCB5" }, - "aacute": { "p": [225], "c": "\u00E1" }, - "aacute;": { "p": [225], "c": "\u00E1" }, - "abreve;": { "p": [259], "c": "\u0103" }, - "ac;": { "p": [8766], "c": "\u223E" }, - "acE;": { "p": [8766, 819], "c": "\u223E\u0333" }, - "acd;": { "p": [8767], "c": "\u223F" }, - "acirc": { "p": [226], "c": "\u00E2" }, - "acirc;": { "p": [226], "c": "\u00E2" }, - "acute": { "p": [180], "c": "\u00B4" }, - "acute;": { "p": [180], "c": "\u00B4" }, - "acy;": { "p": [1072], "c": "\u0430" }, - "aelig": { "p": [230], "c": "\u00E6" }, - "aelig;": { "p": [230], "c": "\u00E6" }, - "af;": { "p": [8289], "c": "\u2061" }, - "afr;": { "p": [120094], "c": "\uD835\uDD1E" }, - "agrave": { "p": [224], "c": "\u00E0" }, - "agrave;": { "p": [224], "c": "\u00E0" }, - "alefsym;": { "p": [8501], "c": "\u2135" }, - "aleph;": { "p": [8501], "c": "\u2135" }, - "alpha;": { "p": [945], "c": "\u03B1" }, - "amacr;": { "p": [257], "c": "\u0101" }, - "amalg;": { "p": [10815], "c": "\u2A3F" }, - "amp": { "p": [38], "c": "\u0026" }, - "amp;": { "p": [38], "c": "\u0026" }, - "and;": { "p": [8743], "c": "\u2227" }, - "andand;": { "p": [10837], "c": "\u2A55" }, - "andd;": { "p": [10844], "c": "\u2A5C" }, - "andslope;": { "p": [10840], "c": "\u2A58" }, - "andv;": { "p": [10842], "c": "\u2A5A" }, - "ang;": { "p": [8736], "c": "\u2220" }, - "ange;": { "p": [10660], "c": "\u29A4" }, - "angle;": { "p": [8736], "c": "\u2220" }, - "angmsd;": { "p": [8737], "c": "\u2221" }, - "angmsdaa;": { "p": [10664], "c": "\u29A8" }, - "angmsdab;": { "p": [10665], "c": "\u29A9" }, - "angmsdac;": { "p": [10666], "c": "\u29AA" }, - "angmsdad;": { "p": [10667], "c": "\u29AB" }, - "angmsdae;": { "p": [10668], "c": "\u29AC" }, - "angmsdaf;": { "p": [10669], "c": "\u29AD" }, - "angmsdag;": { "p": [10670], "c": "\u29AE" }, - "angmsdah;": { "p": [10671], "c": "\u29AF" }, - "angrt;": { "p": [8735], "c": "\u221F" }, - "angrtvb;": { "p": [8894], "c": "\u22BE" }, - "angrtvbd;": { "p": [10653], "c": "\u299D" }, - "angsph;": { "p": [8738], "c": "\u2222" }, - "angst;": { "p": [197], "c": "\u00C5" }, - "angzarr;": { "p": [9084], "c": "\u237C" }, - "aogon;": { "p": [261], "c": "\u0105" }, - "aopf;": { "p": [120146], "c": "\uD835\uDD52" }, - "ap;": { "p": [8776], "c": "\u2248" }, - "apE;": { "p": [10864], "c": "\u2A70" }, - "apacir;": { "p": [10863], "c": "\u2A6F" }, - "ape;": { "p": [8778], "c": "\u224A" }, - "apid;": { "p": [8779], "c": "\u224B" }, - "apos;": { "p": [39], "c": "\u0027" }, - "approx;": { "p": [8776], "c": "\u2248" }, - "approxeq;": { "p": [8778], "c": "\u224A" }, - "aring": { "p": [229], "c": "\u00E5" }, - "aring;": { "p": [229], "c": "\u00E5" }, - "ascr;": { "p": [119990], "c": "\uD835\uDCB6" }, - "ast;": { "p": [42], "c": "\u002A" }, - "asymp;": { "p": [8776], "c": "\u2248" }, - "asympeq;": { "p": [8781], "c": "\u224D" }, - "atilde": { "p": [227], "c": "\u00E3" }, - "atilde;": { "p": [227], "c": "\u00E3" }, - "auml": { "p": [228], "c": "\u00E4" }, - "auml;": { "p": [228], "c": "\u00E4" }, - "awconint;": { "p": [8755], "c": "\u2233" }, - "awint;": { "p": [10769], "c": "\u2A11" }, - "bNot;": { "p": [10989], "c": "\u2AED" }, - "backcong;": { "p": [8780], "c": "\u224C" }, - "backepsilon;": { "p": [1014], "c": "\u03F6" }, - "backprime;": { "p": [8245], "c": "\u2035" }, - "backsim;": { "p": [8765], "c": "\u223D" }, - "backsimeq;": { "p": [8909], "c": "\u22CD" }, - "barvee;": { "p": [8893], "c": "\u22BD" }, - "barwed;": { "p": [8965], "c": "\u2305" }, - "barwedge;": { "p": [8965], "c": "\u2305" }, - "bbrk;": { "p": [9141], "c": "\u23B5" }, - "bbrktbrk;": { "p": [9142], "c": "\u23B6" }, - "bcong;": { "p": [8780], "c": "\u224C" }, - "bcy;": { "p": [1073], "c": "\u0431" }, - "bdquo;": { "p": [8222], "c": "\u201E" }, - "becaus;": { "p": [8757], "c": "\u2235" }, - "because;": { "p": [8757], "c": "\u2235" }, - "bemptyv;": { "p": [10672], "c": "\u29B0" }, - "bepsi;": { "p": [1014], "c": "\u03F6" }, - "bernou;": { "p": [8492], "c": "\u212C" }, - "beta;": { "p": [946], "c": "\u03B2" }, - "beth;": { "p": [8502], "c": "\u2136" }, - "between;": { "p": [8812], "c": "\u226C" }, - "bfr;": { "p": [120095], "c": "\uD835\uDD1F" }, - "bigcap;": { "p": [8898], "c": "\u22C2" }, - "bigcirc;": { "p": [9711], "c": "\u25EF" }, - "bigcup;": { "p": [8899], "c": "\u22C3" }, - "bigodot;": { "p": [10752], "c": "\u2A00" }, - "bigoplus;": { "p": [10753], "c": "\u2A01" }, - "bigotimes;": { "p": [10754], "c": "\u2A02" }, - "bigsqcup;": { "p": [10758], "c": "\u2A06" }, - "bigstar;": { "p": [9733], "c": "\u2605" }, - "bigtriangledown;": { "p": [9661], "c": "\u25BD" }, - "bigtriangleup;": { "p": [9651], "c": "\u25B3" }, - "biguplus;": { "p": [10756], "c": "\u2A04" }, - "bigvee;": { "p": [8897], "c": "\u22C1" }, - "bigwedge;": { "p": [8896], "c": "\u22C0" }, - "bkarow;": { "p": [10509], "c": "\u290D" }, - "blacklozenge;": { "p": [10731], "c": "\u29EB" }, - "blacksquare;": { "p": [9642], "c": "\u25AA" }, - "blacktriangle;": { "p": [9652], "c": "\u25B4" }, - "blacktriangledown;": { "p": [9662], "c": "\u25BE" }, - "blacktriangleleft;": { "p": [9666], "c": "\u25C2" }, - "blacktriangleright;": { "p": [9656], "c": "\u25B8" }, - "blank;": { "p": [9251], "c": "\u2423" }, - "blk12;": { "p": [9618], "c": "\u2592" }, - "blk14;": { "p": [9617], "c": "\u2591" }, - "blk34;": { "p": [9619], "c": "\u2593" }, - "block;": { "p": [9608], "c": "\u2588" }, - "bne;": { "p": [61, 8421], "c": "\u003D\u20E5" }, - "bnequiv;": { "p": [8801, 8421], "c": "\u2261\u20E5" }, - "bnot;": { "p": [8976], "c": "\u2310" }, - "bopf;": { "p": [120147], "c": "\uD835\uDD53" }, - "bot;": { "p": [8869], "c": "\u22A5" }, - "bottom;": { "p": [8869], "c": "\u22A5" }, - "bowtie;": { "p": [8904], "c": "\u22C8" }, - "boxDL;": { "p": [9559], "c": "\u2557" }, - "boxDR;": { "p": [9556], "c": "\u2554" }, - "boxDl;": { "p": [9558], "c": "\u2556" }, - "boxDr;": { "p": [9555], "c": "\u2553" }, - "boxH;": { "p": [9552], "c": "\u2550" }, - "boxHD;": { "p": [9574], "c": "\u2566" }, - "boxHU;": { "p": [9577], "c": "\u2569" }, - "boxHd;": { "p": [9572], "c": "\u2564" }, - "boxHu;": { "p": [9575], "c": "\u2567" }, - "boxUL;": { "p": [9565], "c": "\u255D" }, - "boxUR;": { "p": [9562], "c": "\u255A" }, - "boxUl;": { "p": [9564], "c": "\u255C" }, - "boxUr;": { "p": [9561], "c": "\u2559" }, - "boxV;": { "p": [9553], "c": "\u2551" }, - "boxVH;": { "p": [9580], "c": "\u256C" }, - "boxVL;": { "p": [9571], "c": "\u2563" }, - "boxVR;": { "p": [9568], "c": "\u2560" }, - "boxVh;": { "p": [9579], "c": "\u256B" }, - "boxVl;": { "p": [9570], "c": "\u2562" }, - "boxVr;": { "p": [9567], "c": "\u255F" }, - "boxbox;": { "p": [10697], "c": "\u29C9" }, - "boxdL;": { "p": [9557], "c": "\u2555" }, - "boxdR;": { "p": [9554], "c": "\u2552" }, - "boxdl;": { "p": [9488], "c": "\u2510" }, - "boxdr;": { "p": [9484], "c": "\u250C" }, - "boxh;": { "p": [9472], "c": "\u2500" }, - "boxhD;": { "p": [9573], "c": "\u2565" }, - "boxhU;": { "p": [9576], "c": "\u2568" }, - "boxhd;": { "p": [9516], "c": "\u252C" }, - "boxhu;": { "p": [9524], "c": "\u2534" }, - "boxminus;": { "p": [8863], "c": "\u229F" }, - "boxplus;": { "p": [8862], "c": "\u229E" }, - "boxtimes;": { "p": [8864], "c": "\u22A0" }, - "boxuL;": { "p": [9563], "c": "\u255B" }, - "boxuR;": { "p": [9560], "c": "\u2558" }, - "boxul;": { "p": [9496], "c": "\u2518" }, - "boxur;": { "p": [9492], "c": "\u2514" }, - "boxv;": { "p": [9474], "c": "\u2502" }, - "boxvH;": { "p": [9578], "c": "\u256A" }, - "boxvL;": { "p": [9569], "c": "\u2561" }, - "boxvR;": { "p": [9566], "c": "\u255E" }, - "boxvh;": { "p": [9532], "c": "\u253C" }, - "boxvl;": { "p": [9508], "c": "\u2524" }, - "boxvr;": { "p": [9500], "c": "\u251C" }, - "bprime;": { "p": [8245], "c": "\u2035" }, - "breve;": { "p": [728], "c": "\u02D8" }, - "brvbar": { "p": [166], "c": "\u00A6" }, - "brvbar;": { "p": [166], "c": "\u00A6" }, - "bscr;": { "p": [119991], "c": "\uD835\uDCB7" }, - "bsemi;": { "p": [8271], "c": "\u204F" }, - "bsim;": { "p": [8765], "c": "\u223D" }, - "bsime;": { "p": [8909], "c": "\u22CD" }, - "bsol;": { "p": [92], "c": "\u005C" }, - "bsolb;": { "p": [10693], "c": "\u29C5" }, - "bsolhsub;": { "p": [10184], "c": "\u27C8" }, - "bull;": { "p": [8226], "c": "\u2022" }, - "bullet;": { "p": [8226], "c": "\u2022" }, - "bump;": { "p": [8782], "c": "\u224E" }, - "bumpE;": { "p": [10926], "c": "\u2AAE" }, - "bumpe;": { "p": [8783], "c": "\u224F" }, - "bumpeq;": { "p": [8783], "c": "\u224F" }, - "cacute;": { "p": [263], "c": "\u0107" }, - "cap;": { "p": [8745], "c": "\u2229" }, - "capand;": { "p": [10820], "c": "\u2A44" }, - "capbrcup;": { "p": [10825], "c": "\u2A49" }, - "capcap;": { "p": [10827], "c": "\u2A4B" }, - "capcup;": { "p": [10823], "c": "\u2A47" }, - "capdot;": { "p": [10816], "c": "\u2A40" }, - "caps;": { "p": [8745, 65024], "c": "\u2229\uFE00" }, - "caret;": { "p": [8257], "c": "\u2041" }, - "caron;": { "p": [711], "c": "\u02C7" }, - "ccaps;": { "p": [10829], "c": "\u2A4D" }, - "ccaron;": { "p": [269], "c": "\u010D" }, - "ccedil": { "p": [231], "c": "\u00E7" }, - "ccedil;": { "p": [231], "c": "\u00E7" }, - "ccirc;": { "p": [265], "c": "\u0109" }, - "ccups;": { "p": [10828], "c": "\u2A4C" }, - "ccupssm;": { "p": [10832], "c": "\u2A50" }, - "cdot;": { "p": [267], "c": "\u010B" }, - "cedil": { "p": [184], "c": "\u00B8" }, - "cedil;": { "p": [184], "c": "\u00B8" }, - "cemptyv;": { "p": [10674], "c": "\u29B2" }, - "cent": { "p": [162], "c": "\u00A2" }, - "cent;": { "p": [162], "c": "\u00A2" }, - "centerdot;": { "p": [183], "c": "\u00B7" }, - "cfr;": { "p": [120096], "c": "\uD835\uDD20" }, - "chcy;": { "p": [1095], "c": "\u0447" }, - "check;": { "p": [10003], "c": "\u2713" }, - "checkmark;": { "p": [10003], "c": "\u2713" }, - "chi;": { "p": [967], "c": "\u03C7" }, - "cir;": { "p": [9675], "c": "\u25CB" }, - "cirE;": { "p": [10691], "c": "\u29C3" }, - "circ;": { "p": [710], "c": "\u02C6" }, - "circeq;": { "p": [8791], "c": "\u2257" }, - "circlearrowleft;": { "p": [8634], "c": "\u21BA" }, - "circlearrowright;": { "p": [8635], "c": "\u21BB" }, - "circledR;": { "p": [174], "c": "\u00AE" }, - "circledS;": { "p": [9416], "c": "\u24C8" }, - "circledast;": { "p": [8859], "c": "\u229B" }, - "circledcirc;": { "p": [8858], "c": "\u229A" }, - "circleddash;": { "p": [8861], "c": "\u229D" }, - "cire;": { "p": [8791], "c": "\u2257" }, - "cirfnint;": { "p": [10768], "c": "\u2A10" }, - "cirmid;": { "p": [10991], "c": "\u2AEF" }, - "cirscir;": { "p": [10690], "c": "\u29C2" }, - "clubs;": { "p": [9827], "c": "\u2663" }, - "clubsuit;": { "p": [9827], "c": "\u2663" }, - "colon;": { "p": [58], "c": "\u003A" }, - "colone;": { "p": [8788], "c": "\u2254" }, - "coloneq;": { "p": [8788], "c": "\u2254" }, - "comma;": { "p": [44], "c": "\u002C" }, - "commat;": { "p": [64], "c": "\u0040" }, - "comp;": { "p": [8705], "c": "\u2201" }, - "compfn;": { "p": [8728], "c": "\u2218" }, - "complement;": { "p": [8705], "c": "\u2201" }, - "complexes;": { "p": [8450], "c": "\u2102" }, - "cong;": { "p": [8773], "c": "\u2245" }, - "congdot;": { "p": [10861], "c": "\u2A6D" }, - "conint;": { "p": [8750], "c": "\u222E" }, - "copf;": { "p": [120148], "c": "\uD835\uDD54" }, - "coprod;": { "p": [8720], "c": "\u2210" }, - "copy": { "p": [169], "c": "\u00A9" }, - "copy;": { "p": [169], "c": "\u00A9" }, - "copysr;": { "p": [8471], "c": "\u2117" }, - "crarr;": { "p": [8629], "c": "\u21B5" }, - "cross;": { "p": [10007], "c": "\u2717" }, - "cscr;": { "p": [119992], "c": "\uD835\uDCB8" }, - "csub;": { "p": [10959], "c": "\u2ACF" }, - "csube;": { "p": [10961], "c": "\u2AD1" }, - "csup;": { "p": [10960], "c": "\u2AD0" }, - "csupe;": { "p": [10962], "c": "\u2AD2" }, - "ctdot;": { "p": [8943], "c": "\u22EF" }, - "cudarrl;": { "p": [10552], "c": "\u2938" }, - "cudarrr;": { "p": [10549], "c": "\u2935" }, - "cuepr;": { "p": [8926], "c": "\u22DE" }, - "cuesc;": { "p": [8927], "c": "\u22DF" }, - "cularr;": { "p": [8630], "c": "\u21B6" }, - "cularrp;": { "p": [10557], "c": "\u293D" }, - "cup;": { "p": [8746], "c": "\u222A" }, - "cupbrcap;": { "p": [10824], "c": "\u2A48" }, - "cupcap;": { "p": [10822], "c": "\u2A46" }, - "cupcup;": { "p": [10826], "c": "\u2A4A" }, - "cupdot;": { "p": [8845], "c": "\u228D" }, - "cupor;": { "p": [10821], "c": "\u2A45" }, - "cups;": { "p": [8746, 65024], "c": "\u222A\uFE00" }, - "curarr;": { "p": [8631], "c": "\u21B7" }, - "curarrm;": { "p": [10556], "c": "\u293C" }, - "curlyeqprec;": { "p": [8926], "c": "\u22DE" }, - "curlyeqsucc;": { "p": [8927], "c": "\u22DF" }, - "curlyvee;": { "p": [8910], "c": "\u22CE" }, - "curlywedge;": { "p": [8911], "c": "\u22CF" }, - "curren": { "p": [164], "c": "\u00A4" }, - "curren;": { "p": [164], "c": "\u00A4" }, - "curvearrowleft;": { "p": [8630], "c": "\u21B6" }, - "curvearrowright;": { "p": [8631], "c": "\u21B7" }, - "cuvee;": { "p": [8910], "c": "\u22CE" }, - "cuwed;": { "p": [8911], "c": "\u22CF" }, - "cwconint;": { "p": [8754], "c": "\u2232" }, - "cwint;": { "p": [8753], "c": "\u2231" }, - "cylcty;": { "p": [9005], "c": "\u232D" }, - "dArr;": { "p": [8659], "c": "\u21D3" }, - "dHar;": { "p": [10597], "c": "\u2965" }, - "dagger;": { "p": [8224], "c": "\u2020" }, - "daleth;": { "p": [8504], "c": "\u2138" }, - "darr;": { "p": [8595], "c": "\u2193" }, - "dash;": { "p": [8208], "c": "\u2010" }, - "dashv;": { "p": [8867], "c": "\u22A3" }, - "dbkarow;": { "p": [10511], "c": "\u290F" }, - "dblac;": { "p": [733], "c": "\u02DD" }, - "dcaron;": { "p": [271], "c": "\u010F" }, - "dcy;": { "p": [1076], "c": "\u0434" }, - "dd;": { "p": [8518], "c": "\u2146" }, - "ddagger;": { "p": [8225], "c": "\u2021" }, - "ddarr;": { "p": [8650], "c": "\u21CA" }, - "ddotseq;": { "p": [10871], "c": "\u2A77" }, - "deg": { "p": [176], "c": "\u00B0" }, - "deg;": { "p": [176], "c": "\u00B0" }, - "delta;": { "p": [948], "c": "\u03B4" }, - "demptyv;": { "p": [10673], "c": "\u29B1" }, - "dfisht;": { "p": [10623], "c": "\u297F" }, - "dfr;": { "p": [120097], "c": "\uD835\uDD21" }, - "dharl;": { "p": [8643], "c": "\u21C3" }, - "dharr;": { "p": [8642], "c": "\u21C2" }, - "diam;": { "p": [8900], "c": "\u22C4" }, - "diamond;": { "p": [8900], "c": "\u22C4" }, - "diamondsuit;": { "p": [9830], "c": "\u2666" }, - "diams;": { "p": [9830], "c": "\u2666" }, - "die;": { "p": [168], "c": "\u00A8" }, - "digamma;": { "p": [989], "c": "\u03DD" }, - "disin;": { "p": [8946], "c": "\u22F2" }, - "div;": { "p": [247], "c": "\u00F7" }, - "divide": { "p": [247], "c": "\u00F7" }, - "divide;": { "p": [247], "c": "\u00F7" }, - "divideontimes;": { "p": [8903], "c": "\u22C7" }, - "divonx;": { "p": [8903], "c": "\u22C7" }, - "djcy;": { "p": [1106], "c": "\u0452" }, - "dlcorn;": { "p": [8990], "c": "\u231E" }, - "dlcrop;": { "p": [8973], "c": "\u230D" }, - "dollar;": { "p": [36], "c": "\u0024" }, - "dopf;": { "p": [120149], "c": "\uD835\uDD55" }, - "dot;": { "p": [729], "c": "\u02D9" }, - "doteq;": { "p": [8784], "c": "\u2250" }, - "doteqdot;": { "p": [8785], "c": "\u2251" }, - "dotminus;": { "p": [8760], "c": "\u2238" }, - "dotplus;": { "p": [8724], "c": "\u2214" }, - "dotsquare;": { "p": [8865], "c": "\u22A1" }, - "doublebarwedge;": { "p": [8966], "c": "\u2306" }, - "downarrow;": { "p": [8595], "c": "\u2193" }, - "downdownarrows;": { "p": [8650], "c": "\u21CA" }, - "downharpoonleft;": { "p": [8643], "c": "\u21C3" }, - "downharpoonright;": { "p": [8642], "c": "\u21C2" }, - "drbkarow;": { "p": [10512], "c": "\u2910" }, - "drcorn;": { "p": [8991], "c": "\u231F" }, - "drcrop;": { "p": [8972], "c": "\u230C" }, - "dscr;": { "p": [119993], "c": "\uD835\uDCB9" }, - "dscy;": { "p": [1109], "c": "\u0455" }, - "dsol;": { "p": [10742], "c": "\u29F6" }, - "dstrok;": { "p": [273], "c": "\u0111" }, - "dtdot;": { "p": [8945], "c": "\u22F1" }, - "dtri;": { "p": [9663], "c": "\u25BF" }, - "dtrif;": { "p": [9662], "c": "\u25BE" }, - "duarr;": { "p": [8693], "c": "\u21F5" }, - "duhar;": { "p": [10607], "c": "\u296F" }, - "dwangle;": { "p": [10662], "c": "\u29A6" }, - "dzcy;": { "p": [1119], "c": "\u045F" }, - "dzigrarr;": { "p": [10239], "c": "\u27FF" }, - "eDDot;": { "p": [10871], "c": "\u2A77" }, - "eDot;": { "p": [8785], "c": "\u2251" }, - "eacute": { "p": [233], "c": "\u00E9" }, - "eacute;": { "p": [233], "c": "\u00E9" }, - "easter;": { "p": [10862], "c": "\u2A6E" }, - "ecaron;": { "p": [283], "c": "\u011B" }, - "ecir;": { "p": [8790], "c": "\u2256" }, - "ecirc": { "p": [234], "c": "\u00EA" }, - "ecirc;": { "p": [234], "c": "\u00EA" }, - "ecolon;": { "p": [8789], "c": "\u2255" }, - "ecy;": { "p": [1101], "c": "\u044D" }, - "edot;": { "p": [279], "c": "\u0117" }, - "ee;": { "p": [8519], "c": "\u2147" }, - "efDot;": { "p": [8786], "c": "\u2252" }, - "efr;": { "p": [120098], "c": "\uD835\uDD22" }, - "eg;": { "p": [10906], "c": "\u2A9A" }, - "egrave": { "p": [232], "c": "\u00E8" }, - "egrave;": { "p": [232], "c": "\u00E8" }, - "egs;": { "p": [10902], "c": "\u2A96" }, - "egsdot;": { "p": [10904], "c": "\u2A98" }, - "el;": { "p": [10905], "c": "\u2A99" }, - "elinters;": { "p": [9191], "c": "\u23E7" }, - "ell;": { "p": [8467], "c": "\u2113" }, - "els;": { "p": [10901], "c": "\u2A95" }, - "elsdot;": { "p": [10903], "c": "\u2A97" }, - "emacr;": { "p": [275], "c": "\u0113" }, - "empty;": { "p": [8709], "c": "\u2205" }, - "emptyset;": { "p": [8709], "c": "\u2205" }, - "emptyv;": { "p": [8709], "c": "\u2205" }, - "emsp13;": { "p": [8196], "c": "\u2004" }, - "emsp14;": { "p": [8197], "c": "\u2005" }, - "emsp;": { "p": [8195], "c": "\u2003" }, - "eng;": { "p": [331], "c": "\u014B" }, - "ensp;": { "p": [8194], "c": "\u2002" }, - "eogon;": { "p": [281], "c": "\u0119" }, - "eopf;": { "p": [120150], "c": "\uD835\uDD56" }, - "epar;": { "p": [8917], "c": "\u22D5" }, - "eparsl;": { "p": [10723], "c": "\u29E3" }, - "eplus;": { "p": [10865], "c": "\u2A71" }, - "epsi;": { "p": [949], "c": "\u03B5" }, - "epsilon;": { "p": [949], "c": "\u03B5" }, - "epsiv;": { "p": [1013], "c": "\u03F5" }, - "eqcirc;": { "p": [8790], "c": "\u2256" }, - "eqcolon;": { "p": [8789], "c": "\u2255" }, - "eqsim;": { "p": [8770], "c": "\u2242" }, - "eqslantgtr;": { "p": [10902], "c": "\u2A96" }, - "eqslantless;": { "p": [10901], "c": "\u2A95" }, - "equals;": { "p": [61], "c": "\u003D" }, - "equest;": { "p": [8799], "c": "\u225F" }, - "equiv;": { "p": [8801], "c": "\u2261" }, - "equivDD;": { "p": [10872], "c": "\u2A78" }, - "eqvparsl;": { "p": [10725], "c": "\u29E5" }, - "erDot;": { "p": [8787], "c": "\u2253" }, - "erarr;": { "p": [10609], "c": "\u2971" }, - "escr;": { "p": [8495], "c": "\u212F" }, - "esdot;": { "p": [8784], "c": "\u2250" }, - "esim;": { "p": [8770], "c": "\u2242" }, - "eta;": { "p": [951], "c": "\u03B7" }, - "eth": { "p": [240], "c": "\u00F0" }, - "eth;": { "p": [240], "c": "\u00F0" }, - "euml": { "p": [235], "c": "\u00EB" }, - "euml;": { "p": [235], "c": "\u00EB" }, - "euro;": { "p": [8364], "c": "\u20AC" }, - "excl;": { "p": [33], "c": "\u0021" }, - "exist;": { "p": [8707], "c": "\u2203" }, - "expectation;": { "p": [8496], "c": "\u2130" }, - "exponentiale;": { "p": [8519], "c": "\u2147" }, - "fallingdotseq;": { "p": [8786], "c": "\u2252" }, - "fcy;": { "p": [1092], "c": "\u0444" }, - "female;": { "p": [9792], "c": "\u2640" }, - "ffilig;": { "p": [64259], "c": "\uFB03" }, - "fflig;": { "p": [64256], "c": "\uFB00" }, - "ffllig;": { "p": [64260], "c": "\uFB04" }, - "ffr;": { "p": [120099], "c": "\uD835\uDD23" }, - "filig;": { "p": [64257], "c": "\uFB01" }, - "fjlig;": { "p": [102, 106], "c": "\u0066\u006A" }, - "flat;": { "p": [9837], "c": "\u266D" }, - "fllig;": { "p": [64258], "c": "\uFB02" }, - "fltns;": { "p": [9649], "c": "\u25B1" }, - "fnof;": { "p": [402], "c": "\u0192" }, - "fopf;": { "p": [120151], "c": "\uD835\uDD57" }, - "forall;": { "p": [8704], "c": "\u2200" }, - "fork;": { "p": [8916], "c": "\u22D4" }, - "forkv;": { "p": [10969], "c": "\u2AD9" }, - "fpartint;": { "p": [10765], "c": "\u2A0D" }, - "frac12": { "p": [189], "c": "\u00BD" }, - "frac12;": { "p": [189], "c": "\u00BD" }, - "frac13;": { "p": [8531], "c": "\u2153" }, - "frac14": { "p": [188], "c": "\u00BC" }, - "frac14;": { "p": [188], "c": "\u00BC" }, - "frac15;": { "p": [8533], "c": "\u2155" }, - "frac16;": { "p": [8537], "c": "\u2159" }, - "frac18;": { "p": [8539], "c": "\u215B" }, - "frac23;": { "p": [8532], "c": "\u2154" }, - "frac25;": { "p": [8534], "c": "\u2156" }, - "frac34": { "p": [190], "c": "\u00BE" }, - "frac34;": { "p": [190], "c": "\u00BE" }, - "frac35;": { "p": [8535], "c": "\u2157" }, - "frac38;": { "p": [8540], "c": "\u215C" }, - "frac45;": { "p": [8536], "c": "\u2158" }, - "frac56;": { "p": [8538], "c": "\u215A" }, - "frac58;": { "p": [8541], "c": "\u215D" }, - "frac78;": { "p": [8542], "c": "\u215E" }, - "frasl;": { "p": [8260], "c": "\u2044" }, - "frown;": { "p": [8994], "c": "\u2322" }, - "fscr;": { "p": [119995], "c": "\uD835\uDCBB" }, - "gE;": { "p": [8807], "c": "\u2267" }, - "gEl;": { "p": [10892], "c": "\u2A8C" }, - "gacute;": { "p": [501], "c": "\u01F5" }, - "gamma;": { "p": [947], "c": "\u03B3" }, - "gammad;": { "p": [989], "c": "\u03DD" }, - "gap;": { "p": [10886], "c": "\u2A86" }, - "gbreve;": { "p": [287], "c": "\u011F" }, - "gcirc;": { "p": [285], "c": "\u011D" }, - "gcy;": { "p": [1075], "c": "\u0433" }, - "gdot;": { "p": [289], "c": "\u0121" }, - "ge;": { "p": [8805], "c": "\u2265" }, - "gel;": { "p": [8923], "c": "\u22DB" }, - "geq;": { "p": [8805], "c": "\u2265" }, - "geqq;": { "p": [8807], "c": "\u2267" }, - "geqslant;": { "p": [10878], "c": "\u2A7E" }, - "ges;": { "p": [10878], "c": "\u2A7E" }, - "gescc;": { "p": [10921], "c": "\u2AA9" }, - "gesdot;": { "p": [10880], "c": "\u2A80" }, - "gesdoto;": { "p": [10882], "c": "\u2A82" }, - "gesdotol;": { "p": [10884], "c": "\u2A84" }, - "gesl;": { "p": [8923, 65024], "c": "\u22DB\uFE00" }, - "gesles;": { "p": [10900], "c": "\u2A94" }, - "gfr;": { "p": [120100], "c": "\uD835\uDD24" }, - "gg;": { "p": [8811], "c": "\u226B" }, - "ggg;": { "p": [8921], "c": "\u22D9" }, - "gimel;": { "p": [8503], "c": "\u2137" }, - "gjcy;": { "p": [1107], "c": "\u0453" }, - "gl;": { "p": [8823], "c": "\u2277" }, - "glE;": { "p": [10898], "c": "\u2A92" }, - "gla;": { "p": [10917], "c": "\u2AA5" }, - "glj;": { "p": [10916], "c": "\u2AA4" }, - "gnE;": { "p": [8809], "c": "\u2269" }, - "gnap;": { "p": [10890], "c": "\u2A8A" }, - "gnapprox;": { "p": [10890], "c": "\u2A8A" }, - "gne;": { "p": [10888], "c": "\u2A88" }, - "gneq;": { "p": [10888], "c": "\u2A88" }, - "gneqq;": { "p": [8809], "c": "\u2269" }, - "gnsim;": { "p": [8935], "c": "\u22E7" }, - "gopf;": { "p": [120152], "c": "\uD835\uDD58" }, - "grave;": { "p": [96], "c": "\u0060" }, - "gscr;": { "p": [8458], "c": "\u210A" }, - "gsim;": { "p": [8819], "c": "\u2273" }, - "gsime;": { "p": [10894], "c": "\u2A8E" }, - "gsiml;": { "p": [10896], "c": "\u2A90" }, - "gt": { "p": [62], "c": "\u003E" }, - "gt;": { "p": [62], "c": "\u003E" }, - "gtcc;": { "p": [10919], "c": "\u2AA7" }, - "gtcir;": { "p": [10874], "c": "\u2A7A" }, - "gtdot;": { "p": [8919], "c": "\u22D7" }, - "gtlPar;": { "p": [10645], "c": "\u2995" }, - "gtquest;": { "p": [10876], "c": "\u2A7C" }, - "gtrapprox;": { "p": [10886], "c": "\u2A86" }, - "gtrarr;": { "p": [10616], "c": "\u2978" }, - "gtrdot;": { "p": [8919], "c": "\u22D7" }, - "gtreqless;": { "p": [8923], "c": "\u22DB" }, - "gtreqqless;": { "p": [10892], "c": "\u2A8C" }, - "gtrless;": { "p": [8823], "c": "\u2277" }, - "gtrsim;": { "p": [8819], "c": "\u2273" }, - "gvertneqq;": { - "p": [8809, 65024], - "c": "\u2269\uFE00" - }, - "gvnE;": { "p": [8809, 65024], "c": "\u2269\uFE00" }, - "hArr;": { "p": [8660], "c": "\u21D4" }, - "hairsp;": { "p": [8202], "c": "\u200A" }, - "half;": { "p": [189], "c": "\u00BD" }, - "hamilt;": { "p": [8459], "c": "\u210B" }, - "hardcy;": { "p": [1098], "c": "\u044A" }, - "harr;": { "p": [8596], "c": "\u2194" }, - "harrcir;": { "p": [10568], "c": "\u2948" }, - "harrw;": { "p": [8621], "c": "\u21AD" }, - "hbar;": { "p": [8463], "c": "\u210F" }, - "hcirc;": { "p": [293], "c": "\u0125" }, - "hearts;": { "p": [9829], "c": "\u2665" }, - "heartsuit;": { "p": [9829], "c": "\u2665" }, - "hellip;": { "p": [8230], "c": "\u2026" }, - "hercon;": { "p": [8889], "c": "\u22B9" }, - "hfr;": { "p": [120101], "c": "\uD835\uDD25" }, - "hksearow;": { "p": [10533], "c": "\u2925" }, - "hkswarow;": { "p": [10534], "c": "\u2926" }, - "hoarr;": { "p": [8703], "c": "\u21FF" }, - "homtht;": { "p": [8763], "c": "\u223B" }, - "hookleftarrow;": { "p": [8617], "c": "\u21A9" }, - "hookrightarrow;": { "p": [8618], "c": "\u21AA" }, - "hopf;": { "p": [120153], "c": "\uD835\uDD59" }, - "horbar;": { "p": [8213], "c": "\u2015" }, - "hscr;": { "p": [119997], "c": "\uD835\uDCBD" }, - "hslash;": { "p": [8463], "c": "\u210F" }, - "hstrok;": { "p": [295], "c": "\u0127" }, - "hybull;": { "p": [8259], "c": "\u2043" }, - "hyphen;": { "p": [8208], "c": "\u2010" }, - "iacute": { "p": [237], "c": "\u00ED" }, - "iacute;": { "p": [237], "c": "\u00ED" }, - "ic;": { "p": [8291], "c": "\u2063" }, - "icirc": { "p": [238], "c": "\u00EE" }, - "icirc;": { "p": [238], "c": "\u00EE" }, - "icy;": { "p": [1080], "c": "\u0438" }, - "iecy;": { "p": [1077], "c": "\u0435" }, - "iexcl": { "p": [161], "c": "\u00A1" }, - "iexcl;": { "p": [161], "c": "\u00A1" }, - "iff;": { "p": [8660], "c": "\u21D4" }, - "ifr;": { "p": [120102], "c": "\uD835\uDD26" }, - "igrave": { "p": [236], "c": "\u00EC" }, - "igrave;": { "p": [236], "c": "\u00EC" }, - "ii;": { "p": [8520], "c": "\u2148" }, - "iiiint;": { "p": [10764], "c": "\u2A0C" }, - "iiint;": { "p": [8749], "c": "\u222D" }, - "iinfin;": { "p": [10716], "c": "\u29DC" }, - "iiota;": { "p": [8489], "c": "\u2129" }, - "ijlig;": { "p": [307], "c": "\u0133" }, - "imacr;": { "p": [299], "c": "\u012B" }, - "image;": { "p": [8465], "c": "\u2111" }, - "imagline;": { "p": [8464], "c": "\u2110" }, - "imagpart;": { "p": [8465], "c": "\u2111" }, - "imath;": { "p": [305], "c": "\u0131" }, - "imof;": { "p": [8887], "c": "\u22B7" }, - "imped;": { "p": [437], "c": "\u01B5" }, - "in;": { "p": [8712], "c": "\u2208" }, - "incare;": { "p": [8453], "c": "\u2105" }, - "infin;": { "p": [8734], "c": "\u221E" }, - "infintie;": { "p": [10717], "c": "\u29DD" }, - "inodot;": { "p": [305], "c": "\u0131" }, - "int;": { "p": [8747], "c": "\u222B" }, - "intcal;": { "p": [8890], "c": "\u22BA" }, - "integers;": { "p": [8484], "c": "\u2124" }, - "intercal;": { "p": [8890], "c": "\u22BA" }, - "intlarhk;": { "p": [10775], "c": "\u2A17" }, - "intprod;": { "p": [10812], "c": "\u2A3C" }, - "iocy;": { "p": [1105], "c": "\u0451" }, - "iogon;": { "p": [303], "c": "\u012F" }, - "iopf;": { "p": [120154], "c": "\uD835\uDD5A" }, - "iota;": { "p": [953], "c": "\u03B9" }, - "iprod;": { "p": [10812], "c": "\u2A3C" }, - "iquest": { "p": [191], "c": "\u00BF" }, - "iquest;": { "p": [191], "c": "\u00BF" }, - "iscr;": { "p": [119998], "c": "\uD835\uDCBE" }, - "isin;": { "p": [8712], "c": "\u2208" }, - "isinE;": { "p": [8953], "c": "\u22F9" }, - "isindot;": { "p": [8949], "c": "\u22F5" }, - "isins;": { "p": [8948], "c": "\u22F4" }, - "isinsv;": { "p": [8947], "c": "\u22F3" }, - "isinv;": { "p": [8712], "c": "\u2208" }, - "it;": { "p": [8290], "c": "\u2062" }, - "itilde;": { "p": [297], "c": "\u0129" }, - "iukcy;": { "p": [1110], "c": "\u0456" }, - "iuml": { "p": [239], "c": "\u00EF" }, - "iuml;": { "p": [239], "c": "\u00EF" }, - "jcirc;": { "p": [309], "c": "\u0135" }, - "jcy;": { "p": [1081], "c": "\u0439" }, - "jfr;": { "p": [120103], "c": "\uD835\uDD27" }, - "jmath;": { "p": [567], "c": "\u0237" }, - "jopf;": { "p": [120155], "c": "\uD835\uDD5B" }, - "jscr;": { "p": [119999], "c": "\uD835\uDCBF" }, - "jsercy;": { "p": [1112], "c": "\u0458" }, - "jukcy;": { "p": [1108], "c": "\u0454" }, - "kappa;": { "p": [954], "c": "\u03BA" }, - "kappav;": { "p": [1008], "c": "\u03F0" }, - "kcedil;": { "p": [311], "c": "\u0137" }, - "kcy;": { "p": [1082], "c": "\u043A" }, - "kfr;": { "p": [120104], "c": "\uD835\uDD28" }, - "kgreen;": { "p": [312], "c": "\u0138" }, - "khcy;": { "p": [1093], "c": "\u0445" }, - "kjcy;": { "p": [1116], "c": "\u045C" }, - "kopf;": { "p": [120156], "c": "\uD835\uDD5C" }, - "kscr;": { "p": [120000], "c": "\uD835\uDCC0" }, - "lAarr;": { "p": [8666], "c": "\u21DA" }, - "lArr;": { "p": [8656], "c": "\u21D0" }, - "lAtail;": { "p": [10523], "c": "\u291B" }, - "lBarr;": { "p": [10510], "c": "\u290E" }, - "lE;": { "p": [8806], "c": "\u2266" }, - "lEg;": { "p": [10891], "c": "\u2A8B" }, - "lHar;": { "p": [10594], "c": "\u2962" }, - "lacute;": { "p": [314], "c": "\u013A" }, - "laemptyv;": { "p": [10676], "c": "\u29B4" }, - "lagran;": { "p": [8466], "c": "\u2112" }, - "lambda;": { "p": [955], "c": "\u03BB" }, - "lang;": { "p": [10216], "c": "\u27E8" }, - "langd;": { "p": [10641], "c": "\u2991" }, - "langle;": { "p": [10216], "c": "\u27E8" }, - "lap;": { "p": [10885], "c": "\u2A85" }, - "laquo": { "p": [171], "c": "\u00AB" }, - "laquo;": { "p": [171], "c": "\u00AB" }, - "larr;": { "p": [8592], "c": "\u2190" }, - "larrb;": { "p": [8676], "c": "\u21E4" }, - "larrbfs;": { "p": [10527], "c": "\u291F" }, - "larrfs;": { "p": [10525], "c": "\u291D" }, - "larrhk;": { "p": [8617], "c": "\u21A9" }, - "larrlp;": { "p": [8619], "c": "\u21AB" }, - "larrpl;": { "p": [10553], "c": "\u2939" }, - "larrsim;": { "p": [10611], "c": "\u2973" }, - "larrtl;": { "p": [8610], "c": "\u21A2" }, - "lat;": { "p": [10923], "c": "\u2AAB" }, - "latail;": { "p": [10521], "c": "\u2919" }, - "late;": { "p": [10925], "c": "\u2AAD" }, - "lates;": { "p": [10925, 65024], "c": "\u2AAD\uFE00" }, - "lbarr;": { "p": [10508], "c": "\u290C" }, - "lbbrk;": { "p": [10098], "c": "\u2772" }, - "lbrace;": { "p": [123], "c": "\u007B" }, - "lbrack;": { "p": [91], "c": "\u005B" }, - "lbrke;": { "p": [10635], "c": "\u298B" }, - "lbrksld;": { "p": [10639], "c": "\u298F" }, - "lbrkslu;": { "p": [10637], "c": "\u298D" }, - "lcaron;": { "p": [318], "c": "\u013E" }, - "lcedil;": { "p": [316], "c": "\u013C" }, - "lceil;": { "p": [8968], "c": "\u2308" }, - "lcub;": { "p": [123], "c": "\u007B" }, - "lcy;": { "p": [1083], "c": "\u043B" }, - "ldca;": { "p": [10550], "c": "\u2936" }, - "ldquo;": { "p": [8220], "c": "\u201C" }, - "ldquor;": { "p": [8222], "c": "\u201E" }, - "ldrdhar;": { "p": [10599], "c": "\u2967" }, - "ldrushar;": { "p": [10571], "c": "\u294B" }, - "ldsh;": { "p": [8626], "c": "\u21B2" }, - "le;": { "p": [8804], "c": "\u2264" }, - "leftarrow;": { "p": [8592], "c": "\u2190" }, - "leftarrowtail;": { "p": [8610], "c": "\u21A2" }, - "leftharpoondown;": { "p": [8637], "c": "\u21BD" }, - "leftharpoonup;": { "p": [8636], "c": "\u21BC" }, - "leftleftarrows;": { "p": [8647], "c": "\u21C7" }, - "leftrightarrow;": { "p": [8596], "c": "\u2194" }, - "leftrightarrows;": { "p": [8646], "c": "\u21C6" }, - "leftrightharpoons;": { "p": [8651], "c": "\u21CB" }, - "leftrightsquigarrow;": { "p": [8621], "c": "\u21AD" }, - "leftthreetimes;": { "p": [8907], "c": "\u22CB" }, - "leg;": { "p": [8922], "c": "\u22DA" }, - "leq;": { "p": [8804], "c": "\u2264" }, - "leqq;": { "p": [8806], "c": "\u2266" }, - "leqslant;": { "p": [10877], "c": "\u2A7D" }, - "les;": { "p": [10877], "c": "\u2A7D" }, - "lescc;": { "p": [10920], "c": "\u2AA8" }, - "lesdot;": { "p": [10879], "c": "\u2A7F" }, - "lesdoto;": { "p": [10881], "c": "\u2A81" }, - "lesdotor;": { "p": [10883], "c": "\u2A83" }, - "lesg;": { "p": [8922, 65024], "c": "\u22DA\uFE00" }, - "lesges;": { "p": [10899], "c": "\u2A93" }, - "lessapprox;": { "p": [10885], "c": "\u2A85" }, - "lessdot;": { "p": [8918], "c": "\u22D6" }, - "lesseqgtr;": { "p": [8922], "c": "\u22DA" }, - "lesseqqgtr;": { "p": [10891], "c": "\u2A8B" }, - "lessgtr;": { "p": [8822], "c": "\u2276" }, - "lesssim;": { "p": [8818], "c": "\u2272" }, - "lfisht;": { "p": [10620], "c": "\u297C" }, - "lfloor;": { "p": [8970], "c": "\u230A" }, - "lfr;": { "p": [120105], "c": "\uD835\uDD29" }, - "lg;": { "p": [8822], "c": "\u2276" }, - "lgE;": { "p": [10897], "c": "\u2A91" }, - "lhard;": { "p": [8637], "c": "\u21BD" }, - "lharu;": { "p": [8636], "c": "\u21BC" }, - "lharul;": { "p": [10602], "c": "\u296A" }, - "lhblk;": { "p": [9604], "c": "\u2584" }, - "ljcy;": { "p": [1113], "c": "\u0459" }, - "ll;": { "p": [8810], "c": "\u226A" }, - "llarr;": { "p": [8647], "c": "\u21C7" }, - "llcorner;": { "p": [8990], "c": "\u231E" }, - "llhard;": { "p": [10603], "c": "\u296B" }, - "lltri;": { "p": [9722], "c": "\u25FA" }, - "lmidot;": { "p": [320], "c": "\u0140" }, - "lmoust;": { "p": [9136], "c": "\u23B0" }, - "lmoustache;": { "p": [9136], "c": "\u23B0" }, - "lnE;": { "p": [8808], "c": "\u2268" }, - "lnap;": { "p": [10889], "c": "\u2A89" }, - "lnapprox;": { "p": [10889], "c": "\u2A89" }, - "lne;": { "p": [10887], "c": "\u2A87" }, - "lneq;": { "p": [10887], "c": "\u2A87" }, - "lneqq;": { "p": [8808], "c": "\u2268" }, - "lnsim;": { "p": [8934], "c": "\u22E6" }, - "loang;": { "p": [10220], "c": "\u27EC" }, - "loarr;": { "p": [8701], "c": "\u21FD" }, - "lobrk;": { "p": [10214], "c": "\u27E6" }, - "longleftarrow;": { "p": [10229], "c": "\u27F5" }, - "longleftrightarrow;": { "p": [10231], "c": "\u27F7" }, - "longmapsto;": { "p": [10236], "c": "\u27FC" }, - "longrightarrow;": { "p": [10230], "c": "\u27F6" }, - "looparrowleft;": { "p": [8619], "c": "\u21AB" }, - "looparrowright;": { "p": [8620], "c": "\u21AC" }, - "lopar;": { "p": [10629], "c": "\u2985" }, - "lopf;": { "p": [120157], "c": "\uD835\uDD5D" }, - "loplus;": { "p": [10797], "c": "\u2A2D" }, - "lotimes;": { "p": [10804], "c": "\u2A34" }, - "lowast;": { "p": [8727], "c": "\u2217" }, - "lowbar;": { "p": [95], "c": "\u005F" }, - "loz;": { "p": [9674], "c": "\u25CA" }, - "lozenge;": { "p": [9674], "c": "\u25CA" }, - "lozf;": { "p": [10731], "c": "\u29EB" }, - "lpar;": { "p": [40], "c": "\u0028" }, - "lparlt;": { "p": [10643], "c": "\u2993" }, - "lrarr;": { "p": [8646], "c": "\u21C6" }, - "lrcorner;": { "p": [8991], "c": "\u231F" }, - "lrhar;": { "p": [8651], "c": "\u21CB" }, - "lrhard;": { "p": [10605], "c": "\u296D" }, - "lrm;": { "p": [8206], "c": "\u200E" }, - "lrtri;": { "p": [8895], "c": "\u22BF" }, - "lsaquo;": { "p": [8249], "c": "\u2039" }, - "lscr;": { "p": [120001], "c": "\uD835\uDCC1" }, - "lsh;": { "p": [8624], "c": "\u21B0" }, - "lsim;": { "p": [8818], "c": "\u2272" }, - "lsime;": { "p": [10893], "c": "\u2A8D" }, - "lsimg;": { "p": [10895], "c": "\u2A8F" }, - "lsqb;": { "p": [91], "c": "\u005B" }, - "lsquo;": { "p": [8216], "c": "\u2018" }, - "lsquor;": { "p": [8218], "c": "\u201A" }, - "lstrok;": { "p": [322], "c": "\u0142" }, - "lt": { "p": [60], "c": "\u003C" }, - "lt;": { "p": [60], "c": "\u003C" }, - "ltcc;": { "p": [10918], "c": "\u2AA6" }, - "ltcir;": { "p": [10873], "c": "\u2A79" }, - "ltdot;": { "p": [8918], "c": "\u22D6" }, - "lthree;": { "p": [8907], "c": "\u22CB" }, - "ltimes;": { "p": [8905], "c": "\u22C9" }, - "ltlarr;": { "p": [10614], "c": "\u2976" }, - "ltquest;": { "p": [10875], "c": "\u2A7B" }, - "ltrPar;": { "p": [10646], "c": "\u2996" }, - "ltri;": { "p": [9667], "c": "\u25C3" }, - "ltrie;": { "p": [8884], "c": "\u22B4" }, - "ltrif;": { "p": [9666], "c": "\u25C2" }, - "lurdshar;": { "p": [10570], "c": "\u294A" }, - "luruhar;": { "p": [10598], "c": "\u2966" }, - "lvertneqq;": { - "p": [8808, 65024], - "c": "\u2268\uFE00" - }, - "lvnE;": { "p": [8808, 65024], "c": "\u2268\uFE00" }, - "mDDot;": { "p": [8762], "c": "\u223A" }, - "macr": { "p": [175], "c": "\u00AF" }, - "macr;": { "p": [175], "c": "\u00AF" }, - "male;": { "p": [9794], "c": "\u2642" }, - "malt;": { "p": [10016], "c": "\u2720" }, - "maltese;": { "p": [10016], "c": "\u2720" }, - "map;": { "p": [8614], "c": "\u21A6" }, - "mapsto;": { "p": [8614], "c": "\u21A6" }, - "mapstodown;": { "p": [8615], "c": "\u21A7" }, - "mapstoleft;": { "p": [8612], "c": "\u21A4" }, - "mapstoup;": { "p": [8613], "c": "\u21A5" }, - "marker;": { "p": [9646], "c": "\u25AE" }, - "mcomma;": { "p": [10793], "c": "\u2A29" }, - "mcy;": { "p": [1084], "c": "\u043C" }, - "mdash;": { "p": [8212], "c": "\u2014" }, - "measuredangle;": { "p": [8737], "c": "\u2221" }, - "mfr;": { "p": [120106], "c": "\uD835\uDD2A" }, - "mho;": { "p": [8487], "c": "\u2127" }, - "micro": { "p": [181], "c": "\u00B5" }, - "micro;": { "p": [181], "c": "\u00B5" }, - "mid;": { "p": [8739], "c": "\u2223" }, - "midast;": { "p": [42], "c": "\u002A" }, - "midcir;": { "p": [10992], "c": "\u2AF0" }, - "middot": { "p": [183], "c": "\u00B7" }, - "middot;": { "p": [183], "c": "\u00B7" }, - "minus;": { "p": [8722], "c": "\u2212" }, - "minusb;": { "p": [8863], "c": "\u229F" }, - "minusd;": { "p": [8760], "c": "\u2238" }, - "minusdu;": { "p": [10794], "c": "\u2A2A" }, - "mlcp;": { "p": [10971], "c": "\u2ADB" }, - "mldr;": { "p": [8230], "c": "\u2026" }, - "mnplus;": { "p": [8723], "c": "\u2213" }, - "models;": { "p": [8871], "c": "\u22A7" }, - "mopf;": { "p": [120158], "c": "\uD835\uDD5E" }, - "mp;": { "p": [8723], "c": "\u2213" }, - "mscr;": { "p": [120002], "c": "\uD835\uDCC2" }, - "mstpos;": { "p": [8766], "c": "\u223E" }, - "mu;": { "p": [956], "c": "\u03BC" }, - "multimap;": { "p": [8888], "c": "\u22B8" }, - "mumap;": { "p": [8888], "c": "\u22B8" }, - "nGg;": { "p": [8921, 824], "c": "\u22D9\u0338" }, - "nGt;": { "p": [8811, 8402], "c": "\u226B\u20D2" }, - "nGtv;": { "p": [8811, 824], "c": "\u226B\u0338" }, - "nLeftarrow;": { "p": [8653], "c": "\u21CD" }, - "nLeftrightarrow;": { "p": [8654], "c": "\u21CE" }, - "nLl;": { "p": [8920, 824], "c": "\u22D8\u0338" }, - "nLt;": { "p": [8810, 8402], "c": "\u226A\u20D2" }, - "nLtv;": { "p": [8810, 824], "c": "\u226A\u0338" }, - "nRightarrow;": { "p": [8655], "c": "\u21CF" }, - "nVDash;": { "p": [8879], "c": "\u22AF" }, - "nVdash;": { "p": [8878], "c": "\u22AE" }, - "nabla;": { "p": [8711], "c": "\u2207" }, - "nacute;": { "p": [324], "c": "\u0144" }, - "nang;": { "p": [8736, 8402], "c": "\u2220\u20D2" }, - "nap;": { "p": [8777], "c": "\u2249" }, - "napE;": { "p": [10864, 824], "c": "\u2A70\u0338" }, - "napid;": { "p": [8779, 824], "c": "\u224B\u0338" }, - "napos;": { "p": [329], "c": "\u0149" }, - "napprox;": { "p": [8777], "c": "\u2249" }, - "natur;": { "p": [9838], "c": "\u266E" }, - "natural;": { "p": [9838], "c": "\u266E" }, - "naturals;": { "p": [8469], "c": "\u2115" }, - "nbsp": { "p": [160], "c": "\u00A0" }, - "nbsp;": { "p": [160], "c": "\u00A0" }, - "nbump;": { "p": [8782, 824], "c": "\u224E\u0338" }, - "nbumpe;": { "p": [8783, 824], "c": "\u224F\u0338" }, - "ncap;": { "p": [10819], "c": "\u2A43" }, - "ncaron;": { "p": [328], "c": "\u0148" }, - "ncedil;": { "p": [326], "c": "\u0146" }, - "ncong;": { "p": [8775], "c": "\u2247" }, - "ncongdot;": { "p": [10861, 824], "c": "\u2A6D\u0338" }, - "ncup;": { "p": [10818], "c": "\u2A42" }, - "ncy;": { "p": [1085], "c": "\u043D" }, - "ndash;": { "p": [8211], "c": "\u2013" }, - "ne;": { "p": [8800], "c": "\u2260" }, - "neArr;": { "p": [8663], "c": "\u21D7" }, - "nearhk;": { "p": [10532], "c": "\u2924" }, - "nearr;": { "p": [8599], "c": "\u2197" }, - "nearrow;": { "p": [8599], "c": "\u2197" }, - "nedot;": { "p": [8784, 824], "c": "\u2250\u0338" }, - "nequiv;": { "p": [8802], "c": "\u2262" }, - "nesear;": { "p": [10536], "c": "\u2928" }, - "nesim;": { "p": [8770, 824], "c": "\u2242\u0338" }, - "nexist;": { "p": [8708], "c": "\u2204" }, - "nexists;": { "p": [8708], "c": "\u2204" }, - "nfr;": { "p": [120107], "c": "\uD835\uDD2B" }, - "ngE;": { "p": [8807, 824], "c": "\u2267\u0338" }, - "nge;": { "p": [8817], "c": "\u2271" }, - "ngeq;": { "p": [8817], "c": "\u2271" }, - "ngeqq;": { "p": [8807, 824], "c": "\u2267\u0338" }, - "ngeqslant;": { "p": [10878, 824], "c": "\u2A7E\u0338" }, - "nges;": { "p": [10878, 824], "c": "\u2A7E\u0338" }, - "ngsim;": { "p": [8821], "c": "\u2275" }, - "ngt;": { "p": [8815], "c": "\u226F" }, - "ngtr;": { "p": [8815], "c": "\u226F" }, - "nhArr;": { "p": [8654], "c": "\u21CE" }, - "nharr;": { "p": [8622], "c": "\u21AE" }, - "nhpar;": { "p": [10994], "c": "\u2AF2" }, - "ni;": { "p": [8715], "c": "\u220B" }, - "nis;": { "p": [8956], "c": "\u22FC" }, - "nisd;": { "p": [8954], "c": "\u22FA" }, - "niv;": { "p": [8715], "c": "\u220B" }, - "njcy;": { "p": [1114], "c": "\u045A" }, - "nlArr;": { "p": [8653], "c": "\u21CD" }, - "nlE;": { "p": [8806, 824], "c": "\u2266\u0338" }, - "nlarr;": { "p": [8602], "c": "\u219A" }, - "nldr;": { "p": [8229], "c": "\u2025" }, - "nle;": { "p": [8816], "c": "\u2270" }, - "nleftarrow;": { "p": [8602], "c": "\u219A" }, - "nleftrightarrow;": { "p": [8622], "c": "\u21AE" }, - "nleq;": { "p": [8816], "c": "\u2270" }, - "nleqq;": { "p": [8806, 824], "c": "\u2266\u0338" }, - "nleqslant;": { "p": [10877, 824], "c": "\u2A7D\u0338" }, - "nles;": { "p": [10877, 824], "c": "\u2A7D\u0338" }, - "nless;": { "p": [8814], "c": "\u226E" }, - "nlsim;": { "p": [8820], "c": "\u2274" }, - "nlt;": { "p": [8814], "c": "\u226E" }, - "nltri;": { "p": [8938], "c": "\u22EA" }, - "nltrie;": { "p": [8940], "c": "\u22EC" }, - "nmid;": { "p": [8740], "c": "\u2224" }, - "nopf;": { "p": [120159], "c": "\uD835\uDD5F" }, - "not": { "p": [172], "c": "\u00AC" }, - "not;": { "p": [172], "c": "\u00AC" }, - "notin;": { "p": [8713], "c": "\u2209" }, - "notinE;": { "p": [8953, 824], "c": "\u22F9\u0338" }, - "notindot;": { "p": [8949, 824], "c": "\u22F5\u0338" }, - "notinva;": { "p": [8713], "c": "\u2209" }, - "notinvb;": { "p": [8951], "c": "\u22F7" }, - "notinvc;": { "p": [8950], "c": "\u22F6" }, - "notni;": { "p": [8716], "c": "\u220C" }, - "notniva;": { "p": [8716], "c": "\u220C" }, - "notnivb;": { "p": [8958], "c": "\u22FE" }, - "notnivc;": { "p": [8957], "c": "\u22FD" }, - "npar;": { "p": [8742], "c": "\u2226" }, - "nparallel;": { "p": [8742], "c": "\u2226" }, - "nparsl;": { "p": [11005, 8421], "c": "\u2AFD\u20E5" }, - "npart;": { "p": [8706, 824], "c": "\u2202\u0338" }, - "npolint;": { "p": [10772], "c": "\u2A14" }, - "npr;": { "p": [8832], "c": "\u2280" }, - "nprcue;": { "p": [8928], "c": "\u22E0" }, - "npre;": { "p": [10927, 824], "c": "\u2AAF\u0338" }, - "nprec;": { "p": [8832], "c": "\u2280" }, - "npreceq;": { "p": [10927, 824], "c": "\u2AAF\u0338" }, - "nrArr;": { "p": [8655], "c": "\u21CF" }, - "nrarr;": { "p": [8603], "c": "\u219B" }, - "nrarrc;": { "p": [10547, 824], "c": "\u2933\u0338" }, - "nrarrw;": { "p": [8605, 824], "c": "\u219D\u0338" }, - "nrightarrow;": { "p": [8603], "c": "\u219B" }, - "nrtri;": { "p": [8939], "c": "\u22EB" }, - "nrtrie;": { "p": [8941], "c": "\u22ED" }, - "nsc;": { "p": [8833], "c": "\u2281" }, - "nsccue;": { "p": [8929], "c": "\u22E1" }, - "nsce;": { "p": [10928, 824], "c": "\u2AB0\u0338" }, - "nscr;": { "p": [120003], "c": "\uD835\uDCC3" }, - "nshortmid;": { "p": [8740], "c": "\u2224" }, - "nshortparallel;": { "p": [8742], "c": "\u2226" }, - "nsim;": { "p": [8769], "c": "\u2241" }, - "nsime;": { "p": [8772], "c": "\u2244" }, - "nsimeq;": { "p": [8772], "c": "\u2244" }, - "nsmid;": { "p": [8740], "c": "\u2224" }, - "nspar;": { "p": [8742], "c": "\u2226" }, - "nsqsube;": { "p": [8930], "c": "\u22E2" }, - "nsqsupe;": { "p": [8931], "c": "\u22E3" }, - "nsub;": { "p": [8836], "c": "\u2284" }, - "nsubE;": { "p": [10949, 824], "c": "\u2AC5\u0338" }, - "nsube;": { "p": [8840], "c": "\u2288" }, - "nsubset;": { "p": [8834, 8402], "c": "\u2282\u20D2" }, - "nsubseteq;": { "p": [8840], "c": "\u2288" }, - "nsubseteqq;": { - "p": [10949, 824], - "c": "\u2AC5\u0338" - }, - "nsucc;": { "p": [8833], "c": "\u2281" }, - "nsucceq;": { "p": [10928, 824], "c": "\u2AB0\u0338" }, - "nsup;": { "p": [8837], "c": "\u2285" }, - "nsupE;": { "p": [10950, 824], "c": "\u2AC6\u0338" }, - "nsupe;": { "p": [8841], "c": "\u2289" }, - "nsupset;": { "p": [8835, 8402], "c": "\u2283\u20D2" }, - "nsupseteq;": { "p": [8841], "c": "\u2289" }, - "nsupseteqq;": { - "p": [10950, 824], - "c": "\u2AC6\u0338" - }, - "ntgl;": { "p": [8825], "c": "\u2279" }, - "ntilde": { "p": [241], "c": "\u00F1" }, - "ntilde;": { "p": [241], "c": "\u00F1" }, - "ntlg;": { "p": [8824], "c": "\u2278" }, - "ntriangleleft;": { "p": [8938], "c": "\u22EA" }, - "ntrianglelefteq;": { "p": [8940], "c": "\u22EC" }, - "ntriangleright;": { "p": [8939], "c": "\u22EB" }, - "ntrianglerighteq;": { "p": [8941], "c": "\u22ED" }, - "nu;": { "p": [957], "c": "\u03BD" }, - "num;": { "p": [35], "c": "\u0023" }, - "numero;": { "p": [8470], "c": "\u2116" }, - "numsp;": { "p": [8199], "c": "\u2007" }, - "nvDash;": { "p": [8877], "c": "\u22AD" }, - "nvHarr;": { "p": [10500], "c": "\u2904" }, - "nvap;": { "p": [8781, 8402], "c": "\u224D\u20D2" }, - "nvdash;": { "p": [8876], "c": "\u22AC" }, - "nvge;": { "p": [8805, 8402], "c": "\u2265\u20D2" }, - "nvgt;": { "p": [62, 8402], "c": "\u003E\u20D2" }, - "nvinfin;": { "p": [10718], "c": "\u29DE" }, - "nvlArr;": { "p": [10498], "c": "\u2902" }, - "nvle;": { "p": [8804, 8402], "c": "\u2264\u20D2" }, - "nvlt;": { "p": [60, 8402], "c": "\u003C\u20D2" }, - "nvltrie;": { "p": [8884, 8402], "c": "\u22B4\u20D2" }, - "nvrArr;": { "p": [10499], "c": "\u2903" }, - "nvrtrie;": { "p": [8885, 8402], "c": "\u22B5\u20D2" }, - "nvsim;": { "p": [8764, 8402], "c": "\u223C\u20D2" }, - "nwArr;": { "p": [8662], "c": "\u21D6" }, - "nwarhk;": { "p": [10531], "c": "\u2923" }, - "nwarr;": { "p": [8598], "c": "\u2196" }, - "nwarrow;": { "p": [8598], "c": "\u2196" }, - "nwnear;": { "p": [10535], "c": "\u2927" }, - "oS;": { "p": [9416], "c": "\u24C8" }, - "oacute": { "p": [243], "c": "\u00F3" }, - "oacute;": { "p": [243], "c": "\u00F3" }, - "oast;": { "p": [8859], "c": "\u229B" }, - "ocir;": { "p": [8858], "c": "\u229A" }, - "ocirc": { "p": [244], "c": "\u00F4" }, - "ocirc;": { "p": [244], "c": "\u00F4" }, - "ocy;": { "p": [1086], "c": "\u043E" }, - "odash;": { "p": [8861], "c": "\u229D" }, - "odblac;": { "p": [337], "c": "\u0151" }, - "odiv;": { "p": [10808], "c": "\u2A38" }, - "odot;": { "p": [8857], "c": "\u2299" }, - "odsold;": { "p": [10684], "c": "\u29BC" }, - "oelig;": { "p": [339], "c": "\u0153" }, - "ofcir;": { "p": [10687], "c": "\u29BF" }, - "ofr;": { "p": [120108], "c": "\uD835\uDD2C" }, - "ogon;": { "p": [731], "c": "\u02DB" }, - "ograve": { "p": [242], "c": "\u00F2" }, - "ograve;": { "p": [242], "c": "\u00F2" }, - "ogt;": { "p": [10689], "c": "\u29C1" }, - "ohbar;": { "p": [10677], "c": "\u29B5" }, - "ohm;": { "p": [937], "c": "\u03A9" }, - "oint;": { "p": [8750], "c": "\u222E" }, - "olarr;": { "p": [8634], "c": "\u21BA" }, - "olcir;": { "p": [10686], "c": "\u29BE" }, - "olcross;": { "p": [10683], "c": "\u29BB" }, - "oline;": { "p": [8254], "c": "\u203E" }, - "olt;": { "p": [10688], "c": "\u29C0" }, - "omacr;": { "p": [333], "c": "\u014D" }, - "omega;": { "p": [969], "c": "\u03C9" }, - "omicron;": { "p": [959], "c": "\u03BF" }, - "omid;": { "p": [10678], "c": "\u29B6" }, - "ominus;": { "p": [8854], "c": "\u2296" }, - "oopf;": { "p": [120160], "c": "\uD835\uDD60" }, - "opar;": { "p": [10679], "c": "\u29B7" }, - "operp;": { "p": [10681], "c": "\u29B9" }, - "oplus;": { "p": [8853], "c": "\u2295" }, - "or;": { "p": [8744], "c": "\u2228" }, - "orarr;": { "p": [8635], "c": "\u21BB" }, - "ord;": { "p": [10845], "c": "\u2A5D" }, - "order;": { "p": [8500], "c": "\u2134" }, - "orderof;": { "p": [8500], "c": "\u2134" }, - "ordf": { "p": [170], "c": "\u00AA" }, - "ordf;": { "p": [170], "c": "\u00AA" }, - "ordm": { "p": [186], "c": "\u00BA" }, - "ordm;": { "p": [186], "c": "\u00BA" }, - "origof;": { "p": [8886], "c": "\u22B6" }, - "oror;": { "p": [10838], "c": "\u2A56" }, - "orslope;": { "p": [10839], "c": "\u2A57" }, - "orv;": { "p": [10843], "c": "\u2A5B" }, - "oscr;": { "p": [8500], "c": "\u2134" }, - "oslash": { "p": [248], "c": "\u00F8" }, - "oslash;": { "p": [248], "c": "\u00F8" }, - "osol;": { "p": [8856], "c": "\u2298" }, - "otilde": { "p": [245], "c": "\u00F5" }, - "otilde;": { "p": [245], "c": "\u00F5" }, - "otimes;": { "p": [8855], "c": "\u2297" }, - "otimesas;": { "p": [10806], "c": "\u2A36" }, - "ouml": { "p": [246], "c": "\u00F6" }, - "ouml;": { "p": [246], "c": "\u00F6" }, - "ovbar;": { "p": [9021], "c": "\u233D" }, - "par;": { "p": [8741], "c": "\u2225" }, - "para": { "p": [182], "c": "\u00B6" }, - "para;": { "p": [182], "c": "\u00B6" }, - "parallel;": { "p": [8741], "c": "\u2225" }, - "parsim;": { "p": [10995], "c": "\u2AF3" }, - "parsl;": { "p": [11005], "c": "\u2AFD" }, - "part;": { "p": [8706], "c": "\u2202" }, - "pcy;": { "p": [1087], "c": "\u043F" }, - "percnt;": { "p": [37], "c": "\u0025" }, - "period;": { "p": [46], "c": "\u002E" }, - "permil;": { "p": [8240], "c": "\u2030" }, - "perp;": { "p": [8869], "c": "\u22A5" }, - "pertenk;": { "p": [8241], "c": "\u2031" }, - "pfr;": { "p": [120109], "c": "\uD835\uDD2D" }, - "phi;": { "p": [966], "c": "\u03C6" }, - "phiv;": { "p": [981], "c": "\u03D5" }, - "phmmat;": { "p": [8499], "c": "\u2133" }, - "phone;": { "p": [9742], "c": "\u260E" }, - "pi;": { "p": [960], "c": "\u03C0" }, - "pitchfork;": { "p": [8916], "c": "\u22D4" }, - "piv;": { "p": [982], "c": "\u03D6" }, - "planck;": { "p": [8463], "c": "\u210F" }, - "planckh;": { "p": [8462], "c": "\u210E" }, - "plankv;": { "p": [8463], "c": "\u210F" }, - "plus;": { "p": [43], "c": "\u002B" }, - "plusacir;": { "p": [10787], "c": "\u2A23" }, - "plusb;": { "p": [8862], "c": "\u229E" }, - "pluscir;": { "p": [10786], "c": "\u2A22" }, - "plusdo;": { "p": [8724], "c": "\u2214" }, - "plusdu;": { "p": [10789], "c": "\u2A25" }, - "pluse;": { "p": [10866], "c": "\u2A72" }, - "plusmn": { "p": [177], "c": "\u00B1" }, - "plusmn;": { "p": [177], "c": "\u00B1" }, - "plussim;": { "p": [10790], "c": "\u2A26" }, - "plustwo;": { "p": [10791], "c": "\u2A27" }, - "pm;": { "p": [177], "c": "\u00B1" }, - "pointint;": { "p": [10773], "c": "\u2A15" }, - "popf;": { "p": [120161], "c": "\uD835\uDD61" }, - "pound": { "p": [163], "c": "\u00A3" }, - "pound;": { "p": [163], "c": "\u00A3" }, - "pr;": { "p": [8826], "c": "\u227A" }, - "prE;": { "p": [10931], "c": "\u2AB3" }, - "prap;": { "p": [10935], "c": "\u2AB7" }, - "prcue;": { "p": [8828], "c": "\u227C" }, - "pre;": { "p": [10927], "c": "\u2AAF" }, - "prec;": { "p": [8826], "c": "\u227A" }, - "precapprox;": { "p": [10935], "c": "\u2AB7" }, - "preccurlyeq;": { "p": [8828], "c": "\u227C" }, - "preceq;": { "p": [10927], "c": "\u2AAF" }, - "precnapprox;": { "p": [10937], "c": "\u2AB9" }, - "precneqq;": { "p": [10933], "c": "\u2AB5" }, - "precnsim;": { "p": [8936], "c": "\u22E8" }, - "precsim;": { "p": [8830], "c": "\u227E" }, - "prime;": { "p": [8242], "c": "\u2032" }, - "primes;": { "p": [8473], "c": "\u2119" }, - "prnE;": { "p": [10933], "c": "\u2AB5" }, - "prnap;": { "p": [10937], "c": "\u2AB9" }, - "prnsim;": { "p": [8936], "c": "\u22E8" }, - "prod;": { "p": [8719], "c": "\u220F" }, - "profalar;": { "p": [9006], "c": "\u232E" }, - "profline;": { "p": [8978], "c": "\u2312" }, - "profsurf;": { "p": [8979], "c": "\u2313" }, - "prop;": { "p": [8733], "c": "\u221D" }, - "propto;": { "p": [8733], "c": "\u221D" }, - "prsim;": { "p": [8830], "c": "\u227E" }, - "prurel;": { "p": [8880], "c": "\u22B0" }, - "pscr;": { "p": [120005], "c": "\uD835\uDCC5" }, - "psi;": { "p": [968], "c": "\u03C8" }, - "puncsp;": { "p": [8200], "c": "\u2008" }, - "qfr;": { "p": [120110], "c": "\uD835\uDD2E" }, - "qint;": { "p": [10764], "c": "\u2A0C" }, - "qopf;": { "p": [120162], "c": "\uD835\uDD62" }, - "qprime;": { "p": [8279], "c": "\u2057" }, - "qscr;": { "p": [120006], "c": "\uD835\uDCC6" }, - "quaternions;": { "p": [8461], "c": "\u210D" }, - "quatint;": { "p": [10774], "c": "\u2A16" }, - "quest;": { "p": [63], "c": "\u003F" }, - "questeq;": { "p": [8799], "c": "\u225F" }, - "quot": { "p": [34], "c": "\u0022" }, - "quot;": { "p": [34], "c": "\u0022" }, - "rAarr;": { "p": [8667], "c": "\u21DB" }, - "rArr;": { "p": [8658], "c": "\u21D2" }, - "rAtail;": { "p": [10524], "c": "\u291C" }, - "rBarr;": { "p": [10511], "c": "\u290F" }, - "rHar;": { "p": [10596], "c": "\u2964" }, - "race;": { "p": [8765, 817], "c": "\u223D\u0331" }, - "racute;": { "p": [341], "c": "\u0155" }, - "radic;": { "p": [8730], "c": "\u221A" }, - "raemptyv;": { "p": [10675], "c": "\u29B3" }, - "rang;": { "p": [10217], "c": "\u27E9" }, - "rangd;": { "p": [10642], "c": "\u2992" }, - "range;": { "p": [10661], "c": "\u29A5" }, - "rangle;": { "p": [10217], "c": "\u27E9" }, - "raquo": { "p": [187], "c": "\u00BB" }, - "raquo;": { "p": [187], "c": "\u00BB" }, - "rarr;": { "p": [8594], "c": "\u2192" }, - "rarrap;": { "p": [10613], "c": "\u2975" }, - "rarrb;": { "p": [8677], "c": "\u21E5" }, - "rarrbfs;": { "p": [10528], "c": "\u2920" }, - "rarrc;": { "p": [10547], "c": "\u2933" }, - "rarrfs;": { "p": [10526], "c": "\u291E" }, - "rarrhk;": { "p": [8618], "c": "\u21AA" }, - "rarrlp;": { "p": [8620], "c": "\u21AC" }, - "rarrpl;": { "p": [10565], "c": "\u2945" }, - "rarrsim;": { "p": [10612], "c": "\u2974" }, - "rarrtl;": { "p": [8611], "c": "\u21A3" }, - "rarrw;": { "p": [8605], "c": "\u219D" }, - "ratail;": { "p": [10522], "c": "\u291A" }, - "ratio;": { "p": [8758], "c": "\u2236" }, - "rationals;": { "p": [8474], "c": "\u211A" }, - "rbarr;": { "p": [10509], "c": "\u290D" }, - "rbbrk;": { "p": [10099], "c": "\u2773" }, - "rbrace;": { "p": [125], "c": "\u007D" }, - "rbrack;": { "p": [93], "c": "\u005D" }, - "rbrke;": { "p": [10636], "c": "\u298C" }, - "rbrksld;": { "p": [10638], "c": "\u298E" }, - "rbrkslu;": { "p": [10640], "c": "\u2990" }, - "rcaron;": { "p": [345], "c": "\u0159" }, - "rcedil;": { "p": [343], "c": "\u0157" }, - "rceil;": { "p": [8969], "c": "\u2309" }, - "rcub;": { "p": [125], "c": "\u007D" }, - "rcy;": { "p": [1088], "c": "\u0440" }, - "rdca;": { "p": [10551], "c": "\u2937" }, - "rdldhar;": { "p": [10601], "c": "\u2969" }, - "rdquo;": { "p": [8221], "c": "\u201D" }, - "rdquor;": { "p": [8221], "c": "\u201D" }, - "rdsh;": { "p": [8627], "c": "\u21B3" }, - "real;": { "p": [8476], "c": "\u211C" }, - "realine;": { "p": [8475], "c": "\u211B" }, - "realpart;": { "p": [8476], "c": "\u211C" }, - "reals;": { "p": [8477], "c": "\u211D" }, - "rect;": { "p": [9645], "c": "\u25AD" }, - "reg": { "p": [174], "c": "\u00AE" }, - "reg;": { "p": [174], "c": "\u00AE" }, - "rfisht;": { "p": [10621], "c": "\u297D" }, - "rfloor;": { "p": [8971], "c": "\u230B" }, - "rfr;": { "p": [120111], "c": "\uD835\uDD2F" }, - "rhard;": { "p": [8641], "c": "\u21C1" }, - "rharu;": { "p": [8640], "c": "\u21C0" }, - "rharul;": { "p": [10604], "c": "\u296C" }, - "rho;": { "p": [961], "c": "\u03C1" }, - "rhov;": { "p": [1009], "c": "\u03F1" }, - "rightarrow;": { "p": [8594], "c": "\u2192" }, - "rightarrowtail;": { "p": [8611], "c": "\u21A3" }, - "rightharpoondown;": { "p": [8641], "c": "\u21C1" }, - "rightharpoonup;": { "p": [8640], "c": "\u21C0" }, - "rightleftarrows;": { "p": [8644], "c": "\u21C4" }, - "rightleftharpoons;": { "p": [8652], "c": "\u21CC" }, - "rightrightarrows;": { "p": [8649], "c": "\u21C9" }, - "rightsquigarrow;": { "p": [8605], "c": "\u219D" }, - "rightthreetimes;": { "p": [8908], "c": "\u22CC" }, - "ring;": { "p": [730], "c": "\u02DA" }, - "risingdotseq;": { "p": [8787], "c": "\u2253" }, - "rlarr;": { "p": [8644], "c": "\u21C4" }, - "rlhar;": { "p": [8652], "c": "\u21CC" }, - "rlm;": { "p": [8207], "c": "\u200F" }, - "rmoust;": { "p": [9137], "c": "\u23B1" }, - "rmoustache;": { "p": [9137], "c": "\u23B1" }, - "rnmid;": { "p": [10990], "c": "\u2AEE" }, - "roang;": { "p": [10221], "c": "\u27ED" }, - "roarr;": { "p": [8702], "c": "\u21FE" }, - "robrk;": { "p": [10215], "c": "\u27E7" }, - "ropar;": { "p": [10630], "c": "\u2986" }, - "ropf;": { "p": [120163], "c": "\uD835\uDD63" }, - "roplus;": { "p": [10798], "c": "\u2A2E" }, - "rotimes;": { "p": [10805], "c": "\u2A35" }, - "rpar;": { "p": [41], "c": "\u0029" }, - "rpargt;": { "p": [10644], "c": "\u2994" }, - "rppolint;": { "p": [10770], "c": "\u2A12" }, - "rrarr;": { "p": [8649], "c": "\u21C9" }, - "rsaquo;": { "p": [8250], "c": "\u203A" }, - "rscr;": { "p": [120007], "c": "\uD835\uDCC7" }, - "rsh;": { "p": [8625], "c": "\u21B1" }, - "rsqb;": { "p": [93], "c": "\u005D" }, - "rsquo;": { "p": [8217], "c": "\u2019" }, - "rsquor;": { "p": [8217], "c": "\u2019" }, - "rthree;": { "p": [8908], "c": "\u22CC" }, - "rtimes;": { "p": [8906], "c": "\u22CA" }, - "rtri;": { "p": [9657], "c": "\u25B9" }, - "rtrie;": { "p": [8885], "c": "\u22B5" }, - "rtrif;": { "p": [9656], "c": "\u25B8" }, - "rtriltri;": { "p": [10702], "c": "\u29CE" }, - "ruluhar;": { "p": [10600], "c": "\u2968" }, - "rx;": { "p": [8478], "c": "\u211E" }, - "sacute;": { "p": [347], "c": "\u015B" }, - "sbquo;": { "p": [8218], "c": "\u201A" }, - "sc;": { "p": [8827], "c": "\u227B" }, - "scE;": { "p": [10932], "c": "\u2AB4" }, - "scap;": { "p": [10936], "c": "\u2AB8" }, - "scaron;": { "p": [353], "c": "\u0161" }, - "sccue;": { "p": [8829], "c": "\u227D" }, - "sce;": { "p": [10928], "c": "\u2AB0" }, - "scedil;": { "p": [351], "c": "\u015F" }, - "scirc;": { "p": [349], "c": "\u015D" }, - "scnE;": { "p": [10934], "c": "\u2AB6" }, - "scnap;": { "p": [10938], "c": "\u2ABA" }, - "scnsim;": { "p": [8937], "c": "\u22E9" }, - "scpolint;": { "p": [10771], "c": "\u2A13" }, - "scsim;": { "p": [8831], "c": "\u227F" }, - "scy;": { "p": [1089], "c": "\u0441" }, - "sdot;": { "p": [8901], "c": "\u22C5" }, - "sdotb;": { "p": [8865], "c": "\u22A1" }, - "sdote;": { "p": [10854], "c": "\u2A66" }, - "seArr;": { "p": [8664], "c": "\u21D8" }, - "searhk;": { "p": [10533], "c": "\u2925" }, - "searr;": { "p": [8600], "c": "\u2198" }, - "searrow;": { "p": [8600], "c": "\u2198" }, - "sect": { "p": [167], "c": "\u00A7" }, - "sect;": { "p": [167], "c": "\u00A7" }, - "semi;": { "p": [59], "c": "\u003B" }, - "seswar;": { "p": [10537], "c": "\u2929" }, - "setminus;": { "p": [8726], "c": "\u2216" }, - "setmn;": { "p": [8726], "c": "\u2216" }, - "sext;": { "p": [10038], "c": "\u2736" }, - "sfr;": { "p": [120112], "c": "\uD835\uDD30" }, - "sfrown;": { "p": [8994], "c": "\u2322" }, - "sharp;": { "p": [9839], "c": "\u266F" }, - "shchcy;": { "p": [1097], "c": "\u0449" }, - "shcy;": { "p": [1096], "c": "\u0448" }, - "shortmid;": { "p": [8739], "c": "\u2223" }, - "shortparallel;": { "p": [8741], "c": "\u2225" }, - "shy": { "p": [173], "c": "\u00AD" }, - "shy;": { "p": [173], "c": "\u00AD" }, - "sigma;": { "p": [963], "c": "\u03C3" }, - "sigmaf;": { "p": [962], "c": "\u03C2" }, - "sigmav;": { "p": [962], "c": "\u03C2" }, - "sim;": { "p": [8764], "c": "\u223C" }, - "simdot;": { "p": [10858], "c": "\u2A6A" }, - "sime;": { "p": [8771], "c": "\u2243" }, - "simeq;": { "p": [8771], "c": "\u2243" }, - "simg;": { "p": [10910], "c": "\u2A9E" }, - "simgE;": { "p": [10912], "c": "\u2AA0" }, - "siml;": { "p": [10909], "c": "\u2A9D" }, - "simlE;": { "p": [10911], "c": "\u2A9F" }, - "simne;": { "p": [8774], "c": "\u2246" }, - "simplus;": { "p": [10788], "c": "\u2A24" }, - "simrarr;": { "p": [10610], "c": "\u2972" }, - "slarr;": { "p": [8592], "c": "\u2190" }, - "smallsetminus;": { "p": [8726], "c": "\u2216" }, - "smashp;": { "p": [10803], "c": "\u2A33" }, - "smeparsl;": { "p": [10724], "c": "\u29E4" }, - "smid;": { "p": [8739], "c": "\u2223" }, - "smile;": { "p": [8995], "c": "\u2323" }, - "smt;": { "p": [10922], "c": "\u2AAA" }, - "smte;": { "p": [10924], "c": "\u2AAC" }, - "smtes;": { "p": [10924, 65024], "c": "\u2AAC\uFE00" }, - "softcy;": { "p": [1100], "c": "\u044C" }, - "sol;": { "p": [47], "c": "\u002F" }, - "solb;": { "p": [10692], "c": "\u29C4" }, - "solbar;": { "p": [9023], "c": "\u233F" }, - "sopf;": { "p": [120164], "c": "\uD835\uDD64" }, - "spades;": { "p": [9824], "c": "\u2660" }, - "spadesuit;": { "p": [9824], "c": "\u2660" }, - "spar;": { "p": [8741], "c": "\u2225" }, - "sqcap;": { "p": [8851], "c": "\u2293" }, - "sqcaps;": { "p": [8851, 65024], "c": "\u2293\uFE00" }, - "sqcup;": { "p": [8852], "c": "\u2294" }, - "sqcups;": { "p": [8852, 65024], "c": "\u2294\uFE00" }, - "sqsub;": { "p": [8847], "c": "\u228F" }, - "sqsube;": { "p": [8849], "c": "\u2291" }, - "sqsubset;": { "p": [8847], "c": "\u228F" }, - "sqsubseteq;": { "p": [8849], "c": "\u2291" }, - "sqsup;": { "p": [8848], "c": "\u2290" }, - "sqsupe;": { "p": [8850], "c": "\u2292" }, - "sqsupset;": { "p": [8848], "c": "\u2290" }, - "sqsupseteq;": { "p": [8850], "c": "\u2292" }, - "squ;": { "p": [9633], "c": "\u25A1" }, - "square;": { "p": [9633], "c": "\u25A1" }, - "squarf;": { "p": [9642], "c": "\u25AA" }, - "squf;": { "p": [9642], "c": "\u25AA" }, - "srarr;": { "p": [8594], "c": "\u2192" }, - "sscr;": { "p": [120008], "c": "\uD835\uDCC8" }, - "ssetmn;": { "p": [8726], "c": "\u2216" }, - "ssmile;": { "p": [8995], "c": "\u2323" }, - "sstarf;": { "p": [8902], "c": "\u22C6" }, - "star;": { "p": [9734], "c": "\u2606" }, - "starf;": { "p": [9733], "c": "\u2605" }, - "straightepsilon;": { "p": [1013], "c": "\u03F5" }, - "straightphi;": { "p": [981], "c": "\u03D5" }, - "strns;": { "p": [175], "c": "\u00AF" }, - "sub;": { "p": [8834], "c": "\u2282" }, - "subE;": { "p": [10949], "c": "\u2AC5" }, - "subdot;": { "p": [10941], "c": "\u2ABD" }, - "sube;": { "p": [8838], "c": "\u2286" }, - "subedot;": { "p": [10947], "c": "\u2AC3" }, - "submult;": { "p": [10945], "c": "\u2AC1" }, - "subnE;": { "p": [10955], "c": "\u2ACB" }, - "subne;": { "p": [8842], "c": "\u228A" }, - "subplus;": { "p": [10943], "c": "\u2ABF" }, - "subrarr;": { "p": [10617], "c": "\u2979" }, - "subset;": { "p": [8834], "c": "\u2282" }, - "subseteq;": { "p": [8838], "c": "\u2286" }, - "subseteqq;": { "p": [10949], "c": "\u2AC5" }, - "subsetneq;": { "p": [8842], "c": "\u228A" }, - "subsetneqq;": { "p": [10955], "c": "\u2ACB" }, - "subsim;": { "p": [10951], "c": "\u2AC7" }, - "subsub;": { "p": [10965], "c": "\u2AD5" }, - "subsup;": { "p": [10963], "c": "\u2AD3" }, - "succ;": { "p": [8827], "c": "\u227B" }, - "succapprox;": { "p": [10936], "c": "\u2AB8" }, - "succcurlyeq;": { "p": [8829], "c": "\u227D" }, - "succeq;": { "p": [10928], "c": "\u2AB0" }, - "succnapprox;": { "p": [10938], "c": "\u2ABA" }, - "succneqq;": { "p": [10934], "c": "\u2AB6" }, - "succnsim;": { "p": [8937], "c": "\u22E9" }, - "succsim;": { "p": [8831], "c": "\u227F" }, - "sum;": { "p": [8721], "c": "\u2211" }, - "sung;": { "p": [9834], "c": "\u266A" }, - "sup1": { "p": [185], "c": "\u00B9" }, - "sup1;": { "p": [185], "c": "\u00B9" }, - "sup2": { "p": [178], "c": "\u00B2" }, - "sup2;": { "p": [178], "c": "\u00B2" }, - "sup3": { "p": [179], "c": "\u00B3" }, - "sup3;": { "p": [179], "c": "\u00B3" }, - "sup;": { "p": [8835], "c": "\u2283" }, - "supE;": { "p": [10950], "c": "\u2AC6" }, - "supdot;": { "p": [10942], "c": "\u2ABE" }, - "supdsub;": { "p": [10968], "c": "\u2AD8" }, - "supe;": { "p": [8839], "c": "\u2287" }, - "supedot;": { "p": [10948], "c": "\u2AC4" }, - "suphsol;": { "p": [10185], "c": "\u27C9" }, - "suphsub;": { "p": [10967], "c": "\u2AD7" }, - "suplarr;": { "p": [10619], "c": "\u297B" }, - "supmult;": { "p": [10946], "c": "\u2AC2" }, - "supnE;": { "p": [10956], "c": "\u2ACC" }, - "supne;": { "p": [8843], "c": "\u228B" }, - "supplus;": { "p": [10944], "c": "\u2AC0" }, - "supset;": { "p": [8835], "c": "\u2283" }, - "supseteq;": { "p": [8839], "c": "\u2287" }, - "supseteqq;": { "p": [10950], "c": "\u2AC6" }, - "supsetneq;": { "p": [8843], "c": "\u228B" }, - "supsetneqq;": { "p": [10956], "c": "\u2ACC" }, - "supsim;": { "p": [10952], "c": "\u2AC8" }, - "supsub;": { "p": [10964], "c": "\u2AD4" }, - "supsup;": { "p": [10966], "c": "\u2AD6" }, - "swArr;": { "p": [8665], "c": "\u21D9" }, - "swarhk;": { "p": [10534], "c": "\u2926" }, - "swarr;": { "p": [8601], "c": "\u2199" }, - "swarrow;": { "p": [8601], "c": "\u2199" }, - "swnwar;": { "p": [10538], "c": "\u292A" }, - "szlig": { "p": [223], "c": "\u00DF" }, - "szlig;": { "p": [223], "c": "\u00DF" }, - "target;": { "p": [8982], "c": "\u2316" }, - "tau;": { "p": [964], "c": "\u03C4" }, - "tbrk;": { "p": [9140], "c": "\u23B4" }, - "tcaron;": { "p": [357], "c": "\u0165" }, - "tcedil;": { "p": [355], "c": "\u0163" }, - "tcy;": { "p": [1090], "c": "\u0442" }, - "tdot;": { "p": [8411], "c": "\u20DB" }, - "telrec;": { "p": [8981], "c": "\u2315" }, - "tfr;": { "p": [120113], "c": "\uD835\uDD31" }, - "there4;": { "p": [8756], "c": "\u2234" }, - "therefore;": { "p": [8756], "c": "\u2234" }, - "theta;": { "p": [952], "c": "\u03B8" }, - "thetasym;": { "p": [977], "c": "\u03D1" }, - "thetav;": { "p": [977], "c": "\u03D1" }, - "thickapprox;": { "p": [8776], "c": "\u2248" }, - "thicksim;": { "p": [8764], "c": "\u223C" }, - "thinsp;": { "p": [8201], "c": "\u2009" }, - "thkap;": { "p": [8776], "c": "\u2248" }, - "thksim;": { "p": [8764], "c": "\u223C" }, - "thorn": { "p": [254], "c": "\u00FE" }, - "thorn;": { "p": [254], "c": "\u00FE" }, - "tilde;": { "p": [732], "c": "\u02DC" }, - "times": { "p": [215], "c": "\u00D7" }, - "times;": { "p": [215], "c": "\u00D7" }, - "timesb;": { "p": [8864], "c": "\u22A0" }, - "timesbar;": { "p": [10801], "c": "\u2A31" }, - "timesd;": { "p": [10800], "c": "\u2A30" }, - "tint;": { "p": [8749], "c": "\u222D" }, - "toea;": { "p": [10536], "c": "\u2928" }, - "top;": { "p": [8868], "c": "\u22A4" }, - "topbot;": { "p": [9014], "c": "\u2336" }, - "topcir;": { "p": [10993], "c": "\u2AF1" }, - "topf;": { "p": [120165], "c": "\uD835\uDD65" }, - "topfork;": { "p": [10970], "c": "\u2ADA" }, - "tosa;": { "p": [10537], "c": "\u2929" }, - "tprime;": { "p": [8244], "c": "\u2034" }, - "trade;": { "p": [8482], "c": "\u2122" }, - "triangle;": { "p": [9653], "c": "\u25B5" }, - "triangledown;": { "p": [9663], "c": "\u25BF" }, - "triangleleft;": { "p": [9667], "c": "\u25C3" }, - "trianglelefteq;": { "p": [8884], "c": "\u22B4" }, - "triangleq;": { "p": [8796], "c": "\u225C" }, - "triangleright;": { "p": [9657], "c": "\u25B9" }, - "trianglerighteq;": { "p": [8885], "c": "\u22B5" }, - "tridot;": { "p": [9708], "c": "\u25EC" }, - "trie;": { "p": [8796], "c": "\u225C" }, - "triminus;": { "p": [10810], "c": "\u2A3A" }, - "triplus;": { "p": [10809], "c": "\u2A39" }, - "trisb;": { "p": [10701], "c": "\u29CD" }, - "tritime;": { "p": [10811], "c": "\u2A3B" }, - "trpezium;": { "p": [9186], "c": "\u23E2" }, - "tscr;": { "p": [120009], "c": "\uD835\uDCC9" }, - "tscy;": { "p": [1094], "c": "\u0446" }, - "tshcy;": { "p": [1115], "c": "\u045B" }, - "tstrok;": { "p": [359], "c": "\u0167" }, - "twixt;": { "p": [8812], "c": "\u226C" }, - "twoheadleftarrow;": { "p": [8606], "c": "\u219E" }, - "twoheadrightarrow;": { "p": [8608], "c": "\u21A0" }, - "uArr;": { "p": [8657], "c": "\u21D1" }, - "uHar;": { "p": [10595], "c": "\u2963" }, - "uacute": { "p": [250], "c": "\u00FA" }, - "uacute;": { "p": [250], "c": "\u00FA" }, - "uarr;": { "p": [8593], "c": "\u2191" }, - "ubrcy;": { "p": [1118], "c": "\u045E" }, - "ubreve;": { "p": [365], "c": "\u016D" }, - "ucirc": { "p": [251], "c": "\u00FB" }, - "ucirc;": { "p": [251], "c": "\u00FB" }, - "ucy;": { "p": [1091], "c": "\u0443" }, - "udarr;": { "p": [8645], "c": "\u21C5" }, - "udblac;": { "p": [369], "c": "\u0171" }, - "udhar;": { "p": [10606], "c": "\u296E" }, - "ufisht;": { "p": [10622], "c": "\u297E" }, - "ufr;": { "p": [120114], "c": "\uD835\uDD32" }, - "ugrave": { "p": [249], "c": "\u00F9" }, - "ugrave;": { "p": [249], "c": "\u00F9" }, - "uharl;": { "p": [8639], "c": "\u21BF" }, - "uharr;": { "p": [8638], "c": "\u21BE" }, - "uhblk;": { "p": [9600], "c": "\u2580" }, - "ulcorn;": { "p": [8988], "c": "\u231C" }, - "ulcorner;": { "p": [8988], "c": "\u231C" }, - "ulcrop;": { "p": [8975], "c": "\u230F" }, - "ultri;": { "p": [9720], "c": "\u25F8" }, - "umacr;": { "p": [363], "c": "\u016B" }, - "uml": { "p": [168], "c": "\u00A8" }, - "uml;": { "p": [168], "c": "\u00A8" }, - "uogon;": { "p": [371], "c": "\u0173" }, - "uopf;": { "p": [120166], "c": "\uD835\uDD66" }, - "uparrow;": { "p": [8593], "c": "\u2191" }, - "updownarrow;": { "p": [8597], "c": "\u2195" }, - "upharpoonleft;": { "p": [8639], "c": "\u21BF" }, - "upharpoonright;": { "p": [8638], "c": "\u21BE" }, - "uplus;": { "p": [8846], "c": "\u228E" }, - "upsi;": { "p": [965], "c": "\u03C5" }, - "upsih;": { "p": [978], "c": "\u03D2" }, - "upsilon;": { "p": [965], "c": "\u03C5" }, - "upuparrows;": { "p": [8648], "c": "\u21C8" }, - "urcorn;": { "p": [8989], "c": "\u231D" }, - "urcorner;": { "p": [8989], "c": "\u231D" }, - "urcrop;": { "p": [8974], "c": "\u230E" }, - "uring;": { "p": [367], "c": "\u016F" }, - "urtri;": { "p": [9721], "c": "\u25F9" }, - "uscr;": { "p": [120010], "c": "\uD835\uDCCA" }, - "utdot;": { "p": [8944], "c": "\u22F0" }, - "utilde;": { "p": [361], "c": "\u0169" }, - "utri;": { "p": [9653], "c": "\u25B5" }, - "utrif;": { "p": [9652], "c": "\u25B4" }, - "uuarr;": { "p": [8648], "c": "\u21C8" }, - "uuml": { "p": [252], "c": "\u00FC" }, - "uuml;": { "p": [252], "c": "\u00FC" }, - "uwangle;": { "p": [10663], "c": "\u29A7" }, - "vArr;": { "p": [8661], "c": "\u21D5" }, - "vBar;": { "p": [10984], "c": "\u2AE8" }, - "vBarv;": { "p": [10985], "c": "\u2AE9" }, - "vDash;": { "p": [8872], "c": "\u22A8" }, - "vangrt;": { "p": [10652], "c": "\u299C" }, - "varepsilon;": { "p": [1013], "c": "\u03F5" }, - "varkappa;": { "p": [1008], "c": "\u03F0" }, - "varnothing;": { "p": [8709], "c": "\u2205" }, - "varphi;": { "p": [981], "c": "\u03D5" }, - "varpi;": { "p": [982], "c": "\u03D6" }, - "varpropto;": { "p": [8733], "c": "\u221D" }, - "varr;": { "p": [8597], "c": "\u2195" }, - "varrho;": { "p": [1009], "c": "\u03F1" }, - "varsigma;": { "p": [962], "c": "\u03C2" }, - "varsubsetneq;": { - "p": [8842, 65024], - "c": "\u228A\uFE00" - }, - "varsubsetneqq;": { - "p": [10955, 65024], - "c": "\u2ACB\uFE00" - }, - "varsupsetneq;": { - "p": [8843, 65024], - "c": "\u228B\uFE00" - }, - "varsupsetneqq;": { - "p": [10956, 65024], - "c": "\u2ACC\uFE00" - }, - "vartheta;": { "p": [977], "c": "\u03D1" }, - "vartriangleleft;": { "p": [8882], "c": "\u22B2" }, - "vartriangleright;": { "p": [8883], "c": "\u22B3" }, - "vcy;": { "p": [1074], "c": "\u0432" }, - "vdash;": { "p": [8866], "c": "\u22A2" }, - "vee;": { "p": [8744], "c": "\u2228" }, - "veebar;": { "p": [8891], "c": "\u22BB" }, - "veeeq;": { "p": [8794], "c": "\u225A" }, - "vellip;": { "p": [8942], "c": "\u22EE" }, - "verbar;": { "p": [124], "c": "\u007C" }, - "vert;": { "p": [124], "c": "\u007C" }, - "vfr;": { "p": [120115], "c": "\uD835\uDD33" }, - "vltri;": { "p": [8882], "c": "\u22B2" }, - "vnsub;": { "p": [8834, 8402], "c": "\u2282\u20D2" }, - "vnsup;": { "p": [8835, 8402], "c": "\u2283\u20D2" }, - "vopf;": { "p": [120167], "c": "\uD835\uDD67" }, - "vprop;": { "p": [8733], "c": "\u221D" }, - "vrtri;": { "p": [8883], "c": "\u22B3" }, - "vscr;": { "p": [120011], "c": "\uD835\uDCCB" }, - "vsubnE;": { "p": [10955, 65024], "c": "\u2ACB\uFE00" }, - "vsubne;": { "p": [8842, 65024], "c": "\u228A\uFE00" }, - "vsupnE;": { "p": [10956, 65024], "c": "\u2ACC\uFE00" }, - "vsupne;": { "p": [8843, 65024], "c": "\u228B\uFE00" }, - "vzigzag;": { "p": [10650], "c": "\u299A" }, - "wcirc;": { "p": [373], "c": "\u0175" }, - "wedbar;": { "p": [10847], "c": "\u2A5F" }, - "wedge;": { "p": [8743], "c": "\u2227" }, - "wedgeq;": { "p": [8793], "c": "\u2259" }, - "weierp;": { "p": [8472], "c": "\u2118" }, - "wfr;": { "p": [120116], "c": "\uD835\uDD34" }, - "wopf;": { "p": [120168], "c": "\uD835\uDD68" }, - "wp;": { "p": [8472], "c": "\u2118" }, - "wr;": { "p": [8768], "c": "\u2240" }, - "wreath;": { "p": [8768], "c": "\u2240" }, - "wscr;": { "p": [120012], "c": "\uD835\uDCCC" }, - "xcap;": { "p": [8898], "c": "\u22C2" }, - "xcirc;": { "p": [9711], "c": "\u25EF" }, - "xcup;": { "p": [8899], "c": "\u22C3" }, - "xdtri;": { "p": [9661], "c": "\u25BD" }, - "xfr;": { "p": [120117], "c": "\uD835\uDD35" }, - "xhArr;": { "p": [10234], "c": "\u27FA" }, - "xharr;": { "p": [10231], "c": "\u27F7" }, - "xi;": { "p": [958], "c": "\u03BE" }, - "xlArr;": { "p": [10232], "c": "\u27F8" }, - "xlarr;": { "p": [10229], "c": "\u27F5" }, - "xmap;": { "p": [10236], "c": "\u27FC" }, - "xnis;": { "p": [8955], "c": "\u22FB" }, - "xodot;": { "p": [10752], "c": "\u2A00" }, - "xopf;": { "p": [120169], "c": "\uD835\uDD69" }, - "xoplus;": { "p": [10753], "c": "\u2A01" }, - "xotime;": { "p": [10754], "c": "\u2A02" }, - "xrArr;": { "p": [10233], "c": "\u27F9" }, - "xrarr;": { "p": [10230], "c": "\u27F6" }, - "xscr;": { "p": [120013], "c": "\uD835\uDCCD" }, - "xsqcup;": { "p": [10758], "c": "\u2A06" }, - "xuplus;": { "p": [10756], "c": "\u2A04" }, - "xutri;": { "p": [9651], "c": "\u25B3" }, - "xvee;": { "p": [8897], "c": "\u22C1" }, - "xwedge;": { "p": [8896], "c": "\u22C0" }, - "yacute": { "p": [253], "c": "\u00FD" }, - "yacute;": { "p": [253], "c": "\u00FD" }, - "yacy;": { "p": [1103], "c": "\u044F" }, - "ycirc;": { "p": [375], "c": "\u0177" }, - "ycy;": { "p": [1099], "c": "\u044B" }, - "yen": { "p": [165], "c": "\u00A5" }, - "yen;": { "p": [165], "c": "\u00A5" }, - "yfr;": { "p": [120118], "c": "\uD835\uDD36" }, - "yicy;": { "p": [1111], "c": "\u0457" }, - "yopf;": { "p": [120170], "c": "\uD835\uDD6A" }, - "yscr;": { "p": [120014], "c": "\uD835\uDCCE" }, - "yucy;": { "p": [1102], "c": "\u044E" }, - "yuml": { "p": [255], "c": "\u00FF" }, - "yuml;": { "p": [255], "c": "\u00FF" }, - "zacute;": { "p": [378], "c": "\u017A" }, - "zcaron;": { "p": [382], "c": "\u017E" }, - "zcy;": { "p": [1079], "c": "\u0437" }, - "zdot;": { "p": [380], "c": "\u017C" }, - "zeetrf;": { "p": [8488], "c": "\u2128" }, - "zeta;": { "p": [950], "c": "\u03B6" }, - "zfr;": { "p": [120119], "c": "\uD835\uDD37" }, - "zhcy;": { "p": [1078], "c": "\u0436" }, - "zigrarr;": { "p": [8669], "c": "\u21DD" }, - "zopf;": { "p": [120171], "c": "\uD835\uDD6B" }, - "zscr;": { "p": [120015], "c": "\uD835\uDCCF" }, - "zwj;": { "p": [8205], "c": "\u200D" }, - "zwnj;": { "p": [8204], "c": "\u200C" } -} diff --git a/src/lib/utils/html-entities.ts b/src/lib/utils/html-entities.ts new file mode 100644 index 000000000..1e65c44de --- /dev/null +++ b/src/lib/utils/html-entities.ts @@ -0,0 +1,2330 @@ +// There is a fixed list of named character references which will not be expanded in the future. +// This file is based on https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references +// with some modifications to reduce the file size of the original JSON. + +export const htmlEntities = { + AElig: { p: [198], c: "\u00C6" }, + "AElig;": { p: [198], c: "\u00C6" }, + AMP: { p: [38], c: "\u0026" }, + "AMP;": { p: [38], c: "\u0026" }, + Aacute: { p: [193], c: "\u00C1" }, + "Aacute;": { p: [193], c: "\u00C1" }, + "Abreve;": { p: [258], c: "\u0102" }, + Acirc: { p: [194], c: "\u00C2" }, + "Acirc;": { p: [194], c: "\u00C2" }, + "Acy;": { p: [1040], c: "\u0410" }, + "Afr;": { p: [120068], c: "\uD835\uDD04" }, + Agrave: { p: [192], c: "\u00C0" }, + "Agrave;": { p: [192], c: "\u00C0" }, + "Alpha;": { p: [913], c: "\u0391" }, + "Amacr;": { p: [256], c: "\u0100" }, + "And;": { p: [10835], c: "\u2A53" }, + "Aogon;": { p: [260], c: "\u0104" }, + "Aopf;": { p: [120120], c: "\uD835\uDD38" }, + "ApplyFunction;": { p: [8289], c: "\u2061" }, + Aring: { p: [197], c: "\u00C5" }, + "Aring;": { p: [197], c: "\u00C5" }, + "Ascr;": { p: [119964], c: "\uD835\uDC9C" }, + "Assign;": { p: [8788], c: "\u2254" }, + Atilde: { p: [195], c: "\u00C3" }, + "Atilde;": { p: [195], c: "\u00C3" }, + Auml: { p: [196], c: "\u00C4" }, + "Auml;": { p: [196], c: "\u00C4" }, + "Backslash;": { p: [8726], c: "\u2216" }, + "Barv;": { p: [10983], c: "\u2AE7" }, + "Barwed;": { p: [8966], c: "\u2306" }, + "Bcy;": { p: [1041], c: "\u0411" }, + "Because;": { p: [8757], c: "\u2235" }, + "Bernoullis;": { p: [8492], c: "\u212C" }, + "Beta;": { p: [914], c: "\u0392" }, + "Bfr;": { p: [120069], c: "\uD835\uDD05" }, + "Bopf;": { p: [120121], c: "\uD835\uDD39" }, + "Breve;": { p: [728], c: "\u02D8" }, + "Bscr;": { p: [8492], c: "\u212C" }, + "Bumpeq;": { p: [8782], c: "\u224E" }, + "CHcy;": { p: [1063], c: "\u0427" }, + COPY: { p: [169], c: "\u00A9" }, + "COPY;": { p: [169], c: "\u00A9" }, + "Cacute;": { p: [262], c: "\u0106" }, + "Cap;": { p: [8914], c: "\u22D2" }, + "CapitalDifferentialD;": { p: [8517], c: "\u2145" }, + "Cayleys;": { p: [8493], c: "\u212D" }, + "Ccaron;": { p: [268], c: "\u010C" }, + Ccedil: { p: [199], c: "\u00C7" }, + "Ccedil;": { p: [199], c: "\u00C7" }, + "Ccirc;": { p: [264], c: "\u0108" }, + "Cconint;": { p: [8752], c: "\u2230" }, + "Cdot;": { p: [266], c: "\u010A" }, + "Cedilla;": { p: [184], c: "\u00B8" }, + "CenterDot;": { p: [183], c: "\u00B7" }, + "Cfr;": { p: [8493], c: "\u212D" }, + "Chi;": { p: [935], c: "\u03A7" }, + "CircleDot;": { p: [8857], c: "\u2299" }, + "CircleMinus;": { p: [8854], c: "\u2296" }, + "CirclePlus;": { p: [8853], c: "\u2295" }, + "CircleTimes;": { p: [8855], c: "\u2297" }, + "ClockwiseContourIntegral;": { + p: [8754], + c: "\u2232", + }, + "CloseCurlyDoubleQuote;": { p: [8221], c: "\u201D" }, + "CloseCurlyQuote;": { p: [8217], c: "\u2019" }, + "Colon;": { p: [8759], c: "\u2237" }, + "Colone;": { p: [10868], c: "\u2A74" }, + "Congruent;": { p: [8801], c: "\u2261" }, + "Conint;": { p: [8751], c: "\u222F" }, + "ContourIntegral;": { p: [8750], c: "\u222E" }, + "Copf;": { p: [8450], c: "\u2102" }, + "Coproduct;": { p: [8720], c: "\u2210" }, + "CounterClockwiseContourIntegral;": { + p: [8755], + c: "\u2233", + }, + "Cross;": { p: [10799], c: "\u2A2F" }, + "Cscr;": { p: [119966], c: "\uD835\uDC9E" }, + "Cup;": { p: [8915], c: "\u22D3" }, + "CupCap;": { p: [8781], c: "\u224D" }, + "DD;": { p: [8517], c: "\u2145" }, + "DDotrahd;": { p: [10513], c: "\u2911" }, + "DJcy;": { p: [1026], c: "\u0402" }, + "DScy;": { p: [1029], c: "\u0405" }, + "DZcy;": { p: [1039], c: "\u040F" }, + "Dagger;": { p: [8225], c: "\u2021" }, + "Darr;": { p: [8609], c: "\u21A1" }, + "Dashv;": { p: [10980], c: "\u2AE4" }, + "Dcaron;": { p: [270], c: "\u010E" }, + "Dcy;": { p: [1044], c: "\u0414" }, + "Del;": { p: [8711], c: "\u2207" }, + "Delta;": { p: [916], c: "\u0394" }, + "Dfr;": { p: [120071], c: "\uD835\uDD07" }, + "DiacriticalAcute;": { p: [180], c: "\u00B4" }, + "DiacriticalDot;": { p: [729], c: "\u02D9" }, + "DiacriticalDoubleAcute;": { p: [733], c: "\u02DD" }, + "DiacriticalGrave;": { p: [96], c: "\u0060" }, + "DiacriticalTilde;": { p: [732], c: "\u02DC" }, + "Diamond;": { p: [8900], c: "\u22C4" }, + "DifferentialD;": { p: [8518], c: "\u2146" }, + "Dopf;": { p: [120123], c: "\uD835\uDD3B" }, + "Dot;": { p: [168], c: "\u00A8" }, + "DotDot;": { p: [8412], c: "\u20DC" }, + "DotEqual;": { p: [8784], c: "\u2250" }, + "DoubleContourIntegral;": { p: [8751], c: "\u222F" }, + "DoubleDot;": { p: [168], c: "\u00A8" }, + "DoubleDownArrow;": { p: [8659], c: "\u21D3" }, + "DoubleLeftArrow;": { p: [8656], c: "\u21D0" }, + "DoubleLeftRightArrow;": { p: [8660], c: "\u21D4" }, + "DoubleLeftTee;": { p: [10980], c: "\u2AE4" }, + "DoubleLongLeftArrow;": { p: [10232], c: "\u27F8" }, + "DoubleLongLeftRightArrow;": { + p: [10234], + c: "\u27FA", + }, + "DoubleLongRightArrow;": { p: [10233], c: "\u27F9" }, + "DoubleRightArrow;": { p: [8658], c: "\u21D2" }, + "DoubleRightTee;": { p: [8872], c: "\u22A8" }, + "DoubleUpArrow;": { p: [8657], c: "\u21D1" }, + "DoubleUpDownArrow;": { p: [8661], c: "\u21D5" }, + "DoubleVerticalBar;": { p: [8741], c: "\u2225" }, + "DownArrow;": { p: [8595], c: "\u2193" }, + "DownArrowBar;": { p: [10515], c: "\u2913" }, + "DownArrowUpArrow;": { p: [8693], c: "\u21F5" }, + "DownBreve;": { p: [785], c: "\u0311" }, + "DownLeftRightVector;": { p: [10576], c: "\u2950" }, + "DownLeftTeeVector;": { p: [10590], c: "\u295E" }, + "DownLeftVector;": { p: [8637], c: "\u21BD" }, + "DownLeftVectorBar;": { p: [10582], c: "\u2956" }, + "DownRightTeeVector;": { p: [10591], c: "\u295F" }, + "DownRightVector;": { p: [8641], c: "\u21C1" }, + "DownRightVectorBar;": { p: [10583], c: "\u2957" }, + "DownTee;": { p: [8868], c: "\u22A4" }, + "DownTeeArrow;": { p: [8615], c: "\u21A7" }, + "Downarrow;": { p: [8659], c: "\u21D3" }, + "Dscr;": { p: [119967], c: "\uD835\uDC9F" }, + "Dstrok;": { p: [272], c: "\u0110" }, + "ENG;": { p: [330], c: "\u014A" }, + ETH: { p: [208], c: "\u00D0" }, + "ETH;": { p: [208], c: "\u00D0" }, + Eacute: { p: [201], c: "\u00C9" }, + "Eacute;": { p: [201], c: "\u00C9" }, + "Ecaron;": { p: [282], c: "\u011A" }, + Ecirc: { p: [202], c: "\u00CA" }, + "Ecirc;": { p: [202], c: "\u00CA" }, + "Ecy;": { p: [1069], c: "\u042D" }, + "Edot;": { p: [278], c: "\u0116" }, + "Efr;": { p: [120072], c: "\uD835\uDD08" }, + Egrave: { p: [200], c: "\u00C8" }, + "Egrave;": { p: [200], c: "\u00C8" }, + "Element;": { p: [8712], c: "\u2208" }, + "Emacr;": { p: [274], c: "\u0112" }, + "EmptySmallSquare;": { p: [9723], c: "\u25FB" }, + "EmptyVerySmallSquare;": { p: [9643], c: "\u25AB" }, + "Eogon;": { p: [280], c: "\u0118" }, + "Eopf;": { p: [120124], c: "\uD835\uDD3C" }, + "Epsilon;": { p: [917], c: "\u0395" }, + "Equal;": { p: [10869], c: "\u2A75" }, + "EqualTilde;": { p: [8770], c: "\u2242" }, + "Equilibrium;": { p: [8652], c: "\u21CC" }, + "Escr;": { p: [8496], c: "\u2130" }, + "Esim;": { p: [10867], c: "\u2A73" }, + "Eta;": { p: [919], c: "\u0397" }, + Euml: { p: [203], c: "\u00CB" }, + "Euml;": { p: [203], c: "\u00CB" }, + "Exists;": { p: [8707], c: "\u2203" }, + "ExponentialE;": { p: [8519], c: "\u2147" }, + "Fcy;": { p: [1060], c: "\u0424" }, + "Ffr;": { p: [120073], c: "\uD835\uDD09" }, + "FilledSmallSquare;": { p: [9724], c: "\u25FC" }, + "FilledVerySmallSquare;": { p: [9642], c: "\u25AA" }, + "Fopf;": { p: [120125], c: "\uD835\uDD3D" }, + "ForAll;": { p: [8704], c: "\u2200" }, + "Fouriertrf;": { p: [8497], c: "\u2131" }, + "Fscr;": { p: [8497], c: "\u2131" }, + "GJcy;": { p: [1027], c: "\u0403" }, + GT: { p: [62], c: "\u003E" }, + "GT;": { p: [62], c: "\u003E" }, + "Gamma;": { p: [915], c: "\u0393" }, + "Gammad;": { p: [988], c: "\u03DC" }, + "Gbreve;": { p: [286], c: "\u011E" }, + "Gcedil;": { p: [290], c: "\u0122" }, + "Gcirc;": { p: [284], c: "\u011C" }, + "Gcy;": { p: [1043], c: "\u0413" }, + "Gdot;": { p: [288], c: "\u0120" }, + "Gfr;": { p: [120074], c: "\uD835\uDD0A" }, + "Gg;": { p: [8921], c: "\u22D9" }, + "Gopf;": { p: [120126], c: "\uD835\uDD3E" }, + "GreaterEqual;": { p: [8805], c: "\u2265" }, + "GreaterEqualLess;": { p: [8923], c: "\u22DB" }, + "GreaterFullEqual;": { p: [8807], c: "\u2267" }, + "GreaterGreater;": { p: [10914], c: "\u2AA2" }, + "GreaterLess;": { p: [8823], c: "\u2277" }, + "GreaterSlantEqual;": { p: [10878], c: "\u2A7E" }, + "GreaterTilde;": { p: [8819], c: "\u2273" }, + "Gscr;": { p: [119970], c: "\uD835\uDCA2" }, + "Gt;": { p: [8811], c: "\u226B" }, + "HARDcy;": { p: [1066], c: "\u042A" }, + "Hacek;": { p: [711], c: "\u02C7" }, + "Hat;": { p: [94], c: "\u005E" }, + "Hcirc;": { p: [292], c: "\u0124" }, + "Hfr;": { p: [8460], c: "\u210C" }, + "HilbertSpace;": { p: [8459], c: "\u210B" }, + "Hopf;": { p: [8461], c: "\u210D" }, + "HorizontalLine;": { p: [9472], c: "\u2500" }, + "Hscr;": { p: [8459], c: "\u210B" }, + "Hstrok;": { p: [294], c: "\u0126" }, + "HumpDownHump;": { p: [8782], c: "\u224E" }, + "HumpEqual;": { p: [8783], c: "\u224F" }, + "IEcy;": { p: [1045], c: "\u0415" }, + "IJlig;": { p: [306], c: "\u0132" }, + "IOcy;": { p: [1025], c: "\u0401" }, + Iacute: { p: [205], c: "\u00CD" }, + "Iacute;": { p: [205], c: "\u00CD" }, + Icirc: { p: [206], c: "\u00CE" }, + "Icirc;": { p: [206], c: "\u00CE" }, + "Icy;": { p: [1048], c: "\u0418" }, + "Idot;": { p: [304], c: "\u0130" }, + "Ifr;": { p: [8465], c: "\u2111" }, + Igrave: { p: [204], c: "\u00CC" }, + "Igrave;": { p: [204], c: "\u00CC" }, + "Im;": { p: [8465], c: "\u2111" }, + "Imacr;": { p: [298], c: "\u012A" }, + "ImaginaryI;": { p: [8520], c: "\u2148" }, + "Implies;": { p: [8658], c: "\u21D2" }, + "Int;": { p: [8748], c: "\u222C" }, + "Integral;": { p: [8747], c: "\u222B" }, + "Intersection;": { p: [8898], c: "\u22C2" }, + "InvisibleComma;": { p: [8291], c: "\u2063" }, + "InvisibleTimes;": { p: [8290], c: "\u2062" }, + "Iogon;": { p: [302], c: "\u012E" }, + "Iopf;": { p: [120128], c: "\uD835\uDD40" }, + "Iota;": { p: [921], c: "\u0399" }, + "Iscr;": { p: [8464], c: "\u2110" }, + "Itilde;": { p: [296], c: "\u0128" }, + "Iukcy;": { p: [1030], c: "\u0406" }, + Iuml: { p: [207], c: "\u00CF" }, + "Iuml;": { p: [207], c: "\u00CF" }, + "Jcirc;": { p: [308], c: "\u0134" }, + "Jcy;": { p: [1049], c: "\u0419" }, + "Jfr;": { p: [120077], c: "\uD835\uDD0D" }, + "Jopf;": { p: [120129], c: "\uD835\uDD41" }, + "Jscr;": { p: [119973], c: "\uD835\uDCA5" }, + "Jsercy;": { p: [1032], c: "\u0408" }, + "Jukcy;": { p: [1028], c: "\u0404" }, + "KHcy;": { p: [1061], c: "\u0425" }, + "KJcy;": { p: [1036], c: "\u040C" }, + "Kappa;": { p: [922], c: "\u039A" }, + "Kcedil;": { p: [310], c: "\u0136" }, + "Kcy;": { p: [1050], c: "\u041A" }, + "Kfr;": { p: [120078], c: "\uD835\uDD0E" }, + "Kopf;": { p: [120130], c: "\uD835\uDD42" }, + "Kscr;": { p: [119974], c: "\uD835\uDCA6" }, + "LJcy;": { p: [1033], c: "\u0409" }, + LT: { p: [60], c: "\u003C" }, + "LT;": { p: [60], c: "\u003C" }, + "Lacute;": { p: [313], c: "\u0139" }, + "Lambda;": { p: [923], c: "\u039B" }, + "Lang;": { p: [10218], c: "\u27EA" }, + "Laplacetrf;": { p: [8466], c: "\u2112" }, + "Larr;": { p: [8606], c: "\u219E" }, + "Lcaron;": { p: [317], c: "\u013D" }, + "Lcedil;": { p: [315], c: "\u013B" }, + "Lcy;": { p: [1051], c: "\u041B" }, + "LeftAngleBracket;": { p: [10216], c: "\u27E8" }, + "LeftArrow;": { p: [8592], c: "\u2190" }, + "LeftArrowBar;": { p: [8676], c: "\u21E4" }, + "LeftArrowRightArrow;": { p: [8646], c: "\u21C6" }, + "LeftCeiling;": { p: [8968], c: "\u2308" }, + "LeftDoubleBracket;": { p: [10214], c: "\u27E6" }, + "LeftDownTeeVector;": { p: [10593], c: "\u2961" }, + "LeftDownVector;": { p: [8643], c: "\u21C3" }, + "LeftDownVectorBar;": { p: [10585], c: "\u2959" }, + "LeftFloor;": { p: [8970], c: "\u230A" }, + "LeftRightArrow;": { p: [8596], c: "\u2194" }, + "LeftRightVector;": { p: [10574], c: "\u294E" }, + "LeftTee;": { p: [8867], c: "\u22A3" }, + "LeftTeeArrow;": { p: [8612], c: "\u21A4" }, + "LeftTeeVector;": { p: [10586], c: "\u295A" }, + "LeftTriangle;": { p: [8882], c: "\u22B2" }, + "LeftTriangleBar;": { p: [10703], c: "\u29CF" }, + "LeftTriangleEqual;": { p: [8884], c: "\u22B4" }, + "LeftUpDownVector;": { p: [10577], c: "\u2951" }, + "LeftUpTeeVector;": { p: [10592], c: "\u2960" }, + "LeftUpVector;": { p: [8639], c: "\u21BF" }, + "LeftUpVectorBar;": { p: [10584], c: "\u2958" }, + "LeftVector;": { p: [8636], c: "\u21BC" }, + "LeftVectorBar;": { p: [10578], c: "\u2952" }, + "Leftarrow;": { p: [8656], c: "\u21D0" }, + "Leftrightarrow;": { p: [8660], c: "\u21D4" }, + "LessEqualGreater;": { p: [8922], c: "\u22DA" }, + "LessFullEqual;": { p: [8806], c: "\u2266" }, + "LessGreater;": { p: [8822], c: "\u2276" }, + "LessLess;": { p: [10913], c: "\u2AA1" }, + "LessSlantEqual;": { p: [10877], c: "\u2A7D" }, + "LessTilde;": { p: [8818], c: "\u2272" }, + "Lfr;": { p: [120079], c: "\uD835\uDD0F" }, + "Ll;": { p: [8920], c: "\u22D8" }, + "Lleftarrow;": { p: [8666], c: "\u21DA" }, + "Lmidot;": { p: [319], c: "\u013F" }, + "LongLeftArrow;": { p: [10229], c: "\u27F5" }, + "LongLeftRightArrow;": { p: [10231], c: "\u27F7" }, + "LongRightArrow;": { p: [10230], c: "\u27F6" }, + "Longleftarrow;": { p: [10232], c: "\u27F8" }, + "Longleftrightarrow;": { p: [10234], c: "\u27FA" }, + "Longrightarrow;": { p: [10233], c: "\u27F9" }, + "Lopf;": { p: [120131], c: "\uD835\uDD43" }, + "LowerLeftArrow;": { p: [8601], c: "\u2199" }, + "LowerRightArrow;": { p: [8600], c: "\u2198" }, + "Lscr;": { p: [8466], c: "\u2112" }, + "Lsh;": { p: [8624], c: "\u21B0" }, + "Lstrok;": { p: [321], c: "\u0141" }, + "Lt;": { p: [8810], c: "\u226A" }, + "Map;": { p: [10501], c: "\u2905" }, + "Mcy;": { p: [1052], c: "\u041C" }, + "MediumSpace;": { p: [8287], c: "\u205F" }, + "Mellintrf;": { p: [8499], c: "\u2133" }, + "Mfr;": { p: [120080], c: "\uD835\uDD10" }, + "MinusPlus;": { p: [8723], c: "\u2213" }, + "Mopf;": { p: [120132], c: "\uD835\uDD44" }, + "Mscr;": { p: [8499], c: "\u2133" }, + "Mu;": { p: [924], c: "\u039C" }, + "NJcy;": { p: [1034], c: "\u040A" }, + "Nacute;": { p: [323], c: "\u0143" }, + "Ncaron;": { p: [327], c: "\u0147" }, + "Ncedil;": { p: [325], c: "\u0145" }, + "Ncy;": { p: [1053], c: "\u041D" }, + "NegativeMediumSpace;": { p: [8203], c: "\u200B" }, + "NegativeThickSpace;": { p: [8203], c: "\u200B" }, + "NegativeThinSpace;": { p: [8203], c: "\u200B" }, + "NegativeVeryThinSpace;": { p: [8203], c: "\u200B" }, + "NestedGreaterGreater;": { p: [8811], c: "\u226B" }, + "NestedLessLess;": { p: [8810], c: "\u226A" }, + "NewLine;": { p: [10], c: "\u000A" }, + "Nfr;": { p: [120081], c: "\uD835\uDD11" }, + "NoBreak;": { p: [8288], c: "\u2060" }, + "NonBreakingSpace;": { p: [160], c: "\u00A0" }, + "Nopf;": { p: [8469], c: "\u2115" }, + "Not;": { p: [10988], c: "\u2AEC" }, + "NotCongruent;": { p: [8802], c: "\u2262" }, + "NotCupCap;": { p: [8813], c: "\u226D" }, + "NotDoubleVerticalBar;": { p: [8742], c: "\u2226" }, + "NotElement;": { p: [8713], c: "\u2209" }, + "NotEqual;": { p: [8800], c: "\u2260" }, + "NotEqualTilde;": { + p: [8770, 824], + c: "\u2242\u0338", + }, + "NotExists;": { p: [8708], c: "\u2204" }, + "NotGreater;": { p: [8815], c: "\u226F" }, + "NotGreaterEqual;": { p: [8817], c: "\u2271" }, + "NotGreaterFullEqual;": { + p: [8807, 824], + c: "\u2267\u0338", + }, + "NotGreaterGreater;": { + p: [8811, 824], + c: "\u226B\u0338", + }, + "NotGreaterLess;": { p: [8825], c: "\u2279" }, + "NotGreaterSlantEqual;": { + p: [10878, 824], + c: "\u2A7E\u0338", + }, + "NotGreaterTilde;": { p: [8821], c: "\u2275" }, + "NotHumpDownHump;": { + p: [8782, 824], + c: "\u224E\u0338", + }, + "NotHumpEqual;": { + p: [8783, 824], + c: "\u224F\u0338", + }, + "NotLeftTriangle;": { p: [8938], c: "\u22EA" }, + "NotLeftTriangleBar;": { + p: [10703, 824], + c: "\u29CF\u0338", + }, + "NotLeftTriangleEqual;": { p: [8940], c: "\u22EC" }, + "NotLess;": { p: [8814], c: "\u226E" }, + "NotLessEqual;": { p: [8816], c: "\u2270" }, + "NotLessGreater;": { p: [8824], c: "\u2278" }, + "NotLessLess;": { + p: [8810, 824], + c: "\u226A\u0338", + }, + "NotLessSlantEqual;": { + p: [10877, 824], + c: "\u2A7D\u0338", + }, + "NotLessTilde;": { p: [8820], c: "\u2274" }, + "NotNestedGreaterGreater;": { + p: [10914, 824], + c: "\u2AA2\u0338", + }, + "NotNestedLessLess;": { + p: [10913, 824], + c: "\u2AA1\u0338", + }, + "NotPrecedes;": { p: [8832], c: "\u2280" }, + "NotPrecedesEqual;": { + p: [10927, 824], + c: "\u2AAF\u0338", + }, + "NotPrecedesSlantEqual;": { p: [8928], c: "\u22E0" }, + "NotReverseElement;": { p: [8716], c: "\u220C" }, + "NotRightTriangle;": { p: [8939], c: "\u22EB" }, + "NotRightTriangleBar;": { + p: [10704, 824], + c: "\u29D0\u0338", + }, + "NotRightTriangleEqual;": { p: [8941], c: "\u22ED" }, + "NotSquareSubset;": { + p: [8847, 824], + c: "\u228F\u0338", + }, + "NotSquareSubsetEqual;": { p: [8930], c: "\u22E2" }, + "NotSquareSuperset;": { + p: [8848, 824], + c: "\u2290\u0338", + }, + "NotSquareSupersetEqual;": { + p: [8931], + c: "\u22E3", + }, + "NotSubset;": { p: [8834, 8402], c: "\u2282\u20D2" }, + "NotSubsetEqual;": { p: [8840], c: "\u2288" }, + "NotSucceeds;": { p: [8833], c: "\u2281" }, + "NotSucceedsEqual;": { + p: [10928, 824], + c: "\u2AB0\u0338", + }, + "NotSucceedsSlantEqual;": { p: [8929], c: "\u22E1" }, + "NotSucceedsTilde;": { + p: [8831, 824], + c: "\u227F\u0338", + }, + "NotSuperset;": { + p: [8835, 8402], + c: "\u2283\u20D2", + }, + "NotSupersetEqual;": { p: [8841], c: "\u2289" }, + "NotTilde;": { p: [8769], c: "\u2241" }, + "NotTildeEqual;": { p: [8772], c: "\u2244" }, + "NotTildeFullEqual;": { p: [8775], c: "\u2247" }, + "NotTildeTilde;": { p: [8777], c: "\u2249" }, + "NotVerticalBar;": { p: [8740], c: "\u2224" }, + "Nscr;": { p: [119977], c: "\uD835\uDCA9" }, + Ntilde: { p: [209], c: "\u00D1" }, + "Ntilde;": { p: [209], c: "\u00D1" }, + "Nu;": { p: [925], c: "\u039D" }, + "OElig;": { p: [338], c: "\u0152" }, + Oacute: { p: [211], c: "\u00D3" }, + "Oacute;": { p: [211], c: "\u00D3" }, + Ocirc: { p: [212], c: "\u00D4" }, + "Ocirc;": { p: [212], c: "\u00D4" }, + "Ocy;": { p: [1054], c: "\u041E" }, + "Odblac;": { p: [336], c: "\u0150" }, + "Ofr;": { p: [120082], c: "\uD835\uDD12" }, + Ograve: { p: [210], c: "\u00D2" }, + "Ograve;": { p: [210], c: "\u00D2" }, + "Omacr;": { p: [332], c: "\u014C" }, + "Omega;": { p: [937], c: "\u03A9" }, + "Omicron;": { p: [927], c: "\u039F" }, + "Oopf;": { p: [120134], c: "\uD835\uDD46" }, + "OpenCurlyDoubleQuote;": { p: [8220], c: "\u201C" }, + "OpenCurlyQuote;": { p: [8216], c: "\u2018" }, + "Or;": { p: [10836], c: "\u2A54" }, + "Oscr;": { p: [119978], c: "\uD835\uDCAA" }, + Oslash: { p: [216], c: "\u00D8" }, + "Oslash;": { p: [216], c: "\u00D8" }, + Otilde: { p: [213], c: "\u00D5" }, + "Otilde;": { p: [213], c: "\u00D5" }, + "Otimes;": { p: [10807], c: "\u2A37" }, + Ouml: { p: [214], c: "\u00D6" }, + "Ouml;": { p: [214], c: "\u00D6" }, + "OverBar;": { p: [8254], c: "\u203E" }, + "OverBrace;": { p: [9182], c: "\u23DE" }, + "OverBracket;": { p: [9140], c: "\u23B4" }, + "OverParenthesis;": { p: [9180], c: "\u23DC" }, + "PartialD;": { p: [8706], c: "\u2202" }, + "Pcy;": { p: [1055], c: "\u041F" }, + "Pfr;": { p: [120083], c: "\uD835\uDD13" }, + "Phi;": { p: [934], c: "\u03A6" }, + "Pi;": { p: [928], c: "\u03A0" }, + "PlusMinus;": { p: [177], c: "\u00B1" }, + "Poincareplane;": { p: [8460], c: "\u210C" }, + "Popf;": { p: [8473], c: "\u2119" }, + "Pr;": { p: [10939], c: "\u2ABB" }, + "Precedes;": { p: [8826], c: "\u227A" }, + "PrecedesEqual;": { p: [10927], c: "\u2AAF" }, + "PrecedesSlantEqual;": { p: [8828], c: "\u227C" }, + "PrecedesTilde;": { p: [8830], c: "\u227E" }, + "Prime;": { p: [8243], c: "\u2033" }, + "Product;": { p: [8719], c: "\u220F" }, + "Proportion;": { p: [8759], c: "\u2237" }, + "Proportional;": { p: [8733], c: "\u221D" }, + "Pscr;": { p: [119979], c: "\uD835\uDCAB" }, + "Psi;": { p: [936], c: "\u03A8" }, + QUOT: { p: [34], c: "\u0022" }, + "QUOT;": { p: [34], c: "\u0022" }, + "Qfr;": { p: [120084], c: "\uD835\uDD14" }, + "Qopf;": { p: [8474], c: "\u211A" }, + "Qscr;": { p: [119980], c: "\uD835\uDCAC" }, + "RBarr;": { p: [10512], c: "\u2910" }, + REG: { p: [174], c: "\u00AE" }, + "REG;": { p: [174], c: "\u00AE" }, + "Racute;": { p: [340], c: "\u0154" }, + "Rang;": { p: [10219], c: "\u27EB" }, + "Rarr;": { p: [8608], c: "\u21A0" }, + "Rarrtl;": { p: [10518], c: "\u2916" }, + "Rcaron;": { p: [344], c: "\u0158" }, + "Rcedil;": { p: [342], c: "\u0156" }, + "Rcy;": { p: [1056], c: "\u0420" }, + "Re;": { p: [8476], c: "\u211C" }, + "ReverseElement;": { p: [8715], c: "\u220B" }, + "ReverseEquilibrium;": { p: [8651], c: "\u21CB" }, + "ReverseUpEquilibrium;": { p: [10607], c: "\u296F" }, + "Rfr;": { p: [8476], c: "\u211C" }, + "Rho;": { p: [929], c: "\u03A1" }, + "RightAngleBracket;": { p: [10217], c: "\u27E9" }, + "RightArrow;": { p: [8594], c: "\u2192" }, + "RightArrowBar;": { p: [8677], c: "\u21E5" }, + "RightArrowLeftArrow;": { p: [8644], c: "\u21C4" }, + "RightCeiling;": { p: [8969], c: "\u2309" }, + "RightDoubleBracket;": { p: [10215], c: "\u27E7" }, + "RightDownTeeVector;": { p: [10589], c: "\u295D" }, + "RightDownVector;": { p: [8642], c: "\u21C2" }, + "RightDownVectorBar;": { p: [10581], c: "\u2955" }, + "RightFloor;": { p: [8971], c: "\u230B" }, + "RightTee;": { p: [8866], c: "\u22A2" }, + "RightTeeArrow;": { p: [8614], c: "\u21A6" }, + "RightTeeVector;": { p: [10587], c: "\u295B" }, + "RightTriangle;": { p: [8883], c: "\u22B3" }, + "RightTriangleBar;": { p: [10704], c: "\u29D0" }, + "RightTriangleEqual;": { p: [8885], c: "\u22B5" }, + "RightUpDownVector;": { p: [10575], c: "\u294F" }, + "RightUpTeeVector;": { p: [10588], c: "\u295C" }, + "RightUpVector;": { p: [8638], c: "\u21BE" }, + "RightUpVectorBar;": { p: [10580], c: "\u2954" }, + "RightVector;": { p: [8640], c: "\u21C0" }, + "RightVectorBar;": { p: [10579], c: "\u2953" }, + "Rightarrow;": { p: [8658], c: "\u21D2" }, + "Ropf;": { p: [8477], c: "\u211D" }, + "RoundImplies;": { p: [10608], c: "\u2970" }, + "Rrightarrow;": { p: [8667], c: "\u21DB" }, + "Rscr;": { p: [8475], c: "\u211B" }, + "Rsh;": { p: [8625], c: "\u21B1" }, + "RuleDelayed;": { p: [10740], c: "\u29F4" }, + "SHCHcy;": { p: [1065], c: "\u0429" }, + "SHcy;": { p: [1064], c: "\u0428" }, + "SOFTcy;": { p: [1068], c: "\u042C" }, + "Sacute;": { p: [346], c: "\u015A" }, + "Sc;": { p: [10940], c: "\u2ABC" }, + "Scaron;": { p: [352], c: "\u0160" }, + "Scedil;": { p: [350], c: "\u015E" }, + "Scirc;": { p: [348], c: "\u015C" }, + "Scy;": { p: [1057], c: "\u0421" }, + "Sfr;": { p: [120086], c: "\uD835\uDD16" }, + "ShortDownArrow;": { p: [8595], c: "\u2193" }, + "ShortLeftArrow;": { p: [8592], c: "\u2190" }, + "ShortRightArrow;": { p: [8594], c: "\u2192" }, + "ShortUpArrow;": { p: [8593], c: "\u2191" }, + "Sigma;": { p: [931], c: "\u03A3" }, + "SmallCircle;": { p: [8728], c: "\u2218" }, + "Sopf;": { p: [120138], c: "\uD835\uDD4A" }, + "Sqrt;": { p: [8730], c: "\u221A" }, + "Square;": { p: [9633], c: "\u25A1" }, + "SquareIntersection;": { p: [8851], c: "\u2293" }, + "SquareSubset;": { p: [8847], c: "\u228F" }, + "SquareSubsetEqual;": { p: [8849], c: "\u2291" }, + "SquareSuperset;": { p: [8848], c: "\u2290" }, + "SquareSupersetEqual;": { p: [8850], c: "\u2292" }, + "SquareUnion;": { p: [8852], c: "\u2294" }, + "Sscr;": { p: [119982], c: "\uD835\uDCAE" }, + "Star;": { p: [8902], c: "\u22C6" }, + "Sub;": { p: [8912], c: "\u22D0" }, + "Subset;": { p: [8912], c: "\u22D0" }, + "SubsetEqual;": { p: [8838], c: "\u2286" }, + "Succeeds;": { p: [8827], c: "\u227B" }, + "SucceedsEqual;": { p: [10928], c: "\u2AB0" }, + "SucceedsSlantEqual;": { p: [8829], c: "\u227D" }, + "SucceedsTilde;": { p: [8831], c: "\u227F" }, + "SuchThat;": { p: [8715], c: "\u220B" }, + "Sum;": { p: [8721], c: "\u2211" }, + "Sup;": { p: [8913], c: "\u22D1" }, + "Superset;": { p: [8835], c: "\u2283" }, + "SupersetEqual;": { p: [8839], c: "\u2287" }, + "Supset;": { p: [8913], c: "\u22D1" }, + THORN: { p: [222], c: "\u00DE" }, + "THORN;": { p: [222], c: "\u00DE" }, + "TRADE;": { p: [8482], c: "\u2122" }, + "TSHcy;": { p: [1035], c: "\u040B" }, + "TScy;": { p: [1062], c: "\u0426" }, + "Tab;": { p: [9], c: "\u0009" }, + "Tau;": { p: [932], c: "\u03A4" }, + "Tcaron;": { p: [356], c: "\u0164" }, + "Tcedil;": { p: [354], c: "\u0162" }, + "Tcy;": { p: [1058], c: "\u0422" }, + "Tfr;": { p: [120087], c: "\uD835\uDD17" }, + "Therefore;": { p: [8756], c: "\u2234" }, + "Theta;": { p: [920], c: "\u0398" }, + "ThickSpace;": { + p: [8287, 8202], + c: "\u205F\u200A", + }, + "ThinSpace;": { p: [8201], c: "\u2009" }, + "Tilde;": { p: [8764], c: "\u223C" }, + "TildeEqual;": { p: [8771], c: "\u2243" }, + "TildeFullEqual;": { p: [8773], c: "\u2245" }, + "TildeTilde;": { p: [8776], c: "\u2248" }, + "Topf;": { p: [120139], c: "\uD835\uDD4B" }, + "TripleDot;": { p: [8411], c: "\u20DB" }, + "Tscr;": { p: [119983], c: "\uD835\uDCAF" }, + "Tstrok;": { p: [358], c: "\u0166" }, + Uacute: { p: [218], c: "\u00DA" }, + "Uacute;": { p: [218], c: "\u00DA" }, + "Uarr;": { p: [8607], c: "\u219F" }, + "Uarrocir;": { p: [10569], c: "\u2949" }, + "Ubrcy;": { p: [1038], c: "\u040E" }, + "Ubreve;": { p: [364], c: "\u016C" }, + Ucirc: { p: [219], c: "\u00DB" }, + "Ucirc;": { p: [219], c: "\u00DB" }, + "Ucy;": { p: [1059], c: "\u0423" }, + "Udblac;": { p: [368], c: "\u0170" }, + "Ufr;": { p: [120088], c: "\uD835\uDD18" }, + Ugrave: { p: [217], c: "\u00D9" }, + "Ugrave;": { p: [217], c: "\u00D9" }, + "Umacr;": { p: [362], c: "\u016A" }, + "UnderBar;": { p: [95], c: "\u005F" }, + "UnderBrace;": { p: [9183], c: "\u23DF" }, + "UnderBracket;": { p: [9141], c: "\u23B5" }, + "UnderParenthesis;": { p: [9181], c: "\u23DD" }, + "Union;": { p: [8899], c: "\u22C3" }, + "UnionPlus;": { p: [8846], c: "\u228E" }, + "Uogon;": { p: [370], c: "\u0172" }, + "Uopf;": { p: [120140], c: "\uD835\uDD4C" }, + "UpArrow;": { p: [8593], c: "\u2191" }, + "UpArrowBar;": { p: [10514], c: "\u2912" }, + "UpArrowDownArrow;": { p: [8645], c: "\u21C5" }, + "UpDownArrow;": { p: [8597], c: "\u2195" }, + "UpEquilibrium;": { p: [10606], c: "\u296E" }, + "UpTee;": { p: [8869], c: "\u22A5" }, + "UpTeeArrow;": { p: [8613], c: "\u21A5" }, + "Uparrow;": { p: [8657], c: "\u21D1" }, + "Updownarrow;": { p: [8661], c: "\u21D5" }, + "UpperLeftArrow;": { p: [8598], c: "\u2196" }, + "UpperRightArrow;": { p: [8599], c: "\u2197" }, + "Upsi;": { p: [978], c: "\u03D2" }, + "Upsilon;": { p: [933], c: "\u03A5" }, + "Uring;": { p: [366], c: "\u016E" }, + "Uscr;": { p: [119984], c: "\uD835\uDCB0" }, + "Utilde;": { p: [360], c: "\u0168" }, + Uuml: { p: [220], c: "\u00DC" }, + "Uuml;": { p: [220], c: "\u00DC" }, + "VDash;": { p: [8875], c: "\u22AB" }, + "Vbar;": { p: [10987], c: "\u2AEB" }, + "Vcy;": { p: [1042], c: "\u0412" }, + "Vdash;": { p: [8873], c: "\u22A9" }, + "Vdashl;": { p: [10982], c: "\u2AE6" }, + "Vee;": { p: [8897], c: "\u22C1" }, + "Verbar;": { p: [8214], c: "\u2016" }, + "Vert;": { p: [8214], c: "\u2016" }, + "VerticalBar;": { p: [8739], c: "\u2223" }, + "VerticalLine;": { p: [124], c: "\u007C" }, + "VerticalSeparator;": { p: [10072], c: "\u2758" }, + "VerticalTilde;": { p: [8768], c: "\u2240" }, + "VeryThinSpace;": { p: [8202], c: "\u200A" }, + "Vfr;": { p: [120089], c: "\uD835\uDD19" }, + "Vopf;": { p: [120141], c: "\uD835\uDD4D" }, + "Vscr;": { p: [119985], c: "\uD835\uDCB1" }, + "Vvdash;": { p: [8874], c: "\u22AA" }, + "Wcirc;": { p: [372], c: "\u0174" }, + "Wedge;": { p: [8896], c: "\u22C0" }, + "Wfr;": { p: [120090], c: "\uD835\uDD1A" }, + "Wopf;": { p: [120142], c: "\uD835\uDD4E" }, + "Wscr;": { p: [119986], c: "\uD835\uDCB2" }, + "Xfr;": { p: [120091], c: "\uD835\uDD1B" }, + "Xi;": { p: [926], c: "\u039E" }, + "Xopf;": { p: [120143], c: "\uD835\uDD4F" }, + "Xscr;": { p: [119987], c: "\uD835\uDCB3" }, + "YAcy;": { p: [1071], c: "\u042F" }, + "YIcy;": { p: [1031], c: "\u0407" }, + "YUcy;": { p: [1070], c: "\u042E" }, + Yacute: { p: [221], c: "\u00DD" }, + "Yacute;": { p: [221], c: "\u00DD" }, + "Ycirc;": { p: [374], c: "\u0176" }, + "Ycy;": { p: [1067], c: "\u042B" }, + "Yfr;": { p: [120092], c: "\uD835\uDD1C" }, + "Yopf;": { p: [120144], c: "\uD835\uDD50" }, + "Yscr;": { p: [119988], c: "\uD835\uDCB4" }, + "Yuml;": { p: [376], c: "\u0178" }, + "ZHcy;": { p: [1046], c: "\u0416" }, + "Zacute;": { p: [377], c: "\u0179" }, + "Zcaron;": { p: [381], c: "\u017D" }, + "Zcy;": { p: [1047], c: "\u0417" }, + "Zdot;": { p: [379], c: "\u017B" }, + "ZeroWidthSpace;": { p: [8203], c: "\u200B" }, + "Zeta;": { p: [918], c: "\u0396" }, + "Zfr;": { p: [8488], c: "\u2128" }, + "Zopf;": { p: [8484], c: "\u2124" }, + "Zscr;": { p: [119989], c: "\uD835\uDCB5" }, + aacute: { p: [225], c: "\u00E1" }, + "aacute;": { p: [225], c: "\u00E1" }, + "abreve;": { p: [259], c: "\u0103" }, + "ac;": { p: [8766], c: "\u223E" }, + "acE;": { p: [8766, 819], c: "\u223E\u0333" }, + "acd;": { p: [8767], c: "\u223F" }, + acirc: { p: [226], c: "\u00E2" }, + "acirc;": { p: [226], c: "\u00E2" }, + acute: { p: [180], c: "\u00B4" }, + "acute;": { p: [180], c: "\u00B4" }, + "acy;": { p: [1072], c: "\u0430" }, + aelig: { p: [230], c: "\u00E6" }, + "aelig;": { p: [230], c: "\u00E6" }, + "af;": { p: [8289], c: "\u2061" }, + "afr;": { p: [120094], c: "\uD835\uDD1E" }, + agrave: { p: [224], c: "\u00E0" }, + "agrave;": { p: [224], c: "\u00E0" }, + "alefsym;": { p: [8501], c: "\u2135" }, + "aleph;": { p: [8501], c: "\u2135" }, + "alpha;": { p: [945], c: "\u03B1" }, + "amacr;": { p: [257], c: "\u0101" }, + "amalg;": { p: [10815], c: "\u2A3F" }, + amp: { p: [38], c: "\u0026" }, + "amp;": { p: [38], c: "\u0026" }, + "and;": { p: [8743], c: "\u2227" }, + "andand;": { p: [10837], c: "\u2A55" }, + "andd;": { p: [10844], c: "\u2A5C" }, + "andslope;": { p: [10840], c: "\u2A58" }, + "andv;": { p: [10842], c: "\u2A5A" }, + "ang;": { p: [8736], c: "\u2220" }, + "ange;": { p: [10660], c: "\u29A4" }, + "angle;": { p: [8736], c: "\u2220" }, + "angmsd;": { p: [8737], c: "\u2221" }, + "angmsdaa;": { p: [10664], c: "\u29A8" }, + "angmsdab;": { p: [10665], c: "\u29A9" }, + "angmsdac;": { p: [10666], c: "\u29AA" }, + "angmsdad;": { p: [10667], c: "\u29AB" }, + "angmsdae;": { p: [10668], c: "\u29AC" }, + "angmsdaf;": { p: [10669], c: "\u29AD" }, + "angmsdag;": { p: [10670], c: "\u29AE" }, + "angmsdah;": { p: [10671], c: "\u29AF" }, + "angrt;": { p: [8735], c: "\u221F" }, + "angrtvb;": { p: [8894], c: "\u22BE" }, + "angrtvbd;": { p: [10653], c: "\u299D" }, + "angsph;": { p: [8738], c: "\u2222" }, + "angst;": { p: [197], c: "\u00C5" }, + "angzarr;": { p: [9084], c: "\u237C" }, + "aogon;": { p: [261], c: "\u0105" }, + "aopf;": { p: [120146], c: "\uD835\uDD52" }, + "ap;": { p: [8776], c: "\u2248" }, + "apE;": { p: [10864], c: "\u2A70" }, + "apacir;": { p: [10863], c: "\u2A6F" }, + "ape;": { p: [8778], c: "\u224A" }, + "apid;": { p: [8779], c: "\u224B" }, + "apos;": { p: [39], c: "\u0027" }, + "approx;": { p: [8776], c: "\u2248" }, + "approxeq;": { p: [8778], c: "\u224A" }, + aring: { p: [229], c: "\u00E5" }, + "aring;": { p: [229], c: "\u00E5" }, + "ascr;": { p: [119990], c: "\uD835\uDCB6" }, + "ast;": { p: [42], c: "\u002A" }, + "asymp;": { p: [8776], c: "\u2248" }, + "asympeq;": { p: [8781], c: "\u224D" }, + atilde: { p: [227], c: "\u00E3" }, + "atilde;": { p: [227], c: "\u00E3" }, + auml: { p: [228], c: "\u00E4" }, + "auml;": { p: [228], c: "\u00E4" }, + "awconint;": { p: [8755], c: "\u2233" }, + "awint;": { p: [10769], c: "\u2A11" }, + "bNot;": { p: [10989], c: "\u2AED" }, + "backcong;": { p: [8780], c: "\u224C" }, + "backepsilon;": { p: [1014], c: "\u03F6" }, + "backprime;": { p: [8245], c: "\u2035" }, + "backsim;": { p: [8765], c: "\u223D" }, + "backsimeq;": { p: [8909], c: "\u22CD" }, + "barvee;": { p: [8893], c: "\u22BD" }, + "barwed;": { p: [8965], c: "\u2305" }, + "barwedge;": { p: [8965], c: "\u2305" }, + "bbrk;": { p: [9141], c: "\u23B5" }, + "bbrktbrk;": { p: [9142], c: "\u23B6" }, + "bcong;": { p: [8780], c: "\u224C" }, + "bcy;": { p: [1073], c: "\u0431" }, + "bdquo;": { p: [8222], c: "\u201E" }, + "becaus;": { p: [8757], c: "\u2235" }, + "because;": { p: [8757], c: "\u2235" }, + "bemptyv;": { p: [10672], c: "\u29B0" }, + "bepsi;": { p: [1014], c: "\u03F6" }, + "bernou;": { p: [8492], c: "\u212C" }, + "beta;": { p: [946], c: "\u03B2" }, + "beth;": { p: [8502], c: "\u2136" }, + "between;": { p: [8812], c: "\u226C" }, + "bfr;": { p: [120095], c: "\uD835\uDD1F" }, + "bigcap;": { p: [8898], c: "\u22C2" }, + "bigcirc;": { p: [9711], c: "\u25EF" }, + "bigcup;": { p: [8899], c: "\u22C3" }, + "bigodot;": { p: [10752], c: "\u2A00" }, + "bigoplus;": { p: [10753], c: "\u2A01" }, + "bigotimes;": { p: [10754], c: "\u2A02" }, + "bigsqcup;": { p: [10758], c: "\u2A06" }, + "bigstar;": { p: [9733], c: "\u2605" }, + "bigtriangledown;": { p: [9661], c: "\u25BD" }, + "bigtriangleup;": { p: [9651], c: "\u25B3" }, + "biguplus;": { p: [10756], c: "\u2A04" }, + "bigvee;": { p: [8897], c: "\u22C1" }, + "bigwedge;": { p: [8896], c: "\u22C0" }, + "bkarow;": { p: [10509], c: "\u290D" }, + "blacklozenge;": { p: [10731], c: "\u29EB" }, + "blacksquare;": { p: [9642], c: "\u25AA" }, + "blacktriangle;": { p: [9652], c: "\u25B4" }, + "blacktriangledown;": { p: [9662], c: "\u25BE" }, + "blacktriangleleft;": { p: [9666], c: "\u25C2" }, + "blacktriangleright;": { p: [9656], c: "\u25B8" }, + "blank;": { p: [9251], c: "\u2423" }, + "blk12;": { p: [9618], c: "\u2592" }, + "blk14;": { p: [9617], c: "\u2591" }, + "blk34;": { p: [9619], c: "\u2593" }, + "block;": { p: [9608], c: "\u2588" }, + "bne;": { p: [61, 8421], c: "\u003D\u20E5" }, + "bnequiv;": { p: [8801, 8421], c: "\u2261\u20E5" }, + "bnot;": { p: [8976], c: "\u2310" }, + "bopf;": { p: [120147], c: "\uD835\uDD53" }, + "bot;": { p: [8869], c: "\u22A5" }, + "bottom;": { p: [8869], c: "\u22A5" }, + "bowtie;": { p: [8904], c: "\u22C8" }, + "boxDL;": { p: [9559], c: "\u2557" }, + "boxDR;": { p: [9556], c: "\u2554" }, + "boxDl;": { p: [9558], c: "\u2556" }, + "boxDr;": { p: [9555], c: "\u2553" }, + "boxH;": { p: [9552], c: "\u2550" }, + "boxHD;": { p: [9574], c: "\u2566" }, + "boxHU;": { p: [9577], c: "\u2569" }, + "boxHd;": { p: [9572], c: "\u2564" }, + "boxHu;": { p: [9575], c: "\u2567" }, + "boxUL;": { p: [9565], c: "\u255D" }, + "boxUR;": { p: [9562], c: "\u255A" }, + "boxUl;": { p: [9564], c: "\u255C" }, + "boxUr;": { p: [9561], c: "\u2559" }, + "boxV;": { p: [9553], c: "\u2551" }, + "boxVH;": { p: [9580], c: "\u256C" }, + "boxVL;": { p: [9571], c: "\u2563" }, + "boxVR;": { p: [9568], c: "\u2560" }, + "boxVh;": { p: [9579], c: "\u256B" }, + "boxVl;": { p: [9570], c: "\u2562" }, + "boxVr;": { p: [9567], c: "\u255F" }, + "boxbox;": { p: [10697], c: "\u29C9" }, + "boxdL;": { p: [9557], c: "\u2555" }, + "boxdR;": { p: [9554], c: "\u2552" }, + "boxdl;": { p: [9488], c: "\u2510" }, + "boxdr;": { p: [9484], c: "\u250C" }, + "boxh;": { p: [9472], c: "\u2500" }, + "boxhD;": { p: [9573], c: "\u2565" }, + "boxhU;": { p: [9576], c: "\u2568" }, + "boxhd;": { p: [9516], c: "\u252C" }, + "boxhu;": { p: [9524], c: "\u2534" }, + "boxminus;": { p: [8863], c: "\u229F" }, + "boxplus;": { p: [8862], c: "\u229E" }, + "boxtimes;": { p: [8864], c: "\u22A0" }, + "boxuL;": { p: [9563], c: "\u255B" }, + "boxuR;": { p: [9560], c: "\u2558" }, + "boxul;": { p: [9496], c: "\u2518" }, + "boxur;": { p: [9492], c: "\u2514" }, + "boxv;": { p: [9474], c: "\u2502" }, + "boxvH;": { p: [9578], c: "\u256A" }, + "boxvL;": { p: [9569], c: "\u2561" }, + "boxvR;": { p: [9566], c: "\u255E" }, + "boxvh;": { p: [9532], c: "\u253C" }, + "boxvl;": { p: [9508], c: "\u2524" }, + "boxvr;": { p: [9500], c: "\u251C" }, + "bprime;": { p: [8245], c: "\u2035" }, + "breve;": { p: [728], c: "\u02D8" }, + brvbar: { p: [166], c: "\u00A6" }, + "brvbar;": { p: [166], c: "\u00A6" }, + "bscr;": { p: [119991], c: "\uD835\uDCB7" }, + "bsemi;": { p: [8271], c: "\u204F" }, + "bsim;": { p: [8765], c: "\u223D" }, + "bsime;": { p: [8909], c: "\u22CD" }, + "bsol;": { p: [92], c: "\u005C" }, + "bsolb;": { p: [10693], c: "\u29C5" }, + "bsolhsub;": { p: [10184], c: "\u27C8" }, + "bull;": { p: [8226], c: "\u2022" }, + "bullet;": { p: [8226], c: "\u2022" }, + "bump;": { p: [8782], c: "\u224E" }, + "bumpE;": { p: [10926], c: "\u2AAE" }, + "bumpe;": { p: [8783], c: "\u224F" }, + "bumpeq;": { p: [8783], c: "\u224F" }, + "cacute;": { p: [263], c: "\u0107" }, + "cap;": { p: [8745], c: "\u2229" }, + "capand;": { p: [10820], c: "\u2A44" }, + "capbrcup;": { p: [10825], c: "\u2A49" }, + "capcap;": { p: [10827], c: "\u2A4B" }, + "capcup;": { p: [10823], c: "\u2A47" }, + "capdot;": { p: [10816], c: "\u2A40" }, + "caps;": { p: [8745, 65024], c: "\u2229\uFE00" }, + "caret;": { p: [8257], c: "\u2041" }, + "caron;": { p: [711], c: "\u02C7" }, + "ccaps;": { p: [10829], c: "\u2A4D" }, + "ccaron;": { p: [269], c: "\u010D" }, + ccedil: { p: [231], c: "\u00E7" }, + "ccedil;": { p: [231], c: "\u00E7" }, + "ccirc;": { p: [265], c: "\u0109" }, + "ccups;": { p: [10828], c: "\u2A4C" }, + "ccupssm;": { p: [10832], c: "\u2A50" }, + "cdot;": { p: [267], c: "\u010B" }, + cedil: { p: [184], c: "\u00B8" }, + "cedil;": { p: [184], c: "\u00B8" }, + "cemptyv;": { p: [10674], c: "\u29B2" }, + cent: { p: [162], c: "\u00A2" }, + "cent;": { p: [162], c: "\u00A2" }, + "centerdot;": { p: [183], c: "\u00B7" }, + "cfr;": { p: [120096], c: "\uD835\uDD20" }, + "chcy;": { p: [1095], c: "\u0447" }, + "check;": { p: [10003], c: "\u2713" }, + "checkmark;": { p: [10003], c: "\u2713" }, + "chi;": { p: [967], c: "\u03C7" }, + "cir;": { p: [9675], c: "\u25CB" }, + "cirE;": { p: [10691], c: "\u29C3" }, + "circ;": { p: [710], c: "\u02C6" }, + "circeq;": { p: [8791], c: "\u2257" }, + "circlearrowleft;": { p: [8634], c: "\u21BA" }, + "circlearrowright;": { p: [8635], c: "\u21BB" }, + "circledR;": { p: [174], c: "\u00AE" }, + "circledS;": { p: [9416], c: "\u24C8" }, + "circledast;": { p: [8859], c: "\u229B" }, + "circledcirc;": { p: [8858], c: "\u229A" }, + "circleddash;": { p: [8861], c: "\u229D" }, + "cire;": { p: [8791], c: "\u2257" }, + "cirfnint;": { p: [10768], c: "\u2A10" }, + "cirmid;": { p: [10991], c: "\u2AEF" }, + "cirscir;": { p: [10690], c: "\u29C2" }, + "clubs;": { p: [9827], c: "\u2663" }, + "clubsuit;": { p: [9827], c: "\u2663" }, + "colon;": { p: [58], c: "\u003A" }, + "colone;": { p: [8788], c: "\u2254" }, + "coloneq;": { p: [8788], c: "\u2254" }, + "comma;": { p: [44], c: "\u002C" }, + "commat;": { p: [64], c: "\u0040" }, + "comp;": { p: [8705], c: "\u2201" }, + "compfn;": { p: [8728], c: "\u2218" }, + "complement;": { p: [8705], c: "\u2201" }, + "complexes;": { p: [8450], c: "\u2102" }, + "cong;": { p: [8773], c: "\u2245" }, + "congdot;": { p: [10861], c: "\u2A6D" }, + "conint;": { p: [8750], c: "\u222E" }, + "copf;": { p: [120148], c: "\uD835\uDD54" }, + "coprod;": { p: [8720], c: "\u2210" }, + copy: { p: [169], c: "\u00A9" }, + "copy;": { p: [169], c: "\u00A9" }, + "copysr;": { p: [8471], c: "\u2117" }, + "crarr;": { p: [8629], c: "\u21B5" }, + "cross;": { p: [10007], c: "\u2717" }, + "cscr;": { p: [119992], c: "\uD835\uDCB8" }, + "csub;": { p: [10959], c: "\u2ACF" }, + "csube;": { p: [10961], c: "\u2AD1" }, + "csup;": { p: [10960], c: "\u2AD0" }, + "csupe;": { p: [10962], c: "\u2AD2" }, + "ctdot;": { p: [8943], c: "\u22EF" }, + "cudarrl;": { p: [10552], c: "\u2938" }, + "cudarrr;": { p: [10549], c: "\u2935" }, + "cuepr;": { p: [8926], c: "\u22DE" }, + "cuesc;": { p: [8927], c: "\u22DF" }, + "cularr;": { p: [8630], c: "\u21B6" }, + "cularrp;": { p: [10557], c: "\u293D" }, + "cup;": { p: [8746], c: "\u222A" }, + "cupbrcap;": { p: [10824], c: "\u2A48" }, + "cupcap;": { p: [10822], c: "\u2A46" }, + "cupcup;": { p: [10826], c: "\u2A4A" }, + "cupdot;": { p: [8845], c: "\u228D" }, + "cupor;": { p: [10821], c: "\u2A45" }, + "cups;": { p: [8746, 65024], c: "\u222A\uFE00" }, + "curarr;": { p: [8631], c: "\u21B7" }, + "curarrm;": { p: [10556], c: "\u293C" }, + "curlyeqprec;": { p: [8926], c: "\u22DE" }, + "curlyeqsucc;": { p: [8927], c: "\u22DF" }, + "curlyvee;": { p: [8910], c: "\u22CE" }, + "curlywedge;": { p: [8911], c: "\u22CF" }, + curren: { p: [164], c: "\u00A4" }, + "curren;": { p: [164], c: "\u00A4" }, + "curvearrowleft;": { p: [8630], c: "\u21B6" }, + "curvearrowright;": { p: [8631], c: "\u21B7" }, + "cuvee;": { p: [8910], c: "\u22CE" }, + "cuwed;": { p: [8911], c: "\u22CF" }, + "cwconint;": { p: [8754], c: "\u2232" }, + "cwint;": { p: [8753], c: "\u2231" }, + "cylcty;": { p: [9005], c: "\u232D" }, + "dArr;": { p: [8659], c: "\u21D3" }, + "dHar;": { p: [10597], c: "\u2965" }, + "dagger;": { p: [8224], c: "\u2020" }, + "daleth;": { p: [8504], c: "\u2138" }, + "darr;": { p: [8595], c: "\u2193" }, + "dash;": { p: [8208], c: "\u2010" }, + "dashv;": { p: [8867], c: "\u22A3" }, + "dbkarow;": { p: [10511], c: "\u290F" }, + "dblac;": { p: [733], c: "\u02DD" }, + "dcaron;": { p: [271], c: "\u010F" }, + "dcy;": { p: [1076], c: "\u0434" }, + "dd;": { p: [8518], c: "\u2146" }, + "ddagger;": { p: [8225], c: "\u2021" }, + "ddarr;": { p: [8650], c: "\u21CA" }, + "ddotseq;": { p: [10871], c: "\u2A77" }, + deg: { p: [176], c: "\u00B0" }, + "deg;": { p: [176], c: "\u00B0" }, + "delta;": { p: [948], c: "\u03B4" }, + "demptyv;": { p: [10673], c: "\u29B1" }, + "dfisht;": { p: [10623], c: "\u297F" }, + "dfr;": { p: [120097], c: "\uD835\uDD21" }, + "dharl;": { p: [8643], c: "\u21C3" }, + "dharr;": { p: [8642], c: "\u21C2" }, + "diam;": { p: [8900], c: "\u22C4" }, + "diamond;": { p: [8900], c: "\u22C4" }, + "diamondsuit;": { p: [9830], c: "\u2666" }, + "diams;": { p: [9830], c: "\u2666" }, + "die;": { p: [168], c: "\u00A8" }, + "digamma;": { p: [989], c: "\u03DD" }, + "disin;": { p: [8946], c: "\u22F2" }, + "div;": { p: [247], c: "\u00F7" }, + divide: { p: [247], c: "\u00F7" }, + "divide;": { p: [247], c: "\u00F7" }, + "divideontimes;": { p: [8903], c: "\u22C7" }, + "divonx;": { p: [8903], c: "\u22C7" }, + "djcy;": { p: [1106], c: "\u0452" }, + "dlcorn;": { p: [8990], c: "\u231E" }, + "dlcrop;": { p: [8973], c: "\u230D" }, + "dollar;": { p: [36], c: "\u0024" }, + "dopf;": { p: [120149], c: "\uD835\uDD55" }, + "dot;": { p: [729], c: "\u02D9" }, + "doteq;": { p: [8784], c: "\u2250" }, + "doteqdot;": { p: [8785], c: "\u2251" }, + "dotminus;": { p: [8760], c: "\u2238" }, + "dotplus;": { p: [8724], c: "\u2214" }, + "dotsquare;": { p: [8865], c: "\u22A1" }, + "doublebarwedge;": { p: [8966], c: "\u2306" }, + "downarrow;": { p: [8595], c: "\u2193" }, + "downdownarrows;": { p: [8650], c: "\u21CA" }, + "downharpoonleft;": { p: [8643], c: "\u21C3" }, + "downharpoonright;": { p: [8642], c: "\u21C2" }, + "drbkarow;": { p: [10512], c: "\u2910" }, + "drcorn;": { p: [8991], c: "\u231F" }, + "drcrop;": { p: [8972], c: "\u230C" }, + "dscr;": { p: [119993], c: "\uD835\uDCB9" }, + "dscy;": { p: [1109], c: "\u0455" }, + "dsol;": { p: [10742], c: "\u29F6" }, + "dstrok;": { p: [273], c: "\u0111" }, + "dtdot;": { p: [8945], c: "\u22F1" }, + "dtri;": { p: [9663], c: "\u25BF" }, + "dtrif;": { p: [9662], c: "\u25BE" }, + "duarr;": { p: [8693], c: "\u21F5" }, + "duhar;": { p: [10607], c: "\u296F" }, + "dwangle;": { p: [10662], c: "\u29A6" }, + "dzcy;": { p: [1119], c: "\u045F" }, + "dzigrarr;": { p: [10239], c: "\u27FF" }, + "eDDot;": { p: [10871], c: "\u2A77" }, + "eDot;": { p: [8785], c: "\u2251" }, + eacute: { p: [233], c: "\u00E9" }, + "eacute;": { p: [233], c: "\u00E9" }, + "easter;": { p: [10862], c: "\u2A6E" }, + "ecaron;": { p: [283], c: "\u011B" }, + "ecir;": { p: [8790], c: "\u2256" }, + ecirc: { p: [234], c: "\u00EA" }, + "ecirc;": { p: [234], c: "\u00EA" }, + "ecolon;": { p: [8789], c: "\u2255" }, + "ecy;": { p: [1101], c: "\u044D" }, + "edot;": { p: [279], c: "\u0117" }, + "ee;": { p: [8519], c: "\u2147" }, + "efDot;": { p: [8786], c: "\u2252" }, + "efr;": { p: [120098], c: "\uD835\uDD22" }, + "eg;": { p: [10906], c: "\u2A9A" }, + egrave: { p: [232], c: "\u00E8" }, + "egrave;": { p: [232], c: "\u00E8" }, + "egs;": { p: [10902], c: "\u2A96" }, + "egsdot;": { p: [10904], c: "\u2A98" }, + "el;": { p: [10905], c: "\u2A99" }, + "elinters;": { p: [9191], c: "\u23E7" }, + "ell;": { p: [8467], c: "\u2113" }, + "els;": { p: [10901], c: "\u2A95" }, + "elsdot;": { p: [10903], c: "\u2A97" }, + "emacr;": { p: [275], c: "\u0113" }, + "empty;": { p: [8709], c: "\u2205" }, + "emptyset;": { p: [8709], c: "\u2205" }, + "emptyv;": { p: [8709], c: "\u2205" }, + "emsp13;": { p: [8196], c: "\u2004" }, + "emsp14;": { p: [8197], c: "\u2005" }, + "emsp;": { p: [8195], c: "\u2003" }, + "eng;": { p: [331], c: "\u014B" }, + "ensp;": { p: [8194], c: "\u2002" }, + "eogon;": { p: [281], c: "\u0119" }, + "eopf;": { p: [120150], c: "\uD835\uDD56" }, + "epar;": { p: [8917], c: "\u22D5" }, + "eparsl;": { p: [10723], c: "\u29E3" }, + "eplus;": { p: [10865], c: "\u2A71" }, + "epsi;": { p: [949], c: "\u03B5" }, + "epsilon;": { p: [949], c: "\u03B5" }, + "epsiv;": { p: [1013], c: "\u03F5" }, + "eqcirc;": { p: [8790], c: "\u2256" }, + "eqcolon;": { p: [8789], c: "\u2255" }, + "eqsim;": { p: [8770], c: "\u2242" }, + "eqslantgtr;": { p: [10902], c: "\u2A96" }, + "eqslantless;": { p: [10901], c: "\u2A95" }, + "equals;": { p: [61], c: "\u003D" }, + "equest;": { p: [8799], c: "\u225F" }, + "equiv;": { p: [8801], c: "\u2261" }, + "equivDD;": { p: [10872], c: "\u2A78" }, + "eqvparsl;": { p: [10725], c: "\u29E5" }, + "erDot;": { p: [8787], c: "\u2253" }, + "erarr;": { p: [10609], c: "\u2971" }, + "escr;": { p: [8495], c: "\u212F" }, + "esdot;": { p: [8784], c: "\u2250" }, + "esim;": { p: [8770], c: "\u2242" }, + "eta;": { p: [951], c: "\u03B7" }, + eth: { p: [240], c: "\u00F0" }, + "eth;": { p: [240], c: "\u00F0" }, + euml: { p: [235], c: "\u00EB" }, + "euml;": { p: [235], c: "\u00EB" }, + "euro;": { p: [8364], c: "\u20AC" }, + "excl;": { p: [33], c: "\u0021" }, + "exist;": { p: [8707], c: "\u2203" }, + "expectation;": { p: [8496], c: "\u2130" }, + "exponentiale;": { p: [8519], c: "\u2147" }, + "fallingdotseq;": { p: [8786], c: "\u2252" }, + "fcy;": { p: [1092], c: "\u0444" }, + "female;": { p: [9792], c: "\u2640" }, + "ffilig;": { p: [64259], c: "\uFB03" }, + "fflig;": { p: [64256], c: "\uFB00" }, + "ffllig;": { p: [64260], c: "\uFB04" }, + "ffr;": { p: [120099], c: "\uD835\uDD23" }, + "filig;": { p: [64257], c: "\uFB01" }, + "fjlig;": { p: [102, 106], c: "\u0066\u006A" }, + "flat;": { p: [9837], c: "\u266D" }, + "fllig;": { p: [64258], c: "\uFB02" }, + "fltns;": { p: [9649], c: "\u25B1" }, + "fnof;": { p: [402], c: "\u0192" }, + "fopf;": { p: [120151], c: "\uD835\uDD57" }, + "forall;": { p: [8704], c: "\u2200" }, + "fork;": { p: [8916], c: "\u22D4" }, + "forkv;": { p: [10969], c: "\u2AD9" }, + "fpartint;": { p: [10765], c: "\u2A0D" }, + frac12: { p: [189], c: "\u00BD" }, + "frac12;": { p: [189], c: "\u00BD" }, + "frac13;": { p: [8531], c: "\u2153" }, + frac14: { p: [188], c: "\u00BC" }, + "frac14;": { p: [188], c: "\u00BC" }, + "frac15;": { p: [8533], c: "\u2155" }, + "frac16;": { p: [8537], c: "\u2159" }, + "frac18;": { p: [8539], c: "\u215B" }, + "frac23;": { p: [8532], c: "\u2154" }, + "frac25;": { p: [8534], c: "\u2156" }, + frac34: { p: [190], c: "\u00BE" }, + "frac34;": { p: [190], c: "\u00BE" }, + "frac35;": { p: [8535], c: "\u2157" }, + "frac38;": { p: [8540], c: "\u215C" }, + "frac45;": { p: [8536], c: "\u2158" }, + "frac56;": { p: [8538], c: "\u215A" }, + "frac58;": { p: [8541], c: "\u215D" }, + "frac78;": { p: [8542], c: "\u215E" }, + "frasl;": { p: [8260], c: "\u2044" }, + "frown;": { p: [8994], c: "\u2322" }, + "fscr;": { p: [119995], c: "\uD835\uDCBB" }, + "gE;": { p: [8807], c: "\u2267" }, + "gEl;": { p: [10892], c: "\u2A8C" }, + "gacute;": { p: [501], c: "\u01F5" }, + "gamma;": { p: [947], c: "\u03B3" }, + "gammad;": { p: [989], c: "\u03DD" }, + "gap;": { p: [10886], c: "\u2A86" }, + "gbreve;": { p: [287], c: "\u011F" }, + "gcirc;": { p: [285], c: "\u011D" }, + "gcy;": { p: [1075], c: "\u0433" }, + "gdot;": { p: [289], c: "\u0121" }, + "ge;": { p: [8805], c: "\u2265" }, + "gel;": { p: [8923], c: "\u22DB" }, + "geq;": { p: [8805], c: "\u2265" }, + "geqq;": { p: [8807], c: "\u2267" }, + "geqslant;": { p: [10878], c: "\u2A7E" }, + "ges;": { p: [10878], c: "\u2A7E" }, + "gescc;": { p: [10921], c: "\u2AA9" }, + "gesdot;": { p: [10880], c: "\u2A80" }, + "gesdoto;": { p: [10882], c: "\u2A82" }, + "gesdotol;": { p: [10884], c: "\u2A84" }, + "gesl;": { p: [8923, 65024], c: "\u22DB\uFE00" }, + "gesles;": { p: [10900], c: "\u2A94" }, + "gfr;": { p: [120100], c: "\uD835\uDD24" }, + "gg;": { p: [8811], c: "\u226B" }, + "ggg;": { p: [8921], c: "\u22D9" }, + "gimel;": { p: [8503], c: "\u2137" }, + "gjcy;": { p: [1107], c: "\u0453" }, + "gl;": { p: [8823], c: "\u2277" }, + "glE;": { p: [10898], c: "\u2A92" }, + "gla;": { p: [10917], c: "\u2AA5" }, + "glj;": { p: [10916], c: "\u2AA4" }, + "gnE;": { p: [8809], c: "\u2269" }, + "gnap;": { p: [10890], c: "\u2A8A" }, + "gnapprox;": { p: [10890], c: "\u2A8A" }, + "gne;": { p: [10888], c: "\u2A88" }, + "gneq;": { p: [10888], c: "\u2A88" }, + "gneqq;": { p: [8809], c: "\u2269" }, + "gnsim;": { p: [8935], c: "\u22E7" }, + "gopf;": { p: [120152], c: "\uD835\uDD58" }, + "grave;": { p: [96], c: "\u0060" }, + "gscr;": { p: [8458], c: "\u210A" }, + "gsim;": { p: [8819], c: "\u2273" }, + "gsime;": { p: [10894], c: "\u2A8E" }, + "gsiml;": { p: [10896], c: "\u2A90" }, + gt: { p: [62], c: "\u003E" }, + "gt;": { p: [62], c: "\u003E" }, + "gtcc;": { p: [10919], c: "\u2AA7" }, + "gtcir;": { p: [10874], c: "\u2A7A" }, + "gtdot;": { p: [8919], c: "\u22D7" }, + "gtlPar;": { p: [10645], c: "\u2995" }, + "gtquest;": { p: [10876], c: "\u2A7C" }, + "gtrapprox;": { p: [10886], c: "\u2A86" }, + "gtrarr;": { p: [10616], c: "\u2978" }, + "gtrdot;": { p: [8919], c: "\u22D7" }, + "gtreqless;": { p: [8923], c: "\u22DB" }, + "gtreqqless;": { p: [10892], c: "\u2A8C" }, + "gtrless;": { p: [8823], c: "\u2277" }, + "gtrsim;": { p: [8819], c: "\u2273" }, + "gvertneqq;": { + p: [8809, 65024], + c: "\u2269\uFE00", + }, + "gvnE;": { p: [8809, 65024], c: "\u2269\uFE00" }, + "hArr;": { p: [8660], c: "\u21D4" }, + "hairsp;": { p: [8202], c: "\u200A" }, + "half;": { p: [189], c: "\u00BD" }, + "hamilt;": { p: [8459], c: "\u210B" }, + "hardcy;": { p: [1098], c: "\u044A" }, + "harr;": { p: [8596], c: "\u2194" }, + "harrcir;": { p: [10568], c: "\u2948" }, + "harrw;": { p: [8621], c: "\u21AD" }, + "hbar;": { p: [8463], c: "\u210F" }, + "hcirc;": { p: [293], c: "\u0125" }, + "hearts;": { p: [9829], c: "\u2665" }, + "heartsuit;": { p: [9829], c: "\u2665" }, + "hellip;": { p: [8230], c: "\u2026" }, + "hercon;": { p: [8889], c: "\u22B9" }, + "hfr;": { p: [120101], c: "\uD835\uDD25" }, + "hksearow;": { p: [10533], c: "\u2925" }, + "hkswarow;": { p: [10534], c: "\u2926" }, + "hoarr;": { p: [8703], c: "\u21FF" }, + "homtht;": { p: [8763], c: "\u223B" }, + "hookleftarrow;": { p: [8617], c: "\u21A9" }, + "hookrightarrow;": { p: [8618], c: "\u21AA" }, + "hopf;": { p: [120153], c: "\uD835\uDD59" }, + "horbar;": { p: [8213], c: "\u2015" }, + "hscr;": { p: [119997], c: "\uD835\uDCBD" }, + "hslash;": { p: [8463], c: "\u210F" }, + "hstrok;": { p: [295], c: "\u0127" }, + "hybull;": { p: [8259], c: "\u2043" }, + "hyphen;": { p: [8208], c: "\u2010" }, + iacute: { p: [237], c: "\u00ED" }, + "iacute;": { p: [237], c: "\u00ED" }, + "ic;": { p: [8291], c: "\u2063" }, + icirc: { p: [238], c: "\u00EE" }, + "icirc;": { p: [238], c: "\u00EE" }, + "icy;": { p: [1080], c: "\u0438" }, + "iecy;": { p: [1077], c: "\u0435" }, + iexcl: { p: [161], c: "\u00A1" }, + "iexcl;": { p: [161], c: "\u00A1" }, + "iff;": { p: [8660], c: "\u21D4" }, + "ifr;": { p: [120102], c: "\uD835\uDD26" }, + igrave: { p: [236], c: "\u00EC" }, + "igrave;": { p: [236], c: "\u00EC" }, + "ii;": { p: [8520], c: "\u2148" }, + "iiiint;": { p: [10764], c: "\u2A0C" }, + "iiint;": { p: [8749], c: "\u222D" }, + "iinfin;": { p: [10716], c: "\u29DC" }, + "iiota;": { p: [8489], c: "\u2129" }, + "ijlig;": { p: [307], c: "\u0133" }, + "imacr;": { p: [299], c: "\u012B" }, + "image;": { p: [8465], c: "\u2111" }, + "imagline;": { p: [8464], c: "\u2110" }, + "imagpart;": { p: [8465], c: "\u2111" }, + "imath;": { p: [305], c: "\u0131" }, + "imof;": { p: [8887], c: "\u22B7" }, + "imped;": { p: [437], c: "\u01B5" }, + "in;": { p: [8712], c: "\u2208" }, + "incare;": { p: [8453], c: "\u2105" }, + "infin;": { p: [8734], c: "\u221E" }, + "infintie;": { p: [10717], c: "\u29DD" }, + "inodot;": { p: [305], c: "\u0131" }, + "int;": { p: [8747], c: "\u222B" }, + "intcal;": { p: [8890], c: "\u22BA" }, + "integers;": { p: [8484], c: "\u2124" }, + "intercal;": { p: [8890], c: "\u22BA" }, + "intlarhk;": { p: [10775], c: "\u2A17" }, + "intprod;": { p: [10812], c: "\u2A3C" }, + "iocy;": { p: [1105], c: "\u0451" }, + "iogon;": { p: [303], c: "\u012F" }, + "iopf;": { p: [120154], c: "\uD835\uDD5A" }, + "iota;": { p: [953], c: "\u03B9" }, + "iprod;": { p: [10812], c: "\u2A3C" }, + iquest: { p: [191], c: "\u00BF" }, + "iquest;": { p: [191], c: "\u00BF" }, + "iscr;": { p: [119998], c: "\uD835\uDCBE" }, + "isin;": { p: [8712], c: "\u2208" }, + "isinE;": { p: [8953], c: "\u22F9" }, + "isindot;": { p: [8949], c: "\u22F5" }, + "isins;": { p: [8948], c: "\u22F4" }, + "isinsv;": { p: [8947], c: "\u22F3" }, + "isinv;": { p: [8712], c: "\u2208" }, + "it;": { p: [8290], c: "\u2062" }, + "itilde;": { p: [297], c: "\u0129" }, + "iukcy;": { p: [1110], c: "\u0456" }, + iuml: { p: [239], c: "\u00EF" }, + "iuml;": { p: [239], c: "\u00EF" }, + "jcirc;": { p: [309], c: "\u0135" }, + "jcy;": { p: [1081], c: "\u0439" }, + "jfr;": { p: [120103], c: "\uD835\uDD27" }, + "jmath;": { p: [567], c: "\u0237" }, + "jopf;": { p: [120155], c: "\uD835\uDD5B" }, + "jscr;": { p: [119999], c: "\uD835\uDCBF" }, + "jsercy;": { p: [1112], c: "\u0458" }, + "jukcy;": { p: [1108], c: "\u0454" }, + "kappa;": { p: [954], c: "\u03BA" }, + "kappav;": { p: [1008], c: "\u03F0" }, + "kcedil;": { p: [311], c: "\u0137" }, + "kcy;": { p: [1082], c: "\u043A" }, + "kfr;": { p: [120104], c: "\uD835\uDD28" }, + "kgreen;": { p: [312], c: "\u0138" }, + "khcy;": { p: [1093], c: "\u0445" }, + "kjcy;": { p: [1116], c: "\u045C" }, + "kopf;": { p: [120156], c: "\uD835\uDD5C" }, + "kscr;": { p: [120000], c: "\uD835\uDCC0" }, + "lAarr;": { p: [8666], c: "\u21DA" }, + "lArr;": { p: [8656], c: "\u21D0" }, + "lAtail;": { p: [10523], c: "\u291B" }, + "lBarr;": { p: [10510], c: "\u290E" }, + "lE;": { p: [8806], c: "\u2266" }, + "lEg;": { p: [10891], c: "\u2A8B" }, + "lHar;": { p: [10594], c: "\u2962" }, + "lacute;": { p: [314], c: "\u013A" }, + "laemptyv;": { p: [10676], c: "\u29B4" }, + "lagran;": { p: [8466], c: "\u2112" }, + "lambda;": { p: [955], c: "\u03BB" }, + "lang;": { p: [10216], c: "\u27E8" }, + "langd;": { p: [10641], c: "\u2991" }, + "langle;": { p: [10216], c: "\u27E8" }, + "lap;": { p: [10885], c: "\u2A85" }, + laquo: { p: [171], c: "\u00AB" }, + "laquo;": { p: [171], c: "\u00AB" }, + "larr;": { p: [8592], c: "\u2190" }, + "larrb;": { p: [8676], c: "\u21E4" }, + "larrbfs;": { p: [10527], c: "\u291F" }, + "larrfs;": { p: [10525], c: "\u291D" }, + "larrhk;": { p: [8617], c: "\u21A9" }, + "larrlp;": { p: [8619], c: "\u21AB" }, + "larrpl;": { p: [10553], c: "\u2939" }, + "larrsim;": { p: [10611], c: "\u2973" }, + "larrtl;": { p: [8610], c: "\u21A2" }, + "lat;": { p: [10923], c: "\u2AAB" }, + "latail;": { p: [10521], c: "\u2919" }, + "late;": { p: [10925], c: "\u2AAD" }, + "lates;": { p: [10925, 65024], c: "\u2AAD\uFE00" }, + "lbarr;": { p: [10508], c: "\u290C" }, + "lbbrk;": { p: [10098], c: "\u2772" }, + "lbrace;": { p: [123], c: "\u007B" }, + "lbrack;": { p: [91], c: "\u005B" }, + "lbrke;": { p: [10635], c: "\u298B" }, + "lbrksld;": { p: [10639], c: "\u298F" }, + "lbrkslu;": { p: [10637], c: "\u298D" }, + "lcaron;": { p: [318], c: "\u013E" }, + "lcedil;": { p: [316], c: "\u013C" }, + "lceil;": { p: [8968], c: "\u2308" }, + "lcub;": { p: [123], c: "\u007B" }, + "lcy;": { p: [1083], c: "\u043B" }, + "ldca;": { p: [10550], c: "\u2936" }, + "ldquo;": { p: [8220], c: "\u201C" }, + "ldquor;": { p: [8222], c: "\u201E" }, + "ldrdhar;": { p: [10599], c: "\u2967" }, + "ldrushar;": { p: [10571], c: "\u294B" }, + "ldsh;": { p: [8626], c: "\u21B2" }, + "le;": { p: [8804], c: "\u2264" }, + "leftarrow;": { p: [8592], c: "\u2190" }, + "leftarrowtail;": { p: [8610], c: "\u21A2" }, + "leftharpoondown;": { p: [8637], c: "\u21BD" }, + "leftharpoonup;": { p: [8636], c: "\u21BC" }, + "leftleftarrows;": { p: [8647], c: "\u21C7" }, + "leftrightarrow;": { p: [8596], c: "\u2194" }, + "leftrightarrows;": { p: [8646], c: "\u21C6" }, + "leftrightharpoons;": { p: [8651], c: "\u21CB" }, + "leftrightsquigarrow;": { p: [8621], c: "\u21AD" }, + "leftthreetimes;": { p: [8907], c: "\u22CB" }, + "leg;": { p: [8922], c: "\u22DA" }, + "leq;": { p: [8804], c: "\u2264" }, + "leqq;": { p: [8806], c: "\u2266" }, + "leqslant;": { p: [10877], c: "\u2A7D" }, + "les;": { p: [10877], c: "\u2A7D" }, + "lescc;": { p: [10920], c: "\u2AA8" }, + "lesdot;": { p: [10879], c: "\u2A7F" }, + "lesdoto;": { p: [10881], c: "\u2A81" }, + "lesdotor;": { p: [10883], c: "\u2A83" }, + "lesg;": { p: [8922, 65024], c: "\u22DA\uFE00" }, + "lesges;": { p: [10899], c: "\u2A93" }, + "lessapprox;": { p: [10885], c: "\u2A85" }, + "lessdot;": { p: [8918], c: "\u22D6" }, + "lesseqgtr;": { p: [8922], c: "\u22DA" }, + "lesseqqgtr;": { p: [10891], c: "\u2A8B" }, + "lessgtr;": { p: [8822], c: "\u2276" }, + "lesssim;": { p: [8818], c: "\u2272" }, + "lfisht;": { p: [10620], c: "\u297C" }, + "lfloor;": { p: [8970], c: "\u230A" }, + "lfr;": { p: [120105], c: "\uD835\uDD29" }, + "lg;": { p: [8822], c: "\u2276" }, + "lgE;": { p: [10897], c: "\u2A91" }, + "lhard;": { p: [8637], c: "\u21BD" }, + "lharu;": { p: [8636], c: "\u21BC" }, + "lharul;": { p: [10602], c: "\u296A" }, + "lhblk;": { p: [9604], c: "\u2584" }, + "ljcy;": { p: [1113], c: "\u0459" }, + "ll;": { p: [8810], c: "\u226A" }, + "llarr;": { p: [8647], c: "\u21C7" }, + "llcorner;": { p: [8990], c: "\u231E" }, + "llhard;": { p: [10603], c: "\u296B" }, + "lltri;": { p: [9722], c: "\u25FA" }, + "lmidot;": { p: [320], c: "\u0140" }, + "lmoust;": { p: [9136], c: "\u23B0" }, + "lmoustache;": { p: [9136], c: "\u23B0" }, + "lnE;": { p: [8808], c: "\u2268" }, + "lnap;": { p: [10889], c: "\u2A89" }, + "lnapprox;": { p: [10889], c: "\u2A89" }, + "lne;": { p: [10887], c: "\u2A87" }, + "lneq;": { p: [10887], c: "\u2A87" }, + "lneqq;": { p: [8808], c: "\u2268" }, + "lnsim;": { p: [8934], c: "\u22E6" }, + "loang;": { p: [10220], c: "\u27EC" }, + "loarr;": { p: [8701], c: "\u21FD" }, + "lobrk;": { p: [10214], c: "\u27E6" }, + "longleftarrow;": { p: [10229], c: "\u27F5" }, + "longleftrightarrow;": { p: [10231], c: "\u27F7" }, + "longmapsto;": { p: [10236], c: "\u27FC" }, + "longrightarrow;": { p: [10230], c: "\u27F6" }, + "looparrowleft;": { p: [8619], c: "\u21AB" }, + "looparrowright;": { p: [8620], c: "\u21AC" }, + "lopar;": { p: [10629], c: "\u2985" }, + "lopf;": { p: [120157], c: "\uD835\uDD5D" }, + "loplus;": { p: [10797], c: "\u2A2D" }, + "lotimes;": { p: [10804], c: "\u2A34" }, + "lowast;": { p: [8727], c: "\u2217" }, + "lowbar;": { p: [95], c: "\u005F" }, + "loz;": { p: [9674], c: "\u25CA" }, + "lozenge;": { p: [9674], c: "\u25CA" }, + "lozf;": { p: [10731], c: "\u29EB" }, + "lpar;": { p: [40], c: "\u0028" }, + "lparlt;": { p: [10643], c: "\u2993" }, + "lrarr;": { p: [8646], c: "\u21C6" }, + "lrcorner;": { p: [8991], c: "\u231F" }, + "lrhar;": { p: [8651], c: "\u21CB" }, + "lrhard;": { p: [10605], c: "\u296D" }, + "lrm;": { p: [8206], c: "\u200E" }, + "lrtri;": { p: [8895], c: "\u22BF" }, + "lsaquo;": { p: [8249], c: "\u2039" }, + "lscr;": { p: [120001], c: "\uD835\uDCC1" }, + "lsh;": { p: [8624], c: "\u21B0" }, + "lsim;": { p: [8818], c: "\u2272" }, + "lsime;": { p: [10893], c: "\u2A8D" }, + "lsimg;": { p: [10895], c: "\u2A8F" }, + "lsqb;": { p: [91], c: "\u005B" }, + "lsquo;": { p: [8216], c: "\u2018" }, + "lsquor;": { p: [8218], c: "\u201A" }, + "lstrok;": { p: [322], c: "\u0142" }, + lt: { p: [60], c: "\u003C" }, + "lt;": { p: [60], c: "\u003C" }, + "ltcc;": { p: [10918], c: "\u2AA6" }, + "ltcir;": { p: [10873], c: "\u2A79" }, + "ltdot;": { p: [8918], c: "\u22D6" }, + "lthree;": { p: [8907], c: "\u22CB" }, + "ltimes;": { p: [8905], c: "\u22C9" }, + "ltlarr;": { p: [10614], c: "\u2976" }, + "ltquest;": { p: [10875], c: "\u2A7B" }, + "ltrPar;": { p: [10646], c: "\u2996" }, + "ltri;": { p: [9667], c: "\u25C3" }, + "ltrie;": { p: [8884], c: "\u22B4" }, + "ltrif;": { p: [9666], c: "\u25C2" }, + "lurdshar;": { p: [10570], c: "\u294A" }, + "luruhar;": { p: [10598], c: "\u2966" }, + "lvertneqq;": { + p: [8808, 65024], + c: "\u2268\uFE00", + }, + "lvnE;": { p: [8808, 65024], c: "\u2268\uFE00" }, + "mDDot;": { p: [8762], c: "\u223A" }, + macr: { p: [175], c: "\u00AF" }, + "macr;": { p: [175], c: "\u00AF" }, + "male;": { p: [9794], c: "\u2642" }, + "malt;": { p: [10016], c: "\u2720" }, + "maltese;": { p: [10016], c: "\u2720" }, + "map;": { p: [8614], c: "\u21A6" }, + "mapsto;": { p: [8614], c: "\u21A6" }, + "mapstodown;": { p: [8615], c: "\u21A7" }, + "mapstoleft;": { p: [8612], c: "\u21A4" }, + "mapstoup;": { p: [8613], c: "\u21A5" }, + "marker;": { p: [9646], c: "\u25AE" }, + "mcomma;": { p: [10793], c: "\u2A29" }, + "mcy;": { p: [1084], c: "\u043C" }, + "mdash;": { p: [8212], c: "\u2014" }, + "measuredangle;": { p: [8737], c: "\u2221" }, + "mfr;": { p: [120106], c: "\uD835\uDD2A" }, + "mho;": { p: [8487], c: "\u2127" }, + micro: { p: [181], c: "\u00B5" }, + "micro;": { p: [181], c: "\u00B5" }, + "mid;": { p: [8739], c: "\u2223" }, + "midast;": { p: [42], c: "\u002A" }, + "midcir;": { p: [10992], c: "\u2AF0" }, + middot: { p: [183], c: "\u00B7" }, + "middot;": { p: [183], c: "\u00B7" }, + "minus;": { p: [8722], c: "\u2212" }, + "minusb;": { p: [8863], c: "\u229F" }, + "minusd;": { p: [8760], c: "\u2238" }, + "minusdu;": { p: [10794], c: "\u2A2A" }, + "mlcp;": { p: [10971], c: "\u2ADB" }, + "mldr;": { p: [8230], c: "\u2026" }, + "mnplus;": { p: [8723], c: "\u2213" }, + "models;": { p: [8871], c: "\u22A7" }, + "mopf;": { p: [120158], c: "\uD835\uDD5E" }, + "mp;": { p: [8723], c: "\u2213" }, + "mscr;": { p: [120002], c: "\uD835\uDCC2" }, + "mstpos;": { p: [8766], c: "\u223E" }, + "mu;": { p: [956], c: "\u03BC" }, + "multimap;": { p: [8888], c: "\u22B8" }, + "mumap;": { p: [8888], c: "\u22B8" }, + "nGg;": { p: [8921, 824], c: "\u22D9\u0338" }, + "nGt;": { p: [8811, 8402], c: "\u226B\u20D2" }, + "nGtv;": { p: [8811, 824], c: "\u226B\u0338" }, + "nLeftarrow;": { p: [8653], c: "\u21CD" }, + "nLeftrightarrow;": { p: [8654], c: "\u21CE" }, + "nLl;": { p: [8920, 824], c: "\u22D8\u0338" }, + "nLt;": { p: [8810, 8402], c: "\u226A\u20D2" }, + "nLtv;": { p: [8810, 824], c: "\u226A\u0338" }, + "nRightarrow;": { p: [8655], c: "\u21CF" }, + "nVDash;": { p: [8879], c: "\u22AF" }, + "nVdash;": { p: [8878], c: "\u22AE" }, + "nabla;": { p: [8711], c: "\u2207" }, + "nacute;": { p: [324], c: "\u0144" }, + "nang;": { p: [8736, 8402], c: "\u2220\u20D2" }, + "nap;": { p: [8777], c: "\u2249" }, + "napE;": { p: [10864, 824], c: "\u2A70\u0338" }, + "napid;": { p: [8779, 824], c: "\u224B\u0338" }, + "napos;": { p: [329], c: "\u0149" }, + "napprox;": { p: [8777], c: "\u2249" }, + "natur;": { p: [9838], c: "\u266E" }, + "natural;": { p: [9838], c: "\u266E" }, + "naturals;": { p: [8469], c: "\u2115" }, + nbsp: { p: [160], c: "\u00A0" }, + "nbsp;": { p: [160], c: "\u00A0" }, + "nbump;": { p: [8782, 824], c: "\u224E\u0338" }, + "nbumpe;": { p: [8783, 824], c: "\u224F\u0338" }, + "ncap;": { p: [10819], c: "\u2A43" }, + "ncaron;": { p: [328], c: "\u0148" }, + "ncedil;": { p: [326], c: "\u0146" }, + "ncong;": { p: [8775], c: "\u2247" }, + "ncongdot;": { p: [10861, 824], c: "\u2A6D\u0338" }, + "ncup;": { p: [10818], c: "\u2A42" }, + "ncy;": { p: [1085], c: "\u043D" }, + "ndash;": { p: [8211], c: "\u2013" }, + "ne;": { p: [8800], c: "\u2260" }, + "neArr;": { p: [8663], c: "\u21D7" }, + "nearhk;": { p: [10532], c: "\u2924" }, + "nearr;": { p: [8599], c: "\u2197" }, + "nearrow;": { p: [8599], c: "\u2197" }, + "nedot;": { p: [8784, 824], c: "\u2250\u0338" }, + "nequiv;": { p: [8802], c: "\u2262" }, + "nesear;": { p: [10536], c: "\u2928" }, + "nesim;": { p: [8770, 824], c: "\u2242\u0338" }, + "nexist;": { p: [8708], c: "\u2204" }, + "nexists;": { p: [8708], c: "\u2204" }, + "nfr;": { p: [120107], c: "\uD835\uDD2B" }, + "ngE;": { p: [8807, 824], c: "\u2267\u0338" }, + "nge;": { p: [8817], c: "\u2271" }, + "ngeq;": { p: [8817], c: "\u2271" }, + "ngeqq;": { p: [8807, 824], c: "\u2267\u0338" }, + "ngeqslant;": { p: [10878, 824], c: "\u2A7E\u0338" }, + "nges;": { p: [10878, 824], c: "\u2A7E\u0338" }, + "ngsim;": { p: [8821], c: "\u2275" }, + "ngt;": { p: [8815], c: "\u226F" }, + "ngtr;": { p: [8815], c: "\u226F" }, + "nhArr;": { p: [8654], c: "\u21CE" }, + "nharr;": { p: [8622], c: "\u21AE" }, + "nhpar;": { p: [10994], c: "\u2AF2" }, + "ni;": { p: [8715], c: "\u220B" }, + "nis;": { p: [8956], c: "\u22FC" }, + "nisd;": { p: [8954], c: "\u22FA" }, + "niv;": { p: [8715], c: "\u220B" }, + "njcy;": { p: [1114], c: "\u045A" }, + "nlArr;": { p: [8653], c: "\u21CD" }, + "nlE;": { p: [8806, 824], c: "\u2266\u0338" }, + "nlarr;": { p: [8602], c: "\u219A" }, + "nldr;": { p: [8229], c: "\u2025" }, + "nle;": { p: [8816], c: "\u2270" }, + "nleftarrow;": { p: [8602], c: "\u219A" }, + "nleftrightarrow;": { p: [8622], c: "\u21AE" }, + "nleq;": { p: [8816], c: "\u2270" }, + "nleqq;": { p: [8806, 824], c: "\u2266\u0338" }, + "nleqslant;": { p: [10877, 824], c: "\u2A7D\u0338" }, + "nles;": { p: [10877, 824], c: "\u2A7D\u0338" }, + "nless;": { p: [8814], c: "\u226E" }, + "nlsim;": { p: [8820], c: "\u2274" }, + "nlt;": { p: [8814], c: "\u226E" }, + "nltri;": { p: [8938], c: "\u22EA" }, + "nltrie;": { p: [8940], c: "\u22EC" }, + "nmid;": { p: [8740], c: "\u2224" }, + "nopf;": { p: [120159], c: "\uD835\uDD5F" }, + not: { p: [172], c: "\u00AC" }, + "not;": { p: [172], c: "\u00AC" }, + "notin;": { p: [8713], c: "\u2209" }, + "notinE;": { p: [8953, 824], c: "\u22F9\u0338" }, + "notindot;": { p: [8949, 824], c: "\u22F5\u0338" }, + "notinva;": { p: [8713], c: "\u2209" }, + "notinvb;": { p: [8951], c: "\u22F7" }, + "notinvc;": { p: [8950], c: "\u22F6" }, + "notni;": { p: [8716], c: "\u220C" }, + "notniva;": { p: [8716], c: "\u220C" }, + "notnivb;": { p: [8958], c: "\u22FE" }, + "notnivc;": { p: [8957], c: "\u22FD" }, + "npar;": { p: [8742], c: "\u2226" }, + "nparallel;": { p: [8742], c: "\u2226" }, + "nparsl;": { p: [11005, 8421], c: "\u2AFD\u20E5" }, + "npart;": { p: [8706, 824], c: "\u2202\u0338" }, + "npolint;": { p: [10772], c: "\u2A14" }, + "npr;": { p: [8832], c: "\u2280" }, + "nprcue;": { p: [8928], c: "\u22E0" }, + "npre;": { p: [10927, 824], c: "\u2AAF\u0338" }, + "nprec;": { p: [8832], c: "\u2280" }, + "npreceq;": { p: [10927, 824], c: "\u2AAF\u0338" }, + "nrArr;": { p: [8655], c: "\u21CF" }, + "nrarr;": { p: [8603], c: "\u219B" }, + "nrarrc;": { p: [10547, 824], c: "\u2933\u0338" }, + "nrarrw;": { p: [8605, 824], c: "\u219D\u0338" }, + "nrightarrow;": { p: [8603], c: "\u219B" }, + "nrtri;": { p: [8939], c: "\u22EB" }, + "nrtrie;": { p: [8941], c: "\u22ED" }, + "nsc;": { p: [8833], c: "\u2281" }, + "nsccue;": { p: [8929], c: "\u22E1" }, + "nsce;": { p: [10928, 824], c: "\u2AB0\u0338" }, + "nscr;": { p: [120003], c: "\uD835\uDCC3" }, + "nshortmid;": { p: [8740], c: "\u2224" }, + "nshortparallel;": { p: [8742], c: "\u2226" }, + "nsim;": { p: [8769], c: "\u2241" }, + "nsime;": { p: [8772], c: "\u2244" }, + "nsimeq;": { p: [8772], c: "\u2244" }, + "nsmid;": { p: [8740], c: "\u2224" }, + "nspar;": { p: [8742], c: "\u2226" }, + "nsqsube;": { p: [8930], c: "\u22E2" }, + "nsqsupe;": { p: [8931], c: "\u22E3" }, + "nsub;": { p: [8836], c: "\u2284" }, + "nsubE;": { p: [10949, 824], c: "\u2AC5\u0338" }, + "nsube;": { p: [8840], c: "\u2288" }, + "nsubset;": { p: [8834, 8402], c: "\u2282\u20D2" }, + "nsubseteq;": { p: [8840], c: "\u2288" }, + "nsubseteqq;": { + p: [10949, 824], + c: "\u2AC5\u0338", + }, + "nsucc;": { p: [8833], c: "\u2281" }, + "nsucceq;": { p: [10928, 824], c: "\u2AB0\u0338" }, + "nsup;": { p: [8837], c: "\u2285" }, + "nsupE;": { p: [10950, 824], c: "\u2AC6\u0338" }, + "nsupe;": { p: [8841], c: "\u2289" }, + "nsupset;": { p: [8835, 8402], c: "\u2283\u20D2" }, + "nsupseteq;": { p: [8841], c: "\u2289" }, + "nsupseteqq;": { + p: [10950, 824], + c: "\u2AC6\u0338", + }, + "ntgl;": { p: [8825], c: "\u2279" }, + ntilde: { p: [241], c: "\u00F1" }, + "ntilde;": { p: [241], c: "\u00F1" }, + "ntlg;": { p: [8824], c: "\u2278" }, + "ntriangleleft;": { p: [8938], c: "\u22EA" }, + "ntrianglelefteq;": { p: [8940], c: "\u22EC" }, + "ntriangleright;": { p: [8939], c: "\u22EB" }, + "ntrianglerighteq;": { p: [8941], c: "\u22ED" }, + "nu;": { p: [957], c: "\u03BD" }, + "num;": { p: [35], c: "\u0023" }, + "numero;": { p: [8470], c: "\u2116" }, + "numsp;": { p: [8199], c: "\u2007" }, + "nvDash;": { p: [8877], c: "\u22AD" }, + "nvHarr;": { p: [10500], c: "\u2904" }, + "nvap;": { p: [8781, 8402], c: "\u224D\u20D2" }, + "nvdash;": { p: [8876], c: "\u22AC" }, + "nvge;": { p: [8805, 8402], c: "\u2265\u20D2" }, + "nvgt;": { p: [62, 8402], c: "\u003E\u20D2" }, + "nvinfin;": { p: [10718], c: "\u29DE" }, + "nvlArr;": { p: [10498], c: "\u2902" }, + "nvle;": { p: [8804, 8402], c: "\u2264\u20D2" }, + "nvlt;": { p: [60, 8402], c: "\u003C\u20D2" }, + "nvltrie;": { p: [8884, 8402], c: "\u22B4\u20D2" }, + "nvrArr;": { p: [10499], c: "\u2903" }, + "nvrtrie;": { p: [8885, 8402], c: "\u22B5\u20D2" }, + "nvsim;": { p: [8764, 8402], c: "\u223C\u20D2" }, + "nwArr;": { p: [8662], c: "\u21D6" }, + "nwarhk;": { p: [10531], c: "\u2923" }, + "nwarr;": { p: [8598], c: "\u2196" }, + "nwarrow;": { p: [8598], c: "\u2196" }, + "nwnear;": { p: [10535], c: "\u2927" }, + "oS;": { p: [9416], c: "\u24C8" }, + oacute: { p: [243], c: "\u00F3" }, + "oacute;": { p: [243], c: "\u00F3" }, + "oast;": { p: [8859], c: "\u229B" }, + "ocir;": { p: [8858], c: "\u229A" }, + ocirc: { p: [244], c: "\u00F4" }, + "ocirc;": { p: [244], c: "\u00F4" }, + "ocy;": { p: [1086], c: "\u043E" }, + "odash;": { p: [8861], c: "\u229D" }, + "odblac;": { p: [337], c: "\u0151" }, + "odiv;": { p: [10808], c: "\u2A38" }, + "odot;": { p: [8857], c: "\u2299" }, + "odsold;": { p: [10684], c: "\u29BC" }, + "oelig;": { p: [339], c: "\u0153" }, + "ofcir;": { p: [10687], c: "\u29BF" }, + "ofr;": { p: [120108], c: "\uD835\uDD2C" }, + "ogon;": { p: [731], c: "\u02DB" }, + ograve: { p: [242], c: "\u00F2" }, + "ograve;": { p: [242], c: "\u00F2" }, + "ogt;": { p: [10689], c: "\u29C1" }, + "ohbar;": { p: [10677], c: "\u29B5" }, + "ohm;": { p: [937], c: "\u03A9" }, + "oint;": { p: [8750], c: "\u222E" }, + "olarr;": { p: [8634], c: "\u21BA" }, + "olcir;": { p: [10686], c: "\u29BE" }, + "olcross;": { p: [10683], c: "\u29BB" }, + "oline;": { p: [8254], c: "\u203E" }, + "olt;": { p: [10688], c: "\u29C0" }, + "omacr;": { p: [333], c: "\u014D" }, + "omega;": { p: [969], c: "\u03C9" }, + "omicron;": { p: [959], c: "\u03BF" }, + "omid;": { p: [10678], c: "\u29B6" }, + "ominus;": { p: [8854], c: "\u2296" }, + "oopf;": { p: [120160], c: "\uD835\uDD60" }, + "opar;": { p: [10679], c: "\u29B7" }, + "operp;": { p: [10681], c: "\u29B9" }, + "oplus;": { p: [8853], c: "\u2295" }, + "or;": { p: [8744], c: "\u2228" }, + "orarr;": { p: [8635], c: "\u21BB" }, + "ord;": { p: [10845], c: "\u2A5D" }, + "order;": { p: [8500], c: "\u2134" }, + "orderof;": { p: [8500], c: "\u2134" }, + ordf: { p: [170], c: "\u00AA" }, + "ordf;": { p: [170], c: "\u00AA" }, + ordm: { p: [186], c: "\u00BA" }, + "ordm;": { p: [186], c: "\u00BA" }, + "origof;": { p: [8886], c: "\u22B6" }, + "oror;": { p: [10838], c: "\u2A56" }, + "orslope;": { p: [10839], c: "\u2A57" }, + "orv;": { p: [10843], c: "\u2A5B" }, + "oscr;": { p: [8500], c: "\u2134" }, + oslash: { p: [248], c: "\u00F8" }, + "oslash;": { p: [248], c: "\u00F8" }, + "osol;": { p: [8856], c: "\u2298" }, + otilde: { p: [245], c: "\u00F5" }, + "otilde;": { p: [245], c: "\u00F5" }, + "otimes;": { p: [8855], c: "\u2297" }, + "otimesas;": { p: [10806], c: "\u2A36" }, + ouml: { p: [246], c: "\u00F6" }, + "ouml;": { p: [246], c: "\u00F6" }, + "ovbar;": { p: [9021], c: "\u233D" }, + "par;": { p: [8741], c: "\u2225" }, + para: { p: [182], c: "\u00B6" }, + "para;": { p: [182], c: "\u00B6" }, + "parallel;": { p: [8741], c: "\u2225" }, + "parsim;": { p: [10995], c: "\u2AF3" }, + "parsl;": { p: [11005], c: "\u2AFD" }, + "part;": { p: [8706], c: "\u2202" }, + "pcy;": { p: [1087], c: "\u043F" }, + "percnt;": { p: [37], c: "\u0025" }, + "period;": { p: [46], c: "\u002E" }, + "permil;": { p: [8240], c: "\u2030" }, + "perp;": { p: [8869], c: "\u22A5" }, + "pertenk;": { p: [8241], c: "\u2031" }, + "pfr;": { p: [120109], c: "\uD835\uDD2D" }, + "phi;": { p: [966], c: "\u03C6" }, + "phiv;": { p: [981], c: "\u03D5" }, + "phmmat;": { p: [8499], c: "\u2133" }, + "phone;": { p: [9742], c: "\u260E" }, + "pi;": { p: [960], c: "\u03C0" }, + "pitchfork;": { p: [8916], c: "\u22D4" }, + "piv;": { p: [982], c: "\u03D6" }, + "planck;": { p: [8463], c: "\u210F" }, + "planckh;": { p: [8462], c: "\u210E" }, + "plankv;": { p: [8463], c: "\u210F" }, + "plus;": { p: [43], c: "\u002B" }, + "plusacir;": { p: [10787], c: "\u2A23" }, + "plusb;": { p: [8862], c: "\u229E" }, + "pluscir;": { p: [10786], c: "\u2A22" }, + "plusdo;": { p: [8724], c: "\u2214" }, + "plusdu;": { p: [10789], c: "\u2A25" }, + "pluse;": { p: [10866], c: "\u2A72" }, + plusmn: { p: [177], c: "\u00B1" }, + "plusmn;": { p: [177], c: "\u00B1" }, + "plussim;": { p: [10790], c: "\u2A26" }, + "plustwo;": { p: [10791], c: "\u2A27" }, + "pm;": { p: [177], c: "\u00B1" }, + "pointint;": { p: [10773], c: "\u2A15" }, + "popf;": { p: [120161], c: "\uD835\uDD61" }, + pound: { p: [163], c: "\u00A3" }, + "pound;": { p: [163], c: "\u00A3" }, + "pr;": { p: [8826], c: "\u227A" }, + "prE;": { p: [10931], c: "\u2AB3" }, + "prap;": { p: [10935], c: "\u2AB7" }, + "prcue;": { p: [8828], c: "\u227C" }, + "pre;": { p: [10927], c: "\u2AAF" }, + "prec;": { p: [8826], c: "\u227A" }, + "precapprox;": { p: [10935], c: "\u2AB7" }, + "preccurlyeq;": { p: [8828], c: "\u227C" }, + "preceq;": { p: [10927], c: "\u2AAF" }, + "precnapprox;": { p: [10937], c: "\u2AB9" }, + "precneqq;": { p: [10933], c: "\u2AB5" }, + "precnsim;": { p: [8936], c: "\u22E8" }, + "precsim;": { p: [8830], c: "\u227E" }, + "prime;": { p: [8242], c: "\u2032" }, + "primes;": { p: [8473], c: "\u2119" }, + "prnE;": { p: [10933], c: "\u2AB5" }, + "prnap;": { p: [10937], c: "\u2AB9" }, + "prnsim;": { p: [8936], c: "\u22E8" }, + "prod;": { p: [8719], c: "\u220F" }, + "profalar;": { p: [9006], c: "\u232E" }, + "profline;": { p: [8978], c: "\u2312" }, + "profsurf;": { p: [8979], c: "\u2313" }, + "prop;": { p: [8733], c: "\u221D" }, + "propto;": { p: [8733], c: "\u221D" }, + "prsim;": { p: [8830], c: "\u227E" }, + "prurel;": { p: [8880], c: "\u22B0" }, + "pscr;": { p: [120005], c: "\uD835\uDCC5" }, + "psi;": { p: [968], c: "\u03C8" }, + "puncsp;": { p: [8200], c: "\u2008" }, + "qfr;": { p: [120110], c: "\uD835\uDD2E" }, + "qint;": { p: [10764], c: "\u2A0C" }, + "qopf;": { p: [120162], c: "\uD835\uDD62" }, + "qprime;": { p: [8279], c: "\u2057" }, + "qscr;": { p: [120006], c: "\uD835\uDCC6" }, + "quaternions;": { p: [8461], c: "\u210D" }, + "quatint;": { p: [10774], c: "\u2A16" }, + "quest;": { p: [63], c: "\u003F" }, + "questeq;": { p: [8799], c: "\u225F" }, + quot: { p: [34], c: "\u0022" }, + "quot;": { p: [34], c: "\u0022" }, + "rAarr;": { p: [8667], c: "\u21DB" }, + "rArr;": { p: [8658], c: "\u21D2" }, + "rAtail;": { p: [10524], c: "\u291C" }, + "rBarr;": { p: [10511], c: "\u290F" }, + "rHar;": { p: [10596], c: "\u2964" }, + "race;": { p: [8765, 817], c: "\u223D\u0331" }, + "racute;": { p: [341], c: "\u0155" }, + "radic;": { p: [8730], c: "\u221A" }, + "raemptyv;": { p: [10675], c: "\u29B3" }, + "rang;": { p: [10217], c: "\u27E9" }, + "rangd;": { p: [10642], c: "\u2992" }, + "range;": { p: [10661], c: "\u29A5" }, + "rangle;": { p: [10217], c: "\u27E9" }, + raquo: { p: [187], c: "\u00BB" }, + "raquo;": { p: [187], c: "\u00BB" }, + "rarr;": { p: [8594], c: "\u2192" }, + "rarrap;": { p: [10613], c: "\u2975" }, + "rarrb;": { p: [8677], c: "\u21E5" }, + "rarrbfs;": { p: [10528], c: "\u2920" }, + "rarrc;": { p: [10547], c: "\u2933" }, + "rarrfs;": { p: [10526], c: "\u291E" }, + "rarrhk;": { p: [8618], c: "\u21AA" }, + "rarrlp;": { p: [8620], c: "\u21AC" }, + "rarrpl;": { p: [10565], c: "\u2945" }, + "rarrsim;": { p: [10612], c: "\u2974" }, + "rarrtl;": { p: [8611], c: "\u21A3" }, + "rarrw;": { p: [8605], c: "\u219D" }, + "ratail;": { p: [10522], c: "\u291A" }, + "ratio;": { p: [8758], c: "\u2236" }, + "rationals;": { p: [8474], c: "\u211A" }, + "rbarr;": { p: [10509], c: "\u290D" }, + "rbbrk;": { p: [10099], c: "\u2773" }, + "rbrace;": { p: [125], c: "\u007D" }, + "rbrack;": { p: [93], c: "\u005D" }, + "rbrke;": { p: [10636], c: "\u298C" }, + "rbrksld;": { p: [10638], c: "\u298E" }, + "rbrkslu;": { p: [10640], c: "\u2990" }, + "rcaron;": { p: [345], c: "\u0159" }, + "rcedil;": { p: [343], c: "\u0157" }, + "rceil;": { p: [8969], c: "\u2309" }, + "rcub;": { p: [125], c: "\u007D" }, + "rcy;": { p: [1088], c: "\u0440" }, + "rdca;": { p: [10551], c: "\u2937" }, + "rdldhar;": { p: [10601], c: "\u2969" }, + "rdquo;": { p: [8221], c: "\u201D" }, + "rdquor;": { p: [8221], c: "\u201D" }, + "rdsh;": { p: [8627], c: "\u21B3" }, + "real;": { p: [8476], c: "\u211C" }, + "realine;": { p: [8475], c: "\u211B" }, + "realpart;": { p: [8476], c: "\u211C" }, + "reals;": { p: [8477], c: "\u211D" }, + "rect;": { p: [9645], c: "\u25AD" }, + reg: { p: [174], c: "\u00AE" }, + "reg;": { p: [174], c: "\u00AE" }, + "rfisht;": { p: [10621], c: "\u297D" }, + "rfloor;": { p: [8971], c: "\u230B" }, + "rfr;": { p: [120111], c: "\uD835\uDD2F" }, + "rhard;": { p: [8641], c: "\u21C1" }, + "rharu;": { p: [8640], c: "\u21C0" }, + "rharul;": { p: [10604], c: "\u296C" }, + "rho;": { p: [961], c: "\u03C1" }, + "rhov;": { p: [1009], c: "\u03F1" }, + "rightarrow;": { p: [8594], c: "\u2192" }, + "rightarrowtail;": { p: [8611], c: "\u21A3" }, + "rightharpoondown;": { p: [8641], c: "\u21C1" }, + "rightharpoonup;": { p: [8640], c: "\u21C0" }, + "rightleftarrows;": { p: [8644], c: "\u21C4" }, + "rightleftharpoons;": { p: [8652], c: "\u21CC" }, + "rightrightarrows;": { p: [8649], c: "\u21C9" }, + "rightsquigarrow;": { p: [8605], c: "\u219D" }, + "rightthreetimes;": { p: [8908], c: "\u22CC" }, + "ring;": { p: [730], c: "\u02DA" }, + "risingdotseq;": { p: [8787], c: "\u2253" }, + "rlarr;": { p: [8644], c: "\u21C4" }, + "rlhar;": { p: [8652], c: "\u21CC" }, + "rlm;": { p: [8207], c: "\u200F" }, + "rmoust;": { p: [9137], c: "\u23B1" }, + "rmoustache;": { p: [9137], c: "\u23B1" }, + "rnmid;": { p: [10990], c: "\u2AEE" }, + "roang;": { p: [10221], c: "\u27ED" }, + "roarr;": { p: [8702], c: "\u21FE" }, + "robrk;": { p: [10215], c: "\u27E7" }, + "ropar;": { p: [10630], c: "\u2986" }, + "ropf;": { p: [120163], c: "\uD835\uDD63" }, + "roplus;": { p: [10798], c: "\u2A2E" }, + "rotimes;": { p: [10805], c: "\u2A35" }, + "rpar;": { p: [41], c: "\u0029" }, + "rpargt;": { p: [10644], c: "\u2994" }, + "rppolint;": { p: [10770], c: "\u2A12" }, + "rrarr;": { p: [8649], c: "\u21C9" }, + "rsaquo;": { p: [8250], c: "\u203A" }, + "rscr;": { p: [120007], c: "\uD835\uDCC7" }, + "rsh;": { p: [8625], c: "\u21B1" }, + "rsqb;": { p: [93], c: "\u005D" }, + "rsquo;": { p: [8217], c: "\u2019" }, + "rsquor;": { p: [8217], c: "\u2019" }, + "rthree;": { p: [8908], c: "\u22CC" }, + "rtimes;": { p: [8906], c: "\u22CA" }, + "rtri;": { p: [9657], c: "\u25B9" }, + "rtrie;": { p: [8885], c: "\u22B5" }, + "rtrif;": { p: [9656], c: "\u25B8" }, + "rtriltri;": { p: [10702], c: "\u29CE" }, + "ruluhar;": { p: [10600], c: "\u2968" }, + "rx;": { p: [8478], c: "\u211E" }, + "sacute;": { p: [347], c: "\u015B" }, + "sbquo;": { p: [8218], c: "\u201A" }, + "sc;": { p: [8827], c: "\u227B" }, + "scE;": { p: [10932], c: "\u2AB4" }, + "scap;": { p: [10936], c: "\u2AB8" }, + "scaron;": { p: [353], c: "\u0161" }, + "sccue;": { p: [8829], c: "\u227D" }, + "sce;": { p: [10928], c: "\u2AB0" }, + "scedil;": { p: [351], c: "\u015F" }, + "scirc;": { p: [349], c: "\u015D" }, + "scnE;": { p: [10934], c: "\u2AB6" }, + "scnap;": { p: [10938], c: "\u2ABA" }, + "scnsim;": { p: [8937], c: "\u22E9" }, + "scpolint;": { p: [10771], c: "\u2A13" }, + "scsim;": { p: [8831], c: "\u227F" }, + "scy;": { p: [1089], c: "\u0441" }, + "sdot;": { p: [8901], c: "\u22C5" }, + "sdotb;": { p: [8865], c: "\u22A1" }, + "sdote;": { p: [10854], c: "\u2A66" }, + "seArr;": { p: [8664], c: "\u21D8" }, + "searhk;": { p: [10533], c: "\u2925" }, + "searr;": { p: [8600], c: "\u2198" }, + "searrow;": { p: [8600], c: "\u2198" }, + sect: { p: [167], c: "\u00A7" }, + "sect;": { p: [167], c: "\u00A7" }, + "semi;": { p: [59], c: "\u003B" }, + "seswar;": { p: [10537], c: "\u2929" }, + "setminus;": { p: [8726], c: "\u2216" }, + "setmn;": { p: [8726], c: "\u2216" }, + "sext;": { p: [10038], c: "\u2736" }, + "sfr;": { p: [120112], c: "\uD835\uDD30" }, + "sfrown;": { p: [8994], c: "\u2322" }, + "sharp;": { p: [9839], c: "\u266F" }, + "shchcy;": { p: [1097], c: "\u0449" }, + "shcy;": { p: [1096], c: "\u0448" }, + "shortmid;": { p: [8739], c: "\u2223" }, + "shortparallel;": { p: [8741], c: "\u2225" }, + shy: { p: [173], c: "\u00AD" }, + "shy;": { p: [173], c: "\u00AD" }, + "sigma;": { p: [963], c: "\u03C3" }, + "sigmaf;": { p: [962], c: "\u03C2" }, + "sigmav;": { p: [962], c: "\u03C2" }, + "sim;": { p: [8764], c: "\u223C" }, + "simdot;": { p: [10858], c: "\u2A6A" }, + "sime;": { p: [8771], c: "\u2243" }, + "simeq;": { p: [8771], c: "\u2243" }, + "simg;": { p: [10910], c: "\u2A9E" }, + "simgE;": { p: [10912], c: "\u2AA0" }, + "siml;": { p: [10909], c: "\u2A9D" }, + "simlE;": { p: [10911], c: "\u2A9F" }, + "simne;": { p: [8774], c: "\u2246" }, + "simplus;": { p: [10788], c: "\u2A24" }, + "simrarr;": { p: [10610], c: "\u2972" }, + "slarr;": { p: [8592], c: "\u2190" }, + "smallsetminus;": { p: [8726], c: "\u2216" }, + "smashp;": { p: [10803], c: "\u2A33" }, + "smeparsl;": { p: [10724], c: "\u29E4" }, + "smid;": { p: [8739], c: "\u2223" }, + "smile;": { p: [8995], c: "\u2323" }, + "smt;": { p: [10922], c: "\u2AAA" }, + "smte;": { p: [10924], c: "\u2AAC" }, + "smtes;": { p: [10924, 65024], c: "\u2AAC\uFE00" }, + "softcy;": { p: [1100], c: "\u044C" }, + "sol;": { p: [47], c: "\u002F" }, + "solb;": { p: [10692], c: "\u29C4" }, + "solbar;": { p: [9023], c: "\u233F" }, + "sopf;": { p: [120164], c: "\uD835\uDD64" }, + "spades;": { p: [9824], c: "\u2660" }, + "spadesuit;": { p: [9824], c: "\u2660" }, + "spar;": { p: [8741], c: "\u2225" }, + "sqcap;": { p: [8851], c: "\u2293" }, + "sqcaps;": { p: [8851, 65024], c: "\u2293\uFE00" }, + "sqcup;": { p: [8852], c: "\u2294" }, + "sqcups;": { p: [8852, 65024], c: "\u2294\uFE00" }, + "sqsub;": { p: [8847], c: "\u228F" }, + "sqsube;": { p: [8849], c: "\u2291" }, + "sqsubset;": { p: [8847], c: "\u228F" }, + "sqsubseteq;": { p: [8849], c: "\u2291" }, + "sqsup;": { p: [8848], c: "\u2290" }, + "sqsupe;": { p: [8850], c: "\u2292" }, + "sqsupset;": { p: [8848], c: "\u2290" }, + "sqsupseteq;": { p: [8850], c: "\u2292" }, + "squ;": { p: [9633], c: "\u25A1" }, + "square;": { p: [9633], c: "\u25A1" }, + "squarf;": { p: [9642], c: "\u25AA" }, + "squf;": { p: [9642], c: "\u25AA" }, + "srarr;": { p: [8594], c: "\u2192" }, + "sscr;": { p: [120008], c: "\uD835\uDCC8" }, + "ssetmn;": { p: [8726], c: "\u2216" }, + "ssmile;": { p: [8995], c: "\u2323" }, + "sstarf;": { p: [8902], c: "\u22C6" }, + "star;": { p: [9734], c: "\u2606" }, + "starf;": { p: [9733], c: "\u2605" }, + "straightepsilon;": { p: [1013], c: "\u03F5" }, + "straightphi;": { p: [981], c: "\u03D5" }, + "strns;": { p: [175], c: "\u00AF" }, + "sub;": { p: [8834], c: "\u2282" }, + "subE;": { p: [10949], c: "\u2AC5" }, + "subdot;": { p: [10941], c: "\u2ABD" }, + "sube;": { p: [8838], c: "\u2286" }, + "subedot;": { p: [10947], c: "\u2AC3" }, + "submult;": { p: [10945], c: "\u2AC1" }, + "subnE;": { p: [10955], c: "\u2ACB" }, + "subne;": { p: [8842], c: "\u228A" }, + "subplus;": { p: [10943], c: "\u2ABF" }, + "subrarr;": { p: [10617], c: "\u2979" }, + "subset;": { p: [8834], c: "\u2282" }, + "subseteq;": { p: [8838], c: "\u2286" }, + "subseteqq;": { p: [10949], c: "\u2AC5" }, + "subsetneq;": { p: [8842], c: "\u228A" }, + "subsetneqq;": { p: [10955], c: "\u2ACB" }, + "subsim;": { p: [10951], c: "\u2AC7" }, + "subsub;": { p: [10965], c: "\u2AD5" }, + "subsup;": { p: [10963], c: "\u2AD3" }, + "succ;": { p: [8827], c: "\u227B" }, + "succapprox;": { p: [10936], c: "\u2AB8" }, + "succcurlyeq;": { p: [8829], c: "\u227D" }, + "succeq;": { p: [10928], c: "\u2AB0" }, + "succnapprox;": { p: [10938], c: "\u2ABA" }, + "succneqq;": { p: [10934], c: "\u2AB6" }, + "succnsim;": { p: [8937], c: "\u22E9" }, + "succsim;": { p: [8831], c: "\u227F" }, + "sum;": { p: [8721], c: "\u2211" }, + "sung;": { p: [9834], c: "\u266A" }, + sup1: { p: [185], c: "\u00B9" }, + "sup1;": { p: [185], c: "\u00B9" }, + sup2: { p: [178], c: "\u00B2" }, + "sup2;": { p: [178], c: "\u00B2" }, + sup3: { p: [179], c: "\u00B3" }, + "sup3;": { p: [179], c: "\u00B3" }, + "sup;": { p: [8835], c: "\u2283" }, + "supE;": { p: [10950], c: "\u2AC6" }, + "supdot;": { p: [10942], c: "\u2ABE" }, + "supdsub;": { p: [10968], c: "\u2AD8" }, + "supe;": { p: [8839], c: "\u2287" }, + "supedot;": { p: [10948], c: "\u2AC4" }, + "suphsol;": { p: [10185], c: "\u27C9" }, + "suphsub;": { p: [10967], c: "\u2AD7" }, + "suplarr;": { p: [10619], c: "\u297B" }, + "supmult;": { p: [10946], c: "\u2AC2" }, + "supnE;": { p: [10956], c: "\u2ACC" }, + "supne;": { p: [8843], c: "\u228B" }, + "supplus;": { p: [10944], c: "\u2AC0" }, + "supset;": { p: [8835], c: "\u2283" }, + "supseteq;": { p: [8839], c: "\u2287" }, + "supseteqq;": { p: [10950], c: "\u2AC6" }, + "supsetneq;": { p: [8843], c: "\u228B" }, + "supsetneqq;": { p: [10956], c: "\u2ACC" }, + "supsim;": { p: [10952], c: "\u2AC8" }, + "supsub;": { p: [10964], c: "\u2AD4" }, + "supsup;": { p: [10966], c: "\u2AD6" }, + "swArr;": { p: [8665], c: "\u21D9" }, + "swarhk;": { p: [10534], c: "\u2926" }, + "swarr;": { p: [8601], c: "\u2199" }, + "swarrow;": { p: [8601], c: "\u2199" }, + "swnwar;": { p: [10538], c: "\u292A" }, + szlig: { p: [223], c: "\u00DF" }, + "szlig;": { p: [223], c: "\u00DF" }, + "target;": { p: [8982], c: "\u2316" }, + "tau;": { p: [964], c: "\u03C4" }, + "tbrk;": { p: [9140], c: "\u23B4" }, + "tcaron;": { p: [357], c: "\u0165" }, + "tcedil;": { p: [355], c: "\u0163" }, + "tcy;": { p: [1090], c: "\u0442" }, + "tdot;": { p: [8411], c: "\u20DB" }, + "telrec;": { p: [8981], c: "\u2315" }, + "tfr;": { p: [120113], c: "\uD835\uDD31" }, + "there4;": { p: [8756], c: "\u2234" }, + "therefore;": { p: [8756], c: "\u2234" }, + "theta;": { p: [952], c: "\u03B8" }, + "thetasym;": { p: [977], c: "\u03D1" }, + "thetav;": { p: [977], c: "\u03D1" }, + "thickapprox;": { p: [8776], c: "\u2248" }, + "thicksim;": { p: [8764], c: "\u223C" }, + "thinsp;": { p: [8201], c: "\u2009" }, + "thkap;": { p: [8776], c: "\u2248" }, + "thksim;": { p: [8764], c: "\u223C" }, + thorn: { p: [254], c: "\u00FE" }, + "thorn;": { p: [254], c: "\u00FE" }, + "tilde;": { p: [732], c: "\u02DC" }, + times: { p: [215], c: "\u00D7" }, + "times;": { p: [215], c: "\u00D7" }, + "timesb;": { p: [8864], c: "\u22A0" }, + "timesbar;": { p: [10801], c: "\u2A31" }, + "timesd;": { p: [10800], c: "\u2A30" }, + "tint;": { p: [8749], c: "\u222D" }, + "toea;": { p: [10536], c: "\u2928" }, + "top;": { p: [8868], c: "\u22A4" }, + "topbot;": { p: [9014], c: "\u2336" }, + "topcir;": { p: [10993], c: "\u2AF1" }, + "topf;": { p: [120165], c: "\uD835\uDD65" }, + "topfork;": { p: [10970], c: "\u2ADA" }, + "tosa;": { p: [10537], c: "\u2929" }, + "tprime;": { p: [8244], c: "\u2034" }, + "trade;": { p: [8482], c: "\u2122" }, + "triangle;": { p: [9653], c: "\u25B5" }, + "triangledown;": { p: [9663], c: "\u25BF" }, + "triangleleft;": { p: [9667], c: "\u25C3" }, + "trianglelefteq;": { p: [8884], c: "\u22B4" }, + "triangleq;": { p: [8796], c: "\u225C" }, + "triangleright;": { p: [9657], c: "\u25B9" }, + "trianglerighteq;": { p: [8885], c: "\u22B5" }, + "tridot;": { p: [9708], c: "\u25EC" }, + "trie;": { p: [8796], c: "\u225C" }, + "triminus;": { p: [10810], c: "\u2A3A" }, + "triplus;": { p: [10809], c: "\u2A39" }, + "trisb;": { p: [10701], c: "\u29CD" }, + "tritime;": { p: [10811], c: "\u2A3B" }, + "trpezium;": { p: [9186], c: "\u23E2" }, + "tscr;": { p: [120009], c: "\uD835\uDCC9" }, + "tscy;": { p: [1094], c: "\u0446" }, + "tshcy;": { p: [1115], c: "\u045B" }, + "tstrok;": { p: [359], c: "\u0167" }, + "twixt;": { p: [8812], c: "\u226C" }, + "twoheadleftarrow;": { p: [8606], c: "\u219E" }, + "twoheadrightarrow;": { p: [8608], c: "\u21A0" }, + "uArr;": { p: [8657], c: "\u21D1" }, + "uHar;": { p: [10595], c: "\u2963" }, + uacute: { p: [250], c: "\u00FA" }, + "uacute;": { p: [250], c: "\u00FA" }, + "uarr;": { p: [8593], c: "\u2191" }, + "ubrcy;": { p: [1118], c: "\u045E" }, + "ubreve;": { p: [365], c: "\u016D" }, + ucirc: { p: [251], c: "\u00FB" }, + "ucirc;": { p: [251], c: "\u00FB" }, + "ucy;": { p: [1091], c: "\u0443" }, + "udarr;": { p: [8645], c: "\u21C5" }, + "udblac;": { p: [369], c: "\u0171" }, + "udhar;": { p: [10606], c: "\u296E" }, + "ufisht;": { p: [10622], c: "\u297E" }, + "ufr;": { p: [120114], c: "\uD835\uDD32" }, + ugrave: { p: [249], c: "\u00F9" }, + "ugrave;": { p: [249], c: "\u00F9" }, + "uharl;": { p: [8639], c: "\u21BF" }, + "uharr;": { p: [8638], c: "\u21BE" }, + "uhblk;": { p: [9600], c: "\u2580" }, + "ulcorn;": { p: [8988], c: "\u231C" }, + "ulcorner;": { p: [8988], c: "\u231C" }, + "ulcrop;": { p: [8975], c: "\u230F" }, + "ultri;": { p: [9720], c: "\u25F8" }, + "umacr;": { p: [363], c: "\u016B" }, + uml: { p: [168], c: "\u00A8" }, + "uml;": { p: [168], c: "\u00A8" }, + "uogon;": { p: [371], c: "\u0173" }, + "uopf;": { p: [120166], c: "\uD835\uDD66" }, + "uparrow;": { p: [8593], c: "\u2191" }, + "updownarrow;": { p: [8597], c: "\u2195" }, + "upharpoonleft;": { p: [8639], c: "\u21BF" }, + "upharpoonright;": { p: [8638], c: "\u21BE" }, + "uplus;": { p: [8846], c: "\u228E" }, + "upsi;": { p: [965], c: "\u03C5" }, + "upsih;": { p: [978], c: "\u03D2" }, + "upsilon;": { p: [965], c: "\u03C5" }, + "upuparrows;": { p: [8648], c: "\u21C8" }, + "urcorn;": { p: [8989], c: "\u231D" }, + "urcorner;": { p: [8989], c: "\u231D" }, + "urcrop;": { p: [8974], c: "\u230E" }, + "uring;": { p: [367], c: "\u016F" }, + "urtri;": { p: [9721], c: "\u25F9" }, + "uscr;": { p: [120010], c: "\uD835\uDCCA" }, + "utdot;": { p: [8944], c: "\u22F0" }, + "utilde;": { p: [361], c: "\u0169" }, + "utri;": { p: [9653], c: "\u25B5" }, + "utrif;": { p: [9652], c: "\u25B4" }, + "uuarr;": { p: [8648], c: "\u21C8" }, + uuml: { p: [252], c: "\u00FC" }, + "uuml;": { p: [252], c: "\u00FC" }, + "uwangle;": { p: [10663], c: "\u29A7" }, + "vArr;": { p: [8661], c: "\u21D5" }, + "vBar;": { p: [10984], c: "\u2AE8" }, + "vBarv;": { p: [10985], c: "\u2AE9" }, + "vDash;": { p: [8872], c: "\u22A8" }, + "vangrt;": { p: [10652], c: "\u299C" }, + "varepsilon;": { p: [1013], c: "\u03F5" }, + "varkappa;": { p: [1008], c: "\u03F0" }, + "varnothing;": { p: [8709], c: "\u2205" }, + "varphi;": { p: [981], c: "\u03D5" }, + "varpi;": { p: [982], c: "\u03D6" }, + "varpropto;": { p: [8733], c: "\u221D" }, + "varr;": { p: [8597], c: "\u2195" }, + "varrho;": { p: [1009], c: "\u03F1" }, + "varsigma;": { p: [962], c: "\u03C2" }, + "varsubsetneq;": { + p: [8842, 65024], + c: "\u228A\uFE00", + }, + "varsubsetneqq;": { + p: [10955, 65024], + c: "\u2ACB\uFE00", + }, + "varsupsetneq;": { + p: [8843, 65024], + c: "\u228B\uFE00", + }, + "varsupsetneqq;": { + p: [10956, 65024], + c: "\u2ACC\uFE00", + }, + "vartheta;": { p: [977], c: "\u03D1" }, + "vartriangleleft;": { p: [8882], c: "\u22B2" }, + "vartriangleright;": { p: [8883], c: "\u22B3" }, + "vcy;": { p: [1074], c: "\u0432" }, + "vdash;": { p: [8866], c: "\u22A2" }, + "vee;": { p: [8744], c: "\u2228" }, + "veebar;": { p: [8891], c: "\u22BB" }, + "veeeq;": { p: [8794], c: "\u225A" }, + "vellip;": { p: [8942], c: "\u22EE" }, + "verbar;": { p: [124], c: "\u007C" }, + "vert;": { p: [124], c: "\u007C" }, + "vfr;": { p: [120115], c: "\uD835\uDD33" }, + "vltri;": { p: [8882], c: "\u22B2" }, + "vnsub;": { p: [8834, 8402], c: "\u2282\u20D2" }, + "vnsup;": { p: [8835, 8402], c: "\u2283\u20D2" }, + "vopf;": { p: [120167], c: "\uD835\uDD67" }, + "vprop;": { p: [8733], c: "\u221D" }, + "vrtri;": { p: [8883], c: "\u22B3" }, + "vscr;": { p: [120011], c: "\uD835\uDCCB" }, + "vsubnE;": { p: [10955, 65024], c: "\u2ACB\uFE00" }, + "vsubne;": { p: [8842, 65024], c: "\u228A\uFE00" }, + "vsupnE;": { p: [10956, 65024], c: "\u2ACC\uFE00" }, + "vsupne;": { p: [8843, 65024], c: "\u228B\uFE00" }, + "vzigzag;": { p: [10650], c: "\u299A" }, + "wcirc;": { p: [373], c: "\u0175" }, + "wedbar;": { p: [10847], c: "\u2A5F" }, + "wedge;": { p: [8743], c: "\u2227" }, + "wedgeq;": { p: [8793], c: "\u2259" }, + "weierp;": { p: [8472], c: "\u2118" }, + "wfr;": { p: [120116], c: "\uD835\uDD34" }, + "wopf;": { p: [120168], c: "\uD835\uDD68" }, + "wp;": { p: [8472], c: "\u2118" }, + "wr;": { p: [8768], c: "\u2240" }, + "wreath;": { p: [8768], c: "\u2240" }, + "wscr;": { p: [120012], c: "\uD835\uDCCC" }, + "xcap;": { p: [8898], c: "\u22C2" }, + "xcirc;": { p: [9711], c: "\u25EF" }, + "xcup;": { p: [8899], c: "\u22C3" }, + "xdtri;": { p: [9661], c: "\u25BD" }, + "xfr;": { p: [120117], c: "\uD835\uDD35" }, + "xhArr;": { p: [10234], c: "\u27FA" }, + "xharr;": { p: [10231], c: "\u27F7" }, + "xi;": { p: [958], c: "\u03BE" }, + "xlArr;": { p: [10232], c: "\u27F8" }, + "xlarr;": { p: [10229], c: "\u27F5" }, + "xmap;": { p: [10236], c: "\u27FC" }, + "xnis;": { p: [8955], c: "\u22FB" }, + "xodot;": { p: [10752], c: "\u2A00" }, + "xopf;": { p: [120169], c: "\uD835\uDD69" }, + "xoplus;": { p: [10753], c: "\u2A01" }, + "xotime;": { p: [10754], c: "\u2A02" }, + "xrArr;": { p: [10233], c: "\u27F9" }, + "xrarr;": { p: [10230], c: "\u27F6" }, + "xscr;": { p: [120013], c: "\uD835\uDCCD" }, + "xsqcup;": { p: [10758], c: "\u2A06" }, + "xuplus;": { p: [10756], c: "\u2A04" }, + "xutri;": { p: [9651], c: "\u25B3" }, + "xvee;": { p: [8897], c: "\u22C1" }, + "xwedge;": { p: [8896], c: "\u22C0" }, + yacute: { p: [253], c: "\u00FD" }, + "yacute;": { p: [253], c: "\u00FD" }, + "yacy;": { p: [1103], c: "\u044F" }, + "ycirc;": { p: [375], c: "\u0177" }, + "ycy;": { p: [1099], c: "\u044B" }, + yen: { p: [165], c: "\u00A5" }, + "yen;": { p: [165], c: "\u00A5" }, + "yfr;": { p: [120118], c: "\uD835\uDD36" }, + "yicy;": { p: [1111], c: "\u0457" }, + "yopf;": { p: [120170], c: "\uD835\uDD6A" }, + "yscr;": { p: [120014], c: "\uD835\uDCCE" }, + "yucy;": { p: [1102], c: "\u044E" }, + yuml: { p: [255], c: "\u00FF" }, + "yuml;": { p: [255], c: "\u00FF" }, + "zacute;": { p: [378], c: "\u017A" }, + "zcaron;": { p: [382], c: "\u017E" }, + "zcy;": { p: [1079], c: "\u0437" }, + "zdot;": { p: [380], c: "\u017C" }, + "zeetrf;": { p: [8488], c: "\u2128" }, + "zeta;": { p: [950], c: "\u03B6" }, + "zfr;": { p: [120119], c: "\uD835\uDD37" }, + "zhcy;": { p: [1078], c: "\u0436" }, + "zigrarr;": { p: [8669], c: "\u21DD" }, + "zopf;": { p: [120171], c: "\uD835\uDD6B" }, + "zscr;": { p: [120015], c: "\uD835\uDCCF" }, + "zwj;": { p: [8205], c: "\u200D" }, + "zwnj;": { p: [8204], c: "\u200C" }, +}; diff --git a/src/lib/utils/html.ts b/src/lib/utils/html.ts index a2c30dc67..5ac4abc88 100644 --- a/src/lib/utils/html.ts +++ b/src/lib/utils/html.ts @@ -1,8 +1,5 @@ -// There is a fixed list of named character references which will not be expanded in the future. -// This json file is based on https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references -// with some modifications to reduce the file size of the original JSON. import { assertNever } from "./general.js"; -import htmlEntities from "./html-entities.json"; +import { htmlEntities } from "./html-entities.js"; interface EntityData { /** code points associated with this escape */ diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 9fa27e6f3..8095e73a3 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -6,11 +6,7 @@ export { removeIfPresent, unique, } from "./array.js"; -export { - AbstractComponent, - ChildableComponent, - Component, -} from "./component.js"; +export { AbstractComponent } from "./component.js"; export * from "./enum.js"; export { EventDispatcher } from "./events.js"; export { From 31cb75092b68f704579dcf5a5191dba9fecf0fb9 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 19:22:10 -0600 Subject: [PATCH 007/219] Finish removing ts-node --- .config/mocha.full.json | 2 +- .config/mocha.test-explorer.json | 2 +- .github/workflows/publish.yml | 2 +- .vscode/launch.json | 3 +- package-lock.json | 141 ------------------ package.json | 1 - scripts/accept_visual_regression.js | 15 +- scripts/create_release.js | 23 ++- ...wnload_plugins.js => download_plugins.cjs} | 0 scripts/generate_options_schema.js | 35 ++--- scripts/rebuild_specs.js | 6 +- scripts/set_strict.js | 10 +- scripts/testcase.js | 10 +- .../internationalization.ts | 8 +- .../slow/internationalization-usage.test.ts | 20 +-- tsconfig.json | 8 +- 16 files changed, 67 insertions(+), 219 deletions(-) rename scripts/{download_plugins.js => download_plugins.cjs} (100%) diff --git a/.config/mocha.full.json b/.config/mocha.full.json index 641407a28..a7a780bed 100644 --- a/.config/mocha.full.json +++ b/.config/mocha.full.json @@ -3,5 +3,5 @@ "timeout": 0, "spec": ["src/test/**/*.test.ts", "src/test/**/*.test.tsx"], "exclude": ["src/test/packages/**"], - "require": ["ts-node/register"] + "node-option": ["import=tsx"] } diff --git a/.config/mocha.test-explorer.json b/.config/mocha.test-explorer.json index 980a101b0..801b9d3d0 100644 --- a/.config/mocha.test-explorer.json +++ b/.config/mocha.test-explorer.json @@ -3,7 +3,7 @@ "extension": ["ts"], "ignore": ["src/test/slow/**", "src/test/packages/**"], "package": "./package.json", - "require": "ts-node/register", + "node-option": ["import=tsx"], "slow": 500, "spec": ["src/**/*.test.ts", "src/**/*.test.tsx"], "timeout": 0, diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b364e0dbf..5f77f3da7 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -40,6 +40,6 @@ jobs: run: | git config user.email "typedoc@gerritbirkeland.com" git config user.name "TypeDoc Bot" - node scripts/create_release.js + node scripts/create_release.cjs env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.vscode/launch.json b/.vscode/launch.json index 1e9ea1e36..10b8b3635 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,8 +6,7 @@ "configurations": [ { "args": [ - "-r", - "ts-node/register", + "--import=tsx", "--timeout", "0", "--config", diff --git a/package-lock.json b/package-lock.json index 70d1dddb3..2651e1734 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "mocha": "^10.4.0", "prettier": "3.3.2", "puppeteer": "^22.12.0", - "ts-node": "^10.9.2", "tsx": "^4.15.7", "typescript": "5.5.2", "typescript-eslint": "^7.13.1" @@ -175,18 +174,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -864,16 +851,6 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -956,30 +933,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1270,15 +1223,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", @@ -1355,12 +1299,6 @@ "node": ">= 8" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1751,12 +1689,6 @@ } } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3014,12 +2946,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -4078,58 +4004,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", @@ -4261,12 +4135,6 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.2.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", @@ -4456,15 +4324,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 45525fa32..c6cc41be5 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "mocha": "^10.4.0", "prettier": "3.3.2", "puppeteer": "^22.12.0", - "ts-node": "^10.9.2", "tsx": "^4.15.7", "typescript-eslint": "^7.13.1", "typescript": "5.5.2" diff --git a/scripts/accept_visual_regression.js b/scripts/accept_visual_regression.js index a5ddd6709..70f5d9bd1 100644 --- a/scripts/accept_visual_regression.js +++ b/scripts/accept_visual_regression.js @@ -1,17 +1,10 @@ //@ts-check -require("ts-node/register"); - -const fs = require("fs/promises"); -const { copy } = require("../src/lib/utils/fs"); -const { join } = require("path"); +import fs from "fs/promises"; +import { join } from "path"; const expectedDir = join(__dirname, "../tmp/baseline"); const outputDir = join(__dirname, "../tmp/screenshots"); -fs.rm(expectedDir, { recursive: true, force: true }) - .then(() => copy(outputDir, expectedDir)) - .catch((err) => { - console.error(err); - process.exit(1); - }); +await fs.rm(expectedDir, { recursive: true, force: true }); +await fs.cp(outputDir, expectedDir, { recursive: true, force: true }); diff --git a/scripts/create_release.js b/scripts/create_release.js index 49456fc4e..2f12291ce 100644 --- a/scripts/create_release.js +++ b/scripts/create_release.js @@ -1,13 +1,22 @@ // @ts-check -const cp = require("child_process"); -const { join } = require("path"); -const https = require("https"); -const { readFile, writeFile } = require("fs/promises"); +import cp from "child_process"; +import { join } from "path"; +import https from "https"; +import { readFile, writeFile } from "fs/promises"; +import { fileURLToPath } from "url"; +import { readFileSync } from "fs"; const REMOTE = "origin"; const REPO = "TypeStrong/typedoc"; -const CHANGELOG_MD = join(__dirname, "../CHANGELOG.md"); +const CHANGELOG_MD = join(fileURLToPath(import.meta.url), "../../CHANGELOG.md"); + +const packageInfo = JSON.parse( + readFileSync( + join(fileURLToPath(import.meta.url), "../../package.json"), + "utf-8", + ), +); /** * @param {string} cmd @@ -62,9 +71,7 @@ async function createGitHubRelease(args) { async function main() { const lastTag = await exec("git describe --tags --abbrev=0"); - const currentVersion = `v${ - require(join(__dirname, "..", "package.json")).version - }`; + const currentVersion = `v${packageInfo.version}`; const [_major, _minor, patch] = currentVersion.substring(1).split("."); if (lastTag == currentVersion) { diff --git a/scripts/download_plugins.js b/scripts/download_plugins.cjs similarity index 100% rename from scripts/download_plugins.js rename to scripts/download_plugins.cjs diff --git a/scripts/generate_options_schema.js b/scripts/generate_options_schema.js index d3864252d..569023d1e 100644 --- a/scripts/generate_options_schema.js +++ b/scripts/generate_options_schema.js @@ -1,13 +1,9 @@ //@ts-check -require("ts-node/register"); - -const { writeFileSync } = require("fs"); -const { addTypeDocOptions } = require("../src/lib/utils/options/sources"); -const { ParameterType } = require("../src"); -const { - Internationalization, -} = require("../src/lib/internationalization/internationalization"); +import { writeFileSync } from "fs"; +import { ParameterType, Internationalization } from "../dist/index.js"; +import { addTypeDocOptions } from "../dist/lib/utils/options/sources/typedoc.js"; +import { SORT_STRATEGIES } from "../dist/lib/utils/sort.js"; const IGNORED_OPTIONS = new Set(["help", "version"]); @@ -21,10 +17,10 @@ const schema = { allowTrailingCommas: true, }; -const i18n = new Internationalization(null).proxy; +const i18n = new Internationalization.Internationalization(null).proxy; addTypeDocOptions({ - /** @param {import("../src").DeclarationOption} option */ + /** @param {import("../dist/index.js").DeclarationOption} option */ addDeclaration(option) { if (IGNORED_OPTIONS.has(option.name)) return; @@ -41,7 +37,7 @@ addTypeDocOptions({ data.type = "array"; data.items = { type: "string" }; data.default = - /** @type {import("../src").ArrayDeclarationOption} */ ( + /** @type {import("../dist/index.js").ArrayDeclarationOption} */ ( option ).defaultValue ?? []; break; @@ -50,7 +46,7 @@ addTypeDocOptions({ data.type = "string"; if (!IGNORED_DEFAULT_OPTIONS.has(option.name)) { data.default = - /** @type {import("../src").StringDeclarationOption} */ ( + /** @type {import("../dist/index.js").StringDeclarationOption} */ ( option ).defaultValue ?? ""; } @@ -58,13 +54,13 @@ addTypeDocOptions({ case ParameterType.Boolean: data.type = "boolean"; data.default = - /** @type {import("../src").BooleanDeclarationOption} */ ( + /** @type {import("../dist/index.js").BooleanDeclarationOption} */ ( option ).defaultValue ?? false; break; case ParameterType.Number: { const decl = - /** @type {import("../src").NumberDeclarationOption} */ ( + /** @type {import("../dist/index.js").NumberDeclarationOption} */ ( option ); data.type = "number"; @@ -75,7 +71,7 @@ addTypeDocOptions({ } case ParameterType.Map: { const map = - /** @type {import("../src").MapDeclarationOption} */ ( + /** @type {import("../dist/index.js").MapDeclarationOption} */ ( option ).map; data.enum = @@ -87,7 +83,7 @@ addTypeDocOptions({ typeof map[key] === "number" ? key : map[key], ); data.default = - /** @type {import("../src").MapDeclarationOption} */ ( + /** @type {import("../dist/index.js").MapDeclarationOption} */ ( option ).defaultValue; if (!data.enum.includes(data.default)) { @@ -108,7 +104,7 @@ addTypeDocOptions({ properties: {}, }; const defaults = - /** @type {import("../src").FlagsDeclarationOption>} */ ( + /** @type {import("../dist/index.js").FlagsDeclarationOption>} */ ( option ).defaults; @@ -124,7 +120,7 @@ addTypeDocOptions({ case ParameterType.Mixed: case ParameterType.Object: data.default = - /** @type {import("../src").MixedDeclarationOption} */ ( + /** @type {import("../dist/index.js").MixedDeclarationOption} */ ( option ).defaultValue; break; @@ -159,8 +155,7 @@ schema.properties.extends = { }; delete schema.properties.sort.items.type; -schema.properties.sort.items.enum = - require("../src/lib/utils/sort").SORT_STRATEGIES; +schema.properties.sort.items.enum = SORT_STRATEGIES; const output = JSON.stringify(schema, null, "\t"); diff --git a/scripts/rebuild_specs.js b/scripts/rebuild_specs.js index 3da78f1b0..ee3713ca7 100644 --- a/scripts/rebuild_specs.js +++ b/scripts/rebuild_specs.js @@ -10,7 +10,10 @@ import { getExpandedEntryPointsForPaths } from "../dist/lib/utils/index.js"; import { ok } from "assert"; import { fileURLToPath } from "url"; -const base = path.join(fileURLToPath(import.meta.url), "../../src/test/converter"); +const base = path.join( + fileURLToPath(import.meta.url), + "../../src/test/converter", +); async function getApp() { const app = await td.Application.bootstrap( @@ -50,6 +53,7 @@ async function getApp() { supports(obj) { return obj instanceof td.ProjectReflection; }, + /** @param {td.ProjectReflection} obj */ toObject(_refl, obj) { delete obj.packageVersion; return obj; diff --git a/scripts/set_strict.js b/scripts/set_strict.js index d811c6624..bf0ead168 100644 --- a/scripts/set_strict.js +++ b/scripts/set_strict.js @@ -2,10 +2,14 @@ // Sets the Strict type that TypeDoc uses to enable overloads for consumers only. // See the rationale in src/lib/utils/general.ts -const { promises: fs } = require("fs"); -const { join } = require("path"); +import fs from "fs/promises"; +import { join } from "path"; +import { fileURLToPath } from "url"; -const file = join(__dirname, "../src/lib/utils/general.ts"); +const file = join( + fileURLToPath(import.meta.dirname), + "../../src/lib/utils/general.ts", +); const isStrict = process.argv[2] === "true"; diff --git a/scripts/testcase.js b/scripts/testcase.js index e7063d15a..384c56bc0 100644 --- a/scripts/testcase.js +++ b/scripts/testcase.js @@ -1,7 +1,7 @@ // @ts-check -const md = require("markdown-it"); -const cp = require("child_process"); -const { writeFile } = require("fs/promises"); +import md from "markdown-it"; +import cp from "child_process"; +import { writeFile } from "fs/promises"; const curl = `curl -s -L -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/typestrong/typedoc/issues/ISSUE`; @@ -23,9 +23,9 @@ function exec(cmd) { }); } -/** @param {marked.marked.Tokens.Code} code */ +/** @param {import("markdown-it", { with: { "resolution-mode": "require" }}).Token} code */ function guessExtension(code) { - switch (code.lang) { + switch (code.info) { case "js": case "jsx": return ".js"; diff --git a/src/lib/internationalization/internationalization.ts b/src/lib/internationalization/internationalization.ts index ffb5a856c..283101ca0 100644 --- a/src/lib/internationalization/internationalization.ts +++ b/src/lib/internationalization/internationalization.ts @@ -59,12 +59,6 @@ export type TranslationProxy = { ) => TranslatedString; }; -// If we're running in ts-node, then we need the TS source rather than -// the compiled file. -const ext = process[Symbol.for("ts-node.register.instance") as never] - ? "cts" - : "cjs"; - /** * Simple internationalization module which supports placeholders. * See {@link TranslatableStrings} for a description of how this module works and how @@ -80,7 +74,7 @@ export class Internationalization { "Locale names may only contain letters and dashes", ); try { - return new Map(Object.entries(req(`./locales/${lang}.${ext}`))); + return new Map(Object.entries(req(`./locales/${lang}.cjs`))); } catch { return new Map(); } diff --git a/src/test/slow/internationalization-usage.test.ts b/src/test/slow/internationalization-usage.test.ts index edcc64815..68d0eafcc 100644 --- a/src/test/slow/internationalization-usage.test.ts +++ b/src/test/slow/internationalization-usage.test.ts @@ -12,9 +12,9 @@ describe("Internationalization", () => { const tsconfigReader = new TSConfigReader(); tsconfigReader.read(options, new Logger(), process.cwd()); - const translatableTs = join( + const defaultLocaleTs = join( fileURLToPath(import.meta.url), - "../../../lib/internationalization/translatable.ts", + "../../../lib/internationalization/locales/en.cts", ); const host: ts.LanguageServiceHost = { @@ -44,24 +44,24 @@ describe("Internationalization", () => { const program = service.getProgram(); ok(program, "Failed to get program for i18n analysis"); - const sf = program.getSourceFile(translatableTs); + const sf = program.getSourceFile(defaultLocaleTs); ok(sf, "Failed to get source file"); const moduleSymbol = program.getTypeChecker().getSymbolAtLocation(sf)!; - const translatable = program - .getTypeChecker() - .tryGetMemberInModuleExports("translatable", moduleSymbol); + const translatable = moduleSymbol.exports?.get( + "export=" as ts.__String, + ); ok(translatable, "Failed to get translatable symbol"); - ok(ts.isVariableDeclaration(translatable.valueDeclaration!)); - ok(ts.isAsExpression(translatable.valueDeclaration.initializer!)); + ok(ts.isExportAssignment(translatable.valueDeclaration!)); + ok(ts.isAsExpression(translatable.valueDeclaration.expression)); ok( ts.isObjectLiteralExpression( - translatable.valueDeclaration.initializer.expression, + translatable.valueDeclaration.expression.expression, ), ); const translatableObj = - translatable.valueDeclaration.initializer.expression; + translatable.valueDeclaration.expression.expression; translatableObj.forEachChild((child) => { ok(ts.isPropertyAssignment(child)); diff --git a/tsconfig.json b/tsconfig.json index e5c1b60f1..49660e079 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -48,11 +48,5 @@ "src/test/packages", "src/test/slow/entry-points", "src/test/renderer/testProject" - ], - // We use ts-node to support mocha runner directly on files - "ts-node": { - "transpileOnly": true, - "esm": true, - "preferTsExts": true - } + ] } From a50343ecef9c10f38599bf74feb154d6901b95db Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 19:26:16 -0600 Subject: [PATCH 008/219] Fix test explorer --- .vscode/settings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index bb54bcf11..303ea4fb8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -37,6 +37,8 @@ "prettier.configPath": ".config/.prettierrc.json", "prettier.ignorePath": ".config/.prettierignore", + "mochaExplorer.nodeArgv": ["--import=tsx"], + "eslint.workingDirectories": [".", "./example"], "mochaExplorer.configFile": ".config/mocha.test-explorer.json", "cSpell.words": [ From 1292b5c74927e211cc6be415143e69ca63638a88 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 19:27:47 -0600 Subject: [PATCH 009/219] Fix set_strict script --- scripts/set_strict.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/set_strict.js b/scripts/set_strict.js index bf0ead168..1184afac6 100644 --- a/scripts/set_strict.js +++ b/scripts/set_strict.js @@ -7,7 +7,7 @@ import { join } from "path"; import { fileURLToPath } from "url"; const file = join( - fileURLToPath(import.meta.dirname), + fileURLToPath(import.meta.url), "../../src/lib/utils/general.ts", ); From cad2fba8a64b0ad1f9afd6645103a84a5efbc945 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 19:35:21 -0600 Subject: [PATCH 010/219] Circular dependencies --- src/lib/converter/plugins/CategoryPlugin.ts | 6 +++--- src/lib/converter/plugins/CommentPlugin.ts | 14 +++++++------- src/lib/converter/plugins/GroupPlugin.ts | 6 +++--- src/lib/converter/plugins/ImplementsPlugin.ts | 8 ++++---- src/lib/converter/plugins/InheritDocPlugin.ts | 4 ++-- src/lib/converter/plugins/PackagePlugin.ts | 8 ++++---- src/lib/converter/plugins/SourcePlugin.ts | 10 +++++----- src/lib/converter/plugins/TypePlugin.ts | 8 ++++---- 8 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/lib/converter/plugins/CategoryPlugin.ts b/src/lib/converter/plugins/CategoryPlugin.ts index f4b573681..11082c552 100644 --- a/src/lib/converter/plugins/CategoryPlugin.ts +++ b/src/lib/converter/plugins/CategoryPlugin.ts @@ -6,9 +6,9 @@ import { } from "../../models/index.js"; import { ReflectionCategory } from "../../models/index.js"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { Option, getSortFunction, removeIf } from "../../utils/index.js"; +import { ConverterEvents } from "../converter-events.js"; /** * A handler that sorts and categorizes the found reflections in the resolving phase. @@ -42,9 +42,9 @@ export class CategoryPlugin extends ConverterComponent { * Create a new CategoryPlugin instance. */ override initialize() { - this.owner.on(Converter.EVENT_BEGIN, this.onBegin.bind(this), -200); + this.owner.on(ConverterEvents.BEGIN, this.onBegin.bind(this), -200); this.owner.on( - Converter.EVENT_RESOLVE_END, + ConverterEvents.RESOLVE_END, this.onEndResolve.bind(this), -200, ); diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index 9f1457e06..ed7603410 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -1,5 +1,4 @@ import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { type Reflection, @@ -25,6 +24,7 @@ import { } from "../../utils/index.js"; import { CategoryPlugin } from "./CategoryPlugin.js"; import { setIntersection } from "../../utils/set.js"; +import { ConverterEvents } from "../converter-events.js"; /** * These tags are not useful to display in the generated documentation. @@ -155,23 +155,23 @@ export class CommentPlugin extends ConverterComponent { */ override initialize() { this.owner.on( - Converter.EVENT_CREATE_DECLARATION, + ConverterEvents.CREATE_DECLARATION, this.onDeclaration.bind(this), ); this.owner.on( - Converter.EVENT_CREATE_SIGNATURE, + ConverterEvents.CREATE_SIGNATURE, this.onDeclaration.bind(this), ); this.owner.on( - Converter.EVENT_CREATE_TYPE_PARAMETER, + ConverterEvents.CREATE_TYPE_PARAMETER, this.onCreateTypeParameter.bind(this), ); this.owner.on( - Converter.EVENT_RESOLVE_BEGIN, + ConverterEvents.RESOLVE_BEGIN, this.onBeginResolve.bind(this), ); - this.owner.on(Converter.EVENT_RESOLVE, this.onResolve.bind(this)); - this.owner.on(Converter.EVENT_END, () => { + this.owner.on(ConverterEvents.RESOLVE, this.onResolve.bind(this)); + this.owner.on(ConverterEvents.END, () => { this._excludeKinds = undefined; }); } diff --git a/src/lib/converter/plugins/GroupPlugin.ts b/src/lib/converter/plugins/GroupPlugin.ts index 5866aae28..abf974d00 100644 --- a/src/lib/converter/plugins/GroupPlugin.ts +++ b/src/lib/converter/plugins/GroupPlugin.ts @@ -6,11 +6,11 @@ import { } from "../../models/reflections/index.js"; import { ReflectionGroup } from "../../models/ReflectionGroup.js"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { getSortFunction } from "../../utils/sort.js"; import { Option, removeIf } from "../../utils/index.js"; import { Comment } from "../../models/index.js"; +import { ConverterEvents } from "../converter-events.js"; // Same as the defaultKindSortOrder in sort.ts const defaultGroupOrder = [ @@ -63,7 +63,7 @@ export class GroupPlugin extends ConverterComponent { */ override initialize() { this.owner.on( - Converter.EVENT_RESOLVE_BEGIN, + ConverterEvents.RESOLVE_BEGIN, () => { this.sortFunction = getSortFunction(this.application.options); GroupPlugin.WEIGHTS = this.groupOrder; @@ -78,7 +78,7 @@ export class GroupPlugin extends ConverterComponent { -100, ); this.owner.on( - Converter.EVENT_RESOLVE_END, + ConverterEvents.RESOLVE_END, this.onEndResolve.bind(this), -100, ); diff --git a/src/lib/converter/plugins/ImplementsPlugin.ts b/src/lib/converter/plugins/ImplementsPlugin.ts index de2fc41ed..6456d319f 100644 --- a/src/lib/converter/plugins/ImplementsPlugin.ts +++ b/src/lib/converter/plugins/ImplementsPlugin.ts @@ -17,9 +17,9 @@ import { import { filterMap, zip } from "../../utils/array.js"; import { ConverterComponent } from "../components.js"; import type { Context } from "../context.js"; -import { Converter } from "../converter.js"; import { getHumanName } from "../../utils/index.js"; import type { TranslatedString } from "../../internationalization/internationalization.js"; +import { ConverterEvents } from "../converter-events.js"; /** * A plugin that detects interface implementations of functions and @@ -34,16 +34,16 @@ export class ImplementsPlugin extends ConverterComponent { */ override initialize() { this.owner.on( - Converter.EVENT_RESOLVE_END, + ConverterEvents.RESOLVE_END, this.onResolveEnd.bind(this), ); this.owner.on( - Converter.EVENT_CREATE_DECLARATION, + ConverterEvents.CREATE_DECLARATION, this.onDeclaration.bind(this), -1000, ); this.owner.on( - Converter.EVENT_CREATE_SIGNATURE, + ConverterEvents.CREATE_SIGNATURE, this.onSignature.bind(this), 1000, ); diff --git a/src/lib/converter/plugins/InheritDocPlugin.ts b/src/lib/converter/plugins/InheritDocPlugin.ts index 98311045e..58aa51a9d 100644 --- a/src/lib/converter/plugins/InheritDocPlugin.ts +++ b/src/lib/converter/plugins/InheritDocPlugin.ts @@ -7,7 +7,6 @@ import { SignatureReflection, } from "../../models/index.js"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import type { Reflection } from "../../models/reflections/abstract.js"; import { @@ -19,6 +18,7 @@ import { zip } from "../../utils/array.js"; import { parseDeclarationReference } from "../comments/declarationReference.js"; import { resolveDeclarationReference } from "../comments/declarationReferenceResolver.js"; import { ApplicationEvents } from "../../application-events.js"; +import { ConverterEvents } from "../converter-events.js"; /** * A plugin that handles `@inheritDoc` tags by copying documentation from another API item. @@ -44,7 +44,7 @@ export class InheritDocPlugin extends ConverterComponent { * Create a new InheritDocPlugin instance. */ override initialize() { - this.owner.on(Converter.EVENT_RESOLVE_END, (context: Context) => + this.owner.on(ConverterEvents.RESOLVE_END, (context: Context) => this.processInheritDoc(context.project), ); this.application.on( diff --git a/src/lib/converter/plugins/PackagePlugin.ts b/src/lib/converter/plugins/PackagePlugin.ts index 56b1a431d..2bc1ad0c3 100644 --- a/src/lib/converter/plugins/PackagePlugin.ts +++ b/src/lib/converter/plugins/PackagePlugin.ts @@ -1,7 +1,6 @@ import * as Path from "path"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { Option, EntryPointStrategy, readFile } from "../../utils/index.js"; import { @@ -14,6 +13,7 @@ import { MinimalSourceFile } from "../../utils/minimalSourceFile.js"; import type { ProjectReflection } from "../../models/index.js"; import { ApplicationEvents } from "../../application-events.js"; import { join } from "path"; +import { ConverterEvents } from "../converter-events.js"; /** * A handler that tries to find the package.json and readme.md files of the @@ -48,12 +48,12 @@ export class PackagePlugin extends ConverterComponent { private packageJson?: { name: string; version?: string }; override initialize() { - this.owner.on(Converter.EVENT_BEGIN, this.onBegin.bind(this)); + this.owner.on(ConverterEvents.BEGIN, this.onBegin.bind(this)); this.owner.on( - Converter.EVENT_RESOLVE_BEGIN, + ConverterEvents.RESOLVE_BEGIN, this.onBeginResolve.bind(this), ); - this.owner.on(Converter.EVENT_END, () => { + this.owner.on(ConverterEvents.END, () => { delete this.readmeFile; delete this.readmeContents; delete this.packageJson; diff --git a/src/lib/converter/plugins/SourcePlugin.ts b/src/lib/converter/plugins/SourcePlugin.ts index fff6e4a14..53fcd7359 100644 --- a/src/lib/converter/plugins/SourcePlugin.ts +++ b/src/lib/converter/plugins/SourcePlugin.ts @@ -5,7 +5,6 @@ import { SignatureReflection, } from "../../models/reflections/index.js"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { Option, @@ -16,6 +15,7 @@ import { isNamedNode } from "../utils/nodes.js"; import { relative } from "path"; import { SourceReference } from "../../models/index.js"; import { gitIsInstalled, RepositoryManager } from "../utils/repository.js"; +import { ConverterEvents } from "../converter-events.js"; /** * A handler that attaches source file information to reflections. @@ -50,17 +50,17 @@ export class SourcePlugin extends ConverterComponent { * Create a new SourceHandler instance. */ override initialize() { - this.owner.on(Converter.EVENT_END, this.onEnd.bind(this)); + this.owner.on(ConverterEvents.END, this.onEnd.bind(this)); this.owner.on( - Converter.EVENT_CREATE_DECLARATION, + ConverterEvents.CREATE_DECLARATION, this.onDeclaration.bind(this), ); this.owner.on( - Converter.EVENT_CREATE_SIGNATURE, + ConverterEvents.CREATE_SIGNATURE, this.onSignature.bind(this), ); this.owner.on( - Converter.EVENT_RESOLVE_BEGIN, + ConverterEvents.RESOLVE_BEGIN, this.onBeginResolve.bind(this), ); } diff --git a/src/lib/converter/plugins/TypePlugin.ts b/src/lib/converter/plugins/TypePlugin.ts index ab7505a60..127a8999c 100644 --- a/src/lib/converter/plugins/TypePlugin.ts +++ b/src/lib/converter/plugins/TypePlugin.ts @@ -7,9 +7,9 @@ import { } from "../../models/reflections/index.js"; import { type Type, ReferenceType } from "../../models/types.js"; import { ConverterComponent } from "../components.js"; -import { Converter } from "../converter.js"; import type { Context } from "../context.js"; import { ApplicationEvents } from "../../application-events.js"; +import { ConverterEvents } from "../converter-events.js"; /** * Responsible for adding `implementedBy` / `implementedFrom` @@ -21,12 +21,12 @@ export class TypePlugin extends ConverterComponent { * Create a new TypeHandler instance. */ override initialize() { - this.owner.on(Converter.EVENT_RESOLVE, this.onResolve.bind(this)); + this.owner.on(ConverterEvents.RESOLVE, this.onResolve.bind(this)); this.owner.on( - Converter.EVENT_RESOLVE_END, + ConverterEvents.RESOLVE_END, this.onResolveEnd.bind(this), ); - this.owner.on(Converter.EVENT_END, () => this.reflections.clear()); + this.owner.on(ConverterEvents.END, () => this.reflections.clear()); this.application.on(ApplicationEvents.REVIVE, this.onRevive.bind(this)); } From ae490c5528c99ed282cebcceb2039bfeef48d9db Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 23 Jun 2024 19:38:04 -0600 Subject: [PATCH 011/219] Bump version to 0.26.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2651e1734..0ba5376da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typedoc", - "version": "0.26.1", + "version": "0.26.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typedoc", - "version": "0.26.1", + "version": "0.26.2", "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", diff --git a/package.json b/package.json index c6cc41be5..ad9f81f9c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typedoc", "description": "Create api documentation for TypeScript projects.", - "version": "0.26.1", + "version": "0.26.2", "homepage": "https://typedoc.org", "type": "module", "exports": { From 649175688fd6bf90df54bda0e861deb7524744e3 Mon Sep 17 00:00:00 2001 From: TypeDoc Bot Date: Mon, 24 Jun 2024 01:38:54 +0000 Subject: [PATCH 012/219] Update changelog for release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b352c5294..aff3316e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +## v0.26.2 (2024-06-24) + ### Features - Added a `--suppressCommentWarningsInDeclarationFiles` option to disable warnings from From d66d41cd6048c30a7883b8aa3005395371516b83 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Mon, 24 Jun 2024 20:51:23 -0600 Subject: [PATCH 013/219] Add `@since` to the default list of recognized tags Resolves #2614 --- CHANGELOG.md | 4 ++++ src/lib/utils/options/tsdoc-defaults.ts | 3 ++- src/test/converter2/issues/gh2614.ts | 4 ++++ src/test/issues.c2.test.ts | 11 +++++++++++ tsdoc.json | 4 ++++ 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/test/converter2/issues/gh2614.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index aff3316e2..b77148f24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +### Features + +- Added `@since` to the default list of recognized tags, #2614. + ## v0.26.2 (2024-06-24) ### Features diff --git a/src/lib/utils/options/tsdoc-defaults.ts b/src/lib/utils/options/tsdoc-defaults.ts index 41ec3ce16..17a7e23c9 100644 --- a/src/lib/utils/options/tsdoc-defaults.ts +++ b/src/lib/utils/options/tsdoc-defaults.ts @@ -32,8 +32,9 @@ export const blockTags = [ "@property", "@return", "@satisfies", + "@since", "@template", // Alias for @typeParam - "@type", // Because TypeScript is important! + "@type", "@typedef", ] as const; diff --git a/src/test/converter2/issues/gh2614.ts b/src/test/converter2/issues/gh2614.ts new file mode 100644 index 000000000..2f495bb60 --- /dev/null +++ b/src/test/converter2/issues/gh2614.ts @@ -0,0 +1,4 @@ +/** + * @since 1.0.0 + */ +export function foo() {} diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 6d5ad8132..e14e250ac 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1625,4 +1625,15 @@ describe("Issue Tests", () => { convert(); logger.expectNoOtherMessages(); }); + + it("#2614 supports @since tag", () => { + const project = convert(); + const foo = querySig(project, "foo"); + equal( + foo.comment?.getTag("@since"), + new CommentTag("@since", [{ kind: "text", text: "1.0.0" }]), + ); + + logger.expectNoOtherMessages(); + }); }); diff --git a/tsdoc.json b/tsdoc.json index 2177d5561..9bed22577 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -115,6 +115,10 @@ "tagName": "@satisfies", "syntaxKind": "block" }, + { + "tagName": "@since", + "syntaxKind": "block" + }, { "tagName": "@license", "syntaxKind": "block" From 472cc52dff1f2adb964b80967cc9f3e2185e9424 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Mon, 24 Jun 2024 21:05:22 -0600 Subject: [PATCH 014/219] Correct handling of `mailto:` links Resolves #2613 --- CHANGELOG.md | 3 ++- src/lib/converter/comments/textParser.ts | 16 +++++++++++----- src/test/comments.test.ts | 10 ++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b77148f24..3321c0d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Unreleased -### Features +### Bug Fixes +- `mailto:` links are no longer incorrectly recognized as relative paths, #2613. - Added `@since` to the default list of recognized tags, #2614. ## v0.26.2 (2024-06-24) diff --git a/src/lib/converter/comments/textParser.ts b/src/lib/converter/comments/textParser.ts index bde33428d..638e54f22 100644 --- a/src/lib/converter/comments/textParser.ts +++ b/src/lib/converter/comments/textParser.ts @@ -189,7 +189,7 @@ function checkMarkdownLink( if (link.ok) { // Only make a relative-link display part if it's actually a relative link. // Discard protocol:// links, unix style absolute paths, and windows style absolute paths. - if (isRelativeLink(link.str)) { + if (isRelativePath(link.str)) { return { pos: labelEnd + 2, end: link.pos, @@ -240,7 +240,7 @@ function checkReference(data: TextParserData): RelativeLink | undefined { ); if (link.ok) { - if (isRelativeLink(link.str)) { + if (isRelativePath(link.str)) { return { pos: lookahead, end: link.pos, @@ -284,7 +284,7 @@ function checkAttribute( ) { parser.step(); - if (isRelativeLink(parser.currentAttributeValue)) { + if (isRelativePath(parser.currentAttributeValue)) { data.pos = parser.pos; return { pos: parser.currentAttributeValueStart, @@ -302,8 +302,14 @@ function checkAttribute( } } -function isRelativeLink(link: string) { - return !/^[a-z]+:\/\/|^\/|^[a-z]:\\|^#/i.test(link); +function isRelativePath(link: string) { + // Lots of edge cases encoded right here! + // Originally, this attempted to match protocol://, but... + // `mailto:example@example.com` is not a relative path + // `C:\foo` is not a relative path + // `/etc/passwd` is not a relative path + // `#anchor` is not a relative path + return !/^[a-z]+:|^\/|^#/i.test(link); } function findLabelEnd(text: string, pos: number) { diff --git a/src/test/comments.test.ts b/src/test/comments.test.ts index c2e5e286e..bda4a6df4 100644 --- a/src/test/comments.test.ts +++ b/src/test/comments.test.ts @@ -1447,6 +1447,16 @@ describe("Comment Parser", () => { ] satisfies CommentDisplayPart[]); }); + it("Does not mistake mailto: links as relative paths", () => { + const comment = getComment(`/** + * [1]: mailto:example@example.com + */`); + + equal(comment.summary, [ + { kind: "text", text: "[1]: mailto:example@example.com" }, + ] satisfies CommentDisplayPart[]); + }); + it("Recognizes HTML image links", () => { const comment = getComment(`/** * From 176595445628dc7825085e1a68242d1e08ec2cd7 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Thu, 27 Jun 2024 19:49:15 -0600 Subject: [PATCH 015/219] Do not copy relative paths to directories Resolves #2617 --- CHANGELOG.md | 1 + src/lib/converter/comments/textParser.ts | 2 +- src/lib/internationalization/locales/en.cts | 2 +- src/lib/internationalization/locales/jp.cts | 5 ++--- src/lib/internationalization/locales/zh.cts | 5 ++--- src/lib/models/FileRegistry.ts | 9 ++++----- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3321c0d42..b0d895c39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - `mailto:` links are no longer incorrectly recognized as relative paths, #2613. - Added `@since` to the default list of recognized tags, #2614. +- Relative paths to directories will no longer cause the directory to be copied into the media directory, #2617. ## v0.26.2 (2024-06-24) diff --git a/src/lib/converter/comments/textParser.ts b/src/lib/converter/comments/textParser.ts index 638e54f22..24a34ca93 100644 --- a/src/lib/converter/comments/textParser.ts +++ b/src/lib/converter/comments/textParser.ts @@ -101,7 +101,7 @@ export function textContent( data.pos = ref.end; if (!ref.target) { warning( - i18n.relative_path_0_does_not_exist( + i18n.relative_path_0_is_not_a_file_and_will_not_be_copied_to_output( token.text.slice(ref.pos, ref.end), ), { diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 1e2dace58..3026c0dfc 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -144,7 +144,7 @@ export = { // deserialization serialized_project_referenced_0_not_part_of_project: `Serialized project referenced reflection {0}, which was not a part of the project`, - saved_relative_path_0_resolved_from_1_does_not_exist: `Serialized project referenced {0}, which does not exist relative to {1}`, + saved_relative_path_0_resolved_from_1_is_not_a_file: `Serialized project referenced {0}, which does not exist relative to {1}`, // options circular_reference_extends_0: `Circular reference encountered for "extends" field of {0}`, diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index df858dc02..7a8ae1659 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -59,7 +59,7 @@ export = localeUtils.buildIncompleteTranslation({ "TypeDoc は、コメント付きの単一の @template タグで定義された複数の型パラメータをサポートしていません。", failed_to_find_jsdoc_tag_for_name_0: "コメントを解析した後、{0} の JSDoc タグが見つかりませんでした。バグレポートを提出してください。", - relative_path_0_does_not_exist: "相対パス {0} は存在しません", + // relative_path_0_is_not_a_file_and_will_not_be_copied_to_output inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "インライン @inheritDoc タグはブロック タグ内に出現しないでください。{0} のコメントでは処理されません。", at_most_one_remarks_tag_expected_in_comment_at_0: @@ -169,8 +169,7 @@ export = localeUtils.buildIncompleteTranslation({ file_0_not_an_object: "ファイル {0} はオブジェクトではありません", serialized_project_referenced_0_not_part_of_project: "シリアル化されたプロジェクトは、プロジェクトの一部ではないリフレクション {0} を参照しました", - saved_relative_path_0_resolved_from_1_does_not_exist: - "シリアル化されたプロジェクトは {0} を参照していますが、{1} に関連して存在しません", + // saved_relative_path_0_resolved_from_1_is_not_a_file circular_reference_extends_0: '{0} の "extends" フィールドで循環参照が検出されました', failed_resolve_0_to_file_in_1: diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index a316d284c..d9ecd7798 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -52,7 +52,7 @@ export = localeUtils.buildIncompleteTranslation({ "TypeDoc 不支持在带有注释的单个 @template 标记中定义多个类型参数", failed_to_find_jsdoc_tag_for_name_0: "解析注释后无法找到 {0} 的 JSDoc 标签,请提交错误报告", - relative_path_0_does_not_exist: "相对路径 {0} 不存在", + // relative_path_0_is_not_a_file_and_will_not_be_copied_to_output inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "内联 @inheritDoc 标记不应出现在块标记内,因为它不会在 {0} 处的注释中被处理。", at_most_one_remarks_tag_expected_in_comment_at_0: @@ -145,8 +145,7 @@ export = localeUtils.buildIncompleteTranslation({ file_0_not_an_object: "文件 {0} 不是对象", serialized_project_referenced_0_not_part_of_project: "序列化项目引用了反射 {0},但它不是项目的一部分", - saved_relative_path_0_resolved_from_1_does_not_exist: - "序列化项目引用了 {0},相对于 {1} 而言,它并不存在", + // saved_relative_path_0_resolved_from_1_is_not_a_file circular_reference_extends_0: "{0} 的“extends”字段出现循环引用", failed_resolve_0_to_file_in_1: "无法将 {0} 解析为 {1} 中的文件", option_0_can_only_be_specified_by_config_file: diff --git a/src/lib/models/FileRegistry.ts b/src/lib/models/FileRegistry.ts index 1b1ea99fc..fc432275a 100644 --- a/src/lib/models/FileRegistry.ts +++ b/src/lib/models/FileRegistry.ts @@ -1,8 +1,7 @@ import { basename, dirname, parse, relative, resolve } from "path"; import type { Deserializer, Serializer } from "../serialization/index.js"; import type { FileRegistry as JSONFileRegistry } from "../serialization/schema.js"; -import { normalizePath } from "../utils/index.js"; -import { existsSync } from "fs"; +import { isFile, normalizePath } from "../utils/index.js"; import type { Reflection } from "./reflections/index.js"; export class FileRegistry { @@ -137,7 +136,7 @@ export class ValidatingFileRegistry extends FileRegistry { relativePath: string, ): number | undefined { const absolute = resolve(dirname(sourcePath), relativePath); - if (!existsSync(absolute)) { + if (!isFile(absolute)) { return; } return this.registerAbsolute(absolute); @@ -146,9 +145,9 @@ export class ValidatingFileRegistry extends FileRegistry { override fromObject(de: Deserializer, obj: JSONFileRegistry) { for (const [key, val] of Object.entries(obj.entries)) { const absolute = normalizePath(resolve(de.projectRoot, val)); - if (!existsSync(absolute)) { + if (!isFile(absolute)) { de.logger.warn( - de.logger.i18n.saved_relative_path_0_resolved_from_1_does_not_exist( + de.logger.i18n.saved_relative_path_0_resolved_from_1_is_not_a_file( val, de.projectRoot, ), From 97381908259baeff2b0ecca4e285a33e5e2bcb63 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Tue, 25 Jun 2024 20:40:53 -0600 Subject: [PATCH 016/219] Include page groups in page TOC Resolves #2616 --- CHANGELOG.md | 4 + src/lib/output/events.ts | 38 ++++++-- .../default/DefaultThemeRenderContext.ts | 4 +- .../themes/default/partials/members.group.tsx | 41 --------- .../themes/default/partials/members.tsx | 86 ++++++++++++------- .../themes/default/partials/navigation.tsx | 39 +++++++-- src/lib/utils/enum.ts | 6 +- src/lib/utils/options/declaration.ts | 2 +- static/style.css | 10 +++ 9 files changed, 138 insertions(+), 92 deletions(-) delete mode 100644 src/lib/output/themes/default/partials/members.group.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index b0d895c39..acbb1e840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Unreleased +### Features + +- "On This Page" navigation now includes the page groups in collapsible sections, #2616. + ### Bug Fixes - `mailto:` links are no longer incorrectly recognized as relative paths, #2613. diff --git a/src/lib/output/events.ts b/src/lib/output/events.ts index 9869bc6d2..5ac65123b 100644 --- a/src/lib/output/events.ts +++ b/src/lib/output/events.ts @@ -69,6 +69,14 @@ export class RendererEvent { } } +export interface PageHeading { + link: string; + text: string; + level?: number; + kind?: ReflectionKind; + classes?: string; +} + /** * An event emitted by the {@link Renderer} class before and after the * markup of a page is rendered. @@ -108,13 +116,29 @@ export class PageEvent extends Event { * Links to content within this page that should be rendered in the page navigation. * This is built when rendering the document content. */ - pageHeadings: Array<{ - link: string; - text: string; - level?: number; - kind?: ReflectionKind; - classes?: string; - }> = []; + pageHeadings: PageHeading[] = []; + + /** + * Sections of the page, generally set by `@group`s + */ + pageSections = [ + { + title: "", + headings: this.pageHeadings, + }, + ]; + + /** + * Start a new section of the page. Sections are collapsible within + * the "On This Page" sidebar. + */ + startNewSection(title: string) { + this.pageHeadings = []; + this.pageSections.push({ + title, + headings: this.pageHeadings, + }); + } /** * Triggered before a document will be rendered. diff --git a/src/lib/output/themes/default/DefaultThemeRenderContext.ts b/src/lib/output/themes/default/DefaultThemeRenderContext.ts index a337067cb..baa40adb9 100644 --- a/src/lib/output/themes/default/DefaultThemeRenderContext.ts +++ b/src/lib/output/themes/default/DefaultThemeRenderContext.ts @@ -32,7 +32,6 @@ import { memberSignatureTitle } from "./partials/member.signature.title.js"; import { memberSignatures } from "./partials/member.signatures.js"; import { memberSources } from "./partials/member.sources.js"; import { members } from "./partials/members.js"; -import { membersGroup } from "./partials/members.group.js"; import { sidebar, pageSidebar, @@ -63,7 +62,7 @@ export class DefaultThemeRenderContext { i18n: TranslationProxy; constructor( - private theme: DefaultTheme, + readonly theme: DefaultTheme, public page: PageEvent, options: Options, ) { @@ -144,7 +143,6 @@ export class DefaultThemeRenderContext { memberSignatures = bind(memberSignatures, this); memberSources = bind(memberSources, this); members = bind(members, this); - membersGroup = bind(membersGroup, this); sidebar = bind(sidebar, this); pageSidebar = bind(pageSidebar, this); sidebarLinks = bind(sidebarLinks, this); diff --git a/src/lib/output/themes/default/partials/members.group.tsx b/src/lib/output/themes/default/partials/members.group.tsx deleted file mode 100644 index c03455e8c..000000000 --- a/src/lib/output/themes/default/partials/members.group.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -import { JSX } from "../../../../utils/index.js"; -import type { ReflectionGroup } from "../../../../models/index.js"; - -void JSX; // Trick TS into seeing this as used, the import is required. - -export function membersGroup(context: DefaultThemeRenderContext, group: ReflectionGroup) { - if (group.categories) { - return ( - <> - {group.categories.map((item) => { - const title = `${group.title} - ${item.title}`; - - return ( -
        - -

        - {context.icons.chevronDown()} {title} -

        -
        -
        - {item.children.map((item) => !item.hasOwnDocument && context.member(item))} -
        -
        - ); - })} - - ); - } - - return ( -
        - -

        - {context.icons.chevronDown()} {group.title} -

        -
        -
        {group.children.map((item) => !item.hasOwnDocument && context.member(item))}
        -
        - ); -} diff --git a/src/lib/output/themes/default/partials/members.tsx b/src/lib/output/themes/default/partials/members.tsx index e5b3d8def..04cb4c547 100644 --- a/src/lib/output/themes/default/partials/members.tsx +++ b/src/lib/output/themes/default/partials/members.tsx @@ -1,37 +1,63 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -import { JSX } from "../../../../utils/index.js"; -import { type ContainerReflection, DeclarationReflection } from "../../../../models/index.js"; -import { classNames } from "../../lib.js"; +import { filterMap, JSX } from "../../../../utils/index.js"; +import { type ContainerReflection } from "../../../../models/index.js"; void JSX; // Trick TS into seeing this as used, the import is required. -export function members(context: DefaultThemeRenderContext, props: ContainerReflection) { - if (props.categories && props.categories.length) { - return ( - <> - {props.categories.map( - (item) => - !item.allChildrenHaveOwnDocument() && ( -
        - -

        - {context.icons.chevronDown()} {item.title} -

        -
        -
        - {item.children.map((item) => !item.hasOwnDocument && context.member(item))} -
        -
        - ), - )} - - ); +function getMemberSections(parent: ContainerReflection) { + if (parent.categories?.length) { + return filterMap(parent.categories, (cat) => { + if (!cat.allChildrenHaveOwnDocument()) { + return { + title: cat.title, + children: cat.children.filter((child) => !child.hasOwnDocument), + }; + } + }); } - return <>{props.groups?.map((item) => !item.allChildrenHaveOwnDocument() && context.membersGroup(item))}; + if (parent.groups?.length) { + return parent.groups.flatMap((group) => { + if (group.categories?.length) { + return filterMap(group.categories, (cat) => { + if (!cat.allChildrenHaveOwnDocument()) { + return { + title: `${group.title} - ${cat.title}`, + children: cat.children.filter((child) => !child.hasOwnDocument), + }; + } + }); + } + + return { + title: group.title, + children: group.children.filter((child) => !child.hasOwnDocument), + }; + }); + } + + return []; +} + +export function members(context: DefaultThemeRenderContext, props: ContainerReflection) { + const sections = getMemberSections(props).filter((sect) => sect.children.length); + + return ( + <> + {sections.map(({ title, children }) => { + context.page.startNewSection(title); + + return ( +
        + +

        + {context.icons.chevronDown()} {title} +

        +
        +
        {children.map((item) => context.member(item))}
        +
        + ); + })} + + ); } diff --git a/src/lib/output/themes/default/partials/navigation.tsx b/src/lib/output/themes/default/partials/navigation.tsx index 301598f16..be8ad099d 100644 --- a/src/lib/output/themes/default/partials/navigation.tsx +++ b/src/lib/output/themes/default/partials/navigation.tsx @@ -145,7 +145,7 @@ export function pageSidebar(context: DefaultThemeRenderContext, props: PageEvent ); } -export function pageNavigation(context: DefaultThemeRenderContext, props: PageEvent) { +function buildSectionNavigation(context: DefaultThemeRenderContext, headings: PageHeading[]) { const levels: JSX.Element[][] = [[]]; function finalizeLevel(finishedHandlingHeadings: boolean) { @@ -165,8 +165,12 @@ export function pageNavigation(context: DefaultThemeRenderContext, props: PageEv levels[levels.length - 1].push(built); } - for (const heading of props.pageHeadings) { - const inferredLevel = heading.level ? heading.level + 1 : 1; + for (const heading of headings) { + const inferredLevel = heading.level + ? heading.level + 2 // regular heading + : heading.kind + ? 2 // reflection + : 1; // group/category while (inferredLevel < levels.length) { finalizeLevel(false); } @@ -187,12 +191,33 @@ export function pageNavigation(context: DefaultThemeRenderContext, props: PageEv finalizeLevel(true); } - if (!levels[0].length) { + levels.unshift([]); + finalizeLevel(true); + return levels[0]; +} + +export function pageNavigation(context: DefaultThemeRenderContext, props: PageEvent) { + if (!props.pageSections.some((sect) => sect.headings.length)) { return <>; } - levels.unshift([]); - finalizeLevel(true); + const sections: JSX.Children = []; + + for (const section of props.pageSections) { + if (section.title) { + sections.push( +
        + + {context.icons.chevronDown()} + {section.title} + +
        {buildSectionNavigation(context, section.headings)}
        +
        , + ); + } else { + sections.push(buildSectionNavigation(context, section.headings)); + } + } return (
        @@ -202,7 +227,7 @@ export function pageNavigation(context: DefaultThemeRenderContext, props: PageEv {context.i18n.theme_on_this_page()} -
        {levels[0]}
        +
        {sections}
        ); } diff --git a/src/lib/utils/enum.ts b/src/lib/utils/enum.ts index 5b0ab7c94..798dffab5 100644 --- a/src/lib/utils/enum.ts +++ b/src/lib/utils/enum.ts @@ -34,6 +34,6 @@ export function getEnumKeys(Enum: {}): string[] { return Object.keys(E).filter((k) => E[E[k]] === k); } -export type EnumKeys = keyof { - [K in keyof E as number extends E[K] ? K : never]: 1; -}; +export type EnumKeys = { + [K in keyof E]: number extends E[K] ? K : never; +}[keyof E] & {}; diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index b88a82051..f726448d5 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -110,7 +110,7 @@ export interface TypeDocOptionMap { externalPattern: string[]; excludeExternals: boolean; excludeNotDocumented: boolean; - excludeNotDocumentedKinds: Array; + excludeNotDocumentedKinds: ReflectionKind.KindString[]; excludeInternal: boolean; excludePrivate: boolean; excludeProtected: boolean; diff --git a/static/style.css b/static/style.css index d0c980d41..9d619a641 100644 --- a/static/style.css +++ b/static/style.css @@ -793,6 +793,15 @@ input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { margin-left: -1.5rem; } +.tsd-page-navigation-section { + margin-left: 10px; +} +.tsd-page-navigation-section > summary { + padding: 0.25rem; +} +.tsd-page-navigation-section > div { + margin-left: 20px; +} .tsd-page-navigation ul { padding-left: 1.75rem; } @@ -841,6 +850,7 @@ a.tsd-index-link { } .tsd-accordion .tsd-accordion-summary > svg { margin-left: 0.25rem; + vertical-align: text-top; } .tsd-index-content > :not(:first-child) { margin-top: 0.75rem; From 0b43475cc9d5a5f927b0395c3c1e2f9f404e4e98 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Tue, 25 Jun 2024 20:44:04 -0600 Subject: [PATCH 017/219] Fix lint issue --- src/lib/converter/plugins/CommentPlugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index ed7603410..46a3951a4 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -146,7 +146,7 @@ export class CommentPlugin extends ConverterComponent { private get excludeNotDocumentedKinds(): number { this._excludeKinds ??= this.application.options .getValue("excludeNotDocumentedKinds") - .reduce((a, b) => a | (ReflectionKind[b] as number), 0); + .reduce((a, b) => a | ReflectionKind[b], 0); return this._excludeKinds; } From c7228d922659cbe0ad39d7291d9f8e5483132738 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Thu, 27 Jun 2024 19:35:14 -0600 Subject: [PATCH 018/219] Update deps --- package-lock.json | 165 +++++++++++++++++++++++----------------------- package.json | 12 ++-- 2 files changed, 89 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ba5376da..152133ed2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "lunr": "^2.3.9", "markdown-it": "^14.1.0", - "minimatch": "^9.0.4", - "shiki": "^1.9.0", + "minimatch": "^9.0.5", + "shiki": "^1.9.1", "yaml": "^2.4.5" }, "bin": { @@ -21,18 +21,18 @@ "devDependencies": { "@types/lunr": "^2.3.7", "@types/markdown-it": "^14.1.1", - "@types/mocha": "^10.0.6", + "@types/mocha": "^10.0.7", "@types/node": "18", "@typestrong/fs-fixture-builder": "github:TypeStrong/fs-fixture-builder#34113409e3a171e68ce5e2b55461ef5c35591cfe", "c8": "^10.1.2", "esbuild": "^0.21.5", "eslint": "^9.5.0", - "mocha": "^10.4.0", + "mocha": "^10.5.2", "prettier": "3.3.2", - "puppeteer": "^22.12.0", + "puppeteer": "^22.12.1", "tsx": "^4.15.7", "typescript": "5.5.2", - "typescript-eslint": "^7.13.1" + "typescript-eslint": "^7.14.1" }, "engines": { "node": ">= 18" @@ -921,9 +921,9 @@ } }, "node_modules/@shikijs/core": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.9.0.tgz", - "integrity": "sha512-cbSoY8P/jgGByG8UOl3jnP/CWg/Qk+1q+eAKWtcrU3pNoILF8wTsLB0jT44qUBV8Ce1SvA9uqcM9Xf+u3fJFBw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.9.1.tgz", + "integrity": "sha512-EmUful2MQtY8KgCF1OkBtOuMcvaZEvmdubhW0UHCGXi21O9dRLeADVCj+k6ZS+de7Mz9d2qixOXJ+GLhcK3pXg==", "license": "MIT" }, "node_modules/@tootallnate/quickjs-emscripten": { @@ -971,10 +971,11 @@ "license": "MIT" }, "node_modules/@types/mocha": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz", - "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==", - "dev": true + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.7.tgz", + "integrity": "sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "18.19.39", @@ -998,17 +999,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", + "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/type-utils": "7.14.1", + "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1032,16 +1033,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4" }, "engines": { @@ -1061,14 +1062,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1079,14 +1080,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", + "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/utils": "7.14.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1107,9 +1108,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", "dev": true, "license": "MIT", "engines": { @@ -1121,14 +1122,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1150,16 +1151,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1173,13 +1174,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.14.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2994,9 +2995,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -3026,15 +3027,15 @@ "license": "MIT" }, "node_modules/mocha": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz", - "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==", + "version": "10.5.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.5.2.tgz", + "integrity": "sha512-9btlN3JKCefPf+vKd/kcKz2SXxi12z6JswkGfaAF0saQvnsqLJk504ZmbxhSoENge08E9dsymozKgFMTl5PQsA==", "dev": true, "license": "MIT", "dependencies": { "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.5.3", + "chokidar": "^3.5.3", "debug": "4.3.4", "diff": "5.0.0", "escape-string-regexp": "4.0.0", @@ -3476,17 +3477,17 @@ } }, "node_modules/puppeteer": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.12.0.tgz", - "integrity": "sha512-kyUYI12SyJIjf9UGTnHfhNMYv4oVK321Jb9QZDBiGVNx5453SplvbdKI7UrF+S//3RtCneuUFCyHxnvQXQjpxg==", + "version": "22.12.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.12.1.tgz", + "integrity": "sha512-1GxY8dnEnHr1SLzdSDr0FCjM6JQfAh2E2I/EqzeF8a58DbGVk9oVjj4lFdqNoVbpgFSpAbz7VER9St7S1wDpNg==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.2.3", - "cosmiconfig": "9.0.0", + "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1299070", - "puppeteer-core": "22.12.0" + "puppeteer-core": "22.12.1" }, "bin": { "puppeteer": "lib/esm/puppeteer/node/cli.js" @@ -3496,17 +3497,17 @@ } }, "node_modules/puppeteer-core": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.12.0.tgz", - "integrity": "sha512-9gY+JwBW/Fp3/x9+cOGK7ZcwqjvtvY2xjqRqsAA0B3ZFMzBauVTSZ26iWTmvOQX2sk78TN/rd5rnetxVxmK5CQ==", + "version": "22.12.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.12.1.tgz", + "integrity": "sha512-XmqeDPVdC5/3nGJys1jbgeoZ02wP0WV1GBlPtr/ULRbGXJFuqgXMcKQ3eeNtFpBzGRbpeoCGWHge1ZWKWl0Exw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.2.3", "chromium-bidi": "0.5.24", - "debug": "4.3.5", + "debug": "^4.3.5", "devtools-protocol": "0.0.1299070", - "ws": "8.17.1" + "ws": "^8.17.1" }, "engines": { "node": ">=18" @@ -3706,12 +3707,12 @@ } }, "node_modules/shiki": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.9.0.tgz", - "integrity": "sha512-i6//Lqgn7+7nZA0qVjoYH0085YdNk4MC+tJV4bo+HgjgRMJ0JmkLZzFAuvVioJqLkcGDK5GAMpghZEZkCnwxpQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.9.1.tgz", + "integrity": "sha512-8PDkgb5ja3nfujTjvC4VytL6wGOGCtFAClUb2r3QROevYXxcq+/shVJK5s6gy0HZnjaJgFxd6BpPqpRfqne5rA==", "license": "MIT", "dependencies": { - "@shikijs/core": "1.9.0" + "@shikijs/core": "1.9.1" } }, "node_modules/signal-exit": { @@ -4058,15 +4059,15 @@ } }, "node_modules/typescript-eslint": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", - "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.14.1.tgz", + "integrity": "sha512-Eo1X+Y0JgGPspcANKjeR6nIqXl4VL5ldXLc15k4m9upq+eY5fhU2IueiEZL6jmHrKH8aCfbIvM/v3IrX5Hg99w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", - "@typescript-eslint/utils": "7.13.1" + "@typescript-eslint/eslint-plugin": "7.14.1", + "@typescript-eslint/parser": "7.14.1", + "@typescript-eslint/utils": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" diff --git a/package.json b/package.json index ad9f81f9c..97d7e7327 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,8 @@ "dependencies": { "lunr": "^2.3.9", "markdown-it": "^14.1.0", - "minimatch": "^9.0.4", - "shiki": "^1.9.0", + "minimatch": "^9.0.5", + "shiki": "^1.9.1", "yaml": "^2.4.5" }, "peerDependencies": { @@ -37,17 +37,17 @@ "devDependencies": { "@types/lunr": "^2.3.7", "@types/markdown-it": "^14.1.1", - "@types/mocha": "^10.0.6", + "@types/mocha": "^10.0.7", "@types/node": "18", "@typestrong/fs-fixture-builder": "github:TypeStrong/fs-fixture-builder#34113409e3a171e68ce5e2b55461ef5c35591cfe", "c8": "^10.1.2", "esbuild": "^0.21.5", "eslint": "^9.5.0", - "mocha": "^10.4.0", + "mocha": "^10.5.2", "prettier": "3.3.2", - "puppeteer": "^22.12.0", + "puppeteer": "^22.12.1", "tsx": "^4.15.7", - "typescript-eslint": "^7.13.1", + "typescript-eslint": "^7.14.1", "typescript": "5.5.2" }, "files": [ From c95a0b1865d2fa180f9f23b20c651e8dcbabc164 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Thu, 27 Jun 2024 19:36:59 -0600 Subject: [PATCH 019/219] Bump version to 0.26.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 152133ed2..8c32d15a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typedoc", - "version": "0.26.2", + "version": "0.26.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typedoc", - "version": "0.26.2", + "version": "0.26.3", "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", diff --git a/package.json b/package.json index 97d7e7327..8628baf6b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typedoc", "description": "Create api documentation for TypeScript projects.", - "version": "0.26.2", + "version": "0.26.3", "homepage": "https://typedoc.org", "type": "module", "exports": { From 2c99f0f7f134121deb6c252ca316d6fab449020f Mon Sep 17 00:00:00 2001 From: TypeDoc Bot Date: Fri, 28 Jun 2024 01:37:48 +0000 Subject: [PATCH 020/219] Update changelog for release --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index acbb1e840..8ccd5abf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Unreleased +## v0.26.3 (2024-06-28) + ### Features - "On This Page" navigation now includes the page groups in collapsible sections, #2616. From 93bf6500ccfe85648b2c848421ddef4e3d1135b2 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Thu, 27 Jun 2024 20:15:19 -0600 Subject: [PATCH 021/219] Fix build from rebase confusion --- src/lib/internationalization/locales/en.cts | 2 +- src/lib/output/themes/default/partials/navigation.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 3026c0dfc..10656e5e1 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -57,7 +57,7 @@ export = { // comments/parser.ts multiple_type_parameters_on_template_tag_unsupported: `TypeDoc does not support multiple type parameters defined in a single @template tag with a comment`, failed_to_find_jsdoc_tag_for_name_0: `Failed to find JSDoc tag for {0} after parsing comment, please file a bug report`, - relative_path_0_does_not_exist: `The relative path {0} does not exist`, + relative_path_0_is_not_a_file_and_will_not_be_copied_to_output: `The relative path {0} is not a file and will not be copied to the output directory`, inline_inheritdoc_should_not_appear_in_block_tag_in_comment_at_0: "An inline @inheritDoc tag should not appear within a block tag as it will not be processed in comment at {0}", diff --git a/src/lib/output/themes/default/partials/navigation.tsx b/src/lib/output/themes/default/partials/navigation.tsx index be8ad099d..ab1a6125a 100644 --- a/src/lib/output/themes/default/partials/navigation.tsx +++ b/src/lib/output/themes/default/partials/navigation.tsx @@ -1,6 +1,6 @@ import { type Reflection, ReflectionFlag, ReflectionKind } from "../../../../models/index.js"; import { JSX } from "../../../../utils/index.js"; -import type { PageEvent } from "../../../events.js"; +import type { PageEvent, PageHeading } from "../../../events.js"; import { classNames, getDisplayName, wbr } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; From ed61f5d22d386c8f07abd8f8eb4ec4ec67db6d3b Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Fri, 28 Jun 2024 14:27:35 -0600 Subject: [PATCH 022/219] WIP: Type Details partial in default theme --- CHANGELOG.md | 5 + internal-docs/visual-regression-tests.md | 13 +- scripts/accept_visual_regression.js | 10 - scripts/capture_screenshots.mjs | 5 +- scripts/compare_screenshots.sh | 12 - scripts/visual_regression.js | 166 +++++++++++++ src/lib/converter/symbols.ts | 10 + src/lib/internationalization/locales/en.cts | 4 +- src/lib/internationalization/locales/jp.cts | 3 +- src/lib/internationalization/locales/ko.cts | 3 +- src/lib/internationalization/locales/zh.cts | 2 +- src/lib/models/comments/comment.ts | 4 +- src/lib/models/types.ts | 54 ++++- .../default/DefaultThemeRenderContext.ts | 25 +- .../default/assets/typedoc/Component.ts | 7 +- .../assets/typedoc/components/Accordion.ts | 4 +- .../assets/typedoc/components/Filter.ts | 4 +- .../default/partials/member.declaration.tsx | 53 +--- .../partials/member.signature.body.tsx | 6 +- .../partials/member.signature.title.tsx | 8 +- .../themes/default/partials/parameter.tsx | 138 ----------- .../output/themes/default/partials/type.tsx | 6 +- .../themes/default/partials/typeDetails.tsx | 229 ++++++++++++++++++ .../themes/default/templates/reflection.tsx | 3 +- src/lib/output/themes/lib.tsx | 2 +- src/lib/utils/array.ts | 26 ++ src/lib/utils/options/declaration.ts | 2 +- src/lib/utils/options/sources/typedoc.ts | 4 +- src/test/behavior.c2.test.ts | 5 +- src/test/converter/variables/specs.json | 57 ++--- src/test/converter/variables/specs.nodoc.json | 57 ++--- src/test/issues.c2.test.ts | 18 +- 32 files changed, 594 insertions(+), 351 deletions(-) delete mode 100644 scripts/accept_visual_regression.js delete mode 100755 scripts/compare_screenshots.sh create mode 100644 scripts/visual_regression.js delete mode 100644 src/lib/output/themes/default/partials/parameter.tsx create mode 100644 src/lib/output/themes/default/partials/typeDetails.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ccd5abf8..2aeb7aaa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# Beta + +- The `hideParameterTypesInTitle` option has been renamed to `hideTypesInSignatureTitle` and now controls return types as well. +- Fixed an issue where properties were not properly marked optional in some cases. This primarily affected destructured parameters. + # Unreleased ## v0.26.3 (2024-06-28) diff --git a/internal-docs/visual-regression-tests.md b/internal-docs/visual-regression-tests.md index ebdbd241b..13a40c490 100644 --- a/internal-docs/visual-regression-tests.md +++ b/internal-docs/visual-regression-tests.md @@ -3,10 +3,9 @@ When making changes to the themes, it is useful to be able to compare screenshots from the new/old runs. -1. Build some documentation project to `./docs` -2. Run `node scripts/capture_screenshots.mjs` -3. Run `node scripts/accept_visual_regression.js` -4. Make the UI change -5. Build the same documentation project to `./docs` -6. Run `./scripts/compare_screenshots.sh` -7. Open `./tmp/output/index.html` in a browser. +1. Run `node scripts/visual_regression.js` +2. Make the UI change +3. Run `node scripts/visual_regression.js` + +The visual regression script accepts several arguments to control what it does, +run it with `--help` to see a summary of the available options. diff --git a/scripts/accept_visual_regression.js b/scripts/accept_visual_regression.js deleted file mode 100644 index 70f5d9bd1..000000000 --- a/scripts/accept_visual_regression.js +++ /dev/null @@ -1,10 +0,0 @@ -//@ts-check - -import fs from "fs/promises"; -import { join } from "path"; - -const expectedDir = join(__dirname, "../tmp/baseline"); -const outputDir = join(__dirname, "../tmp/screenshots"); - -await fs.rm(expectedDir, { recursive: true, force: true }); -await fs.cp(outputDir, expectedDir, { recursive: true, force: true }); diff --git a/scripts/capture_screenshots.mjs b/scripts/capture_screenshots.mjs index 7bb5fe73c..3e01a5da7 100644 --- a/scripts/capture_screenshots.mjs +++ b/scripts/capture_screenshots.mjs @@ -103,6 +103,7 @@ export async function captureScreenshots( const queue = new PQueue(jobs); const pages = findHtmlPages(resolve(baseDirectory)); + let finished = 0; console.log(`Processing ${pages.length} pages with ${jobs} workers`); for (const file of pages) { queue.add(async () => { @@ -128,7 +129,9 @@ export async function captureScreenshots( }); await context.close(); - console.log("Finished", relative(baseDirectory, file)); + ++finished; + const percent = Math.floor((finished / pages.length) * 100); + console.log(`[${percent}%] ${relative(baseDirectory, file)}`); }); } diff --git a/scripts/compare_screenshots.sh b/scripts/compare_screenshots.sh deleted file mode 100755 index c0cf2580b..000000000 --- a/scripts/compare_screenshots.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -test -d ./tmp/output && rm -rf ./tmp/output -mkdir -p ./tmp/{output,screenshots,baseline} - -docker run \ - --rm \ - --name typedoc-reg-suit \ - -v "$PWD/tmp/screenshots:/new" \ - -v "$PWD/tmp/baseline:/old" \ - -v "$PWD/tmp/output:/out" \ - ghcr.io/gerrit0/reg-suit-container:main diff --git a/scripts/visual_regression.js b/scripts/visual_regression.js new file mode 100644 index 000000000..4c85a3c86 --- /dev/null +++ b/scripts/visual_regression.js @@ -0,0 +1,166 @@ +// @ts-check +import util from "util"; +import { cpSync, existsSync, mkdirSync, rmSync } from "fs"; +import { spawnSync } from "child_process"; +import { captureScreenshots } from "./capture_screenshots.mjs"; +import { fileURLToPath } from "url"; +import { join } from "path"; + +/** @param {string} dir */ +function accept(dir) { + const expectedDir = join(dir, "baseline"); + const outputDir = join(dir, "screenshots"); + rmSync(expectedDir, { recursive: true, force: true }); + cpSync(outputDir, expectedDir, { recursive: true, force: true }); +} + +/** @param {string} dir */ +function compare(dir) { + rmSync(join(dir, "output"), { recursive: true, force: true }); + mkdirSync(join(dir, "output"), { recursive: true }); + + spawnSync( + "docker", + [ + "run", + "--rm", + "--name", + "typedoc-reg-suit", + "-v", + `${join(dir, "screenshots")}:/new`, + "-v", + `${join(dir, "baseline")}:/old`, + "-v", + `${join(dir, "output")}:/out`, + "ghcr.io/gerrit0/reg-suit-container:main", + ], + { stdio: "inherit" }, + ); +} + +function printHelp() { + const help = [ + "DIRECTORIES", + " --dir The root folder that visual regression info is tracked in,", + " defaults to ./tmp/visual_regression", + " --docs The folder containing built documentation, used when --run is active", + "FLAGS", + " --jobs, -j Specify the number of workers to use when capturing screenshots, defaults to 6", + " --theme Specify the theme to use when capturing screenshots, default to light", + " --help, -h Show this message", + "TASKS", + " --run Execute ./bin/typedoc, runs first", + " --screenshot Use puppeteer to capture screenshots of the generated docs, runs second", + " --compare Use reg-suit to compare baseline/regression screenshots, runs third", + " --accept Accept the current screenshots, runs last.", + "", + "If no task flags are specified, will act as if all but --accept are specified", + ]; + console.log("node scripts/visual_regression.js"); + console.log(help.join("\n")); +} + +async function main() { + const args = util.parseArgs({ + options: { + dir: { + type: "string", + }, + docs: { + type: "string", + }, + accept: { + type: "boolean", + }, + run: { + type: "boolean", + }, + screenshot: { + type: "boolean", + }, + compare: { + type: "boolean", + }, + jobs: { + short: "j", + type: "string", + default: "6", + }, + theme: { + type: "string", + }, + help: { + type: "boolean", + short: "h", + }, + }, + }); + + if (args.values.help) { + printHelp(); + return; + } + + const dir = + args.values.dir ?? + fileURLToPath(new URL("../tmp/visual_regression", import.meta.url)); + const docs = args.values.docs ?? new URL("../docs", import.meta.url); + const jobs = parseInt(args.values.jobs || "6"); + + const userSpecifiedJob = + args.values.accept || + args.values.run || + args.values.screenshot || + args.values.compare; + + if (args.values.run || !userSpecifiedJob) { + spawnSync("node", ["bin/typedoc"], { + cwd: new URL("../", import.meta.url), + stdio: "inherit", + }); + } + + if (args.values.screenshot || !userSpecifiedJob) { + await captureScreenshots( + typeof docs === "string" ? docs : fileURLToPath(docs), + join(dir, "screenshots"), + jobs, + true, + args.values.theme ?? "light", + ); + + if (!existsSync(join(dir, "baseline"))) { + accept(dir); + console.log("Initial baseline accepted, run again to compare."); + return; + } + } + + if (args.values.compare || !userSpecifiedJob) { + compare(dir); + console.log(`Open ${dir}/output/index.html to review diffs`); + } + + if (args.values.accept) { + accept(dir); + return; + } +} + +if (import.meta.url.endsWith(process.argv[1])) { + try { + const start = Date.now(); + await main(); + console.log( + "Took", + ((Date.now() - start) / 1000).toFixed(3), + "seconds", + ); + } catch (error) { + if (error.code == "ERR_PARSE_ARGS_UNKNOWN_OPTION") { + printHelp(); + process.exit(1); + } + throw error; + } +} diff --git a/src/lib/converter/symbols.ts b/src/lib/converter/symbols.ts index 1fcf27337..f998b62e4 100644 --- a/src/lib/converter/symbols.ts +++ b/src/lib/converter/symbols.ts @@ -754,6 +754,8 @@ function convertProperty( parameterType = declaration.type; } setModifiers(symbol, declaration, reflection); + } else { + setSymbolModifiers(symbol, reflection); } reflection.defaultValue = declaration && convertDefaultValue(declaration); @@ -1283,6 +1285,7 @@ function setModifiers( declaration: ts.Declaration | undefined, reflection: Reflection, ) { + setSymbolModifiers(symbol, reflection); if (!declaration) { return; } @@ -1334,3 +1337,10 @@ function setModifiers( // ReflectionFlag.Static happens when constructing the reflection. // We don't have sufficient information here to determine if it ought to be static. } + +function setSymbolModifiers(symbol: ts.Symbol, reflection: Reflection) { + reflection.setFlag( + ReflectionFlag.Optional, + hasAllFlags(symbol.flags, ts.SymbolFlags.Optional), + ); +} diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 10656e5e1..2e87960b4 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -263,8 +263,8 @@ export = { help_customFooterHtml: "Custom footer after the TypeDoc link", help_customFooterHtmlDisableWrapper: "If set, disables the wrapper element for customFooterHtml", - help_hideParameterTypesInTitle: - "Hides parameter types in signature titles for easier scanning", + help_hideTypesInSignatureTitle: + "Hides parameter and return types in signature titles for easier scanning", help_cacheBust: "Include the generation time in links to static assets", help_searchInComments: "If set, the search index will also include comments. This will greatly increase the size of the search index", diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 7a8ae1659..69503f5b1 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -287,8 +287,7 @@ export = localeUtils.buildIncompleteTranslation({ help_customFooterHtml: "TypeDoc リンクの後のカスタム フッター", help_customFooterHtmlDisableWrapper: "設定されている場合、customFooterHtml のラッパー要素が無効になります。", - help_hideParameterTypesInTitle: - "署名タイトルのパラメータタイプを非表示にしてスキャンしやすくします", + // help_hideTypesInSignatureTitle help_cacheBust: "静的アセットへのリンクに生成時間を含める", help_searchInComments: "設定すると、検索インデックスにコメントも含まれます。これにより、検索インデックスのサイズが大幅に増加します。", diff --git a/src/lib/internationalization/locales/ko.cts b/src/lib/internationalization/locales/ko.cts index b5952c90e..f505c3ca3 100644 --- a/src/lib/internationalization/locales/ko.cts +++ b/src/lib/internationalization/locales/ko.cts @@ -133,8 +133,7 @@ export = localeUtils.buildIncompleteTranslation({ help_customFooterHtml: "TypeDoc 링크 뒤에 사용자 정의 푸터를 지정합니다", help_customFooterHtmlDisableWrapper: "customFooterHtml의 래퍼 요소를 비활성화합니다", - help_hideParameterTypesInTitle: - "제목에서 매개변수 유형을 숨겨 스캔하기 쉽게합니다", + // help_hideTypesInSignatureTitle help_cacheBust: "정적 자산의 링크에 생성 시간을 포함합니다", help_searchInComments: "검색 인덱스에 주석도 포함합니다. 이 옵션을 사용하면 검색 인덱스의 크기가 크게 증가합니다", diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index d9ecd7798..79371cb90 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -241,7 +241,7 @@ export = localeUtils.buildIncompleteTranslation({ help_customFooterHtml: "TypeDoc 链接后的自定义页脚", help_customFooterHtmlDisableWrapper: "如果设置,则禁用 customFooterHtml 的包装元素", - help_hideParameterTypesInTitle: "隐藏签名标题中的参数类型,以便于扫描", + // help_hideTypesInSignatureTitle help_cacheBust: "在静态资产链接中包含生成时间", help_searchInComments: "如果设置,搜索索引还将包括评论。这将大大增加搜索索引的大小", diff --git a/src/lib/models/comments/comment.ts b/src/lib/models/comments/comment.ts index e0ab45a9d..daabfabbf 100644 --- a/src/lib/models/comments/comment.ts +++ b/src/lib/models/comments/comment.ts @@ -170,7 +170,9 @@ export class Comment { /** * Helper utility to clone {@link Comment.summary} or {@link CommentTag.content} */ - static cloneDisplayParts(parts: readonly CommentDisplayPart[]) { + static cloneDisplayParts( + parts: readonly CommentDisplayPart[], + ): CommentDisplayPart[] { return parts.map((p) => ({ ...p })); } diff --git a/src/lib/models/types.ts b/src/lib/models/types.ts index 282c4a3de..7ae20c1db 100644 --- a/src/lib/models/types.ts +++ b/src/lib/models/types.ts @@ -14,6 +14,8 @@ import type { DeclarationReference } from "../converter/comments/declarationRefe import { findPackageForPath } from "../utils/fs.js"; import { ReflectionKind } from "./reflections/kind.js"; import { Comment, type CommentDisplayPart } from "./comments/index.js"; +import { joinArray } from "../utils/array.js"; +import type { SignatureReflection } from "./reflections/signature.js"; /** * Base class of all type definitions. @@ -60,6 +62,13 @@ export abstract class Type { * the returned string should be wrapped in parenthesis. */ protected abstract getTypeString(): string; + + /** + * Return the estimated size of the type if it was all printed on one line. + */ + estimatePrintWidth(): number { + return this.getTypeString().length; + } } /** @category Types */ @@ -1060,15 +1069,29 @@ export class ReflectionType extends Type { super(); } - // This really ought to do better, but I'm putting off investing effort here until - // I'm fully convinced that keeping this is a good idea. Currently, I'd much rather - // change object types to not create reflections. protected override getTypeString() { - if (!this.declaration.children && this.declaration.signatures) { - return "Function"; - } else { - return "Object"; + const parts: string[] = []; + const sigs = this.declaration.getAllSignatures(); + for (const sig of sigs) { + parts.push(sigStr(sig, ": ")); + } + + if (this.declaration.children) { + for (const p of this.declaration.children) { + parts.push(`${p.name}${propertySep(p)} ${typeStr(p.type)}`); + } + return `{ ${parts.join("; ")} }`; + } + + if (sigs.length === 1) { + return sigStr(sigs[0], " => "); } + + if (parts.length === 0) { + return "{}"; + } + + return `{ ${parts.join("; ")} }`; } override needsParenthesis(): boolean { @@ -1423,3 +1446,20 @@ export class UnknownType extends Type { }; } } + +function propertySep(refl: Reflection) { + return refl.flags.isOptional ? "?:" : ":"; +} + +function typeStr(type: Type | undefined) { + return type?.toString() ?? "any"; +} + +function sigStr(sig: SignatureReflection, sep: string) { + const params = joinArray( + sig.parameters, + ", ", + (p) => `${p.name}${propertySep(p)} ${typeStr(p.type)}`, + ); + return `(${params})${sep}${typeStr(sig.type)}`; +} diff --git a/src/lib/output/themes/default/DefaultThemeRenderContext.ts b/src/lib/output/themes/default/DefaultThemeRenderContext.ts index baa40adb9..991c92659 100644 --- a/src/lib/output/themes/default/DefaultThemeRenderContext.ts +++ b/src/lib/output/themes/default/DefaultThemeRenderContext.ts @@ -40,7 +40,6 @@ import { settings, sidebarLinks, } from "./partials/navigation.js"; -import { parameter } from "./partials/parameter.js"; import { reflectionPreview } from "./partials/reflectionPreview.js"; import { toolbar } from "./partials/toolbar.js"; import { type } from "./partials/type.js"; @@ -50,6 +49,11 @@ import { indexTemplate } from "./templates/index.js"; import { documentTemplate } from "./templates/document.js"; import { hierarchyTemplate } from "./templates/hierarchy.js"; import { reflectionTemplate } from "./templates/reflection.js"; +import { + typeDeclaration, + typeDetails, + typeDetailsIfUseful, +} from "./partials/typeDetails.js"; function bind(fn: (f: F, ...a: L) => R, first: F) { return (...r: L) => fn(first, ...r); @@ -126,6 +130,24 @@ export class DefaultThemeRenderContext { */ reflectionPreview = bind(reflectionPreview, this); + /** + * Used to render additional details about a type. This is used to implement + * the `@expand` tag, comments on union members, comments on object type members... + */ + typeDetails = bind(typeDetails, this); + + /** + * Should call the {@link typeDetails} helper if rendering additional details + * about the type will provide the user with more information about the type. + */ + typeDetailsIfUseful = bind(typeDetailsIfUseful, this); + + /** + * Wrapper around {@link typeDetails} which checks if it is useful + * and includes a "Type Declaration" header. + */ + typeDeclaration = bind(typeDeclaration, this); + breadcrumb = bind(breadcrumb, this); commentSummary = bind(commentSummary, this); commentTags = bind(commentTags, this); @@ -149,7 +171,6 @@ export class DefaultThemeRenderContext { settings = bind(settings, this); navigation = bind(navigation, this); pageNavigation = bind(pageNavigation, this); - parameter = bind(parameter, this); toolbar = bind(toolbar, this); type = bind(type, this); typeAndParent = bind(typeAndParent, this); diff --git a/src/lib/output/themes/default/assets/typedoc/Component.ts b/src/lib/output/themes/default/assets/typedoc/Component.ts index b8238bfb2..fdc180436 100644 --- a/src/lib/output/themes/default/assets/typedoc/Component.ts +++ b/src/lib/output/themes/default/assets/typedoc/Component.ts @@ -8,12 +8,13 @@ export interface IComponentOptions { /** * TypeDoc component class. */ -export class Component { - protected el: HTMLElement; +export class Component { + protected el: E; protected app: Application; constructor(options: IComponentOptions) { - this.el = options.el; + this.el = options.el as E; this.app = options.app; + console.log("Created", this, "for", options); } } diff --git a/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts b/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts index 815fd026c..2da0ccc9d 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Accordion.ts @@ -4,9 +4,7 @@ import { storage } from "../utils/storage.js"; /** * Handles accordion dropdown behavior. */ -export class Accordion extends Component { - override el!: HTMLDetailsElement; - +export class Accordion extends Component { /** * The heading container for this accordion. */ diff --git a/src/lib/output/themes/default/assets/typedoc/components/Filter.ts b/src/lib/output/themes/default/assets/typedoc/components/Filter.ts index f4874a2b4..4975aafa3 100644 --- a/src/lib/output/themes/default/assets/typedoc/components/Filter.ts +++ b/src/lib/output/themes/default/assets/typedoc/components/Filter.ts @@ -7,9 +7,7 @@ style.dataset.for = "filters"; /** * Handles sidebar filtering functionality. */ -export class Filter extends Component { - override el!: HTMLInputElement; - +export class Filter extends Component { /** * The class name & ID by which to store the filter value. */ diff --git a/src/lib/output/themes/default/partials/member.declaration.tsx b/src/lib/output/themes/default/partials/member.declaration.tsx index 0b6eeebf7..e586ebf0f 100644 --- a/src/lib/output/themes/default/partials/member.declaration.tsx +++ b/src/lib/output/themes/default/partials/member.declaration.tsx @@ -1,34 +1,11 @@ -import type { DeclarationReflection, ReflectionType } from "../../../../models/index.js"; -import { JSX, Raw } from "../../../../utils/index.js"; +import type { DeclarationReflection } from "../../../../models/index.js"; +import { JSX } from "../../../../utils/index.js"; import { getKindClass, hasTypeParameters, renderTypeParametersSignature, wbr } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -function renderingTypeDeclarationIsUseful(declaration: DeclarationReflection): boolean { - if (declaration.hasComment()) return true; - if (declaration.children?.some(renderingTypeDeclarationIsUseful)) return true; - if (declaration.type?.type === "reflection" && renderingTypeDeclarationIsUseful(declaration.type.declaration)) { - return true; - } - - return declaration.getAllSignatures().some((sig) => { - return sig.hasComment() || sig.parameters?.some((p) => p.hasComment()); - }); -} +void JSX; // TS is confused and thinks this is unused export function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection) { - function renderTypeDeclaration(type: ReflectionType) { - if (renderingTypeDeclarationIsUseful(type.declaration)) { - return ( -
        -

        {context.i18n.theme_type_declaration()}

        - {context.parameter(type.declaration)} -
        - ); - } - } - - const visitor = { reflection: renderTypeDeclaration }; - return ( <>
        @@ -54,29 +31,7 @@ export function memberDeclaration(context: DefaultThemeRenderContext, props: Dec {hasTypeParameters(props) && context.typeParameters(props.typeParameters)} - {props.type?.visit({ - reflection: renderTypeDeclaration, - array: (arr) => arr.elementType.visit(visitor), - intersection: (int) => int.types.map((t) => t.visit(visitor)), - union: (union) => { - if (union.elementSummaries) { - const result: JSX.Children = []; - for (let i = 0; i < union.types.length; ++i) { - result.push( -
      • - {context.type(union.types[i])} - - {union.types[i].visit(visitor)} -
      • , - ); - } - return
          {result}
        ; - } - return union.types.map((t) => t.visit(visitor)); - }, - reference: (ref) => ref.typeArguments?.map((t) => t.visit(visitor)), - tuple: (ref) => ref.elements.map((t) => t.visit(visitor)), - })} + {props.type && context.typeDeclaration(props.type)} {context.commentTags(props)} diff --git a/src/lib/output/themes/default/partials/member.signature.body.tsx b/src/lib/output/themes/default/partials/member.signature.body.tsx index bfa9773e4..c82405bbf 100644 --- a/src/lib/output/themes/default/partials/member.signature.body.tsx +++ b/src/lib/output/themes/default/partials/member.signature.body.tsx @@ -1,6 +1,6 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; import { JSX, Raw } from "../../../../utils/index.js"; -import { ReflectionType, type SignatureReflection } from "../../../../models/index.js"; +import type { SignatureReflection } from "../../../../models/index.js"; import { hasTypeParameters } from "../../lib.js"; export function memberSignatureBody( @@ -38,7 +38,7 @@ export function memberSignatureBody( {context.commentSummary(item)} {context.commentTags(item)} - {item.type instanceof ReflectionType && context.parameter(item.type.declaration)} + {context.typeDetailsIfUseful(item.type)} ))}
      @@ -50,7 +50,7 @@ export function memberSignatureBody( {context.i18n.theme_returns()} {context.type(props.type)} {returnsTag && } - {props.type instanceof ReflectionType && context.parameter(props.type.declaration)} + {context.typeDetailsIfUseful(props.type)} )} diff --git a/src/lib/output/themes/default/partials/member.signature.title.tsx b/src/lib/output/themes/default/partials/member.signature.title.tsx index 3bb053063..572a0e017 100644 --- a/src/lib/output/themes/default/partials/member.signature.title.tsx +++ b/src/lib/output/themes/default/partials/member.signature.title.tsx @@ -36,10 +36,10 @@ export function memberSignatureTitle( { hideName = false, arrowStyle = false, - hideParamTypes = context.options.getValue("hideParameterTypesInTitle"), - }: { hideName?: boolean; arrowStyle?: boolean; hideParamTypes?: boolean } = {}, + hideTypes = context.options.getValue("hideTypesInSignatureTitle"), + }: { hideName?: boolean; arrowStyle?: boolean; hideTypes?: boolean } = {}, ) { - const renderParam = hideParamTypes ? renderParameterWithoutType : renderParameterWithType.bind(null, context); + const renderParam = hideTypes ? renderParameterWithoutType : renderParameterWithType.bind(null, context); return ( <> @@ -59,7 +59,7 @@ export function memberSignatureTitle( ( {join(", ", props.parameters ?? [], renderParam)} ) - {!!props.type && ( + {!!props.type && !hideTypes && ( <> {arrowStyle ? " => " : ": "} {context.type(props.type)} diff --git a/src/lib/output/themes/default/partials/parameter.tsx b/src/lib/output/themes/default/partials/parameter.tsx deleted file mode 100644 index a1e392792..000000000 --- a/src/lib/output/themes/default/partials/parameter.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { classNames, getKindClass, wbr } from "../../lib.js"; -import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -import { JSX } from "../../../../utils/index.js"; -import { type DeclarationReflection, ReflectionType, type SignatureReflection } from "../../../../models/index.js"; - -void JSX; // Trick TS into seeing this as used, the import is required. - -export const parameter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( - <> -
        - {!!props.signatures && ( -
      • -
          - {props.signatures.map((item) => ( - <> -
        • - {context.memberSignatureTitle(item, { - hideName: true, - })} -
        • -
        • - {context.memberSignatureBody(item, { - hideSources: true, - })} -
        • - - ))} -
        -
      • - )} - {props.indexSignatures?.map((index) => renderParamIndexSignature(context, index))} - {props.children?.map((item) => ( - <> - {item.signatures ? ( -
      • -
        - {!!item.flags.isRest && ...} - {wbr(item.name)} - {!!item.flags.isOptional && "?"}: - function -
        - - {context.memberSignatures(item)} -
      • - ) : item.type ? ( - <> - {/* standard type */} -
      • -
        - {context.reflectionFlags(item)} - {!!item.flags.isRest && ...} - {wbr(item.name)} - - {!!item.flags.isOptional && "?"} - {": "} - - {context.type(item.type)} -
        - {context.commentSummary(item)} - {context.commentTags(item)} - {!!item.children && context.parameter(item)} - {item.type instanceof ReflectionType && context.parameter(item.type.declaration)} -
      • - - ) : ( - <> - {/* getter/setter */} - {item.getSignature && ( - <> - {/* getter */} -
      • -
        - {context.reflectionFlags(item.getSignature)} - get - {wbr(item.name)} - (): - {context.type(item.getSignature.type)} -
        - - {context.commentSummary(item.getSignature)} - {context.commentTags(item.getSignature)} -
      • - - )} - {item.setSignature && ( - <> - {/* setter */} -
      • -
        - {context.reflectionFlags(item.setSignature)} - set - {wbr(item.name)} - ( - {item.setSignature.parameters?.map((item) => ( - <> - {item.name} - : - {context.type(item.type)} - - ))} - ): - {context.type(item.setSignature.type)} -
        - - {context.commentSummary(item.setSignature)} - {context.commentTags(item.setSignature)} -
      • - - )} - - )} - - ))} -
      - -); - -function renderParamIndexSignature(context: DefaultThemeRenderContext, index: SignatureReflection) { - return ( -
    • -
      - [ - {index.parameters!.map((item) => ( - <> - {item.name} - {": "} - {context.type(item.type)} - - ))} - {"]: "} - {context.type(index.type)} -
      - {context.commentSummary(index)} - {context.commentTags(index)} - {index.type instanceof ReflectionType && context.parameter(index.type.declaration)} -
    • - ); -} diff --git a/src/lib/output/themes/default/partials/type.tsx b/src/lib/output/themes/default/partials/type.tsx index 5749b219f..8bfd4d13b 100644 --- a/src/lib/output/themes/default/partials/type.tsx +++ b/src/lib/output/themes/default/partials/type.tsx @@ -379,7 +379,7 @@ const typeRenderers: { {context.memberSignatureTitle(sig, { hideName: true, arrowStyle: false, - hideParamTypes: false, + hideTypes: false, })} , ); @@ -418,7 +418,7 @@ const typeRenderers: { {context.memberSignatureTitle(type.declaration.signatures[0], { hideName: true, arrowStyle: true, - hideParamTypes: false, + hideTypes: false, })} ) @@ -426,7 +426,7 @@ const typeRenderers: { } for (const item of type.declaration.signatures || []) { - members.push(context.memberSignatureTitle(item, { hideName: true, hideParamTypes: false })); + members.push(context.memberSignatureTitle(item, { hideName: true, hideTypes: false })); } if (members.length) { diff --git a/src/lib/output/themes/default/partials/typeDetails.tsx b/src/lib/output/themes/default/partials/typeDetails.tsx new file mode 100644 index 000000000..392c4e65a --- /dev/null +++ b/src/lib/output/themes/default/partials/typeDetails.tsx @@ -0,0 +1,229 @@ +import type { DeclarationReflection, SignatureReflection } from "../../../../models/index.js"; +import type { SomeType, TypeVisitor } from "../../../../models/types.js"; +import { JSX, Raw } from "../../../../utils/index.js"; +import { classNames, getKindClass } from "../../lib.js"; +import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; + +const isUsefulVisitor: Partial> = { + array(type) { + return renderingTypeDetailsIsUseful(type.elementType); + }, + intersection(type) { + return type.types.some(renderingTypeDetailsIsUseful); + }, + union(type) { + return !!type.elementSummaries || type.types.some(renderingTypeDetailsIsUseful); + }, + reflection(type) { + return renderingChildIsUseful(type.declaration); + }, +}; + +function renderingTypeDetailsIsUseful(type: SomeType) { + return type.visit(isUsefulVisitor) ?? false; +} + +export function typeDeclaration(context: DefaultThemeRenderContext, type: SomeType): JSX.Children { + if (renderingTypeDetailsIsUseful(type)) { + return ( +
      +

      {context.i18n.theme_type_declaration()}

      + {context.typeDetails(type)} +
      + ); + } + return null; +} + +export function typeDetails(context: DefaultThemeRenderContext, type: SomeType): JSX.Children { + return type.visit({ + array(type) { + return context.typeDetails(type.elementType); + }, + intersection(type) { + return type.types.map(context.typeDetails); + }, + union(type) { + const result: JSX.Children = []; + for (let i = 0; i < type.types.length; ++i) { + result.push( +
    • + {context.type(type.types[i])} + + {context.typeDetailsIfUseful(type.types[i])} +
    • , + ); + } + return
        {result}
      ; + }, + reflection(type) { + const declaration = type.declaration; + + return ( +
        + {declaration.signatures && ( +
      • +
          + {declaration.signatures.map((item) => ( + <> +
        • + {context.memberSignatureTitle(item, { + hideName: true, + hideTypes: true, + })} +
        • +
        • + {context.memberSignatureBody(item, { + hideSources: true, + })} +
        • + + ))} +
        +
      • + )} + {declaration.indexSignatures?.map((index) => renderIndexSignature(context, index))} + {declaration.children?.map((child) => renderChild(context, child))} +
      + ); + }, + reference() { + // TODO: Check for @expand + return null; + }, + // tuple?? + }); +} + +export function typeDetailsIfUseful(context: DefaultThemeRenderContext, type: SomeType | undefined): JSX.Children { + if (type && renderingTypeDetailsIsUseful(type)) { + return context.typeDetails(type); + } +} + +function renderChild(context: DefaultThemeRenderContext, child: DeclarationReflection) { + if (child.signatures) { + return ( +
    • +
      + {!!child.flags.isRest && ...} + {child.name} + {!!child.flags.isOptional && "?"}: + function +
      + + {context.memberSignatures(child)} +
    • + ); + } + + // standard type + if (child.type) { + return ( +
    • +
      + {context.reflectionFlags(child)} + {!!child.flags.isRest && ...} + {child.name} + + {!!child.flags.isOptional && "?"} + {": "} + + {context.type(child.type)} +
      + {context.commentSummary(child)} + {context.commentTags(child)} + {child.children?.some(renderingChildIsUseful) && ( +
        {child.children.map((c) => renderChild(context, c))}
      + )} +
    • + ); + } + + // getter/setter + return ( + <> + {child.getSignature && ( +
    • +
      + {context.reflectionFlags(child.getSignature)} + get + {child.name} + (): + {context.type(child.getSignature.type)} +
      + + {context.commentSummary(child.getSignature)} + {context.commentTags(child.getSignature)} +
    • + )} + {child.setSignature && ( +
    • +
      + {context.reflectionFlags(child.setSignature)} + set + {child.name} + ( + {child.setSignature.parameters?.map((item) => ( + <> + {item.name} + : + {context.type(item.type)} + + ))} + ): + {context.type(child.setSignature.type)} +
      + + {context.commentSummary(child.setSignature)} + {context.commentTags(child.setSignature)} +
    • + )} + + ); +} + +function renderIndexSignature(context: DefaultThemeRenderContext, index: SignatureReflection) { + return ( +
    • +
      + [ + {index.parameters!.map((item) => ( + <> + {item.name} + {": "} + {context.type(item.type)} + + ))} + {"]: "} + {context.type(index.type)} +
      + {context.commentSummary(index)} + {context.commentTags(index)} + {context.typeDeclaration(index.type!)} +
    • + ); +} + +function renderingChildIsUseful(refl: DeclarationReflection) { + if (refl.hasComment()) return true; + if ( + refl.children?.some((child) => { + if (child.hasComment()) return true; + if (child.type) { + return renderingTypeDetailsIsUseful(child.type); + } + }) + ) { + return true; + } + + return refl.getAllSignatures().some((sig) => { + return sig.hasComment() || sig.parameters?.some((p) => p.hasComment()); + }); +} diff --git a/src/lib/output/themes/default/templates/reflection.tsx b/src/lib/output/themes/default/templates/reflection.tsx index e71756a6b..5cdd7408a 100644 --- a/src/lib/output/themes/default/templates/reflection.tsx +++ b/src/lib/output/themes/default/templates/reflection.tsx @@ -5,7 +5,6 @@ import { type ContainerReflection, DeclarationReflection, ReflectionKind, - ReflectionType, type SignatureReflection, } from "../../../../models/index.js"; import { JSX, Raw } from "../../../../utils/index.js"; @@ -96,7 +95,7 @@ function renderIndexSignature(context: DefaultThemeRenderContext, index: Signatu
{context.commentSummary(index)} {context.commentTags(index)} - {index.type instanceof ReflectionType && context.parameter(index.type.declaration)} + {context.typeDetailsIfUseful(index.type)} ); } diff --git a/src/lib/output/themes/lib.tsx b/src/lib/output/themes/lib.tsx index 390f031c7..037c2b146 100644 --- a/src/lib/output/themes/lib.tsx +++ b/src/lib/output/themes/lib.tsx @@ -98,7 +98,7 @@ export function renderTypeParametersSignature( typeParameters: readonly TypeParameterReflection[] | undefined, ): JSX.Element { if (!typeParameters || typeParameters.length === 0) return <>; - const hideParamTypes = context.options.getValue("hideParameterTypesInTitle"); + const hideParamTypes = context.options.getValue("hideTypesInSignatureTitle"); if (hideParamTypes) { return ( diff --git a/src/lib/utils/array.ts b/src/lib/utils/array.ts index ff79d13aa..c6ef3f1bb 100644 --- a/src/lib/utils/array.ts +++ b/src/lib/utils/array.ts @@ -170,3 +170,29 @@ export function filter( ): readonly T[] { return array ? array.filter(predicate) : emptyArray; } + +export function aggregate(arr: T[], fn: (item: T) => number) { + return arr.reduce((sum, it) => sum + fn(it), 0); +} + +export function aggregateWithJoiner( + arr: T[], + fn: (item: T) => number, + joiner: string, +) { + return ( + arr.reduce((sum, it) => sum + fn(it), 0) + + (arr.length - 1) * joiner.length + ); +} + +export function joinArray( + arr: readonly T[] | undefined, + joiner: string, + mapper: (item: T) => string, +): string { + if (arr?.length) { + return arr.map(mapper).join(joiner); + } + return ""; +} diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index f726448d5..d44b89a3b 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -168,7 +168,7 @@ export interface TypeDocOptionMap { hideGenerator: boolean; customFooterHtml: string; customFooterHtmlDisableWrapper: boolean; - hideParameterTypesInTitle: boolean; + hideTypesInSignatureTitle: boolean; searchInComments: boolean; searchInDocuments: boolean; cleanOutputDir: boolean; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index 7618b6501..a6ceb865d 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -506,8 +506,8 @@ export function addTypeDocOptions(options: Pick) { type: ParameterType.Boolean, }); options.addDeclaration({ - name: "hideParameterTypesInTitle", - help: (i18n) => i18n.help_hideParameterTypesInTitle(), + name: "hideTypesInSignatureTitle", + help: (i18n) => i18n.help_hideTypesInSignatureTitle(), type: ParameterType.Boolean, defaultValue: true, }); diff --git a/src/test/behavior.c2.test.ts b/src/test/behavior.c2.test.ts index 8f7697766..893e57a11 100644 --- a/src/test/behavior.c2.test.ts +++ b/src/test/behavior.c2.test.ts @@ -1189,7 +1189,10 @@ describe("Behavior Tests", () => { it("Should not warn about recursive types", () => { const project = convert("refusingToRecurse"); const schemaTypeBased = query(project, "schemaTypeBased"); - equal(schemaTypeBased.type?.toString(), "Object & Object"); + equal( + schemaTypeBased.type?.toString(), + "{} & { x: ({ y?: string } & { z: string })[] }", + ); equal( querySig(project, "Map.getFilter").type?.toString(), "void | ExpressionSpecification", diff --git a/src/test/converter/variables/specs.json b/src/test/converter/variables/specs.json index b0d5a47fc..786157538 100644 --- a/src/test/converter/variables/specs.json +++ b/src/test/converter/variables/specs.json @@ -676,19 +676,12 @@ "name": "bold", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ - { - "type": "intrinsic", - "name": "undefined" - }, - { - "type": "intrinsic", - "name": "boolean" - } - ] + "type": "intrinsic", + "name": "boolean" }, "defaultValue": "false" }, @@ -697,26 +690,19 @@ "name": "location", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ + "type": "tuple", + "elements": [ { "type": "intrinsic", - "name": "undefined" + "name": "number" }, { - "type": "tuple", - "elements": [ - { - "type": "intrinsic", - "name": "number" - }, - { - "type": "intrinsic", - "name": "number" - } - ] + "type": "intrinsic", + "name": "number" } ] }, @@ -727,19 +713,12 @@ "name": "text", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ - { - "type": "intrinsic", - "name": "undefined" - }, - { - "type": "intrinsic", - "name": "string" - } - ] + "type": "intrinsic", + "name": "string" }, "defaultValue": "\"\"" } diff --git a/src/test/converter/variables/specs.nodoc.json b/src/test/converter/variables/specs.nodoc.json index 2b7a85989..5451e9e89 100644 --- a/src/test/converter/variables/specs.nodoc.json +++ b/src/test/converter/variables/specs.nodoc.json @@ -314,19 +314,12 @@ "name": "bold", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ - { - "type": "intrinsic", - "name": "undefined" - }, - { - "type": "intrinsic", - "name": "boolean" - } - ] + "type": "intrinsic", + "name": "boolean" }, "defaultValue": "false" }, @@ -335,26 +328,19 @@ "name": "location", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ + "type": "tuple", + "elements": [ { "type": "intrinsic", - "name": "undefined" + "name": "number" }, { - "type": "tuple", - "elements": [ - { - "type": "intrinsic", - "name": "number" - }, - { - "type": "intrinsic", - "name": "number" - } - ] + "type": "intrinsic", + "name": "number" } ] }, @@ -365,19 +351,12 @@ "name": "text", "variant": "declaration", "kind": 1024, - "flags": {}, + "flags": { + "isOptional": true + }, "type": { - "type": "union", - "types": [ - { - "type": "intrinsic", - "name": "undefined" - }, - { - "type": "intrinsic", - "name": "string" - } - ] + "type": "intrinsic", + "name": "string" }, "defaultValue": "\"\"" } diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index e14e250ac..3d1ada738 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1355,7 +1355,7 @@ describe("Issue Tests", () => { const project = convert(); const is = querySig(project, "FooA.is"); - equal(is.type?.toString(), "this is Foo & Object"); + equal(is.type?.toString(), "this is Foo & { type: Type }"); }); it("#2466 Does not care about conversion order for @link resolution, ", () => { @@ -1437,18 +1437,10 @@ describe("Issue Tests", () => { const project = convert(); const type = querySig(project, "fromPartial").typeParameters![0].type; - // function fromPartial(object: I): void - equal(type?.toString(), "Value & Object"); + equal( + type?.toString(), + "Value & { values: Value[] & (Value & { values: Value[] & (Value & { values: (...) & (...) })[] })[] }", + ); }); it("#2508 Handles constructed references to enumeration types, ", () => { From df0b9b5be7ff28a302d948b720ce867cf5d7e5b7 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 30 Jun 2024 19:55:23 -0600 Subject: [PATCH 023/219] Smart type formatter I think this is mostly complete at this point, there's some minor cleanup to be done still, but it works! --- .config/.prettierrc.json | 6 + CHANGELOG.md | 5 +- scripts/visual_regression.js | 5 +- src/index.ts | 1 + src/lib/converter/factories/signature.ts | 4 +- src/lib/converter/plugins/TypePlugin.ts | 4 +- src/lib/internationalization/locales/en.cts | 2 - src/lib/models/reflections/abstract.ts | 1 - src/lib/models/reflections/declaration.ts | 9 +- src/lib/models/types.ts | 18 +- src/lib/output/formatter.tsx | 1109 +++++++++++++++++ src/lib/output/index.ts | 1 + src/lib/output/renderer.ts | 2 - .../default/partials/member.declaration.tsx | 17 +- .../default/partials/member.getterSetter.tsx | 10 +- .../partials/member.signature.title.tsx | 71 +- .../default/partials/reflectionPreview.tsx | 19 +- .../output/themes/default/partials/type.tsx | 569 +-------- .../themes/default/partials/typeDetails.tsx | 1 - src/lib/output/themes/lib.tsx | 2 +- src/lib/serialization/components.ts | 3 - src/lib/utils/jsx.ts | 50 +- src/lib/utils/options/declaration.ts | 1 - src/lib/utils/options/sources/typedoc.ts | 6 - src/test/behavior.c2.test.ts | 10 +- src/test/comments.test.ts | 19 +- .../class/specs-with-lump-categories.json | 32 +- src/test/converter/class/specs.json | 32 +- src/test/converter/comment/specs.json | 2 +- src/test/converter/declaration/specs.json | 6 +- src/test/converter/function/specs.json | 2 +- .../converter/inherit-param-doc/specs.json | 6 +- src/test/converter/inheritance/specs.json | 4 +- src/test/converter/interface/specs.json | 12 +- src/test/converter/mixin/specs.json | 12 +- src/test/converter/react/specs.json | 2 +- src/test/converter/variables/specs.json | 6 +- src/test/output/formatter.test.ts | 346 +++++ src/test/utils.ts | 18 + 39 files changed, 1653 insertions(+), 772 deletions(-) create mode 100644 src/lib/output/formatter.tsx create mode 100644 src/test/output/formatter.test.ts diff --git a/.config/.prettierrc.json b/.config/.prettierrc.json index ff1608b53..d60c8c079 100644 --- a/.config/.prettierrc.json +++ b/.config/.prettierrc.json @@ -5,6 +5,12 @@ "options": { "printWidth": 120 } + }, + { + "files": "formatter.tsx", + "options": { + "printWidth": 80 + } } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aeb7aaa8..37f5fdb5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ # Beta -- The `hideParameterTypesInTitle` option has been renamed to `hideTypesInSignatureTitle` and now controls return types as well. - Fixed an issue where properties were not properly marked optional in some cases. This primarily affected destructured parameters. +- Constructor signatures now use the parent class name as their name (e.g. `X`, not `new X`) +- Removed the `hideParameterTypesInTitle` option, this was originally added as a workaround for many signatures overflowing + the available horizontal space in rendered pages. TypeDoc now has logic to wrap types/signatures smartly, so this option is + no longer necessary. # Unreleased diff --git a/scripts/visual_regression.js b/scripts/visual_regression.js index 4c85a3c86..65088de81 100644 --- a/scripts/visual_regression.js +++ b/scripts/visual_regression.js @@ -114,10 +114,13 @@ async function main() { args.values.compare; if (args.values.run || !userSpecifiedJob) { - spawnSync("node", ["bin/typedoc"], { + const runResult = spawnSync("node", ["bin/typedoc"], { cwd: new URL("../", import.meta.url), stdio: "inherit", }); + if (runResult.status) { + process.exit(1); + } } if (args.values.screenshot || !userSpecifiedJob) { diff --git a/src/index.ts b/src/index.ts index 6a3afd154..362c23534 100644 --- a/src/index.ts +++ b/src/index.ts @@ -49,6 +49,7 @@ export type { RendererHooks, NavigationElement, RendererEvents, + PageHeading, } from "./lib/output/index.js"; export { diff --git a/src/lib/converter/factories/signature.ts b/src/lib/converter/factories/signature.ts index dfd21debd..b1841bc0b 100644 --- a/src/lib/converter/factories/signature.ts +++ b/src/lib/converter/factories/signature.ts @@ -38,7 +38,7 @@ export function createSignature( const sigRef = new SignatureReflection( kind == ReflectionKind.ConstructorSignature - ? `new ${context.scope.parent!.name}` + ? context.scope.parent!.name : context.scope.name, kind, context.scope, @@ -148,7 +148,7 @@ export function createConstructSignatureWithType( | undefined; const sigRef = new SignatureReflection( - `new ${context.scope.parent!.name}`, + context.scope.parent!.name, ReflectionKind.ConstructorSignature, context.scope, ); diff --git a/src/lib/converter/plugins/TypePlugin.ts b/src/lib/converter/plugins/TypePlugin.ts index 127a8999c..a36be2658 100644 --- a/src/lib/converter/plugins/TypePlugin.ts +++ b/src/lib/converter/plugins/TypePlugin.ts @@ -5,7 +5,7 @@ import { type ProjectReflection, type Reflection, } from "../../models/reflections/index.js"; -import { type Type, ReferenceType } from "../../models/types.js"; +import { type SomeType, type Type, ReferenceType } from "../../models/types.js"; import { ConverterComponent } from "../components.js"; import type { Context } from "../context.js"; import { ApplicationEvents } from "../../application-events.js"; @@ -129,7 +129,7 @@ export class TypePlugin extends ConverterComponent { let root: DeclarationHierarchy | undefined; let hierarchy: DeclarationHierarchy | undefined; - function push(types: Type[]) { + function push(types: SomeType[]) { const level: DeclarationHierarchy = { types: types }; if (hierarchy) { hierarchy.next = level; diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 2e87960b4..0374c89ad 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -263,8 +263,6 @@ export = { help_customFooterHtml: "Custom footer after the TypeDoc link", help_customFooterHtmlDisableWrapper: "If set, disables the wrapper element for customFooterHtml", - help_hideTypesInSignatureTitle: - "Hides parameter and return types in signature titles for easier scanning", help_cacheBust: "Include the generation time in links to static assets", help_searchInComments: "If set, the search index will also include comments. This will greatly increase the size of the search index", diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index e25e76703..09aa683c0 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -51,7 +51,6 @@ const relevantFlags: ReflectionFlag[] = [ ReflectionFlag.Protected, ReflectionFlag.Static, ReflectionFlag.Optional, - ReflectionFlag.Rest, ReflectionFlag.Abstract, ReflectionFlag.Const, ReflectionFlag.Readonly, diff --git a/src/lib/models/reflections/declaration.ts b/src/lib/models/reflections/declaration.ts index eb5d0adbc..d4a3ce14b 100644 --- a/src/lib/models/reflections/declaration.ts +++ b/src/lib/models/reflections/declaration.ts @@ -1,10 +1,5 @@ import type * as ts from "typescript"; -import { - type ReferenceType, - ReflectionType, - type Type, - type SomeType, -} from "../types.js"; +import { type ReferenceType, ReflectionType, type SomeType } from "../types.js"; import { type TraverseCallback, TraverseProperty } from "./abstract.js"; import { ContainerReflection } from "./container.js"; import type { SignatureReflection } from "./signature.js"; @@ -28,7 +23,7 @@ export interface DeclarationHierarchy { /** * The types represented by this node in the hierarchy. */ - types: Type[]; + types: SomeType[]; /** * The next hierarchy level. diff --git a/src/lib/models/types.ts b/src/lib/models/types.ts index 7ae20c1db..ced9f307e 100644 --- a/src/lib/models/types.ts +++ b/src/lib/models/types.ts @@ -37,10 +37,16 @@ export abstract class Type { /** * Visit this type, returning the value returned by the visitor. */ - visit(visitor: TypeVisitor): T; - visit(visitor: Partial>): T | undefined; - visit(visitor: Partial>): unknown { - return visitor[this.type]?.(this as never); + visit(visitor: TypeVisitor, ...args: A): T; + visit( + visitor: Partial>, + ...args: A + ): T | undefined; + visit( + visitor: Partial>, + ...args: any[] + ): unknown { + return visitor[this.type]?.(this as never, ...args); } stringify(context: TypeContext) { @@ -95,8 +101,8 @@ export interface TypeKindMap { unknown: UnknownType; } -export type TypeVisitor = { - [K in TypeKind]: (type: TypeKindMap[K]) => T; +export type TypeVisitor = { + [K in TypeKind]: (type: TypeKindMap[K], ...args: A) => T; }; export function makeRecursiveVisitor( diff --git a/src/lib/output/formatter.tsx b/src/lib/output/formatter.tsx new file mode 100644 index 000000000..def15d39a --- /dev/null +++ b/src/lib/output/formatter.tsx @@ -0,0 +1,1109 @@ +// Heavily based on https://yorickpeterse.com/articles/how-to-write-a-code-formatter/ +// Implements roughly the same algorithm as Prettier + +import { ok } from "assert"; +import { + LiteralType, + ReferenceType, + TypeContext, + type SomeType, + type TypeVisitor, +} from "../models/types.js"; +import { aggregate } from "../utils/array.js"; +import { assertNever, JSX } from "../utils/index.js"; +import { getKindClass, stringify } from "./themes/lib.js"; +import { + type ProjectReflection, + ReflectionKind, + type Reflection, + type DeclarationReflection, + type SignatureReflection, + type TypeParameterReflection, + type ParameterReflection, +} from "../models/index.js"; + +// Non breaking space +const INDENT = "\u00A0\u00A0\u00A0\u00A0"; + +type Node = + | { type: "text"; content: string } + | { type: "element"; content: JSX.Element; length: number } + | { type: "line" } + | { type: "space_or_line" } + | { type: "indent"; content: Node[] } + | { type: "group"; id: number; content: Node[] } + | { type: "nodes"; content: Node[] } + | { type: "if_wrap"; id: number; true: Node; false: Node }; + +const emptyNode = textNode(""); + +function space() { + return textNode(" "); +} +function textNode(content: string): Node { + return { type: "text", content }; +} +function simpleElement(element: JSX.Element): Node { + ok(element.children.length === 1); + ok(typeof element.children[0] === "string"); + return { + type: "element", + content: element, + length: element.children[0].length, + }; +} +function line(): Node { + return { type: "line" }; +} +function spaceOrLine(): Node { + return { type: "space_or_line" }; +} +function indent(content: Node[]): Node { + return { type: "indent", content }; +} +function group(id: number, content: Node[]): Node { + return { type: "group", id, content }; +} +function nodes(...content: Node[]): Node { + return { type: "nodes", content }; +} +function ifWrap( + id: number, + trueBranch: Node, + falseBranch: Node = emptyNode, +): Node { + return { type: "if_wrap", id, true: trueBranch, false: falseBranch }; +} + +function join(joiner: Node, list: readonly T[], cb: (x: T) => Node): Node { + const content: Node[] = []; + + for (const item of list) { + if (content.length > 0) { + content.push(joiner); + } + content.push(cb(item)); + } + + return { type: "nodes", content }; +} + +function nodeWidth(node: Node, wrapped: Set): number { + switch (node.type) { + case "text": + return node.content.length; + case "element": + return node.length; + case "line": + return 0; + case "space_or_line": + return 1; + case "indent": + case "group": + case "nodes": + return aggregate(node.content, (n) => nodeWidth(n, wrapped)); + case "if_wrap": + return wrapped.has(node.id) + ? nodeWidth(node.true, wrapped) + : nodeWidth(node.false, wrapped); + } +} + +export enum Wrap { + Detect = 0, + Enable = 1, +} + +/** + * Responsible for rendering nodes + */ +export class FormattedCodeGenerator { + private buffer: Array = []; + /** Indentation level, not number of chars */ + private indent = 0; + /** The number of characters on the current line */ + private size: number; + /** Maximum number of characters allowed per line */ + private max: number; + /** Groups which need to be wrapped */ + private wrapped = new Set(); + + constructor(maxWidth: number = 80, startWidth = 0) { + this.max = maxWidth; + this.size = startWidth; + } + + toElement(): JSX.Element { + return <>{this.buffer}; + } + + node(node: Node, wrap: Wrap): void { + switch (node.type) { + case "nodes": { + for (const n of node.content) { + this.node(n, wrap); + } + break; + } + case "group": { + const width = aggregate(node.content, (n) => + nodeWidth(n, this.wrapped), + ); + let wrap: Wrap; + if (this.size + width > this.max) { + this.wrapped.add(node.id); + wrap = Wrap.Enable; + } else { + wrap = Wrap.Detect; + } + for (const n of node.content) { + this.node(n, wrap); + } + break; + } + case "if_wrap": { + if (this.wrapped.has(node.id)) { + this.node(node.true, Wrap.Enable); + } else { + this.node(node.false, wrap); + } + break; + } + case "text": { + this.text(node.content, node.content.length); + break; + } + case "element": { + this.text(node.content, node.length); + break; + } + case "line": { + if (wrap == Wrap.Enable) { + this.newLine(); + } + break; + } + case "space_or_line": { + if (wrap === Wrap.Enable) { + this.newLine(); + } else { + this.text(" ", 1); + } + break; + } + case "indent": { + if (wrap === Wrap.Enable) { + this.size += INDENT.length; + this.indent += 1; + this.buffer.push(INDENT); + for (const n of node.content) { + this.node(n, wrap); + } + this.indent -= 1; + } else { + for (const n of node.content) { + this.node(n, wrap); + } + } + break; + } + default: + assertNever(node); + } + } + + private text(value: string | JSX.Element, chars: number) { + this.size += chars; + this.buffer.push(value); + } + + private newLine() { + this.size = INDENT.length + this.indent; + const last = this.buffer[this.buffer.length - 1]; + if (typeof last === "string") { + this.buffer[this.buffer.length - 1] = last.trimEnd(); + } + this.buffer.push(
); + this.buffer.push(INDENT.repeat(this.indent)); + } +} + +const EXPORTABLE: ReflectionKind = + ReflectionKind.Class | + ReflectionKind.Interface | + ReflectionKind.Enum | + ReflectionKind.TypeAlias | + ReflectionKind.Function | + ReflectionKind.Variable | + ReflectionKind.Namespace; + +const nameCollisionCache = new WeakMap< + ProjectReflection, + Record +>(); +function getNameCollisionCount( + project: ProjectReflection, + name: string, +): number { + let collisions = nameCollisionCache.get(project); + if (collisions === undefined) { + collisions = {}; + for (const reflection of project.getReflectionsByKind(EXPORTABLE)) { + collisions[reflection.name] = + (collisions[reflection.name] ?? 0) + 1; + } + nameCollisionCache.set(project, collisions); + } + return collisions[name] ?? 0; +} + +/** + * Returns a (hopefully) globally unique path for the given reflection. + * + * This only works for exportable symbols, so e.g. methods are not affected by this. + * + * If the given reflection has a globally unique name already, then it will be returned as is. If the name is + * ambiguous (i.e. there are two classes with the same name in different namespaces), then the namespaces path of the + * reflection will be returned. + */ +function getUniquePath(reflection: Reflection): Reflection[] { + if (reflection.kindOf(EXPORTABLE)) { + if (getNameCollisionCount(reflection.project, reflection.name) >= 2) { + return getNamespacedPath(reflection); + } + } + return [reflection]; +} +function getNamespacedPath(reflection: Reflection): Reflection[] { + const path = [reflection]; + let parent = reflection.parent; + while (parent?.kindOf(ReflectionKind.Namespace)) { + path.unshift(parent); + parent = parent.parent; + } + return path; +} + +const typeBuilder: TypeVisitor< + Node, + [FormattedCodeBuilder, { topLevelLinks: boolean }] +> = { + array(type, builder) { + return nodes( + builder.type(type.elementType, TypeContext.arrayElement), + simpleElement([]), + ); + }, + conditional(type, builder) { + const id = builder.newId(); + return group(id, [ + builder.type(type.checkType, TypeContext.conditionalCheck), + space(), + simpleElement(extends), + space(), + builder.type(type.extendsType, TypeContext.conditionalExtends), + spaceOrLine(), + indent([ + simpleElement(?), + space(), + builder.type(type.trueType, TypeContext.conditionalTrue), + spaceOrLine(), + simpleElement(:), + space(), + builder.type(type.falseType, TypeContext.conditionalFalse), + ]), + ]); + }, + indexedAccess(type, builder) { + let indexType = builder.type(type.indexType, TypeContext.indexedIndex); + + if ( + type.objectType instanceof ReferenceType && + type.objectType.reflection && + type.indexType instanceof LiteralType && + typeof type.indexType.value === "string" + ) { + const childReflection = type.objectType.reflection.getChildByName([ + type.indexType.value, + ]); + if (childReflection) { + const displayed = stringify(type.indexType.value); + indexType = { + type: "element", + content: ( + + {displayed} + + ), + length: displayed.length, + }; + } + } + + return nodes( + builder.type(type.objectType, TypeContext.indexedObject), + simpleElement([), + indexType, + simpleElement(]), + ); + }, + inferred(type, builder) { + const simple = nodes( + simpleElement(infer), + space(), + simpleElement( + {type.name}, + ), + ); + + if (type.constraint) { + const id = builder.newId(); + return group(id, [ + simple, + space(), + simpleElement( + extends, + ), + spaceOrLine(), + indent([ + builder.type( + type.constraint, + TypeContext.inferredConstraint, + ), + ]), + ]); + } + + return simple; + }, + intersection(type, builder) { + // Prettier doesn't do smart wrapping here like we do with unions + // so... TypeDoc won't either, at least for now. + return join( + nodes( + space(), + simpleElement(&), + space(), + ), + type.types, + (type) => builder.type(type, TypeContext.intersectionElement), + ); + }, + intrinsic(type) { + return simpleElement( + {type.name}, + ); + }, + literal(type) { + return simpleElement( + {stringify(type.value)}, + ); + }, + mapped(type, builder) { + const parts: Node[] = []; + + switch (type.readonlyModifier) { + case "+": + parts.push( + simpleElement( + readonly, + ), + space(), + ); + break; + case "-": + parts.push( + simpleElement(-), + simpleElement( + readonly, + ), + space(), + ); + break; + } + + parts.push( + simpleElement([), + simpleElement( + {type.parameter}, + ), + space(), + simpleElement(in), + space(), + builder.type(type.parameterType, TypeContext.mappedParameter), + ); + + if (type.nameType) { + parts.push( + space(), + simpleElement(as), + space(), + builder.type(type.nameType, TypeContext.mappedName), + ); + } + + parts.push(simpleElement(])); + + switch (type.optionalModifier) { + case "+": + parts.push( + simpleElement(?:), + ); + break; + case "-": + parts.push( + simpleElement( + -?:, + ), + ); + break; + default: + parts.push( + simpleElement(:), + ); + } + + parts.push( + space(), + builder.type(type.templateType, TypeContext.mappedTemplate), + ); + + return group(builder.newId(), [ + simpleElement({"{"}), + spaceOrLine(), + indent(parts), + spaceOrLine(), + simpleElement({"}"}), + ]); + }, + namedTupleMember(type, builder) { + return nodes( + textNode(type.name), + type.isOptional + ? simpleElement(?:) + : simpleElement(:), + space(), + builder.type(type.element, TypeContext.none), + ); + }, + optional(type, builder) { + return nodes( + builder.type(type.elementType, TypeContext.optionalElement), + simpleElement(?), + ); + }, + predicate(type, builder) { + const content: Node[] = []; + if (type.asserts) { + content.push( + simpleElement( + asserts, + ), + space(), + ); + } + + content.push( + simpleElement({type.name}), + ); + + if (type.targetType) { + content.push( + space(), + simpleElement(is), + space(), + builder.type(type.targetType, TypeContext.predicateTarget), + ); + } + + return nodes(...content); + }, + query(type, builder) { + return nodes( + simpleElement(typeof), + space(), + builder.type(type.queryType, TypeContext.queryTypeTarget), + ); + }, + reference(type, builder) { + const reflection = type.reflection; + let name: Node; + + if (reflection) { + if (reflection.kindOf(ReflectionKind.TypeParameter)) { + name = simpleElement( + + {reflection.name} + , + ); + } else { + name = join( + simpleElement(.), + getUniquePath(reflection), + (item) => + simpleElement( + + {item.name} + , + ), + ); + } + } else if (type.externalUrl) { + name = simpleElement( + + {type.name} + , + ); + } else if (type.refersToTypeParameter) { + name = simpleElement( + + {type.name} + , + ); + } else { + name = simpleElement( + {type.name}, + ); + } + + if (type.typeArguments?.length) { + const id = builder.newId(); + return group(id, [ + name, + simpleElement({"<"}), + line(), + indent([ + join( + nodes( + simpleElement( + ,, + ), + spaceOrLine(), + ), + type.typeArguments, + (item) => + builder.type( + item, + TypeContext.referenceTypeArgument, + ), + ), + ifWrap( + id, + simpleElement( + ,, + ), + ), + ]), + line(), + simpleElement({">"}), + ]); + } + + return name; + }, + reflection(type, builder, options) { + return builder.reflection(type.declaration, options); + }, + rest(type, builder) { + return nodes( + simpleElement(...), + builder.type(type.elementType, TypeContext.restElement), + ); + }, + templateLiteral(type, builder) { + const content: Node[] = []; + content.push( + simpleElement(`), + ); + + if (type.head) { + content.push( + simpleElement( + {type.head}, + ), + ); + } + + for (const item of type.tail) { + content.push( + simpleElement({"${"}), + builder.type(item[0], TypeContext.templateLiteralElement), + simpleElement({"}"}), + ); + if (item[1]) { + content.push( + simpleElement( + {item[1]}, + ), + ); + } + } + + content.push( + simpleElement(`), + ); + + return nodes(...content); + }, + tuple(type, builder) { + const id = builder.newId(); + + return group(id, [ + simpleElement([), + line(), + indent([ + join( + nodes( + simpleElement( + ,, + ), + spaceOrLine(), + ), + type.elements, + (item) => builder.type(item, TypeContext.tupleElement), + ), + ]), + ifWrap( + id, + simpleElement(,), + ), + line(), + simpleElement(]), + ]); + }, + typeOperator(type, builder) { + return nodes( + simpleElement( + {type.operator}, + ), + space(), + builder.type(type.target, TypeContext.typeOperatorTarget), + ); + }, + union(type, builder) { + const parentId = builder.id; + const id = builder.newId(); + const pipe = simpleElement(|); + + const elements = type.types.flatMap((type, i) => [ + i == 0 ? ifWrap(id, nodes(pipe, space())) : space(), + builder.type(type, TypeContext.unionElement), + spaceOrLine(), + pipe, + ]); + elements.pop(); // Remove last pipe + elements.pop(); // Remove last spaceOrLine + + return group(id, [ + ifWrap(parentId, emptyNode, line()), + ifWrap(parentId, nodes(...elements), indent(elements)), + ]); + }, + unknown(type) { + return textNode(type.name); + }, +}; + +/** + * Responsible for generating Nodes from a type tree. + */ +export class FormattedCodeBuilder { + id = 0; + + constructor(readonly urlTo: (refl: Reflection) => string) {} + + newId() { + return ++this.id; + } + + type( + type: SomeType | undefined, + where: TypeContext, + options: { topLevelLinks: boolean } = { topLevelLinks: false }, + ): Node { + if (!type) { + return simpleElement(any); + } + + const rendered = type.visit(typeBuilder, this, options); + if (type.needsParenthesis(where)) { + const id = this.newId(); + return group(id, [ + textNode("("), + line(), + indent([rendered]), + line(), + textNode(")"), + ]); + } + return rendered; + } + + reflection( + reflection: DeclarationReflection, + options: { topLevelLinks: boolean }, + ): Node { + const members: Node[] = []; + const children = reflection.children || []; + + for (const item of children) { + members.push(this.member(item, options)); + } + + if (reflection.indexSignatures) { + for (const index of reflection.indexSignatures) { + members.push( + nodes( + simpleElement( + [, + ), + simpleElement( + + {index.parameters![0].name} + , + ), + simpleElement( + ], + ), + space(), + this.type(index.parameters![0].type, TypeContext.none), + simpleElement( + ]:, + ), + space(), + this.type(index.type, TypeContext.none), + ), + ); + } + } + + if (!members.length && reflection.signatures?.length === 1) { + return this.signature(reflection.signatures[0], { + hideName: true, + arrowStyle: true, + }); + } + + for (const item of reflection.signatures || []) { + members.push(this.signature(item, { hideName: true })); + } + + if (members.length) { + const id = this.newId(); + return group(id, [ + simpleElement({"{"}), + spaceOrLine(), + indent([ + join( + nodes( + simpleElement( + ;, + ), + spaceOrLine(), + ), + members, + (node) => node, + ), + ]), + spaceOrLine(), + simpleElement({"}"}), + ]); + // + } + + return simpleElement({"{}"}); + } + + interface(item: DeclarationReflection) { + return nodes( + simpleElement(interface), + space(), + simpleElement({item.name}), + this.typeParameters(item), + space(), + this.reflection(item, { topLevelLinks: true }), + ); + } + + member(item: DeclarationReflection, options: { topLevelLinks: boolean }) { + if (item.getSignature && item.setSignature) { + return nodes( + this.signature(item.getSignature, options), + line(), + this.signature(item.getSignature, options), + ); + } + + if (item.getSignature) { + return this.signature(item.getSignature, options); + } + + if (item.setSignature) { + return this.signature(item.setSignature, options); + } + + if (item.signatures) { + return nodes( + ...item.signatures.map((sig) => this.signature(sig, options)), + ); + } + + return nodes( + this.propertyName(item, options), + simpleElement( + + {item.flags.isOptional ? "?:" : ":"} + , + ), + space(), + this.type(item.type, TypeContext.none), + ); + } + + signature( + sig: SignatureReflection, + options: { + topLevelLinks?: boolean; + hideName?: boolean; + arrowStyle?: boolean; + }, + ): Node { + let name: Node = options.hideName + ? emptyNode + : this.propertyName(sig, options); + switch (sig.kind) { + case ReflectionKind.ConstructorSignature: { + let label = emptyNode; + if (sig.flags.isAbstract) { + label = nodes( + simpleElement( + abstract, + ), + space(), + ); + } + label = nodes( + simpleElement( + new, + ), + space(), + ); + name = nodes(label, name); + break; + } + case ReflectionKind.GetSignature: { + name = nodes( + simpleElement( + get, + ), + space(), + name, + ); + break; + } + case ReflectionKind.SetSignature: { + name = nodes( + simpleElement( + set, + ), + space(), + name, + ); + break; + } + } + + const id = this.newId(); + return group(id, [ + name, + this.typeParameters(sig), + ...this.parameters(sig, id), + nodes( + simpleElement( + // TODO + + {options.arrowStyle ? " => " : ": "} + , + ), + this.type(sig.type, TypeContext.none), + ), + ]); + } + + private typeParameters( + sig: SignatureReflection | DeclarationReflection, + ): Node { + if (!sig.typeParameters?.length) { + return emptyNode; + } + + const id = this.newId(); + return group(id, [ + simpleElement({"<"}), + line(), + indent([ + join( + nodes( + simpleElement( + ,, + ), + spaceOrLine(), + ), + sig.typeParameters, + (item) => this.typeParameter(item), + ), + ]), + ifWrap( + id, + simpleElement(,), + ), + line(), + simpleElement({">"}), + ]); + } + + private typeParameter(param: TypeParameterReflection) { + let prefix = emptyNode; + if (param.flags.isConst) { + prefix = nodes( + simpleElement(const), + space(), + ); + } + if (param.varianceModifier) { + prefix = nodes( + prefix, + simpleElement( + + {param.varianceModifier} + , + ), + space(), + ); + } + const content = [ + prefix, + simpleElement( + + {param.name} + , + ), + ]; + + if (param.type) { + content.push( + space(), + simpleElement( + extends, + ), + spaceOrLine(), + indent([this.type(param.type, TypeContext.none)]), + ); + } + + if (param.default) { + content.push( + space(), + simpleElement(=), + space(), + this.type(param.default, TypeContext.none), + ); + } + + return group(this.newId(), content); + } + + private parameters(sig: SignatureReflection, id: number): Node[] { + if (!sig.parameters?.length) { + return [ + simpleElement(()), + ]; + } + + return [ + simpleElement((), + line(), + indent([ + join( + nodes( + simpleElement( + ,, + ), + spaceOrLine(), + ), + sig.parameters, + (item) => this.parameter(item), + ), + ]), + ifWrap( + id, + simpleElement(,), + ), + line(), + simpleElement()), + ]; + } + + private parameter(param: ParameterReflection) { + const content: Node[] = []; + if (param.flags.isRest) { + content.push( + simpleElement(...), + ); + } + content.push( + simpleElement({param.name}), + ); + + if (param.flags.isOptional || param.defaultValue) { + content.push( + simpleElement(?:), + ); + } else { + content.push( + simpleElement(:), + ); + } + content.push(space()); + content.push(this.type(param.type, TypeContext.none)); + return nodes(...content); + } + + private propertyName( + reflection: Reflection, + options: { topLevelLinks?: boolean }, + ): Node { + const entityName = /^[A-Z_$][\w$]*$/i.test(reflection.name) + ? reflection.name + : JSON.stringify(reflection.name); + + if (options.topLevelLinks) { + return simpleElement( + + {entityName} + , + ); + } + return simpleElement( + {entityName}, + ); + } +} diff --git a/src/lib/output/index.ts b/src/lib/output/index.ts index 5a06e17af..3ccc5f2aa 100644 --- a/src/lib/output/index.ts +++ b/src/lib/output/index.ts @@ -3,6 +3,7 @@ export { RendererEvent, MarkdownEvent, IndexEvent, + type PageHeading, } from "./events.js"; export { UrlMapping } from "./models/UrlMapping.js"; export type { RenderTemplate } from "./models/UrlMapping.js"; diff --git a/src/lib/output/renderer.ts b/src/lib/output/renderer.ts index 14f853fdf..4cebb8494 100644 --- a/src/lib/output/renderer.ts +++ b/src/lib/output/renderer.ts @@ -30,7 +30,6 @@ import type { import { type Comment, Reflection } from "../models/index.js"; import type { JsxElement } from "../utils/jsx.elements.js"; import type { DefaultThemeRenderContext } from "./themes/default/DefaultThemeRenderContext.js"; -import { validateStateIsClean } from "./themes/default/partials/type.js"; import { setRenderSettings } from "../utils/jsx.js"; import { @@ -313,7 +312,6 @@ export class Renderer extends AbstractComponent { ); output.urls.forEach((mapping) => { this.renderDocument(...output.createPageEvent(mapping)); - validateStateIsClean(mapping.url); }); await Promise.all(this.postRenderAsyncJobs.map((job) => job(output))); diff --git a/src/lib/output/themes/default/partials/member.declaration.tsx b/src/lib/output/themes/default/partials/member.declaration.tsx index e586ebf0f..400e32dd5 100644 --- a/src/lib/output/themes/default/partials/member.declaration.tsx +++ b/src/lib/output/themes/default/partials/member.declaration.tsx @@ -1,22 +1,21 @@ import type { DeclarationReflection } from "../../../../models/index.js"; import { JSX } from "../../../../utils/index.js"; -import { getKindClass, hasTypeParameters, renderTypeParametersSignature, wbr } from "../../lib.js"; +import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js"; +import { hasTypeParameters } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; void JSX; // TS is confused and thinks this is unused export function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection) { + const builder = new FormattedCodeBuilder(context.urlTo); + const tree = builder.member(props, { topLevelLinks: false }); + const generator = new FormattedCodeGenerator(); + generator.node(tree, Wrap.Detect); + return ( <>
- {wbr(props.name)} - {renderTypeParametersSignature(context, props.typeParameters)} - {props.type && ( - <> - {!!props.flags.isOptional && "?"}:{" "} - {context.type(props.type)} - - )} + {generator.toElement()} {!!props.defaultValue && ( <> diff --git a/src/lib/output/themes/default/partials/member.getterSetter.tsx b/src/lib/output/themes/default/partials/member.getterSetter.tsx index 85ff45262..d5c1abf6f 100644 --- a/src/lib/output/themes/default/partials/member.getterSetter.tsx +++ b/src/lib/output/themes/default/partials/member.getterSetter.tsx @@ -18,10 +18,7 @@ export const memberGetterSetter = (context: DefaultThemeRenderContext, props: De {!!props.getSignature && ( <>
  • - get {props.name} - {context.memberSignatureTitle(props.getSignature, { - hideName: true, - })} + {context.memberSignatureTitle(props.getSignature)}
  • {context.memberSignatureBody(props.getSignature)}
  • @@ -29,10 +26,7 @@ export const memberGetterSetter = (context: DefaultThemeRenderContext, props: De {!!props.setSignature && ( <>
  • - set {props.name} - {context.memberSignatureTitle(props.setSignature, { - hideName: true, - })} + {context.memberSignatureTitle(props.setSignature)}
  • {context.memberSignatureBody(props.setSignature)}
  • diff --git a/src/lib/output/themes/default/partials/member.signature.title.tsx b/src/lib/output/themes/default/partials/member.signature.title.tsx index 572a0e017..dd1421f8d 100644 --- a/src/lib/output/themes/default/partials/member.signature.title.tsx +++ b/src/lib/output/themes/default/partials/member.signature.title.tsx @@ -1,70 +1,15 @@ -import { getKindClass, join, renderTypeParametersSignature, wbr } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -import { JSX } from "../../../../utils/index.js"; -import { type ParameterReflection, ReflectionKind, type SignatureReflection } from "../../../../models/index.js"; - -void JSX; // Trick TS into seeing this as used, the import is required. - -function renderParameterWithType(context: DefaultThemeRenderContext, item: ParameterReflection) { - return ( - <> - {!!item.flags.isRest && ...} - {item.name} - - {!!item.flags.isOptional && "?"} - {!!item.defaultValue && "?"} - {": "} - - {context.type(item.type)} - - ); -} - -function renderParameterWithoutType(item: ParameterReflection) { - return ( - <> - {!!item.flags.isRest && ...} - {item.name} - {(item.flags.isOptional || item.defaultValue) && ?} - - ); -} +import { type SignatureReflection } from "../../../../models/index.js"; +import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js"; export function memberSignatureTitle( context: DefaultThemeRenderContext, props: SignatureReflection, - { - hideName = false, - arrowStyle = false, - hideTypes = context.options.getValue("hideTypesInSignatureTitle"), - }: { hideName?: boolean; arrowStyle?: boolean; hideTypes?: boolean } = {}, + options: { hideName?: boolean } = {}, ) { - const renderParam = hideTypes ? renderParameterWithoutType : renderParameterWithType.bind(null, context); - - return ( - <> - {!hideName ? ( - {wbr(props.name)} - ) : ( - <> - {props.kind === ReflectionKind.ConstructorSignature && ( - <> - {!!props.flags.isAbstract && abstract } - new - - )} - - )} - {renderTypeParametersSignature(context, props.typeParameters)} - ( - {join(", ", props.parameters ?? [], renderParam)} - ) - {!!props.type && !hideTypes && ( - <> - {arrowStyle ? " => " : ": "} - {context.type(props.type)} - - )} - - ); + const builder = new FormattedCodeBuilder(context.urlTo); + const tree = builder.signature(props, options); + const generator = new FormattedCodeGenerator(); + generator.node(tree, Wrap.Detect); + return generator.toElement(); } diff --git a/src/lib/output/themes/default/partials/reflectionPreview.tsx b/src/lib/output/themes/default/partials/reflectionPreview.tsx index 78b0a4e20..b89fa27cb 100644 --- a/src/lib/output/themes/default/partials/reflectionPreview.tsx +++ b/src/lib/output/themes/default/partials/reflectionPreview.tsx @@ -1,6 +1,6 @@ -import { DeclarationReflection, ReflectionKind, type Reflection, ReflectionType } from "../../../../models/index.js"; +import { DeclarationReflection, ReflectionKind, type Reflection } from "../../../../models/index.js"; import { JSX } from "../../../../utils/index.js"; -import { getKindClass, renderTypeParametersSignature } from "../../lib.js"; +import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; void JSX; // Trick TS into seeing this as used, the import is required. @@ -12,13 +12,12 @@ export function reflectionPreview(context: DefaultThemeRenderContext, props: Ref // a type-like object with links to each member. Don't do this if we don't have any children as it will // generate a broken looking interface. (See TraverseCallback) if (props.kindOf(ReflectionKind.Interface) && props.children) { - return ( -
    - interface - {props.name} - {renderTypeParametersSignature(context, props.typeParameters)}{" "} - {context.type(new ReflectionType(props), { topLevelLinks: true })} -
    - ); + const builder = new FormattedCodeBuilder(context.urlTo); + const tree = builder.interface(props); + // Pass infinity to force properties onto new lines + const generator = new FormattedCodeGenerator(undefined, Infinity); + generator.node(tree, Wrap.Enable); + + return
    {generator.toElement()}
    ; } } diff --git a/src/lib/output/themes/default/partials/type.tsx b/src/lib/output/themes/default/partials/type.tsx index 8bfd4d13b..073162f5a 100644 --- a/src/lib/output/themes/default/partials/type.tsx +++ b/src/lib/output/themes/default/partials/type.tsx @@ -1,568 +1,15 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -import { - type DeclarationReflection, - LiteralType, - type ProjectReflection, - ReferenceType, - type Reflection, - ReflectionKind, - type Type, - TypeContext, - type TypeKindMap, -} from "../../../../models/index.js"; -import { JSX } from "../../../../utils/index.js"; -import { getKindClass, join, stringify } from "../../lib.js"; -import { ok } from "assert"; - -const EXPORTABLE: ReflectionKind = - ReflectionKind.Class | - ReflectionKind.Interface | - ReflectionKind.Enum | - ReflectionKind.TypeAlias | - ReflectionKind.Function | - ReflectionKind.Variable; - -const nameCollisionCache = new WeakMap>(); -function getNameCollisionCount(project: ProjectReflection, name: string): number { - let collisions = nameCollisionCache.get(project); - if (collisions === undefined) { - collisions = {}; - for (const reflection of project.getReflectionsByKind(EXPORTABLE)) { - collisions[reflection.name] = (collisions[reflection.name] ?? 0) + 1; - } - nameCollisionCache.set(project, collisions); - } - return collisions[name] ?? 0; -} - -/** - * Returns a (hopefully) globally unique path for the given reflection. - * - * This only works for exportable symbols, so e.g. methods are not affected by this. - * - * If the given reflection has a globally unique name already, then it will be returned as is. If the name is - * ambiguous (i.e. there are two classes with the same name in different namespaces), then the namespaces path of the - * reflection will be returned. - */ -function getUniquePath(reflection: Reflection): Reflection[] { - if (reflection.kindOf(EXPORTABLE)) { - if (getNameCollisionCount(reflection.project, reflection.name) >= 2) { - return getNamespacedPath(reflection); - } - } - return [reflection]; -} -function getNamespacedPath(reflection: Reflection): Reflection[] { - const path = [reflection]; - let parent = reflection.parent; - while (parent?.kindOf(ReflectionKind.Namespace)) { - path.unshift(parent); - parent = parent.parent; - } - return path; -} -function renderUniquePath(context: DefaultThemeRenderContext, reflection: Reflection): JSX.Element { - return join(., getUniquePath(reflection), (item) => ( - - {item.name} - - )); -} - -const indentSize = 4; -let indentationDepth = 0; -function includeIndentation(): JSX.Element { - return indentationDepth > 0 ? {"\u00A0".repeat(indentationDepth * indentSize)} : <>; -} - -export function validateStateIsClean(page: string) { - ok( - indentationDepth === 0, - `Rendering ${page}: Indentation depth increment/decrement not matched: ${indentationDepth}`, - ); -} - -// The type helper accepts an optional needsParens parameter that is checked -// if an inner type may result in invalid output without them. For example: -// 1 | 2[] !== (1 | 2)[] -// () => 1 | 2 !== (() => 1) | 2 -const typeRenderers: { - [K in keyof TypeKindMap]: ( - context: DefaultThemeRenderContext, - type: TypeKindMap[K], - options: { topLevelLinks: boolean }, - ) => JSX.Element; -} = { - array(context, type) { - return ( - <> - {renderType(context, type.elementType, TypeContext.arrayElement)} - [] - - ); - }, - conditional(context, type) { - indentationDepth++; - const parts: JSX.Element[] = [ - renderType(context, type.checkType, TypeContext.conditionalCheck), - extends , - renderType(context, type.extendsType, TypeContext.conditionalExtends), -
    , - includeIndentation(), - ? , - renderType(context, type.trueType, TypeContext.conditionalTrue), -
    , - includeIndentation(), - : , - renderType(context, type.falseType, TypeContext.conditionalFalse), - ]; - indentationDepth--; - - return <>{parts}; - }, - indexedAccess(context, type) { - let indexType: JSX.Element = renderType(context, type.indexType, TypeContext.indexedIndex); - - if ( - type.objectType instanceof ReferenceType && - type.objectType.reflection && - type.indexType instanceof LiteralType && - typeof type.indexType.value === "string" - ) { - const childReflection = type.objectType.reflection.getChildByName([type.indexType.value]); - if (childReflection) { - indexType = {indexType}; - } - } - - return ( - <> - {renderType(context, type.objectType, TypeContext.indexedObject)} - [ - {indexType} - ] - - ); - }, - inferred(context, type) { - return ( - <> - infer {" "} - {type.name} - {type.constraint && ( - <> - extends - {renderType(context, type.constraint, TypeContext.inferredConstraint)} - - )} - - ); - }, - intersection(context, type) { - return join( & , type.types, (item) => - renderType(context, item, TypeContext.intersectionElement), - ); - }, - intrinsic(_context, type) { - return {type.name}; - }, - literal(_context, type) { - return {stringify(type.value)}; - }, - mapped(context, type) { - indentationDepth++; - const parts = [{"{"},
    , includeIndentation()]; - - switch (type.readonlyModifier) { - case "+": - parts.push(readonly ); - break; - case "-": - parts.push( - <> - - - readonly - , - ); - break; - } - - parts.push( - [, - {type.parameter}, - in , - renderType(context, type.parameterType, TypeContext.mappedParameter), - ); - - if (type.nameType) { - parts.push( - as , - renderType(context, type.nameType, TypeContext.mappedName), - ); - } - - parts.push(]); - - switch (type.optionalModifier) { - case "+": - parts.push(?: ); - break; - case "-": - parts.push(-?: ); - break; - default: - parts.push(: ); - } - - parts.push(renderType(context, type.templateType, TypeContext.mappedTemplate)); - - indentationDepth--; - - return ( - <> - {parts} -
    - {includeIndentation()} - {"}"} - - ); - }, - namedTupleMember(context, type) { - return ( - <> - {type.name} - {type.isOptional ? ( - ?: - ) : ( - : - )} - {renderType(context, type.element, TypeContext.tupleElement)} - - ); - }, - optional(context, type) { - return ( - <> - {renderType(context, type.elementType, TypeContext.optionalElement)} - ? - - ); - }, - predicate(context, type) { - return ( - <> - {!!type.asserts && asserts } - {type.name} - {!!type.targetType && ( - <> - is - {renderType(context, type.targetType, TypeContext.predicateTarget)} - - )} - - ); - }, - query(context, type) { - return ( - <> - typeof - {renderType(context, type.queryType, TypeContext.queryTypeTarget)} - - ); - }, - reference(context, type) { - const reflection = type.reflection; - - let name: JSX.Element; - - if (reflection) { - if (reflection.kindOf(ReflectionKind.TypeParameter)) { - name = ( - - {reflection.name} - - ); - } else { - name = renderUniquePath(context, reflection); - } - } else if (type.externalUrl) { - name = ( - - {type.name} - - ); - } else if (type.refersToTypeParameter) { - name = {type.name}; - } else { - name = {type.name}; - } - - if (type.typeArguments?.length) { - return ( - <> - {name} - {"<"} - {join(, , type.typeArguments, (item) => - renderType(context, item, TypeContext.referenceTypeArgument), - )} - {">"} - - ); - } - - return name; - }, - reflection(context, type, { topLevelLinks }) { - const members: JSX.Element[] = []; - const children: DeclarationReflection[] = type.declaration.children || []; - - indentationDepth++; - - const renderName = (named: Reflection) => - topLevelLinks ? ( - - {named.name} - - ) : ( - {named.name} - ); - - for (const item of children) { - if (item.getSignature && item.setSignature) { - members.push( - <> - {renderName(item)} - : - {renderType(context, item.getSignature.type, TypeContext.none)} - , - ); - continue; - } - - if (item.getSignature) { - members.push( - <> - get - {renderName(item.getSignature)} - (): - {renderType(context, item.getSignature.type, TypeContext.none)} - , - ); - continue; - } - - if (item.setSignature) { - members.push( - <> - set - {renderName(item.setSignature)} - ( - {item.setSignature.parameters?.map((item) => ( - <> - {item.name} - : - {renderType(context, item.type, TypeContext.none)} - - ))} - ) - , - ); - continue; - } - - if (item.signatures) { - for (const sig of item.signatures) { - members.push( - <> - {renderName(sig)} - {item.flags.isOptional && ?} - {context.memberSignatureTitle(sig, { - hideName: true, - arrowStyle: false, - hideTypes: false, - })} - , - ); - } - continue; - } - - members.push( - <> - {renderName(item)} - {item.flags.isOptional ? "?: " : ": "} - {renderType(context, item.type, TypeContext.none)} - , - ); - } - - if (type.declaration.indexSignatures) { - for (const index of type.declaration.indexSignatures) { - members.push( - <> - [{index.parameters![0].name}:{" "} - {renderType(context, index.parameters![0].type, TypeContext.none)}] - : - {renderType(context, index.type, TypeContext.none)} - , - ); - } - } - - if (!members.length && type.declaration.signatures?.length === 1) { - indentationDepth--; - - return ( - <> - ( - {context.memberSignatureTitle(type.declaration.signatures[0], { - hideName: true, - arrowStyle: true, - hideTypes: false, - })} - ) - - ); - } - - for (const item of type.declaration.signatures || []) { - members.push(context.memberSignatureTitle(item, { hideName: true, hideTypes: false })); - } - - if (members.length) { - const membersWithSeparators = members.flatMap((m) => [ - includeIndentation(), - m, - ; , -

    , - ]); - membersWithSeparators.pop(); - - indentationDepth--; - return ( - <> - {"{"} -

    - {membersWithSeparators} -

    - {includeIndentation()} - {"}"} - - ); - } - - indentationDepth--; - return {"{}"}; - }, - rest(context, type) { - return ( - <> - ... - {renderType(context, type.elementType, TypeContext.restElement)} - - ); - }, - templateLiteral(context, type) { - return ( - <> - ` - {type.head && {type.head}} - {type.tail.map((item) => ( - <> - {"${"} - {renderType(context, item[0], TypeContext.templateLiteralElement)} - {"}"} - {item[1] && {item[1]}} - - ))} - ` - - ); - }, - tuple(context, type) { - return ( - <> - [ - {join(, , type.elements, (item) => - renderType(context, item, TypeContext.tupleElement), - )} - ] - - ); - }, - typeOperator(context, type) { - return ( - <> - {type.operator} - {renderType(context, type.target, TypeContext.typeOperatorTarget)} - - ); - }, - union(context, type) { - // This could likely be improved with some print width based heuristic like - // how prettier works, but my initial investigation with it didn't consistently - // produce better results than this much simpler method as the print width - // method doesn't track how far into the current line we are, and I don't want - // to spend the time right now to properly track that here. PR welcome if someone - // wants to take the time to make that a real capability. - // https://gist.github.com/Gerrit0/5cebc127fd4b181e49e354b786d181d7 - if (type.types.length > 3) { - ++indentationDepth; - const membersWithSeparators = type.types.flatMap((item) => [ - includeIndentation(), - | , - renderType(context, item, TypeContext.unionElement), -

    , - ]); - membersWithSeparators.pop(); - --indentationDepth; - - return ( - <> -
    - {membersWithSeparators} - - ); - } - return join( | , type.types, (item) => - renderType(context, item, TypeContext.unionElement), - ); - }, - unknown(_context, type) { - return <>{type.name}; - }, -}; - -function renderType( - context: DefaultThemeRenderContext, - type: Type | undefined, - where: TypeContext, - options: { topLevelLinks: boolean } = { topLevelLinks: false }, -) { - if (!type) { - return any; - } - - const renderFn = typeRenderers[type.type]; - const rendered = renderFn(context, type as never, options); - - if (type.needsParenthesis(where)) { - return ( - <> - ( - {rendered} - ) - - ); - } - - return rendered; -} +import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js"; +import { TypeContext, type SomeType } from "../../../../models/types.js"; export function type( context: DefaultThemeRenderContext, - type: Type | undefined, + type: SomeType | undefined, options: { topLevelLinks: boolean } = { topLevelLinks: false }, ) { - return renderType(context, type, TypeContext.none, options); + const builder = new FormattedCodeBuilder(context.urlTo); + const tree = builder.type(type, TypeContext.none, options); + const generator = new FormattedCodeGenerator(); + generator.node(tree, Wrap.Detect); + return generator.toElement(); } diff --git a/src/lib/output/themes/default/partials/typeDetails.tsx b/src/lib/output/themes/default/partials/typeDetails.tsx index 392c4e65a..703878142 100644 --- a/src/lib/output/themes/default/partials/typeDetails.tsx +++ b/src/lib/output/themes/default/partials/typeDetails.tsx @@ -74,7 +74,6 @@ export function typeDetails(context: DefaultThemeRenderContext, type: SomeType):
  • {context.memberSignatureTitle(item, { hideName: true, - hideTypes: true, })}
  • diff --git a/src/lib/output/themes/lib.tsx b/src/lib/output/themes/lib.tsx index 037c2b146..2f97fed97 100644 --- a/src/lib/output/themes/lib.tsx +++ b/src/lib/output/themes/lib.tsx @@ -98,7 +98,7 @@ export function renderTypeParametersSignature( typeParameters: readonly TypeParameterReflection[] | undefined, ): JSX.Element { if (!typeParameters || typeParameters.length === 0) return <>; - const hideParamTypes = context.options.getValue("hideTypesInSignatureTitle"); + const hideParamTypes = false; // context.options.getValue("hideTypesInSignatureTitle"); if (hideParamTypes) { return ( diff --git a/src/lib/serialization/components.ts b/src/lib/serialization/components.ts index d8f7cf13f..d9afdfe3c 100644 --- a/src/lib/serialization/components.ts +++ b/src/lib/serialization/components.ts @@ -6,9 +6,6 @@ import type { ModelToObject } from "./schema.js"; * * Like {@link Converter} plugins each {@link Serializer} plugin defines a predicate that instructs if an * object can be serialized by it. This is done dynamically at runtime via a `supports` method. - * - * Additionally, each {@link Serializer} plugin must define a predicate that instructs the group - * it belongs to. */ export interface SerializerComponent { /** diff --git a/src/lib/utils/jsx.ts b/src/lib/utils/jsx.ts index c35e6c154..d2b74d936 100644 --- a/src/lib/utils/jsx.ts +++ b/src/lib/utils/jsx.ts @@ -105,9 +105,7 @@ export function setRenderSettings(options: { pretty: boolean }) { renderPretty = options.pretty; } -export const renderElement = function renderElement( - element: JsxElement | null | undefined, -): string { +export function renderElement(element: JsxElement | null | undefined): string { if (!element || typeof element === "boolean") { return ""; } @@ -188,4 +186,48 @@ export const renderElement = function renderElement( } } } -}; +} + +/** + * Render an element to text, stripping out any HTML tags. + * This is roughly equivalent to getting `innerText` on a rendered element. + * @internal + */ +export function renderElementToText(element: JsxElement | null | undefined) { + if (!element || typeof element === "boolean") { + return ""; + } + + const { tag, props, children } = element; + + if (typeof tag === "function") { + if (tag === Raw) { + return String((props as any).html); + } + return renderElementToText(tag(Object.assign({ children }, props))); + } else if (tag === "br") { + return "\n"; + } + + let html = ""; + + if (children.length) { + renderChildren(children); + } + + return html; + + function renderChildren(children: JsxChildren[]) { + for (const child of children) { + if (!child) continue; + + if (Array.isArray(child)) { + renderChildren(child); + } else if (typeof child === "string" || typeof child === "number") { + html += child.toString().replaceAll("\u00A0", " "); + } else { + html += renderElementToText(child); + } + } + } +} diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index d44b89a3b..d0b9963f2 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -168,7 +168,6 @@ export interface TypeDocOptionMap { hideGenerator: boolean; customFooterHtml: string; customFooterHtmlDisableWrapper: boolean; - hideTypesInSignatureTitle: boolean; searchInComments: boolean; searchInDocuments: boolean; cleanOutputDir: boolean; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index a6ceb865d..b7cf042fe 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -505,12 +505,6 @@ export function addTypeDocOptions(options: Pick) { help: (i18n) => i18n.help_customFooterHtmlDisableWrapper(), type: ParameterType.Boolean, }); - options.addDeclaration({ - name: "hideTypesInSignatureTitle", - help: (i18n) => i18n.help_hideTypesInSignatureTitle(), - type: ParameterType.Boolean, - defaultValue: true, - }); options.addDeclaration({ name: "cacheBust", help: (i18n) => i18n.help_cacheBust(), diff --git a/src/test/behavior.c2.test.ts b/src/test/behavior.c2.test.ts index 893e57a11..68025934b 100644 --- a/src/test/behavior.c2.test.ts +++ b/src/test/behavior.c2.test.ts @@ -783,9 +783,9 @@ describe("Behavior Tests", () => { ["Meanings.E.E", 0], [ReflectionKind.Variable, "Meanings.F"], - ["Meanings.B.constructor.new B", 0], - ["Meanings.B.constructor.new B", 0], - ["Meanings.B.constructor.new B", 1], + ["Meanings.B.constructor.B", 0], + ["Meanings.B.constructor.B", 0], + ["Meanings.B.constructor.B", 1], [ReflectionKind.EnumMember, "Meanings.A.A"], [undefined], @@ -793,8 +793,8 @@ describe("Behavior Tests", () => { ["Meanings.E.E", 0], ["Meanings.E.E", 1], - ["Meanings.B.constructor.new B", 0], - ["Meanings.B.constructor.new B", 1], + ["Meanings.B.constructor.B", 0], + ["Meanings.B.constructor.B", 1], ["Meanings.B.__index", undefined], [ReflectionKind.Interface, "Meanings.G"], diff --git a/src/test/comments.test.ts b/src/test/comments.test.ts index bda4a6df4..abd330319 100644 --- a/src/test/comments.test.ts +++ b/src/test/comments.test.ts @@ -19,24 +19,7 @@ import { MinimalSourceFile } from "../lib/utils/minimalSourceFile.js"; import { TestLogger } from "./TestLogger.js"; import { extractTagName } from "../lib/converter/comments/tagName.js"; import { FileRegistry } from "../lib/models/FileRegistry.js"; - -function dedent(text: string) { - const lines = text.split(/\r?\n/); - while (lines.length && lines[0].search(/\S/) === -1) { - lines.shift(); - } - while (lines.length && lines[lines.length - 1].search(/\S/) === -1) { - lines.pop(); - } - - const minIndent = lines.reduce( - (indent, line) => - line.length ? Math.min(indent, line.search(/\S/)) : indent, - Infinity, - ); - - return lines.map((line) => line.substring(minIndent)).join("\n"); -} +import { dedent } from "./utils.js"; describe("Dedent test helper", () => { it("Works on empty string", () => { diff --git a/src/test/converter/class/specs-with-lump-categories.json b/src/test/converter/class/specs-with-lump-categories.json index ebdd6b2d3..56a7fa700 100644 --- a/src/test/converter/class/specs-with-lump-categories.json +++ b/src/test/converter/class/specs-with-lump-categories.json @@ -587,7 +587,7 @@ "signatures": [ { "id": 88, - "name": "new Abstract", + "name": "Abstract", "variant": "signature", "kind": 16384, "flags": {}, @@ -678,7 +678,7 @@ "signatures": [ { "id": 77, - "name": "new ComputedNames", + "name": "ComputedNames", "variant": "signature", "kind": 16384, "flags": {}, @@ -816,7 +816,7 @@ "signatures": [ { "id": 65, - "name": "new TestAbstractClass", + "name": "TestAbstractClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -942,7 +942,7 @@ "signatures": [ { "id": 71, - "name": "new TestAbstractClassImplementation", + "name": "TestAbstractClassImplementation", "variant": "signature", "kind": 16384, "flags": {}, @@ -1124,7 +1124,7 @@ "signatures": [ { "id": 27, - "name": "new TestClass", + "name": "TestClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -1593,7 +1593,7 @@ "signatures": [ { "id": 43, - "name": "new TestSubClass", + "name": "TestSubClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -2216,7 +2216,7 @@ "signatures": [ { "id": 84, - "name": "new Ts38PrivateFields", + "name": "Ts38PrivateFields", "variant": "signature", "kind": 16384, "flags": {}, @@ -2408,7 +2408,7 @@ "signatures": [ { "id": 97, - "name": "new Vector2", + "name": "Vector2", "variant": "signature", "kind": 16384, "flags": {}, @@ -2640,7 +2640,7 @@ "signatures": [ { "id": 106, - "name": "new Vector3", + "name": "Vector3", "variant": "signature", "kind": 16384, "flags": {}, @@ -2968,7 +2968,7 @@ "signatures": [ { "id": 131, - "name": "new DecoratedClass", + "name": "DecoratedClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -3393,7 +3393,7 @@ "signatures": [ { "id": 165, - "name": "new EventDispatcher", + "name": "EventDispatcher", "variant": "signature", "kind": 16384, "flags": {}, @@ -4081,7 +4081,7 @@ "signatures": [ { "id": 169, - "name": "new GenericClass", + "name": "GenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -4369,7 +4369,7 @@ "signatures": [ { "id": 179, - "name": "new NonGenericClass", + "name": "NonGenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -4658,7 +4658,7 @@ "signatures": [ { "id": 188, - "name": "new GetterSetter", + "name": "GetterSetter", "variant": "signature", "kind": 16384, "flags": {}, @@ -5045,7 +5045,7 @@ "signatures": [ { "id": 213, - "name": "new GenericClass", + "name": "GenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -5194,7 +5194,7 @@ "signatures": [ { "id": 208, - "name": "new TestClass", + "name": "TestClass", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/class/specs.json b/src/test/converter/class/specs.json index ebdd6b2d3..56a7fa700 100644 --- a/src/test/converter/class/specs.json +++ b/src/test/converter/class/specs.json @@ -587,7 +587,7 @@ "signatures": [ { "id": 88, - "name": "new Abstract", + "name": "Abstract", "variant": "signature", "kind": 16384, "flags": {}, @@ -678,7 +678,7 @@ "signatures": [ { "id": 77, - "name": "new ComputedNames", + "name": "ComputedNames", "variant": "signature", "kind": 16384, "flags": {}, @@ -816,7 +816,7 @@ "signatures": [ { "id": 65, - "name": "new TestAbstractClass", + "name": "TestAbstractClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -942,7 +942,7 @@ "signatures": [ { "id": 71, - "name": "new TestAbstractClassImplementation", + "name": "TestAbstractClassImplementation", "variant": "signature", "kind": 16384, "flags": {}, @@ -1124,7 +1124,7 @@ "signatures": [ { "id": 27, - "name": "new TestClass", + "name": "TestClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -1593,7 +1593,7 @@ "signatures": [ { "id": 43, - "name": "new TestSubClass", + "name": "TestSubClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -2216,7 +2216,7 @@ "signatures": [ { "id": 84, - "name": "new Ts38PrivateFields", + "name": "Ts38PrivateFields", "variant": "signature", "kind": 16384, "flags": {}, @@ -2408,7 +2408,7 @@ "signatures": [ { "id": 97, - "name": "new Vector2", + "name": "Vector2", "variant": "signature", "kind": 16384, "flags": {}, @@ -2640,7 +2640,7 @@ "signatures": [ { "id": 106, - "name": "new Vector3", + "name": "Vector3", "variant": "signature", "kind": 16384, "flags": {}, @@ -2968,7 +2968,7 @@ "signatures": [ { "id": 131, - "name": "new DecoratedClass", + "name": "DecoratedClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -3393,7 +3393,7 @@ "signatures": [ { "id": 165, - "name": "new EventDispatcher", + "name": "EventDispatcher", "variant": "signature", "kind": 16384, "flags": {}, @@ -4081,7 +4081,7 @@ "signatures": [ { "id": 169, - "name": "new GenericClass", + "name": "GenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -4369,7 +4369,7 @@ "signatures": [ { "id": 179, - "name": "new NonGenericClass", + "name": "NonGenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -4658,7 +4658,7 @@ "signatures": [ { "id": 188, - "name": "new GetterSetter", + "name": "GetterSetter", "variant": "signature", "kind": 16384, "flags": {}, @@ -5045,7 +5045,7 @@ "signatures": [ { "id": 213, - "name": "new GenericClass", + "name": "GenericClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -5194,7 +5194,7 @@ "signatures": [ { "id": 208, - "name": "new TestClass", + "name": "TestClass", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/comment/specs.json b/src/test/converter/comment/specs.json index 883a708cc..eacab0d13 100644 --- a/src/test/converter/comment/specs.json +++ b/src/test/converter/comment/specs.json @@ -46,7 +46,7 @@ "signatures": [ { "id": 4, - "name": "new CommentedClass", + "name": "CommentedClass", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/declaration/specs.json b/src/test/converter/declaration/specs.json index e8e9d729e..e9b00e756 100644 --- a/src/test/converter/declaration/specs.json +++ b/src/test/converter/declaration/specs.json @@ -28,7 +28,7 @@ "signatures": [ { "id": 4, - "name": "new Decl", + "name": "Decl", "variant": "signature", "kind": 16384, "flags": {}, @@ -152,7 +152,7 @@ "signatures": [ { "id": 10, - "name": "new Exported", + "name": "Exported", "variant": "signature", "kind": 16384, "flags": {}, @@ -199,7 +199,7 @@ "signatures": [ { "id": 13, - "name": "new NotExported", + "name": "NotExported", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/function/specs.json b/src/test/converter/function/specs.json index c4c9a1ffd..df4e39d42 100644 --- a/src/test/converter/function/specs.json +++ b/src/test/converter/function/specs.json @@ -189,7 +189,7 @@ "signatures": [ { "id": 71, - "name": "new Predicates", + "name": "Predicates", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/inherit-param-doc/specs.json b/src/test/converter/inherit-param-doc/specs.json index 264c557bf..16e3eafdf 100644 --- a/src/test/converter/inherit-param-doc/specs.json +++ b/src/test/converter/inherit-param-doc/specs.json @@ -21,7 +21,7 @@ "signatures": [ { "id": 12, - "name": "new Class1", + "name": "Class1", "variant": "signature", "kind": 16384, "flags": {}, @@ -215,7 +215,7 @@ "signatures": [ { "id": 21, - "name": "new Class2", + "name": "Class2", "variant": "signature", "kind": 16384, "flags": {}, @@ -430,7 +430,7 @@ "signatures": [ { "id": 31, - "name": "new Class3", + "name": "Class3", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/inheritance/specs.json b/src/test/converter/inheritance/specs.json index 3370f5e10..e76c06c3c 100644 --- a/src/test/converter/inheritance/specs.json +++ b/src/test/converter/inheritance/specs.json @@ -658,7 +658,7 @@ "signatures": [ { "id": 35, - "name": "new MySubClass", + "name": "MySubClass", "variant": "signature", "kind": 16384, "flags": {}, @@ -856,7 +856,7 @@ "signatures": [ { "id": 28, - "name": "new MyCtor", + "name": "MyCtor", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/interface/specs.json b/src/test/converter/interface/specs.json index 471b6f3c0..08e71ce92 100644 --- a/src/test/converter/interface/specs.json +++ b/src/test/converter/interface/specs.json @@ -36,7 +36,7 @@ "signatures": [ { "id": 4, - "name": "new Constructor", + "name": "Constructor", "variant": "signature", "kind": 16384, "flags": {}, @@ -79,7 +79,7 @@ }, { "id": 7, - "name": "new Constructor", + "name": "Constructor", "variant": "signature", "kind": 16384, "flags": {}, @@ -124,7 +124,7 @@ }, { "id": 10, - "name": "new Constructor", + "name": "Constructor", "variant": "signature", "kind": 16384, "flags": {}, @@ -556,7 +556,7 @@ "signatures": [ { "id": 34, - "name": "new ClassImplementingEmptyInterface", + "name": "ClassImplementingEmptyInterface", "variant": "signature", "kind": 16384, "flags": {}, @@ -769,7 +769,7 @@ "signatures": [ { "id": 85, - "name": "new EventDispatcher", + "name": "EventDispatcher", "variant": "signature", "kind": 16384, "flags": {}, @@ -1269,7 +1269,7 @@ "signatures": [ { "id": 53, - "name": "new Subscription", + "name": "Subscription", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/mixin/specs.json b/src/test/converter/mixin/specs.json index 5ba85c2b5..a2af1922b 100644 --- a/src/test/converter/mixin/specs.json +++ b/src/test/converter/mixin/specs.json @@ -29,7 +29,7 @@ "signatures": [ { "id": 15, - "name": "new Base", + "name": "Base", "variant": "signature", "kind": 16384, "flags": {}, @@ -152,7 +152,7 @@ "signatures": [ { "id": 70, - "name": "new SomeClassWithMixin", + "name": "SomeClassWithMixin", "variant": "signature", "kind": 16384, "flags": {}, @@ -596,7 +596,7 @@ "signatures": [ { "id": 67, - "name": "new SomeClassWithMixin", + "name": "SomeClassWithMixin", "variant": "signature", "kind": 16384, "flags": {}, @@ -1701,7 +1701,7 @@ "signatures": [ { "id": 25, - "name": "new Mixin1Func", + "name": "Mixin1Func", "variant": "signature", "kind": 16384, "flags": {}, @@ -1900,7 +1900,7 @@ "signatures": [ { "id": 41, - "name": "new Mixin2", + "name": "Mixin2", "variant": "signature", "kind": 16384, "flags": {}, @@ -2092,7 +2092,7 @@ "signatures": [ { "id": 61, - "name": "new Mixin3", + "name": "Mixin3", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/react/specs.json b/src/test/converter/react/specs.json index c3225a456..0c6c9e509 100644 --- a/src/test/converter/react/specs.json +++ b/src/test/converter/react/specs.json @@ -29,7 +29,7 @@ "signatures": [ { "id": 6, - "name": "new Demo", + "name": "Demo", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/converter/variables/specs.json b/src/test/converter/variables/specs.json index 786157538..4f40b17b1 100644 --- a/src/test/converter/variables/specs.json +++ b/src/test/converter/variables/specs.json @@ -36,7 +36,7 @@ "signatures": [ { "id": 4, - "name": "new Array", + "name": "Array", "variant": "signature", "kind": 16384, "flags": {}, @@ -126,7 +126,7 @@ "signatures": [ { "id": 11, - "name": "new Foo", + "name": "Foo", "variant": "signature", "kind": 16384, "flags": {}, @@ -181,7 +181,7 @@ "signatures": [ { "id": 14, - "name": "new FooList", + "name": "FooList", "variant": "signature", "kind": 16384, "flags": {}, diff --git a/src/test/output/formatter.test.ts b/src/test/output/formatter.test.ts new file mode 100644 index 000000000..dde8ddb67 --- /dev/null +++ b/src/test/output/formatter.test.ts @@ -0,0 +1,346 @@ +import { equal } from "assert"; +import { + ConditionalType, + IndexedAccessType, + InferredType, + IntersectionType, + IntrinsicType, + LiteralType, + MappedType, + NamedTupleMember, + OptionalType, + PredicateType, + QueryType, + ReferenceType, + RestType, + TemplateLiteralType, + TupleType, + TypeContext, + TypeOperatorType, + UnionType, + UnknownType, + type SomeType, +} from "../../lib/models/types.js"; +import { renderElementToText } from "../../lib/utils/jsx.js"; +import { dedent } from "../utils.js"; +import { + DeclarationReflection, + FileRegistry, + ProjectReflection, + ReflectionKind, +} from "../../lib/models/index.js"; +import { + FormattedCodeBuilder, + FormattedCodeGenerator, + Wrap, +} from "../../lib/output/formatter.js"; + +export function renderType(type: SomeType, maxWidth = 80, startWidth = 0) { + const builder = new FormattedCodeBuilder(() => ""); + const tree = builder.type(type, TypeContext.none); + const generator = new FormattedCodeGenerator(maxWidth, startWidth); + generator.node(tree, Wrap.Detect); + return generator.toElement(); +} + +describe("Formatter", () => { + it("Handles a literal type", () => { + const literal = new LiteralType(123); + const text = renderElementToText(renderType(literal)); + equal(text, "123"); + }); + + it("Handles a conditional type", () => { + const [a, b, c, d] = ["a", "b", "c", "d"].map( + (x) => new LiteralType(x), + ); + const cond = new ConditionalType(a, b, c, d); + + const text = renderElementToText(renderType(cond)); + equal(text, `"a" extends "b" ? "c" : "d"`); + + const wrappedText = renderElementToText(renderType(cond, 10)); + equal( + wrappedText, + dedent(` + "a" extends "b" + ? "c" + : "d" + `), + ); + }); + + it("Handles an indexed access type", () => { + const [a, b] = ["object", "index"].map((x) => new LiteralType(x)); + const type = new IndexedAccessType(a, b); + + const text = renderElementToText(renderType(type)); + equal(text, `"object"["index"]`); + + const wrappedText = renderElementToText(renderType(type, 2)); + equal(wrappedText, `"object"["index"]`); + }); + + it("Handles a simple inferred type", () => { + const [a, _b, c, d] = ["a", "b", "c", "d"].map( + (x) => new LiteralType(x), + ); + const inferred = new InferredType("U"); + const type = new ConditionalType(a, inferred, c, d); + + const text = renderElementToText(renderType(type)); + equal(text, `"a" extends infer U ? "c" : "d"`); + }); + + it("Handles a complex inferred type", () => { + const [a, b, c, d] = ["a", "b", "c", "d"].map( + (x) => new LiteralType(x), + ); + const inferred = new InferredType("U", b); + const type = new ConditionalType(a, inferred, c, d); + + const text = renderElementToText(renderType(type)); + equal(text, `"a" extends infer U extends "b" ? "c" : "d"`); + + const wrappedText = renderElementToText(renderType(type, 2)); + equal( + wrappedText, + dedent(` + "a" extends infer U extends + "b" + ? "c" + : "d" + `), + ); + }); + + it("Handles intersection types", () => { + const types = ["a", "b", "c", "d"].map((x) => new LiteralType(x)); + const type = new IntersectionType(types); + + const text = renderElementToText(renderType(type)); + equal(text, `"a" & "b" & "c" & "d"`); + }); + + it("Handles intrinsic types", () => { + const type = new IntrinsicType("string"); + const text = renderElementToText(renderType(type)); + equal(text, `string`); + }); + + it("Handles mapped types", () => { + const [a, b, c, d] = ["a", "b", "c", "d"].map( + (x) => new LiteralType(x), + ); + const type = new MappedType("K", a, new UnionType([c, d]), "+", "-", b); + + const text = renderElementToText(renderType(type)); + equal(text, `{ readonly [K in "a" as "b"]-?: "c" | "d" }`); + + const text2 = renderElementToText(renderType(type, 50, 8)); + equal( + text2, + dedent(` + { + readonly [K in "a" as "b"]-?: "c" | "d" + } + `), + ); + + const text3 = renderElementToText(renderType(type, 40, 8)); + equal( + text3, + dedent(` + { + readonly [K in "a" as "b"]-?: + | "c" + | "d" + } + `), + ); + }); + + it("Handles named tuple members", () => { + const type = new NamedTupleMember("a", false, new LiteralType(123)); + + const text = renderElementToText(renderType(type)); + equal(text, `a: 123`); + + const type2 = new NamedTupleMember("a", true, new LiteralType(123)); + const text2 = renderElementToText(renderType(type2)); + equal(text2, `a?: 123`); + }); + + it("Handles optional types", () => { + const type = new OptionalType(new LiteralType(123)); + const text = renderElementToText(renderType(type)); + equal(text, `123?`); + }); + + it("Handles predicate types", () => { + const type = new PredicateType("x", true); + const text = renderElementToText(renderType(type)); + equal(text, `asserts x`); + + const type2 = new PredicateType( + "x", + false, + new IntrinsicType("string"), + ); + const text2 = renderElementToText(renderType(type2)); + equal(text2, `x is string`); + }); + + it("Handles query types", () => { + const project = new ProjectReflection("", new FileRegistry()); + const type = new QueryType( + ReferenceType.createBrokenReference("x", project), + ); + const text = renderElementToText(renderType(type)); + equal(text, `typeof x`); + }); + + it("Handles a simple reference type", () => { + const project = new ProjectReflection("", new FileRegistry()); + const type = ReferenceType.createBrokenReference("x", project); + const text = renderElementToText(renderType(type)); + equal(text, `x`); + }); + + it("Handles a resolved reference type", () => { + const project = new ProjectReflection("", new FileRegistry()); + const ns = new DeclarationReflection( + "ns", + ReflectionKind.Namespace, + project, + ); + const ns2 = new DeclarationReflection( + "target", // shares name with target + ReflectionKind.Namespace, + project, + ); + const target = new DeclarationReflection( + "target", + ReflectionKind.Variable, + ns, + ); + project.registerReflection(ns, undefined, undefined); + project.registerReflection(ns2, undefined, undefined); + project.registerReflection(target, undefined, undefined); + + const type = ReferenceType.createResolvedReference( + "x", + target, + project, + ); + const text = renderElementToText(renderType(type)); + equal(text, `ns.target`); + + target.kind = ReflectionKind.TypeParameter; + const text2 = renderElementToText(renderType(type)); + equal(text2, `target`); + }); + + it("Handles a reference type pointing to an external url", () => { + const project = new ProjectReflection("", new FileRegistry()); + const type = ReferenceType.createBrokenReference("x", project); + type.externalUrl = "https://example.com"; + const text = renderElementToText(renderType(type)); + equal(text, `x`); + }); + + it("Handles a reference type targeting a type parameter", () => { + const project = new ProjectReflection("", new FileRegistry()); + const type = ReferenceType.createBrokenReference("x", project); + type.refersToTypeParameter = true; + const text = renderElementToText(renderType(type)); + equal(text, `x`); + }); + + it("Handles a reference type with type arguments", () => { + const project = new ProjectReflection("", new FileRegistry()); + const type = ReferenceType.createBrokenReference("x", project); + type.typeArguments = [ + new LiteralType(123), + new LiteralType(456), + new LiteralType(789), + ]; + const text = renderElementToText(renderType(type)); + equal(text, `x<123, 456, 789>`); + + const text2 = renderElementToText(renderType(type, 0)); + equal( + text2, + dedent(` + x< + 123, + 456, + 789, + > + `), + ); + }); + + // TODO: reflection + + it("Handles rest types", () => { + const type = new RestType(new LiteralType("x")); + const text = renderElementToText(renderType(type)); + equal(text, `..."x"`); + }); + + it("Handles template literal types", () => { + const type = new TemplateLiteralType("head", [ + [new LiteralType(123), "more"], + [new LiteralType(2), ""], + ]); + const text = renderElementToText(renderType(type)); + equal(text, "`head${123}more${2}`"); + }); + + it("Handles tuple types", () => { + const types = Array.from({ length: 5 }, (_, i) => new LiteralType(i)); + const type = new TupleType(types); + const text = renderElementToText(renderType(type)); + equal(text, `[0, 1, 2, 3, 4]`); + + const text2 = renderElementToText(renderType(type, 0)); + equal( + text2, + dedent(` + [ + 0, + 1, + 2, + 3, + 4, + ] + `), + ); + }); + + it("Handles type operator types", () => { + const type = new TypeOperatorType(new LiteralType(123), "keyof"); + const text = renderElementToText(renderType(type)); + equal(text, `keyof 123`); + }); + + it("Handles a union type", () => { + const lit = new LiteralType(123); + const union = new UnionType([lit, lit, lit, lit, lit]); + const text = renderElementToText(renderType(union)); + equal(text, "123 | 123 | 123 | 123 | 123"); + + const wrappedText = renderElementToText(renderType(union, 10)); + equal( + wrappedText, + `\n | ${union.types.map((t) => t.toString()).join("\n | ")}`, + ); + }); + + it("Handles unknown types", () => { + const type = new UnknownType("a | + line.length ? Math.min(indent, line.search(/\S/)) : indent, + Infinity, + ); + + return lines.map((line) => line.substring(minIndent)).join("\n"); +} From 6e76611b0d38cb09c5628d67bd2ad1c1b7299964 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 30 Jun 2024 20:02:01 -0600 Subject: [PATCH 024/219] Add a test for parens --- src/test/output/formatter.test.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/output/formatter.test.ts b/src/test/output/formatter.test.ts index dde8ddb67..d3f852947 100644 --- a/src/test/output/formatter.test.ts +++ b/src/test/output/formatter.test.ts @@ -343,4 +343,18 @@ describe("Formatter", () => { const text = renderElementToText(renderType(type)); equal(text, "a | { + const [a, b, c, d] = Array.from( + { length: 4 }, + (_, i) => new LiteralType(i), + ); + const type = new IntersectionType([ + new UnionType([a, b]), + new UnionType([c, d]), + ]); + + const text = renderElementToText(renderType(type)); + equal(text, "(0 | 1) & (2 | 3)"); + }); }); From c1bf00b414fcf53c64eaaf1bf2dfa168a75b8db8 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 30 Jun 2024 20:32:23 -0600 Subject: [PATCH 025/219] Add support for an `@expand` tag. Closes #2303 --- CHANGELOG.md | 12 +++ src/lib/models/comments/comment.ts | 18 ++-- .../themes/default/partials/typeDetails.tsx | 99 ++++++++++++------- src/lib/utils/options/tsdoc-defaults.ts | 1 + tsdoc.json | 4 + 5 files changed, 89 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37f5fdb5f..639cf39e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,18 @@ - Removed the `hideParameterTypesInTitle` option, this was originally added as a workaround for many signatures overflowing the available horizontal space in rendered pages. TypeDoc now has logic to wrap types/signatures smartly, so this option is no longer necessary. +- Add support for an `@expand` tag which can be placed on type aliases and interfaces. + When a type with `@expand` is referenced and TypeDoc has a place to include additional details about the type, + the properties of the type will be included in the page where `@expand` is found. Note that use of this tag can + _significantly_ increase the size of your generated documentation if it is applied to commonly used types as + it will result in inlining the comments for those types everywhere they are referenced, #2303. + +TODO: + +- Add an option for controlling print width. +- Add an option for non-rendered tags, add `@expand` to it by default. +- Finish cleaning up formatter TODO comments, tests +- Write docs for `@expand` # Unreleased diff --git a/src/lib/models/comments/comment.ts b/src/lib/models/comments/comment.ts index daabfabbf..fe52a2db0 100644 --- a/src/lib/models/comments/comment.ts +++ b/src/lib/models/comments/comment.ts @@ -24,23 +24,18 @@ export type CommentDisplayPart = * that TypeDoc knows to skip it when parsing relative links and inline tags. **/ | { kind: "code"; text: string } - /** - * Represents an inline tag like `{@link Foo}` - */ | InlineTagDisplayPart - /** - * Represents a reference to a path relative to where the comment resides. - * This is used to detect and copy relative image links. - * Use {@link FileRegistry} to determine what path on disc this refers to. - */ | RelativeLinkDisplayPart; /** + * Represents an inline tag like `{@link Foo}` + * * The `@link`, `@linkcode`, and `@linkplain` tags may have a `target` * property set indicating which reflection/url they link to. They may also * have a `tsLinkText` property which includes the part of the `text` which * TypeScript thinks should be displayed as the link text. * @category Comments + * @expand */ export interface InlineTagDisplayPart { kind: "inline-tag"; @@ -51,9 +46,16 @@ export interface InlineTagDisplayPart { } /** + * Represents a reference to a path relative to where the comment resides. + * This is used to detect and copy relative image links. + * + * Use {@link FileRegistry} to determine what path on disc this refers to. + * * This is used for relative links within comments/documents. * It is used to mark pieces of text which need to be replaced * to make links work properly. + * @category Comments + * @expand */ export interface RelativeLinkDisplayPart { kind: "relative-link"; diff --git a/src/lib/output/themes/default/partials/typeDetails.tsx b/src/lib/output/themes/default/partials/typeDetails.tsx index 703878142..ce1ba8893 100644 --- a/src/lib/output/themes/default/partials/typeDetails.tsx +++ b/src/lib/output/themes/default/partials/typeDetails.tsx @@ -1,5 +1,10 @@ -import type { DeclarationReflection, SignatureReflection } from "../../../../models/index.js"; -import type { SomeType, TypeVisitor } from "../../../../models/types.js"; +import { + type Reflection, + ReflectionKind, + type DeclarationReflection, + type SignatureReflection, +} from "../../../../models/index.js"; +import type { ReferenceType, SomeType, TypeVisitor } from "../../../../models/types.js"; import { JSX, Raw } from "../../../../utils/index.js"; import { classNames, getKindClass } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; @@ -17,6 +22,9 @@ const isUsefulVisitor: Partial> = { reflection(type) { return renderingChildIsUseful(type.declaration); }, + reference(type) { + return shouldExpandReference(type); + }, }; function renderingTypeDetailsIsUseful(type: SomeType) { @@ -35,6 +43,15 @@ export function typeDeclaration(context: DefaultThemeRenderContext, type: SomeTy return null; } +const expanded = new Set(); +function shouldExpandReference(reference: ReferenceType) { + const target = reference.reflection; + if (!target?.kindOf(ReflectionKind.TypeAlias | ReflectionKind.Interface)) return false; + if (!target.comment?.hasModifier("@expand")) return false; + + return expanded.has(target) === false; +} + export function typeDetails(context: DefaultThemeRenderContext, type: SomeType): JSX.Children { return type.visit({ array(type) { @@ -58,42 +75,18 @@ export function typeDetails(context: DefaultThemeRenderContext, type: SomeType): }, reflection(type) { const declaration = type.declaration; - - return ( -
      - {declaration.signatures && ( -
    • -
        - {declaration.signatures.map((item) => ( - <> -
      • - {context.memberSignatureTitle(item, { - hideName: true, - })} -
      • -
      • - {context.memberSignatureBody(item, { - hideSources: true, - })} -
      • - - ))} -
      -
    • - )} - {declaration.indexSignatures?.map((index) => renderIndexSignature(context, index))} - {declaration.children?.map((child) => renderChild(context, child))} -
    - ); + return declarationDetails(context, declaration); }, - reference() { - // TODO: Check for @expand - return null; + reference(reference) { + if (shouldExpandReference(reference)) { + const target = reference.reflection as DeclarationReflection; + + // Ensure we don't go into an infinite loop here + expanded.add(target); + const details = target.type ? typeDetails(context, target.type) : declarationDetails(context, target); + expanded.delete(target); + return details; + } }, // tuple?? }); @@ -105,6 +98,38 @@ export function typeDetailsIfUseful(context: DefaultThemeRenderContext, type: So } } +function declarationDetails(context: DefaultThemeRenderContext, declaration: DeclarationReflection): JSX.Children { + return ( + <> + {context.commentSummary(declaration)} +
      + {declaration.signatures && ( +
    • +
        + {declaration.signatures.map((item) => ( + <> +
      • + {context.memberSignatureTitle(item, { + hideName: true, + })} +
      • +
      • + {context.memberSignatureBody(item, { + hideSources: true, + })} +
      • + + ))} +
      +
    • + )} + {declaration.indexSignatures?.map((index) => renderIndexSignature(context, index))} + {declaration.children?.map((child) => renderChild(context, child))} +
    + + ); +} + function renderChild(context: DefaultThemeRenderContext, child: DeclarationReflection) { if (child.signatures) { return ( diff --git a/src/lib/utils/options/tsdoc-defaults.ts b/src/lib/utils/options/tsdoc-defaults.ts index 17a7e23c9..16bedc0c8 100644 --- a/src/lib/utils/options/tsdoc-defaults.ts +++ b/src/lib/utils/options/tsdoc-defaults.ts @@ -64,6 +64,7 @@ export const modifierTags = [ "@class", "@enum", "@event", + "@expand", "@hidden", "@hideCategories", "@hideconstructor", diff --git a/tsdoc.json b/tsdoc.json index 9bed22577..62ab0dd50 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -88,6 +88,10 @@ "tagName": "@event", "syntaxKind": "modifier" }, + { + "tagName": "@expand", + "syntaxKind": "modifier" + }, { "tagName": "@template", "syntaxKind": "block", From 01e4f7168eba4ba99424090d8d22e576d2093203 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Tue, 2 Jul 2024 06:56:30 -0600 Subject: [PATCH 026/219] Add notRenderedTags option --- CHANGELOG.md | 3 +- src/lib/internationalization/locales/en.cts | 2 + src/lib/internationalization/locales/jp.cts | 1 + src/lib/internationalization/locales/ko.cts | 1 + src/lib/internationalization/locales/zh.cts | 1 + .../themes/default/partials/comment.tsx | 10 ++- src/lib/utils/options/declaration.ts | 1 + src/lib/utils/options/sources/typedoc.ts | 90 +++++++++---------- 8 files changed, 54 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 639cf39e0..a874ac7ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,12 @@ the properties of the type will be included in the page where `@expand` is found. Note that use of this tag can _significantly_ increase the size of your generated documentation if it is applied to commonly used types as it will result in inlining the comments for those types everywhere they are referenced, #2303. +- Add `notRenderedTags` option. This option is similar to the `excludeTags` option, but while `excludeTags` will result in the + tag being completely removed from the documentation, `notRenderedTags` only prevents it from being included when rendering. TODO: - Add an option for controlling print width. -- Add an option for non-rendered tags, add `@expand` to it by default. - Finish cleaning up formatter TODO comments, tests - Write docs for `@expand` diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index 0374c89ad..ba61e3400 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -247,6 +247,8 @@ export = { help_basePath: "Specifies the base path to be used when displaying file paths", help_excludeTags: "Remove the listed block/modifier tags from doc comments", + help_notRenderedTags: + "Tags which will be preserved in doc comments, but not rendered when creating output", help_readme: "Path to the readme file that should be displayed on the index page. Pass `none` to disable the index page and start the documentation on the globals page", help_cname: diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 69503f5b1..8ad223cf4 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -270,6 +270,7 @@ export = localeUtils.buildIncompleteTranslation({ help_basePath: "ファイルパスを表示するときに使用するベースパスを指定します", help_excludeTags: "ドキュメントコメントからリストされたブロック/修飾子タグを削除します", + // help_notRenderedTags help_readme: "インデックス ページに表示される Readme ファイルへのパス。インデックス ページを無効にしてグローバル ページでドキュメントを開始するには、`none` を渡します。", help_cname: diff --git a/src/lib/internationalization/locales/ko.cts b/src/lib/internationalization/locales/ko.cts index f505c3ca3..5ce23ddef 100644 --- a/src/lib/internationalization/locales/ko.cts +++ b/src/lib/internationalization/locales/ko.cts @@ -117,6 +117,7 @@ export = localeUtils.buildIncompleteTranslation({ "모든 것을 sourceLinkTemplate로 링크할 수 있도록 가정합니다. 이 옵션을 사용하려면 sourceLinkTemplate이 설정되어 있어야 합니다. {path}는 basePath에서 시작됩니다", help_basePath: "파일 경로를 표시할 때 사용할 기본 경로를 지정합니다", help_excludeTags: "문서 주석에서 제거할 블록/수정자 태그를 지정합니다", + // help_notRenderedTags help_readme: "인덱스 페이지에 표시할 readme 파일의 경로를 지정합니다. 'none'을 전달하여 인덱스 페이지를 비활성화하고 글로벌 페이지에서 문서화를 시작합니다", help_cname: diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index 79371cb90..311473d39 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -227,6 +227,7 @@ export = localeUtils.buildIncompleteTranslation({ "假设所有内容都可以通过 sourceLinkTemplate 进行链接,如果启用此功能,则必须设置 sourceLinkTemplate。{path} 将以 basePath 为根", help_basePath: "指定显示文件路径时使用的基本路径", help_excludeTags: "从文档注释中删除列出的块/修饰符标签", + // help_notRenderedTags help_readme: "应显示在索引页上的自述文件路径。传递“none”以禁用索引页并在全局页上启动文档", help_cname: "设置 CNAME 文件文本,这对于 GitHub Pages 上的自定义域很有用", diff --git a/src/lib/output/themes/default/partials/comment.tsx b/src/lib/output/themes/default/partials/comment.tsx index fb8b3430a..a115fb39a 100644 --- a/src/lib/output/themes/default/partials/comment.tsx +++ b/src/lib/output/themes/default/partials/comment.tsx @@ -19,12 +19,15 @@ export function commentSummary({ markdown }: DefaultThemeRenderContext, props: R export function commentTags(context: DefaultThemeRenderContext, props: Reflection) { if (!props.comment) return; + const skippedTags = context.options.getValue("notRenderedTags"); const beforeTags = context.hook("comment.beforeTags", context, props.comment, props); const afterTags = context.hook("comment.afterTags", context, props.comment, props); const tags = props.kindOf(ReflectionKind.SomeSignature) - ? props.comment.blockTags.filter((tag) => tag.tag !== "@returns" && !tag.skipRendering) - : props.comment.blockTags.filter((tag) => !tag.skipRendering); + ? props.comment.blockTags.filter( + (tag) => tag.tag !== "@returns" && !tag.skipRendering && !skippedTags.includes(tag.tag), + ) + : props.comment.blockTags.filter((tag) => !tag.skipRendering && !skippedTags.includes(tag.tag)); return ( <> @@ -54,9 +57,8 @@ export function commentTags(context: DefaultThemeRenderContext, props: Reflectio ); } -const flagsNotRendered: `@${string}`[] = ["@showCategories", "@showGroups", "@hideCategories", "@hideGroups"]; - export function reflectionFlags(context: DefaultThemeRenderContext, props: Reflection) { + const flagsNotRendered = context.options.getValue("notRenderedTags"); const allFlags = props.flags.getFlagStrings(context.internationalization); if (props.comment) { for (const tag of props.comment.modifierTags) { diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index d0b9963f2..d51516dd4 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -200,6 +200,7 @@ export interface TypeDocOptionMap { inlineTags: `@${string}`[]; modifierTags: `@${string}`[]; excludeTags: `@${string}`[]; + notRenderedTags: `@${string}`[]; externalSymbolLinkMappings: ManuallyValidatedOption< Record> >; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index b7cf042fe..936dbcfc7 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -1,4 +1,4 @@ -import type { Options } from "../index.js"; +import type { Options, TypeDocOptionMap } from "../index.js"; import { LogLevel } from "../../loggers.js"; import { ParameterType, @@ -21,6 +21,15 @@ import { getSupportedThemes, } from "../../highlighter.js"; import { setDifference } from "../../set.js"; +import type { TranslationProxy } from "../../../internationalization/index.js"; + +function makeTagArrayValidator(name: keyof TypeDocOptionMap) { + return (value: string[], i18n: TranslationProxy) => { + if (!Validation.validate([Array, Validation.isTagString], value)) { + throw new Error(i18n.option_0_values_must_be_array_of_tags(name)); + } + }; +} // For convenience, added in the same order as they are documented on the website. export function addTypeDocOptions(options: Pick) { @@ -437,25 +446,6 @@ export function addTypeDocOptions(options: Pick) { help: (i18n) => i18n.help_basePath(), type: ParameterType.Path, }); - options.addDeclaration({ - name: "excludeTags", - help: (i18n) => i18n.help_excludeTags(), - type: ParameterType.Array, - defaultValue: [ - "@override", - "@virtual", - "@privateRemarks", - "@satisfies", - "@overload", - ], - validate(value, i18n) { - if (!Validation.validate([Array, Validation.isTagString], value)) { - throw new Error( - i18n.option_0_values_must_be_array_of_tags("excludeTags"), - ); - } - }, - }); options.addDeclaration({ name: "readme", help: (i18n) => i18n.help_readme(), @@ -711,54 +701,54 @@ export function addTypeDocOptions(options: Pick) { help: (i18n) => i18n.help_blockTags(), type: ParameterType.Array, defaultValue: blockTags, - validate(value, i18n) { - if (!Validation.validate([Array, Validation.isTagString], value)) { - throw new Error( - i18n.option_0_values_must_be_array_of_tags("blockTags"), - ); - } - }, + validate: makeTagArrayValidator("blockTags"), }); options.addDeclaration({ name: "inlineTags", help: (i18n) => i18n.help_inlineTags(), type: ParameterType.Array, defaultValue: inlineTags, - validate(value, i18n) { - if (!Validation.validate([Array, Validation.isTagString], value)) { - throw new Error( - i18n.option_0_values_must_be_array_of_tags("inlineTags"), - ); - } - }, + validate: makeTagArrayValidator("inlineTags"), }); options.addDeclaration({ name: "modifierTags", help: (i18n) => i18n.help_modifierTags(), type: ParameterType.Array, defaultValue: modifierTags, - validate(value, i18n) { - if (!Validation.validate([Array, Validation.isTagString], value)) { - throw new Error( - i18n.option_0_values_must_be_array_of_tags("modifierTags"), - ); - } - }, + validate: makeTagArrayValidator("modifierTags"), + }); + options.addDeclaration({ + name: "excludeTags", + help: (i18n) => i18n.help_excludeTags(), + type: ParameterType.Array, + defaultValue: [ + "@override", + "@virtual", + "@privateRemarks", + "@satisfies", + "@overload", + ], + validate: makeTagArrayValidator("excludeTags"), + }); + options.addDeclaration({ + name: "notRenderedTags", + help: (i18n) => i18n.help_notRenderedTags(), + type: ParameterType.Array, + defaultValue: [ + "@showCategories", + "@showGroups", + "@hideCategories", + "@hideGroups", + "@expand", + ], + validate: makeTagArrayValidator("notRenderedTags"), }); options.addDeclaration({ name: "cascadedModifierTags", help: (i18n) => i18n.help_modifierTags(), type: ParameterType.Array, defaultValue: ["@alpha", "@beta", "@experimental"], - validate(value, i18n) { - if (!Validation.validate([Array, Validation.isTagString], value)) { - throw new Error( - i18n.option_0_values_must_be_array_of_tags( - "cascadedModifierTags", - ), - ); - } - }, + validate: makeTagArrayValidator("cascadedModifierTags"), }); /////////////////////////// From db86ac3768c1db611c2f64647b2bc46a6280841c Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Fri, 26 Jul 2024 10:08:57 -0600 Subject: [PATCH 027/219] Fix some issues with the formatter, add tests --- CHANGELOG.md | 1 - internal-docs/plugins.md | 2 +- src/lib/output/formatter.tsx | 140 ++++---- .../default/partials/member.declaration.tsx | 7 +- src/test/output/formatter.test.ts | 311 +++++++++++++++++- 5 files changed, 398 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72adc54ee..88655c5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,6 @@ TODO: - Add an option for controlling print width. -- Finish cleaning up formatter TODO comments, tests - Write docs for `@expand` # Unreleased diff --git a/internal-docs/plugins.md b/internal-docs/plugins.md index 3520453d1..2eee95665 100644 --- a/internal-docs/plugins.md +++ b/internal-docs/plugins.md @@ -21,7 +21,7 @@ Plugins may be either ESM or CommonJS. import td from "typedoc"; /** @param {td.Application} app */ export function load(app) { - // todo: Add event listeners to app, app.converter, etc. + // Add event listeners to app, app.converter, etc. // this function may be async } ``` diff --git a/src/lib/output/formatter.tsx b/src/lib/output/formatter.tsx index def15d39a..3ce3cda35 100644 --- a/src/lib/output/formatter.tsx +++ b/src/lib/output/formatter.tsx @@ -25,25 +25,30 @@ import { // Non breaking space const INDENT = "\u00A0\u00A0\u00A0\u00A0"; -type Node = +export type FormatterNode = | { type: "text"; content: string } | { type: "element"; content: JSX.Element; length: number } | { type: "line" } | { type: "space_or_line" } - | { type: "indent"; content: Node[] } - | { type: "group"; id: number; content: Node[] } - | { type: "nodes"; content: Node[] } - | { type: "if_wrap"; id: number; true: Node; false: Node }; + | { type: "indent"; content: FormatterNode[] } + | { type: "group"; id: number; content: FormatterNode[] } + | { type: "nodes"; content: FormatterNode[] } + | { + type: "if_wrap"; + id: number; + true: FormatterNode; + false: FormatterNode; + }; const emptyNode = textNode(""); function space() { return textNode(" "); } -function textNode(content: string): Node { +function textNode(content: string): FormatterNode { return { type: "text", content }; } -function simpleElement(element: JSX.Element): Node { +function simpleElement(element: JSX.Element): FormatterNode { ok(element.children.length === 1); ok(typeof element.children[0] === "string"); return { @@ -52,31 +57,35 @@ function simpleElement(element: JSX.Element): Node { length: element.children[0].length, }; } -function line(): Node { +function line(): FormatterNode { return { type: "line" }; } -function spaceOrLine(): Node { +function spaceOrLine(): FormatterNode { return { type: "space_or_line" }; } -function indent(content: Node[]): Node { +function indent(content: FormatterNode[]): FormatterNode { return { type: "indent", content }; } -function group(id: number, content: Node[]): Node { +function group(id: number, content: FormatterNode[]): FormatterNode { return { type: "group", id, content }; } -function nodes(...content: Node[]): Node { +function nodes(...content: FormatterNode[]): FormatterNode { return { type: "nodes", content }; } function ifWrap( id: number, - trueBranch: Node, - falseBranch: Node = emptyNode, -): Node { + trueBranch: FormatterNode, + falseBranch: FormatterNode = emptyNode, +): FormatterNode { return { type: "if_wrap", id, true: trueBranch, false: falseBranch }; } -function join(joiner: Node, list: readonly T[], cb: (x: T) => Node): Node { - const content: Node[] = []; +function join( + joiner: FormatterNode, + list: readonly T[], + cb: (x: T) => FormatterNode, +): FormatterNode { + const content: FormatterNode[] = []; for (const item of list) { if (content.length > 0) { @@ -88,7 +97,7 @@ function join(joiner: Node, list: readonly T[], cb: (x: T) => Node): Node { return { type: "nodes", content }; } -function nodeWidth(node: Node, wrapped: Set): number { +function nodeWidth(node: FormatterNode, wrapped: Set): number { switch (node.type) { case "text": return node.content.length; @@ -137,7 +146,7 @@ export class FormattedCodeGenerator { return <>{this.buffer}; } - node(node: Node, wrap: Wrap): void { + node(node: FormatterNode, wrap: Wrap): void { switch (node.type) { case "nodes": { for (const n of node.content) { @@ -285,7 +294,7 @@ function getNamespacedPath(reflection: Reflection): Reflection[] { } const typeBuilder: TypeVisitor< - Node, + FormatterNode, [FormattedCodeBuilder, { topLevelLinks: boolean }] > = { array(type, builder) { @@ -400,7 +409,7 @@ const typeBuilder: TypeVisitor< ); }, mapped(type, builder) { - const parts: Node[] = []; + const parts: FormatterNode[] = []; switch (type.readonlyModifier) { case "+": @@ -493,7 +502,7 @@ const typeBuilder: TypeVisitor< ); }, predicate(type, builder) { - const content: Node[] = []; + const content: FormatterNode[] = []; if (type.asserts) { content.push( simpleElement( @@ -527,7 +536,7 @@ const typeBuilder: TypeVisitor< }, reference(type, builder) { const reflection = type.reflection; - let name: Node; + let name: FormatterNode; if (reflection) { if (reflection.kindOf(ReflectionKind.TypeParameter)) { @@ -623,7 +632,7 @@ const typeBuilder: TypeVisitor< ); }, templateLiteral(type, builder) { - const content: Node[] = []; + const content: FormatterNode[] = []; content.push( simpleElement(`), ); @@ -732,34 +741,33 @@ export class FormattedCodeBuilder { type: SomeType | undefined, where: TypeContext, options: { topLevelLinks: boolean } = { topLevelLinks: false }, - ): Node { + ): FormatterNode { if (!type) { return simpleElement(any); } - const rendered = type.visit(typeBuilder, this, options); if (type.needsParenthesis(where)) { const id = this.newId(); return group(id, [ textNode("("), line(), - indent([rendered]), + indent([type.visit(typeBuilder, this, options)]), line(), textNode(")"), ]); } - return rendered; + return type.visit(typeBuilder, this, options); } reflection( reflection: DeclarationReflection, options: { topLevelLinks: boolean }, - ): Node { - const members: Node[] = []; + ): FormatterNode { + const members: FormatterNode[] = []; const children = reflection.children || []; for (const item of children) { - members.push(this.member(item, options)); + this.member(members, item, options); } if (reflection.indexSignatures) { @@ -775,7 +783,7 @@ export class FormattedCodeBuilder { , ), simpleElement( - ], + :, ), space(), this.type(index.parameters![0].type, TypeContext.none), @@ -817,10 +825,13 @@ export class FormattedCodeBuilder { (node) => node, ), ]), + ifWrap( + id, + simpleElement(;), + ), spaceOrLine(), simpleElement({"}"}), ]); - // } return simpleElement({"{}"}); @@ -837,38 +848,47 @@ export class FormattedCodeBuilder { ); } - member(item: DeclarationReflection, options: { topLevelLinks: boolean }) { + member( + members: FormatterNode[], + item: DeclarationReflection, + options: { topLevelLinks: boolean }, + ): void { if (item.getSignature && item.setSignature) { - return nodes( - this.signature(item.getSignature, options), - line(), + members.push( this.signature(item.getSignature, options), + this.signature(item.setSignature, options), ); + return; } if (item.getSignature) { - return this.signature(item.getSignature, options); + members.push(this.signature(item.getSignature, options)); + return; } if (item.setSignature) { - return this.signature(item.setSignature, options); + members.push(this.signature(item.setSignature, options)); + return; } if (item.signatures) { - return nodes( + members.push( ...item.signatures.map((sig) => this.signature(sig, options)), ); + return; } - return nodes( - this.propertyName(item, options), - simpleElement( - - {item.flags.isOptional ? "?:" : ":"} - , + members.push( + nodes( + this.propertyName(item, options), + simpleElement( + + {item.flags.isOptional ? "?:" : ":"} + , + ), + space(), + this.type(item.type, TypeContext.none), ), - space(), - this.type(item.type, TypeContext.none), ); } @@ -879,8 +899,8 @@ export class FormattedCodeBuilder { hideName?: boolean; arrowStyle?: boolean; }, - ): Node { - let name: Node = options.hideName + ): FormatterNode { + let name: FormatterNode = options.hideName ? emptyNode : this.propertyName(sig, options); switch (sig.kind) { @@ -895,6 +915,7 @@ export class FormattedCodeBuilder { ); } label = nodes( + label, simpleElement( new, ), @@ -931,12 +952,13 @@ export class FormattedCodeBuilder { this.typeParameters(sig), ...this.parameters(sig, id), nodes( + options.arrowStyle ? space() : emptyNode, simpleElement( - // TODO - {options.arrowStyle ? " => " : ": "} + {options.arrowStyle ? "=>" : ":"} , ), + space(), this.type(sig.type, TypeContext.none), ), ]); @@ -944,7 +966,7 @@ export class FormattedCodeBuilder { private typeParameters( sig: SignatureReflection | DeclarationReflection, - ): Node { + ): FormatterNode { if (!sig.typeParameters?.length) { return emptyNode; } @@ -1028,7 +1050,7 @@ export class FormattedCodeBuilder { return group(this.newId(), content); } - private parameters(sig: SignatureReflection, id: number): Node[] { + private parameters(sig: SignatureReflection, id: number): FormatterNode[] { if (!sig.parameters?.length) { return [ simpleElement(()), @@ -1060,7 +1082,7 @@ export class FormattedCodeBuilder { } private parameter(param: ParameterReflection) { - const content: Node[] = []; + const content: FormatterNode[] = []; if (param.flags.isRest) { content.push( simpleElement(...), @@ -1079,7 +1101,11 @@ export class FormattedCodeBuilder { simpleElement(:), ); } - content.push(space()); + // Tricky: We don't introduce a branch here via group() + // the branch may be introduced by the union type if the parameter + // value is a union. + const id = this.newId(); + content.push(ifWrap(id, emptyNode, space())); content.push(this.type(param.type, TypeContext.none)); return nodes(...content); } @@ -1087,7 +1113,7 @@ export class FormattedCodeBuilder { private propertyName( reflection: Reflection, options: { topLevelLinks?: boolean }, - ): Node { + ): FormatterNode { const entityName = /^[A-Z_$][\w$]*$/i.test(reflection.name) ? reflection.name : JSON.stringify(reflection.name); diff --git a/src/lib/output/themes/default/partials/member.declaration.tsx b/src/lib/output/themes/default/partials/member.declaration.tsx index 400e32dd5..3b960ab4d 100644 --- a/src/lib/output/themes/default/partials/member.declaration.tsx +++ b/src/lib/output/themes/default/partials/member.declaration.tsx @@ -1,6 +1,6 @@ import type { DeclarationReflection } from "../../../../models/index.js"; import { JSX } from "../../../../utils/index.js"; -import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap } from "../../../formatter.js"; +import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap, type FormatterNode } from "../../../formatter.js"; import { hasTypeParameters } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; @@ -8,9 +8,10 @@ void JSX; // TS is confused and thinks this is unused export function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection) { const builder = new FormattedCodeBuilder(context.urlTo); - const tree = builder.member(props, { topLevelLinks: false }); + const content: FormatterNode[] = []; + builder.member(content, props, { topLevelLinks: false }); const generator = new FormattedCodeGenerator(); - generator.node(tree, Wrap.Detect); + generator.node({ type: "nodes", content }, Wrap.Detect); return ( <> diff --git a/src/test/output/formatter.test.ts b/src/test/output/formatter.test.ts index d3f852947..d0b653551 100644 --- a/src/test/output/formatter.test.ts +++ b/src/test/output/formatter.test.ts @@ -12,6 +12,7 @@ import { PredicateType, QueryType, ReferenceType, + ReflectionType, RestType, TemplateLiteralType, TupleType, @@ -26,8 +27,12 @@ import { dedent } from "../utils.js"; import { DeclarationReflection, FileRegistry, + ParameterReflection, ProjectReflection, + ReflectionFlag, ReflectionKind, + SignatureReflection, + TypeParameterReflection, } from "../../lib/models/index.js"; import { FormattedCodeBuilder, @@ -281,7 +286,311 @@ describe("Formatter", () => { ); }); - // TODO: reflection + it("Handles an index signature reflection type", () => { + const decl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + decl.indexSignatures = [ + new SignatureReflection( + "__index", + ReflectionKind.IndexSignature, + decl, + ), + ]; + decl.indexSignatures[0].type = new IntrinsicType("string"); + decl.indexSignatures[0].parameters = [ + new ParameterReflection("x", ReflectionKind.Parameter), + ]; + decl.indexSignatures[0].parameters[0].type = new IntrinsicType( + "number", + ); + + const type = new ReflectionType(decl); + const text = renderElementToText(renderType(type)); + equal(text, `{ [x: number]: string }`); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + { + [x: number]: string; + } + `), + ); + }); + + it("Handles single signature callback reflection types", () => { + const decl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const sig = new SignatureReflection( + "__call", + ReflectionKind.CallSignature, + decl, + ); + decl.signatures = [sig]; + sig.type = new LiteralType("str"); + sig.parameters = [ + new ParameterReflection("x", ReflectionKind.Parameter), + new ParameterReflection("y", ReflectionKind.Parameter), + ]; + sig.parameters[0].setFlag(ReflectionFlag.Optional); + sig.parameters[1].setFlag(ReflectionFlag.Rest); + sig.parameters[0].type = new IntrinsicType("string"); + sig.parameters[1].type = new IntrinsicType("number"); + + const type = new ReflectionType(decl); + const text = renderElementToText(renderType(type)); + equal(text, `(x?: string, ...y: number) => "str"`); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + ( + x?: string, + ...y: number, + ) => "str" + `), + ); + }); + + it("Handles abstract construct signature", () => { + const decl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const sig = new SignatureReflection( + "__call", + ReflectionKind.ConstructorSignature, + decl, + ); + sig.type = new IntrinsicType("Number"); + sig.flags.setFlag(ReflectionFlag.Abstract, true); + decl.signatures = [sig]; + + const type = new ReflectionType(decl); + const text = renderElementToText(renderType(type)); + equal(text, `abstract new () => Number`); + }); + + it("Handles multiple signature callback reflection types", () => { + const decl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const sig = new SignatureReflection( + "__call", + ReflectionKind.CallSignature, + decl, + ); + decl.signatures = [sig, sig]; + sig.type = new LiteralType("str"); + sig.parameters = [ + new ParameterReflection("x", ReflectionKind.Parameter), + new ParameterReflection("y", ReflectionKind.Parameter), + ]; + sig.parameters[0].type = new IntrinsicType("string"); + sig.parameters[1].type = new IntrinsicType("number"); + + const type = new ReflectionType(decl); + const text = renderElementToText(renderType(type, 1000, 0)); + equal( + text, + `{ (x: string, y: number): "str"; (x: string, y: number): "str" }`, + ); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + { + ( + x: string, + y: number, + ): "str"; + ( + x: string, + y: number, + ): "str"; + } + `), + ); + }); + + it("Handles type parameters on signatures", () => { + const decl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const sig = new SignatureReflection( + "__call", + ReflectionKind.CallSignature, + decl, + ); + const a = new TypeParameterReflection("a", sig, undefined); + a.setFlag(ReflectionFlag.Const); + a.type = new IntrinsicType("string"); + const b = new TypeParameterReflection("b", sig, "in out"); + const c = new TypeParameterReflection("c", sig, undefined); + c.default = new IntrinsicType("string"); + sig.typeParameters = [a, b, c]; + decl.signatures = [sig]; + + const type = new ReflectionType(decl); + const text = renderElementToText(renderType(type)); + equal(text, `() => any`); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + < + const a extends + string, + in out b, + c = string, + >() => any + `), + ); + }); + + it("Handles simple object types", () => { + const refl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const a = new DeclarationReflection("a", ReflectionKind.Property, refl); + a.type = new IntrinsicType("string"); + refl.addChild(a); + const b = new DeclarationReflection("b", ReflectionKind.Property, refl); + b.getSignature = new SignatureReflection( + "b", + ReflectionKind.GetSignature, + b, + ); + b.getSignature.type = new IntrinsicType("string"); + b.setSignature = new SignatureReflection( + "b", + ReflectionKind.SetSignature, + b, + ); + b.setSignature.type = new IntrinsicType("void"); + b.setSignature.parameters = [ + new ParameterReflection("value", ReflectionKind.Parameter), + ]; + b.setSignature.parameters[0].type = new UnionType([ + new IntrinsicType("string"), + new IntrinsicType("number"), + ]); + refl.addChild(b); + + const type = new ReflectionType(refl); + const text = renderElementToText(renderType(type)); + equal( + text, + "{ a: string; get b(): string; set b(value: string | number): void }", + ); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + { + a: string; + get b(): string; + set b( + value: + | string + | number, + ): void; + } + `), + ); + }); + + it("Handles get/set only properties", () => { + const refl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const a = new DeclarationReflection("a", ReflectionKind.Property, refl); + a.getSignature = new SignatureReflection( + "a", + ReflectionKind.GetSignature, + a, + ); + a.getSignature.type = new IntrinsicType("string"); + refl.addChild(a); + const b = new DeclarationReflection("b", ReflectionKind.Property, refl); + b.setSignature = new SignatureReflection( + "b", + ReflectionKind.SetSignature, + b, + ); + b.setSignature.type = new IntrinsicType("void"); + b.setSignature.parameters = [ + new ParameterReflection("value", ReflectionKind.Parameter), + ]; + b.setSignature.parameters[0].type = new UnionType([ + new IntrinsicType("string"), + new IntrinsicType("number"), + ]); + refl.addChild(b); + + const type = new ReflectionType(refl); + const text = renderElementToText(renderType(type)); + equal(text, "{ get a(): string; set b(value: string | number): void }"); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + { + get a(): string; + set b( + value: + | string + | number, + ): void; + } + `), + ); + }); + + it("Handles callable members", () => { + const refl = new DeclarationReflection( + "__type", + ReflectionKind.TypeLiteral, + ); + const a = new DeclarationReflection("a", ReflectionKind.Property, refl); + const sig = new SignatureReflection( + "a", + ReflectionKind.CallSignature, + a, + ); + sig.type = new IntrinsicType("string"); + a.signatures = [sig, sig]; + refl.addChild(a); + + const type = new ReflectionType(refl); + const text = renderElementToText(renderType(type)); + equal(text, "{ a(): string; a(): string }"); + + const textWrap = renderElementToText(renderType(type, 0)); + equal( + textWrap, + dedent(` + { + a(): string; + a(): string; + } + `), + ); + }); it("Handles rest types", () => { const type = new RestType(new LiteralType("x")); From 2cde6bccd8003488f42c443994d330bb74dcd12f Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Fri, 26 Jul 2024 10:21:51 -0600 Subject: [PATCH 028/219] Fix rendering of interface preview with type parameters --- src/lib/output/formatter.tsx | 12 +++++++++++- .../themes/default/partials/reflectionPreview.tsx | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/lib/output/formatter.tsx b/src/lib/output/formatter.tsx index 3ce3cda35..e557ef9ad 100644 --- a/src/lib/output/formatter.tsx +++ b/src/lib/output/formatter.tsx @@ -142,6 +142,12 @@ export class FormattedCodeGenerator { this.size = startWidth; } + forceWrap(wrapped: Set) { + for (const id of wrapped) { + this.wrapped.add(id); + } + } + toElement(): JSX.Element { return <>{this.buffer}; } @@ -159,7 +165,7 @@ export class FormattedCodeGenerator { nodeWidth(n, this.wrapped), ); let wrap: Wrap; - if (this.size + width > this.max) { + if (this.size + width > this.max || this.wrapped.has(node.id)) { this.wrapped.add(node.id); wrap = Wrap.Enable; } else { @@ -729,6 +735,7 @@ const typeBuilder: TypeVisitor< * Responsible for generating Nodes from a type tree. */ export class FormattedCodeBuilder { + forceWrap = new Set(); id = 0; constructor(readonly urlTo: (refl: Reflection) => string) {} @@ -810,6 +817,9 @@ export class FormattedCodeBuilder { if (members.length) { const id = this.newId(); + if (options.topLevelLinks) { + this.forceWrap.add(id); + } return group(id, [ simpleElement({"{"}), spaceOrLine(), diff --git a/src/lib/output/themes/default/partials/reflectionPreview.tsx b/src/lib/output/themes/default/partials/reflectionPreview.tsx index b89fa27cb..f9e9fc27b 100644 --- a/src/lib/output/themes/default/partials/reflectionPreview.tsx +++ b/src/lib/output/themes/default/partials/reflectionPreview.tsx @@ -14,8 +14,8 @@ export function reflectionPreview(context: DefaultThemeRenderContext, props: Ref if (props.kindOf(ReflectionKind.Interface) && props.children) { const builder = new FormattedCodeBuilder(context.urlTo); const tree = builder.interface(props); - // Pass infinity to force properties onto new lines - const generator = new FormattedCodeGenerator(undefined, Infinity); + const generator = new FormattedCodeGenerator(); + generator.forceWrap(builder.forceWrap); // Ensure elements are added to new lines. generator.node(tree, Wrap.Enable); return
    {generator.toElement()}
    ; From c26cb22419632eee94e8fcfe78d20d0e483bd7c5 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sat, 10 Aug 2024 11:00:58 -0600 Subject: [PATCH 029/219] Default option improvements --- .config/typedoc.json | 2 +- CHANGELOG.md | 2 ++ src/lib/converter/plugins/GroupPlugin.ts | 2 +- src/lib/utils/options/defaults.ts | 12 ++---------- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/.config/typedoc.json b/.config/typedoc.json index 1eec70673..eaef91b37 100644 --- a/.config/typedoc.json +++ b/.config/typedoc.json @@ -14,7 +14,7 @@ "excludeExternals": true, "excludeInternal": false, "excludePrivate": true, - "excludeReferences": true, + // "excludeReferences": true, "jsDocCompatibility": false, "treatWarningsAsErrors": false, "categorizeByGroup": false, diff --git a/CHANGELOG.md b/CHANGELOG.md index 88655c5ca..412f61131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ it will result in inlining the comments for those types everywhere they are referenced, #2303. - Add `notRenderedTags` option. This option is similar to the `excludeTags` option, but while `excludeTags` will result in the tag being completely removed from the documentation, `notRenderedTags` only prevents it from being included when rendering. +- Changed the default `kindSortOrder` to put references last. +- Changed the default `sort` order to use `alphabetical-ignoring-documents` instead of `alphabetical`. TODO: diff --git a/src/lib/converter/plugins/GroupPlugin.ts b/src/lib/converter/plugins/GroupPlugin.ts index abf974d00..d02976e67 100644 --- a/src/lib/converter/plugins/GroupPlugin.ts +++ b/src/lib/converter/plugins/GroupPlugin.ts @@ -15,7 +15,6 @@ import { ConverterEvents } from "../converter-events.js"; // Same as the defaultKindSortOrder in sort.ts const defaultGroupOrder = [ ReflectionKind.Document, - ReflectionKind.Reference, // project is never a child so never added to a group ReflectionKind.Module, ReflectionKind.Namespace, @@ -32,6 +31,7 @@ const defaultGroupOrder = [ ReflectionKind.Accessor, ReflectionKind.Method, + ReflectionKind.Reference, // others are never added to groups ]; diff --git a/src/lib/utils/options/defaults.ts b/src/lib/utils/options/defaults.ts index 7a63adceb..f037e4119 100644 --- a/src/lib/utils/options/defaults.ts +++ b/src/lib/utils/options/defaults.ts @@ -67,10 +67,9 @@ export const OptionDefaults: { "tsx", "typescript", ], - sort: ["kind", "instance-first", "alphabetical"], + sort: ["kind", "instance-first", "alphabetical-ignoring-documents"], kindSortOrder: [ "Document", - "Reference", "Project", "Module", "Namespace", @@ -87,14 +86,7 @@ export const OptionDefaults: { "Accessor", "Method", - "Parameter", - "TypeParameter", - "TypeLiteral", - "CallSignature", - "ConstructorSignature", - "IndexSignature", - "GetSignature", - "SetSignature", + "Reference", ], requiredToBeDocumented: [ "Enum", From b51d60a82ec7c9cd170be17dd17fca1bb08f1809 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 18 Aug 2024 16:55:40 -0600 Subject: [PATCH 030/219] Fix failing tests --- src/test/converter/exports/specs.json | 458 ++++++++++---------- src/test/converter/exports/specs.nodoc.json | 110 ++--- src/test/issues.c2.test.ts | 6 +- src/test/utils/sort.test.ts | 40 +- 4 files changed, 301 insertions(+), 313 deletions(-) diff --git a/src/test/converter/exports/specs.json b/src/test/converter/exports/specs.json index e888ba424..b856ad858 100644 --- a/src/test/converter/exports/specs.json +++ b/src/test/converter/exports/specs.json @@ -12,150 +12,6 @@ "kind": 2, "flags": {}, "children": [ - { - "id": 48, - "name": "GH1453Helper", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "mod.ts", - "line": 42, - "character": 12, - "url": "typedoc://mod.ts#L42" - } - ], - "target": 35 - }, - { - "id": 41, - "name": "Mod", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "export.ts", - "line": 5, - "character": 22, - "url": "typedoc://export.ts#L5" - } - ], - "target": 29 - }, - { - "id": 43, - "name": "Mod2", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "This is a comment for Mod that overwrites the one specified in \"mod\"" - } - ] - }, - "sources": [ - { - "fileName": "export.ts", - "line": 14, - "character": 12, - "url": "typedoc://export.ts#L14" - } - ], - "target": 29 - }, - { - "id": 42, - "name": "ModDefault", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "export.ts", - "line": 5, - "character": 27, - "url": "typedoc://export.ts#L5" - } - ], - "target": 36 - }, - { - "id": 47, - "name": "ThisModule", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "mod.ts", - "line": 40, - "character": 12, - "url": "typedoc://mod.ts#L40" - } - ], - "target": 34 - }, - { - "id": 44, - "name": "a", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "mod.ts", - "line": 8, - "character": 13, - "url": "typedoc://mod.ts#L8" - } - ], - "target": 30 - }, - { - "id": 45, - "name": "b", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "An export of a local under a different name." - } - ] - }, - "sources": [ - { - "fileName": "mod.ts", - "line": 13, - "character": 14, - "url": "typedoc://mod.ts#L13" - } - ], - "target": 31 - }, - { - "id": 40, - "name": "c", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "export.ts", - "line": 5, - "character": 14, - "url": "typedoc://export.ts#L5" - } - ], - "target": 30 - }, { "id": 20, "name": "GH1453", @@ -413,22 +269,153 @@ } } ] + }, + { + "id": 48, + "name": "GH1453Helper", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "mod.ts", + "line": 42, + "character": 12, + "url": "typedoc://mod.ts#L42" + } + ], + "target": 35 + }, + { + "id": 41, + "name": "Mod", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "export.ts", + "line": 5, + "character": 22, + "url": "typedoc://export.ts#L5" + } + ], + "target": 29 + }, + { + "id": 43, + "name": "Mod2", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "This is a comment for Mod that overwrites the one specified in \"mod\"" + } + ] + }, + "sources": [ + { + "fileName": "export.ts", + "line": 14, + "character": 12, + "url": "typedoc://export.ts#L14" + } + ], + "target": 29 + }, + { + "id": 42, + "name": "ModDefault", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "export.ts", + "line": 5, + "character": 27, + "url": "typedoc://export.ts#L5" + } + ], + "target": 36 + }, + { + "id": 47, + "name": "ThisModule", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "mod.ts", + "line": 40, + "character": 12, + "url": "typedoc://mod.ts#L40" + } + ], + "target": 34 + }, + { + "id": 44, + "name": "a", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "mod.ts", + "line": 8, + "character": 13, + "url": "typedoc://mod.ts#L8" + } + ], + "target": 30 + }, + { + "id": 45, + "name": "b", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "An export of a local under a different name." + } + ] + }, + "sources": [ + { + "fileName": "mod.ts", + "line": 13, + "character": 14, + "url": "typedoc://mod.ts#L13" + } + ], + "target": 31 + }, + { + "id": 40, + "name": "c", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "export.ts", + "line": 5, + "character": 14, + "url": "typedoc://export.ts#L5" + } + ], + "target": 30 } ], "groups": [ - { - "title": "References", - "children": [ - 48, - 41, - 43, - 42, - 47, - 44, - 45, - 40 - ] - }, { "title": "Namespaces", "children": [ @@ -441,6 +428,19 @@ 15, 26 ] + }, + { + "title": "References", + "children": [ + 48, + 41, + 43, + 42, + 47, + 44, + 45, + 40 + ] } ], "sources": [ @@ -704,70 +704,6 @@ "kind": 2, "flags": {}, "children": [ - { - "id": 34, - "name": "ThisModule", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "sources": [ - { - "fileName": "mod.ts", - "line": 40, - "character": 12, - "url": "typedoc://mod.ts#L40" - } - ], - "target": 29 - }, - { - "id": 31, - "name": "b", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "An export of a local under a different name." - } - ] - }, - "sources": [ - { - "fileName": "mod.ts", - "line": 13, - "character": 14, - "url": "typedoc://mod.ts#L13" - } - ], - "target": 30 - }, - { - "id": 32, - "name": "c", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "An export with a module specifier that comes from this file." - } - ] - }, - "sources": [ - { - "fileName": "mod.ts", - "line": 18, - "character": 14, - "url": "typedoc://mod.ts#L18" - } - ], - "target": 30 - }, { "id": 35, "name": "GH1453Helper", @@ -860,17 +796,73 @@ } } ] + }, + { + "id": 34, + "name": "ThisModule", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "sources": [ + { + "fileName": "mod.ts", + "line": 40, + "character": 12, + "url": "typedoc://mod.ts#L40" + } + ], + "target": 29 + }, + { + "id": 31, + "name": "b", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "An export of a local under a different name." + } + ] + }, + "sources": [ + { + "fileName": "mod.ts", + "line": 13, + "character": 14, + "url": "typedoc://mod.ts#L13" + } + ], + "target": 30 + }, + { + "id": 32, + "name": "c", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "An export with a module specifier that comes from this file." + } + ] + }, + "sources": [ + { + "fileName": "mod.ts", + "line": 18, + "character": 14, + "url": "typedoc://mod.ts#L18" + } + ], + "target": 30 } ], "groups": [ - { - "title": "References", - "children": [ - 34, - 31, - 32 - ] - }, { "title": "Type Aliases", "children": [ @@ -888,6 +880,14 @@ "children": [ 36 ] + }, + { + "title": "References", + "children": [ + 34, + 31, + 32 + ] } ], "sources": [ diff --git a/src/test/converter/exports/specs.nodoc.json b/src/test/converter/exports/specs.nodoc.json index efa9f878e..e28b359db 100644 --- a/src/test/converter/exports/specs.nodoc.json +++ b/src/test/converter/exports/specs.nodoc.json @@ -86,54 +86,6 @@ "kind": 2, "flags": {}, "children": [ - { - "id": 31, - "name": "b", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "An export of a local under a different name." - } - ] - }, - "sources": [ - { - "fileName": "mod.ts", - "line": 13, - "character": 14, - "url": "typedoc://mod.ts#L13" - } - ], - "target": 30 - }, - { - "id": 32, - "name": "c", - "variant": "reference", - "kind": 4194304, - "flags": {}, - "comment": { - "summary": [ - { - "kind": "text", - "text": "An export with a module specifier that comes from this file." - } - ] - }, - "sources": [ - { - "fileName": "mod.ts", - "line": 18, - "character": 14, - "url": "typedoc://mod.ts#L18" - } - ], - "target": 30 - }, { "id": 30, "name": "a", @@ -207,16 +159,57 @@ } } ] + }, + { + "id": 31, + "name": "b", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "An export of a local under a different name." + } + ] + }, + "sources": [ + { + "fileName": "mod.ts", + "line": 13, + "character": 14, + "url": "typedoc://mod.ts#L13" + } + ], + "target": 30 + }, + { + "id": 32, + "name": "c", + "variant": "reference", + "kind": 4194304, + "flags": {}, + "comment": { + "summary": [ + { + "kind": "text", + "text": "An export with a module specifier that comes from this file." + } + ] + }, + "sources": [ + { + "fileName": "mod.ts", + "line": 18, + "character": 14, + "url": "typedoc://mod.ts#L18" + } + ], + "target": 30 } ], "groups": [ - { - "title": "References", - "children": [ - 31, - 32 - ] - }, { "title": "Variables", "children": [ @@ -228,6 +221,13 @@ "children": [ 36 ] + }, + { + "title": "References", + "children": [ + 31, + 32 + ] } ], "sources": [ diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 4634a80b6..d07a6cca9 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -510,10 +510,10 @@ describe("Issue Tests", () => { const project = convert(); equal( project.children?.map((c) => c.name), - ["default", "foo"], + ["foo", "default"], ); - ok(project.children[0].kind === ReflectionKind.Reference); - ok(project.children[1].kind !== ReflectionKind.Reference); + ok(project.children[0].kind !== ReflectionKind.Reference); + ok(project.children[1].kind === ReflectionKind.Reference); }); it("#1804", () => { diff --git a/src/test/utils/sort.test.ts b/src/test/utils/sort.test.ts index b354d7c26..535b5df9f 100644 --- a/src/test/utils/sort.test.ts +++ b/src/test/utils/sort.test.ts @@ -177,32 +177,20 @@ describe("Sort", () => { it("Should sort by kind", () => { const arr = [ - new DeclarationReflection("1", ReflectionKind.Reference), - new DeclarationReflection("23", ReflectionKind.SetSignature), - new DeclarationReflection("3", ReflectionKind.Module), - new DeclarationReflection("4", ReflectionKind.Namespace), - new DeclarationReflection("5", ReflectionKind.Enum), - new DeclarationReflection("6", ReflectionKind.EnumMember), - new DeclarationReflection("15", ReflectionKind.Method), - new DeclarationReflection("8", ReflectionKind.Interface), - new DeclarationReflection("9", ReflectionKind.TypeAlias), - new DeclarationReflection("10", ReflectionKind.Constructor), - new DeclarationReflection("2", ReflectionKind.Project), - new DeclarationReflection("22", ReflectionKind.GetSignature), - new DeclarationReflection("12", ReflectionKind.Variable), - new DeclarationReflection("13", ReflectionKind.Function), - new DeclarationReflection("14", ReflectionKind.Accessor), - new DeclarationReflection("11", ReflectionKind.Property), - new DeclarationReflection("18", ReflectionKind.TypeLiteral), - new DeclarationReflection("16", ReflectionKind.Parameter), - new DeclarationReflection("17", ReflectionKind.TypeParameter), - new DeclarationReflection("19", ReflectionKind.CallSignature), - new DeclarationReflection("7", ReflectionKind.Class), - new DeclarationReflection( - "20", - ReflectionKind.ConstructorSignature, - ), - new DeclarationReflection("21", ReflectionKind.IndexSignature), + new DeclarationReflection("14", ReflectionKind.Reference), + new DeclarationReflection("2", ReflectionKind.Module), + new DeclarationReflection("3", ReflectionKind.Namespace), + new DeclarationReflection("4", ReflectionKind.Enum), + new DeclarationReflection("5", ReflectionKind.EnumMember), + new DeclarationReflection("7", ReflectionKind.Interface), + new DeclarationReflection("8", ReflectionKind.TypeAlias), + new DeclarationReflection("9", ReflectionKind.Constructor), + new DeclarationReflection("1", ReflectionKind.Project), + new DeclarationReflection("11", ReflectionKind.Variable), + new DeclarationReflection("12", ReflectionKind.Function), + new DeclarationReflection("13", ReflectionKind.Accessor), + new DeclarationReflection("10", ReflectionKind.Property), + new DeclarationReflection("6", ReflectionKind.Class), ]; sortReflections(arr, ["kind"]); From 1861f10fb1ba0a719406ac91e13676c8f8c8050a Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 18 Aug 2024 16:56:17 -0600 Subject: [PATCH 031/219] Merge branch master into beta --- .config/typedoc.json | 2 + CHANGELOG.md | 15 ++ eslint.config.mjs | 4 + package-lock.json | 134 +++++++++--------- package.json | 6 +- src/lib/application.ts | 5 +- src/lib/converter/comments/parser.ts | 3 +- src/lib/internationalization/translatable.ts | 10 +- src/lib/models/FileRegistry.ts | 6 +- src/lib/models/reflections/project.ts | 20 ++- .../output/plugins/JavascriptIndexPlugin.ts | 6 +- .../output/themes/default/DefaultTheme.tsx | 50 ++++--- .../default/assets/typedoc/Navigation.ts | 2 +- src/lib/serialization/components.ts | 2 +- src/lib/serialization/deserializer.ts | 1 - src/lib/serialization/serializer.ts | 11 +- src/lib/utils/enum.ts | 6 +- src/lib/utils/events.ts | 2 +- src/lib/utils/fs.ts | 4 + src/lib/utils/hooks.ts | 6 +- src/lib/utils/options/declaration.ts | 3 +- src/lib/utils/options/sources/typedoc.ts | 1 + src/lib/utils/options/tsdoc-defaults.ts | 3 + src/lib/utils/perf.ts | 11 +- src/test/models/reflections.test.ts | 9 ++ src/test/utils/fs.test.ts | 4 +- src/test/utils/sort.test.ts | 3 +- tsdoc.json | 12 ++ 28 files changed, 215 insertions(+), 126 deletions(-) create mode 100644 src/test/models/reflections.test.ts diff --git a/.config/typedoc.json b/.config/typedoc.json index eaef91b37..7aec0985f 100644 --- a/.config/typedoc.json +++ b/.config/typedoc.json @@ -37,6 +37,8 @@ "Enumerations": 2.0, "Type Aliases": 2.0 }, + "searchInComments": true, + "searchInDocuments": true, "navigation": { "includeCategories": true, "includeGroups": false diff --git a/CHANGELOG.md b/CHANGELOG.md index 412f61131..aec25505d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,21 @@ TODO: # Unreleased +## v0.26.6 (2024-08-18) + +### Features + +- Use of the `@extends` block tag no longer produces warnings, #2659. + This tag should only be used in JavaScript projects to specify the type parameters used when extending a parent class. It will not be rendered. +- Added new `navigation.compactFolders` option to prevent TypeDoc from compacting folders, similar to the VSCode option. #2667. + +### Bug Fixes + +- The `suppressCommentWarningsInDeclarationFiles` option now correctly ignores warnings in `.d.cts` and `.d.mts` files, #2647. +- Restored re-exports in the page navigation menu, #2671. +- JSON serialized projects will no longer contain reflection IDs for other projects created in the same run. Gerrit0/typedoc-plugin-zod#6. +- In packages mode the reflection ID counter will no longer be reset when converting projects. This previously could result in links to files not working as expected. + ## v0.26.5 (2024-07-21) ### Features diff --git a/eslint.config.mjs b/eslint.config.mjs index ed0341e0d..5221a9034 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -30,6 +30,9 @@ const config = { }, ], + // This can probably be turned back on in 0.27, when the component hierarchy goes away + "@typescript-eslint/no-unsafe-function-type": "off", + // This one is just annoying since it complains at incomplete code "no-empty": "off", @@ -58,6 +61,7 @@ const config = { "@typescript-eslint/no-unsafe-return": "off", "@typescript-eslint/no-unsafe-member-access": "off", "@typescript-eslint/no-unsafe-call": "off", + "@typescript-eslint/no-empty-object-type": "off", // Really annoying, doesn't provide any value. "@typescript-eslint/no-empty-function": "off", diff --git a/package-lock.json b/package-lock.json index 32e1c36f8..27ec2300f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typedoc", - "version": "0.26.5", + "version": "0.26.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typedoc", - "version": "0.26.5", + "version": "0.26.6", "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", @@ -32,7 +32,7 @@ "puppeteer": "^22.12.1", "tsx": "^4.15.7", "typescript": "5.5.2", - "typescript-eslint": "^7.14.1" + "typescript-eslint": "^8.0.1" }, "engines": { "node": ">= 18" @@ -999,32 +999,32 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", - "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", + "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/type-utils": "7.14.1", - "@typescript-eslint/utils": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/type-utils": "8.0.1", + "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1033,27 +1033,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", + "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1062,17 +1062,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", + "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1080,27 +1080,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", - "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", + "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/utils": "8.0.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1108,13 +1105,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", + "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1122,14 +1119,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", + "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1138,7 +1135,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1151,40 +1148,40 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", + "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", + "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -4059,26 +4056,23 @@ } }, "node_modules/typescript-eslint": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.14.1.tgz", - "integrity": "sha512-Eo1X+Y0JgGPspcANKjeR6nIqXl4VL5ldXLc15k4m9upq+eY5fhU2IueiEZL6jmHrKH8aCfbIvM/v3IrX5Hg99w==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.0.1.tgz", + "integrity": "sha512-V3Y+MdfhawxEjE16dWpb7/IOgeXnLwAEEkS7v8oDqNcR1oYlqWhGH/iHqHdKVdpWme1VPZ0SoywXAkCqawj2eQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.14.1", - "@typescript-eslint/parser": "7.14.1", - "@typescript-eslint/utils": "7.14.1" + "@typescript-eslint/eslint-plugin": "8.0.1", + "@typescript-eslint/parser": "8.0.1", + "@typescript-eslint/utils": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true diff --git a/package.json b/package.json index 989c2dfd8..4447aadc3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typedoc", "description": "Create api documentation for TypeScript projects.", - "version": "0.26.5", + "version": "0.26.6", "homepage": "https://typedoc.org", "type": "module", "exports": { @@ -47,8 +47,8 @@ "prettier": "3.3.2", "puppeteer": "^22.12.1", "tsx": "^4.15.7", - "typescript-eslint": "^7.14.1", - "typescript": "5.5.2" + "typescript": "5.5.2", + "typescript-eslint": "^8.0.1" }, "files": [ "/bin", diff --git a/src/lib/application.ts b/src/lib/application.ts index 29ca06868..b3350aec0 100644 --- a/src/lib/application.ts +++ b/src/lib/application.ts @@ -40,7 +40,6 @@ import { validateLinks } from "./validation/links.js"; import { ApplicationEvents } from "./application-events.js"; import { findTsConfigFile } from "./utils/tsconfig.js"; import { deriveRootDir, glob, readFile } from "./utils/fs.js"; -import { resetReflectionID } from "./models/reflections/abstract.js"; import { addInferredDeclarationMapPaths } from "./models/reflections/ReflectionSymbolId.js"; import { Internationalization, @@ -712,13 +711,13 @@ export class Application extends AbstractComponent< } // When debugging memory issues, it's useful to set these - // here so that a breakpoint on resetReflectionID below + // here so that a breakpoint on the continue statement below // gets the memory as it ought to be with all TS objects released. project = undefined; this.files = undefined!; // global.gc!(); - resetReflectionID(); + continue; } this.options = origOptions; diff --git a/src/lib/converter/comments/parser.ts b/src/lib/converter/comments/parser.ts index c3f935c37..1a1df1fd0 100644 --- a/src/lib/converter/comments/parser.ts +++ b/src/lib/converter/comments/parser.ts @@ -18,6 +18,7 @@ import type { } from "../../internationalization/internationalization.js"; import { FileRegistry } from "../../models/FileRegistry.js"; import { textContent, TextParserReentryState } from "./textParser.js"; +import { hasDeclarationFileExtension } from "../../utils/fs.js"; interface LookaheadGenerator { done(): boolean; @@ -111,7 +112,7 @@ export function parseComment( function warningImpl(message: TranslatedString, token: Token) { if ( config.suppressCommentWarningsInDeclarationFiles && - file.fileName.endsWith(".d.ts") + hasDeclarationFileExtension(file.fileName) ) { return; } diff --git a/src/lib/internationalization/translatable.ts b/src/lib/internationalization/translatable.ts index b7725937e..843c7d65f 100644 --- a/src/lib/internationalization/translatable.ts +++ b/src/lib/internationalization/translatable.ts @@ -51,20 +51,18 @@ type TranslationConstraint = [ // Compiler errors here which says a property is missing indicates that the value on translatable // is not a literal string. It should be so that TypeDoc's placeholder replacement detection // can validate that all placeholders have been specified. -const _validateLiteralStrings: { +({}) satisfies { [K in keyof typeof translatable as string extends (typeof translatable)[K] ? K : never]: never; -} = {}; -_validateLiteralStrings; +}; // Compiler errors here which says a property is missing indicates that the key on translatable // contains a placeholder _0/_1, etc. but the value does not match the expected constraint. -const _validatePlaceholdersPresent: { +translatable satisfies { [K in keyof typeof translatable]: K extends `${string}_1${string}` ? TranslationConstraint[2] : K extends `${string}_0${string}` ? TranslationConstraint[1] : TranslationConstraint[0]; -} = translatable; -_validatePlaceholdersPresent; +}; diff --git a/src/lib/models/FileRegistry.ts b/src/lib/models/FileRegistry.ts index 15c155b45..79cf892bf 100644 --- a/src/lib/models/FileRegistry.ts +++ b/src/lib/models/FileRegistry.ts @@ -101,7 +101,11 @@ export class FileRegistry { result.entries[key] = normalizePath(relative(ser.projectRoot, val)); } for (const [key, val] of this.mediaToReflection.entries()) { - result.reflections[key] = val.id; + // A registry may be shared by multiple projects. When serializing, + // only save reflection mapping for reflections in the serialized project. + if (ser.project.getReflectionById(val.id)) { + result.reflections[key] = val.id; + } } return result; diff --git a/src/lib/models/reflections/project.ts b/src/lib/models/reflections/project.ts index b2106dd37..d9ac4a3a5 100644 --- a/src/lib/models/reflections/project.ts +++ b/src/lib/models/reflections/project.ts @@ -5,7 +5,7 @@ import { ReferenceReflection } from "./reference.js"; import type { DeclarationReflection } from "./declaration.js"; import type { SignatureReflection } from "./signature.js"; import type { ParameterReflection } from "./parameter.js"; -import { IntrinsicType } from "../types.js"; +import { IntrinsicType, makeRecursiveVisitor, type Type } from "../types.js"; import type { TypeParameterReflection } from "./type-parameter.js"; import { assertNever, removeIf, removeIfPresent } from "../../utils/index.js"; import { ReflectionKind } from "./kind.js"; @@ -49,7 +49,7 @@ export class ProjectReflection extends ContainerReflection { * * This may be replaced with a `Map` someday. */ - reflections: { [id: number]: Reflection } = {}; + reflections: { [id: number]: Reflection } = { [this.id]: this }; /** * The name of the package that this reflection documents according to package.json. @@ -153,6 +153,22 @@ export class ProjectReflection extends ContainerReflection { } } + /** + * Removes references to reflections contained within the provided type. + * Plugins which overwrite types on reflections should pass the type to this + * method before overwriting the property. + * @since 0.26.6 + */ + removeTypeReflections(type: Type | undefined) { + type?.visit( + makeRecursiveVisitor({ + reflection: (type) => { + this.removeReflection(type.declaration); + }, + }), + ); + } + /** * Removes a reflection from the documentation. Can be used by plugins to filter reflections * out of the generated documentation. Has no effect if the reflection is not present in the diff --git a/src/lib/output/plugins/JavascriptIndexPlugin.ts b/src/lib/output/plugins/JavascriptIndexPlugin.ts index f81a48efc..5c9ebf25a 100644 --- a/src/lib/output/plugins/JavascriptIndexPlugin.ts +++ b/src/lib/output/plugins/JavascriptIndexPlugin.ts @@ -155,10 +155,12 @@ export class JavascriptIndexPlugin extends RendererComponent { reflection.signatures?.forEach( (s) => s.comment && comments.push(s.comment), ); - reflection.getSignature?.comment && + if (reflection.getSignature?.comment) { comments.push(reflection.getSignature.comment); - reflection.setSignature?.comment && + } + if (reflection.setSignature?.comment) { comments.push(reflection.setSignature.comment); + } } if (!comments.length) { diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index 3cda9e2be..854b2b459 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -332,10 +332,6 @@ export class DefaultTheme extends Theme { }; } - if (!element.hasOwnDocument) { - return; - } - return { text: getDisplayName(element), path: element.url, @@ -383,11 +379,11 @@ export class DefaultTheme extends Theme { } if (parent.categories && shouldShowCategories(parent, opts)) { - return filterMap(parent.categories, toNavigation); + return filterMapWithNoneCollection(parent.categories); } if (parent.groups && shouldShowGroups(parent, opts)) { - return filterMap(parent.groups, toNavigation); + return filterMapWithNoneCollection(parent.groups); } if (opts.includeFolders && parent.childrenIncludingDocuments?.some((child) => child.name.includes("/"))) { @@ -397,6 +393,20 @@ export class DefaultTheme extends Theme { return filterMap(parent.childrenIncludingDocuments, toNavigation); } + function filterMapWithNoneCollection(reflection: ReflectionGroup[] | ReflectionCategory[]) { + const none = reflection.find((x) => x.title.toLocaleLowerCase() === "none"); + const others = reflection.filter((x) => x.title.toLocaleLowerCase() !== "none"); + + const mappedOthers = filterMap(others, toNavigation); + + if (none) { + const noneMappedChildren = filterMap(none.children, toNavigation); + return [...noneMappedChildren, ...mappedOthers]; + } + + return mappedOthers; + } + function deriveModuleFolders(children: Array) { const result: NavigationElement[] = []; @@ -435,19 +445,21 @@ export class DefaultTheme extends Theme { // Now merge single-possible-paths together so we don't have folders in our navigation // which contain only another single folder. - const queue = [...result]; - while (queue.length) { - const review = queue.shift()!; - queue.push(...(review.children || [])); - if (review.kind || review.path) continue; - - if (review.children?.length === 1) { - const copyFrom = review.children[0]; - const fullName = `${review.text}/${copyFrom.text}`; - delete review.children; - Object.assign(review, copyFrom); - review.text = fullName; - queue.push(review); + if (opts.compactFolders) { + const queue = [...result]; + while (queue.length) { + const review = queue.shift()!; + queue.push(...(review.children || [])); + if (review.kind || review.path) continue; + + if (review.children?.length === 1) { + const copyFrom = review.children[0]; + const fullName = `${review.text}/${copyFrom.text}`; + delete review.children; + Object.assign(review, copyFrom); + review.text = fullName; + queue.push(review); + } } } diff --git a/src/lib/output/themes/default/assets/typedoc/Navigation.ts b/src/lib/output/themes/default/assets/typedoc/Navigation.ts index 0bd320e9b..5c6a4f682 100644 --- a/src/lib/output/themes/default/assets/typedoc/Navigation.ts +++ b/src/lib/output/themes/default/assets/typedoc/Navigation.ts @@ -95,7 +95,7 @@ function addNavText( if (classes) { a.className = classes; } - if (location.pathname === a.pathname) { + if (location.pathname === a.pathname && !a.href.includes("#")) { a.classList.add("current"); } if (el.kind) { diff --git a/src/lib/serialization/components.ts b/src/lib/serialization/components.ts index d9afdfe3c..4f1f515f3 100644 --- a/src/lib/serialization/components.ts +++ b/src/lib/serialization/components.ts @@ -7,7 +7,7 @@ import type { ModelToObject } from "./schema.js"; * Like {@link Converter} plugins each {@link Serializer} plugin defines a predicate that instructs if an * object can be serialized by it. This is done dynamically at runtime via a `supports` method. */ -export interface SerializerComponent { +export interface SerializerComponent { /** * The priority this serializer should be executed with. * A higher priority means the {@link Serializer} will be applied earlier. diff --git a/src/lib/serialization/deserializer.ts b/src/lib/serialization/deserializer.ts index 216a03bc9..455b67514 100644 --- a/src/lib/serialization/deserializer.ts +++ b/src/lib/serialization/deserializer.ts @@ -240,7 +240,6 @@ export class Deserializer { name || projectObj.name, registry, ); - project.registerReflection(project, undefined, undefined); this.project = project; this.projectRoot = projectRoot; this.oldIdToNewId = { [projectObj.id]: project.id }; diff --git a/src/lib/serialization/serializer.ts b/src/lib/serialization/serializer.ts index a3c3b904e..f458826e1 100644 --- a/src/lib/serialization/serializer.ts +++ b/src/lib/serialization/serializer.ts @@ -31,7 +31,12 @@ export class Serializer extends EventDispatcher { */ projectRoot!: string; - addSerializer(serializer: SerializerComponent): void { + /** + * Only set when serializing + */ + project!: ProjectReflection; + + addSerializer(serializer: SerializerComponent): void { insertPrioritySorted(this.serializers, serializer); } @@ -75,6 +80,7 @@ export class Serializer extends EventDispatcher { projectRoot: string, ): ModelToObject { this.projectRoot = projectRoot; + this.project = value; const eventBegin = new SerializeEvent(value); this.trigger(Serializer.EVENT_BEGIN, eventBegin); @@ -84,6 +90,9 @@ export class Serializer extends EventDispatcher { const eventEnd = new SerializeEvent(value, project); this.trigger(Serializer.EVENT_END, eventEnd); + this.project = undefined!; + this.projectRoot = undefined!; + return project; } } diff --git a/src/lib/utils/enum.ts b/src/lib/utils/enum.ts index 798dffab5..f21eab162 100644 --- a/src/lib/utils/enum.ts +++ b/src/lib/utils/enum.ts @@ -22,18 +22,18 @@ export function hasAnyFlag(flags: number, check: number): boolean { return (flags & check) !== 0; } -export function debugFlags(Enum: {}, flags: number): string[] { +export function debugFlags(Enum: object, flags: number): string[] { return getEnumKeys(Enum).filter( (key) => ((Enum as any)[key] & flags) === (Enum as any)[key], ); } // Note: String enums are not handled. -export function getEnumKeys(Enum: {}): string[] { +export function getEnumKeys(Enum: object): string[] { const E = Enum as any; return Object.keys(E).filter((k) => E[E[k]] === k); } -export type EnumKeys = { +export type EnumKeys = { [K in keyof E]: number extends E[K] ? K : never; }[keyof E] & {}; diff --git a/src/lib/utils/events.ts b/src/lib/utils/events.ts index 0303b6db6..697d97d21 100644 --- a/src/lib/utils/events.ts +++ b/src/lib/utils/events.ts @@ -12,7 +12,7 @@ export class EventDispatcher> { private _listeners = new Map< keyof T, { - listener: Function; + listener: (..._: any) => any; priority: number; }[] >(); diff --git a/src/lib/utils/fs.ts b/src/lib/utils/fs.ts index a48c32de4..f529920c0 100644 --- a/src/lib/utils/fs.ts +++ b/src/lib/utils/fs.ts @@ -271,6 +271,10 @@ export function hasTsExtension(path: string): boolean { return /\.[cm]?ts$|\.tsx$/.test(path); } +export function hasDeclarationFileExtension(path: string) { + return /\.d\.[cm]?ts$/.test(path); +} + export function discoverInParentDir( name: string, dir: string, diff --git a/src/lib/utils/hooks.ts b/src/lib/utils/hooks.ts index 534f7e92a..12af6b145 100644 --- a/src/lib/utils/hooks.ts +++ b/src/lib/utils/hooks.ts @@ -2,7 +2,7 @@ import { insertOrderSorted } from "./array.js"; const momentos = new WeakMap< EventHooksMomento, - Map + Map any; once?: boolean; order: number }[]> >(); type EventHooksMomento, _R> = { @@ -30,7 +30,7 @@ export class EventHooks, R> { // contracts in the methods while not casting everywhere this is used. private _listeners = new Map< keyof T, - { listener: Function; once?: boolean; order: number }[] + { listener: (..._: any) => any; once?: boolean; order: number }[] >(); /** @@ -98,7 +98,7 @@ export class EventHooks, R> { const momento = {} as EventHooksMomento; const save = new Map< keyof T, - { listener: Function; once?: boolean; order: number }[] + { listener: (..._: any) => any; once?: boolean; order: number }[] >(); for (const [key, val] of this._listeners) { diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index d51516dd4..deb4c8ebb 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -179,6 +179,7 @@ export interface TypeDocOptionMap { includeCategories: boolean; includeGroups: boolean; includeFolders: boolean; + compactFolders: boolean; }; visibilityFilters: ManuallyValidatedOption<{ protected?: boolean; @@ -653,7 +654,7 @@ const converters: { [ParameterType.Object](value, option, i18n, _configPath, oldValue) { option.validate?.(value, i18n); if (typeof oldValue !== "undefined") - value = { ...(oldValue as {}), ...(value as {}) }; + value = { ...(oldValue as object), ...(value as object) }; return value; }, [ParameterType.Flags](value, option, i18n) { diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index 69bd9352a..6db043bb7 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -542,6 +542,7 @@ export function addTypeDocOptions(options: Pick) { includeCategories: false, includeGroups: false, includeFolders: true, + compactFolders: true, }, }); diff --git a/src/lib/utils/options/tsdoc-defaults.ts b/src/lib/utils/options/tsdoc-defaults.ts index 16bedc0c8..1b7b42bda 100644 --- a/src/lib/utils/options/tsdoc-defaults.ts +++ b/src/lib/utils/options/tsdoc-defaults.ts @@ -21,6 +21,9 @@ export const blockTags = [ "@categoryDescription", "@default", "@document", + "@extends", + "@augments", //Alias for @extends + "@yields", "@group", "@groupDescription", "@import", diff --git a/src/lib/utils/perf.ts b/src/lib/utils/perf.ts index 1950feaf3..de6cc92f7 100644 --- a/src/lib/utils/perf.ts +++ b/src/lib/utils/perf.ts @@ -4,7 +4,10 @@ import { performance } from "perf_hooks"; const benchmarks: { name: string; calls: number; time: number }[] = []; -export function bench(fn: T, name: string = fn.name): T { +export function bench any>( + fn: T, + name: string = fn.name, +): T { const matching = benchmarks.find((b) => b.name === name); const timer = matching || { name, @@ -43,10 +46,10 @@ export function bench(fn: T, name: string = fn.name): T { } as any; } -export function Bench( +export function Bench any>( value: T, context: ClassMethodDecoratorContext, -) { +): T { let runner: T | undefined; return function (this: any, ...args: any) { if (!runner) { @@ -56,7 +59,7 @@ export function Bench( runner = bench(value, `${className}.${String(context.name)}`); } return runner.apply(this, args); - }; + } as any; } export function measure(cb: () => T): T { diff --git a/src/test/models/reflections.test.ts b/src/test/models/reflections.test.ts new file mode 100644 index 000000000..0d8542139 --- /dev/null +++ b/src/test/models/reflections.test.ts @@ -0,0 +1,9 @@ +import { ok } from "assert"; +import { FileRegistry, ProjectReflection } from "../../lib/models/index.js"; + +describe("ProjectReflection", () => { + it("getReflectionById works with the project ID", () => { + const project = new ProjectReflection("", new FileRegistry()); + ok(project === project.getReflectionById(project.id)); + }); +}); diff --git a/src/test/utils/fs.test.ts b/src/test/utils/fs.test.ts index 462466793..a316f983d 100644 --- a/src/test/utils/fs.test.ts +++ b/src/test/utils/fs.test.ts @@ -120,7 +120,7 @@ describe("fs.ts", () => { describe("when node_modules is present in the pattern", function () { it("should traverse node_modules", function () { - fix.dir("node_modules").addFile("test.ts").path; + fix.dir("node_modules").addFile("test.ts"); fix.write(); equal( glob(`${fix.cwd}/node_modules/test.ts`, fix.cwd).map((f) => @@ -133,7 +133,7 @@ describe("fs.ts", () => { describe("when node_modules is not present in the pattern", function () { it("should not traverse node_modules", function () { - fix.dir("node_modules").addFile("test.ts").path; + fix.dir("node_modules").addFile("test.ts"); fix.write(); equal( glob(`${fix.cwd}/**/test.ts`, fix.cwd).map((f) => diff --git a/src/test/utils/sort.test.ts b/src/test/utils/sort.test.ts index 535b5df9f..45682f0da 100644 --- a/src/test/utils/sort.test.ts +++ b/src/test/utils/sort.test.ts @@ -177,11 +177,12 @@ describe("Sort", () => { it("Should sort by kind", () => { const arr = [ - new DeclarationReflection("14", ReflectionKind.Reference), + new DeclarationReflection("15", ReflectionKind.Reference), new DeclarationReflection("2", ReflectionKind.Module), new DeclarationReflection("3", ReflectionKind.Namespace), new DeclarationReflection("4", ReflectionKind.Enum), new DeclarationReflection("5", ReflectionKind.EnumMember), + new DeclarationReflection("14", ReflectionKind.Method), new DeclarationReflection("7", ReflectionKind.Interface), new DeclarationReflection("8", ReflectionKind.TypeAlias), new DeclarationReflection("9", ReflectionKind.Constructor), diff --git a/tsdoc.json b/tsdoc.json index 62ab0dd50..e42de6ea0 100644 --- a/tsdoc.json +++ b/tsdoc.json @@ -75,11 +75,23 @@ "tagName": "@default", "syntaxKind": "block" }, + { + "tagName": "@extends", + "syntaxKind": "block" + }, + { + "tagName": "@augments", + "syntaxKind": "block" + }, { // TSDoc defines @returns, we also recognize @return for JSDoc compat "tagName": "@return", "syntaxKind": "block" }, + { + "tagName": "@yields", + "syntaxKind": "block" + }, { "tagName": "@enum", "syntaxKind": "modifier" From 89300613aa0783ebfa9daabf6ed4a2810646078d Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 18 Aug 2024 17:07:47 -0600 Subject: [PATCH 032/219] Fix lint issues --- .github/workflows/ci.yml | 2 +- eslint.config.mjs | 8 ++++++++ package.json | 2 +- src/lib/models/types.ts | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2bec1775c..ab820868b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Test run: npm run test:full - name: Lint - run: npm run lint -- --max-warnings 0 + run: npm run lint - name: Circular dependency check uses: gerrit0/circular-dependency-check@v2.0.2 with: diff --git a/eslint.config.mjs b/eslint.config.mjs index 5221a9034..db8c180a4 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -63,6 +63,14 @@ const config = { "@typescript-eslint/no-unsafe-call": "off", "@typescript-eslint/no-empty-object-type": "off", + // Needed for the locales today, don't want to make every contributor to those turn it off. + "@typescript-eslint/no-require-imports": [ + "error", + { + allow: ["/[^/]+\\.cjs"], + }, + ], + // Really annoying, doesn't provide any value. "@typescript-eslint/no-empty-function": "off", diff --git a/package.json b/package.json index 4447aadc3..ca11a20c7 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "build:themes": "node scripts/build_themes.js", "build:prod": "npm run build:prod:tsc && npm run build:themes", "build:prod:tsc": "tsc --project . --sourceMap false --declarationMap false", - "lint": "eslint . && npm run prettier -- --check .", + "lint": "eslint . --max-warnings 0 && npm run prettier -- --check .", "prettier": "prettier --config .config/.prettierrc.json --ignore-path .config/.prettierignore", "prepack": "node scripts/set_strict.js false && npm run build:prod", "prepare": "node scripts/prepare.mjs", diff --git a/src/lib/models/types.ts b/src/lib/models/types.ts index ced9f307e..ccfac8821 100644 --- a/src/lib/models/types.ts +++ b/src/lib/models/types.ts @@ -39,7 +39,7 @@ export abstract class Type { */ visit(visitor: TypeVisitor, ...args: A): T; visit( - visitor: Partial>, + visitor: Partial>, ...args: A ): T | undefined; visit( From e5638e19b89fcd4c2a076ddccfb5f3b2df46fb54 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 18 Aug 2024 17:09:54 -0600 Subject: [PATCH 033/219] Fix circular dependency --- src/lib/utils/options/sources/typedoc.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index 6db043bb7..5752339a2 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -1,8 +1,4 @@ -import { - OptionDefaults, - type Options, - type TypeDocOptionMap, -} from "../index.js"; +import { type Options, type TypeDocOptionMap } from "../index.js"; import { LogLevel } from "../../loggers.js"; import { ParameterType, @@ -10,6 +6,7 @@ import { EmitStrategy, CommentStyle, } from "../declaration.js"; +import { OptionDefaults } from "../defaults.js"; import { SORT_STRATEGIES } from "../../sort.js"; import { EntryPointStrategy } from "../../entry-point.js"; import { ReflectionKind } from "../../../models/reflections/kind.js"; From e3b176b23bb4d7148f689401a4f8bd4dad4b1e97 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 18 Aug 2024 17:28:01 -0600 Subject: [PATCH 034/219] Update TS to remove need for hack --- package-lock.json | 8 ++++---- package.json | 2 +- src/lib/internationalization/locales/jp.cts | 2 +- src/lib/output/themes/default/partials/anchor-icon.tsx | 2 -- src/lib/output/themes/default/partials/header.tsx | 2 -- src/lib/output/themes/default/partials/hierarchy.tsx | 2 -- .../output/themes/default/partials/member.declaration.tsx | 2 -- .../themes/default/partials/member.getterSetter.tsx | 2 -- .../output/themes/default/partials/member.reference.tsx | 2 -- .../output/themes/default/partials/member.signatures.tsx | 2 -- src/lib/output/themes/default/partials/members.tsx | 2 -- .../output/themes/default/partials/reflectionPreview.tsx | 2 -- src/lib/output/themes/default/partials/toolbar.tsx | 2 -- src/lib/output/themes/default/partials/typeParameters.tsx | 2 -- src/lib/output/themes/default/templates/hierarchy.tsx | 2 -- 15 files changed, 6 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27ec2300f..564291185 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "prettier": "3.3.2", "puppeteer": "^22.12.1", "tsx": "^4.15.7", - "typescript": "5.5.2", + "typescript": "5.5.4", "typescript-eslint": "^8.0.1" }, "engines": { @@ -4042,9 +4042,9 @@ } }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index ca11a20c7..faffd0ca1 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "prettier": "3.3.2", "puppeteer": "^22.12.1", "tsx": "^4.15.7", - "typescript": "5.5.2", + "typescript": "5.5.4", "typescript-eslint": "^8.0.1" }, "files": [ diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 8ad223cf4..1734bf469 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -99,7 +99,7 @@ export = localeUtils.buildIncompleteTranslation({ not_all_search_group_boosts_used_0: "searchGroupBoosts で指定されたすべてのグループがドキュメントで使用されているわけではありません。使用されていないグループは次のとおりです:\n{0}", comment_for_0_includes_categoryDescription_for_1_but_no_child_in_group: - "{0} のコメントに「{1}」の @categoryDe​​scription が含まれていますが、そのカテゴリに子が配置されていません", + "{0} のコメントに「{1}」の @categoryDescription が含まれていますが、そのカテゴリに子が配置されていません", comment_for_0_includes_groupDescription_for_1_but_no_child_in_group: '{0} のコメントに "{1}" の @groupDescription が含まれていますが、そのグループには子が配置されていません', label_0_for_1_cannot_be_referenced: diff --git a/src/lib/output/themes/default/partials/anchor-icon.tsx b/src/lib/output/themes/default/partials/anchor-icon.tsx index 384265db1..d6ff3fed0 100644 --- a/src/lib/output/themes/default/partials/anchor-icon.tsx +++ b/src/lib/output/themes/default/partials/anchor-icon.tsx @@ -1,8 +1,6 @@ import { JSX } from "../../../../utils/index.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -void JSX; // Trick TS into seeing this as used, the import is required. - export function anchorIcon(context: DefaultThemeRenderContext, anchor: string | undefined) { if (!anchor) return <>; diff --git a/src/lib/output/themes/default/partials/header.tsx b/src/lib/output/themes/default/partials/header.tsx index 8a4446d6e..a29cd86d7 100644 --- a/src/lib/output/themes/default/partials/header.tsx +++ b/src/lib/output/themes/default/partials/header.tsx @@ -4,8 +4,6 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import type { PageEvent } from "../../../events.js"; import { type Reflection, ReflectionKind } from "../../../../models/index.js"; -void JSX; // Trick TS into seeing this as used, the import is required. - export const header = (context: DefaultThemeRenderContext, props: PageEvent) => { const HeadingLevel = props.model.isProject() ? "h2" : "h1"; return ( diff --git a/src/lib/output/themes/default/partials/hierarchy.tsx b/src/lib/output/themes/default/partials/hierarchy.tsx index e21c6c4d9..16c6bda7f 100644 --- a/src/lib/output/themes/default/partials/hierarchy.tsx +++ b/src/lib/output/themes/default/partials/hierarchy.tsx @@ -2,8 +2,6 @@ import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js" import { JSX } from "../../../../utils/index.js"; import type { DeclarationHierarchy, Type } from "../../../../models/index.js"; -void JSX; // Trick TS into seeing this as used, the import is required. - const isLinkedReferenceType = (type: Type) => type.visit({ reference: (ref) => ref.reflection !== undefined, diff --git a/src/lib/output/themes/default/partials/member.declaration.tsx b/src/lib/output/themes/default/partials/member.declaration.tsx index 3b960ab4d..502fd406f 100644 --- a/src/lib/output/themes/default/partials/member.declaration.tsx +++ b/src/lib/output/themes/default/partials/member.declaration.tsx @@ -4,8 +4,6 @@ import { FormattedCodeBuilder, FormattedCodeGenerator, Wrap, type FormatterNode import { hasTypeParameters } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -void JSX; // TS is confused and thinks this is unused - export function memberDeclaration(context: DefaultThemeRenderContext, props: DeclarationReflection) { const builder = new FormattedCodeBuilder(context.urlTo); const content: FormatterNode[] = []; diff --git a/src/lib/output/themes/default/partials/member.getterSetter.tsx b/src/lib/output/themes/default/partials/member.getterSetter.tsx index d5c1abf6f..e4bfad1c2 100644 --- a/src/lib/output/themes/default/partials/member.getterSetter.tsx +++ b/src/lib/output/themes/default/partials/member.getterSetter.tsx @@ -3,8 +3,6 @@ import { JSX } from "../../../../utils/index.js"; import { classNames } from "../../lib.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; -void JSX; // Trick TS into seeing this as used, the import is required. - export const memberGetterSetter = (context: DefaultThemeRenderContext, props: DeclarationReflection) => ( <> ); @@ -241,8 +244,8 @@ function renderChild( {context.type(child.type)} {highlightOrComment(child)} - {child.children?.some(renderingChildIsUseful) && ( -
      {child.children.map((c) => renderChild(context, c))}
    + {child.getProperties().some(renderingChildIsUseful) && ( +
      {child.getProperties().map((c) => renderChild(context, c))}
    )}
  • ); @@ -312,19 +315,20 @@ function renderIndexSignature(context: DefaultThemeRenderContext, index: Signatu } function renderingChildIsUseful(refl: DeclarationReflection) { - if (refl.hasComment()) return true; - if ( - refl.children?.some((child) => { - if (child.hasComment()) return true; - if (child.type) { - return renderingTypeDetailsIsUseful(child.type); - } - }) - ) { + if (renderingThisChildIsUseful(refl)) { return true; } - return refl.getAllSignatures().some((sig) => { + return refl.getProperties().some(renderingThisChildIsUseful); +} + +function renderingThisChildIsUseful(refl: DeclarationReflection) { + if (refl.hasComment()) return true; + + const declaration = refl.type?.type === "reflection" ? refl.type.declaration : refl; + if (declaration.hasComment()) return true; + + return declaration.getAllSignatures().some((sig) => { return sig.hasComment() || sig.parameters?.some((p) => p.hasComment()); }); } diff --git a/src/test/converter2/issues/gh2555.ts b/src/test/converter2/issues/gh2555.ts new file mode 100644 index 000000000..a9cd0fa87 --- /dev/null +++ b/src/test/converter2/issues/gh2555.ts @@ -0,0 +1,14 @@ +/** + * @param props - Component properties. + * @param props.title - Title. + * @param props.options - Options. + * @param props.options.featureA - Turn on or off featureA. + * @param props.options.featureB - Turn on or off featureB. + */ +export function ComponentWithOptions({ + title, + options, +}: { + title: string; + options: { featureA: boolean; featureB: boolean }; +}) {} diff --git a/src/test/converter2/typedoc.json b/src/test/converter2/typedoc.json index 8e5327731..576a24c39 100644 --- a/src/test/converter2/typedoc.json +++ b/src/test/converter2/typedoc.json @@ -1,4 +1,14 @@ // This is here so we can point to it with doc:c2 and avoid warnings caused by TypeDoc's actual configuration. { - "logLevel": "Verbose" + "logLevel": "Verbose", + "outputs": [ + { + "name": "html", + "path": "../../../docs" + }, + { + "name": "json", + "path": "../../../docs/docs.json" + } + ] } diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index b0ee76218..7d1565326 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1509,6 +1509,39 @@ describe("Issue Tests", () => { logger.expectNoOtherMessages(); }); + it("#2555 allows nested @param comments", () => { + const project = convert(); + const sig = querySig(project, "ComponentWithOptions"); + const param = sig.parameters?.[0]; + equal(param?.type?.type, "reflection"); + const title = param.type.declaration.getChildOrTypePropertyByName([ + "title", + ]); + const options = param.type.declaration.getChildOrTypePropertyByName([ + "options", + ]); + const featureA = param.type.declaration.getChildOrTypePropertyByName([ + "options", + "featureA", + ]); + const featureB = param.type.declaration.getChildOrTypePropertyByName([ + "options", + "featureB", + ]); + + const comments = [param, title, options, featureA, featureB].map((d) => + Comment.combineDisplayParts(d?.comment?.summary), + ); + + equal(comments, [ + "Component properties.", + "Title.", + "Options.", + "Turn on or off featureA.", + "Turn on or off featureB.", + ]); + }); + it("#2574 default export", () => { const project = convert(); const sig = querySig(project, "usesDefaultExport"); From 981964639330c1b91d89e66b984b040c57f42a1b Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 17:41:42 -0700 Subject: [PATCH 106/219] Bring back excludeCategories --- CHANGELOG.md | 3 --- src/lib/converter/plugins/CommentPlugin.ts | 24 +++++++++++++++++++ src/lib/utils/options/declaration.ts | 1 + src/lib/utils/options/sources/typedoc.ts | 6 +++++ src/test/behavior.c2.test.ts | 10 ++++++++ .../converter2/behavior/excludeCategories.ts | 14 +++++++++++ 6 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/test/converter2/behavior/excludeCategories.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b6ba2ea9..8cdfc235b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,6 @@ title: Changelog - Changed the default `sort` order to use `alphabetical-ignoring-documents` instead of `alphabetical`. - Changed default of `suppressCommentWarningsInDeclarationFiles` to `true` -- Removed `excludeCategories` option which has existed for over a year, but - GitHub indicates has only ever been used by one project and breaks with - changes to make categories work with packages mode. - API: Constructor signatures now use the parent class name as their name (e.g. `X`, not `new X`) - API: `@group`, `@category`, `@groupDescription` and `@categoryDescription` diff --git a/src/lib/converter/plugins/CommentPlugin.ts b/src/lib/converter/plugins/CommentPlugin.ts index 4e7a05882..9539fa4ac 100644 --- a/src/lib/converter/plugins/CommentPlugin.ts +++ b/src/lib/converter/plugins/CommentPlugin.ts @@ -26,6 +26,7 @@ import { ConverterComponent } from "../components.js"; import type { Context } from "../context.js"; import { ConverterEvents } from "../converter-events.js"; import type { Converter } from "../converter.js"; +import { CategoryPlugin } from "./CategoryPlugin.js"; /** * These tags are not useful to display in the generated documentation. @@ -137,6 +138,9 @@ export class CommentPlugin extends ConverterComponent { @Option("excludeNotDocumented") accessor excludeNotDocumented!: boolean; + @Option("excludeCategories") + accessor excludeCategories!: string[]; + @Option("defaultCategory") accessor defaultCategory!: string; @@ -566,6 +570,10 @@ export class CommentPlugin extends ConverterComponent { return true; } + if (this.excludedByCategory(reflection)) { + return true; + } + if ( reflection.kindOf( ReflectionKind.ConstructorSignature | @@ -649,6 +657,22 @@ export class CommentPlugin extends ConverterComponent { return isHidden; } + private excludedByCategory(reflection: Reflection): boolean { + const excludeCategories = this.excludeCategories; + let target: DeclarationReflection | undefined; + if (reflection instanceof DeclarationReflection) { + target = reflection; + } else if (reflection instanceof SignatureReflection) { + target = reflection.parent; + } + if (!target || !excludeCategories.length) return false; + const categories = CategoryPlugin.getCategories(target); + if (categories.size === 0) { + categories.add(this.defaultCategory); + } + return excludeCategories.some((cat) => categories.has(cat)); + } + private validateParamTags( signature: SignatureReflection, comment: Comment, diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index 396be9907..ca349f4d3 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -121,6 +121,7 @@ export interface TypeDocOptionMap { excludePrivate: boolean; excludeProtected: boolean; excludeReferences: boolean; + excludeCategories: string[]; maxTypeConversionDepth: number; name: string; includeVersion: boolean; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index f224e8b51..d767691a4 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -192,6 +192,12 @@ export function addTypeDocOptions(options: Pick) { help: (i18n) => i18n.help_excludeInternal(), type: ParameterType.Boolean, }); + options.addDeclaration({ + name: "excludeCategories", + help: (i18n) => i18n.help_excludeCategories(), + type: ParameterType.Array, + defaultValue: [], + }); options.addDeclaration({ name: "excludePrivate", help: (i18n) => i18n.help_excludePrivate(), diff --git a/src/test/behavior.c2.test.ts b/src/test/behavior.c2.test.ts index cd364b8d4..854247535 100644 --- a/src/test/behavior.c2.test.ts +++ b/src/test/behavior.c2.test.ts @@ -436,6 +436,16 @@ describe("Behavior Tests", () => { logger.expectNoOtherMessages(); }); + it("Handles excludeCategories", () => { + app.options.setValue("excludeCategories", ["A", "Default"]); + app.options.setValue("defaultCategory", "Default"); + const project = convert("excludeCategories"); + equal( + project.children?.map((c) => c.name), + ["c"], + ); + }); + it("Handles excludeNotDocumentedKinds", () => { app.options.setValue("excludeNotDocumented", true); app.options.setValue("excludeNotDocumentedKinds", ["Property"]); diff --git a/src/test/converter2/behavior/excludeCategories.ts b/src/test/converter2/behavior/excludeCategories.ts new file mode 100644 index 000000000..b2b312c3e --- /dev/null +++ b/src/test/converter2/behavior/excludeCategories.ts @@ -0,0 +1,14 @@ +/** + * @category A + */ +export const a = 1; +/** + * @category A + * @category B + */ +export const b = 1; +/** + * @category C + */ +export const c = 1; +export const d = 1; From 45959de26cedb8892fd660cdec8149e5ba89283a Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 18:16:28 -0700 Subject: [PATCH 107/219] Support linking to type alias properties Resolves #2524 --- CHANGELOG.md | 1 + src/lib/models/reflections/abstract.ts | 4 ++ src/lib/models/reflections/index.ts | 2 +- src/lib/models/reflections/variant.ts | 2 + .../themes/default/partials/typeDetails.tsx | 41 ++++++++++++------- src/test/converter2/issues/gh2524.ts | 6 +++ src/test/issues.c2.test.ts | 31 ++++++++++++++ src/test/utils.ts | 36 ++++++++++++++-- 8 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 src/test/converter2/issues/gh2524.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cdfc235b..ddcb93b65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ title: Changelog overloads if present, #2718. - Fixed handling of `@enum` if the type was declared before the variable, #2719. - Fixed empty top level modules page in packages mode, #2753. +- TypeDoc can now link to type alias properties, #2524. - Fixed an issue where properties were not properly marked optional in some cases. This primarily affected destructured parameters. - Added `yaml` to the highlight languages supported by default. diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index 97e79b8e2..e36301bd2 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -18,6 +18,7 @@ import type { } from "../../internationalization/index.js"; import type { ParameterReflection } from "./parameter.js"; import { createNormalizedUrl } from "../../utils/html.js"; +import type { ReferenceReflection } from "./reference.js"; /** * Current reflection id. @@ -486,6 +487,9 @@ export abstract class Reflection { isDocument(): this is DocumentReflection { return false; } + isReference(): this is ReferenceReflection { + return this.variant === "reference"; + } /** * Check if this reflection or any of its parents have been marked with the `@deprecated` tag. diff --git a/src/lib/models/reflections/index.ts b/src/lib/models/reflections/index.ts index c0a1d73e3..bae28c391 100644 --- a/src/lib/models/reflections/index.ts +++ b/src/lib/models/reflections/index.ts @@ -24,4 +24,4 @@ export { export { SignatureReflection } from "./signature.js"; export { TypeParameterReflection, VarianceModifier } from "./type-parameter.js"; export { splitUnquotedString } from "./utils.js"; -export type { ReflectionVariant } from "./variant.js"; +export type { ReflectionVariant, SomeReflection } from "./variant.js"; diff --git a/src/lib/models/reflections/variant.ts b/src/lib/models/reflections/variant.ts index 02f1ae3f1..4c921b62b 100644 --- a/src/lib/models/reflections/variant.ts +++ b/src/lib/models/reflections/variant.ts @@ -19,3 +19,5 @@ export interface ReflectionVariant { typeParam: TypeParameterReflection; document: DocumentReflection; } + +export type SomeReflection = ReflectionVariant[keyof ReflectionVariant]; diff --git a/src/lib/output/themes/default/partials/typeDetails.tsx b/src/lib/output/themes/default/partials/typeDetails.tsx index c9b48d3da..149706794 100644 --- a/src/lib/output/themes/default/partials/typeDetails.tsx +++ b/src/lib/output/themes/default/partials/typeDetails.tsx @@ -37,7 +37,7 @@ export function typeDeclaration(context: DefaultThemeRenderContext, type: SomeTy return (

    {context.i18n.theme_type_declaration()}

    - {context.typeDetails(type)} + {context.typeDetails(type, true)}
    ); } @@ -57,21 +57,22 @@ function shouldExpandReference(reference: ReferenceType) { return expanded.has(target) === false; } -export function typeDetails(context: DefaultThemeRenderContext, type: SomeType): JSX.Children { - return typeDetailsImpl(context, type); +export function typeDetails(context: DefaultThemeRenderContext, type: SomeType, renderAnchors: boolean): JSX.Children { + return typeDetailsImpl(context, type, renderAnchors); } export function typeDetailsImpl( context: DefaultThemeRenderContext, type: SomeType, + renderAnchors: boolean, highlighted?: Map, ): JSX.Children { const result = type.visit({ array(type) { - return context.typeDetails(type.elementType); + return context.typeDetails(type.elementType, renderAnchors); }, intersection(type) { - return type.types.map(context.typeDetails); + return type.types.map((t) => context.typeDetails(t, renderAnchors)); }, union(type) { const result: JSX.Children = []; @@ -89,9 +90,9 @@ export function typeDetailsImpl( reflection(type) { const declaration = type.declaration; if (highlighted) { - return highlightedDeclarationDetails(context, declaration, highlighted); + return highlightedDeclarationDetails(context, declaration, renderAnchors, highlighted); } - return declarationDetails(context, declaration); + return declarationDetails(context, declaration, renderAnchors); }, reference(reference) { if (shouldExpandReference(reference)) { @@ -103,8 +104,8 @@ export function typeDetailsImpl( // Ensure we don't go into an infinite loop here expanded.add(target); const details = target.type - ? typeDetailsImpl(context, target.type) - : declarationDetails(context, target); + ? context.typeDetails(target.type, renderAnchors) + : declarationDetails(context, target, renderAnchors); expanded.delete(target); return details; } @@ -121,7 +122,7 @@ export function typeDetailsImpl( export function typeDetailsIfUseful(context: DefaultThemeRenderContext, type: SomeType | undefined): JSX.Children { if (type && renderingTypeDetailsIsUseful(type)) { - return context.typeDetails(type); + return context.typeDetails(type, false); } } @@ -150,6 +151,7 @@ function highlightedPropertyDetails( function highlightedDeclarationDetails( context: DefaultThemeRenderContext, declaration: DeclarationReflection, + renderAnchors: boolean, highlightedProperties?: Map, ) { return ( @@ -159,13 +161,17 @@ function highlightedDeclarationDetails( ?.map( (child) => highlightedProperties?.has(child.name) && - renderChild(context, child, highlightedProperties.get(child.name)), + renderChild(context, child, renderAnchors, highlightedProperties.get(child.name)), )} ); } -function declarationDetails(context: DefaultThemeRenderContext, declaration: DeclarationReflection): JSX.Children { +function declarationDetails( + context: DefaultThemeRenderContext, + declaration: DeclarationReflection, + renderAnchors: boolean, +): JSX.Children { return ( <> {context.commentSummary(declaration)} @@ -191,7 +197,7 @@ function declarationDetails(context: DefaultThemeRenderContext, declaration: Dec )} {declaration.indexSignatures?.map((index) => renderIndexSignature(context, index))} - {declaration.getProperties()?.map((child) => renderChild(context, child))} + {declaration.getProperties()?.map((child) => renderChild(context, child, renderAnchors))} ); @@ -200,6 +206,7 @@ function declarationDetails(context: DefaultThemeRenderContext, declaration: Dec function renderChild( context: DefaultThemeRenderContext, child: DeclarationReflection, + renderAnchors: boolean, highlight?: CommentDisplayPart[], ) { if (child.signatures) { @@ -208,6 +215,7 @@ function renderChild(
    {!!child.flags.isRest && ...} {child.name} + {!!child.flags.isOptional && "?"}: function
    @@ -237,6 +245,7 @@ function renderChild( {context.reflectionFlags(child)} {!!child.flags.isRest && ...} {child.name} + {!!child.flags.isOptional && "?"} {": "} @@ -245,7 +254,9 @@ function renderChild( {highlightOrComment(child)} {child.getProperties().some(renderingChildIsUseful) && ( -
      {child.getProperties().map((c) => renderChild(context, c))}
    +
      + {child.getProperties().map((c) => renderChild(context, c, renderAnchors))} +
    )} ); @@ -260,6 +271,7 @@ function renderChild( {context.reflectionFlags(child.getSignature)} get {child.name} + (): {context.type(child.getSignature.type)} @@ -273,6 +285,7 @@ function renderChild( {context.reflectionFlags(child.setSignature)} set {child.name} + {!child.getSignature && } ( {child.setSignature.parameters?.map((item) => ( <> diff --git a/src/test/converter2/issues/gh2524.ts b/src/test/converter2/issues/gh2524.ts new file mode 100644 index 000000000..7d29176bd --- /dev/null +++ b/src/test/converter2/issues/gh2524.ts @@ -0,0 +1,6 @@ +export type Alias = { + /** {@link Alias.other} {@link other} */ + readonly default: string; + /** {@link Alias.default} {@link default} */ + readonly other: string; +}; diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 7d1565326..06790b1a4 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -1471,6 +1471,37 @@ describe("Issue Tests", () => { equal(getSigComment(project, "fooWithComment", 1), "Overload 2"); }); + it("#2524 Handles links to type alias properties", () => { + const project = convert(); + app.options.setValue("validation", false); + app.options.setValue("validation", { invalidLink: true }); + app.validate(project); + + const def = query(project, "Alias.default"); + equal(getLinks(def), [ + { + display: "other", + target: [ReflectionKind.Property, "Alias.__type.other"], + }, + { + display: "other", + target: [ReflectionKind.Property, "Alias.__type.other"], + }, + ]); + + const other = query(project, "Alias.other"); + equal(getLinks(other), [ + { + display: "default", + target: [ReflectionKind.Property, "Alias.__type.default"], + }, + { + display: "default", + target: [ReflectionKind.Property, "Alias.__type.default"], + }, + ]); + }); + it("#2545 discovers comments from non-exported 'parent' methods", () => { const project = convert(); diff --git a/src/test/utils.ts b/src/test/utils.ts index cbfcd53a1..0f5e2a1a4 100644 --- a/src/test/utils.ts +++ b/src/test/utils.ts @@ -9,14 +9,44 @@ import { } from "../index.js"; import { filterMap } from "../lib/utils/index.js"; import { equal } from "assert/strict"; +import type { SomeReflection } from "../lib/models/reflections/variant.js"; export function query( project: ProjectReflection, name: string, ): DeclarationReflection { - const reflection = project.getChildByName(name); - ok(reflection instanceof DeclarationReflection, `Failed to find ${name}`); - return reflection; + let refl: SomeReflection | undefined = project; + const parts = name.split("."); + + for (let i = 0; i < parts.length; ++i) { + if (!refl) break; + if (refl.isReference()) { + refl = refl.getTargetReflectionDeep() as SomeReflection; + } + + if (refl.isDocument()) { + throw new Error("Found document"); + } + + if (refl.isProject()) { + refl = refl.getChildByName([parts[i]]) as + | SomeReflection + | undefined; + continue; + } + + if (refl.type?.type === "reflection") { + refl = refl.type.declaration.getChildByName([parts[i]]) as + | SomeReflection + | undefined; + continue; + } + + refl = refl.getChildByName([parts[i]]) as SomeReflection | undefined; + } + + ok(refl instanceof DeclarationReflection, `Failed to find ${name}`); + return refl; } export function querySig( From eca4451b2e0e53b5a9034a13acf8ad55abbb7314 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 20:13:37 -0700 Subject: [PATCH 108/219] Validate anchors in relative links --- CHANGELOG.md | 9 +- site/options/output.md | 32 +++++++ site/overview.md | 2 +- src/lib/converter/comments/textParser.ts | 36 ++++++-- src/lib/internationalization/locales/en.cts | 4 +- src/lib/internationalization/locales/jp.cts | 2 - src/lib/internationalization/locales/zh.cts | 2 - src/lib/models/FileRegistry.ts | 40 +++++--- src/lib/models/comments/comment.ts | 13 ++- src/lib/models/reflections/abstract.ts | 47 ---------- src/lib/output/theme.ts | 15 +++ src/lib/output/themes/MarkedPlugin.tsx | 82 ++++++++++++----- .../output/themes/default/DefaultTheme.tsx | 79 +++++++++------- .../default/DefaultThemeRenderContext.ts | 4 + src/lib/output/themes/default/Slugger.ts | 31 +++++-- .../themes/default/partials/comment.tsx | 2 +- .../default/partials/moduleReflection.tsx | 7 +- src/lib/serialization/schema.ts | 4 + src/lib/utils/general.ts | 52 ++++++++++- src/lib/utils/options/declaration.ts | 3 + src/lib/utils/options/options.ts | 48 +--------- src/lib/utils/options/sources/typedoc.ts | 9 +- src/test/comments.test.ts | 91 +++++++++++++++++-- src/test/issues.c2.test.ts | 9 -- src/test/output/Slugger.test.ts | 16 ++++ 25 files changed, 420 insertions(+), 219 deletions(-) create mode 100644 src/test/output/Slugger.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ddcb93b65..b1b6ce7f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ title: Changelog - Relaxed requirements for file names and generated url fragments. This may result in a different file name structure, #2714. +- Anchors to document headings and reflections within a HTML generated pages + have changed. They can be partially restored to the previous format by + setting `--sluggerConfiguration.lowercase false`. This change was made to + more closely match the default behavior of GitHub's markdown rendering and + VSCode's autocomplete when creating a relative link to an external markdown + file. - Removed the `hideParameterTypesInTitle` option, this was originally added as a workaround for many signatures overflowing the available horizontal space in rendered pages. TypeDoc now has logic to wrap types/signatures smartly, @@ -26,6 +32,8 @@ title: Changelog - TypeDoc will now discover entry points from `package.json` exports if they are not provided manually, #1937. +- Relative links to markdown files may now include `#anchor` links to + reference a heading within them. - Improved support for `@param` comments with nested object types, #2555. - Improved support for `@param` comments which reference a type alias/interface. Important properties on the referenced type can now be @@ -94,7 +102,6 @@ title: Changelog TODO: -- Validate anchors within relative linked paths? - Figure out automation for beta releases # Unreleased diff --git a/site/options/output.md b/site/options/output.md index 7bd3d7ca5..1e38c247e 100644 --- a/site/options/output.md +++ b/site/options/output.md @@ -354,6 +354,38 @@ categories/groups. - `@showCategories` - `@hideCategories` +## headings + +```json +// typedoc.json +{ + "headings": { + "readme": true, + "document": false + } +} +``` + +Defines whether a heading describing the reflection should be included on the rendered page. + +## sluggerConfiguration + +```json +// typedoc.json +{ + "sluggerConfiguration": { + "lowercase": true + } +} +``` + +Determines how anchors within a page are created. This option exists primarily +for backwards compatibility. It may be removed in a future release. TypeDoc 0.26 +did not lowercase headings within a page which is inconsistent with how GitHub +pages sites commonly generate headings and does not play well with VSCode's +autocomplete to anchors within external markdown files. In 0.27, this option +defaults to `true`. + ## navigationLeaves ```json diff --git a/site/overview.md b/site/overview.md index f2eb188dd..eb93d0733 100644 --- a/site/overview.md +++ b/site/overview.md @@ -32,7 +32,7 @@ support more versions of TypeScript. TypeDoc's CLI can be used through your terminal or npm scripts. Any arguments passed to TypeDoc which are not flags are parsed as entry points. TypeDoc will -also read configuration from several files. See [Configuration](./options/configuration.md) +also read configuration from several files. See [Configuration](./options/configuration.md#compileroptions) for details on where options are read from.
    diff --git a/src/lib/converter/comments/textParser.ts b/src/lib/converter/comments/textParser.ts index 24a34ca93..c379e24bd 100644 --- a/src/lib/converter/comments/textParser.ts +++ b/src/lib/converter/comments/textParser.ts @@ -9,7 +9,10 @@ import type { TranslationProxy, TranslatedString, } from "../../internationalization/index.js"; -import type { CommentDisplayPart } from "../../models/index.js"; +import type { + CommentDisplayPart, + RelativeLinkDisplayPart, +} from "../../models/index.js"; import type { FileRegistry } from "../../models/FileRegistry.js"; import { HtmlAttributeParser, ParserState } from "../../utils/html.js"; import { type Token, TokenSyntaxKind } from "./lexer.js"; @@ -32,6 +35,7 @@ interface RelativeLink { end: number; /** May be undefined if the registry can't find this file */ target: number | undefined; + targetAnchor: string | undefined; } /** @@ -92,11 +96,13 @@ export function textContent( kind: "text", text: token.text.slice(lastPartEnd, ref.pos), }); - outContent.push({ + const link: RelativeLinkDisplayPart = { kind: "relative-link", text: token.text.slice(ref.pos, ref.end), target: ref.target, - }); + targetAnchor: ref.targetAnchor, + }; + outContent.push(link); lastPartEnd = ref.end; data.pos = ref.end; if (!ref.target) { @@ -190,10 +196,15 @@ function checkMarkdownLink( // Only make a relative-link display part if it's actually a relative link. // Discard protocol:// links, unix style absolute paths, and windows style absolute paths. if (isRelativePath(link.str)) { + const { target, anchor } = files.register( + sourcePath, + link.str, + ) || { target: undefined, anchor: undefined }; return { pos: labelEnd + 2, end: link.pos, - target: files.register(sourcePath, link.str), + target, + targetAnchor: anchor, }; } @@ -241,10 +252,15 @@ function checkReference(data: TextParserData): RelativeLink | undefined { if (link.ok) { if (isRelativePath(link.str)) { + const { target, anchor } = files.register( + sourcePath, + link.str, + ) || { target: undefined, anchor: undefined }; return { pos: lookahead, end: link.pos, - target: files.register(sourcePath, link.str), + target, + targetAnchor: anchor, }; } @@ -286,13 +302,15 @@ function checkAttribute( if (isRelativePath(parser.currentAttributeValue)) { data.pos = parser.pos; + const { target, anchor } = data.files.register( + data.sourcePath, + parser.currentAttributeValue, + ) || { target: undefined, anchor: undefined }; return { pos: parser.currentAttributeValueStart, end: parser.currentAttributeValueEnd, - target: data.files.register( - data.sourcePath, - parser.currentAttributeValue, - ), + target, + targetAnchor: anchor, }; } return; diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index e64ae2956..f6329fc7b 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -131,7 +131,7 @@ export = { could_not_empty_output_directory_0: `Could not empty the output directory {0}`, could_not_create_output_directory_0: `Could not create the output directory {0}`, theme_0_is_not_defined_available_are_1: `The theme '{0}' is not defined. The available themes are: {1}`, - custom_theme_does_not_define_getSlugger: `Custom theme does not define a getSlugger(reflection) method, but tries to render markdown`, + reflection_0_links_to_1_but_anchor_does_not_exist_try_2: `{0} links to {1}, but the anchor does not exist. You may have meant:\n\t{2}`, // entry points no_entry_points_provided: @@ -295,6 +295,8 @@ export = { help_navigationLeaves: "Branches of the navigation tree which should not be expanded", help_headings: "Determines which optional headings are rendered", + help_sluggerConfiguration: + "Determines how anchors within rendered HTML are determined.", help_navigation: "Determines how the navigation sidebar is organized", help_visibilityFilters: "Specify the default visibility for builtin filters and additional filters according to modifier tags", diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 0a376c233..c0b33d417 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -142,8 +142,6 @@ export = localeUtils.buildIncompleteTranslation({ "出力ディレクトリ {0} を作成できませんでした", theme_0_is_not_defined_available_are_1: "テーマ '{0}' は定義されていません。使用可能なテーマは次のとおりです: {1}", - custom_theme_does_not_define_getSlugger: - "カスタムテーマはgetSlugger(reflection)メソッドを定義していませんが、マークダウンをレンダリングしようとします", // no_entry_points_provided: unable_to_find_any_entry_points: "エントリ ポイントが見つかりません。以前の警告を参照してください", diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index ef85199d1..550f70a63 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -146,8 +146,6 @@ export = localeUtils.buildIncompleteTranslation({ could_not_empty_output_directory_0: "无法清空输出目录 {0}", could_not_create_output_directory_0: "无法创建输出目录 {0}", theme_0_is_not_defined_available_are_1: "主题“{0}”未定义。可用主题为:{1}", - custom_theme_does_not_define_getSlugger: - "自定义主题没有定义 getSlugger(reflection) 方法,但尝试渲染 markdown", no_entry_points_provided: "没有提供入口点,这可能是配置错误", unable_to_find_any_entry_points: "无法找到任何入口点。请参阅先前的警告", diff --git a/src/lib/models/FileRegistry.ts b/src/lib/models/FileRegistry.ts index 67418f1e4..2313cd4ec 100644 --- a/src/lib/models/FileRegistry.ts +++ b/src/lib/models/FileRegistry.ts @@ -19,32 +19,44 @@ export class FileRegistry { protected names = new Map(); protected nameUsage = new Map(); - registerAbsolute(absolute: string) { + registerAbsolute(absolute: string): { + target: number; + anchor: string | undefined; + } { + const anchorIndex = absolute.indexOf("#"); + let anchor: string | undefined = undefined; + if (anchorIndex !== -1) { + anchor = absolute.substring(anchorIndex + 1); + absolute = absolute.substring(0, anchorIndex); + } absolute = normalizePath(absolute).replace(/#.*/, ""); const existing = this.pathToMedia.get(absolute); if (existing) { - return existing; + return { target: existing, anchor }; } this.mediaToPath.set(this.nextId, absolute); this.pathToMedia.set(absolute, this.nextId); - return this.nextId++; + return { target: this.nextId++, anchor }; } /** Called by {@link ProjectReflection.registerReflection} @internal*/ registerReflection(absolute: string, reflection: Reflection) { absolute = normalizePath(absolute); - const id = this.registerAbsolute(absolute); + const { target } = this.registerAbsolute(absolute); this.reflectionToPath.set(reflection.id, absolute); - this.mediaToReflection.set(id, reflection.id); + this.mediaToReflection.set(target, reflection.id); } getReflectionPath(reflection: Reflection): string | undefined { return this.reflectionToPath.get(reflection.id); } - register(sourcePath: string, relativePath: string): number | undefined { + register( + sourcePath: string, + relativePath: string, + ): { target: number; anchor: string | undefined } | undefined { return this.registerAbsolute( resolve(dirname(sourcePath), relativePath), ); @@ -131,7 +143,8 @@ export class FileRegistry { fromObject(de: Deserializer, obj: JSONFileRegistry): void { for (const [key, val] of Object.entries(obj.entries)) { const absolute = normalizePath(resolve(de.projectRoot, val)); - de.oldFileIdToNewFileId[+key] = this.registerAbsolute(absolute); + de.oldFileIdToNewFileId[+key] = + this.registerAbsolute(absolute).target; } de.defer((project) => { @@ -154,12 +167,10 @@ export class ValidatingFileRegistry extends FileRegistry { override register( sourcePath: string, relativePath: string, - ): number | undefined { - const absolute = resolve(dirname(sourcePath), relativePath).replace( - /#.*/, - "", - ); - if (!isFile(absolute)) { + ): { target: number; anchor: string | undefined } | undefined { + const absolute = resolve(dirname(sourcePath), relativePath); + const absoluteWithoutAnchor = absolute.replace(/#.*/, ""); + if (!isFile(absoluteWithoutAnchor)) { return; } return this.registerAbsolute(absolute); @@ -178,7 +189,8 @@ export class ValidatingFileRegistry extends FileRegistry { continue; } - de.oldFileIdToNewFileId[+key] = this.registerAbsolute(absolute); + de.oldFileIdToNewFileId[+key] = + this.registerAbsolute(absolute).target; } de.defer((project) => { diff --git a/src/lib/models/comments/comment.ts b/src/lib/models/comments/comment.ts index 97a516a60..f0b022ac8 100644 --- a/src/lib/models/comments/comment.ts +++ b/src/lib/models/comments/comment.ts @@ -68,6 +68,10 @@ export interface RelativeLinkDisplayPart { * This may be `undefined` if the relative path does not exist. */ target: number | undefined; + /** + * Anchor within the target page, validated after rendering if possible + */ + targetAnchor: string | undefined; } /** @@ -230,7 +234,7 @@ export class Comment { case "relative-link": { return { ...part, - }; + } satisfies JSONOutput.CommentDisplayPart; } } }); @@ -293,11 +297,16 @@ export class Comment { kind: "relative-link", text: part.text, target: null!, + targetAnchor: part.targetAnchor, } satisfies RelativeLinkDisplayPart; files.push([part.target, part2]); return part2; } - return { ...part, target: undefined }; + return { + ...part, + target: undefined, + targetAnchor: part.targetAnchor, + }; } } }); diff --git a/src/lib/models/reflections/abstract.ts b/src/lib/models/reflections/abstract.ts index e36301bd2..293c7b00c 100644 --- a/src/lib/models/reflections/abstract.ts +++ b/src/lib/models/reflections/abstract.ts @@ -17,7 +17,6 @@ import type { TranslatedString, } from "../../internationalization/index.js"; import type { ParameterReflection } from "./parameter.js"; -import { createNormalizedUrl } from "../../utils/html.js"; import type { ReferenceReflection } from "./reference.js"; /** @@ -315,13 +314,6 @@ export abstract class Reflection { */ hasOwnDocument?: boolean; - /** - * Url safe alias for this reflection. - */ - private _alias?: string; - - private _aliases?: Map; - constructor(name: string, kind: ReflectionKind, parent?: Reflection) { this.id = REFLECTION_ID++ as ReflectionId; this.parent = parent; @@ -392,45 +384,6 @@ export abstract class Reflection { this.flags.setFlag(flag, value); } - /** - * Return an url safe alias for this reflection. - */ - getAlias(): string { - this._alias ||= this.getUniqueAliasInPage( - createNormalizedUrl(this.name) || `reflection-${this.id}`, - ); - - return this._alias; - } - - // This really ought not live here, it ought to live in the html renderer, but moving that - // is more work than I want right now, it can wait for 0.27 when trying to split models into - // a bundleable structure. - getUniqueAliasInPage(heading: string) { - // NTFS/ExFAT use uppercase, so we will too. It probably won't matter - // in this case since names will generally be valid identifiers, but to be safe... - const upperAlias = heading.toUpperCase(); - - let target = this as Reflection; - while (target.parent && !target.hasOwnDocument) { - target = target.parent; - } - - target._aliases ||= new Map(); - - let suffix = ""; - if (!target._aliases.has(upperAlias)) { - target._aliases.set(upperAlias, 1); - } else { - const count = target._aliases.get(upperAlias)!; - suffix = "-" + count.toString(); - target._aliases.set(upperAlias, count + 1); - } - - heading += suffix; - return heading; - } - /** * Has this reflection a visible comment? * diff --git a/src/lib/output/theme.ts b/src/lib/output/theme.ts index 2bfecd3c7..c44c05a4f 100644 --- a/src/lib/output/theme.ts +++ b/src/lib/output/theme.ts @@ -4,6 +4,7 @@ import type { RenderTemplate, UrlMapping } from "./models/UrlMapping.js"; import { RendererComponent } from "./components.js"; import type { PageEvent } from "./events.js"; import type { Reflection } from "../models/index.js"; +import type { Slugger } from "./themes/default/Slugger.js"; /** * Base class of all themes. @@ -14,6 +15,8 @@ import type { Reflection } from "../models/index.js"; * {@link Renderer} to control and manipulate the output process. */ export abstract class Theme extends RendererComponent { + private sluggers = new Map(); + /** * Map the models of the given project to the desired output files. * It is assumed that with the project structure: @@ -39,4 +42,16 @@ export abstract class Theme extends RendererComponent { page: PageEvent, template: RenderTemplate>, ): string; + + setSlugger(reflection: Reflection, slugger: Slugger) { + this.sluggers.set(reflection, slugger); + } + + getSlugger(reflection: Reflection): Slugger { + if (this.sluggers.has(reflection)) { + return this.sluggers.get(reflection)!; + } + // A slugger should always be defined at least for the project + return this.getSlugger(reflection.parent!); + } } diff --git a/src/lib/output/themes/MarkedPlugin.tsx b/src/lib/output/themes/MarkedPlugin.tsx index d6c05f70d..4df2618db 100644 --- a/src/lib/output/themes/MarkedPlugin.tsx +++ b/src/lib/output/themes/MarkedPlugin.tsx @@ -3,26 +3,21 @@ import MarkdownIt from "markdown-it"; import type md from "markdown-it" with { "resolution-mode": "require" }; import { ContextAwareRendererComponent } from "../components.js"; -import { type RendererEvent, MarkdownEvent, type PageEvent } from "../events.js"; -import { Option, type Logger, renderElement, assertNever } from "../../utils/index.js"; +import { MarkdownEvent, RendererEvent, type PageEvent } from "../events.js"; +import { Option, renderElement, assertNever } from "../../utils/index.js"; import { highlight, isLoadedLanguage, isSupportedLanguage } from "../../utils/highlighter.js"; import type { BundledTheme } from "shiki" with { "resolution-mode": "import" }; import { escapeHtml } from "../../utils/html.js"; -import type { DefaultTheme, DefaultThemeRenderContext, Renderer } from "../index.js"; -import { Slugger } from "./default/Slugger.js"; +import type { DefaultThemeRenderContext, Renderer } from "../index.js"; import { anchorIcon } from "./default/partials/anchor-icon.js"; -import { type Reflection, ReflectionKind, type CommentDisplayPart } from "../../models/index.js"; +import { + type Reflection, + ReflectionKind, + type CommentDisplayPart, + type RelativeLinkDisplayPart, +} from "../../models/index.js"; import type { TranslatedString, TranslationProxy } from "../../internationalization/index.js"; -let defaultSlugger: Slugger | undefined; -function getDefaultSlugger(logger: Logger) { - if (!defaultSlugger) { - logger.warn(logger.i18n.custom_theme_does_not_define_getSlugger()); - defaultSlugger = new Slugger(); - } - return defaultSlugger; -} - /** * Implements markdown and relativeURL helpers for templates. * @internal @@ -42,6 +37,12 @@ export class MarkedPlugin extends ContextAwareRendererComponent { private parser?: MarkdownIt; + private renderedRelativeLinks: { + source: Reflection; + target: Reflection; + link: RelativeLinkDisplayPart; + }[] = []; + /** * This needing to be here really feels hacky... probably some nicer way to do this. * Revisit when adding support for arbitrary pages in 0.26. @@ -52,6 +53,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent { constructor(owner: Renderer) { super(owner); this.owner.on(MarkdownEvent.PARSE, this.onParseMarkdown.bind(this)); + this.owner.on(RendererEvent.END, this.onEnd.bind(this)); } /** @@ -182,8 +184,21 @@ export class MarkedPlugin extends ContextAwareRendererComponent { } if (url) { - if (!url.includes("#") && part.text.includes("#")) { - url += part.text.substring(part.text.indexOf("#")); + if (part.targetAnchor) { + url += "#" + part.targetAnchor; + + if (typeof refl === "object") { + this.renderedRelativeLinks.push({ + source: this.page!.model, + target: refl, + link: part, + }); + } else { + console.log("NOPE", part); + } + } + if (url.endsWith("Options.Configuration.html")) { + debugger; } result.push(url); break; @@ -203,6 +218,27 @@ export class MarkedPlugin extends ContextAwareRendererComponent { return result.join(""); } + private onEnd() { + for (const { source, target, link } of this.renderedRelativeLinks) { + const slugger = this.owner.theme!.getSlugger(target); + if (!slugger.hasAnchor(link.targetAnchor!)) { + this.application.logger.warn( + this.application.i18n.reflection_0_links_to_1_but_anchor_does_not_exist_try_2( + source.getFriendlyFullName(), + link.text, + slugger + .getSimilarAnchors(link.targetAnchor!) + .map((a) => link.text.replace(/#.*/, "#" + a)) + .join("\n\t"), + ), + ); + } + } + + // In case we're in watch mode + this.renderedRelativeLinks = []; + } + /** * Triggered before the renderer starts rendering a project. * @@ -214,10 +250,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent { } private getSlugger() { - if ("getSlugger" in this.owner.theme!) { - return (this.owner.theme as DefaultTheme).getSlugger(this.page!.model); - } - return getDefaultSlugger(this.application.logger); + return this.owner.theme!.getSlugger(this.page!.model); } /** @@ -254,24 +287,23 @@ export class MarkedPlugin extends ContextAwareRendererComponent { const slug = this.getSlugger().slug(content); this.lastHeaderSlug = slug; - // Prefix the slug with an extra `md:` to prevent conflicts with TypeDoc's anchors. this.page!.pageHeadings.push({ - link: `#md:${slug}`, + link: `#${slug}`, text: content, level, }); - return `<${token.tag} class="tsd-anchor-link">`; + return `<${token.tag} class="tsd-anchor-link">`; }; this.parser.renderer.rules["heading_close"] = (tokens, idx) => { - return `${renderElement(anchorIcon(this.renderContext, `md:${this.lastHeaderSlug}`))}`; + return `${renderElement(anchorIcon(this.renderContext, `${this.lastHeaderSlug}`))}`; }; // Rewrite anchor links inline in a readme file to links targeting the `md:` prefixed anchors // that TypeDoc creates. this.parser.renderer.rules["link_open"] = (tokens, idx, options, _env, self) => { const token = tokens[idx]; - const href = token.attrGet("href")?.replace(/^#(?:md:)?(.+)/, "#md:$1"); + const href = token.attrGet("href"); if (href) { // Note: This doesn't catch @link tags to reflections as those // will be relative links. This will likely have to change with diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index ac91ab165..4dfbd8e2e 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -17,10 +17,11 @@ import { type RenderTemplate, UrlMapping } from "../../models/UrlMapping.js"; import type { PageEvent } from "../../events.js"; import type { MarkedPlugin } from "../../plugins/index.js"; import { DefaultThemeRenderContext } from "./DefaultThemeRenderContext.js"; -import { filterMap, JSX } from "../../../utils/index.js"; +import { filterMap, JSX, Option, type TypeDocOptionMap } from "../../../utils/index.js"; import { classNames, getDisplayName, getHierarchyRoots, toStyleClass } from "../lib.js"; import { icons } from "./partials/icon.js"; import { Slugger } from "./Slugger.js"; +import { createNormalizedUrl } from "../../../utils/html.js"; /** * Defines a mapping of a {@link Models.Kind} to a template file. @@ -52,11 +53,14 @@ export interface NavigationElement { children?: NavigationElement[]; } -/** - * Default theme implementation of TypeDoc. If a theme does not provide a custom - * {@link Theme} implementation, this theme class will be used. - */ export class DefaultTheme extends Theme { + // Note: This will always contain lowercased names to avoid issues with + // case-insensitive file systems. + usedFileNames = new Set(); + + @Option("sluggerConfiguration") + private accessor sluggerConfiguration!: TypeDocOptionMap["sluggerConfiguration"]; + /** @internal */ markedPlugin: MarkedPlugin; @@ -166,8 +170,9 @@ export class DefaultTheme extends Theme { * should be rendered to which files. */ getUrls(project: ProjectReflection): UrlMapping[] { + this.usedFileNames = new Set(); const urls: UrlMapping[] = []; - this.sluggers.set(project, new Slugger()); + this.setSlugger(project, new Slugger(this.sluggerConfiguration)); if (!project.readme?.length) { project.url = "index.html"; @@ -188,21 +193,29 @@ export class DefaultTheme extends Theme { } /** - * Return a url for the given reflection. - * * @param reflection The reflection the url should be generated for. - * @param relative The parent reflection the url generation should stop on. - * @param separator The separator used to generate the url. - * @returns The generated url. */ - static getUrl(reflection: Reflection, relative?: Reflection, separator = "."): string { - let url = reflection.getAlias(); + getFileName(reflection: Reflection): string { + const parts = [createNormalizedUrl(reflection.name)]; + while (reflection.parent && !reflection.parent.isProject()) { + reflection = reflection.parent; + parts.unshift(createNormalizedUrl(reflection.name)); + } + + const baseName = parts.join("."); + const lowerBaseName = baseName.toLocaleLowerCase(); + if (this.usedFileNames.has(lowerBaseName)) { + let index = 1; + while (this.usedFileNames.has(`${lowerBaseName}-${index}`)) { + ++index; + } - if (reflection.parent && reflection.parent !== relative && !(reflection.parent instanceof ProjectReflection)) { - url = DefaultTheme.getUrl(reflection.parent, relative, separator) + separator + url; + this.usedFileNames.add(`${lowerBaseName}-${index}`); + return `${baseName}-${index}.html`; } - return url; + this.usedFileNames.add(lowerBaseName); + return `${baseName}.html`; } /** @@ -226,9 +239,9 @@ export class DefaultTheme extends Theme { const mapping = this.getMapping(reflection); if (mapping) { if (!reflection.url || !DefaultTheme.URL_PREFIX.test(reflection.url)) { - const url = [mapping.directory, DefaultTheme.getUrl(reflection) + ".html"].join("/"); + const url = [mapping.directory, this.getFileName(reflection)].join("/"); urls.push(new UrlMapping(url, reflection, mapping.template)); - this.sluggers.set(reflection, new Slugger()); + this.setSlugger(reflection, new Slugger(this.sluggerConfiguration)); reflection.url = url; reflection.hasOwnDocument = true; @@ -238,12 +251,12 @@ export class DefaultTheme extends Theme { if (child.isDeclaration() || child.isDocument()) { this.buildUrls(child, urls); } else { - DefaultTheme.applyAnchorUrl(child, reflection); + this.applyAnchorUrl(child, reflection); } return true; }); } else if (reflection.parent) { - DefaultTheme.applyAnchorUrl(reflection, reflection.parent); + this.applyAnchorUrl(reflection, reflection.parent); } return urls; @@ -431,23 +444,13 @@ export class DefaultTheme extends Theme { } } - private sluggers = new Map(); - - getSlugger(reflection: Reflection): Slugger { - if (this.sluggers.has(reflection)) { - return this.sluggers.get(reflection)!; - } - // A slugger should always be defined at least for the project - return this.getSlugger(reflection.parent!); - } - /** * Generate an anchor url for the given reflection and all of its children. * * @param reflection The reflection an anchor url should be created for. * @param container The nearest reflection having an own document. */ - static applyAnchorUrl(reflection: Reflection, container: Reflection) { + applyAnchorUrl(reflection: Reflection, container: Reflection) { if ( !(reflection instanceof DeclarationReflection) && !(reflection instanceof SignatureReflection) && @@ -457,7 +460,17 @@ export class DefaultTheme extends Theme { } if (!reflection.url || !DefaultTheme.URL_PREFIX.test(reflection.url)) { - const anchor = DefaultTheme.getUrl(reflection, container, "."); + let refl: Reflection | undefined = reflection; + let parts = [refl.name]; + while (refl.parent && refl.parent !== container && !(reflection.parent instanceof ProjectReflection)) { + refl = refl.parent; + // Avoid duplicate names for signatures + if (parts[0] !== refl.name) { + parts.unshift(refl.name); + } + } + + const anchor = this.getSlugger(reflection).slug(parts.join(".")); reflection.url = container.url! + "#" + anchor; reflection.anchor = anchor; @@ -465,7 +478,7 @@ export class DefaultTheme extends Theme { } reflection.traverse((child) => { - DefaultTheme.applyAnchorUrl(child, container); + this.applyAnchorUrl(child, container); return true; }); } diff --git a/src/lib/output/themes/default/DefaultThemeRenderContext.ts b/src/lib/output/themes/default/DefaultThemeRenderContext.ts index d0d56850a..d5634fea3 100644 --- a/src/lib/output/themes/default/DefaultThemeRenderContext.ts +++ b/src/lib/output/themes/default/DefaultThemeRenderContext.ts @@ -91,6 +91,10 @@ export class DefaultThemeRenderContext { return this._refIcons; } + get slugger() { + return this.theme.getSlugger(this.page.model); + } + hook: Renderer["hooks"]["emit"] = (...params) => { return this.theme.owner.hooks.emit(...params); }; diff --git a/src/lib/output/themes/default/Slugger.ts b/src/lib/output/themes/default/Slugger.ts index 0571bea1b..89895bfeb 100644 --- a/src/lib/output/themes/default/Slugger.ts +++ b/src/lib/output/themes/default/Slugger.ts @@ -1,3 +1,6 @@ +import { getSimilarValues } from "../../../utils/general.js"; +import type { TypeDocOptionMap } from "../../../utils/index.js"; + /** * Responsible for getting a unique anchor for elements within a page. */ @@ -5,6 +8,9 @@ export class Slugger { private seen = new Map(); private serialize(value: string) { + // Notes: + // There are quite a few trade-offs here. + return ( value .trim() @@ -19,19 +25,32 @@ export class Slugger { ); } + constructor(private options: TypeDocOptionMap["sluggerConfiguration"]) {} + slug(value: string) { const originalSlug = this.serialize(value); - let slug = originalSlug; + const lowerOriginalSlug = originalSlug.toLocaleLowerCase(); let count = 0; - if (this.seen.has(slug)) { - count = this.seen.get(originalSlug)!; + let slug = lowerOriginalSlug; + if (this.seen.has(lowerOriginalSlug)) { + count = this.seen.get(lowerOriginalSlug)!; do { count++; - slug = `${originalSlug}-${count}`; + slug = `${lowerOriginalSlug}-${count}`; } while (this.seen.has(slug)); } - this.seen.set(originalSlug, count); - this.seen.set(slug, 0); + this.seen.set(lowerOriginalSlug, count); + if (!this.options.lowercase) { + return count === 0 ? originalSlug : `${originalSlug}-${count}`; + } return slug; } + + hasAnchor(anchor: string) { + return this.seen.has(anchor); + } + + getSimilarAnchors(anchor: string) { + return getSimilarValues(this.seen.keys(), anchor); + } } diff --git a/src/lib/output/themes/default/partials/comment.tsx b/src/lib/output/themes/default/partials/comment.tsx index 46f508fec..54a4c359a 100644 --- a/src/lib/output/themes/default/partials/comment.tsx +++ b/src/lib/output/themes/default/partials/comment.tsx @@ -75,7 +75,7 @@ export function commentTags(context: DefaultThemeRenderContext, props: Reflectio ? `${context.internationalization.translateTagName(item.tag)}: ${item.name}` : context.internationalization.translateTagName(item.tag); - const anchor = props.getUniqueAliasInPage(name); + const anchor = context.slugger.slug(name); return ( <> diff --git a/src/lib/output/themes/default/partials/moduleReflection.tsx b/src/lib/output/themes/default/partials/moduleReflection.tsx index 939a43f9f..1a3585d4f 100644 --- a/src/lib/output/themes/default/partials/moduleReflection.tsx +++ b/src/lib/output/themes/default/partials/moduleReflection.tsx @@ -8,13 +8,11 @@ import { } from "../../../../models/index.js"; import { JSX, Raw } from "../../../../utils/index.js"; import { classNames, getDisplayName, getMemberSections, getUniquePath, join } from "../../lib.js"; -import { Slugger } from "../Slugger.js"; import type { DefaultThemeRenderContext } from "../DefaultThemeRenderContext.js"; import { anchorIcon } from "./anchor-icon.js"; export function moduleReflection(context: DefaultThemeRenderContext, mod: DeclarationReflection | ProjectReflection) { const sections = getMemberSections(mod); - const slugger = new Slugger(); return ( <> @@ -42,7 +40,7 @@ export function moduleReflection(context: DefaultThemeRenderContext, mod: Declar
    - {children.map((item) => context.moduleMemberSummary(item, slugger))} + {children.map((item) => context.moduleMemberSummary(item))}
    ); @@ -54,9 +52,8 @@ export function moduleReflection(context: DefaultThemeRenderContext, mod: Declar export function moduleMemberSummary( context: DefaultThemeRenderContext, member: DeclarationReflection | DocumentReflection, - slugger: Slugger, ) { - const id = slugger.slug(member.name); + const id = context.slugger.slug(member.name); context.page.pageHeadings.push({ link: `#${id}`, text: getDisplayName(member), diff --git a/src/lib/serialization/schema.ts b/src/lib/serialization/schema.ts index 456c421f4..bd8544c09 100644 --- a/src/lib/serialization/schema.ts +++ b/src/lib/serialization/schema.ts @@ -437,6 +437,10 @@ export interface RelativeLinkDisplayPart { * File ID, if present */ target?: number; + /** + * Anchor within the target file, if present + */ + targetAnchor?: string; } export interface SourceReference diff --git a/src/lib/utils/general.ts b/src/lib/utils/general.ts index 2e1c9a796..959033151 100644 --- a/src/lib/utils/general.ts +++ b/src/lib/utils/general.ts @@ -1,6 +1,7 @@ import { dirname } from "path"; import * as Util from "util"; import url from "url"; +import { DefaultMap } from "./map.js"; /** * This type provides a flag that can be used to turn off more lax overloads intended for @@ -56,11 +57,52 @@ export function assertNever(x: never): never { ); } -export function camelToTitleCase(text: string) { - return ( - text.substring(0, 1).toUpperCase() + - text.substring(1).replace(/[a-z][A-Z]/g, (x) => `${x[0]} ${x[1]}`) - ); +// Based on https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows +// Slightly modified for improved match results for options +export function editDistance(s: string, t: string): number { + if (s.length < t.length) return editDistance(t, s); + + let v0 = Array.from({ length: t.length + 1 }, (_, i) => i); + let v1 = Array.from({ length: t.length + 1 }, () => 0); + + for (let i = 0; i < s.length; i++) { + v1[0] = i + 1; + + for (let j = 0; j < s.length; j++) { + const deletionCost = v0[j + 1] + 1; + const insertionCost = v1[j] + 1; + let substitutionCost: number; + if (s[i] === t[j]) { + substitutionCost = v0[j]; + } else if (s[i]?.toUpperCase() === t[j]?.toUpperCase()) { + substitutionCost = v0[j] + 1; + } else { + substitutionCost = v0[j] + 3; + } + + v1[j + 1] = Math.min(deletionCost, insertionCost, substitutionCost); + } + + [v0, v1] = [v1, v0]; + } + + return v0[t.length]; +} + +export function getSimilarValues(values: Iterable, compareTo: string) { + const results = new DefaultMap(() => []); + let lowest = Infinity; + for (const name of values) { + const distance = editDistance(compareTo, name); + lowest = Math.min(lowest, distance); + results.get(distance).push(name); + } + + // Experimenting a bit, it seems an edit distance of 3 is roughly the + // right metric for relevant "similar" results without showing obviously wrong suggestions + return results + .get(lowest) + .concat(results.get(lowest + 1), results.get(lowest + 2)); } export function NonEnumerable( diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index ca349f4d3..b82c38939 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -197,6 +197,9 @@ export interface TypeDocOptionMap { readme: boolean; document: boolean; }; + sluggerConfiguration: { + lowercase: boolean; + }; visibilityFilters: ManuallyValidatedOption<{ protected?: boolean; private?: boolean; diff --git a/src/lib/utils/options/options.ts b/src/lib/utils/options/options.ts index 96fb0ab45..daa9f2a6f 100644 --- a/src/lib/utils/options/options.ts +++ b/src/lib/utils/options/options.ts @@ -2,7 +2,6 @@ import type * as ts from "typescript"; import { resolve } from "path"; import { ParameterType } from "./declaration.js"; import type { NeverIfInternal, OutputSpecification } from "../index.js"; -import { DefaultMap } from "../map.js"; import type { Application } from "../../../index.js"; import { insertOrderSorted, unique } from "../array.js"; import type { Logger } from "../loggers.js"; @@ -18,6 +17,7 @@ import { import { addTypeDocOptions } from "./sources/index.js"; import { getOptionsHelp } from "./help.js"; import type { TranslationProxy } from "../../internationalization/internationalization.js"; +import { getSimilarValues } from "../general.js"; /** * Describes an option reader that discovers user configuration and converts it to the @@ -442,19 +442,7 @@ export class Options { * Discover similar option names to the given name, for use in error reporting. */ getSimilarOptions(missingName: string): string[] { - const results = new DefaultMap(() => []); - let lowest = Infinity; - for (const name of this._declarations.keys()) { - const distance = editDistance(missingName, name); - lowest = Math.min(lowest, distance); - results.get(distance).push(name); - } - - // Experimenting a bit, it seems an edit distance of 3 is roughly the - // right metric for relevant "similar" results without showing obviously wrong suggestions - return results - .get(lowest) - .concat(results.get(lowest + 1), results.get(lowest + 2)); + return getSimilarValues(this._declarations.keys(), missingName); } /** @@ -492,35 +480,3 @@ export function Option(name: K) { }; }; } - -// Based on https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows -// Slightly modified for improved match results for options -function editDistance(s: string, t: string): number { - if (s.length < t.length) return editDistance(t, s); - - let v0 = Array.from({ length: t.length + 1 }, (_, i) => i); - let v1 = Array.from({ length: t.length + 1 }, () => 0); - - for (let i = 0; i < s.length; i++) { - v1[0] = i + 1; - - for (let j = 0; j < s.length; j++) { - const deletionCost = v0[j + 1] + 1; - const insertionCost = v1[j] + 1; - let substitutionCost: number; - if (s[i] === t[j]) { - substitutionCost = v0[j]; - } else if (s[i]?.toUpperCase() === t[j]?.toUpperCase()) { - substitutionCost = v0[j] + 1; - } else { - substitutionCost = v0[j] + 3; - } - - v1[j + 1] = Math.min(deletionCost, insertionCost, substitutionCost); - } - - [v0, v1] = [v1, v0]; - } - - return v0[t.length]; -} diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index d767691a4..25e43b3a4 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -600,7 +600,6 @@ export function addTypeDocOptions(options: Pick) { excludeReferences: false, }, }); - options.addDeclaration({ name: "headings", help: (i18n) => i18n.help_headings(), @@ -610,6 +609,14 @@ export function addTypeDocOptions(options: Pick) { document: false, }, }); + options.addDeclaration({ + name: "sluggerConfiguration", + help: (i18n) => i18n.help_sluggerConfiguration(), + type: ParameterType.Flags, + defaults: { + lowercase: true, + }, + }); options.addDeclaration({ name: "visibilityFilters", diff --git a/src/test/comments.test.ts b/src/test/comments.test.ts index 2dd3bd7a5..4faa3dcf3 100644 --- a/src/test/comments.test.ts +++ b/src/test/comments.test.ts @@ -1354,9 +1354,19 @@ describe("Comment Parser", () => { equal(comment.summary, [ { kind: "text", text: "[text](" }, - { kind: "relative-link", text: "./relative.md", target: 1 }, + { + kind: "relative-link", + text: "./relative.md", + target: 1, + targetAnchor: undefined, + }, { kind: "text", text: ") ![](" }, - { kind: "relative-link", text: "image.png", target: 2 }, + { + kind: "relative-link", + text: "image.png", + target: 2, + targetAnchor: undefined, + }, { kind: "text", text: ")\nNot relative: [passwd](/etc/passwd) [Windows](C:\\\\\\\\Windows) [example.com](http://example.com) [hash](#hash)", @@ -1379,12 +1389,22 @@ describe("Comment Parser", () => { { kind: "text", text: "[" }, { kind: "code", text: "`text`" }, { kind: "text", text: "](" }, - { kind: "relative-link", text: "./relative.md", target: 1 }, + { + kind: "relative-link", + text: "./relative.md", + target: 1, + targetAnchor: undefined, + }, // Labels can also include single newlines { kind: "text", text: ")\n[" }, { kind: "code", text: "`text`" }, { kind: "text", text: "\nmore](" }, - { kind: "relative-link", text: "./relative.md", target: 1 }, + { + kind: "relative-link", + text: "./relative.md", + target: 1, + targetAnchor: undefined, + }, // But not double! { kind: "text", text: ")\n[" }, { kind: "code", text: "`text`" }, @@ -1401,7 +1421,12 @@ describe("Comment Parser", () => { { kind: "text", text: "[" }, { kind: "code", text: "`text`" }, { kind: "text", text: "](" }, - { kind: "relative-link", text: "./relative.md", target: 1 }, + { + kind: "relative-link", + text: "./relative.md", + target: 1, + targetAnchor: undefined, + }, { kind: "text", text: ")" }, ] satisfies CommentDisplayPart[]); }); @@ -1416,12 +1441,18 @@ describe("Comment Parser", () => { equal(comment.summary, [ { kind: "text", text: "[1]: " }, - { kind: "relative-link", text: "./example.md", target: 1 }, + { + kind: "relative-link", + text: "./example.md", + target: 1, + targetAnchor: undefined, + }, { kind: "text", text: "\n[2]:" }, { kind: "relative-link", text: "<./example with space>", target: 2, + targetAnchor: undefined, }, { kind: "text", @@ -1449,12 +1480,18 @@ describe("Comment Parser", () => { equal(comment.summary, [ { kind: "text", text: '\n { equal(comment.summary, [ { kind: "text", text: '\n { ] satisfies CommentDisplayPart[]); }); + it("Recognizes anchors within relative links", () => { + const comment = getComment(`/** + * + * [test](./test.txt#bar) + */`); + + equal(comment.summary, [ + { kind: "text", text: '\n[test](' }, + { + kind: "relative-link", + text: "./test.txt#bar", + target: 2, + targetAnchor: "bar", + }, + { kind: "text", text: ")" }, + ] satisfies CommentDisplayPart[]); + }); + it("Properly handles character escapes", () => { const comment = getComment(`/** * @@ -1494,7 +1562,12 @@ describe("Comment Parser", () => { equal(comment.summary, [ { kind: "text", text: '' }, ] satisfies CommentDisplayPart[]); diff --git a/src/test/issues.c2.test.ts b/src/test/issues.c2.test.ts index 06790b1a4..10a38caae 100644 --- a/src/test/issues.c2.test.ts +++ b/src/test/issues.c2.test.ts @@ -802,15 +802,6 @@ describe("Issue Tests", () => { notEqual(type.types[1], "intersection"); }); - it("#2012", () => { - const project = convert(); - project.hasOwnDocument = true; - const model = query(project, "model"); - const Model = query(project, "Model"); - equal(model.getAlias(), "model"); - equal(Model.getAlias(), "Model-1"); - }); - it("#2019", () => { const project = convert(); const param = query(project, "A.constructor").signatures![0] diff --git a/src/test/output/Slugger.test.ts b/src/test/output/Slugger.test.ts new file mode 100644 index 000000000..f11f9c1b6 --- /dev/null +++ b/src/test/output/Slugger.test.ts @@ -0,0 +1,16 @@ +import { deepStrictEqual as equal } from "assert"; +import { Slugger } from "../../lib/output/index.js"; + +describe("Slugger", () => { + it("Is case sensitive #2012", () => { + const slugger = new Slugger({ lowercase: true }); + equal(slugger.slug("model"), "model"); + equal(slugger.slug("Model"), "model-1"); + }); + + it("Is case sensitive even when lowercasing output is disabled", () => { + const slugger = new Slugger({ lowercase: false }); + equal(slugger.slug("model"), "model"); + equal(slugger.slug("Model"), "Model-1"); + }); +}); From 92dbd3b0cda378c516af66ac7359c74be8ecc2d2 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 20:17:12 -0700 Subject: [PATCH 109/219] Fix lint --- src/lib/output/themes/MarkedPlugin.tsx | 7 +------ src/lib/output/themes/default/DefaultTheme.tsx | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/output/themes/MarkedPlugin.tsx b/src/lib/output/themes/MarkedPlugin.tsx index 4df2618db..3108074a2 100644 --- a/src/lib/output/themes/MarkedPlugin.tsx +++ b/src/lib/output/themes/MarkedPlugin.tsx @@ -193,13 +193,8 @@ export class MarkedPlugin extends ContextAwareRendererComponent { target: refl, link: part, }); - } else { - console.log("NOPE", part); } } - if (url.endsWith("Options.Configuration.html")) { - debugger; - } result.push(url); break; } @@ -296,7 +291,7 @@ export class MarkedPlugin extends ContextAwareRendererComponent { return `<${token.tag} class="tsd-anchor-link">`; }; this.parser.renderer.rules["heading_close"] = (tokens, idx) => { - return `${renderElement(anchorIcon(this.renderContext, `${this.lastHeaderSlug}`))}`; + return `${renderElement(anchorIcon(this.renderContext, this.lastHeaderSlug))}`; }; // Rewrite anchor links inline in a readme file to links targeting the `md:` prefixed anchors diff --git a/src/lib/output/themes/default/DefaultTheme.tsx b/src/lib/output/themes/default/DefaultTheme.tsx index 4dfbd8e2e..70f9122c2 100644 --- a/src/lib/output/themes/default/DefaultTheme.tsx +++ b/src/lib/output/themes/default/DefaultTheme.tsx @@ -461,7 +461,7 @@ export class DefaultTheme extends Theme { if (!reflection.url || !DefaultTheme.URL_PREFIX.test(reflection.url)) { let refl: Reflection | undefined = reflection; - let parts = [refl.name]; + const parts = [refl.name]; while (refl.parent && refl.parent !== container && !(reflection.parent instanceof ProjectReflection)) { refl = refl.parent; // Avoid duplicate names for signatures From b5fd8d066a7532f194b2ed645391dc03551aae86 Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 20:18:26 -0700 Subject: [PATCH 110/219] Add missed issue number to changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1b6ce7f3..749fe6ceb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ title: Changelog improve their documentation, #2654.. - Added a new `@mergeModuleWith` tag which can be used to tell TypeDoc to place a module/namespace's children under a different module/namespace and - remove the real parent. + remove the real parent, #2281. - Add `notRenderedTags` option. This option is similar to the `excludeTags` option, but while `excludeTags` will result in the tag being completely removed from the documentation, `notRenderedTags` only prevents it from From 6aff5d60ce87d9cabfd0e7126fd5f8cd0529dd1f Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 3 Nov 2024 20:35:24 -0700 Subject: [PATCH 111/219] Bump version to 0.27.0-beta.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe5ec53f9..47691648f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typedoc", - "version": "0.26.11", + "version": "0.27.0-beta.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typedoc", - "version": "0.26.11", + "version": "0.27.0-beta.0", "license": "Apache-2.0", "dependencies": { "lunr": "^2.3.9", diff --git a/package.json b/package.json index 89723e739..26f9570f9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typedoc", "description": "Create api documentation for TypeScript projects.", - "version": "0.26.11", + "version": "0.27.0-beta.0", "homepage": "https://typedoc.org", "type": "module", "exports": { From 700ae5d3647e35f357c14dd472badfcf81f9fe0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xuan=20Huang=20=28=E9=BB=84=E7=8E=84=29?= Date: Mon, 4 Nov 2024 15:01:49 -0800 Subject: [PATCH 112/219] Correct "kind_parameter" in zh.cts Re how to review if you don't understand Chinese: try ask ChatGPT? --- src/lib/internationalization/locales/zh.cts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index 0dbd39a69..32df644fe 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -374,7 +374,7 @@ export = buildIncompleteTranslation({ kind_call_signature: "调用签名", kind_index_signature: "索引签名", kind_constructor_signature: "构造函数签名", - kind_parameter: "范围", + kind_parameter: "参数", kind_type_literal: "类型字面量", kind_type_parameter: "类型参数", kind_accessor: "访问器", From 70491cc6094e61dea590c06b60f6aa2ca8de06ff Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Fri, 8 Nov 2024 20:58:30 -0700 Subject: [PATCH 113/219] Support TypeScript 5.7, drop TS <5.0 Also fix readonly index signatures. --- CHANGELOG.md | 3 + eslint.config.mjs | 3 + package-lock.json | 10 +- package.json | 4 +- site/overview.md | 2 +- .../converter/factories/index-signature.ts | 73 ++- src/lib/converter/symbols.ts | 4 +- src/lib/converter/types.ts | 4 +- src/lib/output/formatter.tsx | 10 + .../themes/default/partials/typeDetails.tsx | 1 + .../themes/default/templates/reflection.tsx | 1 + src/lib/utils/jsx.elements.ts | 4 +- src/lib/utils/jsx.ts | 82 ++- src/test/converter/types/index-signature.ts | 17 + src/test/converter/types/specs.json | 580 +++++++++++++----- 15 files changed, 572 insertions(+), 226 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 749fe6ceb..859c60be0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ title: Changelog ## Breaking Changes +- Drop support for TypeScript <5.0, no longer supported by DefinitelyTyped - Relaxed requirements for file names and generated url fragments. This may result in a different file name structure, #2714. - Anchors to document headings and reflections within a HTML generated pages @@ -30,6 +31,7 @@ title: Changelog ## Features +- Add support for TypeScript 5.7 - TypeDoc will now discover entry points from `package.json` exports if they are not provided manually, #1937. - Relative links to markdown files may now include `#anchor` links to @@ -79,6 +81,7 @@ title: Changelog ## Bug Fixes +- TypeDoc now properly flags `readonly` index signatures. - TypeDoc will now use the first signature's comment for later signatures in overloads if present, #2718. - Fixed handling of `@enum` if the type was declared before the variable, #2719. diff --git a/eslint.config.mjs b/eslint.config.mjs index ccf15c5b2..7a01c86dc 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -8,6 +8,9 @@ const config = { parserOptions: { project: true, tsconfigRootDir: import.meta.dirname, + // We're fairly frequently on a later version of the TS compiler than + // is officially supported. So far this has never been a real problem. + warnOnUnsupportedTypeScriptVersion: false, }, }, rules: { diff --git a/package-lock.json b/package-lock.json index 47691648f..b272c6fbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,14 +33,14 @@ "puppeteer": "^23.6.1", "semver": "^7.6.3", "tsx": "^4.19.2", - "typescript": "5.6.3", + "typescript": "5.7.1-rc", "typescript-eslint": "^8.12.2" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -4922,9 +4922,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.1-rc", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.1-rc.tgz", + "integrity": "sha512-d6m+HT78uZtyUbXbUyIvuJ6kXCTSJEfy+2pZSUwt9d6JZ0kOMNDwhIILfV5FnaxMwVa48Yfw4sK0ISC4Qyq5tw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 26f9570f9..d6bd0fd64 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "yaml": "^2.6.0" }, "peerDependencies": { - "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x" + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" }, "devDependencies": { "@types/lunr": "^2.3.7", @@ -49,7 +49,7 @@ "puppeteer": "^23.6.1", "semver": "^7.6.3", "tsx": "^4.19.2", - "typescript": "5.6.3", + "typescript": "5.7.1-rc", "typescript-eslint": "^8.12.2" }, "files": [ diff --git a/site/overview.md b/site/overview.md index eb93d0733..7fa80a0a6 100644 --- a/site/overview.md +++ b/site/overview.md @@ -18,7 +18,7 @@ support more versions of TypeScript. | TypeDoc Version | TypeScript Version | | --------------- | ------------------ | -| 0.27 | 4.6 through 5.7 | +| 0.27 | 5.0 through 5.7 | | 0.26 | 4.6 through 5.6 | | 0.25 | 4.6 through 5.4 | | 0.24 | 4.6 through 5.1 | diff --git a/src/lib/converter/factories/index-signature.ts b/src/lib/converter/factories/index-signature.ts index 24ebcbefb..c2b6bf406 100644 --- a/src/lib/converter/factories/index-signature.ts +++ b/src/lib/converter/factories/index-signature.ts @@ -1,56 +1,97 @@ import assert from "assert"; -import ts from "typescript"; +import type ts from "typescript"; import { DeclarationReflection, ParameterReflection, + ReflectionFlag, ReflectionKind, SignatureReflection, + UnionType, } from "../../models/index.js"; import type { Context } from "../context.js"; import { ConverterEvents } from "../converter-events.js"; -export function convertIndexSignatures(context: Context, symbol: ts.Symbol) { +export function convertIndexSignatures(context: Context, type: ts.Type) { assert(context.scope instanceof DeclarationReflection); - const indexSymbol = symbol.members?.get("__index" as ts.__String); - if (!indexSymbol) return; + // Each declaration should have one SignatureReflection + // If we don't have a declaration, the index signature was inferred by TS + // and we should make a separate SignatureReflection for each index signature. + const seenByDeclaration = new Map(); + const createdSignatures: [ + ts.IndexSignatureDeclaration | undefined, + SignatureReflection, + ][] = []; - for (const indexDeclaration of indexSymbol.getDeclarations() || []) { - assert(ts.isIndexSignatureDeclaration(indexDeclaration)); - const param = indexDeclaration.parameters[0] as - | ts.ParameterDeclaration - | undefined; - assert(param && ts.isParameter(param)); + for (const indexInfo of context.checker.getIndexInfosOfType(type)) { + // Check if we've already created an index signature for this type + if ( + indexInfo.declaration && + seenByDeclaration.has(indexInfo.declaration) + ) { + const createdSig = seenByDeclaration.get(indexInfo.declaration)!; + if (createdSig.parameters![0].type?.type !== "union") { + createdSig.parameters![0].type = new UnionType([ + createdSig.parameters![0].type!, + ]); + } + createdSig.parameters![0].type.types.push( + context.converter.convertType( + context.withScope(createdSig), + indexInfo.keyType, + ), + ); + // No need to update the return type as it will be the same for all members. + continue; + } + + // Otherwise create a new one const index = new SignatureReflection( "__index", ReflectionKind.IndexSignature, context.scope, ); - index.comment = context.getNodeComment(indexDeclaration, false); + if (indexInfo.isReadonly) { + index.setFlag(ReflectionFlag.Readonly); + } + + createdSignatures.push([indexInfo.declaration, index]); + if (indexInfo.declaration) { + seenByDeclaration.set(indexInfo.declaration, index); + index.comment = context.getNodeComment( + indexInfo.declaration, + /* moduleComment */ false, + ); + } + index.parameters = [ new ParameterReflection( - param.name.getText(), + indexInfo.declaration?.parameters[0].name.getText() ?? "key", ReflectionKind.Parameter, index, ), ]; index.parameters[0].type = context.converter.convertType( context.withScope(index.parameters[0]), - param.type, + indexInfo.keyType, ); index.type = context.converter.convertType( context.withScope(index), - indexDeclaration.type, + indexInfo.type, ); - context.registerReflection(index, indexSymbol); + + context.registerReflection(index, indexInfo.declaration?.symbol); context.scope.indexSignatures ||= []; context.scope.indexSignatures.push(index); + } + // Now that we've created everything, trigger events for them. + for (const [declaration, index] of createdSignatures) { context.converter.trigger( ConverterEvents.CREATE_SIGNATURE, context, index, - indexDeclaration, + declaration, ); } } diff --git a/src/lib/converter/symbols.ts b/src/lib/converter/symbols.ts index 3da497b51..ee6f3a9cc 100644 --- a/src/lib/converter/symbols.ts +++ b/src/lib/converter/symbols.ts @@ -459,7 +459,7 @@ function convertTypeAliasAsInterface( convertConstructSignatures(rc, symbol); // And finally, index signatures - convertIndexSignatures(rc, symbol); + convertIndexSignatures(rc, type); } function convertFunctionOrMethod( @@ -674,7 +674,7 @@ function convertClassOrInterface( convertConstructSignatures(reflectionContext, symbol); // And finally, index signatures - convertIndexSignatures(reflectionContext, symbol); + convertIndexSignatures(reflectionContext, instanceType); // Normally this shouldn't matter, unless someone did something with skipLibCheck on. return ts.SymbolFlags.Alias; diff --git a/src/lib/converter/types.ts b/src/lib/converter/types.ts index bea1b7b20..0ed2f63b0 100644 --- a/src/lib/converter/types.ts +++ b/src/lib/converter/types.ts @@ -631,7 +631,7 @@ const typeLiteralConverter: TypeConverter = { ); } - convertIndexSignatures(rc, symbol); + convertIndexSignatures(rc, type); return new ReflectionType(reflection); }, @@ -670,7 +670,7 @@ const typeLiteralConverter: TypeConverter = { } if (symbol) { - convertIndexSignatures(context.withScope(reflection), symbol); + convertIndexSignatures(context.withScope(reflection), type); } return new ReflectionType(reflection); diff --git a/src/lib/output/formatter.tsx b/src/lib/output/formatter.tsx index 2871aa8d2..4e7944508 100644 --- a/src/lib/output/formatter.tsx +++ b/src/lib/output/formatter.tsx @@ -724,6 +724,16 @@ export class FormattedCodeBuilder { for (const index of reflection.indexSignatures) { members.push( nodes( + ...(index.flags.isReadonly + ? [ + simpleElement( + + readonly + , + ), + space(), + ] + : []), simpleElement( [, ), diff --git a/src/lib/output/themes/default/partials/typeDetails.tsx b/src/lib/output/themes/default/partials/typeDetails.tsx index 149706794..bf92fe808 100644 --- a/src/lib/output/themes/default/partials/typeDetails.tsx +++ b/src/lib/output/themes/default/partials/typeDetails.tsx @@ -309,6 +309,7 @@ function renderIndexSignature(context: DefaultThemeRenderContext, index: Signatu return (
  • + {index.flags.isReadonly && readonly } [ {index.parameters!.map((item) => ( <> diff --git a/src/lib/output/themes/default/templates/reflection.tsx b/src/lib/output/themes/default/templates/reflection.tsx index 668791037..022176d33 100644 --- a/src/lib/output/themes/default/templates/reflection.tsx +++ b/src/lib/output/themes/default/templates/reflection.tsx @@ -84,6 +84,7 @@ function renderIndexSignature(context: DefaultThemeRenderContext, index: Signatu return (
  • + {index.flags.isReadonly && readonly } [ {index.parameters!.map((item) => ( <> diff --git a/src/lib/utils/jsx.elements.ts b/src/lib/utils/jsx.elements.ts index d4a9928f6..b60898e20 100644 --- a/src/lib/utils/jsx.elements.ts +++ b/src/lib/utils/jsx.elements.ts @@ -127,7 +127,9 @@ export interface IntrinsicElements { text: JsxTextElementProps; } -export const JsxFragment: unique symbol = Symbol(); +export function JsxFragment(): never { + throw new Error("Should never be called"); +} export type JsxComponent

    = (props: P) => JsxElement | null | undefined; diff --git a/src/lib/utils/jsx.ts b/src/lib/utils/jsx.ts index c16c06547..8e5959674 100644 --- a/src/lib/utils/jsx.ts +++ b/src/lib/utils/jsx.ts @@ -21,7 +21,7 @@ import type { JsxChildren, JsxComponent, } from "./jsx.elements.js"; -import { JsxFragment as Fragment } from "./jsx.elements.js"; +import { JsxFragment } from "./jsx.elements.js"; export type { JsxElement as Element, @@ -94,7 +94,7 @@ const blockElements = new Set([ * @param children */ export function createElement( - tag: typeof Fragment | string | JsxComponent, + tag: string | JsxComponent, props: object | null, ...children: JsxChildren[] ): JsxElement { @@ -112,61 +112,55 @@ export function renderElement(element: JsxElement | null | undefined): string { } const { tag, props, children } = element; + let html = ""; if (typeof tag === "function") { if (tag === Raw) { return String((props as any).html); } + if (tag === JsxFragment) { + renderChildren(children); + return html; + } return renderElement(tag(Object.assign({ children }, props))); } - let html = ""; - - if (tag !== Fragment) { - if (blockElements.has(tag) && renderPretty && html) { - html += "\n"; - } - html += "<"; - html += tag; + if (blockElements.has(tag) && renderPretty && html) { + html += "\n"; + } + html += "<"; + html += tag; - for (const [key, val] of Object.entries(props ?? {})) { - if (val == null) continue; + for (const [key, val] of Object.entries(props ?? {})) { + if (val == null) continue; - if (typeof val == "boolean") { - if (val) { - html += " "; - html += key; - } - } else { + if (typeof val == "boolean") { + if (val) { html += " "; html += key; - html += '="'; - html += ( - typeof val === "string" ? val : JSON.stringify(val) - ).replaceAll('"', """); - html += '"'; } + } else { + html += " "; + html += key; + html += '="'; + html += ( + typeof val === "string" ? val : JSON.stringify(val) + ).replaceAll('"', """); + html += '"'; } } - let hasChildren = false; if (children.length) { - hasChildren = true; - if (tag !== Fragment) html += ">"; + html += ">"; renderChildren(children); - } - - if (tag !== Fragment) { - if (!hasChildren) { - if (voidElements.has(tag)) { - html += "/>"; - } else { - html += ">"; - } + html += ""; + } else { + if (voidElements.has(tag)) { + html += "/>"; } else { - html += ""; } @@ -200,22 +194,22 @@ export function renderElementToText(element: JsxElement | null | undefined) { } const { tag, props, children } = element; + let html = ""; if (typeof tag === "function") { if (tag === Raw) { return String((props as any).html); } + if (tag === JsxFragment) { + renderChildren(children); + return html; + } return renderElementToText(tag(Object.assign({ children }, props))); } else if (tag === "br") { return "\n"; } - let html = ""; - - if (children.length) { - renderChildren(children); - } - + renderChildren(children); return html; function renderChildren(children: JsxChildren[]) { diff --git a/src/test/converter/types/index-signature.ts b/src/test/converter/types/index-signature.ts index f74804f16..92f70e73c 100644 --- a/src/test/converter/types/index-signature.ts +++ b/src/test/converter/types/index-signature.ts @@ -8,4 +8,21 @@ export interface PartialIndex { export interface UnionIndex { [optName: string | symbol]: unknown; + [numName: number]: string; +} + +export interface ReadonlyIndex { + readonly [x: string]: string; +} + +declare const symbolMethodName: symbol; +declare const symbolPropertyName: symbol; + +export class A { + [symbolMethodName]() { + return 1; + } + [symbolPropertyName]() { + return "x"; + } } diff --git a/src/test/converter/types/specs.json b/src/test/converter/types/specs.json index 066942332..568bc63f3 100644 --- a/src/test/converter/types/specs.json +++ b/src/test/converter/types/specs.json @@ -330,6 +330,158 @@ "kind": 2, "flags": {}, "children": [ + { + "id": 28, + "name": "A", + "variant": "declaration", + "kind": 128, + "flags": {}, + "children": [ + { + "id": 29, + "name": "constructor", + "variant": "declaration", + "kind": 512, + "flags": {}, + "signatures": [ + { + "id": 30, + "name": "A", + "variant": "signature", + "kind": 16384, + "flags": {}, + "type": { + "type": "reference", + "target": 28, + "name": "A", + "package": "typedoc" + } + } + ] + } + ], + "groups": [ + { + "title": "Constructors", + "children": [ + 29 + ] + } + ], + "sources": [ + { + "fileName": "index-signature.ts", + "line": 21, + "character": 13, + "url": "typedoc://index-signature.ts#L21" + } + ], + "indexSignatures": [ + { + "id": 31, + "name": "__index", + "variant": "signature", + "kind": 8192, + "flags": {}, + "parameters": [ + { + "id": 32, + "name": "key", + "variant": "param", + "kind": 32768, + "flags": {}, + "type": { + "type": "intrinsic", + "name": "symbol" + } + } + ], + "type": { + "type": "union", + "types": [ + { + "type": "reflection", + "declaration": { + "id": 33, + "name": "__type", + "variant": "declaration", + "kind": 65536, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 22, + "character": 4, + "url": "typedoc://index-signature.ts#L22" + } + ], + "signatures": [ + { + "id": 34, + "name": "__type", + "variant": "signature", + "kind": 4096, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 22, + "character": 4, + "url": "typedoc://index-signature.ts#L22" + } + ], + "type": { + "type": "intrinsic", + "name": "number" + } + } + ] + } + }, + { + "type": "reflection", + "declaration": { + "id": 35, + "name": "__type", + "variant": "declaration", + "kind": 65536, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 25, + "character": 4, + "url": "typedoc://index-signature.ts#L25" + } + ], + "signatures": [ + { + "id": 36, + "name": "__type", + "variant": "signature", + "kind": 4096, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 25, + "character": 4, + "url": "typedoc://index-signature.ts#L25" + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + } + } + ] + } + } + ] + }, { "id": 17, "name": "PartialIndex", @@ -388,6 +540,57 @@ } ] }, + { + "id": 25, + "name": "ReadonlyIndex", + "variant": "declaration", + "kind": 256, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 14, + "character": 17, + "url": "typedoc://index-signature.ts#L14" + } + ], + "indexSignatures": [ + { + "id": 26, + "name": "__index", + "variant": "signature", + "kind": 8192, + "flags": { + "isReadonly": true + }, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 15, + "character": 4, + "url": "typedoc://index-signature.ts#L15" + } + ], + "parameters": [ + { + "id": 27, + "name": "x", + "variant": "param", + "kind": 32768, + "flags": {}, + "type": { + "type": "intrinsic", + "name": "string" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } + } + ] + }, { "id": 14, "name": "SymbolIndex", @@ -492,15 +695,54 @@ "type": "intrinsic", "name": "unknown" } + }, + { + "id": 23, + "name": "__index", + "variant": "signature", + "kind": 8192, + "flags": {}, + "sources": [ + { + "fileName": "index-signature.ts", + "line": 11, + "character": 4, + "url": "typedoc://index-signature.ts#L11" + } + ], + "parameters": [ + { + "id": 24, + "name": "numName", + "variant": "param", + "kind": 32768, + "flags": {}, + "type": { + "type": "intrinsic", + "name": "number" + } + } + ], + "type": { + "type": "intrinsic", + "name": "string" + } } ] } ], "groups": [ + { + "title": "Classes", + "children": [ + 28 + ] + }, { "title": "Interfaces", "children": [ 17, + 25, 14, 20 ] @@ -516,14 +758,14 @@ ] }, { - "id": 23, + "id": 37, "name": "mapped", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 34, + "id": 48, "name": "DoubleKey", "variant": "declaration", "kind": 2097152, @@ -538,7 +780,7 @@ ], "typeParameters": [ { - "id": 35, + "id": 49, "name": "T", "variant": "typeParam", "kind": 131072, @@ -556,7 +798,7 @@ "operator": "keyof", "target": { "type": "reference", - "target": 35, + "target": 49, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -582,7 +824,7 @@ }, "objectType": { "type": "reference", - "target": 35, + "target": 49, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -623,7 +865,7 @@ } }, { - "id": 32, + "id": 46, "name": "Mappy", "variant": "declaration", "kind": 2097152, @@ -638,7 +880,7 @@ ], "typeParameters": [ { - "id": 33, + "id": 47, "name": "T", "variant": "typeParam", "kind": 131072, @@ -653,7 +895,7 @@ "operator": "keyof", "target": { "type": "reference", - "target": 33, + "target": 47, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -673,7 +915,7 @@ }, "objectType": { "type": "reference", - "target": 33, + "target": 47, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -682,7 +924,7 @@ } }, { - "id": 28, + "id": 42, "name": "doubleKey", "variant": "declaration", "kind": 64, @@ -697,7 +939,7 @@ ], "signatures": [ { - "id": 29, + "id": 43, "name": "doubleKey", "variant": "signature", "kind": 4096, @@ -712,7 +954,7 @@ ], "typeParameters": [ { - "id": 30, + "id": 44, "name": "T", "variant": "typeParam", "kind": 131072, @@ -721,14 +963,14 @@ ], "parameters": [ { - "id": 31, + "id": 45, "name": "arg", "variant": "param", "kind": 32768, "flags": {}, "type": { "type": "reference", - "target": 30, + "target": 44, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -756,7 +998,7 @@ }, "objectType": { "type": "reference", - "target": 30, + "target": 44, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -799,7 +1041,7 @@ ] }, { - "id": 24, + "id": 38, "name": "mapped", "variant": "declaration", "kind": 64, @@ -814,7 +1056,7 @@ ], "signatures": [ { - "id": 25, + "id": 39, "name": "mapped", "variant": "signature", "kind": 4096, @@ -829,7 +1071,7 @@ ], "typeParameters": [ { - "id": 26, + "id": 40, "name": "T", "variant": "typeParam", "kind": 131072, @@ -838,14 +1080,14 @@ ], "parameters": [ { - "id": 27, + "id": 41, "name": "arg", "variant": "param", "kind": 32768, "flags": {}, "type": { "type": "reference", - "target": 26, + "target": 40, "name": "T", "package": "typedoc", "refersToTypeParameter": true @@ -887,15 +1129,15 @@ { "title": "Type Aliases", "children": [ - 34, - 32 + 48, + 46 ] }, { "title": "Functions", "children": [ - 28, - 24 + 42, + 38 ] } ], @@ -909,14 +1151,14 @@ ] }, { - "id": 36, + "id": 50, "name": "parens", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 37, + "id": 51, "name": "ZZ", "variant": "declaration", "kind": 2097152, @@ -939,14 +1181,14 @@ { "type": "reflection", "declaration": { - "id": 38, + "id": 52, "name": "__type", "variant": "declaration", "kind": 65536, "flags": {}, "children": [ { - "id": 39, + "id": 53, "name": "a", "variant": "declaration", "kind": 1024, @@ -969,7 +1211,7 @@ { "title": "Properties", "children": [ - 39 + 53 ] } ], @@ -991,7 +1233,7 @@ { "title": "Type Aliases", "children": [ - 37 + 51 ] } ], @@ -1005,14 +1247,14 @@ ] }, { - "id": 40, + "id": 54, "name": "query", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 42, + "id": 56, "name": "TypeOfX", "variant": "declaration", "kind": 2097152, @@ -1029,14 +1271,14 @@ "type": "query", "queryType": { "type": "reference", - "target": 41, + "target": 55, "name": "x", "package": "typedoc" } } }, { - "id": 41, + "id": 55, "name": "x", "variant": "declaration", "kind": 32, @@ -1062,13 +1304,13 @@ { "title": "Type Aliases", "children": [ - 42 + 56 ] }, { "title": "Variables", "children": [ - 41 + 55 ] } ], @@ -1082,14 +1324,14 @@ ] }, { - "id": 43, + "id": 57, "name": "tuple", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 52, + "id": 66, "name": "LeadingRest", "variant": "declaration", "kind": 2097152, @@ -1123,7 +1365,7 @@ } }, { - "id": 44, + "id": 58, "name": "NamedTuple", "variant": "declaration", "kind": 2097152, @@ -1161,7 +1403,7 @@ } }, { - "id": 50, + "id": 64, "name": "WithOptionalElements", "variant": "declaration", "kind": 2097152, @@ -1199,7 +1441,7 @@ } }, { - "id": 46, + "id": 60, "name": "WithRestType", "variant": "declaration", "kind": 2097152, @@ -1233,7 +1475,7 @@ } }, { - "id": 48, + "id": 62, "name": "WithRestTypeNames", "variant": "declaration", "kind": 2097152, @@ -1274,7 +1516,7 @@ } }, { - "id": 53, + "id": 67, "name": "leadingRest", "variant": "declaration", "kind": 32, @@ -1311,7 +1553,7 @@ "defaultValue": "..." }, { - "id": 45, + "id": 59, "name": "namedTuple", "variant": "declaration", "kind": 32, @@ -1352,7 +1594,7 @@ "defaultValue": "..." }, { - "id": 51, + "id": 65, "name": "withOptionalElements", "variant": "declaration", "kind": 32, @@ -1393,7 +1635,7 @@ "defaultValue": "..." }, { - "id": 47, + "id": 61, "name": "withRestType", "variant": "declaration", "kind": 32, @@ -1430,7 +1672,7 @@ "defaultValue": "..." }, { - "id": 49, + "id": 63, "name": "withRestTypeNames", "variant": "declaration", "kind": 32, @@ -1481,21 +1723,21 @@ { "title": "Type Aliases", "children": [ - 52, - 44, - 50, - 46, - 48 + 66, + 58, + 64, + 60, + 62 ] }, { "title": "Variables", "children": [ - 53, - 45, - 51, - 47, - 49 + 67, + 59, + 65, + 61, + 63 ] } ], @@ -1509,14 +1751,14 @@ ] }, { - "id": 54, + "id": 68, "name": "type-operator", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 56, + "id": 70, "name": "B", "variant": "declaration", "kind": 2097152, @@ -1542,7 +1784,7 @@ } }, { - "id": 57, + "id": 71, "name": "C", "variant": "declaration", "kind": 2097152, @@ -1558,14 +1800,14 @@ "type": { "type": "reflection", "declaration": { - "id": 58, + "id": 72, "name": "__type", "variant": "declaration", "kind": 65536, "flags": {}, "children": [ { - "id": 59, + "id": 73, "name": "prop1", "variant": "declaration", "kind": 1024, @@ -1584,7 +1826,7 @@ } }, { - "id": 60, + "id": 74, "name": "prop2", "variant": "declaration", "kind": 1024, @@ -1607,8 +1849,8 @@ { "title": "Properties", "children": [ - 59, - 60 + 73, + 74 ] } ], @@ -1624,7 +1866,7 @@ } }, { - "id": 61, + "id": 75, "name": "D", "variant": "declaration", "kind": 2097152, @@ -1642,14 +1884,14 @@ "operator": "keyof", "target": { "type": "reference", - "target": 57, + "target": 71, "name": "C", "package": "typedoc" } } }, { - "id": 55, + "id": 69, "name": "a", "variant": "declaration", "kind": 32, @@ -1679,15 +1921,15 @@ { "title": "Type Aliases", "children": [ - 56, - 57, - 61 + 70, + 71, + 75 ] }, { "title": "Variables", "children": [ - 55 + 69 ] } ], @@ -1701,14 +1943,14 @@ ] }, { - "id": 62, + "id": 76, "name": "union-or-intersection", "variant": "declaration", "kind": 2, "flags": {}, "children": [ { - "id": 63, + "id": 77, "name": "FirstType", "variant": "declaration", "kind": 256, @@ -1723,7 +1965,7 @@ }, "children": [ { - "id": 64, + "id": 78, "name": "firstProperty", "variant": "declaration", "kind": 1024, @@ -1754,7 +1996,7 @@ { "title": "Properties", "children": [ - 64 + 78 ] } ], @@ -1768,7 +2010,7 @@ ] }, { - "id": 65, + "id": 79, "name": "SecondType", "variant": "declaration", "kind": 256, @@ -1783,7 +2025,7 @@ }, "children": [ { - "id": 66, + "id": 80, "name": "secondProperty", "variant": "declaration", "kind": 1024, @@ -1814,7 +2056,7 @@ { "title": "Properties", "children": [ - 66 + 80 ] } ], @@ -1828,7 +2070,7 @@ ] }, { - "id": 67, + "id": 81, "name": "ThirdType", "variant": "declaration", "kind": 256, @@ -1843,7 +2085,7 @@ }, "children": [ { - "id": 70, + "id": 84, "name": "thirdComplexProperty", "variant": "declaration", "kind": 1024, @@ -1880,13 +2122,13 @@ "types": [ { "type": "reference", - "target": 63, + "target": 77, "name": "FirstType", "package": "typedoc" }, { "type": "reference", - "target": 65, + "target": 79, "name": "SecondType", "package": "typedoc" } @@ -1898,7 +2140,7 @@ } }, { - "id": 69, + "id": 83, "name": "thirdIntersectionProperty", "variant": "declaration", "kind": 1024, @@ -1924,13 +2166,13 @@ "types": [ { "type": "reference", - "target": 63, + "target": 77, "name": "FirstType", "package": "typedoc" }, { "type": "reference", - "target": 67, + "target": 81, "name": "ThirdType", "package": "typedoc" } @@ -1938,7 +2180,7 @@ } }, { - "id": 68, + "id": 82, "name": "thirdUnionProperty", "variant": "declaration", "kind": 1024, @@ -1964,13 +2206,13 @@ "types": [ { "type": "reference", - "target": 63, + "target": 77, "name": "FirstType", "package": "typedoc" }, { "type": "reference", - "target": 65, + "target": 79, "name": "SecondType", "package": "typedoc" } @@ -1982,9 +2224,9 @@ { "title": "Properties", "children": [ - 70, - 69, - 68 + 84, + 83, + 82 ] } ], @@ -2002,9 +2244,9 @@ { "title": "Interfaces", "children": [ - 63, - 65, - 67 + 77, + 79, + 81 ] } ], @@ -2024,12 +2266,12 @@ "children": [ 1, 13, - 23, - 36, - 40, - 43, + 37, + 50, 54, - 62 + 57, + 68, + 76 ] } ], @@ -2112,194 +2354,226 @@ "qualifiedName": "UnionIndex.__index" }, "23": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "UnionIndex.__index" + }, + "25": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "ReadonlyIndex" + }, + "26": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "ReadonlyIndex.__index" + }, + "28": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "A" + }, + "33": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "A.__computed" + }, + "34": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "A.__computed" + }, + "35": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "A.__computed" + }, + "36": { + "sourceFileName": "src/test/converter/types/index-signature.ts", + "qualifiedName": "A.__computed" + }, + "37": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "" }, - "24": { + "38": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "mapped" }, - "25": { + "39": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "mapped" }, - "26": { + "40": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "T" }, - "27": { + "41": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "arg" }, - "28": { + "42": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "doubleKey" }, - "29": { + "43": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "doubleKey" }, - "30": { + "44": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "T" }, - "31": { + "45": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "arg" }, - "32": { + "46": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "Mappy" }, - "33": { + "47": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "T" }, - "34": { + "48": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "DoubleKey" }, - "35": { + "49": { "sourceFileName": "src/test/converter/types/mapped.ts", "qualifiedName": "T" }, - "36": { + "50": { "sourceFileName": "src/test/converter/types/parens.ts", "qualifiedName": "" }, - "37": { + "51": { "sourceFileName": "src/test/converter/types/parens.ts", "qualifiedName": "ZZ" }, - "38": { + "52": { "sourceFileName": "src/test/converter/types/parens.ts", "qualifiedName": "__type" }, - "39": { + "53": { "sourceFileName": "src/test/converter/types/parens.ts", "qualifiedName": "__type.a" }, - "40": { + "54": { "sourceFileName": "src/test/converter/types/query.ts", "qualifiedName": "" }, - "41": { + "55": { "sourceFileName": "src/test/converter/types/query.ts", "qualifiedName": "x" }, - "42": { + "56": { "sourceFileName": "src/test/converter/types/query.ts", "qualifiedName": "TypeOfX" }, - "43": { + "57": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "" }, - "44": { + "58": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "NamedTuple" }, - "45": { + "59": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "namedTuple" }, - "46": { + "60": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "WithRestType" }, - "47": { + "61": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "withRestType" }, - "48": { + "62": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "WithRestTypeNames" }, - "49": { + "63": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "withRestTypeNames" }, - "50": { + "64": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "WithOptionalElements" }, - "51": { + "65": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "withOptionalElements" }, - "52": { + "66": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "LeadingRest" }, - "53": { + "67": { "sourceFileName": "src/test/converter/types/tuple.ts", "qualifiedName": "leadingRest" }, - "54": { + "68": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "" }, - "55": { + "69": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "a" }, - "56": { + "70": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "B" }, - "57": { + "71": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "C" }, - "58": { + "72": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "__type" }, - "59": { + "73": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "__type.prop1" }, - "60": { + "74": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "__type.prop2" }, - "61": { + "75": { "sourceFileName": "src/test/converter/types/type-operator.ts", "qualifiedName": "D" }, - "62": { + "76": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "" }, - "63": { + "77": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "FirstType" }, - "64": { + "78": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "FirstType.firstProperty" }, - "65": { + "79": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "SecondType" }, - "66": { + "80": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "SecondType.secondProperty" }, - "67": { + "81": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "ThirdType" }, - "68": { + "82": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "ThirdType.thirdUnionProperty" }, - "69": { + "83": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "ThirdType.thirdIntersectionProperty" }, - "70": { + "84": { "sourceFileName": "src/test/converter/types/union-or-intersection.ts", "qualifiedName": "ThirdType.thirdComplexProperty" } @@ -2318,12 +2592,12 @@ "reflections": { "1": 1, "2": 13, - "3": 23, - "4": 36, - "5": 40, - "6": 43, - "7": 54, - "8": 62 + "3": 37, + "4": 50, + "5": 54, + "6": 57, + "7": 68, + "8": 76 } } } From 4c2c1061a32da987c15aa5090cf4d2301c97b02c Mon Sep 17 00:00:00 2001 From: tgreyuk Date: Sun, 10 Nov 2024 00:27:44 +0000 Subject: [PATCH 114/219] Create dedicated html outputShortcut --- src/lib/internationalization/locales/en.cts | 5 ++++- src/lib/internationalization/locales/jp.cts | 4 +++- src/lib/internationalization/locales/ko.cts | 4 +++- src/lib/internationalization/locales/zh.cts | 3 ++- src/lib/utils/options/declaration.ts | 5 +++-- src/lib/utils/options/sources/typedoc.ts | 8 +++++++- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index f6329fc7b..d9cdf6a9c 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -221,7 +221,10 @@ export = { "If a symbol is exported multiple times, ignore all but the first export", help_externalSymbolLinkMappings: "Define custom links for symbols not included in the documentation", - help_out: "Specify the location the documentation should be written to", + help_out: + "Specify the location the documentation for the default output should be written to", + help_html: + "Specify the location where the html documentation should be written to. For the default theme, this is equivalent to the out option", help_json: "Specify the location and filename a JSON file describing the project is written to", help_pretty: diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index c0b33d417..141c4ff50 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -234,7 +234,9 @@ export = localeUtils.buildIncompleteTranslation({ "シンボルが複数回エクスポートされた場合、最初のエクスポート以外はすべて無視されます。", help_externalSymbolLinkMappings: "ドキュメントに含まれていないシンボルのカスタムリンクを定義する", - help_out: "ドキュメントを書き込む場所を指定します", + help_out: "デフォルトの出力ドキュメントを保存する場所を指定してください。", + help_html: + "HTMLドキュメントを保存する場所を指定してください。デフォルトテーマでは、これは out オプションと同等です。", help_json: "プロジェクトを説明するJSONファイルが書き込まれる場所とファイル名を指定します", help_pretty: "出力JSONをタブでフォーマットするかどうかを指定します", diff --git a/src/lib/internationalization/locales/ko.cts b/src/lib/internationalization/locales/ko.cts index 315c087a1..b05219234 100644 --- a/src/lib/internationalization/locales/ko.cts +++ b/src/lib/internationalization/locales/ko.cts @@ -86,7 +86,9 @@ export = localeUtils.buildIncompleteTranslation({ "심볼이 여러 번 내보내진 경우 첫 번째 내보내기를 제외하고 모두 무시합니다", help_externalSymbolLinkMappings: "문서에 포함되지 않은 심볼에 대한 사용자 정의 링크를 정의합니다", - help_out: "문서가 쓰여질 위치를 지정합니다", + help_out: "기본 출력 문서가 작성될 위치를 지정하세요.", + help_html: + "HTML 문서가 작성될 위치를 지정하세요. 기본 테마의 경우, 이는 out 옵션과 동일합니다.", help_json: "프로젝트를 설명하는 JSON 파일의 위치와 파일 이름을 지정합니다", help_pretty: "출력 JSON을 탭으로 포맷팅할 지 여부를 지정합니다", help_emit: diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index 550f70a63..48c2066a3 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -227,7 +227,8 @@ export = localeUtils.buildIncompleteTranslation({ help_excludeReferences: "如果一个符号被导出多次,则忽略除第一次导出之外的所有导出", help_externalSymbolLinkMappings: "为文档中未包含的符号定义自定义链接", - help_out: "指定文档应写入的位置", + help_out: "指定默认输出文档的保存位置。", + help_html: "指定HTML文档的保存位置。对于默认主题,这相当于out选项。", help_json: "指定描述项目的 JSON 文件写入的位置和文件名", help_pretty: "指定输出 JSON 是否应使用制表符进行格式化", help_emit: "指定 TypeDoc 应发出的内容,“docs”、“both”或“none”", diff --git a/src/lib/utils/options/declaration.ts b/src/lib/utils/options/declaration.ts index b82c38939..ea77ed05c 100644 --- a/src/lib/utils/options/declaration.ts +++ b/src/lib/utils/options/declaration.ts @@ -136,8 +136,9 @@ export interface TypeDocOptionMap { // Output outputs: ManuallyValidatedOption>; - out: string; // shortcut for defining an output - json: string; // shortcut for defining an output + out: string; // default output directory + html: string; // shortcut for defining html output + json: string; // shortcut for defining json output pretty: boolean; emit: typeof EmitStrategy; theme: string; diff --git a/src/lib/utils/options/sources/typedoc.ts b/src/lib/utils/options/sources/typedoc.ts index 25e43b3a4..ebcd1a949 100644 --- a/src/lib/utils/options/sources/typedoc.ts +++ b/src/lib/utils/options/sources/typedoc.ts @@ -276,12 +276,18 @@ export function addTypeDocOptions(options: Pick) { }); options.addDeclaration({ name: "out", - outputShortcut: "html", help: (i18n) => i18n.help_out(), type: ParameterType.Path, hint: ParameterHint.Directory, defaultValue: "./docs", }); + options.addDeclaration({ + name: "html", + outputShortcut: "html", + help: (i18n) => i18n.help_html(), + type: ParameterType.Path, + hint: ParameterHint.Directory, + }); options.addDeclaration({ name: "json", outputShortcut: "json", From 61d83f050bfe136c271a97369f8e8c27186a876c Mon Sep 17 00:00:00 2001 From: Gerrit Birkeland Date: Sun, 10 Nov 2024 10:40:27 -0700 Subject: [PATCH 115/219] Fix bug when both --out and output shortcut are specified Also remove machine generated translations and reword help messages --- src/lib/internationalization/locales/en.cts | 4 +- src/lib/internationalization/locales/jp.cts | 9 +- src/lib/internationalization/locales/ko.cts | 9 +- src/lib/internationalization/locales/zh.cts | 8 +- src/lib/output/output.ts | 48 +++-- src/test/output/output.test.ts | 195 ++++++++++++++++++++ 6 files changed, 250 insertions(+), 23 deletions(-) create mode 100644 src/test/output/output.test.ts diff --git a/src/lib/internationalization/locales/en.cts b/src/lib/internationalization/locales/en.cts index d9cdf6a9c..8292b4d1d 100644 --- a/src/lib/internationalization/locales/en.cts +++ b/src/lib/internationalization/locales/en.cts @@ -222,9 +222,9 @@ export = { help_externalSymbolLinkMappings: "Define custom links for symbols not included in the documentation", help_out: - "Specify the location the documentation for the default output should be written to", + "Specify the location the documentation for the default output should be written to. The default output type may be changed by plugins.", help_html: - "Specify the location where the html documentation should be written to. For the default theme, this is equivalent to the out option", + "Specify the location where html documentation should be written to.", help_json: "Specify the location and filename a JSON file describing the project is written to", help_pretty: diff --git a/src/lib/internationalization/locales/jp.cts b/src/lib/internationalization/locales/jp.cts index 141c4ff50..1880545d1 100644 --- a/src/lib/internationalization/locales/jp.cts +++ b/src/lib/internationalization/locales/jp.cts @@ -1,3 +1,7 @@ +// Please DO NOT include machine generated translations here. +// If adding a new key, leave it commented out for a native speaker +// to update. + import localeUtils = require("../locale-utils.cjs"); export = localeUtils.buildIncompleteTranslation({ @@ -234,9 +238,8 @@ export = localeUtils.buildIncompleteTranslation({ "シンボルが複数回エクスポートされた場合、最初のエクスポート以外はすべて無視されます。", help_externalSymbolLinkMappings: "ドキュメントに含まれていないシンボルのカスタムリンクを定義する", - help_out: "デフォルトの出力ドキュメントを保存する場所を指定してください。", - help_html: - "HTMLドキュメントを保存する場所を指定してください。デフォルトテーマでは、これは out オプションと同等です。", + // help_out + // help_html help_json: "プロジェクトを説明するJSONファイルが書き込まれる場所とファイル名を指定します", help_pretty: "出力JSONをタブでフォーマットするかどうかを指定します", diff --git a/src/lib/internationalization/locales/ko.cts b/src/lib/internationalization/locales/ko.cts index b05219234..d9e941fa8 100644 --- a/src/lib/internationalization/locales/ko.cts +++ b/src/lib/internationalization/locales/ko.cts @@ -1,3 +1,7 @@ +// Please DO NOT include machine generated translations here. +// If adding a new key, leave it commented out for a native speaker +// to update. + import localeUtils = require("../locale-utils.cjs"); export = localeUtils.buildIncompleteTranslation({ @@ -86,9 +90,8 @@ export = localeUtils.buildIncompleteTranslation({ "심볼이 여러 번 내보내진 경우 첫 번째 내보내기를 제외하고 모두 무시합니다", help_externalSymbolLinkMappings: "문서에 포함되지 않은 심볼에 대한 사용자 정의 링크를 정의합니다", - help_out: "기본 출력 문서가 작성될 위치를 지정하세요.", - help_html: - "HTML 문서가 작성될 위치를 지정하세요. 기본 테마의 경우, 이는 out 옵션과 동일합니다.", + // help_out + // help_html help_json: "프로젝트를 설명하는 JSON 파일의 위치와 파일 이름을 지정합니다", help_pretty: "출력 JSON을 탭으로 포맷팅할 지 여부를 지정합니다", help_emit: diff --git a/src/lib/internationalization/locales/zh.cts b/src/lib/internationalization/locales/zh.cts index 48c2066a3..210c86225 100644 --- a/src/lib/internationalization/locales/zh.cts +++ b/src/lib/internationalization/locales/zh.cts @@ -1,3 +1,7 @@ +// Please DO NOT include machine generated translations here. +// If adding a new key, leave it commented out for a native speaker +// to update. + import localeUtils = require("../locale-utils.cjs"); export = localeUtils.buildIncompleteTranslation({ @@ -227,8 +231,8 @@ export = localeUtils.buildIncompleteTranslation({ help_excludeReferences: "如果一个符号被导出多次,则忽略除第一次导出之外的所有导出", help_externalSymbolLinkMappings: "为文档中未包含的符号定义自定义链接", - help_out: "指定默认输出文档的保存位置。", - help_html: "指定HTML文档的保存位置。对于默认主题,这相当于out选项。", + // help_out + // help_html help_json: "指定描述项目的 JSON 文件写入的位置和文件名", help_pretty: "指定输出 JSON 是否应使用制表符进行格式化", help_emit: "指定 TypeDoc 应发出的内容,“docs”、“both”或“none”", diff --git a/src/lib/output/output.ts b/src/lib/output/output.ts index e4ced7755..8078cdc2f 100644 --- a/src/lib/output/output.ts +++ b/src/lib/output/output.ts @@ -1,4 +1,5 @@ import type { Application } from "../application.js"; +import type { TranslatedString } from "../internationalization/index.js"; import type { ProjectReflection } from "../models/index.js"; import { ParameterType, @@ -13,12 +14,7 @@ export class Outputs { (path: string, project: ProjectReflection) => Promise >(); - private defaultOutput = () => { - return { - name: "html", - path: this.application.options.getValue("out"), - }; - }; + private defaultOutput = "html"; constructor(readonly application: Application) {} @@ -32,11 +28,11 @@ export class Outputs { this.outputs.set(name, output); } - setDefaultOutput(retriever: () => OutputSpecification) { - this.defaultOutput = retriever; + setDefaultOutputName(name: string) { + this.defaultOutput = name; } - async writeOutputs(project: ProjectReflection): Promise { + getOutputSpecs(): OutputSpecification[] { const options = this.application.options; let outputs: OutputSpecification[] = []; @@ -48,23 +44,43 @@ export class Outputs { decl.type === ParameterType.Path && decl.outputShortcut, ); + // --out is a special case. It isn't marked as a shortcut as what it is + // a shortcut for may be modified by plugins. However, it is effectively + // treated as an output shortcut, so check it here. + if (options.isSet("out")) { + outputs.push({ + name: this.defaultOutput, + path: options.getValue("out"), + }); + } for (const shortcut of outputShortcuts) { - if (options.isSet(shortcut.name as "out")) { + if (options.isSet(shortcut.name as "html")) { outputs.push({ name: (shortcut as StringDeclarationOption).outputShortcut!, - path: options.getValue(shortcut.name as "out"), + path: options.getValue(shortcut.name as "html"), }); } } + // If no shortcuts have been defined, use the dedicated outputs option if (outputs.length === 0) { outputs = options.getValue("outputs") || []; } + // If no outputs have been defined, just write the default output. if (!outputs.length) { - outputs.push(this.defaultOutput.call(null)); + outputs.push({ + name: this.defaultOutput, + path: options.getValue("out"), + }); } + return outputs; + } + + async writeOutputs(project: ProjectReflection): Promise { + const outputs = this.getOutputSpecs(); + for (const output of outputs) { await this.writeOutput(output, project); } @@ -91,7 +107,13 @@ export class Outputs { const preErrors = this.application.logger.errorCount; const start = Date.now(); - await writer(output.path, project); + try { + await writer(output.path, project); + } catch (error) { + const message = + error instanceof Error ? error.message : String(error); + this.application.logger.error(message as TranslatedString); + } if (this.application.logger.errorCount === preErrors) { this.application.logger.info( diff --git a/src/test/output/output.test.ts b/src/test/output/output.test.ts new file mode 100644 index 000000000..6899b156d --- /dev/null +++ b/src/test/output/output.test.ts @@ -0,0 +1,195 @@ +import { deepStrictEqual as equal, throws } from "assert"; +import { getConverter2App } from "../programs.js"; +import { resolve } from "path"; +import { Outputs } from "../../lib/output/output.js"; +import { TestLogger } from "../TestLogger.js"; +import { FileRegistry, ProjectReflection } from "../../lib/models/index.js"; +import type { TranslatedString } from "../../lib/internationalization/index.js"; + +const app = getConverter2App(); + +describe("Output", () => { + let optionsSnap: { __optionSnapshot: never }; + + let outputs: Outputs; + let logger: TestLogger; + let htmlWritten = false; + let jsonWritten = false; + + const dummyProject = new ProjectReflection("", new FileRegistry()); + + before(() => { + optionsSnap = app.options.snapshot(); + }); + + beforeEach(() => { + outputs = new Outputs(app); + outputs.addOutput("html", () => { + htmlWritten = true; + return Promise.resolve(); + }); + outputs.addOutput("json", () => { + jsonWritten = true; + return Promise.resolve(); + }); + + logger = app.logger = new TestLogger(); + + htmlWritten = false; + jsonWritten = false; + }); + + afterEach(() => { + app.options.restore(optionsSnap); + logger.expectNoOtherMessages(); + }); + + it("Uses the --out output by default", () => { + const specs = outputs.getOutputSpecs(); + equal(specs, [{ name: "html", path: resolve("./docs") }]); + }); + + it("Does not use default value of --out if there is a specified output shortcut", () => { + app.options.setValue("html", "./html_docs"); + const specs = outputs.getOutputSpecs(); + equal(specs, [{ name: "html", path: resolve("./html_docs") }]); + }); + + it("Uses --out if specified", () => { + app.options.setValue("html", "./html_docs"); + app.options.setValue("out", "./out_docs"); + const specs = outputs.getOutputSpecs(); + equal(specs, [ + { name: "html", path: resolve("./out_docs") }, + { name: "html", path: resolve("./html_docs") }, + ]); + }); + + it("Uses --outputs if specified", () => { + app.options.setValue("outputs", [ + { name: "html", path: "./html_docs" }, + ]); + const specs = outputs.getOutputSpecs(); + equal(specs, [{ name: "html", path: resolve("./html_docs") }]); + }); + + it("Prioritizes shortcuts if both outputs and shortcuts are specified", () => { + app.options.setValue("outputs", [ + { name: "html", path: "./html_docs" }, + ]); + app.options.setValue("html", "./html_docs2"); + const specs = outputs.getOutputSpecs(); + equal(specs, [{ name: "html", path: resolve("./html_docs2") }]); + }); + + it("Prioritizes --out if both outputs and --out are specified", () => { + app.options.setValue("outputs", [ + { name: "html", path: "./html_docs" }, + ]); + app.options.setValue("out", "./html_docs2"); + const specs = outputs.getOutputSpecs(); + equal(specs, [{ name: "html", path: resolve("./html_docs2") }]); + }); + + it("Supports specifying a different default output name", () => { + outputs.setDefaultOutputName("json"); + const specs = outputs.getOutputSpecs(); + try { + equal(specs, [{ name: "json", path: resolve("./docs") }]); + } finally { + outputs.setDefaultOutputName("html"); + } + }); + + it("Errors if an output is attempted to be redefined", () => { + throws( + () => outputs.addOutput("json", () => Promise.resolve()), + new Error("Output type 'json' has already been defined"), + ); + }); + + it("Errors if an unspecified output is written", async () => { + await outputs.writeOutput( + { + name: "notDefined", + path: "./docs", + }, + dummyProject, + ); + + logger.expectMessage( + 'error: Specified output "notDefined" has not been defined.', + ); + }); + + it("Writes all selected outputs, even if one fails", async () => { + app.options.setValue("outputs", [ + { name: "html", path: "./html_docs" }, + { name: "notDefined", path: "./dummy" }, + { name: "json", path: "./json_docs" }, + ]); + + await outputs.writeOutputs(dummyProject); + equal(htmlWritten, true); + equal(jsonWritten, true); + + logger.expectMessage( + 'error: Specified output "notDefined" has not been defined.', + ); + logger.expectMessage("info: html generated at ./html_docs"); + logger.expectMessage("info: json generated at ./json_docs"); + }); + + it("Skips writing an output if setting options fails", async () => { + app.options.setValue("outputs", [ + { + name: "html", + path: "./html_docs", + options: { notDefined: true } as any, + }, + ]); + + await outputs.writeOutputs(dummyProject); + equal(htmlWritten, false); + + logger.expectMessage( + "error: Unknown option 'notDefined' You may have meant:*", + ); + }); + + it("Logs an error if an output prints an error message", async () => { + outputs.addOutput("test", () => { + app.logger.error("Test Error" as TranslatedString); + return Promise.resolve(); + }); + await outputs.writeOutput({ name: "test", path: "test" }, dummyProject); + + logger.expectMessage("error: Test Error"); + logger.expectMessage( + "error: test output could not be generated due to the errors above", + ); + }); + + it("Logs an error if an output throws", async () => { + outputs.addOutput("test", () => + Promise.reject(new Error("Test Error")), + ); + await outputs.writeOutput({ name: "test", path: "test" }, dummyProject); + + logger.expectMessage("error: Test Error"); + logger.expectMessage( + "error: test output could not be generated due to the errors above", + ); + }); + + it("Logs an error if an output throws a non-error", async () => { + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors + outputs.addOutput("test", () => Promise.reject("Test Error")); + await outputs.writeOutput({ name: "test", path: "test" }, dummyProject); + + logger.expectMessage("error: Test Error"); + logger.expectMessage( + "error: test output could not be generated due to the errors above", + ); + }); +}); From 983aa5e42481ea13ee1b9057b97c5b201a02868b Mon Sep 17 00:00:00 2001 From: ProjectXero Date: Tue, 12 Nov 2024 12:47:15 +0800 Subject: [PATCH 116/219] Use tag instead of display name as class name --- src/lib/output/themes/default/partials/comment.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/output/themes/default/partials/comment.tsx b/src/lib/output/themes/default/partials/comment.tsx index 8eca12f95..c7c318531 100644 --- a/src/lib/output/themes/default/partials/comment.tsx +++ b/src/lib/output/themes/default/partials/comment.tsx @@ -39,7 +39,7 @@ export function commentTags(context: DefaultThemeRenderContext, props: Reflectio return ( <> -

    +