UNPKG

@gobstones/typedoc-theme-gobstones

Version:

A simple theme for the Gobstones generated documentation.

957 lines (941 loc) 171 kB
import { load as load$1 } from 'typedoc-plugin-mdn-links'; import { load as load$2 } from 'typedoc-plugin-merge-modules'; import { TypeScript, ParameterType, Converter, Application, ReflectionKind, JSX, DeclarationReflection, ProjectReflection, SignatureReflection, ReferenceReflection, TypeContext, ReferenceType, LiteralType, ReflectionFlag, ArrayType, DefaultThemeRenderContext, DefaultTheme, RendererEvent } from 'typedoc'; import fs from 'fs'; import path from 'path'; import url from 'url'; import assert, { ok } from 'assert'; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * Return the theme's default configuration to be set, if no configuration * that overwrites it is provided by the user. * * @param typedocApp - The instance of the running TypeDoc application * * @returns A TypeDoc partial configuration. * * @internal */ const getDefaults = (typedocApp) => ({ // Input entryPointStrategy: 'expand', exclude: ['./node_modules/**/*', './**/*.test.ts', './src/index.ts'], excludeExternals: true, excludeInternal: false, excludePrivate: false, // Input (at TypeDoc docs, but is actually output) disableSources: false, includeVersion: true, // Output categorizeByGroup: true, hideGenerator: true, githubPages: true, headings: { readme: false, document: true }, visibilityFilters: { '@internal': false, protected: false, private: false, inherited: false }, // Comments modifierTags: ['@mergeTarget', ...typedocApp.options.getValue('modifierTags')], excludeTags: ['@override', '@virtual', '@satisfies', '@overload'], // Plugins mergeModulesMergeMode: 'module-category' }); /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * A class that wraps the idea of a `Plugin` for TypeDoc. * * @remarks * Similarly to themes, this class is structured so that * subclasses can access the main TypeDoc app through * the `this.application` property. * * Subclasses are expected to overwrite this class and to * define an `initialize` method, which is just a fancy name * for the `load` function that is exported by regular plugins. */ class TypedocPlugin { application; /** * Create a new instance of this plugin. * * @param application - The instance of the running TypeDoc application */ constructor(application) { this.application = application; } } /** * Load a plugin into the application. * * @param typedocApp - The instance of the running TypeDoc application * @param plugin - The class of the plugin to load. */ const loadPlugin = (typedocApp, plugin) => { void new plugin(typedocApp).initialize(); }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Plugins * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ // @ts-expect-error: Plugin is JS only, ignore import as any. /** * A Plugin class that wraps the `typedoc-plugin-mdn-links` plugin. */ class MdnLinksPlugin extends TypedocPlugin { /** @inheritdoc */ initialize() { // eslint-disable-next-line @typescript-eslint/no-unsafe-call load$1(this.application); } } /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Plugins * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * A Plugin class that wraps the `typedoc-plugin-merge-modules` plugin. */ class MergeModulePlugin extends TypedocPlugin { /** @inheritdoc */ initialize() { load$2(this.application); } } /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Plugins * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * Adapted copy of * typedoc-plugin-not-exported * TypeDoc plugin that forces inclusion of non-exported symbols (variables) * Originally from https://github.com/TypeStrong/typedoc/issues/1474#issuecomment-766178261 * And: https://github.com/tomchen/typedoc-plugin-not-exported * CC0 */ // eslint-disable-next-line no-bitwise const ModuleFlags = TypeScript.SymbolFlags.ValueModule | TypeScript.SymbolFlags.NamespaceModule; /** * A Plugin class that re-defines the `typedoc-plugin-not-exported` plugin. * * @remarks * As it was defined, the `typedoc-plugin-not-exported` plugin is not quite * useful to our theme. By making small modifications, the plugin now uses * the `internal` flag to also include elements as exported. * * Note that there are some limitations on the behavior of the plugin. The * `internal` modifier should only be used with modules, or members of a module, * but not classes or interfaces. */ class NotExportedPlugin extends TypedocPlugin { /** * The reflections already checked for module exports */ checkedForModuleExports = new Map(); /** * The tags to include into the documentation. Note that by default * _internal_ is used, thus, requiring the includeInternal option to * be set to true. */ _includedTags = ['@internal']; /** @inheritdoc */ initialize() { this.application.options.addDeclaration({ name: 'includeTags', defaultValue: this._includedTags, help: '[typedoc-theme-gobstones]: A set of tags used to add elements within it, even if not exported directly by the module.', type: ParameterType.Array }); this.application.converter.on(Converter.EVENT_BEGIN, () => { const includeTagTemp = this.application.options.getValue('includeTags'); if (typeof includeTagTemp === 'string') { const tagName = includeTagTemp.toLocaleLowerCase(); this._includedTags = (tagName.startsWith('@') ? [tagName] : [`@${tagName}`]); } else if (Array.isArray(includeTagTemp)) { this._includedTags = includeTagTemp; } }); this.application.converter.on(Converter.EVENT_CREATE_DECLARATION, (context, reflection) => { this._lookForFakeExports(context, reflection); }); this.application.converter.on(Converter.EVENT_END, () => { this.checkedForModuleExports.clear(); }); // Fix for the new TypeDoc JSDoc tag linting. this.application.on(Application.EVENT_BOOTSTRAP_END, () => { const modifiers = this.application.options.getValue('modifierTags'); for (const tag of this._includedTags) { if (!modifiers.includes(tag)) { this.application.options.setValue('modifierTags', [...modifiers, tag]); } } }); } _lookForFakeExports(context, reflection) { // Figure out where "not exports" will be placed, go up the tree until we get to // the module where it belongs. let targetModule = reflection; // eslint-disable-next-line no-bitwise while (!targetModule.kindOf(ReflectionKind.Module | ReflectionKind.Project)) { targetModule = targetModule.parent; } const moduleContext = context.withScope(targetModule); const reflSymbol = context.project.getSymbolFromReflection(reflection); if (!reflSymbol) { // Global file, no point in doing anything here. TypeDoc will already // include everything declared in this file. return; } for (const declaration of reflSymbol.declarations || []) { this._checkFakeExportsOfFile(declaration.getSourceFile(), moduleContext); } } _checkFakeExportsOfFile(file, context) { const moduleSymbol = context.checker.getSymbolAtLocation(file); // Make sure we are allowed to call getExportsOfModule // eslint-disable-next-line no-bitwise if (!moduleSymbol || (moduleSymbol.flags & ModuleFlags) === 0) { return; } const checkedScopes = this.checkedForModuleExports.get(context.scope) || new Set(); this.checkedForModuleExports.set(context.scope, checkedScopes); if (checkedScopes.has(file)) return; checkedScopes.add(file); const exportedSymbols = context.checker.getExportsOfModule(moduleSymbol); const symbols = context.checker .getSymbolsInScope(file, TypeScript.SymbolFlags.ModuleMember) .filter((symbol) => symbol.declarations?.some((d) => d.getSourceFile() === file) && !exportedSymbols.includes(symbol)); for (const symbol of symbols) { if (symbol .getJsDocTags() .some((tag) => this._includedTags.includes(`@${tag.name.toLocaleLowerCase()}`))) { context.converter.convertSymbol(context, symbol); } } } } /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Plugins * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * A Plugin to remove re-exports references. * * This is just a copy of the code at `typedoc-plugin-remove-references` * that has not been updated in a while and it's still in CJS while everything has been * migrated to ESM. If in the future the module receives updates we can wrap * around it as we do with other plugins. */ class RemoveReferencesPlugin extends TypedocPlugin { /** @inheritdoc */ initialize() { this.application.converter.on(Converter.EVENT_RESOLVE_BEGIN, (context) => { for (const reflection of context.project.getReflectionsByKind(ReflectionKind.Reference)) { context.project.removeReflection(reflection); } }); } } /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Icons * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * Return an element that contains the SVG for the icon used by the kind of * an element, such as the icon to use for classes, the one used by functions * and so on. * * @param letterPath - The svg element that represents the letter to showcase inside the icon. * @param color - The color to use as outline of this icon. * @param circular - Whether to display this as a circular icon (if not, squared is default). * * @returns An SVG.Element with the SVG icon. */ const kindIcon = (letterPath, color, circular = false) => (JSX.createElement("svg", { class: "tsd-kind-icon", viewBox: "0 0 24 24" }, JSX.createElement("rect", { fill: "var(--color-icon-background)", stroke: color, "stroke-width": "1.5", x: "1", y: "1", width: "22", height: "22", rx: circular ? '12' : '6' }), letterPath)); /** * A record of all possible reflection kinds along with a function that * returns it's associated icon. */ ({ [ReflectionKind.Accessor]: () => kindIcon(JSX.createElement("path", { d: "M8.85 16L11.13 7.24H12.582L14.85 16H13.758L13.182 13.672H10.53L9.954 16H8.85ZM10.746 12.76H12.954L12.282 10.06C12.154 9.548 12.054 9.12 11.982 8.776C11.91 8.432 11.866 8.208 11.85 8.104C11.834 8.208 11.79 8.432 11.718 8.776C11.646 9.12 11.546 9.544 11.418 10.048L10.746 12.76Z", fill: "var(--color-text)" }), '#FF4D4D', true), [ReflectionKind.CallSignature]() { return this[ReflectionKind.Function](); }, [ReflectionKind.Class]: () => kindIcon(JSX.createElement("path", { d: "M11.898 16.1201C11.098 16.1201 10.466 15.8961 10.002 15.4481C9.53803 15.0001 9.30603 14.3841 9.30603 13.6001V9.64012C9.30603 8.85612 9.53803 8.24012 10.002 7.79212C10.466 7.34412 11.098 7.12012 11.898 7.12012C12.682 7.12012 13.306 7.34812 13.77 7.80412C14.234 8.25212 14.466 8.86412 14.466 9.64012H13.386C13.386 9.14412 13.254 8.76412 12.99 8.50012C12.734 8.22812 12.37 8.09212 11.898 8.09212C11.426 8.09212 11.054 8.22412 10.782 8.48812C10.518 8.75212 10.386 9.13212 10.386 9.62812V13.6001C10.386 14.0961 10.518 14.4801 10.782 14.7521C11.054 15.0161 11.426 15.1481 11.898 15.1481C12.37 15.1481 12.734 15.0161 12.99 14.7521C13.254 14.4801 13.386 14.0961 13.386 13.6001H14.466C14.466 14.3761 14.234 14.9921 13.77 15.4481C13.306 15.8961 12.682 16.1201 11.898 16.1201Z", fill: "var(--color-text)" }), 'var(--color-ts-class)'), [ReflectionKind.Constructor]: () => kindIcon(JSX.createElement("path", { d: "M11.898 16.1201C11.098 16.1201 10.466 15.8961 10.002 15.4481C9.53803 15.0001 9.30603 14.3841 9.30603 13.6001V9.64012C9.30603 8.85612 9.53803 8.24012 10.002 7.79212C10.466 7.34412 11.098 7.12012 11.898 7.12012C12.682 7.12012 13.306 7.34812 13.77 7.80412C14.234 8.25212 14.466 8.86412 14.466 9.64012H13.386C13.386 9.14412 13.254 8.76412 12.99 8.50012C12.734 8.22812 12.37 8.09212 11.898 8.09212C11.426 8.09212 11.054 8.22412 10.782 8.48812C10.518 8.75212 10.386 9.13212 10.386 9.62812V13.6001C10.386 14.0961 10.518 14.4801 10.782 14.7521C11.054 15.0161 11.426 15.1481 11.898 15.1481C12.37 15.1481 12.734 15.0161 12.99 14.7521C13.254 14.4801 13.386 14.0961 13.386 13.6001H14.466C14.466 14.3761 14.234 14.9921 13.77 15.4481C13.306 15.8961 12.682 16.1201 11.898 16.1201Z", fill: "var(--color-text)" }), '#4D7FFF', true), [ReflectionKind.ConstructorSignature]() { return this[ReflectionKind.Constructor](); }, [ReflectionKind.Enum]: () => kindIcon(JSX.createElement("path", { d: "M9.45 16V7.24H14.49V8.224H10.518V10.936H14.07V11.908H10.518V15.016H14.49V16H9.45Z", fill: "var(--color-text)" }), 'var(--color-ts-enum)'), [ReflectionKind.EnumMember]() { return this[ReflectionKind.Property](); }, [ReflectionKind.Function]: () => kindIcon(JSX.createElement("path", { d: "M9.39 16V7.24H14.55V8.224H10.446V11.128H14.238V12.112H10.47V16H9.39Z", fill: "var(--color-text)" }), 'var(--color-ts-function)'), [ReflectionKind.GetSignature]() { return this[ReflectionKind.Accessor](); }, [ReflectionKind.IndexSignature]() { return this[ReflectionKind.Property](); }, [ReflectionKind.Interface]: () => kindIcon(JSX.createElement("path", { d: "M9.51 16V15.016H11.298V8.224H9.51V7.24H14.19V8.224H12.402V15.016H14.19V16H9.51Z", fill: "var(--color-text)" }), 'var(--color-ts-interface)'), [ReflectionKind.Method]: () => kindIcon(JSX.createElement("path", { d: "M9.162 16V7.24H10.578L11.514 10.072C11.602 10.328 11.674 10.584 11.73 10.84C11.794 11.088 11.842 11.28 11.874 11.416C11.906 11.28 11.954 11.088 12.018 10.84C12.082 10.584 12.154 10.324 12.234 10.06L13.122 7.24H14.538V16H13.482V12.82C13.482 12.468 13.49 12.068 13.506 11.62C13.53 11.172 13.558 10.716 13.59 10.252C13.622 9.78 13.654 9.332 13.686 8.908C13.726 8.476 13.762 8.1 13.794 7.78L12.366 12.16H11.334L9.894 7.78C9.934 8.092 9.97 8.456 10.002 8.872C10.042 9.28 10.078 9.716 10.11 10.18C10.142 10.636 10.166 11.092 10.182 11.548C10.206 12.004 10.218 12.428 10.218 12.82V16H9.162Z", fill: "var(--color-text)" }), '#FF4DB8', true), [ReflectionKind.Module]: () => kindIcon(JSX.createElement("path", { d: "M9.162 16V7.24H10.578L11.514 10.072C11.602 10.328 11.674 10.584 11.73 10.84C11.794 11.088 11.842 11.28 11.874 11.416C11.906 11.28 11.954 11.088 12.018 10.84C12.082 10.584 12.154 10.324 12.234 10.06L13.122 7.24H14.538V16H13.482V12.82C13.482 12.468 13.49 12.068 13.506 11.62C13.53 11.172 13.558 10.716 13.59 10.252C13.622 9.78 13.654 9.332 13.686 8.908C13.726 8.476 13.762 8.1 13.794 7.78L12.366 12.16H11.334L9.894 7.78C9.934 8.092 9.97 8.456 10.002 8.872C10.042 9.28 10.078 9.716 10.11 10.18C10.142 10.636 10.166 11.092 10.182 11.548C10.206 12.004 10.218 12.428 10.218 12.82V16H9.162Z", fill: "var(--color-text)" }), 'var(--color-ts-module)'), [ReflectionKind.Namespace]: () => kindIcon(JSX.createElement("path", { d: "M9.33 16V7.24H10.77L13.446 14.74C13.43 14.54 13.41 14.296 13.386 14.008C13.37 13.712 13.354 13.404 13.338 13.084C13.33 12.756 13.326 12.448 13.326 12.16V7.24H14.37V16H12.93L10.266 8.5C10.282 8.692 10.298 8.936 10.314 9.232C10.33 9.52 10.342 9.828 10.35 10.156C10.366 10.476 10.374 10.784 10.374 11.08V16H9.33Z", fill: "var(--color-text)" }), 'var(--color-ts-namespace)'), [ReflectionKind.Parameter]() { return this[ReflectionKind.Property](); }, [ReflectionKind.Project]() { return this[ReflectionKind.Module](); }, [ReflectionKind.Property]: () => kindIcon(JSX.createElement("path", { d: "M9.354 16V7.24H12.174C12.99 7.24 13.638 7.476 14.118 7.948C14.606 8.412 14.85 9.036 14.85 9.82C14.85 10.604 14.606 11.232 14.118 11.704C13.638 12.168 12.99 12.4 12.174 12.4H10.434V16H9.354ZM10.434 11.428H12.174C12.646 11.428 13.022 11.284 13.302 10.996C13.59 10.7 13.734 10.308 13.734 9.82C13.734 9.324 13.59 8.932 13.302 8.644C13.022 8.356 12.646 8.212 12.174 8.212H10.434V11.428Z", fill: "var(--color-text)" }), '#FF984D', true), [ReflectionKind.Reference]: () => kindIcon(JSX.createElement("path", { d: "M10.354 17V8.24H13.066C13.586 8.24 14.042 8.348 14.434 8.564C14.826 8.772 15.13 9.064 15.346 9.44C15.562 9.816 15.67 10.256 15.67 10.76C15.67 11.352 15.514 11.86 15.202 12.284C14.898 12.708 14.482 13 13.954 13.16L15.79 17H14.518L12.838 13.28H11.434V17H10.354ZM11.434 12.308H13.066C13.514 12.308 13.874 12.168 14.146 11.888C14.418 11.6 14.554 11.224 14.554 10.76C14.554 10.288 14.418 9.912 14.146 9.632C13.874 9.352 13.514 9.212 13.066 9.212H11.434V12.308Z", fill: "var(--color-text)" }), '#FF4D82', // extract into a CSS variable potentially? true), [ReflectionKind.SetSignature]() { return this[ReflectionKind.Accessor](); }, [ReflectionKind.TypeAlias]: () => kindIcon(JSX.createElement("path", { d: "M11.31 16V8.224H8.91V7.24H14.79V8.224H12.39V16H11.31Z", fill: "var(--color-text)" }), 'var(--color-ts-type-alias)'), [ReflectionKind.TypeLiteral]() { return this[ReflectionKind.TypeAlias](); }, [ReflectionKind.TypeParameter]() { return this[ReflectionKind.TypeAlias](); }, [ReflectionKind.Variable]: () => kindIcon(JSX.createElement("path", { d: "M11.106 16L8.85 7.24H9.966L11.454 13.192C11.558 13.608 11.646 13.996 11.718 14.356C11.79 14.708 11.842 14.976 11.874 15.16C11.906 14.976 11.954 14.708 12.018 14.356C12.09 13.996 12.178 13.608 12.282 13.192L13.758 7.24H14.85L12.582 16H11.106Z", fill: "var(--color-text)" }), 'var(--color-ts-variable)'), [ReflectionKind.Document]: () => kindIcon(JSX.createElement("g", { stroke: "var(--color-text)", fill: "var(--color-icon-background)" }, JSX.createElement("polygon", { points: "6,5 6,19 18,19, 18,9 15,5" }), JSX.createElement("line", { x1: "9", y1: "9", x2: "14", y2: "9" }), JSX.createElement("line", { x1: "9", y1: "12", x2: "15", y2: "12" }), JSX.createElement("line", { x1: "9", y1: "15", x2: "15", y2: "15" })), 'var(--color-document)'), chevronDown: () => (JSX.createElement("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none" }, JSX.createElement("path", { d: "M4.93896 8.531L12 15.591L19.061 8.531L16.939 6.409L12 11.349L7.06098 6.409L4.93896 8.531Z", fill: "var(--color-text)" }))), chevronSmall: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, JSX.createElement("path", { d: "M1.5 5.50969L8 11.6609L14.5 5.50969L12.5466 3.66086L8 7.96494L3.45341 3.66086L1.5 5.50969Z", fill: "var(--color-text)" }))), checkbox: () => (JSX.createElement("svg", { width: "32", height: "32", viewBox: "0 0 32 32", "aria-hidden": "true" }, JSX.createElement("rect", { class: "tsd-checkbox-background", width: "30", height: "30", x: "1", y: "1", rx: "6", fill: "none" }), JSX.createElement("path", { class: "tsd-checkbox-checkmark", d: "M8.35422 16.8214L13.2143 21.75L24.6458 10.25", stroke: "none", "stroke-width": "3.5", "stroke-linejoin": "round", fill: "none" }))), menu: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, ['3', '7', '11'].map((y) => (JSX.createElement("rect", { x: "1", y: y, width: "14", height: "2", fill: "var(--color-text)" }))))), search: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, JSX.createElement("path", { d: "M15.7824 13.833L12.6666 10.7177C12.5259 10.5771 12.3353 10.499 12.1353 10.499H11.6259C12.4884 9.39596 13.001 8.00859 13.001 6.49937C13.001 2.90909 10.0914 0 6.50048 0C2.90959 0 0 2.90909 0 6.49937C0 10.0896 2.90959 12.9987 6.50048 12.9987C8.00996 12.9987 9.39756 12.4863 10.5008 11.6239V12.1332C10.5008 12.3332 10.5789 12.5238 10.7195 12.6644L13.8354 15.7797C14.1292 16.0734 14.6042 16.0734 14.8948 15.7797L15.7793 14.8954C16.0731 14.6017 16.0731 14.1267 15.7824 13.833ZM6.50048 10.499C4.29094 10.499 2.50018 8.71165 2.50018 6.49937C2.50018 4.29021 4.28781 2.49976 6.50048 2.49976C8.71001 2.49976 10.5008 4.28708 10.5008 6.49937C10.5008 8.70852 8.71314 10.499 6.50048 10.499Z", fill: "var(--color-text)" }))), anchor: () => (JSX.createElement("svg", { viewBox: "0 0 24 24" }, JSX.createElement("g", { "stroke-width": "2", stroke: "currentColor", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }, JSX.createElement("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }), JSX.createElement("path", { d: "M10 14a3.5 3.5 0 0 0 5 0l4 -4a3.5 3.5 0 0 0 -5 -5l-.5 .5" }), JSX.createElement("path", { d: "M14 10a3.5 3.5 0 0 0 -5 0l-4 4a3.5 3.5 0 0 0 5 5l.5 -.5" })))), folder: () => kindIcon(JSX.createElement("g", { stroke: "var(--color-icon-text)", fill: "none", "stroke-width": "1.5" }, JSX.createElement("polygon", { points: "5,5 10,5 12,8 19,8 19,18 5,18" })), 'var(--color-document)'), alertNote: () => (JSX.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16" }, JSX.createElement("path", { fill: "var(--color-alert-note)", d: "M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z" }))), alertTip: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" }, JSX.createElement("path", { fill: "var(--color-alert-tip)", d: "M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z" }))), alertImportant: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" }, JSX.createElement("path", { fill: "var(--color-alert-important)", d: "M0 1.75C0 .784.784 0 1.75 0h12.5C15.216 0 16 .784 16 1.75v9.5A1.75 1.75 0 0 1 14.25 13H8.06l-2.573 2.573A1.458 1.458 0 0 1 3 14.543V13H1.75A1.75 1.75 0 0 1 0 11.25Zm1.75-.25a.25.25 0 0 0-.25.25v9.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h6.5a.25.25 0 0 0 .25-.25v-9.5a.25.25 0 0 0-.25-.25Zm7 2.25v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z" }))), alertWarning: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" }, JSX.createElement("path", { fill: "var(--color-alert-warning)", d: "M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z" }))), alertCaution: () => (JSX.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16" }, JSX.createElement("path", { fill: "var(--color-alert-caution)", d: "M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z" }))) }); /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Icons * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * Returns a record of all possible icon names with a function that returns * the matching JSX.Element for such icon. * * @param icons - The icons * @param context - The render context of this theme * @returns A function that creates all icons. */ const buildRefIcons = (icons, context) => { const refs = {}; for (const [name, builder] of Object.entries(icons)) { const jsx = builder.call(icons); assert(jsx.tag === 'svg', "TypeDoc's frontend assumes that icons are written as svg elements"); // This one cannot be cached because the CSS selector depends on targeting SVG elements // within it. Ick. Surely there's a nicer way? if (name === 'checkbox') { refs[name] = () => jsx; continue; } const ref = (JSX.createElement("svg", { ...jsx.props, id: undefined }, JSX.createElement("use", { href: `${context.relativeURL('assets/img/icons.svg')}#icon-${name}` }))); refs[name] = () => ref; } return refs; }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Layouts * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * Calculate the favicon file based on the extension. * * @param context The theme context. * @returns The favicon component to use in the template. */ const favicon = (context) => { const fav = context.options.getValue('favicon'); if (!fav) return undefined; switch (path.extname(fav)) { case '.ico': return JSX.createElement("link", { rel: "icon", href: context.relativeURL('assets/favicon.ico', true) }); case '.png': return JSX.createElement("link", { rel: "icon", href: context.relativeURL('assets/favicon.png', true), type: "image/png" }); case '.svg': return JSX.createElement("link", { rel: "icon", href: context.relativeURL('assets/favicon.svg', true), type: "image/svg+xml" }); default: return undefined; } }; const buildSiteMetadata = (context) => { try { // We have to know where we are hosted in order to generate this block const url = new URL(context.options.getValue('hostedBaseUrl')); // No point in generating this if we aren't the root page on the site if (url.pathname !== '/') { return undefined; } return (JSX.createElement("script", { type: "application/ld+json" }, JSX.createElement(JSX.Raw, { html: JSON.stringify({ '@context': 'https://schema.org', '@type': 'WebSite', name: context.page.project.name, url: url.toString() }) }))); } catch { return undefined; } }; /** * The name to display as the main title of the documentation. * Default to the package name followed by a dash and a "v" followd * by the version number. * * @param refl - The main reflection * * @returns The display name as a string */ const getDisplayName$1 = (refl) => { let version = ''; if ((refl instanceof DeclarationReflection || refl instanceof ProjectReflection) && refl.packageVersion) { version = ` - v${refl.packageVersion}`; } return `${refl.name}${version}`; }; /** * The default layout to use by the theme. * * @remarks * The layout is the main structure of the produced HTML document, including * the main tags, such as head and body, as well as loading all the scripts * and styles. * * @privateRemarks * Note that there are ways to load a style or script into a theme through code, * yet, as we are redefining the template, loading custom elements is done entirely * into this file. * * @param context - The theme's context * @param template - The template in use. * @param props - The page event with the reflection. * * @returns The default layout in use as a JSX.Element. */ const defaultLayout = (context, template, props) => (JSX.createElement("html", { class: "default", lang: context.options.getValue('lang'), "data-base": context.relativeURL('./') }, JSX.createElement("head", null, JSX.createElement("meta", { charset: "utf-8" }), context.hook('head.begin', context), JSX.createElement("meta", { "http-equiv": "x-ua-compatible", content: "IE=edge" }), JSX.createElement("title", null, props.model.isProject() ? getDisplayName$1(props.model) : `${getDisplayName$1(props.model)} | ${getDisplayName$1(props.project)}`), favicon(context), props.url === 'index.html' && buildSiteMetadata(context), JSX.createElement("meta", { name: "description", content: 'Documentation for ' + props.project.name }), JSX.createElement("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), JSX.createElement("link", { rel: "stylesheet", href: context.relativeURL('assets/css/style.css', true) }), JSX.createElement("link", { rel: "stylesheet", href: context.relativeURL('assets/css/highlight.css', true) }), JSX.createElement("link", { rel: "stylesheet", href: context.relativeURL('assets/css/typedoc-theme-gobstones.css', true) }), context.options.getValue('customCss') && (JSX.createElement("link", { rel: "stylesheet", href: context.relativeURL('assets/custom.css', true) })), JSX.createElement("script", { async: true, src: context.relativeURL('assets/js/icons.js', true), id: "tsd-icons-script" }), JSX.createElement("script", { async: true, src: context.relativeURL('assets/js/search.js', true), id: "tsd-search-script" }), JSX.createElement("script", { async: true, src: context.relativeURL('assets/js/navigation.js', true), id: "tsd-nav-script" }), JSX.createElement("script", { defer: true, src: context.relativeURL('assets/js/main.js', true) }), JSX.createElement("script", { defer: true, src: context.relativeURL('assets/js/typedoc-theme-gobstones.js', true) }), context.hook('head.end', context)), JSX.createElement("body", null, context.hook('body.begin', context), JSX.createElement("script", null, JSX.createElement(JSX.Raw, { html: 'document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";' }), JSX.createElement(JSX.Raw, { html: 'document.body.style.display="none";' }), JSX.createElement(JSX.Raw, { html: 'setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)' })), context.toolbar(props), JSX.createElement("div", { class: "container container-main" }, JSX.createElement("div", { class: "col-content" }, context.hook('content.begin', context), context.header(props), template(props), context.hook('content.end', context)), JSX.createElement("div", { class: "col-sidebar" }, JSX.createElement("div", { class: "page-menu" }, context.hook('pageSidebar.begin', context), context.pageSidebar(props), context.hook('pageSidebar.end', context)), JSX.createElement("div", { class: "site-menu" }, context.hook('sidebar.begin', context), context.sidebar(props), context.hook('sidebar.end', context)))), context.footer(), JSX.createElement("div", { class: "overlay" }), context.hook('body.end', context)))); /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ const commentShortSummary = (context, props) => { let shortSummary; if (props.isDocument()) { if (typeof props.frontmatter.summary === 'string') { shortSummary = [{ kind: 'text', text: props.frontmatter.summary }]; } } else { shortSummary = props.comment?.getShortSummary(context.options.getValue('useFirstParagraphOfCommentAsSummary')); } if (!shortSummary?.length && props.isDeclaration() && props.signatures?.length) { return commentShortSummary(context, props.signatures[0]); } if (!shortSummary?.some((part) => part.text)) return; return context.displayParts(shortSummary); }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ // Note: Comment modifiers are handled in `renderFlags` const commentSummary = (context, props) => { if (props.comment?.summary.some((part) => part.text)) { return context.displayParts?.(props.comment.summary); } const target = (props.isDeclaration() || props.isParameter()) && props.type?.type === 'reference' ? props.type.reflection : undefined; if (target?.comment?.hasModifier('@expand') && target?.comment?.summary.some((part) => part.text)) { return context.displayParts?.(target.comment.summary); } }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Partials * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ const anchorIcon = (context, anchor) => { if (!anchor) return JSX.createElement(JSX.Fragment, null); return (JSX.createElement("a", { href: `#${anchor}`, "aria-label": context.i18n.theme_permalink(), class: "tsd-anchor-icon" }, context.icons.anchor())); }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Partials/Comments * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ const commentTags = (context, props) => { if (!props.comment) return; const skipSave = props.comment.blockTags.map((tag) => tag.skipRendering); 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 && !skippedTags.includes(tag.tag)) : props.comment.blockTags.filter((tag) => !tag.skipRendering && !skippedTags.includes(tag.tag)); skipSave.forEach((skip, i) => { if (props.comment) { props.comment.blockTags[i].skipRendering = skip; } }); return (JSX.createElement(JSX.Fragment, null, beforeTags, JSX.createElement("div", { class: "tsd-comment tsd-typography" }, tags.map((item) => { const name = item.name ? `${context.internationalization.translateTagName(item.tag)}: ${item.name}` : context.internationalization.translateTagName(item.tag); // const anchor = props.getUniqueAliasInPage(name); const anchor = context.slugger.slug(name); return (JSX.createElement(JSX.Fragment, null, JSX.createElement("div", { class: `tsd-tag-${item.tag.substring(1)}` }, JSX.createElement("h4", { class: "tsd-anchor-link" }, JSX.createElement("a", { id: anchor, class: "tsd-anchor" }), name, anchorIcon(context, anchor)), JSX.createElement(JSX.Raw, { html: context.markdown(item.content) })))); })), afterTags)); }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Utils/lib * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ /** * A helper function that both filters and transforms elements in an array. */ const filterMap$1 = (iter, fn) => { const result = []; for (const item of iter || []) { const newItem = fn(item); if (newItem !== undefined) { result.push(newItem); } } return result; }; /** * Get the full package name. */ const getDisplayName = (refl) => { let version = ''; if ((refl instanceof DeclarationReflection || refl instanceof ProjectReflection) && refl.packageVersion) { version = ` - v${refl.packageVersion}`; } return `${refl.name}${version}`; }; /** * Get the kind of a reflection. */ const getKindClass = (refl) => { if (refl instanceof ReferenceReflection) { return getKindClass(refl.getTargetReflectionDeep()); } return ReflectionKind.classString(refl.kind); }; /** * Insert word break tags ``<wbr>`` into the given string. * * Breaks the given string at ``_``, ``-`` and capital letters. * * @param str The string that should be split. * @return The original string containing ``<wbr>`` tags where possible. */ const wbr = (str) => { // TODO surely there is a better way to do this, but I'm tired. const ret = []; const re = /[\s\S]*?(?:[^_-][_-](?=[^_-])|[^A-Z](?=[A-Z][^A-Z]))/g; let match; let i = 0; while ((match = re.exec(str))) { ret.push(match[0], JSX.createElement("wbr", null)); i += match[0].length; } ret.push(str.slice(i)); return ret; }; /** * Join all the elements. */ const join$1 = (joiner, list, cb) => { const result = []; for (const item of list) { if (result.length > 0) { result.push(joiner); } result.push(cb(item)); } return JSX.createElement(JSX.Fragment, null, result); }; /** * Return the class names for css of the given names. */ const classNames = (names, extraCss) => { const css = Object.keys(names) .filter((key) => names[key]) .concat(extraCss || '') .join(' ') .trim() .replace(/\s+/g, ' '); return css.length ? css : undefined; }; /** * Answer if the given reflection has type parameters. */ const hasTypeParameters = (reflection) => (reflection instanceof DeclarationReflection || reflection instanceof SignatureReflection) && reflection.typeParameters !== undefined && // eslint-disable-next-line no-null/no-null reflection.typeParameters !== null && reflection.typeParameters.length > 0; class DefaultMap extends Map { creator; constructor(creator) { super(); this.creator = creator; } get(key) { const saved = super.get(key); // eslint-disable-next-line no-null/no-null if (saved != null) { return saved; } const created = this.creator(key); this.set(key, created); return created; } getNoInsert(key) { return super.get(key); } } const nameCollisionCache = new WeakMap(); const getNameCollisionCount = (project, name) => { let collisions = nameCollisionCache.get(project); if (collisions === undefined) { collisions = new DefaultMap(() => 0); for (const reflection of project.getReflectionsByKind(ReflectionKind.SomeExport)) { collisions.set(reflection.name, collisions.get(reflection.name) + 1); } nameCollisionCache.set(project, collisions); } return collisions.get(name); }; const getNamespacedPath = (reflection) => { const path = [reflection]; let parent = reflection.parent; while (parent?.kindOf(ReflectionKind.Namespace)) { path.unshift(parent); parent = parent.parent; } return path; }; /** * 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. */ const getUniquePath = (reflection) => { if (reflection.kindOf(ReflectionKind.SomeExport)) { if (getNameCollisionCount(reflection.project, reflection.name) >= 2) { return getNamespacedPath(reflection); } } return [reflection]; }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Partials/Comments * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ const reflectionFlags = (context, props) => { const flagsNotRendered = context.options.getValue('notRenderedTags') ?? [ '@showCategories', '@showGroups', '@hideCategories', '@hideGroups' ]; const allFlags = props.flags.getFlagStrings(context.internationalization); if (props.comment) { for (const tag of props.comment.modifierTags) { if (!flagsNotRendered.includes(tag)) { allFlags.push(context.internationalization.translateTagName(tag)); } } } return join$1(' ', allFlags, (item) => (JSX.createElement("code", { class: `tsd-tag tsd-tag-${item.toLowerCase()}` }, item))); }; /* * ***************************************************************************** * Copyright (C) National University of Quilmes 2018-2024 * Gobstones (TM) is a trademark of the National University of Quilmes. * * This program is free software distributed under the terms of the * GNU Affero General Public License version 3. * Additional terms added in compliance to section 7 of such license apply. * * You may read the full license at https://gobstones.github.io/gobstones-guidelines/LICENSE. * ***************************************************************************** */ /** * @module Theme/Partials/Comments * @author Alan Rodas Bonjour <alanrodas@gmail.com> */ con