From 66c5764ef9591a6c90cd5020d5b64a96d06a3e5f Mon Sep 17 00:00:00 2001 From: tjcouch-sil Date: Wed, 13 Dec 2023 12:00:28 -0600 Subject: [PATCH] Prep for use in multi-extension-template - moved files, synced formatting settings with core, added more template instructions to readme --- .editorconfig | 3 + .eslintignore | 2 +- .eslintrc.js | 37 +- .prettierignore | 2 +- .prettierrc.js | 3 + .stylelintignore | 2 +- .vscode/extensions.json | 9 + .vscode/settings.json | 32 +- LICENSE | 2 +- README.md | 144 ++- cspell.json | 60 ++ public/manifest.json => manifest.json | 3 +- package-lock.json | 1035 ++++++++++++++++++++ package.json | 6 +- src/webpack-env.d.ts | 20 +- tsconfig.json | 7 +- webpack/web-view-resolve-webpack-plugin.ts | 28 +- webpack/webpack.config.base.ts | 13 +- webpack/webpack.config.main.ts | 18 +- webpack/webpack.config.web-view.ts | 2 +- webpack/webpack.util.ts | 25 +- 21 files changed, 1314 insertions(+), 139 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 cspell.json rename public/manifest.json => manifest.json (71%) diff --git a/.editorconfig b/.editorconfig index 2930e09..f4575f8 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,3 +11,6 @@ max_line_length = 100 [*.md] trim_trailing_whitespace = false + +[*.cs] +indent_size = 4 diff --git a/.eslintignore b/.eslintignore index 9752186..3ec84fe 100644 --- a/.eslintignore +++ b/.eslintignore @@ -22,7 +22,7 @@ npm-debug.log.* *.sass.d.ts *.scss.d.ts -# Packager output +# Built files dist release temp-build diff --git a/.eslintrc.js b/.eslintrc.js index a069cfe..9aa0057 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,6 +3,9 @@ module.exports = { // https://github.com/electron-react-boilerplate/eslint-config-erb/blob/main/index.js // airbnb rules are embedded in erb https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb 'erb', + // Make sure this is last so it gets the chance to override other configs. + // See https://github.com/prettier/eslint-config-prettier and https://github.com/prettier/eslint-plugin-prettier + 'plugin:prettier/recommended', ], rules: { @@ -47,6 +50,17 @@ module.exports = { '@typescript-eslint/no-non-null-assertion': 'error', 'no-redeclare': 'off', '@typescript-eslint/no-redeclare': 'error', + 'no-restricted-imports': [ + 'error', + { + patterns: [ + { + group: ['shared/*', 'renderer/*', 'extension-host/*', 'node/*', 'client/*', 'main/*'], + message: `Importing from this path is not allowed. Try importing from @papi/core. Imports from paths like 'shared', 'renderer', 'node', 'client' and 'main' are not allowed to prevent unnecessary import break.`, + }, + ], + }, + ], 'no-shadow': 'off', '@typescript-eslint/no-shadow': 'error', 'no-use-before-define': 'off', @@ -70,17 +84,7 @@ module.exports = { 'no-console': 'warn', 'no-null/no-null': 2, 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], - 'no-restricted-imports': [ - 'error', - { - patterns: [ - { - group: ['shared/*', 'renderer/*', 'extension-host/*', 'node/*', 'client/*', 'main/*'], - message: `Importing from this path is not allowed. Try importing from @papi/core. Imports from paths like 'shared', 'renderer', 'node', 'client' and 'main' are not allowed to prevent unnecessary import break.`, - }, - ], - }, - ], + 'no-type-assertion/no-type-assertion': 'error', 'prettier/prettier': ['warn', { tabWidth: 2, trailingComma: 'all' }], 'react/jsx-indent-props': ['warn', 2], 'react/jsx-props-no-spreading': ['error', { custom: 'ignore' }], @@ -90,7 +94,7 @@ module.exports = { // #endregion - // #region Overrides from paranext-core extension .eslintrc.cjs + // #region Overrides shared with paranext-multi-extension-template .eslintrc.cjs 'import/no-unresolved': ['error', { ignore: ['@papi'] }], @@ -113,6 +117,13 @@ module.exports = { 'import/prefer-default-export': 'off', }, }, + { + files: ['./lib/*', './webpack/*'], + rules: { + // These files are scripts not running in Platform.Bible, so they can't use the logger + 'no-console': 'off', + }, + }, ], parserOptions: { ecmaVersion: 2020, @@ -121,7 +132,7 @@ module.exports = { tsconfigRootDir: __dirname, createDefaultProgram: true, }, - plugins: ['@typescript-eslint', 'no-null'], + plugins: ['@typescript-eslint', 'no-type-assertion', 'no-null'], settings: { 'import/resolver': { typescript: { diff --git a/.prettierignore b/.prettierignore index abb2869..03f6570 100644 --- a/.prettierignore +++ b/.prettierignore @@ -22,7 +22,7 @@ npm-debug.log.* *.sass.d.ts *.scss.d.ts -# Packager output +# Built files dist release temp-build diff --git a/.prettierrc.js b/.prettierrc.js index 6288d4c..ae319d5 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -3,6 +3,9 @@ module.exports = { trailingComma: 'all', endOfLine: 'lf', singleQuote: true, + // prettier-plugin-jsdoc options + tsdoc: true, + plugins: ['prettier-plugin-jsdoc'], overrides: [ { files: '*.json', diff --git a/.stylelintignore b/.stylelintignore index a519d57..dffbdf4 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -22,7 +22,7 @@ npm-debug.log.* *.sass.d.ts *.scss.d.ts -# Packager output +# Built files dist release temp-build diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..798b808 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "streetsidesoftware.code-spell-checker", + "stylelint.vscode-stylelint" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 688cb5c..cefc6be 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,22 +1,36 @@ { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, "editor.rulers": [100], "editor.wordWrapColumn": 100, + "eslint.validate": ["javascript", "javascriptreact", "html", "typescriptreact"], + "files.associations": { ".eslintignore": "ignore", ".prettierignore": "ignore", ".stylelintignore": "ignore" }, "files.eol": "\n", - "cSpell.words": [ - "asyncs", - "endregion", - "papi", - "paranext", - "sillsdev", - "unsub", - "unsubscriber", - "usfm" + + "javascript.validate.enable": false, + "javascript.format.enable": false, + "typescript.format.enable": false, + + "search.exclude": { + ".git": true, + ".eslintcache": true, + "node_modules": true, + "npm-debug.log.*": true, + "package-lock.json": true, + "*.{css,sass,scss}.d.ts": true + }, + + "json.schemas": [ + { + "fileMatch": ["*tsconfig*.json"], + "url": "http://json.schemastore.org/tsconfig" + } ], "todohighlight.keywords": [ diff --git a/LICENSE b/LICENSE index 0126101..6cb99c1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Paranext +Copyright (c) 2023-present SIL International Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index e2b390b..e7ed2b3 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,99 @@ # paranext-extension-template -Basic extension template for Paranext +Basic extension template for Platform.Bible -## Summary +## Template Info -This is a webpack project template pre-configured to build Paranext extensions. It contains the bare minimum of what an extension needs. Note that the `*.web-view.*` files and the `public/assets` folder mentioned below are not present in this template. For inspiration on what these could look like, refer to any extension that is built using this template. An example would be the [Text Collection extension](https://github.com/paranext/paranext-extension-text-collection). +This is a webpack project template pre-configured to build a Platform.Bible extension. It contains the bare minimum of what an extension needs. Note that the `*.web-view.*` files and the `public/assets` folder mentioned in [Summary](#summary) are not present in this template. For inspiration on what these could look like, refer to any extension that is built using this template. An example would be the [Text Collection extension](https://github.com/paranext/paranext-extension-text-collection). -- `package.json` contains information about this extension's npm package. It is required for Paranext to use the extension properly. It is copied into the build folder -- `src` contains the source code for the extension - - `src/main.ts` is the main entry file for the extension - - `src/types/paranext-extension-template.d.ts` is this extension's types file that defines how other extensions can use this extension through the `papi`. It is copied into the build folder - - `*.web-view.tsx` files will be treated as React WebViews - - `*.web-view.html` files are a conventional way to provide HTML WebViews (no special functionality) -- `public` contains static files that are copied into the build folder - - `public/manifest.json` is the manifest file that defines the extension and important properties for Paranext - - `public/package.json` defines the npm package for this extension and is required for Paranext to use it appropriately - - `public/assets` contains asset files the extension and its WebViews can retrieve using the `papi-extension:` protocol -- `dist` is a generated folder containing your built extension files -- `release` is a generated folder containing a zip of your built extension files +There is also [a template pre-configured to build an arbitrary number of Platform.Bible extensions in one repo](https://github.com/paranext/paranext-multi-extension-template). -## To install +### Customize extension details -### Configure paths to `paranext-core` repo +Follow these instructions to customize the template to be your own Platform.Bible extension. This section is a more compact version of the [`Your first extension` guide](https://github.com/paranext/paranext-extension-template/wiki/Your-First-Extension). -In order to interact with `paranext-core`, you must point `package.json` to your installed `paranext-core` repository: +#### Install and hook up to the template -1. Follow the instructions to install [`paranext-core`](https://github.com/paranext/paranext-core#developer-install). We recommend you clone `paranext-core` in the same parent directory in which you cloned this repository so you do not have to reconfigure paths to `paranext-core`. -2. If you cloned `paranext-core` anywhere other than in the same parent directory in which you cloned this repository, update the paths to `paranext-core` in this repository's `package.json` to point to the correct `paranext-core` directory. +Note: please skip this section and continue with [Replace placeholders](#replace-placeholders) if you are following these instructions as part of [creating an extension within `paranext-multi-extension-template`](https://github.com/paranext/paranext-multi-extension-template#to-create-a-new-extension-in-this-repo). + +To make the process of customizing from the template as smooth as possible, we recommend you do the following before anything else: + +- [Install and set up this repo](#to-install) +- [Update this extension from the template](#to-update-this-extension-from-the-template) + +#### Replace placeholders + +- At the top of this `README.md`: + + - Replace the first line `# paranext-extension-template` with `# your-extension-name` + - Below the first line, replace the extension description with your own description + - In the [Summary](#summary) section, replace `src/types/paranext-extension-template.d.ts` with `src/types/.d.ts` + +- In `manifest.json`: + + - Replace `paranext-extension-template` with `your-extension-name` (2 occurrences) + - Replace the description with your own description + +- In `package.json`: + + - Replace `paranext-extension-template` with `your-extension-name` (2 occurrences) + - Replace the description with your own description -### Install dependencies +- Rename `src/types/paranext-extension-template.d.ts` to `src/types/.d.ts` -Run `npm install` to install local and published dependencies + - In this renamed file, replace `paranext-extension-template` with `your-extension-name` -### Configure extension details +- In `src/main.ts`, replace `Extension template` with `Your Extension Name` (2 occurrences) -This section is a more compact version of the [`Your first extension` guide](https://github.com/paranext/paranext-extension-template/wiki/Your-First-Extension). +#### Customize the extension manifest and package information -#### Search and replace placeholders +The `manifest.json` and `package.json` files contain information specific to your extension. Add your extension's details in these two files as needed. See more information on the `manifest.json` and `package.json` files in [Extension Anatomy](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy#extension-manifest). -- **Search for:** paranext-extension-template - **Replace with:** your-extension-name -- **Search for:** Extension Template - **Replace with:** Your Extension - (Be sure to match case) +#### Remove Template Info -#### Filenames +Once finished customizing this template to be your own, you can remove the [Template Info](#template-info) section and sub-sections of this readme. -You need to change the filename of the `.d.ts` file, which is located in `/src/types` and referenced in the `package.json` “types” field. See more information on the [.d.ts files](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy#type-declaration-files-dts). +## Summary + +The general file structure is as follows: + +- `package.json` contains information about this extension's npm package. It is required for Platform.Bible to use the extension properly. It is copied into the build folder +- `manifest.json` is the manifest file that defines the extension and important properties for Platform.Bible. It is copied into the build folder +- `src/` contains the source code for the extension + - `src/main.ts` is the main entry file for the extension + - `src/types/paranext-extension-template.d.ts` is this extension's types file that defines how other extensions can use this extension through the `papi`. It is copied into the build folder + - `*.web-view.tsx` files will be treated as React WebViews + - `*.web-view.html` files are a conventional way to provide HTML WebViews (no special functionality) +- `assets/` contains asset files the extension and its WebViews can retrieve using the `papi-extension:` protocol. It is copied into the build folder +- `public/` contains other static files that are copied into the build folder +- `dist/` is a generated folder containing the built extension files +- `release/` is a generated folder containing a zip of the built extension files -#### Manifest +## To install -The `manifest.json` and `package.json` files makeup your extension manifest. Add your details in these two files based on your extension name and what you renamed the files described in 1 and 2. See more information on the `manifest.json` and `package.json` files in [Extension Anatomy](https://github.com/paranext/paranext-extension-template/wiki/Extension-Anatomy#extension-manifest). +### Install dependencies: -#### Webpack +1. Follow the instructions to install [`paranext-core`](https://github.com/paranext/paranext-core#developer-install). +2. In this repo, run `npm install` to install local and published dependencies -You will need to add your extension's name into `webpack.config.main.ts` and `webpack.util.ts`. The search and replace actions listed above will correct this for you. +### Configure paths to `paranext-core` repo + +In order to interact with `paranext-core`, you must point `package.json` to your installed `paranext-core` repository: + +1. Follow the instructions to install [`paranext-core`](https://github.com/paranext/paranext-core#developer-install). We recommend you clone `paranext-core` in the same parent directory in which you cloned this repository so you do not have to reconfigure paths to `paranext-core`. +2. If you cloned `paranext-core` anywhere other than in the same parent directory in which you cloned this repository, update the paths to `paranext-core` in this repository's `package.json` to point to the correct `paranext-core` directory. ## To run -### Running Paranext with your extension +### Running Platform.Bible with this extension -To run Paranext with your extension: +To run Platform.Bible with this extension: `npm start` -Note: The built extension will be in the `dist` folder. In order for Paranext to run your extension, you must provide the directory to your built extension to Paranext via a command-line argument. This command-line argument is already provided in this `package.json`'s `start` script. If you want to start Paranext and use your extension any other way, you must provide this command-line argument or put the `dist` folder into Paranext's `extensions` folder. +Note: The built extension will be in the `dist` folder. In order for Platform.Bible to run this extension, you must provide the directory to this built extension to Platform.Bible via a command-line argument. This command-line argument is already provided in this `package.json`'s `start` script. If you want to start Platform.Bible and use this extension any other way, you must provide this command-line argument or put the `dist` folder into Platform.Bible's `extensions` folder. -### Building your extension independently +### Building this extension independently To watch extension files (in `src`) for changes: @@ -78,23 +105,38 @@ To build the extension once: ## To package for distribution -To package your extension into a zip file for distribution: +To package this extension into a zip file for distribution: `npm run package` -## To update +## To update this extension from the template + +This extension project is forked from [`paranext-extension-template`](https://github.com/paranext/paranext-extension-template), which is updated periodically and will sometimes receive updates that help with breaking changes on [`paranext-core`](https://github.com/paranext/paranext-core). We recommend you periodically update your extension by merging the latest template updates into your extension. + +To set up this extension to be updated from the template, run the following command once after cloning this repo: + +```bash +git remote add template https://github.com/paranext/paranext-extension-template +``` + +To update this extension from the template, make sure your repo has no working changes. Then run the following commands: + +```bash +git fetch template +git merge template/main --allow-unrelated-histories +``` -The `paranext-extension-template` will be updated regularly, and will sometimes receive updates that help with breaking changes on `paranext-core`. So we recommend you periodically update your extension by merging the latest template updates into your extension. You can do so by following [these instructions](https://github.com/paranext/paranext-extension-template/wiki/Merging-Template-Changes-into-Your-Extension). +For more information, read [the instructions on the wiki](https://github.com/paranext/paranext-extension-template/wiki/Merging-Template-Changes-into-Your-Extension). -## Special features of the template +## Special features in this project -This template has special features and specific configuration to make building an extension for Paranext easier. Following are a few important notes: +This project has special features and specific configuration to make building an extension for Platform.Bible easier. Following are a few important notes: ### React WebView files - `.web-view.tsx` -Paranext WebViews must be treated differently than other code, so this template makes doing that simpler: +Platform.Bible WebViews must be treated differently than other code, so this project makes doing that simpler: -- WebView code must be bundled and can only import specific packages provided by Paranext (see `externals` in `webpack.config.base.ts`), so this template bundles React WebViews before bundling the main extension file to support this requirement. The template discovers and bundles files that end with `.web-view.tsx` in this way. +- WebView code must be bundled and can only import specific packages provided by Platform.Bible (see `externals` in `webpack.config.base.ts`), so this project bundles React WebViews before bundling the main extension file to support this requirement. The project discovers and bundles files that end with `.web-view.tsx` in this way. - Note: while watching for changes, if you add a new `.web-view.tsx` file, you must either restart webpack or make a nominal change and save in an existing `.web-view.tsx` file for webpack to discover and bundle this new file. - WebView code and styles must be provided to the `papi` as strings, so you can import WebView files with [`?inline`](#special-imports) after the file path to import the file as a string. @@ -106,18 +148,18 @@ Paranext WebViews must be treated differently than other code, so this template ### Misc features -- Paranext extension code must be bundled all together in one file, so webpack bundles all the code together into one main extension file. -- Paranext extensions can interact with other extensions, but they cannot import and export like in a normal Node environment. Instead, they interact through the `papi`. As such, the `src/types` folder contains this extension's declarations file that tells other extensions how to interact with it through the `papi`. +- Platform.Bible extension code must be bundled all together in one file, so webpack bundles all the code together into one main extension file. +- Platform.Bible extensions can interact with other extensions, but they cannot import and export like in a normal Node environment. Instead, they interact through the `papi`. As such, the `src/types` folder contains this extension's declarations file that tells other extensions how to interact with it through the `papi`. ### Two-step webpack build -This extension template is built by webpack (`webpack.config.ts`) in two steps: a WebView bundling step and a main bundling step: +This extension is built by webpack (`webpack.config.ts`) in two steps: a WebView bundling step and a main bundling step: #### Build 1: TypeScript WebView bundling Webpack (`./webpack/webpack.config.web-view.ts`) prepares TypeScript WebViews for use and outputs them into temporary build folders adjacent to the WebView files: -- Formats WebViews to match how they should look to work in Paranext +- Formats WebViews to match how they should look to work in Platform.Bible - Transpiles React/TypeScript WebViews into JavaScript - Bundles dependencies into the WebViews - Embeds Sourcemaps into the WebViews inline diff --git a/cspell.json b/cspell.json new file mode 100644 index 0000000..e65b0a3 --- /dev/null +++ b/cspell.json @@ -0,0 +1,60 @@ +{ + "version": "0.2", + "ignorePaths": [ + ".git/objects", + ".vscode", + ".vscode-insiders", + "electron-builder.json5", + "node_modules", + "package.json", + "package-lock.json", + "vscode-extension" + ], + "dictionaryDefinitions": [], + "dictionaries": [], + "words": [ + "appdata", + "asyncs", + "autodocs", + "dockbox", + "electronmon", + "endregion", + "finalizer", + "Fragmenter", + "guids", + "hopkinson", + "iframes", + "localstorage", + "maximizable", + "networkable", + "Newtonsoft", + "nodebuffer", + "nums", + "papi", + "papis", + "paranext", + "paratext", + "pdpf", + "pdps", + "plusplus", + "proxied", + "reinitializing", + "reserialized", + "sillsdev", + "steenwyk", + "stringifiable", + "Stylesheet", + "typedefs", + "unregistering", + "unregisters", + "unsub", + "unsubs", + "unsubscriber", + "unsubscribers", + "usfm", + "verseref", + "versification" + ], + "ignoreWords": [], + "import": [] +} diff --git a/public/manifest.json b/manifest.json similarity index 71% rename from public/manifest.json rename to manifest.json index 541c761..92ba8bb 100644 --- a/public/manifest.json +++ b/manifest.json @@ -4,6 +4,7 @@ "description": "Extension template for Paranext. Powered by webpack", "author": "Paranext", "license": "MIT", - "main": "paranext-extension-template.ts", + "main": "src/main.ts", + "types": "src/types/paranext-extension-template.d.ts", "activationEvents": [] } diff --git a/package-lock.json b/package-lock.json index a6383ff..a52a346 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "eslint-plugin-jest": "^27.2.3", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-no-type-assertion": "^1.3.0", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", @@ -36,6 +37,7 @@ "papi-components": "file:../paranext-core/lib/papi-components", "papi-dts": "file:../paranext-core/lib/papi-dts", "prettier": "^2.8.8", + "prettier-plugin-jsdoc": "^0.4.2", "sass": "^1.66.1", "sass-loader": "^13.3.2", "stylelint": "^15.10.3", @@ -2182,6 +2184,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "8.44.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", @@ -2257,12 +2268,27 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, "node_modules/@types/node": { "version": "18.17.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.12.tgz", @@ -2320,6 +2346,12 @@ "dev": true, "peer": true }, + "node_modules/@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "node_modules/@types/webpack": { "version": "5.28.2", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-5.28.2.tgz", @@ -3536,6 +3568,12 @@ "node": ">=8" } }, + "node_modules/binary-searching": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-searching/-/binary-searching-2.0.5.tgz", + "integrity": "sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==", + "dev": true + }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -3767,6 +3805,16 @@ "node": ">=10" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -4041,6 +4089,15 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/compress-commons": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", @@ -4566,6 +4623,19 @@ "node": ">=0.10.0" } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", @@ -5327,6 +5397,19 @@ "eslint": ">=3.0.0" } }, + "node_modules/eslint-plugin-no-type-assertion": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-type-assertion/-/eslint-plugin-no-type-assertion-1.3.0.tgz", + "integrity": "sha512-04wuuIP5ptNzp969tTt0gf/Jsw4G0T5md2/nbgv3dRL/HySSNU7H4vIKNjkuno9T+6h2daj1T9Aki6bDgmXDEw==", + "dev": true, + "engines": { + "node": ">=12.0.0", + "yarn": "^1.13.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -9492,6 +9575,43 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dev": true, + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -9551,6 +9671,448 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -9647,6 +10209,15 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -10471,6 +11042,23 @@ "node": ">=6.0.0" } }, + "node_modules/prettier-plugin-jsdoc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/prettier-plugin-jsdoc/-/prettier-plugin-jsdoc-0.4.2.tgz", + "integrity": "sha512-w2jnAQm3z0GAG0bhzVJeehzDtrhGMSxJjit5ApCc2oxWfc7+jmLAkbtdOXaSpfwZz3IWkk+PiQPeRrLNpbM+Mw==", + "dev": true, + "dependencies": { + "binary-searching": "^2.0.5", + "comment-parser": "^1.3.1", + "mdast-util-from-markdown": "^1.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "prettier": ">=2.1.2" + } + }, "node_modules/pretty-format": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", @@ -11010,6 +11598,18 @@ "tslib": "^2.1.0" } }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-array-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", @@ -12465,6 +13065,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -12510,6 +13123,42 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "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", @@ -14700,6 +15349,15 @@ "@babel/types": "^7.20.7" } }, + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, "@types/eslint": { "version": "8.44.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.2.tgz", @@ -14775,12 +15433,27 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/mdast": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dev": true, + "requires": { + "@types/unist": "^2" + } + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, + "@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true + }, "@types/node": { "version": "18.17.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.12.tgz", @@ -14838,6 +15511,12 @@ "dev": true, "peer": true }, + "@types/unist": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", + "dev": true + }, "@types/webpack": { "version": "5.28.2", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-5.28.2.tgz", @@ -15758,6 +16437,12 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "binary-searching": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/binary-searching/-/binary-searching-2.0.5.tgz", + "integrity": "sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==", + "dev": true + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -15906,6 +16591,12 @@ "dev": true, "peer": true }, + "character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -16114,6 +16805,12 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, + "comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true + }, "compress-commons": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", @@ -16482,6 +17179,15 @@ } } }, + "decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dev": true, + "requires": { + "character-entities": "^2.0.0" + } + }, "dedent": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz", @@ -17140,6 +17846,13 @@ "dev": true, "requires": {} }, + "eslint-plugin-no-type-assertion": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-no-type-assertion/-/eslint-plugin-no-type-assertion-1.3.0.tgz", + "integrity": "sha512-04wuuIP5ptNzp969tTt0gf/Jsw4G0T5md2/nbgv3dRL/HySSNU7H4vIKNjkuno9T+6h2daj1T9Aki6bDgmXDEw==", + "dev": true, + "requires": {} + }, "eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -20164,6 +20877,35 @@ "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, + "mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + } + }, + "mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dev": true, + "requires": { + "@types/mdast": "^3.0.0" + } + }, "mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -20210,6 +20952,238 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "dev": true, + "requires": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "dev": true, + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "dev": true, + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "dev": true, + "requires": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "dev": true, + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "dev": true, + "requires": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "dev": true + }, + "micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "dev": true + }, + "micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "dev": true, + "requires": { + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "dev": true, + "requires": { + "micromark-util-types": "^1.0.0" + } + }, + "micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "dev": true, + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" + } + }, + "micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "dev": true, + "requires": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "dev": true + }, + "micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "dev": true + }, "micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -20279,6 +21253,12 @@ "integrity": "sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==", "dev": true }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -20876,6 +21856,17 @@ "fast-diff": "^1.1.2" } }, + "prettier-plugin-jsdoc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/prettier-plugin-jsdoc/-/prettier-plugin-jsdoc-0.4.2.tgz", + "integrity": "sha512-w2jnAQm3z0GAG0bhzVJeehzDtrhGMSxJjit5ApCc2oxWfc7+jmLAkbtdOXaSpfwZz3IWkk+PiQPeRrLNpbM+Mw==", + "dev": true, + "requires": { + "binary-searching": "^2.0.5", + "comment-parser": "^1.3.1", + "mdast-util-from-markdown": "^1.2.0" + } + }, "pretty-format": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", @@ -21263,6 +22254,15 @@ "tslib": "^2.1.0" } }, + "sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "requires": { + "mri": "^1.1.0" + } + }, "safe-array-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", @@ -22325,6 +23325,15 @@ "which-boxed-primitive": "^1.0.2" } }, + "unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0" + } + }, "update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", @@ -22350,6 +23359,32 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dev": true, + "requires": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "dependencies": { + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true + }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + } + } + }, "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", diff --git a/package.json b/package.json index bf009ba..9f93361 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,8 @@ "name": "paranext-extension-template", "private": true, "version": "0.0.1", - "main": "paranext-extension-template.js", - "types": "paranext-extension-template.d.ts", + "main": "src/main.js", + "types": "src/types/paranext-extension-template.d.ts", "author": "Paranext", "license": "MIT", "scripts": { @@ -52,6 +52,7 @@ "eslint-plugin-jest": "^27.2.3", "eslint-plugin-jsx-a11y": "^6.7.1", "eslint-plugin-no-null": "^1.0.2", + "eslint-plugin-no-type-assertion": "^1.3.0", "eslint-plugin-promise": "^6.1.1", "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", @@ -59,6 +60,7 @@ "papi-components": "file:../paranext-core/lib/papi-components", "papi-dts": "file:../paranext-core/lib/papi-dts", "prettier": "^2.8.8", + "prettier-plugin-jsdoc": "^0.4.2", "sass": "^1.66.1", "sass-loader": "^13.3.2", "stylelint": "^15.10.3", diff --git a/src/webpack-env.d.ts b/src/webpack-env.d.ts index a2eb21e..fa9ba2c 100644 --- a/src/webpack-env.d.ts +++ b/src/webpack-env.d.ts @@ -12,41 +12,33 @@ * Import fully loaded and transformed files as strings with "./file?inline" * * WARNING: These files are NOT bundled. The rules are applied, but webpack does not bundle - * dependencies into these files before providing them, unfortunately. However, React WebView - * files are an exception as they are fully bundled. + * dependencies into these files before providing them, unfortunately. However, React WebView files + * are an exception as they are fully bundled. */ declare module '*?inline' { const content: string; export default content; } -/** - * Import files with no transformation as strings with "./file?raw" - */ +/** Import files with no transformation as strings with "./file?raw" */ declare module '*?raw' { const content: string; export default content; } -/** - * Import scss, sass, and css files as strings - */ +/** Import scss, sass, and css files as strings */ declare module '*.scss' { const content: string; export default content; } -/** - * Import scss, sass, and css files as strings - */ +/** Import scss, sass, and css files as strings */ declare module '*.sass' { const content: string; export default content; } -/** - * Import scss, sass, and css files as strings - */ +/** Import scss, sass, and css files as strings */ declare module '*.css' { const content: string; export default content; diff --git a/tsconfig.json b/tsconfig.json index 5a78f8a..ac6b9fa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -55,9 +55,14 @@ // We want sourcemaps so we can bundle them with webpack "sourceMap": true, // We need a baseurl for webpack's tsconfig path aliases plugin - "baseUrl": "./" + "baseUrl": "./", + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true }, "include": ["src"], + "exclude": ["node_modules"], "ts-node": { // This allows us to use path aliases in ts-node "require": ["tsconfig-paths/register"], diff --git a/webpack/web-view-resolve-webpack-plugin.ts b/webpack/web-view-resolve-webpack-plugin.ts index 49a5c84..677a147 100644 --- a/webpack/web-view-resolve-webpack-plugin.ts +++ b/webpack/web-view-resolve-webpack-plugin.ts @@ -26,6 +26,7 @@ export default class WebViewResolveWebpackPlugin { /** * Function that applies this plugin to webpack resolving. Use the resolver to "tap into" webpack * resolving with our own logic + * * @param resolver */ apply(resolver: Resolver) { @@ -43,19 +44,20 @@ export default class WebViewResolveWebpackPlugin { /** * The logic to add to webpack resolving so it will look in the temp dir for built code. * - * @param request information about the resolve request - * @param resolveContext information about the process the hook has taken to get here - * @param callback function to run to continue the resolution process - * - call with no parameters to continue resolving like this plugin did nothing - * - call with first parameter null and second parameter a fully resolved - * `{ path, relativePath }` (including file extension) to conclude resolving at that file - * - call with first parameter `string` or `Error` or something (not sure) to indicate - * error - * - Note: another option is to call `resolver.doResolve` to start the resolution process - * over with a new `path` and `relativePath` that do not need to be fully resolved. Just - * make sure that second call can't come into your hook again and cause another - * `resolver.doResolve`, or you will have an infinite loop. We pass this `callback` param - * into `resolver.doResolve`, and it calls it automatically + * @param request Information about the resolve request + * @param resolveContext Information about the process the hook has taken to get here + * @param callback Function to run to continue the resolution process + * + * - Call with no parameters to continue resolving like this plugin did nothing + * - Call with first parameter null and second parameter a fully resolved `{ path, + * relativePath }` (including file extension) to conclude resolving at that file + * - Call with first parameter `string` or `Error` or something (not sure) to indicate error + * - Note: another option is to call `resolver.doResolve` to start the resolution process over + * with a new `path` and `relativePath` that do not need to be fully resolved. Just + * make sure that second call can't come into your hook again and cause another + * `resolver.doResolve`, or you will have an infinite loop. We pass this `callback` + * param into `resolver.doResolve`, and it calls it automatically + * * @returns Seems it doesn't matter if or what you return. Just return to quit early */ (request, resolveContext, callback) => { diff --git a/webpack/webpack.config.base.ts b/webpack/webpack.config.base.ts index b1de943..21b2030 100644 --- a/webpack/webpack.config.base.ts +++ b/webpack/webpack.config.base.ts @@ -23,7 +23,7 @@ export const LIBRARY_TYPE: NonNullable = // Note: we do not want to do any chunking because neither webViews nor main can import dependencies // other than those listed in configBase.externals. Each webView must contain all its dependency // code, and main must contain all its dependency code. -/** webpack configuration shared by webView building and main building */ +/** Webpack configuration shared by webView building and main building */ const configBase: webpack.Configuration = { // The operating directory for webpack instead of current working directory context: rootDir, @@ -88,9 +88,7 @@ const configBase: webpack.Configuration = { }, exclude: /node_modules/, }, - /** - * Import scss, sass, and css files as strings - */ + /** Import scss, sass, and css files as strings */ // https://webpack.js.org/loaders/sass-loader/#getting-started { test: /\.(sa|sc|c)ss$/, @@ -103,7 +101,8 @@ const configBase: webpack.Configuration = { 'sass-loader', ], }, - /** Load images as data uris + /** + * Load images as data uris * * Note: it is generally advised to use the `papi-extension:` protocol to load assets */ @@ -122,9 +121,7 @@ const configBase: webpack.Configuration = { test: /\.(woff|woff2|eot|ttf|otf)$/i, type: 'asset/inline', }, - /** - * Import files with no transformation as strings with "./file?raw" - */ + /** Import files with no transformation as strings with "./file?raw" */ // This must be the last rule in order to be applied before all other transformations // https://webpack.js.org/guides/asset-modules/#replacing-inline-loader-syntax { diff --git a/webpack/webpack.config.main.ts b/webpack/webpack.config.main.ts index 22291f3..f97a991 100644 --- a/webpack/webpack.config.main.ts +++ b/webpack/webpack.config.main.ts @@ -6,7 +6,7 @@ import configBase, { LIBRARY_TYPE, rootDir } from './webpack.config.base'; import WebViewResolveWebpackPlugin from './web-view-resolve-webpack-plugin'; import { outputFolder } from './webpack.util'; -/** webpack configuration for building main */ +/** Webpack configuration for building main */ const configMain: webpack.Configuration = merge(configBase, { // #region shared with https://github.com/paranext/paranext-core/blob/main/extensions/webpack/webpack.config.main.ts @@ -42,7 +42,7 @@ const configMain: webpack.Configuration = merge(configBase, { entry: { main: { import: './src/main.ts', - filename: 'paranext-extension-template.js', + filename: './src/main.js', }, }, plugins: [ @@ -50,11 +50,15 @@ const configMain: webpack.Configuration = merge(configBase, { new CopyPlugin({ patterns: [ // We want all files from the public folder copied into the output folder - { from: 'public', to: './' }, - // Copy this extension's type declaration file into the output folder - { from: 'src/types/paranext-extension-template.d.ts', to: './' }, - // We need to distribute the package.json for Paranext to read the extension properly - { from: 'package.json', to: './' }, + { from: 'public', to: './', noErrorOnMissing: true }, + // We want all files from the assets folder copied into the output folder under assets + { from: 'assets', to: './assets/', noErrorOnMissing: true }, + // Copy this extension's type declaration file into the output folder under src/types + { from: 'src/types', to: './src/types', noErrorOnMissing: true }, + // We need to distribute the package.json for Platform.Bible to read the extension properly + { from: 'package.json', to: './', noErrorOnMissing: true }, + // We need to distribute the manifest.json to inform Platform.Bible about the extension + { from: 'manifest.json', to: './' }, ], }), ], diff --git a/webpack/webpack.config.web-view.ts b/webpack/webpack.config.web-view.ts index 59122e6..7a4debe 100644 --- a/webpack/webpack.config.web-view.ts +++ b/webpack/webpack.config.web-view.ts @@ -5,7 +5,7 @@ import merge from 'webpack-merge'; import configBase, { rootDir } from './webpack.config.base'; import { getWebViewEntries } from './webpack.util'; -/** webpack configuration for building webViews */ +/** Webpack configuration for building webViews */ const configWebView: webpack.Configuration = merge(configBase, { // Build for web since Paranext loads WebViews in browser https://webpack.js.org/concepts/targets/ target: 'web', diff --git a/webpack/webpack.util.ts b/webpack/webpack.util.ts index ce819e9..8841049 100644 --- a/webpack/webpack.util.ts +++ b/webpack/webpack.util.ts @@ -11,14 +11,10 @@ import { glob } from 'glob'; * Web Views should be named .web-view. */ const webViewTag = '.web-view'; -/** - * Glob filename matcher for React web views. - * React Web Views should be named .web-view.tsx - */ +/** Glob filename matcher for React web views. React Web Views should be named .web-view.tsx */ const webViewTsxGlob = '**/*.web-view.tsx'; /** - * Regex file name matcher for React web views. - * React Web Views should be named .web-view.tsx + * Regex file name matcher for React web views. React Web Views should be named .web-view.tsx * * Note: this regex allows the extension to be optional. */ @@ -29,18 +25,16 @@ export const webViewTempDir = 'temp-build'; /** Folder containing the built extension files */ export const outputFolder = 'dist'; -/** - * Get a list of TypeScript WebView files to bundle. - * Path relative to project root - */ +/** Get a list of TypeScript WebView files to bundle. Path relative to project root */ function getWebViewTsxPaths() { return glob(webViewTsxGlob, { ignore: 'node_modules/**' }); } /** * Gets the bundled WebView path for a WebView file path - * @param webViewPath relative path to webView e.g. './src/extension-template.web-view.tsx' - * @param join function to use to join the paths together + * + * @param webViewPath Relative path to webView e.g. './src/extension-template.web-view.tsx' + * @param join Function to use to join the paths together * @returns WebView path with temporary WebView directory inserted into the module path */ export function getWebViewTempPath( @@ -63,17 +57,18 @@ export function getWebViewTempPath( /** * Get webpack entry configuration to build each web-view source file and put it in a temporary * folder in the same directory - * @returns promise that resolves to the webView entry config + * + * @returns Promise that resolves to the webView entry config */ export async function getWebViewEntries(): Promise { const tsxWebViews = await getWebViewTsxPaths(); const webViewEntries = Object.fromEntries( - tsxWebViews.map((webViewPath) => [ + tsxWebViews.map((webViewPath): [string, webpack.EntryObject[string]] => [ webViewPath, { import: webViewPath, filename: getWebViewTempPath(webViewPath), - } as webpack.EntryObject[string], + }, ]), ); return webViewEntries;